* feat(skills): add audio visualizer effect with extraction script
Adds reactive audio visualization patterns for HyperFrames:
Script: extract-audio-data.py pre-extracts per-frame RMS amplitude and
frequency band data via ffmpeg. Uses a 4096-sample FFT window for clean
frequency resolution and per-band normalization across the full track
so treble activity is visible alongside louder bass.
Patterns: spectrum bars, mirrored waveform, pulsing circle, circular
visualizer, background glow — all Canvas 2D driven from the GSAP
timeline via tl.call() at each frame.
Includes smoothing helper, band count guide, band ordering rules
(horizontal: low-left high-right), and combining patterns section.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(skills): replace prescriptive examples with data model + motion principles
Removes five hardcoded draw functions that would get copy-pasted verbatim.
Replaces with:
- Clear data model docs (what rms and bands mean, how to index)
- Rendering approach setup for Canvas 2D, WebGL/Three.js, and DOM
- Motion principles (smoothing, value mapping, what makes it feel good)
- Spatial mapping conventions (low-left/high-right, etc)
The LLM invents the visualization; the skill teaches the data contract
and motion constraints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(skills): off-by-one in band slicing, add data loading, fix trigger
- Fix exclusive slice end: high_bin clamped to n_bins (not n_bins-1)
so the last FFT bin in each band is included
- Add data loading section to skill doc (inline and fetch patterns)
- Fix example JSON to show frame 0 at time 0.0
- Update description to trigger when audio is analyzed and music detected
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(skills): require numpy, fix bugs, clean up skill doc
Script rewrite:
- numpy is now required (pure-Python DFT was unusable for real files)
- Use np.frombuffer instead of struct.unpack (~10x less memory)
- Precompute Hann window and band edges (were recalculated every frame)
- Extract SAMPLE_RATE as module-level constant
- Clamp band bins to prevent max() on empty slice
- Validate --fps and --bands inputs
Skill doc fixes:
- Fix fetch loading example (was null ref on sync for-loop)
- Remove redundant Canvas 2D section (was duplicate of Step 3)
- Fix opening line (said "Canvas 2D" but doc covers 3 approaches)
- Fix undefined W/H in example
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>