"use client"; import { useState, type ReactNode } from "react"; import "./focus-pull-cta.css"; /** * Focus Pull * The block has three planes: the headline, the primary action, the * secondary action. At rest the headline is the subject. Move toward an * action and focus racks onto it — it overshoots, softens a touch, then * locks (a lens hunting) — while the other planes fall back and blur. */ type Action = { label: string; href?: string; onClick?: () => void }; type Props = { eyebrow?: string; title: ReactNode; note?: ReactNode; primary: Action; secondary: Action; accent?: string; className?: string; }; type Plane = "title" | "primary" | "secondary"; export function FocusPullCta({ eyebrow, title, note, primary, secondary, accent = "#e8a24a", className = "" }: Props) { const [subject, setSubject] = useState("title"); const [shot, setShot] = useState(0); // bumps on every rack so the hunt replays const rack = (p: Plane) => { if (p === subject) return; setSubject(p); setShot((s) => s + 1); }; const act = (a: Action, plane: Plane) => ( rack(plane)} onFocus={() => rack(plane)} onClick={(e) => { if (!a.href) e.preventDefault(); a.onClick?.(); }} > {a.label} {plane === "primary" && ( )} ); return (
rack("title")} onBlur={(e) => { if (!e.currentTarget.contains(e.relatedTarget)) rack("title"); }} >
{eyebrow &&

{eyebrow}

}

{title}

{act(primary, "primary")} {act(secondary, "secondary")}
{note &&

{note}

}
); }