reelkit-cli 0.8.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/package.json +49 -10
- package/skill/.claude-plugin/plugin.json +7 -0
- package/skill/SKILL.md +44 -19
- package/skill/THIRD_PARTY.md +37 -5
- package/skill/commands/launch-film.md +1 -1
- package/skill/hooks/hooks.json +1 -0
- package/skill/hooks/player.ts +278 -0
- package/skill/hooks/project.ts +227 -0
- package/skill/hooks/register.tsx +533 -0
- package/skill/hooks/timeline.ts +218 -0
- package/skill/reference/art-styles.md +70 -0
- package/skill/reference/backgrounds.md +1 -1
- package/skill/reference/brand-motion.md +62 -0
- package/skill/reference/clips.md +3 -3
- package/skill/reference/component-authoring.md +3 -1
- package/skill/reference/continuity.md +5 -5
- package/skill/reference/delivery-review.md +40 -0
- package/skill/reference/hebrew-rtl.md +3 -4
- package/skill/reference/higgsfield-production.md +70 -0
- package/skill/reference/{remotion-composition.md → hyperframes-composition.md} +14 -8
- package/skill/reference/kit.md +7 -3
- package/skill/reference/launch-film.md +13 -9
- package/skill/reference/motion-design.md +26 -22
- package/skill/reference/sound-design.md +34 -12
- package/skill/reference/studio-editing.md +55 -0
- package/skill/reference/studio-pane.md +31 -0
- package/skill/reference/style-components.md +40 -0
- package/skill/reference/style-recipes.md +86 -0
- package/skill/reference/styles.md +17 -10
- package/skill/reference/three-d.md +8 -7
- package/skill/reference/voice-sync.md +1 -1
- package/skill/tests/studio.test.ts +111 -0
- package/skill/types/index.d.ts +65 -0
- package/src/commands/assets.ts +5 -1
- package/src/contract/index.ts +1 -1
- package/src/hyperframes/Root.tsx +1 -0
- package/src/hyperframes/fonts.ts +54 -0
- package/src/hyperframes/frame.tsx +46 -0
- package/src/hyperframes/host.tsx +38 -0
- package/src/{remotion → hyperframes}/kit/Assemble3D.tsx +1 -1
- package/src/hyperframes/kit/BrandTransform3D.tsx +12 -0
- package/src/{remotion → hyperframes}/kit/BrowserFrame.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Camera.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Captions.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Card3D.tsx +2 -2
- package/src/{remotion → hyperframes}/kit/Carry.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/ChapterFrame.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/ClipLayer.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Counter.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/CounterRoll.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Entrance.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/FootageLayer.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/GlassPanel.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Grounds.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Headline.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Hero3D.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/HudOverlay.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/ImageLayers.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/KenBurnsImage.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/KeyedClip.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Layers.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/LowerThird.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Music.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/NamedCursor.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Orbit3D.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Particles3D.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Place.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/PromptBox.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Scene3D.tsx +2 -2
- package/src/{remotion → hyperframes}/kit/SceneFrame.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/ScreenOverlay.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Sfx.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/SoundCues.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/TerminalLog.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Text3D.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/TextOnImage.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/TitleCard.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Voiceover.tsx +1 -1
- package/src/{remotion → hyperframes}/kit/Warp3D.tsx +1 -1
- package/src/hyperframes/kit/brand-transform.ts +25 -0
- package/src/{remotion → hyperframes}/kit/docs.ts +6 -2
- package/src/{remotion → hyperframes}/kit/index.ts +3 -0
- package/src/{remotion → hyperframes}/kit/sound-cues.ts +1 -1
- package/src/{remotion → hyperframes}/kit/sound-kinds.ts +14 -1
- package/src/{remotion → hyperframes}/kit/theme.ts +42 -40
- package/src/{remotion → hyperframes}/kit/ui-math.ts +1 -1
- package/src/hyperframes/math.ts +62 -0
- package/src/hyperframes/three.tsx +10 -0
- package/src/project/chromakey.ts +1 -1
- package/src/project/layers.ts +1 -1
- package/src/project/serve.ts +2 -2
- package/src/render/component-preview.ts +11 -55
- package/src/render/render.ts +62 -64
- package/src/render/serve.ts +31 -0
- package/src/render/static-check.ts +15 -4
- package/src/render/validate.ts +4 -4
- package/src/render/word-check.ts +1 -1
- package/src/render/worker.ts +71 -0
- package/src/testing/fixtures.ts +1 -1
- package/src/remotion/Root.tsx +0 -31
- /package/src/{remotion → hyperframes}/kit/Icon.tsx +0 -0
- /package/src/{remotion → hyperframes}/kit/beat.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/bg-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/brand-icons.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/caption-groups.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/caption-style.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/image-layers-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/inter-bold-typeface.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/media.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/motion-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/music-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/quiet-three.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/sample-text.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/scene3d-context.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/seeded.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/three-fx-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/three-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/transition-math.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/ui-theme.ts +0 -0
- /package/src/{remotion → hyperframes}/kit/word-anchor.ts +0 -0
- /package/src/{remotion → hyperframes}/types.ts +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: higgsfield-production
|
|
3
|
+
description: Choose optional Higgsfield cutout, Blender, hosted 3D or native motion workflows and hand their inspected output to a Reelkit composition.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# External media and motion production
|
|
7
|
+
|
|
8
|
+
Read this when a shot needs a clean cutout, an editable product model, custom lighting, character rigging or compositing beyond the Reelkit kit. Use the smallest workflow that serves the shot. A skill teaches a workflow; loading one does not establish an editor connection or add a CLI capability.
|
|
9
|
+
|
|
10
|
+
## Choose by the deliverable
|
|
11
|
+
|
|
12
|
+
| Need | Candidate | What comes back |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Put a supplied product photo over graphics | Higgsfield Background Remover | A transparent PNG; inspect the edges and original identity |
|
|
15
|
+
| Put a moving subject over graphics | Reelkit green key or video cutout, `reference/clips.md` | A keyed WebM; check the matte over time |
|
|
16
|
+
| Show how a product comes apart and assembles | Higgsfield `/exploded-view` in local Blender | Editable parts, camera and animation; requires the local Blender connection |
|
|
17
|
+
| Establish a stylized 3D look | `/cartoon-shaders` in local Blender | Editable materials; verify them from the delivery camera |
|
|
18
|
+
| Build a new set, prop layout or camera blockout | Hosted `/3d-jutsu` | A separate revisioned scene with render, `.blend` and GLB export paths |
|
|
19
|
+
| Compose supplied footage into a VFX shot | `/shot-composer` in local After Effects | An editable AE project; requires the AE connection |
|
|
20
|
+
| Coordinate editable logo, type and graphic motion | `/motion-bundle`, `/logo-animation`, `/kinetic-typography` | Local After Effects workflows; resolve the selected command's current instructions |
|
|
21
|
+
| Author native Higgsedit motion | Installed `motion-craft` and `video-editing` skills | Native composition tracks and keyframes, rather than Reelkit TSX |
|
|
22
|
+
|
|
23
|
+
Higgsfield's connected preset-instructions lookup resolves these commands without running them. Read the exact selected workflow and its required references before editing. Check available tools and runtime versions; a web feature, command listing or model recommendation is not evidence that its tool is connected. Background Remover exists on the website, but this research did not find a dedicated Higgsfield background-removal tool in the current connector. Preserve that distinction when reporting availability.
|
|
24
|
+
|
|
25
|
+
## Three different Blender connections
|
|
26
|
+
|
|
27
|
+
- **Local background MCP:** `/use-blender` starts its own Blender session. It can open saved local `.blend` files; it does not attach to unsaved work in an open window. Verify with the workflow's health and scene-summary tools, render appearance checks, and explicitly save the source.
|
|
28
|
+
- **Desktop add-on and Bridge:** the official add-on operates in the open scene and provides scene building, 3D models, character animation, image/video and camera tools. Its published requirement is Blender 5.1 or later. Check the current requirement before setup. The separate Bridge connects an agent to this add-on.
|
|
29
|
+
- **Hosted 3D Jutsu:** no local installation; edits use service-side Blender Python. The current instructions allow curated asset imports, not arbitrary user model or texture files. Recheck those restrictions before selecting it for a supplied product. A local project cannot silently become a hosted one.
|
|
30
|
+
|
|
31
|
+
An account connection, editor installation and generated asset are separate steps. Use existing authorization and working connections. A documentation search does not authorize a new editor setup or a paid generation.
|
|
32
|
+
|
|
33
|
+
## Cutout quality
|
|
34
|
+
|
|
35
|
+
Keep the original alongside the processed output. A transparent PNG proves image isolation, not video matting or recovered hidden geometry. Inspect hair, fingers, handles, thin straps, glass, holes and the product outline against light and dark backgrounds at delivery scale. Check brand lettering against the source. Add a contact shadow and agree on light direction when placing the subject in a new setting.
|
|
36
|
+
|
|
37
|
+
For a moving subject inspect opening, fastest motion, overlap, landing and ending for edge shimmer, missing parts and spill. Verify transparency in the actual Reelkit preview; an ordinary H.264 MP4 does not carry an alpha channel. Follow `reference/clips.md` for the supported keyed-media path. Do not promise a lossless subject merely because a provider advertises pixel-perfect removal.
|
|
38
|
+
|
|
39
|
+
## Editable 3D and handoff
|
|
40
|
+
|
|
41
|
+
Start from the delivery camera, subject silhouette, real dimensions and a simple motivated light rig. Keep named parts and materials editable. For assembly, move semantic parts along plausible paths and verify contact, intersections, camera clearance and the final assembled pose. For materials, inspect roughness, highlight continuity and silhouette under the actual shot lighting before adding surface detail.
|
|
42
|
+
|
|
43
|
+
Hosted 3D has bounded execution time: keyframe first, prove critical states with low-cost stills, then render the requested motion. A generated video from one scene render is a new AI interpretation; it is not proof of the keyed Blender animation. Preserve exact geometry, logos and mechanics through an authored render when those are the point.
|
|
44
|
+
|
|
45
|
+
Retain `.blend` or `.aep` as editable source. GLB may omit procedural materials and lighting. Reelkit's composition allowlist does not provide a general GLB or Lottie loader: use supported local image/video output, or explicitly implement and validate a new kit capability. Check dimensions, fps, duration, alpha, color and source audio before ingesting the inspected file as a user asset. Register it with a truthful description; choose the supported image, clip or footage layer and use `urls[path]` inside the composition.
|
|
46
|
+
|
|
47
|
+
## Additional motion skills
|
|
48
|
+
|
|
49
|
+
Prefer the official HyperFrames domain skills as sources:
|
|
50
|
+
|
|
51
|
+
- `hyperframes-animation`: choreography, transitions, runtime adapters and scene recipes.
|
|
52
|
+
- `hyperframes-keyframes`: visible poses, subject continuity, masks, camera moves and motion diagnostics.
|
|
53
|
+
- `hyperframes-creative`: brand tokens, typography, visual hierarchy and beat planning.
|
|
54
|
+
- `hyperframes-audio`: mixing placed tracks, envelopes and speech/music relationships.
|
|
55
|
+
- `media-use`: sourcing, reuse and media operations, with provider-specific setup.
|
|
56
|
+
|
|
57
|
+
Their native authoring surface is HTML with registered seekable runtimes. This Reelkit version uses the adapter described in `reference/hyperframes-composition.md`: translate applicable craft into frame-driven kit code rather than pasting GSAP, shader, bus or media attributes into `Video.tsx`. Preserve the pinned engine and import allowlist. Installing every external workflow would not make its APIs available in Reelkit.
|
|
58
|
+
|
|
59
|
+
Review rest, peak, landing, readable hold and final frames. Keep one subject continuous when it moves between layouts; use a dissolve for replacement. Make the visual landing and sound cue share one event frame. Test a direct seek to important states and the loop seam when relevant; inspect rendered pixels, not only numeric keyframes. For source speech, derive music ducking from the actual speech spans, as explained in `reference/studio-editing.md`.
|
|
60
|
+
|
|
61
|
+
## Sources and freshness
|
|
62
|
+
|
|
63
|
+
Reviewed 2026-10-06. Re-resolve runtime-dependent workflows when using them.
|
|
64
|
+
|
|
65
|
+
- [Higgsfield skill hub](https://higgsfield.ai/skills)
|
|
66
|
+
- [Background Remover: supported image input and transparent PNG output](https://higgsfield.ai/apps/image-background-remover)
|
|
67
|
+
- [Blender add-on, version requirements and Bridge](https://higgsfield.ai/plugins/blender)
|
|
68
|
+
- [Official HyperFrames skills](https://github.com/heygen-com/hyperframes/tree/main/skills)
|
|
69
|
+
|
|
70
|
+
The connected Higgsfield instructions for `/use-blender`, `/exploded-view`, `/cartoon-shaders`, `/shot-composer`, `/motion-bundle` and `/3d-jutsu` supply the editor-specific rules. Keep those live lookups authoritative instead of copying a full manual into this reference.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: hyperframes-composition
|
|
3
3
|
description: Use when writing Video.tsx - the file rules, timing model and media rules every composition must follow.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Writing the composition
|
|
7
7
|
|
|
8
|
+
Reelkit uses HyperFrames with a seekable React adapter. Author TSX in `src/Video.tsx`; `reelkit/frame` supplies the frame clock, sequences, media, and animation math. The generated HTML exposes HyperFrames' seek protocol for capture and rendering.
|
|
9
|
+
|
|
8
10
|
## Files
|
|
9
11
|
- `Video.tsx` is required and must contain `export const Video: React.FC<VideoProps> = ({ manifest, urls }) => ...`.
|
|
10
12
|
- Extra component files are flat siblings, PascalCase, one component per file: `NumberBadge.tsx` exports `NumberBadge`. Import them in Video.tsx as `./NumberBadge`.
|
|
11
|
-
- Video.tsx may import only `react`, `
|
|
13
|
+
- Video.tsx may import only `react`, `reelkit/frame`, `reelkit/kit` and sibling components. No other packages, no network, no file access, no `process`.
|
|
12
14
|
|
|
13
15
|
## What the composition receives
|
|
14
16
|
`Video` gets two props, `{ manifest, urls }` (type `VideoProps`, exported by `reelkit/kit`). `manifest` is the content of `manifest.json` in the project, rewritten by `reelkit assets voiceover`, `check`, `preview` and `render` from `plan.json` and the recorded voiceovers. It is not hand-edited. `urls` is separate: it is built at render time and is not in `manifest.json`.
|
|
@@ -28,7 +30,7 @@ Each `scenes` entry:
|
|
|
28
30
|
- `imageKey`: only on an illustration scene that has its image; the project path of the image.
|
|
29
31
|
- `userAssetKeys`: project paths of the user's own files that the plan assigned to this scene (an empty array when none).
|
|
30
32
|
|
|
31
|
-
`urls` maps a project path (every file under `assets/`, except `.json` files) to the address
|
|
33
|
+
`urls` maps a project path (every file under `assets/`, except `.json` files) to the address HyperFrames can load it from. Pass paths from the manifest, or one you pulled, such as `urls["assets/lib/<id>/clip.mp3"]`; never build an address yourself.
|
|
32
34
|
|
|
33
35
|
```json
|
|
34
36
|
{
|
|
@@ -51,12 +53,12 @@ Each `scenes` entry:
|
|
|
51
53
|
- Reference media only as `urls[path]`, where `path` is the file's project path, using the paths in the manifest: `s.voiceoverKey`, `s.imageKey`, `s.clipKey`, `s.clipKeyedKey`, `s.userAssetKeys`, `manifest.footageKey`. Never hard-code a URL.
|
|
52
54
|
- A scene with narration has `s.voiceoverKey`: give it exactly one `<Voiceover src={urls[s.voiceoverKey]} />` inside its SceneFrame, and `<Captions words={s.words} />` unless the notes say otherwise. In a plan with `voice: "none"` no scene has a `voiceoverKey` and `s.words` is empty, so render no `<Voiceover>` and no `<Captions>` (`manifest.captions` is `"none"`); keep the guard `s.voiceoverKey ? ... : null` so the same code works either way.
|
|
53
55
|
- Footage mode (`manifest.footageKey` is set): one `<FootageLayer>` at the bottom, outside the scenes.
|
|
54
|
-
- User images: `<Img src={urls[key]} />` from
|
|
56
|
+
- User images: `<Img src={urls[key]} />` from reelkit/frame.
|
|
55
57
|
- Write a media path as one plain string, so that `reelkit check` can verify the file exists. A path built with a template string or by joining parts (`` `assets/lib/${id}/hit.mp3` ``) cannot be checked and is reported as missing. Write `"assets/lib/sfx-ab12/hit.mp3"` in full, or read the key from the manifest.
|
|
56
58
|
|
|
57
59
|
## Layer stack (every video, bottom to top)
|
|
58
|
-
1. Background:
|
|
59
|
-
2. Images: `<KenBurnsImage>`
|
|
60
|
+
1. Background: a chosen field, picture, `<BgMesh>` or `<FootageLayer>` in footage mode. A flat colour is valid when it serves the design.
|
|
61
|
+
2. Images: `<KenBurnsImage>` when a camera move helps, or a stable image for reading and comparison. Keep important details in frame.
|
|
60
62
|
3. Clips: `<ClipLayer>` inside its scene (a clip scene's picture); a green-screen `<KeyedClip>` above the scene's background and below its type and captions. See `reference/clips.md`.
|
|
61
63
|
4. Graphics and type, inside each scene's SceneFrame.
|
|
62
64
|
5. Anything that must survive a scene change: a `<Carry>` layer beside the scenes and above them (outside the SceneFrame fades), and `<Camera>` around the scenes when one camera moves through all of them. See `reference/continuity.md`.
|
|
@@ -70,9 +72,9 @@ Each `scenes` entry:
|
|
|
70
72
|
- Run `reelkit assets pull <id>` before referencing an overlay. It lands in `assets/lib/<id>/`; reference it as `urls["assets/lib/<id>/<file>"]`, and read its duration from `assets/library.json`.
|
|
71
73
|
|
|
72
74
|
## Animation rules
|
|
73
|
-
-
|
|
75
|
+
- Choose easing or a spring to fit the move; linear interpolation is valid for steady motion. Clamp finite interpolation ranges with `extrapolateLeft: "clamp"` and `extrapolateRight: "clamp"` so elements do not drift beyond their intended pose.
|
|
74
76
|
- **Entrances move two or three properties together** (opacity, position, scale). Wrap content in `<Entrance>` rather than fading alone.
|
|
75
|
-
-
|
|
77
|
+
- Stagger related items when that improves hierarchy; simultaneous motion is valid for one coordinated action. Spoken words follow their real timestamps rather than a fixed stagger.
|
|
76
78
|
- **Exits exist and are faster than entrances** (about 10 frames against 20). Use `<Entrance exitAt={...}>` or the SceneFrame fade.
|
|
77
79
|
- **A missing clamp shows elements before their entrance or after their exit.** Check for it.
|
|
78
80
|
- Derive timing from `fps` in `useVideoConfig()`, not bare frame counts, when you express a duration in seconds.
|
|
@@ -91,3 +93,7 @@ Each `scenes` entry:
|
|
|
91
93
|
1. `reelkit assets search "<description>" --kind component`, and `reelkit assets pull <id>` for any you plan to use (it lands in `src/`).
|
|
92
94
|
2. Write each new component in `src/`, then `src/Video.tsx`.
|
|
93
95
|
3. `reelkit check`. Fix every error it reports and check again until it passes.
|
|
96
|
+
|
|
97
|
+
## Revising a shot in HyperFrames
|
|
98
|
+
|
|
99
|
+
Every pose must be computable from the current frame, including a direct seek to the landing or held state. Use `reelkit/frame` timing helpers; avoid CSS animations, wall-clock timers, and state accumulated by previous frames. Derive sound from the same event frames as the visual. Inside a `SceneFrame` timing is local; outside it add `startFrame` once. For a branded arrival use `BrandTransform3D` and `brandTransformFrames` (`reference/brand-motion.md`). Preview early, middle and held states after retiming, and listen to the rendered file after changing sound.
|
package/skill/reference/kit.md
CHANGED
|
@@ -127,6 +127,10 @@ Scene3D { camera?: { keys: { frame: number; x?: number; y?: number; z?: number;
|
|
|
127
127
|
A three.js scene at the size of the frame, for real depth. Transparent unless background is set, so it lays over a 2D ground; a soft three-point light is placed for you (lights={false} to place your own); mood ("studio", "night", "sunset" or "neon") chooses the light colours, their intensities and the fog tint together instead, so lights are never hand-tuned. Put it inside a SceneFrame, with captions and small labels in 2D above it. camera.keys move the camera with the same timing as Camera (a spring that starts 12 frames before the key's frame and lands on it); the default camera is at z 6, looking at the origin, fov 50, and a key that leaves a value out keeps the one before. What it sees: at fov 50 the height is 0.93 times the distance to the object and the width that times width over height, so 3.1 units across at z 6 on 9:16 (4.7 at z 9), 5.6 on 1:1 and 9.9 on 16:9 (not "5.5"). Text3D and Orbit3D read the camera keys and size themselves to fit at the key where the camera is closest: leave their sizes out. visibleWidth(distance, aspect, fov?) and visibleHeight(distance, fov?) give the same numbers. No GL context is made unless a Scene3D is on screen. A 3D scene renders slower: use it only for the shots that need it. See reference/three-d.md.
|
|
128
128
|
<Scene3D camera={{ keys: [{ frame: 0, z: 7.5 }, { frame: 40, z: 6 }] }}><Text3D text="Reelkit" color={palette.hero} enter="rise" /></Scene3D>
|
|
129
129
|
|
|
130
|
+
BrandTransform3D { mode?: "turn" | "arc" | "launch"; from?: number (0); frames?: number (32); strength?: number (0 to 1, default 1); children }
|
|
131
|
+
A deterministic arrival for a branded object inside Scene3D: turn exposes its face, arc carries it on a curved path, launch approaches from depth. Wrap Text3D, Card3D or Hero3D; the final pose is neutral and holds exactly. Keep the supplied identity intact and allow a readable hold after landing. A transformation has no built-in audio. brandTransformFrames({ from, frames }) returns { start, settle } in the same local clock; cuesFor([start, settle], "transform", { offset: scene.startFrame, voice, sweepFrames }) places the transform-sweep role before the landing and transform-lock on it. Map both roles to pulled sound files. sweepFrames is the chosen sound's attack in frames (default 10). brandTransformAt(frame, fps, options) returns { visible, position, rotation, scale }; BRAND_TRANSFORMS lists the modes. See reference/brand-motion.md for when and why to choose each.
|
|
132
|
+
<BrandTransform3D mode="turn" from={6} frames={32}><Text3D text="Reelkit" fit={0.72} /></BrandTransform3D>
|
|
133
|
+
|
|
130
134
|
Text3D { text: string; fit?: number (0.8); size?: number; depth?: number; color?: string; position?: [x, y, z]; rotation?: [x, y, z] (degrees); enter?: "rise" | "turn" | "fly" | "none"; delay?: number }
|
|
131
135
|
Extruded text, centred on its position, inside a Scene3D. Latin letters, digits and common punctuation only (one bundled typeface, Inter Bold): Hebrew and other scripts stay 2D. Leave size out: the word is measured on its own letters and sized to fill fit (default 0.8) of the frame's width at the closest the Scene3D camera comes, so it is whole at every moment on any aspect; a line break in the text makes a second line, and the height is held to fit of the frame's height. A size you give wins (scene units, the height of a capital-ish line). A push-in starts the word smaller in proportion: z 7.5 to 6 is a gentle one. depth is how far it is extruded (default a quarter of the size). enter is how it arrives, starting delay frames into the scene; "none" is there from the start. Keep type that must be read facing the camera and held at least 1.5 seconds.
|
|
132
136
|
<Text3D text="Meet Reelkit" color="#ffffff" position={[0, 1, 0]} enter="turn" delay={6} />
|
|
@@ -227,8 +231,8 @@ cuesOnChanges(scenes, { impact?: { sound, volume? }, whoosh?: { sound, volume?,
|
|
|
227
231
|
Sounds for the scene changes, placed where the eye sees them. A SceneFrame transition is complete on the boundary but the picture changes most half the transition's frames before it (4 for the default 8, 3 for transitionFrames={6}; none for "cut"), and a hit on the boundary lands after the change. scenes are the manifest's scenes, each with the exit and transitionFrames its SceneFrame has: cuesOnChanges gives an impact on that peak and a whoosh (frames long, from the search line's duration times 30) that ENDS on it, for every change but the one after the last scene; skip lists scene indices to leave silent. changeFrame(scene) is the peak for one scene. A camera zoom, zoomTo or punch is a picture change too: cueOnCamera(frame) is the frame where the Camera move to the key at "frame" is fastest (about 9 frames before it); with punch: true, the fastest frame of a punch (just after its frame). The Camera counts frames from the scene's start when it is inside a SceneFrame, so add the scene's startFrame for an absolute cue.
|
|
228
232
|
const exits = [{ exit: "zoom-through" as const }, { exit: "whip-left" as const, transitionFrames: 6 }, {}]; const cues = cuesOnChanges(manifest.scenes.map((s, i) => ({ ...s, ...exits[i] })), { impact: { sound: "thud", volume: 0.55 }, whoosh: { sound: "whoosh", frames: 24, volume: 0.3 } });
|
|
229
233
|
|
|
230
|
-
cuesFor(events, kind, { offset?, fps?, voice?, volume?, seed?, riserFrames? }): { at, sound, volume }[] clearBefore(cues, frame, { seconds?, fps?, riserFrames? }): cues
|
|
231
|
-
Turns the event frames a component reports into SoundCues with a sensible sound role, level and density for the kind: "type" (promptFrames(...).type: a tick on every 2nd or 3rd character, at most 12 a second, a little different in level each, and a thock one frame after the last), "click" (clickFrames), "snap" (panelSettleFrame: a card or panel landing), "pop" (chapterFrames(...).badges), "count" ([start, settleFrame]: a train of ticks that speeds up and ends on a chime ON settleFrame), "stream" (terminalFrames(...).lines: one soft tick per line, at most 6 a second), "assemble" ([start, lockFrame]: a rising run that gets louder and a lock hit on lockFrame) and "resolve" ([frame] the logo or end card lands: a riser that ends on the chime, which is on the frame). offset is the scene's startFrame when the events are in the scene's own clock. voice: true gives the quieter levels for a film with a narrator (never over 0.3). Each cue's sound is a role: type-tick, type-return, click, snap, pop, count-tick, count-settle, stream, assemble-run, assemble-lock, resolve-riser, resolve-chime. Map each role to a pulled file in sounds, searching with: type-tick "mouse click"; type-return "glass tap"; click "mouse click"; snap "soft impact"; pop "bubble pop"; count-tick "counter ticks"; count-settle "success chime"; stream "glass tap"; assemble-run "counter ticks"; assemble-lock "soft impact"; resolve-riser "whoosh buildup"; resolve-chime "sparkle shimmer" (reelkit assets search "<words>" --kind sfx; the interface pack's names begin with sfx-ui-). clearBefore(cues, chimeFrame) removes every other cue in the second before the riser so the end card has a clear second of nothing; give the music a dip there (Music dips).
|
|
234
|
+
cuesFor(events, kind, { offset?, fps?, voice?, volume?, seed?, sweepFrames?, riserFrames? }): { at, sound, volume }[] clearBefore(cues, frame, { seconds?, fps?, riserFrames? }): cues
|
|
235
|
+
Turns the event frames a component reports into SoundCues with a sensible sound role, level and density for the kind: "type" (promptFrames(...).type: a tick on every 2nd or 3rd character, at most 12 a second, a little different in level each, and a thock one frame after the last), "click" (clickFrames), "snap" (panelSettleFrame: a card or panel landing), "pop" (chapterFrames(...).badges), "count" ([start, settleFrame]: a train of ticks that speeds up and ends on a chime ON settleFrame), "stream" (terminalFrames(...).lines: one soft tick per line, at most 6 a second), "assemble" ([start, lockFrame]: a rising run that gets louder and a lock hit on lockFrame), "transform" ([start, settle]: transform-sweep begins sweepFrames before settle, never before start, and transform-lock lands on settle) and "resolve" ([frame] the logo or end card lands: a riser that ends on the chime, which is on the frame). offset is the scene's startFrame when the events are in the scene's own clock. voice: true gives the quieter levels for a film with a narrator (never over 0.3). Each cue's sound is a role: type-tick, type-return, click, snap, pop, count-tick, count-settle, stream, assemble-run, assemble-lock, transform-sweep, transform-lock, resolve-riser, resolve-chime. Map each role to a pulled file in sounds, searching with: type-tick "mouse click"; type-return "glass tap"; click "mouse click"; snap "soft impact"; pop "bubble pop"; count-tick "counter ticks"; count-settle "success chime"; stream "glass tap"; assemble-run "counter ticks"; assemble-lock "soft impact"; transform-sweep "soft ui whoosh"; transform-lock "soft impact"; resolve-riser "whoosh buildup"; resolve-chime "sparkle shimmer" (reelkit assets search "<words>" --kind sfx; the interface pack's names begin with sfx-ui-). clearBefore(cues, chimeFrame) removes every other cue in the second before the riser so the end card has a clear second of nothing; give the music a dip there (Music dips).
|
|
232
236
|
const p = promptFrames({ text, reply }, fps); const cues = [...cuesFor(p.type, "type", { offset: s.startFrame }), ...cuesFor([p.send], "click", { offset: s.startFrame }), ...cuesFor([settleFrame({ delay: 20 })], "snap", { offset: s.startFrame })];
|
|
233
237
|
|
|
234
238
|
Music { src: string; volume?: number; duckTo?: number; dips?: { from: number; to: number; volume: number }[] }
|
|
@@ -252,7 +256,7 @@ Voiceover { src: string; volume?: number }
|
|
|
252
256
|
|
|
253
257
|
```tsx
|
|
254
258
|
import React from "react";
|
|
255
|
-
import { AbsoluteFill, useVideoConfig } from "
|
|
259
|
+
import { AbsoluteFill, useVideoConfig } from "reelkit/frame";
|
|
256
260
|
import { BgMesh, Captions, FootageLayer, fonts, Grade, Grain, KenBurnsImage, palettes, SceneFrame, Vignette, Voiceover, WordReveal } from "reelkit/kit";
|
|
257
261
|
import type { VideoProps } from "reelkit/kit";
|
|
258
262
|
|
|
@@ -9,11 +9,11 @@ The short films that studios post when a product launches have no narrator. The
|
|
|
9
9
|
|
|
10
10
|
## When to choose it
|
|
11
11
|
|
|
12
|
-
Choose it for a product, a feature or a brand reveal where nobody needs to explain anything out loud. If the user wants a person to talk, or a story told in sentences, it is the wrong tool: write a narrated video instead.
|
|
12
|
+
Choose it for a product, a feature or a brand reveal where nobody needs to explain anything out loud. If the user wants a person to talk, or a story told in sentences, it is the wrong tool: write a narrated video instead. Use the requested format; ask about narration only if that decision is still consequential and unclear. Skip the voice and caption steps.
|
|
13
13
|
|
|
14
14
|
## What good ones measured
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Four previously measured launch films of 15 to 55 seconds provide examples of one energetic style. Their ranges are context, not targets for every brand or edit; a calm reveal can use fewer sounds and longer holds.
|
|
17
17
|
|
|
18
18
|
- No speech at all. Loudness between -14.1 and -14.8 LUFS in every one.
|
|
19
19
|
- 2.0 to 3.0 sound hits a second over the whole film (music beats and effects together), 1.5 to 2.8 of them low, and a whoosh-like swell every one to two seconds (0.5 to 1.3 a second).
|
|
@@ -27,7 +27,7 @@ The owner measured four launch films of 15 to 55 seconds. Use these numbers as t
|
|
|
27
27
|
|
|
28
28
|
Write `plan.json` with `"voice": "none"`. Every scene then has `seconds` (a number from 0.3 to 15) and `narration` may be an empty string; `voiceId` is not needed, and `captions` is `none` unless you set it. Up to 16 scenes are allowed in this mode.
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- A common short launch film is 15 to 45 seconds with 6 to 14 shots; adapt to the requested duration and reading time.
|
|
31
31
|
- Lengths vary at least fourfold: one or two shots under a second, one long hold, the rest in between.
|
|
32
32
|
- On-screen text carries every word the viewer will read, so each scene has `onScreenText` or `notes` saying what is on screen (`reelkit plan check` flags a scene with neither).
|
|
33
33
|
- The product's logo comes first or last.
|
|
@@ -56,7 +56,7 @@ What the strongest short launch films have in common, in rules a plan can follow
|
|
|
56
56
|
- **Open on the question.** When the product is an assistant or a tool, the first scene is the user's own question typed into a `PromptBox`. Always end on an end card: the wordmark, one line, one call to action, with a clear second before it (`clearBefore`).
|
|
57
57
|
- **Ask for the real material before writing**: screenshots, the real numbers, the logo, the exact product name; and use it. No third-party brand marks.
|
|
58
58
|
- **Length.** 15 to 40 seconds; state it in the plan. Over 60 seconds the same effect repeats.
|
|
59
|
-
- **Review.**
|
|
59
|
+
- **Review.** Inspect the preview for phone readability, demonstrated claims, planned grounds and the hero object where it belongs. Fix observed problems and recheck changed shots. Finish with `reference/delivery-review.md`.
|
|
60
60
|
|
|
61
61
|
## The pictures
|
|
62
62
|
|
|
@@ -71,12 +71,12 @@ With no voice the sound is half of the film. Plan it as you plan the picture.
|
|
|
71
71
|
|
|
72
72
|
1. **Choose the track first and let the beat set the cuts.** Search for 107 to 145 BPM (`reelkit assets search "driving clean product launch, 120 BPM" --kind music`), pull it with `reelkit assets pull <id> --music`, and read `reference/beat-sync.md`. The CLI holds each scene to the next beat, so every cut lands on the beat, a little more than the films did. Let the effects fill the places between.
|
|
73
73
|
2. **Sound from the first frame.** A cue at frame 0 and the music running from frame 0. `reelkit check` notes a film with nothing placed in the first half second.
|
|
74
|
-
3. **
|
|
74
|
+
3. **Score meaningful changes on the frame where the eye sees them.** A press clicks, a card arriving pops, a move whooshes, a scene change lands on a low hit, and a reveal is led in by a riser that ends on it (`cueBefore`). Two things the measurement showed:
|
|
75
75
|
- A `SceneFrame` transition is complete on the boundary, but the picture changes most in the middle of it: for a zoom-through, blur, push or whip exit that is half the transition's frames before the boundary (4 frames for the default 8, 3 for `transitionFrames={6}`). A hit on the boundary frame lands after the change and does not register against it. Use `cuesOnChanges(scenes, { impact, whoosh })`: it puts the impact on the visual peak and the whoosh so that it ENDS there. Give each scene the same `exit` and `transitionFrames` you give its `SceneFrame` (one array for both, so they cannot disagree).
|
|
76
76
|
- A camera zoom, `zoomTo` or punch is a picture change too and needs its own hit. `cueOnCamera(frame)` gives the frame where a `Camera` key's move is fastest (about 9 frames before the key's frame, because the move starts 12 frames early); `cueOnCamera(frame, { punch: true })` gives it for a punch (just after its frame). Inside a `SceneFrame` the Camera counts frames from the start of the scene: add the scene's `startFrame` for an absolute cue.
|
|
77
|
-
4. **Density.**
|
|
77
|
+
4. **Density.** An energetic burst may use frequent effects; a restrained film may need only the main actions and reveal. Allow deliberate silence. The measured 2 to 3 hits a second describes examples, not a quality threshold. `reelkit check` counts what the code places and says when it is under one per two seconds; that is a count of the code, not a listening test. Its sound-count notes stay silent when the cues are computed (built by a loop, a helper such as `cuesOnBeats`, or a variable that is not a plain list), so their absence proves nothing: use the render's sound report to see what the film really has.
|
|
78
78
|
5. **One family of sounds.** Take them from the interface pack in `reference/sound-design.md`, and mix families only when one is missing what you need. For the music, see "Background music" there.
|
|
79
|
-
6. **Levels.** For a film with no voice these are
|
|
79
|
+
6. **Levels.** For a film with no voice these are starting levels for the example style, rather than universal overrides of `reference/sound-design.md` and the narrated range in `reference/beat-sync.md`:
|
|
80
80
|
|
|
81
81
|
| What | `volume` |
|
|
82
82
|
|---|---|
|
|
@@ -85,7 +85,7 @@ With no voice the sound is half of the film. Plan it as you plan the picture.
|
|
|
85
85
|
| Impacts and drops on a scene change | 0.5 to 0.6 |
|
|
86
86
|
| Swells: whooshes that rise, risers | 0.25 to 0.35 |
|
|
87
87
|
|
|
88
|
-
Every pulled sound is levelled on the way in (the interface effects got a gain of 0.7 to 0.8), and `reelkit render` then masters the whole film to -14 LUFS, so only the balance between these matters. At 0.2 to 0.3 an effect sits 6 dB or more under the music, which the tester of 0.8.0 found too quiet to register against the picture; a swell above about 0.35 hides the impact that ends it (the impact no longer rises out of what came before, and the report counts a change with no hit: on a test film, whooshes at 0.2 left 5 of 6 changes with a hit and at 0.35 or more only 2 of 6). Read the report
|
|
88
|
+
Every pulled sound is levelled on the way in (the interface effects got a gain of 0.7 to 0.8), and `reelkit render` then masters the whole film to -14 LUFS, so only the balance between these matters. At 0.2 to 0.3 an effect sits 6 dB or more under the music, which the tester of 0.8.0 found too quiet to register against the picture; a swell above about 0.35 hides the impact that ends it (the impact no longer rises out of what came before, and the report counts a change with no hit: on a test film, whooshes at 0.2 left 5 of 6 changes with a hit and at 0.35 or more only 2 of 6). Read the report and audition the mix when possible; change levels for an audible balance or timing problem, not merely to increase a measured count.
|
|
89
89
|
- **Which sounds swell.** The library's own "UI" pack (`sfx-ui-soft-whoosh`, `sfx-ui-fast-whip`) is made of short bursts that start at full level and fall away: they are hits to a listener and to the report, not swells. A swell that carries rises for half a second or more and cuts off on the change. Search for these words: `reelkit assets search "reverse whoosh" --kind sfx` (the reverse whooshes of the Quantum Motion pack, 1.7 to 2.3 seconds, with energy between 2 and 10 kHz), `"whoosh sweep"` and `"wind sweep"` for longer air, and `"riser building up"` or `"riser tension"` for a lead into a reveal. Their length is at the end of the search line: give it to `cueBefore` or `cuesOnChanges` (`whoosh: { frames }`), minus the tail after the peak. Measured on a test film, seven reverse whooshes at 0.2 gave six swells where they stand, while the film's UI whooshes gave three at the same places.
|
|
90
90
|
7. **Silence.** Before the biggest moment, drop the effects, or the music, for a beat or two. The hit that follows then lands. Give `Music` a `dips` entry for the rest, in absolute frames: `dips={[{ from: reveal.startFrame - 24, to: reveal.startFrame, volume: 0.05 }]}` brings the track down for the last moments before the reveal and back up after it.
|
|
91
91
|
|
|
@@ -93,7 +93,7 @@ Place all the cues once, outside the scenes, with `SoundCues`; use `cuesOnBeats`
|
|
|
93
93
|
|
|
94
94
|
```tsx
|
|
95
95
|
import React from "react";
|
|
96
|
-
import { AbsoluteFill } from "
|
|
96
|
+
import { AbsoluteFill } from "reelkit/frame";
|
|
97
97
|
import { Music, SceneFrame, SoundCues, cueBefore, cuesOnBeats, cuesOnChanges } from "reelkit/kit";
|
|
98
98
|
import type { VideoProps } from "reelkit/kit";
|
|
99
99
|
|
|
@@ -188,3 +188,7 @@ The same numbers are in the render's `data.sound`. A measurement that cannot be
|
|
|
188
188
|
## Check before you show it
|
|
189
189
|
|
|
190
190
|
`reelkit preview` shows two frames per scene and prints a continuity line and a beat line (how many scene changes carry something across and land on the beat). It prints no rhythm line: the rhythm of the scene lengths is `reelkit plan check`'s. Look for a shot that holds still for long (the films were still for 11 to 35 percent of the time and no more), a shot whose type is over the object, and a second accent colour. Then show the user the frames, as in the main steps.
|
|
191
|
+
|
|
192
|
+
## Brand reveals and transformations
|
|
193
|
+
|
|
194
|
+
For a brand-led shot, consult `reference/brand-motion.md`. Choose `BrandTransform3D` turn, arc or launch by the idea it connects; use the supplied identity, finish in a readable neutral pose, and place the sweep and lock from `brandTransformFrames` with `cuesFor(..., "transform")`. Several 3D shots are appropriate for a requested brand film when they each have a different purpose. Map the `transform-sweep` and `transform-lock` roles to the chosen whoosh and impact files. Treat the sound report as evidence to investigate, not a quota to fill with extra hits. Existing approval to edit or render carries through to the requested revision.
|
|
@@ -5,6 +5,8 @@ description: Use when deciding how a scene looks and moves - layout, typography,
|
|
|
5
5
|
|
|
6
6
|
# Motion design guidelines
|
|
7
7
|
|
|
8
|
+
Use these as starting craft choices, not a universal style. The selected look, source material and user direction decide the treatment; `reference/style-recipes.md` translates all supported style families into action, sound and review evidence. Engine constraints, factual source identity and actual speech timing remain requirements across looks.
|
|
9
|
+
|
|
8
10
|
## The user's uploads
|
|
9
11
|
`assets/index.json` lists the user's own files with a description of each. Ask for a logo as an SVG where the user has one: its edges stay sharp at any size, while a PNG softens when scaled up. Show each one only in the scenes whose userAssetKeys include it, sized and framed for what it is: a logo small and clean on a plain area; a screenshot framed in a device or browser mockup (search the library with `reelkit assets search "phone mockup" --kind component`, then `reelkit assets pull <id>`, which puts it in `src/`; if none fits, build a simple rounded framed card); a product photo large, with KenBurnsImage or a rounded card. Never stretch a logo, never crop a screenshot's important part, and never invent a screen when a real one was supplied.
|
|
10
12
|
|
|
@@ -32,28 +34,28 @@ description: Use when deciding how a scene looks and moves - layout, typography,
|
|
|
32
34
|
- Reveal Latin text with a masked rise (translate up from behind an overflow-hidden box), word by word, about 2 frames apart. Avoid plain opacity fades for headlines. Hebrew never uses a mask: its words enter whole (see `reference/hebrew-rtl.md`).
|
|
33
35
|
|
|
34
36
|
## Motion
|
|
35
|
-
- **Springs
|
|
36
|
-
-
|
|
37
|
+
- **Match the motion to the material.** Springs suit responsive UI and weighty arrivals; restrained eased motion suits calm or premium shots. Bounce, squash and overshoot suit playful scenes when deliberate. Useful spring starting points (stiffness / damping): snappy UI 320 / 30, containers 170 / 26, heavy type and logos 120 / 24.
|
|
38
|
+
- Use anticipation when it clarifies the move's direction or physical weight; a UI state change can respond immediately.
|
|
37
39
|
- Exits are faster than entrances. An entrance takes about 0.1 to 0.25 seconds.
|
|
38
|
-
- Linear motion
|
|
40
|
+
- Linear motion suits steady scrolls or continuous travel; entrances and stops need an intentional easing or spring unless the chosen effect is a hard cut.
|
|
39
41
|
- **The camera is a group.** Put the whole scene inside one wrapper and move that: a slow push of 2 to 4 percent across a shot, on a softer spring than the content. Never scale text up by enlarging a container that holds it as an image; set the size so it stays sharp.
|
|
40
|
-
- **
|
|
41
|
-
-
|
|
42
|
-
- **Pace to speech.**
|
|
43
|
-
-
|
|
42
|
+
- **Choose the clock.** Use spoken triggers for narrated meaning and music beats for rhythmic decoration. Do not invent an event to fill every grid step.
|
|
43
|
+
- Stage attention. Stagger a list when each item matters; move related objects together when their shared action explains the idea.
|
|
44
|
+
- **Pace to speech.** Use actual word events for the ideas they name. `wordFrame` gives the word onset and `onWord` starts an entrance so it lands there; do not treat the entrance start as the semantic landing. A deliberate reading hold can span several spoken beats.
|
|
45
|
+
- Make the premise clear early. Change the picture when attention or meaning needs it; a useful pause, close-up or readable hold is not dead time.
|
|
44
46
|
- **Rhythm is hit, hold, build.** A fast move, then a hold of about half a second where nothing new enters, then the next move. Constant motion reads amateur; contrast reads expensive. During a hold, settled elements keep their slow breathe.
|
|
45
|
-
-
|
|
47
|
+
- A held pose can remain still. Add a slow drift only when it supports the look and keeps text sharp; do not force it onto footage or a reading-heavy shot.
|
|
46
48
|
- Let an element finish animating and stay readable for at least 1.5 seconds before it leaves. A label or phrase of more than one word stays at least 1.3 seconds; the closing title or message is held at least 1.5 seconds before the last frame. If the plan's length cannot fit that, lengthen the scene and tell the user.
|
|
47
|
-
- Counters
|
|
49
|
+
- Counters and progress bars land on the event they explain, such as the spoken result or task completion; leave a readable hold afterward.
|
|
48
50
|
- Text that swaps inside a container that is also changing size needs its own exit and enter timing, or old and new text overlap.
|
|
49
51
|
- **Whatever a scene adds, the scene removes.** Every overlay, label and effect leaves when its moment ends. A leftover from an earlier scene is the most common thing a review finds.
|
|
50
|
-
- **Show
|
|
52
|
+
- **Show what is being said.** A visual must clarify the current idea. Reuse a supplied object, picture or clip when continuity or comparison needs it; avoid unrelated repetition used to fill time.
|
|
51
53
|
|
|
52
54
|
## Legibility over images and footage
|
|
53
55
|
- Text over an image or footage needs help: a dim layer of 0.2 to 0.45 on the media, or a solid plate behind the text, plus a soft shadow.
|
|
54
56
|
- In footage mode keep overlays to one graphic at a time, clear of the subject.
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
+
- Use a punch-in on selected emphasis or to improve framing; calm personal speech may need none. Keep the face framed and avoid repeated resets. Do not add a second zoom over footage that already zooms.
|
|
58
|
+
- Add an insert where it clarifies the speech or demonstrates evidence, not merely because a timer elapsed.
|
|
57
59
|
- A punch-in softens 1080 footage. If the user can still choose, suggest filming in 4K when zooms are planned.
|
|
58
60
|
|
|
59
61
|
## Truth on screen
|
|
@@ -62,7 +64,7 @@ description: Use when deciding how a scene looks and moves - layout, typography,
|
|
|
62
64
|
- Do not invent product screens or features. A recreated interface that is not the user's real one is illustrative and should look generic.
|
|
63
65
|
|
|
64
66
|
## Determinism
|
|
65
|
-
- Never use `Math.random()` or the clock. A frame must render the same every time. Use `random(seed)` from
|
|
67
|
+
- Never use `Math.random()` or the clock. A frame must render the same every time. Use `random(seed)` from reelkit/frame for any variation.
|
|
66
68
|
- Everything is a function of `useCurrentFrame()`. No CSS transitions or animations, no timers.
|
|
67
69
|
|
|
68
70
|
## Shape of a 30 second video
|
|
@@ -86,22 +88,24 @@ Hook (first 1.5 s: the boldest visual and claim) → context (one line, one visu
|
|
|
86
88
|
- Compute heavy geometry once, outside the frame function, and only position it per frame.
|
|
87
89
|
- Grain or paper texture is one static layer above everything, outside the camera group. Inside a zooming group it is slow and the grain swells into blotches.
|
|
88
90
|
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
Flat solid backgrounds, opacity-only fades, everything entering at once, rainbow or multi-stop gradients on text and UI, particles and sparkles, glows on interface chrome, emoji as graphics, bouncy easing, gratuitous 3D flips, a centred title on a plain gradient, mixed icon styles, lorem ipsum, and anything that looks like a stock template.
|
|
91
|
+
## Techniques need a purpose
|
|
92
|
+
A flat field, fade, particles, glow, comic bounce or 3D transformation can be right for the chosen idea. Avoid combining them as generic decoration. Keep identity, hierarchy and readability intact. Placeholder copy, false product results and unrelated logos are defects regardless of style. Consult `reference/styles.md` and `reference/brand-motion.md` for techniques that fit the message.
|
|
93
93
|
|
|
94
94
|
## The studio test
|
|
95
|
-
|
|
95
|
+
Review the selected treatment against observable evidence:
|
|
96
96
|
1. There is one clear idea at each moment, and the eye knows where to look.
|
|
97
|
-
2.
|
|
97
|
+
2. Motion starts, lands and holds intentionally, with the timing and weight the material needs.
|
|
98
98
|
3. Nothing is frozen longer than the look allows, and nothing shakes without a reason.
|
|
99
99
|
4. Every word reads at phone size, in the right order, uncut and not touching its neighbour.
|
|
100
100
|
5. Every colour comes from the palette that was agreed; no shade crept in on the way.
|
|
101
|
-
6.
|
|
102
|
-
7.
|
|
101
|
+
6. Departures from the treatment's defaults are intentional and preserve the user's direction.
|
|
102
|
+
7. Source identity, factual content and the requested style survive the motion and final hold.
|
|
103
103
|
|
|
104
104
|
## Check your own frames
|
|
105
|
-
|
|
105
|
+
Preview and fix observable defects; repeat after a real change or unresolved problem. If an approved shot does not fit, make the smallest layout or timing correction and explain it. A substantial change of message or concept needs user direction when it was not already delegated. Use `reference/delivery-review.md` to verify the export.
|
|
106
106
|
|
|
107
107
|
Run `reelkit preview`, then look at both frames of every scene in `out/preview/` (early at 30%, late at 90%) as a harsh director would. Hunt for: text overlapping during a swap, text cut by the frame edge, type too small for a phone, a frame with nothing in it, and anything that looks like a template. Fix what is real, then check again.
|
|
108
|
+
|
|
109
|
+
## Choosing a transformation
|
|
110
|
+
|
|
111
|
+
Change the shot when the idea changes or the same object must take a new role. Name the relationship first: question to answer, parts to whole, product to result, or result to brand. Keep the agreed palette and the actual identity through the change. Use `reference/brand-motion.md` to choose a 2D carry, clear cut or branded 3D arrival and its sound. A deliberate readable hold can remain still; do not add drift or a flip just to meet a motion quota.
|
|
@@ -5,16 +5,16 @@ description: Use when adding sound effects to a video - which moments get a soun
|
|
|
5
5
|
|
|
6
6
|
# Sound design
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Sound gives selected actions weight and shapes the story. Density follows the material: calm speech may need almost no effects; an energetic graphic sequence may use many small cues. Spoken words take priority whenever speech is present.
|
|
9
9
|
|
|
10
10
|
## What gets a sound
|
|
11
11
|
- **Entrances that matter:** the hook's first hit, each numbered point arriving, the payoff. A whoosh, swipe or soft impact.
|
|
12
12
|
- **Scene changes:** a short transition sound across the cut.
|
|
13
13
|
- **Interface moments:** a notification arriving, a button tap, a tick appearing. A click, pop or chime.
|
|
14
14
|
- **Build-ups:** a riser into the payoff or the final call to action.
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
15
|
+
- Choose the important actions rather than sounding every decorative element. A dense interface sequence can use quiet ticks; a personal story can rely on voice and silence.
|
|
16
|
+
- Keep a family of sounds and reserve the strongest hits for the main moments. Whooshes support movement; they should not cover its landing or a spoken word.
|
|
17
|
+
- Use a boom when the reveal needs weight, not at every cut. A deliberate quiet beat can make the next arrival stronger.
|
|
18
18
|
|
|
19
19
|
## Finding sounds
|
|
20
20
|
1. `reelkit assets search "<description>" --kind sfx` with what you want to hear: "whoosh", "soft click", "notification pop", "riser", "camera shutter", "bass impact". Add "one-shot" or "short" to the query for one-shots.
|
|
@@ -23,25 +23,43 @@ A few well-placed sounds make motion feel real. Too many make a video tiring. Th
|
|
|
23
23
|
4. Reuse one whoosh and one click across the video rather than a different sound each time. Consistency sounds designed.
|
|
24
24
|
|
|
25
25
|
## Timing
|
|
26
|
-
-
|
|
26
|
+
- Align the audible peak with the visual landing. A short UI whoosh may need a 2 to 3 frame lead; a reverse swell may need much more. Inspect the actual file's attack and tail rather than using one lead for every sound.
|
|
27
27
|
- Put impacts and clicks on the exact frame the visual hits.
|
|
28
28
|
- Start a riser so that it **ends** on the reveal: `at = revealFrame - durationSec * fps`.
|
|
29
29
|
- Use the word timings in `s.words` when a sound belongs to a spoken word.
|
|
30
30
|
|
|
31
31
|
## Volume
|
|
32
|
-
- The voiceover plays at 1.
|
|
32
|
+
- The voiceover plays at 1. While narration is heard, sound effects stay at 0.3 or below. Without narration, effects can sit between 0.2 and 0.45 and a chosen hook impact can reach 0.6.
|
|
33
33
|
- Ambience and drone beds: 0.06 to 0.12.
|
|
34
|
-
-
|
|
34
|
+
- Overlap only deliberately; avoid summed peaks that clip or mask the speech. Lower competing layers before mastering.
|
|
35
35
|
- When the same kind of sound repeats, grade it: the first at full level, the rest quieter.
|
|
36
36
|
|
|
37
37
|
## Background music
|
|
38
|
-
-
|
|
39
|
-
- `reelkit assets pull <id
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- One track for the whole video. Pick the tempo first: scene changes on a grid of the beat (60 / bpm seconds, or two or four of them) make ordinary cuts feel designed.
|
|
38
|
+
- Choose music from the story's tone and pace; a personal or documentary moment can work with no music. Search by genre, mood and use, usually with English library terms. Decide a fitting track and explain the reason rather than requiring the user to choose a playlist.
|
|
39
|
+
- `reelkit assets pull <id> --music` records the selected track and its beat grid. Place `<Music src={urls[manifest.music.key]} />` once outside the scenes. It applies the measured gain, ducks under speech, loops when needed, and fades at the end. Do not manually repeat the track with `Sfx`.
|
|
40
|
+
- Leave `Music` at its defaults initially; adjust `volume`, `duckTo` or a planned `dips` interval only after listening to the rendered mix. The music should support the brand reveal without covering its lock sound.
|
|
41
|
+
- One track is usually enough for a short film. Pick its tempo before beat-led scene timing, and read `reference/beat-sync.md`. Align the peak with the reveal, allow a rest before it, and give the ending a musical resolution. Under speech prefer instrumental passages; avoid lyrics competing with the message. The current `Music` component loops from the supplied file's start, so trim a derived copy if a different loop section or entry point is needed.
|
|
43
42
|
- Never use the music of a reference or of any video the user points at. Describe its mood and tempo and search the library with that.
|
|
44
43
|
|
|
44
|
+
## Music direction by material
|
|
45
|
+
|
|
46
|
+
| Material | Starting search direction | What to listen for |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Tech demo or energetic explainer | `minimal tech instrumental`, `tech house instrumental`, `glitch hop` | Clear rhythm, room for words, no long empty intro |
|
|
49
|
+
| Tutorial or calm routine | `chillhop instrumental`, `deep house soft`, `light acoustic` | Steady support without a melody fighting the explanation |
|
|
50
|
+
| Premium product or brand | `cinematic minimal`, `dark downtempo`, `luxury deep house` | Restraint and a reveal that earns its weight |
|
|
51
|
+
| Montage or fashion | `fashion house`, `UK garage instrumental`, `nu disco` | Phrases that match changes of action and framing |
|
|
52
|
+
| Personal story | `felt piano`, `documentary acoustic`, or silence | Emotional fit without over-scoring a small moment |
|
|
53
|
+
| Humor or playful graphics | `quirky funk`, `chiptune`, `comedy pizzicato` | Timing that supports the joke without dictating it |
|
|
54
|
+
|
|
55
|
+
These are starting terms, not required genres or BPM ranges. A supplied track takes precedence when the user wants it. Do not infer commercial rights from a song being downloadable or present in an editor; verify a relevant license if the destination requires it.
|
|
56
|
+
|
|
57
|
+
## Phone playback and verification
|
|
58
|
+
|
|
59
|
+
Do not judge music by its sub-bass alone. A track with audible percussion, melodic content or bass harmonics can survive small speakers better than a sub-only bed. Check speech intelligibility and whether the intended music still contributes with reduced bass or actual phone playback. Adjust relative levels and arrangement, not just the final loudness.
|
|
60
|
+
|
|
61
|
+
Verify the finished export for present stems, cue alignment, clipping and truncated tails (`reference/delivery-review.md`). Measurements can locate a problem but cannot prove emotional fit. Do not impose a universal frequency-energy percentage, hit count or volume ratio. If playback is unavailable, report the checks you performed without claiming to have listened.
|
|
62
|
+
|
|
45
63
|
## The interface pack
|
|
46
64
|
The library holds a matched set made for interface motion; search these words with `--kind sfx`: "soft ui whoosh" and "fast whip" for moves, "bubble pop" and "glass tap" for things appearing and being pressed, "keyboard typing" under a typed field, "toggle switch", "message sent", "notification ping", "success chime" on a tick, "sparkle shimmer" on an AI result, "counter ticks" under a number counting up, "soft impact" and "sub bass drop" for the landing and the payoff, "short riser" into a reveal, "camera shutter" on a freeze. Sounds from one set sit together; mix sets only when one is missing what you need.
|
|
47
65
|
|
|
@@ -55,3 +73,7 @@ The library holds a matched set made for interface motion; search these words wi
|
|
|
55
73
|
<Sfx src={urls["assets/lib/<id>/clip.mp3"]} at={12} volume={0.35} />
|
|
56
74
|
```
|
|
57
75
|
Inside a SceneFrame, `at` counts from the start of that scene.
|
|
76
|
+
|
|
77
|
+
## Branded transformations
|
|
78
|
+
|
|
79
|
+
Read `reference/brand-motion.md` when the move reveals a brand, carries an object, or turns the product toward the viewer. Use `brandTransformFrames` and `cuesFor([start, settle], "transform", { offset: scene.startFrame, voice: true, sweepFrames: 10 })` for one sweep and one lock. Adjust the sweep lead to the actual sound file. Keep sounds outside `Scene3D`, and add the scene offset once. Listen to the final video; a high hit count is not a quality target by itself.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: studio-editing
|
|
3
|
+
description: Choose an editing approach from the actual material: footage, screen recordings, graphics, mixed media, pacing, inserts and sound. Read for an open brief or an existing-video edit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Choose the edit from the material
|
|
7
|
+
|
|
8
|
+
Understand the message, audience, intended action, emotional tone and strongest source moments before adding effects. Watch supplied footage when playback is available; otherwise inspect sampled frames, metadata and an accurate transcript and state that limitation. Read the entire transcript in context, including pauses and emphasis. Do not infer spoken words from a few stills.
|
|
9
|
+
|
|
10
|
+
Choose the direction and explain it briefly. Ask about a missing fact, audience or goal only if it changes the edit. A request to improve a particular shot should produce that revision, not a new briefing or an unsolicited replacement concept.
|
|
11
|
+
|
|
12
|
+
## Choose the mode
|
|
13
|
+
|
|
14
|
+
| Material and purpose | Starting approach | What would weaken it |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| Personal or calm talking head | Preserve expression and useful pauses; clean captions; occasional motivated punch-in; quiet music or none | Constant zooms, whooshes and cuts that remove emotional timing |
|
|
17
|
+
| Energetic explanation or opinion | Strong opening claim supported by evidence; emphasis cuts; a few illustrative inserts | Effects that obscure the argument or alter its meaning |
|
|
18
|
+
| Tutorial or screen recording | Real screen, callout on the relevant control, step tracker, readable hold after the action | Camera moves or captions covering the control being taught |
|
|
19
|
+
| Product or premium brand | Supplied identity, consistent type and materials, restrained object motion, purposeful sound | Generic fabricated UI, conflicting styles or perpetual logo spin |
|
|
20
|
+
| Narration carried by graphics | A visual metaphor per idea; word-timed emphasis; continuity through a recurring object, type or accent | Repeating one flat layout or animating every word equally |
|
|
21
|
+
| Fashion, montage or reveal without speech | Cut by action and musical phrasing; minimal text; peak on the reveal | Adding explanatory captions or a narrator without a reason |
|
|
22
|
+
|
|
23
|
+
These are starting points, not templates. Mixed media can change visual worlds at a change of meaning while retaining a thread. A consistent brand system can vary framing, depth and scale without changing its identity.
|
|
24
|
+
|
|
25
|
+
## Build the edit map
|
|
26
|
+
|
|
27
|
+
For a substantial new film, keep a compact table in the project notes: source time or scene, purpose, visible action, spoken trigger or beat, text and sound. Each insert needs a reason: explain a step, demonstrate a claim, reveal the result, or make an abstract idea visible. The first few seconds should make the premise clear; a hook can be a strong image or a question, not necessarily a loud effect. End with an action only when the video's goal calls for one.
|
|
28
|
+
|
|
29
|
+
Use real footage, screens and logos first. Use code for exact type, numbers, diagrams, UI interactions and brand motion. Generate imagery only when an illustrative or filmed subject is missing. Search the shared library before generation, check the allowance with `reelkit whoami`, and use an alternative when the allowance is exhausted or a result cannot be used. Do not repeatedly regenerate an asset to chase minor taste differences.
|
|
30
|
+
|
|
31
|
+
For a new concept, show the essential direction if the user needs to choose it. Earlier approval and an explicit instruction to edit or render remain valid. A routine fix does not restart approval.
|
|
32
|
+
|
|
33
|
+
## Footage in this CLI
|
|
34
|
+
|
|
35
|
+
Reelkit overlays graphics on registered footage; it is not a CapCut draft editor or an automatic transcript-based jump-cut tool. It does not provide a CapCut JSON writer, original-speech transcription import, or an edit-decision-list command. Do not invent those commands or replace someone's recorded speech with generated narration.
|
|
36
|
+
|
|
37
|
+
Register a derived working copy with `reelkit assets upload ./working.mp4 --footage --describe "what the footage shows"`. Preserve the original. The plan then uses `mode: "footage"` and every scene uses `treatment: "footage-overlay"`. The manifest uses the footage's dimensions, capped at 1920 on the long side, and its full duration. Use one `FootageLayer` below the graphics; its `muted` default is true. Set `muted={false}` when the original audio is wanted, and do not duplicate that audio as another track. For existing speech use `voice: "none"` to avoid generating a second voice; that setting means no generated narration, not that the source audio must be silent.
|
|
38
|
+
|
|
39
|
+
If the requested edit needs cuts, normalization or reframing, make a separate derived clip with available local video tools, verify its new source timing, and register that copy. If a needed operation is unavailable, identify the missing capability. Do not install or automate another editor merely because the inspiration skill uses one. Keep media paths stable and the sources reproducible.
|
|
40
|
+
|
|
41
|
+
Original-speech captions need accurate timestamps from the supplied transcript or an available transcription tool authorized to process that recording. The standard manifest's `s.words` comes from generated voiceovers; uploading footage does not populate it. Keep original-speech timings in a separate local source and explicitly implement and validate their use in the composition. Do not hand-edit the generated manifest or use generated narration timings for the speaker. If timings cannot be obtained, complete the feasible edit and report the caption limitation. Music ducking also needs these real speech spans: pass `Music` a `scenes` array of `{ startFrame, words }` using scene-local word seconds, or keep the music conservatively low through the recording. With empty manifest words the default music cannot detect source speech.
|
|
42
|
+
|
|
43
|
+
## Inserts and pacing
|
|
44
|
+
|
|
45
|
+
Prioritize the moments where the viewer needs help. A number pop should show the real number as it is said; a callout should point at the actual control; a step tracker should advance with the step. Avoid unrelated B-roll that merely looks attractive. Align narrated visuals with the actual word onset, not the nearest clip boundary (`reference/voice-sync.md`). Keep captions and inserts clear of faces and controls.
|
|
46
|
+
|
|
47
|
+
Cut dead air, false starts and repeats only when it preserves meaning and cadence. Do not remove all pauses. Use a punch-in for emphasis or reframing, not on every sentence. Do not stack it on a screen recording that already zooms. Reduce travel or lengthen a move if it smears or ghosts; a held frame is valid when the viewer needs to read, compare or feel the moment.
|
|
48
|
+
|
|
49
|
+
When source speed changes, update the entire clock. At speed factor r, source time t maps to output time t/r. For a trimmed segment beginning at source time a and output time b, map t to b + (t-a)/r. Recompute word events, inserts and SFX from the edited timeline; regenerate narration timings if generated narration changed. Choose music phrasing separately rather than stretching the finished mix to repair sync.
|
|
50
|
+
|
|
51
|
+
## Design and sound references
|
|
52
|
+
|
|
53
|
+
Read only what the edit needs: `reference/styles.md` for visual techniques, `reference/motion-design.md` for staging, `reference/brand-motion.md` for transformations, `reference/three-d.md` for depth, `reference/hebrew-rtl.md` for Hebrew, `reference/captions.md` for generated-speech captions, and `reference/sound-design.md` for scoring. These are choices that serve the video, not requirements to use every technique.
|
|
54
|
+
|
|
55
|
+
Useful transformations include a field becoming its result, a sketch resolving into a product, a number joining its chart, or a product turning to expose its relevant face. Use particles, text rings, a comic or a 3D environment only when that metaphor fits the message and chosen style. Keep the identity recognizable after the transformation and give it a readable hold.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# The studio pane
|
|
2
|
+
|
|
3
|
+
The skill folder is also a Claude Code mod: `.claude-plugin/plugin.json` names it, `hooks/hooks.json` names its one hooks module, and Claude Code 2.1.287 or newer loads it from the installed skill folder. Older versions and other agents ignore these files.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| File | What it holds |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `hooks/register.tsx` | The hooks: the `/reelkit-studio` command, the pane's drawing, the refresh after a `reelkit` command or an edit inside a project. The only file that touches the engine (`$`). |
|
|
10
|
+
| `hooks/project.ts` | Reads a project into one `Film` value: `plan.json`, `manifest.json`, `assets/music.json`, `assets/library.json`, `assets/index.json`, `src/*.tsx`, `out/video.mp4`, `out/preview/`. |
|
|
11
|
+
| `hooks/timeline.ts` | Draws the timeline: one SVG for the desktop app, the editor and mobile; rows of character cells for the terminal. |
|
|
12
|
+
| `hooks/player.ts` | Builds `out/studio.html`, the page **Play with timeline** opens. |
|
|
13
|
+
| `types/index.d.ts` | The state the pane keeps (`tab`, `film`, `projects`, `scene`, `component`, `search`). |
|
|
14
|
+
| `tests/studio.test.ts` | Run with `claude plugin test <skill folder>`. |
|
|
15
|
+
|
|
16
|
+
## What it reads and writes
|
|
17
|
+
|
|
18
|
+
- Timings come from `manifest.json`. Before the voice is recorded there is none, so scene lengths are estimated from the plan and the pane marks them `est.`.
|
|
19
|
+
- The filmstrip is cut from `out/preview/NN-<scene>-late.jpg` (or `-early.jpg`) into `out/.studio/<scene>.jpg` with ffmpeg, or `sips` where there is no ffmpeg. No preview frames, no filmstrip: the clips are plain colour.
|
|
20
|
+
- It writes only `out/.studio/` and `out/studio.html`. The plan, the composition and the assets are never written by the pane.
|
|
21
|
+
- The Browser tab runs `reelkit assets search "<query>" --kind <kind> --json` in the project, so it needs the CLI on the PATH and a login, and it counts against the search throttle like any search.
|
|
22
|
+
|
|
23
|
+
## Limits
|
|
24
|
+
|
|
25
|
+
- A pane cannot hold a video or a web page. Playback is the browser page; the pane's timeline shows the selected scene, not a moving playhead.
|
|
26
|
+
- Sound effects have no lane: their timing lives in `src/Video.tsx`, not in a file the pane reads. The Music tab lists the ones pulled.
|
|
27
|
+
- Up to 24 scenes, 24 components and 12 projects are shown.
|
|
28
|
+
|
|
29
|
+
## Changing it
|
|
30
|
+
|
|
31
|
+
Keep every `$` call in `register.tsx`: the engine does not follow `$` into another file, so `project.ts` takes plain functions (`Host`). Draw one string per `Text`. Branch on `e.surface` to know which elements a surface draws (the terminal has no `Svg`, mobile no `Input` or `Select`). After a change run `claude plugin validate` and `claude plugin test` on the skill folder, and `pnpm test` for the drawing and loader tests.
|