65 lines
2.3 KiB
TypeScript
Executable File
65 lines
2.3 KiB
TypeScript
Executable File
import * as React from "react";
|
|
import { FadeIn } from "../motion";
|
|
import { Button } from "../components/button";
|
|
import { cn } from "../lib/cn";
|
|
|
|
export function Hero({
|
|
eyebrow,
|
|
title,
|
|
subtitle,
|
|
primaryCta,
|
|
secondaryCta,
|
|
className,
|
|
}: {
|
|
eyebrow?: string;
|
|
title: React.ReactNode;
|
|
subtitle?: React.ReactNode;
|
|
primaryCta?: { label: string; href?: string; onClick?: () => void };
|
|
secondaryCta?: { label: string; href?: string; onClick?: () => void };
|
|
className?: string;
|
|
}) {
|
|
return (
|
|
<section className={cn("relative overflow-hidden bg-bg px-6 py-24 text-center", className)}>
|
|
{/* Subtle brand aura — depth, not a purple gradient. */}
|
|
<div
|
|
aria-hidden
|
|
className="pointer-events-none absolute inset-x-0 top-0 h-[420px] opacity-60"
|
|
style={{ background: "radial-gradient(600px 300px at 50% 0%, hsl(var(--brand) / 0.14), transparent 70%)" }}
|
|
/>
|
|
<div className="relative mx-auto max-w-3xl">
|
|
{eyebrow && (
|
|
<FadeIn>
|
|
<span className="mb-4 inline-block rounded-sm bg-brand/15 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-brand">
|
|
{eyebrow}
|
|
</span>
|
|
</FadeIn>
|
|
)}
|
|
<FadeIn delay={0.05}>
|
|
<h1 className="font-display text-4xl font-bold leading-[1.1] tracking-tight sm:text-6xl">{title}</h1>
|
|
</FadeIn>
|
|
{subtitle && (
|
|
<FadeIn delay={0.1}>
|
|
<p className="mx-auto mt-6 max-w-xl text-lg text-muted">{subtitle}</p>
|
|
</FadeIn>
|
|
)}
|
|
{(primaryCta || secondaryCta) && (
|
|
<FadeIn delay={0.15}>
|
|
<div className="mt-10 flex flex-col items-stretch justify-center gap-3 sm:flex-row sm:items-center">
|
|
{primaryCta && (
|
|
<Button size="lg" asChild={!!primaryCta.href} onClick={primaryCta.onClick}>
|
|
{primaryCta.href ? <a href={primaryCta.href}>{primaryCta.label}</a> : primaryCta.label}
|
|
</Button>
|
|
)}
|
|
{secondaryCta && (
|
|
<Button size="lg" variant="outline" asChild={!!secondaryCta.href} onClick={secondaryCta.onClick}>
|
|
{secondaryCta.href ? <a href={secondaryCta.href}>{secondaryCta.label}</a> : secondaryCta.label}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</FadeIn>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|