Skip to content
Design
Skill

/design-doctrine

The house rules for ANY design or UI work - the verification protocol (run the gate, never claim a number), the absolute no-emoji rule, token by intent, one shared theme, the eight states, one thing leads, and output completeness. Load this FIRST whenever building, reviewing, or

From plugin
ux-ui-agent-skills
3.1k26 skills1 agent1 command3 hooks
+1

Claude Code

$ npx -y skills add plugin87/ux-ui-agent-skills --skill design-doctrine --agent claude-code

SKILL.md

design-doctrine.SKILL.md
name: design-doctrine
description: The house rules for ANY design or UI work - the verification protocol (run the gate, never claim a number), the absolute no-emoji rule, token by intent, one shared theme, the eight states, one thing leads, and output completeness. Load this FIRST whenever building, reviewing, or theming a screen, component, or token set. Installed as a plugin, this skill carries what CLAUDE.md carries in the repo.

Skill: Design Doctrine

Requirements

This skill needs the full UX/UI Agent Skills kit: the gates, the references and the design-system library. Install it with `npx ux-ui-agent-skills@3.1.0 init` or as the Claude Code plugin. `npx skills@1.7.6 add` copies the skill folder and nothing else. Installed that way, this skill runs in **guidance-only mode**: no gate runs, so it gives no verdict.

> **Step 0: is the kit here?** Check once: > `ls ${CLAUDE_SKILL_DIR}/../../../tokens >/dev/null 2>&1 && echo KIT_OK || echo KIT_MISSING` > On `KIT_MISSING`, open your reply with: "Guidance-only mode: the UX/UI Agent > Skills kit is not installed here, so no gate ran and nothing below is > measured." Then work from this file and general practice, under three rules. > Do not guess or cite the contents of a kit file you could not open. State no > measured number (no contrast ratio, no N/N, no "passes WCAG"): write "not > verified" where one would go. End with a line `Skipped (kit not installed):` > that names every gate script this file tells you to run, then the install > command above.

A plugin's root `CLAUDE.md` is not loaded as project context, so the always-on brief travels here instead. Read this before the first line of any design work, then load the rule file for the territory you are actually in.

Verification protocol - run gates, never claim

1. **Never state a number you did not measure.** Any contrast ratio, "WCAG pass", or "100%" must come from running a gate and reporting its real output. If you have not run it, say "not verified yet." 2. **Verify every state, not just resting.** `node ${CLAUDE_SKILL_DIR}/../../../scripts/gate.mjs verify_states.mjs <file> [--dark]` measures default, hover and focus - a button that passes at rest can fail on hover. 3. **One command before reporting done:** `node ${CLAUDE_SKILL_DIR}/../../../scripts/accuracy_report.mjs`. Report the real `N/N` line. It is all-or-nothing. 4. **Build with the gates, not after them.** Fix and re-run until green; never announce success between failures. 5. **Render and LOOK.** Gates pass while a UI is still visibly broken. Screenshot the harness in both themes, click every control, and confirm the state changed. 6. **Responsive is gated too:** `node ${CLAUDE_SKILL_DIR}/../../../scripts/gate.mjs verify_responsive.mjs <file|dir>`: no horizontal overflow from 280 to 951px, iPhone Duo included, and a hinge kept clear by any page that answers the fold. 7. **Honest scope.** The gates prove objective correctness. They never prove taste. For that, run `/critique`, look at the work yourself, and start from the taste preflight below rather than from default components. 8. **SKIPPED is not a pass.** With no browser installed a render gate prints `SKIPPED` and exits 0, reporting nothing. Run single render gates behind `DS_REQUIRE_BROWSER=1` so that becomes `REQUIRED, FAILING`, and fix it with `npx playwright install chrome` rather than by removing the flag.

Mobile is the base

Base styles ARE the phone layout. Wider screens are layered on with `min-width`. `max-width` is not banned - it is right for a genuine narrow refinement, or for a range between two breakpoints - but a desktop-first stylesheet, where the base assumes a wide screen and mobile is patched in afterwards, is a bug.

Measured by `${CLAUDE_SKILL_DIR}/../../../scripts/verify_mobile_first.mjs`, which removes every `@media` and `@container` rule and renders what is left at 320px. A mobile-first page passes because its base already is the phone layout. A desktop-first page cannot fit.

Two house rules on what never ships

**Never ship a native `<select>`.** It draws its own chevron, pressed against the control's edge with no breathing room, and `appearance: none` plus a custom chevron fights the platform instead of matching the system. Use the Listbox or Combobox pattern in `${CLAUDE_SKILL_DIR}/../../../components/forms-advanced.md`: a button trigger that announces the current value, the chevron placed with inner padding from tokens, and full keyboard parity (typeahead, arrows, Home/End, Escape, `aria-expanded` that really toggles something visible). Losing native select means accessibility stops being free, so the replacement has to pass every state, keyboard and axe gate before it counts. Measured by `${CLAUDE_SKILL_DIR}/../../../scripts/lint_native_select.py`.

**Never a colored border on one side only** of a card, alert, toast or callout - `border-left`, `border-right`, `border-top`, `border-bottom`, or the logical `border-inline-*` and `border-block-*` forms. The tinted 3-4px bar is a generated-UI cliche in every direction, not only on the left: it is decoration standing in for hierarchy the layout never established. Use a full hairline border on all sides, or surface and elevation separation, and carry status with a real icon plus text, never colour alone. Measured on the render by the one-sided accent-border tell in `${CLAUDE_SKILL_DIR}/../../../scripts/slop_tells.mjs`.

Taste preflight - before any markup

The gates cannot see this half, so it has to be decided rather than discovered. Write the block into your reply, then build to it. Generating first is where generated-looking work comes from.

Domain:          fintech | editorial | dev-tool | healthcare | consumer | ...
Audience & tone: expert vs first-time, calm vs energetic, premium vs utilitarian
Mood:            the one adjective the result must earn - "expensive", "precise", "warm"
Motion depth:    none | subtle feedba
Read more
@plugin87
Ships withux-ui-agent-skills

aka XIAS

3.1k26 skills1 agent2 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
3.1k
Star history of plugin87/ux-ui-agent-skills on GitHub, a chart by star-history.com

Other skills on ux-ui-agent-skills.

a11y-audit

a11y-audit

Audit a UI or design against WCAG 2.2 AA/AAA and ARIA patterns, returning criterion-referenced findings with severity and…

brandkit

brandkit

Generate a complete, accessible brand design system from a brief, as primitive → semantic → component DTCG tokens (color, type,…

critique

critique

Adversarial design critique of the current work. Render it, look at it, and argue for rejection. Run after the gates are green,…

design-code

design-code

Generate production-ready, accessible, token-driven component code for ANY framework (React+Tailwind, Next.js, SwiftUI, Vue,…

More skills from other plugins.

impeccable

impeccable

Use to design, redesign, critique, audit, polish or animate a frontend: websites, landing pages, dashboards, app UI, components,…

@pbakaus@pbakausInstall Skill

Questions about design-doctrine.

Which coding agents can use design-doctrine?
design-doctrine installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.