Bento Grid
An adaptive, high-impact grid system designed for feature showcases. Utilizes CSS Grid spanning logic to create a balanced visual hierarchy for modern SaaS and landing pages.
Live Preview
Built for the Modern Stack
Everything you need to ship production-ready interfaces in record time.
Server-Side Performance
Optimized for Next.js 15 App Router. Zero hydration mismatch and blazing fast LCP scores.
export function ForkButton() {
return <button className="bg-emerald-600 text-white">
Fork Me
</button>
}Enterprise Security
Strict CSP compliance and sanitized inputs by default.
Responsive
Mobile-first approach to every component.
Global Edge
Deploy to any edge network instantly.
Customized Themes
Powerful CSS variables and Tailwind integration. Switch from Emerald to Rose in a single line.
Open Source
MIT Licensed. Fork it, change it, own it.
Dependencies
npm install
framer-motionlucide-reactUtils
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
Code
"use client";
import React from "react";
import { motion } from "framer-motion";
import { Zap, Shield, Smartphone, Globe, Code, Cpu } from "lucide-react";
import { cn } from "@/lib/utils";
interface BentoItemProps {
title: string;
description: string;
icon: React.ReactNode;
className?: string;
graphic?: React.ReactNode;
}
const BentoCard = ({
title,
description,
icon,
className,
graphic,
}: BentoItemProps) => (
<motion.div
whileHover={{ y: -5 }}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className={cn(
"group relative overflow-hidden rounded-3xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900/50 p-6 flex flex-col justify-between transition-all hover:shadow-2xl hover:shadow-emerald-500/10",
className,
)}
>
<div className="absolute -right-10 -top-10 h-32 w-32 rounded-full bg-emerald-500/5 blur-3xl group-hover:bg-emerald-500/10 transition-colors" />
<div>
<div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-xl bg-gray-500/10 text-gray-600 dark:text-gray-400">
{icon}
</div>
<h3 className="text-xl font-bold tracking-tight dark:text-white">
{title}
</h3>
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400 leading-relaxed">
{description}
</p>
</div>
{graphic && (
<div className="mt-6 w-full flex justify-center">{graphic}</div>
)}
</motion.div>
);
export default function BentoGrid() {
return (
<section className="py-24 px-6 max-w-7xl mx-auto">
<div className="mb-12 text-center">
<h2 className="text-4xl md:text-5xl font-black tracking-tighter dark:text-white">
Built for the <span className="text-[#7A7A73]">Modern Stack</span>
</h2>
<p className="text-zinc-500 mt-4 max-w-lg mx-auto">
Everything you need to ship production-ready interfaces in record
time.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-4 md:grid-rows-3 gap-4 h-full md:h-[800px]">
<BentoCard
title="Server-Side Performance"
description="Optimized for Next.js 15 App Router. Zero hydration mismatch and blazing fast LCP scores."
icon={<Zap size={24} />}
className="md:col-span-2 md:row-span-2 bg-gray-50/50 dark:bg-gray-950/10 border-gray-500/20"
graphic={<CodeGraphic />}
/>
<BentoCard
title="Enterprise Security"
description="Strict CSP compliance and sanitized inputs by default."
icon={<Shield size={24} />}
className="md:col-span-1 md:row-span-2"
/>
<BentoCard
title="Responsive"
description="Mobile-first approach to every component."
icon={<Smartphone size={24} />}
className="md:col-span-1 md:row-span-1"
/>
<BentoCard
title="Global Edge"
description="Deploy to any edge network instantly."
icon={<Globe size={24} />}
className="md:col-span-1 md:row-span-1"
/>
<BentoCard
title="Customized Themes"
description="Powerful CSS variables and Tailwind integration. Switch from Emerald to Rose in a single line."
icon={<Cpu size={24} />}
className="md:col-span-3 md:row-span-1 flex-row items-center gap-6"
graphic={<ThemeToggleGraphic />}
/>
<BentoCard
title="Open Source"
description="MIT Licensed. Fork it, change it, own it."
icon={<Code size={24} />}
className="md:col-span-1 md:row-span-1"
/>
</div>
</section>
);
}
function CodeGraphic() {
return (
<div className="w-full h-32 bg-zinc-950 rounded-xl p-4 font-mono text-[10px] text-emerald-400/80 border border-emerald-500/20 overflow-hidden">
<div className="flex gap-2 mb-2">
<div className="w-2 h-2 rounded-full bg-red-500/50" />
<div className="w-2 h-2 rounded-full bg-yellow-500/50" />
<div className="w-2 h-2 rounded-full bg-green-500/50" />
</div>
{/* replace your code here */}
<code>
{`export function ForkButton() {`} <br />
{` return <button className="bg-emerald-600 text-white">`} <br />
{` Fork Me`} <br />
{` </button>`} <br />
{`}`}
</code>
</div>
);
}
function ThemeToggleGraphic() {
return (
<div className="flex gap-2">
{[1, 2, 3].map((i) => (
<div
key={i}
className={cn(
"w-8 h-8 rounded-full border-2",
i === 1
? "bg-emerald-500 border-white"
: i === 2
? "bg-rose-500 border-transparent"
: "bg-violet-500 border-transparent",
)}
/>
))}
</div>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | - | The primary heading of the card. |
| description | string | - | Supporting text for the feature. |
| icon | ReactNode | - | Lucide icon or custom SVG. |
| className | string | undefined | Tailwind classes for grid spanning. |
| graphic | ReactNode | null | Optional visual element (code/charts). |