Files
claude-plugins/composer/skills/ui-system/SKILL.md
movq 0cdbb1b4a4 fix(composer,symphony): use \${CLAUDE_PLUGIN_ROOT} for plugin-internal paths
Per plugin-structure spec, plugin-internal references in component
files (commands, agents, skills) must use \${CLAUDE_PLUGIN_ROOT} so
they resolve correctly regardless of where the plugin is installed
(local repo, marketplace cache, npm-installed, etc.).

Updated:
- symphony/skills/symphony-init/SKILL.md: WORKFLOW.md template ref
- composer/skills/ui-system/SKILL.md: all six template refs in the
  Write phase
- composer/skills/composer/SKILL.md: added a Templates section that
  enumerates each phase's template path with \${CLAUDE_PLUGIN_ROOT},
  plus the ADR template ref in phase 8

Composer's CLAUDE.md gains a clarifying note that templates/design-
system/SKILL.md and templates/interaction-design/SKILL.md are template
skeletons, not actual plugin skills — they're copied into a consuming
project's .claude/skills/ at install-time of the design system. Per
the auto-discovery rule (scans skills/ only), they are not loaded as
plugin skills.

Removed empty composer/agents/ directory (composer has no agents;
workers are owned by symphony).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 22:02:03 -05:00

16 KiB
Raw Blame History

name, description
name description
ui-system Interview the user and produce two project-local skills — a design-system skill and an interaction-design skill — that auto-load whenever UI work is in progress. Output goes to .claude/skills/<slug>-design-system/ and .claude/skills/<slug>-interaction-design/, NOT docs/planning/. The skills load themselves into context when anyone codes UI (mock or real); a plain reference doc would not. Use when the composer skill reaches phase 4 or 5, or when the user asks to "set up the design system", "specify interaction patterns", or "redo the UI system".

UI system

You run a focused interview that produces two project-local skills:

.claude/skills/<slug>-design-system/
├── SKILL.md       ← canonical visual reference; auto-loads on UI work
├── tokens.ts      ← machine-readable color / type / spacing / motion tokens
└── components.md  ← component vocabulary with anatomy

.claude/skills/<slug>-interaction-design/
└── SKILL.md       ← interaction patterns, state surfaces, input modes, i18n

Plus pointer stubs in docs/planning/{design-system,interaction-design}.md so the planning index finds them.

Why these are skills, not docs

A reference doc gets read once and drifts out of context as the conversation grows. UI work later — generating a mock, writing a component, picking a color — wouldn't have it loaded.

A skill with a UI-triggered description loads automatically every time the trigger matches. The design system and interaction design must be skills, full stop.

Slug

Resolve in order:

  1. package.json name — slugify.
  2. Git remote name (e.g., git remote get-url origin → repo name).
  3. Directory name.
  4. Ask.

Slug rule: lowercase kebab-case, ASCII only. SourdoughTrackersourdough-trackersourdough-tracker-design-system.

Interview shape

Two parts, sequential: design system first (visual), then interaction design (behavioral). Don't interleave — they're different conversations and the visual posture often informs interaction choices.

Each phase:

  1. State what's being decided and why it matters (one line).
  2. Show the default if there is one.
  3. Ask the question. Batch related questions when they cluster naturally.
  4. Confirm the answer back as it'll appear in the artifact.
  5. Move on.

The user can answer default or skip at any phase:

  • default → accept the offered default and move on.
  • skip → mark <TBD: ...> and move on; user can revisit.

Never invent on the user's behalf. <TBD> is a worklist, not a failure.


Phase 0 — Material ingestion (silent)

Before asking anything, scan for material the user already has. Read without asking; surface findings before the first question.

Source What to extract
package.json name (slug), version, dependencies (UI framework hints)
tailwind.config.{js,ts} existing tokens, theme extensions
tokens.{ts,json,css} anywhere in repo existing token values
*.css, *.scss brand colors mentioned, font families imported
index.html, <head> of any HTML font loads, color-scheme meta
assets/, public/, docs/ for logos/screenshots brand colors via image inspection
README.md, BRANDING.md, STYLE.md style notes the user wrote
Existing docs/planning/concept.md platform hint (web/mobile/native)

Then before the interview opens:

Material I found and will use:
  • <thing> — <how it'll inform the interview>
  • <thing>
Not found (will ask): brand color, type family, motion posture.

If the user has named a reference like "make it look like Linear" in a previous Composer phase, surface it here and apply the matching preset (see "Reference banks" below).


Part 1 — Design system

D1 — Visual posture (one paragraph)

The north star sentence for visual decisions. Don't ask for paragraphs; ask for adjectives and assemble.

Three or four words that describe how this should feel.
Examples: "quiet, dense, monochrome, one accent" / "playful,
generous, expressive type" / "clinical, neutral, accessibility-forward".

Compose into a single sentence; show; accept.

D2 — Color

Batch as a single phase with sub-questions; tight loop.

D2.1 Brand primary. If material gave a color, propose it. Else:

Pick a brand primary. Either name a hex, name a color
("warm orange", "deep teal"), or name a reference ("Linear's purple",
"Stripe's indigo"). I'll generate the variants from there.

D2.2 Brand secondary. Optional. default = none.

D2.3 Neutral tone. Warm / cool / true. One question.

For grays, do they feel slightly tan (warm), slightly blue (cool),
or truly neutral (true)? Default: cool.

D2.4 Generate the neutral scale. Compute 50950 from the chosen tone and brand contrast targets. Show the user; offer default or "redo with warmer/cooler/more contrast".

D2.5 Semantic colors. Success / warning / error / info. Show defaults that contrast against both light and dark backgrounds; user accepts or overrides one at a time.

D2.6 Dark mode. yes / no / system-following. Default: system. If yes, generate the dark token mapping (invert + adjust saturation per token class) and show.

D2.7 Accessibility check. Compute contrast ratios between primary + neutral pairs. Flag anything below 4.5:1 for body text or 3:1 for UI. Don't silently accept failures — surface and confirm or adjust.

D3 — Typography

D3.1 One family or two? Default: one.

D3.2 Family choice. If user has no preference, offer presets:

  • Modern sans: Inter (free, broad weights)
  • Humanist: Source Sans 3 / IBM Plex Sans
  • System stack: native to OS (free, no load)
  • Editorial: Inter + Fraunces (display)
  • Technical: IBM Plex Sans + IBM Plex Mono

D3.3 Scale base. 14, 15, 16. Default: 16 (web), 17 (iOS native), 14 (compact dashboards).

D3.4 Scale ratio. 1.125 (subtle), 1.2, 1.25 (default), 1.333 (dramatic), 1.5 (display-heavy).

D3.5 Line-height policy.

  • Display: 1.11.2 (tight)
  • Body: 1.5 (normal)
  • Long-form prose: 1.7 (relaxed) Defaults usually fine; user can override one of three.

D4 — Spacing

D4.1 Base unit. 4 (default — finer control) or 8 (rougher cadence; iOS native often).

D4.2 Scale. Use the standard 12-step (0, 0.5, 1, 1.5, 2, 3, 4, 6, 8, 12, 16, 24) — almost always accepted as default.

D5 — Radii

D5.1 Posture. sharp (04) / tight (48) / medium (816) / pillowy (16+) / mixed.

D5.2 Generate sm/md/lg/pill/full. Show; accept or tweak one.

D6 — Shadows & elevation

D6.1 Posture. flat (none) / subtle / generous.

D6.2 Scale. xs/sm/md/lg/xl. Generated from posture; show; accept.

D7 — Density

D7.1 Default density. comfortable (default; web app) / cozy / compact (data-heavy dashboard).

This drives component padding tokens — important enough to ask, easy to forget otherwise.

D8 — Visual motion

D8.1 Default duration. fast (150ms), default (250ms), slow (400ms). Default: default. D8.2 Default easing. standard / accel / decel / custom. Default: standard.

Behavioral motion (when things animate) lives in interaction design.

D9 — Components

Read the entity vocabulary from ia.md. Confirm the standard set (Button, Input, Card, Surface) and ask for project-specific additions found in IA.

For each project-specific component, ask: variants? states? anatomy? Default to "standard variants only" if user is unsure — better to add later than over-spec now.

D10 — Theme variants (skip by default)

Multi-brand / tenant theming usually no for v1. Default: skip.

D11 — Accessibility tokens

D11.1 Focus ring. Style (solid / double / inner-outer) and color (brand / accent / outline-default). Default: solid 2px brand at 60% opacity.

D11.2 Contrast targets. Confirm WCAG AA (4.5:1 text, 3:1 UI). AAA optional. Default: AA.


Part 2 — Interaction design

I1 — Input model

I1.1 Primary input. touch (mobile/tablet) / mouse / keyboard / mixed. Often determined by platform from concept.md — confirm rather than ask cold.

I1.2 Supported inputs. Which secondaries must work; which are not in scope.

I1.3 Voice / switch / assistive. Defer unless users.md has an actor that needs it.

I2 — State surface declarations

The most important phase. For each action class, pick one pattern. Walk through them in this order:

Action class Common picks Default
Quick edit (single field) inline edit / popover / drawer inline edit
Multi-field create drawer / modal / full-page route drawer (web), modal (native)
Multi-field edit drawer / modal / full-page route same as create
Confirm destructive modal modal (always — non-negotiable)
Settings / configuration full-page route full-page route
Top-level navigation sidebar / tab bar / header nav tab bar (mobile), sidebar (desktop)
Detail-from-list full route / side panel / drawer full route
Filtering / sorting inline controls / popover / drawer inline (small set), drawer (large set)
Search header search / command palette / page header search

For each, show the default and the alternatives. User confirms or picks.

I3 — Motion posture

I3.1 Posture. minimal / restrained / expressive.

I3.2 Animation triggers. For each, yes/no/conditional:

  • Page/route transitions
  • List item enter/exit
  • Modal/drawer open/close
  • State changes (toggle, expand)
  • Loading→loaded transitions

Defaults from the posture choice — show; accept.

I3.3 Reduced motion fallbacks. Confirm prefers-reduced-motion is honored (always yes; this is policy, not preference).

I4 — Breakpoints

I4.1 Count. 2 (mobile / desktop) / 3 (mobile / tablet / desktop) / 4 (with large desktop) / fluid.

I4.2 Values. Defaults: 640 / 768 / 1024 / 1280. Tweakable.

I4.3 Primary target. mobile-first / desktop-first / fluid. Determined by platform.

I5 — i18n

I5.1 Locales at launch. Default: just English (en or en-US).

I5.2 RTL support. yes / no / planned. Default: no in v1.

I5.3 Pluralization. ICU MessageFormat / library / manual. Default: ICU MessageFormat (industry standard).

I5.4 String length budget. Default: assume +30% over English for de/fr translations. Always declared.

I6 — State postures

Four sub-decisions; one declared posture each.

I6.1 Empty state.

  • Visual: icon + heading + body + CTA / heading + body / heading only.
  • Tone: encouraging / neutral / matter-of-fact.
  • CTA: present always / present when actionable / never.

I6.2 Loading state.

  • Default: skeleton / spinner / blocking. Pick one default; assign exceptions.
  • Threshold for showing loading at all: 200ms (default) / 300ms / immediate.

I6.3 Error state.

  • Surface: inline (default) / toast / dialog. By severity class.
  • Recovery: retry / clear path forward / report.
  • Copy tone: plain language always; what happened + what to do next.

I6.4 Offline state.

  • Behavior: full subset works / banner only / "go online to continue".
  • Sync: queue + flush on reconnect / fail loudly / not in v1.

I7 — Time formatting

I7.1 Relative-time threshold. Within <7 days> / <30 days> / <24 hours> / never. Default: 7 days.

I7.2 Absolute format. MMM d, yyyy h:mm a / ISO / locale-aware. Default: locale-aware via Intl.DateTimeFormat.

I7.3 Time zones. user-local / fixed (which?) / configurable. Default: user-local.

I8 — Keyboard

I8.1 Global shortcuts. Y/N for v1. If yes, list them; if no, mark "deferred to vN".

I8.2 Modal escape. Always yes; confirm.

I8.3 Focus trap in modal. Always yes; confirm. Restore on close.

I8.4 Form submit. Enter submits / Cmd+Enter submits / explicit only. Default: Enter submits.

I8.5 List navigation. Arrow keys yes/no. Default: no in v1 unless lists are central.

I9 — Optimistic updates & error recovery

I9.1 Default posture.

  • Optimistic with rollback (default for most actions — feels fast)
  • Pessimistic (default for destructive or money-related actions)
  • Mixed (most actions optimistic; some classes pessimistic)

I9.2 Rollback strategy. Toast + revert / silent revert / dialog. Default: toast + revert.

I9.3 Conflict resolution. Last-write-wins / show conflict UI / append. Default depends on platform.

I10 — Gestures (touch only)

Skip this phase if I1.1 didn't include touch.

I10.1 Swipe actions on rows. Y/N. If yes: which actions, which directions.

I10.2 Long-press menu. Y/N. Default: yes (iOS/Android conventional).

I10.3 Pull-to-refresh. Y/N for list views.

I11 — Focus management

I11.1 After modal close. Restore previous focus (default — non-negotiable for a11y).

I11.2 After route change. Heading focus (default) / container focus / no change.

I11.3 After form error. Focus first error field (default).


Reference banks

When the user names a reference ("like Linear", "like Notion"), apply these presets as starting points — user still confirms each value.

Reference Visual posture Color tone Type Density Motion Radii
Linear quiet, dense, monochrome with one purple accent cool neutral Inter compact restrained, fast tight
Notion minimal, generous spacing, friendly warm-leaning true neutral Inter / system comfortable minimal medium
Stripe clean, technical, indigo accent cool neutral Camphor / system comfortable restrained medium
GitHub utilitarian, dense, clear hierarchy cool true neutral -apple-system stack compact minimal tight
Vercel sharp, monochrome, contrasty true neutral, almost B&W Geist / Inter comfortable restrained, fast tight
Apple HIG spacious, soft, system-native warm-cool mix per platform SF Pro cozy expressive medium
Material 3 adaptive, expressive, dynamic color tone-based dynamic Roboto / Plus Jakarta comfortable expressive pillowy

For "make it look exotic / brutalist / playful / etc.", branch cleanly: ask for two or three reference URLs the user has in mind, and reflect them back as a posture sentence rather than picking presets.

Write phase

After the interview ends, write all six files in one batch:

  1. .claude/skills/<slug>-design-system/SKILL.md from ${CLAUDE_PLUGIN_ROOT}/templates/design-system/SKILL.md — substitute slug, project name, and all interview answers.
  2. .claude/skills/<slug>-design-system/tokens.ts from ${CLAUDE_PLUGIN_ROOT}/templates/design-system/tokens.ts — fill in all values; <TBD> for skipped phases.
  3. .claude/skills/<slug>-design-system/components.md from ${CLAUDE_PLUGIN_ROOT}/templates/design-system/components.md — vocabulary matched to ia.md.
  4. .claude/skills/<slug>-interaction-design/SKILL.md from ${CLAUDE_PLUGIN_ROOT}/templates/interaction-design/SKILL.md — fill in all interview answers.
  5. docs/planning/design-system.md from ${CLAUDE_PLUGIN_ROOT}/templates/planning-pointers/design-system.md.
  6. docs/planning/interaction-design.md from ${CLAUDE_PLUGIN_ROOT}/templates/planning-pointers/interaction-design.md.

Then tell the user:

Wrote two project skills:
  .claude/skills/<slug>-design-system/      (SKILL.md, tokens.ts, components.md)
  .claude/skills/<slug>-interaction-design/ (SKILL.md)

These auto-load whenever UI work is happening. They should be available
immediately in this session; if you're starting a new session in this
repo, they'll load on the first UI-related prompt.

Items still <TBD> (return-pass worklist):
  • <list any phases that were skipped or had unanswered questions>

Re-entry

Re-running the skill on a project that already has the artifacts:

  1. Read both existing SKILL.md files plus tokens.ts and components.md.
  2. List what's currently set; mark <TBD> items prominently.
  3. Ask: "Update everything, just the TBDs, or pick a phase?"
  4. Run only the chosen scope.
  5. Always show a diff before writing.

Hard rules

  • Always produce all six files. Mocks can't proceed without them.
  • Always slug-namespace so projects on the same machine don't collide.
  • <TBD: ...> rather than invent. TBDs are the return-pass worklist.
  • Verify a11y contrast before writing color tokens. Don't silently accept failures.
  • Honor prefers-reduced-motion is policy, not opinion. Always declare it as honored.
  • Confirm before overwriting existing skill files on re-entry.
  • Tell the user what was written and where, plus how to verify the skills load.