Bento Grid System
A highly interactive Bento Grid system with mouse-follow borders, spotlight overlays, and moving laser effects. Perfect for showcasing features or system metrics in a futuristic UI.
Installation
Add this component to your project using the CLI:
npx vui-registry-cli-v1 add bento-gridSource Code
'use client'
import React, { useRef, useState, useEffect } from 'react'
import { motion, useMotionValue, useSpring, useMotionTemplate } from 'framer-motion'
import {
ArrowUpRight,
Mail,
MessageSquare,
Globe,
Cpu,
Zap,
Shield,
Terminal,
Layers,
Activity,
Settings,
Fingerprint,
Database,
Share2,
ChevronRight,
Binary,
Wifi,
HardDrive,
} from 'lucide-react'
import { cn } from '@/lib/utils'
interface BentoCardProps {
children: React.ReactNode
className?: string
span?: 'sm' | 'lg' | 'tall' | 'full'
title?: string
id?: string
image?: string
}
const spanClasses = {
sm: 'col-span-1 row-span-1',
lg: 'col-span-1 sm:col-span-2 row-span-1',
tall: 'col-span-1 row-span-2',
full: 'col-span-1 sm:col-span-2 md:col-span-4 row-span-1',
}
const MovingLaser = ({ isHovered }: { isHovered: boolean }) => {
return (
<div
className={cn(
'absolute inset-0 pointer-events-none overflow-hidden rounded-2xl opacity-0 transition-opacity duration-500',
isHovered && 'opacity-100',
)}
>
{/* SHIMMER BORDER EFFECT */}
<motion.div
className="absolute -inset-[150%] bg-[conic-gradient(from_0deg,transparent_0_340deg,white_360deg)] opacity-20"
animate={{ rotate: 360 }}
transition={{ duration: 4, repeat: Infinity, ease: 'linear' }}
style={{ filter: 'blur(20px)' }}
/>
{/* HOVER GLOW */}
<motion.div
className="absolute inset-0 bg-white/5 opacity-0 transition-opacity duration-500"
animate={{ opacity: isHovered ? 1 : 0 }}
/>
</div>
)
}
const CornerBrackets = () => (
<div className="absolute inset-0 pointer-events-none">
<div className="absolute top-2 left-2 w-2 h-2 border-t-2 border-l-2 border-white/30 rounded-tl-sm" />
<div className="absolute top-2 right-2 w-2 h-2 border-t-2 border-r-2 border-white/30 rounded-tr-sm" />
<div className="absolute bottom-2 left-2 w-2 h-2 border-b-2 border-l-2 border-white/30 rounded-bl-sm" />
<div className="absolute bottom-2 right-2 w-2 h-2 border-b-2 border-r-2 border-white/30 rounded-br-sm" />
</div>
)
const BentoCard = ({ children, className, span = 'sm', title, id, image }: BentoCardProps) => {
const [isHovered, setIsHovered] = useState(false)
return (
<motion.div
layout
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className={cn(
'relative group rounded-2xl overflow-hidden w-full h-full transition-all duration-500 hover:shadow-2xl border border-white/10 hover:border-white/20 bg-zinc-900/50',
spanClasses[span],
className,
)}
>
{/* DOUBLE BORDER EFFECT - DOTTED INNER */}
<div className="absolute inset-1.5 border border-dotted border-white/20 rounded-xl pointer-events-none z-30" />
{/* IMAGE BACKGROUND */}
{image && (
<div className="absolute inset-0 z-0">
<img
src={image}
alt={title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105 opacity-80"
/>
{/* Default Gradient */}
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/50 to-transparent opacity-60" />
{/* Hover Dark Overlay for Text Visibility */}
<div className="absolute inset-0 bg-black/60 opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
</div>
)}
{/* SHIMMER EFFECT - BEHIND CONTENT */}
<div className="absolute inset-0 z-10">
<MovingLaser isHovered={isHovered} />
</div>
<div className="relative z-20 flex flex-col h-full p-6">
{/* HEADER */}
<div className="flex justify-between items-start mb-4">
<div className="overflow-hidden">
<motion.h3 className="text-lg font-bold text-white tracking-wide uppercase drop-shadow-md translate-y-8 opacity-0 transition-all duration-500 group-hover:translate-y-0 group-hover:opacity-100">
{title}
</motion.h3>
</div>
{id && (
<span className="text-[10px] font-mono text-white/50 border border-white/10 px-2 py-1 rounded backdrop-blur-md opacity-0 transition-opacity duration-500 group-hover:opacity-100 delay-100">
{id}
</span>
)}
</div>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-500 delay-200">
<CornerBrackets />
</div>
{/* CONTENT REVEAL ON HOVER */}
<div
className={cn(
'relative z-40 flex-1 flex flex-col justify-between transition-all duration-500 translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 delay-100',
)}
>
{children}
</div>
</div>
</motion.div>
)
}
// --- 4. MAIN APPLICATION GRID ---
interface BentoGridProps {
className?: string
style?: React.CSSProperties
}
export function BentoGrid({ className, style }: BentoGridProps) {
const [cpuLoad, setCpuLoad] = useState(64)
const [activePackets, setActivePackets] = useState(1280)
useEffect(() => {
const interval = setInterval(() => {
setCpuLoad((prev) => Math.min(Math.max(prev + (Math.random() * 6 - 3), 30), 98))
setActivePackets((prev) => prev + Math.floor(Math.random() * 20 - 10))
}, 1500)
return () => clearInterval(interval)
}, [])
return (
<div
className={cn(
'w-full h-full bg-transparent flex items-center justify-center p-8 selection:bg-cyan-500/30 text-white transition-colors duration-300',
className,
)}
style={style}
>
<div className="grid w-full max-w-7xl grid-cols-1 sm:grid-cols-2 md:grid-cols-4 auto-rows-[240px] gap-2 grid-flow-dense">
{/* 1. FERRARI (LG) */}
<BentoCard
span="lg"
title="Ferrari SF90 Stradale"
id="SF90-V8"
image="https://images.pexels.com/photos/10292239/pexels-photo-10292239.jpeg"
>
<div className="flex justify-between items-start">
<div className="space-y-2">
<h3 className="text-4xl font-bold tracking-tighter text-white drop-shadow-lg">
986<span className="text-red-500 text-2xl">HP</span>
</h3>
<div className="flex items-center gap-2">
<span className="px-2 py-0.5 rounded-full bg-red-600/20 text-red-400 text-[10px] font-bold uppercase backdrop-blur-sm border border-red-500/20">
PHEV V8
</span>
</div>
</div>
</div>
<div className="mt-auto flex justify-between items-end border-t border-white/20 pt-4">
<div className="flex gap-8">
<div className="space-y-1">
<p className="text-[8px] text-zinc-300 uppercase font-bold">0-60 MPH</p>
<p className="text-sm text-white font-mono">2.5s</p>
</div>
<div className="space-y-1">
<p className="text-[8px] text-zinc-300 uppercase font-bold">Top Speed</p>
<p className="text-sm text-red-400 font-mono">211 MPH</p>
</div>
</div>
<div className="flex items-center gap-2 bg-white/10 px-3 py-1.5 rounded-full backdrop-blur-md border border-white/10">
<Activity size={12} className="text-red-400" />
<span className="text-[8px] text-white font-bold uppercase tracking-tighter">
Fiorano Spec
</span>
</div>
</div>
</BentoCard>
{/* 2. FERRARI 812 (SM) */}
<BentoCard
title="Ferrari 812 Competizione"
id="812-V12"
image="https://images.unsplash.com/photo-1669644767278-c12464be133a?q=80&w=688&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
>
<div className="flex flex-col h-full justify-end">
<div className="space-y-2">
<h4 className="text-2xl font-bold text-white drop-shadow-md">V12 Fury</h4>
<p className="text-[10px] text-zinc-300 line-clamp-2">
The highest-revving V12 engine ever built by Ferrari. 9500 RPM limit.
</p>
<div className="flex gap-2 pt-2">
<span className="text-[9px] px-2 py-1 bg-white/10 rounded text-white font-bold backdrop-blur-md">
819 HP
</span>
<span className="text-[9px] px-2 py-1 bg-white/10 rounded text-white font-bold backdrop-blur-md">
RWD
</span>
</div>
</div>
</div>
</BentoCard>
{/* 3. F1 (TALL) */}
<BentoCard
span="tall"
title="Scuderia Ferrari F1-75"
id="F1-75"
image="https://plus.unsplash.com/premium_photo-1677993185885-985af6b425c4?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
>
<div className="flex flex-col h-full justify-between">
<div className="p-2 bg-black/40 backdrop-blur-sm rounded-lg border border-white/10">
<div className="flex justify-between items-center mb-2">
<span className="text-[9px] text-zinc-400 uppercase">Season</span>
<span className="text-[9px] text-white font-bold">2022/23</span>
</div>
<div className="h-[1px] bg-white/10 w-full mb-2" />
<p className="text-[10px] text-zinc-300 leading-relaxed">
Aggressive sidepods and ground effect aerodynamics. The pride of Maranello.
</p>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-[10px] uppercase font-bold text-white">Downforce</span>
<Cpu size={12} className="text-red-500" />
</div>
<div className="w-full bg-white/10 h-1 rounded-full overflow-hidden">
<motion.div
className="h-full bg-red-600"
initial={{ width: 0 }}
whileInView={{ width: '100%' }}
transition={{ duration: 1.5 }}
/>
</div>
<div className="flex justify-between text-[9px] font-mono text-zinc-400">
<span>Low Drag</span>
<span>High G</span>
</div>
</div>
<button className="mt-4 group flex items-center justify-center w-full py-3 bg-red-600/20 hover:bg-red-600/40 border border-red-500/20 rounded-lg text-[9px] font-bold uppercase tracking-[0.2em] text-white transition-all backdrop-blur-md">
Telemetry
<ChevronRight
size={12}
className="ml-1 group-hover:translate-x-1 transition-transform"
/>
</button>
</div>
</BentoCard>
{/* 4. G-WAGON (SM) */}
<BentoCard
title="Mercedes-AMG G63"
id="G63-AMG"
image="https://images.unsplash.com/photo-1709072245760-ec5b9a6b9f9b?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
>
<div className="flex flex-col h-full justify-end">
<div className="flex justify-between items-end mb-2">
<h4 className="text-xl font-bold text-white">G-Class</h4>
<span className="text-[10px] font-mono text-zinc-400">V8 BITURBO</span>
</div>
<div className="grid grid-cols-2 gap-2">
<div className="bg-black/50 p-2 rounded border border-white/10 backdrop-blur-sm">
<p className="text-[8px] text-zinc-400 uppercase">Torque</p>
<p className="text-xs text-white font-bold">850 Nm</p>
</div>
<div className="bg-black/50 p-2 rounded border border-white/10 backdrop-blur-sm">
<p className="text-[8px] text-zinc-400 uppercase">0-60</p>
<p className="text-xs text-white font-bold">4.5s</p>
</div>
</div>
</div>
</BentoCard>
{/* 5. ROLLS ROYCE (LG) - CENTER */}
<BentoCard
span="lg"
title="Rolls-Royce Phantom"
id="RR-PHANTOM"
image="https://images.unsplash.com/photo-1647200527826-e9395f4683ea?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
>
<div className="flex flex-col h-full justify-between">
<div className="flex items-center gap-2">
<Zap size={14} className="text-purple-400" />
<span className="text-[10px] font-bold uppercase text-purple-400 tracking-widest">
Ultimate Luxury
</span>
</div>
<div className="flex justify-between items-end">
<div className="space-y-1">
<h3 className="text-3xl font-thin text-white">
V12 <span className="text-sm font-bold text-zinc-400">6.75L</span>
</h3>
<p className="text-[9px] text-zinc-300 max-w-[200px]">
The quietest cabin in the world. Magic Carpet Ride suspension.
</p>
</div>
<div className="flex gap-4">
<div className="text-right">
<p className="text-[8px] text-zinc-500 uppercase">Wheelbase</p>
<p className="text-xs text-white font-mono">Extended</p>
</div>
<div className="text-right">
<p className="text-[8px] text-zinc-500 uppercase">Finish</p>
<p className="text-xs text-white font-mono">Bespoke</p>
</div>
</div>
</div>
</div>
</BentoCard>
{/* 6. BENTLEY (SM) */}
<BentoCard
title="Bentley Continental GT"
id="BENTLEY-GT"
image="https://images.unsplash.com/photo-1618418721668-0d1f72aa4bab?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
>
<div className="h-full flex flex-col justify-end">
<div className="space-y-2">
<h4 className="text-xl font-bold text-white drop-shadow-md">Grand Tourer</h4>
<div className="flex justify-between items-center border-t border-white/10 pt-2">
<span className="text-[10px] text-zinc-300">W12 Engine</span>
<span className="text-[10px] text-white font-bold">650 HP</span>
</div>
</div>
</div>
</BentoCard>
{/* 7. BUGATTI (SM) */}
<BentoCard
title="Bugatti Divo"
id="DIVO-W16"
image="https://images.weserv.nl/?url=i.pinimg.com/1200x/ba/1d/cb/ba1dcbf28de2155a41ef94862eeaa21b.jpg"
>
<div className="h-full flex flex-col justify-end">
<div className="space-y-2">
<h4 className="text-xl font-bold text-white drop-shadow-md">Hypercar</h4>
<div className="flex justify-between items-center border-t border-white/10 pt-2">
<span className="text-[10px] text-zinc-300">Cornering</span>
<span className="text-[10px] text-white font-bold">1.6 G</span>
</div>
</div>
</div>
</BentoCard>
{/* 8. MCLAREN (LG) */}
<BentoCard
span="lg"
title="McLaren 765LT"
id="765LT"
image="https://images.unsplash.com/photo-1617814086906-d847a8bc6fca?q=80&w=1142&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3Dg"
>
<div className="h-full flex flex-col justify-end">
<div className="flex items-center justify-between border-b border-white/10 pb-4 mb-4">
<div>
<p className="text-[10px] text-orange-400 font-mono uppercase">0-124 MPH</p>
<p className="text-2xl font-bold text-white">7.0s</p>
</div>
<div className="text-right">
<p className="text-[10px] text-orange-400 font-mono uppercase">Power</p>
<p className="text-lg font-bold text-white">755 HP</p>
</div>
</div>
<div className="flex items-center justify-between">
<p className="text-[9px] text-zinc-400 italic">"Longtail legend."</p>
<div className="flex gap-1">
{[1, 2, 3, 4].map((i) => (
<div key={i} className="w-1 h-6 bg-orange-500/20 rounded-full overflow-hidden">
<motion.div
className="w-full bg-orange-500"
animate={{ height: ['20%', '100%', '20%'] }}
transition={{ duration: 0.5, delay: i * 0.05, repeat: Infinity }}
/>
</div>
))}
</div>
</div>
</div>
</BentoCard>
</div>
</div>
)
}
Dependencies
framer-motion: latestlucide-react: latestclsx: latesttailwind-merge: latest
Props
Component property reference.
| Name | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | - | Content to render inside the grid or card. |
| className | string | - | Additional CSS classes. |
| span | 'sm' | 'md' | 'lg' | 'tall' | 'sm' | Controls the column/row span of the card. |
Most components here are inspired by outstanding libraries and creators in the ecosystem. I don’t claim to be the original author — this is my space for learning, rebuilding, and understanding great work at a deeper level.
I’m still a student of the craft, constantly studying the best and translating what I learn through my own perspective. Every piece reflects curiosity, respect for the community, and small creative touches that feel true to me.
I’ve done my best to credit inspirations properly. If anything is missing or inaccurate, I truly appreciate a message so it can be corrected with care.

