Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 1m25s
Build & Deploy / 🧪 QA (push) Failing after 1m25s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 3s
- Replaced synchronous `motion` imports with `m` and `LazyMotion` across all components - Removed 1-second `animate-in` delay on LCP element in HeroVideo - Added AVIF image format support to next.config.mjs - Fixed ReferencesSlider carousel left padding alignment - Dropped Total Blocking Time (TBT) to 0ms
155 lines
8.1 KiB
TypeScript
155 lines
8.1 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { m, LazyMotion, domAnimation, Variants } from 'framer-motion';
|
|
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
|
|
import { LogoArcs } from '@/components/ui/LogoArcs';
|
|
|
|
export interface BenefitItem {
|
|
id: string;
|
|
title: string;
|
|
description?: string;
|
|
icon: 'contract' | 'team' | 'money' | 'vacation' | 'clothes' | 'card' | 'retirement' | 'education' | 'car' | 'family' | 'region' | 'allowance';
|
|
}
|
|
|
|
interface BenefitGridProps {
|
|
badge?: string;
|
|
title?: string;
|
|
description?: string;
|
|
benefits: BenefitItem[];
|
|
}
|
|
|
|
const containerVariants: Variants = {
|
|
hidden: { opacity: 0 },
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.1,
|
|
},
|
|
},
|
|
};
|
|
|
|
const itemVariants: Variants = {
|
|
hidden: { opacity: 0, y: 20 },
|
|
visible: { opacity: 1, y: 0, transition: { duration: 1.0, ease: [0.16, 1, 0.3, 1] } },
|
|
};
|
|
|
|
const Icons = {
|
|
contract: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><path d="M16 13H8"></path><path d="M16 17H8"></path><path d="M10 9H8"></path></svg>
|
|
),
|
|
team: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
|
|
),
|
|
money: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg>
|
|
),
|
|
vacation: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"></path><path d="M2 12h20"></path></svg>
|
|
),
|
|
clothes: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20.38 3.46L16 2a8 8 0 0 1-8 0L3.62 3.46a2 2 0 0 0-1.34 2.23l.58 3.47a1 1 0 0 0 .99.84H6v10c0 1.1.9 2 2 2h8a2 2 0 0 0 2-2V10h2.15a1 1 0 0 0 .99-.84l.58-3.47a2 2 0 0 0-1.34-2.23z"></path></svg>
|
|
),
|
|
card: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line></svg>
|
|
),
|
|
retirement: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v20"></path><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg>
|
|
),
|
|
education: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 10v6M2 10l10-5 10 5-10 5z"></path><path d="M6 12v5c3 3 9 3 12 0v-5"></path></svg>
|
|
),
|
|
car: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="1" y="3" width="15" height="13"></rect><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"></polygon><circle cx="5.5" cy="18.5" r="2.5"></circle><circle cx="18.5" cy="18.5" r="2.5"></circle></svg>
|
|
),
|
|
family: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20.42 4.58a5.4 5.4 0 0 0-7.65 0l-.77.78-.77-.78a5.4 5.4 0 0 0-7.65 0C1.46 6.7 1.33 10.28 4 13l8 8 8-8c2.67-2.72 2.54-6.3.42-8.42z"></path></svg>
|
|
),
|
|
region: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"></polygon><line x1="8" y1="2" x2="8" y2="18"></line><line x1="16" y1="6" x2="16" y2="22"></line></svg>
|
|
),
|
|
allowance: (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg>
|
|
),
|
|
};
|
|
|
|
export function BenefitGrid({ badge, title, description, benefits }: BenefitGridProps) {
|
|
return (
|
|
<section className="bg-white py-16 md:py-24 lg:py-32 relative overflow-hidden border-t border-neutral-100">
|
|
<div className="container px-4 max-w-7xl mx-auto relative z-10">
|
|
|
|
<div className="max-w-3xl mx-auto text-center mb-16">
|
|
{badge && <h2 className="text-primary font-bold tracking-wider uppercase text-sm mb-4">{badge}</h2>}
|
|
{title && (
|
|
<h3 className="font-heading text-2xl md:text-5xl font-extrabold text-neutral-dark mb-6">
|
|
{title}
|
|
</h3>
|
|
)}
|
|
<div className="w-20 h-2 bg-primary mx-auto mb-8 rounded-full"></div>
|
|
|
|
{description && (
|
|
<p className="text-text-secondary text-lg md:text-xl leading-relaxed">
|
|
{description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
|
|
<m.div
|
|
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
>
|
|
{benefits.map((benefit, index) => {
|
|
const bgPositionClasses = [
|
|
"-bottom-[30%] -right-[30%]",
|
|
"-top-[30%] -left-[30%]",
|
|
"-bottom-[30%] -left-[30%]"
|
|
];
|
|
const animationClasses = [
|
|
"animate-[spin_60s_linear_infinite]",
|
|
"animate-[spin_80s_linear_infinite]",
|
|
"animate-[spin_100s_linear_infinite]"
|
|
];
|
|
const positionClass = bgPositionClasses[index % bgPositionClasses.length];
|
|
const animationClass = animationClasses[index % animationClasses.length];
|
|
|
|
return (
|
|
<m.div
|
|
key={benefit.id}
|
|
variants={itemVariants}
|
|
className="group relative overflow-hidden bg-neutral-50/50 border border-neutral-200/60 rounded-3xl p-8 transition-all duration-500 hover:bg-white hover:border-primary/30 hover:shadow-[0_20px_40px_-15px_rgba(0,0,0,0.05)] hover:-translate-y-1"
|
|
>
|
|
<HoverShineOverlay shineColor="via-primary/5" />
|
|
|
|
{/* Subtle Background Logo Arcs */}
|
|
<div className={`absolute ${positionClass} w-[120%] h-[120%] z-0 opacity-0 group-hover:opacity-[0.03] transition-opacity duration-1000 pointer-events-none mix-blend-multiply`}>
|
|
<LogoArcs className={`w-full h-full text-primary ${animationClass}`} />
|
|
</div>
|
|
|
|
<div className="relative z-10 flex items-start gap-4">
|
|
<div className="relative shrink-0 w-12 h-12 flex items-center justify-center bg-primary/10 text-primary rounded-xl transition-all duration-500 group-hover:bg-primary group-hover:text-white group-hover:scale-110 group-hover:-rotate-3">
|
|
{Icons[benefit.icon]}
|
|
</div>
|
|
|
|
<div className="pt-1">
|
|
<h4 className="font-bold text-neutral-dark text-lg mb-2 leading-tight group-hover:text-primary transition-colors duration-300">
|
|
{benefit.title}
|
|
</h4>
|
|
{benefit.description && (
|
|
<p className="text-text-secondary text-sm leading-relaxed">
|
|
{benefit.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</m.div>
|
|
);
|
|
})}
|
|
</m.div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|