'use client'; import { motion } from 'framer-motion'; import { useTranslations } from 'next-intl'; import { cn } from '@/lib/utils'; import { staggerContainerWide, slideLeftVariants, fadeVariants, viewportOnce, } from '@/lib/animations'; import { Link } from '@/i18n/navigation'; import { Lock, Clock, ArrowRight } from 'lucide-react'; // ─── Types ──────────────────────────────────────────────────────────────────── interface Project { /** i18n key under "work.projects" (e.g. "monaco") */ i18nKey: string; slug: string; /** number of tags to resolve from the translation array */ tagCount: number; featured?: boolean; } interface ComingSoonItem { /** i18n key under "work.comingSoonProjects" (e.g. "riviera") */ i18nKey: string; confidential?: boolean; } // ─── Data ────────────────────────────────────────────────────────────────────── const PROJECTS: Project[] = [ { i18nKey: 'monaco', slug: 'monaco-ocean', tagCount: 2, featured: true, }, { i18nKey: 'portNimara', slug: 'port-nimara', tagCount: 2, }, { i18nKey: 'portAmador', slug: 'port-amador', tagCount: 2, }, ]; const COMING_SOON: ComingSoonItem[] = [ { i18nKey: 'riviera', confidential: true }, { i18nKey: 'sophia' }, ]; // ─── Animation Variants ─────────────────────────────────────────────────────── const ease = [0.16, 1, 0.3, 1] as const; const featuredCardVariants = { hidden: { opacity: 0, y: 48 }, visible: { opacity: 1, y: 0, transition: { duration: 0.7, ease }, }, }; const smallCardVariants = { hidden: { opacity: 0, y: 32 }, visible: { opacity: 1, y: 0, transition: { duration: 0.6, ease }, }, }; const comingSoonVariants = { hidden: { opacity: 0, y: 24 }, visible: { opacity: 1, y: 0, transition: { duration: 0.55, ease }, }, }; // ─── Geometric Placeholder ──────────────────────────────────────────────────── function GeometricPlaceholder({ variant = 'featured', cardVariant = 'default', className, }: { variant?: 'featured' | 'small'; cardVariant?: 'default' | 'nimara' | 'amador'; className?: string; }) { const isFeatured = variant === 'featured'; // Different gradient bases per card so secondary cards look distinct const gradientMap = { default: 'from-primary-dark/90 to-primary/70', nimara: 'from-navy/95 to-primary-dark/75', amador: 'from-[#1a3a4a]/95 to-primary/60', }; return (