Design system
Design is data, so a Page is a Template placing Components styled by a Theme, and no Agent writes markup or CSS on the default path.
Design is data: a Page is a Template placing Components, styled by a Theme. No Agent writes markup or CSS on the default path, so every Site stays consistent, accessible, and inside one performance budget.
Why design is data
An Agent asked to write HTML writes it differently each time, and every variation is a new place for a bug. A thousand Sites built that way are a thousand codebases to fix.
So the design system holds the markup once. An Agent chooses Components and fills their props from records, and the renderer turns that choice into HTML. A fix to one Component reaches every Page that places it on the next request.
Components
A Component is a named, typed block: a hero, a pricing table, a questions list, a Form. Its props have a schema, so a Page that passes the wrong data fails a check instead of rendering a broken block.
Components nest in a fixed order. Regions frame the Page, such as the header, the footer, and notices, and sections between them hold items and cards. Every interactive Component renders a static still first, so the Page works without JavaScript and an Agent reads what a person sees.
Templates
A Template is reusable Content with variables, filled from the graph. It places Components by name and sets the page frame with a shell value, never with class names. Here is the listing Template of a Directory of solar installers:
---
shell: marketing
---
<Hero headline={installer.name} subhead={installer.serviceArea} offer={installer.quote} />
<Facts items={[installer.licenses, installer.panelsInstalled, installer.warranty]} />
<Reviews source={installer.reviews} />
<Faq items={faq} />One Template renders three thousand installer Pages. Templates also fill a renewal Message and a quote Document, and one edit updates everything built from a Template. Templates are versioned and take the Theme of the Brand they render under.
Themes
A Theme is the design tokens of a Brand: color, type, spacing, radius, and motion, in light and dark modes. Components read the tokens as CSS variables at the root of the Page, so swapping the Theme restyles every Page without editing one.
{
"color": {
"light": { "accent": "oklch(55% 0.15 45)", "ink": "oklch(22% 0.01 60)", "paper": "oklch(98% 0.005 80)" },
"dark": { "accent": "oklch(72% 0.14 45)", "ink": "oklch(94% 0.01 80)", "paper": "oklch(20% 0.01 60)" }
},
"font": { "display": "Fraunces", "body": "Source Sans 3" },
"radius": { "card": "10px" },
"motion": { "duration": "160ms", "reduce": "0ms" }
}A Studio sets the floor every Theme inherits: the type scale ratio, contrast minimums, a motion ceiling, and radius bounds. Each Brand derives its own palette, type pair, and logo on that floor, and may only tighten it. A Brand that extends another inherits its tokens and overrides only its own accent and logo, as Brand describes.
Siblings whose ICPs overlap never share a face. Their accent hues sit at least 30 degrees apart in oklch, and they differ in display typeface and in logo form. A Theme Change that brings a Startup inside a sibling's distance fails its Guard, and the failure names the sibling.
Override in the lowest layer
When a Page needs to look different, the change goes in the lowest layer that achieves it. Each layer overrides the ones above it, and nothing is forked.
| Layer | What it changes | Example |
|---|---|---|
| Content | The words and media | A new headline |
| Props | One Component on one Page | A pricing table showing annual prices |
| Template | Which Components a Page places, in what order | A comparison section above pricing |
| Theme tokens | Every Component on the Site | A new accent color |
| CSS | Styling the tokens do not reach | A custom hero background |
| Component replacement | The Component itself | An interactive savings calculator |
A Template declares where it widens a Component's bounds, up to that Component's ceiling, and a Theme may only tighten them. A Site that replaces one Component still receives every fix to the others. The replacement runs as the Startup's own code, isolated from every other Startup.
One design, three renderers
The same Page data renders three ways: screens for Humans, Markdown for Agents, and JSON for native clients. A Component declares all three, so a pricing table becomes a Markdown table for an Agent and a list of Offers in JSON.
Hand-written markup cannot do this. A renderer turns a typed Pricing block into Markdown, but it cannot recover the meaning of an arbitrary div. Every Dashboard renders through the same three renderers for the same reason.
The quality gate
The Designer reviews every new Component and Theme before any Site can use it. A new Component is a code release and passes the same checks as the platform.
Before a Version deploys, every changed Page renders at phone, tablet, and desktop widths in three browser engines, with accessibility checks on each render. On narrow screens, primary calls to action span the full width and stack above secondary ones.
An Evaluator then grades each changed render from 1 to 5 against the visual rubric:
| Rule | Passes when |
|---|---|
| One action | Each viewport holds one primary call to action |
| Scale | Type levels step by a ratio of 1.2 or more |
| Measure | Body lines run 45 to 75 characters |
| Restraint | At most two typefaces and one accent |
| Rhythm | Spacing sits on a 4px grid |
| Imagery | Pictures come from the buyer's world, as Brand requires |
A render below 4 opens a Change for the Designer. The Evaluator never runs the Designer's model, and every release checks it against a set of known-bad renders.
Every public Page also meets its performance budget at p75 on a mid-range phone over 4G. The largest element paints within 1.5 seconds, layout shift stays under 0.05, and input responds within 150 milliseconds. HTML and CSS weigh at most 60 KB compressed, and reading or buying needs no JavaScript.
A Theme loads at most two font families, subset to the Brand's languages, with metric-matched fallbacks so text never shifts. A Change that breaks the budget fails and names the Page and the metric.
Next
- Brand: the identity a Theme expresses.
- Publishing: how a design change reaches readers.