Complete rewrite of all 4 liquid glass registry blocks using
jeantimex/liquid-glass-html-in-canvas for real WebGPU glass rendering.
Architecture: Three.js aurora shader (z:0) + empty glass panels in
layoutsubtree canvas (z:1) + CSS text overlay (z:2). Text is crisp
and never passes through the glass shader.
- Renders via Brave with WebGPU + drawElementImage flags
- Continuous motion throughout — panels sweep across the screen
- liquid-glass.iife.js bundle (25KB) replaces liquid-dom (88KB)
The #f6f6f4 off-white background was showing through the 30px grid
gaps and behind translated cards during the zoom/unzoom transitions,
creating visible white strips in the rendered video. Changed to
#1a1a20 (near-black) so gaps read as intentional dark separators.
Also added a .zoom-backdrop div behind the grid in the zoom demo that
fades to the focus card's gold gradient during the transition, covering
any gaps left by sibling cards translating off-screen.
Co-authored-by: Kanyini <onebenson@gmail.com>
The renderer's Page.captureScreenshot can introduce a 1-2px offset
at viewport boundaries due to compositor subpixel rounding. Grid rows
are now 341px (3×341 + 2×30 = 1083), overflowing the 1080 viewport
by 3px. The overflow is clipped by overflow: hidden, but ensures any
capture offset still sees grid content rather than the body background.
Also removed flex centering from .demo-canvas — unnecessary now that
the grid fills the viewport, and it was a source of non-deterministic
positioning under multi-worker rendering.
Co-authored-by: Kanyini <onebenson@gmail.com>
Cards 360×340 with 30px gap = exactly 1920×1080. No body background
visible at any frame. Focus scale drops from 9 to 6 (360×6 = 2160,
still overshoots viewport by 240px).
Co-authored-by: Kanyini <onebenson@gmail.com>
- Increase --focus-scale from 8 to 9 — at scale 8 the card matched
the viewport width exactly (240×8=1920), leaving zero tolerance for
subpixel rounding. Scale 9 overshoots by 240px on each axis.
- Reduce grid gap from 40px to 24px — the 1040px grid in a 1080px
viewport left only 20px of padding, causing bottom-row cards and
their box-shadows to clip at the frame edge.
- Remove transform-style: preserve-3d from both snippets — no 3D
transforms are used, and preserve-3d can cause compositing artifacts
with overflow: hidden ancestors.
- Unzoom: set --pu-sibling-fade to 0 and drive sibling opacity via
GSAP (starting at t=2.0s). Previously, CSS-driven opacity made cards
70% visible when they first peeked into the viewport, creating
colored strips at the frame edge during the reveal.
Co-authored-by: Kanyini <onebenson@gmail.com>
Two companion components inspired by the eBay Playbook hero transition:
- parallax-zoom: center card scales up to fill the frame while siblings
parallax outward. Single CSS variable (--pz-progress 0→1), fully
seekable and deterministic.
- parallax-unzoom: the reverse — focus card starts at full-frame scale
and shrinks back into its grid position while siblings parallax inward.
Uses --pu-progress with the pu prefix to avoid variable collisions when
both components live in the same composition.
Designed to chain: zoom INTO a card in scene 1, unzoom OUT of it in
scene 2 to reveal a fresh grid underneath.
Includes demo compositions, registry manifests, and catalog pages.
Preview assets rendered and uploaded to CDN.
Co-authored-by: Kanyini <onebenson@gmail.com>
Caption components are overlays — their root element should not
intercept pointer events, allowing clicks to pass through to the
underlying composition content in Studio.
Replace opaque backgrounds (#0a0a0a, #000, #000000) with transparent
on both html/body and the composition root div for all 15 caption
components. Captions are overlays — opaque backgrounds cover the
underlying video when loaded as sub-compositions.
Timeline locking:
- Add data-timeline-locked attribute support — fully disables move,
trim-start, and trim-end in Studio for clips that carry this attr
- Runtime propagates the attribute from inner composition root to host
element so component authors control it from their HTML
- All 15 caption components in the registry now carry the attribute
Font fix:
- Extract <link rel="stylesheet"> and <link rel="preconnect"> from
sub-composition <head> alongside existing <style>/<script> extraction
- Fixes caption components (and any sub-comp using Google Fonts via
<link> tags) losing their font-family when loaded as sub-compositions
- Applied in both runtime (compositionLoader) and compiler
(inlineSubCompositions) paths
Catalog preview script (scripts/generate-catalog-previews.ts) uses demo.html
as the component entry point. Missing file caused the Render catalog previews
job to fail with "Item not found".
Adds a Blocks tab to the Studio left sidebar with the full 78-item registry
catalog (58 blocks + 20 components). Users can browse by category, search by
title/description, preview CDN-hosted poster thumbnails with video-on-hover,
and install items on-demand with one click or drag-to-timeline.
Core changes:
- BlockCategory type + resolveBlockCategory() for 7 categories (Captions, VFX,
Transitions, Effects, Social, Data, Scenes)
- Registry API routes: GET /api/registry/blocks (catalog) + POST install
- StudioApiAdapter extended with listRegistryCatalog + installRegistryBlock
- Vite adapter reads from disk; CLI adapter fetches from GitHub (24h cache)
- BlockParam interface + params on 6 blocks for future parameter controls
Studio UI:
- 4th sidebar tab "Blocks" with responsive grid, category pills, search bar
- BlockCard: CDN poster thumbnail, video autoplay on hover, duration + WebGL badges
- On-demand install: blocks append as sub-compositions on timeline; components
overlay at start=0 spanning full duration with transparent background patching
- TIMELINE_BLOCK_MIME drag-and-drop to timeline
- BlockParamsPanel (Phase 3 scaffold) auto-opens for parameterized blocks
Registry manifests:
- All 58 blocks backfilled with preview: { video, poster } CDN URLs
- All 20 components normalized to object format + poster URLs added
- 6 blocks annotated with params (Liquid Glass/Background, Portal, Chart,
Logo Outro, Magnetic)
- flowchart-vertical preview generated and uploaded to CDN
Rename component to caption-texture and bundle 6 popular textures
(lava, marble, metal, wood, concrete, rock). The texture is configurable
via the texture composition variable (default: lava).
Usage: hyperframes render --variables '{"texture":"marble-012"}'
Tested: lava, marble-012, metal-046-b all render correctly with
distinct visual patterns.
- Replace from:"random" with from:"center" stagger in us-map,
world-map, spain-map — random stagger is non-deterministic across
parallel render workers, causing visual jumps at chunk boundaries.
- Exempt type="importmap" and type="module" inline scripts from the
invalid_inline_script_syntax lint rule. The rule used new Function()
to parse, which rejects import statements and JSON import maps.
Closes#929.
- Cache-bust all map MDX preview video URLs after re-rendering with
the deterministic stagger fix.
New block: spain-map — animated Spain choropleth by autonomous
community using D3 conic conformal projection with GDP per capita
data and red-to-amber color scale.
Also switches all map MDX preview URLs from S3 to local paths
so they render in mintlify dev without needing S3 upload first.
New blocks: world-map (D3 Natural Earth choropleth), us-map-bubble
(proportional city markers), us-map-hex (hexagonal tile grid),
us-map-flow (animated connection arcs between cities).
All blocks share the same dark theme and are composable — layer
bubble or flow on top of the choropleth via track indexes.
Adds "Maps" section to the catalog docs with MDX pages for all 5
map blocks (including the us-map from the previous commit).
Animated US population density choropleth using D3 geoAlbersUsa
projection with TopoJSON. Includes staggered state reveals, label
fade-ins, gradient legend, and highlight pulses on densest states.
Upload re-rendered videos with -v2 filenames to bypass CloudFront
immutable cache. Replace gradient-fill with improved version from
sandbox composition.
The deterministic font system now supplements its embedded font bundle
with Google Fonts fetches for any weights not in the pre-bundled set.
This fixes compositions that request font weights (e.g. Montserrat 300)
not included in the CANONICAL_FONTS faces array — previously those
weights were silently dropped, causing invisible text in renders.
Also replaces caption-glitch-rgb and caption-weight-shift with improved
versions from avatar preview compositions, adapted to 1920x1080 with
standard demo transcript.
- clip-wipe: slower reveal (0.3s), longer hold, smoother exit
- glitch-rgb: 2.5x larger RGB split, stronger scanlines, more dramatic jitter
- gradient-fill: smoother word transitions (0.15s), longer exit
- typewriter: extended group hold times so text lingers on screen
- weight-shift: per-word font-weight animation (200→900), was broken
with only line-level shift that never triggered on single-line groups
- Add caption-highlight: red background sweep behind active word (TikTok-style)
- Re-rendered and uploaded preview videos for all 6 components
- Fix timeline_id_mismatch on all 15 caption components: __timelines key
now matches data-composition-id (e.g. "caption-clip-wipe" not "clip-wipe")
- Regenerate docs/public/catalog-index.json with 15 new caption entries
- Add "Captions" group mapping to generate-catalog-pages.ts (priority 0)
- Regenerate docs.json nav and mdx pages via the catalog script
- Upload docs preview videos to docs/images CDN path
- Fix caption-texture-lava mask URL to use local lava.png instead of
/assets/texture-mask-text/masks/ absolute path that 404s on install
- Add lava.png to registry-item.json files array so it ships with
npx hyperframes add caption-texture-lava
- Remove unused mulberry32 function from caption-clip-wipe
- Add 15 .mdx doc pages under docs/catalog/components/ for all caption styles
- Add "Captions" group as first section in the Catalog tab navigation
- Add canvas-based fitFontSize to 14 caption components to prevent text overflow
- Fix parallax-layers vertical clipping by repositioning the behind safe zone
- Re-render all 15 preview videos at high quality and upload to CDN
Two surgical changes, both isolated to the catalog-previews flow:
1. `packages/studio/src/player/hooks/usePlaybackKeyboard.test.ts`
PR #842 changed `seek()` to take `(time, { keepPlaying: true })` for the
A/E shortcuts. The keyboard-layout tests added by #839 still asserted the
single-arg form. Both landed on main without cross-checking, so `main`
itself has been failing Test/Windows since. Update the two assertions
to match the new signature. Same fix Miguel already authored on
`feat/studio-preview-pasteboard-bg`.
2. `registry/components/vignette/demo.html`
The original demo captured a frame where the vignette was at its
weakest point — the effect was nearly invisible in the static preview
used by docs. Reworked the demo so:
- The backdrop is a layered "cinematic still" (warm key + teal rim +
dark falloff) and includes a centered subject ("moon"), so the
vignette has a focal point to frame.
- Vignette starts soft (size 70%, alpha 0.35) and ramps to a dramatic
cinematic vignette (size 26%, alpha 0.92) over 1.6s.
- Peak intensity holds across t≈3.0s, which is exactly where the
catalog script samples the thumbnail (`Math.min(3.0, duration*0.6)`
with duration=5).
- Breathing motion in t=3.4–5.2s gives the video loop visible life
without disturbing the still frame.
Pure-CSS radial darkening overlay that fills its positioned parent and
pulls focus toward the center. Shape, size, and color are exposed as
CSS custom properties (--vignette-shape, --vignette-size,
--vignette-edge, --vignette-color), so a GSAP timeline can animate any
of them — the snippet's header comment shows the pattern for fading
the vignette in.
The Components section currently has four entries; this fills the
cinematic-cinematography gap a video editor expects out of the box
without bundling any asset (the effect is a single radial-gradient).
Default z-index 90 sits below grain-overlay (100) so grain reads on
top of the darkened corners.
Catalog page, registry index, and nav are regenerated via
scripts/generate-catalog-pages.ts.
* fix(player): replay from start when play is pressed after video ends
When a non-looping composition reaches its end, pressing play again
had no effect because the playhead stayed at the final frame. Now
play() detects the ended state and seeks to 0 before resuming.
* chore: fix pre-existing format issues in registry files
* docs: group VFX blocks under HTML-in-Canvas, captions under Captions in sidebar
* docs: add HTML-in-Canvas guide, Chrome flag disclaimer, remove captions
- Add docs/guides/html-in-canvas.mdx — comprehensive guide covering the
API, feature detection, re-capture patterns, and catalog blocks
- Add Chrome flag Warning banner to every HTML-in-Canvas block page
- Remove captions blocks from registry (will ship separately)
- Add html-in-canvas guide to docs navigation (top of Guides section)
* feat: update liquid glass, portal, shatter with HyperFrames branding
Replace generic placeholder content with HyperFrames-themed text:
- Liquid Glass: 'Ship videos 10x faster' with stats and gradient text
- Portal: 'Write HTML / Render Video' with HyperFrames nav
- Shatter: 'HTML is Video' with render speed/file size metrics
Re-rendered and uploaded preview videos to S3.
hyperframes add now auto-detects whether the argument is a single
block name or a tag. No --tag flag needed:
hyperframes add html-in-canvas # installs all 7 html-in-canvas blocks
hyperframes add captions # installs all 5 caption blocks
hyperframes add vfx-shatter # installs one block
When the name doesn't match a registry item, the CLI falls back to
tag-based resolution and bulk-installs all matching blocks.
Also fixes tag assignments:
- VFX blocks tagged "html-in-canvas" (not "vfx")
- Caption blocks tagged "captions" only (no html-in-canvas)
All 12 blocks now share the 'html-in-canvas' tag, enabling:
hyperframes add --tag html-in-canvas
This installs all VFX + caption blocks in one command.
Add 12 new registry blocks across two new categories:
**VFX Blocks (7):**
- vfx-text-cursor: dramatic text reveal with cursor glow and chromatic shadows
- vfx-liquid-background: organic liquid simulation with vertex displacement
- vfx-iphone-device: real GLTF iPhone + MacBook with live HTML screens
- vfx-magnetic: magnetic field particle visualization
- vfx-portal: dimension breach portal transition
- vfx-liquid-glass: Voronoi glass fracture with parallax reveal
- vfx-shatter: glass shatter with physics-driven fragments
**Caption Blocks (5):**
- captions-slam: bold uppercase scale-pop with back.out overshoot
- captions-karaoke: word-by-word color reveal on frosted glass pill
- captions-minimal: clean Netflix-subtitle style fade
- captions-bounce: playful elastic bounce with colorful word pills
- captions-cinematic: elegant slow fade with letter-spacing animation
All blocks include registry-item.json and are registered in registry.json.
VFX blocks use experimental stability, caption blocks use stable.