caliper uidocs

Hero section

Block

The top of a landing page: eyebrow, title, copy, actions and proof.

Installs components/ui/hero-section.tsxDepends on none beyond ReactMotion shared motion tokens
pnpm dlx shadcn@latest add https://caliperui.site/r/hero-section.json
New Agents, tables and threads

Interface parts you own, with the details done

Install readable components, edit them freely, and ship screens that feel finished: keyboard first, calm motion, real states.

Free to start. No card needed.

Trusted by product teams at studios, startups and agencies.

When to use #

Use it for

  • A page needs a clear promise and one main action.
  • Adding media or logos beneath the copy.

Skip it when

  • Inside the product; use a page header.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/hero-section.json

Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above.

example.tsx
import { ArrowRight } from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { HeroSection } from "@/components/ui/hero-section"

export function HeroSectionDemo() {
  return (
    <HeroSection
              animated
              eyebrow={
                <a href="#changelog" className="inline-flex items-center gap-2 rounded-full border border-border bg-background px-3 py-1 text-xs no-underline outline-none hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring">
                  <Badge>New</Badge> Agents, tables and threads <ArrowRight aria-hidden="true" className="size-3" />
                </a>
              }
              title="Interface parts you own, with the details done"
              description="Install readable components, edit them freely, and ship screens that feel finished: keyboard first, calm motion, real states."
              actions={
                <>
                  <Button size="lg">Get started</Button>
                  <Button size="lg" variant="secondary">Browse components</Button>
                </>
              }
              note="Free to start. No card needed."
              media={
                <div className="overflow-hidden rounded-overlay border border-border bg-background">
                  <div className="flex items-center gap-1.5 border-b border-border px-3 py-2" aria-hidden="true">
                    <span className="size-2.5 rounded-full bg-muted-foreground/40" />
                    <span className="size-2.5 rounded-full bg-muted-foreground/40" />
                    <span className="size-2.5 rounded-full bg-muted-foreground/40" />
                  </div>
                  <div className="grid gap-3 p-5 sm:grid-cols-3" aria-hidden="true">
                    {[72, 48, 88].map((w, i) => (
                      <div key={i} className="grid gap-2 rounded-surface bg-surface p-4">
                        <span className="h-2 w-1/3 rounded-full bg-foreground/15" />
                        <span className="h-6 rounded-md bg-foreground/10" style={{ width: `${w}%` }} />
                        <span className="h-2 w-2/3 rounded-full bg-foreground/10" />
                      </div>
                    ))}
                  </div>
                </div>
              }
              proof="Trusted by product teams at studios, startups and agencies."
            />
  );
}

API reference #

HeroSection

component
PropTypeDefaultDescription
eyebrowReactNode—A small announcement above the title, often a badge that links somewhere.
title *ReactNode—One sentence. With `animated`, a string whose words rise into view.
descriptionReactNode—
actionsReactNode—The main button and at most one quieter alternative.
noteReactNode—A line of reassurance under the buttons, such as "Free for small teams".
mediaReactNode—A product shot, demo or illustration below the copy.
proofReactNode—Logos or a short line of social proof.
align"center" | "start""center"
animatedbooleanfalse
classNamestring—

Accessibility #

It is built on native elements, so roles and focus come from the browser.

No custom key handling; Tab and the native activation keys do the work.

Motion #

Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.