Workspace / block / hero

Minimal Hero

One headline, one line of support, one link. Generous whitespace and a strict type scale do all of the work.

Workspaceblockhero

paxfx add blocks/block-hero-minimal-06local only

Tier: 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>
  );
}