The GRAIN design system
One interface. A person and an AI operate it through the same controls.
A human click and an AI decision become the same intent, flow through one door, and come back as visible edits. The AI's presence is shown, never hidden: grain is the signature of a machine at work.
Every surface on this page is one of GRAIN's own components. Open the Catalog tab, then hover anything (or tap it on a touch screen) to reveal its entry.
Grade as signal
One rule reads instantly and everywhere: grain type means the AI is acting or a value is in transit; clean type means a human wrote it or it has committed. Same words, two typefaces, no badges to learn.
a personDraft the Thursday plan.
the AIDraft the Thursday plan.
Two hands, one thread
You (clean) and the AI (grain) in one conversation: the AI's line stays grain; provenance never evaporates into looking human.
Your optimistic action settles
- Archive last week's notesarchived
Archiving is your action: grain while in-transit, then clean once it commits. AI speech, by contrast, stays grain; only your committed data reads clean.
One surface, both operators desk offline: live demo unavailable
A real GRAIN composition, operated through the one door. Ask it something yourself, or watch the AI act: both use the same GRAIN door and dispatcher. On this static site, the browser client door keeps each action in your tab; bun run dev:stub shows the server door, which posts to /intent and streams operations over SSE. There is no privileged AI → DOM path; the same page powers this demo.
- Draft the Q3 plan active
- Review the design thread done
How it worksAI interface
The whole system is one closed vocabulary of verbs and surfaces (contract.ts). A human click and an AI decision are the same Intent; both flow through one door and return as RenderOps pushed over SSE. There is no privileged AI → DOM back channel.
- One vocabulary. Verbs and surfaces live in a single registry, referenced, never re-typed as strings.
- A manifest the AI reads. Each screen has a drift-proof, machine-readable map of what's operable, harvested from the components, so the AI is shown the page, not told about it. Read how the interface works.
- Self-documenting. Every component auto-appears in a live component catalog: the design system browses itself.
- Auditable by design. Every interaction, human or AI, is one source-tagged Intent through one server-side door, so a full human + AI interaction log is a server-side drop-in.
- Two door transports, one contract. On the live server the door is POST /intent; on a static host this page opts into the client-side door: the same vocabulary and the same ops, run in your browser with no backend. The client door is deliberately fenced: everything it loads is client-safe by contract, static-style modules only, no secrets or tokens, nothing that needs a server. Anything that does need one (real data, a real model) stays behind the server door and is simply absent here.
- No build step. Server-rendered hypermedia on BATCH: Bun, TypeScript, CSS, htmx. Ship the source.
Themes
Every theme is a pure token override: one signature accent hue, no component edits (the topbar ◆ toggle cycles these site-wide too). Pick one:
Sourdough
Warm monochrome e-ink: the default, hueless.
Baguette
Clean and crisp: near-white light, near-black dark, a soft-blue accent.
Brioche
Warm cream and honey-gold: the cozy one.
AccessibilityThe audit
GRAIN's components and all three themes meet WCAG 2.2 AA, and that gets checked on every change rather than assumed. This site is built on GRAIN, and an automated scan of every one of its pages, in light and in dark, passes with zero violations.
- Built in, so you inherit it. Every text color clears 4.5:1, every control is at least 24px, every focusable thing draws a ring, and anything that scrolls can be scrolled from a keyboard, on any page that loads GRAIN.
- Tested, not certified. A scanner covers part of WCAG. Nobody has walked these pages with a screen reader yet, and that is the next pass.
- Your half stays yours. GRAIN can promise its components. Your alt text, your headings and your link wording are still your job, and the same scan will check them.