← All skills
Productionv1.0.0 · 2026-08-07
Design System Spec
A brand has colours and a logo. A design system tells you what size the body text is, which colour pairs are legal to put together, and how far apart two things sit. Without it, every page is decided from scratch and no two look related.
What it does
- Set the type scale
- Check the palette before committing to it
- Set the spacing scale
- Set the breakpoints
- Specify the components
- Write it down
SKILL.md
--- name: design-system-spec description: Turn a brand into a usable website design system — type scale, colour palette with checked contrast, spacing scale, breakpoints and component specs. Use when asked to design a website, create a design system or style guide, pick fonts and colours for a site, check colour contrast or accessibility of a palette, set typography or spacing standards, set up brand guidelines for web, hand a developer a visual spec, or someone says 'every page we make looks different'. For the copy that fills the system, see landing-page-copy. For auditing a built page against it, see design-review. metadata: version: 1.0.0 --- # Design system spec A brand has colours and a logo. A **design system** tells you what size the body text is, which colour pairs are legal to put together, and how far apart two things sit. Without it, every page is decided from scratch and no two look related. This produces a written spec a developer or designer builds from. It does not produce a website. The whole job in one line: **decide once, apply everywhere.** ## Before you start | Input | Why | | --- | --- | | Brand colours as hex codes | Step 2 checks which pairs are legible. Names like "our blue" cannot be checked | | Brand fonts, or a decision to pick some | Step 1 needs a body font before it can set a scale | | The logo file and where it sits | Header spec | | What the site is for — content-heavy, marketing, dashboard | Drives the type ratio in step 1 | If you have brand colours but not as hex, get the hex first. Everything in step 2 is arithmetic on those values. ## Step 1 — Set the type scale ```bash python3 scripts/type_scale.py --base 16 --ratio major-third python3 scripts/type_scale.py --ratio 1.333 --css # emit CSS variables ``` A modular scale multiplies each step by a fixed ratio, so sizes relate to one another instead of being picked one at a time. That relationship is most of what makes a page look designed. | Site type | Ratio | Why | | --- | --- | --- | | Dashboard, dense UI | 1.125–1.2 | Many levels, little room | | Content-heavy, blog | 1.2–1.25 | Comfortable hierarchy that survives long pages | | Marketing, landing pages | 1.333–1.5 | Fewer levels, bigger statements | **Body copy is 16px minimum.** Below that, iOS Safari zooms the page when someone focuses an input, and long-form reading gets tiring. The script warns you. Line length matters as much as size: **45–75 characters** per line, around 66 ideal. Set a `max-width` on text containers, not just a font size. ## Step 2 — Check the palette before committing to it ```bash python3 scripts/contrast.py "#E1306C" "#ffffff" python3 scripts/contrast.py --palette brand.txt --min 4.5 ``` Do not eyeball this. Contrast is a defined ratio and the script computes exactly what an auditor's tool will report. | Requirement | Ratio | WCAG | | --- | --- | --- | | Body text | **4.5:1** | SC 1.4.3, Level AA | | Large text — 24px+, or 18.5px+ bold | **3:1** | SC 1.4.3, Level AA | | Icons, borders, form outlines, focus rings | **3:1** | SC 1.4.11, Level AA | | Body text, enhanced | 7:1 | SC 1.4.6, Level AAA | Expect some brand colours to fail. That is normal and it is not a reason to ignore the number — it is a reason to define a **text-safe variant**. A worked example using a real brand palette is in [references/palette-worked-example.md](references/palette-worked-example.md). Record for every colour: its hex, what it may be used for, and its checked ratio against your background. ## Step 3 — Set the spacing scale An **8px base grid**: 8, 16, 24, 32, 40, 48, 56, 64. Use 4px only for fine adjustments inside components. Every margin and padding in the spec comes from this list. "Whatever looks right" is what produces pages where nothing lines up. ## Step 4 — Set the breakpoints Three is usually enough: | Name | Width | Represents | | --- | --- | --- | | Mobile | base, no media query | Design here first | | Tablet | 768px | Two columns become possible | | Desktop | 1024px | Full layout | | Wide (optional) | 1280px | Cap the content width, do not keep stretching | **Design mobile first.** It is far easier to add space than to remove it, and most traffic to a marketing site is mobile. Breakpoints should follow your content, not device names. If your layout breaks at 900px, put a breakpoint at 900px. ## Step 5 — Specify the components For each one, state the resting look, the states, and the size. Minimum set: button (primary, secondary), link, form input, card, header, footer. **Every interactive element needs four states**: rest, hover, focus, disabled. The one people skip is **focus** — that is how keyboard users see where they are, and its outline needs 3:1 contrast against the background. **Touch targets: 24×24 CSS px minimum** (WCAG 2.2 SC 2.5.8, Level AA). Aim for **44×44** on anything important (SC 2.5.5, Level AAA) — it is the difference between a button people hit and one they miss. ## Step 6 — Write it down Produce the spec as a single document. A design system that lives in someone's head is not a design system. ## Output ``` # Design system: <brand> ## Type Font: <body font> / <heading font> Base: 16px Ratio: 1.25 (major third) | Step | px | rem | line-height | Use for | Max line length: <n>ch ## Colour | Name | Hex | Ratio on <bg> | Usable for | Text-safe variants: <where a brand colour failed and what replaces it> ## Spacing 8px grid: 8 / 16 / 24 / 32 / 40 / 48 / 56 / 64 ## Breakpoints mobile (base) / tablet 768px / desktop 1024px ## Components ### Button (primary) Rest / Hover / Focus / Disabled — with hex, size, radius, padding Min target: 44x44 ## Known limits <Any brand colour that cannot be used for text, and what to use instead.> ``` ## When it breaks | What you see | What it means | The fix | | --- | --- | --- | | A brand colour fails 4.5:1 | The brand was designed for print or logos, not body text | Define a darker text-safe variant. Keep the original for large text and graphics | | Every pair in the palette fails | The palette is all mid-tones with no light/dark anchors | Add a near-black and a near-white. Most palettes need both | | Body text set below 16px | Density was chosen over readability | Raise to 16px. iOS zooms on input focus below it | | Headings look almost the same size | The ratio is too small for the number of levels | Raise the ratio, or cut a heading level | | Top heading is enormous next to body | Ratio too large across too many steps | Lower the ratio, or drop the top step | | Layout looks cramped or arbitrary | Spacing picked per element instead of from the scale | Every value comes from the 8px grid | | Keyboard users get lost | Focus states were never specified | Add a visible focus ring at 3:1 contrast to every interactive element | | Buttons hard to tap on mobile | Targets under 24×24 CSS px | 24×24 is the AA floor; use 44×44 for anything important | | Developer keeps asking "what about…" | The spec covers only the happy path | Specify all four states for every component | If brand colours are not available as hex, stop and get them. Guessing a hex from a screenshot produces a spec that does not match the brand. ## Rules - **Check contrast, never estimate it.** It is a computed ratio; a guess that looks fine to you can fail for someone with low vision. - **A failing brand colour gets a text-safe variant, not an exception.** "It's our brand colour" does not make 3:1 text readable. - **16px body minimum.** No exceptions for "design reasons". - **Every interactive element specifies all four states.** Skipping focus locks out keyboard users entirely. - **Design mobile first.** Adding space is easy; removing it is a rebuild. - **Every spacing value comes from the scale.** One arbitrary value invites fifty. - This skill produces a **written spec**, not a built site. It does not cover animation, illustration style, or print. Its standards are external — see `SOURCES.md`. ## Related skills - **design-review** — audits built pages against this spec's standards. - **landing-page-copy** — the words this system sets; copy and system ship together. - **static-ad-builder** — ad-format assembly under the same brand-lock idea. - **ai-image-generation-rules** — generated imagery obeys this system's lock too.
Reviews
Sign in to leave a review.
