agentleFS
soilmasssoilmass/motion-design-agent/skills/narrative-arc/SKILL.md

narrative-arc

Skill7 starsChanged 10 months agoMITView on GitHub

Story structure for motion sequences using Freytag's pyramid. Use when designing multi-step animations that need dramatic structure, from micro-interactions to full page transitions with exposition, rising action, climax, and resolution phases.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

Files
SKILL.md

Narrative Arc

Apply dramatic story structure to animation sequences. Transform mechanical motion into meaningful narrative experiences using Freytag's pyramid adapted for UI motion.

Standards Reference

StandardDocumentation
W3C DTCGdesigntokens.org
Freytag's PyramidClassic dramatic structure
Material Design 3m3.material.io/styles/motion

Quick Reference

Load from: tokens/narrative-arc.tokens.json

Arc Phases

PhaseIntensityDuration WeightPurpose
Exposition0.315%Set context, introduce elements
Rising Action0.625%Build momentum, add complexity
Climax1.015%Maximum impact moment
Falling Action0.425%Energy dissipation
Resolution0.220%Settle to new equilibrium

Arc Presets

PresetDurationPhasesUse Case
micro300msincident → climax → resolutionButton press, toggle
short600ms4-phase (no falling)Modal open, card expand
medium1200msFull 5-phasePage transition
extended3000msFull 5-phaseOnboarding flow

Selection Guide

What's the interaction scope?

├── Single element, instant feedback
│   └── micro arc (300ms)
│       └── Phases: incident → climax → resolution
│
├── Component state change
│   └── short arc (600ms)
│       └── Phases: exposition → rising → climax → resolution
│
├── View transition
│   └── medium arc (1200ms)
│       └── Full Freytag pyramid
│
└── Multi-step experience
    └── extended arc (3000ms)
        └── Full pyramid with breathing room

Narrative Arc Patterns

Micro Arc (Button Confirmation)

3-phase compressed structure for immediate feedback.

Timeline:

0ms ─────── 75ms ───────── 180ms ─────── 300ms
│ incident │    climax    │   resolution │
│   25%    │     35%      │     40%      │

Framer Motion:

const microArc = {
  incident: {
    scale: 0.95,
    transition: { duration: 0.075, ease: 'easeIn' }
  },
  climax: {
    scale: 1.1,
    transition: { duration: 0.105, type: 'spring', stiffness: 400 }
  },
  resolution: {
    scale: 1,
    transition: { duration: 0.12, ease: 'easeOut' }
  }
};

GSAP:

const tl = gsap.timeline();

tl.to(button, {
  scale: 0.95,
  duration: 0.075,
  ease: 'power2.in'
})
.to(button, {
  scale: 1.1,
  duration: 0.105,
  ease: 'back.out(2)'
})
.to(button, {
  scale: 1,
  duration: 0.12,
  ease: 'power2.out'
});

Short Arc (Modal Entrance)

4-phase structure for component transitions.

Timeline:

0ms ──── 90ms ──── 270ms ──── 420ms ──── 600ms
│  exp  │  rising │  climax  │  resolution │
│  15%  │   30%   │   25%    │     30%     │

Framer Motion:

const modalVariants = {
  hidden: { opacity: 0, scale: 0.9, y: 20 },
  visible: {
    opacity: 1,
    scale: 1,
    y: 0,
    transition: {
      duration: 0.6,
      times: [0, 0.15, 0.45, 0.70, 1], // Phase boundaries
      ease: [[0.05, 0.7, 0.1, 1]] // emphasized-decelerate
    }
  }
};

// Orchestrated with children
const containerVariants = {
  hidden: {},
  visible: {
    transition: {
      staggerChildren: 0.08,
      delayChildren: 0.15 // After exposition
    }
  }
};

Medium Arc (Page Transition)

Full 5-phase Freytag structure.

Timeline:

0ms ─ 144ms ─ 444ms ─ 660ms ─ 924ms ─ 1200ms
│exp │rising │climax │falling│ resolution │
│12% │  25%  │  18%  │  22%  │    23%     │

GSAP Timeline:

const pageTransition = gsap.timeline();

// Exposition: establish context
pageTransition.to('.current-page', {
  opacity: 0.8,
  scale: 0.98,
  duration: 0.144,
  ease: 'power1.out'
});

// Rising Action: build momentum
pageTransition.to('.current-page', {
  opacity: 0,
  x: -50,
  duration: 0.3,
  ease: 'power2.in'
}, '-=0.05');

pageTransition.fromTo('.next-page', {
  opacity: 0,
  x: 50
}, {
  opacity: 0.5,
  x: 25,
  duration: 0.3,
  ease: 'power2.out'
}, '-=0.2');

// Climax: maximum impact
pageTransition.to('.next-page', {
  opacity: 1,
  x: 0,
  scale: 1.02,
  duration: 0.216,
  ease: 'power3.out'
});

// Falling Action: energy dissipation
pageTransition.to('.next-page', {
  scale: 1,
  duration: 0.264,
  ease: 'power2.out'
});

// Resolution: content reveals
pageTransition.from('.next-page .content', {
  opacity: 0,
  y: 20,
  duration: 0.276,
  stagger: 0.05,
  ease: 'power2.out'
}, '-=0.15');

Beat Types

Story beats are discrete narrative moments within arcs.

BeatIntensityDurationPurpose
setup0.2-0.4150msEstablish context
build0.4-0.7200msIncrease tension
payoff0.8-1.0250msDeliver result
surprise0.9-1.0180msUnexpected moment
breathe0.1-0.2400msPause for absorption
echo0.2-0.4200msCallback to earlier motion

Beat Sequence Example

// Form submission with narrative beats
const formSubmit = gsap.timeline();

// SETUP: Prepare for action
formSubmit.to('.submit-btn', {
  scale: 0.98,
  duration: 0.15,
  ease: 'power1.in'
});

// BUILD: Tension increases
formSubmit.to('.submit-btn .spinner', {
  opacity: 1,
  rotate: 360,
  duration: 0.2,
  ease: 'power2.inOut'
});

// PAYOFF: Success moment
formSubmit.to('.submit-btn', {
  backgroundColor: '#4CAF50',
  scale: 1.05,
  duration: 0.25,
  ease: 'back.out(2)'
});

// BREATHE: Let user absorb
formSubmit.to('.submit-btn', {
  duration: 0.4
});

// ECHO: Subtle reminder
formSubmit.to('.submit-btn', {
  scale: 1,
  duration: 0.2,
  ease: 'power2.out'
});

Tension Curves

How intensity builds across the arc.

CurveFormulaUse Case
linear-riseLinearEducational content
exponential-riseease-inReveals, surprises
steppedsteps(5)Wizard steps
wavesineDashboards, ongoing processes

Resolution Types

How narratives conclude.

TypeFinal IntensityMotionUse
complete0.0settle-to-restClear ending
open0.15gentle-pulseInvites continuation
cliffhanger0.4hold-tensionCreates anticipation
cyclical0.3return-originSuggests loop

Integration with Other Narrative Skills

Narrative Arc
     │
     ├── Provides: Phase structure, intensity, timing
     │
     └── Consumed by:
         ├── dramaturgy/ → Scene composition uses arc phases
         ├── consequence/ → Chain timing aligns with arc
         ├── emotional-journey/ → States map to arc phases
         └── intent/ → Intent intensity modulated by phase

Reduced Motion

For prefers-reduced-motion: reduce:

Full ArcReduced Alternative
Multi-phase transitionSingle fade
Building intensityInstant state change
Climax emphasisSubtle opacity shift
Extended resolutionImmediate rest
const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;

if (prefersReducedMotion) {
  // Replace arc with simple fade
  gsap.to(element, { opacity: 1, duration: 0.2 });
} else {
  // Full narrative arc
  playNarrativeArc(element);
}

Cross-References

  • See dramaturgy/ for scene composition using arcs
  • See emotional-journey/ for emotional state mapping to arc phases
  • See intent/ for purpose-driven intensity within arcs
  • See sequencing/ for timing multiple elements within arc phases
  • See duration/ for base timing values

References

  • references/freytag-pyramid.md — Dramatic structure theory
  • references/beat-types.md — Story beat patterns

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.