motionrender 0.2.1 → 0.2.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/dist/cli.js +2634 -528
- package/dist/index.js +46 -1
- package/dist/player.js +13 -13
- package/dist/react.js +704 -9
- package/dist/types/packages/ai/src/agent.d.ts +57 -0
- package/dist/types/packages/ai/src/brand-scraper.d.ts +35 -0
- package/dist/types/packages/ai/src/captions.d.ts +11 -0
- package/dist/types/packages/ai/src/compose.d.ts +2 -0
- package/dist/types/packages/ai/src/edit.d.ts +69 -0
- package/dist/types/packages/ai/src/index.d.ts +8 -1
- package/dist/types/packages/ai/src/plan.d.ts +42 -0
- package/dist/types/packages/ai/src/prompt.d.ts +18 -0
- package/dist/types/packages/ai/src/providers.d.ts +35 -2
- package/dist/types/packages/ai/src/registry.d.ts +81 -0
- package/dist/types/packages/ai/src/retime.d.ts +7 -0
- package/dist/types/packages/ai/src/shorts.d.ts +75 -0
- package/dist/types/packages/cli/src/agent-cli.d.ts +15 -0
- package/dist/types/packages/cli/src/ai-studio-page.d.ts +1 -1
- package/dist/types/packages/cli/src/ai.d.ts +1 -1
- package/dist/types/packages/cli/src/build.d.ts +2 -0
- package/dist/types/packages/cli/src/templates.d.ts +13 -4
- package/dist/types/packages/contracts/src/index.d.ts +12 -12
- package/dist/types/packages/core/src/review.d.ts +24 -0
- package/dist/types/packages/ffmpeg/src/index.d.ts +1 -0
- package/dist/types/packages/jobs/src/queue.d.ts +2 -2
- package/dist/types/packages/jobs/src/redis.d.ts +2 -2
- package/dist/types/packages/react/src/components.d.ts +166 -0
- package/dist/types/packages/react/src/index.d.ts +54 -2
- package/dist/types/packages/react/src/springs.d.ts +25 -0
- package/dist/types/packages/schema/src/captions.d.ts +2 -0
- package/dist/types/packages/schema/src/index.d.ts +66 -66
- package/dist/types/scripts/eval-briefs.d.ts +67 -0
- package/package.json +1 -1
- package/skills/ove/SKILL.md +40 -2
- package/skills/ove-agent/SKILL.md +144 -0
- package/skills/ove-code-video/SKILL.md +17 -9
- package/skills/ove-motion-graphics/SKILL.md +113 -0
- package/skills/ove-react-video/SKILL.md +212 -0
- package/skills/ove-remotion/SKILL.md +122 -0
- package/studio/assets/index-DmZj9wTZ.css +1 -0
- package/studio/assets/index-n3DJI_GV.js +10 -0
- package/studio/index.html +2 -2
- package/templates/case-study/composition.json +25 -10
- package/templates/event-invite/composition.json +12 -2
- package/templates/explainer-square/composition.json +1 -1
- package/templates/keynote-wide/composition.json +2 -2
- package/templates/kinetic-reel/composition.json +73 -0
- package/templates/kinetic-reel/composition.schema.json +9295 -0
- package/templates/kinetic-reel/template.json +17 -0
- package/templates/kinetic-reel/video.bundle.js +72 -0
- package/templates/kinetic-reel/video.tsx +283 -0
- package/templates/product-card/composition.json +7 -2
- package/templates/product-wide/composition.json +1 -1
- package/templates/quote-card/composition.json +6 -1
- package/templates/saas-launch/composition.json +70 -0
- package/templates/saas-launch/composition.schema.json +9295 -0
- package/templates/saas-launch/template.json +16 -0
- package/templates/saas-launch/video.bundle.js +72 -0
- package/templates/saas-launch/video.tsx +217 -0
- package/templates/sale-promo/composition.json +16 -1
- package/templates/showcase-tall/composition.json +4 -4
- package/templates/slideshow/composition.json +1 -1
- package/templates/social-reel/composition.json +19 -4
- package/templates/story-tall/composition.json +1 -1
- package/studio/assets/index-CzOvWv9w.css +0 -1
- package/studio/assets/index-J_fvKgng.js +0 -11
package/skills/ove/SKILL.md
CHANGED
|
@@ -5,10 +5,24 @@ description: Create and edit videos with Open Video Engine (OVE) by writing a JS
|
|
|
5
5
|
|
|
6
6
|
# Making videos with Open Video Engine
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This is the entry-point skill for OVE: start here, choose the route below, and load the short task guide that matches the request — `ove-react-video` (high-end React videos with spring physics, glassmorphism and kinetic typography), `ove-code-video` (video written as code, code layers), `ove-make-reel` (social video from blocks), `ove-voiceover-captions`, `ove-batch-videos` and `ove-ai-compose` (AI drafts, refine, history). Come back here for field details.
|
|
9
9
|
|
|
10
10
|
An OVE video is one JSON file, `composition.json`. You never write rendering code: you edit data, check it, look at frames, and render. `composition.schema.json` next to it is the authoritative JSON Schema; read it when unsure about a field.
|
|
11
11
|
|
|
12
|
+
## Choose the route first
|
|
13
|
+
|
|
14
|
+
Before composing anything, decide *how* this video gets made, in one step: run `ove ai capabilities` (machine-readable with `--json`) and pick the route that fits the brief. The template route is the primary path; the composed and agentic routes below it are secondary, for briefs no template fits.
|
|
15
|
+
|
|
16
|
+
- **Template route (primary)** — the brief matches one of the registered templates (promo, slideshow, product card, flash sale…) in kind and aspect. Fastest, cheapest and most consistent: `ove ai compose` fills its text variables from the brief, or `ove init --template <name>` starts an editable project. A `--duration` different from the template's own stretches or trims the resolved composition to fit (scene timing scales proportionally; the result is saved as a plain composition, since the timing is then bespoke), so a length difference is not a reason to leave this route.
|
|
17
|
+
- **JSON route (secondary)** — when no template fits the brief's kind and aspect: `ove ai compose --brief "…"` writes a full composition, or you write `composition.json` by hand from the fields below. Length, layout and motion are all yours; the registry lists every block, effect and sound you can name.
|
|
18
|
+
- **React route (secondary)** — when the brief needs spring physics, interlocking layouts or generated visuals: load `ove-react-video` (or `ove-code-video` for scene logic as code) and use a `type: "react"` layer inside an otherwise ordinary composition.
|
|
19
|
+
- **Batch or narration** — many rows of fields → `ove-batch-videos`; voiceover or captions → `ove-voiceover-captions`.
|
|
20
|
+
- **Raw footage** — a recorded clip to clean up (talking head, demo, vlog) → `ove ai edit` (below): transcribe, cut silences and fillers, caption, and write an edited project. A long recording to split up (podcast, stream, webinar) → `ove ai shorts` (below): one transcription, the strongest runs scored and written as separate vertical reel projects. No brief needed; the clip is the input.
|
|
21
|
+
|
|
22
|
+
If the brief also carries template fields (`--fields metric,value`), it goes to the JSON route: templates take neither batch fields nor data-driven lists. The chosen route is a real routing contract, not a suggestion — the AI planner makes the same decision (`template` vs `json`) before generating, prefers a template whenever its kind and aspect fit the brief (length differences included), and falls back to templates when planning fails. `--no-plan` opts out.
|
|
23
|
+
|
|
24
|
+
The registry the planner reads is the same list you just saw: `ove ai capabilities --json` is the machine-readable menu of every template, theme, block, component, effect and sound, one entry per capability with its kind and name. Third-party agents and skills should compose *on* OVE — read that registry, write a `composition.json`, and use the validate → still → review loop here — rather than re-implementing rendering. Whatever generates the JSON (planner, model, or you), it stays outside the render path: the renderer only ever reads a validated schema-compliant composition.
|
|
25
|
+
|
|
12
26
|
## Loop
|
|
13
27
|
|
|
14
28
|
1. For a new video of more than a few seconds, agree beats, look and storyboard first (see Planning a video). Then edit `composition.json`.
|
|
@@ -17,10 +31,12 @@ An OVE video is one JSON file, `composition.json`. You never write rendering cod
|
|
|
17
31
|
4. `ove review composition.json --output review.png`: fix every error and warning it lists, then look at the contact sheet it writes (20 frames across the video, labelled with frame numbers) as a whole. Does each scene have one clear focus? Does the video keep moving? Do scenes look like one system?
|
|
18
32
|
5. `ove render composition.json --output out.mp4` once the review is clean and the sheet looks right.
|
|
19
33
|
|
|
20
|
-
`ove review` samples a frame every half second and reports, with frame numbers and layer ids: text cut short with "…", running off the frame, under 2% of the frame's short side, overlapping other text or sitting under the captions (when that lasts a second or more); more than 40 words on screen; text on screen too briefly to read its words (about a quarter of a second a word, plus half a second); more than two headline-size texts competing (a headline set one word per line counts once); caption lines on screen under 0.7 s or faster than about 20 characters a second; sounds cut off mid-phrase by the end of their scene or `endFrame`; nearly equal font sizes or more than 8 steps of size; more than 5 text colours; 4 seconds or more where nothing moves; scenes all the same length; three or more transition styles; and sound quieter than -20 LUFS, louder than -11 LUFS or peaking above -1 dBTP. It exits with an error when it finds errors, `--json` prints the findings as JSON, `--every n` samples every n frames, `--sheet-frames n` sets how many frames the sheet shows. It is a check, not a verdict on taste: a clean review still needs your eye on the sheet.
|
|
34
|
+
`ove review` samples a frame every half second and reports, with frame numbers and layer ids: text cut short with "…", running off the frame, under 2% of the frame's short side, overlapping other text or sitting under the captions (when that lasts a second or more); text sitting where a platform's own UI covers the picture (on a 9:16 canvas the bottom 18% and right 11% — Instagram Reels, TikTok and YouTube Shorts all draw their caption, audio and action controls there; a wider tall canvas such as 4:5 or square is letterboxed in the player, so the bands shrink to where the chrome actually lands — flagging any text whose area is more than a quarter inside a band); more than 40 words on screen; text on screen too briefly to read its words (about a quarter of a second a word, plus half a second); more than two headline-size texts competing (a headline set one word per line counts once); caption lines on screen under 0.7 s or faster than about 20 characters a second; sounds cut off mid-phrase by the end of their scene or `endFrame`; nearly equal font sizes or more than 8 steps of size; more than 5 text colours; 4 seconds or more where nothing moves; scenes all the same length; three or more transition styles; and sound quieter than -20 LUFS, louder than -11 LUFS or peaking above -1 dBTP. It exits with an error when it finds errors, `--json` prints the findings as JSON, `--every n` samples every n frames, `--sheet-frames n` sets how many frames the sheet shows. It is a check, not a verdict on taste: a clean review still needs your eye on the sheet.
|
|
21
35
|
|
|
22
36
|
`ove inspect composition.json` prints duration, scene count, variables and assets. A person working alongside you can run `ove dev composition.json` for a live preview that reloads on every save. Its Studio can also edit `composition.json` (layer timing and properties), so re-read the file before changing it rather than relying on an earlier copy. `ove doctor` checks FFmpeg, its encoders and the browser when a render fails for setup reasons. `ove schema` prints the JSON Schema. Every command checks its options: a misspelt or misplaced option stops it with a suggestion, and `--name=value` works as well as `--name value`. Inside the OVE repository itself, run the CLI as `npm run ove -- <command>`; paths are then relative to the repository root.
|
|
23
37
|
|
|
38
|
+
What you leave behind in the project folder, every time: the final `composition.json`, `out.mp4`, the contact sheet (`review.png`), and one still per scene or beat (`still-<frame>.png`). Another agent, a person, or a CI run must be able to audit the video from those files alone — validation output is ephemeral, the artifacts are not. `ove review`'s contact sheet doubles as the storyboard for a first rough build (see Planning a video).
|
|
39
|
+
|
|
24
40
|
## Time
|
|
25
41
|
|
|
26
42
|
- Everything is in integer frames. Seconds × `fps` = frames (2 s at 30 fps = 60).
|
|
@@ -214,10 +230,31 @@ Every audio and video asset is measured when a composition mentions `media`, so
|
|
|
214
230
|
- `src` is a `captions` asset (or a path): an `.srt` or `.vtt` file, or JSON with timed lines (`{ "cues": [{ "text", "start", "end" }] }`) or timed words (`{ "words": [{ "text", "start", "end" }] }`, seconds). Give the layer the same `startFrame` as its voice layer.
|
|
215
231
|
- With word timings the word being said is highlighted (`highlightColor`), words already said use `color`, and words still to come use `upcomingColor`; `mode: "lines"` shows plain lines. Words are grouped into lines at sentence ends, commas and pauses, up to `maxWords`.
|
|
216
232
|
- The line is centred on `x` (with `textAlign: "center"`) with its top at `y`, wrapped to `maxWidth`, on a `background` box with `padding` and `radius`. Style with `fontSize`, `fontFamily`, `fontWeight` and the outline options. `offset` shifts the timing in seconds.
|
|
233
|
+
- On a 9:16 canvas, keep the caption block above the bottom UI band (the bottom 18% is where Instagram/TikTok draw their controls) and inside the side bands: a top around y 77% of the height and a `maxWidth` of about 76% of the width clears both. A 4:5 or square canvas is letterboxed in the player, so the band lands lower and the check accounts for it. `ove review`'s `safe-zone` check flags text that sits in a band.
|
|
217
234
|
- Filler words (um, uh, erm, ah, hmm…) and words said twice in a row are left out of captions by default (`dropFillers: false` keeps them), in the video and in exported subtitles.
|
|
218
235
|
- `emphasis: ["agent", "goal"]` draws those words (any case, punctuation ignored) in `emphasisColor` (default `highlightColor`) once they are said: two or three key words per video, not one per line.
|
|
219
236
|
- `ove captions composition.json --output captions.srt` (or `.vtt`) writes every captions layer as a subtitle file for uploads.
|
|
220
237
|
|
|
238
|
+
## Editing raw footage
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
ove ai edit ./raw/take.mp4 --out reel --max-silence 0.5
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- Turns a raw clip into an edited project: the clip's audio is transcribed with word timings, pauses longer than `--max-silence` seconds (default 0.5) and filler words (um, uh, erm…) plus immediate repeats become a cut list, and the project is written as `composition.json` + `composition.schema.json` + `assets/`. The result is one `video` layer per kept stretch (`trimStart` skips the removed source, the clip's own sound carried through, hard jump cuts between stretches) and a word-timed captions layer above the platform UI band.
|
|
245
|
+
- `--width`/`--height` set the canvas (default 1080×1920, the clip centre-cropped with `objectFit: cover` — the standard landscape-talking-head-to-reel move); `--keep-fillers` leaves the ums in; `--no-captions` skips the captions layer; `--force` writes into a directory that already has files.
|
|
246
|
+
- The output is an ordinary project: review it (`ove review reel/composition.json --output review.png`), tune it (the cut list is visible as the scene boundaries — delete a `clip-N` scene to restore a moment, or re-run with a different `--max-silence`), then render (`ove render reel/composition.json --output out.mp4`). Transcription needs a provider with `transcribe` (`--provider groq`, or any adapter that implements it); everything else is local.
|
|
247
|
+
|
|
248
|
+
## Splitting a long recording into shorts
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
ove ai shorts ./raw/podcast.mp4 --out shorts --count 5 --min 15 --max 60
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- Transcribes the recording **once**, splits it into sentence runs (punctuation or a pause over `--max-silence` seconds ends one), and scores every window of whole sentences with a transparent rubric: a clean ending (2), a hook in the first sentence — question, direct address, number, or words like *best/never/secret/mistake* (2), speech density near 2.5 words a second (0–1), and a length near the 25–45 s sweet spot (0–1). The best `--count` non-overlapping windows are written as `shorts/short-01/`, `short-02/`, … each a full project.
|
|
255
|
+
- Each short gets the same edited-reel shape as `ove ai edit` (silences and fillers tightened inside it, word-timed captions above the platform UI band, 1080×1920 centre-cropped). `--no-cut` keeps each short one continuous stretch; `--no-captions`, `--width/--height/--fps` work as there.
|
|
256
|
+
- The rubric is a lead, not a verdict: the summary prints each short's time range, score and opening line — swap a weak pick by editing its `composition.json`, or re-run with different `--min/--max`. Very long recordings may exceed the transcription provider's upload limit; trim or split the source first.
|
|
257
|
+
|
|
221
258
|
## Media
|
|
222
259
|
|
|
223
260
|
- Declare files in `assets` with an `id`, then reference that id from an image or video layer's `src`. A `src` may also be a path relative to `composition.json` or an `https://` URL.
|
|
@@ -340,6 +377,7 @@ Aim for what a motion designer would hand over, not a slide. Before rendering, l
|
|
|
340
377
|
- **A grid and margins.** Keep content inside 120 px margins at 1920 wide (100 at 1080 wide), align left edges to the same x, and use consistent gaps (multiples of 8). Left-aligned layouts read better for content scenes; save centred layouts for titles and endings. Keep the same layout pattern from scene to scene (for example a numbered label, heading and subheading in the same place).
|
|
341
378
|
- **Fill the frame.** Content should span the width. Small cards floating in the top third look unfinished; make cards larger, use fewer of them, or add a supporting visual on the empty side.
|
|
342
379
|
- **Leave a band for captions.** Keep content above about y 880 when captions sit at the bottom, and put captions in the same place in every scene.
|
|
380
|
+
- **On a vertical canvas, respect the platform's UI bands.** The bottom 18% and the right 11% of a 9:16 frame are where Instagram Reels, TikTok and YouTube Shorts draw their own caption, audio tag and action buttons — text there is hidden in the feed (a 4:5 or square canvas is letterboxed in the player, so the bands shrink; the `safe-zone` review check knows). Keep text out of them, and keep captions above the bottom band.
|
|
343
381
|
- **Depth without clutter.** Backgrounds: a dark gradient `background`, one or two large soft radial glows (a `circle` with a radial fill that fades to transparent), optionally a faint grid (`rgba(255,255,255,0.035)`) and a vignette (a full-frame `rect` with a radial fill from transparent to dark edges). Cards: `rgba(255,255,255,0.04)` fill, a 1–2 px `rgba(255,255,255,0.1)` stroke, radius 24–32, a large soft shadow. Highlight one thing with the accent, not everything.
|
|
344
382
|
- **Icons, not letters.** Draw simple line icons as `path` layers (stroke 4–5, round caps and joins) inside a rounded tile, rather than a letter in a circle.
|
|
345
383
|
- **Kinetic type.** Animate headlines word by word (`split`) rather than as one block, with the `rise` or `blur` preset and a 3–5 frame stagger; keep one split style through a video.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ove-agent
|
|
3
|
+
description: Autonomous AI motion graphics director that generates, compiles, and self-corrects broadcast-quality React video components from a plain-text brief. Supports vertical reel auto-detection, brand pack tokens, visual self-healing review, and multi-provider LLM backends.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `ove agent` — Autonomous Video Agent
|
|
7
|
+
|
|
8
|
+
The `ove agent` command runs an autonomous AI loop that:
|
|
9
|
+
|
|
10
|
+
1. **Generates** a complete `video.tsx` React component from your brief using an LLM provider.
|
|
11
|
+
2. **Compiles** it with esbuild via the `buildReact` helper.
|
|
12
|
+
3. **Self-corrects** on compiler errors (up to 3 total attempts), feeding the error back to the LLM.
|
|
13
|
+
4. **Visual self-healing**: after a successful compile, runs `ove review` on 3 still frames (20%, 50%, 80% of duration) and loops back to the LLM if design errors (text cut, off-frame, overlapping text) are found.
|
|
14
|
+
5. **Renders** the final MP4 with headless Chromium (unless `--no-render` is passed).
|
|
15
|
+
|
|
16
|
+
Auto-detects vertical reel format when the brief contains keywords: `reel`, `short`, `9:16`, `viral`, `tiktok`, `instagram`, `shorts`, `reels`, `vertical`.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
ove agent "<brief>" [dir] [options]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## CLI Options
|
|
25
|
+
|
|
26
|
+
| Option | Description | Default |
|
|
27
|
+
|--------|-------------|---------|
|
|
28
|
+
| `--url <website>` | Ingest brand colors, logo and value propositions from a website URL | None |
|
|
29
|
+
| `--landscape` | Landscape 16:9 video for YouTube/Web (1920×1080) | Off (default: 9:16 reel) |
|
|
30
|
+
| `--duration <sec>` | Length in seconds | `6` |
|
|
31
|
+
| `--fps <number>` | Frames per second | `30` |
|
|
32
|
+
| `--no-render` | Generate and compile React code only; skip MP4 rendering | Off |
|
|
33
|
+
| `--no-plan` | Skip the route planner and always run the React agent loop | Off |
|
|
34
|
+
| `--provider <name>` | AI provider: `nvidia`, `anthropic`, `groq` | Auto-detected |
|
|
35
|
+
| `--model <id>` | Model ID override (passed to the selected provider) | Provider default |
|
|
36
|
+
|
|
37
|
+
## Brand Pack API
|
|
38
|
+
|
|
39
|
+
Pass brand tokens programmatically via the `brand` field in `AgentOptions` to lock the LLM to your design system:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import type { BrandPack } from '@ove/ai';
|
|
43
|
+
|
|
44
|
+
export type BrandColor = {
|
|
45
|
+
primary: string;
|
|
46
|
+
secondary?: string;
|
|
47
|
+
accent?: string;
|
|
48
|
+
background?: string;
|
|
49
|
+
text?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type BrandFont = {
|
|
53
|
+
heading?: string;
|
|
54
|
+
body?: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type BrandPack = {
|
|
58
|
+
colors?: BrandColor;
|
|
59
|
+
fonts?: BrandFont;
|
|
60
|
+
logo?: string; // file path or URL
|
|
61
|
+
name?: string; // brand name to include in copy
|
|
62
|
+
style?: string; // free-text style notes e.g. "minimalist", "playful tech"
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When a brand pack is supplied, the agent appends a **Brand Tokens** section to its system prompt instructing the LLM to use *only* those colors and fonts.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
### 1. Reel Auto-Detection (keyword in brief)
|
|
71
|
+
|
|
72
|
+
The brief contains "TikTok", so the agent auto-selects 9:16 vertical reel format with safe-zone rules:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
ove agent "A viral TikTok promo for our new AI coding assistant — punchy, neon, fast cuts" ./my-reel
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The agent will use 1080×1920, enforce safe zones (top 8%, bottom 18%, right 11%), and require `BentoGrid`, `KineticText`, `GlassCard`, and `AmbientGlow`.
|
|
79
|
+
|
|
80
|
+
### 2. Brand Pack (programmatic API)
|
|
81
|
+
|
|
82
|
+
Wire up brand tokens when calling `runVideoAgent` directly:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { runVideoAgent } from '@ove/ai';
|
|
86
|
+
import { createProvider } from '@ove/ai';
|
|
87
|
+
import { buildReact } from '@ove/cli/build';
|
|
88
|
+
|
|
89
|
+
const provider = createProvider({ provider: 'anthropic' });
|
|
90
|
+
|
|
91
|
+
await runVideoAgent(provider, {
|
|
92
|
+
brief: 'Product launch video for Acme SaaS — showcase the dashboard speed',
|
|
93
|
+
dir: './acme-launch',
|
|
94
|
+
format: 'landscape',
|
|
95
|
+
durationSeconds: 10,
|
|
96
|
+
brand: {
|
|
97
|
+
name: 'Acme',
|
|
98
|
+
colors: {
|
|
99
|
+
primary: '#6366f1',
|
|
100
|
+
secondary: '#8b5cf6',
|
|
101
|
+
accent: '#38bdf8',
|
|
102
|
+
background: '#070a12',
|
|
103
|
+
text: '#f8fafc',
|
|
104
|
+
},
|
|
105
|
+
fonts: { heading: 'Inter', body: 'Inter' },
|
|
106
|
+
style: 'minimalist, modern SaaS, dark mode',
|
|
107
|
+
},
|
|
108
|
+
onProgress: msg => console.log(msg),
|
|
109
|
+
}, buildReact);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 3. Landscape Video (explicit flag)
|
|
113
|
+
|
|
114
|
+
Force landscape 16:9 format regardless of brief content:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
ove agent "Modern SaaS product demo showing 10x speed improvements" ./saas-demo --landscape --duration 12 --fps 30
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
After generation, preview and render manually:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
ove still ./saas-demo/composition.json --allow-code --frame 30 --output preview.png
|
|
124
|
+
ove review ./saas-demo/composition.json --output review.png
|
|
125
|
+
ove render ./saas-demo/composition.json --allow-code --output out.mp4
|
|
126
|
+
ove build ./saas-demo/video.tsx --output ./saas-demo/video.bundle.js
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Valid `ove` Commands Reference
|
|
130
|
+
|
|
131
|
+
The following commands are available in the Open Video Engine CLI:
|
|
132
|
+
|
|
133
|
+
- `ove agent` — Autonomous AI video agent (this skill)
|
|
134
|
+
- `ove render` — Render a composition to MP4/WebM/GIF
|
|
135
|
+
- `ove review` — Sample frames and check for design issues; produces a contact sheet
|
|
136
|
+
- `ove build` — Compile a React video component with esbuild
|
|
137
|
+
- `ove still` — Render a single frame as PNG
|
|
138
|
+
|
|
139
|
+
## Notes
|
|
140
|
+
|
|
141
|
+
- The agent uses up to 3 total attempts across both compile errors and visual review failures.
|
|
142
|
+
- Visual self-healing only runs when `buildHelper` is provided (CLI mode); in standalone API mode it is skipped.
|
|
143
|
+
- The `--no-plan` flag bypasses the route planner and always uses the React code loop.
|
|
144
|
+
- Safe-zone auto-enforcement applies only when the reel format is auto-detected (not when `--landscape` is set explicitly).
|
|
@@ -30,22 +30,30 @@ export default v;
|
|
|
30
30
|
- Layers without an `id` get one (`text-1`); a repeated explicit id is an error. `v.variable`, `v.component`, `v.asset`, `v.export` set the other parts. `use('component', { values }, { x, y })` places a component.
|
|
31
31
|
- Layer constructors: `text rect circle path image clip audio sfx group html lottie shader captions code use`.
|
|
32
32
|
|
|
33
|
-
## 2. React components (
|
|
33
|
+
## 2. React components (see the dedicated `ove-react-video` skill for the full component kit)
|
|
34
34
|
|
|
35
|
-
For Remotion-style videos: components that are pure functions of the frame.
|
|
35
|
+
For Remotion-style videos: components that are pure functions of the frame with spring physics, glassmorphism, and kinetic typography.
|
|
36
36
|
|
|
37
37
|
```tsx
|
|
38
|
-
import { AbsoluteFill,
|
|
38
|
+
import { AbsoluteFill, Sequence, KineticText, GlassCard, AmbientGlow, Audio, useCurrentFrame, useVideoConfig } from 'open-video-engine/react';
|
|
39
39
|
export const config = { id: 'promo', width: 1920, height: 1080, fps: 30, durationInFrames: 270, background: '#0b1020', props: { title: 'Hello' } };
|
|
40
|
-
export
|
|
41
|
-
|
|
40
|
+
export default function Promo({ title }) {
|
|
41
|
+
const frame = useCurrentFrame();
|
|
42
|
+
return (
|
|
43
|
+
<AbsoluteFill style={{ color: '#fff' }}>
|
|
44
|
+
<AmbientGlow />
|
|
45
|
+
<Sequence from={0} durationInFrames={90}>
|
|
46
|
+
<Audio src="sfx:whoosh" />
|
|
47
|
+
<GlassCard><KineticText text={title} /></GlassCard>
|
|
48
|
+
</Sequence>
|
|
49
|
+
</AbsoluteFill>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
42
52
|
```
|
|
43
53
|
|
|
44
54
|
- `ove build promo.tsx` (needs `react`, `react-dom`, `esbuild` installed) writes `composition.json` and `promo.bundle.js`; render with `--allow-code`. Rebuild after every edit.
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
- Pictures: declare each in `config.assets` ({ id, type: 'image', src }) and use `<img src="id">`. Fonts: Inter is built in; add other fonts as font assets.
|
|
48
|
-
- No audio from components: add sound with exported `layers` (`sfx:…`, audio files, captions).
|
|
55
|
+
- Audio and video: `<Audio src="sfx:whoosh" />` and `<Video src="..." />` are automatically scanned and promoted to native audio/video layers.
|
|
56
|
+
- For complete guide, component library, and spring presets, read the **`ove-react-video`** skill.
|
|
49
57
|
|
|
50
58
|
## 3. The code layer: your own drawing every frame (trusted files only)
|
|
51
59
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ove-motion-graphics
|
|
3
|
+
description: Create viral modern motion graphics, bento grids, kinetic typography reels, code editor walk-throughs, and audio waveforms using spring physics and React.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Modern Motion Graphics Guide (`@ove/react`)
|
|
7
|
+
|
|
8
|
+
Open Video Engine provides a motion design toolkit matching top-tier Claude-style motion graphic reels and product release videos.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Design Aesthetics & Visual Foundations
|
|
13
|
+
|
|
14
|
+
- **Canvas Background**: Deep dark tones (`#07080d`, `#0a0b12`, `#090d16`).
|
|
15
|
+
- **Glow & Atmosphere**: Use `<AmbientGlow>` with 2-3 colorful radial orbs (`#6366f1` Indigo, `#a855f7` Purple, `#ec4899` Pink, `#06b6d4` Cyan) with 100px+ blur.
|
|
16
|
+
- **Surface Elevation**: Frosted glassmorphism with `rgba(255, 255, 255, 0.05)`, `backdropFilter: blur(24px)`, and fine 1px border highlight `rgba(255, 255, 255, 0.12)`.
|
|
17
|
+
- **Spring Physics over Linear Easing**: Always animate entrances using `springValue` presets:
|
|
18
|
+
- `'snappy'`: UI cards, bento containers, buttons (stiffness 180, damping 18)
|
|
19
|
+
- `'bouncy'`: Badges, icons, reaction elements (stiffness 150, damping 10)
|
|
20
|
+
- `'smooth'`: Camera moves, counter tickers (stiffness 90, damping 14)
|
|
21
|
+
- `'gentle'`: Background transitions, subtle drifting (stiffness 50, damping 12)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. Motion Component Kit
|
|
26
|
+
|
|
27
|
+
### Bento Grid & Cards
|
|
28
|
+
```tsx
|
|
29
|
+
import { BentoGrid, BentoCard, Badge } from '@ove/react';
|
|
30
|
+
|
|
31
|
+
<BentoGrid columns={3} gap={20}>
|
|
32
|
+
<BentoCard
|
|
33
|
+
colSpan={2}
|
|
34
|
+
title="Real-Time Engine"
|
|
35
|
+
subtitle="Ultra low-latency distributed frame synthesis"
|
|
36
|
+
badge={<Badge dotColor="#10b981">60 FPS</Badge>}
|
|
37
|
+
delay={10}
|
|
38
|
+
>
|
|
39
|
+
<div style={{ height: 120 }}>{/* card content */}</div>
|
|
40
|
+
</BentoCard>
|
|
41
|
+
|
|
42
|
+
<BentoCard title="Metrics" delay={18}>
|
|
43
|
+
<NumberTicker value={99.9} suffix="%" delay={22} decimals={1} />
|
|
44
|
+
</BentoCard>
|
|
45
|
+
</BentoGrid>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Kinetic Typography
|
|
49
|
+
```tsx
|
|
50
|
+
import { KineticText } from '@ove/react';
|
|
51
|
+
|
|
52
|
+
// Word-by-word staggered spring reveal:
|
|
53
|
+
<KineticText
|
|
54
|
+
text="BUILD THE FUTURE OF VIDEO"
|
|
55
|
+
delay={5}
|
|
56
|
+
staggerDelay={4}
|
|
57
|
+
preset="bouncy"
|
|
58
|
+
style={{ fontSize: 64, fontWeight: 900, color: '#fff' }}
|
|
59
|
+
/>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Typewriter Effect
|
|
63
|
+
```tsx
|
|
64
|
+
import { Typewriter } from '@ove/react';
|
|
65
|
+
|
|
66
|
+
<Typewriter
|
|
67
|
+
text="mr agent --prompt 'Build an AI video'"
|
|
68
|
+
delay={15}
|
|
69
|
+
speed={0.8}
|
|
70
|
+
style={{ fontSize: 24, color: '#38bdf8' }}
|
|
71
|
+
/>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Dynamic Audio Waveform
|
|
75
|
+
```tsx
|
|
76
|
+
import { Waveform } from '@ove/react';
|
|
77
|
+
|
|
78
|
+
<Waveform bars={32} height={60} color="#6366f1" activeColor="#ec4899" speed={0.15} />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Code Editor Window
|
|
82
|
+
```tsx
|
|
83
|
+
import { CodeEditor } from '@ove/react';
|
|
84
|
+
|
|
85
|
+
<CodeEditor
|
|
86
|
+
filename="pipeline.ts"
|
|
87
|
+
code={`export const render = async () => {\n const engine = new VideoEngine();\n await engine.generate();\n};`}
|
|
88
|
+
highlightLines={[2]}
|
|
89
|
+
delay={10}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 3. Viral Reel Structure (9:16 Vertical, 1080x1920)
|
|
96
|
+
|
|
97
|
+
1. **Hook (0-2s / frames 0-60)**:
|
|
98
|
+
- High-energy kinetic headline with `<KineticText>`.
|
|
99
|
+
- Vibrant ambient glow with `<AmbientGlow>`.
|
|
100
|
+
- Status pill with `<Badge dot>NEW RELEASE</Badge>`.
|
|
101
|
+
2. **Value & Feature Showcase (2-5s / frames 60-150)**:
|
|
102
|
+
- Bento box layout (`<BentoGrid>` + `<BentoCard>`) or mock UI window (`<DeviceFrame>` or `<CodeEditor>`).
|
|
103
|
+
- Dynamic metric counters (`<NumberTicker>`) or interactive visualizer (`<Waveform>`).
|
|
104
|
+
3. **Call-to-Action (5-7s / frames 150-210)**:
|
|
105
|
+
- Centered payoff with glowing brand badge, website URL, and glowing CTA button.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 4. Commands
|
|
110
|
+
|
|
111
|
+
- `ove review video.tsx --output review.png`
|
|
112
|
+
- `ove render video.tsx --output reel.mp4`
|
|
113
|
+
- `ove agent --prompt "Build a kinetic typography reel for an AI launch"`
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ove-react-video
|
|
3
|
+
description: Design and build high-end motion graphics videos using React, TypeScript (TSX), Flexbox, spring physics, and @ove/react components. Use whenever the user wants to build a video with React, improve design quality, or create SaaS launch reels, kinetic typography, bento grids, or UI explainers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Designing Videos with React (`@ove/react`)
|
|
7
|
+
|
|
8
|
+
Open Video Engine lets you build complete, broadcast-quality motion graphics videos as pure React components.
|
|
9
|
+
Instead of computing manual pixel coordinates in JSON, you write modern **TSX with Flexbox, CSS Grid, spring physics, glassmorphism, and live media**.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Quick Starter (`video.tsx`)
|
|
14
|
+
|
|
15
|
+
Every React video is a default export component that accepts `props`, accompanied by an exported `config`:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import {
|
|
19
|
+
AbsoluteFill,
|
|
20
|
+
Sequence,
|
|
21
|
+
useCurrentFrame,
|
|
22
|
+
useVideoConfig,
|
|
23
|
+
springValue,
|
|
24
|
+
KineticText,
|
|
25
|
+
GlassCard,
|
|
26
|
+
Badge,
|
|
27
|
+
NumberTicker,
|
|
28
|
+
AmbientGlow,
|
|
29
|
+
Audio
|
|
30
|
+
} from 'open-video-engine/react';
|
|
31
|
+
|
|
32
|
+
export const config = {
|
|
33
|
+
id: 'saas-launch',
|
|
34
|
+
width: 1920,
|
|
35
|
+
height: 1080,
|
|
36
|
+
fps: 30,
|
|
37
|
+
durationInFrames: 180, // 6 seconds at 30 fps
|
|
38
|
+
background: '#090d16',
|
|
39
|
+
props: {
|
|
40
|
+
title: 'The Future of Video Production',
|
|
41
|
+
stat: 99.9,
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default function Video({ title, stat }: typeof config.props) {
|
|
46
|
+
const frame = useCurrentFrame();
|
|
47
|
+
const { fps, width, height } = useVideoConfig();
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<AbsoluteFill style={{ color: '#fff', fontFamily: 'Inter, system-ui, sans-serif' }}>
|
|
51
|
+
{/* 1. Atmospheric Ambient Lighting */}
|
|
52
|
+
<AmbientGlow
|
|
53
|
+
orbs={[
|
|
54
|
+
{ x: '25%', y: '20%', size: 700, color: '#6366f1', opacity: 0.28 },
|
|
55
|
+
{ x: '80%', y: '80%', size: 800, color: '#ec4899', opacity: 0.22 },
|
|
56
|
+
]}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
{/* 2. Scene 1: Kinetic Headline (Frames 0 to 90) */}
|
|
60
|
+
<Sequence from={0} durationInFrames={90}>
|
|
61
|
+
<Audio src="sfx:whoosh" volume={0.5} />
|
|
62
|
+
<AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center', gap: 24, padding: 80 }}>
|
|
63
|
+
<Badge dotColor="#38bdf8" delay={4}>NEXT GEN ENGINE</Badge>
|
|
64
|
+
<h1 style={{ fontSize: 84, fontWeight: 800, letterSpacing: '-0.04em', margin: 0, textAlign: 'center' }}>
|
|
65
|
+
<KineticText text={title} delay={8} preset="bouncy" />
|
|
66
|
+
</h1>
|
|
67
|
+
</AbsoluteFill>
|
|
68
|
+
</Sequence>
|
|
69
|
+
|
|
70
|
+
{/* 3. Scene 2: Glassmorphic Metric Card (Frames 90 to 180) */}
|
|
71
|
+
<Sequence from={90} durationInFrames={90}>
|
|
72
|
+
<Audio src="sfx:ding" volume={0.6} />
|
|
73
|
+
<AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center' }}>
|
|
74
|
+
<GlassCard delay={6} style={{ width: 560, display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
75
|
+
<span style={{ fontSize: 18, color: '#94a3b8', fontWeight: 600 }}>SYSTEM ACCURACY</span>
|
|
76
|
+
<div style={{ fontSize: 92, fontWeight: 900, color: '#38bdf8', letterSpacing: '-0.03em' }}>
|
|
77
|
+
<NumberTicker value={stat} decimals={1} suffix="%" delay={10} preset="smooth" />
|
|
78
|
+
</div>
|
|
79
|
+
<p style={{ margin: 0, color: '#cbd5e1', fontSize: 16, lineHeight: 1.5 }}>
|
|
80
|
+
Deterministic frame-accurate rendering powered by headless Chromium and React.
|
|
81
|
+
</p>
|
|
82
|
+
</GlassCard>
|
|
83
|
+
</AbsoluteFill>
|
|
84
|
+
</Sequence>
|
|
85
|
+
</AbsoluteFill>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 2. Core Build Loop
|
|
93
|
+
|
|
94
|
+
1. **Write or edit** `video.tsx`.
|
|
95
|
+
2. **Build the bundle & composition**:
|
|
96
|
+
```bash
|
|
97
|
+
ove build video.tsx
|
|
98
|
+
```
|
|
99
|
+
* Compiles your React JSX with `esbuild`.
|
|
100
|
+
* Emits `video.bundle.js` and `composition.json`.
|
|
101
|
+
3. **Inspect Still Frames**:
|
|
102
|
+
```bash
|
|
103
|
+
ove still composition.json --frame 45 --output still-45.png
|
|
104
|
+
ove still composition.json --frame 135 --output still-135.png
|
|
105
|
+
```
|
|
106
|
+
4. **Visual Review Sheet** (samples frames across the whole video):
|
|
107
|
+
```bash
|
|
108
|
+
ove review composition.json --output review.png
|
|
109
|
+
```
|
|
110
|
+
5. **Render High-Quality MP4**:
|
|
111
|
+
```bash
|
|
112
|
+
ove render composition.json --allow-code --output out.mp4
|
|
113
|
+
```
|
|
114
|
+
*(Note: React videos execute component code during headless rendering, so `--allow-code` is required).*
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 3. Motion Components Kit Reference
|
|
119
|
+
|
|
120
|
+
Import directly from `open-video-engine/react` (or `@ove/react`):
|
|
121
|
+
|
|
122
|
+
### `<AmbientGlow orbs={[...]} blur={100} />`
|
|
123
|
+
Creates floating, organic gradient light orbs with continuous sine-wave drift in the background.
|
|
124
|
+
* `orbs`: Array of `{ x, y, size, color, opacity, speed, phase }`.
|
|
125
|
+
* Never leaves the canvas looking like a flat black box.
|
|
126
|
+
|
|
127
|
+
### `<GlassCard delay={n} preset="snappy">`
|
|
128
|
+
A frosted glass surface with spring entry:
|
|
129
|
+
* `background: rgba(255, 255, 255, 0.05)`
|
|
130
|
+
* `backdropFilter: blur(24px)`
|
|
131
|
+
* `border: 1px solid rgba(255, 255, 255, 0.12)`
|
|
132
|
+
* `boxShadow: 0 20px 50px rgba(0, 0, 0, 0.4)`
|
|
133
|
+
|
|
134
|
+
### `<KineticText text="..." delay={0} staggerDelay={3} preset="bouncy" />`
|
|
135
|
+
Staggers every word with natural spring physics:
|
|
136
|
+
* `preset`: `'bouncy'` (fun pop), `'snappy'` (modern tech), `'smooth'` (editorial), or `'gentle'`.
|
|
137
|
+
* `wordStyle`: Optional custom styling per word.
|
|
138
|
+
|
|
139
|
+
### `<NumberTicker value={1250} decimals={0} prefix="$" suffix="/mo" delay={10} />`
|
|
140
|
+
Smoothly animates numbers from 0 up to `value` using tabular numerals.
|
|
141
|
+
|
|
142
|
+
### `<Badge dot={true} dotColor="#10b981" delay={4}>`
|
|
143
|
+
SaaS status pill badge for kickers and category labels.
|
|
144
|
+
|
|
145
|
+
### `<DeviceFrame title="Dashboard" url="app.ove.dev" delay={8}>`
|
|
146
|
+
A sleek macOS browser window frame with traffic lights and URL bar.
|
|
147
|
+
|
|
148
|
+
### `<ProgressBar value={0.75} color="#38bdf8" delay={5} />`
|
|
149
|
+
Glowing horizontal progress bar with spring expansion.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 4. Spring Physics & Animation Formulas
|
|
154
|
+
|
|
155
|
+
### `springValue(options)`
|
|
156
|
+
Evaluates spring damping physics directly from `frame`:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
const scale = springValue({ frame, fps, delay: 10, preset: 'bouncy', from: 0.8, to: 1.0 });
|
|
160
|
+
const y = springValue({ frame, fps, delay: 10, preset: 'snappy', from: 40, to: 0 });
|
|
161
|
+
const opacity = springValue({ frame, fps, delay: 10, from: 0, to: 1 });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Preset Guide:**
|
|
165
|
+
* `'bouncy'`: `{ damping: 10, stiffness: 120, mass: 0.8 }` — for titles, badges, and icon pop-ins.
|
|
166
|
+
* `'snappy'`: `{ damping: 18, stiffness: 180, mass: 0.5 }` — for UI cards, device frames, buttons.
|
|
167
|
+
* `'smooth'`: `{ damping: 20, stiffness: 90, mass: 1.0 }` — for charts, progress bars, tickers.
|
|
168
|
+
* `'wobbly'`: `{ damping: 7, stiffness: 85, mass: 1.0 }` — playful overshoot.
|
|
169
|
+
|
|
170
|
+
### `stagger(index, framesPerItem, startDelay)`
|
|
171
|
+
Calculates the starting frame for staggered lists:
|
|
172
|
+
```tsx
|
|
173
|
+
const itemDelay = stagger(index, 4, 15);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 5. Media & Timing in React
|
|
179
|
+
|
|
180
|
+
### Audio & Sound Effects
|
|
181
|
+
Use `<Audio />` anywhere inside a `<Sequence>`. When the sequence starts, the sound plays automatically:
|
|
182
|
+
```tsx
|
|
183
|
+
<Sequence from={0} durationInFrames={60}>
|
|
184
|
+
<Audio src="sfx:whoosh" volume={0.6} />
|
|
185
|
+
{/* visual content */}
|
|
186
|
+
</Sequence>
|
|
187
|
+
```
|
|
188
|
+
Supported sound effect presets: `sfx:whoosh`, `sfx:ding`, `sfx:click`, `sfx:pop`, `sfx:thump`, `sfx:tick`, `sfx:riser`.
|
|
189
|
+
|
|
190
|
+
### Video Footage
|
|
191
|
+
Use `<Video />` to place video clips under or over your components:
|
|
192
|
+
```tsx
|
|
193
|
+
<Video src="assets/background.mp4" layer="back" objectFit="cover" muted loop />
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Pictures & Fonts
|
|
197
|
+
* Place images in `assets/` and declare them in `config.assets`.
|
|
198
|
+
* Use `<Img src="assets/logo.png" />`.
|
|
199
|
+
* Inter font is built in with all weights (300 to 900).
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 6. Pro Design Rules for AI Video Production
|
|
204
|
+
|
|
205
|
+
1. **Always use Flexbox/Grid**: Never calculate absolute pixels like `left: 450px`. Let CSS Flexbox center and space cards cleanly.
|
|
206
|
+
2. **Secondary Motion**: Never let a scene stay 100% still. Combine a fast spring entry (`frame 0-20`) with subtle continuous scale or drift (`interpolate(frame, [0, 90], [1, 1.04])`).
|
|
207
|
+
3. **Typographic Hierarchy**:
|
|
208
|
+
* Kicker / Badge: 14-16px, uppercase, letterSpacing: `0.05em`.
|
|
209
|
+
* Headline: 64-96px, fontWeight: `800` or `900`, letterSpacing: `-0.04em`.
|
|
210
|
+
* Body / Caption: 18-24px, color: `#94a3b8`, lineHeight: `1.6`.
|
|
211
|
+
4. **Pure Function Rule**: Every render MUST be a pure deterministic function of `frame`. Do NOT use `useState`, `setTimeout`, or `Math.random()`. Use `random('seed')` from `open-video-engine/react` for repeatable randomness.
|
|
212
|
+
|