The real problem

Ask three times, get three decks

Same prompt, no design system
Same prompt, design system in the repo

A deck isn’t eleven images. It’s one thing, seen eleven times — and drift is what makes an AI‑built deck feel cheap. Left alone, a model regresses to the mean of its training data: gradient hero, three cards, a stock icon. It’s fine. Fine is the problem.

Guidance, in English

The design system is a document, not a config file

excerpt · .claude/skills/presentation-slides/SKILL.md
Orange accent (#e73c17 dark / #bd3012 light) for emphasis, never overused.
Montserrat for all text, JetBrains Mono for code and data.
Subtle grid background at 60px intervals. Always support dark and light.
“Never overused” is not a number. It’s a judgement — and judgement is exactly what the model is good at. So write it in the language judgement comes in.

Anyone in this webinar can write this document about their own brand this afternoon. It is the brand guidelines you already have, addressed for the first time to a reader who will actually follow them. This is the takeaway even if you never write a line of HTML — a written design system is how you get consistent output from any agent, doing anything.

One rule, most of the value

Never measure against the window.
Measure against the slide.

WRONG — sized against the browser window
max-height: calc(100vh - 320px); /* guesses the chrome height */
On a tall window the slide’s content runs off the bottom of the stage. No scrollbar appears. You find out on the projector.
RIGHT — sized against the 16:9 stage
max-height: 70cqb; /* 70% of the slide's height */
Every deck is a fixed 16:9 stage, letterboxed to fit whatever it’s shown on. Design once; it looks the same everywhere.

cqb means 1% of the slide’s height. That is the whole explanation, and it is the single highest‑value rule in the system: it fixes the failure everyone in this webinar has watched happen live — content sliding off the bottom edge on a projector with the wrong aspect ratio.

Keeping it honest

Written rules get followed most of the time

.claude/settings.json
"PostToolUse": [{ "matcher": "Write|Edit|MultiEdit", "hooks": [{ "type": "command", "command": "node scripts/lint-slides.mjs" }] }]
what the agent sees
$ node lint-slides.mjs Slide stage-safe sizing violations: 02-teaching-taste.html:214 rule: calc-with-viewport line: max-height:calc(100vh - 320px) fix: calc() with viewport units double-counts chrome the stage already excludes. Use cqb. 1 violation(s). exit 2 … agent reads this, fixes it, retries ✓ clean

Most of the time isn’t good enough when the failure is invisible until you’re on stage. So the mechanical half gets enforced in code: the script scans every <style> block, the hook runs it after every edit the agent makes, non‑zero exit, the agent fixes its own mistake. No human in that loop. It only inspects the new text, so a legacy violation elsewhere doesn’t block today’s work.

Take this bit with you

Where to draw the line

Prose for taste
Anything needing judgement. “Never overused.” “One idea per slide.” Write it the way you’d brief a designer.
Linter for physics
Anything mechanical and checkable. Forbidden units. Missing alt text. Contrast ratios. Fail loudly.

Nothing in this split is about slides. Every agent workflow you build should be cut along the same line — and the failure mode to watch for is trying to write taste as a rule, or trusting prose to enforce physics.

1 / 1