A hero built as one dark panel: a light display heading, two actions, and a hairline table of service commitments beside a bordered image column that floats a live uptime strip.
A hero built as one dark panel: a light display heading, two actions and a hairline table of service commitments, beside a bordered image column that floats a live uptime strip.
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/hero160?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/hero160?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hero160.tsx, the indicator14 uptime piece it floats in the right column (installed to components/beste/piece/indicator14.tsx), and the badge23 and button21 components it uses for the eyebrow and the actions.
The installed file exports hero160Demo alongside the block: the exact props behind the preview above. Spread it to get a working hero in one line.
import { Hero160, hero160Demo } from "@/components/beste/block/hero160";
export default function Page() {
return <Hero160 {...hero160Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hero160 } from "@/components/beste/block/hero160";
import { Indicator14 } from "@/components/beste/piece/indicator14";
export default function Page() {
return (
<Hero160
badge={{ label: "Always on" }}
heading="Bookings that hold up on the worst Monday of the year"
description="The schedule, the reminders, and the waiting list run on infrastructure your team never has to think about."
buttons={[
{ label: "Read the status page", href: "/status" },
{ label: "Book a demo", href: "/demo" },
]}
assurances={[
{ label: "Uptime commitment", value: "99.95%" },
{ label: "Data residency", value: "EU and UK" },
{ label: "Incident response", value: "Under 15 min" },
]}
media={
<Indicator14
title="Booking service"
uptime="99.98%"
range="Last 45 days"
bars={["up", "up", "partial", "up", "down", "up", "up"]}
/>
}
image={{ src: "/backdrops/green.jpg", alt: "Deep green gradient backdrop" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow at the top of the panel, retoned for the dark surface |
heading | string | – | Display heading, rendered as the page h1 |
description | string | – | Supporting paragraph, capped at max-w-md |
buttons | ActionLink[] | [] | Actions in source order, the first one solid and the rest outlined |
assurances | AssuranceRow[] | [] | Label and value pairs in the commitments table |
media | ReactNode | – | Live asset in the right column, indicator14 in the demo |
image | { src: string; alt: string } | – | Backdrop behind the media column |
className | string | – | Extra classes for the outer section |
type ActionLink = {
label: string;
href: string;
};
type AssuranceRow = {
label: string;
value: string;
};bg-foreground panel inside the normal page container, so it reads as an inverted card rather than a full-bleed band. Every text token inside is a fixed background value, not an adaptive one, because the surface is fixed.Badge23 is retoned inline with border-background/30 text-background/70. The component's own tones are built for light surfaces, so the override is what keeps the eyebrow legible here.primary, and every later one renders outline with an extra border-background/30 class so the outline is visible against the dark panel. The ActionLink type deliberately has no tone field.dl with dt and dd per row. Each row carries border-t and the last one adds last:border-b, which closes the table instead of leaving it open at the bottom.lg:grid-cols-5 split, three columns of copy against two of media. Below lg it stacks and the divider flips from lg:border-l to border-t, so the seam always runs across the join rather than through it.items-center. On a short copy column the piece stays centered rather than pinning to the top.hero161
A hero that pairs a light display heading with an offset paragraph and action, then drops a wide image band under them and overlaps its lower edge with a live savings card.
hero139
Full-bleed monochrome hero with a giant display heading over a static image, paired with a card that auto-cycles through testimonials and click-to-select dots.
hero164
A hero that opens on a full-bleed image band with a live phone frame anchored into it, then sets the eyebrow, light display heading, paragraph, and actions underneath rather than above.
hero162
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.