registry/blocks/gallery-grid.tsx
const tiles = [
{ name: "Grid", className: "bg-grid-sm" },
{ name: "Dots", className: "bg-dots" },
{ name: "Hatch", className: "bg-stripes" },
{ name: "Ink", className: "bg-foreground" },
];
/**
* Swap the pattern tiles for real screenshots or photos when you have
* them — the frame, captions and layout stay identical.
*/
export default function GalleryGrid() {
return (
<section className="bg-background">
<div className="mx-auto w-full max-w-5xl px-6 py-20 sm:py-24">
<div className="mb-10 flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
<div>
<h2 className="text-2xl font-semibold tracking-tight text-balance sm:text-3xl">
Built from a small set of rules
</h2>
<p className="mt-2 max-w-md text-muted-foreground">
Four textures carry the whole identity — print, product and
site.
</p>
</div>
<p className="font-mono text-xs text-muted-foreground tabular-nums">
04 assets
</p>
</div>
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
{tiles.map((tile, index) => (
<figure key={tile.name}>
<div
className={`aspect-square rounded-xl border border-border/60 ${tile.className}`}
/>
<figcaption className="mt-2.5 flex items-baseline justify-between">
<span className="text-sm font-medium">{tile.name}</span>
<span className="font-mono text-xs text-muted-foreground tabular-nums">
{String(index + 1).padStart(2, "0")}
</span>
</figcaption>
</figure>
))}
</div>
</div>
</section>
);
}