Card

Bento Cell

Bento grid and cell parts: a 2, 3, 4 or 6 column Bento with a 2px seam or 8px gutter, and cells with an optional 32px outer corner, ink wash, fading media and caption slots. Titles use Hanken Grotesk.

The source comes with full access.

One payment of $149 ($49 for now) opens the source right here and lets the CLI install every paid component, with lifetime updates.

Installation

pnpm dlx shadcn add @01orbital/bento-cell
npx shadcn add @01orbital/bento-cell
yarn shadcn add @01orbital/bento-cell
bunx --bun shadcn add @01orbital/bento-cell

Part of the 01orbital library. With a license, put ORBITAL_TOKEN in .env.local and the same command installs it (licensed install, pricing).

It lands at components/card/bento-cell.tsx, as source you own and edit.

The example also uses section. Install it too:

pnpm dlx shadcn add @01orbital/section
npx shadcn add @01orbital/section
yarn shadcn add @01orbital/section
bunx --bun shadcn add @01orbital/section

Usage

import {
  Bento,
  BentoCell,
  BentoCellContent,
  BentoCellDescription,
  BentoCellEyebrow,
  BentoCellTitle,
  BentoCellValue,
} from "@/components/card/bento-cell"
import {
  Section,
  SectionContent,
} from "@/components/editorial/section"

// Every word on the page. Change copy here, not in the markup.
const COPY = {
  eyebrow: "Reply time",
  value: "4.2s",
  body: "Median first draft, measured across every inbox this week.",
  eyebrow2: "Coverage",
  title: "Support in every timezone",
  body2: "Agents cover the quiet hours, so no queue waits for morning.",
  eyebrow3: "Scale",
  value2: "2M+",
  body3: "Conversations a month through the deck.",
} as const

// The cell is material the blocks compose into a Bento: the seam grid row,
// corner cells rounding the row's outer shoulders.
export default function BentoCellDemo() {
  return (
    <Section>
      <SectionContent>
        <Bento>
          <BentoCell corner="l">
            <BentoCellContent>
              <BentoCellEyebrow>{COPY.eyebrow}</BentoCellEyebrow>
              <div>
                <BentoCellValue>{COPY.value}</BentoCellValue>
                <BentoCellDescription>{COPY.body}</BentoCellDescription>
              </div>
            </BentoCellContent>
          </BentoCell>
          <BentoCell>
            <BentoCellContent>
              <BentoCellEyebrow>{COPY.eyebrow2}</BentoCellEyebrow>
              <div>
                <BentoCellTitle>{COPY.title}</BentoCellTitle>
                <BentoCellDescription>{COPY.body2}</BentoCellDescription>
              </div>
            </BentoCellContent>
          </BentoCell>
          <BentoCell corner="r">
            <BentoCellContent>
              <BentoCellEyebrow>{COPY.eyebrow3}</BentoCellEyebrow>
              <div>
                <BentoCellValue>{COPY.value2}</BentoCellValue>
                <BentoCellDescription>{COPY.body3}</BentoCellDescription>
              </div>
            </BentoCellContent>
          </BentoCell>
        </Bento>
      </SectionContent>
    </Section>
  )
}

Anatomy

Bento Cell is built from 10 parts. In the example they nest like this:

Bento
└─ BentoCell
   └─ BentoCellContent
      ├─ BentoCellEyebrow
      ├─ BentoCellValue
      ├─ BentoCellDescription
      └─ BentoCellTitle
  • Bento: The grid that holds BentoCells. The cells stack in one column on small screens and switch to cols columns at the md breakpoint.
  • BentoCell: One cell of a Bento: a card-colored panel with 8px corners and a hairline border. Its children stack in a column and are clipped to the rounded corners. Put a BentoCellMedia, BentoCellContent or BentoCellCaption inside.
  • BentoCellContent: The padded body of a BentoCell. It grows to fill the cell and spreads its children from the top to the bottom.
  • BentoCellEyebrow: A small semibold label above a BentoCellTitle.
  • BentoCellValue: A large figure, such as a stat, in the display font. It steps up a size from the sm breakpoint.
  • BentoCellDescription: Muted supporting text under the title, capped at 28rem wide.
  • BentoCellTitle: The heading of a BentoCell, an h3 in the display font. Pass render to use another heading level.
  • BentoCellMedia: A picture area inside a BentoCell. By default it sits in the cell's column at its own height and clips what is inside it.
  • BentoCellCaption: The padded text block at the bottom of a BentoCell. It is pushed to the bottom of the cell and sits on top of a bleeding BentoCellMedia.
  • RampAvatar: A small 28px square for initials, filled with the primary color. Avatars in a row differ by how strong that one color is, never by hue.

API reference

Bento

The grid that holds BentoCells. The cells stack in one column on small screens and switch to cols columns at the md breakpoint.

Prop

Type

It also accepts the HTML attributes of the element it renders.

BentoCell

One cell of a Bento: a card-colored panel with 8px corners and a hairline border. Its children stack in a column and are clipped to the rounded corners. Put a BentoCellMedia, BentoCellContent or BentoCellCaption inside.

The border is drawn on top of everything in the cell, so a picture that bleeds to the edges never covers it. className lands on the outer cell.

Prop

Type

It also accepts the HTML attributes of the element it renders.

BentoCellContent

The padded body of a BentoCell. It grows to fill the cell and spreads its children from the top to the bottom.

It accepts the HTML attributes of the element it renders.

BentoCellEyebrow

A small semibold label above a BentoCellTitle.

It accepts the HTML attributes of the element it renders.

BentoCellValue

A large figure, such as a stat, in the display font. It steps up a size from the sm breakpoint.

It accepts the HTML attributes of the element it renders.

BentoCellDescription

Muted supporting text under the title, capped at 28rem wide.

It accepts the HTML attributes of the element it renders.

BentoCellTitle

The heading of a BentoCell, an h3 in the display font. Pass render to use another heading level.

It accepts the props of the Base UI part it wraps, and the HTML attributes of the element it renders.

BentoCellMedia

A picture area inside a BentoCell. By default it sits in the cell's column at its own height and clips what is inside it.

With fade, the picture fades into --media-fade, which is the card background unless you set it, for example to the picture's own deepest tone. The picture is masked rather than covered, so no light line shows along a rounded corner.

Prop

Type

It also accepts the HTML attributes of the element it renders.

BentoCellCaption

The padded text block at the bottom of a BentoCell. It is pushed to the bottom of the cell and sits on top of a bleeding BentoCellMedia.

It accepts the HTML attributes of the element it renders.

RampAvatar

A small 28px square for initials, filled with the primary color. Avatars in a row differ by how strong that one color is, never by hue.

Prop

Type

It also accepts the HTML attributes of the element it renders.

Dependencies

npm: @base-ui/react, cn. The CLI installs them for you.

Registry pieces it installs with it:

  • font-hanken-grotesk