Modern Hero

( Hero / Landing / Marketing )

A centred landing hero on a soft aurora background, with a badge, gradient headline, dual CTAs and avatar social proof.

Live preview and source code for Modern Hero

New — v2.0 is live

Ship interfaces your users actually remember

A component collection built for teams who care about the last five percent. Copy, paste, and make it yours — no config, no lock-in.

ARDMKFLN+2
Trusted by 2,400+ product teams

A centred landing page hero section: an eyebrow pill, a large headline with one phrase picked out in a gradient, a supporting line, two calls to action and a row of overlapping avatars as social proof. The aurora background and dot grid are drawn in CSS rather than shipped as an image, so there is nothing to optimise and the whole section scales with the viewport. Every element fades and unblurs upward in a stagger on mount.

Installation

Copy the source from the Code tab above into your project as ModernHero.tsx. Its styles are a <style> block of mh- prefixed classes that travels with the file, so there is no stylesheet to import and no Tailwind config to touch.

It imports framer-motion for the entrance stagger and lucide-react for the arrow, play and star icons:

Terminal
npm install framer-motion lucide-react

It also renders three items from this collection, so copy those files too and fix the import paths at the top to match where you put them: Avatar, Badge and Button.

Usage

Every prop is optional and the defaults are a complete hero, so start by rendering it and replacing the copy one prop at a time:

Example.tsx
import ModernHero from "./components/ModernHero";

export default function Example() {
    return (
        <ModernHero
            headline="Ship interfaces your users actually remember"
            highlight="actually remember"
            primaryCta="Start building"
        />
    );
}

highlight is the substring of headline that gets the gradient. The match is exact and case sensitive and only the first occurrence is tinted; if it is not found, the headline still renders, just without an accent.

eyebrow and secondaryCta each accept null to remove that element, and socialProof={false} removes the avatar row.

When to reach for it

The top of a product or marketing page where the job is one message, one action, and enough visual interest that the fold does not look like a document.

A launch or changelog page, using eyebrow for the version pill. It renders a Badge with a dot and a star icon.

An internal tool's landing screen, where the aurora and the avatar stack do the work a designer would otherwise have to spend a day on.

When not to

If the page already has an <h1>. This renders one, and two on a page is a structural problem rather than a styling one.

If the hero needs to capture anything. There is no children slot and no form, so an email capture, a search field or a video embed means editing the copied file rather than passing a prop.

If your brand is dark. The palette is hard-coded light: a near-white background, near-black text and three pastel blobs. That is four values to change in the copied file, but no prop reaches them.

Accessibility

The aurora blobs and the dot grid are aria-hidden, so nothing decorative reaches the accessibility tree. The headline is a real <h1> and the highlighted phrase is a <span> inside it, so the gradient does not split the heading text.

The entrance animation is not gated on prefers-reduced-motion. Content starts at reduced opacity and blurred and animates in, which means removing the initial and animate values in the copied file if you honour that setting. The ghost button's hover transition is gated, but that is the only part that is.

Notes

The social proof line is placeholder copy. The six names and the "Trusted by 2,400+ product teams" string are constants in the source, not props. Replace them with something true or set socialProof={false}, because shipping an invented number is worse than shipping no number.

Neither call to action has a click handler. The primary one is a Button and the secondary is a plain <button> styled in the block's own CSS, and both do nothing until you wire them up or swap them for links.

The mh- class names are global once the section renders. Two heroes on one page share one set of rules, which is fine, but a class of your own named mh-something would collide.