Feature grid
Heading and intro above a ruled grid of numbered feature notes. Three, two, or one column by width.
id features-grid · revision f2896265613a · catalogue 0.1.0
Preview
Every token this component reads is set by the style, and every font is loaded or a system font.
Copy it
These two files are exactly what the previews above render. The MCP tool get_component returns the same files.
- Save FeaturesGrid.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/FeaturesGrid.tsx
export interface Feature {
title: string;
body: string;
}
export interface FeaturesGridProps {
heading?: string;
intro?: string;
features?: Feature[];
}
/**
* Heading and intro above a three-column grid of short feature notes, each
* numbered in the mono face. Drops to two columns on tablets and one on phones.
*/
export function FeaturesGrid({
heading = "Built for the week after launch",
intro = "The parts of release work that usually slip, done the same way every time.",
features = [
{ title: "Drafts from real changes", body: "Each note starts from the merged pull request, so nothing is invented." },
{ title: "Review before it ships", body: "Drafts wait for a person to approve them. Nothing publishes on its own." },
{ title: "Your words, kept", body: "Edits you make to one draft carry into the style of the next." },
{ title: "One changelog", body: "Web, email, and in-app notes come from the same approved text." },
{ title: "Quiet by default", body: "Minor fixes are grouped into a weekly digest instead of separate posts." },
{ title: "Plain exports", body: "Download everything as Markdown whenever you like." },
],
}: FeaturesGridProps) {
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 max-w-6xl">
<div className="max-w-2xl">
<h2 className="text-balance font-[family-name:var(--nl-font-display)] text-3xl font-semibold sm:text-4xl">{heading}</h2>
<p className="mt-4 text-lg text-[color:var(--nl-muted)]">{intro}</p>
</div>
<ul className="mt-12 grid gap-px overflow-hidden rounded-[var(--nl-radius)] border border-[color:var(--nl-line)] bg-[color:var(--nl-line)] sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature, index) => (
<li key={feature.title} className="bg-[color:var(--nl-surface)] p-6">
<p className="font-[family-name:var(--nl-font-mono)] text-xs text-[color:var(--nl-muted)]">
{String(index + 1).padStart(2, "0")}
</p>
<h3 className="mt-3 font-semibold">{feature.title}</h3>
<p className="mt-2 text-sm leading-relaxed text-[color:var(--nl-muted)]">{feature.body}</p>
</li>
))}
</ul>
</div>
</section>
);
}
styles/neat-paper.css
/* Neat Labs theme "paper" (revision 9e029aa69c45) for features-grid (revision f2896265613a), catalogue 0.1.0. */
:root {
--nl-canvas: #F5F1E8;
--nl-surface: #FFFDF8;
--nl-ink: #1F1B16;
--nl-muted: #5E554A;
--nl-line: #D9D0C1;
--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;
}
MCP tool call
{
"name": "get_component",
"arguments": {
"id": "features-grid",
"style": "paper"
}
}