diff --git a/composer/skills/ui-system/SKILL.md b/composer/skills/ui-system/SKILL.md index d65bf42..b97d657 100644 --- a/composer/skills/ui-system/SKILL.md +++ b/composer/skills/ui-system/SKILL.md @@ -1,137 +1,420 @@ --- name: ui-system -description: 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/-design-system/ and .claude/skills/-interaction-design/, NOT docs/planning/. The skills load themselves into context when anyone codes UI (mock or real); a plain reference doc would not. Currently a placeholder skill that captures the minimum needed for downstream phases to proceed; planned for a fuller specification pass. Use when the composer skill reaches phase 4 or 5, or when the user asks to "set up the design system" or "specify interaction patterns." +description: 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/-design-system/ and .claude/skills/-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 (placeholder) +# UI system -> **Status: PLACEHOLDER.** This skill currently captures the minimum -> design-system and interaction-design content needed for the mocks -> phase to proceed. A fuller specification pass is planned. When the -> user returns to flesh this out, expand the interview sections below -> and the SKILL.md / sidecar templates. - -## Why this is a skill, not a doc - -A reference document at `docs/planning/design-system.md` gets read once -and then drifts out of context as the conversation grows. UI work that -happens later — generating a mock, writing a component, picking a color — -won't have it loaded. - -A **skill** with a description that triggers on UI work is loaded -automatically every time the trigger matches. That's the whole point of -the skill mechanism. The design system and interaction design must be -skills. - -## What this skill produces - -Two project-local skills, plus their sidecar data files: +You run a focused interview that produces two project-local skills: ``` .claude/skills/-design-system/ -├── SKILL.md ← the skill itself; auto-loads on UI work -├── tokens.ts ← machine-readable color / type / spacing / motion tokens -└── components.md ← component vocabulary with anatomy +├── 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/-interaction-design/ -└── SKILL.md ← interaction patterns, state surfaces, input modes, i18n +└── SKILL.md ← interaction patterns, state surfaces, input modes, i18n ``` -And two stub pointer files in `docs/planning/` so the planning index -finds them: +Plus pointer stubs in `docs/planning/{design-system,interaction-design}.md` +so the planning index finds them. -``` -docs/planning/design-system.md ← pointer; tells humans where the skill lives -docs/planning/interaction-design.md ← pointer -``` +## 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 -The skills need a project slug for their `name:` frontmatter, so they -don't collide with skills from other projects on the same machine. +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. -Resolution order: -1. If `package.json` has a `name`, slugify it. -2. Else if a git remote exists, slugify the repo name. -3. Else ask the user. Default to the directory name. +Slug rule: lowercase kebab-case, ASCII only. +`SourdoughTracker` → `sourdough-tracker` → `sourdough-tracker-design-system`. -Slug rule: lowercase, hyphenated, kebab-case, ASCII only. Example: -`SourdoughTracker` → `sourdough-tracker` → skill `sourdough-tracker-design-system`. +## Interview shape -## design-system interview (placeholder pass) +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. -Ask the user, in order, with sensible defaults: +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. -1. **Existing material?** Brand assets, mood boards, screenshots, - "make it look like Linear/Notion/Stripe", or nothing. If material - exists, ingest it before asking the rest. -2. **Color**: brand color(s), neutral scale (warm/cool/true), dark mode - (yes/no/system). Offer to generate accessible contrast pairs. -3. **Typography**: one family or two (display + body), size scale base - and ratio, line-height policy. -4. **Spacing**: scale base (4px / 8px), key spacing tokens. -5. **Radii**: tight / medium / pillowy. -6. **Shadows**: flat / subtle / generous. -7. **Visual motion**: default duration, default easing. -8. **Components**: confirm vocabulary against `ia.md`. +The user can answer **`default`** or **`skip`** at any phase: +- `default` → accept the offered default and move on. +- `skip` → mark `` and move on; user can revisit. -Mark unanswered with `` so the return pass has a worklist. +Never invent on the user's behalf. `` is a worklist, not a failure. -### Write phase — design-system +--- -1. Write `.claude/skills/-design-system/SKILL.md` from - `templates/design-system/SKILL.md`. Substitute the slug into the - `name:` field and the project name into the `description:`. -2. Write `.claude/skills/-design-system/tokens.ts` from - `templates/design-system/tokens.ts`. Fill in the values gathered in - the interview; `` for unanswered. -3. Write `.claude/skills/-design-system/components.md` from - `templates/design-system/components.md`. -4. Write `docs/planning/design-system.md` from the pointer template — - one paragraph saying where the skill lives. +## Phase 0 — Material ingestion (silent) -## interaction-design interview (placeholder pass) +Before asking anything, scan for material the user already has. Read +without asking; surface findings before the first question. -Ask, in order: +| 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`, `` 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) | -1. **Primary input**: touch / mouse / keyboard / mixed. Primary, supported, not supported. -2. **State surfaces**: pick one pattern per action class. -3. **Motion**: minimal / restrained / expressive. `prefers-reduced-motion` always honored. -4. **Breakpoints**: count, primary design target. -5. **i18n**: locales planned, RTL, string-length budget. -6. **Empty/loading/error/offline**: one declared posture each. -7. **Time formatting**: relative threshold, absolute format. -8. **Keyboard**: global shortcuts, escape behavior. +Then before the interview opens: -### Write phase — interaction-design +``` +Material I found and will use: + • + • +Not found (will ask): brand color, type family, motion posture. +``` -1. Write `.claude/skills/-interaction-design/SKILL.md` from - `templates/interaction-design/SKILL.md`. -2. Write `docs/planning/interaction-design.md` pointer. +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 50–950 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.1–1.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 (0–4) / tight (4–8) / medium (8–16) / 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/-design-system/SKILL.md` from `templates/design-system/SKILL.md` — substitute slug, project name, and all interview answers. +2. `.claude/skills/-design-system/tokens.ts` from `templates/design-system/tokens.ts` — fill in all values; `` for skipped phases. +3. `.claude/skills/-design-system/components.md` from `templates/design-system/components.md` — vocabulary matched to `ia.md`. +4. `.claude/skills/-interaction-design/SKILL.md` from `templates/interaction-design/SKILL.md` — fill in all interview answers. +5. `docs/planning/design-system.md` from `templates/planning-pointers/design-system.md`. +6. `docs/planning/interaction-design.md` from `templates/planning-pointers/interaction-design.md`. + +Then tell the user: + +``` +Wrote two project skills: + .claude/skills/-design-system/ (SKILL.md, tokens.ts, components.md) + .claude/skills/-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 (return-pass worklist): + • +``` ## Re-entry -When the user returns to flesh this out fully: -- Expand the interviews above. -- Expand the SKILL.md and sidecar templates. -- Both skills are version-controlled in `.claude/skills/` — re-running - this phase shows the user a diff before overwriting. +Re-running the skill on a project that already has the artifacts: -The downstream contract is: `composer-mocks` reads the **skills**, not -the planning pointer files. That contract does not change as the -templates grow. +1. Read both existing SKILL.md files plus tokens.ts and components.md. +2. List what's currently set; mark `` 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 even in placeholder mode +## Hard rules -- **Always produce both skills with sidecars.** Mocks can't proceed without them. +- **Always produce all six files.** Mocks can't proceed without them. - **Always slug-namespace** so projects on the same machine don't collide. -- **Mark unknowns with ``** rather than inventing — TBDs are the return-pass worklist. -- **Don't pretend.** If the user has nothing and no opinions, say so in the SKILL.md: "No design direction set; defaults applied. Revisit before mocks are committed." -- **Tell the user what just happened.** After write, print: - ``` - Wrote two project skills: - .claude/skills/-design-system/SKILL.md - .claude/skills/-interaction-design/SKILL.md - These auto-load whenever UI work is happening. Verify after restart - with /agents (they should appear as project-local skills). - ``` +- **`` 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. diff --git a/composer/templates/design-system/SKILL.md b/composer/templates/design-system/SKILL.md index ae6f39c..4c06098 100644 --- a/composer/templates/design-system/SKILL.md +++ b/composer/templates/design-system/SKILL.md @@ -1,94 +1,140 @@ --- name: -design-system -description: Design system for the project. Color tokens, typography, spacing, radii, shadows, motion durations, and component vocabulary. Load and apply whenever building UI for this project — generating mocks, writing components, picking colors, configuring Tailwind, styling native screens, building themes, designing CSS, or making any visual decision. The canonical visual reference for this project; if anything visible is being touched, this skill should be in context. Pairs with -interaction-design. +description: Design system for the project. Color tokens, typography, spacing, radii, shadows, density, motion, accessibility tokens, and component vocabulary. Load and apply whenever building UI for this project — generating mocks, writing components, picking colors, configuring Tailwind, styling native screens, building themes, designing CSS, or making any visual decision. The canonical visual reference for this project; if anything visible is being touched, this skill should be in context. Pairs with -interaction-design. --- # design system > **Status: ** > Generated by Composer's `ui-system` phase. Re-running that phase -> updates this skill (with confirmation). +> updates this skill (with confirmation on overwrite). ## How to use this skill -Whenever you generate or edit UI for this project — a mock, a real -component, a theme, a CSS file — read this SKILL.md and the sidecar -files first, then use the tokens. Do not hardcode values. Do not -introduce new components without proposing them here first. +When generating or editing UI for this project — a mock, a real +component, a theme, a CSS file — read this SKILL.md and `tokens.ts` +first, then use the tokens. Never hardcode visual values. Don't +introduce new components without proposing them in `components.md`. Sidecar files in this skill directory: - `tokens.ts` — machine-readable token export. Import in mocks/code. -- `components.md` — component vocabulary with anatomy. +- `components.md` — component vocabulary, anatomy, states. ## Visual posture - + - + ## Color ### Brand -- Primary: `<#hex>` — -- (Secondary, if any): `<#hex>` — +- **Primary**: `<#hex>` — +- **Secondary** *(if any)*: `<#hex>` — ### Neutrals -- Tone: -- Scale: 50 / 100 / 200 / 300 / 400 / 500 / 600 / 700 / 800 / 900 / 950 +- **Tone**: +- **Scale**: 50 / 100 / 200 / 300 / 400 / 500 / 600 / 700 / 800 / 900 / 950 +- See `tokens.ts` for hex values. ### Semantic -| Role | Value | -|---|---| -| Success | `<#hex>` | -| Warning | `<#hex>` | -| Error | `<#hex>` | -| Info | `<#hex>` | +| Role | Light | Dark *(if dark mode)* | +|---|---|---| +| Success | `<#hex>` | `<#hex>` | +| Warning | `<#hex>` | `<#hex>` | +| Error | `<#hex>` | `<#hex>` | +| Info | `<#hex>` | `<#hex>` | ### Dark mode - +- **Posture**: +- **Token mapping**: see `tokens.ts` `colorDark` (if applicable) + +### Accessibility contrast +- **Target**: WCAG +- **Verified pairings** (against `neutral.50` light bg, `neutral.950` dark bg): + - body text: — ✅ + - UI components: — ✅ + - ## Typography - **Display family**: , weights -- **Body family**: , weights -- **Scale base**: , ratio <1.125 | 1.2 | 1.25 | 1.333> -- **Sizes**: xs / sm / base / lg / xl / 2xl / 3xl / 4xl -- **Line-height**: tight for display, normal for body, relaxed for long-form prose - -See `tokens.ts` for exact px values. +- **Body family**: , weights +- **Mono family** *(if used)*: +- **Scale base**: , ratio <1.125 | 1.2 | 1.25 | 1.333 | 1.5> +- **Sizes**: see `tokens.ts` `fontSize` — xs / sm / base / lg / xl / 2xl / 3xl / 4xl +- **Line-height**: + - Tight (display): + - Normal (body): + - Relaxed (long-form): +- **Letter-spacing** *(if customized)*: ## Spacing - **Base unit**: <4px | 8px> - **Scale (in base units)**: 0, 0.5, 1, 1.5, 2, 3, 4, 6, 8, 12, 16, 24 +- See `tokens.ts` `spacing` for px values. ## Radii -- `sm`, `md`, `lg`, `pill`, `full` — values in `tokens.ts`. +- **Posture**: +- `sm` · `md` · `lg` · `pill` 9999px · `full` 9999px -## Shadows +## Shadows & elevation -- `xs / sm / md / lg / xl` — values in `tokens.ts`. -- (Or: "flat — no shadows" if the posture is flat.) +- **Posture**: +- Scale: `xs / sm / md / lg / xl` — see `tokens.ts` `shadow` +- (Or "no shadows in this system" if posture is flat — use borders for elevation hierarchy.) + +## Density + +- **Default**: +- **Padding tokens**: see `tokens.ts` `padding` — `tight / default / loose` +- **Component impact**: list components whose default density differs from the global default. ## Visual motion -- **Default duration**: -- **Default easing**: +- **Default duration**: (token: `motion.duration.default`) +- **Default easing**: (token: `motion.easing.standard`) +- **Reduced-motion fallback**: linear, instant where appropriate -Behavioral motion (when things animate, what does and doesn't) lives -in the interaction-design skill. +Behavioral motion (when things animate, what triggers them) is in the +**interaction-design** skill, not here. + +## Accessibility tokens + +- **Focus ring**: