102 lines
3.7 KiB
TypeScript
102 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import { useState } from "react";
|
|
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
import type { Locale } from "@/i18n-config";
|
|
|
|
const easeOutExpo = [0.16, 1, 0.3, 1] as [number, number, number, number];
|
|
|
|
const fadeUp = {
|
|
hidden: { opacity: 0, y: 30 },
|
|
show: { opacity: 1, y: 0, transition: { duration: 0.8, ease: easeOutExpo } },
|
|
};
|
|
|
|
const stagger = {
|
|
hidden: {},
|
|
show: { transition: { staggerChildren: 0.1 } },
|
|
};
|
|
|
|
const IconPlus = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="w-4 h-4">
|
|
<line x1="12" y1="5" x2="12" y2="19" />
|
|
<line x1="5" y1="12" x2="19" y2="12" />
|
|
</svg>
|
|
);
|
|
|
|
export default function FAQClient({ lang, dict }: { lang: Locale; dict: any }) {
|
|
const [activeFaq, setActiveFaq] = useState<number | null>(null);
|
|
const faqs = dict.faq.items;
|
|
|
|
return (
|
|
<div className="bg-[#F4F0E8] text-[#0A0A0A] font-body min-h-screen">
|
|
<Header lang={lang} dict={dict.nav} />
|
|
|
|
<main className="pt-32 pb-24 px-6 min-h-screen max-w-3xl mx-auto">
|
|
|
|
{/* Header */}
|
|
<div className="border-b border-[#C8C2B8] pb-12 mb-16">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<div className="w-3 h-3 bg-[#FFE600]" />
|
|
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">{dict.faq.badge}</span>
|
|
</div>
|
|
<motion.h1
|
|
className="font-display font-black text-5xl sm:text-6xl lg:text-8xl uppercase leading-[0.85] tracking-tight"
|
|
initial={{ opacity: 0, y: 30 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.8 }}
|
|
>
|
|
{dict.faq.title}
|
|
</motion.h1>
|
|
</div>
|
|
|
|
{/* Accordions */}
|
|
<div>
|
|
{faqs.map((faq: any, idx: number) => (
|
|
<motion.div
|
|
key={idx}
|
|
className="border-b border-[#C8C2B8]"
|
|
initial={{ opacity: 0 }}
|
|
whileInView={{ opacity: 1 }}
|
|
viewport={{ once: true }}
|
|
transition={{ delay: idx * 0.06 }}
|
|
>
|
|
<button
|
|
className="w-full flex items-center justify-between py-6 text-left cursor-pointer group"
|
|
onClick={() => setActiveFaq(activeFaq === idx ? null : idx)}
|
|
>
|
|
<span className="font-display font-black text-base sm:text-lg uppercase text-[#0A0A0A] pr-8 leading-snug">{faq.q}</span>
|
|
<motion.div
|
|
className="flex-shrink-0 w-8 h-8 border border-[#C8C2B8] group-hover:border-[#0A0A0A] group-hover:bg-[#FFE600] text-[#8A8480] group-hover:text-[#0A0A0A] flex items-center justify-center transition-colors"
|
|
animate={{ rotate: activeFaq === idx ? 45 : 0 }}
|
|
>
|
|
<IconPlus />
|
|
</motion.div>
|
|
</button>
|
|
|
|
<AnimatePresence initial={false}>
|
|
{activeFaq === idx && (
|
|
<motion.div
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: "auto", opacity: 1 }}
|
|
exit={{ height: 0, opacity: 0 }}
|
|
transition={{ duration: 0.3, ease: easeOutExpo }}
|
|
>
|
|
<p className="text-[#6A6460] text-[14px] leading-relaxed pb-6 border-l-2 border-[#FFE600] pl-6">
|
|
{faq.a}
|
|
</p>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<Footer lang={lang} dict={dict} />
|
|
</div>
|
|
);
|
|
}
|