Building a Design System
Chapter objectives
- Generate an accessible palette with clear roles
- Define a typographic and spacing scale
- Get reusable tokens in CSS
Why a system, not pages
The classic beginner mistake — human or AI-assisted — is designing pages one by one. The homepage is pretty, the pricing page is pretty, but put side by side, they don't seem to belong to the same product: the blues differ slightly, the spacing changes, the buttons don't share the same corner radius. The result looks amateur, even if each isolated page is well done.
Good design isn't an accumulation of pretty pages, it's a coherent system: a small set of decisions (colors, typefaces, spacing, radii, shadows) made once and reused everywhere. Consistency has a measurable psychological effect: it inspires trust. The user senses — without being able to verbalize it — that a consistent product is a careful product, and therefore a reliable one. For a meditation app asking for a subscription, that trust is literally money.
With AI, the system becomes even more crucial: every new conversation starts from zero. If you don't provide your visual decisions, the model will improvise different values with each generation. The design system is your external memory: you paste it at the start of every prompt, and all the generated screens speak the same language.
Design tokens: the grammar of your interface
Concretely, a design system starts with design tokens: named variables that carry each visual decision. Instead of writing #4A7C6F in forty places, you define --color-primary: #4A7C6F once and reference the variable everywhere. The day the client wants a deeper green, you change one line and the whole interface follows.
Tokens typically cover five families: colors, typography (families, sizes, weights, line heights), spacing, border radii and shadows. In CSS, all of this fits in a :root block of about fifty lines. That block is what you'll ask the AI to generate — and then re-inject into every prompt of the project.
:root {
/* Colors — roles, not hues */
--color-primary: #4A7C6F; /* sage green: primary actions */
--color-primary-hover: #3D685D;
--color-accent: #E8A87C; /* soft peach: occasional highlights */
--color-surface: #FAF8F5; /* warm cream background */
--color-surface-raised: #FFFFFF;
--color-text: #2D3A36; /* 11.2:1 contrast on surface */
--color-text-muted: #5C6B66; /* 5.1:1 contrast — AA ok */
--color-success: #4A7C5F;
--color-error: #B5544D;
/* Typography — 1.25 scale (major third) */
--font-heading: "Fraunces", Georgia, serif;
--font-body: "Inter", system-ui, sans-serif;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.25rem;
--text-xl: 1.563rem;
--text-2xl: 1.953rem;
--text-3xl: 2.441rem;
--text-4xl: 3.052rem;
--leading-tight: 1.2;
--leading-body: 1.6;
/* Spacing — 4px base */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-6: 24px;
--space-8: 32px;
--space-12: 48px;
--space-16: 64px;
--space-24: 96px;
/* Radii and shadows */
--radius-sm: 6px;
--radius-md: 12px;
--radius-lg: 20px;
--shadow-soft: 0 2px 12px rgba(45, 58, 54, 0.06);
--shadow-raised: 0 8px 28px rgba(45, 58, 54, 0.10);
}Colors: roles, not hues
Notice how the color tokens above are named: primary, surface, text-muted — functional roles, never hues (--green-1, --beige). The nuance is crucial. A role describes the use: "the color of primary actions", "the background of raised cards". If you change palettes, the names stay valid. And above all, the AI understands roles: "use --color-accent only for occasional highlights" is an instruction it will respect screen after screen.
On the composition side, the empirical 60-30-10 rule remains an excellent guardrail: roughly 60% of the screen in surface color, 30% in text and structure colors, and only 10% for the accent color. That dosage is what makes an accent punchy — a color used everywhere no longer accents anything. The "generic AI" look often saturates the screen with color; your system, by contrast, enforces restraint.
Create a design system for a meditation app, calm and premium mood (brief: generosity of space, soft color palette, crisp typography):
- 8 colors with functional roles (primary, primary-hover, accent, surface, surface-raised, text, text-muted, error) as CSS variables
- accessible contrast: AA minimum for all text, give the ratio of each text/background combination
- typographic scale at a 1.25 ratio, from small to h1, with line heights
- spacing scale on a 4px base (4 → 96)
- 3 border radii and 2 subtle shadows
Deliver it all in a commented :root { } CSS block, then explain the color choices in 3 sentences.Contrast and accessibility: non-negotiable
Let's talk about the topic that the "pretty" render too often makes people forget: accessibility. The contrast between a text and its background is measured by a ratio ranging from 1:1 (invisible) to 21:1 (black on white). The WCAG define two thresholds: AA requires 4.5:1 for body text (3:1 for large headings), and AAA raises it to 7:1. AA is your absolute minimum — not a goal, a floor.
Why be uncompromising? First because roughly one person in twelve perceives certain colors poorly, and everyone reads their phone in direct sunlight someday. Second because "soft and calming" moods — precisely what our client is asking for — naturally push toward light grays on cream backgrounds that fall below the thresholds. A premium design that isn't legible isn't premium: it's a manufacturing defect. Systematically ask the AI to give the contrast ratios of each text/background combination, and have the edge cases checked.
Typography: a scale, not random sizes
Typography alone carries half of the "premium" impression. Two decisions structure everything: the choice of families (one for headings, one for body text — rarely more than two) and the scale of sizes. Rather than picking each size by feel, you derive all sizes from a constant ratio: each level is 1.25 times larger than the previous one, for example. That ratio creates a mathematical harmony the eye perceives without understanding it — exactly like intervals in music.
A moderate ratio (1.2 – 1.25) gives a gentle hierarchy, suited to dense interfaces; a strong ratio (1.333 – 1.5) creates spectacular headings, perfect for a landing page where the hero must command attention. For Sereno, a 1.25 with an elegant serif for headings (warmth, humanity) and a neutral sans-serif for body (legibility) translates "calm premium" well. Don't forget line heights: 1.5 to 1.6 for body text, tighter (1.1 – 1.2) for large headings, otherwise they float.
Spacing: the invisible rhythm
Spacing is the most invisible and most decisive parameter of an interface. A page "that breathes" and a page "that's cramped" often use the same components — only the spaces differ. The principle: a fixed scale on a 4px base (4, 8, 12, 16, 24, 32, 48, 64, 96) that you never leave. No 17px or 23px margins: every space is a multiple chosen from the scale.
This constraint produces vertical rhythm: the regularity of intervals creates an invisible grid that calms the eye. It also exploits the law of proximity: nearby elements are perceived as related, distant elements as distinct. A heading must therefore be closer to the paragraph it introduces than to the section it closes — a simple rule, violated by half the web. Finally, be generous between sections: 96px of gap on desktop isn't emptiness, it's punctuation. The generic crams; the premium breathes.
From token to screens: keeping the system alive
Once your tokens are defined, the system follows an irrigation logic: tokens feed components (buttons, cards, form fields), and components assemble into screens. With each new generation, explicitly ask the AI to reuse the existing variables rather than inventing values: "use exclusively the provided tokens; if a need isn't covered, propose a new token instead of a hard-coded value".
flowchart TD T["Tokens: colors + type + spacing"] --> CP["Components: buttons, cards, forms"] CP --> E1["Landing page"] CP --> E2["Pricing page"] CP --> E3["Next screens"]
That last instruction — propose a token rather than a hard-coded value — is precious: it grows your system in a controlled way. As the project progresses, you'll see needs emerge that the initial version didn't cover (a border color, an intermediate spacing). Every addition passes through you, gets named, documented, and joins the reference file. The system remains the single source of truth.
Context
Studio Mango must lay Sereno's visual foundation before designing a single screen. The client's developer will integrate the code after you: if your values are inconsistent or inaccessible, he's the one who'll pay the price — and the studio will lose the phase 2 contract. You have one hour to deliver a clean, verified, documented token file.
Instructions
- Take your art direction brief from chapter 1 and paste it at the top of the prompt.
- Ask for a complete design system: 8 colors with roles, a typographic scale at a 1.25 ratio, spacing on a 4px base, radii and shadows.
- Demand the numerical contrast ratios for each text/background combination, and check that everything passes AA (4.5:1 body text).
- Have any combination below the threshold fixed — especially muted text on colored backgrounds.
- Save the final :root block in a reference file (tokens.css) with one comment line per key decision.
- Ask for a variant with a bolder accent, compare the two side by side and choose with justification.
- Final test: ask the AI to generate a simple testimonial card using exclusively your tokens, and check that no hard-coded value slipped into the code.
In summary
- A design system is a small set of decisions reused everywhere — consistency inspires trust, and trust converts.
- Design tokens (named CSS variables) are the project's external memory: re-inject them into every prompt.
- Name colors by functional role (primary, surface, text-muted), never by hue.
- The 60-30-10 rule doses surface, structure and accent: an accent everywhere no longer accents anything.
- Demand AA-minimum accessible contrast (4.5:1) with numerical ratios — soft palettes often fail.
- Derive type sizes from a constant ratio (1.25 for a gentle hierarchy, 1.333+ for spectacular headings).
- Spacing on a 4px base creates vertical rhythm; generosity between sections makes the premium.
- Grow the system in a controlled way: every new need becomes a named token, never a hard-coded value.
Quiz — check your understanding
1. What makes a good design?
2. How should color tokens be named?
3. What contrast level should you target at minimum for body text?
4. What is a constant typographic ratio (e.g. 1.25) for?
5. What should you ask the AI when a need isn't covered by the existing tokens?
6. What does the 60-30-10 rule say?