PROJECT 01
The Precious Thing
A low-poly 3D fable in which a lost corgi searches a park and finds its human companion again.
Watch
02Inspect source1 scenes · 12 archive files
Verified archive
- Identity
ae8b6499cb2f993ff0f11c576c0d126c616292d0d973e1b25be78042547b5698- Format
- narova.project/1
- Packer version
- Narova 0.40.0
- Contents
- 12 members · 2,034,882 bytes
- Release check
- The approved 31-second master passed Narova's release check with zero warnings and the encoded motion audit; publication preserves its exact bytes.
- Accessibility
- Visible controls, complete English WebVTT captions without an opaque card, a representative poster, text fallback, and script-free collapsed inspection are present.
assets.lock.jsonasset-registry · 3,556 bytesassets/dog.glbasset · 73,516 bytesassets/music-bed.mp3asset · 560,736 bytesassets/narration-final-captions.srtasset · 520 bytesassets/narration-final-turns.jsonasset · 3,809 bytesassets/narration-final.wavasset · 1,367,178 bytesclaims.mdclaims-ledger · 669 bytescreative-brief.mdcreative-brief · 1,761 bytesevidence/motion.jsonauthored-module · 4,608 bytesreel.config.jsonauthoring-config · 1,664 bytesscene.jsauthored-module · 16,795 bytestheme.cssauthored-module · 70 bytes
Provenance & rights
Original first-party lost-and-found fable rendered as one authored deterministic Three.js scene with local Piper narration, word timings, music bed, creative brief, motion evidence, CC0 corgi source record, and portable static authoring source included in the archive.
No recorded remix parent.
Hosting basis: First-party script, narration, music, authored 3D park and human, rendered media, and a CC0 Gobkit corgi model are published under the gallery's CC0-compatible boundary; attribution and proof of use are not required.
- The Precious Thing — Ammar Hasan (voluntary credit; CC0-1.0)
- Corgi model — Gobkit / Ariescar (CC0-1.0; voluntary credit)
Scene & narration inventory
-
01
story
- narrator Some things in life are so close, we forget they can be taken away.
- narrator Until one day, they are gone. And the world feels impossibly big.
- narrator He searches. Through every path, every sound, every memory.
- narrator And then, there it is. The precious thing you thought was lost, standing right in front of you.
Authoring source
claims.mdclaims-ledger · 669 bytes
# Claims and rights
## Story
This is an invented emotional fable, not an external factual claim.
## Publication rights
- The Corgi model is from the Gobkit Free Animal Pack under CC0-1.0.
- The park, human figure, choreography, script, and final composition are
first-party authored work.
- The narration was generated locally with Piper for this project.
- The instrumental bed was created for the source project and encoded locally
with FFmpeg.
- The owner approved the final film for first-party CC0 publication.
## Creative boundary
The motion is authored deterministic choreography. It is not represented as a
scientific or physically simulated account.
creative-brief.mdcreative-brief · 1,761 bytes
# Creative Brief: The Precious Thing (Rebuild)
Status: approved
## Concept
A 31-second emotional 3D narrated short about a dog who gets lost and finally finds his human companion. The theme explores what it means to lose something precious — and the overwhelming joy of finding it again.
## Intended Effect
The viewer should feel the ache of separation and the warmth of reunion. The dog's journey from companionship to loneliness to reunion mirrors the universal human experience of losing and cherishing what matters most.
## Visual Direction
- **Medium**: 3D rendered through Narova's Three.js pipeline
- **Palette**: Warm golden hour tones — soft amber light, muted greens, gentle shadows
- **Camera**: Cinematic atmospheric motion — subtle dolly, gentle drift. Camera never substitutes for subject motion.
- **Representation**: Corgi dog (dog.glb, Gobkit CC0) + procedural human companion (intentionally distinct from dog model) in a natural park setting
## Narrative Structure
1. **Together** (0-4s): Dog and human in a sunlit park, peaceful companionship
2. **Lost** (4-10s): Human walks away and exits frame, dog watches, confused
3. **Searching** (10-20s): Dog wanders through environment, actively searching
4. **Reunion** (20-31s): Dog spots human, approaches, human bends to greet, contact, changed final state
## Audio
- Single narrator voice (warm, contemplative, Piper en_US-ryan-high)
- Emotional piano music bed
## Rejection Criteria
- Both subjects must be visibly distinct without labels
- Every story beat must have meaningful subject motion (camera cannot substitute)
- Separation must close through approach and contact
- Final state must be visibly different from initial state
- Captions must have no opaque/background card
evidence/motion.jsonauthored-module · 4,608 bytes
{
"schema": "narova.scene-state/1",
"producer": { "id": "gate-b-film-v4", "version": "1" },
"description": "World-space transform evidence for Gate B film (repair v4). All values authored on sceneTl in scene.js. Verified by encoded-frame inspection at 1.5s, 6s, 12s, 17s, 23s, 26s, 30s.",
"subjects": {
"dog": {
"representation": "dog.glb (Gobkit Corgi) — GLB skeletal model, scale 0.0025 (reduced from 0.0035 to prevent occlusion at contact)",
"initialPosition": { "x": 1.5, "y": 0, "z": 0 },
"initialRotation": { "y": 1.5708 },
"finalPosition": { "x": -0.8, "y": 0, "z": 0.5 },
"finalRotation": { "y": 2.199 }
},
"human": {
"representation": "Procedural authored humanoid (cylinders + spheres: torso, head, 2-segment arms, 2-segment legs)",
"initialPosition": { "x": -1.5, "y": 0, "z": 0 },
"initialRotation": { "y": 0.3 },
"finalPosition": { "x": -2.0, "y": -0.05, "z": 0 },
"finalRotation": { "y": 0 }
}
},
"observations": [
{
"id": "frame-1.5s-together",
"time": { "at": 1.5 },
"status": "available",
"method": "Encoded frame inspection. Both human (blue shirt, x=-1.5) and dog (corgi, x=1.5) clearly visible side-by-side. Path between them. Trees (brown trunk + green sphere canopy) visible on both sides. Bushes (green spheres) and rocks (dodecahedrons) in foreground.",
"bothVisible": true,
"environmentVisible": true,
"captionPresent": true,
"basis": "MEASURED"
},
{
"id": "frame-6s-together",
"time": { "at": 6 },
"status": "available",
"method": "Encoded frame inspection. Both still together. First caption 'Some things in life are so close, we forget they can be taken away' fully displayed.",
"bothVisible": true,
"captionComplete": true,
"basis": "MEASURED"
},
{
"id": "frame-12s-departure",
"time": { "at": 12 },
"status": "available",
"method": "Encoded frame inspection. Human walking left (blue shirt visible at left edge). Dog turned to face camera/center at different position. Caption 'And the world feels impossibly big.' Separation reads clearly.",
"humanDeparting": true,
"dogTurned": true,
"basis": "MEASURED"
},
{
"id": "frame-17s-search",
"time": { "at": 17 },
"status": "available",
"method": "Encoded frame inspection. Human nearly off-screen left. Dog in different position (center-right), turned to face viewer. Caption 'Through every path, every sound, every memory.' with 'path,' highlighted.",
"dogVariedPosition": true,
"humanAbsent": true,
"basis": "MEASURED"
},
{
"id": "frame-23s-approach",
"time": { "at": 23 },
"status": "available",
"method": "Encoded frame inspection. Dog facing camera, alert posture. Human visible at far left edge. Caption 'And then, there it is.' Two-sided approach visible.",
"dogAlert": true,
"humanVisible": true,
"basis": "MEASURED"
},
{
"id": "frame-26s-contact",
"time": { "at": 26 },
"status": "available",
"method": "Encoded frame inspection. Human and dog side-by-side, both complete silhouettes clearly readable as separate entities. Dog smaller (0.0025 scale). Human standing, dog on path next to human. Caption 'The precious thing you thought was lost, standing right in front of you.'",
"bothVisible": true,
"silhouettesSeparated": true,
"contactReadable": true,
"basis": "MEASURED"
},
{
"id": "frame-30s-final",
"time": { "at": 30 },
"status": "available",
"method": "Encoded frame inspection. Human and dog together, close but with clear separation. Both complete silhouettes visible. Trees, bushes, rocks visible. Caption continues. Final state visibly different from initial (closer together, human bent).",
"bothVisible": true,
"changedState": true,
"basis": "MEASURED"
},
{
"id": "motion-audit",
"time": { "start": 0, "end": 31 },
"status": "available",
"method": "Narova build --release motion audit. No 2s frozen or 0.5s black segments detected.",
"motionAuditPass": true,
"basis": "MEASURED"
},
{
"id": "audio-streams",
"time": { "start": 0, "end": 31 },
"status": "available",
"method": "ffprobe verification. Video: H.264 1280x720 30fps. Audio: AAC stereo 48kHz. Both 31.000s.",
"videoCodec": "h264",
"audioCodec": "aac",
"duration": 31.0,
"basis": "MEASURED"
}
]
}
reel.config.jsonauthoring-config · 1,664 bytes
{
"title": "The Precious Thing",
"size": "16:9",
"assets": "assets",
"chrome": false,
"safeLayout": false,
"patterns": false,
"provenance": {
"script": {
"authorship": "agent",
"note": "Original lost-and-found fable; final film approved by the owner"
},
"disclosure": "Contains locally generated Piper narration"
},
"theme": {
"mode": "dark",
"accent": "#f5c542",
"bg": "#1a1410",
"css": "theme.css"
},
"voices": {
"narrator": {
"backend": "piper",
"speaker": "en_US-ryan-high",
"color": "#f5c542",
"label": "Narrator"
}
},
"captions": {
"preset": "karaoke",
"emphasis": ["precious", "lost", "found"],
"size": 28,
"plate": false
},
"timing": {
"gapSentence": 0.3,
"gapTurn": 4,
"lead": 0.18,
"tail": 0.6,
"tempo": 1.1
},
"bed": {
"file": "assets/music-bed.mp3",
"volume": 0.18,
"fadeIn": 2,
"fadeOut": 3
},
"scenes": [
{
"id": "story",
"minDur": 31,
"vo": [
{
"who": "narrator",
"text": "Some things in life are so close, we forget they can be taken away."
},
{
"who": "narrator",
"text": "Until one day, they are gone. And the world feels impossibly big."
},
{
"who": "narrator",
"text": "He searches. Through every path, every sound, every memory."
},
{
"who": "narrator",
"text": "And then, there it is. The precious thing you thought was lost, standing right in front of you."
}
],
"threeModule": "scene.js"
}
]
}
scene.jsauthored-module · 16,795 bytes
/* The Precious Thing — Lost Dog Rebuild (Gate B, repair v4)
Continuous 3D scene with authored motion for all story beats.
Every movement beat includes meaningful subject motion; camera motion
cannot substitute. Both subjects visible in establishing shot.
Environment uses Three.js primitives (no GLB reliance for park elements). */
var loader = new THREE.GLTFLoader();
/* ── camera: wide establishing shot, both subjects visible ──────────── */
camera.position.set(-0.3, 4.0, 8.5);
camera.lookAt(-0.3, 0.4, 0);
camera.fov = 48;
camera.updateProjectionMatrix();
/* ── lights ─────────────────────────────────────────────────────────── */
scene.add(new THREE.AmbientLight(0xffffff, 0.7));
var dirLight = new THREE.DirectionalLight(0xffffff, 0.9);
dirLight.position.set(4, 6, 3);
scene.add(dirLight);
var fillLight = new THREE.DirectionalLight(0xaabbcc, 0.3);
fillLight.position.set(-3, 2, -2);
scene.add(fillLight);
/* ── ground ─────────────────────────────────────────────────────────── */
var groundGeo = new THREE.PlaneGeometry(40, 40);
var groundMat = new THREE.MeshStandardMaterial({ color: 0x4a7c3f, roughness: 0.85 });
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = 0;
ground.receiveShadow = true;
scene.add(ground);
/* ── park environment: Three.js primitives inside camera frustum ────── */
var trunkMat = new THREE.MeshStandardMaterial({ color: 0x6b4226, roughness: 0.9 });
var canopyMat = new THREE.MeshStandardMaterial({ color: 0x2d6b1e, roughness: 0.8 });
var bushMat = new THREE.MeshStandardMaterial({ color: 0x3a7a2a, roughness: 0.85 });
var rockMat = new THREE.MeshStandardMaterial({ color: 0x7a7a72, roughness: 0.9 });
function makeTree(x, z, trunkH, canopyR) {
var trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.12, 0.15, trunkH, 6), trunkMat);
trunk.position.set(x, trunkH / 2, z);
scene.add(trunk);
var canopy = new THREE.Mesh(new THREE.SphereGeometry(canopyR, 8, 6), canopyMat);
canopy.position.set(x, trunkH + canopyR * 0.6, z);
scene.add(canopy);
}
function makeBush(x, z, r) {
var bush = new THREE.Mesh(new THREE.SphereGeometry(r, 7, 5), bushMat);
bush.position.set(x, r * 0.6, z);
scene.add(bush);
}
function makeRock(x, z, r) {
var rock = new THREE.Mesh(new THREE.DodecahedronGeometry(r, 0), rockMat);
rock.position.set(x, r * 0.4, z);
scene.add(rock);
}
/* Framing trees — left and right of the camera view */
makeTree(-5.5, -3, 2.5, 1.4);
makeTree(5.0, -4, 3.0, 1.6);
makeTree(-7.5, 1.5, 2.0, 1.2);
makeTree(7.0, 0.5, 2.8, 1.5);
/* Near-ground bushes — inside frustum, not blocking subjects */
makeBush(-3.5, 2.5, 0.5);
makeBush(4.0, 1.8, 0.4);
makeBush(-1.5, 4.0, 0.35);
/* Rocks */
makeRock(2.5, 3.5, 0.35);
makeRock(-4.0, 4.5, 0.3);
/* ── procedural path (simple flat plane, slightly lighter green) ─────── */
var pathGeo = new THREE.PlaneGeometry(1.2, 16);
var pathMat = new THREE.MeshStandardMaterial({ color: 0x6a9a5a, roughness: 0.9 });
var pathMesh = new THREE.Mesh(pathGeo, pathMat);
pathMesh.rotation.x = -Math.PI / 2;
pathMesh.rotation.z = 0.12;
pathMesh.position.set(-0.5, 0.005, 0);
pathMesh.receiveShadow = true;
scene.add(pathMesh);
/* ── materials ──────────────────────────────────────────────────────── */
var skinMat = new THREE.MeshStandardMaterial({
color: 0xd4a574,
roughness: 0.6,
metalness: 0.0,
});
var shirtMat = new THREE.MeshStandardMaterial({
color: 0x3366aa,
roughness: 0.7,
metalness: 0.0,
});
var pantsMat = new THREE.MeshStandardMaterial({
color: 0x333344,
roughness: 0.8,
metalness: 0.0,
});
/* ── procedural human (clearly distinct from the corgi) ─────────────── */
var humanGroup = new THREE.Group();
/* Torso */
var torso = new THREE.Mesh(
new THREE.CylinderGeometry(0.18, 0.15, 0.55, 8),
shirtMat
);
torso.position.y = 0.85;
humanGroup.add(torso);
/* Head */
var head = new THREE.Mesh(
new THREE.SphereGeometry(0.14, 12, 8),
skinMat
);
head.position.y = 1.28;
humanGroup.add(head);
/* Left arm — two segments for bending */
var leftArm = new THREE.Group();
var leftUpper = new THREE.Mesh(
new THREE.CylinderGeometry(0.05, 0.045, 0.3, 6),
shirtMat
);
leftUpper.position.y = -0.15;
leftArm.add(leftUpper);
var leftForearm = new THREE.Mesh(
new THREE.CylinderGeometry(0.045, 0.04, 0.28, 6),
skinMat
);
leftForearm.position.set(0, -0.38, 0);
leftArm.add(leftForearm);
leftArm.position.set(-0.24, 1.05, 0);
humanGroup.add(leftArm);
/* Right arm — two segments for bending */
var rightArm = new THREE.Group();
var rightUpper = new THREE.Mesh(
new THREE.CylinderGeometry(0.05, 0.045, 0.3, 6),
shirtMat
);
rightUpper.position.y = -0.15;
rightArm.add(rightUpper);
var rightForearm = new THREE.Mesh(
new THREE.CylinderGeometry(0.045, 0.04, 0.28, 6),
skinMat
);
rightForearm.position.set(0, -0.38, 0);
rightArm.add(rightForearm);
rightArm.position.set(0.24, 1.05, 0);
humanGroup.add(rightArm);
/* Left leg — two segments for walking */
var leftLeg = new THREE.Group();
var leftThigh = new THREE.Mesh(
new THREE.CylinderGeometry(0.07, 0.06, 0.35, 6),
pantsMat
);
leftThigh.position.y = -0.18;
leftLeg.add(leftThigh);
var leftShin = new THREE.Mesh(
new THREE.CylinderGeometry(0.06, 0.05, 0.35, 6),
pantsMat
);
leftShin.position.set(0, -0.42, 0);
leftLeg.add(leftShin);
leftLeg.position.set(-0.1, 0.45, 0);
humanGroup.add(leftLeg);
/* Right leg — two segments for walking */
var rightLeg = new THREE.Group();
var rightThigh = new THREE.Mesh(
new THREE.CylinderGeometry(0.07, 0.06, 0.35, 6),
pantsMat
);
rightThigh.position.y = -0.18;
rightLeg.add(rightThigh);
var rightShin = new THREE.Mesh(
new THREE.CylinderGeometry(0.06, 0.05, 0.35, 6),
pantsMat
);
rightShin.position.set(0, -0.42, 0);
rightLeg.add(rightShin);
rightLeg.position.set(0.1, 0.45, 0);
humanGroup.add(rightLeg);
/* Initial position — human at x=-1.5, clearly visible in establishing shot */
humanGroup.position.set(-1.5, 0, 0);
humanGroup.rotation.y = 0.3;
scene.add(humanGroup);
/* ── load dog model (smaller scale for readability) ─────────────────── */
var dogGltf;
var dogLoad = new Promise(function (resolve) {
loader.load(assets("dog.glb"), function (gltf) {
dogGltf = gltf;
resolve(gltf);
});
});
pending.push(dogLoad);
/* ── setup once dog loaded, then author all motion ──────────────────── */
dogLoad.then(function () {
/* Dog parent group — world-space locomotion on parent, bob on child */
var dogRoot = new THREE.Group();
scene.add(dogRoot);
var dogScene = dogGltf.scene;
/* Smaller scale so dog doesn't occlude human at contact */
dogScene.scale.set(0.0025, 0.0025, 0.0025);
dogScene.position.set(0, 0, 0);
dogScene.rotation.y = Math.PI;
dogRoot.add(dogScene);
/* Initial position — dog at x=1.5, clearly visible in establishing shot */
dogRoot.position.set(1.5, 0, 0);
dogRoot.rotation.y = Math.PI * 0.5;
/* ═══════════════════════════════════════════════════════════════════
AUTHORED MOTION — every beat has meaningful subject motion.
Camera motion is subtle atmosphere, never a substitute.
═══════════════════════════════════════════════════════════════════ */
/* ── Beat 1: Establishing / Together (0–8s) ───────────────────────── */
/* Both idle with subtle life. Dog tail wag. Human gentle sway. */
/* Dog idle tail wag — subtle rotation.z oscillation */
sceneTl.to(dogScene.rotation, {
z: 0.08,
duration: 0.4,
ease: "sine.inOut",
yoyo: true,
repeat: 19,
}, 0);
/* Dog subtle breathing — scale pulse */
sceneTl.to(dogScene.scale, {
x: 0.0026,
y: 0.0026,
z: 0.0025,
duration: 1.2,
ease: "sine.inOut",
yoyo: true,
repeat: 6,
}, 0);
/* Human subtle sway */
sceneTl.to(humanGroup.rotation, {
y: 0.35,
duration: 2,
ease: "sine.inOut",
yoyo: true,
repeat: 3,
}, 0);
/* ── Beat 2: Separation — Human departs (8–16s) ───────────────────── */
/* Human turns, walks left, legs animate, exits frame.
Dog stays, watches human leave, reacts with head turn + body shift. */
/* Human turns to face walking direction */
sceneTl.to(humanGroup.rotation, {
y: Math.PI * 0.5,
duration: 1.0,
ease: "power2.inOut",
}, 8);
/* Human walks away — world-space translate left */
sceneTl.to(humanGroup.position, {
x: -7.0,
duration: 4.5,
ease: "power1.inOut",
}, 9);
/* Human leg walk cycle */
sceneTl.to(leftLeg.rotation, {
x: 0.5,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 12,
}, 9);
sceneTl.to(rightLeg.rotation, {
x: -0.5,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 12,
}, 9);
/* Human arm swing */
sceneTl.to(leftArm.rotation, {
x: -0.3,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 12,
}, 9);
sceneTl.to(rightArm.rotation, {
x: 0.3,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 12,
}, 9);
/* Dog watches human leave — body rotates to follow */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 1.0,
duration: 1.5,
ease: "power2.inOut",
}, 8.5);
/* Dog head lifts (looks up as human walks away) */
sceneTl.to(dogScene.rotation, {
x: -0.15,
duration: 0.8,
ease: "power1.inOut",
}, 9);
/* Dog steps forward slightly — reacts to departure */
sceneTl.to(dogRoot.position, {
x: 1.0,
duration: 1.2,
ease: "power1.inOut",
}, 9.5);
/* Dog confused look-around — rotation oscillation */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 1.3,
duration: 1.0,
ease: "power1.inOut",
}, 11);
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 0.8,
duration: 1.0,
ease: "power1.inOut",
}, 12);
/* ── Beat 3: Active search (14–22s) ───────────────────────────────── */
/* Dog moves through environment — world-space wandering path.
Turning, pausing to sniff, changing direction. */
/* Dog turns to face search direction */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 0.3,
duration: 1.0,
ease: "power2.inOut",
}, 14);
/* Walk cycle for search phase */
sceneTl.to(dogScene.position, {
y: 0.05,
duration: 0.3,
ease: "sine.inOut",
yoyo: true,
repeat: 25,
}, 14.5);
/* Dog wanders forward */
sceneTl.to(dogRoot.position, {
x: 0.0,
z: 1.5,
duration: 2.5,
ease: "power1.inOut",
}, 14.5);
/* Pause to sniff */
sceneTl.to(dogScene.rotation, {
x: 0.15,
duration: 0.6,
ease: "power1.inOut",
}, 17);
sceneTl.to(dogScene.rotation, {
x: 0,
duration: 0.4,
ease: "power1.inOut",
}, 17.8);
/* Dog turns and moves to new area */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 1.5,
duration: 1.2,
ease: "power2.inOut",
}, 18);
sceneTl.to(dogRoot.position, {
x: 1.0,
z: 2.5,
duration: 2.5,
ease: "power1.inOut",
}, 18.5);
/* Another pause — look around */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 1.8,
duration: 0.8,
ease: "power1.inOut",
}, 21);
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 1.2,
duration: 0.8,
ease: "power1.inOut",
}, 21.8);
/* ── Beat 4: Approach and reunion (22–28s) ────────────────────────── */
/* Dog spots human — reacts, approaches. Human walks back in from left.
Both converge side-by-side (not overlapping). Contact: human bends,
reaches. Dog settles close but with clear separation. */
/* Dog reacts — alert posture, head lifts */
sceneTl.to(dogScene.rotation, {
x: -0.2,
duration: 0.5,
ease: "power2.out",
}, 22);
/* Dog turns toward human's direction */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 0.5,
duration: 0.8,
ease: "power2.inOut",
}, 22.5);
/* Dog approaches — purposeful walk toward human, stops at x=-0.5 */
sceneTl.to(dogRoot.position, {
x: -0.5,
z: 0.3,
duration: 3.0,
ease: "power2.inOut",
}, 23);
/* Dog tail wags excitedly during approach */
sceneTl.to(dogScene.rotation, {
z: 0.12,
duration: 0.2,
ease: "sine.inOut",
yoyo: true,
repeat: 14,
}, 23);
/* Human walks back in from offscreen left.
Departure tween left human at x=-7, rotation.y=Math.PI*0.5.
This tween brings them back to x=-2.0. */
sceneTl.to(humanGroup.position, {
x: -2.0,
duration: 3.0,
ease: "power2.inOut",
}, 23);
/* Human walk cycle */
sceneTl.to(leftLeg.rotation, {
x: 0.4,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 8,
}, 23);
sceneTl.to(rightLeg.rotation, {
x: -0.4,
duration: 0.35,
ease: "sine.inOut",
yoyo: true,
repeat: 8,
}, 23);
/* Human turns to face dog */
sceneTl.to(humanGroup.rotation, {
y: 0,
duration: 1.0,
ease: "power2.inOut",
}, 25.5);
/* ── Beat 5: Contact and changed state (26–31s) ───────────────────── */
/* Human bends down, reaches arm toward dog. Dog settles close.
Both side-by-side with clear silhouette separation.
Final pose visibly changed from initial state. */
/* Human bends down */
sceneTl.to(humanGroup.position, {
y: -0.15,
duration: 0.8,
ease: "power2.inOut",
}, 26);
/* Human right arm reaches down toward dog */
sceneTl.to(rightArm.rotation, {
x: -1.3,
duration: 0.8,
ease: "power2.inOut",
}, 26);
/* Human left arm reaches slightly */
sceneTl.to(leftArm.rotation, {
x: -0.5,
duration: 0.8,
ease: "power2.inOut",
}, 26.2);
/* Dog nudges closer — final approach, stops beside human (not on top) */
sceneTl.to(dogRoot.position, {
x: -0.8,
z: 0.3,
duration: 1.2,
ease: "power1.inOut",
}, 26.5);
/* Dog looks up at human */
sceneTl.to(dogScene.rotation, {
x: -0.18,
duration: 0.6,
ease: "power1.inOut",
}, 27);
/* Dog settles next to human — final position, clear side-by-side */
sceneTl.to(dogRoot.position, {
x: -0.8,
z: 0.5,
duration: 1.5,
ease: "power2.inOut",
}, 28);
/* Dog rotation settles — facing toward human */
sceneTl.to(dogRoot.rotation, {
y: Math.PI * 0.7,
duration: 1.2,
ease: "power1.inOut",
}, 28);
/* Dog head lowers — relaxed, content */
sceneTl.to(dogScene.rotation, {
x: 0.05,
y: 0,
z: 0,
duration: 1.0,
ease: "power1.inOut",
}, 29);
/* Human stands slightly back up but arm stays reached */
sceneTl.to(humanGroup.position, {
y: -0.05,
duration: 1.0,
ease: "power1.inOut",
}, 29.5);
/* ═══════════════════════════════════════════════════════════════════
CAMERA — subtle atmospheric motion, never a substitute for
subject motion. The subjects do all the storytelling work.
═══════════════════════════════════════════════════════════════════ */
/* Establishing: very slow drift */
sceneTl.to(camera.position, {
x: -0.2,
duration: 8,
ease: "power1.inOut",
}, 0);
/* Separation: camera follows departing human slightly */
sceneTl.to(camera.position, {
x: -0.8,
z: 8.0,
duration: 6,
ease: "power1.inOut",
}, 9);
/* Search: camera recenters on dog */
sceneTl.to(camera.position, {
x: 0.0,
z: 8.5,
duration: 5,
ease: "power1.inOut",
}, 15);
/* Reunion: frame both side-by-side, pull back slightly for contact */
sceneTl.to(camera.position, {
x: -0.6,
z: 7.5,
y: 3.5,
duration: 5,
ease: "power2.inOut",
}, 23);
});
theme.cssauthored-module · 70 bytes
/* Lost Dog Rebuild — minimal theme, no caption background cards */
Remix
Download the verified project, then run the exact local archive command.
narova remix the-precious-thing.narova --dir the-precious-thing-remixArchives are untrusted input. Inspect first; building executes authored project source with your account's ambient authority.