Create a Tooltip component with styled popover (dark bg, border,
shadow) that appears on hover with a 400ms delay. Applied to:
- Left sidebar tabs: Code, Comps, Assets, Catalog
- Right panel tabs: Design, Layers, Motion, Renders
Replaces native title attributes with proper styled tooltips.
Add title attributes to interactive elements that were missing them:
- PlayerControls: Play/Pause, playback speed, shortcuts panel, clear
in/out-point buttons, and jump-to-frame Go button
- StudioRightPanel: Design, Layers, Motion, and Renders tab buttons
Call tl.pause() both before AND after tl.seek() in the adapter.
GSAP's seek() can reactivate a timeline depending on internal state;
the second pause() guarantees it stays frozen at the seeked position.
When seeking via the slider or timeline scrub, explicitly pause all
<video> and <audio> elements inside the preview iframe. The GSAP
timeline pauses but iframe media elements can continue playing
independently, causing audio to keep going after a seek.
Clicking "Ask agent" now opens a modal that shows the full generated
prompt so the user can read it before copying. The modal has a "Copy
prompt" button that turns green on success. This replaces the silent
clipboard copy that gave no visibility into what was copied.
- Ask agent button turns green with checkmark on copy
- Add button shows tooltip "Add to composition at current time"
- Ask agent shows tooltip "Copy a prompt to paste into your AI agent"
- Tab tooltips: Code, Comps, Assets, Catalog each explain their purpose
- Search placeholder updated to "Search by name, category, or tag…"
Add button rules: VFX, Social, Scenes get Add + Ask agent. Captions,
Transitions, Effects, Data get Ask agent only.
Search now matches category names and tags, so searching "captions"
shows all caption blocks.
Components (hyperframes:component) get both "Add" and "Ask agent"
buttons since they work as drop-in overlays. Blocks (scenes, data,
VFX, transitions) show only "Ask agent" since they need agent-guided
customization.
The "Ask agent" button now copies the current composition state along
with the category-specific prompt: playback time, active composition
path, dimensions, and all elements visible at the current time with
their track, timing, and source paths. Gives the agent full context
to place and customize the block correctly.
When previewing a component (compositions/components/*), render the
main composition player as a backdrop behind the transparent component
overlay. This lets users see captions, vignettes, and other overlays
in context instead of against a black void.
Registry blocks are authored at 1920x1080 but projects may use
different dimensions (e.g. 1280x720). After installing a block, the
server now reads the host project's data-width/data-height from
index.html and rewrites the block's viewport meta and CSS dimensions
to match, preventing overflow.
Remove the Add button and drag-and-drop from catalog cards — blocks
and components need agent-guided customization, not blind insertion.
Each card now shows a single "Ask agent" button that copies a rich,
category-specific prompt to clipboard with context about what the
block does and how to customize it (captions: transcribe + style,
transitions: place at cut point, data: replace values, etc.).
Each catalog card now shows two hover buttons:
- "Add" — inserts the block/component into the composition at the
current playhead position (existing behavior, now with + icon)
- "Agent prompt" — copies a contextual prompt to clipboard tailored
to the block's category (captions, transitions, VFX, etc.) so the
user can paste it into their AI agent for guided customization
Blocks and components now start at the current playhead position
instead of being appended after all existing content. If the new
element extends beyond the root composition's data-duration, the
root is automatically extended to fit.
insertTimelineAssetIntoSource now detects the parent indent level and
adds the new element with matching child indentation. Block attributes
are written one-per-line for readability.
Blocks were using their own native dimensions (e.g. 1920x1080) instead
of the host composition dimensions (e.g. 1280x720), causing them to
overflow the viewport and break the layout. The block's iframe scales
its content to fit the container, so using host dimensions is correct.
Replace fragile regex z-index parsing with getComputedStyle on the
preview iframe elements — the same source of truth the inspector uses.
Rename "Layer" to "Z-index" in the design panel for clarity.
The DomEditOverlay sits at z-10 with pointer-events:auto over the
preview, intercepting all drag events before they reach NLEPreview's
viewport. Move block drop handling from NLEPreview up to the wrapper
div in NLELayout that contains both the preview and the overlay, so
drag-and-drop from the Catalog panel onto the preview area works
regardless of inspector state.
VITE_STUDIO_* env vars set in the user's shell had no effect when
running `hyperframes preview` because the pre-built studio bundle had
them baked at Vite build time.
The embedded Hono server now collects VITE_STUDIO_* vars from
process.env and injects them as a `window.__HF_STUDIO_ENV__` script
tag into index.html. The client merges this runtime object on top of
the baked `import.meta.env`, so flags like
VITE_STUDIO_ENABLE_BLOCKS_PANEL=1 work as expected at runtime.
- Rename "Blocks" tab to "Catalog"
- Replace fullscreen hover popup with inline preview in main area
- Fix z-index: newly added blocks/components use max existing z-index + 1
instead of element count, ensuring they appear on top
Blocks dragged from the Blocks panel and dropped onto the composition
preview now land at the position where they were dropped, instead of
always being placed at (0, 0).
The preview viewport converts screen coordinates to composition space
using the stage element's bounding rect, accounting for zoom and pan.
A visual drop indicator (dashed border overlay) appears while dragging
over the preview.
When the Code tab is active and a user clicks an element in the preview,
the code editor now auto-scrolls to the corresponding HTML source. This
removes the need for Alt+click — the existing click-to-source mechanism
fires automatically when the Code tab is already open.
- Add getTab() to LeftSidebarHandle for reading the active tab
- Add getSidebarTab getter to useDomEditSession
- Add effect that calls openSourceForSelection on selection change
when Code tab is active
Previous baseline was generated on arm64 host, causing 87 failed
frames in CI (amd64). Regenerated with --platform linux/amd64 to
match CI's Chrome/FFmpeg pixel output.
gsap.fromTo(target, fromVars, toVars) animates to toVars, not to
the current CSS value — so fromTo({opacity:0}, {opacity:1}) with
CSS opacity:0 is a legitimate 0→1 fade-in, not a noop. The rule
was false-positiving on these calls with error severity, which
would block the render pipeline.
Drop the fromTo branch from the trigger guard and add a test case
that proves fromTo does not fire.
Per James and Miguel's review feedback:
James: "you can only reference the skill or recreate things"
Miguel: "I'd just reference the skill without trying to copy
everything"
James: "we can't vendor their artifacts in our own repo"
The 48 vendored text-effects JSON files were direct copies from
pixel-point/animate-text (verified: typewriter.json matches the
upstream byte-for-byte at duration_ms: 240, stagger_ms: 46,
easing: steps(1, end)). That repo has no LICENSE file, so the
files default to "all rights reserved" — Apache 2.0 redistribution
in our repo is a compliance violation.
The earlier "rewrite from scratch" attempt produced JSON that
didn't render correctly (7 of 24 effects broke when I built a demo
HTML to validate them). Rather than keep iterating on a rewrite
that doesn't match the upstream's calibration, this commit drops
the vendored files entirely and updates skill prose to REFERENCE
the upstream skill instead.
### Changes
- Delete `skills/hyperframes/assets/text-effects/` (48 JSON files
+ the dual-directory structure, 8451 lines).
- Rewrite `skills/hyperframes/references/text-effects.md` as a
reference page that:
- Names pixel-point/animate-text as the source of truth
- Explains why we don't ship the catalog (licensing gap)
- Tells sub-agents to load `/animate-text` via Claude Code skill
invocation or `npx skills add pixel-point/animate-text`
- Lists the 24 effect IDs by category as vocabulary (so agents
can name effects in STORYBOARD.md before loading the upstream)
- Documents the fallback path: implement from name + GSAP
knowledge if the upstream skill isn't available
- Update 5 cross-references to reframe the catalog as upstream-
referenced instead of repo-bundled:
- skills/hyperframes/references/techniques.md (TOC pointer)
- skills/hyperframes/references/beat-direction.md (text-anim
guidance bullet)
- skills/website-to-hyperframes/references/capabilities.md
(registry-overview entry)
- skills/website-to-hyperframes/references/step-3-storyboard.md
(storyboard template + Text Animations section format)
- skills/website-to-hyperframes/references/beat-builder-guide.md
(references table row)
### What sub-agents see
Before: read `text-effects.md` → see 24 named effects → read each
spec from in-repo `assets/text-effects/effects/<id>.json`.
After: read `text-effects.md` → see 24 named IDs and a load
instruction → invoke `/animate-text` (or `npx skills add
pixel-point/animate-text`) → read each spec from
`.agents/skills/animate-text/assets/effects/<id>.json` (the
upstream's own files, not vendored copies).
End-user UX cost: one extra `npx skills add` for projects that
want the deterministic catalog. Or accept the fallback where
sub-agents implement from effect name + GSAP knowledge — works
fine for simple effects, less ideal for the 3 layout-aware ones
(kinetic-center-build, short-slide-right, short-slide-down).
Net diff on #991: -8488 lines.
Two follow-ups caught by a post-restructure audit pass:
- skills/hyperframes/references/transitions.md:46 had a parenthetical
"(derived from visual-vocabulary.md)" pointing at a file deleted
earlier in this stack. Drop the parenthetical; the surrounding
sentence reads cleanly without it.
- skills/hyperframes/SKILL.md:476 still said "20 visual techniques"
and listed 7 entries that the techniques.md trim removed (frosted
glass, impact lines, device mockups, aurora gradients, floating
particles, terminal UI, moodboard layouts). Updated to the actual
13 primitive techniques + a pointer to registry/blocks/ for the
pre-built UI templates that used to be conflated with techniques.
Removed 7 entries that are not techniques. They're either UI style
treatments, hand-rolled CSS templates, or named effects — different
kinds of artifacts that don't belong under the same "primitive
animation techniques" frame:
- 12. Frosted Glass Panels → style treatment
- 15. Impact Line on Text Drop → named effect
- 16. Device Mockups (Laptop + Phone) → hand-rolled CSS template
- 17. Aurora Gradient Backgrounds → style treatment
- 18. Floating Particles → style treatment
- 19. Terminal UI with Typing → hand-rolled CSS template
- 20. Moodboard / Editorial Layout → hand-rolled layout
The 13 entries that remain (SVG drawing, Canvas 2D, CSS 3D, Per-Word
Kinetic Type, Lottie, Video Compositing, Char Typing, Variable Font,
MotionPath, Velocity-Matched Transitions, Audio-Reactive, Clip-Path
Reveal, WebGL Shader Art) are real primitives — animation building
blocks an agent composes into beats, not finished recipes to lift
verbatim.
Updated the header to say 13 and point at `registry/blocks/` for
pre-built UI templates instead of pretending they're techniques. ToC
table and section numbering both updated. Net: -361 / +6 lines.
Per review feedback, these 5 files should not change in this stack:
- visual-styles.md — keep main's existing version
- house-style.md — keep main's light/dark prescription
- references/typography.md — keep main's tone + Banned/Guardrails framing
- references/video-composition.md — keep main's density guidance
- CLAUDE.md — drop the local-CLI Capture/Snapshot section added in
this branch; the local-CLI dev-instruction block for adding CLI
commands stays (was already on main, unrelated to skill prose).
Net: removes ~545 lines of churn from PR #991's diff.
Three concrete bugs found while auditing PR #991:
1. html-in-canvas-patterns.md (#1 in catalog, 3D Rotation with Bloom):
The code example used `new THREE.EffectComposer(renderer)` UMD-style
namespace access while the ESM imports right below pull them in as
bare named imports. Three.js r150+ removed the UMD `examples/js/`
globals, so as written the example throws `TypeError:
THREE.EffectComposer is not a constructor`. Switched to the bare
names matching the imports. THREE.Vector2 stays as-is — Vector2 is
on the THREE namespace.
2. techniques.md (#5, Lottie Animation): The CDN path
`@lottiefiles/dotlottie-web/dist/dotlottie-player.js` returns 404.
`@lottiefiles/dotlottie-web` is the JavaScript SDK, not a web
component — its `main` is `dist/index.cjs`. The web-component
package is `@lottiefiles/dotlottie-wc` and the custom element is
`<dotlottie-wc>`, not `<dotlottie-player>`. Updated both.
3. techniques.md (5 occurrences across Lottie / lottie-web /
Video / @font-face examples): asset paths used the `../capture/`
pattern that PR #989's `invalid_capture_path` lint rule emits an
error for. Replaced all with root-relative `capture/...`. PRs #989
and #991 are no longer self-contradictory.
Rewrites the standalone `hyperframes` skill (the main authoring
skill used by every hyperframes user, not just the
website-to-hyperframes pipeline) to remove prescriptive lookup
tables that drove monoculture output, restore tone, and bundle
24 named text animation effects directly into the skill so
agents don't need a separate install.
This is a +9951/-567 change touching 61 files in `skills/hyperframes/`.
It deserves its own review separate from the capture pipeline and
the website-to-hyperframes pipeline because it affects every
hyperframes user — not just the website-to-video flow.
**Prescriptive tables removed / restructured**
External rater feedback across two rounds identified six lookup
tables agents were pasting wholesale as recipes:
- `visual-styles.md` YAML blocks — completely replaced. Old version
had 8 styles with full YAML token blocks (colors / typography /
motion / transition names). Agents copy-pasted. New version
renames to actual design traditions (Swiss / Late-Modernist
Editorial / Punk / Maximalist / Computational / Humanist /
Vernacular / Cinematic) and replaces YAML with prose: "what it
teaches / where it resonates / pitfalls when borrowing." No
lookup table.
- `motion-principles.md` — complete rewrite. Old version opened
every section with "You know these rules but violate them. Stop."
/ "You will try to use 14px. Don't." New version: "Common defaults
that produce monoculture" framing. All load-bearing GSAP rules
preserved verbatim (those are correct and critical).
- `beat-direction.md` rhythm table — removed. Replaced with
questions that derive rhythm from brand + storyboard. Verb table
regrouped by physical character (Impact / Directional / Reveals /
Organic / Mechanical) without energy labels.
- `transitions.md` Energy → Transition table + Mood → Type table —
removed named transitions, replaced with motion-quality
descriptions (Soft/organic, Directional/purposeful,
Percussive/instant). Mixing documented: CSS crossfade + shader
in the same HyperShader composition (verified working).
- `dynamic-techniques.md` energy table — restructured with
explanatory principles (highlight amplitude, exit style, cycle
variation) before showing the table as calibration reference.
- `techniques.md` "When to Use What" table — deleted. Replaced
with "choose techniques based on beat concept, not video genre."
- `typography.md` — "Guardrails / You know these rules but violate
them" → "Defaults to watch for." Banned fonts gain a caveat:
if the brand actually uses one of these fonts, use it.
- `video-composition.md` — fixed density contradiction
("8–10 visual elements" removed; sparse beats are intentional).
**Text-effects bundle (new)**
24 named text-animation effects shipped as paired specs:
- `assets/text-effects/effects/<id>.json` — GSAP-specific recipe
agents can paste verbatim
- `assets/text-effects/specs/<id>.json` — portable motion contract
(engine-agnostic, so the same effect can be re-implemented in any
animation library)
Catalog at `references/text-effects.md`. Storyboards reference effects
by name (typewriter, kinetic-center-build, shimmer-sweep, …) instead
of saying "fades in," which produced inconsistent typography across
beats.
Effects organized by target:
- Per-character (7): soft-blur-in, per-character-rise, typewriter,
bottom-up-letters, top-down-letters, stagger-from-{center,edges}
- Per-word (8): per-word-crossfade, spring-scale-in, shared-axis-y,
blur-out-up, kinetic-center-build, short-slide-{right,down},
depth-parallax-words
- Per-line (2): mask-reveal-up, line-by-line-slide
- Whole element (7): micro-scale-fade, shimmer-sweep, fade-through,
shared-axis-{x,z}, scale-down-fade, focus-blur-resolve
Sources adapted from `pixel-point/animate-text`; copied into the
repo so users don't need a separate install.
**Misc cleanups**
- `house-style.md` — light/dark prescription removed; defer to brand.
- `prompt-expansion.md` — `design.md` → `DESIGN.md` casing fixed.
- `html-in-canvas-patterns.md` — Three.js 0.147.0 (legacy
`examples/js/`) → 0.181.2 (`examples/jsm/` ESM imports);
`Math.random()` in the shatter example → mulberry32 seeded PRNG
so output is deterministic.
**.gitignore + CLAUDE.md**
- `.gitignore` catches per-brand video project directories agents
leave at the repo root (`huly-*/`, `raycast-*/`, `*-demo-*/`,
`test-runs/`, `test-outputs/`) plus the `videos/` folder
conventions.
- `CLAUDE.md` documents the local CLI for `capture` + `snapshot`
(since the published `npx hyperframes` doesn't yet include the
capture pipeline improvements from this stack) and the local
shader-transitions build copy convention.