Add a Running exercise with an animated stride figure

Stance and flight keyframes with single-frame foot pins for the strikes,
forward lean, opposite-arm drive, and daylight under both feet in flight —
distinct from Cardio's high-knee march, which stays as is.

Claude-Session: https://claude.ai/code/session_01PKptrgbx74peTwHGRxBojv
This commit is contained in:
2026-07-12 00:37:23 -04:00
parent 79e75a9127
commit d04526826c
11 changed files with 298 additions and 6 deletions
+5 -5
View File
@@ -15,7 +15,7 @@ Data flows one way: you edit the **source**, run `render.py --export`, and the
**bundle** is overwritten. Never hand-edit anything under
`Workouts/Resources/ExerciseMotions/` — it is regenerated.
As of this writing the catalog is **64 exercises**.
As of this writing the catalog is **65 exercises**.
```
Exercise Library/ ← authoring source (repo root)
@@ -23,7 +23,7 @@ Exercise Library/ ← authoring source (repo root)
├── skeleton.json ← shared rig: bone lengths + joint ROM
├── render.py kinematics.py ← the render pipeline + the FK math
├── contact-sheet.png demo-sheet.png ← generated QA sheets
└── <Exercise Name>/ ← one folder per exercise, 64 of them
└── <Exercise Name>/ ← one folder per exercise, 65 of them
├── info.md ← AUTHORED: the reference page
├── motion.json ← AUTHORED: the rig script (canonical visual source)
├── frames/frame-N.svg ← generated: one SVG per key frame
@@ -35,8 +35,8 @@ Exercise Library/ ← authoring source (repo root)
Workouts/Resources/ExerciseMotions/ ← bundle (flat, unique basenames)
├── skeleton.json
├── <Exercise Name>.motion.json ← 64
└── <Exercise Name>.info.md ← 64
├── <Exercise Name>.motion.json ← 65
└── <Exercise Name>.info.md ← 65
│ Bundle.main lookups
@@ -208,7 +208,7 @@ three kinds of file:
The generated SVGs and GIFs do **not** ship — the app renders the figure live
from the rig instead. The rename to `<Name>.motion.json` / `<Name>.info.md` is
what lets Xcode's flat resource copy hold all 64 without collision.
what lets Xcode's flat resource copy hold all 65 without collision.
## The app-side consumers (`Workouts/ExerciseFigure/`)