Skip to content
cccskills
FreePublished on GitHub

motion-principles

Motion design foundation - timing, easing, enter/exit patterns, accessibility, performance.

The English summary is being prepared. Showing the original description.

See how to install

Files included (4)

  • SKILL.md8.9 KB
  • references/designers.md5.5 KB
  • references/easing-guide.md7.5 KB
  • references/enter-exit-recipes.md10.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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

ContextDurationWhy
Micro-interaction (toggle, hover, focus)100-150msInstant feedback, no perceived delay
UI transition (modal, drawer, tab switch)200-300msSmooth but never sluggish
Page/route transition300-500msEstablishes spatial narrative
Scroll-driven / 3DFree (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

ActionEasingWhy
Element entersease-out / springDecelerates into resting position (natural arrival)
Element exitsease-inAccelerates away (gets out of the way)
Element moves between statesease-in-outSmooth start and stop
Scroll-syncedlinear / noneMatches 1:1 with input, no lag perception
Bouncy/playfulspring (underdamped)Overshoot creates life
Snappy UIcubic-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)SwiftUICompose
cubic-bezier(0.2, 0, 0, 1).spring(response: 0.4, dampingFraction: 0.85) or .snappyspring(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.

PlatformAPI
Web CSS@media (prefers-reduced-motion: reduce)
Web JSwindow.matchMedia('(prefers-reduced-motion: reduce)')
SwiftUI@Environment(\.accessibilityReduceMotion) var reduceMotion
UIKitUIAccessibility.isReduceMotionEnabled (+ reduceMotionStatusDidChangeNotification)
ComposeCustom helper using Settings.Global.ANIMATOR_DURATION_SCALE (deep-dive in mobile-principles/references/accessibility-mobile.md)

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:

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:

@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.

/* 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):

// 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):

// 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.

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

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

SwiftUI equivalent:

// BAD
.scaleEffect(visible ? 1.0 : 0.0)

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

Compose equivalent:

// 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.

/* 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.

// 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:

// BAD
.animation(.easeInOut(duration: 0.8), value: state)

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

Compose:

// 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.

// 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

NeedLoad
Easing deep-dive, spring configsreferences/easing-guide.md
Copy-paste enter/exit patternsreferences/enter-exit-recipes.md
Designer-weighted style choicereferences/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

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Summon shadow clones: genjutsu's full-scale pipeline for a whole website or web app, from scratch or as a full redesign. Harvests the client's real material, researches in parallel, lets Impeccable lead the direction and genjutsu the motion, builds the pages with parallel agents, then loops fixes, verdicts and a cold-eyes art director until only minor issues remain, the round cap of the chosen tier is reached, or a round fixes nothing. Announces its cost first and asks twice. Web. Needs a host that can spawn subagents.

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

Algorithmic and generative art with Canvas 2D - particles, flow fields, noise, fractals, L-systems.

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

cast

Free

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).

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

Advanced Compose visuals - Material 3 Expressive motion physics, AGSL shaders (Android 13+), Canvas/DrawScope generative, graphicsLayer effects.

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

Jetpack Compose animation foundations - animate*AsState, AnimatedVisibility, Crossfade, updateTransition, SharedTransitionLayout, gestures.

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

Compose Multiplatform / KMP patterns - expect/actual composables, platform-specific code, density and font handling cross-target, iOS/Android/Desktop interop.

The English summary is being prepared. Showing the original description.

AThevon/genjutsu555Updated Oct 6, 2026

See all skills by AThevon

Report a problem with this skill