A hero that sets a light display heading and one action against a column of numbered hairline rows, then closes on a full-bleed image band with a live approval request pinned into its corner.
A hero that sets a light display heading and one action against a column of numbered hairline rows, then closes on a full-bleed image band with a live approval request pinned into its corner.
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/hero162?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/hero162?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hero162.tsx, the notification20 approval piece it pins to the band (installed to components/beste/piece/notification20.tsx), and the badge23 and button21 components it uses for the eyebrow and the action.
The installed file exports hero162Demo alongside the block: the exact props behind the preview above. Spread it to get a working hero in one line.
import { Hero162, hero162Demo } from "@/components/beste/block/hero162";
export default function Page() {
return <Hero162 {...hero162Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hero162 } from "@/components/beste/block/hero162";
import { Notification20 } from "@/components/beste/piece/notification20";
import { ShieldCheck } from "lucide-react";
export default function Page() {
return (
<Hero162
badge={{ label: "Who sees what" }}
heading="Permissions your compliance lead can read in one sitting"
description="Roles are written in plain language, requested in the product, and logged the moment they change."
button={{ label: "Book a security review", href: "/security" }}
rows={[
{
index: "01",
title: "Roles, not checkbox grids",
description: "Six named roles cover the whole practice, and each one reads like a job.",
},
{
index: "02",
title: "Access asked for in the open",
description: "Requests land with the lead who owns that record, never in a shared inbox.",
},
]}
image={{ src: "/backdrops/green.jpg", alt: "Deep green gradient backdrop" }}
media={
<Notification20
icon={ShieldCheck}
title="Access request"
meta="Noah Reyes is asking for the records role"
primaryLabel="Approve"
secondaryLabel="Decline"
/>
}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow above the hairline rule, rendered through Badge23 |
heading | string | – | Display heading, rendered as the page h1 |
description | string | – | Supporting paragraph, capped at max-w-md |
button | { label: string; href: string } | – | Single action under the paragraph |
rows | CapabilityRow[] | [] | Numbered hairline rows in the right column |
image | { src: string; alt: string } | – | Full-bleed band closing the section |
media | ReactNode | – | Live asset pinned into the band's corner |
className | string | – | Extra classes for the outer section |
type CapabilityRow = {
index: string;
title: string;
description: string;
};
type BandImage = {
src: string;
alt: string;
};index is copy, not a computed counter. Passing "01", "A", or "Step 1" all work, and the block never renumbers rows for you, so a reordered array keeps whatever labels you wrote.border-t with first:border-t-0 first:pt-0, which means the first row sits flush against the top of its column and the rules only ever appear between rows, never above the first one.max-w-7xl container, so it runs edge to edge while the copy above it stays gridded. That is why the band is the last child of the section rather than part of the grid.bottom-4 right-4, moving to md:bottom-8 md:right-8, and is width-capped at w-80. It overlays the photograph rather than sitting in a tile, so a busy image will show through around it.pt-16 and no bottom padding: the band is meant to run into whatever follows, which is what makes it read as a closing edge rather than a boxed image.h2, so the numbered list stays a real document outline under the h1 rather than a sequence of styled paragraphs.hero119
Full-bleed image hero with an oversized three-word display heading, a row of monospace meta labels, a bold sub-headline, and a featured card with thumbnail, category, paginated index, and title.
hero166
An editorial hero that breaks its display heading across two lines and slots a square image tile floating a live payment card into the gap, with the paragraph and action landing under a hairline.
hero122
Centered typographic hero on a muted card with an oversized heading, inline CTA, and a bottom monospace meta row of three labels.
hero146
A full-bleed photographic hero with a gradient scrim, an eyebrow over an oversized light heading, paired accent and hairline actions, and a three-figure proof row along the bottom rule.