A hero that splits the viewport in two: an eyebrow, light display heading, two actions, and a hairline proof row on one side, and a full-height photo column floating a live trend metric on the other.
A hero split down the middle of the viewport: an eyebrow, a light display heading, two actions and a hairline proof row on one side, and a full-height photograph on the other with a live trend metric floating over it.
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/hero157?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/hero157?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hero157.tsx, the stats16 trend-metric piece it floats over the photo column (installed to components/beste/piece/stats16.tsx), and the badge23 and button21 components it uses for the eyebrow and the actions.
The installed file exports hero157Demo alongside the block: the exact props behind the preview above. Spread it to get a working hero in one line.
import { Hero157, hero157Demo } from "@/components/beste/block/hero157";
export default function Page() {
return <Hero157 {...hero157Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hero157 } from "@/components/beste/block/hero157";
import { Stats16 } from "@/components/beste/piece/stats16";
export default function Page() {
return (
<Hero157
badge={{ label: "Care operations" }}
heading="The quiet system behind a busy clinic"
description="Intake, scheduling, and follow-up on one surface, so the day runs on what your team already decided."
buttons={[
{ label: "Book a demo", href: "/demo" },
{ label: "See how it works", href: "/product", tone: "outline" },
]}
proof={[
{ value: "18 min", label: "saved per intake" },
{ value: "4 tools", label: "retired on average" },
{ value: "1 day", label: "to first live clinic" },
]}
media={
<Stats16
label="Intakes completed"
value="1,284"
delta="12.4%"
direction="up"
caption="vs. 1,142 the month before"
bars={[38, 52, 44, 61, 55, 72, 68, 86]}
/>
}
image={{ src: "/clinic/reception.jpg", alt: "A clinician in a bright clinic" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow above the heading, rendered through Badge23 |
heading | string | – | Display heading, rendered as the page h1 |
description | string | – | Supporting paragraph under the heading, capped at max-w-md |
buttons | ActionLink[] | [] | Actions in source order, each wrapping a next/link |
proof | ProofItem[] | [] | Figure and label pairs on the hairline row under the actions |
media | ReactNode | – | Live asset layered over the photograph, stats16 in the demo |
image | { src: string; alt: string } | – | Photograph filling the second column |
className | string | – | Extra classes for the outer section |
type ButtonTone = "primary" | "neutral" | "outline";
type ActionLink = {
label: string;
href: string;
tone?: ButtonTone;
};
type ProofItem = {
value: string;
label: string;
};px-4 py-16, md:px-6 md:py-24), so the photograph bleeds to the edge of the viewport on every side it touches.order-first on small screens and lg:order-last, so the photograph leads on mobile and sits on the right once the layout goes two-up.lg (h-80, then md:h-96) and switches to lg:h-auto with lg:min-h-[38rem], letting the text column dictate the height on large screens while guaranteeing a floor.media is absolutely positioned at inset-0 z-10 over the image, so the piece is layered on the photograph rather than placed beside it. Pieces center themselves inside their own root, so anything from the piece catalogue drops in without extra wrapping.tone is honored when set, otherwise the first button renders primary and every later one renders outline. Passing an explicit tone on the first entry is the way to get two outline actions.proof renders only when the array has entries, and it brings its own border-t hairline and top padding with it, so an empty array leaves no stray rule behind the actions.max-w-xl and pushed to lg:justify-end with lg:pr-12, which keeps the measure readable and holds the copy against the centre seam instead of letting it drift wide.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.
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.
hero115
Full-bleed background-image hero with a legibility scrim and bottom-aligned eyebrow, headline, copy and CTAs.
hero131
Full-bleed hero whose background crossfades between frames, with a clickable filmstrip of thumbnails pinned along the bottom and an auto-advancing active tile.