"use client"; import clsx from "clsx"; import type { ReactNode } from "react"; import { useCallback, useRef } from "react"; import { motion } from "framer-motion"; export interface CardProps { children: ReactNode; className?: string; /** Enable spotlight hover effect */ spotlight?: boolean; /** Glass morphism intensity */ glass?: "none" | "subtle" | "medium" | "strong"; /** Depth level for layered shadows */ depth?: 0 | 1 | 2 | 3; /** Hover lift effect */ hoverLift?: boolean; /** Animated entrance */ animate?: boolean; /** Entrance animation delay */ delay?: number; } /** * Card - Translucent surface with hairline border. * Features spotlight illumination, glass morphism, and depth effects. */ export default function Card({ children, className, spotlight = true, glass = "none", depth = 1, hoverLift = true, animate = false, delay = 0, }: CardProps) { const cardRef = useRef(null); const handleMouseMove = useCallback((e: React.MouseEvent) => { if (!cardRef.current || !spotlight) return; const rect = cardRef.current.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; cardRef.current.style.setProperty("--mouse-x", `${x}%`); cardRef.current.style.setProperty("--mouse-y", `${y}%`); }, [spotlight]); const glassClasses = { none: "", subtle: "bg-surface/60 backdrop-blur-sm", medium: "bg-surface/80 backdrop-blur-md", strong: "bg-surface/95 backdrop-blur-lg", }; const depthClasses = { 0: "", 1: "depth-1", 2: "depth-2", 3: "depth-3", }; const cardContent = (
{/* Inner glow at top edge */}
{/* Content */}
{children}
); if (animate) { return ( {cardContent} ); } return cardContent; } /** * InteractiveCard - Card with enhanced hover/tap interactions */ export interface InteractiveCardProps extends CardProps { onClick?: () => void; href?: string; } export function InteractiveCard({ children, className, spotlight = true, glass = "none", depth = 1, hoverLift = true, onClick, href, }: InteractiveCardProps) { // Use state to track mouse position for spotlight effect const handleMouseMove = useCallback((e: React.MouseEvent) => { if (!spotlight) return; const rect = e.currentTarget.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; e.currentTarget.style.setProperty("--mouse-x", `${x}%`); e.currentTarget.style.setProperty("--mouse-y", `${y}%`); }, [spotlight]); const glassClasses = { none: "", subtle: "bg-surface/60 backdrop-blur-sm", medium: "bg-surface/80 backdrop-blur-md", strong: "bg-surface/95 backdrop-blur-lg", }; const depthClasses = { 0: "", 1: "depth-1", 2: "depth-2", 3: "depth-3", }; // Use motion.div for consistent typing, with conditional href on anchor return ( {/* Inner glow */}
{/* Hover accent line */} {/* Content */} {href ? ( {children} ) : (
{children}
)}
); }