---
name: design-system
description: "Use when a task creates, changes, reviews or audits user interface and needs to know which design rules bind it — implement-feature before a UI phase, gate-builder looking for the source of a design-system gate, qa-preflight needing the values to measure, or a person asking to write a project's design-system doc or to audit a screen against one. Stack-agnostic. The project's own tracked design-system doc always wins; with none, a bundled Material 3 baseline guides new UI. Never invents a project rule and never edits production code."
---

# Design System

One answer to *"which design rules apply to this UI?"*, for every skill and person that asks.

> **The baseline guides; the project's doc binds.** A rule is the project's only when the
> project wrote it down in a tracked document. Everything this skill bundles is guidance for UI
> that is being written — never a gate, and never a defect by itself.

> References, loaded on demand, all of which travel with this skill:
> `references/material-3.md` (the default baseline: color roles, type scale, shape, state,
> motion, layout), `references/interface-rules.md` (interaction and accessibility rules, each
> tagged `[gate]` or `[review]`), `references/design-direction.md` (the brand layer and interface
> writing, for what a system leaves free), `references/measuring.md` (auditing by measured value)
> and `references/design-system-template.md` (the shape of a project's own doc).
>
> Rationale — why this skill exists and what it took from where:
> `https://github.com/dayvisonassis/sdd-skills/blob/main/docs/Skill_Design_System.md`. That file
> is not part of an installed copy; everything needed to run is in this folder.

## INPUT

- `mode` — `apply` (default: UI is about to be written, or another skill dispatched this one),
  `author` or `audit`.
- The target: the files, surfaces or routes concerned (`apply`, `audit`); nothing for `author`.
- Auto-discovers: `GATES.md`, the project's design-system doc, and the UI library from the
  project's manifest.

## OUTPUT

- **Always, first: the resolution line** — which source binds and why. One of:
  `design system: <path>` · `baseline: Material 3 — the project declares no design system` ·
  `library conventions: <library> — Material 3 does not apply` .
- `apply` — the rules for the UI at hand, gated ones first, and the verification to run.
- `author` — the project's design-system doc, written from the template at a tracked path.
- `audit` — a findings report. No file is edited.

---

## Step 1 — Resolve the source (every mode, before anything else)

**This is the one definition.** `implement-feature`, `gate-builder` and `qa-preflight` refer to
it and do not restate it.

1. The path `GATES.md` names in its design-system section.
2. Otherwise a **tracked** doc at a conventional path: `docs/design-system.md`, `DESIGN.md`,
   `docs/**/design*.md`, `docs/**/ui*.md`, a `.cursor/rules/*.mdc` that describes UI standards,
   a tokens or Storybook doc.
3. Otherwise none: the bundled baseline applies, as the table below says.

"Tracked" means `git ls-files` lists it. A doc that lives only in an ignored or untracked folder
— a skills folder, typically — is local to this machine: use it for this run, say that it is not
shared, and never let a gate point at it.

Which part of the baseline applies — when there is no doc, and for whatever a doc is silent on:

| The project's UI | Baseline that applies |
|---|---|
| A Material 3 implementation, or no UI library chosen yet | `material-3.md` + `interface-rules.md` |
| Another component library or design language (Bootstrap, Ant, Fluent, a utility-class kit, a custom one) | that library's own conventions + `interface-rules.md`. `material-3.md` does not apply |
| Not web (native mobile, desktop) | `material-3.md` on a Material platform; of `interface-rules.md`, only the rules that do not name a web technology |

**Precedence:** the project's doc → the UI library's conventions → the bundled baseline. A
conflict is the higher one's to win; two sources are never averaged. When the doc and the
dominant pattern in the code disagree, say so — in `apply`, follow the doc and report the
divergence; in `author`, ask.

What each source may be used for:

| Use | Project's doc | Bundled baseline |
|---|---|---|
| Guiding UI that is being written | yes | yes |
| Source of a gate's rules | yes — its machine-checkable section | **never** |
| A finding reported as a defect | yes | only the accessibility floors of `interface-rules.md`; anything else is a suggestion |

---

## Mode `apply` — before writing UI

1. Resolve (Step 1) and state the resolution line.
2. Read only what the UI at hand needs: a form reads forms, states and density; a new page reads
   layout. Do not load every reference.
3. **Gated rules first.** The doc's machine-checkable section is what the project's
   design-system gate rejects (`GATES.md` says which gate). Write the UI in the accepted pattern
   from the start — learning a rule from a failed gate run costs a retry.
4. Then the judgement rules: hierarchy, density, spacing, and the states nobody asks for —
   empty, loading and failure are designed, and they must not look alike.
5. **A token wherever one exists.** A literal color, size, radius or duration where the system
   has a role for it is a divergence, even when the two values are equal today.
6. Verify per `references/measuring.md`: rendered, in every theme the project ships, with the
   numeric rules read as computed values. What could not be verified is reported by name, so the
   caller can log it — never as verified.
7. The doc is silent on something this UI needs → follow the baseline and report the gap
   (`doc is silent on <x>; used <baseline rule>`). Never edit the doc in this mode.

## Mode `author` — writing the project's doc (a person asks; never dispatched)

1. Resolve. A doc already exists → ask whether to update it or replace it. Never overwrite
   silently.
2. **Existing UI:** derive from what is really there. For each candidate rule, count conforming
   and non-conforming occurrences and take the majority as the rule; near an even split, ask, or
   record the rule as advisory. Read numeric values from the rendered screen, not from class
   names (`references/measuring.md`). List every place where the code and the intended rule
   disagree.
3. **No UI yet:** use `references/design-direction.md` — the subject, the audience, the tone —
   and decide what the system leaves free: source color, typefaces, shape, density, the
   personality of motion. One question at a time, each with a recommended answer.
4. Fill `references/design-system-template.md`. **Every rule lands in exactly one of two lists:**
   machine-checkable (a tool can decide it from a file) or judgement (a person or a rendered
   screen decides it). Every numeric value goes in the measured-values table with its unit, the
   element to measure and the theme.
5. Save at a tracked path — `docs/design-system.md` unless the person names another. Say that
   `gate-builder` builds the design-system gate from the machine-checkable section and records
   the path in `GATES.md`.
6. Refuse your own output when: a rule sits in neither list; a value was copied from the
   baseline without anyone choosing it; two rules contradict each other.

## Mode `audit` — read-only review

1. Resolve.
2. **Static pass** over the target files: the doc's machine-checkable rules and the `[gate]`
   rules of `references/interface-rules.md`.
3. **Rendered pass**, when the app can be brought up: every numeric rule measured per
   `references/measuring.md`, in every theme, with contrast computed over the composed
   background.
4. Report, grouped by file or screen, one line per finding:
   `<file>:<line> — <rule id> — <what is wrong> — measured <x>, expected <y>`.
   Split the report in two — **objective** (a rule of the project's doc, or an accessibility
   floor) and **judgement** (everything else, including every baseline rule) — and end with what
   was **not measured**, by name.
5. Change nothing. A correction belongs to whoever asked: `qa-preflight` dispatches
   `fix-runner`; a person fixes or delegates.

---

## RULES

**Always:**
- Resolve first, and state the resolution line before any rule.
- Let the project's doc win over the library and the library over the baseline.
- Keep machine-checkable rules and judgement rules apart, in the doc and in every report.
- Read numeric rules as computed values on the rendered screen, in every theme the project ships.
- Name what was not verified.

**Never:**
- Invent a project rule, or present a baseline value as if the project had chosen it.
- Use the baseline as the source of a gate, or report a baseline rule as a defect — the
  accessibility floors excepted.
- Conclude conformance from a class, attribute or token name being present.
- Write gate infrastructure (that is `gate-builder`'s) or edit production code.
- Store the project's doc in a skill folder or any untracked path.
- Fetch rules from the network at run time: the references are bundled so a run is reproducible.
- Write or overwrite a doc nobody asked for.

---

## Edge cases

**The scope has no UI** (a backend-only change, a library): say so and stop; there is nothing to
resolve.

**The only doc is untracked:** use it for this run, state that it is local, and recommend moving
it to a tracked path. `gate-builder` will not build a gate from it.

**Several candidate docs:** the one `GATES.md` names wins. With none named, ask (`author`,
`audit`); when dispatched, take the most specific one and report which.

**The project ships two themes and the doc describes one:** verify both anyway, and report the
doc's silence as a gap.

**The doc is older than the code:** the dominant pattern contradicts it in several places —
report the list. Which one is right is the team's decision, not this skill's.

**A project on an earlier Material version:** its installed library version's conventions win.
Do not migrate tokens or components as a side effect of another task.

**"Make it look better" where a doc exists:** `design-direction.md` covers only what the doc
leaves free. Changing the system itself is an `author` change, made on purpose.

**Dispatched and something is ambiguous:** apply the higher-precedence source, report the
ambiguity, and proceed. Never pause a dispatched run to ask.
