--- name: design-system-guardrails description: Enforces the team design system on all UI work. Use this skill whenever building, modifying, styling, or prototyping ANY user interface — components, screens, pages, layouts, prototypes, or one-off UI experiments — even if the user doesn't mention the design system. Also use it when the user asks for a new component, a custom color, a type style, or any visual change, so the request can be checked against the system first. Guarantees UI is composed only from existing design-system components and tokens, flags anything that doesn't exist instead of inventing it, and files a component request to notify the system designer about gaps. --- # Design System Guardrails This team ships UI from one design system. Every screen anyone builds — designer, engineer, or agent — must be composed from the system's existing components and tokens. The system is the single source of truth; the moment agents start inventing one-off buttons and hex colors, the system stops being a system. Your role under this skill: **composer, not creator.** You assemble UI from parts that already exist. When a part doesn't exist, you flag it — you never quietly invent it. ## Step 0 — Select the design system This skill is system-agnostic: it enforces whichever design system governs the *current project*. Resolve that system before anything else, in this order: 1. **Project config file:** a `design-system.md` at the project root (or `.claude/design-system.md`). This is the project's declaration of its system — read it and use its values for everything below. 2. **CLAUDE.md section:** a "Design system" section in the project's CLAUDE.md with the same information. 3. **Detect from the project:** an installed design-system package, or an obvious in-repo system (a `components/` tree plus a tokens file). State what you detected and confirm with the user before relying on it — a wrong guess here defeats the whole skill. 4. **Ask the user** which system applies, then **offer to write `design-system.md`** with their answers so no future session has to ask again. The config declares: ```markdown # Design system - **System repo / package:** - **Components live in:** - **Design tokens live in:** - **System owner (component requests go to):** ``` One project, one system. A different project can declare a different system — the guardrails below apply identically to whichever one is selected. ## Step 1 — Inventory before you build Before writing any UI code, know what exists. In order of preference: 1. If the current project already contains or imports the design system, read its component directories and token files directly. 2. Otherwise, consult the system repo/package from the config — list its component directories and read the token file so you know the real palette, type scale, spacing, radii, and shadows. Never work from memory of "what design systems usually have." Check what *this* one has. A guess that happens to be wrong is exactly the kind of drift this skill exists to prevent. ## Step 2 — Compose only from what exists - **Components:** use existing system components. Composing them together (a `Card` containing a `Badge` and a `Button`) is encouraged — that's what a system is for. Writing a new component file, or copy-pasting a system component to tweak it, is not. - **Color:** only token values. No raw hex, rgb/hsl, or named CSS colors. No arbitrary Tailwind values like `bg-[#3b82f6]`. - **Typography:** only the system's type styles and font families. No ad-hoc sizes (`text-[13px]`), weights, or new fonts. - **Spacing, radii, shadows, motion:** same rule — tokens and system utilities only. - **The system itself is read-only.** Never edit files inside the design system repo or its installed package. Changes to the system go through the system owner. Variants and props that a component already supports are fair game. Overriding a component's internals with inline styles or `!important` to force it into a shape it doesn't support is a gap — treat it as one (Step 3), don't hack around it. ## Step 3 — When something doesn't exist: flag it If the task needs a component, variant, or token that the system doesn't have: 1. **Say so plainly.** Tell the user what's missing, e.g. "The system has no date-range picker — only a single-date `DatePicker`." 2. **Offer the nearest legal alternative.** Often a composition of existing parts covers 90% of the need. Let the user decide whether the alternative is good enough for now. 3. **File a component request** (see below) so the gap reaches the system owner, whether or not the alternative was accepted. The request is how the system grows deliberately instead of by accident. The same applies to *stylistic* gaps: if the user asks for "a slightly darker teal" and no such token exists, that's a request for the system owner — not a new hex value. ## Filing a component request Create `design-system-requests/-.md` in the project (create the folder if needed): ```markdown # Component request: [name] - **Type:** [component / variant of existing component / token / type style] - **Requested by:** [user's name], [date] - **Project:** [project name / path] - **Nearest existing alternative:** [what exists today and why it falls short] ## What it needs to do [plain-language purpose, the states/variants/props it would need] ## Where it was needed [the screen or flow that surfaced the gap, with reference images or links if available] ``` Then get it to the system owner (from the config): if an email or messaging tool is connected, draft a short message to that address with the request contents, show the user the draft, and send once they confirm. If no such tool is available, tell the user the request file is ready and ask them to send it along. Either way, the gap gets recorded the moment it's found — requests that live only in chat history die there. ## If the user pushes back Someone will eventually say "just make the button purple, it's only a prototype." Hold the line once, kindly: explain that one-off deviations are how design systems rot, and that the request path exists precisely so gaps get fixed at the source. Offer the nearest system-legal option. If they explicitly insist on overriding anyway, comply — it's their project — but (1) isolate the deviation clearly in the code with a comment marking it as an unapproved deviation, and (2) still file a component request noting the override happened. The system owner should never discover drift by accident months later.