Miro.Design

Overview

Miro.Design is the internal platform where the design system is published twice from one source: as pages a designer reads, and as data a coding agent fetches. I set the model it runs on — a quality bar that changes volume instead of standing still, and four areas that each replaced something that used to be word of mouth.

Role
Design Manager
Focus
Design system for agentic product design
Timeline
2025 – 26
Team
[Team and key partners]
Status
Internal to Miro

The platform

Five questions, and one of the readers is not a person.

It opens on the questions a designer actually arrives with rather than a table of contents. Seven of its eight readers are people; the eighth is the coding agent working on their behalf, and it needs the same answers in a form it can fetch.

Every frame below carries the same switch. Flip one and they all change register at once.

Miro.Design · home
  • What is the product made of?

    Surfaces, color, scale, type, motion

    page  product-language
    data  visual-language.json
  • How do we build an experience?

    Three volumes, and a run start to finish

    page  build
    data  build.json
  • What can I pull into my tools?

    Skills, servers, packages, bases

    page  toolkit
    data  toolkit.json
  • What is everyone working on?

    Every prototype, and who made it

    page  explorations
    data  in-flight.json
  • How much should I trust this?

    Stable, experimental, deprecated, unresolved

    page  quality
    data  gaps.json
Rebuilt here rather than screenshotted: the real one is behind the VPN, and a picture of an interface is less than the interface. Every name and value on this page is a stand-in.

Long story, short.

Designers ship through agents now, and the system was invisible to them.

A design system that lives as guidance — prose, principles, a library — is something a person opens and applies judgment to. A coding agent does neither. It is fast, literal and confident, and it will build the screen whether or not it knows the rules: hand-rolled chrome where a component existed, invented color, nothing that survives translation.

Nobody finds out until handover, which is the most expensive possible moment to find out.

The gate that was already tried

Two hard gates had been built before, and both were shelved.

The obvious fix is enforcement: define the rules, block anything that breaks them. Miro had tried it twice. The lesson recorded from those attempts was blunt — forcing token-only usage backfires, because people hack around the design system instead of using it.

Which means the problem was never the rules. It was applying all of them at every moment, including the moments where the work is still an idea. What follows is the platform in four parts, and what each part replaced.

What the design system contains

Values resolved once, with the gaps named.

The product language is the four surfaces and the layers underneath them: color, the one physical scale, type, content and motion. Color is the clearest case. Nine hues, each carrying a family of seven semantic roles, so you pick a hue and the roles come with it rather than picking a value and hoping.

Every resolved role carries its measured contrast. The roles nobody has settled say so.

Product language · color

Before

Guidance to read

A component library, a principles deck and a set of values that lived in three places at once. Which one was current depended on who you asked. Contrast checked by eye, if at all.

nothing to fetch — the agent inferred it from a screenshot

After

  • Lemon#FAE980
  • Tangerine#FAB980
  • Coral#FA8880
  • Rose#FA80B5
  • Violet#C180FA
  • Cobalt#80ACFA
  • Aqua#80EDFA
  • Lime#B1FA80
  • Slate#DDDCD9

Lemon, opened. Seven roles, two still unresolved.

background-mild#FAE9806.9:1
background-subtle#FDFAE58.1:1
text#574D0F
surface-dark#2B260912.3:1
border-dark#A08C1B4.5:1
border-strongnot resolvedvariable export
iconnot resolvedvariable export
lemon
  background-mild     #FAE980   text 6.9:1
  background-subtle   #FDFAE5   text 8.1:1
  text                #574D0F
  surface-dark        #2B2609   mild 12.3:1
  border-dark         #A08C1B   dark 4.5:1
  border-strong       null      unresolved
  icon                null      unresolved
What improved: the values are resolved in one place, every ratio on this page is measured against the value beside it, and the roles nobody has settled are published as gaps rather than quietly filled in with something plausible.

The run, start to finish

The quality conversation moved off the end of the project.

One feature, from a screenshot to a pull request. What makes it a run rather than a workflow diagram is that two of the steps are decisions you make out loud: promote this, or kill it.

Build · a run, start to finish

Before

Three steps, one of them hope

  1. Prototype
  2. Hope
  3. Argue about quality at handover

nothing to fetch — the process lived in people’s heads

After

  1. Get it on screensketch
  2. Keep or killsketch
  3. promote — do not tidy first
  4. Re-derive it properlyfeature
  5. Build with notices onfeature
  6. Log what the system could not dofeature
  7. the one strict moment
  8. Run the gatehandover
  9. Ship the artifacts, not just the branchhandover
What improved: quality stopped being an argument at the end and became a step you name at the start. A prototype that dies in the first two steps costs twenty minutes and never enters the codebase.

One checklist, three volumes

So the bar became a variable.

This is the mechanism under the run. The checklist never changes; what changes is the consequence of breaking one of its rows, what the agent reaches for first, and what you are left holding. Switch volumes and watch the rows refuse to move.

Build · the mechanism
Volume

The checklist

Banned dependenciesBlocksBlocksBlocks
Hardcoded colorBlocksBlocksBlocks
Real componentsQuietFlaggedBlocks
Tokens, not raw valuesQuietFlaggedBlocks
AccessibilityStructureFlaggedBlocks
Survives translationNot checkedRecordedBlocks
check                    sketch   feature   handover
banned-dependencies      block    block     block
hardcoded-color          block    block     block
real-components          quiet    notice    block
tokens-not-raw-values    quiet    notice    block
accessibility            struct   notice    block
survives-translation     off      record    block

You say

State: sketch. Rough is fine.
Build the screen in this
screenshot as fast as you can.
Don't stop to look things up.
State: feature. This ships.
Read the component docs first.
Tokens only. Tell me each time
you slip, but keep going.
State: handover. Strict.
Audit it, fix what you can,
list what you can't with the
reason, then write the spec.

It says back

Nothing. Only the floor speaks here, and you did not trip it.
padding: 10px isn’t on the scale — nearest are 8 and 12. Snap it either way; both line up with everything else.
Two icon buttons had no accessible name, so they announced as “button”. Fixed. The avatar stack is hand-rolled, so it needs a row in the gap list.
tone  name the thing, name the fix,
      get out of the way
rule  never imply that exploring
      was a mistake
What improved: one definition of done instead of three. Flipped, the same checklist shows every volume at once, because data has no current state — a person needs one answer, a machine needs the rule.

What you can pull in

Four kinds of thing, and knowing which is which is most of the battle.

The toolkit is where a designer sets themselves up. Its real work is definitional: people were mixing up things the agent reads with things the product is built from, which is how you end up with a prototype that behaves correctly and ships nothing, or ships everything and behaves like a stranger.

Toolkit · what each kind of thing is

Before

A thread, and someone who remembers

Setup was folklore. Commands passed between people, half of them stale, and no way to tell which half without running them.

nothing to fetch — the install steps were in a chat log

After

Read by the agent

Skill

Instructions the agent installs once and loads itself when they are relevant. Never shipped.

Reach for it when you are pasting the same context every session.

kind      skill
status    official
verified  3 weeks ago

Server

Live access to a system rather than a description of one. The agent asks instead of guessing.

Reach for it when the answer changes and a document would already be wrong.

kind      server
status    official
access    internal

Becomes the product

Package

The components and tokens themselves. The only one of the four that ends up in what ships.

Reach for it when you are about to write UI and want it right from the first component.

kind      package
status    official
peer      required

Base

A repository you clone rather than an empty folder. Arrives already wired to the system.

Reach for it whenever you are starting something new.

kind      base
status    official
clones    tracked

The gate is the fifth thing and belongs to both columns: one command on your machine, the same one in CI.

kind  gate    runs  local · ci
What improved: setup stopped being folklore. Every entry carries what it is, what it needs, and the date somebody last checked that it still works — so nothing in the toolkit is a rumour.

What everyone is building

The system finally gets to see itself being used.

The prototypes page lists every app on the platform, resolved to a person, a team, a status and the thing it was cloned from. It sounds like an activity feed. It is actually the evidence base: what people reached for, and what they had to hand-roll because nothing existed.

Explorations · the prototypes page

Before

Nobody could see it

Prototypes lived on the machines that made them. The same thing got built twice, and nothing ever came back to the design system about what it could not do.

nothing to fetch — there was no record that a prototype existed

After

  • experimental
    owner …  team …  from base
  • stable
    owner …  team …  from base
  • experimental
    owner …  team …  from fork
  • deprecated
    owner …  team …  from fork

And what it could not do

Anything hand-rolled earns a row in the gap registry: what was missing, what was used instead, and where that fill now lives so the next person reuses it rather than inventing a second one.

gap       …
fill      composed from primitives
owner     null
status    unresolved
What improved: the language now gets revised from evidence rather than opinion. Owners and names are redacted here; on the real page they resolve to a person and a team.

Neither move works alone

The graded bar and the second reader are one idea.

A bar that changes volume is useless if the thing building the screen cannot find out what correct means at each volume — it just becomes a slower way to be wrong. And a machine-readable design system is pointless if all it can say is no, because that is the gate that already failed twice.

Put together they work: the agent can read what the rule is, and read how loudly it applies right now.

Publishing the uncertainty

A graded bar is only honest if you publish which grades are real.

Four labels run across everything, and the fourth is the load-bearing one: a gap with no owner, a proposal nobody ratified, a value the system has no answer for. If a thing carries no status, nobody has decided — which is unresolved, not stable.

Which is why the three volumes carry that label themselves. The mechanism that grades everything else is published as a proposal, on the same page that lists everything the platform does not yet know. That is not a caveat. It is the only thing that makes the rest of it trustworthy.

Shipped outcome

Internal, in use, and still arguing with itself in public.

  1. A designer names the volume and gets the matching severity, instead of negotiating with a bar that never moved.
  2. The language is published once and read two ways, so the value a designer checks by eye is the value an agent fetches.
  3. Roles nobody has resolved say so, rather than being filled in with a plausible guess that then ships.
  4. Setup is a dated manifest instead of folklore, and the four kinds of thing in it are finally distinguishable.
  5. What the system could not cover comes back as evidence, so the language is revised from what happened rather than from what was intended.

About

A design system used to be something you read. Most of the reading is now done by something that acts on it immediately and never asks a follow-up question. That changes what the documentation is for: less persuasion, and much more precision about what is true, what is proposed, and what nobody has decided yet.