Recipes
Copy-paste compositions of components, tokens, and mixins for the patterns you build most.
Settings form
Stack FormField wrappers around Input and Checkbox controls; close with a primary Button. The labels, hints, and error ids are wired automatically.
<FormField label="Email" hint="We only use this for sign-in."> <Input type="email" placeholder="you@studio.com" /> </FormField> <FormField label="Password"> <Input type="password" /> </FormField> <Checkbox label="Remember me on this device" /> <Button variant="primary">Sign in</Button>
Form spacing uses --space-md between controls. Swap themes and the input chrome, focus ring, and checkmark follow.
Pricing card grid
A responsive three-tier pricing grid using Card with bodyAs="none" so each card can hold a price, feature list, and call-to-action.
Starter
$0 /mo
- 1 project
- Community support
- Public themes
Studio
$24 /mo
- Unlimited projects
- Priority email
- Private themes
Atelier
$96 /mo
- Team seats
- Design review calls
- Custom brand kit
<div style={{ display: "grid", gap: "var(--space-md)", gridTemplateColumns: "repeat(auto-fit,minmax(240px,1fr))" }}> <Card title="Starter" bodyAs="none"> /* price, feature list, button */ <Button variant="outline">Start free</Button> </Card> /* Studio, Atelier… */ </div>
auto-fit with minmax(240px,1fr) collapses the grid to one column on narrow viewports without a media query.
Hero section
Display-font headline, soft deck paragraph, and a paired button row. Every value pulls from tokens so the hero re-skins with the theme.
Paint the page with one stylesheet.
css-is-awesome is a mixin-first design system. Swap the theme link and the whole site re-skins — no markup changes, no rebuild.
<section style={{ padding: "var(--space-xl) var(--space-lg)", background: "var(--paper-raised)" }}> <h1 style={{ fontFamily: "var(--font-display)" }}> Paint the page with one stylesheet. </h1> <p style={{ color: "var(--ink-soft)" }}>Deck copy…</p> <Button variant="primary" href="/docs">Get started</Button> <Button variant="outline" href="/showcase">See examples</Button> </section>
Type scale uses --font-display; the soft deck colour pulls from --ink-soft. Spacing steps through --space-sm, --space-lg, and --space-xl.
Dashboard shell
A two-column app shell: sticky sidebar nav plus a main content region with a KPI row and a stack of cards. The grid collapses to one column on narrow viewports via auto-fit.
Recent activity
- Avery published the Sketchbook landing
- Jordan shipped the Brutalist theme
- Priya drafted the Recipes page
Upcoming
Design review on Friday covers the Icon authoring spec and the Token audit follow-ups.
<div style={{ display: "grid", gridTemplateColumns: "minmax(0, 200px) 1fr" }}> <nav aria-label="Dashboard"> <a href="#">Overview</a> /* more links… */ </nav> <main> <StatChip value="12,487" label="active users" /> <Card title="Recent activity">…</Card> </main> </div>
The active nav link uses --paper-sunk plus --ink to indicate state; inactive links fall back to --ink-soft.
Empty state
A focused empty-state panel centred inside a Card. Use it when a list is empty on first visit — a single primary action is enough.
No projects yet
Projects are where you collect themes, components, and copy. Start one and invite a teammate when you are ready.
<Card title="" bodyAs="none" style={{ textAlign: "center", padding: "var(--space-xl) var(--space-lg)" }}> <p style={{ fontFamily: "var(--font-display)" }}>No projects yet</p> <p style={{ color: "var(--ink-soft)" }}>Prose explanation…</p> <Button variant="primary">Create your first project</Button> </Card>
Notification / toast row
All four Alert status variants. Note that Alert uses status="…", not variant.
Theme saved
Heads up
Cache expiring
Publish failed
<Alert status="success" title="Theme saved">…</Alert> <Alert status="info" title="Heads up">…</Alert> <Alert status="warning" title="Cache expiring">…</Alert> <Alert status="error" title="Publish failed">…</Alert>
Data table
A small, sortable, hoverable DataTable. Click the Project or Updated header to toggle sort. Data is declared inline in the page — no fake API.
| Owner | Stage | ||
|---|---|---|---|
| Docs recipes | Priya Patel | draft | 2026-04-23 |
| Sketchbook landing | Avery Chen | shipped | 2026-04-21 |
| Brutalist theme | Jordan Ito | review | 2026-04-20 |
| Icon authoring | Mateo Silva | review | 2026-04-19 |
| Token audit | Sasha Kim | shipped | 2026-04-15 |
// columns declared once, reused across pages <DataTable data={projectRows} columns={projectColumns} rowKey={(r) => r.id} defaultSort={{ columnId: 'updated', direction: 'desc' }} hoverable />
DataTable is a client component under the hood — importing it from this server page works because Next.js inserts the client boundary automatically.
Tabs panel
A three-panel Tabs group. Switch tabs with a click or the arrow keys; only the active panel is mounted.
A short summary of the project: goals, scope, and status at a glance.
<Tabs defaultValue="overview"> <Tabs.List> <Tabs.Trigger value="overview">Overview</Tabs.Trigger> <Tabs.Trigger value="tokens">Tokens</Tabs.Trigger> <Tabs.Trigger value="changelog">Changelog</Tabs.Trigger> </Tabs.List> <Tabs.Panel value="overview">…</Tabs.Panel> /* more panels… */ </Tabs>
Modal trigger
Modal is portal-rendered and always client-side, so the preview below shows the trigger plus a static rendering of the dialog shell. The live interactive version is on the components gallery — this recipe is the copy-paste wiring.
Delete project?
This removes the project and all of its themes. You cannot undo this.
// in a client component const [open, setOpen] = useState(false); <Button variant="primary" onClick={() => setOpen(true)}> Open dialog </Button> <Modal open={open} onClose={() => setOpen(false)}> <Modal.Header>Delete project?</Modal.Header> <Modal.Body> This removes the project and all of its themes. </Modal.Body> <Modal.Footer> <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button> <Button variant="primary">Delete</Button> </Modal.Footer> </Modal>
Modal accepts open and onClose — state lives in the parent client component. Keyboard focus is trapped while the dialog is open and returned on close.