'use client'; import { motion, type HTMLMotionProps, type Variants } from 'framer-motion'; import { useRef, useState, type ReactNode, type MouseEvent } from 'react'; import { cn } from '@/lib/utils'; const cardVariants: Variants = { hidden: { opacity: 0, y: 30, scale: 0.95, }, visible: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.6, ease: [0.16, 1, 0.3, 1], }, }, }; interface InkCardProps extends HTMLMotionProps<'div'> { children: ReactNode; className?: string; hoverScale?: number; hoverRotate?: number; inkColor?: string; showInkOnHover?: boolean; } export function InkCard({ children, className = '', hoverScale = 1.02, hoverRotate = 0, inkColor = 'rgba(196, 30, 58, 0.05)', showInkOnHover = true, ...props }: InkCardProps) { const cardRef = useRef(null); const [inkPosition, setInkPosition] = useState({ x: 50, y: 50 }); const [isHovered, setIsHovered] = useState(false); const handleMouseMove = (e: MouseEvent) => { if (!cardRef.current) return; const rect = cardRef.current.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setInkPosition({ x, y }); }; return ( setIsHovered(true)} onHoverEnd={() => setIsHovered(false)} onMouseMove={handleMouseMove} transition={{ type: 'spring', stiffness: 300, damping: 20, }} className={cn( 'relative overflow-hidden bg-white border border-[#E5E5E5] rounded-xl transition-shadow duration-300', 'hover:shadow-[0_12px_24px_rgba(28,28,28,0.08)]', className )} {...props} > {showInkOnHover && (
)}
{children}
); } interface GeometricCardProps extends HTMLMotionProps<'div'> { children: ReactNode; className?: string; cornerColor?: string; } export function GeometricCard({ children, className = '', cornerColor = '#C41E3A', ...props }: GeometricCardProps) { return (
{children} ); } interface FlipCardProps { front: ReactNode; back: ReactNode; className?: string; frontClassName?: string; backClassName?: string; } export function FlipCard({ front, back, className = '', frontClassName = '', backClassName = '', }: FlipCardProps) { const [isFlipped, setIsFlipped] = useState(false); return ( setIsFlipped(!isFlipped)} style={{ perspective: 1000 }} >
{front}
{back}
); } interface TiltCardProps extends HTMLMotionProps<'div'> { children: ReactNode; className?: string; maxTilt?: number; scale?: number; } export function TiltCard({ children, className = '', maxTilt = 10, scale = 1.02, ...props }: TiltCardProps) { const cardRef = useRef(null); const [rotateX, setRotateX] = useState(0); const [rotateY, setRotateY] = useState(0); const handleMouseMove = (e: MouseEvent) => { if (!cardRef.current) return; const rect = cardRef.current.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const mouseX = e.clientX - centerX; const mouseY = e.clientY - centerY; const rotateXValue = (mouseY / (rect.height / 2)) * -maxTilt; const rotateYValue = (mouseX / (rect.width / 2)) * maxTilt; setRotateX(rotateXValue); setRotateY(rotateYValue); }; const handleMouseLeave = () => { setRotateX(0); setRotateY(0); }; return ( {children} ); } interface GlowCardProps extends HTMLMotionProps<'div'> { children: ReactNode; className?: string; glowColor?: string; } export function GlowCard({ children, className = '', glowColor = 'rgba(196, 30, 58, 0.15)', ...props }: GlowCardProps) { const cardRef = useRef(null); const [glowPosition, setGlowPosition] = useState({ x: 50, y: 50 }); const handleMouseMove = (e: MouseEvent) => { if (!cardRef.current) return; const rect = cardRef.current.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setGlowPosition({ x, y }); }; return (
{children}
); } interface ExpandCardProps extends HTMLMotionProps<'div'> { children: ReactNode; className?: string; expandedContent?: ReactNode; } export function ExpandCard({ children, className = '', expandedContent, ...props }: ExpandCardProps) { const [isExpanded, setIsExpanded] = useState(false); return ( setIsExpanded(!isExpanded)} transition={{ type: 'spring', stiffness: 300, damping: 20 }} className={cn( 'relative overflow-hidden bg-white border border-[#E5E5E5] rounded-xl cursor-pointer', 'transition-shadow duration-300', 'hover:shadow-[0_12px_24px_rgba(28,28,28,0.08)]', className )} {...props} >
{children}
{expandedContent && (
{expandedContent}
)}
); }