156 lines
5.4 KiB
TypeScript
156 lines
5.4 KiB
TypeScript
'use client'
|
|
|
|
import React from 'react'
|
|
import { motion } from 'framer-motion'
|
|
|
|
interface Step {
|
|
number: string
|
|
title: string
|
|
description: string
|
|
}
|
|
|
|
const steps: Step[] = [
|
|
{
|
|
number: '1',
|
|
title: 'Kunde wählen',
|
|
description: 'Gewünschten Kunden auswählen, der die Lizenz erhalten soll.'
|
|
},
|
|
{
|
|
number: '2',
|
|
title: 'Lizenz wählen',
|
|
description: 'Gewünschte Lizenzen für den Kunden auswählen und die Bestellung abschließen.'
|
|
},
|
|
{
|
|
number: '3',
|
|
title: 'Live gehen',
|
|
description: 'Nach dem Erhalt der Lizenz direkt live gehen und durchstarten.'
|
|
}
|
|
]
|
|
|
|
const containerVariants = {
|
|
hidden: {},
|
|
visible: {
|
|
transition: {
|
|
delayChildren: 0.2,
|
|
staggerChildren: 0.35
|
|
}
|
|
}
|
|
}
|
|
|
|
const stepVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
y: 20
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
type: 'spring' as const,
|
|
stiffness: 70,
|
|
damping: 16
|
|
}
|
|
}
|
|
}
|
|
|
|
export function ProcessSteps() {
|
|
return (
|
|
<section className="w-full py-16 px-4 relative z-10">
|
|
<div className="container max-w-5xl mx-auto flex flex-col items-center">
|
|
{/* Section Header */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: '-80px' }}
|
|
transition={{ type: 'spring' as const, stiffness: 60, damping: 15 }}
|
|
className="text-center space-y-3 mb-16 max-w-2xl"
|
|
>
|
|
<h2 className="text-3xl sm:text-4xl font-extrabold text-white tracking-tight">
|
|
Wie funktioniert die Bereitstellung?
|
|
</h2>
|
|
<p className="text-slate-400 text-base sm:text-lg leading-relaxed">
|
|
In nur drei einfachen Schritten richten Sie CASPOS Lizenzen für Ihre Kunden ein.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Horizontale Timeline */}
|
|
<div className="relative w-full">
|
|
{/* Basis-Linie exakt zwischen Schritt 1 und 3 */}
|
|
<div className="hidden md:block absolute top-6 left-[16.6%] right-[16.6%] h-[2px] bg-white/10 z-0 rounded-full" />
|
|
|
|
{/* Animierte, aufgeladene Linie (sky-500) */}
|
|
<motion.div
|
|
initial={{ scaleX: 0 }}
|
|
whileInView={{ scaleX: 1 }}
|
|
viewport={{ once: true, margin: '-50px' }}
|
|
transition={{
|
|
duration: 1.5,
|
|
ease: 'easeInOut',
|
|
delay: 0.2
|
|
}}
|
|
className="hidden md:block absolute top-6 left-[16.6%] right-[16.6%] h-[2px] bg-sky-500 origin-left z-0 rounded-full shadow-[0_0_12px_rgba(14,165,233,0.8)]"
|
|
/>
|
|
|
|
{/* 3 Schritte Nebeneinander */}
|
|
<motion.div
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true, margin: '-50px' }}
|
|
className="grid grid-cols-1 md:grid-cols-3 gap-10 md:gap-6 w-full relative z-10"
|
|
>
|
|
{steps.map((step, index) => {
|
|
const isLiveStep = index === 2
|
|
|
|
return (
|
|
<motion.div
|
|
key={step.number}
|
|
variants={stepVariants}
|
|
className="group flex flex-col items-center text-center space-y-4 cursor-pointer relative"
|
|
>
|
|
{/* Nummer im runden Kreis auf der Linie */}
|
|
<div className="relative">
|
|
<motion.div
|
|
whileHover={{ scale: 1.15 }}
|
|
transition={{ type: 'spring' as const, stiffness: 300, damping: 20 }}
|
|
className="w-12 h-12 rounded-full bg-slate-950 border-2 border-slate-700 text-slate-300 font-extrabold text-lg flex items-center justify-center group-hover:border-sky-400 group-hover:text-sky-400 group-hover:bg-slate-900 group-hover:shadow-[0_0_20px_rgba(56,189,248,0.4)] transition-all duration-300 z-10 relative"
|
|
>
|
|
{step.number}
|
|
</motion.div>
|
|
|
|
{/* Pulsierender Ziel-Ring bei Schritt 3 */}
|
|
{isLiveStep && (
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.8 }}
|
|
whileInView={{ opacity: 1, scale: 1 }}
|
|
viewport={{ once: true }}
|
|
transition={{ delay: 1.6 }}
|
|
className="absolute inset-0 rounded-full border-2 border-emerald-400/60 pointer-events-none animate-ping"
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
{/* Text-Inhalt zentriert ohne Boxen-Hintergrund */}
|
|
<div className="space-y-2 max-w-[280px]">
|
|
<h3 className="text-xl font-bold text-white group-hover:text-sky-400 transition-colors duration-300 flex items-center justify-center gap-2">
|
|
{step.title}
|
|
{isLiveStep && (
|
|
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
|
|
LIVE
|
|
</span>
|
|
)}
|
|
</h3>
|
|
<p className="text-slate-400 text-sm leading-relaxed">
|
|
{step.description}
|
|
</p>
|
|
</div>
|
|
</motion.div>
|
|
)
|
|
})}
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|