Split hero
Headline, supporting copy, and two actions beside a numbered checklist panel. Stacks on phones.
id hero-split · revision 7a37deb08c96 · catalogue 0.1.0
Preview
Every token this component reads is set by the style, and every font is loaded or a system font.
Hover and keyboard focus
The component's own hover and focus styles, switched on for every link and button at once so you can see them without a mouse. In the previews above they work as usual.
Copy it
These two files are exactly what the previews above render. The MCP tool get_component returns the same files.
- Save HeroSplit.tsx with your components and styles/neat-paper.css with your styles.
- Import styles/neat-paper.css once, after @import "tailwindcss" in your global stylesheet.
- Make sure Tailwind scans the folder that holds the component.
- For dark mode, set data-theme="dark" on the <html> element.
- Add <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,[email protected],600&display=swap"> to the document head.
components/HeroSplit.tsx
export interface HeroSplitProps {
eyebrow?: string;
title?: string;
body?: string;
primary?: { label: string; href: string };
secondary?: { label: string; href: string };
checklist?: string[];
}
const focusRing =
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--nl-focus)]";
/**
* Two-column hero: the promise and actions on the left, a checklist panel on
* the right that shows what the product does. Stacks on phones.
*/
export function HeroSplit({
eyebrow = "Release notes, handled",
title = "Ship the update. We'll write it up.",
body = "Example Studio turns merged pull requests into release notes your customers will read. Review the draft, edit anything, and publish.",
primary = { label: "Start a trial", href: "#start" },
secondary = { label: "See a sample", href: "#sample" },
checklist = ["Drafts from merged pull requests", "Edits stay in your voice", "Publishes to your changelog"],
}: HeroSplitProps) {
return (
<section className="bg-[color:var(--nl-canvas)] px-6 py-[var(--nl-section-y)] font-[family-name:var(--nl-font-sans)] text-[color:var(--nl-ink)]">
<div className="mx-auto grid max-w-6xl items-center gap-12 lg:grid-cols-2">
<div>
<p className="font-[family-name:var(--nl-font-mono)] text-xs uppercase tracking-wider text-[color:var(--nl-muted)]">{eyebrow}</p>
<h1 className="mt-4 text-balance font-[family-name:var(--nl-font-display)] text-4xl leading-tight font-semibold sm:text-5xl">
{title}
</h1>
<p className="mt-6 max-w-prose text-lg leading-relaxed text-[color:var(--nl-muted)]">{body}</p>
<div className="mt-8 flex flex-wrap gap-3">
<a
href={primary.href}
className={`rounded-[var(--nl-radius)] bg-[color:var(--nl-accent)] px-5 py-3 font-medium text-[color:var(--nl-accent-ink)] hover:opacity-90 ${focusRing}`}
>
{primary.label}
</a>
<a
href={secondary.href}
className={`rounded-[var(--nl-radius)] border border-[color:var(--nl-line)] px-5 py-3 font-medium hover:bg-[color:var(--nl-surface)] ${focusRing}`}
>
{secondary.label}
</a>
</div>
</div>
<div className="rounded-[var(--nl-radius)] border border-[color:var(--nl-line)] bg-[color:var(--nl-surface)] p-6 sm:p-8">
<p className="text-sm font-medium text-[color:var(--nl-muted)]">What happens after you merge</p>
<ol className="mt-6 space-y-4">
{checklist.map((item, index) => (
<li key={item} className="flex items-start gap-4">
<span
aria-hidden="true"
className="flex size-7 shrink-0 items-center justify-center rounded-full bg-[color:var(--nl-accent)] font-[family-name:var(--nl-font-mono)] text-xs text-[color:var(--nl-accent-ink)]"
>
{index + 1}
</span>
<span className="pt-0.5">{item}</span>
</li>
))}
</ol>
</div>
</div>
</section>
);
}
styles/neat-paper.css
/* Neat Labs theme "paper" (revision 9e029aa69c45) for hero-split (revision 7a37deb08c96), catalogue 0.1.0. */
:root {
--nl-canvas: #F5F1E8;
--nl-surface: #FFFDF8;
--nl-ink: #1F1B16;
--nl-muted: #5E554A;
--nl-line: #D9D0C1;
--nl-accent: #B4462C;
--nl-accent-ink: #FFFFFF;
--nl-focus: #1F5FBF;
--nl-font-display: "Fraunces", ui-serif, Georgia, serif;
--nl-font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--nl-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
--nl-radius: 6px;
--nl-section-y: 96px;
}
[data-theme="dark"] {
--nl-canvas: #16130F;
--nl-surface: #211D18;
--nl-ink: #F2ECE1;
--nl-muted: #B3A999;
--nl-line: #3A342C;
--nl-accent: #E07A5F;
--nl-accent-ink: #1A0F0B;
--nl-focus: #8AB4F8;
}
MCP tool call
{
"name": "get_component",
"arguments": {
"id": "hero-split",
"style": "paper"
}
}