원클릭으로
design-audit
Design audit checklist - motion gaps, accessibility, color consistency, responsive, performance.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Design audit checklist - motion gaps, accessibility, color consistency, responsive, performance.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Cast genjutsu on a UI - creative coding for motion, micro-interactions, and wow-factor. Scans the stack, proposes an interaction thesis, loads the right sub-skills, implements the illusion. Adapts to Web, Android (Compose), Apple (SwiftUI).
Paint a complete visual universe with genjutsu - art direction brainstorm, design system, implementation, audit. Anti-AI-slop design pipeline. Adapts to Web, Android (Compose), Apple (SwiftUI).
Algorithmic and generative art with Canvas 2D - particles, flow fields, noise, fractals, L-systems.
Advanced Compose visuals - Material 3 Expressive motion physics, AGSL shaders (Android 13+), Canvas/DrawScope generative, graphicsLayer effects.
Jetpack Compose animation foundations - animate*AsState, AnimatedVisibility, Crossfade, updateTransition, SharedTransitionLayout, gestures.
Compose Multiplatform / KMP patterns - expect/actual composables, platform-specific code, density and font handling cross-target, iOS/Android/Desktop interop.
| name | design-audit |
| description | Design audit checklist - motion gaps, accessibility, color consistency, responsive, performance. |
The final checkpoint. Loaded by
/genjutsu:paintat the end of the pipeline. Scans the codebase for motion gaps, a11y violations, perf issues, and inconsistencies.
Run these greps against the project to detect missing animations.
grep -rn '{.*&&\s*<\|{.*?\s*:\s*<\|{.*ternary.*<' --include='*.tsx' --include='*.jsx' src/ | grep -v 'AnimatePresence'
Look for: {show && <Component />} or ternary renders without a wrapping <AnimatePresence>. Every conditional mount/unmount needs exit animation support.
grep -rn ':hover' --include='*.css' --include='*.scss' --include='*.module.css' src/ | grep -vE 'transition|animation'
Every :hover rule must have a corresponding transition on the base selector. Instant state flips feel broken.
grep -rn '\.map(' --include='*.tsx' --include='*.jsx' src/ | grep -vE 'stagger|delay.*index|variants|transition.*delay'
Lists rendered via .map() should stagger their entrance. Simultaneous pop-in looks cheap.
grep -rn 'style={{' --include='*.tsx' --include='*.jsx' src/ | grep -vE 'transition|transform|opacity'
Inline style changes (e.g., dynamic background, color) need a CSS transition or motion wrapper.
grep -rn 'initial=' --include='*.tsx' --include='*.jsx' src/ | grep -v 'exit='
Every Framer Motion initial + animate should have an exit prop when inside AnimatePresence.
A project with animation MUST have at least one global handler matching its stack. Run all 3 greps:
# Web
grep -rn 'prefers-reduced-motion' --include='*.css' --include='*.scss' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' src/ 2>/dev/null
# SwiftUI / UIKit
grep -rn 'accessibilityReduceMotion\|isReduceMotionEnabled\|reduceMotionStatusDidChangeNotification' --include='*.swift' . 2>/dev/null
# Compose
grep -rn 'LocalAccessibilityManager\|isReduceTransitions\|TRANSITION_ANIMATION_SCALE\|ANIMATOR_DURATION_SCALE\|areTransitionsEnabled' --include='*.kt' . 2>/dev/null
Zero results across all 3 in an animated project = critical violation. At least one handler must exist somewhere. Cross-reference motion-principles/SKILL.md for canonical implementations per stack.
npx pa11y <url> or Lighthouse accessibility auditgrep -rn 'outline:\s*none\|outline:\s*0' --include='*.css' --include='*.scss' --include='*.module.css' src/
Any outline: none MUST be paired with a custom :focus-visible style. Removing focus rings without replacement is a WCAG failure.
grep -rn 'onClick' --include='*.tsx' --include='*.jsx' src/ | grep -E '<div|<span' | grep -v 'role='
Every <div onClick> or <span onClick> must either be a <button>, an <a>, or have role="button" + tabIndex + onKeyDown.
grep -rn '<motion\.\|<animated\.\|<Lottie\|<Canvas' --include='*.tsx' --include='*.jsx' src/ | grep -v 'aria-hidden'
Purely decorative animations (background particles, ambient motion, Lottie illustrations) must have aria-hidden="true" to avoid polluting screen readers.
grep -rn 'transition.*\(width\|height\|top\|left\|right\|bottom\|margin\|padding\)' --include='*.css' --include='*.scss' --include='*.module.css' src/
Animating layout properties triggers reflow every frame. Replace with transform: translate/scale and opacity.
grep -rn 'will-change' --include='*.css' --include='*.scss' --include='*.module.css' src/
will-change should be rare and scoped. If more than ~5 elements use it permanently, the GPU memory cost outweighs the benefit. Apply it dynamically (add on hover/focus, remove on animation end).
Check actual impact:
npx source-map-explorer dist/**/*.js 2>/dev/null || npx vite-bundle-visualizer 2>/dev/null
Reference sizes (gzipped): framer-motion ~30KB, GSAP ~25KB, popmotion ~5KB, CSS-only = 0KB. If the project only uses fade+slide, a 30KB lib is overkill.
On mobile native, the APK / IPA size matters. A third-party animation library adds typically 500KB-2MB:
| Library | Size impact (uncompressed) |
|---|---|
| Lottie (iOS) | ~600KB |
| Lottie (Android) | ~900KB |
| Rive (iOS) | ~1.5MB |
| Rive (Android) | ~2MB |
| Native Compose / SwiftUI animations | 0KB (built-in) |
If the project only uses fades, slides, and springs, native APIs (Compose animate*AsState + spring, SwiftUI withAnimation) are sufficient. Justify a Lottie / Rive dependency only for genuinely complex pre-designed animations (e.g., onboarding illustrations).
grep -rn 'setTimeout\|setInterval' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' src/ | grep -iE 'anim\|motion\|scroll\|position\|style\|transform'
Animation loops must use requestAnimationFrame. setTimeout/setInterval causes frame drops and doesn't pause in background tabs.
grep -rnoE 'duration[:"'\''= ]+[0-9.]+' --include='*.tsx' --include='*.jsx' --include='*.ts' --include='*.css' --include='*.scss' src/ | sort -t: -k3 | uniq -c -f2 | sort -rn
A well-designed project uses 3-5 distinct durations max (e.g., 0.15, 0.25, 0.35, 0.5). If you see 15 different values, extract them into a motion tokens file.
Run all 3 greps to inventory easing values across the codebase:
# Web (CSS / JS / TSX)
grep -rnoE 'ease[A-Za-z]*|cubic-bezier\([^)]+\)|spring\([^)]*\)' --include='*.tsx' --include='*.jsx' --include='*.ts' --include='*.css' --include='*.scss' src/ 2>/dev/null
# SwiftUI
grep -rnoE '\.spring\([^)]*\)|\.snappy|\.bouncy|\.smooth|\.linear\(|\.easeIn|\.easeOut|\.interpolatingSpring' --include='*.swift' . 2>/dev/null
# Compose
grep -rnoE 'spring\([^)]*\)|tween\([^)]*\)|FastOutSlowInEasing|LinearOutSlowInEasing|FastOutLinearInEasing|CubicBezierEasing' --include='*.kt' . 2>/dev/null
Same rule across all stacks: 3-5 named easings max in the design system. Random values scattered across files = visual inconsistency. If the codebase has 12 different cubic-bezier(...) values or 8 custom spring(response:dampingFraction:) configurations, that's a design-system violation, fix it by centralizing into named tokens.
Scan for motion components and verify that:
ease-out, exit uses ease-ingrep -A5 'exit=' --include='*.tsx' --include='*.jsx' -rn src/
Compare animate and exit props side by side. Asymmetric timing (fast exit, slow enter) is correct. The reverse is wrong.
Pick the subsection matching the project stack.
androidx.benchmark.macro): measure frame timing on a real device under representative scrolling / animation load. Target: <16.67ms per frame at 60fps, <8.33ms at 120fps.Modifier.recomposeHighlighter() (Compose 1.6+) or Layout Inspector.BaselineProfileGenerator) for production builds.Modifier.semantics is set on custom components (TalkBack support)..accessibilityLabel / .accessibilityHint on every interactive view.Environment Overrides in Xcode).Structure findings by severity:
prefers-reduced-motion handlingoutline: none without :focus-visible replacementAnimatePresencearia-hidden on decorative animationssetTimeout used for animation loopswill-change usage