"use client";
import { motion } from "framer-motion";
interface PerspectiveGridProps {
/** Grid line color. Default: 'rgba(99,102,241,0.15)' */
lineColor?: string;
/** Number of columns. Default: 14 */
columns?: number;
/** Number of rows. Default: 10 */
rows?: number;
className?: string;
}
export function PerspectiveGrid({
lineColor = "rgba(99,102,241,0.15)",
columns = 14,
rows = 10,
className = "",
}: PerspectiveGridProps) {
return (
<div
className={`relative w-full h-full overflow-hidden bg-zinc-950 ${className}`}
aria-hidden="true"
>
{/* Perspective container */}
<div
className="absolute inset-x-0 bottom-0 h-[110%]"
style={{
transform: "rotateX(60deg)",
transformOrigin: "bottom center",
perspective: "800px",
perspectiveOrigin: "50% 100%",
}}
>
{/* Horizontal lines */}
{Array.from({ length: rows + 1 }).map((_, i) => (
<motion.div
key={`h-${i}`}
className="absolute w-full h-px"
style={{
top: `${(i / rows) * 100}%`,
background: lineColor,
boxShadow: i === 0 ? `0 0 8px ${lineColor}` : "none",
}}
animate={{ opacity: [0.3, 0.8, 0.3] }}
transition={{ duration: 4, repeat: Infinity, delay: i * 0.2, ease: "easeInOut" }}
/>
))}
{/* Vertical lines */}
{Array.from({ length: columns + 1 }).map((_, i) => (
<motion.div
key={`v-${i}`}
className="absolute h-full w-px"
style={{
left: `${(i / columns) * 100}%`,
background: lineColor,
}}
animate={{ opacity: [0.2, 0.6, 0.2] }}
transition={{ duration: 3, repeat: Infinity, delay: i * 0.1, ease: "easeInOut" }}
/>
))}
</div>
{/* Fade out to top */}
<div className="absolute inset-0 bg-gradient-to-b from-zinc-950 via-transparent to-transparent pointer-events-none" />
</div>
);
}