Files
zeekay a582b4c1b3 Put Blue on screen, and dissolve between the feelings
Blue has never appeared. Every clip in public/bg_video was a 132-byte Git LFS
pointer, so the door has been a plain dark rectangle since it went live — and
nothing anywhere said so: the file existed, the request answered 200, the
content-type was video/mp4, and the page rendered. Only its SIZE was wrong.
The real files were in LFS on the remote the whole time.

Two things then kept them off screen, and both are the same shape as the first.

A CDN caches by URL, and `/bg_video/emotion/Happiness.mp4` was the same URL
before and after the bytes behind it changed — so once the real clips reached
the origin, the edge went on serving the pointers it already had, for a day at
the origin's own max-age. Each clip's URL now carries a hash of its own
contents, computed before the build, so new bytes cannot inherit an old URL and
a clip that did not change is not re-fetched. Purging is the other answer and
it is worse: it needs a credential at deploy time, it is a step someone has to
remember, and it throws away a whole zone to fix one file.

And a single video element cannot change what it plays without going blank —
set src, call load(), and it holds nothing until the first frame of the next
clip arrives. That is a black flash in the middle of a sentence, at exactly the
moment the page is asking to be watched. There are two elements now, stacked:
the one you can see keeps playing while the other loads the next clip in
silence, and they trade opacity only once that one says it can play. A clip
that fails to load never gets its turn, so a dead connection leaves the current
one running — a beluga at rest beats a black rectangle.

Proven end to end against the live site: the clip plays at 1920x1080, the free
lane answers with real science, and asking why beluga calves are born grey
dissolves the resting loop into Interest.
2026-09-05 15:09:43 -07:00

48 lines
1.4 KiB
JSON

{
"name": "zoolabs.io",
"version": "1.0.0",
"private": true,
"packageManager": "[email protected]",
"engines": {
"node": ">=22.18"
},
"scripts": {
"dev": "node scripts/clips.mjs && node scripts/gui-css.mjs && next dev --webpack",
"build": "node scripts/clips.mjs && node scripts/gui-css.mjs && next build --webpack",
"start": "next start",
"test": "node --test lib/*.test.ts",
"research": "node scripts/research.mjs",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@hanzo/appearance": "^0.2.4",
"@hanzo/design": "^0.5.25",
"@hanzo/font": "^1.9.3",
"@hanzo/gui": "^8.3.1",
"@hanzo/ui": "^8.27.7",
"@hanzogui/animations-css": "8.3.1",
"@hanzogui/config": "8.3.1",
"@hanzogui/lucide-icons-2": "catalog:",
"@hanzogui/next-theme": "catalog:",
"@hanzogui/telemetry": "8.3.2",
"@hanzogui/toast": "8.3.1",
"@hanzogui/web": "8.3.1",
"@react-native/assets-registry": "^0.86.2",
"next": "^16.3.3",
"next-themes": "^0.4.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.87.0",
"react-native-svg": "^15.15.5",
"react-native-web": "^0.21.2"
},
"devDependencies": {
"@types/node": "^22.10.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"esbuild": "^0.25.0",
"playwright-core": "^1.62.1",
"typescript": "^5.9.3"
}
}