feat(catalog): add the seven 3D-motion pieces as installable registry blocks - #4056
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at 7d089fd8. Note the head moved while I was reading (d09af651 → 7d089fd8), so I re-verified against the new head rather than posting findings pinned to the old one.
First, the head move is clean — and worth recording, because it looks alarming by every cheap measure.
style(catalog): run oxfmt on the seven ported composition files is +5905/-1894 across 8 files, and the whitespace-stripped content of frost-sequence-camera-orbit.html shrinks by 30,064 bytes. A formatter adds whitespace; it does not delete a quarter of a file's real content, so I chased it. The cause is benign: the data-composition-variables blob on <html> was a double-quoted attribute holding "-escaped JSON, and the formatter re-delimited the attribute with single quotes and decoded the entities (5,258 " → 0). Same JSON, ~5 bytes saved per quote.
That rewrite has exactly one failure mode — an apostrophe anywhere in the JSON would now terminate the attribute early — so I executed the check rather than reasoning about it: for all seven pieces at this head, every single-quote-delimited attribute whose value starts [/{ parses as JSON, 0 failures. Structural token counts (<script>, <style>, function, const, gsap., addEventListener, data-composition-id) are identical across the move. So the reformat is semantically safe on all seven.
blocker — this PR's own CREDITS.md states a precondition that merging would bypass
The added "Third-party licenses" entry says the seven pieces "were ported from a reference implementation. License terms for these pieces are not confirmed upstream — do not assume this repository's Apache 2.0 license applies to this directory until confirmed."
I read that as an open question, not a disclosure that closes by being written down. This is a public Apache-2.0 repository; the pieces land as installable registry blocks (/registry/install) and the docs surface publishes hover previews for them. Merging is the step that redistributes ~251k lines whose terms the PR itself declines to assert, to people who will reasonably assume the repo's license covers what they install. Worth resolving upstream — or landing the blocks behind whatever gate the answer implies — before this goes in. Flagging it because it is the one finding here that a later commit cannot quietly fix.
important — vendored MIT copies ship without their notices, and unevenly within this same PR
frost-sequence-camera-orbit/assets/frost.js:1declares its own contents:three@0.185.1 (MIT)+three-mesh-bvh@0.9.14 (MIT). That block's only licence file isassets/fonts/Geist-OFL.txt— a font licence. Neither MIT notice ships with the copy.cuboid-carouselandorbit-carddo shipassets/Three-LICENSE.txt. So the convention is established inside this PR and applied to two of the three blocks that need it.gsap-3.14.2.min.jsis vendored into four blocks (orbit-card,frost-sequence-camera-orbit,cuboid-carousel,code-slice-hero) with no GSAP licence file in any of them. GSAP's terms are not MIT, so it deserves naming explicitly rather than ridingCREDITS.md's "Thanks also to … GSAP".glass-shard-title/assets/glass-main.js(24,624 lines) ships with no header and no licence file, so its provenance can't be established from the tree at all.
important — frost.js is a build artifact whose source doesn't ship
Its first line reads "Generated by build.mjs; edit src/ and rebuild." There is no src/ and no build.mjs anywhere in this PR — I checked the full file list, not just that block. So the instruction in the file cannot be followed in this repository, and 78,870 lines of bundled three.js + BVH have no patch path here: a three.js security bump would have nowhere to land. motion.js (43,785 lines) is the same shape with no header at all. Either ship the source and build script, or record in the block's SKILL.md where upstream lives and how to regenerate.
note — glass-main.mjs (1,018 lines, authored, oxfmt-owned) sits beside glass-main.js (24,624 lines, built) with nothing in the tree relating them. Whatever produces the .js isn't in the repo, so the pair can drift silently and a reader can't tell which one is authoritative.
On the body's own split: "the hand-written part is small" holds as a line-count claim. I separated generated from authored by reading file headers rather than taking the split on faith, and the authored surface is the seven <piece>.html, glass-main.mjs, the per-block registry-item.json / presets/ / SKILL.md, and the seven docs/catalog/blocks/*.mdx. The thing that split surfaced is the .mjs/.js pair above.
Audited: the head-move delta (all 8 files, semantically), provenance and licence inventory per block, the generated-vs-authored split, CREDITS.md, .gitattributes LFS routing for the preview clips.
Trusting / not reviewed: the seven pieces' motion content and visual correctness, the check-docs-catalog parity checks, and the Mintlify preview — your own note says merge waits on your look at that, so I have deliberately not posted the approval that would release it.
Verdict: REQUEST CHANGES
Reasoning: the licensing precondition is stated by the PR itself, and three of the blocks that vendor MIT libraries ship without their notices. The reformat and the block wiring are fine; this is about what gets redistributed.
One mechanic so nobody is left guessing why it stays red: this repo sets dismiss_stale_reviews_on_push: false, so this review stays live across pushes and needs an explicit approval from this account to clear once it's addressed. Ping me and I'll turn it around quickly.
— Rames Jusso
|
Thanks for the thorough pass. Both findings addressed at the latest commit: Licensing precondition. The maintainer has confirmed the author's permission for these seven pieces under this repository's license. Vendored notices and frost's build artifacts. Every third-party library vendored across the seven blocks now ships its own license notice, consistently: GSAP (added to all four blocks that vendor it), three.js and the Geist font's OFL notice (added wherever they were missing), and three-mesh-bvh, opentype.js, and ClipperLib for For One thing this surfaced that's outside this pass: |
5cb1fc8 to
2cebedc
Compare
jrusso1020
left a comment
There was a problem hiding this comment.
Re-review at the squashed head. My previous CHANGES_REQUESTED is cleared by this review — both findings are addressed.
A note on how I checked: "history squashed to one commit" would normally mean my earlier read carries over, so I compared the tree hashes rather than the commit list. They differ (bbc5bddf → d32ee52f), so the squash carried content changes too and I re-read the delta. Worth knowing for next time — the squash also dropped glass-main.mjs and rebuilt frost.js/motion.js.
Strengths
- The licence audit went past what I flagged. I named three@0.185.1 + three-mesh-bvh@0.9.14 and GSAP; you also found OpentypeJS and Clipper and shipped notices for both (
registry/blocks/frost-sequence-camera-orbit/assets/). That's the enumeration done properly rather than to the letter of the review. - Every notice is wired into
registry-item.jsonwith atarget, so it actually installs alongside the library it covers. A notice that sits in the repo but not in the manifest would look right in the diff and ship nothing — checking the manifest was the part I expected to be missed, and it wasn't. source/build.mjsruns a TS preflight plus a headless WGSL shard-compile probe before bundling (source/tools/run-shard-compile.mjs). Catching shader failures without a GPU is a genuinely useful gate to have brought along.
Findings — none blocking
important — frost-sequence-camera-orbit.html:3173-3174 publishes window.__hf.buildReady.frost = frost.ready, and nothing in the repo reads buildReady (those two lines are its only occurrences, repo-wide). The rig has real async startup (source/src/frost.ts:336,586), and the producer's actual gate is window.__renderReady — read at packages/producer/src/services/fileServer.ts:653 and packages/producer/src/parity-harness.ts:79-80, and recognised by the compiler at packages/core/src/compiler/htmlDocument.ts:22. No block in this PR sets it. So if the intent was to hold capture until the ice rig is built, this hook doesn't do that; if it's a debug handle, it's dead code. Worth naming which — and if it is meant to gate capture, the wired form is window.__renderReady = false up front, flipped after await frost.ready.
important — nothing ties the shipped bundle to the source that now accompanies it. source/build.mjs writes assets/frost.js, the README documents "edit src/ and rebuild", but no workflow in .github/workflows/ references frost, source/package.json is private: true and outside the workspace build, and .oxlintrc.json now excludes source/** from lint entirely. I verified the absence of a gate; I did not test whether the current bundle matches the current source. The result is two copies of the same logic with nothing checking they correspond — and the build is exactly where that silently diverges.
important — registry/blocks/glass-shard-title/SKILL.md no longer matches its own directory after the squash. Line 82 still says to "rebuild with esbuild and re-inline after editing the .mjs source", but assets/glass-main.mjs was deleted here; the Files list still carries build-bundle.mjs (1 KB), which is absent at this head. The deletion itself is clean — the composition loads the built assets/glass-main.js and the manifest entry went with the file — but these are agent-facing instructions, so what's left points at two files that no longer exist. Same class as the frost finding I opened, just inverted: there the instruction outran the source, here the source was removed and the instruction stayed.
nit — the CodeQL "prototype-polluting function" alert on source/src/dials/defaults.ts:485 is still open at this head (the defaults.ts change in the squash is a comment rename, not a fix). I don't think it's exploitable: values only ever comes from the committed baked.json, withBaked has no callers outside its own file, and __proto__ already hits the k.startsWith("_") guard, while constructor can't recurse because functions don't satisfy typeof c === "object". But that mitigation is incidental — the guard was written to skip internal keys, not to stop pollution — so an explicit key check would both close the alert and make the protection intentional.
nit — the CREDITS.md line now reads "contributed with their author's permission under this repository's license", and the SKILL.md files drop their Source experiment: pointers. Dropping internal experiment names from a public repo is the house convention, so no issue there; the effect is just that CREDITS.md is the only remaining record and it doesn't name what was ported. If the upstream is nameable publicly, naming it would make the attestation auditable by someone who wasn't in this thread. To be explicit about my own position: I'm accepting the permission statement, not verifying it — an offline licensing confirmation isn't something a code review can audit.
Note, not a finding — GSAP's minified bundle was already vendored in this repo before this PR (skills/music-to-video/references/motion-primitives/assets/gsap.min.js, skills/talking-head-recut/assets/vendor/gsap.min.js both exist at the merge base), so how an Apache-2.0 repo redistributes an all-rights-reserved bundle isn't this PR's question to answer. I'd raised the missing notice; your GSAP-NOTICE.txt files now make these four blocks the only place in the repo that carries one. The two older copies still have none — worth a separate pass, not something to load onto this PR.
Verdict: APPROVE
Reasoning: The licensing precondition that blocked this — the PR's own CREDITS.md disclaiming its licence terms — is gone, and every vendored library now ships a notice that actually installs. The three important findings are drift and wiring issues that don't affect what renders, so they're better as follow-ups than as another round.
Gate mechanics, for whoever is tracking the merge: dismiss_stale_reviews_on_push is false on this repo, so my earlier CHANGES_REQUESTED survived the force-push and only an explicit approval from this account could clear it. This is that approval. Merge timing is yours — you'd mentioned the Mintlify preview.
— Rames Jusso
|
Refresh at
|
|
Correction to the refresh comment above: I said frost-sequence-camera-orbit's Inter font got an OFL notice added. That's only true of an intermediate commit in this range — a later commit in the same range found the font had zero runtime references and deleted it entirely (font + notice both), so at the current head there is no Inter font at all. The Cormorant Garamond notice for glass-shard-title is correct and still stands. |
9ed226b to
80c3a5d
Compare
The base branch was changed.
80c3a5d to
a68fdb6
Compare
…render paths CREDITS.md states the three.js version and vendored-or-CDN status per block, adds d3-delaunay, Clipper on the CDN and the Google Fonts loads, and lists every texture with no known origin. The SKILL.md test now also checks the mount and render paths against the manifest composition.
The two checks shared a copied manifest read, which fallow flagged as a clone with a high score.
… and check git not the disk The compositions/ and *-ad/ ignore rules matched folder names under docs/public/catalog/items, so 33 hosted fonts, textures and marks were generated but never committed and would 404 on the docs host. The rules now have a negation for that tree and the files are added. The drift check read the checkout, where git-ignored files still exist, so it passed locally and failed only in CI. It now unpacks HEAD with git archive and compares that.
…rror, and test the wiring The manifest webgpu tag now decides whether an item may lack an adapter, and the error wording decides which lines are that absence. Any other page or console error on the item, and every failed request, still fails. The per-item decision is one exported function the tests drive, marker payloads are parsed by a tested helper, and the SKILL.md variable counts are checked against their tables (cuboid-carousel said forty-nine for forty).
… adapter request failed to request .*adapter also matched errors about other adapters. It now matches only a request for the WebGPU adapter, so a tagged item cannot hide an unrelated failure behind it.
terencecho
left a comment
There was a problem hiding this comment.
APPROVING at 899e66ce — delta since Rames's 2cebedcb APPROVE is 60 author commits of refinement + drift gates + CI hardening; both of the still-actionable "important" flags from that review are addressed at HEAD; nothing new looks regression-shaped.
Framing
To be explicit before I stamp: I have no prior review on this PR to clear. The CHANGES_REQUESTED at 7d089fd8 was Rames's, and per his own 2cebedcb re-review (5245364236, DISMISSED reason "The base branch was changed") that concern was resolved and his verdict was APPROVE. require_last_push_approval=true invalidated that approval on the subsequent push. This stamp is a fresh code-merit read at 899e66ce.
Scope of the delta reviewed (2cebedcb..899e66ce, 60 author commits, ~759 net new files)
Bulk of the file count is generated catalog output (~750 new docs/catalog/blocks/*.mdx). Per Home's guidance I audit the generator + gate, not the generated leaves:
scripts/catalog-detail.jsx(the shared detail-page component) — read every commit that touched it.scripts/generate-catalog-previews.ts,scripts/catalog-payload-assets.ts,scripts/catalog-script-inlining.ts,scripts/verify-catalog-payloads.ts— refactor to single-purpose helpers with 20-casenode:testcoverage incatalog-detail.test.ts..github/workflows/ci.yml— new gates:check:catalog-drift,check:docs-catalog,verify:catalog-payloads --changed origin/main(headless-Chrome load of every changed payload).
The three UX fixes Miguel called out are present and correct:
- Install command above the preview (
e21efb485+ slot-lookup fix16438e5ed):docs/snippets/catalog-detail.jsxnow finds the install slot via[data-slot='install']on Mintlify's child wrapper, andcatalog-detail.test.tsgained a case that fails if the wrapper's structure changes. - Copy button no size shift on "Copied" (
28fa8f246, refactored byb6c4b927d): swaps todisplay: inline-gridwith both labels layered in the samegrid-area: 1 / 1cell; the inactive one isvisibility: hidden. Classic width-preserving swap. Covered. - Hover contrast on the primary button (
899e66ce, one-line CSS):.hf-ve-action[data-primary="true"]:hover:not(:disabled) { background: var(--ve-on-bg); opacity: 0.88; }— restores the explicitbackgroundso the on-primary hover no longer bleeds through to the neutral row-hover rule below it.catalog-detail.test.tscovers the resulting selector.
Rames's 3 "important" non-blocking flags at HEAD
- Flag 1 —
frost-sequence-camera-orbit.html:3172-3173window.__hf.buildReady.frost = frost.readyis dead code → RESOLVED at the engine seam.packages/engine/src/services/frameCapture.ts:1566now readswindow.__hf.buildReadyas the actual render-ready gate ("window.__hf.buildReady never resolved for: ..." is the produced diagnostic), andframeCapture.test.ts:376,381,405,435pin the contract. Multiple blocks in this PR emit into__hf.buildReady["..."](cuboid-carousel:841,wireframe-portal-title:1585,canopy-part-title:1374,1388,1390) matching the shape frost has. The wiring is real now; frost's hook is meaningful, not dead. - Flag 2 — no CI gate for source ↔ bundle correspondence in
registry/blocks/frost-sequence-camera-orbit/source/→ Same as before, still non-blocking. No workflow referencesfrost/source/build.mjs/shard-compile. Rames flagged this explicitly as "verified the absence of a gate; I did not test whether the current bundle matches the current source" — a follow-up shape, not a code merit issue. Note that the NEWcheck:catalog-driftgate is orthogonal (docs/public/catalog vs the generator), not the frost source-bundle gate. - Flag 3 —
glass-shard-title/SKILL.md:81tells to "rebuild with esbuild and re-inline the .mjs source" butassets/glass-main.mjswas deleted → RESOLVED.9ac126081 fix(catalog): commit the hosted item files a gitignore rule kept outrestoredassets/glass-main.mjs. SKILL.md line 81's instruction now matches what's on disk (.mjssource present,.jsbundle at 549KB per the Files list on line 22).
New strengths since 2cebedcb
- Adapter probe hardened: sync-throw and hang timeouts (
c0cb018b4,8bc5cb499), tagged-item forgiveness now scoped to the specificadapter-absenterror string rather than any adapter failure (917a1eea6+ regression test277c7c750), verify-by-manifest-tag not console-string (db1336c57). This class of fix — "the probe fails cleanly when the environment is missing WebGPU rather than sticking a Tune UI on top of a dead composition" — is exactly the drift-prone surface for a catalog serving all clients. - CI drift gate:
check:catalog-driftre-runs the generator into a temp dir and compares against the committed tree; missing / extra / byte-diff files are listed.check:docs-catalogproves nav lists every page with no duplicates.verify:catalog-payloads --changedruns every payload that differs fromorigin/mainunder headless Chrome. Together these close the "generated tree drifts silently from generator" loop for the DOCS catalog output (Rames's Flag 2 shape, applied to a different surface). - Hosted-reference rewrite refuses bare names it can't safely replace (
9bde77f77) — prevents the class of failure where a script inliner would ship a dead URL. Companion test:scripts/catalog-script-inlining.test.ts. - Payload asset / verify script splits (
ce3aed3aa+9dcdb260f) — makes the generator's failure modes single-cause.
Standing caveat, not a code issue — flagged for visibility
CREDITS.md:57 still carries Origin to be confirmed with the author for six shipped binaries (canopy-part-title/assets/leaf-surface-color.webp + leaf-surface-normal.webp, glass-shard-title/assets/matcap-1.png, frost-sequence-camera-orbit/assets/shards-atlas.png + assets/textures/ice-inclusions-generated.png + assets/textures/bluenoise64.png). This is unchanged from 2cebedcb (Rames accepted the permission statement at approve time with "I'm accepting the permission statement, not verifying it"). A repo-published attestation the review can't itself verify — pushing that to the author is the right seam. Not blocking this stamp per prior review continuity, but calling out that Rames also re-noted it in-thread just now.
CI (deduped by latest per context, at 899e66ce)
60/64 SUCCESS. The four non-success rows are CANCELLED matrix parent placeholders (CLI: npx shim (${{ matrix.os }}), Producer: ${{ matrix.lane }} tests, Tests on windows-latest: ${{ matrix.lane }}, regression-shards) — each expands into individual matrix children that ALL show SUCCESS (CLI: macos/ubuntu/windows; Producer: integration + unit; Tests on windows-latest: studio-core + studio-engine-cli; regression-shards: shards 1-9). Required checks per ruleset 14211637 (Test, Build, Test: runtime contract, Render on windows-latest, Tests on windows-latest, Studio and player captures) all green. No live failures.
Stamp mechanics
reviewDecision: REVIEW_REQUIRED → APPROVE closes the reviewer gate. hf-oss require_last_push_approval=true binds this stamp to 899e66ce. CODEOWNERS covers only check-pr-captures paths (this PR touches none), so one approval at this head opens the gate. Miguel miguel-heygen on trusted stamp list. Ruleset 14211637 on main wants 1 approval — this is it.
— Review by tai (pr-review)
jrusso1020
left a comment
There was a problem hiding this comment.
Re-review at the current head. My earlier CHANGES_REQUESTED on this PR was the licensing/attribution blocker, so this review records how I verified it resolved, and adds an audit of the asset-removal surface the other review here doesn't cover.
Prior blocking finding — resolved. The original block was that installable blocks shipped third-party runtimes without notice files, and the PR body stated a precondition about itself. At this head the precondition wording is gone, and every block that vendors a runtime ships matching notices: frost-sequence-camera-orbit 5/5, cuboid-carousel 2/2, orbit-card 3/3, code-slice-hero 1/1. Control: glass-shard-title carries only Three-LICENSE.txt, which is correct — it CDN-loads GSAP rather than vendoring it.
Asset-removal surface — the part I'd most expect to break. This PR deletes 21 files, including all five av_r*.mp4, bgm.m4a and both font families under registry/blocks/heygen-avatar-promo-card/assets/. Three ways that could go wrong, all clean:
- Dangling install manifest.
registry-item.jsonstill declares 11 files absent from disk — but 27 other blocks share that shape, andcarousel-circle-1has held only 2 files on disk since before this branch. Declared-not-present is the established convention here, not a regression this PR introduces. - Dangling payload references. The served artifact rewrites them.
docs/public/catalog/blocks/heygen-avatar-promo-card.jsoncarries six absolutehttps://static.heygen.ai/hyperframes-oss/registry-assets/…media URLs and five absolute font URLs, with no relative media left — matching the reason recorded incheck-no-main-deletions.mjs. - Collateral from the 13 deleted
docs/public/catalog/assets/*.woff2. None is referenced by any payload. Sweeping all 187 payloads for site-root/public/catalog/…references resolved 316 of 316 against disk.
scripts/check-no-main-deletions.mjs is a good addition. Three-dot diff with the reasoning written down, renames reported separately, and a per-path allowlist carrying a reason per entry rather than a --force escape hatch — which would be reached for by exactly the branch that needs stopping.
nit — scripts/catalog-detail.test.ts:569. The new inset test awaits renderDetail(["install"]), discards the result, then asserts the source file literally contains .hf-ve-tabs-row { margin: 20px 0 0 16px; }. It restates the line it guards, so it passes on a reformat and fails on a rename without the inset ever regressing. 3 of the 19 tests in this file work that way; the other 16 assert on behaviour.
Still open, non-blocking, author's call (unchanged since I first raised it): CREDITS.md records "Origin to be confirmed with the author" for six shipped binaries — canopy leaf-surface colour and normal, glass matcap-1, frost shards-atlas, ice-inclusions-generated, bluenoise64. Merging past it is a decision rather than an oversight; I'm noting it, not gating on it.
Audited: the 21 deletions and 5 renames end-to-end; every catalog payload's asset references (187 payloads, 316 refs); check-no-main-deletions.mjs; verify-catalog-payloads.ts; the root config changes (ci.yml, .prettierignore, .oxlintrc.json, .gitignore, package.json) — the .prettierignore additions do bind, since oxfmt reads .gitignore and .prettierignore from the working directory by default; and the full delta since the previously-reviewed head.
Trusting: the 748 generated docs/catalog/** pages (read as generator output, spot-checked); the vendored three.* and gsap bundles (checked for notices and formatter exclusion, not byte-verified against upstream); the generator refactor internals, which the other review here covers.
Verdict: APPROVE
Reasoning: The original licensing block is resolved at this head, and the riskiest thing in the diff — removing shipped media from a public registry — holds up under a full reference sweep. The one open item is an attribution note for the author to decide on, not a gate.
— Rames Jusso
Summary
Adds seven 3D-motion pieces to the catalog as installable registry blocks: a leaf-parting title card, a glass-shard title, a code-slicing hero, a frosted camera-orbit sequence, a bevelled-cuboid carousel, an orbiting feature card and a wireframe portal title. Each installs like any catalog block (
npx hyperframes add <id>), has a live detail page with source and install, and sits in its own "3D motion" section.This PR is the whole catalog change. The engine script-ordering fix that the
glass-shard-titlerender needed landed first, in #4133.The pieces are contributed with their author's permission under this repository's license (
CREDITS.md).What changed
registry/blocks/<id>/, tagged3d-motionso the existing tag-driven grouping gives them their own section.registry-item.json. Nothing binary was added for them.public/, never.js,.mjsor.hdr(measured against a deployed preview). Shared libraries (gsap, three, RoomEnvironment, BufferGeometryUtils) go once intodocs/public/catalog/vendor/*.jsonand are fetched and blob-loaded at runtime; item scripts are inlined as text; the one HDR is a data URI. Implemented inscripts/catalog-script-inlining.ts, one inliner per item that needs it.processAssetsembeds.jsas a data URI for every item without an inliner, as before, so other catalog items regenerate unchanged.check:docs-catalogin the Lint job and a new "Catalog payloads" job that loads every payload a PR changes in headless Chrome (verify-catalog-payloads.ts --changed origin/main). A WebGPU piece cannot draw on a CI browser without an adapter, so that one error is ignored for payloads that usenavigator.gpu; every other failure still fails the job.scripts/verify-catalog-payloads.tsmodels the docs host's real extension allowlist, so a payload that loads locally but 404s on the host fails the check.frost-sequence-camera-orbit/assets/motion.jsis removed: no reference anywhere, and zero requests across a full play-through.glass-shard-titleloads its vendored engine through<script src>instead of an inlined copy that failed two lint rules.source/directories are excluded from hosted item directories.shards-atlas.png,ice-inclusions-generated.png,matcap-1.png) are hosted through the registry'sfiles[].urlfield on the HeyGen CDN under content-addressed names, exactly like the carousel images:hyperframes addstill writes them to the same local paths, and the catalog payload's inlined scripts point at the URLs. No PNG over the non-LFS limit is committed.ice-fracture-detail-v1.pngwas loaded by nothing and is deleted.frost-sequence-camera-orbitships only what it renders with: the iteration presets (approved-material-v1tov7,current-test, the saved presets and their catalog) are removed, since nothing reads them at render.source/presets/keeps the two files the source build imports..oxlintrc.jsonignores the vendored bundles;CREDITS.mdhas one attribution line.Verification
bun scripts/verify-catalog-payloads.ts --only <id>exits 0 for all seven pieces, plusliquid-glass-widgets,liquid-glass-notificationandhw-write-titleto show the shared generator change did not break other items.git statusclean.glass-shard-titlevideo was found and replaced).crossOrigin=anonymousfrom the deployed preview's origin and read back from a canvas without tainting, which is what WebGL needs; the CDN answersaccess-control-allow-origin: *.Diff size
Far over the 1k-line guideline. Almost all of it is vendored bundles, fonts and textures across seven independent items. The hand-written surface is the manifests, the
scripts/catalog-*changes and their tests.Heavy pieces on a real GPU
The four WebGL/WebGPU pieces now draw across their timeline and flush the GPU inside
window.__hf.buildReady, so shader links and texture uploads happen before the player reports ready instead of on the first visible frames. Measured with the tile path (srcdoc player, muted, play from 0, Apple GPU, headless Chrome for Testing, single run), max rAF gap / longest long task, before then after:Frost: the remaining time is the build phase (geometry, distance fields, particle setup), not first-draw pipeline creation. The player reporting ready before the build gate resolves is a player readiness-gate fix in a separate PR.
Detail page: install command before the preview (deployed docs preview, headless Chromium)
The install command, its copy button and the "That writes ..." line now sit under the description and above the preview, as on the live catalog. Tabs are Preview, Code, Snippet, Docs with Preview selected. The Snippet tab holds the mount element with the values tuned in the panel; the duplicate Terminal command is gone. Frost Sequence Camera Orbit is a WebGPU composition: headless Chromium has no adapter, so its stage shows the recorded clip with the reason on the caption line and no Tune panel. Live WebGPU playback needs a real GPU Chrome.
Before
After
Catalog poster timing (deployed preview, head d7c75e4)
The pinned 3D motion group's six posters load eagerly at high priority. Measured from navigation start:
Copy button layout shift, and a pale copied label
Every copy button (agent request, wiring, link, JSON, render cmd, install) changed size when its label swapped to "Copied", so the row's siblings slid left. Root fix is in the one shared copy control: label and "Copied" now sit in the same grid cell, the inactive one hidden, so the button never resizes. Measured before/after on the deployed preview at 1440/1280/1100/900/390: no box moves now at any width (four of five widths moved before).
The primary button's hover state was then found unreadable in the copied state (white text on a pale background), caused by a hover rule with lower CSS specificity than the generic one. Fixed on the same control; verified computed background stays dark through hover, click, and the copied state.
After, copied state, primary button (agent request):
Tab strip and tab content, 16px left inset
The tab strip and its content (About, Code, Snippet, Docs) sat flush against the page column while the caption, Tune head/list/foot and panel head all use a 16px inset already. Matched that constant:
.hf-ve-tabs-rowmargin-left and.hf-ve-bodypadding-left, both 16px, one place each. Verified on the deployed preview at 1440 and 390: tabs and About now start 16px right of the stage/bar edge at both widths.