Skip to content
ilinxa/pro-ui

Page Hero

alphav0.2.0

Full-bleed gradient hero band — badge, title, highlight, description, stats row, and a reveal-on-mount animation.

Category: MarketingUpdated: 2026-08-11Created: 2026-05-02Author: ilinxa

Context

Top-of-page hero band for landing pages, blog indexes, marketing sections, and app welcomes. Three density levels (compact / default / full) cover full-screen splashes down to sub-page banners. Engine is generic; news-flavored defaults live in dummy-data + demo (kasder NewsHero's content). Composable `children` slot supports stats / CTAs / search / anything. Migration origin: kasder kas-social-front-v0 commons/PageHero.tsx (engine) + sections/news/NewsHero.tsx (news-flavored shell). Drops framer-motion in favor of the existing pro-ui CSS keyframe — saves ~100KB peer dep + inherits prefers-reduced-motion respect for free.

Installation

Initialize shadcn (once per project)Seeds lib/utils.ts and components.json. Skip if you've already used any shadcn component.
pnpm dlx shadcn@latest init
Register the @ilinxa namespace (once per project)Add to your components.json. Merge with existing config.
"registries": {
  "@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}
Install the component
pnpm dlx shadcn@latest add @ilinxa/page-hero

Add -fixtures for dummy data:

pnpm dlx shadcn@latest add @ilinxa/page-hero-fixtures

Preview

News & Updates

Latest StoriesFrom Our Team

Insights, announcements, and behind-the-scenes from our editorial team.

Demo source

demo.tsxtsx

Usage

When to use

Reach for PageHero as the top-of-page hero band on any landing or section: news landing, blog index, marketing page, docs site, app welcome screen. Composes a gradient background, accent badge chip, large title with optional highlight subline, description, and a flexible content slot.

Minimal example

import { PageHero } from "@/components/page-hero";

<PageHero
  badge="News & Updates"
  title="Latest Stories"
  titleHighlight="From Our Team"
  description="Insights and announcements."
/>;

With HeroStats

The HeroStats sub-component renders the typical icon-circle + bold value + small label triplet, designed for the white-on-gradient contrast inside the hero.

import { HeroStats, PageHero } from "@/components/page-hero";
import { Newspaper, TrendingUp, Clock } from "lucide-react";

<PageHero badge="News" title="Stories" description="Stay informed.">
  <HeroStats stats={[
    { icon: Newspaper, value: "500+", label: "Articles" },
    { icon: TrendingUp, value: "10K+", label: "Readers" },
    { icon: Clock, value: "Daily", label: "Updates" },
  ]} />
</PageHero>;

CTA cluster

<PageHero
  badge="New: v2.0"
  title="Build faster"
  titleHighlight="Ship sooner"
>
  <div className="flex justify-center gap-4">
    <Button size="lg" variant="secondary">Get started</Button>
    <Button size="lg" variant="outline">View docs</Button>
  </div>
</PageHero>;

Density variations

Three options via the density prop:

  • compactmin-h-[40vh]. Sub-page heroes, section dividers.
  • defaultmin-h-[70vh]. Most landing pages.
  • fullmin-h-screen. Splash / welcome screens.

Custom title rendering

For mixed-color or italic-word titles beyond the simple title + titleHighlight combo, pass titleSlot:

<PageHero
  title="" // unused when titleSlot is provided
  titleSlot={
    <h1 className="text-5xl font-bold text-primary-foreground">
      The <em className="italic text-primary-foreground">future</em> of news
    </h1>
  }
  description="..."
/>;

Animation

Reveal animation runs on mount via the project-wide reveal-up CSS keyframe with 60ms staggered delays (badge → title → description → children). Respects prefers-reduced-motion automatically (free via the existing keyframe). Disable entirely with disableReveal={true}.

Accessibility

  • Section is a landmark with aria-labelledby pointing to the title id (auto-generated via useId).
  • Badge icon is aria-hidden; badge text is the meaningful label.
  • Heading semantic level configurable via headingAs={"h1" | "h2" | "h3"}. Default h1.
  • Reduced-motion users see content instantly (no transitions).

Features

  • Full-bleed gradient hero band — 3 density levels (compact 40vh / default 70vh / full 100vh)
  • 4-tier reveal stagger via project's `reveal-up` keyframe — badge / title / description / children, 60ms apart
  • Drops framer-motion peer dep (~100KB) — uses existing pro-ui CSS keyframe
  • `prefers-reduced-motion` respect inherited from the keyframe — content fades instantly for reduced-motion users
  • Badge chip (rounded-full, accent tint) with optional Lucide-style icon
  • Title-with-highlight pattern — second `<span>` rendered as a new line in accent color
  • `titleSlot` prop accepts ReactNode for rich custom rendering
  • `children` slot for stats / CTAs / search / breadcrumbs / anything
  • `HeroStats` sub-component exported separately for the icon-circle + value + label triplet pattern
  • Bottom SVG wave that fills with `--background` so the hero transitions cleanly
  • Subtle SVG noise pattern overlay on the gradient
  • ARIA — `aria-labelledby` wires section landmark to title id (useId)
  • Heading semantic level configurable via `headingAs` (h1 | h2 | h3)
  • `disableReveal` prop for SSR-only contexts
  • React.memo wrapped

Tags

page-heromarketingherolandingmigrationnews

Dependencies

npm peer deps: lucide-react@^1.11.0