К основному содержанию
скилл CX Codex

motion-principles — скилл для Claude Code: обзор и установка

Скилл задаёт правила интерфейсной анимации: безопасные свойства, тайминги, кривые разгона и режим reduced-motion для веба, SwiftUI и Jetpack Compose.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add AThevon/genjutsu --skill motion-principles -a claude-code
Открыть на GitHub

Что делает motion-principles

Скилл формулирует правила движения для интерфейсов на вебе и в мобильных приложениях. Внутри собраны таблицы таймингов под микродействия вроде переключателей (100–150 мс) и экранные переходы (до 500 мс). Главный принцип частоты прост. Чем чаще срабатывает действие, тем быстрее и незаметнее должен быть эффект.

Набор запретов отсекает частые ошибки вёрстки. Скилл запрещает анимировать width, height, top или left, так как это запускает перерасчёт раскладки на каждом кадре и вызывает лаги. Вместо этого он переводит анимации на transform, offset или graphicsLayer. Элементы при скрытии не сжимаются до scale(0), а плавно уходят через scale(0.95) с затуханием прозрачности.

Поддержка reduced-motion здесь обязательна. Правила включают готовые сниппеты для CSS, хуков SwiftUI и Compose. Обратите внимание: данные привязаны к ревизии от 2026-09-08 в _jutsu/VERSIONS.md, поэтому перед переносом в продакшен стоит сверить версии библиотек с первоисточниками.

Какие задачи решает

  • подобрать длительность и кривую разгона для модального окна или тултипа
  • переписать анимацию размера на аппаратные свойства трансформации
  • настроить системный режим reduced-motion в CSS, SwiftUI или Jetpack Compose
  • перенести параметры CSS-кривых в нативные пружины SwiftUI и Compose

Примеры запросов агенту

  • Настрой появление всплывающего окна по правилам motion-principles на чистом CSS
  • Проверь карточку в SwiftUI: замени анимацию frame на offset и добавь проверку accessibilityReduceMotion
  • Подбери параметры пружины в Jetpack Compose для закрытия бокового меню без масштабирования в ноль

Как установить motion-principles

1Через Skills CLI (Vercel)

npx skills add AThevon/genjutsu --skill motion-principles -a claude-code

2Вручную: положить файлы

~/.claude/skills/motion-principles/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/motion-principles/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о motion-principles

Как установить motion-principles в Claude Code?

Выполните в терминале команду npx skills add AThevon/genjutsu --skill motion-principles -a claude-code.

Что делает скилл motion-principles?

Он задаёт базовые стандарты моушн-дизайна для Web, SwiftUI и Compose. Агент опирается на эти правила, чтобы подбирать длительность, кривые скорости и безопасные свойства трансформации без падения частоты кадров.

Почему скилл запрещает анимировать ширину и высоту напрямую?

Изменение свойств width, height, top и left заставляет браузер или мобильный движок пересчитывать геометрию раскладки на каждом кадре. Скилл требует заменять их на смещения через transform, offset или graphicsLayer.

Исходный текст

SKILL.md · MIT
---
name: motion-principles
description: "Motion design foundation - timing, easing, enter/exit patterns, accessibility, performance."
metadata:
  internal: true
---

> **Version-sensitive.** Every API name, SDK gate and browser-support claim below was
> verified on **2026-09-08** against primary sources. What against, and when, is in
> `_jutsu/VERSIONS.md`. If that date is old, re-verify before acting on a version number.

# Motion Principles

> The foundation. Loaded by every creative skill invocation.
> Concise rules here. Deep-dive in `references/`.

---

## Timing Rules

| Context | Duration | Why |
|---|---|---|
| Micro-interaction (toggle, hover, focus) | 100-150ms | Instant feedback, no perceived delay |
| UI transition (modal, drawer, tab switch) | 200-300ms | Smooth but never sluggish |
| Page/route transition | 300-500ms | Establishes spatial narrative |
| Scroll-driven / 3D | Free (progress-based) | Tied to user input, no fixed duration |

**Frequency rule:** The more often an animation plays, the shorter and subtler it must be.
A button hover (1000x/day) = 100ms opacity. An onboarding reveal (1x ever) = 600ms+ full choreography.

---

## Easing Cheat Sheet

| Action | Easing | Why |
|---|---|---|
| Element enters | `ease-out` / spring | Decelerates into resting position (natural arrival) |
| Element exits | `ease-in` | Accelerates away (gets out of the way) |
| Element moves between states | `ease-in-out` | Smooth start and stop |
| Scroll-synced | `linear` / `none` | Matches 1:1 with input, no lag perception |
| Bouncy/playful | spring (underdamped) | Overshoot creates life |
| Snappy UI | `cubic-bezier(0.2, 0, 0, 1)` | Fast start, smooth land |

> **Exit is always more subtle than enter.**
> Enter: 300ms ease-out, full choreography. Exit: 200ms ease-in, opacity only.

### Native easing equivalents (cross-platform)

| Web (CSS / JS) | SwiftUI | Compose |
|---|---|---|
| `cubic-bezier(0.2, 0, 0, 1)` | `.spring(response: 0.4, dampingFraction: 0.85)` or `.snappy` | `spring(stiffness = Spring.StiffnessMedium, dampingRatio = 0.85f)` |
| `ease-out` | `.easeOut(duration: 0.3)` | `tween(durationMillis = 300, easing = LinearOutSlowInEasing)` |
| `ease-in` | `.easeIn(duration: 0.2)` | `tween(durationMillis = 200, easing = FastOutLinearInEasing)` |
| spring (bouncy) | `.bouncy` (iOS 17+) | `spring(stiffness = Spring.StiffnessLow, dampingRatio = Spring.DampingRatioMediumBouncy)` |
| spring (smooth) | `.smooth` (iOS 17+) | `spring(stiffness = Spring.StiffnessMedium, dampingRatio = Spring.DampingRatioNoBouncy)` |

---

## Accessibility (Non-Negotiable)

### Reduced motion - MANDATORY

Every animated component must respect the user's reduced-motion preference. No exceptions, regardless of platform.

| Platform | API |
|---|---|
| Web CSS | `@media (prefers-reduced-motion: reduce)` |
| Web JS | `window.matchMedia('(prefers-reduced-motion: reduce)')` |
| SwiftUI | `@Environment(\.accessibilityReduceMotion) var reduceMotion` |
| UIKit | `UIAccessibility.isReduceMotionEnabled` (+ `reduceMotionStatusDidChangeNotification`) |
| Compose | Custom helper using `Settings.Global.ANIMATOR_DURATION_SCALE` (deep-dive in `mobile-principles/references/accessibility-mobile.md`) |

**CSS:**
```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
```

**SwiftUI:**
```swift
struct AnimatedView: View {
    @Environment(\.accessibilityReduceMotion) var reduceMotion
    @State var visible = false

    var body: some View {
        Text("Hello")
            .opacity(visible ? 1 : 0)
            .animation(reduceMotion ? .none : .spring(response: 0.4, dampingFraction: 0.85), value: visible)
    }
}
```

**Compose:**
```kotlin
@Composable
fun rememberReduceMotion(): Boolean {
    val context = LocalContext.current
    return remember {
        Settings.Global.getFloat(context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f) == 0f
    }
}

@Composable
fun AnimatedComponent(visible: Boolean) {
    val reduce = rememberReduceMotion()
    val alpha by animateFloatAsState(
        targetValue = if (visible) 1f else 0f,
        animationSpec = if (reduce) snap() else spring(stiffness = Spring.StiffnessMedium)
    )
}
```

### Other a11y requirements
- Focus indicators must never be hidden by animations
- Animated content must meet WCAG contrast ratios at every frame (no mid-transition fading to invisible text)
- Looping animations: provide a pause mechanism

---

## Universal "Do Not" Rules

### 1. Never animate width/height/top/left

Triggers layout recalculation every frame = jank.

```css
/* BAD */
.drawer { transition: height 0.3s ease; }
.drawer.open { height: 400px; }

/* GOOD */
.drawer { transition: transform 0.3s ease-out; transform: translateY(100%); }
.drawer.open { transform: translateY(0); }
```

**SwiftUI equivalent (BAD vs GOOD):**
```swift
// BAD - animates frame (causes layout pass)
.frame(height: open ? 400 : 0)
.animation(.easeInOut, value: open)

// GOOD - animates transform via offset
.offset(y: open ? 0 : 400)
.animation(.spring(), value: open)
```

**Compose equivalent (BAD vs GOOD):**
```kotlin
// BAD - animates size (full layout pass)
val height by animateDpAsState(if (open) 400.dp else 0.dp)

// GOOD - animates Y offset via graphicsLayer
val translation by animateFloatAsState(if (open) 0f else 400f)
Box(modifier = Modifier.graphicsLayer { translationY = translation })
```

### 2. Never scale to 0

`scale(0)` causes elements to vanish in a black hole. Always keep a minimum.

```css
/* BAD */
.modal-exit { transform: scale(0); }

/* GOOD */
.modal-exit { transform: scale(0.95); opacity: 0; }
```

**SwiftUI equivalent:**
```swift
// BAD
.scaleEffect(visible ? 1.0 : 0.0)

// GOOD
.scaleEffect(visible ? 1.0 : 0.95)
.opacity(visible ? 1.0 : 0.0)
```

**Compose equivalent:**
```kotlin
// BAD
Modifier.graphicsLayer { scaleX = if (visible) 1f else 0f; scaleY = if (visible) 1f else 0f }

// GOOD
Modifier.graphicsLayer {
    scaleX = if (visible) 1f else 0.95f
    scaleY = if (visible) 1f else 0.95f
    alpha = if (visible) 1f else 0f
}
```

### 3. Never ease-in on an entry

Ease-in = slow start. An entering element that hesitates feels broken.

```css
/* BAD */
.card-enter { animation: fadeIn 0.3s ease-in; }

/* GOOD */
.card-enter { animation: fadeIn 0.3s ease-out; }
/* OR spring via JS for natural feel */
```

### 4. Never exceed 500ms on a UI interaction

Modals, dropdowns, tooltips, tabs -- users are waiting. Respect their time.

```js
// BAD
gsap.to(modal, { opacity: 1, y: 0, duration: 0.8 });

// GOOD
gsap.to(modal, { opacity: 1, y: 0, duration: 0.25, ease: "power2.out" });
```

**SwiftUI:**
```swift
// BAD
.animation(.easeInOut(duration: 0.8), value: state)

// GOOD
.animation(.spring(response: 0.25, dampingFraction: 0.85), value: state)
```

**Compose:**
```kotlin
// BAD
animateContentSize(animationSpec = tween(800))

// GOOD
animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessMediumLow))
```

### 5. Never skip prefers-reduced-motion

This is an accessibility requirement, not a nice-to-have.

```js
// BAD
gsap.from('.hero-title', { opacity: 0, y: 40, duration: 0.6 });

// GOOD
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!prefersReduced) {
  gsap.from('.hero-title', { opacity: 0, y: 40, duration: 0.6 });
}
```

> See the cross-platform Reduced Motion section above for SwiftUI / Compose equivalents.

---

## Performance Checklist

- Only animate `transform` and `opacity` (composite-only properties)
- Use `will-change` sparingly and remove it after animation completes
- Prefer `requestAnimationFrame` over `setTimeout`/`setInterval` for JS animations
- For scroll-driven: CSS `animation-timeline` > JS `IntersectionObserver` > scroll listeners
- Test on low-end devices (throttle CPU 4x in DevTools)

---

## Quick Reference: Loading Sub-skills

| Need | Load |
|---|---|
| Easing deep-dive, spring configs | `references/easing-guide.md` |
| Copy-paste enter/exit patterns | `references/enter-exit-recipes.md` |
| Designer-weighted style choice | `references/designers.md` |
| Mobile UX context | `../mobile-principles/SKILL.md` |
| Desktop UX context | `../desktop-principles/SKILL.md` |
| GSAP specifics | `../gsap/SKILL.md` |
| Framer Motion specifics | `../framer-motion/SKILL.md` |
| CSS-only animations | `../css-native/SKILL.md` |
| Three.js / R3F | `../threejs-r3f/SKILL.md` |
| Canvas / generative | `../canvas-generative/SKILL.md` |
| Compose Android animations | `../compose-motion/SKILL.md` |
| Compose Multiplatform | `../compose-multiplatform/SKILL.md` |
| SwiftUI iOS/macOS animations | `../swiftui-motion/SKILL.md` |
| Compose advanced graphics | `../compose-graphics/SKILL.md` |
| SwiftUI advanced graphics | `../swiftui-graphics/SKILL.md` |
| Visual / motion / a11y audit | `../design-audit/SKILL.md` |
| UI/UX intelligence (84 styles, 192 palettes) | `../ui-ux-pro-max/SKILL.md` |

© AThevon · MIT · AThevon/genjutsu

Похожие скиллы

Всё по теме «Фронтенд и UI» →
design-motion-principles kylezantos Создаёт и проверяет анимации интерфейса с учётом контекста продукта и частоты действий. Нужен для переходов, состояний наведения и микровзаимодействий. CX Codex +1 12 700установок motion-design LottieFiles Скилл помогает проектировать анимации интерфейса: выбирать длительность, easing и последовательность движения. Пригодится для микровзаимодействий, загрузки и переходов между страницами. CX Codex +1 19 900установок motion-system Owl-Listener Задаёт единый набор длительностей, кривых и правил для анимаций в продукте. Пригодится, когда у каждого компонента свои тайминги. CX Codex +1 1 800установок accessible-motion dylantarre Скилл помогает заменить опасные анимации на безопасные альтернативы и соблюсти требования WCAG по движению. Пригодится, когда в интерфейсе есть параллакс, зум или бесконечные циклы. CX Codex +1 640установок motion-sickness dylantarre Помогает найти и убрать в интерфейсе анимации, от которых кружится голова: параллакс, зум, вращение. Пригодится, когда пользователи жалуются на тошноту при навигации. CX Codex +1 483установок animation-principles iart-ai Скилл задаёт физику и тайминги интерфейсной анимации. Он выдаёт точные кривые cubic-bezier, задержки шагов и длительности в миллисекундах. CX Codex +1 3 000установок

Из того же набора17

ui-ux-pro-max Подбирает дизайн-системы, палитры и шрифтовые пары под стек и тип продукта через локальную базу правил. Пригодится при вёрстке интерфейсов и проверке доступности. CX Codex +1 948установок cast Скилл для творческого кодинга: превращает статичный интерфейс в живой — движение, микроинтеракции, отклик на действия. Работает с Web, Android (Compose) и Apple (SwiftUI). CX Codex +1 1 300установок paint Запускает пайплайн дизайн-системы для веба, Compose и SwiftUI: от брейншторма арт-дирекшна до кода и аудита доступности. CX Codex +1 1 300установок design-audit Проверяет код фронтенда на проблемы с анимацией, доступностью и дизайн-токенами. Находит визуальные штампы ИИ и ошибки вёрстки перед сдачей проекта. CX Codex +1 1 000установок threejs-r3f Скилл по Three.js и React Three Fiber: правила сцен, хуков, постобработки и производительности. Пригодится, когда агент пишет 3D на React. CX Codex +1 1 000установок css-native Скилл для ИИ-агента, который подсказывает, как делать анимации и визуальные эффекты на нативном CSS без библиотек. CX Codex +1 1 100установок gsap Скилл помогает агенту писать анимации GSAP: таймлайны, каскадные эффекты и ScrollTrigger. Нужен для сложных движений и прокрутки. CX Codex +1 997установок canvas-generative Скилл для алгоритмической графики на Canvas 2D: частицы, flow fields, шум, фракталы и L-системы. Пригодится, когда нужна анимация или генеративная картинка в браузере. CX Codex +1 995установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой