feat(cli): move skills to repo root, support multi-CLI install

- Move skills from .claude/skills/ to skills/ (tool-agnostic location)
- Install to Claude Code, Gemini CLI, Codex CLI by default
- Add --claude, --gemini, --codex, --cursor flags for targeting specific tools
- Update build script to copy from skills/ instead of .claude/skills/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-03-26 17:50:46 +00:00
committed by Vance Ingalls
co-authored by Claude Opus 4.6
parent 4f07e7f804
commit ccee93bb99
23 changed files with 9272 additions and 2 deletions
@@ -0,0 +1,804 @@
# Emotion-to-Motion Iteration 3 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add multi-scene choreography phases, mood transitions, and intra-scene choreography patterns to the emotion-to-motion skill, then evaluate with 30-60s compositions.
**Architecture:** The existing SKILL.md gets three new sections appended (phases, transition matrix, intra-scene choreography). A new evals.json replaces the old one with 2 multi-scene test cases. A/B compositions (with_skill vs without_skill) are generated, deployed to HyperFrames Studio, and graded against 8 criteria.
**Tech Stack:** GSAP 3.14.2 (CustomEase, SplitText, CustomBounce, CustomWiggle), HyperFrames composition format, HyperFrames Studio for preview
**Spec:** `docs/superpowers/specs/2026-03-25-emotion-to-motion-iter3-design.md`
---
## File Structure
| Action | Path | Responsibility |
|--------|------|---------------|
| Modify | `~/.claude/skills/emotion-to-motion/SKILL.md` | Add 3 new sections after existing mood recipes |
| Modify | `~/.claude/skills/emotion-to-motion/evals/evals.json` | Replace with 2 multi-scene test cases |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/eval_metadata.json` | Test case 1 metadata |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/index.html` | Test case 1 with-skill composition |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/grading.json` | Test case 1 with-skill grading |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/timing.json` | Test case 1 with-skill token/time metrics |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/index.html` | Test case 1 without-skill composition |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/grading.json` | Test case 1 without-skill grading |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/timing.json` | Test case 1 without-skill token/time metrics |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/eval_metadata.json` | Test case 2 metadata |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/outputs/index.html` | Test case 2 with-skill composition |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/outputs/grading.json` | Test case 2 with-skill grading |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/timing.json` | Test case 2 with-skill token/time metrics |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/outputs/index.html` | Test case 2 without-skill composition |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/outputs/grading.json` | Test case 2 without-skill grading |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/timing.json` | Test case 2 without-skill token/time metrics |
| Create | `~/.claude/skills/emotion-to-motion-workspace/iteration-3/benchmark.json` | Aggregate scores across both test cases |
| Create | `packages/studio/data/projects/high-contrast-arc-with-skill/index.html` | Studio preview for case 1 with-skill |
| Create | `packages/studio/data/projects/high-contrast-arc-without-skill/index.html` | Studio preview for case 1 without-skill |
| Create | `packages/studio/data/projects/gradual-escalation-with-skill/index.html` | Studio preview for case 2 with-skill |
| Create | `packages/studio/data/projects/gradual-escalation-without-skill/index.html` | Studio preview for case 2 without-skill |
---
### Task 1: Update SKILL.md — Add Choreography Phases Section
**Files:**
- Modify: `~/.claude/skills/emotion-to-motion/SKILL.md` (append after line 269, after the "Punchy / Bold" recipe)
- [ ] **Step 1: Read the existing SKILL.md to confirm current end**
Read `~/.claude/skills/emotion-to-motion/SKILL.md` — verify it ends at line 269 with the Punchy/Bold recipe and there's no existing multi-scene content.
- [ ] **Step 2: Append the Choreography Phases section**
Add the following after the last line of SKILL.md:
```markdown
## Multi-Scene Compositions: Choreography Phases
For compositions longer than 15 seconds or with multiple moods, decompose the prompt into **phases** — ordered segments, each with its own mood and choreography.
### Phase Structure
Each phase has:
- **Mood** — one canonical mood (dramatic, playful, elegant, energetic, calm, tense, punchy)
- **Duration** — seconds in the master timeline
- **Content** — what's visually happening
- **Entrance → Emphasis → Exit** — choreography pattern (see Intra-Scene Choreography below)
### Mood Synonym Resolution
Resolve evocative language to canonical moods before decomposing:
| Synonym | Canonical Mood |
|---------|---------------|
| explosive, intense, fierce | punchy |
| serene, peaceful, tranquil | calm |
| triumphant, victorious, celebratory | playful |
| suspenseful, ominous, creeping | tense |
| luxurious, refined, sophisticated | elegant |
| exciting, dynamic, high-energy | energetic |
| cinematic, epic, grand | dramatic |
### Phase Decomposition
Handle two input styles:
**Explicit per-scene moods** — extract mood (resolving synonyms), duration, and content directly:
> "Scene 1 (tense, 15s): text fragments drift. Scene 2 (punchy, 10s): title shatters. Scene 3 (calm, 20s): debris floats."
**Arc-based descriptions** — decompose into phases:
> "Build from quiet unease to cathartic release to calm aftermath"
1. Map mood anchors: quiet unease → tense, cathartic release → dramatic, calm aftermath → calm
2. Allocate durations by weight:
| Mood | Weight |
|------|--------|
| calm, elegant | 1.2 |
| dramatic, tense | 1.0 |
| energetic, playful | 0.9 |
| punchy | 0.7 |
Formula: `phase_duration = (weight / sum_of_all_weights) * target_total`, rounded to nearest second.
**Minimum phase duration:** 6s — clamp and redistribute from the longest phase.
Expect 3-5 phases for 30-60s compositions. Allow up to 7 if the prompt explicitly calls for more.
### Edge Cases
- **Single mood for 30-60s:** One phase, no transitions. Apply entrance/emphasis/exit across the full duration.
- **Adjacent same-mood phases:** Merge unless content descriptions feature different primary subjects (e.g., "product close-up" vs "lifestyle scene"). If kept separate, use a soft transition.
- **More than 7 phases:** Consolidate phases with similar moods.
```
- [ ] **Step 3: Verify the append**
Read `~/.claude/skills/emotion-to-motion/SKILL.md` from line 269 onward — confirm the Choreography Phases section is present and correctly formatted.
- [ ] **Step 4: Commit**
```bash
cd ~/.claude/skills/emotion-to-motion && git add SKILL.md && git commit -m "feat(skill): add choreography phases section for multi-scene compositions"
```
(If not a git repo, skip commit — this is a local skill file.)
---
### Task 2: Update SKILL.md — Add Transition Matrix Section
**Files:**
- Modify: `~/.claude/skills/emotion-to-motion/SKILL.md` (append after Choreography Phases section)
- [ ] **Step 1: Append the Transition Matrix section**
Add immediately after the Edge Cases subsection:
```markdown
## Transition Matrix
Transitions between phases are inferred from the mood delta. Three categories:
### Hard Transitions (high contrast)
- **Overlap:** 0.3-0.8s
- **Technique:** Scene N's elements snap out (opacity: 0, scale: 0.95) while Scene N+1's elements slam in simultaneously
- **GSAP pattern:**
```js
// Phase N exit — hard snap out
phaseTl.to(".phase-n-elements", { opacity: 0, scale: 0.95, duration: 0.3, ease: "power3.in" }, exitStart);
// Phase N+1 entrance — slam in (overlaps exit by 0.3-0.8s)
nextPhaseTl.from(".phase-n1-elements", { opacity: 0, scale: 1.1, duration: 0.4, ease: "power4.out" }, 0);
```
### Soft Transitions (low contrast)
- **Overlap:** 1.5-3s
- **Technique:** Scene N's elements slowly fade/drift out while Scene N+1's elements gradually emerge underneath
- **GSAP pattern:**
```js
// Phase N exit — slow fade out
phaseTl.to(".phase-n-elements", { opacity: 0, y: -20, duration: 2, ease: "sine.inOut" }, exitStart);
// Phase N+1 entrance — fade in underneath (overlaps by 1.5-3s)
nextPhaseTl.from(".phase-n1-elements", { opacity: 0, y: 20, duration: 2, ease: "sine.inOut" }, 0);
```
### Escalation Transitions (building intensity)
- **Overlap:** 0.8-1.5s
- **Technique:** Scene N's elements accelerate their exit, Scene N+1's entrance inherits that momentum
- **GSAP pattern:**
```js
// Phase N exit — accelerating out
phaseTl.to(".phase-n-elements", { opacity: 0, x: -100, duration: 0.8, ease: "power3.in" }, exitStart);
// Phase N+1 entrance — momentum carry (overlaps by 0.8-1.5s)
nextPhaseTl.from(".phase-n1-elements", { opacity: 0, x: 100, duration: 0.6, ease: "power3.out" }, 0);
```
### Lookup Table
| From ↓ To → | dramatic | playful | elegant | energetic | calm | tense | punchy |
|-------------|----------|---------|---------|-----------|------|-------|--------|
| dramatic | soft | hard | soft | escalation | soft | soft | hard |
| playful | hard | soft | hard | soft | hard | hard | hard |
| elegant | soft | hard | soft | escalation | soft | escalation | hard |
| energetic | hard | soft | hard | soft | hard | hard | hard |
| calm | escalation | hard | soft | escalation | soft | escalation | hard |
| tense | escalation | hard | soft | escalation | soft | soft | hard |
| punchy | hard | soft | hard | hard | hard | hard | soft |
**Rationale for non-obvious entries:**
- playful→punchy = hard: flowing → staccato, a cut emphasizes the shift
- energetic→punchy = hard: sustained → staccato, textural change needs a cut
- tense→elegant = soft: both share restraint, low contrast
- punchy→energetic = hard: staccato → sustained, fundamental rhythm change
**Overlap budget constraint:** Transition overlap is drawn from the exit of phase N and entrance of phase N+1 (not additional time). If combined overlap on both sides of a phase exceeds 50% of its entrance + exit allocation, clamp to 50%.
```
- [ ] **Step 2: Verify the append**
Read the SKILL.md from the "## Transition Matrix" heading — confirm all subsections are present and the lookup table renders correctly.
- [ ] **Step 3: Commit**
```bash
cd ~/.claude/skills/emotion-to-motion && git add SKILL.md && git commit -m "feat(skill): add transition matrix for multi-scene mood transitions"
```
---
### Task 3: Update SKILL.md — Add Intra-Scene Choreography Section
**Files:**
- Modify: `~/.claude/skills/emotion-to-motion/SKILL.md` (append after Transition Matrix section)
- [ ] **Step 1: Append the Intra-Scene Choreography section**
Add immediately after the Transition Matrix section:
```markdown
## Intra-Scene Choreography
Each phase has three acts: **entrance**, **emphasis**, and **exit**. The mood determines the default pattern for each.
### Act Duration Proportions
| Mood | Entrance | Emphasis | Exit |
|------|----------|----------|------|
| dramatic | 25% | 55% | 20% |
| playful | 20% | 60% | 20% |
| elegant | 20% | 65% | 15% |
| energetic | 15% | 65% | 20% |
| calm | 20% | 65% | 15% |
| tense | 25% | 50% | 25% |
| punchy | 15% | 60% | 25% |
### Entrance Patterns
**Cascade** (energetic, playful): Rapid staggered entrances, 0.05-0.1s gaps between elements.
```js
tl.from(".phase-elements", {
opacity: 0, y: 30, scale: 0.9,
duration: 0.4, ease: "back.out(1.7)",
stagger: { each: 0.07, from: "center" } // playful: from center; energetic: from start
}, entranceStart);
```
**Slow reveal** (dramatic, tense): Elements emerge one at a time with long pauses between.
```js
elements.forEach((el, i) => {
tl.from(el, {
opacity: 0, y: 15, duration: 0.8, ease: "power2.out"
}, entranceStart + i * 1.2); // 1.2s between each — builds anticipation
});
```
**Ensemble** (elegant, calm): Elements fade in together or in 2-3 groups.
```js
tl.from(".phase-elements-group1", {
opacity: 0, y: 10, duration: 1.2, ease: "sine.inOut"
}, entranceStart);
tl.from(".phase-elements-group2", {
opacity: 0, y: 10, duration: 1.2, ease: "sine.inOut"
}, entranceStart + 0.4); // slight offset, but feels unified
```
**Impact** (punchy): Hero element hits first and hard, supporting elements follow in quick succession.
```js
tl.from("#hero", {
opacity: 0, scale: 1.3, duration: 0.15, ease: "power4.out"
}, entranceStart);
tl.from(".supporting", {
opacity: 0, y: 20, duration: 0.2, ease: "power3.out",
stagger: 0.04
}, entranceStart + 0.1);
```
### Emphasis Patterns
**Pulse** (energetic, punchy): Subtle scale or brightness oscillation on key elements.
```js
tl.to("#hero", {
scale: 1.02, duration: 0.4, ease: "sine.inOut",
repeat: -1, yoyo: true
}, emphasisStart);
// Note: use repeat count based on emphasis duration, not -1, in compositions
```
**Drift** (calm, elegant): Slow continuous motion — gentle float, rotation, or parallax shift.
```js
tl.to(".bg-element", { y: -15, duration: emphasisDuration, ease: "sine.inOut" }, emphasisStart);
tl.to(".mid-element", { y: -8, rotation: 0.5, duration: emphasisDuration, ease: "sine.inOut" }, emphasisStart);
```
**Tension hold** (tense, dramatic): Near-stillness with micro-tremor on one element.
```js
gsap.registerPlugin(CustomWiggle);
CustomWiggle.create("microTremor", { wiggles: 12, type: "uniform" });
tl.to("#tension-element", {
x: 2, ease: "microTremor", duration: emphasisDuration
}, emphasisStart);
```
**Play** (playful): Secondary action — idle wobbles, bounces, rotation on supporting elements.
```js
gsap.registerPlugin(CustomWiggle);
CustomWiggle.create("wobble", { wiggles: 4, type: "easeOut" });
tl.to(".supporting", {
rotation: 3, ease: "wobble", duration: 1.5,
stagger: { each: 0.3, repeat: -1 }
}, emphasisStart);
// Floating idle on decorative elements
tl.to(".decorative", {
y: -8, duration: 1.2, ease: "sine.inOut",
yoyo: true, repeat: -1
}, emphasisStart);
```
### Exit Patterns
**Scatter** (playful, energetic): Elements exit in different directions with stagger.
```js
tl.to(".phase-elements", {
opacity: 0, x: "random(-100,100)", y: "random(-80,80)",
rotation: "random(-15,15)", duration: 0.5, ease: "power2.in",
stagger: 0.05
}, exitStart);
```
**Fade recede** (calm, elegant): Opacity + slight scale down, elements sink back.
```js
tl.to(".phase-elements", {
opacity: 0, scale: 0.95, y: 10,
duration: 1.2, ease: "sine.inOut", stagger: 0.1
}, exitStart);
```
**Snap out** (dramatic, punchy): Hard opacity to 0, no ease out — just gone.
```js
tl.to(".phase-elements", {
opacity: 0, duration: 0.08, ease: "none"
}, exitStart);
```
**Compress** (tense): Elements slowly contract inward before the next scene hits.
```js
tl.to(".phase-elements", {
scale: 0.9, x: 0, y: 0, opacity: 0.3,
duration: 1.5, ease: "power4.in"
}, exitStart);
```
### Mood-to-Default-Pattern Mapping
| Mood | Entrance | Emphasis | Exit |
|------|----------|----------|------|
| dramatic | slow reveal | tension hold | snap out |
| playful | cascade | play | scatter |
| elegant | ensemble | drift | fade recede |
| energetic | cascade | pulse | scatter |
| calm | ensemble | drift | fade recede |
| tense | slow reveal | tension hold | compress |
| punchy | impact | pulse | snap out |
Prompt-level overrides take precedence: if the prompt says "the title slams in," use impact entrance regardless of mood default.
### Timeline Assembly
Compose phases into a single master timeline:
```js
const master = gsap.timeline({ paused: true });
// Phase 1 (0s - 15s)
const phase1 = gsap.timeline();
// ... entrance/emphasis/exit choreography for phase 1 ...
master.add(phase1, 0);
// Transition 1 overlap: phase1 exit overlaps phase2 entrance
// Look up transition type from matrix: e.g., tense→punchy = hard (0.3-0.8s)
const t1Overlap = 0.5; // within hard range
// Phase 2 (14.5s - 24.5s) — starts t1Overlap before phase1 ends
const phase2 = gsap.timeline();
// ... entrance/emphasis/exit choreography for phase 2 ...
master.add(phase2, 15 - t1Overlap);
// Continue for remaining phases...
```
Each phase is a nested `gsap.timeline()` added to master at the correct position. This keeps phase choreography self-contained while the master timeline handles inter-phase timing.
```
- [ ] **Step 2: Verify the full SKILL.md**
Read the SKILL.md and verify:
1. Original 12 principles + mood recipes are intact (lines 1-269)
2. Choreography Phases section follows
3. Transition Matrix section follows
4. Intra-Scene Choreography section follows with all patterns and GSAP code examples
5. No duplicate content or broken markdown
- [ ] **Step 3: Add the script placement reminder**
Append at the very end of SKILL.md:
```markdown
## Important: Script Placement
All `<script>` tags go at the end of `<body>`, never in `<head>`. Always call `gsap.registerPlugin()` for every plugin loaded via CDN before using it.
```js
<!-- At end of <body> -->
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/CustomEase.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/SplitText.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/CustomBounce.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/CustomWiggle.min.js"></script>
<script>
gsap.registerPlugin(CustomEase, SplitText, CustomBounce, CustomWiggle);
// ... timeline code ...
</script>
```
```
- [ ] **Step 4: Commit**
```bash
cd ~/.claude/skills/emotion-to-motion && git add SKILL.md && git commit -m "feat(skill): add intra-scene choreography patterns and script placement guide"
```
---
### Task 4: Update evals.json with Multi-Scene Test Cases
**Files:**
- Modify: `~/.claude/skills/emotion-to-motion/evals/evals.json`
- [ ] **Step 1: Read the existing evals.json**
Read `~/.claude/skills/emotion-to-motion/evals/evals.json` — note the existing format so we match it.
- [ ] **Step 2: Replace evals.json with iteration-3 test cases**
Write the following (replaces entire file — iteration 1/2 evals are preserved in the workspace):
```json
{
"skill_name": "emotion-to-motion",
"iteration": 3,
"evals": [
{
"id": 0,
"name": "high-contrast-arc",
"prompt": "A thriller title sequence: open with creeping unease as fragments of text drift in darkness, then SNAP — explosive reveal of the title with shattering glass, then settle into calm aftermath with slow floating debris. Total duration ~45 seconds. The title is 'SHATTERED'. Dark background, white and red accents.",
"expected_phases": [
{ "mood": "tense", "duration_s": 15, "entrance": "slow reveal", "emphasis": "tension hold", "exit": "compress" },
{ "mood": "punchy", "duration_s": 10, "entrance": "impact", "emphasis": "pulse", "exit": "snap out" },
{ "mood": "calm", "duration_s": 20, "entrance": "ensemble", "emphasis": "drift", "exit": "fade recede" }
],
"expected_transitions": [
{ "from": "tense", "to": "punchy", "type": "hard", "overlap_range": [0.3, 0.8] },
{ "from": "punchy", "to": "calm", "type": "hard", "overlap_range": [0.3, 0.8] }
],
"grading_criteria": [
"phase-presence",
"entrance-choreography",
"emphasis-choreography",
"exit-choreography",
"transition-technique",
"duration-fidelity",
"mood-appropriate-easing",
"valid-hyperframes"
]
},
{
"id": 1,
"name": "gradual-escalation",
"prompt": "A luxury fitness brand launch: begin with elegant product beauty shots of a sleek fitness tracker called 'APEX', slowly build energy as athletes appear in motion, crescendo into triumphant celebration with the brand tagline 'Rise Above'. Total duration ~40 seconds. Black and gold palette, modern sans-serif typography.",
"expected_phases": [
{ "mood": "elegant", "duration_s": 15, "entrance": "ensemble", "emphasis": "drift", "exit": "fade recede" },
{ "mood": "energetic", "duration_s": 12, "entrance": "cascade", "emphasis": "pulse", "exit": "scatter" },
{ "mood": "playful", "duration_s": 13, "entrance": "cascade", "emphasis": "play", "exit": "scatter" }
],
"expected_transitions": [
{ "from": "elegant", "to": "energetic", "type": "escalation", "overlap_range": [0.8, 1.5] },
{ "from": "energetic", "to": "playful", "type": "soft", "overlap_range": [1.5, 3.0] }
],
"grading_criteria": [
"phase-presence",
"entrance-choreography",
"emphasis-choreography",
"exit-choreography",
"transition-technique",
"duration-fidelity",
"mood-appropriate-easing",
"valid-hyperframes"
]
}
]
}
```
- [ ] **Step 3: Verify the JSON is valid**
```bash
python3 -c "import json; json.load(open('$HOME/.claude/skills/emotion-to-motion/evals/evals.json'))" && echo "Valid JSON"
```
Expected: `Valid JSON`
- [ ] **Step 4: Commit**
```bash
cd ~/.claude/skills/emotion-to-motion && git add evals/evals.json && git commit -m "feat(evals): update test cases for iteration 3 multi-scene compositions"
```
---
### Task 5: Create Iteration-3 Workspace and Eval Metadata
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/eval_metadata.json`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/eval_metadata.json`
- [ ] **Step 1: Create directory structure**
```bash
mkdir -p ~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/{with_skill/outputs,without_skill/outputs}
mkdir -p ~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/{with_skill/outputs,without_skill/outputs}
```
- [ ] **Step 2: Create eval_metadata.json for high-contrast-arc**
Write to `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/eval_metadata.json`:
```json
{
"eval_id": 0,
"eval_name": "high-contrast-arc",
"prompt": "A thriller title sequence: open with creeping unease as fragments of text drift in darkness, then SNAP — explosive reveal of the title with shattering glass, then settle into calm aftermath with slow floating debris. Total duration ~45 seconds. The title is 'SHATTERED'. Dark background, white and red accents.",
"expected_phases": ["tense (15s)", "punchy (10s)", "calm (20s)"],
"expected_transitions": ["tense→punchy: hard", "punchy→calm: hard"]
}
```
- [ ] **Step 3: Create eval_metadata.json for gradual-escalation**
Write to `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/eval_metadata.json`:
```json
{
"eval_id": 1,
"eval_name": "gradual-escalation",
"prompt": "A luxury fitness brand launch: begin with elegant product beauty shots of a sleek fitness tracker called 'APEX', slowly build energy as athletes appear in motion, crescendo into triumphant celebration with the brand tagline 'Rise Above'. Total duration ~40 seconds. Black and gold palette, modern sans-serif typography.",
"expected_phases": ["elegant (15s)", "energetic (12s)", "playful (13s)"],
"expected_transitions": ["elegant→energetic: escalation", "energetic→playful: soft"]
}
```
- [ ] **Step 4: Verify directory structure**
```bash
find ~/.claude/skills/emotion-to-motion-workspace/iteration-3 -type f | sort
```
Expected output shows both `eval_metadata.json` files and the empty output directories.
---
### Task 6: Generate "High Contrast Arc" WITHOUT Skill
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/index.html`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/timing.json`
**Important:** This composition must be generated by a **fresh subagent that does NOT have access to the emotion-to-motion SKILL.md**. The subagent should only receive the prompt and the HyperFrames composition format requirements.
- [ ] **Step 1: Dispatch a fresh subagent with ONLY the prompt**
The subagent receives:
- The prompt from eval_metadata.json
- HyperFrames composition format rules: `data-composition-id` attribute, `gsap.timeline({ paused: true })`, `window.__timelines["id"] = tl`, 1920x1080 viewport, GSAP 3.14.2 from jsdelivr CDN, all `<script>` tags at end of `<body>`, `gsap.registerPlugin()` for all plugins
- **NO** emotion-to-motion skill content
Record the token count and duration in timing.json.
- [ ] **Step 2: Save the output**
Save the generated HTML to `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/index.html`
- [ ] **Step 3: Save timing metrics**
Write timing.json:
```json
{
"total_tokens": <actual>,
"duration_ms": <actual>,
"total_duration_seconds": <actual>
}
```
- [ ] **Step 4: Validate the output**
Verify the HTML:
1. Contains `data-composition-id` attribute
2. Contains `window.__timelines` assignment
3. Uses `gsap.timeline({ paused: true })`
4. GSAP scripts are at end of `<body>`
5. Total timeline duration is approximately 45s
---
### Task 7: Generate "High Contrast Arc" WITH Skill
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/index.html`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/timing.json`
**Important:** This composition must be generated by a **fresh subagent that HAS the full emotion-to-motion SKILL.md** loaded. The subagent receives the prompt AND the skill.
- [ ] **Step 1: Dispatch a fresh subagent with the prompt AND the full SKILL.md content**
The subagent receives:
- The prompt from eval_metadata.json
- The **full content** of `~/.claude/skills/emotion-to-motion/SKILL.md` (all 12 principles, mood recipes, choreography phases, transition matrix, intra-scene choreography)
- HyperFrames composition format rules (same as Task 6)
Record the token count and duration.
- [ ] **Step 2: Save the output**
Save the generated HTML to `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/index.html`
- [ ] **Step 3: Save timing metrics**
Write timing.json with actual values.
- [ ] **Step 4: Validate the output**
Same validation as Task 6, PLUS:
1. Contains 3 distinct phases (tense, punchy, calm)
2. Uses CustomEase for tension curves
3. Has transition choreography between phases
4. Entrance/emphasis/exit patterns are present per phase
---
### Task 8: Generate "Gradual Escalation" WITHOUT Skill
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/outputs/index.html`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/timing.json`
Same approach as Task 6 but with the gradual-escalation prompt. **No skill loaded.**
- [ ] **Step 1: Dispatch fresh subagent with only the prompt**
- [ ] **Step 2: Save output to index.html**
- [ ] **Step 3: Save timing.json**
- [ ] **Step 4: Validate output** (data-composition-id, __timelines, paused timeline, scripts at end of body, ~40s duration)
---
### Task 9: Generate "Gradual Escalation" WITH Skill
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/outputs/index.html`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/timing.json`
Same approach as Task 7 but with the gradual-escalation prompt. **Full SKILL.md loaded.**
- [ ] **Step 1: Dispatch fresh subagent with prompt AND full SKILL.md**
- [ ] **Step 2: Save output to index.html**
- [ ] **Step 3: Save timing.json**
- [ ] **Step 4: Validate output** (same as Task 8 PLUS: 3 phases elegant→energetic→playful, escalation + soft transitions, choreography patterns per phase)
---
### Task 10: Grade All 4 Compositions
**Files:**
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/grading.json`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/grading.json`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/outputs/grading.json`
- Create: `~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/outputs/grading.json`
- [ ] **Step 1: Read all 4 index.html files**
Read each composition output to analyze against the 8 grading criteria.
- [ ] **Step 2: Grade high-contrast-arc/with_skill**
Analyze the composition against the 8 criteria using the 0/1/2 scoring rubric from the spec (see `docs/superpowers/specs/2026-03-25-emotion-to-motion-iter3-design.md`, Grading Criteria section). Write grading.json:
```json
{
"eval_name": "high-contrast-arc",
"variant": "with_skill",
"criteria": [
{ "name": "phase-presence", "score": <0|1|2>, "evidence": "<specific evidence from the HTML>" },
{ "name": "entrance-choreography", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "emphasis-choreography", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "exit-choreography", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "transition-technique", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "duration-fidelity", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "mood-appropriate-easing", "score": <0|1|2>, "evidence": "<...>" },
{ "name": "valid-hyperframes", "score": <0|1|2>, "evidence": "<...>" }
],
"total_score": <sum>,
"max_score": 16
}
```
- [ ] **Step 3: Grade high-contrast-arc/without_skill**
Same format, same rubric.
- [ ] **Step 4: Grade gradual-escalation/with_skill**
Same format, same rubric.
- [ ] **Step 5: Grade gradual-escalation/without_skill**
Same format, same rubric.
- [ ] **Step 6: Create benchmark.json**
Write to `~/.claude/skills/emotion-to-motion-workspace/iteration-3/benchmark.json`:
```json
{
"iteration": 3,
"date": "2026-03-25",
"cases": [
{
"name": "high-contrast-arc",
"with_skill_score": <total>,
"without_skill_score": <total>,
"delta": <with - without>
},
{
"name": "gradual-escalation",
"with_skill_score": <total>,
"without_skill_score": <total>,
"delta": <with - without>
}
],
"average_with_skill": <avg>,
"average_without_skill": <avg>,
"average_delta": <avg delta>
}
```
---
### Task 11: Deploy to HyperFrames Studio for Visual Review
**Files:**
- Create: `packages/studio/data/projects/high-contrast-arc-with-skill/index.html`
- Create: `packages/studio/data/projects/high-contrast-arc-without-skill/index.html`
- Create: `packages/studio/data/projects/gradual-escalation-with-skill/index.html`
- Create: `packages/studio/data/projects/gradual-escalation-without-skill/index.html`
- [ ] **Step 1: Copy compositions to studio projects**
```bash
cp ~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/with_skill/outputs/index.html packages/studio/data/projects/high-contrast-arc-with-skill/index.html
cp ~/.claude/skills/emotion-to-motion-workspace/iteration-3/high-contrast-arc/without_skill/outputs/index.html packages/studio/data/projects/high-contrast-arc-without-skill/index.html
cp ~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/with_skill/outputs/index.html packages/studio/data/projects/gradual-escalation-with-skill/index.html
cp ~/.claude/skills/emotion-to-motion-workspace/iteration-3/gradual-escalation/without_skill/outputs/index.html packages/studio/data/projects/gradual-escalation-without-skill/index.html
```
(Create the project directories first with `mkdir -p` if they don't exist.)
- [ ] **Step 2: Verify studio picks up the projects**
Start or refresh the studio dev server. All 4 projects should appear in the project list.
- [ ] **Step 3: Present results to user**
Report:
1. Benchmark scores (with vs without, per case and average)
2. Key qualitative differences observed during grading
3. Studio URLs for visual review
4. Recommendations for next iteration based on results
---
### Task 12: Update Memory
**Files:**
- Modify: `~/.claude/projects/-Users-vanceingalls-src-hyperframes/memory/project_emotion_to_motion_skill.md`
- [ ] **Step 1: Update the project memory with iteration 3 status**
Update the memory file to reflect:
- Iteration 3 complete
- Multi-scene choreography phases, transition matrix, and intra-scene choreography added to SKILL.md
- 2 test cases (high-contrast-arc, gradual-escalation) at 40-45s duration
- Benchmark scores (fill in actual scores)
- Any learnings or issues discovered during generation
@@ -0,0 +1,318 @@
# Emotion-to-Motion Skill: Iteration 3 Design
## Status
- **Date:** 2026-03-25
- **Iteration:** 3 (previous: iterations 1 & 2 with 8-12s single-scene compositions)
- **Goal:** Support 30-60s multi-scene compositions with mood transitions and intra-scene choreography
## Background
Iterations 1 and 2 validated that the emotion-to-motion skill improves mood alignment in GSAP compositions — custom eases, appropriate plugin choices, and motion that matches emotional intent. However, compositions were short (8-12s) and single-scene. Key findings:
- Playful/fun showed the clearest improvement with choreography principles
- Dramatic and elegant showed subtler differences (restraint is inherent to the mood)
- Short compositions don't give enough room to demonstrate the skill's value
- No support for mood transitions or multi-scene arcs
This iteration addresses all of these by introducing choreography phases, a transition matrix, and intra-scene choreography patterns.
## Design
### 1. Choreography Phases
A composition is decomposed into an ordered list of **phases**. Each phase has:
- **Mood** — one of the canonical moods: dramatic, playful, elegant, energetic, calm, tense, punchy
- **Duration** — seconds this phase occupies in the master timeline
- **Content description** — what's visually happening (elements, text, imagery)
- **Entrance pattern** — how elements arrive (see Section 3)
- **Emphasis pattern** — how the scene holds attention mid-phase (see Section 3)
- **Exit pattern** — how elements leave, feeding into the transition (see Section 3)
#### Mood Synonym Resolution
Prompts often use evocative language that doesn't match canonical mood names. Resolve synonyms before phase decomposition:
| Synonym | Canonical Mood |
|---------|---------------|
| explosive, intense, fierce | punchy |
| serene, peaceful, tranquil | calm |
| triumphant, victorious, celebratory | playful |
| suspenseful, ominous, creeping | tense |
| luxurious, refined, sophisticated | elegant |
| exciting, dynamic, high-energy | energetic |
| cinematic, epic, grand | dramatic |
#### Mood Recipe Reference
Each canonical mood has a recipe (defined in the existing SKILL.md) that provides:
- **Easing curves** — GSAP ease strings (e.g., `"power4.in"`, `CustomEase.create(...)`)
- **Duration range** — min-max seconds per tween (e.g., dramatic: 0.8-2.5s, punchy: 0.1-0.4s)
- **Preferred plugins** — GSAP plugins to load (e.g., dramatic: CustomEase, SplitText; playful: CustomBounce, CustomWiggle)
- **Intensity range** — movement magnitude bounds (e.g., elegant: y 5-20px, rotation 0-2deg; energetic: y 30-80px, rotation 5-15deg)
#### Phase Decomposition Rules
The skill handles two input styles:
**Explicit per-scene moods:** The prompt specifies each scene's mood directly.
> "Scene 1 (tense, 15s): fragments of text drift in darkness. Scene 2 (punchy, 10s): title shatters into view. Scene 3 (calm, 20s): debris floats gently."
The skill extracts mood (resolving synonyms), duration, and content directly from the prompt.
**Arc-based descriptions:** The prompt describes an overall emotional journey.
> "Build from quiet unease to cathartic release to calm aftermath"
The skill decomposes this into phases by:
1. Identifying the mood anchors in the description (quiet unease = tense, cathartic release = dramatic, calm aftermath = calm)
2. Allocating durations using weighted distribution (see table below)
3. Generating content suggestions that serve each mood
**Duration allocation weights** — multiply each phase's weight by the target total, divide by the sum of all weights, round to nearest second:
| Mood | Weight | Rationale |
|------|--------|-----------|
| calm, elegant | 1.2 | Need room to breathe, long durations |
| dramatic, tense | 1.0 | Standard pacing |
| energetic, playful | 0.9 | Sustained energy gets tiring |
| punchy | 0.7 | Impact depends on brevity |
**Minimum phase duration:** 6s. If allocation produces a phase shorter than 6s, clamp to 6s and redistribute the deficit from the longest phase.
For a 30-60s composition, expect 3-5 phases at 8-15s each. Allow up to 7 phases if the prompt explicitly calls for them, but warn that individual phase durations may compress.
#### Edge Cases
- **Single-mood prompts:** If the prompt describes one mood for 30-60s, treat as one phase with no transitions. Apply entrance/emphasis/exit choreography across the full duration.
- **Adjacent same-mood phases:** If two consecutive phases share the same canonical mood, merge them into one phase unless their content descriptions feature different primary subjects or visual elements (e.g., "product close-up" vs. "lifestyle scene"). If kept separate, use a soft transition.
- **More than 7 phases:** Suggest consolidating phases with similar moods. The agent should not produce more than 7 phases in a single composition.
### 2. Transition Matrix
Transitions between phases are inferred from the **mood delta** — how different adjacent phases feel. Three categories:
#### Hard Transitions (high contrast mood shifts)
- **Overlap:** 0.3-0.8s
- **Technique:** Scene N's elements snap out (opacity 0, scale 0.95) while Scene N+1's elements slam in simultaneously
- **Feels like:** A film cut — the energy shift IS the transition
- **When:** tense→punchy, calm→punchy, elegant→energetic, any shift where the moods are fundamentally opposed
#### Soft Transitions (low contrast mood shifts)
- **Overlap:** 1.5-3s
- **Technique:** Scene N's elements slowly fade/drift out while Scene N+1's elements gradually emerge underneath
- **Feels like:** A long crossfade — elements from both scenes coexist briefly
- **When:** elegant→calm, dramatic→tense, calm→elegant, any shift between adjacent emotional temperatures
#### Escalation Transitions (building intensity)
- **Overlap:** 0.8-1.5s
- **Technique:** Scene N's elements accelerate their exit (speeding up ease curves), Scene N+1's entrance inherits that momentum
- **Feels like:** A tempo ramp — motion gets faster before the new scene lands
- **When:** calm→energetic, tense→dramatic, elegant→punchy, any shift that increases intensity
#### Full Transition Lookup Table
| From \ To | dramatic | playful | elegant | energetic | calm | tense | punchy |
|-------------|------------|------------|------------|------------|------------|------------|------------|
| dramatic | soft | hard | soft | escalation | soft | soft | hard |
| playful | hard | soft | hard | soft | hard | hard | hard |
| elegant | soft | hard | soft | escalation | soft | escalation | hard |
| energetic | hard | soft | hard | soft | hard | hard | hard |
| calm | escalation | hard | soft | escalation | soft | escalation | hard |
| tense | escalation | hard | soft | escalation | soft | soft | hard |
| punchy | hard | soft | hard | hard | hard | hard | soft |
**Matrix rationale for non-obvious entries:**
- playful→punchy = hard: playful is flowing, punchy is staccato — a cut emphasizes the character shift
- energetic→punchy = hard: both are high-energy but sustained vs. staccato — a cut marks the textural shift
- tense→elegant = soft: both share restraint and controlled motion, low contrast warrants a crossfade
- punchy→energetic = hard: staccato to sustained flow is a fundamental rhythm change
### 3. Intra-Scene Choreography Patterns
Each phase gets choreography patterns for its three acts (entrance, emphasis, exit), derived from its mood.
#### Entrance Choreography — how elements arrive
| Pattern | Moods | Description |
|--------------|--------------------|-----------------------------------------------------------------------------|
| Cascade | energetic, playful | Rapid staggered entrances, each element slightly offset (0.05-0.1s gaps) |
| Slow reveal | dramatic, tense | Elements emerge one at a time with long pauses between, building anticipation |
| Ensemble | elegant, calm | Elements fade in together or in 2-3 groups, no single element demands attention |
| Impact | punchy | Hero element hits first and hard, supporting elements follow in quick succession |
#### Emphasis Choreography — how the scene holds attention mid-phase
| Pattern | Moods | Description |
|---------------|--------------------|--------------------------------------------------------------------|
| Pulse | energetic, punchy | Subtle scale or brightness oscillation on key elements, keeps rhythm |
| Drift | calm, elegant | Slow continuous motion — gentle float, rotation, or parallax shift |
| Tension hold | tense, dramatic | Near-stillness with micro-tremor on one element, building unease |
| Play | playful | Secondary action — idle wobbles, bounces, rotation on supporting elements |
#### Exit Choreography — how elements leave (feeds into transition)
| Pattern | Moods | Description |
|---------------|--------------------|--------------------------------------------------------------------|
| Scatter | playful, energetic | Elements exit in different directions with stagger |
| Fade recede | calm, elegant | Opacity + slight scale down, elements sink back |
| Snap out | dramatic, punchy | Hard opacity to 0, no ease out — just gone |
| Compress | tense | Elements slowly contract inward before the next scene hits |
#### Mood-to-Default-Pattern Mapping
| Mood | Entrance | Emphasis | Exit |
|------------|-------------|---------------|--------------|
| dramatic | slow reveal | tension hold | snap out |
| playful | cascade | play | scatter |
| elegant | ensemble | drift | fade recede |
| energetic | cascade | pulse | scatter |
| calm | ensemble | drift | fade recede |
| tense | slow reveal | tension hold | compress |
| punchy | impact | pulse | snap out |
Prompt-level overrides take precedence: if the prompt says "the title slams in," use impact entrance regardless of mood default.
### 4. Timeline Assembly
The master GSAP timeline is composed as follows:
```
masterTimeline
├── phase1Timeline (0s - 15s)
│ ├── entrance (0s - 3s)
│ ├── emphasis (3s - 12s)
│ └── exit (12s - 15s)
├── transition1 (overlaps phase1 exit + phase2 entrance)
├── phase2Timeline (14.2s - 24.2s)
│ ├── entrance (14.2s - 17s)
│ ├── emphasis (17s - 21.5s)
│ └── exit (21.5s - 24.2s)
├── transition2 (overlaps phase2 exit + phase3 entrance)
└── phase3Timeline (23s - 43s)
├── entrance (23s - 26s)
├── emphasis (26s - 40s)
└── exit (40s - 43s)
```
- Transitions overlap the exit of phase N and entrance of phase N+1
- Overlap duration comes from the transition matrix category
- Transition overlap is drawn from the exit duration of phase N and entrance duration of phase N+1 (not additional time). If the combined overlap on both sides of a phase exceeds 50% of its entrance + exit allocation, clamp to 50% and shorten the overlap
- Each phase timeline is a nested `gsap.timeline()` added to the master at the correct position
- Phase entrance/emphasis/exit durations scale proportionally to the phase's total duration using these defaults:
| Mood | Entrance | Emphasis | Exit | Rationale |
|------------|----------|----------|-------|-----------|
| dramatic | 25% | 55% | 20% | Slow reveal needs more entrance time |
| playful | 20% | 60% | 20% | Balanced — emphasis carries the fun |
| elegant | 20% | 65% | 15% | Long drift emphasis, gentle fade exit |
| energetic | 15% | 65% | 20% | Fast cascade entrance, sustained pulse |
| calm | 20% | 65% | 15% | Gentle ensemble in, long drift, soft exit |
| tense | 25% | 50% | 25% | Slow reveal + long compress exit for buildup |
| punchy | 15% | 60% | 25% | Impact entrance is fast, snap out exit needs setup |
### 5. Skill File Changes
The existing `~/.claude/skills/emotion-to-motion/SKILL.md` gets three new sections appended:
1. **Choreography Phases** — phase decomposition rules for explicit and arc-based prompts
2. **Transition Matrix** — the full lookup table with overlap durations and technique descriptions
3. **Intra-Scene Choreography** — entrance/emphasis/exit pattern definitions with mood-to-default mapping
Existing mood recipes remain unchanged — they provide the easing curves, duration ranges, and plugin choices that the new choreography patterns reference.
### 6. Known Issue: Subagent Script Placement
From iteration 1/2 learnings: subagents sometimes place `<script>` tags in `<head>` instead of body and forget `gsap.registerPlugin()`. The skill update should include an explicit reminder:
> All `<script>` tags go at the end of `<body>`. Always call `gsap.registerPlugin()` for every plugin loaded via CDN before using it.
## Evaluation
### Test Cases
#### Case 1: High Contrast Arc (~45s)
**Prompt:**
> "A thriller title sequence: open with creeping unease as fragments of text drift in darkness, then SNAP — explosive reveal of the title with shattering glass, then settle into calm aftermath with slow floating debris"
**Expected phases:**
- Phase 1 — tense (15s): text fragments drift, darkness, slow reveal entrance, tension hold emphasis, compress exit
- Phase 2 — punchy (10s): title shatter, impact entrance, pulse emphasis, snap out exit (synonym: "explosive" → punchy)
- Phase 3 — calm (20s): floating debris, ensemble entrance, drift emphasis, fade recede exit
**Expected transitions:**
- tense → punchy: hard (0.3-0.8s overlap, compressed elements snap away as title slams in)
- punchy → calm: hard (0.3-0.8s overlap, title snaps out as debris fades in — high contrast shift)
#### Case 2: Gradual Escalation (~40s)
**Prompt:**
> "A luxury fitness brand launch: begin with elegant product beauty shots, slowly build energy as athletes appear in motion, crescendo into triumphant celebration with the brand tagline"
**Expected phases:**
- Phase 1 — elegant (15s): product shots, ensemble entrance, drift emphasis, fade recede exit
- Phase 2 — energetic (12s): athletes in motion, cascade entrance, pulse emphasis, scatter exit
- Phase 3 — playful (13s): celebration + tagline, cascade entrance, play emphasis, scatter exit (synonym: "triumphant" → playful)
**Expected transitions:**
- elegant → energetic: escalation (0.8-1.5s overlap, product shots accelerate out as athletes carry momentum in)
- energetic → playful: soft (1.5-3s overlap, athletes blend into celebration)
### Grading Criteria (8 per case)
Each criterion is scored: **0** (absent), **1** (partially present), **2** (fully present). Total possible: 16.
| # | Criterion | 0 (absent) | 1 (partial) | 2 (full) |
|---|-----------|------------|-------------|----------|
| 1 | **Phase presence** | One flat mood throughout | Mood shifts exist but phases aren't distinct (no clear boundaries) | Distinct phases with identifiable mood shifts and clear boundaries |
| 2 | **Entrance choreography** | Elements appear with no entrance animation | Entrances exist but don't match mood pattern (e.g., cascade on a tense phase) | Mood-appropriate entrance pattern per the mapping table |
| 3 | **Emphasis choreography** | Dead air mid-phase — elements are static | Some motion exists but doesn't match mood (e.g., pulse on a calm phase) | Mood-appropriate emphasis pattern sustains attention through the phase |
| 4 | **Exit choreography** | Elements hard-disappear or stay until next scene overwrites them | Exit animations exist but don't coordinate with the transition | Elements leave with mood-appropriate exit pattern that feeds into the transition |
| 5 | **Transition technique** | No transitions — phases are hard cuts with no choreography | Transitions exist but wrong type for the mood delta (e.g., soft crossfade between tense→punchy) | Transition matches expected category from the matrix (hard/soft/escalation) |
| 6 | **Duration fidelity** | Total under 25s or over 70s | Total is 30-60s but phase proportions don't match the prompt | Total is 30-60s and phases are proportioned appropriately |
| 7 | **Mood-appropriate easing** | Generic eases only (power1, linear) across all phases | Some mood-specific eases but inconsistent | Each phase uses eases from its mood recipe (CustomEase for dramatic, elastic for playful, etc.) |
| 8 | **Valid HyperFrames** | Missing GSAP, broken HTML, or scripts in head | Valid HTML + GSAP but missing registerPlugin or wrong version | Well-formed HTML, GSAP 3.14.2, all plugins registered, scripts at end of body |
### Evaluation Structure
```
emotion-to-motion-workspace/
iteration-3/
high-contrast-arc/
with_skill/
outputs/
index.html
grading.json
timing.json
without_skill/
outputs/
index.html
grading.json
timing.json
eval_metadata.json
gradual-escalation/
with_skill/
outputs/
index.html
grading.json
timing.json
without_skill/
outputs/
index.html
grading.json
timing.json
eval_metadata.json
benchmark.json
```
## Out of Scope
- Changes to HyperFrames core packages — this is purely a skill-level update
- New GSAP plugins beyond what's already supported
- Audio/music synchronization
- Interactive or scroll-driven compositions
## Dependencies
- GSAP 3.14.2 on jsdelivr CDN (all plugins available)
- GSAP plugin support branch merged or available (feat/gsap-plugin-support — code complete, 95 tests)