motionrender 0.0.0-stage → 0.2.1
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/LICENSE +21 -0
- package/README.md +61 -2
- package/blocks/badge.json +68 -0
- package/blocks/big-stat.json +240 -0
- package/blocks/cta-end.json +283 -0
- package/blocks/feature-list.json +286 -0
- package/blocks/footage.json +43 -0
- package/blocks/fx-background-swap.json +170 -0
- package/blocks/fx-before-after.json +212 -0
- package/blocks/fx-captions.json +34 -0
- package/blocks/fx-chat.json +368 -0
- package/blocks/fx-checklist.json +609 -0
- package/blocks/fx-clone-wall.json +181 -0
- package/blocks/fx-color-pop.json +92 -0
- package/blocks/fx-command-bridge.json +358 -0
- package/blocks/fx-counter-hero.json +206 -0
- package/blocks/fx-cta-card.json +337 -0
- package/blocks/fx-day-to-night.json +174 -0
- package/blocks/fx-duo-title.json +245 -0
- package/blocks/fx-duotone.json +95 -0
- package/blocks/fx-extruded-title.json +309 -0
- package/blocks/fx-gallery.json +239 -0
- package/blocks/fx-glass-cards.json +921 -0
- package/blocks/fx-glitch-title.json +373 -0
- package/blocks/fx-grade-look.json +91 -0
- package/blocks/fx-highlighter.json +53 -0
- package/blocks/fx-icon-orbit.json +2694 -0
- package/blocks/fx-lens-flare.json +325 -0
- package/blocks/fx-letterbox.json +105 -0
- package/blocks/fx-light-leak.json +140 -0
- package/blocks/fx-map-journey.json +443 -0
- package/blocks/fx-neon-outline.json +743 -0
- package/blocks/fx-notifications.json +456 -0
- package/blocks/fx-progress-ring.json +143 -0
- package/blocks/fx-pull-out.json +68 -0
- package/blocks/fx-punch-in.json +81 -0
- package/blocks/fx-rgb-flash.json +166 -0
- package/blocks/fx-shake-hit.json +120 -0
- package/blocks/fx-split-reveal.json +110 -0
- package/blocks/fx-spotlight.json +1383 -0
- package/blocks/fx-stats-split.json +500 -0
- package/blocks/fx-step-tracker.json +528 -0
- package/blocks/fx-sticker-freeze.json +584 -0
- package/blocks/fx-strike-rewrite.json +79 -0
- package/blocks/fx-ticker.json +179 -0
- package/blocks/fx-timeline.json +1287 -0
- package/blocks/fx-tracked-label.json +167 -0
- package/blocks/fx-typewriter-quote.json +164 -0
- package/blocks/handle.json +43 -0
- package/blocks/icon-row.json +404 -0
- package/blocks/image-caption.json +248 -0
- package/blocks/lower-third.json +106 -0
- package/blocks/phone-mockup.json +459 -0
- package/blocks/progress-bar.json +51 -0
- package/blocks/quote.json +347 -0
- package/blocks/section-title.json +240 -0
- package/blocks/split-screen.json +283 -0
- package/blocks/stat-grid.json +315 -0
- package/blocks/steps.json +266 -0
- package/blocks/title-hero.json +287 -0
- package/dist/builder.d.ts +1 -0
- package/dist/builder.js +169 -0
- package/dist/cli.js +9301 -0
- package/dist/fonts/LICENSE-Inter.txt +93 -0
- package/dist/fonts/inter-cyrillic-ext-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-cyrillic-ext-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-cyrillic-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-cyrillic-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-ext-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-greek-ext-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-greek-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-latin-opsz-normal.woff2 +0 -0
- package/dist/fonts/inter-vietnamese-opsz-italic.woff2 +0 -0
- package/dist/fonts/inter-vietnamese-opsz-normal.woff2 +0 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2330 -0
- package/dist/player.d.ts +1 -0
- package/dist/player.js +80 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +140 -0
- package/dist/runtime/canvas-runtime.js +261 -0
- package/dist/runtime/lottie_light_canvas.min.js +1 -0
- package/dist/runtime/text-layout.js +50 -0
- package/dist/sfx/click.wav +0 -0
- package/dist/sfx/ding.wav +0 -0
- package/dist/sfx/pop.wav +0 -0
- package/dist/sfx/riser.wav +0 -0
- package/dist/sfx/thump.wav +0 -0
- package/dist/sfx/tick.wav +0 -0
- package/dist/sfx/whoosh.wav +0 -0
- package/dist/types/packages/ai/src/assets.d.ts +26 -0
- package/dist/types/packages/ai/src/batch.d.ts +19 -0
- package/dist/types/packages/ai/src/compose.d.ts +34 -0
- package/dist/types/packages/ai/src/history.d.ts +37 -0
- package/dist/types/packages/ai/src/image.d.ts +19 -0
- package/dist/types/packages/ai/src/index.d.ts +13 -0
- package/dist/types/packages/ai/src/json.d.ts +2 -0
- package/dist/types/packages/ai/src/narrate.d.ts +63 -0
- package/dist/types/packages/ai/src/patch.d.ts +15 -0
- package/dist/types/packages/ai/src/project.d.ts +27 -0
- package/dist/types/packages/ai/src/prompt.d.ts +30 -0
- package/dist/types/packages/ai/src/providers.d.ts +109 -0
- package/dist/types/packages/ai/src/template.d.ts +80 -0
- package/dist/types/packages/ai/src/voiceover.d.ts +49 -0
- package/dist/types/packages/animation/src/index.d.ts +27 -0
- package/dist/types/packages/assets/src/cache.d.ts +26 -0
- package/dist/types/packages/assets/src/index.d.ts +8 -0
- package/dist/types/packages/builder/src/index.d.ts +270 -0
- package/dist/types/packages/cli/src/ai-studio-page.d.ts +1 -0
- package/dist/types/packages/cli/src/ai-studio.d.ts +35 -0
- package/dist/types/packages/cli/src/ai.d.ts +3 -0
- package/dist/types/packages/cli/src/args.d.ts +9 -0
- package/dist/types/packages/cli/src/blocks-cli.d.ts +3 -0
- package/dist/types/packages/cli/src/blocks.d.ts +50 -0
- package/dist/types/packages/cli/src/build.d.ts +1 -0
- package/dist/types/packages/cli/src/dev-page.d.ts +1 -0
- package/dist/types/packages/cli/src/dev.d.ts +13 -0
- package/dist/types/packages/cli/src/index.d.ts +2 -0
- package/dist/types/packages/cli/src/init.d.ts +10 -0
- package/dist/types/packages/cli/src/serve.d.ts +2 -0
- package/dist/types/packages/cli/src/studio.d.ts +36 -0
- package/dist/types/packages/cli/src/templates.d.ts +63 -0
- package/dist/types/packages/cli/src/thumbnail.d.ts +20 -0
- package/dist/types/packages/cli/src/track.d.ts +35 -0
- package/dist/types/packages/cli/src/worker.d.ts +13 -0
- package/dist/types/packages/contracts/src/index.d.ts +377 -0
- package/dist/types/packages/core/src/audio.d.ts +14 -0
- package/dist/types/packages/core/src/distributed.d.ts +50 -0
- package/dist/types/packages/core/src/index.d.ts +63 -0
- package/dist/types/packages/core/src/media.d.ts +11 -0
- package/dist/types/packages/core/src/review.d.ts +29 -0
- package/dist/types/packages/ffmpeg/src/index.d.ts +68 -0
- package/dist/types/packages/graphics/src/fonts.d.ts +3 -0
- package/dist/types/packages/graphics/src/index.d.ts +121 -0
- package/dist/types/packages/graphics/src/runtime.d.ts +10 -0
- package/dist/types/packages/jobs/src/env.d.ts +78 -0
- package/dist/types/packages/jobs/src/handlers.d.ts +17 -0
- package/dist/types/packages/jobs/src/index.d.ts +5 -0
- package/dist/types/packages/jobs/src/input.d.ts +18 -0
- package/dist/types/packages/jobs/src/queue.d.ts +70 -0
- package/dist/types/packages/jobs/src/redis.d.ts +42 -0
- package/dist/types/packages/player/src/bundle.d.ts +4 -0
- package/dist/types/packages/player/src/canvas-runtime.d.ts +11 -0
- package/dist/types/packages/player/src/index.d.ts +29 -0
- package/dist/types/packages/react/src/index.d.ts +76 -0
- package/dist/types/packages/renderer/src/index.d.ts +35 -0
- package/dist/types/packages/renderer/src/pool.d.ts +7 -0
- package/dist/types/packages/renderer/src/video.d.ts +9 -0
- package/dist/types/packages/schema/src/captions.d.ts +24 -0
- package/dist/types/packages/schema/src/expression.d.ts +1 -0
- package/dist/types/packages/schema/src/index.d.ts +1213 -0
- package/dist/types/packages/schema/src/variables.d.ts +115 -0
- package/dist/types/packages/storage/src/index.d.ts +78 -0
- package/dist/types/packages/timeline/src/index.d.ts +104 -0
- package/package.json +78 -4
- package/skills/ove/SKILL.md +356 -0
- package/skills/ove-ai-compose/SKILL.md +36 -0
- package/skills/ove-batch-videos/SKILL.md +23 -0
- package/skills/ove-code-video/SKILL.md +68 -0
- package/skills/ove-effects/SKILL.md +65 -0
- package/skills/ove-make-reel/SKILL.md +30 -0
- package/skills/ove-voiceover-captions/SKILL.md +31 -0
- package/studio/assets/index-CzOvWv9w.css +1 -0
- package/studio/assets/index-J_fvKgng.js +11 -0
- package/studio/index.html +16 -0
- package/templates/case-study/composition.json +358 -0
- package/templates/case-study/template.json +8 -0
- package/templates/event-invite/composition.json +245 -0
- package/templates/event-invite/template.json +8 -0
- package/templates/explainer-square/composition.json +1335 -0
- package/templates/explainer-square/template.json +13 -0
- package/templates/keynote-wide/composition.json +1458 -0
- package/templates/keynote-wide/template.json +13 -0
- package/templates/launch-wide/composition.json +1306 -0
- package/templates/launch-wide/template.json +13 -0
- package/templates/product-card/composition.json +196 -0
- package/templates/product-card/data.example.json +5 -0
- package/templates/product-card/template.json +8 -0
- package/templates/product-wide/composition.json +1609 -0
- package/templates/product-wide/template.json +14 -0
- package/templates/quote-card/composition.json +123 -0
- package/templates/quote-card/template.json +8 -0
- package/templates/sale-promo/composition.json +290 -0
- package/templates/sale-promo/template.json +8 -0
- package/templates/showcase-tall/composition.json +1646 -0
- package/templates/showcase-tall/template.json +14 -0
- package/templates/slideshow/composition.json +167 -0
- package/templates/slideshow/template.json +8 -0
- package/templates/social-reel/composition.json +252 -0
- package/templates/social-reel/template.json +8 -0
- package/templates/starter/assets/logo.svg +4 -0
- package/templates/starter/composition.json +84 -0
- package/templates/story-tall/composition.json +1379 -0
- package/templates/story-tall/template.json +13 -0
- package/themes/espresso.json +15 -0
- package/themes/midnight.json +15 -0
- package/themes/neon.json +15 -0
- package/themes/paper.json +15 -0
- package/themes/signal.json +15 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ove-make-reel
|
|
3
|
+
description: Make a short social video (reel, story, promo, product or explainer clip) with Open Video Engine from ready-made blocks and themes, then check, preview and render it. Use when the user wants a vertical or square social video quickly and a custom layout is not needed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Make a short social video from blocks
|
|
7
|
+
|
|
8
|
+
For fields and rules beyond this page, read the main `ove` skill. Everything here is plain JSON in `composition.json`.
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. Pick the shape: `9:16` reel or story, `1:1` square post, `16:9` landscape, `4:5` feed. Read the user's wording for length; short videos run 15 to 30 seconds.
|
|
13
|
+
2. Start from a whole template when one fits, or from blocks:
|
|
14
|
+
- `ove init <dir> --template story-tall` (also `launch-wide`, `explainer-square`, `keynote-wide`, `product-wide`, `showcase-tall`, `social-reel`, `sale-promo`, `quote-card`, `event-invite`, `product-card`, `case-study`, `slideshow`).
|
|
15
|
+
- Or build it: `ove add title-hero <dir>/composition.json --aspect 9:16 --theme neon --set headline="..."`, then `ove add big-stat ...`, `ove add cta-end ...`. `ove blocks` lists every block and its parameters.
|
|
16
|
+
3. Write the real words. Replace sample text with the user's own names, numbers and details with `--set name=value` (or edit the `with` of the placement). Keep headlines to about five words. Do not invent prices, dates or claims the user did not give.
|
|
17
|
+
4. Choose a theme to match the mood: `ove theme midnight|paper|neon|espresso <composition.json>`.
|
|
18
|
+
5. Pictures: `phone-mockup`, `image-caption` and `split-screen` take `--set image=<asset id or relative path>`. Use only files the user has.
|
|
19
|
+
6. Overlays go inside a scene: `ove add lower-third <file> --scene <scene id> --at 20 --set name="..."`; also `badge`, `handle`, `progress-bar`.
|
|
20
|
+
7. Check: `ove validate`, then `ove review <file> --output review.png` and look at the sheet. Fix every error and warning, or say why one stays.
|
|
21
|
+
8. Look at frames: `ove still <file> --frame <n> --output still.png` at the end of each scene's entrance.
|
|
22
|
+
9. Cover image: `ove thumbnail <file> --title "..." --output thumbnail.png`.
|
|
23
|
+
10. Render a draft with `ove render <file> --output draft.mp4 --scale 0.5 --no-motion-blur`, then the final with `ove render <file> --output out.mp4`.
|
|
24
|
+
|
|
25
|
+
## Rules that matter
|
|
26
|
+
|
|
27
|
+
- One idea per scene. The blocks already move (camera push, drifting shapes, soft sound effects); do not stack extra motion on top.
|
|
28
|
+
- Use one theme and one transition style per video.
|
|
29
|
+
- Text over a picture needs contrast; `image-caption` already adds a shade.
|
|
30
|
+
- Silent videos feel unfinished: add narration (see `ove-voiceover-captions`) or a soundtrack with `export.audio`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ove-voiceover-captions
|
|
3
|
+
description: Add a voiceover and word-timed captions to an Open Video Engine video, or caption existing audio, with scenes cut to the speech. Use when the user wants narration, subtitles or captions, or a video timed to its audio.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Voiceover and captions
|
|
7
|
+
|
|
8
|
+
Needs an AI provider for speech and transcription (`ove ai doctor` shows what is configured). The main `ove` skill has the caption layer fields and the "Timing from media" section.
|
|
9
|
+
|
|
10
|
+
## Narrate a video
|
|
11
|
+
|
|
12
|
+
- Generate and add the voiceover: `ove ai narrate --brief "what the video says" --composition video.json`.
|
|
13
|
+
- Use your own script: `ove ai narrate script.txt --composition video.json --voice <name>`.
|
|
14
|
+
- For a video made by `ove ai compose --narration` from a template, each scene gets one spoken line and is as long as its line, so words and pictures change together. Other videos get one script over the whole video.
|
|
15
|
+
- The video gets a loudness target of -16 LUFS unless `export.loudness` is already set.
|
|
16
|
+
|
|
17
|
+
## Caption existing audio
|
|
18
|
+
|
|
19
|
+
`ove ai transcribe voice.wav --composition video.json --start 1.2` makes word timings and adds a captions layer. `--start` is the second the audio begins.
|
|
20
|
+
|
|
21
|
+
## Check the result
|
|
22
|
+
|
|
23
|
+
1. `ove review video.json --output review.png`: look for captions on screen under 0.7 s, text under the captions, and loudness outside -20 to -11 LUFS.
|
|
24
|
+
2. `ove still video.json --frame <n>` at a spoken word to confirm captions and the scene agree.
|
|
25
|
+
3. `ove captions video.json --output captions.srt` exports a subtitle file.
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
|
|
29
|
+
- Captions are drawn on top, in their own scene, so they are not zoomed by a scene camera; keep them `fixed` if you place them yourself in a scene that has a camera.
|
|
30
|
+
- Cut scenes to the speech, not the other way round. Time beats to the words (`media[...]`) instead of typing frame numbers.
|
|
31
|
+
- Read the script back: facts in a brief are not verified by OVE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg: #000;--surface: #0a0a0a;--surface-2: #111;--hover: #1a1a1a;--border: #2e2e2e;--border-strong: #454545;--text: #ededed;--muted: #a1a1a1;--faint: #6b6b6b;--inverse: #000;--blue: #3291ff;--green: #50e3c2;--red: #ff6166;--amber: #f5a623;--radius: 8px;--font: "Geist", "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "Geist Mono", ui-monospace, "SF Mono", Consolas, monospace;color-scheme:dark}:root[data-theme=light]{--bg: #fff;--surface: #fafafa;--surface-2: #f2f2f2;--hover: #ededed;--border: #eaeaea;--border-strong: #c9c9c9;--text: #171717;--muted: #666;--faint: #8f8f8f;--inverse: #fff;--blue: #0070f3;--green: #0a8f6c;--red: #e5484d;--amber: #b86e00;color-scheme:light}*{box-sizing:border-box}html,body,#root{height:100%}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 var(--font);-webkit-font-smoothing:antialiased}a{color:var(--text);text-decoration:none}h1,h2,h3{margin:0;letter-spacing:-.02em;font-weight:600}h1{font-size:28px;line-height:1.2}h2{font-size:18px}h3{font-size:15px}::selection{background:color-mix(in srgb,var(--blue) 35%,transparent)}.shell{height:100%;display:flex;flex-direction:column}.topbar{flex:none;display:flex;align-items:center;gap:8px;height:56px;padding:0 24px;border-bottom:1px solid var(--border);background:var(--bg)}.brand,.navtabs a,.topbar .btn{white-space:nowrap}.brand{display:flex;align-items:center;gap:10px;font-weight:600;letter-spacing:-.02em;margin-right:12px}.brand svg{width:18px;height:18px;fill:var(--text)}.brand .slash{color:var(--border-strong);font-weight:300}.navtabs{display:flex;gap:2px;height:100%}.navtabs a{display:flex;align-items:center;padding:0 12px;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px;font-size:14px}.navtabs a:hover{color:var(--text)}.navtabs a.on{color:var(--text);border-bottom-color:var(--text)}.grow{flex:1}.busy{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;max-width:320px;margin-right:8px}.busy span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.main{flex:1;min-height:0;overflow:auto}.main.fixed{overflow:hidden}.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font:inherit;font-weight:500;cursor:pointer;border-radius:6px;border:1px solid transparent;white-space:nowrap;transition:background .12s,border-color .12s,color .12s}.btn.md{height:36px;padding:0 14px}.btn.sm{height:30px;padding:0 10px;font-size:13px}.btn.lg{height:42px;padding:0 18px;font-size:15px}.btn.primary{background:var(--text);color:var(--inverse)}.btn.primary:hover{background:color-mix(in srgb,var(--text) 85%,var(--bg))}.btn.secondary{background:var(--bg);color:var(--text);border-color:var(--border)}.btn.secondary:hover{background:var(--hover);border-color:var(--border-strong)}.btn.ghost{background:transparent;color:var(--muted)}.btn.ghost:hover{background:var(--hover);color:var(--text)}.btn.danger{background:var(--bg);color:var(--red);border-color:var(--border)}.btn.danger:hover{background:color-mix(in srgb,var(--red) 12%,var(--bg));border-color:var(--red)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn:focus-visible,.input:focus-visible,.tile:focus-visible{outline:2px solid var(--blue);outline-offset:1px}.input,textarea.input,select.input{width:100%;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:8px 12px;font:inherit;transition:border-color .12s}.input:hover{border-color:var(--border-strong)}.input:focus{border-color:var(--text);outline:none}textarea.input{resize:vertical;min-height:84px;line-height:1.5}input[type=color].input{padding:2px;height:36px;width:64px;cursor:pointer}input[type=range]{accent-color:var(--text)}.field{display:block;margin-bottom:18px}.field .label{display:block;font-size:13px;font-weight:500;margin-bottom:6px}.field .hint{display:block;color:var(--muted);font-size:12.5px;margin-top:6px}.check{display:flex;align-items:center;gap:10px;margin-bottom:14px;cursor:pointer}.check input{width:16px;height:16px;accent-color:var(--text)}.spinner{width:14px;height:14px;border:2px solid var(--border-strong);border-top-color:var(--text);border-radius:50%;animation:spin .7s linear infinite;flex:none;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.badge{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:999px;font-size:12px;font-weight:500;border:1px solid var(--border);color:var(--muted)}.badge.blue{color:var(--blue);border-color:color-mix(in srgb,var(--blue) 40%,transparent)}.badge.green{color:var(--green);border-color:color-mix(in srgb,var(--green) 40%,transparent)}.badge.amber{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 40%,transparent)}.badge.red{color:var(--red);border-color:color-mix(in srgb,var(--red) 40%,transparent)}.notice{border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;margin:14px 0;font-size:13.5px;color:var(--muted);background:var(--surface);white-space:pre-wrap}.notice.error{color:var(--red);border-color:color-mix(in srgb,var(--red) 45%,transparent);background:color-mix(in srgb,var(--red) 8%,var(--bg))}.notice.warn{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 45%,transparent);background:color-mix(in srgb,var(--amber) 8%,var(--bg))}.empty{text-align:center;border:1px dashed var(--border-strong);border-radius:12px;padding:72px 24px;color:var(--muted)}.empty h3{color:var(--text);font-size:18px;margin-bottom:8px}.empty .btn{margin-top:16px}.page{max-width:1200px;margin:0 auto;padding:40px 24px 80px}.page.narrow{max-width:720px}.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:28px}.sub{color:var(--muted);margin:6px 0 0}.toolbar{display:flex;gap:10px;margin-bottom:20px}.toolbar .input{max-width:320px}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px}.card{border:1px solid var(--border);border-radius:12px;background:var(--bg);overflow:hidden;display:flex;flex-direction:column;transition:border-color .15s}.card:hover{border-color:var(--border-strong)}.thumb{aspect-ratio:16 / 10;background:var(--surface);display:flex;align-items:center;justify-content:center;cursor:pointer;border-bottom:1px solid var(--border);overflow:hidden}.thumb img{width:100%;height:100%;object-fit:contain;display:block}.thumb .ph{color:var(--faint);font-size:13px}.card-body{padding:14px 16px 6px}.card-body b{display:block;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:-.01em}.meta{color:var(--muted);font-size:13px;margin-top:2px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}.card-foot{display:flex;gap:6px;padding:10px 12px 12px}.section-title{margin:36px 0 14px;font-size:13px;font-weight:500;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:22px}.tile{text-align:left;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);color:var(--text);padding:14px;cursor:pointer;font:inherit;transition:border-color .12s}.tile:hover{border-color:var(--border-strong)}.tile b{display:block;font-weight:600}.tile span{color:var(--muted);font-size:13px}.tile.on{border-color:var(--text);box-shadow:0 0 0 1px var(--text)}.chips{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 22px}.chip{border:1px solid var(--border);background:var(--bg);color:var(--muted);border-radius:999px;padding:4px 12px;font:inherit;font-size:13px;cursor:pointer}.chip:hover{color:var(--text);border-color:var(--border-strong)}.drop{border:1px dashed var(--border-strong);border-radius:var(--radius);padding:22px;text-align:center;color:var(--muted);background:var(--surface)}.drop.over{border-color:var(--text);color:var(--text)}.drop a{color:var(--blue);cursor:pointer}.files{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.files span{border:1px solid var(--border);border-radius:6px;padding:2px 8px;font-size:13px;cursor:pointer}.files span:hover{border-color:var(--red)}.two{display:grid;grid-template-columns:1fr 1fr;gap:14px}details{margin:4px 0 20px}summary{cursor:pointer;color:var(--muted);padding:4px 0}details[open] summary{margin-bottom:14px}.center{max-width:560px;margin:100px auto;text-align:center;padding:0 24px}.center .spinner{width:28px;height:28px;border-width:3px;margin-bottom:22px}.log{text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;font:12.5px/1.6 var(--mono);color:var(--muted);max-height:220px;overflow:auto;white-space:pre-wrap;margin-top:18px}.swatches{display:flex;height:28px;border-radius:6px;overflow:hidden;margin-bottom:8px;border:1px solid var(--border)}.swatches i{flex:1}.kv{display:grid;grid-template-columns:180px 1fr;gap:6px 16px;padding:12px 0;border-bottom:1px solid var(--border)}.kv code{font:13px var(--mono);color:var(--muted);word-break:break-all}.editor{height:100%;display:grid;grid-template-columns:minmax(0,1fr) 400px}.stage{min-width:0;min-height:0;overflow:auto;padding:20px 24px;display:flex;flex-direction:column;gap:14px;background:var(--surface)}.etop{display:flex;align-items:center;gap:10px}.etop .input.title{border-color:transparent;background:transparent;font-weight:600;font-size:16px;width:auto;min-width:240px;padding:4px 8px}.etop .input.title:hover{border-color:var(--border)}.etop .input.title:focus{border-color:var(--text);background:var(--bg)}.saved{color:var(--muted);font-size:13px}.screen{background:#000;border:1px solid var(--border);border-radius:10px;overflow:hidden;display:flex;justify-content:center;align-items:center;min-height:200px}.screen .ove-player{margin:0 auto}.screen canvas{max-height:56vh;width:auto!important;max-width:100%;margin:0 auto}.xport{display:flex;align-items:center;gap:12px}.xport input[type=range]{flex:1}.xport .time{color:var(--muted);font:12.5px var(--mono);min-width:92px;text-align:right}.scenes{display:flex;gap:8px;overflow:auto;padding-bottom:2px}.scenes button{flex:none;display:flex;flex-direction:column;align-items:flex-start;gap:0;border:1px solid var(--border);background:var(--bg);color:var(--text);padding:6px 12px;border-radius:6px;font:inherit;font-size:13px;cursor:pointer}.scenes button:hover{border-color:var(--border-strong)}.scenes small{color:var(--muted)}.side{border-left:1px solid var(--border);background:var(--bg);display:flex;flex-direction:column;min-height:0}.tabs{display:flex;padding:0 12px;border-bottom:1px solid var(--border);flex:none}.tabs button{background:none;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;color:var(--muted);padding:14px 10px;font:inherit;font-size:13.5px;cursor:pointer}.tabs button:hover{color:var(--text)}.tabs button.on{color:var(--text);border-bottom-color:var(--text)}.pane{padding:20px;overflow:auto;flex:1;min-height:0}.pane h2{font-size:15px;margin-bottom:4px}.pane .sub{margin:0 0 18px;font-size:13px}.row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;border-top:1px solid var(--border)}.row small{display:block;color:var(--muted)}.row b{font-weight:500}.themes{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:8px}.theme{text-align:left;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);color:var(--text);padding:8px;font:inherit;cursor:pointer}.theme:hover:not(:disabled){border-color:var(--border-strong)}.theme:disabled{opacity:.45;cursor:not-allowed}.theme b{font-weight:500;font-size:13px}.result{margin-top:18px}.result video,.result img{width:100%;border:1px solid var(--border);border-radius:var(--radius);background:#000;margin-top:10px}.toasts{position:fixed;bottom:24px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;gap:8px;z-index:50;align-items:center}.toast{background:var(--text);color:var(--inverse);padding:10px 16px;border-radius:8px;font-size:14px;box-shadow:0 8px 30px #00000059;max-width:80vw}.toast.error{background:var(--red);color:#fff}.overlay{position:fixed;inset:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:40}.dialog{width:min(420px,92vw);background:var(--bg);border:1px solid var(--border);border-radius:12px;padding:22px;box-shadow:0 20px 60px #00000080}.dialog h3{margin-bottom:14px;font-size:16px;line-height:1.4}.dialog-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:20px}@media(max-width:640px){.brand .slash,.brand span:last-child,.theme .lbl{display:none}.navtabs a{padding:0 8px}.topbar{gap:4px;padding:0 10px}.page-head{flex-direction:column;align-items:flex-start}}@media(max-width:900px){.editor{grid-template-columns:1fr;height:auto}.side{border-left:0;border-top:1px solid var(--border)}.main.fixed{overflow:auto}.topbar{padding:0 14px}.busy{display:none}.two{grid-template-columns:1fr}.page{padding-top:24px}}
|