Workspace / block / hero
Minimal Hero
paxfx add blocks/block-hero-minimal-06local onlyTier: low. Reduced motion: Fully static; the single underline draw is skipped.
"use client";
import { cn, useInView, useReducedMotion, type BlockCopy } from "@pax-sh/blocks";
export interface HeroMinimalProps {
copy?: BlockCopy;
className?: string;
}
const DEFAULT_COPY: BlockCopy = {
title: "Less interface. More intent.",
description: "Pax ships the smallest set of moves that still reads as designed.",
primaryCta: { label: "See how it works", href: "/docs" },
};
/**
* One headline, one support line, one link. Extreme whitespace discipline
* does the composition; the only motion is a single underline that draws
* in beneath the link on first view. Reduced motion skips the draw and
* shows the underline complete.
*/
export function HeroMinimal({ copy = DEFAULT_COPY, className }: HeroMinimalProps) {
const reduced = useReducedMotion();
const [ref, inView] = useInView<HTMLDivElement>({ threshold: 0.35 });
const drawn = reduced || inView;
return (
<section
className={cn(
"bg-[var(--pax-paper,#f6f2ea)] px-6 py-28 text-[var(--pax-ink,#12110f)] md:px-10 md:py-40",
className,
)}
data-pax-asset="block-hero-minimal-06"
>
<div ref={ref} className="mx-auto max-w-2xl">
<h1 className="m-0 text-4xl font-semibold leading-[1.06] tracking-tight [text-wrap:balance] md:text-5xl">
{copy.title}
</h1>
{copy.description ? (
<p className="mt-6 text-base leading-relaxed text-[var(--pax-mute,#6b645c)] md:text-lg">
{copy.description}
</p>
) : null}
{copy.primaryCta ? (
<a
href={copy.primaryCta.href}
className="relative mt-12 inline-block text-sm font-semibold outline-offset-4 focus-visible:outline focus-visible:outline-2"
{...(copy.primaryCta.goal ? { "data-fast-goal": copy.primaryCta.goal } : {})}
>
{copy.primaryCta.label}
<span
aria-hidden="true"
className="absolute -bottom-1 left-0 h-0.5 w-full origin-left bg-[var(--pax-acid,#c8ff00)]"
style={
reduced
? undefined
: {
transform: drawn ? "scaleX(1)" : "scaleX(0)",
transition: "transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.25s",
}
}
/>
</a>
) : null}
</div>
</section>
);
}