Components / Website
Bento
A standalone bento grid in the style of mode.com's “Beyond BI” section. Feature cards span a 12-column base grid with rounded corners and a seam-coloured gap between them.
Installation
npx shadcn add https://raw.githubusercontent.com/levi-putna/elements/main/registry/bento/registry.jsonHow it works
- The grid is a 12-column track. Each card sets a
colSpan(and optionalrowSpan), so spans of 7 + 5, or 4 + 3 + 5, fill a row. Auto-flow places them left-to-right, top-to-bottom. - The seamis the container background. It shows through every gap and the equal outer padding, so the frame and the inner gaps are one continuous colour; that's what the eye reads as the join between cards.
- Cards stay rounded. Every cell keeps its corner radius on all four corners. The seam shows through the gaps between them.
Feature grid
Six capabilities on a 12-column grid, with one tall accent card.
Ad hoc analysis
SQL, R and Python in one notebook.
Advanced analytics
Interactive modelling without the rebuild.
Self-serve reporting
Custom data apps
Interactive dashboards
Explorable datasets
import {
BentoGrid,
BentoFeatureCell,
} from "@/components/ui/bento"
import { Code2, LineChart, BarChart3, Boxes, LayoutDashboard, Database } from "lucide-react"
// 12-column base grid. Cells span a slice of it.
<BentoGrid seam="default" cols={12} rowHeight={168} gap={12}>
<BentoFeatureCell icon={<Code2 />} label="Ad hoc analysis" tone="secondary" colSpan={7} />
<BentoFeatureCell icon={<LineChart />} label="Advanced analytics" tone="primary" colSpan={5} rowSpan={2} />
<BentoFeatureCell icon={<BarChart3 />} label="Self-serve reporting" tone="secondary" colSpan={4} />
<BentoFeatureCell icon={<Boxes />} label="Custom data apps" tone="secondary" colSpan={3} />
<BentoFeatureCell icon={<LayoutDashboard />} label="Interactive dashboards" tone="secondary" colSpan={7} />
<BentoFeatureCell icon={<Database />} label="Explorable datasets" tone="secondary" colSpan={5} />
</BentoGrid>Content grid
The editorial variant: BentoContentCell for eyebrow + display heading + copy, alongside BentoVisualCell fills for screenshots and UI previews.
Built for managers
Made for your strata team
Levy notices, maintenance requests, AGM minutes and owner queries: all in one workspace.
Owner experience
And the owners you serve
A self-service portal means fewer calls, more transparency, and owners who trust you.
import {
BentoGrid,
BentoContentCell,
BentoVisualCell,
} from "@/components/ui/bento"
<BentoGrid seam="secondary" cols={2} rowHeight={220} gap={12}>
<BentoContentCell
eyebrow="Built for managers"
heading="Made for your strata team"
body="Levy notices, maintenance requests and owner queries in one workspace."
tone="default"
/>
<BentoVisualCell tone="primary">{/* screenshot */}</BentoVisualCell>
</BentoGrid>BentoGrid Props
| Prop | Type | Default | Description |
|---|---|---|---|
| seam | "default" | "secondary" | "primary" | "alternative" | "default" | Background of the container. Shows through every gap and the outer padding, so it reads as the seam between cards. |
| cols | number | 12 | Base columns. Cells span a slice of these via colSpan. |
| rowHeight | number | 168 | Height (px) of one grid row. Cells with rowSpan get multiples of this. |
| gap | number | 12 | Gap between cells (px). Reused as the outer padding so the frame is even on every side. |
| rounded | number | 28 | Outer container radius (px). Keep it larger than the cell radius so the frame never clips a card corner. |
BentoCell Props
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "default" | "secondary" | "primary" | "alternative" | "dark" | "secondary" | Card background and text colour. |
| colSpan | number | 1 | Columns this cell spans, of the grid's cols. |
| rowSpan | number | 1 | Rows this cell spans. |
| radius | number | 18 | Corner radius of the card (px). |
| clip | boolean | false | Clip overflowing content (images). |
BentoFeatureCell Props
Extends BentoCell props.
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | ReactNode | - | 24px icon (Lucide or any SVG) rendered at the top-left. |
| label | string | - | Primary label pinned to the bottom-left. |
| body | string | - | Optional supporting text under the label. |
| visual | ReactNode | - | Optional chart / screenshot placed between icon and label. |