exaggeration
Skill7 starsChanged 10 months agoMITView on GitHub
Disney's principle of amplifying motion for clarity and impact. Use when determining animation intensity based on brand attitude, narrative phase, and user context. Maps multipliers to scale, distance, and timing.
In this repository87 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- motion-designSkill
- 3d-transformsSkill
- accessibilitySkill
- android-nativeSkill
- animation-recipesSkill
- anticipationSkill
- arc-motionSkill
- attention-choreographySkill
- attentionSkill
- audio-reactiveSkill
- blurSkill
- brand-animationSkill
- cameraSkill
- characterSkill
- choice-resolutionSkill
- cinematicSkill
- code-generationSkill
- colorSkill
- component-animationsSkill
- compositingSkill
- consequenceSkill
- container-transformSkill
- css-advancedSkill
- data-visualizationSkill
- depthSkill
- distortionSkill
- dramaturgySkill
- durationSkill
- easingSkill
- emotional-journeySkill
- emotion-mappingSkill
- emotion-selectionSkill
- empty-statesSkill
- entrance-patternsSkill
- exit-patternsSkill
- exportSkill
- figma-integrationSkill
- follow-throughSkill
- frame-timingSkill
- gesture-motionSkill
- glow-shadowSkill
- intentSkill
- ios-nativeSkill
- loading-statesSkill
- loopingSkill
- lottieSkill
- masksSkill
- microstateSkill
- morphingSkill
- motion-auditSkill
- motion-blurSkill
- motion-principlesSkill
- motion-specsSkill
- narrative-arcSkill
- notificationsSkill
- onboardingSkill
- opacitySkill
- orchestratorSkill
- particlesSkill
- The first 60 shown.
The file
Files
Exaggeration
Pushing motion beyond reality for emotional impact and visual clarity. Real-world motion is often too subtle to read on screen.
Core Principle
Exaggerate motion to communicate clearly. Perfect reality looks lifeless on screen; amplification creates life.
Real life: Small gesture -> Barely visible on screen
Animation: Exaggerated gesture -> Clear, readable, emotionalToken Reference
Load from: tokens/exaggeration.tokens.json
| Token | Multiplier | Scale Boost | Use Case |
subtle | 1.1x | 1.05x | Enterprise, professional |
moderate | 1.3x | 1.15x | Consumer apps |
expressive | 1.6x | 1.30x | Playful, gaming |
dramatic | 2.0x | 1.50x | Hero moments, celebrations |
cartoon | 2.5x | 2.00x | Kids, character animation |
Applying Exaggeration
Scale
// Base scale change: 10%
const baseScale = 1.1;
// With exaggeration multiplier
const exaggeratedScale = 1 + (baseScale - 1) * multiplier;
// subtle (1.1x): 1 + 0.1 * 1.1 = 1.11
// moderate (1.3x): 1 + 0.1 * 1.3 = 1.13
// dramatic (2.0x): 1 + 0.1 * 2.0 = 1.20Distance
// Base movement: 20px
const baseDistance = 20;
// With exaggeration multiplier
const exaggeratedDistance = baseDistance * multiplier;
// subtle (1.1x): 22px
// moderate (1.3x): 26px
// dramatic (2.0x): 40pxTiming (optional stretch)
// Base duration: 300ms
const baseDuration = 300;
// With timing stretch (usually subtle)
const stretchedDuration = baseDuration * timingStretch;
// subtle (1.0x): 300ms (no change)
// moderate (1.1x): 330ms
// dramatic (1.3x): 390msContext Mapping
By Use Case
| Context | Level | Rationale |
| Micro-interactions | subtle | Frequent, shouldn't distract |
| State changes | moderate | Clear feedback without drama |
| Notifications | expressive | Needs attention |
| Celebrations | dramatic | Peak emotional moment |
| Errors | moderate | Noticeable, not alarming |
| Onboarding | expressive | Memorable first impression |
By Brand Attitude
| Brand Style | Level | Examples |
| Elegant/Luxury | subtle | Hermes, Rolex, Apple |
| Professional | subtle-moderate | Salesforce, Notion |
| Friendly | moderate | Mailchimp, Slack |
| Playful | expressive | Discord, Duolingo |
| Bold | dramatic | Nike, Spotify |
By Narrative Phase
| Phase | Level | Purpose |
| Introduction | moderate-expressive | Grab attention |
| Rising action | moderate | Build steadily |
| Climax | dramatic | Maximum impact |
| Resolution | subtle-moderate | Calm return |
Implementation Presets
CSS Custom Properties
:root {
/* Exaggeration levels */
--exaggeration-subtle: 1.1;
--exaggeration-moderate: 1.3;
--exaggeration-expressive: 1.6;
--exaggeration-dramatic: 2.0;
/* Current level (set via JS or class) */
--exaggeration: var(--exaggeration-moderate);
/* Derived values */
--scale-boost: calc(1 + (0.1 * var(--exaggeration)));
--distance-boost: calc(20px * var(--exaggeration));
}
/* Usage */
.card-hover {
transform: scale(var(--scale-boost)) translateY(calc(var(--distance-boost) * -1));
}
/* Brand variants */
.brand-elegant { --exaggeration: var(--exaggeration-subtle); }
.brand-playful { --exaggeration: var(--exaggeration-expressive); }GSAP
import { gsap } from 'gsap';
import tokens from '../tokens/exaggeration.tokens.json';
// Exaggeration utility
function withExaggeration(baseValue, level = 'moderate', type = 'distance') {
const config = tokens.exaggeration[level].$value;
switch (type) {
case 'distance':
return baseValue * config.distanceBoost;
case 'scale':
return 1 + (baseValue - 1) * config.scaleBoost;
case 'duration':
return baseValue * config.timingStretch;
default:
return baseValue * config.multiplier;
}
}
// Example: Button press with configurable exaggeration
function buttonPress(button, level = 'moderate') {
const baseScale = 0.95;
const baseY = 2;
return gsap.to(button, {
scale: withExaggeration(baseScale, level, 'scale'),
y: withExaggeration(baseY, level, 'distance'),
duration: 0.1,
ease: 'power2.out'
});
}
// Success celebration with dramatic exaggeration
function celebrate(element) {
const level = 'dramatic';
return gsap.timeline()
.to(element, {
scale: withExaggeration(1.2, level, 'scale'),
duration: 0.2,
ease: 'back.out(2)'
})
.to(element, {
y: withExaggeration(-30, level, 'distance'),
duration: 0.3,
ease: 'power2.out'
})
.to(element, {
scale: 1,
y: 0,
duration: 0.4,
ease: 'elastic.out(1, 0.5)'
});
}
// Contextual exaggeration based on component
function animateComponent(component, action) {
const contextMap = {
'button': 'subtle',
'card': 'moderate',
'notification': 'expressive',
'hero': 'dramatic'
};
const level = contextMap[component.type] || 'moderate';
// Apply animation with appropriate level
}Framer Motion
import { motion } from 'framer-motion';
import tokens from '../tokens/exaggeration.tokens.json';
// Hook for exaggeration values
const useExaggeration = (level: keyof typeof tokens.exaggeration) => {
const config = tokens.exaggeration[level].$value;
return {
scale: (base: number) => 1 + (base - 1) * config.scaleBoost,
distance: (base: number) => base * config.distanceBoost,
duration: (base: number) => base * config.timingStretch,
multiplier: config.multiplier
};
};
// Component with configurable exaggeration
interface AnimatedCardProps {
exaggeration?: 'subtle' | 'moderate' | 'expressive' | 'dramatic';
children: React.ReactNode;
}
export const AnimatedCard: React.FC<AnimatedCardProps> = ({
exaggeration = 'moderate',
children
}) => {
const ex = useExaggeration(exaggeration);
return (
<motion.div
whileHover={{
y: -ex.distance(10),
scale: ex.scale(1.02),
transition: { duration: ex.duration(0.2) }
}}
whileTap={{
scale: ex.scale(0.98)
}}
>
{children}
</motion.div>
);
};
// Celebration with maximum exaggeration
const celebrationVariants = {
initial: { scale: 0, rotate: -180 },
celebrate: (exLevel: string) => {
const ex = tokens.exaggeration[exLevel].$value;
return {
scale: [0, ex.scaleBoost, 1],
rotate: [-180, 10 * ex.multiplier, 0],
transition: {
duration: 0.6 * ex.timingStretch,
times: [0, 0.6, 1],
ease: 'backOut'
}
};
}
};
export const Celebration: React.FC = () => (
<motion.div
variants={celebrationVariants}
initial="initial"
animate="celebrate"
custom="dramatic"
>
Celebration!
</motion.div>
);Remotion
import { useCurrentFrame, interpolate, spring } from 'remotion';
import tokens from '../tokens/exaggeration.tokens.json';
// Exaggeration utilities for video
export const useExaggeration = (level: 'subtle' | 'moderate' | 'expressive' | 'dramatic') => {
const config = tokens.exaggeration[level].$value;
return {
applyToScale: (base: number) => 1 + (base - 1) * config.scaleBoost,
applyToDistance: (base: number) => base * config.distanceBoost,
applyToDuration: (baseFrames: number) => Math.round(baseFrames * config.timingStretch)
};
};
// Example: Title reveal with exaggeration
export const TitleReveal: React.FC<{
text: string;
startFrame: number;
exaggeration?: 'subtle' | 'moderate' | 'expressive' | 'dramatic';
}> = ({ text, startFrame, exaggeration = 'moderate' }) => {
const frame = useCurrentFrame();
const ex = useExaggeration(exaggeration);
const baseScale = 1.5;
const baseY = 50;
const baseDuration = 20;
const progress = spring({
frame: frame - startFrame,
fps: 30,
config: { damping: 12, stiffness: 100 }
});
const scale = interpolate(
progress,
[0, 0.5, 1],
[ex.applyToScale(baseScale), ex.applyToScale(1.1), 1]
);
const y = interpolate(
progress,
[0, 1],
[ex.applyToDistance(baseY), 0]
);
const opacity = interpolate(
frame,
[startFrame, startFrame + 10],
[0, 1],
{ extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
return (
<div
style={{
transform: `scale(${scale}) translateY(${y}px)`,
opacity
}}
>
{text}
</div>
);
};
// Hero moment with dramatic exaggeration
export const HeroMoment: React.FC<{
triggerFrame: number;
children: React.ReactNode;
}> = ({ triggerFrame, children }) => {
const frame = useCurrentFrame();
const ex = useExaggeration('dramatic');
// Dramatic entrance
const progress = interpolate(
frame,
[triggerFrame, triggerFrame + ex.applyToDuration(30)],
[0, 1],
{ extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
const scale = interpolate(
progress,
[0, 0.6, 0.8, 1],
[0, ex.applyToScale(1.3), ex.applyToScale(0.95), 1]
);
const y = interpolate(
progress,
[0, 0.6, 1],
[ex.applyToDistance(100), ex.applyToDistance(-20), 0]
);
return (
<div style={{ transform: `scale(${scale}) translateY(${y}px)` }}>
{children}
</div>
);
};Realistic vs Stylized Spectrum
| Style | Exaggeration | Physics | Use Case |
| Photorealistic | 1.0x | Accurate | Simulation, data viz |
| Natural | 1.1x | Enhanced | Professional UI |
| Stylized | 1.5x | Adjusted | Consumer apps |
| Cartoon | 2.5x+ | Impossible | Entertainment, kids |
Accessibility
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
// Reduce exaggeration for accessibility
const exaggerationLevel = prefersReducedMotion ? 'subtle' : determinedLevel;
// Or cap maximum exaggeration
const cappedLevel = prefersReducedMotion
? Math.min(level, tokens.exaggeration.subtle.$value.multiplier)
: level;Common Mistakes
- Uniform exaggeration - Different contexts need different levels
- Always dramatic - Save drama for meaningful moments
- Ignoring brand - Exaggeration must match brand personality
- Inconsistent - Same actions should have same exaggeration
- Overshadowing content - Animation serves content, not vice versa
Related Skills
- anticipation - Exaggeration level affects anticipation wind-up intensity
- squash-stretch - Exaggeration determines deformation magnitude
- follow-through - Exaggeration affects overshoot and settle amplitude
- secondary-action - Primary/secondary intensity gap follows exaggeration
- arc-motion - Exaggeration affects arc height and trajectory drama
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

