Motion tokens
Skill almasumdev/awesome-mobile-design-system-agent-skills/.github/skills/motion/motion-tokens
Agent skills for building and maintaining mobile design systems, tokens, and component libraries.
npx -y skills add almasumdev/awesome-mobile-design-system-agent-skills --skill motion-tokensAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Encoding duration, easing, and stagger as DTCG tokens and delivering them to Compose, SwiftUI, Flutter, and React Native. Use this when introducing or refactoring motion tokens.
SKILL.md
5.6 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
Motion Tokens
Instructions
Motion belongs in the token system. A component should no more embed 250ms than it should embed #4F46E5.
1. DTCG Types for Motion
DTCG ships duration and cubicBezier. Compose motion via transition groups.
{
"motion": {
"duration": {
"$type": "duration",
"xs": { "$value": "80ms" },
"sm": { "$value": "150ms" },
"md": { "$value": "250ms" },
"lg": { "$value": "400ms" }
},
"easing": {
"$type": "cubicBezier",
"standard": { "$value": [0.2, 0.0, 0.0, 1.0] },
"accelerate": { "$value": [0.3, 0.0, 1.0, 1.0] },
"decelerate": { "$value": [0.0, 0.0, 0.0, 1.0] },
"emphasized": { "$value": [0.2, 0.0, 0.0, 1.0] }
}
}
}
2. Semantic Motion Aliases
Components consume intent-bearing aliases, not raw motion.duration.md.
{
"motion": {
"transition": {
"stateChange": {
"$type": "transition",
"$value": {
"duration": "{motion.duration.sm}",
"timingFunction": "{motion.easing.standard}",
"delay": "0ms"
}
},
"surfaceEnter": {
"$type": "transition",
"$value": {
"duration": "{motion.duration.md}",
"timingFunction": "{motion.easing.decelerate}",
"delay": "0ms"
}
},
"surfaceExit": {
"$type": "transition",
"$value": {
"duration": "{motion.duration.sm}",
"timingFunction": "{motion.easing.accelerate}",
"delay": "0ms"
}
},
"stagger": {
"$type": "duration",
"$value": "30ms"
}
}
}
}
3. Style Dictionary Transforms
Style Dictionary does not ship duration / cubicBezier transforms out of the box for native platforms. Add small custom transforms.
// style-dictionary.config.js
const StyleDictionary = require('style-dictionary');
StyleDictionary.registerTransform({
name: 'duration/ms-to-number',
type: 'value',
matcher: t => t.$type === 'duration',
transformer: t => parseInt(String(t.$value).replace('ms', ''), 10),
});
StyleDictionary.registerTransform({
name: 'cubicBezier/array',
type: 'value',
matcher: t => t.$type === 'cubicBezier',
transformer: t => t.$value, // [x1,y1,x2,y2]
});
StyleDictionary.registerTransformGroup({
name: 'compose-motion',
transforms: ['attribute/cti', 'name/cti/pascal', 'duration/ms-to-number', 'cubicBezier/array'],
});
4. Compose Delivery
object Motion {
object Duration {
const val Xs = 80
const val Sm = 150
const val Md = 250
const val Lg = 400
}
val EasingStandard = CubicBezierEasing(0.2f, 0.0f, 0.0f, 1.0f)
val EasingDecelerate = CubicBezierEasing(0.0f, 0.0f, 0.0f, 1.0f)
val EasingAccelerate = CubicBezierEasing(0.3f, 0.0f, 1.0f, 1.0f)
}
val SurfaceEnter = tween<Float>(Motion.Duration.Md, easing = Motion.EasingDecelerate)
5. SwiftUI Delivery
public enum DSMotionDuration { public static let xs = 0.08, sm = 0.15, md = 0.25, lg = 0.4 }
public enum DSMotionEasing {
public static let standard = Animation.timingCurve(0.2, 0.0, 0.0, 1.0, duration: DSMotionDuration.md)
public static let decelerate = Animation.timingCurve(0.0, 0.0, 0.0, 1.0, duration: DSMotionDuration.md)
public static let accelerate = Animation.timingCurve(0.3, 0.0, 1.0, 1.0, duration: DSMotionDuration.sm)
}
6. Flutter Delivery
class AppMotion extends ThemeExtension<AppMotion> {
final Duration surfaceEnter;
final Duration surfaceExit;
final Curve standard;
final Curve decelerate;
const AppMotion({
required this.surfaceEnter, required this.surfaceExit,
required this.standard, required this.decelerate,
});
static const standard = AppMotion(
surfaceEnter: Duration(milliseconds: 250),
surfaceExit: Duration(milliseconds: 150),
standard: Cubic(0.2, 0.0, 0.0, 1.0),
decelerate: Cubic(0.0, 0.0, 0.0, 1.0),
);
@override AppMotion copyWith(...) => ...;
@override AppMotion lerp(ThemeExtension<AppMotion>? other, double t) => this;
}
7. React Native Delivery
export const motion = {
duration: { xs: 80, sm: 150, md: 250, lg: 400 },
easing: {
standard: Easing.bezier(0.2, 0.0, 0.0, 1.0),
decelerate: Easing.bezier(0.0, 0.0, 0.0, 1.0),
accelerate: Easing.bezier(0.3, 0.0, 1.0, 1.0),
},
} as const;
8. Reduced-Motion Variant
Ship a second token file motion.reduced.json where every duration resolves to 0ms. The platform provider picks the right file at runtime based on the accessibility flag.
9. Anti-Patterns
tween(300)inline in a component.- Using CSS-string easings on native platforms instead of cubic-bezier arrays.
- Exposing reference durations (
motion.duration.md) as the component-facing API. - Hardcoding stagger in component source — tokenize it.
Checklist
- Duration and easing are DTCG
duration/cubicBeziertokens with semantictransitionaliases. - Style Dictionary has explicit transforms for duration and cubic-bezier output per platform.
- Every target platform has a generated motion artifact (Compose
Motion, SwiftUIDSMotion…, FlutterThemeExtension, RN const). - Components consume semantic motion tokens (
transition.stateChange) only. - A reduced-motion token file is delivered and selected at runtime.
- No raw millisecond or cubic-bezier literals exist in component source.