One mosaic of six tiles: a large photograph that drifts inside its tile, an ink quote tile with film grain, a serif figure that counts up, a small photograph, an hours sheet and a call-to-action tile with a sliding-marker pill, each rising into view in turn.
A practice summary as a bento grid: a tall photograph with a caption over its foot, a grain-textured quote panel, a figure that counts up, a small photo tile, an opening-hours list and a wide closing action, each tile arriving a beat after the last.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/bento15?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/bento15?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/bento15.tsx plus the button22 sliding-marker pill it uses.
The installed file exports bento15Demo alongside the block: the exact props behind the preview above. Spread it to get a working bento grid in one line.
import { Bento15, bento15Demo } from "@/components/beste/block/bento15";
export default function Page() {
return <Bento15 {...bento15Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Bento15 } from "@/components/beste/block/bento15";
export default function Page() {
return (
<Bento15
photo={{ src: "/rooms/bench.jpg", alt: "A sunlit room with a low timber bench", label: "The front room, afternoon" }}
quote={{ text: "The quietest hour of my week.", name: "Sam Fender" }}
figure={{ value: 91, suffix: "%", label: "Come back after session five" }}
smallPhoto={{ src: "/rooms/ledge.jpg", alt: "A ceramic vessel on a plaster ledge" }}
hours={{
title: "Hours",
rows: [
{ day: "Mon to Thu", hours: "9 to 21" },
{ day: "Friday", hours: "9 to 15, then the walk" },
],
}}
cta={{
heading: "Start with a conversation, not a form.",
description: "Twenty minutes, free, and no need to know what you want yet.",
button: { label: "Book the call", href: "/call", tone: "dark" },
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
photo | { src: string; alt: string; label: string } | – | Tall tile, two rows high, with its caption over the foot |
quote | { text: string; name: string } | – | Grain-textured panel on the ink surface |
figure | Figure | – | Counting figure tile |
smallPhoto | { src: string; alt: string } | – | Narrow photo tile |
hours | { title: string; rows: HourRow[] } | – | Opening-hours list |
cta | { heading: string; description: string; button: ActionButton } | – | Wide closing tile |
className | string | – | Extra classes for the outer <section> |
type HourRow = {
day: string;
hours: string;
};
type Figure = {
value: number;
suffix?: string;
label: string;
};
type ActionButton = {
label: string;
href: string;
tone?: "primary" | "light" | "dark" | "outline";
};13rem from md up, which is what lets the tall photograph claim exactly two of them and stay in proportion with everything beside it. Below md the grid is a single column and the two photo tiles fall back to explicit min-h values.-8% to 8% against a 1.18 scale, so the picture moves while the tile's corners stay put.feTurbulence filter with an id from useId, so two of these blocks on one page do not collide on a global SVG id and end up sharing one filter.tabular-nums so the tile does not change width while the number climbs.0.1s stagger by declaration order, so the grid resolves as a sequence rather than as one slab appearing at once.dl, with the day as dt and the hours as dd, so a screen reader keeps the two halves of each row together.bento12
A six-column bento of proof: a row of figure tiles with the first inverted, a tall card whose image tile floats a live breakdown chart, a tile carrying a customer quote card, and a soft note on method.
bento3
Work mosaic on a six-column track mixing photographic tiles that carry their caption inside on a gradient scrim with a soft statement tile and an inverted figure tile, the lead project spanning four columns and two rows.
bento9
Magazine mosaic whose cover story fills a two-row photographic tile with its category and page count on the scrim, beside an inverted figure tile, a bordered publication note and three soft article tiles.
bento2
Studio mosaic whose lead tile floats a mood-board media piece over a dotted field between its own eyebrow and statement, beside a photographic tile captioned on its scrim, an inverted figure tile, a soft quote tile and a bordered CTA tile.