Velocity UI
Loading…
Menu

Interactive Bento Grid

Interactive Bento Grid component with smooth animations and modern UI.

Installation

Add this component to your project using the CLI:

terminal
npx vui-registry-cli-v1 add interactive-bento-grid

Source Code

interactive-bento-grid.tsx
"use client"

import { motion } from "framer-motion"
import { 
    Activity, 
    Globe, 
    Lock, 
    Zap, 
    Search, 
    ShieldCheck, 
    LineChart, 
    BarChart3,
    ArrowUpRight
} from "lucide-react"
import { cn } from "@/lib/utils"

export default function InteractiveBentoGrid() {
  return (
    <div className="flex min-h-[800px] w-full items-center justify-center bg-neutral-950 p-8 font-sans">
      <div className="grid w-full max-w-4xl grid-cols-1 gap-4 md:grid-cols-3 md:grid-rows-3 lg:gap-6">
        
        {/* Large Feature Card (Top Left) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.1 }}
            className="group relative col-span-1 row-span-2 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-8 hover:border-neutral-700 transition-colors"
        >
            <div className="absolute inset-0 bg-gradient-to-b from-blue-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
            <div className="relative z-10 flex flex-col h-full justify-between">
                <div className="h-12 w-12 rounded-full bg-blue-500/20 flex items-center justify-center mb-4">
                    <Globe className="h-6 w-6 text-blue-400" />
                </div>
                <div>
                    <h3 className="text-2xl font-semibold text-white mb-2">Global Scale</h3>
                    <p className="text-neutral-400">Deploy instantly to 35+ regions worldwide with edge caching.</p>
                </div>
                {/* Visual: Simulated Map Points */}
                <div className="absolute right-0 top-0 h-full w-full opacity-20 group-hover:opacity-40 transition-opacity">
                     <div className="absolute top-1/4 right-1/4 h-2 w-2 rounded-full bg-blue-400 animate-ping" />
                     <div className="absolute top-1/2 right-1/3 h-2 w-2 rounded-full bg-blue-400 animate-ping delay-75" />
                     <div className="absolute bottom-1/3 right-1/2 h-2 w-2 rounded-full bg-blue-400 animate-ping delay-150" />
                </div>
            </div>
        </motion.div>

        {/* Medium Card (Top Middle) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.2 }}
            className="group relative col-span-1 row-span-1 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 hover:border-neutral-700 transition-colors"
        >
            <div className="absolute inset-0 bg-gradient-to-tr from-purple-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
            <div className="relative z-10 flex flex-col h-full justify-between">
                <div className="flex justify-between items-start">
                    <div className="h-10 w-10 rounded-full bg-purple-500/20 flex items-center justify-center">
                        <Activity className="h-5 w-5 text-purple-400" />
                    </div>
                    <ArrowUpRight className="h-5 w-5 text-neutral-600 group-hover:text-white transition-colors" />
                </div>
                <div>
                    <h3 className="text-lg font-semibold text-white mt-4">Real-time</h3>
                    <p className="text-sm text-neutral-400">Sub-millisecond latency updates.</p>
                </div>
            </div>
        </motion.div>

        {/* Medium Card (Top Right) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.3 }}
            className="group relative col-span-1 row-span-1 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 hover:border-neutral-700 transition-colors"
        >
            <div className="absolute inset-0 bg-gradient-to-bl from-emerald-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
            <div className="relative z-10 flex flex-col h-full justify-between">
                 <div className="flex justify-between items-start">
                    <div className="h-10 w-10 rounded-full bg-emerald-500/20 flex items-center justify-center">
                        <ShieldCheck className="h-5 w-5 text-emerald-400" />
                    </div>
                    <div className="px-2 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-[10px] font-medium text-emerald-400">
                        99.9% Uptime
                    </div>
                </div>
                <div>
                    <h3 className="text-lg font-semibold text-white mt-4">Secure</h3>
                    <p className="text-sm text-neutral-400">Enterprise-grade encryption.</p>
                </div>
            </div>
        </motion.div>

        {/* Wide Card (Middle Row, Spans 2 Cols) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.4 }}
            className="group relative col-span-1 md:col-span-2 row-span-1 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 hover:border-neutral-700 transition-colors"
        >
            <div className="absolute inset-0 bg-gradient-to-r from-orange-500/10 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
            <div className="relative z-10 flex items-center justify-between h-full gap-8">
                <div className="flex-1">
                     <div className="h-10 w-10 rounded-full bg-orange-500/20 flex items-center justify-center mb-4">
                        <LineChart className="h-5 w-5 text-orange-400" />
                    </div>
                    <h3 className="text-xl font-semibold text-white mb-2">Advanced Analytics</h3>
                    <p className="text-sm text-neutral-400">Deep dive into user behavior with our comprehensive dashboard.</p>
                </div>
                {/* Visual: Simulated Graph */}
                <div className="hidden sm:flex items-end gap-1 h-24 w-48 opacity-50 group-hover:opacity-100 transition-opacity">
                    {[40, 70, 50, 90, 60, 80, 75, 100].map((h, i) => (
                        <motion.div 
                            key={i}
                            initial={{ height: 0 }}
                            whileInView={{ height: `${h}%` }}
                            transition={{ duration: 1, delay: i * 0.1 }}
                            className="flex-1 bg-gradient-to-t from-orange-500/50 to-orange-400 rounded-t-sm"
                        />
                    ))}
                </div>
            </div>
        </motion.div>

        {/* Tall Card (Right, Spans 2 Rows) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.5 }}
            className="group relative col-span-1 row-span-2 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-8 hover:border-neutral-700 transition-colors"
        >
             <div className="absolute inset-0 bg-gradient-to-t from-pink-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
             <div className="relative z-10 flex flex-col h-full justify-between">
                <div>
                     <div className="h-12 w-12 rounded-full bg-pink-500/20 flex items-center justify-center mb-4">
                        <Zap className="h-6 w-6 text-pink-400" />
                    </div>
                    <h3 className="text-2xl font-semibold text-white mb-2">Lightning Fast</h3>
                    <p className="text-neutral-400">Optimized for speed with zero-config builds.</p>
                </div>
                
                {/* Visual: Speed lines */}
                <div className="relative h-40 w-full overflow-hidden mt-8 rounded-xl bg-neutral-950/50 border border-neutral-800">
                    <div className="absolute inset-0 flex items-center justify-center">
                        <span className="text-4xl font-mono font-bold text-white">0.05s</span>
                    </div>
                    <motion.div 
                        animate={{ x: ["-100%", "100%"] }}
                        transition={{ duration: 1.5, repeat: Infinity, ease: "linear" }}
                        className="absolute top-0 bottom-0 left-0 w-1/3 bg-gradient-to-r from-transparent via-pink-500/20 to-transparent skew-x-12"
                    />
                </div>
             </div>
        </motion.div>

        {/* Small Card (Bottom Left) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.6 }}
            className="group relative col-span-1 row-span-1 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 hover:border-neutral-700 transition-colors"
        >
            <div className="absolute inset-0 bg-gradient-to-br from-cyan-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
            <div className="relative z-10 flex items-center gap-4">
                <div className="h-10 w-10 rounded-full bg-cyan-500/20 flex items-center justify-center shrink-0">
                    <Search className="h-5 w-5 text-cyan-400" />
                </div>
                <div>
                    <h3 className="text-lg font-semibold text-white">SEO Ready</h3>
                    <p className="text-xs text-neutral-400">Auto-generated meta tags.</p>
                </div>
            </div>
        </motion.div>

        {/* Small Card (Bottom Middle) */}
        <motion.div 
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.7 }}
            className="group relative col-span-1 row-span-1 overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900/50 p-6 hover:border-neutral-700 transition-colors"
        >
             <div className="absolute inset-0 bg-gradient-to-t from-violet-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
             <div className="relative z-10 flex items-center gap-4">
                <div className="h-10 w-10 rounded-full bg-violet-500/20 flex items-center justify-center shrink-0">
                    <BarChart3 className="h-5 w-5 text-violet-400" />
                </div>
                <div>
                    <h3 className="text-lg font-semibold text-white">Scale Up</h3>
                    <p className="text-xs text-neutral-400">Unlimited API requests.</p>
                </div>
            </div>
        </motion.div>

      </div>
    </div>
  )
}