Framed hero
The critique gate
The design system that audits itself.
Eighty-five tokens. Sixteen machine rules. The gate reads the DOM you ship and exits with the reason.
Design intelligence for the agentic era
d-pill is the discipline layer for interfaces built by anyone — or anything. Tokens carry the decisions, laws carry the judgment, and a sixteen-rule gate reads the real files and says what to fix.
A snippet teaches the page nothing. Tomorrow's page starts from zero, and the year's work argues with itself in a hundred small ways — a radius here, a hover there, a duration everywhere.
One hue, one space scale, one clock. The two-hundredth page agrees with the first because the decisions live in variables, not in each file's mood. Change the hue once; everything follows.
Taste decides, machines verify. Sixteen rules read the real files — the scales, the contrast floors, the names on the controls — and exit 2 hands the agent a reason to react.
The gate
This is the engine agents run — here it runs in your browser. The same sixteen rules, the same severities, the same exit codes the hook contract uses. Warnings are judgment calls to read, not ignore.
An AI-built landing page by feel. Fourteen findings, every one a teachable decision.
How to read it
Errors are decisions the page made without the system — a 300ms hover, a 17px padding, a control nobody named. Warnings are judgment calls: read them, then either fix or write the exception down.
Every finding carries its fix and the reference file behind the rule. Load a sample and run it.
The blocks
Pure HTML and CSS on the token system — no animation library, no runtime. Turn the hue dial in the token explorer and every block re-tints. Copy what you saw: the preview and the payload are the same string.
66 of 66 blocks · 11 categories · 0 animation dependencies
The critique gate
Eighty-five tokens. Sixteen machine rules. The gate reads the DOM you ship and exits with the reason.
The gate
The engine reads the rendered DOM, names the file, the line, and the rule, then hands you the fix.
Both themes. One file.
Every value sits on a scale. Every color wears a role. Change one variable and the whole site re-tints.
Start with the tokensMachine contract
The gate runs where the work happens — hook, MCP, or CI. Findings arrive with a fix and the law behind them.
$ python3 scripts/critique.py hero.html
hero.html:18:9 [space] 14px in padding is not on the scale
hero.html:24:2 [duration] 300ms in transition is not on the scale
1 file checked — 2 error(s), 0 warning(s); exit 2
Change --hue and 85 tokens re-tint. Light and dark move in lockstep.
The gate reads rendered CSS and prints file, line, and fix. No config to write.
One stylesheet serves light and dark. Contrast floors are checked, not hoped for.
Every edge is 1px. Emphasis comes from color and space, never thickness.
Space, type, radius, duration — a named ramp for each. Off-scale does not ship.
Fifteen color jobs and one hue variable. No literal survives review.
Taste arguments end at the exit code. Zero passes. Anything else is a finding.
Drift
0errors on the page you are reading. The gate ran first.
The values come from a file the gate reads. Drift is a build failure, not a debate.
— references/tokens.json, the single source
Space scale
4 to 32px shown. The ramp runs to 128.
Durations
One JSON export is the source of truth. The gate reads it, so the docs cannot lie.
tokens.jsonSixteen checks, each with a fix and a reference attached. Findings teach.
rules.jsonExit 0 is clean. Exit 2 is findings. Exit 1 is your invocation. Hooks and CI speak it natively.
machines.mdThis page audits its own DOM. The number in the corner is live, not a promise.
the demoToken math
The numbers are the product. Count them in the source.
Run the gate on src/app/page.tsx and tell me what fails.
Two findings. Line 41 pads with 14px — off the space scale; --space-3 is the 12px you meant. Line 88 writes 300ms beside var(--ease-out); --dur-3 is the 240ms you meant. The rest of the page is clean.
Tool call
critique src/app/page.tsx
Fixes staged — one line each, no new tokens.
Run
Read
↑↓ move · ↵ run · esc close
The gate reads markup the way a browser does —
every value against its scale, every control
against its name. Nothing ships unche
generating…
Open source — no account needed. Install the skill instead.
| File | Rule | Severity | Line |
|---|---|---|---|
| src/app/page.tsx | space-off-scale | error | 41 |
| src/app/page.tsx | duration-off-scale | warn | 88 |
| src/components/nav.tsx | control-no-name | error | 17 |
| src/components/nav.tsx | hover-no-focus | warn | 23 |
Four findings — two errors, two warnings. Exit 2.
This file has not met the gate. Run it once — every finding arrives with its fix attached.
Reading the file — findings next.
Open
$0/mo
Chosen
Gate
$12/mo
Studio
$49/mo
One honest line: the /mo buys the hosted gate and runner minutes. The tokens, the laws, the engine — one payment of zero. MIT, forever.
“The gate rejected our first hero. It was right.”
“Tokens stopped being a wiki page. Now they are a contract.”
“No taste debates. Exit codes. We ship.”
One skill. Sixteen machine rules. Every page leaves with an exit code.
Shipped under the gate
Raster
One radial-gradient draws the field at a var(--space-4) pitch. The mask thins it toward the edges, so the center stays readable in both themes.
radial-gradient · mask-imageGraph paper
Two 1px gradients draw the squares at a var(--space-6) pitch. A radial mask quiets the field before it reaches the frame.
Night panel
Three diagonal streaks, each loop a calc() of --dur-3 and each delay staggered the same way. Reduced motion stops them cold.
Planes
Translucent oklch panes drift past each other, every loop a calc() of --dur-3. Edges stay hairlines; the skew stays quiet.
Grain
An inline feTurbulence filter paints the grain. No image request, no asset to version, nothing to alt-text.
Beams
Vertical accent washes pulsing on a slow loop. Each delay is a calc() of --dur-3; reduced motion holds them still.
Aurora
Blurred oklch strips tied to var(--hue), each swaying at its own calc() of the duration scale. Nothing here is a literal.
Mesh
Each circle is oklch with var(--hue) and its own lightness. The card floats on var(--surface) with the one shadow the system allows.
Read the laws behind itSpotlight
A radial accent wash behind the headline; the vignette tints toward var(--line), so the edges recede in both themes.
Horizon
Four spans, one keyframe, delays counted in 180ms multiples. Every value is a token the gate can read.
Ink at rest, one accent pass on a loop. The highlight is a gradient clipped to the glyphs — background-position does the sweeping, nothing else moves.
0 error(s), 0 warning(s) — exit 0
The references, on a belt
Pauses for hover and for keyboard focus. Both halves of the belt are the same eight files, so the loop has no seam.
Continuous
One registered angle spins a conic gradient, masked to a one-pixel ring. The border underneath never leaves — no angle support, no drama, just the hairline.
critique --watch · exit 0
Scale and opacity carry the pulse — no glow shadow, one hue variable. This page re-audits itself while the orb breathes.
Drawn, not decorated
A hairline at rest; the accent line redraws on entry and exits the far side. One transform, one duration token.
syncing · references/tokens.json
One hairline ring, one satellite, three dur-3 tokens per lap. Reduced motion parks the orbit in a single frame.
::backdrop carries the same scrim, so showModal needs no second rule.
Scrim at 20, sheet at 40 — the z scale declares the stack.
Row actions
Hover or tab — the tip follows focus, not the pointer.
File actions
One element, no script — the toggle is native, the panel follows the summary.
Live findings
Gate passed — 0 errors, 0 warnings.
18:41:072 errors blocked the run.
18:41:12Tokens re-exported — 85 total.
18:41:15Severity on the left, the clock on the right — both tabular.
One bar counts files; the sweep keeps time without inventing numbers.
Reading the changelog — space is reserved, nothing shifts when text lands.
Six digits from the terminal — they expire with the session.
Questions
On your files. The CLI walks the repo, the site runs the same engine on its own DOM, and both exit with the same codes.
The build stops. Exit 2, the finding, the fix, and the file to read. Taste is never the reason.
Move one variable. --hue turns every role in oklch, light and dark, marks included. No palette to maintain.
The tokens, the laws, and the engine are MIT, forever. The hosted runner is optional, billed per month, not per seat.
Contact
How it works
One command lands the tokens, the laws, and the gate in your repo.
You write HTML and CSS. The roles and the scales make the decisions.
Every push is critiqued. Exit 0 merges; exit 2 teaches.
No build step, no runtime, no style props. The gate reads what the browser reads.
People
Rowan Vale
Tokens
Wrote the scales you import.
Ines Kaur
Engine
Keeps two engines agreeing.
Dana Okafor
Docs
Turns findings into reading.
Milo Park
Gate
Owns exit code 2.
Timeline
Findings teach. Every one carries its fix and the file behind the rule.
Tokens speak DTCG. Design tools read the export directly, no bridge.
Strict mode reaches CI. Warnings stop merges too.
Sixteen rules, one exit code. The gate ships.
Changelog
Findings teach. Every finding now carries its fix and the reference file behind the rule.
Added
Fixed
Tokens speak DTCG. The export is the contract, kept in sync by a check.
Added
Fixed
Compare
| Capability | Free | Pro | Team |
|---|---|---|---|
| Tokens, laws, engine | |||
| CLI gate, local runs | |||
| Hosted runner minutes | |||
| Private rule packs | |||
| CI enforcement on push | |||
| Fix queue, humans on it |
Pro buys the hosted gate and runner minutes. The tokens stay MIT, forever.
Integrations
Six doors into the same gate. Exit codes everywhere, prose nowhere.
Tokens
Every color on this page is oklch carrying the same hue angle. Move the dial and both themes re-tint live — accents, edges, shadows — with no reload and no second palette. Click a card to copy its custom-property name; the values are the machine export, not a picture of it.
Light group
Compound
Three entries are compounds, not single colors — a hairline edge, its heavier sibling, a shadow with distance. They ship whole and ride the hue with everything else.
Contrast, light theme
Computed from the token export at the default hue 215.
| Pair | Ratio | Verdict |
|---|---|---|
| --ink / --bg | 14.39:1 | pass |
| --ink-muted / --bg | 6.80:1 | pass |
| --ink / --surface | 14.79:1 | pass |
| --accent-ink / --accent | 5.95:1 | pass |
| --ink / --accent-soft | 12.66:1 | pass |
The laws
Install
A skill, a plugin, an Action, an MCP server — the same laws and the same gate on every path. The exit-2 hook contract means the agent receives the findings as the reason to react, not as decoration.
Agent skill
Installs into ~/.agents/skills — Claude Code, Codex, Cursor, Cline, Warp, Zed. The agent reads the laws before it writes the interface, then runs the gate before it calls the work done.
npx skills add srivtx/d-pill
Claude plugin
A plugin marketplace entry for Claude Code: the skill, the scripts, and the gate wired as a plugin you can update in place.
/plugin marketplace add srivtx/dpill /plugin install d-pill@d-pill
GitHub Action
Every push and pull request gets the critique. Exit 2 blocks the merge with file:line:col findings — the agent reads them and reacts.
- uses: srivtx/d-pill@v1
with:
paths: src/**/*.htmlMCP server
A stdio MCP server exposing critique, list_rules, and token. Your editor or agent calls the gate like any other tool.
{
"mcpServers": {
"d-pill": {
"command": "python3",
"args": ["path/to/mcp-server.py"]
}
}
}