Files
LetsBeBiz-Site/src/components/sections/Configurator.tsx

162 lines
6.2 KiB
TypeScript
Raw Normal View History

'use client';
import { useTranslations } from 'next-intl';
import { motion } from 'framer-motion';
polish: deep visual pass across all homepage sections Hero: - Removed fake trust proof avatars - Added decorative gradient separator line - Pushed content down for better vertical rhythm - More visible secondary CTA button TrustBar: - Icon circles with primary tint backdrops - Gradient top accent bar on hover - Gradient fade transition from hero section - Increased card padding Services: - Subtle grid texture background - Larger primary-colored feature dots - Enhanced AI narrative with horizontal decorative rules - Hover shadow elevation on pillars Configurator: - Step numbers in tinted circles with vertical rail - ShieldCheck trust icon - Radial gradient glow on wizard panel - Sparkles icon on AI toggle - Empty-state hint message - Service card icons in circular primary backdrops Process: - Gradient top accent strips on cards - Icon containers with primary tint - Vertical accent bar on section heading - Dashed SVG connector lines between cards SelectedWorks: - Distinct geometric compositions per card (Monaco, Nimara, Amador) - Bottom gradient fade on placeholder images - Dot separators between tags - Animated background pulse on coming-soon cards - Enhanced CTA hover animations Philosophy: - Enriched decorative panel (circle rings, diagonal lines, navy gradient) - Primary-colored pillar numbers - Left border accent on pull-quote card CTABanner: - Grid pattern + circle ring overlays - Email link underline-on-hover animation Footer: - Full logo image replacing text wordmark - Larger social icons - Gradient divider line - Larger nav logo (h-14 desktop, h-11 mobile) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:11:30 +01:00
import { ShieldCheck } from 'lucide-react';
import { revealVariants, staggerContainer, viewportOnce } from '@/lib/animations';
import WizardContainer from '@/components/configurator/WizardContainer';
// ─── Step indicator ──────────────────────────────────────────────────────────
function StepIndicator({ index, label, isLast }: { index: number; label: string; isLast: boolean }) {
return (
<motion.div variants={revealVariants} className="flex items-start gap-4">
<div className="flex flex-col items-center">
<div className="w-7 h-7 rounded-full bg-primary/10 border border-primary/20 flex items-center justify-center flex-shrink-0">
<span className="text-xs font-semibold text-primary-dark leading-none">{index}</span>
</div>
{!isLast && (
<div className="w-px h-5 bg-primary/15 mt-1" aria-hidden="true" />
)}
</div>
<span className="text-sm text-outline pt-1">{label}</span>
</motion.div>
);
}
// ─── Component ────────────────────────────────────────────────────────────────
export default function Configurator() {
const t = useTranslations('configurator');
const steps = [
t('step1.title'),
t('step2.title'),
t('step3.title'),
];
return (
<section id="configure" className="relative bg-surface py-24 overflow-hidden">
{/* Subtle diagonal accent line */}
<div
className="absolute top-0 left-0 right-0 h-px pointer-events-none"
style={{
background: 'linear-gradient(90deg, transparent 10%, rgba(91,164,217,0.15) 50%, transparent 90%)',
}}
aria-hidden="true"
/>
<div className="relative z-10 container mx-auto px-6">
<div className="grid grid-cols-1 gap-12 lg:grid-cols-12 lg:gap-16 items-start">
{/* ── Left: Context panel ──────────────────────────────────────── */}
<div className="lg:col-span-5">
<div className="lg:sticky lg:top-24">
<motion.div
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={viewportOnce}
className="flex flex-col gap-6"
>
<motion.span
variants={revealVariants}
className="label-md text-primary"
>
{t('eyebrow')}
</motion.span>
<motion.h2
variants={revealVariants}
className="font-serif text-4xl font-semibold tracking-headline text-on-surface leading-tight md:text-5xl"
>
{t('title')}
</motion.h2>
<motion.p
variants={revealVariants}
className="text-base text-outline leading-relaxed max-w-sm"
>
{t('description')}
</motion.p>
{/* Divider */}
<motion.div
variants={revealVariants}
className="w-12 h-px bg-outline-variant/40"
aria-hidden="true"
/>
{/* Step indicators */}
<motion.div
variants={revealVariants}
className="flex flex-col gap-1"
>
<p className="text-xs font-semibold uppercase tracking-label text-outline/60 mb-3">
{t('howItWorks')}
</p>
{steps.map((step, i) => (
<StepIndicator
key={i}
index={i + 1}
label={step}
isLast={i === steps.length - 1}
/>
))}
</motion.div>
{/* Trust signal */}
<motion.div
variants={revealVariants}
className="flex items-center gap-2 pt-2"
>
<ShieldCheck
size={14}
strokeWidth={1.75}
className="text-primary flex-shrink-0"
aria-hidden="true"
/>
<p className="text-xs text-outline">{t('noCommitment')}</p>
</motion.div>
</motion.div>
</div>
</div>
{/* ── Right: Wizard card ────────────────────────────────────────── */}
<div className="lg:col-span-7">
<motion.div
initial={{ opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={viewportOnce}
transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1], delay: 0.1 }}
className="relative"
>
<div className="relative rounded-2xl bg-surface-high shadow-[0_20px_50px_rgba(25,28,29,0.08)] p-6 sm:p-8 overflow-hidden border border-outline-variant/20">
{/* Top-edge accent line */}
<div
className="absolute top-0 left-6 right-6 h-[2px] rounded-full pointer-events-none"
style={{
background: 'linear-gradient(90deg, #006494, #5BA4D9, transparent)',
}}
aria-hidden="true"
/>
{/* Soft radial glow */}
<div
className="pointer-events-none absolute -top-20 -left-20 w-80 h-80 rounded-full"
style={{
background: 'radial-gradient(circle, rgba(91,164,217,0.05) 0%, transparent 70%)',
}}
aria-hidden="true"
/>
<WizardContainer />
</div>
</motion.div>
</div>
</div>
</div>
</section>
);
}