Hero Aurora

Landing hero with an Aurora background, blur-in headline and two call-to-action links.

pnpm dlx shadcn@latest add @leo/hero-aurora

Props

NameTypeDefaultDescription
classNamestring | undefined-
colorStops[string, string, string] | undefined["#5227FF", "#7cff67", "#5227FF"]
descriptionstring | undefinedAnimated sections you copy into your project and own. No runtime package.
eyebrowstring | undefinedleo-ui-registry
primaryActionHeroAction | undefined{ label: "Get started", href: "#" }
secondaryActionHeroAction | undefined{ label: "Browse components", href: "#" }
titlestring | undefinedBuild landing pages that move

Source

"use client";
import Aurora from "@/components/aurora";
import BlurText from "@/components/blur-text";
import { cn } from "@/lib/utils";

export interface HeroAction {
  label: string;
  href: string;
}

export interface HeroAuroraProps {
  eyebrow?: string;
  title?: string;
  description?: string;
  primaryAction?: HeroAction;
  secondaryAction?: HeroAction;
  colorStops?: [string, string, string];
  className?: string;
}

export default function HeroAurora({
  eyebrow = "leo-ui-registry",
  title = "Build landing pages that move",
  description = "Animated sections you copy into your project and own. No runtime package.",
  primaryAction = { label: "Get started", href: "#" },
  secondaryAction = { label: "Browse components", href: "#" },
  colorStops = ["#5227FF", "#7cff67", "#5227FF"],
  className,
}: HeroAuroraProps) {
  return (
    <section
      className={cn(
        "relative flex min-h-[560px] items-center justify-center overflow-hidden bg-neutral-950 px-6",
        className,
      )}
    >
      <Aurora className="absolute inset-0" colorStops={colorStops} />
      <div className="relative z-10 flex max-w-3xl flex-col items-center text-center">
        {eyebrow && (
          <span className="rounded-full border border-white/15 px-3 py-1 text-xs font-medium tracking-wide text-white/70 uppercase">
            {eyebrow}
          </span>
        )}
        {/* BlurText renders a <p>, which cannot live inside <h1>; screen readers get the plain heading. */}
        <h1 className="sr-only">{title}</h1>
        <div aria-hidden="true">
          <BlurText
            text={title}
            delay={80}
            animateBy="words"
            className="mt-6 justify-center text-4xl font-semibold tracking-tight text-white sm:text-6xl"
          />
        </div>
        <p className="mt-6 max-w-xl text-base text-white/70 sm:text-lg">{description}</p>
        <div className="mt-10 flex flex-wrap items-center justify-center gap-3">
          <a
            href={primaryAction.href}
            className="rounded-lg bg-white px-5 py-2.5 text-sm font-medium text-neutral-950 hover:bg-white/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-950"
          >
            {primaryAction.label}
          </a>
          <a
            href={secondaryAction.href}
            className="rounded-lg border border-white/20 px-5 py-2.5 text-sm font-medium text-white hover:bg-white/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-950"
          >
            {secondaryAction.label}
          </a>
        </div>
      </div>
    </section>
  );
}