npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@depths/waves

v0.5.0

Published

Type-safe video generation engine for converting JSON IR to rendered videos using Remotion

Readme

@depths/waves (v0.5.0)

@depths/waves is a TypeScript-first library + CLI for rendering videos from a JSON "intermediate representation" (IR) using Remotion.

The intended workflow is:

  1. An LLM (or a human) produces JSON that conforms to a schema (VideoIRSchema).
  2. The IR is validated (schema + semantics + registry contracts).
  3. The IR is rendered to an output video file (MP4 by default) using Remotion.

v0.2.0 introduced a shadcn-like catalog of higher-level "composite" components and a hybrid IR that supports:

  • Segments (recommended for agents): sequential scenes with optional overlaps ("transitions")
  • Timeline (escape hatch): explicit timed nodes with overlaps allowed

v0.4.0 focuses on unified aesthetics control:

  • Theme tokens: shadcn-ish design tokens (colors, typography, spacing, radii, shadows, motion) declared once at the video level
  • Presets: built-in theme presets for fast, consistent styling
  • Token-only styling: components reference token keys (no hardcoded styling constants in primitives or composites)
  • Visual debugging workflow: waves stills and --debugBounds/--debugLabels to inspect alignment issues without pixel tests

v0.5.0 focuses on robustness and performance:

  • Faster agent loops: deterministic bundle caching (.waves-cache/) so repeated renders don't re-bundle
  • Fail-fast assets: local /assets/... references are checked before expensive renders
  • Deterministic font loading: theme fonts must load successfully or the render is cancelled
  • Stricter transitions: invalid transition types/props are rejected (no silent overlaps)

Table of contents

Concept (end-to-end)

What problem this solves

Remotion is a powerful way to render videos by writing React components. But for "LLM -> video" workflows, you need more than React:

  • A strict authoring contract (so the model can reliably output something valid)
  • Fast, deterministic validation (so failures happen before render time)
  • A component catalog (so the model composes using known building blocks)
  • A CLI (so an agent can drive the entire pipeline from a terminal)

Waves is a thin, explicit layer over Remotion that provides exactly those pieces.

Mental model

Think of Waves as a compiler + runtime:

  1. Author: you (or an agent) author a JSON IR document
  2. Validate: Waves validates schema + semantics + component props
  3. Compile: Waves compiles high-level authoring (segments) into a render-ready timeline
  4. Render: Waves invokes Remotion bundling + rendering to produce an MP4

At render time, Waves is "just React + Remotion". The strictness lives earlier (IR + validation + registry contracts).

Core building blocks

The codebase has a small number of core concepts:

  • Video IR (VideoIRSchema): the JSON document format you author.
  • v0.4.0+ targets version: "3.0" only.
    • You author exactly one of segments[] (recommended) or timeline[] (escape hatch).
  • Component Registry (ComponentRegistry): a map from string type -> React component + Zod props schema + metadata.
    • Only registered components can render.
    • Props are validated with Zod and defaults are applied deterministically.
  • Validator (IRValidator): validates:
    • IR schema (Zod)
    • semantic rules (timing bounds, duration math, transition overlap constraints)
    • registry contracts (type exists, props valid, children allowed, etc.)
  • Compiler (compileToRenderGraph): compiles authored IR into a normalized, timed representation used by rendering.
    • In segments mode: inserts an internal Segment wrapper node for each segment and computes overlaps.
    • In timeline mode: fills missing timing defaults (whole-video / whole-parent).
  • Renderer (WavesEngine): bundles a temporary Remotion project and calls Remotion's renderer.
    • It writes a temporary entrypoint, bundles, selects a composition, and renders media.

How segments + transitions work

Segments are the recommended authoring style for agents because they reduce timing math:

  • Each segment has durationInFrames and a root node.
  • Segment start times are derived by order.
  • Optional overlaps are declared via transitionToNext.

Waves compiles segments into a "render timeline" (a list of timed component nodes). Each segment becomes:

  • a root Segment node (internal; not shown in the LLM catalog)
  • whose child is the authored root node

Why the internal Segment wrapper exists:

  • Overlap transitions are easiest to implement at the segment boundary.
  • The wrapper can apply fade/slide/zoom/clip effects for the first/last frames of a segment.
  • The wrapper receives both the "enter transition" (inferred from the previous segment's transitionToNext) and the "exit transition" (the current segment's transitionToNext).

Overlap math:

  • Let segment i have duration Di.
  • Let overlap Oi (in frames) be theme.motion.durationsInFrames[segments[i].transitionToNext.duration] (only for segments that have a next segment).
  • Then the compiled start time is:
    • start(0) = 0
    • start(i+1) = start(i) + Di - Oi
  • The compiled video end must equal video.durationInFrames.

Validation model

Waves tries to fail early with errors that are usable for an agent:

  1. Schema validation (Zod):
    • ensures the IR has the expected structure (types, required fields, etc.)
  2. Semantic validation:
    • validates segment overlap constraints (overlap cannot exceed either segment)
    • validates that all timed nodes stay within their parent duration
    • validates that the compiled timeline end equals video.durationInFrames
  3. Registry validation:
    • unknown component types fail
    • props fail if they don't match the component's Zod schema
    • children fail if the component metadata forbids children (or requires a certain number)

The validator applies Zod defaults into the IR node objects. This is intentional: it makes render-time props deterministic and reduces "undefined" cases inside components.

Rendering model

Rendering is done by generating a tiny Remotion project on the fly:

  1. Waves validates + compiles the IR to a timed timeline.
  2. Waves writes a temporary entry.tsx that:
    • registers the WavesComposition as the Remotion root
    • embeds the compiled IR as JSON
    • registers built-in components (and optional user --register modules)
  3. Waves calls @remotion/bundler to create a bundle.
  4. Waves calls @remotion/renderer to select the composition and render media.

This means you do not need to maintain a separate Remotion project just to use Waves.

Installation

npm i @depths/waves

Peer dependencies (must be installed by the consumer):

npm i react remotion

Node: see package.json engines (this repo targets Node 22+).

CLI (agent workflow)

Waves ships a waves CLI so a locally running AI agent (or any terminal user) can:

  1. fetch a system prompt + JSON Schemas + catalog
  2. write a starter IR file
  3. validate the IR
  4. render an MP4 from the IR

Install locally (recommended):

npm i -D @depths/waves

Run via the local bin:

npx waves --help

Typical agent loop

For an agent that can execute terminal commands, the recommended flow is:

  1. waves prompt --format json --out waves-prompt.json
  2. Use waves-prompt.json.systemPrompt + waves-prompt.json.schemas + waves-prompt.json.catalog as the authoring contract for the model
  3. Have the model output a single JSON object (Video IR)
  4. Write that JSON to video.v3.json
  5. waves validate --in video.v3.json until it passes
  6. waves render --in video.v3.json --out output.mp4 ...

1) Get the prompt payload (system prompt + schemas + catalog)

Machine-readable payload (recommended for agents):

npx waves prompt --format json --pretty --out ./waves-prompt.json

Human-readable system prompt:

npx waves prompt --format text --out ./waves-system-prompt.txt

Schemas only:

npx waves schema --kind all --pretty --out ./waves-schemas.json

Component catalog (grouped by category):

npx waves catalog
npx waves catalog --format json --pretty --out ./waves-catalog.json

If you register custom components at module import time, include them with repeatable --register:

npx waves prompt --format json --register ./src/register-waves-components.ts
npx waves schema --kind components --register ./src/register-waves-components.ts
npx waves validate --in ./video.v3.json --register ./src/register-waves-components.ts

Important notes on --register:

  • The value must be a Node-loadable module at runtime (typically a .js/.mjs file).
  • If you pass a path, prefer an absolute path or a relative path with ./.
  • A registration module usually calls globalRegistry.register(...) to add custom components before validation/rendering.
  • Re-registering an existing type throws (registry types are unique).

2) Write IR JSON

npx waves write-ir --template basic --pretty --out ./video.v3.json

3) Validate IR JSON

npx waves validate --in ./video.v3.json

Structured validation result:

npx waves validate --in ./video.v3.json --format json

4) Render MP4

npx waves render --in ./video.v3.json --out ./output.mp4 --codec h264 --crf 28 --concurrency 1

If your IR references "/assets/..." paths, pass --publicDir and ensure the files exist at ${publicDir}/assets/...:

npx waves render --in ./video.v3.json --out ./output.mp4 --publicDir ./public

Exit codes

  • 0: success
  • 1: usage error (invalid flags/command)
  • 2: validation failure (invalid JSON or IR validation errors)
  • 3: render failure
  • 4: I/O error (missing/unreadable/unwritable files)
  • 5: internal error (bug)

Command reference

This section documents every command and flag supported by the current CLI implementation (src/cli.ts).

waves --help / waves help

Prints a short help text.

waves --version

Prints the package version (e.g. 0.5.0).

waves prompt

Outputs an "agent-ready" payload that includes:

  • systemPrompt: a full system prompt string
  • schemas.videoIR: JSON Schema for authoring IR (segments mode)
  • schemas.components: a JSON object keyed by component type containing props JSON Schemas + metadata
  • catalog: categories + items (flattened list for easier prompting / UI)

Flags:

  • --format text|json (default text)
  • --maxChars <n> (text format only; truncates the prompt)
  • --pretty (json format only)
  • --out <path> (optional; writes the output to a file in addition to stdout)
  • --register <module> (repeatable)

Examples:

npx waves prompt --format json --pretty --out ./waves-prompt.json
npx waves prompt --format text --maxChars 4000 --out ./waves-system-prompt.txt

waves schema

Outputs JSON Schemas only.

Flags:

  • --kind video-ir|components|all (default all)
  • --pretty
  • --out <path> (optional; writes output to a file in addition to stdout)
  • --register <module> (repeatable; affects --kind components and all)

Examples:

npx waves schema --kind video-ir --pretty --out ./schema.video-ir.json
npx waves schema --kind components --pretty --out ./schema.components.json

waves catalog

Prints the built-in component catalog grouped by category.

Flags:

  • --format text|json (default text)
  • --pretty (json format only)
  • --out <path> (optional; writes output to a file in addition to stdout)
  • --includeInternal (includes internal-only types such as Segment)
  • --register <module> (repeatable; adds additional registered types)

Examples:

npx waves catalog
npx waves catalog --format json --pretty --out ./waves-catalog.json

waves themes

Lists built-in theme presets (or prints the full token object for a preset).

Flags:

  • --format text|json (default text)
  • --id <preset> (optional; when set, prints the preset tokens instead of listing preset ids)
  • --pretty (json format only)
  • --out <path> (optional)

Examples:

npx waves themes
npx waves themes --format json --pretty --out ./waves-themes.json
npx waves themes --id studio-dark --format json --pretty --out ./studio-dark.tokens.json

waves write-ir

Writes a starter IR JSON file (always version: "3.0" segments mode).

Flags:

  • --template minimal|basic (default minimal)
  • --preset <id> (optional; default studio-dark)
  • --themeOverrides <path> (optional; JSON theme override object merged over the preset)
  • --pretty
  • --out <path> (required)

Examples:

npx waves write-ir --template minimal --pretty --out ./video.v3.json
npx waves write-ir --template basic --pretty --out ./examples/basic.v3.json

waves validate

Validates an IR JSON file.

Flags:

  • --in <path> (required)
  • --format text|json (default text)
  • --pretty (json format only)
  • --preset <id> (optional; overrides the IR theme preset id)
  • --themeOverrides <path> (optional; JSON theme override object merged over IR theme overrides)
  • --register <module> (repeatable)

Behavior:

  • text format prints ok to stdout on success, otherwise prints a human-readable list to stderr and exits non-zero.
  • json format prints { "success": true } or { "success": false, "errors": [...] } to stdout.

Examples:

npx waves validate --in ./video.v3.json
npx waves validate --in ./video.v3.json --format json --pretty

waves render

Renders an MP4 from an IR JSON file.

Flags:

  • --in <path> (required)
  • --out <path> (required)
  • --publicDir <path> (optional; required if your IR uses /assets/... paths)
  • --codec h264|h265|vp8|vp9 (optional; default h264)
  • --crf <n> (optional; forwarded to Remotion renderer)
  • --concurrency <n|string> (optional; forwarded to Remotion renderer)
  • --preset <id> (optional; overrides the IR theme preset id)
  • --themeOverrides <path> (optional; JSON theme override object merged over IR theme overrides)
  • --debugBounds (optional; draws debug outlines for every rendered node)
  • --debugLabels (optional; labels debug outlines with type#id)
  • --register <module> (repeatable)
  • --pretty (only affects the formatting of error JSON when render fails)

Examples:

npx waves render --in ./video.v3.json --out ./output.mp4 --codec h264 --crf 28 --concurrency 1
npx waves render --in ./video.v3.json --out ./output.mp4 --publicDir ./public
npx waves render --in ./video.v3.json --out ./output.mp4 --publicDir ./public --debugBounds --debugLabels

waves stills

Renders a set of still images (single frames) from an IR JSON file. This is the recommended way to iterate on alignment and overlays without re-rendering full MP4s.

Flags:

  • --in <path> (required)
  • --outDir <path> (required)
  • --frames <csv> (required; e.g. "0,30,60")
  • --publicDir <path> (optional; required if your IR uses /assets/... paths)
  • --imageFormat png|jpeg|webp (optional; default png)
  • --scale <n> (optional; default 1)
  • --jpegQuality <n> (optional; default 90; only used when --imageFormat jpeg)
  • --preset <id> (optional; overrides the IR theme preset id)
  • --themeOverrides <path> (optional; JSON theme override object merged over IR theme overrides)
  • --debugBounds / --debugLabels (same as waves render)
  • --register <module> (repeatable)

Examples:

npx waves stills --in ./video.v3.json --outDir ./examples/_stills --frames "0,45,90" --publicDir ./public
npx waves stills --in ./video.v3.json --outDir ./examples/_stills --frames "0,45,90" --publicDir ./public --debugBounds --debugLabels

IR v3.0 (authoring contract)

v0.4.0+ targets version: "3.0" only.

Recommended: segments[] (high-level)

In segments mode, you provide sequential segments and Waves compiles them into an explicit timed timeline. You usually do not need to specify timing on nodes.

Key rules:

  • Segment overlap is controlled by transitionToNext.duration (a theme motion token key like "fast", "base", "slow").
  • transitionToNext is only valid when there is a "next" segment (i.e. it is not allowed on the last segment).
  • The total video duration must match the compiled timeline end:
    • video.durationInFrames = sum(segment.durationInFrames) - sum(overlap)
    • where overlap = theme.motion.durationsInFrames[transitionToNext.duration] for each segment that has a next segment (after resolving the theme preset + overrides).

Minimal example:

{
  "version": "3.0",
  "video": { "id": "main", "width": 1920, "height": 1080, "fps": 30, "durationInFrames": 60 },
  "theme": { "preset": "studio-dark" },
  "segments": [
    {
      "id": "scene-1",
      "durationInFrames": 60,
      "root": {
        "id": "root",
        "type": "Scene",
        "props": { "background": { "type": "color", "token": "background" } },
        "children": [{ "id": "t1", "type": "Text", "props": { "content": "Hello" } }]
      }
    }
  ]
}

Supported transitionToNext.type values (segment overlap transitions):

  • FadeTransition
  • SlideTransition (props: { direction: "left"|"right"|"up"|"down", distance?: "enter"|"nudge"|"travel" })
  • ZoomTransition (props: { type: "zoomIn"|"zoomOut" })
  • WipeTransition (props: { direction: "left"|"right"|"up"|"down"|"diagonal", softEdge?: boolean })
  • CircularReveal (props: { direction: "open"|"close", center?: { x: 0..1, y: 0..1 } })

Escape hatch: timeline[] (low-level)

In timeline mode you provide explicit timings. Each node's timing is relative to its parent sequence (nested timing is "local").

Notes:

  • Root timing is optional; if omitted, Waves treats the node as spanning the full video duration.
  • Child timing is optional; if omitted, Waves treats the child as spanning the full parent duration.
{
  "version": "3.0",
  "video": { "id": "main", "width": 1920, "height": 1080, "fps": 30, "durationInFrames": 60 },
  "theme": { "preset": "studio-dark" },
  "timeline": [
    {
      "id": "scene",
      "type": "Scene",
      "timing": { "from": 0, "durationInFrames": 60 },
      "props": { "background": { "type": "color", "token": "background" } }
    }
  ]
}

Component nodes

Nodes are structural (the IR does not hard-code component types):

type ComponentNode = {
  id: string;
  type: string; // must be registered at validate/render time
  props?: Record<string, unknown>;
  timing?: { from: number; durationInFrames: number };
  children?: ComponentNode[];
};

Validation uses the registry to enforce:

  • unknown component types (error)
  • props schemas (Zod validation, defaults applied)
  • whether a component can have children (metadata contract)

Components (primitives + composites)

Waves renders only components that have been explicitly registered in the ComponentRegistry. Each component is defined by:

  • a string type (e.g. "Scene", "TypewriterText")
  • a React component implementation (Remotion primitives + CSS)
  • a Zod props schema (validation + defaults)
  • metadata (kind/category/description/LLM guidance/children contract)

Primitives vs composites

  • Primitives are low-level building blocks (layout, text, media). They are intentionally generic.
  • Composites are higher-level building blocks (shadcn-like) that encode common video patterns: titles, lower thirds, social cards, charts, transitions, etc.

In general:

  • Prefer composites for agent-authored videos (less "design work" for the model).
  • Use primitives when you need precise control or to build new composites.

Categories and children contracts

Each component is categorized (text, layout, media, transition, etc.) to help an agent choose the right tool.

Some components can have nested children in the IR. This is controlled by metadata:

  • acceptsChildren: true|false
  • optional minChildren / maxChildren constraints

If a component does not accept children and the IR provides children, validation fails before rendering.

Internal props: __wavesDurationInFrames

At render time, Waves injects __wavesDurationInFrames into every component. This is the duration of the node's Sequence.

This allows components to implement "in/out" animations without the author hand-computing timings.

This prop is not part of the author-facing props schema and does not appear in the tables below.

Keeping docs in sync

The tables below are generated from the live registry JSON Schemas to reduce drift.

Regenerate after changing component props/metadata:

npm run build
node scripts/generate-readme-components.mjs

Components summary

| Type | Kind | Category | Children | Internal | Description | | - | - | - | - | - | - | | IntroScene | composite | branding | no | no | Branded intro scene (logo + company name + optional tagline) | | LogoReveal | composite | branding | no | no | Logo intro animation (fade/scale/rotate/slide), optionally with a sound effect | | OutroScene | composite | branding | no | no | End screen with logo, message, optional CTA buttons and social handles | | Watermark | composite | branding | no | no | Persistent logo/text watermark in a corner | | AnimatedCounter | composite | data | no | no | Animated numeric counter (spring or linear), optionally with an icon and suffix | | BarChart | composite | data | no | no | Animated bar chart (vertical or horizontal) | | LineGraph | composite | data | no | no | Animated line graph (SVG) with draw/reveal modes | | ProgressBar | composite | data | no | no | Animated progress bar that fills over the component duration | | ProgressRing | composite | data | no | no | Circular progress indicator (SVG) that animates from 0 to percentage over duration | | Image | primitive | image | no | no | Full-frame image with object-fit options | | ImageCollage | composite | image | no | no | Collage of multiple images in a grid/stack/scatter layout with staggered entrances | | ImageReveal | composite | image | no | no | Reveals an image with wipe/expand/iris entrance effects | | ImageSequence | composite | image | no | no | Plays a numbered image sequence (frame-by-frame) | | ImageWithCaption | composite | image | no | no | Image with a caption strip (top/bottom) or overlay caption | | KenBurnsImage | composite | image | no | no | Slow zoom and pan (Ken Burns effect) for a still image | | Box | primitive | layout | yes | no | Flow container for layout and backgrounds (layout-safe) | | CardStack | composite | layout | no | no | Sequential stacked cards (2-5) with flip/slide/fade transitions | | Frame | primitive | layout | yes | no | Absolute-positioned container (x/y placement) | | Grid | primitive | layout | yes | no | Grid layout container with configurable rows/columns | | GridLayout | composite | layout | yes (1..∞) | no | Simple responsive grid layout for child components | | Layer | primitive | layout | yes (1..∞) | no | One overlay layer with explicit zIndex inside Layers | | Layers | primitive | layout | yes (1..∞) | no | Overlay container for stacking children (use Layer for zIndex) | | Scene | primitive | layout | yes | no | Scene container with a background and nested children | | Segment | primitive | layout | yes (1..1) | yes | Internal segment wrapper (used by v2 segments compiler) | | Shape | primitive | layout | no | no | Simple rect/circle shape for UI accents | | SplitScreen | composite | layout | yes (2..2) | no | Two-panel split screen layout | | Stack | primitive | layout | yes | no | Flexbox stack layout (row/column) with gap and alignment | | ThirdLowerBanner | composite | layout | no | no | Broadcast-style lower-third banner with name/title and optional avatar | | Audio | primitive | media | no | no | Plays an audio file with optional trimming and fade in/out | | Video | primitive | media | no | no | Full-frame video with object-fit options | | VideoWithOverlay | composite | media | no | no | Video background with an optional overlay (text/logo/gradient) | | InstagramStory | composite | social | no | no | Instagram story-style layout with profile header, text overlay, and optional sticker | | TikTokCaption | composite | social | no | no | TikTok-style captions with stroke and optional word highlighting | | TwitterCard | composite | social | no | no | Twitter/X post card layout with author header and optional image | | YouTubeThumbnail | composite | social | no | no | YouTube-style thumbnail layout (16:9) with bold title and optional face cutout | | CountUpText | composite | text | no | no | Counts from a start value to an end value with formatting options | | GlitchText | composite | text | no | no | Cyberpunk-style glitch text with RGB split jitter | | KineticTypography | composite | text | no | no | Rhythmic single-word kinetic typography driven by a timing array | | OutlineText | composite | text | no | no | Outlined title text with simple draw/fill animation | | SplitText | composite | text | no | no | Animated text where each word or letter enters with a staggered effect | | SubtitleText | composite | text | no | no | Caption/subtitle box with fade in/out and optional highlighted words | | Text | primitive | text | no | no | Displays animated text with positioning and animation options | | TypewriterText | composite | text | no | no | Character-by-character text reveal with optional blinking cursor | | CircularReveal | composite | transition | yes (1..∞) | no | Circular iris reveal/hide transition wrapper | | FadeTransition | composite | transition | yes (1..∞) | no | Fade in/out wrapper (used for segment transitions and overlays) | | SlideTransition | composite | transition | yes (1..∞) | no | Slide in/out wrapper transition | | WipeTransition | composite | transition | yes (1..∞) | no | Directional wipe reveal/hide wrapper transition | | ZoomTransition | composite | transition | yes (1..∞) | no | Zoom in/out wrapper transition |

Components reference

Category: branding

IntroScene
  • kind: composite
  • category: branding
  • internal: false
  • children: no
  • description: Branded intro scene (logo + company name + optional tagline)
  • llmGuidance: Use as the first segment. Works best at 3-5 seconds. Uses theme tokens (no raw styling). musicTrack can add ambience.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | background | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "background" | | | companyName | string | yes | | minLength=1 | | font | enum("display" | "body" | "mono") | yes | "display" | | | logoSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "xl" | | | logoSrc | string | yes | | minLength=1 | | musicTrack | string | no | | | | nameColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | nameSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "4xl" | | | nameWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | | | tagline | string | no | | | | taglineColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "mutedForeground" | | | taglineSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "xl" | | | taglineWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "semibold" | |

LogoReveal
  • kind: composite
  • category: branding
  • internal: false
  • children: no
  • description: Logo intro animation (fade/scale/rotate/slide), optionally with a sound effect
  • llmGuidance: Use for intros/outros. Keep the logo high-contrast and centered. Uses theme tokens (no raw styling). soundEffect can be a short sting.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | background | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "background" | | | effect | enum("fade" | "scale" | "rotate" | "slide") | yes | "scale" | | | logoSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "xl" | | | logoSrc | string | yes | | minLength=1 | | slideDistance | enum("enter" | "nudge" | "travel") | yes | "travel" | | | soundEffect | string | no | | |

OutroScene
  • kind: composite
  • category: branding
  • internal: false
  • children: no
  • description: End screen with logo, message, optional CTA buttons and social handles
  • llmGuidance: Use as the last segment. Keep CTAs <=3 for clarity. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | background | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "background" | | | ctaBackground | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | | | ctaButtons | array | no | | maxItems=3 | | ctaColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | ctaRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "md" | | | ctaTextSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "lg" | | | ctaTextWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | logoSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "lg" | | | logoSrc | string | yes | | minLength=1 | | message | string | yes | "Thank You" | | | messageColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | messageFont | enum("display" | "body" | "mono") | yes | "display" | | | messageSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "4xl" | | | messageWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | | | socialColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "mutedForeground" | | | socialHandles | array | no | | maxItems=4 | | socialTextSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "md" | | | socialTextWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "semibold" | |

Watermark
  • kind: composite
  • category: branding
  • internal: false
  • children: no
  • description: Persistent logo/text watermark in a corner
  • llmGuidance: Use subtle opacity. bottomRight is standard. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | color | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "mutedForeground" | | | font | enum("display" | "body" | "mono") | yes | "body" | | | opacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "subtle" | | | position | enum("topLeft" | "topRight" | "bottomLeft" | "bottomRight") | yes | "bottomRight" | | | size | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "16" | | | src | string | no | | | | text | string | no | | | | textSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "lg" | | | textWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | type | enum("logo" | "text") | yes | "logo" | |

Category: data

AnimatedCounter
  • kind: composite
  • category: data
  • internal: false
  • children: no
  • description: Animated numeric counter (spring or linear), optionally with an icon and suffix
  • llmGuidance: Use for big stats. animationType="spring" feels natural. suffix for units (%, K, M). Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | animationType | enum("spring" | "linear") | yes | "spring" | | | color | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | font | enum("display" | "body" | "mono") | yes | "display" | | | from | number | yes | 0 | | | icon | string | no | | | | iconSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "2xl" | | | size | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "5xl" | | | suffix | string | no | | | | to | number | yes | 100 | | | weight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | |

BarChart
  • kind: composite
  • category: data
  • internal: false
  • children: no
  • description: Animated bar chart (vertical or horizontal)
  • llmGuidance: Use 2-6 bars. Provide maxValue to lock scale across multiple charts. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | data | array | yes | | minItems=2, maxItems=8 | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "6" | | | gridColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "border" | | | gridOpacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "faint" | | | gridRowSize | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "16" | | | labelColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | labelSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "md" | | | labelWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "semibold" | | | maxValue | number | no | | | | orientation | enum("horizontal" | "vertical") | yes | "vertical" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "24" | | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "sm" | | | showGrid | boolean | yes | false | | | showValues | boolean | yes | true | | | stagger | enum("fast" | "base" | "slow") | yes | "fast" | | | trackColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | | | trackRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "full" | | | valueColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | valueSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "lg" | | | valueWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | |

LineGraph
  • kind: composite
  • category: data
  • internal: false
  • children: no
  • description: Animated line graph (SVG) with draw/reveal modes
  • llmGuidance: Use 5-20 points. animate="draw" traces the line; animate="reveal" wipes it left-to-right. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | animate | enum("draw" | "reveal") | yes | "draw" | | | color | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "primary" | | | data | array | yes | | minItems=2, maxItems=50 | | dotRadius | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "2" | | | fillArea | boolean | yes | false | | | fillOpacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "faint" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "8" | | | showDots | boolean | yes | true | | | strokeWidth | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "1" | |

ProgressBar
  • kind: composite
  • category: data
  • internal: false
  • children: no
  • description: Animated progress bar that fills over the component duration
  • llmGuidance: Use for loading/countdowns. showPercentage=true is helpful for clarity. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | barColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "primary" | | | edgeOffset | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "12" | | | height | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "3" | | | insetX | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "20" | | | label | string | no | | | | labelColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | labelFont | enum("display" | "body" | "mono") | yes | "body" | | | labelSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "md" | | | labelWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | position | enum("top" | "bottom") | yes | "bottom" | | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "full" | | | showPercentage | boolean | yes | true | | | trackColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | |

ProgressRing
  • kind: composite
  • category: data
  • internal: false
  • children: no
  • description: Circular progress indicator (SVG) that animates from 0 to percentage over duration
  • llmGuidance: Use for completion and goals. showLabel displays the percentage. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | color | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "primary" | | | labelColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | labelFont | enum("display" | "body" | "mono") | yes | "display" | | | labelSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "xl" | | | labelWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | | | percentage | number | yes | | min=0, max=100 | | showLabel | boolean | yes | true | | | size | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "lg" | | | strokeWidth | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "5" | | | trackColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | |

Category: image

Image
  • kind: primitive
  • category: image
  • internal: false
  • children: no
  • description: Full-frame image with object-fit options
  • llmGuidance: Use Image for pictures and backgrounds. Use fit="cover" for full-bleed, fit="contain" to avoid cropping.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | borderRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "none" | | | fit | enum("cover" | "contain") | yes | "cover" | | | opacity | number | yes | 1 | min=0, max=1 | | src | string | yes | | minLength=1 |

ImageCollage
  • kind: composite
  • category: image
  • internal: false
  • children: no
  • description: Collage of multiple images in a grid/stack/scatter layout with staggered entrances
  • llmGuidance: Use 2-6 images for best results. layout="grid" is clean; "scatter" is energetic. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | captionBackground | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "background" | | | captionColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | captionFont | enum("display" | "body" | "mono") | yes | "body" | | | captionOpacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "medium" | | | captionPadding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "3" | | | captionSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "md" | | | captionWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | cardHeight | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "xl" | | | cardWidth | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "2xl" | | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "6" | | | images | array | yes | | minItems=2, maxItems=9 | | layout | enum("grid" | "stack" | "scatter") | yes | "grid" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "20" | | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "md" | | | shadow | enum("sm" | "md" | "lg") | yes | "lg" | | | stagger | enum("fast" | "base" | "slow") | yes | "fast" | |

ImageReveal
  • kind: composite
  • category: image
  • internal: false
  • children: no
  • description: Reveals an image with wipe/expand/iris entrance effects
  • llmGuidance: Use wipe for directional reveals, expand for subtle pop-in, iris for circular mask openings.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | direction | enum("left" | "right" | "top" | "bottom" | "center") | yes | "left" | | | revealType | enum("wipe" | "expand" | "iris") | yes | "wipe" | | | src | string | yes | | minLength=1 |

ImageSequence
  • kind: composite
  • category: image
  • internal: false
  • children: no
  • description: Plays a numbered image sequence (frame-by-frame)
  • llmGuidance: Use for exported sprite sequences. basePath can be /assets/seq and filePattern like img_{frame}.png.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | basePath | string | yes | | minLength=1 | | filePattern | string | yes | "frame_{frame}.png" | | | fps | integer | yes | 30 | min=1, max=120 | | frameCount | integer | yes | | max=9007199254740991 |

ImageWithCaption
  • kind: composite
  • category: image
  • internal: false
  • children: no
  • description: Image with a caption strip (top/bottom) or overlay caption
  • llmGuidance: Use overlay for quotes/testimonials over photos. Use bottom for standard captions. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | caption | string | yes | | maxLength=200 | | captionBackground | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | | | captionColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | captionFont | enum("display" | "body" | "mono") | yes | "body" | | | captionPadding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "5" | | | captionPosition | enum("top" | "bottom" | "overlay") | yes | "bottom" | | | captionRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "md" | | | captionSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "xl" | | | captionWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | src | string | yes | | minLength=1 |

KenBurnsImage
  • kind: composite
  • category: image
  • internal: false
  • children: no
  • description: Slow zoom and pan (Ken Burns effect) for a still image
  • llmGuidance: Classic documentary-style motion. mode controls zoom; panDirection adds drift. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | mode | enum("zoomIn" | "zoomOut" | "none") | yes | "zoomIn" | | | panDirection | enum("none" | "left" | "right" | "up" | "down") | yes | "none" | | | panDistance | enum("enter" | "nudge" | "travel") | yes | "nudge" | | | src | string | yes | | minLength=1 |

Category: layout

Box
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes
  • description: Flow container for layout and backgrounds (layout-safe)
  • llmGuidance: Use Box as a container inside Grid/Stack. Box participates in layout flow. For x/y positioning, use Frame.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | backgroundColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | no | | | | borderRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "none" | | | height | number | no | | | | opacity | number | yes | 1 | min=0, max=1 | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | | | width | number | no | | |

CardStack
  • kind: composite
  • category: layout
  • internal: false
  • children: no
  • description: Sequential stacked cards (2-5) with flip/slide/fade transitions
  • llmGuidance: Use for steps/features. displayDuration is frames per card. Uses theme tokens (no raw styling).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | background | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "surface" | | | cards | array | yes | | minItems=2, maxItems=5 | | contentFont | enum("display" | "body" | "mono") | yes | "body" | | | contentOpacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "strong" | | | contentSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "xl" | | | contentWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "bold" | | | displayDuration | integer | yes | 90 | min=30, max=150 | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "16" | | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "lg" | | | shadow | enum("sm" | "md" | "lg") | yes | "lg" | | | textColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "surfaceForeground" | | | titleFont | enum("display" | "body" | "mono") | yes | "display" | | | titleSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "4xl" | | | titleWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | | | transition | enum("flip" | "slide" | "fade") | yes | "flip" | |

Frame
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes
  • description: Absolute-positioned container (x/y placement)
  • llmGuidance: Use Frame for precise pixel placement (x/y). Use Box for normal layout flow inside Grid/Stack.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | backgroundColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | no | | | | borderRadius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "none" | | | height | number | no | | | | opacity | number | yes | 1 | min=0, max=1 | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | | | width | number | no | | | | x | number | yes | 0 | | | y | number | yes | 0 | |

Grid
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes
  • description: Grid layout container with configurable rows/columns
  • llmGuidance: Use Grid for photo collages and dashboards. Provide exactly rows*columns children when possible.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | align | enum("start" | "center" | "end" | "stretch") | yes | "stretch" | | | columns | integer | yes | 2 | min=1, max=12 | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "6" | | | justify | enum("start" | "center" | "end" | "stretch") | yes | "stretch" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | | | rows | integer | yes | 1 | min=1, max=12 |

GridLayout
  • kind: composite
  • category: layout
  • internal: false
  • children: yes (1..∞)
  • description: Simple responsive grid layout for child components
  • llmGuidance: Use for dashboards and collages. 2x2 is a good default for 4 items.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | columns | integer | yes | 2 | min=1, max=4 | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "5" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "10" | | | rows | integer | yes | 2 | min=1, max=4 |

Layer
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes (1..∞)
  • description: One overlay layer with explicit zIndex inside Layers
  • llmGuidance: Use Layer inside Layers to control stacking. Put exactly one child in a Layer (recommended).

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | inset | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | | | opacity | number | yes | 1 | min=0, max=1 | | pointerEvents | enum("none" | "auto") | yes | "none" | | | zIndex | integer | yes | 0 | min=-9007199254740991, max=9007199254740991 |

Layers
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes (1..∞)
  • description: Overlay container for stacking children (use Layer for zIndex)
  • llmGuidance: Use Layers to stack background/content/overlays. Prefer Layer children with explicit zIndex.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | overflow | enum("visible" | "hidden") | yes | "visible" | |

Scene
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes
  • description: Scene container with a background and nested children
  • llmGuidance: Use Scene to define a segment of the video. Scene timings must be sequential with no gaps. Put Text and Audio as children.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | background | oneOf(object | object | object) | yes | | |

Segment
  • kind: primitive
  • category: layout
  • internal: true
  • children: yes (1..1)
  • description: Internal segment wrapper (used by v2 segments compiler)

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | enterTransition | object | no | | additionalProperties=false | | exitTransition | object | no | | additionalProperties=false |

Shape
  • kind: primitive
  • category: layout
  • internal: false
  • children: no
  • description: Simple rect/circle shape for UI accents
  • llmGuidance: Use Shape for lines, badges, and simple UI blocks. Use circle for dots and rings.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | fill | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | height | number | yes | 100 | | | opacity | number | yes | 1 | min=0, max=1 | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "none" | | | shape | enum("rect" | "circle") | yes | "rect" | | | strokeColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | no | | | | strokeWidth | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | | | width | number | yes | 100 | | | x | number | yes | 0 | | | y | number | yes | 0 | |

SplitScreen
  • kind: composite
  • category: layout
  • internal: false
  • children: yes (2..2)
  • description: Two-panel split screen layout
  • llmGuidance: Provide exactly 2 children. Use orientation="vertical" for left/right and "horizontal" for top/bottom.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | dividerColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | no | | | | dividerOpacity | enum("faint" | "subtle" | "medium" | "strong") | yes | "subtle" | | | dividerThickness | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "1" | | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "12" | | | orientation | enum("vertical" | "horizontal") | yes | "vertical" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "20" | | | split | number | yes | 0.5 | min=0.1, max=0.9 |

Stack
  • kind: primitive
  • category: layout
  • internal: false
  • children: yes
  • description: Flexbox stack layout (row/column) with gap and alignment
  • llmGuidance: Use Stack to arrange child components in a row or column without manual positioning.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | align | enum("start" | "center" | "end" | "stretch") | yes | "center" | | | direction | enum("row" | "column") | yes | "column" | | | gap | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "6" | | | justify | enum("start" | "center" | "end" | "between") | yes | "center" | | | padding | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "0" | |

ThirdLowerBanner
  • kind: composite
  • category: layout
  • internal: false
  • children: no
  • description: Broadcast-style lower-third banner with name/title and optional avatar
  • llmGuidance: Use for speaker introductions. name = big label, title = smaller subtitle. showAvatar + avatarSrc for profile image.

Props:

| Prop | Type | Required | Default | Notes | | - | - | - | - | - | | accent | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "primary" | | | avatarBox | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "md" | | | avatarSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "sm" | | | avatarSrc | string | no | | | | background | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "muted" | | | barWidth | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "2" | | | inset | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "20" | | | minHeight | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl") | yes | "md" | | | name | string | yes | | maxLength=50 | | nameColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "foreground" | | | nameFont | enum("display" | "body" | "mono") | yes | "display" | | | nameSize | enum("xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl") | yes | "3xl" | | | nameWeight | enum("regular" | "medium" | "semibold" | "bold" | "black") | yes | "black" | | | paddingX | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "8" | | | paddingY | enum("0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12" | "16" | "20" | "24" | "32") | yes | "6" | | | radius | enum("none" | "sm" | "md" | "lg" | "full") | yes | "md" | | | showAvatar | boolean | yes | false | | | title | string | yes | | maxLength=100 | | titleColor | enum("background" | "foreground" | "surface" | "surfaceForeground" | "muted" | "mutedForeground" | "primary" | "primaryForeground" | "secondary" | "secondaryForeground" | "accent" | "accentForeground" | "border" | "ring") | yes | "mutedForegro