From claude-dev-kit
Generates a mobile design system, wireframes, and React Native (Expo) prototype from kickoff outputs (UX spec, requirements, architecture). Run after /prd → /kickoff.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-dev-kit:mobile-uiuxThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- AUTO-GENERATED by scripts/gen_skills.py — DO NOT EDIT. Edit SKILL.md.tmpl instead. -->
Run silently at the start:
python3 scripts/kit_update_check.py 2>/dev/null
If exit code is 1 (update available), show the output to the user once. Do not block the workflow.
Run these checks silently at the start. Use results to adapt behavior:
[ -f issues.md ] — if true, this project uses the sprint system. Respect issue numbering and STATUS.md.[ -f docs/sprint_state.md ] — if true and Status shows running, a sprint is active. Be aware of parallel work in worktrees.[ -f docs/prd_digest.md ] — if true, read it for quick project context before starting.gh auth status before any GitHub operation.At the start of this skill, check if contributor mode is enabled:
python3 scripts/kit_config.py get contributor_mode
If the result is true:
python3 scripts/contributor_report.py --skill <name> --step "<step>" --rating <N> --notes "<friction or suggestion>"
/kickoff must be run first so that the following files exist:
docs/ux_spec.md (core input — IA, flows, screen inventory)docs/requirements.md (functional/non-functional requirements)docs/architecture.md (tech stack reference)/kickoff.docs/ux_spec.md — extract screen inventory, IA, flowsdocs/requirements.md — identify UI elements from functional requirementsdocs/architecture.md — confirm tech stack, API endpoints$ARGUMENTS or PRD.md) as supplementary context. If docs/prd_digest.md exists, read it for quick PRD summary.docs/ux_spec.md does not exist:
/kickoff PRD.md first."docs/design_philosophy.md — check if already generated by web /uiuxdocs/copy_guide.md — check if already generated by web /uiux**/*.tsx, **/*.ts, app.json, app.config.js, app.config.ts5.5) Check if docs/design_philosophy.md already exists AND contains a "Decision Matrix" section:
Ask the user the following questions to anchor the design direction. These answers become binding constraints for Phase 2. Present all questions at once (not one-by-one) and wait for answers. Also tell the user: "If any of these are hard to answer right now, just say 'skip'. You can also skip the entire interview."
a) Brand Personality: "If this product were a person, who would they be?" (e.g., a luxury hotel concierge, a neighborhood cafe barista, a strict operating room nurse, a playful friend)
b) Emotional Target: "What one emotion do you want users to feel when they see the first screen?" (e.g., trust, curiosity, relief, excitement, calm)
c) Anti-Reference: "What competing product or design should this absolutely NOT look like?" (a feeling you want to avoid, or a specific product name)
d) Aspiration Reference: "Is there a product or brand you'd like to reference for design? (doesn't have to be the same domain)" (e.g., Stripe's cleanliness, Nintendo's playfulness, Aesop's luxury)
5.6) Handle user response:
Case A — User answers (partially or fully): Record answers in memory — these become HARD CONSTRAINTS for Phase 2. If the user skips individual questions, note them as "unconstrained" but still avoid generic defaults.
Case B — User skips the entire interview (says "skip", "pass", etc.):
CHECKPOINT — MANDATORY — NEVER SKIP Verify Phase 1 outputs:
docs/ux_spec.mdexists, PRD was read, interview answers (or auto-derived/reused constraints) are recorded. If any required input is missing: STOP and report to user.
Check if docs/design_philosophy.md already exists:
/uiux):Analyze the product's identity from PRD and UX spec:
WebFetch returns parsed text, not pixels. Asking the model to extract hex values or spring constants from a Mobbin URL via WebFetch is fabrication. Visual references MUST arrive as actual images.
Pick exactly ONE of three paths:
Path (a) — user-provided images (preferred):
.png/.jpg/.webp OR local file paths). App-store screenshots are ideal.≈#…), font category (SF/Roboto/grotesque/serif/mono with weight), spacing/grid, tab bar / nav treatment, dark-mode strategy, presence of glass/blur/elevation. Spring/haptic constants cannot be extracted from a static image — leave those to the Signature Move, not the Reference Anchors.Path (b) — page URLs:
python3 scripts/capture_reference.py <url> --viewport 390x844
This headless-captures the page at a mobile viewport into docs/references/<slug>.png. If the script exits non-zero, STOP this path and switch to Path (a) or Path (c).Path (c) — no images available:
Reference Anchor skipped: no image provided. Pass 1–3 mobile screenshot paths or a page URL (with Playwright/Chrome installed) to populate this section.Anti-reference: WebSearch for anti-reference titles is acceptable. Anti-cues are written from the model's own knowledge of patterns being avoided.
Synthesis (when Path (a) or (b) ran — output goes into docs/design_philosophy.md "Reference Anchors"):
OLED black #000 + #0A0A0A surface, SF Pro Display 34/40 + SF Mono 13) — source image path under docs/references/ OR user-provided image URL/path. Strong = present in the chosen images, specific enough that no Phase 5 implementer can fall back to a Material/HIG default. Fewer-and-deeper beats more-and-shallow.literal_quote: "<exact string>" — <where it appears>. Examples:
literal_quote: "조용한" — set in 48pt SF Pro Display, onboarding heroliteral_quote: "47.2-A" — sample order ID, mono on the order detail screenliteral_quote: "회" — quantity unit in the picker"luxury", "trust") — the literal quote is text/digits/glyphs the prototype renders.≈ and cite the source image.Verbatim render check — Phase 5B is required to render the literal_quote string verbatim in at least one screen file under prototype-mobile/. The Phase 2 CHECKPOINT below verifies the field is populated; Phase 5B verifies it appears in rendered output.
Commit to a BOLD aesthetic direction with mobile lens:
Generate docs/design_philosophy.md:
Haptics.impactAsync(Medium) + scale(0.96) with spring damping=20 stiffness=300 — never opacity dim"translateY(40 → 0) with spring damping=18 stiffness=180, staggered 60ms per child"borderLeftWidth: 4 in colors.accent on the focused/active row only — no background highlight"swipeDownEnabled + Haptic.Light on snap"docs/references/ or a user-provided image URL/path), 1 literal_quote: field (mandatory unless Phase 1.5 was skipped), 3–5 avoided cues with reasons. If step 7.5 took Path (c) and skipped this section, omit it here too and proceed.Present the design philosophy to the user and ask for approval before proceeding.
CHECKPOINT — MANDATORY — NEVER SKIP Verify
docs/design_philosophy.mdexists with: (a) a Signature Move that is numeric/token-specific (not prose-only); (b) either a populated Reference Anchors section OR an explicit "Reference Anchors skipped (no image input)" line; AND (c) when Reference Anchors is present, exactly 2–3 adopted cues (not 1, not 4+), each citing an image path, plus aliteral_quote:field with a concrete word/number/glyph (NOT an adjective like "luxury"). The literal_quote may only be omitted if Phase 1.5 interview was explicitly skipped — in which caseliteral_quote: (skipped — interview not run)must appear instead of the field being absent. If any of (a) / (b) / (c) fails: STOP and fix before proceeding.
docs/design_system_mobile.md reflecting the chosen aesthetic:
allowFontScaling, maxFontSizeMultiplier).ios/android keys for platform-specific valuesdocs/wireframes_mobile.md:
header flex: 0 0 56pt, content flex: 1, action flex: 0 0 88ptpaddingHorizontal: 20, gap: 12paddingBottom: insets.bottom + 16)hero overhangs left edge by -16pt, card bleeds into safe area by 8ptdocs/interactions_mobile.md:
docs/copy_guide.md already exists:
## Mobile Adaptations section.
## Mobile Adaptations section covering:
docs/copy_guide.md:
docs/ux_spec.md, docs/design_philosophy.md, docs/wireframes_mobile.md, docs/interactions_mobile.md, PRD—/–) — use -, comma, period, or colon; no filler verbs (Elevate, Seamless, Unleash, Next-Gen, Revolutionize); no generic person names (John Doe) or startup-slop brand names (Acme, Nexus, SmartFlow); no fake-perfect numbers (99.99%, round 50%) — use organic values. See "Specific AI Tells" in Anti-AI-Slop Rules.
16-a) Accessibility labels (REQUIRED): Ensure copy_guide.md includes accessibilityLabel for EVERY interactive element (buttons, toggles, list items, navigation items, form inputs). Also include state-change announcement strings for VoiceOver/TalkBack (e.g., "Run completed", "Run unchecked"). This is mandatory per NFR accessibility requirements.CHECKPOINT — MANDATORY — NEVER SKIP Verify
docs/design_system_mobile.md,docs/wireframes_mobile.md,docs/interactions_mobile.md, anddocs/copy_guide.mdall exist. Cross-check: every component in wireframes has a definition in design_system_mobile.md. If any output is missing: STOP and generate it before proceeding.
prototype-mobile/ directory structure:
prototype-mobile/
App.tsx
app.json
package.json
babel.config.js
tsconfig.json
.gitignore
src/
types/
index.ts (shared types)
theme/
tokens.ts
typography.ts
spacing.ts
colors.ts
components/
Button.tsx
Card.tsx
Input.tsx
... (as needed per design system)
screens/
... (one .tsx per screen from wireframes)
navigation/
index.tsx
prototype-mobile/package.json:
"main": MUST be "node_modules/expo/AppEntry.js" (NOT "App.tsx")expo, babel-preset-expo, expo-asset — core Expo runtimereact, react-native — framework@react-navigation/native, @react-navigation/native-stack, @react-navigation/bottom-tabs — navigationreact-native-reanimated, react-native-worklets — animation (worklets is required for Reanimated v4+)react-native-gesture-handler, react-native-safe-area-context, react-native-screens — navigation native depsexpo-haptics, expo-status-bar — interaction/UIexpo-font (only if custom fonts are used)~ ranges for Expo ecosystem packagescd prototype-mobile && npm install && npx expo install --fix to resolve exact compatible versions
17-a) Generate prototype-mobile/babel.config.js:babel-preset-expo as presetreact-native-reanimated/plugin — babel-preset-expo handles it automatically (SDK 54+)
17-b) Generate prototype-mobile/.gitignore:prototype-mobile/tsconfig.json:expo/tsconfig.basebabel-plugin-module-resolver (Metro ignores tsconfig paths)prototype-mobile/app.json:
plugins array: ONLY include packages that provide a config plugin (e.g., expo-font). Do NOT include expo-haptics (it has no config plugin)prototype-mobile/src/theme/:
colors.ts — color palette from design systemspacing.ts — spacing scaletypography.ts — font families, scale, Dynamic Type configtokens.ts — re-exports all theme tokens + shadows, radii, motion configprototype-mobile/src/components/:
docs/design_philosophy.md MUST be implemented as a reusable component, hook, or HOC (e.g., <PressSignature>, useEntryStagger(), withSignatureScale()). It must be referenceable from any screen — not duplicated per-screen.20.5) PHASE 5A — Pilot screens & gate (multi-archetype, catches AI slop before full generation):
- Step 1 — Archetype classification & pilot pick:
- Classify every screen in docs/wireframes_mobile.md into one of these mobile archetypes: list/feed, detail/show, form/input, hub/tabs, modal-sheet, onboarding/wizard, empty/cold-start.
- Pick TWO pilot screens from the two most-distinct archetypes present in the inventory (typically one consumption + one input). If only one archetype exists, fall back to a single pilot and note it.
- Step 2 — Pilot-only generation:
- Generate ONLY the 2 pilot .tsx files in prototype-mobile/src/screens/.
- Generate a TEMPORARY minimal prototype-mobile/src/navigation/index.tsx that mounts ONLY the 2 pilots in a Stack (no full tab/drawer setup yet).
- Generate prototype-mobile/App.tsx (SafeAreaProvider + NavigationContainer + theme provider) so the pilots are runnable.
- Do NOT generate the remaining screens or the full navigation yet.
- Step 2.5 — PILOT GATE — observe → critique → specificity → auto-correct → user HOLD
Generator-as-judge fails: the same context that produced the pilot will not reliably catch its own slop. This block routes critique through a separate sub-agent context and runs up to 3 auto-correction cycles before presenting.
Mobile pilots run live in Expo (no PNG capture in this skill), so the critique inputs are the pilot .tsx source + the design system. This is treated as degraded mode by default — record pilot_degraded: no_screenshot_input in the critique log so the user sees the limitation. Do NOT silently skip the critique.
- **Step 2.5.0 — Neutral observation** (mandatory; BEFORE judgment).
For each pilot `.tsx`, write 5 plain factual statements about what would render.
**Banned vocabulary**: `signature move`, `aesthetic`, `archetype`, `philosophy`, `direction`, `taste`, `slop`, `generic`, `bold`, `restrained`, `premium`, brand names, the chosen aesthetic name. Use only colors, sizes, shapes, positions, counts, content categories.
Save to `prototype-mobile/src/screens/<pilot>.observations.md`.
- **Step 2.5.1 — Separate-context critique** (mandatory). Invoke `design-auditor` via the Task tool. **Do NOT inline-critique in the generator's context.**
Pass:
- the pilot `.tsx` path
- `prototype-mobile/src/screens/<pilot>.observations.md`
- `docs/design_philosophy.md`
- `docs/design_system_mobile.md`
Ask for a 6-axis 1–5 score (Philosophy / Hierarchy / Execution / Specificity / Restraint / Variety), one cited evidence per axis referencing observation indices, and a list of slop signals.
Where ui-reviewer's scope applies (state coverage in the pilot, copy usage), invoke `ui-reviewer` separately. Disjoint scopes (ISSUE-013) — surface both outputs.
Save the structured output to `prototype-mobile/src/screens/<pilot>.critique.md`.
- **Step 2.5.2 — Specificity check** (mandatory). Ask design-auditor:
*"Name 3 details visible in this pilot that ONLY make sense for THIS specific product / domain / user. Generic UI primitives don't count. Domain content does count (real entity names, the literal_quote from Reference Anchors, brand-specific shortcuts/units). Fewer than 3 → FAIL."*
The literal_quote (from ISSUE-012) counts as exactly **1** of the 3.
- **Step 2.5.3 — Auto-correction cycle** (hard cap N=3). If any score < 3, specificity FAIL, or slop signals fire:
1. Identify the patch layer (philosophy / system / layout / pilot only).
2. Apply the patch.
3. Re-observe → re-critique → re-specificity.
4. Increment cycle counter. Append to `prototype-mobile/src/screens/<pilot>.cycles.log`:
`cycle N: layer=<L> change="<summary>" scores=P5 H4 E5 S3 R5 V4 specificity=PASS|FAIL`.
5. **Hard stop at N=3.** After cycle 3, freeze and surface to the user with the full history.
Record final scores at the top of the pilot screen file: `// pre-emit critique cycle=N: P5 H4 E5 S4 R5 V5 specificity=PASS`.
- **Step 3 — PILOT GATE — present and HOLD for user** (do not auto-proceed):
- Tell the user how to run:
```bash
cd prototype-mobile && npx expo start --ios # or --android
```
- Share `prototype-mobile/src/screens/<pilot>.critique.md` and `<pilot>.cycles.log`.
- Ask: "Please run the pilots on simulator/emulator and confirm:
(a) Is the **Signature Move** (`<paste exact text>`) visible and applied on both pilots?
(b) Do both pilots feel like `<aesthetic name>` and read as the same family across the two archetypes?
(c) Do the 3 product-specific details from the specificity check belong to *this* product?
(d) Any slop signals — generic Material/HIG defaults, default Inter/SF feel, flat spring physics, missing haptics?"
- WAIT for explicit approval before continuing to Phase 5B.
- **Step 4 — On rejection** (route to the correct layer):
- Signature Move wrong/absent → revisit Phase 2 step 9.
- Color / type / spring tokens off → revisit Phase 3 design system.
- Layout reads as generic → revisit Phase 4 numeric layout commitments.
- Tokens are right but pilot implementation is generic → fix the pilot `.tsx` and components only.
- Do NOT proceed to Phase 5B with an unaddressed pilot rejection.
prototype-mobile/src/screens/:
docs/copy_guide.mdprototype-mobile/src/navigation/index.tsx:
prototype-mobile/App.tsx if the full navigation needs additional providers or status bar config beyond what the pilot version already set up.package.json "main" is "node_modules/expo/AppEntry.js" (NOT "App.tsx")babel-preset-expo and expo-asset are in dependenciesreact-native-worklets is in dependencies (required for Reanimated v4+)babel.config.js uses ONLY babel-preset-expo preset (no manual reanimated plugin)app.json does NOT reference non-existent asset filesapp.json plugins does NOT include packages without config plugins (e.g., expo-haptics)tsconfig.json exists with "extends": "expo/tsconfig.base".gitignore existssrc/screens/ and src/components/ for hardcoded style valuessrc/theme/docs/wireframes_mobile.mdsrc/screens/docs/copy_guide.md, not placeholder textdocs/design_philosophy.md MUST be fully implemented with Reanimated worklet codeuseReducedMotion() MUST be respected globally, not just in one component
28.3) Contrast sweep (CRITICAL — catches the failures that ship most):<Text> color (ink-on-ink). Most-missed: text in a card that switched backgroundColor but kept the default ink color.file:component, fix, and re-check before proceeding.
28.4) State & motion mechanics sweep:TextInput fields satisfy the state rules from Anti-AI-Slop ("Motion & input mechanics"): constant borderWidth, input height == button height, reserved helper/error slot, multi-channel disabled.transform/opacity (no layout props); overshoot springs appear only on gesture-driven interactions, not incidental state changes; no element stacks multiple simultaneous effects.file:line, fix, and re-sweep.
28.5) Signature Move check:docs/design_philosophy.md must contain a Signature Move with numeric/token specificity (not prose-only).src/components/ or src/theme/..tsx file in src/screens/ (including the pilots) must reference that reusable Signature Move primitive at least once.literal_quote: from docs/design_philosophy.md Reference Anchors.src/screens/*.tsx for the literal string. The string MUST appear verbatim in at least one screen file (inside a string literal, NOT inside a comment).literal_quote: "47.2-A" MUST appear as the literal characters 47.2-A — not 47-2-A, not interpolated from a variable, not inside {/* */}.React.memouseCallback
29.5) AI Tell sweep (CRITICAL):.tsx file in src/screens/ and src/components/ for the banned tells in "Specific AI Tells" (Anti-AI-Slop Rules): em-dash (—/–) in any string literal, generic person/brand names, fake-perfect numbers, section-number eyebrows, version labels, <View>-based fake product UI, decorative status dots, locale/time strips, scroll cues.file:line, fix it, and re-sweep. Zero tolerance on em-dash and View-based fake product UI — these must be 0 before presenting.cd prototype-mobile
npx expo start --ios # iOS Simulator (requires Xcode)
npx expo start --android # Android Emulator (requires Android Studio)
npm install && npx expo install --fix)issues.md or STATUS.md updates./kickoff has already created issues, if additional UI/UX-related issues are needed, add them manually to issues.md or re-run /kickoff.docs/ux_spec.md not found: stop and suggest running /kickoff first (unless user explicitly opts to skip).docs/ cannot be created: stop and report filesystem error.docs/design_system_mobile.md./mobile-uiux overwrites all outputs — safe to retry.prototype-mobile/) can be safely deleted if not needed.These rules prevent Claude from converging on generic, forgettable mobile defaults.
Primary anchor — the Signature Move. The single most effective slop-blocker is the numeric/token-specific Signature Move defined in Phase 2 step 9 and enforced at the Phase 5A pilot gate (step 20.5) and Phase 5.5 step 28.5. Negative rules below are secondary; if the Signature Move is weak or missing, the rules below will not save the output.
NEVER:
INSTEAD:
allowFontScaling and maxFontSizeMultiplierSpecific AI Tells (hard bans — sweep every screen before presenting). Concrete signatures LLMs default to. Banned unless the brief explicitly calls for one.
Content & data:
99.99%, round 50%, 1,234,567) → organic messy values (47.2%, +1 (312) 847-1928).—) and en-dash-as-separator (–): zero tolerance in all visible text (titles, labels, body, empty/error copy). Use a regular hyphen -, comma, period, colon, or line break. The single most-violated tell.Fake product UI:
<View> rectangles (fake chart, fake feed, fake map) to fill a hero/onboarding slide. Use a real screenshot, generated image, real component, or skip it.v0.6.2-rc.1, last sync 4s ago) as decoration.Decorative meta:
001 · Capabilities) or 01 / 4 pagination labels — name the topic in plain language.V0.6, BETA, EARLY ACCESS, ALPHA) unless the brief is explicitly a launch/preview.Lisbon 14:23 · 18°C), no scroll cues (↓ Scroll), no mono-caps decoration strips (BRAND. MOTION. SPATIAL.).· to max 1 per metadata line; never as a universal separator.Typography & interaction tells:
fontStyle: 'italic' on title/display/hero-stat <Text> is a top tell. Emphasis = weight, accent colour, or a drawn underline. Italic only inside running body copy.Motion & input mechanics (React Native):
transform / opacity in Reanimated worklets; never animate layout props (width, height, margin, padding, top, left) that trigger re-layout per frame.TextInput states: keep borderWidth constant across default/focus/error (change borderColor/background, never width — it shifts layout); input height == adjacent button height (44pt floor); reserve the helper/error slot height so an appearing error doesn't push content; disabled needs three channels — dimmed style + editable={false} + accessibilityState={{ disabled: true }} (never opacity alone).<div>, no media queries. Use React Native primitives (View, Text, Pressable, FlatList, etc.).docs/design_philosophy.md and docs/copy_guide.md from web /uiux when they exist. Don't duplicate, extend.npx claudepluginhub pillip/claude-dev-kit --plugin claude-dev-kitEstablishes a design philosophy from kickoff outputs and generates a design system, wireframes, and HTML prototypes. Run /kickoff first.
Designs iOS/Android mobile app screens, UIs, flows via 5-phase process: discovery questions, brief confirmation, specs. Triggers on screen/UI/flow design requests.
Use when asked to design iOS or Android mobile app screens, create mobile UI, spec mobile flows, or produce screen designs for a native app. Examples: "design the onboarding screens", "spec the checkout flow for iOS", "design a home screen for Android", "create mobile UI for this feature".