144 lines
6.9 KiB
TypeScript
144 lines
6.9 KiB
TypeScript
"use client";
|
|
|
|
import { EyeOff, Lock, Globe, Gauge, Cpu } from "lucide-react";
|
|
import { motion, Variants } from "framer-motion";
|
|
import { Dictionary } from "@/lib/IDict";
|
|
|
|
export function Features({ dict }: { dict: Dictionary["features"] }) {
|
|
// Настройки для 5 карточек в стильной Bento-сетке
|
|
// md:col-span-2 = широкая карточка (2/3 ширины)
|
|
// md:col-span-1 = узкая/квадратная карточка (1/3 ширины)
|
|
const bentoConfig = [
|
|
{
|
|
// 1: Широкая сверху
|
|
className:
|
|
"md:col-span-2 min-h-[300px] group overflow-hidden bg-card/40 backdrop-blur-xl border border-border/50 rounded-[2.5rem] p-6 md:p-10 flex flex-col justify-end hover:border-primary/50 transition-all duration-500 hover:shadow-[0_0_40px_rgba(0,240,255,0.1)] relative",
|
|
icon: <EyeOff className="w-8 h-8 text-primary relative z-10 mb-4" />,
|
|
bgElement: (
|
|
<EyeOff className="absolute -bottom-10 -right-10 w-64 h-64 text-primary opacity-[0.03] group-hover:opacity-10 group-hover:scale-110 group-hover:-rotate-12 transition-all duration-700 pointer-events-none" />
|
|
),
|
|
},
|
|
{
|
|
// 2: Узкая справа
|
|
className:
|
|
"md:col-span-1 min-h-[300px] bg-card/40 backdrop-blur-xl border border-border/50 rounded-[2.5rem] p-6 md:p-10 flex flex-col group hover:border-secondary/60 transition-all duration-500 hover:shadow-[0_0_40px_rgba(112,0,255,0.15)] relative overflow-hidden",
|
|
icon: (
|
|
<div className="bg-secondary/10 w-14 h-14 rounded-[1.2rem] flex items-center justify-center mb-auto border border-secondary/20 shadow-[0_0_15px_rgba(112,0,255,0.2)] relative z-10">
|
|
<Lock className="w-7 h-7 text-secondary" />
|
|
</div>
|
|
),
|
|
bgElement: (
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-secondary/20 blur-[60px] opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
|
),
|
|
},
|
|
{
|
|
// 3: Узкая слева в среднем ряду
|
|
className:
|
|
"md:col-span-1 min-h-[300px] bg-card/40 backdrop-blur-xl border border-border/50 rounded-[2.5rem] p-6 md:p-10 flex flex-col group hover:border-primary/50 transition-all duration-500 hover:shadow-[0_0_30px_rgba(0,240,255,0.1)] relative overflow-hidden",
|
|
icon: (
|
|
<div className="bg-primary/10 w-14 h-14 rounded-[1.2rem] flex items-center justify-center mb-auto border border-primary/20 shadow-[0_0_15px_rgba(0,240,255,0.2)] relative z-10">
|
|
<Gauge className="w-7 h-7 text-primary" />
|
|
</div>
|
|
),
|
|
bgElement: (
|
|
<Gauge className="absolute top-10 -right-4 w-40 h-40 text-primary opacity-[0.03] group-hover:opacity-10 transition-all duration-700 pointer-events-none" />
|
|
),
|
|
},
|
|
{
|
|
// 4: Широкая справа в среднем ряду
|
|
className:
|
|
"md:col-span-2 min-h-[300px] bg-gradient-to-br from-card/40 to-background/40 backdrop-blur-xl border border-border/50 rounded-[2.5rem] p-6 md:p-10 flex flex-col justify-end group hover:border-secondary/50 transition-all duration-500 hover:shadow-[0_0_30px_rgba(112,0,255,0.1)] relative overflow-hidden",
|
|
icon: <Cpu className="w-8 h-8 text-secondary relative z-10 mb-4" />,
|
|
bgElement: (
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_bottom_right,_var(--tw-gradient-stops))] from-secondary/10 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
|
),
|
|
},
|
|
{
|
|
// 5: На всю ширину снизу
|
|
className:
|
|
"md:col-span-3 bg-gradient-to-r from-card/40 to-background/40 backdrop-blur-xl border border-border/50 rounded-[2.5rem] p-6 md:p-10 flex flex-col md:flex-row items-start md:items-center gap-6 md:gap-8 group hover:border-primary/50 transition-all duration-500 hover:shadow-[0_0_40px_rgba(0,240,255,0.1)] relative overflow-hidden",
|
|
icon: (
|
|
<div className="bg-primary/10 w-16 h-16 md:w-20 md:h-20 rounded-[1.5rem] md:rounded-[2rem] shrink-0 flex items-center justify-center border border-primary/20 shadow-[0_0_20px_rgba(0,240,255,0.2)] relative z-10">
|
|
<Globe className="w-8 h-8 md:w-10 md:h-10 text-primary" />
|
|
</div>
|
|
),
|
|
bgElement: (
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_left,_var(--tw-gradient-stops))] from-primary/10 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
|
),
|
|
},
|
|
];
|
|
|
|
const containerVariants: Variants = {
|
|
hidden: { opacity: 0 },
|
|
show: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.15,
|
|
},
|
|
},
|
|
};
|
|
|
|
const itemVariants: Variants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
y: 40,
|
|
},
|
|
show: {
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
type: "spring",
|
|
stiffness: 260,
|
|
damping: 20,
|
|
},
|
|
},
|
|
};
|
|
|
|
// Проверка на случай, если переводы еще не подгрузились (предотвращает краш)
|
|
if (!dict || !dict.items || dict.items.length < 5) return null;
|
|
|
|
return (
|
|
// overflow-hidden и w-full здесь чинят горизонтальный скролл на мобильных телефонах
|
|
<section
|
|
id="features"
|
|
className="py-24 px-4 w-full mx-auto relative overflow-hidden"
|
|
>
|
|
{/* Центрированный контейнер для контента */}
|
|
<div className="container max-w-6xl mx-auto relative z-10">
|
|
{/* Фоновое свечение (исправлено позиционирование, чтобы не ломало ширину) */}
|
|
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[100vw] md:w-[600px] h-[600px] bg-secondary/10 blur-[100px] md:blur-[120px] rounded-full pointer-events-none -z-10" />
|
|
|
|
<motion.div
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
whileInView="show"
|
|
viewport={{ once: true, margin: "-100px" }}
|
|
className="grid grid-cols-1 md:grid-cols-3 gap-6"
|
|
>
|
|
{bentoConfig.map((config, idx) => {
|
|
const feature = dict.items[idx];
|
|
return (
|
|
<motion.div
|
|
key={idx}
|
|
variants={itemVariants}
|
|
className={config.className}
|
|
>
|
|
{config.bgElement}
|
|
{config.icon}
|
|
<div className="relative z-10 mt-6 md:mt-0">
|
|
<h3 className="text-xl md:text-2xl font-bold text-foreground mb-3 tracking-tight">
|
|
{feature.title}
|
|
</h3>
|
|
<p className="text-muted-foreground text-sm md:text-base leading-relaxed max-w-lg">
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|