7 · Project: a landing page
Lesson 7 of 8 — build a complete, responsive, dark-mode landing page with everything you have learned.
2 min readv1
Time to build something real: a hero, a feature grid, a pricing section and a footer. Every piece uses the tokens and recipes from lessons 5 and 6.
The config#
TypeScript
// nibcss.config.ts
import { defineConfig } from "@nibcss/core";
export default defineConfig({
darkMode: "class",
tokens: {
color: { brand: "#4F52D9", "brand-hover": "#3A3DBF", ink: "#0f172a", muted: "#64748b", border: "#e2e8f0" },
space: { sm: "8px", md: "16px", lg: "24px", xl: "48px" },
radius: { md: "10px", lg: "16px", pill: "999px" },
},
components: {
container: "w=100%; mxw=1120px; mi=auto; px=$space.lg",
section: "py=64px; md:py=96px",
eyebrow: "fts=13px; ftw=700; txt=uppercase; lts=.08em; cl=$color.brand",
h2: "fts=clamp(26px, 4vw, 40px); ftw=800; lts=-0.02em; lh=1.15",
lead: "fts=18px; lh=1.7; cl=$color.muted; dark:cl=#94a3b8",
card: "p=$space.lg; bdrd=$radius.lg; bgc=#fff; bd=1px solid $color.border; dark:bgc=#0f172a; dark:bd=1px solid #1e293b",
btn: "d=inline-flex; ali=center; g=8px; p=12px 20px; bdrd=$radius.md; ftw=600; txd=none; cur=pointer; ts=all .15s",
"btn-primary": "btn; bgc=$color.brand; cl=#fff; hover:bgc=$color.brand-hover",
"btn-outline": "btn; bd=1px solid $color.border; cl=$color.ink; dark:cl=#fff; hover:bgc=#f8fafc; dark:hover:bgc=#1e293b",
},
});The hero#
HTML
<section nib="section; txa=center; bgi=radial-gradient(ellipse at top, #EEEFFE, transparent 60%); dark:bgi=radial-gradient(ellipse at top, #1e1b4b, transparent 60%)">
<div nib="container; d=flex; flxd=column; ali=center; g=20px">
<span nib="eyebrow">New · v1.1</span>
<h1 nib="fts=clamp(34px, 6vw, 60px); ftw=800; lts=-0.03em; lh=1.05; mxw=16ch">
Styles that live where your markup lives
</h1>
<p nib="lead; mxw=560px">Write CSS as attributes. Ship a static stylesheet. Keep one design system across every framework.</p>
<div nib="d=flex; g=12px; flxw=wrap; jsc=center">
<a nib="btn-primary" href="/start">Get started →</a>
<a nib="btn-outline" href="/docs">Read the docs</a>
</div>
</div>
</section>The feature grid#
HTML
⚡
Zero runtime
Static attributes compile at build time.
◎
Deterministic
Same rule, same class — everywhere.
✓
Helpful errors
Typos come with suggestions.
<div nib="d=grid; gtc=repeat(auto-fit, minmax(200px, 1fr)); g=16px; w=100%; mnw=320px">
<div nib="card; p=20px">
<div nib="w=36px; h=36px; bdrd=10px; bgc=#EEEFFE; cl=#4F52D9; d=grid; pli=center; ftw=800; mb=12px">⚡</div>
<h3 nib="fts=16px; ftw=700; m=0">Zero runtime</h3>
<p nib="fts=14px; cl=$color.ink-muted; mt=6px; lh=1.6">Static attributes compile at build time.</p>
</div>
<div nib="card; p=20px">
<div nib="w=36px; h=36px; bdrd=10px; bgc=#ecfeff; cl=#0891b2; d=grid; pli=center; ftw=800; mb=12px">◎</div>
<h3 nib="fts=16px; ftw=700; m=0">Deterministic</h3>
<p nib="fts=14px; cl=$color.ink-muted; mt=6px; lh=1.6">Same rule, same class — everywhere.</p>
</div>
<div nib="card; p=20px">
<div nib="w=36px; h=36px; bdrd=10px; bgc=#f0fdf4; cl=#16a34a; d=grid; pli=center; ftw=800; mb=12px">✓</div>
<h3 nib="fts=16px; ftw=700; m=0">Helpful errors</h3>
<p nib="fts=14px; cl=$color.ink-muted; mt=6px; lh=1.6">Typos come with suggestions.</p>
</div>
</div>Pricing with a highlighted plan#
HTML
Starter
$0
For side projects
POPULAR
Team
$19
Per seat, per month
Enterprise
Custom
SLA and SSO
<div nib="d=grid; gtc=repeat(auto-fit, minmax(190px, 1fr)); g=16px; ali=stretch; w=100%; mnw=320px">
<div nib="card; p=22px; d=flex; flxd=column; g=10px">
<strong>Starter</strong>
<div nib="fts=32px; ftw=800">$0</div>
<span nib="fts=13px; cl=$color.ink-muted">For side projects</span>
</div>
<div nib="card; p=22px; d=flex; flxd=column; g=10px; bd=2px solid #4F52D9; bxsh=0 12px 32px rgba(79,82,217,.18); pos=relative">
<span nib="pos=absolute; t=-11px; r=16px; p=2px 10px; bdrd=999px; bgc=#4F52D9; cl=#fff; fts=11px; ftw=700">POPULAR</span>
<strong>Team</strong>
<div nib="fts=32px; ftw=800">$19</div>
<span nib="fts=13px; cl=$color.ink-muted">Per seat, per month</span>
</div>
<div nib="card; p=22px; d=flex; flxd=column; g=10px">
<strong>Enterprise</strong>
<div nib="fts=32px; ftw=800">Custom</div>
<span nib="fts=13px; cl=$color.ink-muted">SLA and SSO</span>
</div>
</div>The footer#
HTML
<footer nib="bdt=1px solid $color.border; dark:bdt=1px solid #1e293b; py=32px">
<div nib="container; d=flex; flxd=column; md:flxd=row; jsc=space-between; g=16px; fts=14px; cl=$color.muted">
<span>© 2026 Acme Inc.</span>
<nav nib="d=flex; g=20px">
<a nib="cl=inherit; txd=none; hover:cl=$color.brand" href="/privacy">Privacy</a>
<a nib="cl=inherit; txd=none; hover:cl=$color.brand" href="/terms">Terms</a>
</nav>
</div>
</footer>Review#
- Recipes (
container,section,card,btn-*) carry identity; per-page rules carry position. - Tokens keep colours consistent, and dark mode is a handful of
dark:rules inside recipes. - No media queries were written by hand —
clamp(),auto-fitand a fewmd:rules did it.