Opening
Nine interface elements that appear independent are connected by three shared tokens: an action colour, a control radius and a spacing step. When the radius changes, every connected element changes.
Design systems — a study by Victor Maragioglio
Nine interface elements. Apparently unrelated.Scroll — or press ▶ Present
What is a design system
The definition 'a design system is a collection of components' is struck out and replaced by a map of eighteen connected concerns across deciding, encoding, building and sustaining. Components are one node. The component library covers primitives, components, states and behaviours; the design system is everything.
A design system is a collection of components a network of decisions.
components
Primitives composed with behavior and state. One part of the system.
A component library is part of a design system.
It is not the system.
System stack
A seven-layer stack from brand to product experiences. Five forces — accessibility, content, platform, responsiveness and governance — cut across every layer and change each layer's artifact.
- 01Brandwho we areFieldnote
- 02Foundationscolour · type · gridAa 16/1.45grid 4
- 03Design tokensnamed decisionscolor.action.primary → vermilion.600
- 04Primitivessmallest partsAa
- 05Componentsparts + behaviour
- 06Patternscompositions with intent
- 07Product experienceswhat people useAccountBillingTeam
Each layer consumes the one above. Brand does not reach the product directly — it arrives as foundations, then tokens, then parts.
Design tokens
Primitive tokens hold raw values. Semantic tokens hold meaning and point at primitives. Component tokens point at semantic tokens. Switching to dark mode re-routes only the semantic-to-primitive links; component links do not change. Without the semantic layer, dark mode must be patched component by component, and text becomes unreadable.
Propagation
Seven unrelated interface fragments — navigation, form, table, dialog, date picker, button group and toast — all reference the same tokens. Changing color.action.primary, radius.control or space.base changes every consumer at once. The number of consumers is counted live.
Spacing system
A settings layout built only from spacing tokens. Changing the base rhythm from 4 to 8 pixels expands every gap and inset; at 2 pixels the layout collapses, but minimum target size still holds at 24 pixels.
Primitive to product
Five primitives compose into a button. The button is reused inside a toolbar, the toolbar inside an application header, and the header inside a product interface. Hovering any button highlights every instance.
- surface + text + icon + border + space
- →Button
- →Toolbar
- →Application header
- →Product interface
- Button instances0one definition
Components are state machines
One button moves through nine states — default, hover, focus, active, pressed, selected, disabled, loading and error — and six conditions that multiply them: long content, right-to-left, high contrast, reduced motion, touch input and keyboard focus. A component is not a picture; it is a state machine. At the end the button is live.
A component is not a picture.
It is a state machine.
- long content
- RTL
- high contrast
- reduced motion
- touch input
- keyboard focus
| background | color.action.primary |
|---|---|
| text | color.text.onAction |
| cursor | pointer |
Variants
One button multiplied by 3 sizes, 4 intents, 5 states, 2 themes and 2 densities becomes 240 combinations; across 3 platforms, 720. Nobody designs 720 buttons. They design 19 rules that produce them.
1 button × 3 sizes × 4 intents × 5 states × 2 themes × 2 density × 3 platforms
1 button
One button. One picture of it.
- size 3sm → height − 8, inset × .75 md → size.control.height lg → height + 8, inset × 1.25
- intent 4primary → color.action.* secondary → border.strong ghost → action.text, no fill danger → feedback.error
- state 5hover → *.hover focus → focus.ring disabled → surface.sunken loading → aria-busy, width held default
- theme 2light map dark map
- density 2comfortable × 1 compact × .84
- platform 3web 36 iOS 44 · radius 10 Android 40 · full radius
Entropy
One shared button is forked by six product teams. Over eighteen months each team makes small local changes. An audit finds 17 buttons, 12 action colours, 8 radii, 6 shadows and 4 focus behaviours. Without governance, systems drift. Shared tokens then consolidate them into one component with sanctioned variants and one documented exception.
Consistency ≠ sameness
Three products — a dense operations console, a touch consumer app and a dark editorial site — share tokens, primitives, interaction rules and accessibility logic, and still look different. Consistency is not sameness.
Consistency ≠
sameness
color.action.primary → vermilion.600 #C8370F
text 15.1:1 · action label 5.0:1
color.action.primary → moss.600 #2E6A3E
text 15.1:1 · action label 6.2:1
color.action.primary → ochre.300 #E2BF55
text 16.7:1 · action label 10.6:1
One meaning: the main action. Three brand values. The products share tokens, primitives, interaction rules and accessibility logic — not a look.
Themes and modes
A single interface resolves across four axes — brand, mode, density and platform — 36 configurations in all. Each step changes one axis and the whole interface resolves again.
System:
- brand
- A · Signal
- mode
- LIGHT
- density
- COMFORTABLE
- platform
- WEB
One component set. Visited: 1.
Nothing in this interface knows which brand, mode, density or platform it is in.
Mutation over time
The whole page mutates through five versions of its own design system: v1.0 monochrome with 2px radius and 32px controls; v1.4 adds accessible focus states; v2.0 a brand redesign with no component API changes; v3.0 introduces a mobile platform where some primitives diverge; v4.0 a multi-brand architecture on one semantic layer. The page you have been reading is v4.0.
v1.0
One product, one team
Look at the page around you — the rail, the headings, the readout. The whole study is running v1.0.
- radius 2px
- spacing base 4px
- button height 32px
- monochrome brand
- focus: browser default
| initial release |
- v1.0One product, one team
- v1.4Accessibility requirements
- v2.0Brand redesign
- v3.0Mobile platform
- v4.0Multi-brand architecture
Deprecation
Button / Legacy is deprecated with eight consumers. An adapter and a replacement are introduced. Consumers migrate in batches across releases v3.2 to v4.3; two are blocked by a custom theme and by having no owning team. In v5.0 the legacy component and the adapter are removed. Systems cannot change instantly.
- Checkout
- Billing settings
- Admin / Users
- Search filters
- Onboarding
- Help center
- Internal tools
- Email preferences
kind="primary" small
→ intent="primary" size="sm"0 carriedButton / Legacy: 8 consumers. It works. That is the problem.
Systems cannot
change instantly.
Governance and contribution
Who decides? A promo-code field starts as a local need in one product team, repeats in two others, becomes a proposal, and passes through system review, accessibility validation, engineering and release before products adopt it. A one-off countdown button stays local. Each stage changes the component.
- 01local needCheckout team
- 02local componentCheckout team
- 03pattern repeats3 product teams
- 04proposalCheckout → System team
- 05system reviewSystem team
- 06accessibilityAccessibility
- 07engineeringEngineering
- 08releaseSystem
- 09adoptionProducts
“Apply a promo code without leaving the summary.”
- “Customers need to apply a promo code without leaving the order summary.”
- A real need. Not yet a system concern.
Accessibility as system logic
Accessibility is not a checklist at the end. High contrast resolves semantic colour tokens from a different map; reduced motion sets every motion duration to zero; larger targets raise the minimum target size. The switches apply to the whole study.
Not a checklist.
A constraint on every layer.
| concern | token | standard | standard |
|---|---|---|---|
| color | color.text.secondary | ink.500 · 5.3:1 | ink.500 · 5.3:1 |
| contrast | color.text.onAction / action.primary | vermilion.600 · 5.0:1 | vermilion.600 · 5.0:1 |
| focus | focus.ring.width · color.focus.ring | 2px vermilion.600 · 4.6:1 | 2px vermilion.600 · 4.6:1 |
| motion | motion.duration.base | 360ms | 360ms |
| states | color.text.disabled | disabled → ink.300, never opacity alone | disabled → ink.300, never opacity alone |
| targets | size.target.min | 24px | 24px |
| keyboard | rule | Tab order = DOM order; Esc closes; arrows move | — |
| content | rule | icon-only actions are named — 0 named controls on this page | — |
Scale
At 1, 3, 10 and 50 products, the number of possible pairwise coordination conversations grows from 0 to 3, 45 and 1,225. A system routes coordination through shared rules — 50 connections instead of 1,225 — but requires documentation, versioning, ownership, governance, migration and automation. Scale does not remove complexity; it organizes it.
- products
- 1
- possible pairwise conversations
- 0
- connections through the system
- 1
- decisions made in conversation
- one repo, one designer, one engineer
- a shared library
- a changelog
- naming conventions
- documentation people can find
- semantic versioning
- an owning team
- a contribution process
- release notes, office hours
- a governance forum
- a deprecation policy
- codemods and lint rules
- visual regression in CI
- adoption metrics
- a support rota
At one product, informal decisions work. The system is a habit.
System boundaries
Decisions sit inside or outside the system: system decisions, product decisions, brand decisions and local exceptions. Each decision can be moved across a boundary; each move has a consequence.
The system does not
own every decision.
Boundaries are not purity. They move — and every move changes who maintains what, and who is surprised by it.
- Focus ring behaviour
- Semantic colour tokens
- Button
- Data table density
- Date picker
- Checkout flow layout
- Onboarding sequence
- Wordmark and display type
- Campaign illustration
- Seasonal theme
- Kiosk font size
- Legacy print stylesheet
move any decision across a boundary
The placement above is one team’s current answer, not the right one.
The network
The whole study as one dependency network: 46 nodes and 137 edges from primitives through modes, tokens, components and patterns to products — including this page. Selecting a node shows what depends on it. Applying a breaking change shows the affected network and its migration cost.
Laboratory
A live laboratory. Change mode, density, radius, space base, type scale, brand or platform. Each change shows the token, what it resolves to, which components depend on it, and the resulting interface. The scope can be this specimen or the entire study.
01 · input
decision record · this session
- nothing yet
02 · resolution
space.base = 4
↓ resolves- space.1004px
- space.2008px
- space.30012px
- space.40016px
- space.60024px
- space.80032px
Button · Input · Menu · Dialog · Table · DatePicker · Tag · Nav
↓ result0 elements re-resolved in the specimen
03 · output
A record of decisions
The network simplifies into a single line: a record. Systems do not remove change; they make change manageable. A design system is a record of decisions. A study by Victor Maragioglio.
Every decision in this study, at once. Now let it resolve.
Systems do not remove change.
They make change manageable.
A design system
is a record
of decisions.
- v1.0 radius.control = 2px · space.base = 4px
- v1.4 focus.ring = 2px, offset 2px
- v2.0 color.action.primary → vermilion
- v3.0 size.control.height.ios = 44
- v3.2 Button / Legacy deprecated
- v4.0 semantic layer shared across 3 brands
- v4.4 Field gains an action slot
- v5.0 Button / Legacy removed
- your decisions in the laboratory will be recorded here