This commit is contained in:
2026-01-29 23:51:42 +01:00
parent f506f2d7a3
commit 28d99abf39
5 changed files with 717 additions and 38 deletions

View File

@@ -0,0 +1,245 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
interface IllustrationProps {
className?: string;
delay?: number;
}
export const ConceptCommunication: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="20" cy="60" r="6" className="fill-slate-100 stroke-slate-200" strokeWidth="1" />
<circle cx="100" cy="60" r="6" className="fill-slate-900" />
<path d="M 26 60 H 94" stroke="currentColor" strokeWidth="1" className="text-slate-100" strokeDasharray="4 4" />
<motion.path
d="M 26 60 H 94"
stroke="currentColor"
strokeWidth="2"
className="text-slate-400"
initial={{ pathLength: 0 }}
animate={{ pathLength: [0, 1, 1, 0], opacity: [0, 1, 1, 0] }}
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut", delay }}
/>
<motion.circle r="3" className="fill-slate-900">
<animateMotion
dur="3s"
repeatCount="indefinite"
path="M 26 60 H 94"
/>
</motion.circle>
</svg>
);
export const ConceptPrototyping: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="15" y="25" width="90" height="70" rx="4" stroke="currentColor" strokeWidth="1" className="text-slate-200" />
<path d="M 15 40 H 105" stroke="currentColor" strokeWidth="1" className="text-slate-100" />
<motion.rect
x="25" y="50" width="40" height="8" rx="1"
className="fill-slate-100"
animate={{ width: [0, 40, 40, 0] }}
transition={{ duration: 4, repeat: Infinity, delay }}
/>
<motion.rect
x="25" y="65" width="60" height="8" rx="1"
className="fill-slate-50"
animate={{ width: [0, 60, 60, 0] }}
transition={{ duration: 4, repeat: Infinity, delay: 0.5 }}
/>
<motion.circle
cx="85" cy="75" r="10"
className="fill-slate-900"
animate={{ scale: [0.8, 1.1, 0.8] }}
transition={{ duration: 2, repeat: Infinity }}
/>
</svg>
);
export const ConceptCode: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
{[40, 55, 70, 85].map((y, i) => (
<motion.path
key={y}
d={`M 25 ${y} H ${25 + Math.random() * 60 + 20}`}
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
className="text-slate-200"
initial={{ pathLength: 0 }}
animate={{ pathLength: [0, 1, 1, 0] }}
transition={{ duration: 4, repeat: Infinity, delay: i * 0.2 + delay }}
/>
))}
<motion.path
d="M 90 40 L 100 50 L 115 30"
stroke="currentColor"
strokeWidth="3"
strokeLinecap="round"
strokeLinejoin="round"
className="text-slate-900"
animate={{ opacity: [0, 1, 1, 0], scale: [0.8, 1, 1, 0.8] }}
transition={{ duration: 4, repeat: Infinity, delay: 1.5 }}
/>
</svg>
);
export const ConceptPrice: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="30" y="30" width="60" height="70" rx="2" stroke="currentColor" strokeWidth="1" className="text-slate-200" />
<motion.path
d="M 40 50 H 80 M 40 65 H 80 M 40 80 H 60"
stroke="currentColor"
strokeWidth="1"
className="text-slate-100"
initial={{ pathLength: 0 }}
animate={{ pathLength: [0, 1, 1, 0] }}
transition={{ duration: 5, repeat: Infinity, delay }}
/>
<motion.circle
cx="85" cy="35" r="15"
className="fill-white stroke-slate-900"
strokeWidth="1"
animate={{ y: [0, -5, 0], rotate: [0, 10, 0] }}
transition={{ duration: 4, repeat: Infinity }}
/>
<text x="78" y="40" className="fill-slate-900 font-bold text-[10px]"></text>
</svg>
);
export const ConceptWebsite: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="20" width="100" height="80" rx="4" stroke="currentColor" strokeWidth="1" className="text-slate-200" />
<motion.rect
x="20" y="35" width="80" height="15" rx="2"
className="fill-slate-50"
animate={{ opacity: [0.3, 0.6, 0.3] }}
transition={{ duration: 3, repeat: Infinity }}
/>
<motion.div
animate={{ y: [0, 10, 0] }}
transition={{ duration: 4, repeat: Infinity }}
>
<rect x="20" y="55" width="35" height="35" rx="2" className="fill-slate-100" />
<rect x="65" y="55" width="35" height="35" rx="2" className="fill-slate-100" />
</motion.div>
</svg>
);
export const ConceptSystem: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle cx="60" cy="60" r="15" className="fill-slate-900" />
{[0, 72, 144, 216, 288].map((angle, i) => {
const x = 60 + Math.cos((angle * Math.PI) / 180) * 40;
const y = 60 + Math.sin((angle * Math.PI) / 180) * 40;
return (
<React.Fragment key={i}>
<motion.line
x1="60" y1="60" x2={x} y2={y}
stroke="currentColor" strokeWidth="1" className="text-slate-200"
animate={{ strokeDashoffset: [0, 10] }}
strokeDasharray="2 2"
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
/>
<motion.circle
cx={x} cy={y} r="6"
className="fill-white stroke-slate-300"
animate={{ scale: [1, 1.2, 1] }}
transition={{ duration: 3, repeat: Infinity, delay: i * 0.4 }}
/>
</React.Fragment>
);
})}
</svg>
);
export const ConceptAutomation: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.g
animate={{ rotate: 360 }}
transition={{ duration: 10, repeat: Infinity, ease: "linear" }}
style={{ originX: "40px", originY: "60px" }}
>
<path d="M 40 45 L 50 60 L 40 75 L 30 60 Z" className="fill-slate-200" />
</motion.g>
<motion.g
animate={{ rotate: -360 }}
transition={{ duration: 10, repeat: Infinity, ease: "linear" }}
style={{ originX: "75px", originY: "65px" }}
>
<path d="M 75 50 L 85 65 L 75 80 L 65 65 Z" className="fill-slate-400" />
</motion.g>
<motion.path
d="M 10 60 H 110"
stroke="currentColor" strokeWidth="1" className="text-slate-100"
strokeDasharray="4 4"
animate={{ strokeDashoffset: [0, -20] }}
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
/>
</svg>
);
export const ConceptMessy: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.path
d="M 20 60 C 30 20, 40 100, 50 60 C 60 20, 70 100, 80 60 C 90 20, 100 100, 110 60"
stroke="currentColor" strokeWidth="1" className="text-slate-300"
animate={{ strokeDashoffset: [0, 20] }}
strokeDasharray="4 4"
transition={{ duration: 5, repeat: Infinity, ease: "linear" }}
/>
<motion.path
d="M 20 40 L 100 80 M 20 80 L 100 40"
stroke="currentColor" strokeWidth="1" className="text-slate-200 opacity-50"
/>
</svg>
);
export const FloatingParticles: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{[...Array(10)].map((_, i) => (
<motion.circle
key={i}
r={Math.random() * 2 + 1}
className="fill-slate-200"
initial={{
x: Math.random() * 200,
y: Math.random() * 200,
opacity: 0
}}
animate={{
y: [null, Math.random() * -50 - 20],
opacity: [0, 0.5, 0]
}}
transition={{
duration: Math.random() * 5 + 5,
repeat: Infinity,
delay: Math.random() * 5 + delay,
ease: "linear"
}}
/>
))}
</svg>
);
export const ConceptTarget: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle
cx="60" cy="60" r="50"
stroke="currentColor" strokeWidth="1" className="text-slate-100"
animate={{ scale: [1, 1.05, 1] }}
transition={{ duration: 4, repeat: Infinity }}
/>
<motion.circle
cx="60" cy="60" r="30"
stroke="currentColor" strokeWidth="1" className="text-slate-200"
/>
<motion.circle
cx="60" cy="60" r="10"
className="fill-slate-900"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, repeat: Infinity }}
/>
</svg>
);

View File

@@ -0,0 +1,313 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
interface IllustrationProps {
className?: string;
delay?: number;
}
export const DirectCommunication: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle
cx="20" cy="60" r="4"
className="fill-slate-400"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay }}
/>
<motion.circle
cx="100" cy="60" r="4"
className="fill-slate-900"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.2 }}
/>
<motion.path
d="M 24 60 H 96"
stroke="currentColor"
strokeWidth="1"
className="text-slate-300"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: delay + 0.4 }}
/>
<motion.circle r="2" className="fill-slate-400">
<animateMotion
dur="3s"
repeatCount="indefinite"
path="M 24 60 H 96"
/>
</motion.circle>
</svg>
);
export const FastPrototyping: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.rect
x="20" y="30" width="80" height="60" rx="4"
stroke="currentColor" strokeWidth="1"
className="text-slate-300"
initial={{ pathLength: 0, opacity: 0 }}
whileInView={{ pathLength: 1, opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: delay }}
/>
<motion.path
d="M 20 45 H 100"
stroke="currentColor" strokeWidth="1"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.5 }}
/>
<motion.path
d="M 45 55 L 75 65 L 45 75 Z"
className="fill-slate-200 stroke-slate-300"
strokeWidth="1"
initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.8 }}
/>
<motion.path
d="M 85 37 H 90"
stroke="currentColor" strokeWidth="1"
className="text-slate-300"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1 }}
/>
</svg>
);
export const CleanCode: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.path
d="M 30 40 H 70"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-300"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay }}
/>
<motion.path
d="M 30 55 H 90"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.2 }}
/>
<motion.path
d="M 30 70 H 60"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-300"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.4 }}
/>
<motion.path
d="M 30 85 H 80"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.6 }}
/>
<motion.path
d="M 85 45 L 95 55 L 110 35"
stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
className="text-slate-900"
initial={{ pathLength: 0, opacity: 0 }}
whileInView={{ pathLength: 1, opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 1 }}
/>
</svg>
);
export const FixedPrice: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.rect
x="35" y="35" width="50" height="50" rx="2"
stroke="currentColor" strokeWidth="1"
className="text-slate-300"
initial={{ pathLength: 0, opacity: 0 }}
whileInView={{ pathLength: 1, opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: delay }}
/>
<motion.path
d="M 45 50 H 75 M 45 60 H 75 M 45 70 H 65"
stroke="currentColor" strokeWidth="1"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8, delay: delay + 0.5 }}
/>
<motion.circle
cx="85" cy="35" r="12"
className="fill-white stroke-slate-900"
strokeWidth="1"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ type: "spring", stiffness: 200, damping: 10, delay: delay + 1 }}
/>
<motion.path
d="M 80 35 L 83 38 L 90 31"
stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"
className="text-slate-900"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.3, delay: delay + 1.3 }}
/>
</svg>
);
export const WebsitesIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.rect x="20" y="30" width="80" height="60" rx="2" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.path d="M 20 42 H 100" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.5 }} />
<motion.rect x="30" y="50" width="25" height="30" rx="1" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.8 }} />
<motion.path d="M 65 55 H 90 M 65 65 H 90 M 65 75 H 80" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 1 }} />
</svg>
);
export const SystemsIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.path d="M 40 30 L 20 40 V 80 L 40 90 L 60 80 V 40 L 40 30 Z" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.path d="M 80 50 L 60 60 V 100 L 80 110 L 100 100 V 60 L 80 50 Z" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay: delay + 0.3 }} />
<motion.path d="M 60 60 L 40 50" stroke="currentColor" strokeWidth="1" strokeDasharray="2 2" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.8 }} />
</svg>
);
export const AutomationIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle cx="45" cy="45" r="15" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.circle cx="75" cy="75" r="15" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay: delay + 0.2 }} />
<motion.path d="M 55 55 L 65 65" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.5 }} />
<motion.path d="M 62 58 L 65 65 L 58 62" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.7 }} />
</svg>
);
export const MinimalistArchitect: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.path
d="M 40 160 V 60 L 100 30 L 160 60 V 160"
stroke="currentColor" strokeWidth="1"
className="text-slate-300"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1.5, delay: delay }}
/>
<motion.path
d="M 40 100 H 160 M 100 30 V 160"
stroke="currentColor" strokeWidth="0.5"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: delay + 0.5 }}
/>
<motion.rect
x="85" y="120" width="30" height="40"
stroke="currentColor" strokeWidth="1"
className="text-slate-300"
initial={{ opacity: 0, y: 10 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: delay + 1, duration: 0.5 }}
/>
</svg>
);
export const DifferenceIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 100" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Messy Path */}
<motion.path
d="M 20 50 C 30 20, 40 80, 50 50 C 60 20, 70 80, 80 50"
stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 2, delay }}
/>
{/* Arrow to clean side */}
<motion.path
d="M 90 50 H 110"
stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }} transition={{ delay: delay + 1 }}
/>
{/* Clean Path */}
<motion.path
d="M 120 50 H 180"
stroke="currentColor" strokeWidth="2" strokeLinecap="round" className="text-slate-900"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay: delay + 1.5 }}
/>
</svg>
);
export const TargetGroupIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle cx="60" cy="40" r="20" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ scale: 0 }} whileInView={{ scale: 1 }} viewport={{ once: true }} transition={{ delay }} />
<motion.path d="M 30 90 C 30 70, 90 70, 90 90" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.3 }} />
<motion.path d="M 50 20 L 60 10 L 70 20" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.6 }} />
</svg>
);
export const ContactIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.rect x="20" y="35" width="80" height="50" rx="2" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.path d="M 20 35 L 60 65 L 100 35" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 0.8, delay: delay + 0.5 }} />
<motion.circle cx="90" cy="35" r="5" className="fill-green-500"
initial={{ scale: 0 }} whileInView={{ scale: 1 }} viewport={{ once: true }} transition={{ type: "spring", delay: delay + 1.2 }} />
</svg>
);
export const PromiseSectionIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.path d="M 20 60 L 50 90 L 100 30" stroke="currentColor" strokeWidth="2" className="text-slate-300"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.path d="M 40 50 H 80 M 40 70 H 70" stroke="currentColor" strokeWidth="1" className="text-slate-100"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.5 }} />
</svg>
);
export const ServicesSectionIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.rect x="20" y="20" width="80" height="80" rx="4" stroke="currentColor" strokeWidth="1" className="text-slate-200"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ duration: 1, delay }} />
<motion.circle cx="60" cy="60" r="20" stroke="currentColor" strokeWidth="1" className="text-slate-300"
initial={{ scale: 0 }} whileInView={{ scale: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.5 }} />
<motion.path d="M 60 40 V 80 M 40 60 H 80" stroke="currentColor" strokeWidth="1" className="text-slate-100"
initial={{ pathLength: 0 }} whileInView={{ pathLength: 1 }} viewport={{ once: true }} transition={{ delay: delay + 0.8 }} />
</svg>
);

View File

@@ -1,4 +1,6 @@
export * from './AbstractLines';
export * from './ExplanatoryIllustrations';
export * from './ConceptIllustrations';
export * from './ComparisonRow';
export * from './FeatureCard';
export * from './HeroItem';

View File

@@ -10,6 +10,7 @@ interface SectionProps {
variant?: 'white' | 'gray';
borderTop?: boolean;
connector?: React.ReactNode;
illustration?: React.ReactNode;
}
export const Section: React.FC<SectionProps> = ({
@@ -21,12 +22,13 @@ export const Section: React.FC<SectionProps> = ({
variant = 'white',
borderTop = false,
connector,
illustration,
}) => {
const bgClass = variant === 'gray' ? 'bg-slate-50' : 'bg-white';
const borderClass = borderTop ? 'border-t border-slate-100' : '';
return (
<section className={`relative py-24 md:py-32 ${bgClass} ${borderClass} ${className}`}>
<section className={`relative py-24 md:py-32 group ${bgClass} ${borderClass} ${className}`}>
<div className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 md:gap-16">
{/* Sidebar: Number & Title */}
@@ -56,6 +58,13 @@ export const Section: React.FC<SectionProps> = ({
</div>
</Reveal>
)}
{illustration && (
<Reveal delay={delay + 0.2}>
<div className="pt-12 opacity-20 group-hover:opacity-100 transition-opacity duration-700">
{illustration}
</div>
</Reveal>
)}
</div>
</div>