{
  "name": "remotionui-components",
  "homepage": "https://remotionui.com",
  "generatedFrom": "apps/web/registry.json",
  "guidance": "Use Remotion for framework fundamentals. Use RemotionUI for source-installed video components.",
  "components": [
    {
      "name": "timing",
      "type": "registry:lib",
      "description": "Frame timing helpers and enter easing",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add timing",
      "docsUrl": "https://remotionui.com/docs/components/timing",
      "registryUrl": "https://remotionui.com/r/presets/default/timing.json",
      "detailUrl": "https://remotionui.com/ai/components/timing.json",
      "importPath": "@/remotion/lib/timing",
      "installTarget": "src/remotion/lib/timing",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "springs",
      "type": "registry:lib",
      "description": "Default spring configurations",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add springs",
      "docsUrl": "https://remotionui.com/docs/components/springs",
      "registryUrl": "https://remotionui.com/r/presets/default/springs.json",
      "detailUrl": "https://remotionui.com/ai/components/springs.json",
      "importPath": "@/remotion/lib/springs",
      "installTarget": "src/remotion/lib/springs",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-timing",
      "type": "registry:lib",
      "description": "Shared TransitionSeries timing helpers and layered progress curves",
      "tasks": [
        "transitions"
      ],
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add transition-timing",
      "docsUrl": "https://remotionui.com/docs/components/transition-timing",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-timing.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-timing.json",
      "importPath": "@/remotion/lib/transition-timing",
      "installTarget": "src/remotion/lib/transition-timing",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "ai-composer-utils",
      "type": "registry:lib",
      "description": "Shared typewriter, caret, morph, and intro helpers for AI composer scenes",
      "tasks": [
        "product-intro",
        "scene-overlays"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add ai-composer-utils",
      "docsUrl": "https://remotionui.com/docs/components/ai-composer-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/ai-composer-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/ai-composer-utils.json",
      "importPath": "@/remotion/lib/ai-composer-utils",
      "installTarget": "src/remotion/lib/ai-composer-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "code-syntax",
      "type": "registry:lib",
      "description": "Syntax tokenizer, editor palettes, and revealable code line renderer for the code scenes",
      "tasks": [
        "scene-overlays"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add code-syntax",
      "docsUrl": "https://remotionui.com/docs/components/code-syntax",
      "registryUrl": "https://remotionui.com/r/presets/default/code-syntax.json",
      "detailUrl": "https://remotionui.com/ai/components/code-syntax.json",
      "importPath": "@/remotion/lib/code-syntax",
      "installTarget": "src/remotion/lib/code-syntax",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-emphasis",
      "type": "registry:lib",
      "description": "Word-level phrase matching and marker geometry for scenes that sweep emphasis across text",
      "tasks": [
        "scene-overlays"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add text-emphasis",
      "docsUrl": "https://remotionui.com/docs/components/text-emphasis",
      "registryUrl": "https://remotionui.com/r/presets/default/text-emphasis.json",
      "detailUrl": "https://remotionui.com/ai/components/text-emphasis.json",
      "importPath": "@/remotion/lib/text-emphasis",
      "installTarget": "src/remotion/lib/text-emphasis",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "motion-tokens",
      "type": "registry:lib",
      "description": "Named motion duration and stagger tokens",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "timing",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add motion-tokens",
      "docsUrl": "https://remotionui.com/docs/components/motion-tokens",
      "registryUrl": "https://remotionui.com/r/presets/default/motion-tokens.json",
      "detailUrl": "https://remotionui.com/ai/components/motion-tokens.json",
      "importPath": "@/remotion/lib/motion-tokens",
      "installTarget": "src/remotion/lib/motion-tokens",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "gpu",
      "type": "registry:lib",
      "description": "WebGL2 fragment-shader effect factory for GPU primitives",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add gpu",
      "docsUrl": "https://remotionui.com/docs/components/gpu",
      "registryUrl": "https://remotionui.com/r/presets/default/gpu.json",
      "detailUrl": "https://remotionui.com/ai/components/gpu.json",
      "importPath": "@/remotion/lib/gpu",
      "installTarget": "src/remotion/lib/gpu",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "layout",
      "type": "registry:lib",
      "description": "Format-agnostic layout helpers",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add layout",
      "docsUrl": "https://remotionui.com/docs/components/layout",
      "registryUrl": "https://remotionui.com/r/presets/default/layout.json",
      "detailUrl": "https://remotionui.com/ai/components/layout.json",
      "importPath": "@/remotion/lib/layout",
      "installTarget": "src/remotion/lib/layout",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "motion-wrapper",
      "type": "registry:lib",
      "description": "Inline wrapper for enter/exit animations (avoids AbsoluteFill overlap)",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add motion-wrapper",
      "docsUrl": "https://remotionui.com/docs/components/motion-wrapper",
      "registryUrl": "https://remotionui.com/r/presets/default/motion-wrapper.json",
      "detailUrl": "https://remotionui.com/ai/components/motion-wrapper.json",
      "importPath": "@/remotion/lib/motion-wrapper",
      "installTarget": "src/remotion/lib/motion-wrapper",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "motion-primitive",
      "type": "registry:lib",
      "description": "Enter/exit motion contract shared by the animation primitives — opacity leads, exits are shorter, and a bounded Sequence times the exit itself",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "springs",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add motion-primitive",
      "docsUrl": "https://remotionui.com/docs/components/motion-primitive",
      "registryUrl": "https://remotionui.com/r/presets/default/motion-primitive.json",
      "detailUrl": "https://remotionui.com/ai/components/motion-primitive.json",
      "importPath": "@/remotion/lib/motion-primitive",
      "installTarget": "src/remotion/lib/motion-primitive",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "use-stagger",
      "type": "registry:hook",
      "description": "Hook for staggered child delays",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add use-stagger",
      "docsUrl": "https://remotionui.com/docs/components/use-stagger",
      "registryUrl": "https://remotionui.com/r/presets/default/use-stagger.json",
      "detailUrl": "https://remotionui.com/ai/components/use-stagger.json",
      "importPath": "@/remotion/hooks/use-stagger",
      "installTarget": "src/remotion/hooks/use-stagger",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "fade-in",
      "type": "registry:ui",
      "description": "Opacity-only entrance, with an exit that lands on the end of its sequence",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add fade-in",
      "docsUrl": "https://remotionui.com/docs/components/fade-in",
      "registryUrl": "https://remotionui.com/r/presets/default/fade-in.json",
      "detailUrl": "https://remotionui.com/ai/components/fade-in.json",
      "importPath": "@/remotion/primitives/fade-in",
      "installTarget": "src/remotion/primitives/fade-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate.",
          "schema": {}
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve.",
          "schema": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "smooth",
                  "snappy",
                  "bouncy"
                ]
              },
              {
                "type": "boolean"
              },
              {
                "type": "object"
              }
            ]
          }
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence.",
          "schema": {
            "type": "boolean"
          }
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through.",
          "schema": {
            "type": "string",
            "enum": [
              "reverse",
              "continue"
            ]
          }
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child.",
          "schema": {
            "type": "boolean"
          }
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper.",
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "from",
          "type": "number",
          "default": "0",
          "description": "Opacity the fade starts from.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "to",
          "type": "number",
          "default": "1",
          "description": "Opacity the fade settles on.",
          "schema": {
            "type": "number"
          }
        }
      ],
      "usage": "import { FadeIn } from \"@/remotion/primitives/fade-in\";\n\n<FadeIn durationInFrames={30} exit>\n  <div>Hello world</div>\n</FadeIn>",
      "related": [
        "fade-out",
        "slide-up"
      ],
      "note": "Opacity runs the full duration here; the transform primitives finish theirs at 55% so the element lands solid.",
      "compat": {
        "remotion": "^4.0.0"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "fade-out",
      "type": "registry:ui",
      "description": "Held exit that accelerates away, timed to the last frame of its sequence by default",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "exit"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-wrapper",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add fade-out",
      "docsUrl": "https://remotionui.com/docs/components/fade-out",
      "registryUrl": "https://remotionui.com/r/presets/default/fade-out.json",
      "detailUrl": "https://remotionui.com/ai/components/fade-out.json",
      "importPath": "@/remotion/primitives/fade-out",
      "installTarget": "src/remotion/primitives/fade-out",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to fade away."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the fade in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "end of the sequence",
          "description": "Frame the fade starts on. Omitted, it lands on the last frame of the surrounding Sequence."
        },
        {
          "name": "from",
          "type": "number",
          "default": "1",
          "description": "Opacity held before the fade."
        },
        {
          "name": "to",
          "type": "number",
          "default": "0",
          "description": "Opacity it ends on."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        }
      ],
      "usage": "import { FadeOut } from \"@/remotion/primitives/fade-out\";\n\n<FadeOut durationInFrames={24}>\n  <div>Goodbye</div>\n</FadeOut>",
      "related": [
        "fade-in"
      ],
      "note": "Uses an ease-in curve: an exit accelerates away, it never decelerates into nothing.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "slide-up",
      "type": "registry:ui",
      "description": "Rise into place, with an optional mask reveal and automatic exit",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add slide-up",
      "docsUrl": "https://remotionui.com/docs/components/slide-up",
      "registryUrl": "https://remotionui.com/r/presets/default/slide-up.json",
      "detailUrl": "https://remotionui.com/ai/components/slide-up.json",
      "importPath": "@/remotion/primitives/slide-up",
      "installTarget": "src/remotion/primitives/slide-up",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "distance",
          "type": "number",
          "default": "scaled 40px",
          "description": "Vertical offset in pixels at the start. Under mask, defaults to the element's own height."
        },
        {
          "name": "mask",
          "type": "boolean",
          "default": "false",
          "description": "Clip the child to its own box so it rises out of a mask instead of fading up."
        },
        {
          "name": "maskPadding",
          "type": "number",
          "default": "0",
          "description": "Extra room inside the mask so descenders are not clipped."
        }
      ],
      "usage": "import { SlideUp } from \"@/remotion/primitives/slide-up\";\n\n<SlideUp mask exit>\n  <h1>Title</h1>\n</SlideUp>",
      "related": [
        "slide-left",
        "fade-in"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "slide-left",
      "type": "registry:ui",
      "description": "Slide in from either side, with an optional mask reveal and automatic exit",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add slide-left",
      "docsUrl": "https://remotionui.com/docs/components/slide-left",
      "registryUrl": "https://remotionui.com/r/presets/default/slide-left.json",
      "detailUrl": "https://remotionui.com/ai/components/slide-left.json",
      "importPath": "@/remotion/primitives/slide-left",
      "installTarget": "src/remotion/primitives/slide-left",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "distance",
          "type": "number",
          "default": "scaled 60px",
          "description": "Horizontal offset in pixels at the start. Under mask, defaults to the element's own width."
        },
        {
          "name": "from",
          "type": "\"left\" | \"right\"",
          "default": "\"left\"",
          "description": "Side the child travels in from."
        },
        {
          "name": "mask",
          "type": "boolean",
          "default": "false",
          "description": "Clip the child to its own box so it slides out of a mask."
        }
      ],
      "usage": "import { SlideLeft } from \"@/remotion/primitives/slide-left\";\n\n<SlideLeft distance={60} from=\"left\">\n  <p>Slide in from the left</p>\n</SlideLeft>",
      "related": [
        "slide-up",
        "stagger-children"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "scale-in",
      "type": "registry:ui",
      "description": "Grow into place from just under full size, with an optional spring and exit",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add scale-in",
      "docsUrl": "https://remotionui.com/docs/components/scale-in",
      "registryUrl": "https://remotionui.com/r/presets/default/scale-in.json",
      "detailUrl": "https://remotionui.com/ai/components/scale-in.json",
      "importPath": "@/remotion/primitives/scale-in",
      "installTarget": "src/remotion/primitives/scale-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "from",
          "type": "number",
          "default": "0.92",
          "description": "Scale at the start of the entrance."
        },
        {
          "name": "origin",
          "type": "TransformOrigin",
          "default": "\"center\"",
          "description": "Corner or edge the scale grows out of."
        }
      ],
      "usage": "import { ScaleIn } from \"@/remotion/primitives/scale-in\";\n\n<ScaleIn from={0.9} spring=\"snappy\">\n  <img src={staticFile(\"logo.png\")} />\n</ScaleIn>",
      "related": [
        "spring-in",
        "fade-in"
      ],
      "note": "Anything below ~0.85 wants a spring behind it, or the growth reads as a camera zoom.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "typewriter",
      "type": "registry:ui",
      "description": "Typewriter reveal with rhythm, pauses, looping, and a caret that only blinks at rest",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add typewriter",
      "docsUrl": "https://remotionui.com/docs/components/typewriter",
      "registryUrl": "https://remotionui.com/r/presets/default/typewriter.json",
      "detailUrl": "https://remotionui.com/ai/components/typewriter.json",
      "importPath": "@/remotion/primitives/typewriter",
      "installTarget": "src/remotion/primitives/typewriter",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Full string to reveal character by character. Use [pause:0.5] for inline pauses."
        },
        {
          "name": "charFrames",
          "type": "number",
          "description": "Frames per character (preferred over durationInFrames). Values below 1 type more than one character a frame."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "60",
          "description": "Total duration when charFrames is omitted."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before typing begins."
        },
        {
          "name": "pauseAfter",
          "type": "string",
          "description": "Pause after this substring is typed."
        },
        {
          "name": "pauseSeconds",
          "type": "number",
          "default": "0.6",
          "description": "Length of the pauseAfter pause in seconds."
        },
        {
          "name": "showCursor",
          "type": "boolean",
          "default": "true",
          "description": "Show the caret."
        },
        {
          "name": "cursorBlinkFrames",
          "type": "number",
          "default": "30",
          "description": "Caret blink cycle length in frames, used while it rests."
        },
        {
          "name": "cursorColor",
          "type": "string",
          "description": "Caret colour. Defaults to the text colour."
        },
        {
          "name": "cursorWidth",
          "type": "number",
          "description": "Caret width in pixels (bar/underscore only)."
        },
        {
          "name": "cursorStyle",
          "type": "\"bar\" | \"block\" | \"underscore\"",
          "default": "\"bar\"",
          "description": "Caret shape."
        },
        {
          "name": "humanize",
          "type": "boolean",
          "default": "false",
          "description": "Uneven key rhythm: the difference between typing and a progress bar."
        },
        {
          "name": "respectPunctuation",
          "type": "boolean",
          "default": "false",
          "description": "Pause automatically after . ! ? ; : ,"
        },
        {
          "name": "punctuationPauseSeconds",
          "type": "number",
          "default": "0.25",
          "description": "Length of automatic punctuation pauses."
        },
        {
          "name": "loop",
          "type": "boolean",
          "default": "false",
          "description": "Type, pause, backspace, and repeat."
        },
        {
          "name": "loopPauseSeconds",
          "type": "number",
          "default": "1",
          "description": "Pause at full text before backspacing."
        },
        {
          "name": "backspaceCharFrames",
          "type": "number",
          "default": "1",
          "description": "Frames per character when backspacing."
        },
        {
          "name": "reserveSpace",
          "type": "boolean",
          "default": "true",
          "description": "Measure the full block up front so a wrapping line never reflows mid-sentence."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "scaled 84px",
          "description": "Text size in pixels."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "600",
          "description": "Text weight."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#ececec\"",
          "description": "Text colour."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "description": "Font family for the typed text."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the text span."
        }
      ],
      "usage": "import { Typewriter } from \"@/remotion/primitives/typewriter\";\n\n<Typewriter\n  text=\"Build videos with React.[pause:0.5] One frame at a time.\"\n  charFrames={2}\n  humanize\n  respectPunctuation\n  cursorStyle=\"block\"\n/>",
      "related": [
        "marker-highlight",
        "counter"
      ],
      "note": "The caret holds solid while keys land and only blinks once it rests. Inline [pause:0.5] markers are stripped from the rendered text.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "counter",
      "type": "registry:ui",
      "description": "Animated number with grouping, decimals, odometer digit roll and a reserved width",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "timing",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add counter",
      "docsUrl": "https://remotionui.com/docs/components/counter",
      "registryUrl": "https://remotionui.com/r/presets/default/counter.json",
      "detailUrl": "https://remotionui.com/ai/components/counter.json",
      "importPath": "@/remotion/primitives/counter",
      "installTarget": "src/remotion/primitives/counter",
      "category": "primitive",
      "props": [
        {
          "name": "to",
          "type": "number",
          "required": true,
          "description": "Value the count lands on."
        },
        {
          "name": "from",
          "type": "number",
          "default": "0",
          "description": "Value the count starts from."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "60",
          "description": "Frames over which the value ramps."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the ramp starts."
        },
        {
          "name": "decimals",
          "type": "number",
          "default": "0",
          "description": "Fixed decimal places. Also fixes the width, so nothing shifts."
        },
        {
          "name": "grouping",
          "type": "boolean",
          "default": "true",
          "description": "Group thousands with the locale's separator."
        },
        {
          "name": "locale",
          "type": "string",
          "description": "Locale for grouping and decimal marks."
        },
        {
          "name": "format",
          "type": "(value: number) => string",
          "description": "Full override of the number formatting."
        },
        {
          "name": "prefix",
          "type": "string",
          "description": "Text before the number, e.g. a currency mark."
        },
        {
          "name": "suffix",
          "type": "string",
          "description": "Text after the number, e.g. %, K, M."
        },
        {
          "name": "roll",
          "type": "boolean",
          "default": "false",
          "description": "Roll each digit like an odometer. The lowest column turns continuously and every column above it turns over on the carry. With decimals, the free column is the last decimal place."
        },
        {
          "name": "spring",
          "type": "MotionSpring",
          "description": "Drive the ramp with a spring instead of the ease-out curve."
        },
        {
          "name": "settle",
          "type": "boolean",
          "default": "true",
          "description": "Small scale pop on the frame the number lands."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "scaled 96px",
          "description": "Text size in pixels."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "700",
          "description": "Text weight."
        },
        {
          "name": "color",
          "type": "string",
          "description": "Text colour."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "description": "Font family for the number."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the number."
        }
      ],
      "usage": "import { Counter } from \"@/remotion/primitives/counter\";\n\n<Counter from={0} to={124000} roll durationInFrames={64} />",
      "related": [
        "stat-card",
        "progress-bar"
      ],
      "note": "The width is reserved from the longest value the ramp can produce, so a centred number never reflows the line around it. Every rolling column shares one baseline and one size with the separators and is clipped to a single digit row, so nothing bleeds out of the number's line box.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "blur-in",
      "type": "registry:ui",
      "description": "Resolve out of a defocus — blur clears before the move lands",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add blur-in",
      "docsUrl": "https://remotionui.com/docs/components/blur-in",
      "registryUrl": "https://remotionui.com/r/presets/default/blur-in.json",
      "detailUrl": "https://remotionui.com/ai/components/blur-in.json",
      "importPath": "@/remotion/primitives/blur-in",
      "installTarget": "src/remotion/primitives/blur-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "maxBlur",
          "type": "number",
          "default": "10",
          "description": "Blur radius in pixels at the start."
        },
        {
          "name": "scaleFrom",
          "type": "number",
          "default": "0.98",
          "description": "Scale at the start: the push that sells the pull into focus."
        }
      ],
      "usage": "import { BlurIn } from \"@/remotion/primitives/blur-in\";\n\n<BlurIn maxBlur={12}>\n  <h1>Focus reveal</h1>\n</BlurIn>",
      "related": [
        "fade-in",
        "scale-in"
      ],
      "note": "The blur clears at 80% of the travel; held to the last frame the whole entrance feels soft.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "spring-in",
      "type": "registry:ui",
      "description": "Spring-driven scale and rise, with snappy, smooth and bouncy presets",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add spring-in",
      "docsUrl": "https://remotionui.com/docs/components/spring-in",
      "registryUrl": "https://remotionui.com/r/presets/default/spring-in.json",
      "detailUrl": "https://remotionui.com/ai/components/spring-in.json",
      "importPath": "@/remotion/primitives/spring-in",
      "installTarget": "src/remotion/primitives/spring-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "config",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig>",
          "default": "\"snappy\"",
          "description": "Spring preset, or an override on the snappy config."
        },
        {
          "name": "from",
          "type": "number",
          "default": "0.88",
          "description": "Scale at the start of the entrance."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "scaled 14px",
          "description": "How far it rises as it springs."
        },
        {
          "name": "origin",
          "type": "TransformOrigin",
          "default": "\"center\"",
          "description": "Point the scale grows from."
        }
      ],
      "usage": "import { SpringIn } from \"@/remotion/primitives/spring-in\";\n\n<SpringIn config=\"bouncy\" durationInFrames={40}>\n  <div>Physical entrance</div>\n</SpringIn>",
      "related": [
        "scale-in",
        "rotate-in"
      ],
      "note": "`config=\"bouncy\"` overshoots both the scale and the rise, then settles: the reason to use a spring at all.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "stagger-children",
      "type": "registry:ui",
      "description": "Offset children onto their own sequences, in forward, reverse, centre or edge order, in and out",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "sequence"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add stagger-children",
      "docsUrl": "https://remotionui.com/docs/components/stagger-children",
      "registryUrl": "https://remotionui.com/r/presets/default/stagger-children.json",
      "detailUrl": "https://remotionui.com/ai/components/stagger-children.json",
      "importPath": "@/remotion/primitives/stagger-children",
      "installTarget": "src/remotion/primitives/stagger-children",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Child elements to stagger in sequence."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "8",
          "description": "Frames between one child starting and the next."
        },
        {
          "name": "baseDelayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first child starts."
        },
        {
          "name": "order",
          "type": "\"forward\" | \"reverse\" | \"center\" | \"edges\"",
          "default": "\"forward\"",
          "description": "Which child goes first. center runs outwards from the middle, edges runs inwards."
        },
        {
          "name": "exitStaggerInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames between one child leaving and the next, in the order they arrived. 0 lands the group together."
        }
      ],
      "usage": "import { StaggerChildren } from \"@/remotion/primitives/stagger-children\";\nimport { SlideLeft } from \"@/remotion/primitives/slide-left\";\n\n<StaggerChildren staggerInFrames={8} exitStaggerInFrames={6}>\n  {items.map((item) => (\n    <SlideLeft key={item} exit><span>{item}</span></SlideLeft>\n  ))}\n</StaggerChildren>",
      "related": [
        "slide-left",
        "fade-in"
      ],
      "note": "Each child gets a Sequence with layout=\"none\", so it animates from its own frame 0. Inside a bounded window the slot carries an end too, which is what times each child's exit.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "marker-highlight",
      "type": "registry:ui",
      "description": "Highlighter stroke swept word by word across a phrase, with marker, knockout, underline and box variants",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens",
        "text-emphasis"
      ],
      "installCommand": "npx remotion-ui@latest add marker-highlight",
      "docsUrl": "https://remotionui.com/docs/components/marker-highlight",
      "registryUrl": "https://remotionui.com/r/presets/default/marker-highlight.json",
      "detailUrl": "https://remotionui.com/ai/components/marker-highlight.json",
      "importPath": "@/remotion/primitives/marker-highlight",
      "installTarget": "src/remotion/primitives/marker-highlight",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Full sentence to render."
        },
        {
          "name": "phrase",
          "type": "string",
          "description": "Phrase to sweep. Matched case-insensitively and may span several words."
        },
        {
          "name": "highlightWord",
          "type": "string",
          "description": "Single-word form of phrase."
        },
        {
          "name": "variant",
          "type": "\"marker\" | \"knockout\" | \"underline\" | \"box\"",
          "default": "\"marker\"",
          "description": "How the emphasis is drawn."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "12",
          "description": "Length of the sweep across one word."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first word is struck."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "4",
          "description": "Frames between one word being struck and the next."
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "-4",
          "description": "Angle of the nib in degrees off vertical. Slopes the leading edge only; the band is never rotated, so a joined phrase does not step at every word."
        },
        {
          "name": "inkSoftness",
          "type": "number",
          "default": "0.16",
          "description": "Softness of the leading edge, as a share of the word. 0 is a hard cut."
        },
        {
          "name": "markerColor",
          "type": "string",
          "default": "\"#fbbf24\"",
          "description": "Colour of the stroke."
        },
        {
          "name": "markerOpacity",
          "type": "number",
          "default": "per variant",
          "description": "Alpha of the ink. Defaults to 0.62 for marker, 0.95 for underline, 1 for knockout and box."
        },
        {
          "name": "invertOnHighlight",
          "type": "boolean",
          "default": "knockout only",
          "description": "Flip the ink under the leading edge of the stroke as it passes."
        },
        {
          "name": "inkColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Ink used over a covered word."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#f8fafc\"",
          "description": "Base text colour."
        },
        {
          "name": "textAlign",
          "type": "\"left\" | \"center\" | \"right\"",
          "default": "\"left\"",
          "description": "Alignment of the wrapped words."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "scaled 84px",
          "description": "Text size in pixels."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "600",
          "description": "Text weight."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "description": "Font family for the text."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        }
      ],
      "usage": "import { MarkerHighlight } from \"@/remotion/primitives/marker-highlight\";\n\n<MarkerHighlight\n  text=\"The best motion is code you can read and change.\"\n  phrase=\"code you can read and change\"\n  markerColor=\"#f97316\"\n/>",
      "related": [
        "quote-card",
        "typewriter"
      ],
      "note": "The stroke crosses each marked word in turn, so it reads as a hand moving rather than a background appearing. Band geometry is stated as top plus height in em against each word's own line box, so a phrase that wraps carries the same band on every line.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "progress-bar",
      "type": "registry:ui",
      "description": "Inline progress bar with determinate and indeterminate modes, segments and a value readout",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-tokens",
        "timing",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add progress-bar",
      "docsUrl": "https://remotionui.com/docs/components/progress-bar",
      "registryUrl": "https://remotionui.com/r/presets/default/progress-bar.json",
      "detailUrl": "https://remotionui.com/ai/components/progress-bar.json",
      "importPath": "@/remotion/primitives/progress-bar",
      "installTarget": "src/remotion/primitives/progress-bar",
      "category": "primitive",
      "props": [
        {
          "name": "progress",
          "type": "number",
          "default": "1",
          "description": "Value the bar fills to, 0–1."
        },
        {
          "name": "from",
          "type": "number",
          "default": "0",
          "description": "Value the bar starts from, 0–1."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "60",
          "description": "Frames the fill takes."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the fill starts."
        },
        {
          "name": "spring",
          "type": "MotionSpring",
          "description": "Drive the fill with a spring instead of the ease-out curve."
        },
        {
          "name": "indeterminate",
          "type": "boolean",
          "default": "false",
          "description": "Loop a shuttle across the track: work with no known end."
        },
        {
          "name": "label",
          "type": "string",
          "description": "Label above the track."
        },
        {
          "name": "showValue",
          "type": "boolean",
          "default": "false",
          "description": "Percentage readout on the right of the label row."
        },
        {
          "name": "formatValue",
          "type": "(progress: number) => string",
          "description": "Override the readout text."
        },
        {
          "name": "segments",
          "type": "number",
          "description": "Divide the track into equal steps."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Fill colour."
        },
        {
          "name": "trackColor",
          "type": "string",
          "description": "Colour of the empty track."
        },
        {
          "name": "labelColor",
          "type": "string",
          "description": "Colour of the label row."
        },
        {
          "name": "height",
          "type": "number",
          "default": "scaled 12px",
          "description": "Bar thickness in pixels."
        },
        {
          "name": "radius",
          "type": "number",
          "default": "height",
          "description": "Corner radius."
        },
        {
          "name": "glow",
          "type": "boolean",
          "default": "true",
          "description": "Soft light carried by the leading edge of the fill."
        },
        {
          "name": "width",
          "type": "number | string",
          "default": "\"100%\"",
          "description": "Width of the whole control."
        }
      ],
      "usage": "import { ProgressBar } from \"@/remotion/primitives/progress-bar\";\n\n<ProgressBar progress={0.75} label=\"Rendering\" showValue segments={4} />",
      "related": [
        "counter",
        "intro"
      ],
      "note": "Lays out inline rather than filling the frame, so it composes inside a card or a stat row.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "rotate-in",
      "type": "registry:ui",
      "description": "Swing into place in plane or hinged in depth on the x/y axis",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add rotate-in",
      "docsUrl": "https://remotionui.com/docs/components/rotate-in",
      "registryUrl": "https://remotionui.com/r/presets/default/rotate-in.json",
      "detailUrl": "https://remotionui.com/ai/components/rotate-in.json",
      "importPath": "@/remotion/primitives/rotate-in",
      "installTarget": "src/remotion/primitives/rotate-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Content to animate."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the enter animation in frames."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the animation starts."
        },
        {
          "name": "spring",
          "type": "\"smooth\" | \"snappy\" | \"bouncy\" | Partial<SpringConfig> | boolean",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing on the last frame of the surrounding Sequence."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "70% of durationInFrames",
          "description": "Length of the exit. Exits are shorter than entrances."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on, overriding the end-of-window timing."
        },
        {
          "name": "exitTravel",
          "type": "number",
          "default": "0.6",
          "description": "Share of the enter distance the exit travels."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "reverse leaves the way it came in, continue carries on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping the child."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper."
        },
        {
          "name": "degrees",
          "type": "number",
          "default": "-12",
          "description": "Angle it starts at. Negative tilts anticlockwise."
        },
        {
          "name": "axis",
          "type": "\"z\" | \"x\" | \"y\"",
          "default": "\"z\"",
          "description": "z spins in plane; x and y hinge in depth."
        },
        {
          "name": "perspective",
          "type": "number",
          "default": "1200",
          "description": "Depth of the 3D projection for the x and y axes."
        },
        {
          "name": "scaleFrom",
          "type": "number",
          "default": "0.96",
          "description": "Scale at the start: a rotation that also grows reads as one gesture."
        },
        {
          "name": "origin",
          "type": "TransformOrigin",
          "default": "\"center\"",
          "description": "Point the rotation pivots around."
        }
      ],
      "usage": "import { RotateIn } from \"@/remotion/primitives/rotate-in\";\n\n<RotateIn axis=\"x\" degrees={-24} origin=\"bottom\">\n  <div>Hinge into place</div>\n</RotateIn>",
      "related": [
        "spring-in",
        "scale-in"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-fade",
      "type": "registry:ui",
      "description": "Crossfade between scenes, or dip the cut through a colour",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-fade",
      "docsUrl": "https://remotionui.com/docs/components/transition-fade",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-fade.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-fade.json",
      "importPath": "@/remotion/primitives/transition-fade",
      "installTarget": "src/remotion/primitives/transition-fade",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "18",
          "description": "Overlap duration between scenes."
        },
        {
          "name": "dipTo",
          "type": "string",
          "description": "Colour the cut passes through. Omit to crossfade the scenes directly."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve for the fade."
        }
      ],
      "usage": "import { TransitionSeries } from \"@remotion/transitions\";\nimport { transitionFade } from \"@/remotion/primitives/transition-fade\";\n\n<TransitionSeries>\n  <TransitionSeries.Sequence durationInFrames={60}>...</TransitionSeries.Sequence>\n  <TransitionSeries.Transition {...transitionFade({ durationInFrames: 15 })} />\n  <TransitionSeries.Sequence durationInFrames={60}>...</TransitionSeries.Sequence>\n</TransitionSeries>",
      "related": [
        "transition-slide",
        "showcase"
      ],
      "note": "Returns a config object for `TransitionSeries.Transition`, not a React component.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-slide",
      "type": "registry:ui",
      "description": "Slide transition helper for TransitionSeries",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-slide",
      "docsUrl": "https://remotionui.com/docs/components/transition-slide",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-slide.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-slide.json",
      "importPath": "@/remotion/primitives/transition-slide",
      "installTarget": "src/remotion/primitives/transition-slide",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Overlap duration between scenes."
        },
        {
          "name": "direction",
          "type": "string",
          "default": "\"from-left\"",
          "description": "Slide direction: from-left, from-right, from-top, from-bottom."
        }
      ],
      "usage": "import { transitionSlide } from \"@/remotion/primitives/transition-slide\";\n\n<TransitionSeries.Transition\n  {...transitionSlide({ direction: \"from-left\", durationInFrames: 20 })}\n/>",
      "related": [
        "transition-fade",
        "showcase"
      ],
      "note": "Returns a config object for `TransitionSeries.Transition`, not a React component.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "lower-third",
      "type": "registry:block",
      "description": "Name plate that plays its whole life: wipes out from the frame edge, settles, holds, then retreats the way it came",
      "tasks": [
        "transitions",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add lower-third",
      "docsUrl": "https://remotionui.com/docs/components/lower-third",
      "registryUrl": "https://remotionui.com/r/presets/default/lower-third.json",
      "detailUrl": "https://remotionui.com/ai/components/lower-third.json",
      "importPath": "@/remotion/scenes/lower-third",
      "installTarget": "src/remotion/scenes/lower-third",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "required": true,
          "description": "Primary line."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Secondary line."
        },
        {
          "name": "badge",
          "type": "string",
          "description": "Small tag on the plate (LIVE, EP 12, the segment)."
        },
        {
          "name": "align",
          "type": "\"left\" | \"right\"",
          "default": "\"left\"",
          "description": "Edge the plate wipes out from."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds before the plate retreats. Omit to leave it on screen."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Badge colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the plate background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { LowerThird } from \"@/remotion/scenes/lower-third\";\n\n<LowerThird\n  title=\"Jane Doe\"\n  subtitle=\"Product Designer\"\n  accentColor=\"#f97316\"\n  align=\"left\"\n/>",
      "related": [
        "title-card",
        "end-card"
      ],
      "note": "Transparent overlay scene designed to sit over footage.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "title-card",
      "type": "registry:block",
      "description": "Opening card where each headline line rises out of its own mask and one sweep of light crosses it as it stands",
      "tasks": [
        "product-intro",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add title-card",
      "docsUrl": "https://remotionui.com/docs/components/title-card",
      "registryUrl": "https://remotionui.com/r/presets/default/title-card.json",
      "detailUrl": "https://remotionui.com/ai/components/title-card.json",
      "importPath": "@/remotion/scenes/title-card",
      "installTarget": "src/remotion/scenes/title-card",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "required": true,
          "description": "Headline. Newlines honoured; otherwise lines are balanced."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Chip above the headline."
        },
        {
          "name": "meta",
          "type": "string",
          "description": "Small line under the subtitle (date, author, run time)."
        },
        {
          "name": "charsPerLine",
          "type": "number",
          "default": "22",
          "description": "Characters per line the headline balances to."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Chip, glow, and sweep colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds before the card leaves. Omit to hold: correct inside a TransitionSeries."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { TitleCard } from \"@/remotion/scenes/title-card\";\n\n<TitleCard title=\"Launch Week\" subtitle=\"Day 1\" />",
      "related": [
        "intro",
        "end-card"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "feature-list",
      "type": "registry:block",
      "description": "List being ticked off: each row arrives in turn, its rule draws across, and its check strokes in behind it",
      "tasks": [
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add feature-list",
      "docsUrl": "https://remotionui.com/docs/components/feature-list",
      "registryUrl": "https://remotionui.com/r/presets/default/feature-list.json",
      "detailUrl": "https://remotionui.com/ai/components/feature-list.json",
      "importPath": "@/remotion/scenes/feature-list",
      "installTarget": "src/remotion/scenes/feature-list",
      "category": "scene",
      "props": [
        {
          "name": "items",
          "type": "(string | FeatureItem)[]",
          "required": true,
          "description": "Rows, as strings or { label, detail }. Up to five are shown."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Section heading."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above the heading."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Check and eyebrow colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { FeatureList } from \"@/remotion/scenes/feature-list\";\n\n<FeatureList\n  title=\"Why RemotionUI\"\n  items={[\"Own your components\", \"Live previews\", \"CLI workflow\"]}\n/>",
      "related": [
        "stat-card",
        "showcase"
      ],
      "note": "Self-contained scene. Uses layout and motion-tokens helpers only.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "stat-card",
      "type": "registry:block",
      "description": "A number landing: the ring fills while the counter rolls, then the label and the change against the last period settle",
      "tasks": [
        "data",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add stat-card",
      "docsUrl": "https://remotionui.com/docs/components/stat-card",
      "registryUrl": "https://remotionui.com/r/presets/default/stat-card.json",
      "detailUrl": "https://remotionui.com/ai/components/stat-card.json",
      "importPath": "@/remotion/scenes/stat-card",
      "installTarget": "src/remotion/scenes/stat-card",
      "category": "scene",
      "props": [
        {
          "name": "value",
          "type": "number",
          "default": "98",
          "description": "Number the counter lands on."
        },
        {
          "name": "max",
          "type": "number",
          "description": "What the value is out of. With it the ring is a meter; without it the ring draws a full sweep."
        },
        {
          "name": "suffix",
          "type": "string",
          "default": "\"%\"",
          "description": "Unit after the number."
        },
        {
          "name": "prefix",
          "type": "string",
          "description": "Unit before the number."
        },
        {
          "name": "decimals",
          "type": "number",
          "default": "0",
          "description": "Decimal places while counting and at rest."
        },
        {
          "name": "label",
          "type": "string",
          "default": "\"Satisfaction\"",
          "description": "Metric label."
        },
        {
          "name": "caption",
          "type": "string",
          "description": "Line under the label (source, window, cohort)."
        },
        {
          "name": "delta",
          "type": "number",
          "description": "Change against the previous period; lands after the number settles."
        },
        {
          "name": "deltaSuffix",
          "type": "string",
          "default": "\"%\"",
          "description": "Unit on the delta chip."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#2DD4BF\"",
          "description": "Ring, suffix, and delta colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { StatCard } from \"@/remotion/scenes/stat-card\";\n\n<StatCard value={98} label=\"Satisfaction\" suffix=\"%\" />",
      "related": [
        "counter",
        "feature-list"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "quote-card",
      "type": "registry:block",
      "description": "Pull quote read aloud: the mark draws, the quote rises line by line, a marker sweeps the phrase, the attribution lands last",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "text-emphasis"
      ],
      "installCommand": "npx remotion-ui@latest add quote-card",
      "docsUrl": "https://remotionui.com/docs/components/quote-card",
      "registryUrl": "https://remotionui.com/r/presets/default/quote-card.json",
      "detailUrl": "https://remotionui.com/ai/components/quote-card.json",
      "importPath": "@/remotion/scenes/quote-card",
      "installTarget": "src/remotion/scenes/quote-card",
      "category": "scene",
      "props": [
        {
          "name": "quote",
          "type": "string",
          "required": true,
          "description": "Quote body."
        },
        {
          "name": "emphasis",
          "type": "string",
          "description": "Phrase swept with a marker; matched over the whole quote, so it may span a line break."
        },
        {
          "name": "author",
          "type": "string",
          "description": "Attribution name."
        },
        {
          "name": "role",
          "type": "string",
          "description": "Second attribution line (role, company, handle)."
        },
        {
          "name": "initials",
          "type": "string",
          "description": "Initials in the attribution disc. Defaults to the author's."
        },
        {
          "name": "charsPerLine",
          "type": "number",
          "default": "30",
          "description": "Characters per line the quote balances to."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#F472B6\"",
          "description": "Mark, marker, and disc colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { QuoteCard } from \"@/remotion/scenes/quote-card\";\n\n<QuoteCard\n  quote=\"The best motion is code you can read and change\"\n  emphasis=\"motion\"\n  author=\"Team\"\n/>",
      "related": [
        "text-emphasis",
        "title-card"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "end-card",
      "type": "registry:block",
      "description": "Outro built in the order a viewer acts on it: title, button assembling under its label, address typing, channels, one pulse",
      "tasks": [
        "product-intro",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add end-card",
      "docsUrl": "https://remotionui.com/docs/components/end-card",
      "registryUrl": "https://remotionui.com/r/presets/default/end-card.json",
      "detailUrl": "https://remotionui.com/ai/components/end-card.json",
      "importPath": "@/remotion/scenes/end-card",
      "installTarget": "src/remotion/scenes/end-card",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "required": true,
          "description": "Closing headline."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Line under the title."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Chip above the title."
        },
        {
          "name": "cta",
          "type": "string",
          "description": "Button label. Omit to end on the title alone."
        },
        {
          "name": "url",
          "type": "string",
          "description": "Address typed under the button."
        },
        {
          "name": "handles",
          "type": "string[]",
          "description": "Handles or channels listed along the foot."
        },
        {
          "name": "logoSrc",
          "type": "string",
          "description": "Brand mark image (staticFile or URL)."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Button, pulse, and eyebrow colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { EndCard } from \"@/remotion/scenes/end-card\";\n\n<EndCard title=\"Thanks for watching\" cta=\"Subscribe\" url=\"youtube.com\" />",
      "related": [
        "title-card",
        "intro"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "intro",
      "type": "registry:block",
      "description": "5-second branded intro: chapter marker, headline, topic rail",
      "tasks": [
        "product-intro",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "title-card",
        "fade-out",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add intro",
      "docsUrl": "https://remotionui.com/docs/components/intro",
      "registryUrl": "https://remotionui.com/r/presets/default/intro.json",
      "detailUrl": "https://remotionui.com/ai/components/intro.json",
      "importPath": "@/compositions/intro",
      "installTarget": "src/compositions/intro",
      "category": "composition",
      "props": [
        {
          "name": "title",
          "type": "string",
          "default": "\"Chapter open\"",
          "description": "Main title.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Tagline under the title.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page background behind the intro.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "accentColor",
          "type": "string",
          "description": "Accent used by the progress bar and title.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "usage": "import { Intro } from \"@/remotion/compositions/intro\";\n\n<Intro title=\"My Product\" subtitle=\"Launch video\" />",
      "related": [
        "showcase",
        "title-card"
      ],
      "note": "Full intro sequence with staggered title, subtitle, and progress bar.",
      "composition": {
        "id": "Intro",
        "component": "Intro",
        "durationInFrames": 150,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/intro/index"
      },
      "compat": {
        "remotion": "^4.0.0"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "showcase",
      "type": "registry:block",
      "description": "Full demo reel with TransitionSeries",
      "tasks": [
        "product-intro",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-fade",
        "title-card",
        "feature-list",
        "stat-card",
        "end-card",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add showcase",
      "docsUrl": "https://remotionui.com/docs/components/showcase",
      "registryUrl": "https://remotionui.com/r/presets/default/showcase.json",
      "detailUrl": "https://remotionui.com/ai/components/showcase.json",
      "importPath": "@/compositions/showcase",
      "installTarget": "src/compositions/showcase",
      "category": "composition",
      "props": [
        {
          "name": "title",
          "type": "string",
          "description": "Opening title."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Opening subtitle."
        },
        {
          "name": "featureTitle",
          "type": "string",
          "default": "\"Three layers you own\"",
          "description": "Headline on the feature list scene."
        },
        {
          "name": "featureItems",
          "type": "string[]",
          "description": "Rows ticked off in the feature list."
        },
        {
          "name": "statValue",
          "type": "number",
          "default": "3",
          "description": "Counter value for the stat scene."
        },
        {
          "name": "statLabel",
          "type": "string",
          "default": "\"Runtime dependencies\"",
          "description": "Stat card label."
        },
        {
          "name": "statSuffix",
          "type": "string",
          "default": "\"\"",
          "description": "Unit appended to the stat value, e.g. \"%\"."
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label."
        },
        {
          "name": "ctaUrl",
          "type": "string",
          "description": "URL shown on the end card."
        }
      ],
      "usage": "import { Showcase } from \"@/remotion/compositions/showcase\";\n\n<Showcase title=\"Product story\" subtitle=\"Install source, compose scenes, render on your timeline\" statValue={3} statLabel=\"Runtime dependencies\" />",
      "related": [
        "transition-fade",
        "feature-list"
      ],
      "note": "Demo reel using TransitionSeries across multiple scenes.",
      "composition": {
        "id": "Showcase",
        "component": "Showcase",
        "durationInFrames": 240,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/showcase/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "hero-loop",
      "type": "registry:block",
      "description": "12-second seamless brand ident: the RemotionUI logo animated from its own parts over the site's phosphor light, with a transparent variant",
      "tasks": [
        "product-intro",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "core",
        "tags": [
          "hero",
          "website"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "gpu"
      ],
      "installCommand": "npx remotion-ui@latest add hero-loop",
      "docsUrl": "https://remotionui.com/docs/components/hero-loop",
      "registryUrl": "https://remotionui.com/r/presets/default/hero-loop.json",
      "detailUrl": "https://remotionui.com/ai/components/hero-loop.json",
      "importPath": "@/compositions/hero-loop",
      "installTarget": "src/compositions/hero-loop",
      "category": "composition",
      "props": [
        {
          "name": "background",
          "type": "\"phosphor\" | \"transparent\"",
          "default": "\"phosphor\"",
          "description": "Paint the gold phosphor stage, or nothing so the page shows through.",
          "schema": {
            "type": "string",
            "enum": [
              "phosphor",
              "transparent"
            ]
          }
        },
        {
          "name": "tone",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Page theme under the transparent variant; light inks the wordmark dark.",
          "schema": {
            "type": "string",
            "enum": [
              "dark",
              "light"
            ]
          }
        }
      ],
      "usage": "import { HeroLoop } from \"@/compositions/hero-loop\";\n\n<HeroLoop />\n<HeroLoop background=\"transparent\" tone=\"light\" />",
      "related": [
        "logo-reveal",
        "path-draw"
      ],
      "note": "12-second silent brand ident: the RemotionUI logo animated from its own parts (parallax frames, play press, wordmark re-reveal) over a port of the site's phosphor light. Loops without a seam. The light needs WebGL2 and falls back to a flat stage.",
      "composition": {
        "id": "HeroLoop",
        "component": "HeroLoop",
        "durationInFrames": 360,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/hero-loop/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caption-utils",
      "type": "registry:lib",
      "description": "Caption page grouping and word-active helpers",
      "tasks": [
        "captions"
      ],
      "dependencies": [
        "@remotion/captions"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add caption-utils",
      "docsUrl": "https://remotionui.com/docs/components/caption-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/caption-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/caption-utils.json",
      "importPath": "@/remotion/lib/caption-utils",
      "installTarget": "src/remotion/lib/caption-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audio-viz-utils",
      "type": "registry:lib",
      "description": "Windowed audio spectrum helpers",
      "tasks": [
        "audio"
      ],
      "dependencies": [
        "@remotion/media-utils",
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add audio-viz-utils",
      "docsUrl": "https://remotionui.com/docs/components/audio-viz-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/audio-viz-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/audio-viz-utils.json",
      "importPath": "@/remotion/lib/audio-viz-utils",
      "installTarget": "src/remotion/lib/audio-viz-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-utils",
      "type": "registry:lib",
      "description": "MapLibre and Turf geospatial helpers",
      "tasks": [
        "maps"
      ],
      "dependencies": [
        "maplibre-gl",
        "@turf/turf"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add map-utils",
      "docsUrl": "https://remotionui.com/docs/components/map-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/map-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/map-utils.json",
      "importPath": "@/remotion/lib/map-utils",
      "installTarget": "src/remotion/lib/map-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "path-utils",
      "type": "registry:lib",
      "description": "SVG path measuring, sampling, auto-fit and waypoint helpers",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "@remotion/paths"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add path-utils",
      "docsUrl": "https://remotionui.com/docs/components/path-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/path-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/path-utils.json",
      "importPath": "@/remotion/lib/path-utils",
      "installTarget": "src/remotion/lib/path-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caption-highlight",
      "type": "registry:ui",
      "description": "TikTok-style word-by-word caption highlight",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "caption-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add caption-highlight",
      "docsUrl": "https://remotionui.com/docs/components/caption-highlight",
      "registryUrl": "https://remotionui.com/r/presets/default/caption-highlight.json",
      "detailUrl": "https://remotionui.com/ai/components/caption-highlight.json",
      "importPath": "@/remotion/primitives/caption-highlight",
      "installTarget": "src/remotion/primitives/caption-highlight",
      "category": "primitive",
      "props": [
        {
          "name": "page",
          "type": "TikTokPage",
          "required": true,
          "description": "Caption page from createTikTokStyleCaptions.",
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "activeColor",
          "type": "string",
          "default": "\"#ff6b00\"",
          "description": "Highlight color for the active word.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "inactiveColor",
          "type": "string",
          "default": "\"#111111\"",
          "description": "Color for inactive words.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "64 (scaled)",
          "description": "Caption font size in pixels.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "fontWeight",
          "type": "number | string",
          "default": "650",
          "description": "Resting weight.",
          "schema": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ]
          }
        },
        {
          "name": "activeWeight",
          "type": "number | string",
          "default": "800",
          "description": "Weight the active word steps to.",
          "schema": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ]
          }
        },
        {
          "name": "emphasisScale",
          "type": "number",
          "default": "EMPHASIS.subtle (1.05)",
          "description": "Peak scale of the active word.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "textAlign",
          "type": "\"left\" | \"center\"",
          "default": "\"center\"",
          "description": "Line alignment.",
          "schema": {
            "type": "string",
            "enum": [
              "left",
              "center"
            ]
          }
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence.",
          "schema": {
            "type": "number"
          }
        }
      ],
      "usage": "import { CaptionHighlight } from \"@/remotion/primitives/caption-highlight\";\n\n<CaptionHighlight page={page} activeColor=\"#60a5fa\" />",
      "related": [
        "caption-scene",
        "caption-utils"
      ],
      "note": "Advanced. Installs @remotion/captions.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audiogram-bars",
      "type": "registry:ui",
      "description": "Audio-reactive spectrum bar visualization",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add audiogram-bars",
      "docsUrl": "https://remotionui.com/docs/components/audiogram-bars",
      "registryUrl": "https://remotionui.com/r/presets/default/audiogram-bars.json",
      "detailUrl": "https://remotionui.com/ai/components/audiogram-bars.json",
      "importPath": "@/remotion/primitives/audiogram-bars",
      "installTarget": "src/remotion/primitives/audiogram-bars",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Audio file URL or staticFile path."
        },
        {
          "name": "height",
          "type": "number",
          "default": "120",
          "description": "Bar container height."
        },
        {
          "name": "barColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Bar fill color."
        },
        {
          "name": "barColorEnd",
          "type": "string",
          "description": "Second color for a gradient across the spectrum. Defaults to barColor."
        },
        {
          "name": "barGap",
          "type": "number",
          "default": "3",
          "description": "Gap between bars in px."
        },
        {
          "name": "numberOfSamples",
          "type": "number",
          "default": "128",
          "description": "FFT size used to sample the spectrum."
        },
        {
          "name": "maxBarCount",
          "type": "number",
          "default": "48",
          "description": "Log-spaced bands drawn from the spectrum."
        },
        {
          "name": "align",
          "type": "\"bottom\" | \"center\"",
          "default": "\"bottom\"",
          "description": "Grow bars from the baseline or mirror them around it."
        },
        {
          "name": "showPeaks",
          "type": "boolean",
          "default": "true",
          "description": "Draw the decaying peak cap above each bar."
        },
        {
          "name": "showReflection",
          "type": "boolean",
          "default": "false",
          "description": "Faded mirrored copy below the baseline. Ignored when align is center."
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence."
        }
      ],
      "usage": "import { AudiogramBars } from \"@/remotion/primitives/audiogram-bars\";\n\n<AudiogramBars src={staticFile(\"podcast.wav\")} height={120} />",
      "related": [
        "audiogram-scene"
      ],
      "note": "Advanced. Installs @remotion/media-utils.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "path-draw",
      "type": "registry:ui",
      "description": "SVG stroke reveal with auto-fit framing, multi-path stagger and a drawing head",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/paths"
      ],
      "registryDependencies": [
        "path-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add path-draw",
      "docsUrl": "https://remotionui.com/docs/components/path-draw",
      "registryUrl": "https://remotionui.com/r/presets/default/path-draw.json",
      "detailUrl": "https://remotionui.com/ai/components/path-draw.json",
      "importPath": "@/remotion/primitives/path-draw",
      "installTarget": "src/remotion/primitives/path-draw",
      "category": "primitive",
      "props": [
        {
          "name": "d",
          "type": "string | string[]",
          "required": true,
          "description": "One path, or several drawn in order."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "60",
          "description": "Draw length for each path."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first path starts."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "8",
          "description": "Offset between paths when d is an array."
        },
        {
          "name": "stroke",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Stroke color."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "4",
          "description": "Stroke width in path units."
        },
        {
          "name": "width",
          "type": "number",
          "default": "200",
          "description": "Rendered SVG width in px."
        },
        {
          "name": "height",
          "type": "number",
          "default": "200",
          "description": "Rendered SVG height in px."
        },
        {
          "name": "viewBox",
          "type": "string",
          "description": "Omit to frame the artwork from its bounding box."
        },
        {
          "name": "fill",
          "type": "string",
          "description": "Fill flooded in once the stroke closes."
        },
        {
          "name": "head",
          "type": "boolean",
          "default": "true",
          "description": "Dot riding the tip while it draws."
        },
        {
          "name": "glow",
          "type": "boolean",
          "default": "true",
          "description": "Soft bloom around the stroke."
        }
      ],
      "usage": "import { PathDraw } from \"@/remotion/primitives/path-draw\";\n\n<PathDraw d={[\"M 20 180 L 100 20 L 180 180\", \"M 60 120 L 140 120\"]} durationInFrames={60} />",
      "related": [
        "logo-reveal",
        "cursor-path"
      ],
      "note": "Advanced. Installs @remotion/paths.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-canvas",
      "type": "registry:ui",
      "description": "Deterministic MapLibre map mount",
      "tasks": [
        "maps"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "maplibre-gl"
      ],
      "registryDependencies": [
        "map-utils",
        "motion-tokens",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add map-canvas",
      "docsUrl": "https://remotionui.com/docs/components/map-canvas",
      "registryUrl": "https://remotionui.com/r/presets/default/map-canvas.json",
      "detailUrl": "https://remotionui.com/ai/components/map-canvas.json",
      "importPath": "@/remotion/primitives/map-canvas",
      "installTarget": "src/remotion/primitives/map-canvas",
      "category": "primitive",
      "props": [
        {
          "name": "center",
          "type": "[number, number]",
          "required": true,
          "description": "Map center [lng, lat]."
        },
        {
          "name": "zoom",
          "type": "number",
          "default": "7",
          "description": "Initial zoom level."
        },
        {
          "name": "onMapReady",
          "type": "(map: Map) => void",
          "description": "Called when map is idle."
        }
      ],
      "usage": "import { MapCanvas } from \"@/remotion/primitives/map-canvas\";\n\n<MapCanvas center={[8.54, 47.38]} zoom={7} onMapReady={setMap} />",
      "related": [
        "map-route",
        "map-flight"
      ],
      "note": "Advanced. Installs maplibre-gl. Render with --gl=angle --concurrency=1.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-route",
      "type": "registry:ui",
      "description": "Animated GeoJSON route line on a map",
      "tasks": [
        "maps"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "maplibre-gl",
        "@turf/turf"
      ],
      "registryDependencies": [
        "map-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add map-route",
      "docsUrl": "https://remotionui.com/docs/components/map-route",
      "registryUrl": "https://remotionui.com/r/presets/default/map-route.json",
      "detailUrl": "https://remotionui.com/ai/components/map-route.json",
      "importPath": "@/remotion/primitives/map-route",
      "installTarget": "src/remotion/primitives/map-route",
      "category": "primitive",
      "props": [
        {
          "name": "map",
          "type": "Map | null",
          "required": true,
          "description": "MapLibre map instance."
        },
        {
          "name": "route",
          "type": "Feature<LineString>",
          "required": true,
          "description": "GeoJSON line to animate."
        },
        {
          "name": "progress",
          "type": "number",
          "description": "Route reveal progress 0–1."
        }
      ],
      "usage": "import { MapRoute } from \"@/remotion/primitives/map-route\";\n\n<MapRoute map={map} route={targetRoute} progress={0.5} />",
      "related": [
        "map-flight",
        "map-utils"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-markers",
      "type": "registry:ui",
      "description": "GeoJSON circle and label markers on a map",
      "tasks": [
        "maps"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "maplibre-gl"
      ],
      "registryDependencies": [
        "map-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add map-markers",
      "docsUrl": "https://remotionui.com/docs/components/map-markers",
      "registryUrl": "https://remotionui.com/r/presets/default/map-markers.json",
      "detailUrl": "https://remotionui.com/ai/components/map-markers.json",
      "importPath": "@/remotion/primitives/map-markers",
      "installTarget": "src/remotion/primitives/map-markers",
      "category": "primitive",
      "props": [
        {
          "name": "map",
          "type": "Map | null",
          "required": true,
          "description": "MapLibre map instance."
        },
        {
          "name": "markers",
          "type": "FeatureCollection<Point>",
          "required": true,
          "description": "GeoJSON points with name property."
        }
      ],
      "usage": "import { MapMarkers } from \"@/remotion/primitives/map-markers\";\n\n<MapMarkers map={map} markers={markerCollection} />",
      "related": [
        "map-flight"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-wipe",
      "type": "registry:ui",
      "description": "Wipe transition helper for TransitionSeries",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-wipe",
      "docsUrl": "https://remotionui.com/docs/components/transition-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-wipe.json",
      "importPath": "@/remotion/primitives/transition-wipe",
      "installTarget": "src/remotion/primitives/transition-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Transition overlap length."
        },
        {
          "name": "direction",
          "type": "string",
          "default": "\"from-left\"",
          "description": "Wipe direction."
        }
      ],
      "usage": "import { transitionWipe } from \"@/remotion/primitives/transition-wipe\";\n\n<TransitionSeries.Transition {...transitionWipe({ direction: \"from-left\" })} />",
      "related": [
        "transition-fade",
        "transition-clock-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-clock-wipe",
      "type": "registry:ui",
      "description": "Clock sweep that reads the composition size itself",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-clock-wipe",
      "docsUrl": "https://remotionui.com/docs/components/transition-clock-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-clock-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-clock-wipe.json",
      "importPath": "@/remotion/primitives/transition-clock-wipe",
      "installTarget": "src/remotion/primitives/transition-clock-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Transition overlap length."
        },
        {
          "name": "width",
          "type": "number",
          "description": "Sweep width. Defaults to the composition width."
        },
        {
          "name": "height",
          "type": "number",
          "description": "Sweep height. Defaults to the composition height."
        }
      ],
      "usage": "import { transitionClockWipe } from \"@/remotion/primitives/transition-clock-wipe\";\n\n<TransitionSeries.Transition {...transitionClockWipe({ width: 1920, height: 1080 })} />",
      "related": [
        "transition-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-light-leak",
      "type": "registry:ui",
      "description": "Film flare overlay that peaks on the cut and hides the seam under it",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/light-leaks"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add transition-light-leak",
      "docsUrl": "https://remotionui.com/docs/components/transition-light-leak",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-light-leak.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-light-leak.json",
      "importPath": "@/remotion/primitives/transition-light-leak",
      "installTarget": "src/remotion/primitives/transition-light-leak",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "description": "Length of the flare. Defaults to the overlay's own length."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "0",
          "description": "Light leak pattern seed."
        },
        {
          "name": "hueShift",
          "type": "number",
          "default": "28",
          "description": "Hue rotation in degrees, warm amber by default."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Peak opacity of the leak."
        },
        {
          "name": "peakAt",
          "type": "number",
          "default": "0.5",
          "description": "Where the flare peaks in its window. Sit it on the cut to hide the seam."
        },
        {
          "name": "blendMode",
          "type": "\"screen\" | \"plus-lighter\" | \"normal\"",
          "default": "\"screen\"",
          "description": "How the leak composites over the frame."
        }
      ],
      "usage": "import { TransitionLightLeak } from \"@/remotion/primitives/transition-light-leak\";\n\n<TransitionSeries.Overlay durationInFrames={30}>\n  <TransitionLightLeak seed={2} hueShift={45} />\n</TransitionSeries.Overlay>",
      "related": [
        "transition-fade"
      ],
      "note": "Advanced. Installs @remotion/light-leaks. Rendering needs the ANGLE backend: pass --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "blur-reveal",
      "type": "registry:ui",
      "description": "Cut where the outgoing scene softens away and the incoming one resolves out of blur",
      "tasks": [
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add blur-reveal",
      "docsUrl": "https://remotionui.com/docs/components/blur-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/blur-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/blur-reveal.json",
      "importPath": "@/remotion/primitives/blur-reveal",
      "installTarget": "src/remotion/primitives/blur-reveal",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Transition overlap length."
        },
        {
          "name": "maxBlur",
          "type": "number",
          "default": "24",
          "description": "Peak blur radius in px, reached only mid-transition."
        },
        {
          "name": "scaleBy",
          "type": "number",
          "default": "0.03",
          "description": "Scale headroom the blur rides on. 0 keeps the frame still."
        },
        {
          "name": "shouldBlurOutExitingScene",
          "type": "boolean",
          "default": "true",
          "description": "Blur the outgoing scene too. false holds it sharp underneath."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionBlurReveal } from \"@/remotion/primitives/blur-reveal\";\n\n<TransitionSeries.Transition {...transitionBlurReveal({ maxBlur: 24 })} />",
      "related": [
        "transition-fade",
        "frosted-glass-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "grid-pixelate-wipe",
      "type": "registry:ui",
      "description": "Reveal where the next scene arrives one grid cell at a time",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add grid-pixelate-wipe",
      "docsUrl": "https://remotionui.com/docs/components/grid-pixelate-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/grid-pixelate-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/grid-pixelate-wipe.json",
      "importPath": "@/remotion/primitives/grid-pixelate-wipe",
      "installTarget": "src/remotion/primitives/grid-pixelate-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Transition overlap length."
        },
        {
          "name": "cols",
          "type": "number",
          "default": "12",
          "description": "Grid column count."
        },
        {
          "name": "rows",
          "type": "number",
          "default": "8",
          "description": "Grid row count."
        },
        {
          "name": "order",
          "type": "\"from-left\" | \"from-top\" | \"diagonal\" | \"center\"",
          "default": "\"from-left\"",
          "description": "Which axis or point the cells light up from."
        },
        {
          "name": "shape",
          "type": "\"square\" | \"dot\"",
          "default": "\"square\"",
          "description": "Cells fill as blocks, or as points that grow with their own reveal."
        },
        {
          "name": "stagger",
          "type": "number",
          "default": "0.82",
          "description": "0 pops every cell together; 1 spreads them across the whole window."
        }
      ],
      "usage": "import { transitionGridPixelateWipe } from \"@/remotion/primitives/grid-pixelate-wipe\";\n\n<TransitionSeries.Transition {...transitionGridPixelateWipe({ cols: 12, rows: 8 })} />",
      "related": [
        "transition-wipe",
        "blur-reveal"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "frosted-glass-wipe",
      "type": "registry:ui",
      "description": "A pane of frosted glass crosses the frame and leaves the next scene behind it",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add frosted-glass-wipe",
      "docsUrl": "https://remotionui.com/docs/components/frosted-glass-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/frosted-glass-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/frosted-glass-wipe.json",
      "importPath": "@/remotion/primitives/frosted-glass-wipe",
      "installTarget": "src/remotion/primitives/frosted-glass-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Transition overlap length."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "20",
          "description": "Frost panel blur radius."
        },
        {
          "name": "panelWidth",
          "type": "number",
          "default": "0.14",
          "description": "Sweep panel width as fraction of frame."
        },
        {
          "name": "direction",
          "type": "\"from-left\" | \"from-right\" | \"from-top\" | \"from-bottom\"",
          "default": "\"from-left\"",
          "description": "Sweep direction."
        },
        {
          "name": "frostColor",
          "type": "string",
          "default": "\"rgba(255,255,255,0.12)\"",
          "description": "Tint of the glass panel."
        }
      ],
      "usage": "import { transitionFrostedGlassWipe } from \"@/remotion/primitives/frosted-glass-wipe\";\n\n<TransitionSeries.Transition {...transitionFrostedGlassWipe({ blur: 20 })} />",
      "related": [
        "blur-reveal",
        "transition-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "directional-wipe",
      "type": "registry:ui",
      "description": "Soft-edged wipe that uncovers the next scene without exposing the background",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add directional-wipe",
      "docsUrl": "https://remotionui.com/docs/components/directional-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/directional-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/directional-wipe.json",
      "importPath": "@/remotion/primitives/directional-wipe",
      "installTarget": "src/remotion/primitives/directional-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Transition overlap length."
        },
        {
          "name": "direction",
          "type": "\"from-left\" | \"from-right\" | \"from-top\" | \"from-bottom\"",
          "default": "\"from-left\"",
          "description": "Wipe direction."
        },
        {
          "name": "edgeSoftness",
          "type": "number",
          "default": "0.12",
          "description": "Soft edge width as a share of the frame. 0 cuts hard."
        },
        {
          "name": "depth",
          "type": "number",
          "default": "0.08",
          "description": "Parallax the scenes carry under the wipe."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionDirectionalWipe } from \"@/remotion/primitives/directional-wipe\";\n\n<TransitionSeries.Transition {...transitionDirectionalWipe({ direction: \"from-left\" })} />",
      "related": [
        "transition-wipe",
        "spatial-push"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "spatial-push",
      "type": "registry:ui",
      "description": "Push where both scenes travel locked edge to edge across the frame",
      "tasks": [
        "scene-overlays",
        "maps"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add spatial-push",
      "docsUrl": "https://remotionui.com/docs/components/spatial-push",
      "registryUrl": "https://remotionui.com/r/presets/default/spatial-push.json",
      "detailUrl": "https://remotionui.com/ai/components/spatial-push.json",
      "importPath": "@/remotion/primitives/spatial-push",
      "installTarget": "src/remotion/primitives/spatial-push",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Transition overlap length."
        },
        {
          "name": "direction",
          "type": "\"from-left\" | \"from-right\" | \"from-top\" | \"from-bottom\"",
          "default": "\"from-left\"",
          "description": "Push direction."
        },
        {
          "name": "pushDepth",
          "type": "number",
          "default": "1",
          "description": "Share of the frame each scene travels. Below 1 leaves background showing mid-push."
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "0",
          "description": "Degrees each panel rotates in 3D. Off by default: a tilted full-frame panel uncovers bare background."
        },
        {
          "name": "perspective",
          "type": "number",
          "default": "1200",
          "description": "Perspective distance in px, used when tilt is set."
        }
      ],
      "usage": "import { transitionSpatialPush } from \"@/remotion/primitives/spatial-push\";\n\n<TransitionSeries.Transition {...transitionSpatialPush()} />",
      "related": [
        "directional-wipe",
        "zoom-through"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "chromatic-aberration-wipe",
      "type": "registry:ui",
      "description": "Slide that pulls the colour channels apart at its fastest point and recombines them on landing",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add chromatic-aberration-wipe",
      "docsUrl": "https://remotionui.com/docs/components/chromatic-aberration-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/chromatic-aberration-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/chromatic-aberration-wipe.json",
      "importPath": "@/remotion/primitives/chromatic-aberration-wipe",
      "installTarget": "src/remotion/primitives/chromatic-aberration-wipe",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "14",
          "description": "Transition overlap length."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "12",
          "description": "Peak channel separation in px, reached in the middle of the cut."
        },
        {
          "name": "axis",
          "type": "\"horizontal\" | \"vertical\"",
          "default": "\"horizontal\"",
          "description": "Axis the scenes slide along and the channels separate on."
        },
        {
          "name": "slide",
          "type": "number",
          "default": "1",
          "description": "Share of the frame the scenes travel. Below 1 shows background."
        }
      ],
      "usage": "import { transitionChromaticAberrationWipe } from \"@/remotion/primitives/chromatic-aberration-wipe\";\n\n<TransitionSeries.Transition {...transitionChromaticAberrationWipe({ intensity: 12 })} />",
      "related": [
        "blur-reveal",
        "directional-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "zoom-through",
      "type": "registry:ui",
      "description": "Camera push-through: one scene drives past the lens, the next lands out of the same move",
      "tasks": [
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add zoom-through",
      "docsUrl": "https://remotionui.com/docs/components/zoom-through",
      "registryUrl": "https://remotionui.com/r/presets/default/zoom-through.json",
      "detailUrl": "https://remotionui.com/ai/components/zoom-through.json",
      "importPath": "@/remotion/primitives/zoom-through",
      "installTarget": "src/remotion/primitives/zoom-through",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Transition overlap length."
        },
        {
          "name": "maxScale",
          "type": "number",
          "default": "2.4",
          "description": "Scale the camera travels through."
        },
        {
          "name": "blurPeak",
          "type": "number",
          "default": "8",
          "description": "Blur radius in px at the fastest point of the move."
        },
        {
          "name": "direction",
          "type": "\"in\" | \"out\"",
          "default": "\"in\"",
          "description": "Push the camera through the frame, or pull back from it."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionZoomThrough } from \"@/remotion/primitives/zoom-through\";\n\n<TransitionSeries.Transition {...transitionZoomThrough({ maxScale: 2.4 })} />",
      "related": [
        "spatial-push",
        "blur-reveal"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "mesh-gradient-bg",
      "type": "registry:ui",
      "description": "Living mesh gradient blob background",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens",
        "gpu"
      ],
      "installCommand": "npx remotion-ui@latest add mesh-gradient-bg",
      "docsUrl": "https://remotionui.com/docs/components/mesh-gradient-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/mesh-gradient-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/mesh-gradient-bg.json",
      "importPath": "@/remotion/primitives/mesh-gradient-bg",
      "installTarget": "src/remotion/primitives/mesh-gradient-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Stage color."
        },
        {
          "name": "colors",
          "type": "[string, string, string]",
          "default": "[\"#e8b86d\", \"#e07a5f\", \"#c2557a\"]",
          "description": "Blob accent colors: solid hex, screen-blended over the stage."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Drift amplitude multiplier."
        }
      ],
      "usage": "import { MeshGradientBg } from \"@/remotion/primitives/mesh-gradient-bg\";\n\n<MeshGradientBg />",
      "related": [
        "dynamic-grid"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "dynamic-grid",
      "type": "registry:ui",
      "description": "Subtle drifting dot and line grid background",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add dynamic-grid",
      "docsUrl": "https://remotionui.com/docs/components/dynamic-grid",
      "registryUrl": "https://remotionui.com/r/presets/default/dynamic-grid.json",
      "detailUrl": "https://remotionui.com/ai/components/dynamic-grid.json",
      "importPath": "@/remotion/primitives/dynamic-grid",
      "installTarget": "src/remotion/primitives/dynamic-grid",
      "category": "primitive",
      "props": [
        {
          "name": "spacing",
          "type": "number",
          "default": "64",
          "description": "Grid cell size in px."
        },
        {
          "name": "lineColor",
          "type": "string",
          "default": "\"rgba(255,255,255,0.1)\"",
          "description": "Grid line color."
        },
        {
          "name": "sweepColor",
          "type": "string",
          "default": "\"rgba(232,184,109,0.55)\"",
          "description": "Diagonal light-sweep color."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "0.4",
          "description": "Grid drift speed in px per frame."
        },
        {
          "name": "sweepDurationInFrames",
          "type": "number",
          "default": "150",
          "description": "Frames for one full sweep loop."
        }
      ],
      "usage": "import { DynamicGrid } from \"@/remotion/primitives/dynamic-grid\";\n\n<DynamicGrid spacing={64} />",
      "related": [
        "mesh-gradient-bg"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "simulated-cursor",
      "type": "registry:ui",
      "description": "Frame-timed cursor with press, click ripples, hit targets and labels",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add simulated-cursor",
      "docsUrl": "https://remotionui.com/docs/components/simulated-cursor",
      "registryUrl": "https://remotionui.com/r/presets/default/simulated-cursor.json",
      "detailUrl": "https://remotionui.com/ai/components/simulated-cursor.json",
      "importPath": "@/remotion/primitives/simulated-cursor",
      "installTarget": "src/remotion/primitives/simulated-cursor",
      "category": "primitive",
      "props": [
        {
          "name": "points",
          "type": "Array<{ x: number; y: number; frame: number; label?: string; target?: number }>",
          "description": "Percent-based waypoints with arrival frames. `label` chips the point, `target` rings the hit area in px."
        },
        {
          "name": "clickFrames",
          "type": "number[]",
          "default": "[48]",
          "description": "Frames that press the pointer and fire a ripple."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#f4f4f5\"",
          "description": "Pointer fill."
        },
        {
          "name": "accent",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Ripple and target ring color."
        },
        {
          "name": "size",
          "type": "number",
          "default": "26",
          "description": "Cursor size in px."
        }
      ],
      "usage": "import { SimulatedCursor } from \"@/remotion/primitives/simulated-cursor\";\n\n<SimulatedCursor\n  points={[\n    { x: 20, y: 60, frame: 0 },\n    { x: 70, y: 40, frame: 30, target: 96, label: \"Render\" },\n  ]}\n  clickFrames={[32]}\n/>",
      "related": [
        "cursor-path",
        "tutorial-clip"
      ],
      "note": "Each hop runs its own spring, so the cursor decelerates into a target instead of gliding at a fixed rate.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "confetti-burst",
      "type": "registry:ui",
      "description": "Frame-driven confetti burst overlay",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add confetti-burst",
      "docsUrl": "https://remotionui.com/docs/components/confetti-burst",
      "registryUrl": "https://remotionui.com/r/presets/default/confetti-burst.json",
      "detailUrl": "https://remotionui.com/ai/components/confetti-burst.json",
      "importPath": "@/remotion/primitives/confetti-burst",
      "installTarget": "src/remotion/primitives/confetti-burst",
      "category": "primitive",
      "props": [
        {
          "name": "count",
          "type": "number",
          "default": "48",
          "description": "Particle count."
        },
        {
          "name": "originX",
          "type": "number",
          "default": "50",
          "description": "Burst origin X in percent."
        },
        {
          "name": "originY",
          "type": "number",
          "default": "42",
          "description": "Burst origin Y in percent."
        },
        {
          "name": "seed",
          "type": "string",
          "default": "\"confetti\"",
          "description": "Deterministic random seed."
        },
        {
          "name": "gravity",
          "type": "number",
          "default": "680",
          "description": "Downward acceleration in px/s². The default clears a 1080p frame in about two seconds; lower it to keep the confetti in shot for longer."
        },
        {
          "name": "drag",
          "type": "number",
          "default": "1.6",
          "description": "Air resistance on the outward throw, per second. Higher settles the spread sooner."
        }
      ],
      "usage": "import { ConfettiBurst } from \"@/remotion/primitives/confetti-burst\";\n\n<ConfettiBurst originX={50} originY={40} seed=\"launch\" />",
      "related": [
        "spring-in"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "device-mockup-zoom",
      "type": "registry:block",
      "description": "Cinematic laptop, phone, or browser mockup with staged UI and slow camera pullback",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens",
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add device-mockup-zoom",
      "docsUrl": "https://remotionui.com/docs/components/device-mockup-zoom",
      "registryUrl": "https://remotionui.com/r/presets/default/device-mockup-zoom.json",
      "detailUrl": "https://remotionui.com/ai/components/device-mockup-zoom.json",
      "importPath": "@/remotion/scenes/device-mockup-zoom",
      "installTarget": "src/remotion/scenes/device-mockup-zoom",
      "category": "scene",
      "props": [
        {
          "name": "src",
          "type": "string",
          "description": "Optional screen content image. When omitted, the scene renders a polished product dashboard mockup."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Optional headline. When omitted, the device remains the sole focal point."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Optional supporting line under the headline."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Optional accent label above the headline."
        },
        {
          "name": "device",
          "type": "\"phone\" | \"browser\" | \"laptop\"",
          "default": "\"laptop\"",
          "description": "Mockup shell. Laptop includes a physical base, browser renders chrome only, phone renders a handheld frame."
        },
        {
          "name": "children",
          "type": "React.ReactNode",
          "description": "Custom screen content rendered inside the device."
        }
      ],
      "usage": "import { DeviceMockupZoom } from \"@/remotion/scenes/device-mockup-zoom\";\n\n<DeviceMockupZoom src={staticFile(\"app.png\")} device=\"laptop\" />",
      "related": [
        "media-frame",
        "zoom-pan-frame"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caption-scene",
      "type": "registry:block",
      "description": "Lower-third TikTok-style captions synced to audio",
      "tasks": [
        "captions",
        "audio",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "caption-highlight",
        "caption-utils",
        "layout",
        "karaoke-captions",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add caption-scene",
      "docsUrl": "https://remotionui.com/docs/components/caption-scene",
      "registryUrl": "https://remotionui.com/r/presets/default/caption-scene.json",
      "detailUrl": "https://remotionui.com/ai/components/caption-scene.json",
      "importPath": "@/remotion/scenes/caption-scene",
      "installTarget": "src/remotion/scenes/caption-scene",
      "category": "scene",
      "props": [
        {
          "name": "captions",
          "type": "Caption[]",
          "required": true,
          "description": "Remotion caption array."
        },
        {
          "name": "combineTokensWithinMilliseconds",
          "type": "number",
          "default": "1200",
          "description": "Words per caption page."
        },
        {
          "name": "placement",
          "type": "\"lower-third\" | \"center\"",
          "default": "\"lower-third\"",
          "description": "Caption vertical placement."
        },
        {
          "name": "mode",
          "type": "\"highlight\" | \"karaoke-scale\" | \"karaoke-underline\"",
          "default": "\"highlight\"",
          "description": "Caption emphasis style."
        }
      ],
      "usage": "import { CaptionScene } from \"@/remotion/scenes/caption-scene\";\n\n<CaptionScene captions={captions} />",
      "related": [
        "caption-highlight",
        "social-clip"
      ],
      "note": "Advanced. Installs @remotion/captions.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audiogram-scene",
      "type": "registry:block",
      "description": "Podcast audiogram layout with spectrum bars",
      "tasks": [
        "audio",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audiogram-bars",
        "fade-in",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add audiogram-scene",
      "docsUrl": "https://remotionui.com/docs/components/audiogram-scene",
      "registryUrl": "https://remotionui.com/r/presets/default/audiogram-scene.json",
      "detailUrl": "https://remotionui.com/ai/components/audiogram-scene.json",
      "importPath": "@/remotion/scenes/audiogram-scene",
      "installTarget": "src/remotion/scenes/audiogram-scene",
      "category": "scene",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Audio file URL or staticFile path."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Episode title."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Optional subtitle."
        },
        {
          "name": "logoSrc",
          "type": "string",
          "description": "Optional brand mark above the title."
        }
      ],
      "usage": "import { AudiogramScene } from \"@/remotion/scenes/audiogram-scene\";\n\n<AudiogramScene src={staticFile(\"podcast.wav\")} title=\"Episode 1\" />",
      "related": [
        "audiogram-bars",
        "social-clip"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "logo-reveal",
      "type": "registry:block",
      "description": "Logo mark draw-on with wordmark and tagline beats",
      "tasks": [
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "path-draw",
        "layout",
        "motion-tokens",
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add logo-reveal",
      "docsUrl": "https://remotionui.com/docs/components/logo-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/logo-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/logo-reveal.json",
      "importPath": "@/remotion/scenes/logo-reveal",
      "installTarget": "src/remotion/scenes/logo-reveal",
      "category": "scene",
      "props": [
        {
          "name": "pathD",
          "type": "string | string[]",
          "required": true,
          "description": "Logo path, or paths drawn in sequence."
        },
        {
          "name": "viewBox",
          "type": "string",
          "description": "Omit to frame the mark automatically."
        },
        {
          "name": "size",
          "type": "number",
          "description": "Mark size in px. Defaults to a share of the short edge."
        },
        {
          "name": "wordmark",
          "type": "string",
          "description": "Brand name rising after the mark completes."
        },
        {
          "name": "tagline",
          "type": "string",
          "description": "Supporting line, entering last."
        },
        {
          "name": "stroke",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Mark stroke color."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "description": "Defaults to a share of the mark size."
        },
        {
          "name": "fill",
          "type": "string",
          "description": "Fill flooded into the mark after the draw."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Scene background."
        }
      ],
      "usage": "import { LogoReveal } from \"@/remotion/scenes/logo-reveal\";\n\n<LogoReveal pathD=\"M 100 20 L 180 180 L 20 180 Z\" wordmark=\"Acme\" tagline=\"Ship faster\" />",
      "related": [
        "path-draw",
        "title-card"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-flight",
      "type": "registry:block",
      "description": "Animated map flyover with route reveal and markers",
      "tasks": [
        "maps",
        "scenes"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "maplibre-gl",
        "@turf/turf"
      ],
      "registryDependencies": [
        "map-route",
        "map-markers",
        "map-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add map-flight",
      "docsUrl": "https://remotionui.com/docs/components/map-flight",
      "registryUrl": "https://remotionui.com/r/presets/default/map-flight.json",
      "detailUrl": "https://remotionui.com/ai/components/map-flight.json",
      "importPath": "@/remotion/scenes/map-flight",
      "installTarget": "src/remotion/scenes/map-flight",
      "category": "scene",
      "props": [
        {
          "name": "from",
          "type": "[number, number]",
          "description": "Start coordinates [lng, lat]."
        },
        {
          "name": "to",
          "type": "[number, number]",
          "description": "End coordinates [lng, lat]."
        },
        {
          "name": "fromLabel",
          "type": "string",
          "description": "Start marker label."
        },
        {
          "name": "toLabel",
          "type": "string",
          "description": "End marker label."
        }
      ],
      "usage": "import { MapFlight } from \"@/remotion/scenes/map-flight\";\n\n<MapFlight from={[8.54, 47.38]} to={[-74, 40.71]} fromLabel=\"Zurich\" toLabel=\"New York\" />",
      "related": [
        "map-canvas",
        "map-route",
        "map-markers"
      ],
      "note": "Render with npx remotion render --gl=angle --concurrency=1.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "auto-fit-title",
      "type": "registry:block",
      "description": "Headline sized to the frame it is given, then assembled word by word so any length lands the same way",
      "tasks": [
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "data",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "text-fit-utils"
      ],
      "installCommand": "npx remotion-ui@latest add auto-fit-title",
      "docsUrl": "https://remotionui.com/docs/components/auto-fit-title",
      "registryUrl": "https://remotionui.com/r/presets/default/auto-fit-title.json",
      "detailUrl": "https://remotionui.com/ai/components/auto-fit-title.json",
      "importPath": "@/remotion/scenes/auto-fit-title",
      "installTarget": "src/remotion/scenes/auto-fit-title",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "required": true,
          "description": "Headline, fitted to the safe area whatever its length."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Subtitle; scales with the fitted headline."
        },
        {
          "name": "logoSrc",
          "type": "string",
          "description": "Brand mark above the headline."
        },
        {
          "name": "logoSize",
          "type": "number",
          "description": "Logo size in composition pixels."
        },
        {
          "name": "maxFontSize",
          "type": "number",
          "default": "128",
          "description": "Ceiling for the fitted size, at a 1080-wide stage."
        },
        {
          "name": "minFontSize",
          "type": "number",
          "default": "34",
          "description": "Floor for the fitted size."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Background glow colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds before the card fades and lifts away. Omit to hold. Inside a TransitionSeries, set it so the exit finishes before the cut begins."
        }
      ],
      "usage": "import { AutoFitTitle } from \"@/remotion/scenes/auto-fit-title\";\n\n<AutoFitTitle title=\"Headlines that always fit\" subtitle=\"Any resolution\" />",
      "related": [
        "title-card",
        "social-clip"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "social-clip",
      "type": "registry:block",
      "description": "9:16 social clip with hook, captions, and CTA",
      "tasks": [
        "captions",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions",
        "@remotion/captions",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "transition-fade",
        "auto-fit-title",
        "audiogram-scene",
        "caption-scene",
        "end-card",
        "motion-tokens",
        "sample-media"
      ],
      "installCommand": "npx remotion-ui@latest add social-clip",
      "docsUrl": "https://remotionui.com/docs/components/social-clip",
      "registryUrl": "https://remotionui.com/r/presets/default/social-clip.json",
      "detailUrl": "https://remotionui.com/ai/components/social-clip.json",
      "importPath": "@/compositions/social-clip",
      "installTarget": "src/compositions/social-clip",
      "category": "composition",
      "props": [
        {
          "name": "audioSrc",
          "type": "string",
          "required": true,
          "description": "Podcast audio source.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "captions",
          "type": "Caption[]",
          "required": true,
          "description": "Synced caption array.",
          "schema": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        {
          "name": "hookTitle",
          "type": "string",
          "description": "Opening hook headline.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "hookSubtitle",
          "type": "string",
          "description": "Supporting line under the hook.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "podcastTitle",
          "type": "string",
          "default": "\"Weekly Brief\"",
          "description": "Show name shown over the audiogram body.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "logoSrc",
          "type": "string",
          "description": "Optional brand mark shown in hook, body, and end card.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "ctaTitle",
          "type": "string",
          "default": "\"Hear the full episode\"",
          "description": "End card headline.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "ctaUrl",
          "type": "string",
          "description": "URL shown on the end card.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "usage": "import { SocialClip } from \"@/compositions/social-clip\";\n\n<SocialClip audioSrc={staticFile(\"podcast.wav\")} captions={captions} />",
      "related": [
        "caption-scene",
        "audiogram-scene",
        "auto-fit-title"
      ],
      "note": "9:16 social template (1080×1920). Advanced tier.",
      "composition": {
        "id": "SocialClip",
        "component": "SocialClip",
        "durationInFrames": 216,
        "fps": 30,
        "width": 1080,
        "height": 1920,
        "importPath": "@/compositions/social-clip/index"
      },
      "compat": {
        "remotion": "^4.0.0"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "media-utils",
      "type": "registry:lib",
      "description": "Media item timing and fit helpers",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add media-utils",
      "docsUrl": "https://remotionui.com/docs/components/media-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/media-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/media-utils.json",
      "importPath": "@/remotion/lib/media-utils",
      "installTarget": "src/remotion/lib/media-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "chart-utils",
      "type": "registry:lib",
      "description": "Chart scaling and SVG path helpers",
      "tasks": [
        "data"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add chart-utils",
      "docsUrl": "https://remotionui.com/docs/components/chart-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/chart-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/chart-utils.json",
      "importPath": "@/remotion/lib/chart-utils",
      "installTarget": "src/remotion/lib/chart-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-fit-utils",
      "type": "registry:lib",
      "description": "Safe headline fitting helpers",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add text-fit-utils",
      "docsUrl": "https://remotionui.com/docs/components/text-fit-utils",
      "registryUrl": "https://remotionui.com/r/presets/default/text-fit-utils.json",
      "detailUrl": "https://remotionui.com/ai/components/text-fit-utils.json",
      "importPath": "@/remotion/lib/text-fit-utils",
      "installTarget": "src/remotion/lib/text-fit-utils",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "waveform-line",
      "type": "registry:ui",
      "description": "Audio waveform line visualization",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add waveform-line",
      "docsUrl": "https://remotionui.com/docs/components/waveform-line",
      "registryUrl": "https://remotionui.com/r/presets/default/waveform-line.json",
      "detailUrl": "https://remotionui.com/ai/components/waveform-line.json",
      "importPath": "@/remotion/primitives/waveform-line",
      "installTarget": "src/remotion/primitives/waveform-line",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Audio source."
        },
        {
          "name": "width",
          "type": "number",
          "description": "Drawing width. Defaults to the composition width; pass the slot width inside padding."
        },
        {
          "name": "height",
          "type": "number",
          "default": "144",
          "description": "SVG waveform height."
        },
        {
          "name": "variant",
          "type": "\"envelope\" | \"line\"",
          "default": "\"envelope\"",
          "description": "Mirrored amplitude band, or the raw oscilloscope trace."
        },
        {
          "name": "samples",
          "type": "number",
          "default": "88 / 128",
          "description": "Envelope buckets (88) or trace samples (128)."
        },
        {
          "name": "windowInSeconds",
          "type": "number",
          "default": "1.2",
          "description": "Audio window drawn around the current frame."
        },
        {
          "name": "mirror",
          "type": "boolean",
          "default": "false",
          "description": "Reflected copy of the trace. Ignored by the envelope variant, which is already mirrored."
        },
        {
          "name": "progress",
          "type": "number",
          "description": "Optional 0-1 played progress override."
        },
        {
          "name": "amplitudeScale",
          "type": "number",
          "default": "0.94 / 0.48",
          "description": "Vertical gain: envelope default 0.94, line default 0.48."
        },
        {
          "name": "normalize",
          "type": "boolean",
          "default": "true",
          "description": "Normalize the visible window for readable quiet audio."
        },
        {
          "name": "showBaseline",
          "type": "boolean",
          "default": "true",
          "description": "Render the center baseline."
        }
      ],
      "usage": "import { WaveformLine } from \"@/remotion/primitives/waveform-line\";\n\n<WaveformLine src={staticFile(\"voice.wav\")} />",
      "related": [
        "audiogram-bars",
        "audio-pulse"
      ],
      "note": "Advanced. Installs @remotion/media-utils.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audio-pulse",
      "type": "registry:ui",
      "description": "Audio-reactive pulse rings",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add audio-pulse",
      "docsUrl": "https://remotionui.com/docs/components/audio-pulse",
      "registryUrl": "https://remotionui.com/r/presets/default/audio-pulse.json",
      "detailUrl": "https://remotionui.com/ai/components/audio-pulse.json",
      "importPath": "@/remotion/primitives/audio-pulse",
      "installTarget": "src/remotion/primitives/audio-pulse",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Audio source."
        },
        {
          "name": "size",
          "type": "number",
          "default": "240",
          "description": "Pulse diameter in px."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Ring and core color."
        },
        {
          "name": "ringCount",
          "type": "number",
          "default": "3",
          "description": "Number of reactive rings."
        },
        {
          "name": "sensitivity",
          "type": "number",
          "default": "1",
          "description": "Multiplier on the measured level before it drives the rings."
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence."
        }
      ],
      "usage": "import { AudioPulse } from \"@/remotion/primitives/audio-pulse\";\n\n<AudioPulse src={staticFile(\"voice.wav\")} />",
      "related": [
        "waveform-line",
        "audiogram-scene"
      ],
      "note": "Advanced. Installs @remotion/media-utils.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "karaoke-captions",
      "type": "registry:ui",
      "description": "Active-word karaoke caption styling",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "caption-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add karaoke-captions",
      "docsUrl": "https://remotionui.com/docs/components/karaoke-captions",
      "registryUrl": "https://remotionui.com/r/presets/default/karaoke-captions.json",
      "detailUrl": "https://remotionui.com/ai/components/karaoke-captions.json",
      "importPath": "@/remotion/primitives/karaoke-captions",
      "installTarget": "src/remotion/primitives/karaoke-captions",
      "category": "primitive",
      "props": [
        {
          "name": "page",
          "type": "TikTokPage",
          "required": true,
          "description": "Caption page from @remotion/captions."
        },
        {
          "name": "mode",
          "type": "\"scale\" | \"underline\"",
          "default": "\"underline\"",
          "description": "Active word emphasis style. Both modes also pop and lift the word."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "66 (scaled)",
          "description": "Caption size in px."
        },
        {
          "name": "fontWeight",
          "type": "number | string",
          "default": "800",
          "description": "Caption weight."
        },
        {
          "name": "emphasisScale",
          "type": "number",
          "default": "EMPHASIS.subtle (1.05)",
          "description": "Peak scale of the active word."
        },
        {
          "name": "activeColor",
          "type": "string",
          "default": "\"#ff6b00\"",
          "description": "Color the active word crosses to."
        },
        {
          "name": "completedColor",
          "type": "string",
          "default": "\"#111111\"",
          "description": "Color for words already spoken."
        },
        {
          "name": "inactiveColor",
          "type": "string",
          "default": "\"rgba(17,17,17,0.32)\"",
          "description": "Color for words not yet spoken."
        },
        {
          "name": "trackColor",
          "type": "string",
          "description": "Underline track behind the wipe. Defaults to inactiveColor."
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence."
        }
      ],
      "usage": "import { KaraokeCaptions } from \"@/remotion/primitives/karaoke-captions\";\n\n<KaraokeCaptions page={page} mode=\"scale\" />",
      "related": [
        "caption-highlight",
        "caption-scene"
      ],
      "note": "Use with caption-utils groupCaptionsIntoPages().",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "line-chart-draw",
      "type": "registry:ui",
      "description": "SVG line chart that draws itself on",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/paths"
      ],
      "registryDependencies": [
        "chart-utils",
        "path-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add line-chart-draw",
      "docsUrl": "https://remotionui.com/docs/components/line-chart-draw",
      "registryUrl": "https://remotionui.com/r/presets/default/line-chart-draw.json",
      "detailUrl": "https://remotionui.com/ai/components/line-chart-draw.json",
      "importPath": "@/remotion/primitives/line-chart-draw",
      "installTarget": "src/remotion/primitives/line-chart-draw",
      "category": "primitive",
      "props": [
        {
          "name": "points",
          "type": "ChartPoint[]",
          "required": true,
          "description": "Chart points. `label` supplies the x-axis tick."
        },
        {
          "name": "width",
          "type": "number",
          "description": "Drawing width. Defaults to the composition width; pass the slot width inside padding."
        },
        {
          "name": "height",
          "type": "number",
          "description": "Drawing height. Defaults to 40% of the composition height."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Line, area and dot colour."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "description": "Line weight. Scales with the chart width by default."
        },
        {
          "name": "variant",
          "type": "\"smooth\" | \"linear\"",
          "default": "\"smooth\"",
          "description": "Clamped cardinal spline, or straight segments."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and value labels on rounded ticks."
        },
        {
          "name": "showXLabels",
          "type": "boolean",
          "default": "true",
          "description": "Category labels under the plot."
        },
        {
          "name": "showArea",
          "type": "boolean",
          "default": "true",
          "description": "Gradient fill, wiped in with the draw."
        },
        {
          "name": "showDots",
          "type": "boolean",
          "default": "true",
          "description": "Dot deposited on each point as the line passes it."
        },
        {
          "name": "showHead",
          "type": "boolean",
          "default": "true",
          "description": "Glowing dot riding the tip while the line draws."
        },
        {
          "name": "showEndLabel",
          "type": "boolean",
          "default": "false",
          "description": "Value callout on the final point."
        },
        {
          "name": "includeZero",
          "type": "boolean",
          "default": "true",
          "description": "Anchor the axis at zero. Turn off for sparklines."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "description": "Formats axis ticks and the end label."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "70",
          "description": "Draw-on duration."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Delay before the draw starts."
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence."
        }
      ],
      "usage": "import { LineChartDraw } from \"@/remotion/primitives/line-chart-draw\";\n\n<LineChartDraw\n  points={[\n    { x: 0, y: 12000, label: \"Jan\" },\n    { x: 1, y: 24000, label: \"Feb\" },\n  ]}\n/>",
      "related": [
        "animated-bar-chart",
        "metric-ticker",
        "path-draw"
      ],
      "note": "Advanced. Installs @remotion/paths.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "cursor-path",
      "type": "registry:ui",
      "description": "Cursor travelling a path with drawn trail and click ripples",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/paths"
      ],
      "registryDependencies": [
        "path-utils",
        "motion-tokens",
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add cursor-path",
      "docsUrl": "https://remotionui.com/docs/components/cursor-path",
      "registryUrl": "https://remotionui.com/r/presets/default/cursor-path.json",
      "detailUrl": "https://remotionui.com/ai/components/cursor-path.json",
      "importPath": "@/remotion/primitives/cursor-path",
      "installTarget": "src/remotion/primitives/cursor-path",
      "category": "primitive",
      "props": [
        {
          "name": "points",
          "type": "{ x: number; y: number }[]",
          "description": "Route waypoints in the parent's coordinates."
        },
        {
          "name": "d",
          "type": "string",
          "description": "Authored SVG path to follow instead of points."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "90",
          "description": "Travel duration."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the cursor sets off."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Trail and ripple color."
        },
        {
          "name": "size",
          "type": "number",
          "default": "34",
          "description": "Cursor size in px."
        },
        {
          "name": "smoothing",
          "type": "number",
          "default": "0.6",
          "description": "0 hops in straight lines; higher rounds corners."
        },
        {
          "name": "trail",
          "type": "\"draw\" | \"guide\" | \"none\"",
          "default": "\"draw\"",
          "description": "Reveal the route behind the cursor, show it up front, or hide it."
        },
        {
          "name": "clickAt",
          "type": "number[]",
          "description": "Waypoint indices that ripple as the cursor arrives."
        }
      ],
      "usage": "import { CursorPath } from \"@/remotion/primitives/cursor-path\";\n\n<CursorPath points={[{ x: 80, y: 120 }, { x: 320, y: 80 }]} clickAt={[1]} />",
      "related": [
        "simulated-cursor",
        "callout-spotlight",
        "zoom-pan-frame"
      ],
      "note": "Advanced. Installs @remotion/paths.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "media-frame",
      "type": "registry:block",
      "description": "One piece of media presented: the frame opens like a shutter under a slow push, then the title masks up and the caption settles",
      "tasks": [
        "captions",
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/media"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add media-frame",
      "docsUrl": "https://remotionui.com/docs/components/media-frame",
      "registryUrl": "https://remotionui.com/r/presets/default/media-frame.json",
      "detailUrl": "https://remotionui.com/ai/components/media-frame.json",
      "importPath": "@/remotion/scenes/media-frame",
      "installTarget": "src/remotion/scenes/media-frame",
      "category": "scene",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Image or video source."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Headline above the frame; masks up out of its own line."
        },
        {
          "name": "caption",
          "type": "string",
          "description": "Supporting line under the frame."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above the title."
        },
        {
          "name": "fit",
          "type": "\"cover\" | \"contain\"",
          "default": "\"contain\"",
          "description": "Media object-fit behaviour. Use contain for UI screenshots."
        },
        {
          "name": "aspect",
          "type": "number",
          "default": "16 / 9",
          "description": "Aspect the frame is cut to, so contain media fills it."
        },
        {
          "name": "radius",
          "type": "number",
          "description": "Corner radius in composition pixels."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Rim light and eyebrow colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { MediaFrame } from \"@/remotion/scenes/media-frame\";\n\n<MediaFrame src={staticFile(\"demo.png\")} title=\"Product demo\" />",
      "related": [
        "media-sequence",
        "split-screen"
      ],
      "note": "Advanced. Installs @remotion/media for video sources.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "media-sequence",
      "type": "registry:block",
      "description": "Edited run of shots pushed on one after another, with a chapter strip that fills through the item playing",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens",
        "media-frame",
        "transition-fade",
        "transition-slide"
      ],
      "installCommand": "npx remotion-ui@latest add media-sequence",
      "docsUrl": "https://remotionui.com/docs/components/media-sequence",
      "registryUrl": "https://remotionui.com/r/presets/default/media-sequence.json",
      "detailUrl": "https://remotionui.com/ai/components/media-sequence.json",
      "importPath": "@/remotion/scenes/media-sequence",
      "installTarget": "src/remotion/scenes/media-sequence",
      "category": "scene",
      "props": [
        {
          "name": "items",
          "type": "MediaItem[]",
          "required": true,
          "description": "Timed media items."
        },
        {
          "name": "defaultDurationInFrames",
          "type": "number",
          "default": "78",
          "description": "Length of an item that sets no duration of its own."
        },
        {
          "name": "transitionDurationInFrames",
          "type": "number",
          "default": "14",
          "description": "Overlap between neighbouring items."
        },
        {
          "name": "transition",
          "type": "\"slide\" | \"fade\"",
          "default": "\"slide\"",
          "description": "Push the next item on, or dissolve to it."
        },
        {
          "name": "showProgress",
          "type": "boolean",
          "default": "true",
          "description": "Chapter strip along the foot."
        },
        {
          "name": "aspect",
          "type": "number",
          "default": "16 / 9",
          "description": "Aspect the frames are cut to."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Strip fill and frame rim colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        }
      ],
      "usage": "import { MediaSequence } from \"@/remotion/scenes/media-sequence\";\n\n<MediaSequence items={[{ src: staticFile(\"one.png\"), title: \"Hook\" }]} />",
      "related": [
        "media-frame",
        "tutorial-clip"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "split-screen",
      "type": "registry:block",
      "description": "Before/after that is actually made: panels meet at the divider, labels land, and the divider can travel across to leave one side whole",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/media"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add split-screen",
      "docsUrl": "https://remotionui.com/docs/components/split-screen",
      "registryUrl": "https://remotionui.com/r/presets/default/split-screen.json",
      "detailUrl": "https://remotionui.com/ai/components/split-screen.json",
      "importPath": "@/remotion/scenes/split-screen",
      "installTarget": "src/remotion/scenes/split-screen",
      "category": "scene",
      "props": [
        {
          "name": "left",
          "type": "SplitScreenPanel",
          "required": true,
          "description": "Left panel: { src, label, fit }."
        },
        {
          "name": "right",
          "type": "SplitScreenPanel",
          "required": true,
          "description": "Right panel; sits underneath so the wipe uncovers it."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Headline above the comparison."
        },
        {
          "name": "wipeAtSeconds",
          "type": "number",
          "description": "When the divider travels right to leave the right panel whole."
        },
        {
          "name": "split",
          "type": "number",
          "default": "0.5",
          "description": "Where the divider rests before any wipe, 0–1."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Divider and label colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { SplitScreen } from \"@/remotion/scenes/split-screen\";\n\n<SplitScreen left={{ src: before }} right={{ src: after }} />",
      "related": [
        "media-frame",
        "b-roll-stack"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "b-roll-stack",
      "type": "registry:block",
      "description": "Deck of supporting shots dealt one at a time: each rides to the front with its label while the last slides back into the stack",
      "tasks": [
        "transitions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/media"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add b-roll-stack",
      "docsUrl": "https://remotionui.com/docs/components/b-roll-stack",
      "registryUrl": "https://remotionui.com/r/presets/default/b-roll-stack.json",
      "detailUrl": "https://remotionui.com/ai/components/b-roll-stack.json",
      "importPath": "@/remotion/scenes/b-roll-stack",
      "installTarget": "src/remotion/scenes/b-roll-stack",
      "category": "scene",
      "props": [
        {
          "name": "items",
          "type": "BRollItem[]",
          "description": "Image or video cards to layer. Omit for styled placeholders."
        },
        {
          "name": "kicker",
          "type": "string",
          "default": "\"Supporting visuals\"",
          "description": "Short label above the headline."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Scene headline."
        },
        {
          "name": "caption",
          "type": "string",
          "description": "Supporting copy below the headline."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "default": "1.35",
          "description": "Seconds a shot holds at the front before the deck advances."
        },
        {
          "name": "aspect",
          "type": "number",
          "default": "16 / 9",
          "description": "Aspect the cards are cut to."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Kicker, card rim, and label colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { BRollStack } from \"@/remotion/scenes/b-roll-stack\";\n\n<BRollStack\n  kicker=\"Cutaway\"\n  title=\"Layer proof shots behind the narration\"\n  items={[{ src: staticFile(\"shot.png\"), title: \"Proof\", fit: \"cover\" }]}\n/>",
      "related": [
        "media-frame",
        "media-sequence"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caption-bumper",
      "type": "registry:block",
      "description": "Between-beats card that punches its line in word by word, draws a rule under it, and wipes out when its hold is over",
      "tasks": [
        "captions",
        "transitions",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "data",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "text-fit-utils"
      ],
      "installCommand": "npx remotion-ui@latest add caption-bumper",
      "docsUrl": "https://remotionui.com/docs/components/caption-bumper",
      "registryUrl": "https://remotionui.com/r/presets/default/caption-bumper.json",
      "detailUrl": "https://remotionui.com/ai/components/caption-bumper.json",
      "importPath": "@/remotion/scenes/caption-bumper",
      "installTarget": "src/remotion/scenes/caption-bumper",
      "category": "scene",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "The line the bumper exists to land."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above it (segment, chapter, timestamp)."
        },
        {
          "name": "maxFontSize",
          "type": "number",
          "default": "84",
          "description": "Largest type size at a 1280-wide stage."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds before the card wipes out. Omit to hold to the end."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#F472B6\"",
          "description": "Ground, eyebrow, and rule colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CaptionBumper } from \"@/remotion/scenes/caption-bumper\";\n\n<CaptionBumper text=\"This is the key moment.\" />",
      "related": [
        "karaoke-captions",
        "data-story"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "animated-bar-chart",
      "type": "registry:block",
      "description": "Ranked bar chart scene with a value axis",
      "tasks": [
        "data",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "chart-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add animated-bar-chart",
      "docsUrl": "https://remotionui.com/docs/components/animated-bar-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/animated-bar-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/animated-bar-chart.json",
      "importPath": "@/remotion/scenes/animated-bar-chart",
      "installTarget": "src/remotion/scenes/animated-bar-chart",
      "category": "scene",
      "props": [
        {
          "name": "data",
          "type": "ChartDatum[]",
          "required": true,
          "description": "Bar labels and values. Optional `color` and `delta` per bar."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Scene headline."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line under the title."
        },
        {
          "name": "maxValue",
          "type": "number",
          "description": "Fixed axis top. Defaults to a rounded domain above the largest bar."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "default": "formatCompactNumber",
          "description": "Formats the value on the end of each bar."
        },
        {
          "name": "highlightLabel",
          "type": "string",
          "description": "Label of the bar that carries accentColor."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and the value axis under the bars."
        },
        {
          "name": "maxBars",
          "type": "number",
          "default": "6",
          "description": "Bars beyond this count are dropped rather than squeezed."
        },
        {
          "name": "barColor",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Series colour."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Colour for the highlighted bar."
        }
      ],
      "usage": "import { AnimatedBarChart } from \"@/remotion/scenes/animated-bar-chart\";\n\n<AnimatedBarChart\n  title=\"Views by format\"\n  data={[{ label: \"Shorts\", value: 124000, delta: \"+32%\" }]}\n  highlightLabel=\"Shorts\"\n/>",
      "related": [
        "metric-ticker",
        "line-chart-draw",
        "data-story"
      ],
      "note": "Bars and their counters share one spring, so the number never leads the bar.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "metric-ticker",
      "type": "registry:block",
      "description": "KPI cards that count themselves in",
      "tasks": [
        "data",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts",
          "metrics"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/paths",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "line-chart-draw",
        "chart-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add metric-ticker",
      "docsUrl": "https://remotionui.com/docs/components/metric-ticker",
      "registryUrl": "https://remotionui.com/r/presets/default/metric-ticker.json",
      "detailUrl": "https://remotionui.com/ai/components/metric-ticker.json",
      "importPath": "@/remotion/scenes/metric-ticker",
      "installTarget": "src/remotion/scenes/metric-ticker",
      "category": "scene",
      "props": [
        {
          "name": "metrics",
          "type": "MetricTickerItem[]",
          "required": true,
          "description": "Metric cards: label, value, and optional from, prefix, suffix, delta, trend, color. Set from above value for a metric that counts down."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Scene title."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Short label above the title."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "default": "formatCompactNumber",
          "description": "Formats the counted value."
        },
        {
          "name": "maxCards",
          "type": "number",
          "default": "4",
          "description": "Cards beyond this count are dropped rather than squeezed."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Value colour, overridable per metric."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Scene background."
        }
      ],
      "usage": "import { MetricTicker } from \"@/remotion/scenes/metric-ticker\";\n\n<MetricTicker\n  title=\"Channel momentum\"\n  metrics={[\n    { label: \"Views\", value: 124000, delta: \"+18%\", trend: [62, 84, 96, 124] },\n  ]}\n/>",
      "related": [
        "animated-bar-chart",
        "line-chart-draw",
        "data-story"
      ],
      "note": "A signed delta (+/-) picks the arrow, the chip colour, and the sparkline tint.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "timeline-steps",
      "type": "registry:block",
      "description": "Process walked step by step: the rail draws ahead of a travelling head that lands on each step, works it through a closing ring, then checks it off",
      "tasks": [
        "data",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add timeline-steps",
      "docsUrl": "https://remotionui.com/docs/components/timeline-steps",
      "registryUrl": "https://remotionui.com/r/presets/default/timeline-steps.json",
      "detailUrl": "https://remotionui.com/ai/components/timeline-steps.json",
      "importPath": "@/remotion/scenes/timeline-steps",
      "installTarget": "src/remotion/scenes/timeline-steps",
      "category": "scene",
      "props": [
        {
          "name": "steps",
          "type": "TimelineStep[]",
          "required": true,
          "description": "Steps in order; up to five are walked."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Heading above the rail."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above the heading."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Rail, node, and check colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { TimelineSteps } from \"@/remotion/scenes/timeline-steps\";\n\n<TimelineSteps steps={[{ title: \"Record\" }, { title: \"Render\" }]} />",
      "related": [
        "data-story",
        "feature-list"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "callout-spotlight",
      "type": "registry:block",
      "description": "Spotlight that is aimed: the mask closes from the whole frame onto the target, a ring pings it, then a connector draws out to the callout",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add callout-spotlight",
      "docsUrl": "https://remotionui.com/docs/components/callout-spotlight",
      "registryUrl": "https://remotionui.com/r/presets/default/callout-spotlight.json",
      "detailUrl": "https://remotionui.com/ai/components/callout-spotlight.json",
      "importPath": "@/remotion/scenes/callout-spotlight",
      "installTarget": "src/remotion/scenes/callout-spotlight",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "required": true,
          "description": "Callout headline."
        },
        {
          "name": "kicker",
          "type": "string",
          "description": "Small label above the headline."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line below the headline."
        },
        {
          "name": "target",
          "type": "SpotlightTarget",
          "required": true,
          "description": "Region to spotlight, in source pixels; clamped to the safe area. The card flips above it when bottom clearance is low."
        },
        {
          "name": "backgroundSrc",
          "type": "string",
          "description": "Screenshot or capture under the spotlight."
        },
        {
          "name": "sourceWidth",
          "type": "number",
          "description": "Size the target was measured against. Defaults to the composition."
        },
        {
          "name": "sourceHeight",
          "type": "number",
          "description": "As above, vertically."
        },
        {
          "name": "dim",
          "type": "number",
          "default": "0.72",
          "description": "How far the rest of the frame is knocked back, 0–1."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Outline, ping, and connector colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CalloutSpotlight } from \"@/remotion/scenes/callout-spotlight\";\n\n<CalloutSpotlight kicker=\"Tutorial\" title=\"Click export\" target={{ x: 320, y: 180, width: 420, height: 180 }} />",
      "related": [
        "zoom-pan-frame",
        "tutorial-clip"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "zoom-pan-frame",
      "type": "registry:block",
      "description": "Camera move on a still driven by focal points, settling before the cut, with an optional label chip",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/media"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add zoom-pan-frame",
      "docsUrl": "https://remotionui.com/docs/components/zoom-pan-frame",
      "registryUrl": "https://remotionui.com/r/presets/default/zoom-pan-frame.json",
      "detailUrl": "https://remotionui.com/ai/components/zoom-pan-frame.json",
      "importPath": "@/remotion/scenes/zoom-pan-frame",
      "installTarget": "src/remotion/scenes/zoom-pan-frame",
      "category": "scene",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Image or video source."
        },
        {
          "name": "from",
          "type": "FocalPoint",
          "description": "Where the move starts: { x, y, scale } with x/y in 0–1."
        },
        {
          "name": "to",
          "type": "FocalPoint",
          "description": "Where the move lands. Defaults to a centred 1.24 push."
        },
        {
          "name": "moveInFrames",
          "type": "number",
          "description": "Length of the move. Defaults to the composition minus a short settle."
        },
        {
          "name": "label",
          "type": "string",
          "description": "Chip that rises once the move lands."
        },
        {
          "name": "vignette",
          "type": "number",
          "default": "0.34",
          "description": "Corner darkening; 0 turns it off."
        },
        {
          "name": "fit",
          "type": "\"cover\" | \"contain\"",
          "default": "\"cover\"",
          "description": "Media object-fit behaviour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        }
      ],
      "usage": "import { ZoomPanFrame } from \"@/remotion/scenes/zoom-pan-frame\";\n\n<ZoomPanFrame src={staticFile(\"screenshot.png\")} to={{ x: 0.38, y: 0.4, scale: 1.2 }} />",
      "related": [
        "callout-spotlight",
        "cursor-path"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "code-reveal",
      "type": "registry:block",
      "description": "Editor window that writes a syntax-highlighted file character by character, then focuses the lines that matter",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils",
        "code-syntax",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add code-reveal",
      "docsUrl": "https://remotionui.com/docs/components/code-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/code-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/code-reveal.json",
      "importPath": "@/remotion/scenes/code-reveal",
      "installTarget": "src/remotion/scenes/code-reveal",
      "category": "scene",
      "props": [
        {
          "name": "code",
          "type": "string",
          "description": "Source shown in the editor; surrounding blank lines are trimmed."
        },
        {
          "name": "highlightedLines",
          "type": "number[]",
          "description": "1-based lines focused once the listing finishes writing."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"explainer.tsx\"",
          "description": "Filename on the editor tab."
        },
        {
          "name": "language",
          "type": "string",
          "default": "\"tsx\"",
          "description": "Language badge on the right of the header."
        },
        {
          "name": "startLine",
          "type": "number",
          "default": "1",
          "description": "First line number in the gutter, for excerpts."
        },
        {
          "name": "showLineNumbers",
          "type": "boolean",
          "default": "true",
          "description": "Shows the gutter."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Caret, focus band and glow color."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Editor palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CodeReveal } from \"@/remotion/scenes/code-reveal\";\n\n<CodeReveal title=\"pipeline.ts\" code={source} highlightedLines={[4, 5]} />",
      "related": [
        "tutorial-clip",
        "terminal-simulator",
        "code-diff-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "hook-card",
      "type": "registry:block",
      "description": "Short-form opener where the hook rises line by line out of its mask and an underline draws under the promise",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "creator"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "text-emphasis"
      ],
      "installCommand": "npx remotion-ui@latest add hook-card",
      "docsUrl": "https://remotionui.com/docs/components/hook-card",
      "registryUrl": "https://remotionui.com/r/presets/default/hook-card.json",
      "detailUrl": "https://remotionui.com/ai/components/hook-card.json",
      "importPath": "@/remotion/scenes/hook-card",
      "installTarget": "src/remotion/scenes/hook-card",
      "category": "scene",
      "props": [
        {
          "name": "headline",
          "type": "string",
          "required": true,
          "description": "The hook. Newlines are honoured as written; otherwise it is balanced across lines."
        },
        {
          "name": "kicker",
          "type": "string",
          "description": "Small live label that counts in above the hook."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line that settles once the hook has landed."
        },
        {
          "name": "emphasis",
          "type": "string",
          "description": "Substring of headline that takes the accent colour and the underline. Matched case-insensitively, and may span a line break."
        },
        {
          "name": "align",
          "type": "\"left\" | \"center\"",
          "description": "Hook alignment. Default \"left\"."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Label, underline, and bloom colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "description": "Page palette. Default \"dark\"."
        },
        {
          "name": "speed",
          "type": "number",
          "description": "Animation speed multiplier for fitting a fixed-length Sequence. Default 1."
        }
      ],
      "usage": "import { HookCard } from \"@/remotion/scenes/hook-card\";\n\n<HookCard\n  kicker=\"Creator insight\"\n  headline=\"Make the first second count\"\n  emphasis=\"first second\"\n  subtitle=\"Hook viewers before they scroll\"\n/>",
      "related": [
        "creator-reel",
        "title-card",
        "auto-fit-title"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "talking-head-layout",
      "type": "registry:block",
      "description": "Talking-head clip frame that opens on the speaker, slides a name plate out from behind it, and plays the spoken lines in a reserved caption zone with the waveform reacting",
      "tasks": [
        "captions",
        "audio",
        "transitions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "creator",
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "media-utils",
        "motion-tokens",
        "waveform-line"
      ],
      "installCommand": "npx remotion-ui@latest add talking-head-layout",
      "docsUrl": "https://remotionui.com/docs/components/talking-head-layout",
      "registryUrl": "https://remotionui.com/r/presets/default/talking-head-layout.json",
      "detailUrl": "https://remotionui.com/ai/components/talking-head-layout.json",
      "importPath": "@/remotion/scenes/talking-head-layout",
      "installTarget": "src/remotion/scenes/talking-head-layout",
      "category": "scene",
      "props": [
        {
          "name": "mediaSrc",
          "type": "string",
          "description": "Speaker image or video. Falls back to a framed placeholder."
        },
        {
          "name": "audioSrc",
          "type": "string",
          "description": "Voice track the waveform is drawn from. Omit to hide the waveform."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above the name on the plate, e.g. a role."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Name plate headline."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Second plate line."
        },
        {
          "name": "captions",
          "type": "string[]",
          "description": "Spoken lines. They play one at a time, word by word, in the zone reserved under the frame. Omit and the zone collapses."
        },
        {
          "name": "fit",
          "type": "\"cover\" | \"contain\"",
          "default": "\"cover\"",
          "description": "Media object-fit behavior."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#2DD4BF\"",
          "description": "Plate label, waveform, and ambient light color."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background behind the frame."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Palette the page and plate are drawn from."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds after which the whole layout leaves. Omit to hold: correct inside a TransitionSeries, where the transition covers the tail."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier for shorter Sequences."
        }
      ],
      "usage": "import { TalkingHeadLayout } from \"@/remotion/scenes/talking-head-layout\";\n\n<TalkingHeadLayout\n  mediaSrc={staticFile(\"speaker.mp4\")}\n  audioSrc={staticFile(\"voice.wav\")}\n  eyebrow=\"On camera\"\n  title=\"Maya Okonkwo\"\n  subtitle=\"Founder, Northlight Studio\"\n  captions={[\"Keep the speaker readable.\", \"Reserve the lower frame.\"]}\n/>",
      "related": [
        "creator-reel",
        "caption-scene",
        "media-frame"
      ],
      "note": "Advanced. Installs @remotion/media and waveform-line for optional audio visuals.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "comment-callout",
      "type": "registry:block",
      "description": "Viewer comment answered on screen: it lands from the feed, the ask is marked up, the creator hearts it, and the reply is typed and sent",
      "tasks": [
        "captions",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "creator",
          "social"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils",
        "code-syntax",
        "motion-tokens",
        "text-emphasis"
      ],
      "installCommand": "npx remotion-ui@latest add comment-callout",
      "docsUrl": "https://remotionui.com/docs/components/comment-callout",
      "registryUrl": "https://remotionui.com/r/presets/default/comment-callout.json",
      "detailUrl": "https://remotionui.com/ai/components/comment-callout.json",
      "importPath": "@/remotion/scenes/comment-callout",
      "installTarget": "src/remotion/scenes/comment-callout",
      "category": "scene",
      "props": [
        {
          "name": "body",
          "type": "string",
          "description": "The viewer comment being answered."
        },
        {
          "name": "author",
          "type": "string",
          "description": "Display name of the commenter."
        },
        {
          "name": "handle",
          "type": "string",
          "description": "Social handle, also shown on the reply line."
        },
        {
          "name": "initials",
          "type": "string",
          "description": "Avatar initials. Defaults to the first two letters of author."
        },
        {
          "name": "timestamp",
          "type": "string",
          "description": "Relative time shown after the handle, e.g. \"2h\"."
        },
        {
          "name": "highlight",
          "type": "string",
          "description": "Substring of body the marker sweeps across. Matched case-insensitively; omit to skip the beat."
        },
        {
          "name": "reply",
          "type": "string",
          "description": "Answer typed into the composer and sent. Pass an empty string to end on the comment."
        },
        {
          "name": "replyLabel",
          "type": "string",
          "description": "Label on the reply action. Defaults to \"Reply\"."
        },
        {
          "name": "likes",
          "type": "number",
          "description": "Like count before the creator hearts the comment. Default 128."
        },
        {
          "name": "accentColor",
          "type": "string",
          "description": "Avatar, marker, heart, and send colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background behind the card."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "description": "Card palette. Default \"dark\"."
        },
        {
          "name": "speed",
          "type": "number",
          "description": "Animation speed multiplier for fitting a fixed-length Sequence. Default 1."
        }
      ],
      "usage": "import { CommentCallout } from \"@/remotion/scenes/comment-callout\";\n\n<CommentCallout\n  author=\"Mina Lee\"\n  handle=\"@minamakes\"\n  body=\"Can you turn this into a quick video breakdown?\"\n  highlight=\"a quick video breakdown\"\n  reply=\"Dropping it Thursday, here's the short version.\"\n/>",
      "related": [
        "creator-reel",
        "quote-card",
        "caption-bumper"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "tutorial-clip",
      "type": "registry:block",
      "description": "Tutorial clip composition for demos and explainers",
      "tasks": [
        "captions",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/media",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "auto-fit-title",
        "media-frame",
        "callout-spotlight",
        "code-reveal",
        "end-card",
        "transition-fade",
        "motion-tokens",
        "sample-media"
      ],
      "installCommand": "npx remotion-ui@latest add tutorial-clip",
      "docsUrl": "https://remotionui.com/docs/components/tutorial-clip",
      "registryUrl": "https://remotionui.com/r/presets/default/tutorial-clip.json",
      "detailUrl": "https://remotionui.com/ai/components/tutorial-clip.json",
      "importPath": "@/compositions/tutorial-clip",
      "installTarget": "src/compositions/tutorial-clip",
      "category": "composition",
      "props": [
        {
          "name": "mediaSrc",
          "type": "string",
          "required": true,
          "description": "Screenshot or video source."
        },
        {
          "name": "mediaWidth",
          "type": "number",
          "default": "1280",
          "description": "Pixel width `calloutTarget` was measured against."
        },
        {
          "name": "mediaHeight",
          "type": "number",
          "default": "720",
          "description": "Pixel height `calloutTarget` was measured against."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Opening hook title."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line under the hook."
        },
        {
          "name": "calloutTitle",
          "type": "string",
          "default": "\"Tap Render to queue the job\"",
          "description": "Headline on the spotlight callout card."
        },
        {
          "name": "calloutSubtitle",
          "type": "string",
          "description": "Supporting line on the callout card."
        },
        {
          "name": "calloutTarget",
          "type": "SpotlightTarget",
          "description": "Region to spotlight, in media pixels."
        },
        {
          "name": "code",
          "type": "string",
          "description": "Code reveal content."
        },
        {
          "name": "ctaTitle",
          "type": "string",
          "description": "End card headline. Defaults to `title`."
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label."
        }
      ],
      "usage": "import { TutorialClip } from \"@/compositions/tutorial-clip\";\n\n<TutorialClip mediaSrc={staticFile(\"demo.png\")} />",
      "related": [
        "media-frame",
        "callout-spotlight",
        "code-reveal"
      ],
      "note": "9:16 walkthrough template. `calloutTarget` is read in media pixels and mapped through the same cover crop as the background, so pass `mediaWidth`/`mediaHeight` whenever the capture is not the composition size.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "data-story",
      "type": "registry:block",
      "description": "Data storytelling composition template",
      "tasks": [
        "data",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "data",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions",
        "@remotion/layout-utils"
      ],
      "registryDependencies": [
        "auto-fit-title",
        "animated-bar-chart",
        "metric-ticker",
        "timeline-steps",
        "caption-bumper",
        "end-card",
        "transition-fade",
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add data-story",
      "docsUrl": "https://remotionui.com/docs/components/data-story",
      "registryUrl": "https://remotionui.com/r/presets/default/data-story.json",
      "detailUrl": "https://remotionui.com/ai/components/data-story.json",
      "importPath": "@/compositions/data-story",
      "installTarget": "src/compositions/data-story",
      "category": "composition",
      "props": [
        {
          "name": "title",
          "type": "string",
          "description": "Opening hook headline (auto-fit)."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line under the hook."
        },
        {
          "name": "barData",
          "type": "ChartDatum[]",
          "required": true,
          "description": "Bar chart data."
        },
        {
          "name": "metrics",
          "type": "MetricTickerItem[]",
          "required": true,
          "description": "Metric cards."
        },
        {
          "name": "steps",
          "type": "TimelineStep[]",
          "required": true,
          "description": "Context steps."
        },
        {
          "name": "chartTitle",
          "type": "string",
          "description": "Headline on the bar chart scene."
        },
        {
          "name": "metricsTitle",
          "type": "string",
          "description": "Headline on the metric ticker scene."
        },
        {
          "name": "timelineTitle",
          "type": "string",
          "description": "Headline on the timeline scene."
        },
        {
          "name": "insight",
          "type": "string",
          "description": "Takeaway quote in the insight bumper."
        },
        {
          "name": "insightEyebrow",
          "type": "string",
          "description": "Eyebrow above the insight quote."
        },
        {
          "name": "ctaTitle",
          "type": "string",
          "description": "End card headline (separate from hook)."
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label."
        }
      ],
      "usage": "import { DataStory } from \"@/compositions/data-story\";\n\n<DataStory barData={barData} metrics={metrics} steps={steps} />",
      "related": [
        "animated-bar-chart",
        "metric-ticker",
        "timeline-steps"
      ],
      "note": "1920×1080 data explainer template. Advanced tier.",
      "composition": {
        "id": "DataStory",
        "component": "DataStory",
        "durationInFrames": 420,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/data-story/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "creator-reel",
      "type": "registry:block",
      "description": "Vertical creator media composition template",
      "tasks": [
        "captions",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "media",
        "tier": "advanced",
        "tags": [
          "creator",
          "social"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "auto-fit-title",
        "talking-head-layout",
        "comment-callout",
        "caption-scene",
        "b-roll-stack",
        "end-card",
        "transition-fade",
        "motion-tokens",
        "sample-media"
      ],
      "installCommand": "npx remotion-ui@latest add creator-reel",
      "docsUrl": "https://remotionui.com/docs/components/creator-reel",
      "registryUrl": "https://remotionui.com/r/presets/default/creator-reel.json",
      "detailUrl": "https://remotionui.com/ai/components/creator-reel.json",
      "importPath": "@/compositions/creator-reel",
      "installTarget": "src/compositions/creator-reel",
      "category": "composition",
      "props": [
        {
          "name": "hookHeadline",
          "type": "string",
          "description": "Opening hook headline (auto-fit in portrait).",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "hookSubtitle",
          "type": "string",
          "description": "Supporting line under the hook.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "mediaSrc",
          "type": "string",
          "description": "Speaker image or video source.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "mediaFit",
          "type": "\"cover\" | \"contain\"",
          "default": "\"cover\"",
          "description": "Speaker media object-fit behavior.",
          "schema": {
            "type": "string",
            "enum": [
              "cover",
              "contain"
            ]
          }
        },
        {
          "name": "audioSrc",
          "type": "string",
          "description": "Optional audio source for waveform visuals.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "captions",
          "type": "Caption[]",
          "description": "Synced captions layered over the talking-head scene.",
          "schema": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        {
          "name": "talkingHeadEyebrow",
          "type": "string",
          "description": "Eyebrow label above the talking-head title.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "talkingHeadTitle",
          "type": "string",
          "description": "Short title in the talking-head layout.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "comment",
          "type": "string",
          "description": "Comment callout body text.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "author",
          "type": "string",
          "description": "Comment author display name.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "handle",
          "type": "string",
          "description": "Comment author handle.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "bRollItems",
          "type": "BRollItem[]",
          "description": "Media cards for the proof/b-roll section.",
          "schema": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        {
          "name": "bRollTitle",
          "type": "string",
          "description": "Headline beside the b-roll stack.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "bRollKicker",
          "type": "string",
          "default": "\"Proof beats\"",
          "description": "Eyebrow above the b-roll headline.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "accentColor",
          "type": "string",
          "description": "Accent used across hook, captions, and end card.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "ctaTitle",
          "type": "string",
          "description": "End card headline (separate from hook).",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "usage": "import { CreatorReel } from \"@/compositions/creator-reel\";\n\n<CreatorReel\n  mediaSrc={staticFile(\"speaker.mp4\")}\n  audioSrc={staticFile(\"voice.wav\")}\n  captions={captions}\n/>",
      "related": [
        "hook-card",
        "talking-head-layout",
        "comment-callout"
      ],
      "note": "9:16 creator template. Advanced tier.",
      "composition": {
        "id": "CreatorReel",
        "component": "CreatorReel",
        "durationInFrames": 390,
        "fps": 30,
        "width": 1080,
        "height": 1920,
        "importPath": "@/compositions/creator-reel/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "podcast-clip",
      "type": "registry:block",
      "description": "Podcast clip composition with audio visuals and captions",
      "tasks": [
        "captions",
        "audio",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions",
        "@remotion/media-utils",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "audio-pulse",
        "waveform-line",
        "audiogram-scene",
        "auto-fit-title",
        "caption-scene",
        "end-card",
        "transition-fade",
        "fade-in",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add podcast-clip",
      "docsUrl": "https://remotionui.com/docs/components/podcast-clip",
      "registryUrl": "https://remotionui.com/r/presets/default/podcast-clip.json",
      "detailUrl": "https://remotionui.com/ai/components/podcast-clip.json",
      "importPath": "@/compositions/podcast-clip",
      "installTarget": "src/compositions/podcast-clip",
      "category": "composition",
      "props": [
        {
          "name": "audioSrc",
          "type": "string",
          "required": true,
          "description": "Audio source."
        },
        {
          "name": "captions",
          "type": "Caption[]",
          "required": true,
          "description": "Synced captions."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Opening title, reused as the episode title."
        },
        {
          "name": "subtitle",
          "type": "string",
          "default": "\"Pull one quote into a vertical clip\"",
          "description": "Supporting line under the opening title."
        },
        {
          "name": "showName",
          "type": "string",
          "default": "\"Studio Sessions\"",
          "description": "Show name above the episode title."
        },
        {
          "name": "ctaTitle",
          "type": "string",
          "description": "End card headline. Defaults to `showName`."
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "description": "End card CTA pill label."
        }
      ],
      "usage": "import { PodcastClip } from \"@/compositions/podcast-clip\";\n\n<PodcastClip audioSrc={staticFile(\"podcast.wav\")} captions={captions} />",
      "related": [
        "audio-pulse",
        "waveform-line",
        "caption-scene"
      ],
      "note": "9:16 podcast template (1080×1920).",
      "composition": {
        "id": "PodcastClip",
        "component": "PodcastClip",
        "durationInFrames": 294,
        "fps": 30,
        "width": 1080,
        "height": 1920,
        "importPath": "@/compositions/podcast-clip/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "blur-focus-in",
      "type": "registry:ui",
      "description": "Text fades from heavy blur into sharp focus",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add blur-focus-in",
      "docsUrl": "https://remotionui.com/docs/components/blur-focus-in",
      "registryUrl": "https://remotionui.com/r/presets/default/blur-focus-in.json",
      "detailUrl": "https://remotionui.com/ai/components/blur-focus-in.json",
      "importPath": "@/remotion/primitives/blur-focus-in",
      "installTarget": "src/remotion/primitives/blur-focus-in",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Text to reveal from blur."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "36",
          "description": "Blur-to-sharp duration."
        },
        {
          "name": "maxBlur",
          "type": "number",
          "default": "18",
          "description": "Starting blur in pixels."
        }
      ],
      "usage": "import { BlurFocusIn } from \"@/remotion/primitives/blur-focus-in\";\n\n<BlurFocusIn text=\"Sharp focus\" maxBlur={18} />",
      "related": [
        "blur-in",
        "tracking-in"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "staggered-fade-up",
      "type": "registry:ui",
      "description": "Words rise with cascading fade-up stagger",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add staggered-fade-up",
      "docsUrl": "https://remotionui.com/docs/components/staggered-fade-up",
      "registryUrl": "https://remotionui.com/r/presets/default/staggered-fade-up.json",
      "detailUrl": "https://remotionui.com/ai/components/staggered-fade-up.json",
      "importPath": "@/remotion/primitives/staggered-fade-up",
      "installTarget": "src/remotion/primitives/staggered-fade-up",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Space-separated words to stagger."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "4",
          "description": "Delay between words."
        }
      ],
      "usage": "import { StaggeredFadeUp } from \"@/remotion/primitives/staggered-fade-up\";\n\n<StaggeredFadeUp text=\"Words rise in sequence\" />",
      "related": [
        "stagger-children",
        "masked-slide-reveal"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "masked-slide-reveal",
      "type": "registry:ui",
      "description": "Words slide up through a horizontal mask",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add masked-slide-reveal",
      "docsUrl": "https://remotionui.com/docs/components/masked-slide-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/masked-slide-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/masked-slide-reveal.json",
      "importPath": "@/remotion/primitives/masked-slide-reveal",
      "installTarget": "src/remotion/primitives/masked-slide-reveal",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "Copy to reveal. Splits on newlines for line mode, or words on a single line. Omit when using lines."
        },
        {
          "name": "lines",
          "type": "string[]",
          "description": "Explicit lines to reveal through the mask. Preferred for multi-line headlines."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "6",
          "description": "Frames between each line or word reveal."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames for each masked slide-in."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Delay before the first item animates."
        },
        {
          "name": "textAlign",
          "type": "\"left\" | \"center\" | \"right\"",
          "default": "\"center\"",
          "description": "Horizontal alignment of lines."
        },
        {
          "name": "lineGap",
          "type": "number",
          "default": "0.18",
          "description": "Gap between lines in em units (line mode only)."
        }
      ],
      "usage": "import { MaskedSlideReveal } from \"@/remotion/primitives/masked-slide-reveal\";\n\n<MaskedSlideReveal\n  lines={[\n    \"Three layers in your repo\",\n    \"Drop scenes into\",\n    \"TransitionSeries\",\n  ]}\n/>",
      "related": [
        "staggered-fade-up"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "tracking-in",
      "type": "registry:ui",
      "description": "Letter-spacing collapses with spring snap",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "springs"
      ],
      "installCommand": "npx remotion-ui@latest add tracking-in",
      "docsUrl": "https://remotionui.com/docs/components/tracking-in",
      "registryUrl": "https://remotionui.com/r/presets/default/tracking-in.json",
      "detailUrl": "https://remotionui.com/ai/components/tracking-in.json",
      "importPath": "@/remotion/primitives/tracking-in",
      "installTarget": "src/remotion/primitives/tracking-in",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Headline with tracking collapse."
        }
      ],
      "usage": "import { TrackingIn } from \"@/remotion/primitives/tracking-in\";\n\n<TrackingIn text=\"Tracking snap\" />",
      "related": [
        "blur-focus-in",
        "typewriter"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "light-sweep-text",
      "type": "registry:ui",
      "description": "Light gradient sweeps across dim text",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add light-sweep-text",
      "docsUrl": "https://remotionui.com/docs/components/light-sweep-text",
      "registryUrl": "https://remotionui.com/r/presets/default/light-sweep-text.json",
      "detailUrl": "https://remotionui.com/ai/components/light-sweep-text.json",
      "importPath": "@/remotion/primitives/light-sweep-text",
      "installTarget": "src/remotion/primitives/light-sweep-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Text with gradient sweep."
        }
      ],
      "usage": "import { LightSweepText } from \"@/remotion/primitives/light-sweep-text\";\n\n<LightSweepText text=\"Light pass\" />",
      "related": [
        "marker-highlight"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "slot-roll",
      "type": "registry:ui",
      "description": "Characters roll like a slot reel into place",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add slot-roll",
      "docsUrl": "https://remotionui.com/docs/components/slot-roll",
      "registryUrl": "https://remotionui.com/r/presets/default/slot-roll.json",
      "detailUrl": "https://remotionui.com/ai/components/slot-roll.json",
      "importPath": "@/remotion/primitives/slot-roll",
      "installTarget": "src/remotion/primitives/slot-roll",
      "category": "primitive",
      "props": [
        {
          "name": "from",
          "type": "string",
          "required": true,
          "description": "Starting characters."
        },
        {
          "name": "to",
          "type": "string",
          "required": true,
          "description": "Target characters."
        }
      ],
      "usage": "import { SlotRoll } from \"@/remotion/primitives/slot-roll\";\n\n<SlotRoll from=\"1200\" to=\"9840\" />",
      "related": [
        "counter"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "matrix-decode",
      "type": "registry:ui",
      "description": "Scramble resolves left-to-right into target text",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add matrix-decode",
      "docsUrl": "https://remotionui.com/docs/components/matrix-decode",
      "registryUrl": "https://remotionui.com/r/presets/default/matrix-decode.json",
      "detailUrl": "https://remotionui.com/ai/components/matrix-decode.json",
      "importPath": "@/remotion/primitives/matrix-decode",
      "installTarget": "src/remotion/primitives/matrix-decode",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Target string."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frame the resolve front starts sweeping."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "50",
          "description": "Frames the front takes to cross the whole string."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Resolved and scrambled glyph colour."
        },
        {
          "name": "hotColor",
          "type": "string",
          "default": "\"#5eead4\"",
          "description": "Colour of the single character sitting on the decode front."
        },
        {
          "name": "glyphs",
          "type": "string",
          "description": "Pool the unresolved characters are drawn from. Must be monospace-width in `fontFamily`: full-width katakana are twice a latin advance, so the line changes width as it resolves."
        }
      ],
      "usage": "import { MatrixDecode } from \"@/remotion/primitives/matrix-decode\";\n\n<MatrixDecode text=\"DECODED\" />",
      "related": [
        "rgb-glitch-text",
        "scramble-text"
      ],
      "note": "The front sweeps at a constant rate with a deterministic ±2 character jitter, so glyphs lock in roughly, not exactly, left to right. No `Math.random`: the jitter is hashed off the character index.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "rgb-glitch-text",
      "type": "registry:ui",
      "description": "Signal-lock RGB glitch text with channel splits, slices, and scanlines",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add rgb-glitch-text",
      "docsUrl": "https://remotionui.com/docs/components/rgb-glitch-text",
      "registryUrl": "https://remotionui.com/r/presets/default/rgb-glitch-text.json",
      "detailUrl": "https://remotionui.com/ai/components/rgb-glitch-text.json",
      "importPath": "@/remotion/primitives/rgb-glitch-text",
      "installTarget": "src/remotion/primitives/rgb-glitch-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Readable text rendered under the glitch layers."
        },
        {
          "name": "glitchStartFrame",
          "type": "number",
          "description": "Frame where the RGB/slice glitch begins."
        },
        {
          "name": "glitchDurationInFrames",
          "type": "number",
          "description": "Length of the signal-lock glitch window."
        },
        {
          "name": "intensity",
          "type": "number",
          "description": "Channel offset and slice displacement multiplier, clamped from 0 to 2."
        },
        {
          "name": "sliceCount",
          "type": "number",
          "description": "Number of deterministic horizontal glitch slices, clamped from 3 to 9."
        },
        {
          "name": "redChannelColor",
          "type": "string",
          "description": "Warm channel split color."
        },
        {
          "name": "cyanChannelColor",
          "type": "string",
          "description": "Cool channel split color."
        },
        {
          "name": "accentColor",
          "type": "string",
          "description": "Scanline and final slice accent."
        }
      ],
      "usage": "import { RgbGlitchText } from \"@/remotion/primitives/rgb-glitch-text\";\n\n<RgbGlitchText text=\"SIGNAL LOCK\" glitchDurationInFrames={34} />",
      "related": [
        "matrix-decode"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "infinite-marquee",
      "type": "registry:ui",
      "description": "Endlessly scrolling horizontal text band",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add infinite-marquee",
      "docsUrl": "https://remotionui.com/docs/components/infinite-marquee",
      "registryUrl": "https://remotionui.com/r/presets/default/infinite-marquee.json",
      "detailUrl": "https://remotionui.com/ai/components/infinite-marquee.json",
      "importPath": "@/remotion/primitives/infinite-marquee",
      "installTarget": "src/remotion/primitives/infinite-marquee",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Marquee copy."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "2",
          "description": "Pixels travelled per frame."
        },
        {
          "name": "direction",
          "type": "\"left\" | \"right\"",
          "default": "\"left\"",
          "description": "Which way the text travels."
        },
        {
          "name": "fade",
          "type": "number",
          "default": "0.08",
          "description": "Width of the fade at each edge as a fraction of the visible band. 0 gives a hard edge; capped at 0.45 so the two fades cannot meet."
        },
        {
          "name": "fontSize",
          "type": "number",
          "description": "Overrides the width-scaled default (56 at 1080p)."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#f4f4f5\"",
          "description": "Text colour."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "600",
          "description": "Text weight."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "48",
          "description": "Space between one copy of the text and the next, in px."
        }
      ],
      "usage": "import { InfiniteMarquee } from \"@/remotion/primitives/infinite-marquee\";\n\n<InfiniteMarquee text=\"Scrolling band\" speed={2} direction=\"left\" fade={0.08} />",
      "related": [
        "perspective-marquee"
      ],
      "note": "The loop is one copy of the text wide and seamless by construction: the shift is a percentage of the track, so a mismeasured font changes the speed but can never make the wrap jump.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "perspective-marquee",
      "type": "registry:ui",
      "description": "Marquee tilted in 3D with depth fade",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add perspective-marquee",
      "docsUrl": "https://remotionui.com/docs/components/perspective-marquee",
      "registryUrl": "https://remotionui.com/r/presets/default/perspective-marquee.json",
      "detailUrl": "https://remotionui.com/ai/components/perspective-marquee.json",
      "importPath": "@/remotion/primitives/perspective-marquee",
      "installTarget": "src/remotion/primitives/perspective-marquee",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Marquee copy."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "10",
          "description": "Scroll speed in pixels per frame along the floor plane."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "72",
          "description": "Gap between repeated items in px."
        },
        {
          "name": "floorTilt",
          "type": "number",
          "default": "70",
          "description": "Floor plane tilt in degrees. Higher values exaggerate depth receding toward the horizon."
        },
        {
          "name": "perspective",
          "type": "number",
          "default": "640",
          "description": "Perspective distance in px. Lower values exaggerate depth."
        },
        {
          "name": "showFloorGrid",
          "type": "boolean",
          "default": "true",
          "description": "Draw a perspective grid behind the marquee plane."
        }
      ],
      "usage": "import { PerspectiveMarquee } from \"@/remotion/primitives/perspective-marquee\";\n\n<PerspectiveMarquee text=\"Depth scroll\" speed={10} floorTilt={70} perspective={640} />",
      "related": [
        "infinite-marquee"
      ],
      "note": "Unlike InfiniteMarquee, text scrolls on a receding 3D floor with horizon fade, not a flat band.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "strikethrough-replace",
      "type": "registry:ui",
      "description": "Strikes out one phrase and puts another in its place, on a three-beat correction timeline",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add strikethrough-replace",
      "docsUrl": "https://remotionui.com/docs/components/strikethrough-replace",
      "registryUrl": "https://remotionui.com/r/presets/default/strikethrough-replace.json",
      "detailUrl": "https://remotionui.com/ai/components/strikethrough-replace.json",
      "importPath": "@/remotion/primitives/strikethrough-replace",
      "installTarget": "src/remotion/primitives/strikethrough-replace",
      "category": "primitive",
      "props": [
        {
          "name": "from",
          "type": "string",
          "required": true,
          "description": "Phrase that gets struck out."
        },
        {
          "name": "to",
          "type": "string",
          "required": true,
          "description": "Phrase that takes its place."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the stroke starts travelling."
        },
        {
          "name": "strikeDurationInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the stroke takes to cross the full width of `from`."
        },
        {
          "name": "holdInFrames",
          "type": "number",
          "default": "4",
          "description": "Beat held on the struck-out phrase after the stroke lands, before it leaves."
        },
        {
          "name": "departDurationInFrames",
          "type": "number",
          "default": "12",
          "description": "Frames the old phrase takes to lift away. Its opacity is gone at 62% of it."
        },
        {
          "name": "replaceDelayInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames after the stroke lands before the new phrase starts arriving. Past `holdInFrames + departDurationInFrames` the line goes briefly empty; well below it the two phrases cross-fade."
        },
        {
          "name": "replaceDurationInFrames",
          "type": "number",
          "default": "20",
          "description": "Frames the new phrase takes to rise into place."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "0.42",
          "description": "Vertical handoff distance in em: the old lifts by it, the new rises from it."
        },
        {
          "name": "strikeWeight",
          "type": "number",
          "default": "0.07",
          "description": "Stroke thickness in em, so it tracks the type size."
        },
        {
          "name": "strikeHeight",
          "type": "number",
          "default": "0.5",
          "description": "Stroke height above the baseline in `ex`, units of the font's own x-height. 0.5 is centred through the lowercase mass."
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "-0.6",
          "description": "Stroke angle in degrees off level: a hand does not rule it flat."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#ececec\"",
          "description": "Text colour."
        },
        {
          "name": "strikeColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Stroke colour."
        },
        {
          "name": "replaceColor",
          "type": "string",
          "description": "Ink of the replacement. Defaults to `color`."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "scaled 72px",
          "description": "Text size in pixels."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "600",
          "description": "Text weight."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "description": "Font family for both phrases."
        },
        {
          "name": "textAlign",
          "type": "\"left\" | \"center\" | \"right\"",
          "default": "\"center\"",
          "description": "Alignment of both phrases inside the shared box."
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "description": "Styles merged onto the wrapper span."
        }
      ],
      "usage": "import { StrikethroughReplace } from \"@/remotion/primitives/strikethrough-replace\";\n\n<StrikethroughReplace from=\"Motion you rent\" to=\"Motion you own\" delayInFrames={10} />",
      "related": [
        "marker-highlight",
        "typewriter",
        "slot-roll"
      ],
      "note": "The stroke is aligned from the baseline in ex units, so it stays centred through the lowercase mass at any fontSize or lineHeight, and it departs inside the old phrase's layer rather than switching off. Both phrases share one grid cell, so the box holds the width of the longer one and a centred line never reflows on the swap.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "terminal-simulator",
      "type": "registry:block",
      "description": "Terminal window that types a command, streams spinner-to-check build steps with timings, then returns the prompt",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add terminal-simulator",
      "docsUrl": "https://remotionui.com/docs/components/terminal-simulator",
      "registryUrl": "https://remotionui.com/r/presets/default/terminal-simulator.json",
      "detailUrl": "https://remotionui.com/ai/components/terminal-simulator.json",
      "importPath": "@/remotion/scenes/terminal-simulator",
      "installTarget": "src/remotion/scenes/terminal-simulator",
      "category": "scene",
      "props": [
        {
          "name": "command",
          "type": "string",
          "default": "\"pnpm registry:build\"",
          "description": "Command typed at the prompt before anything runs."
        },
        {
          "name": "steps",
          "type": "TerminalStep[]",
          "description": "Steps printed in order; each spins, then resolves to a glyph and timing."
        },
        {
          "name": "summary",
          "type": "string",
          "default": "\"6 blocks · 1.9 MB · done in 4.2s\"",
          "description": "Dim line printed after the last step."
        },
        {
          "name": "prompt",
          "type": "string",
          "default": "\"~/remotion-ui\"",
          "description": "Prompt prefix, usually a working directory."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"Build output\"",
          "description": "Terminal window title."
        },
        {
          "name": "shell",
          "type": "string",
          "default": "\"zsh\"",
          "description": "Shell label on the right of the header."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Prompt, spinner and glow color."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Terminal palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        },
        {
          "name": "zoom",
          "type": "number",
          "default": "1",
          "description": "Multiplies the fitted stage scale; raise it when the log has to stay legible at tile size."
        }
      ],
      "usage": "import { TerminalSimulator } from \"@/remotion/scenes/terminal-simulator\";\n\n<TerminalSimulator command=\"pnpm build\" summary=\"done in 4.2s\" />",
      "related": [
        "code-reveal",
        "claude-code",
        "opencode"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "code-accordion",
      "type": "registry:block",
      "description": "Stepped walkthrough where each section opens, writes its code, is checked off, and closes behind the next",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils",
        "code-syntax",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add code-accordion",
      "docsUrl": "https://remotionui.com/docs/components/code-accordion",
      "registryUrl": "https://remotionui.com/r/presets/default/code-accordion.json",
      "detailUrl": "https://remotionui.com/ai/components/code-accordion.json",
      "importPath": "@/remotion/scenes/code-accordion",
      "installTarget": "src/remotion/scenes/code-accordion",
      "category": "scene",
      "props": [
        {
          "name": "sections",
          "type": "AccordionSection[]",
          "description": "Steps played in order; each has a title, code, and optional meta."
        },
        {
          "name": "activeIndex",
          "type": "number",
          "description": "Pins one step open instead of walking the list."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"Add it to your project\"",
          "description": "Label above the steps."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "default": "0.75",
          "description": "Seconds an opened step is held before it closes."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Chevron, fill and glow color."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Panel palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CodeAccordion } from \"@/remotion/scenes/code-accordion\";\n\n<CodeAccordion sections={sections} />",
      "related": [
        "code-reveal",
        "code-diff-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "code-diff-wipe",
      "type": "registry:block",
      "description": "Diff patch landing line by line: an apply front travels the file, removals collapse, additions open and write in",
      "tasks": [
        "transitions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils",
        "code-syntax",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add code-diff-wipe",
      "docsUrl": "https://remotionui.com/docs/components/code-diff-wipe",
      "registryUrl": "https://remotionui.com/r/presets/default/code-diff-wipe.json",
      "detailUrl": "https://remotionui.com/ai/components/code-diff-wipe.json",
      "importPath": "@/remotion/scenes/code-diff-wipe",
      "installTarget": "src/remotion/scenes/code-diff-wipe",
      "category": "scene",
      "props": [
        {
          "name": "before",
          "type": "string",
          "description": "Source before the patch."
        },
        {
          "name": "after",
          "type": "string",
          "description": "Source after the patch; the scene diffs the two."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"render.ts\"",
          "description": "Filename on the window header."
        },
        {
          "name": "wipeSeconds",
          "type": "number",
          "default": "1.7",
          "description": "Seconds the apply front takes to travel the file."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Apply front and glow color."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Editor palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CodeDiffWipe } from \"@/remotion/scenes/code-diff-wipe\";\n\n<CodeDiffWipe before={before} after={after} title=\"render.ts\" />",
      "related": [
        "code-reveal",
        "code-accordion"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "data-flow-pipes",
      "type": "registry:block",
      "description": "Pipeline running end to end: stages come up in order, pipes draw between them, and a stream of payloads hops through, lighting each stage and ticking its tally",
      "tasks": [
        "data",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "data"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "path-utils"
      ],
      "installCommand": "npx remotion-ui@latest add data-flow-pipes",
      "docsUrl": "https://remotionui.com/docs/components/data-flow-pipes",
      "registryUrl": "https://remotionui.com/r/presets/default/data-flow-pipes.json",
      "detailUrl": "https://remotionui.com/ai/components/data-flow-pipes.json",
      "importPath": "@/remotion/scenes/data-flow-pipes",
      "installTarget": "src/remotion/scenes/data-flow-pipes",
      "category": "scene",
      "props": [
        {
          "name": "stages",
          "type": "PipeStage[]",
          "description": "Stages in order, each { label, detail }. Two to five read best."
        },
        {
          "name": "unit",
          "type": "string",
          "default": "\"clips\"",
          "description": "Unit counted at each stage."
        },
        {
          "name": "packets",
          "type": "number",
          "default": "9",
          "description": "Payloads pushed through the pipeline."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#2DD4BF\"",
          "description": "Pipe, packet, and node colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { DataFlowPipes } from \"@/remotion/scenes/data-flow-pipes\";\n\n<DataFlowPipes stages={[{ label: \"Ingest\" }, { label: \"Deliver\" }]} />",
      "related": [
        "timeline-steps",
        "metric-ticker"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "drag-drop-flow",
      "type": "registry:block",
      "description": "Cursor drags a file out of a media library into a drop zone that arms, catches it, and uploads it to completion",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens",
        "path-utils"
      ],
      "installCommand": "npx remotion-ui@latest add drag-drop-flow",
      "docsUrl": "https://remotionui.com/docs/components/drag-drop-flow",
      "registryUrl": "https://remotionui.com/r/presets/default/drag-drop-flow.json",
      "detailUrl": "https://remotionui.com/ai/components/drag-drop-flow.json",
      "importPath": "@/remotion/scenes/drag-drop-flow",
      "installTarget": "src/remotion/scenes/drag-drop-flow",
      "category": "scene",
      "props": [
        {
          "name": "fileName",
          "type": "string",
          "default": "\"hero-take.mp4\"",
          "description": "File the cursor picks up."
        },
        {
          "name": "fileSize",
          "type": "string",
          "default": "\"48.2 MB\"",
          "description": "Size shown once the upload completes."
        },
        {
          "name": "siblings",
          "type": "string[]",
          "description": "Other rows in the source list."
        },
        {
          "name": "sourceLabel",
          "type": "string",
          "default": "\"Media library\"",
          "description": "Heading on the source panel."
        },
        {
          "name": "label",
          "type": "string",
          "default": "\"Drop your clip\"",
          "description": "Idle prompt in the drop zone."
        },
        {
          "name": "hint",
          "type": "string",
          "description": "Second line under the prompt."
        },
        {
          "name": "activeLabel",
          "type": "string",
          "default": "\"Release to upload\"",
          "description": "Prompt while the file is held over the zone."
        },
        {
          "name": "doneLabel",
          "type": "string",
          "default": "\"Uploaded\"",
          "description": "Label once the upload finishes."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Zone, cursor ring, and progress colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { DragDropFlow } from \"@/remotion/scenes/drag-drop-flow\";\n\n<DragDropFlow fileName=\"hero-loop.tsx\" />",
      "related": [
        "cursor-path",
        "simulated-cursor",
        "tutorial-clip"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "chat-to-preview",
      "type": "registry:block",
      "description": "Prompt-to-render loop: the ask types into the composer and sends into the thread, the answer streams back, and the preview assembles from wireframe to rendered scene",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add chat-to-preview",
      "docsUrl": "https://remotionui.com/docs/components/chat-to-preview",
      "registryUrl": "https://remotionui.com/r/presets/default/chat-to-preview.json",
      "detailUrl": "https://remotionui.com/ai/components/chat-to-preview.json",
      "importPath": "@/remotion/scenes/chat-to-preview",
      "installTarget": "src/remotion/scenes/chat-to-preview",
      "category": "scene",
      "props": [
        {
          "name": "messages",
          "type": "ChatMessage[]",
          "description": "The exchange, in order. User turns type and send; assistant turns stream. Drives the whole clock."
        },
        {
          "name": "previewTitle",
          "type": "string",
          "default": "\"Ship the scene\"",
          "description": "Title the finished preview renders."
        },
        {
          "name": "previewCaption",
          "type": "string",
          "description": "Supporting line under the preview title."
        },
        {
          "name": "previewLabel",
          "type": "string",
          "default": "\"Preview\"",
          "description": "Name of the preview surface in its header, or its tab title in browser mode."
        },
        {
          "name": "previewUrl",
          "type": "string",
          "description": "Address the preview is loading. Renders the surface as a browser (tab strip, URL bar and a load bar) and starts the page loading when the address is sent."
        },
        {
          "name": "placeholder",
          "type": "string",
          "description": "Composer placeholder before anything is typed."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Assistant bubble, status, and render tint."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Overrides the page background."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ChatToPreview } from \"@/remotion/scenes/chat-to-preview\";\n\n<ChatToPreview messages={messages} previewTitle=\"Ship the scene\" />",
      "related": [
        "talking-head-layout",
        "media-frame"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "hero-device-assemble",
      "type": "registry:block",
      "description": "Device layers assemble hero",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "title-card",
        "device-mockup-zoom",
        "multi-device-lineup",
        "transition-fade",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add hero-device-assemble",
      "docsUrl": "https://remotionui.com/docs/components/hero-device-assemble",
      "registryUrl": "https://remotionui.com/r/presets/default/hero-device-assemble.json",
      "detailUrl": "https://remotionui.com/ai/components/hero-device-assemble.json",
      "importPath": "@/compositions/hero-device-assemble",
      "installTarget": "src/compositions/hero-device-assemble",
      "category": "composition",
      "props": [
        {
          "name": "title",
          "type": "string",
          "description": "Opening title card headline."
        },
        {
          "name": "subtitle",
          "type": "string",
          "description": "Supporting line under the title."
        }
      ],
      "usage": "import { HeroDeviceAssemble } from \"@/compositions/hero-device-assemble\";\n\n<HeroDeviceAssemble title=\"Ship on every screen\" />",
      "related": [
        "title-card",
        "device-mockup-zoom"
      ],
      "note": "1920×1080 product hero. Title card then device mockup assemble.",
      "composition": {
        "id": "HeroDeviceAssemble",
        "component": "HeroDeviceAssemble",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/hero-device-assemble/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "ecosystem-orbit",
      "type": "registry:block",
      "description": "Logo with orbiting satellites",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add ecosystem-orbit",
      "docsUrl": "https://remotionui.com/docs/components/ecosystem-orbit",
      "registryUrl": "https://remotionui.com/r/presets/default/ecosystem-orbit.json",
      "detailUrl": "https://remotionui.com/ai/components/ecosystem-orbit.json",
      "importPath": "@/compositions/ecosystem-orbit",
      "installTarget": "src/compositions/ecosystem-orbit",
      "category": "composition",
      "props": [
        {
          "name": "centerLabel",
          "type": "string",
          "default": "\"RemotionUI\"",
          "description": "Center brand label."
        },
        {
          "name": "satellites",
          "type": "string[]",
          "description": "Orbiting integration labels."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Center accent color."
        }
      ],
      "usage": "import { EcosystemOrbit } from \"@/compositions/ecosystem-orbit\";\n\n<EcosystemOrbit centerLabel=\"Your product\" satellites={[\"GitHub\", \"Vercel\", \"Stripe\"]} />",
      "related": [
        "logo-reveal",
        "showcase"
      ],
      "note": "1920×1080 integration orbit with pulsing connection lines.",
      "composition": {
        "id": "EcosystemOrbit",
        "component": "EcosystemOrbit",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/ecosystem-orbit/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "bento-pan",
      "type": "registry:block",
      "description": "Camera pan across a bento grid of metric cards",
      "tasks": [
        "data",
        "scene-overlays",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add bento-pan",
      "docsUrl": "https://remotionui.com/docs/components/bento-pan",
      "registryUrl": "https://remotionui.com/r/presets/default/bento-pan.json",
      "detailUrl": "https://remotionui.com/ai/components/bento-pan.json",
      "importPath": "@/compositions/bento-pan",
      "installTarget": "src/compositions/bento-pan",
      "category": "composition",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Stage background."
        }
      ],
      "usage": "import { BentoPan } from \"@/compositions/bento-pan\";\n\n<BentoPan />",
      "related": [
        "media-sequence",
        "showcase"
      ],
      "note": "1920×1080 diagonal bento grid pan with vignette.",
      "composition": {
        "id": "BentoPan",
        "component": "BentoPan",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/bento-pan/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "browser-flow",
      "type": "registry:block",
      "description": "URL to browser preview flow",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "title-card",
        "chat-to-preview",
        "transition-fade",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add browser-flow",
      "docsUrl": "https://remotionui.com/docs/components/browser-flow",
      "registryUrl": "https://remotionui.com/r/presets/default/browser-flow.json",
      "detailUrl": "https://remotionui.com/ai/components/browser-flow.json",
      "importPath": "@/compositions/browser-flow",
      "installTarget": "src/compositions/browser-flow",
      "category": "composition",
      "props": [
        {
          "name": "url",
          "type": "string",
          "description": "URL shown in the title card subtitle."
        },
        {
          "name": "title",
          "type": "string",
          "description": "Opening headline."
        }
      ],
      "usage": "import { BrowserFlow } from \"@/compositions/browser-flow\";\n\n<BrowserFlow url=\"remotionui.com/docs\" title=\"Browse the registry\" />",
      "related": [
        "chat-to-preview",
        "title-card"
      ],
      "note": "1920×1080 URL-to-preview flow using chat-to-preview scene.",
      "composition": {
        "id": "BrowserFlow",
        "component": "BrowserFlow",
        "durationInFrames": 168,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/browser-flow/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "ai-generation-canvas",
      "type": "registry:block",
      "description": "Prompt-to-dashboard generation with morphing input, skeleton shimmer, and card flips",
      "tasks": [
        "scene-overlays",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add ai-generation-canvas",
      "docsUrl": "https://remotionui.com/docs/components/ai-generation-canvas",
      "registryUrl": "https://remotionui.com/r/presets/default/ai-generation-canvas.json",
      "detailUrl": "https://remotionui.com/ai/components/ai-generation-canvas.json",
      "importPath": "@/compositions/ai-generation-canvas",
      "installTarget": "src/compositions/ai-generation-canvas",
      "category": "composition",
      "props": [
        {
          "name": "prompt",
          "type": "string",
          "description": "Prompt typed into the input during phase one."
        },
        {
          "name": "accentColor",
          "type": "string",
          "description": "Accent for border, shimmer, and chart highlights."
        },
        {
          "name": "cardCount",
          "type": "number",
          "description": "Dashboard cards revealed in the grid. Clamped between 1 and 6."
        },
        {
          "name": "metrics",
          "type": "AiGenerationMetric[]",
          "description": "Labels, values, and optional deltas for the revealed dashboard cards."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "description": "Small label above the generated dashboard headline."
        },
        {
          "name": "statusLabel",
          "type": "string",
          "description": "Header status text shown after the prompt morphs."
        },
        {
          "name": "speed",
          "type": "number",
          "description": "Timeline multiplier for the composition beat."
        }
      ],
      "usage": "import { AiGenerationCanvas } from \"@/compositions/ai-generation-canvas\";\n\n<AiGenerationCanvas\n  prompt=\"Generate a revenue dashboard for this launch\"\n  accentColor=\"#e8b86d\"\n  cardCount={4}\n/>",
      "related": [
        "dashboard-populate",
        "chat-to-preview"
      ],
      "note": "Responsive prompt-to-dashboard generation beat with safe-area layout, skeleton shimmer, and card flips.",
      "composition": {
        "id": "AiGenerationCanvas",
        "component": "AiGenerationCanvas",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/ai-generation-canvas/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "ai-composer-showcase",
      "type": "registry:block",
      "description": "Showcase reel cutting through five AI composer interfaces with title and end cards",
      "tasks": [
        "product-intro",
        "scene-overlays",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "layout",
        "transition-fade",
        "chat-gpt",
        "claude-chat",
        "v0",
        "claude-code",
        "opencode"
      ],
      "installCommand": "npx remotion-ui@latest add ai-composer-showcase",
      "docsUrl": "https://remotionui.com/docs/components/ai-composer-showcase",
      "registryUrl": "https://remotionui.com/r/presets/default/ai-composer-showcase.json",
      "detailUrl": "https://remotionui.com/ai/components/ai-composer-showcase.json",
      "importPath": "@/compositions/ai-composer-showcase",
      "installTarget": "src/compositions/ai-composer-showcase",
      "category": "composition",
      "props": [],
      "usage": "import { AiComposerShowcase } from \"@/compositions/ai-composer-showcase\";\n\n<AiComposerShowcase />",
      "related": [
        "chat-gpt",
        "claude-chat",
        "v0",
        "claude-code",
        "opencode"
      ],
      "note": "1920×1080 showcase reel: title card, five AI composer scenes (ChatGPT, Claude, v0, Claude Code, OpenCode) each with a feature label, then an end card. No props; customize by editing the SCENES list in source.",
      "composition": {
        "id": "AiComposerShowcase",
        "component": "AiComposerShowcase",
        "durationInFrames": 533,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/ai-composer-showcase/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "live-code-split",
      "type": "registry:block",
      "description": "Editor on the left, its rendered output live on the right",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-reveal",
        "title-card",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add live-code-split",
      "docsUrl": "https://remotionui.com/docs/components/live-code-split",
      "registryUrl": "https://remotionui.com/r/presets/default/live-code-split.json",
      "detailUrl": "https://remotionui.com/ai/components/live-code-split.json",
      "importPath": "@/compositions/live-code-split",
      "installTarget": "src/compositions/live-code-split",
      "category": "composition",
      "props": [
        {
          "name": "code",
          "type": "string",
          "description": "Code reveal content."
        }
      ],
      "usage": "import { LiveCodeSplit } from \"@/compositions/live-code-split\";\n\n<LiveCodeSplit code={sourceCode} />",
      "related": [
        "code-reveal",
        "device-mockup-zoom"
      ],
      "note": "1920×1080 code editor then live device preview.",
      "composition": {
        "id": "LiveCodeSplit",
        "component": "LiveCodeSplit",
        "durationInFrames": 168,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/live-code-split/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "deploy-reveal",
      "type": "registry:block",
      "description": "Terminal deploy to browser",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "terminal-simulator",
        "device-mockup-zoom",
        "transition-fade",
        "motion-tokens",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add deploy-reveal",
      "docsUrl": "https://remotionui.com/docs/components/deploy-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/deploy-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/deploy-reveal.json",
      "importPath": "@/compositions/deploy-reveal",
      "installTarget": "src/compositions/deploy-reveal",
      "category": "composition",
      "props": [],
      "usage": "import { DeployReveal } from \"@/compositions/deploy-reveal\";\n\n<DeployReveal />",
      "related": [
        "terminal-simulator",
        "device-mockup-zoom"
      ],
      "note": "1920×1080 terminal deploy log then browser reveal.",
      "composition": {
        "id": "DeployReveal",
        "component": "DeployReveal",
        "durationInFrames": 168,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/deploy-reveal/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "dashboard-populate",
      "type": "registry:block",
      "description": "Dashboard metrics populate",
      "tasks": [
        "data",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "data",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "metric-ticker",
        "animated-bar-chart",
        "chart-utils",
        "motion-tokens",
        "directional-wipe"
      ],
      "installCommand": "npx remotion-ui@latest add dashboard-populate",
      "docsUrl": "https://remotionui.com/docs/components/dashboard-populate",
      "registryUrl": "https://remotionui.com/r/presets/default/dashboard-populate.json",
      "detailUrl": "https://remotionui.com/ai/components/dashboard-populate.json",
      "importPath": "@/compositions/dashboard-populate",
      "installTarget": "src/compositions/dashboard-populate",
      "category": "composition",
      "props": [
        {
          "name": "metrics",
          "type": "MetricTickerItem[]",
          "description": "Metric cards shown in the opening ticker beat."
        },
        {
          "name": "barData",
          "type": "ChartDatum[]",
          "description": "Bars charted in the closing beat."
        },
        {
          "name": "metricsTitle",
          "type": "string",
          "default": "\"Dashboard waking up\"",
          "description": "Title over the metric ticker beat."
        },
        {
          "name": "chartTitle",
          "type": "string",
          "default": "\"Weekly throughput\"",
          "description": "Title over the bar chart beat."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Scene background color."
        }
      ],
      "usage": "import { DashboardPopulate } from \"@/compositions/dashboard-populate\";\n\n<DashboardPopulate metrics={metrics} barData={barData} />",
      "related": [
        "metric-ticker",
        "animated-bar-chart"
      ],
      "note": "1920×1080 metric ticker then animated bar chart, fading between beats.",
      "composition": {
        "id": "DashboardPopulate",
        "component": "DashboardPopulate",
        "durationInFrames": 168,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/dashboard-populate/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "pricing-focus",
      "type": "registry:block",
      "description": "Pricing tier focus animation",
      "tasks": [
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add pricing-focus",
      "docsUrl": "https://remotionui.com/docs/components/pricing-focus",
      "registryUrl": "https://remotionui.com/r/presets/default/pricing-focus.json",
      "detailUrl": "https://remotionui.com/ai/components/pricing-focus.json",
      "importPath": "@/compositions/pricing-focus",
      "installTarget": "src/compositions/pricing-focus",
      "category": "composition",
      "props": [
        {
          "name": "tiers",
          "type": "Array<{ name: string; price: string; featured?: boolean }>",
          "description": "Pricing cards."
        }
      ],
      "usage": "import { PricingFocus } from \"@/compositions/pricing-focus\";\n\n<PricingFocus tiers={[{ name: \"Starter\", price: \"$0\" }, { name: \"Studio\", price: \"$29\", featured: true }]} />",
      "related": [
        "stat-card",
        "feature-list"
      ],
      "note": "1920×1080 pricing tier focus with lift and dim siblings.",
      "composition": {
        "id": "PricingFocus",
        "component": "PricingFocus",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/pricing-focus/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "landing-code-showcase",
      "type": "registry:block",
      "description": "Landing with install commands",
      "tasks": [
        "product-intro",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "title-card",
        "code-reveal",
        "motion-tokens",
        "transition-fade"
      ],
      "installCommand": "npx remotion-ui@latest add landing-code-showcase",
      "docsUrl": "https://remotionui.com/docs/components/landing-code-showcase",
      "registryUrl": "https://remotionui.com/r/presets/default/landing-code-showcase.json",
      "detailUrl": "https://remotionui.com/ai/components/landing-code-showcase.json",
      "importPath": "@/compositions/landing-code-showcase",
      "installTarget": "src/compositions/landing-code-showcase",
      "category": "composition",
      "props": [],
      "usage": "import { LandingCodeShowcase } from \"@/compositions/landing-code-showcase\";\n\n<LandingCodeShowcase />",
      "related": [
        "title-card",
        "code-reveal"
      ],
      "note": "1920×1080 title card plus install command code reveal.",
      "composition": {
        "id": "LandingCodeShowcase",
        "component": "LandingCodeShowcase",
        "durationInFrames": 180,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/landing-code-showcase/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "tool-menu-slide",
      "type": "registry:block",
      "description": "Tool menu slide-in",
      "tasks": [
        "transitions",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add tool-menu-slide",
      "docsUrl": "https://remotionui.com/docs/components/tool-menu-slide",
      "registryUrl": "https://remotionui.com/r/presets/default/tool-menu-slide.json",
      "detailUrl": "https://remotionui.com/ai/components/tool-menu-slide.json",
      "importPath": "@/compositions/tool-menu-slide",
      "installTarget": "src/compositions/tool-menu-slide",
      "category": "composition",
      "props": [],
      "usage": "import { ToolMenuSlide } from \"@/compositions/tool-menu-slide\";\n\n<ToolMenuSlide />",
      "related": [
        "feature-list",
        "slide-left"
      ],
      "note": "1920×1080 staggered tool menu slide-in.",
      "composition": {
        "id": "ToolMenuSlide",
        "component": "ToolMenuSlide",
        "durationInFrames": 120,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/tool-menu-slide/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "image-expand",
      "type": "registry:block",
      "description": "A still opens from a card to full frame, then takes its caption",
      "tasks": [
        "captions",
        "scene-overlays",
        "scenes",
        "reels"
      ],
      "atlas": {
        "lane": "reels",
        "drive": "media",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add image-expand",
      "docsUrl": "https://remotionui.com/docs/components/image-expand",
      "registryUrl": "https://remotionui.com/r/presets/default/image-expand.json",
      "detailUrl": "https://remotionui.com/ai/components/image-expand.json",
      "importPath": "@/compositions/image-expand",
      "installTarget": "src/compositions/image-expand",
      "category": "composition",
      "props": [
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Thumbnail accent color."
        }
      ],
      "usage": "import { ImageExpand } from \"@/compositions/image-expand\";\n\n<ImageExpand accentColor=\"#e8b86d\" />",
      "related": [
        "media-frame",
        "zoom-pan-frame"
      ],
      "note": "1920×1080 thumbnail expands to full frame.",
      "composition": {
        "id": "ImageExpand",
        "component": "ImageExpand",
        "durationInFrames": 120,
        "fps": 30,
        "width": 1920,
        "height": 1080,
        "importPath": "@/compositions/image-expand/index"
      },
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "claude-chat",
      "type": "registry:block",
      "description": "Claude composer card with typed prompt and waveform-to-send morph",
      "tasks": [
        "audio",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils"
      ],
      "installCommand": "npx remotion-ui@latest add claude-chat",
      "docsUrl": "https://remotionui.com/docs/components/claude-chat",
      "registryUrl": "https://remotionui.com/r/presets/default/claude-chat.json",
      "detailUrl": "https://remotionui.com/ai/components/claude-chat.json",
      "importPath": "@/remotion/scenes/claude-chat",
      "installTarget": "src/remotion/scenes/claude-chat",
      "category": "scene",
      "props": [
        {
          "name": "placeholder",
          "type": "string",
          "default": "\"Try: draft an email · summarize a doc · plan your week\"",
          "description": "Empty composer placeholder text."
        },
        {
          "name": "prompt",
          "type": "string",
          "default": "\"Draft a launch tweet\"",
          "description": "Prompt typed into the composer."
        },
        {
          "name": "modelName",
          "type": "string",
          "default": "\"Opus 4.8\"",
          "description": "Model label in the toolbar."
        },
        {
          "name": "modelTier",
          "type": "string",
          "default": "\"Max\"",
          "description": "Tier label beside the model."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#D97757\"",
          "description": "Terracotta send button color."
        },
        {
          "name": "theme",
          "type": "\"light\" | \"dark\"",
          "default": "\"light\"",
          "description": "Light or dark surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ClaudeChat } from \"@/remotion/scenes/claude-chat\";\n\n<ClaudeChat prompt=\"Draft a launch tweet for our new release\" />",
      "related": [
        "chat-gpt",
        "v0",
        "chat-to-preview"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "chat-gpt",
      "type": "registry:block",
      "description": "ChatGPT composer pill with greeting, suggestion chips, and voice-to-send morph",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils"
      ],
      "installCommand": "npx remotion-ui@latest add chat-gpt",
      "docsUrl": "https://remotionui.com/docs/components/chat-gpt",
      "registryUrl": "https://remotionui.com/r/presets/default/chat-gpt.json",
      "detailUrl": "https://remotionui.com/ai/components/chat-gpt.json",
      "importPath": "@/remotion/scenes/chat-gpt",
      "installTarget": "src/remotion/scenes/chat-gpt",
      "category": "scene",
      "props": [
        {
          "name": "greeting",
          "type": "string",
          "default": "\"What's on your mind today?\"",
          "description": "Headline above the composer."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "\"Ask anything\"",
          "description": "Empty input placeholder."
        },
        {
          "name": "prompt",
          "type": "string",
          "default": "\"Make a sunset over the ocean\"",
          "description": "Prompt typed into the ChatGPT composer."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#2F6FED\"",
          "description": "Voice button color before it morphs to send."
        },
        {
          "name": "theme",
          "type": "\"light\" | \"dark\"",
          "default": "\"light\"",
          "description": "Light or dark surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ChatGpt } from \"@/remotion/scenes/chat-gpt\";\n\n<ChatGpt prompt=\"Make a sunset over a calm ocean\" />",
      "related": [
        "claude-chat",
        "v0",
        "chat-to-preview"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "v0",
      "type": "registry:block",
      "description": "v0 composer with greeting, model chip, project selector, and mic-to-send morph",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils"
      ],
      "installCommand": "npx remotion-ui@latest add v0",
      "docsUrl": "https://remotionui.com/docs/components/v0",
      "registryUrl": "https://remotionui.com/r/presets/default/v0.json",
      "detailUrl": "https://remotionui.com/ai/components/v0.json",
      "importPath": "@/remotion/scenes/v0",
      "installTarget": "src/remotion/scenes/v0",
      "category": "scene",
      "props": [
        {
          "name": "greeting",
          "type": "string",
          "default": "\"What do you want to create?\"",
          "description": "Bold heading above the box."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "\"Ask v0 to build…\"",
          "description": "Empty textarea placeholder."
        },
        {
          "name": "prompt",
          "type": "string",
          "default": "\"a landing page with pricing\"",
          "description": "Build prompt typed into the textarea. The send beat is scheduled off its length, so a long prompt pushes the submit later rather than overrunning the window."
        },
        {
          "name": "modelName",
          "type": "string",
          "default": "\"v0 Max\"",
          "description": "Model chip label in the toolbar."
        },
        {
          "name": "projectName",
          "type": "string",
          "default": "\"Project\"",
          "description": "Project selector label."
        },
        {
          "name": "theme",
          "type": "\"light\" | \"dark\"",
          "default": "\"dark\"",
          "description": "Light or dark surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { V0Composer } from \"@/remotion/scenes/v0\";\n\n<V0Composer prompt=\"a landing page for my SaaS with pricing\" />",
      "related": [
        "claude-chat",
        "chat-gpt",
        "chat-to-preview"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "claude-code",
      "type": "registry:block",
      "description": "Claude Code terminal welcome screen with CLI prompt typing",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils"
      ],
      "installCommand": "npx remotion-ui@latest add claude-code",
      "docsUrl": "https://remotionui.com/docs/components/claude-code",
      "registryUrl": "https://remotionui.com/r/presets/default/claude-code.json",
      "detailUrl": "https://remotionui.com/ai/components/claude-code.json",
      "importPath": "@/remotion/scenes/claude-code",
      "installTarget": "src/remotion/scenes/claude-code",
      "category": "scene",
      "props": [
        {
          "name": "title",
          "type": "string",
          "default": "\"Claude Code v2.0.0\"",
          "description": "Legend label on the dashed welcome box."
        },
        {
          "name": "userName",
          "type": "string",
          "default": "\"Meaghan\"",
          "description": "Welcome message name."
        },
        {
          "name": "model",
          "type": "string",
          "default": "\"Opus 4.8 • Max 20x\"",
          "description": "Active model label."
        },
        {
          "name": "cwd",
          "type": "string",
          "default": "\"/users/meaghan/code/apps\"",
          "description": "Working directory shown in the welcome panel."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "'Try \"edit <filepath> to ...\"'",
          "description": "CLI prompt placeholder before typing."
        },
        {
          "name": "prompt",
          "type": "string",
          "default": "\"edit src/theme.ts to add a dark mode toggle\"",
          "description": "Command typed at the CLI prompt."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#D97757\"",
          "description": "Dashed border and highlight color."
        },
        {
          "name": "theme",
          "type": "\"light\" | \"dark\"",
          "default": "\"dark\"",
          "description": "Light or dark terminal palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ClaudeCode } from \"@/remotion/scenes/claude-code\";\n\n<ClaudeCode prompt='edit src/theme.ts to add a dark mode toggle' />",
      "related": [
        "terminal-simulator",
        "code-reveal",
        "opencode"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "opencode",
      "type": "registry:block",
      "description": "OpenCode TUI composer with agent and model status",
      "tasks": [
        "data",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ai"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "ai-composer-utils"
      ],
      "installCommand": "npx remotion-ui@latest add opencode",
      "docsUrl": "https://remotionui.com/docs/components/opencode",
      "registryUrl": "https://remotionui.com/r/presets/default/opencode.json",
      "detailUrl": "https://remotionui.com/ai/components/opencode.json",
      "importPath": "@/remotion/scenes/opencode",
      "installTarget": "src/remotion/scenes/opencode",
      "category": "scene",
      "props": [
        {
          "name": "placeholder",
          "type": "string",
          "default": "\"Ask anything... \"",
          "description": "Muted prefix before the typed query."
        },
        {
          "name": "query",
          "type": "string",
          "default": "'\"What is the tech stack of this project?\"'",
          "description": "Query typed after the placeholder."
        },
        {
          "name": "agentName",
          "type": "string",
          "default": "\"Build\"",
          "description": "Active agent label."
        },
        {
          "name": "modelName",
          "type": "string",
          "default": "\"Kimi K2.5\"",
          "description": "Model name in the status row."
        },
        {
          "name": "provider",
          "type": "string",
          "default": "\"Moonshot AI\"",
          "description": "Model provider label."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#2B7FFF\"",
          "description": "Left accent bar and agent color."
        },
        {
          "name": "theme",
          "type": "\"light\" | \"dark\"",
          "default": "\"dark\"",
          "description": "Light or dark TUI palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { Opencode } from \"@/remotion/scenes/opencode\";\n\n<Opencode query='\"What is the tech stack of this project?\"' />",
      "related": [
        "claude-code",
        "terminal-simulator",
        "chat-gpt"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-split",
      "type": "registry:lib",
      "description": "Split a string into chars, words or lines with staggered per-unit timing",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add text-split",
      "docsUrl": "https://remotionui.com/docs/components/text-split",
      "registryUrl": "https://remotionui.com/r/presets/default/text-split.json",
      "detailUrl": "https://remotionui.com/ai/components/text-split.json",
      "importPath": "@/remotion/lib/text-split",
      "installTarget": "src/remotion/lib/text-split",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "path-morph",
      "type": "registry:lib",
      "description": "Cached SVG path morphing with winding alignment and box fitting",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "@remotion/paths"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add path-morph",
      "docsUrl": "https://remotionui.com/docs/components/path-morph",
      "registryUrl": "https://remotionui.com/r/presets/default/path-morph.json",
      "detailUrl": "https://remotionui.com/ai/components/path-morph.json",
      "importPath": "@/remotion/lib/path-morph",
      "installTarget": "src/remotion/lib/path-morph",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "displacement-transition",
      "type": "registry:lib",
      "description": "Frame maths for displacement-map and shape-mask transitions",
      "tasks": [
        "transitions",
        "maps"
      ],
      "dependencies": [],
      "registryDependencies": [
        "path-morph"
      ],
      "installCommand": "npx remotion-ui@latest add displacement-transition",
      "docsUrl": "https://remotionui.com/docs/components/displacement-transition",
      "registryUrl": "https://remotionui.com/r/presets/default/displacement-transition.json",
      "detailUrl": "https://remotionui.com/ai/components/displacement-transition.json",
      "importPath": "@/remotion/lib/displacement-transition",
      "installTarget": "src/remotion/lib/displacement-transition",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "displacement-presentation",
      "type": "registry:lib",
      "description": "Shared TransitionSeries presentation for warp and shape-mask cuts",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "displacement-transition",
        "path-morph",
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add displacement-presentation",
      "docsUrl": "https://remotionui.com/docs/components/displacement-presentation",
      "registryUrl": "https://remotionui.com/r/presets/default/displacement-presentation.json",
      "detailUrl": "https://remotionui.com/ai/components/displacement-presentation.json",
      "importPath": "@/remotion/lib/displacement-presentation",
      "installTarget": "src/remotion/lib/displacement-presentation",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "sample-media",
      "type": "registry:lib",
      "description": "Placeholder stills, captions, and audio for composition defaults",
      "tasks": [
        "captions",
        "audio"
      ],
      "dependencies": [
        "@remotion/captions"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add sample-media",
      "docsUrl": "https://remotionui.com/docs/components/sample-media",
      "registryUrl": "https://remotionui.com/r/presets/default/sample-media.json",
      "detailUrl": "https://remotionui.com/ai/components/sample-media.json",
      "importPath": "@/remotion/lib/sample-media",
      "installTarget": "src/remotion/lib/sample-media",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "split-text-chars",
      "type": "registry:ui",
      "description": "Split text into chars, words or lines and stagger them in",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "text-split",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add split-text-chars",
      "docsUrl": "https://remotionui.com/docs/components/split-text-chars",
      "registryUrl": "https://remotionui.com/r/presets/default/split-text-chars.json",
      "detailUrl": "https://remotionui.com/ai/components/split-text-chars.json",
      "importPath": "@/remotion/primitives/split-text-chars",
      "installTarget": "src/remotion/primitives/split-text-chars",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Copy to split. `\\n` starts a new line.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "mode",
          "type": "\"chars\" | \"words\" | \"lines\"",
          "default": "\"chars\"",
          "description": "What one animated unit is. `words` is a word-by-word reveal.",
          "schema": {
            "type": "string",
            "enum": [
              "chars",
              "words",
              "lines"
            ]
          }
        },
        {
          "name": "order",
          "type": "\"start\" | \"end\" | \"center\" | \"edges\" | \"random\"",
          "default": "\"start\"",
          "description": "Which unit animates first. Document order is never changed.",
          "schema": {
            "type": "string",
            "enum": [
              "start",
              "end",
              "center",
              "edges",
              "random"
            ]
          }
        },
        {
          "name": "effect",
          "type": "\"fade-up\" | \"fade\" | \"scale\" | \"blur\" | \"none\"",
          "default": "\"fade-up\"",
          "description": "Built-in look. `none` positions the units and animates nothing.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "renderUnit",
          "type": "(unit: SplitUnitState) => ReactNode",
          "description": "Draws one unit from its own 0-1 progress. This is the composition point for custom text effects.",
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2 chars / 4 words / 7 lines",
          "description": "Frames between consecutive units.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20 chars / 24 words / 28 lines",
          "description": "Length of one unit's entrance.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first unit starts.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "spring",
          "type": "boolean | 'smooth' | 'snappy' | 'bouncy' | Partial<SpringConfig>",
          "description": "Drive the entrance with a spring instead of the ease-out curve.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Animate back out, landing inside the surrounding Sequence.",
          "schema": {
            "type": "boolean"
          }
        },
        {
          "name": "exitStaggerInFrames",
          "type": "number",
          "default": "= staggerInFrames",
          "description": "Frames between consecutive units leaving.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "travel",
          "type": "number",
          "default": "0.42",
          "description": "`fade-up` travel distance in em.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "84 (scaled)",
          "description": "Font size in pixels.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence.",
          "schema": {
            "type": "number"
          }
        }
      ],
      "usage": "import { SplitTextChars } from \"@/remotion/primitives/split-text-chars\";\n\n<SplitTextChars text=\"Ship it on Friday\" mode=\"chars\" order=\"center\" />\n\n// Headless: build your own effect on the same split and stagger.\nimport { useSplitText } from \"@/remotion/lib/text-split\";\nconst { lines } = useSplitText({ text, mode: \"words\" });",
      "related": [
        "staggered-fade-up",
        "tracking-in",
        "typewriter"
      ],
      "note": "The splitting foundation. Other text effects should call `useSplitText()` from `text-split` rather than re-implementing a split.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audio-reactive-scale",
      "type": "registry:ui",
      "description": "Scales any child by per-frame audio amplitude",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "media",
        "tier": "core",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add audio-reactive-scale",
      "docsUrl": "https://remotionui.com/docs/components/audio-reactive-scale",
      "registryUrl": "https://remotionui.com/r/presets/default/audio-reactive-scale.json",
      "detailUrl": "https://remotionui.com/ai/components/audio-reactive-scale.json",
      "importPath": "@/remotion/primitives/audio-reactive-scale",
      "installTarget": "src/remotion/primitives/audio-reactive-scale",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "required": true,
          "description": "Audio source. `useWindowedAudioData()` requires an uncompressed .wav.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": true,
          "description": "Anything to scale with the track.",
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "minScale",
          "type": "number",
          "default": "1",
          "description": "Scale at silence.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "maxScale",
          "type": "number",
          "default": "1.16",
          "description": "Scale at a full-amplitude hit.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "band",
          "type": "\"low\" | \"mid\" | \"high\" | \"full\" | \"bass\"",
          "default": "\"bass\"",
          "description": "Which slice of the spectrum drives the motion.",
          "schema": {
            "type": "string",
            "enum": [
              "low",
              "mid",
              "high",
              "full",
              "bass"
            ]
          }
        },
        {
          "name": "sensitivity",
          "type": "number",
          "default": "1",
          "description": "Multiplies the level before compression.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "compression",
          "type": "number",
          "default": "0.78",
          "description": "Exponent on the level. Below 1 lifts quiet passages.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "axis",
          "type": "\"both\" | \"x\" | \"y\"",
          "default": "\"both\"",
          "description": "Restrict the scale to one axis.",
          "schema": {
            "type": "string",
            "enum": [
              "both",
              "x",
              "y"
            ]
          }
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "0",
          "description": "Degrees of rotation at a full hit.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "minOpacity",
          "type": "number",
          "default": "1",
          "description": "Opacity at silence. Left at 1 the wrapper never touches opacity.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "frame",
          "type": "number",
          "description": "Frame override: pass the parent frame inside a Sequence.",
          "schema": {
            "type": "number"
          }
        }
      ],
      "usage": "import { AudioReactiveScale } from \"@/remotion/primitives/audio-reactive-scale\";\n\n<AudioReactiveScale src={staticFile(\"track.wav\")} maxScale={1.2}>\n  <Img src={staticFile(\"logo.png\")} />\n</AudioReactiveScale>",
      "related": [
        "audio-pulse",
        "audiogram-bars",
        "waveform-line"
      ],
      "note": "Shares `useAudioAmplitude()` with audio-pulse, so two components on one track pump in step.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "srt-caption-track",
      "type": "registry:ui",
      "description": "Renders a caption track straight from an SRT or WebVTT file",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "caption-utils",
        "caption-highlight"
      ],
      "installCommand": "npx remotion-ui@latest add srt-caption-track",
      "docsUrl": "https://remotionui.com/docs/components/srt-caption-track",
      "registryUrl": "https://remotionui.com/r/presets/default/srt-caption-track.json",
      "detailUrl": "https://remotionui.com/ai/components/srt-caption-track.json",
      "importPath": "@/remotion/primitives/srt-caption-track",
      "installTarget": "src/remotion/primitives/srt-caption-track",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "description": "URL of an SRT or WebVTT file. Fetched behind delayRender().",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "source",
          "type": "string",
          "description": "Raw subtitle text, when the transcript is already in hand.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "captions",
          "type": "Caption[]",
          "description": "Pre-parsed captions, e.g. from Whisper, which has real word timing.",
          "schema": {
            "type": "array"
          }
        },
        {
          "name": "wordTiming",
          "type": "\"distribute\" | \"cue\"",
          "default": "\"distribute\"",
          "description": "Subtitle files have no word timestamps. `distribute` spreads each cue across its words by length so highlight styles have something to highlight.",
          "schema": {
            "type": "string",
            "enum": [
              "distribute",
              "cue"
            ]
          }
        },
        {
          "name": "combineTokensWithinMilliseconds",
          "type": "number",
          "default": "1200",
          "description": "Tokens closer than this share a page.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "offsetInFrames",
          "type": "number",
          "default": "0",
          "description": "Shift the whole track. Positive delays it.",
          "schema": {
            "type": "number"
          }
        },
        {
          "name": "renderPage",
          "type": "(page: TikTokPage, index: number) => ReactNode",
          "description": "Draws one page. Defaults to CaptionHighlight.",
          "schema": {
            "type": "object"
          }
        },
        {
          "name": "activeColor",
          "type": "string",
          "default": "\"#ff6b00\"",
          "description": "Passed to the default renderer.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "inactiveColor",
          "type": "string",
          "default": "\"#ffffff\"",
          "description": "Passed to the default renderer.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "fontSize",
          "type": "number",
          "description": "Passed to the default renderer.",
          "schema": {
            "type": "number"
          }
        }
      ],
      "usage": "import { SrtCaptionTrack } from \"@/remotion/primitives/srt-caption-track\";\n\n<SrtCaptionTrack src={staticFile(\"episode.srt\")} />\n\n// Any caption style can render the pages.\n<SrtCaptionTrack\n  src={staticFile(\"episode.srt\")}\n  renderPage={(page) => <KaraokeCaptions page={page} mode=\"underline\" />}\n/>",
      "related": [
        "caption-highlight",
        "karaoke-captions",
        "caption-scene"
      ],
      "note": "Utility, not a look. Installs @remotion/captions and caption-highlight.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-circle-reveal",
      "type": "registry:ui",
      "description": "Circular mask that opens from any point onto the next scene",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-circle-reveal",
      "docsUrl": "https://remotionui.com/docs/components/transition-circle-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-circle-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-circle-reveal.json",
      "importPath": "@/remotion/primitives/transition-circle-reveal",
      "installTarget": "src/remotion/primitives/transition-circle-reveal",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Transition overlap length."
        },
        {
          "name": "originX",
          "type": "number",
          "default": "0.5",
          "description": "Centre of the circle, 0→1 of the frame width."
        },
        {
          "name": "originY",
          "type": "number",
          "default": "0.5",
          "description": "Centre of the circle, 0→1 of the frame height."
        },
        {
          "name": "edgeSoftness",
          "type": "number",
          "default": "0.04",
          "description": "Feathered edge as a share of the final radius. 0 cuts hard."
        },
        {
          "name": "underScale",
          "type": "number",
          "default": "1",
          "description": "Scale the outgoing scene drifts to under the hole. 1 holds it still."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionCircleReveal } from \"@/remotion/primitives/transition-circle-reveal\";\n\n<TransitionSeries.Transition {...transitionCircleReveal({ originX: 0.3, originY: 0.4 })} />",
      "related": [
        "transition-morph-shape",
        "transition-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-card-flip",
      "type": "registry:ui",
      "description": "Whole-frame 3D flip that hands off on backface culling",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-card-flip",
      "docsUrl": "https://remotionui.com/docs/components/transition-card-flip",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-card-flip.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-card-flip.json",
      "importPath": "@/remotion/primitives/transition-card-flip",
      "installTarget": "src/remotion/primitives/transition-card-flip",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Transition overlap length."
        },
        {
          "name": "axis",
          "type": "\"y\" | \"x\"",
          "default": "\"y\"",
          "description": "y flips left-to-right like a page; x flips top over bottom."
        },
        {
          "name": "perspective",
          "type": "number",
          "default": "1600",
          "description": "Perspective distance in px. Lower is a wider-angle flip."
        },
        {
          "name": "backdrop",
          "type": "string",
          "default": "\"#05060a\"",
          "description": "Colour behind the card while it is edge-on. Without it the page background shows at the halfway frame."
        },
        {
          "name": "shading",
          "type": "number",
          "default": "0.55",
          "description": "Peak darkening of the face turning away, 0→1."
        },
        {
          "name": "dip",
          "type": "number",
          "default": "0.86",
          "description": "How far the card recedes at the halfway point."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionCardFlip } from \"@/remotion/primitives/transition-card-flip\";\n\n<TransitionSeries.Transition {...transitionCardFlip({ axis: \"y\" })} />",
      "related": [
        "transition-whip-pan",
        "spatial-push"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-blinds",
      "type": "registry:ui",
      "description": "Staggered slats sweeping open to reveal the next scene",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-blinds",
      "docsUrl": "https://remotionui.com/docs/components/transition-blinds",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-blinds.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-blinds.json",
      "importPath": "@/remotion/primitives/transition-blinds",
      "installTarget": "src/remotion/primitives/transition-blinds",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Transition overlap length."
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "default": "\"horizontal\"",
          "description": "Horizontal slats stack top to bottom and sweep sideways."
        },
        {
          "name": "slats",
          "type": "number",
          "default": "12",
          "description": "Number of slats. Above ~24 it stops reading as slats at 1080p."
        },
        {
          "name": "stagger",
          "type": "number",
          "default": "0.45",
          "description": "Share of the window the cascade spans. 0 opens every slat together."
        },
        {
          "name": "alternate",
          "type": "boolean",
          "default": "false",
          "description": "Reverse alternate slats for a woven counter-sweep."
        },
        {
          "name": "edgeSoftness",
          "type": "number",
          "default": "0.06",
          "description": "Soft leading edge per slat, as a share of its length."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionBlinds } from \"@/remotion/primitives/transition-blinds\";\n\n<TransitionSeries.Transition {...transitionBlinds({ slats: 12, stagger: 0.45 })} />",
      "related": [
        "grid-pixelate-wipe",
        "directional-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-whip-pan",
      "type": "registry:ui",
      "description": "Fast pan with directional motion blur along the travel axis",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-whip-pan",
      "docsUrl": "https://remotionui.com/docs/components/transition-whip-pan",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-whip-pan.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-whip-pan.json",
      "importPath": "@/remotion/primitives/transition-whip-pan",
      "installTarget": "src/remotion/primitives/transition-whip-pan",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "14",
          "description": "Transition overlap length. A whip is short by definition."
        },
        {
          "name": "direction",
          "type": "\"from-left\" | \"from-right\" | \"from-top\" | \"from-bottom\"",
          "default": "\"from-left\"",
          "description": "Side the next scene arrives from."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "26",
          "description": "Peak blur in px along the travel axis, at the fastest point."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "1",
          "description": "Share of the frame each scene travels. Below 1 shows background between them."
        },
        {
          "name": "punch",
          "type": "number",
          "default": "2.2",
          "description": "How hard the move is front-loaded into the middle. 1 is the house ease and reads as a push."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionWhipPan } from \"@/remotion/primitives/transition-whip-pan\";\n\n<TransitionSeries.Transition {...transitionWhipPan({ direction: \"from-left\", blur: 26 })} />",
      "related": [
        "spatial-push",
        "chromatic-aberration-wipe"
      ],
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-morph-shape",
      "type": "registry:ui",
      "description": "Reveal through a shape that morphs as it grows across the frame",
      "tasks": [
        "transitions"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "displacement-presentation",
        "displacement-transition",
        "path-morph",
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-morph-shape",
      "docsUrl": "https://remotionui.com/docs/components/transition-morph-shape",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-morph-shape.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-morph-shape.json",
      "importPath": "@/remotion/primitives/transition-morph-shape",
      "installTarget": "src/remotion/primitives/transition-morph-shape",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Transition overlap length."
        },
        {
          "name": "from",
          "type": "\"circle\" | \"square\" | \"squircle\" | \"triangle\" | \"diamond\" | \"blob\" | string",
          "default": "\"circle\"",
          "description": "Shape the reveal starts as, at zero size. A raw path d also works."
        },
        {
          "name": "to",
          "type": "\"circle\" | \"square\" | \"squircle\" | \"triangle\" | \"diamond\" | \"blob\" | string",
          "default": "\"squircle\"",
          "description": "Shape it has become once it covers the frame."
        },
        {
          "name": "originX",
          "type": "number",
          "default": "0.5",
          "description": "Where the shape grows from, 0→1 of the frame width."
        },
        {
          "name": "originY",
          "type": "number",
          "default": "0.5",
          "description": "Where the shape grows from, 0→1 of the frame height."
        },
        {
          "name": "overshoot",
          "type": "number",
          "default": "1.06",
          "description": "Final size as a multiple of the frame diagonal. Below 1 leaves corners unrevealed."
        },
        {
          "name": "warp",
          "type": "number",
          "default": "0",
          "description": "Optional turbulence on the revealed scene, in px. 0 keeps the silhouette crisp."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionMorphShape } from \"@/remotion/primitives/transition-morph-shape\";\n\n<TransitionSeries.Transition {...transitionMorphShape({ from: \"circle\", to: \"diamond\" })} />",
      "related": [
        "transition-circle-reveal",
        "transition-liquid-warp",
        "path-morph"
      ],
      "note": "Configuration of the shared displacement presentation: the mask channel with turbulence off.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transition-liquid-warp",
      "type": "registry:ui",
      "description": "Liquid displacement warp that stirs one scene into the next",
      "tasks": [
        "transitions",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "cuts",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion",
        "@remotion/transitions"
      ],
      "registryDependencies": [
        "displacement-presentation",
        "displacement-transition",
        "transition-timing"
      ],
      "installCommand": "npx remotion-ui@latest add transition-liquid-warp",
      "docsUrl": "https://remotionui.com/docs/components/transition-liquid-warp",
      "registryUrl": "https://remotionui.com/r/presets/default/transition-liquid-warp.json",
      "detailUrl": "https://remotionui.com/ai/components/transition-liquid-warp.json",
      "importPath": "@/remotion/primitives/transition-liquid-warp",
      "installTarget": "src/remotion/primitives/transition-liquid-warp",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Transition overlap length. Long enough for the field to boil."
        },
        {
          "name": "scaleRatio",
          "type": "number",
          "default": "0.12",
          "description": "Peak displacement at the middle of the cut, as a fraction of the frame's short axis. Frame-relative so the warp reads the same at any composition size."
        },
        {
          "name": "frequency",
          "type": "number",
          "default": "0.006",
          "description": "Turbulence base frequency. Below 0.004 reads as a lens, above 0.02 as noise."
        },
        {
          "name": "octaves",
          "type": "number",
          "default": "2",
          "description": "Turbulence octaves. Above 3 costs a lot and adds almost nothing."
        },
        {
          "name": "churn",
          "type": "number",
          "default": "6",
          "description": "How much the noise field re-seeds across the cut. 0 holds one static lens."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "3",
          "description": "Peak blur in px, on the same curve as the displacement."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "7",
          "description": "Turbulence seed."
        },
        {
          "name": "affect",
          "type": "\"both\" | \"entering\"",
          "default": "\"both\"",
          "description": "Warp both scenes, or only the arriving one."
        },
        {
          "name": "variant",
          "type": "\"linear\" | \"spring\" | \"editorial\"",
          "default": "\"editorial\"",
          "description": "Timing curve."
        }
      ],
      "usage": "import { transitionLiquidWarp } from \"@/remotion/primitives/transition-liquid-warp\";\n\n<TransitionSeries.Transition {...transitionLiquidWarp({ scaleRatio: 0.12 })} />",
      "related": [
        "transition-morph-shape",
        "transition-fade"
      ],
      "note": "Configuration of the shared displacement presentation: the turbulence channel with no mask.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "skew-in",
      "type": "registry:ui",
      "description": "Skew + translate, editorial feel",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "enter"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-primitive",
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add skew-in",
      "docsUrl": "https://remotionui.com/docs/components/skew-in",
      "registryUrl": "https://remotionui.com/r/presets/default/skew-in.json",
      "detailUrl": "https://remotionui.com/ai/components/skew-in.json",
      "importPath": "@/remotion/primitives/skew-in",
      "installTarget": "src/remotion/primitives/skew-in",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What leans in."
        },
        {
          "name": "skew",
          "type": "number",
          "default": "14",
          "description": "Horizontal shear it starts at, in degrees."
        },
        {
          "name": "skewY",
          "type": "number",
          "default": "0",
          "description": "Vertical shear it starts at. Small values only."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "56",
          "description": "How far it slides in, in px. Travels against the lean."
        },
        {
          "name": "direction",
          "type": "\"left\" | \"right\"",
          "default": "\"left\"",
          "description": "Which way the element leans on the way in."
        },
        {
          "name": "origin",
          "type": "TransformOrigin",
          "default": "\"bottom left\"",
          "description": "Pivot. A centre pivot lifts the baseline and the line below jumps."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the entrance."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before it starts."
        },
        {
          "name": "spring",
          "type": "MotionSpring",
          "description": "Drive the entrance with a spring instead of the ease-out curve."
        },
        {
          "name": "exit",
          "type": "boolean",
          "default": "false",
          "description": "Land out at the end of the surrounding Sequence."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the exit starts on. Overrides the automatic timing."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "description": "Length of the exit. Defaults to 70% of the entrance."
        },
        {
          "name": "exitDirection",
          "type": "\"reverse\" | \"continue\"",
          "default": "\"reverse\"",
          "description": "Straighten back, or carry the lean on through."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent's width instead of shrink-wrapping."
        }
      ],
      "usage": "import { SkewIn } from \"@/remotion/primitives/skew-in\";\n\n<SkewIn skew={16} travel={72} durationInFrames={40}>\n  <h1>Leans in, straightens up</h1>\n</SkewIn>",
      "related": [
        "slide-left",
        "rotate-in",
        "spring-in"
      ],
      "note": "The shear opposes the travel on purpose: the element looks dragged upright by its own momentum.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "scramble-text",
      "type": "registry:ui",
      "description": "Random-glyph scramble resolving per character",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split"
      ],
      "installCommand": "npx remotion-ui@latest add scramble-text",
      "docsUrl": "https://remotionui.com/docs/components/scramble-text",
      "registryUrl": "https://remotionui.com/r/presets/default/scramble-text.json",
      "detailUrl": "https://remotionui.com/ai/components/scramble-text.json",
      "importPath": "@/remotion/primitives/scramble-text",
      "installTarget": "src/remotion/primitives/scramble-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The string that resolves. `\\n` breaks a line."
        },
        {
          "name": "charset",
          "type": "\"latin\" | \"symbols\" | \"digits\" | \"blocks\" | string",
          "default": "\"symbols\"",
          "description": "Glyph pool the noise is drawn from. Any string is used as-is."
        },
        {
          "name": "tickInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames one noise glyph is held. 1 is a blur, 4 is a slot machine."
        },
        {
          "name": "scrambleColor",
          "type": "string",
          "description": "Colour of the unresolved glyphs. Defaults to `color`."
        },
        {
          "name": "scrambleOpacity",
          "type": "number",
          "default": "0.72",
          "description": "Opacity of the unresolved glyphs."
        },
        {
          "name": "scrambleOnExit",
          "type": "boolean",
          "default": "true",
          "description": "Scramble again on the way out."
        },
        {
          "name": "order",
          "type": "\"start\" | \"end\" | \"center\" | \"edges\" | \"random\"",
          "default": "\"start\"",
          "description": "Which character resolves first. Document order is never affected."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between one character resolving and the next."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one character's resolve."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first character starts."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Seeds the glyph noise and `order=\"random\"`."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the first character starts leaving on."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "default": "ui-monospace stack",
          "description": "Monospace by default: a proportional face re-flows on every tick."
        }
      ],
      "usage": "import { ScrambleText } from \"@/remotion/primitives/scramble-text\";\n\n<ScrambleText text=\"Resolve out of noise\" order=\"center\" charset=\"symbols\" />",
      "related": [
        "split-text-chars",
        "matrix-decode",
        "slot-roll"
      ],
      "note": "Per-character clocks, so any stagger order works. `matrix-decode` resolves strictly left to right from one shared progress value.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-mask-video",
      "type": "registry:ui",
      "description": "Video or gradient showing through letterforms",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "layout",
        "motion-primitive"
      ],
      "installCommand": "npx remotion-ui@latest add text-mask-video",
      "docsUrl": "https://remotionui.com/docs/components/text-mask-video",
      "registryUrl": "https://remotionui.com/r/presets/default/text-mask-video.json",
      "detailUrl": "https://remotionui.com/ai/components/text-mask-video.json",
      "importPath": "@/remotion/primitives/text-mask-video",
      "installTarget": "src/remotion/primitives/text-mask-video",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The letterforms the media is seen through. `\\n` breaks a line."
        },
        {
          "name": "src",
          "type": "string",
          "description": "Video or image source. Wrap local files in `staticFile()`."
        },
        {
          "name": "media",
          "type": "\"video\" | \"image\" | \"gradient\"",
          "default": "video with a src, gradient without",
          "description": "Which layer is drawn behind the letters."
        },
        {
          "name": "gradient",
          "type": "string",
          "description": "Any CSS background, used by `media=\"gradient\"`."
        },
        {
          "name": "mediaFilter",
          "type": "string",
          "description": "CSS filter on the media. Footage is usually too dark inside letterforms."
        },
        {
          "name": "reveal",
          "type": "\"left\" | \"right\" | \"up\" | \"down\" | \"none\"",
          "default": "\"left\"",
          "description": "Which way the letters are uncovered."
        },
        {
          "name": "width",
          "type": "number",
          "description": "Clip coordinate space. Defaults to a multiple of `fontSize`."
        },
        {
          "name": "height",
          "type": "number",
          "description": "Clip coordinate space. Defaults from the line count."
        },
        {
          "name": "drift",
          "type": "number",
          "default": "26",
          "description": "Peak sideways travel of the media, in px."
        },
        {
          "name": "zoom",
          "type": "number",
          "default": "0.12",
          "description": "Extra scale the media breathes through. 0 holds it still."
        },
        {
          "name": "startFrom",
          "type": "number",
          "description": "Frame offset into the video."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the reveal."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the reveal starts."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the reveal starts unwinding on."
        }
      ],
      "usage": "import { staticFile } from \"remotion\";\nimport { TextMaskVideo } from \"@/remotion/primitives/text-mask-video\";\n\n<TextMaskVideo\n  text={\"IN\\nMOTION\"}\n  src={staticFile(\"clips/skyline.mp4\")}\n  fontSize={172}\n  fontWeight={900}\n/>",
      "related": [
        "light-sweep-text",
        "svg-mask-reveal",
        "stroke-to-fill-text"
      ],
      "note": "An SVG clipPath on a real element, not `background-clip: text`, which only takes a paint, so it can never carry a video.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "handwriting-text",
      "type": "registry:ui",
      "description": "Takes a string and strokes it on",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split"
      ],
      "installCommand": "npx remotion-ui@latest add handwriting-text",
      "docsUrl": "https://remotionui.com/docs/components/handwriting-text",
      "registryUrl": "https://remotionui.com/r/presets/default/handwriting-text.json",
      "detailUrl": "https://remotionui.com/ai/components/handwriting-text.json",
      "importPath": "@/remotion/primitives/handwriting-text",
      "installTarget": "src/remotion/primitives/handwriting-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The line that gets written."
        },
        {
          "name": "penSize",
          "type": "number",
          "default": "0.14",
          "description": "Diameter of the nib, in em. 0 hides it."
        },
        {
          "name": "penColor",
          "type": "string",
          "description": "Nib colour. Defaults to `color`."
        },
        {
          "name": "inkSoftness",
          "type": "number",
          "default": "0.18",
          "description": "Softness of the ink edge, as a share of one glyph."
        },
        {
          "name": "wobble",
          "type": "number",
          "default": "1.6",
          "description": "Per-character tilt and baseline drift, in degrees. Fixed, not animated."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "3",
          "description": "Frames between one character and the next. This is the writing speed."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames one character takes to be drawn."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first stroke."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the ink starts fading on."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "default": "script stack",
          "description": "Ends in generic `cursive`; pass a webfont for identical renders everywhere."
        }
      ],
      "usage": "import { HandwritingText } from \"@/remotion/primitives/handwriting-text\";\n\n<HandwritingText text=\"Signed by hand\" staggerInFrames={9} penColor=\"#e8b86d\" />",
      "related": [
        "path-draw",
        "split-text-chars",
        "marker-highlight"
      ],
      "note": "Takes a string, so there is no stroke order: the ink is wiped on per glyph. `path-draw` takes a path and strokes it properly. `order` and `mode` are deliberately not props.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "stroke-to-fill-text",
      "type": "registry:ui",
      "description": "Outline text filling solid",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split",
        "timing"
      ],
      "installCommand": "npx remotion-ui@latest add stroke-to-fill-text",
      "docsUrl": "https://remotionui.com/docs/components/stroke-to-fill-text",
      "registryUrl": "https://remotionui.com/r/presets/default/stroke-to-fill-text.json",
      "detailUrl": "https://remotionui.com/ai/components/stroke-to-fill-text.json",
      "importPath": "@/remotion/primitives/stroke-to-fill-text",
      "installTarget": "src/remotion/primitives/stroke-to-fill-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The line that outlines and then fills."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "2",
          "description": "Outline weight in px, before it thins into the fill."
        },
        {
          "name": "strokeColor",
          "type": "string",
          "description": "Outline colour. Defaults to `color`."
        },
        {
          "name": "fillColor",
          "type": "string",
          "description": "Colour the letter fills with. Defaults to `color`."
        },
        {
          "name": "direction",
          "type": "\"up\" | \"down\" | \"left\" | \"right\"",
          "default": "\"up\"",
          "description": "Which way the fill floods the letter."
        },
        {
          "name": "edgeSoftness",
          "type": "number",
          "default": "0.12",
          "description": "Softness of the fill edge, as a share of the glyph. 0 is a hard line."
        },
        {
          "name": "strokeRetain",
          "type": "number",
          "default": "0.35",
          "description": "Share of the outline weight left once the letter is full."
        },
        {
          "name": "outlineInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the outline takes to draw. It arrives as a whole word, unstaggered."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between one letter flooding and the next."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one letter's flood."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the outline starts."
        },
        {
          "name": "order",
          "type": "\"start\" | \"end\" | \"center\" | \"edges\" | \"random\"",
          "default": "\"start\"",
          "description": "Which letter floods first."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the fill starts draining on."
        }
      ],
      "usage": "import { StrokeToFillText } from \"@/remotion/primitives/stroke-to-fill-text\";\n\n<StrokeToFillText\n  text=\"Ship faster with source\"\n  strokeColor=\"#e8b86d\"\n  staggerInFrames={5}\n/>",
      "related": [
        "split-text-chars",
        "text-mask-video",
        "path-draw"
      ],
      "note": "The outline is unstaggered and the fill is staggered. Running both on one clock leaves the un-flooded half of the line absent, which reads as truncated type.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "variable-font-morph",
      "type": "registry:ui",
      "description": "Animates weight/width axes of a variable font",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split"
      ],
      "installCommand": "npx remotion-ui@latest add variable-font-morph",
      "docsUrl": "https://remotionui.com/docs/components/variable-font-morph",
      "registryUrl": "https://remotionui.com/r/presets/default/variable-font-morph.json",
      "detailUrl": "https://remotionui.com/ai/components/variable-font-morph.json",
      "importPath": "@/remotion/primitives/variable-font-morph",
      "installTarget": "src/remotion/primitives/variable-font-morph",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The line whose axes are swept."
        },
        {
          "name": "weight",
          "type": "[number, number]",
          "default": "[200, 800]",
          "description": "`wght` axis. Also mirrored onto `font-weight`."
        },
        {
          "name": "width",
          "type": "[number, number]",
          "description": "`wdth` axis in percent. Also mirrored onto `font-stretch`."
        },
        {
          "name": "slant",
          "type": "[number, number]",
          "description": "`slnt` axis in degrees. Negative leans right, per the spec."
        },
        {
          "name": "axes",
          "type": "Record<string, [number, number]>",
          "description": "Any further axes by four-letter tag, e.g. `{ opsz: [14, 96] }`."
        },
        {
          "name": "oscillate",
          "type": "boolean",
          "default": "false",
          "description": "Keep travelling between the two ends instead of landing on `to`."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "60",
          "description": "Frames for one there-and-back when oscillating."
        },
        {
          "name": "phaseStep",
          "type": "number",
          "default": "0.55",
          "description": "Radians of offset per character along the wave."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between one character starting and the next."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one character's ramp."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first character starts."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "description": "Pass a variable face here: the fallback only steps between static weights."
        },
        {
          "name": "reserveSpace",
          "type": "boolean",
          "default": "true",
          "description": "Lay each glyph out in a cell sized by a hidden copy at the heaviest, widest setting. Weight changes advance widths, so without it a centred line re-centres itself every frame."
        }
      ],
      "usage": "import { VariableFontMorph } from \"@/remotion/primitives/variable-font-morph\";\n\n<VariableFontMorph text=\"Weight in motion\" weight={[200, 900]} oscillate />",
      "related": [
        "split-text-chars",
        "wave-text",
        "tracking-in"
      ],
      "note": "One 0–1 position drives every axis at once. On a static face the values fall back to `font-weight`/`font-stretch`, which steps rather than glides.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "liquid-text-morph",
      "type": "registry:ui",
      "description": "Letterforms morphing between two words",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split",
        "layout"
      ],
      "installCommand": "npx remotion-ui@latest add liquid-text-morph",
      "docsUrl": "https://remotionui.com/docs/components/liquid-text-morph",
      "registryUrl": "https://remotionui.com/r/presets/default/liquid-text-morph.json",
      "detailUrl": "https://remotionui.com/ai/components/liquid-text-morph.json",
      "importPath": "@/remotion/primitives/liquid-text-morph",
      "installTarget": "src/remotion/primitives/liquid-text-morph",
      "category": "primitive",
      "props": [
        {
          "name": "words",
          "type": "string[]",
          "description": "Two or more words. The last melts back into the first when looping."
        },
        {
          "name": "holdInFrames",
          "type": "number",
          "default": "12",
          "description": "Frames a word is held before it starts melting."
        },
        {
          "name": "morphInFrames",
          "type": "number",
          "default": "22",
          "description": "Frames one word takes to become the next."
        },
        {
          "name": "loop",
          "type": "boolean",
          "default": "true",
          "description": "Keep cycling. When false the last word is held forever."
        },
        {
          "name": "gooStrength",
          "type": "number",
          "default": "0.045",
          "description": "Blur feeding the threshold, in em. This is what makes letters merge."
        },
        {
          "name": "gooContrast",
          "type": "number",
          "default": "18",
          "description": "Alpha contrast on the blurred layer. Lower is softer and wetter."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between neighbouring letters melting. Clamped to fit the morph."
        },
        {
          "name": "fontSize",
          "type": "number",
          "description": "Defaults to a scaled 96px at the composition width."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#f4f4f5\"",
          "description": "Ink colour."
        },
        {
          "name": "fontWeight",
          "type": "number | string",
          "default": "700",
          "description": "Heavier weights fuse more readily under the threshold."
        }
      ],
      "usage": "import { LiquidTextMorph } from \"@/remotion/primitives/liquid-text-morph\";\n\n<LiquidTextMorph words={[\"Melt\", \"Merge\", \"Reform\"]} morphInFrames={22} />",
      "related": [
        "shape-morph",
        "split-text-chars",
        "blob-morph"
      ],
      "note": "A gooey threshold filter, not path interpolation: two arbitrary letters do not have matching node counts. Use `shape-morph` for paths you control.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "wave-text",
      "type": "registry:ui",
      "description": "Per-character sine displacement",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split"
      ],
      "installCommand": "npx remotion-ui@latest add wave-text",
      "docsUrl": "https://remotionui.com/docs/components/wave-text",
      "registryUrl": "https://remotionui.com/r/presets/default/wave-text.json",
      "detailUrl": "https://remotionui.com/ai/components/wave-text.json",
      "importPath": "@/remotion/primitives/wave-text",
      "installTarget": "src/remotion/primitives/wave-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The line the wave runs along."
        },
        {
          "name": "amplitude",
          "type": "number",
          "default": "0.16",
          "description": "Peak displacement, in em of the font size."
        },
        {
          "name": "wavelength",
          "type": "number",
          "default": "6",
          "description": "Characters per full wave. Higher spreads the crest wider."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "48",
          "description": "Frames for one full cycle."
        },
        {
          "name": "direction",
          "type": "\"forward\" | \"backward\"",
          "default": "\"forward\"",
          "description": "Travel direction along the line."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "0.06",
          "description": "Extra scale on the crest, so it reads as depth rather than jitter."
        },
        {
          "name": "shade",
          "type": "number",
          "default": "0.25",
          "description": "How far the trough fades. 0 keeps every character at full opacity."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between one character arriving and the next."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one character's entrance."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the first character arrives."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the line starts leaving on. The wave lowers with it."
        }
      ],
      "usage": "import { WaveText } from \"@/remotion/primitives/wave-text\";\n\n<WaveText text=\"Ride the sine\" amplitude={0.2} wavelength={5} />",
      "related": [
        "split-text-chars",
        "infinite-marquee",
        "variable-font-morph"
      ],
      "note": "Ambient: the wave is a function of the frame and never settles. Phase follows document order, not the stagger rank.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "neon-flicker-text",
      "type": "registry:ui",
      "description": "Neon sign flicker and settle",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "split-text-chars",
        "text-split"
      ],
      "installCommand": "npx remotion-ui@latest add neon-flicker-text",
      "docsUrl": "https://remotionui.com/docs/components/neon-flicker-text",
      "registryUrl": "https://remotionui.com/r/presets/default/neon-flicker-text.json",
      "detailUrl": "https://remotionui.com/ai/components/neon-flicker-text.json",
      "importPath": "@/remotion/primitives/neon-flicker-text",
      "installTarget": "src/remotion/primitives/neon-flicker-text",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "description": "The sign."
        },
        {
          "name": "glowColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Colour of the halo around the tube."
        },
        {
          "name": "glowSize",
          "type": "number",
          "default": "26",
          "description": "Halo radius in px at full brightness. Four stacked shadows, so it stays soft."
        },
        {
          "name": "offColor",
          "type": "string",
          "default": "faint pink",
          "description": "The tube with no gas lit: cold glass, not invisible."
        },
        {
          "name": "offLevel",
          "type": "number",
          "default": "0.14",
          "description": "Brightness of an unlit tube, 0–1."
        },
        {
          "name": "hum",
          "type": "number",
          "default": "0.12",
          "description": "Depth of the mains hum once the sign has settled."
        },
        {
          "name": "buzz",
          "type": "number",
          "default": "0.06",
          "description": "Chance per beat that a settled tube stutters. 0 disables it."
        },
        {
          "name": "flickerOnExit",
          "type": "boolean",
          "default": "true",
          "description": "Stutter back off instead of fading cleanly."
        },
        {
          "name": "order",
          "type": "\"start\" | \"end\" | \"center\" | \"edges\" | \"random\"",
          "default": "\"start\"",
          "description": "Which tube strikes first. `random` is the natural fit."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames between one tube striking and the next."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one tube's ignition. Longer sputters more."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Seeds the flicker and `order=\"random\"`."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the sign starts cutting out on."
        }
      ],
      "usage": "import { NeonFlickerText } from \"@/remotion/primitives/neon-flicker-text\";\n\n<NeonFlickerText text=\"Open all night\" order=\"random\" glowColor=\"#f472b6\" />",
      "related": [
        "split-text-chars",
        "glow-pulse",
        "rgb-glitch-text"
      ],
      "note": "A gas-discharge model: unlit tubes are still cold glass, strike probability climbs so the sign resolves, and a lit tube keeps a hum. A settled state with no hum looks like a PNG.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "aurora-bg",
      "type": "registry:ui",
      "description": "Drifting light ribbons",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add aurora-bg",
      "docsUrl": "https://remotionui.com/docs/components/aurora-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/aurora-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/aurora-bg.json",
      "importPath": "@/remotion/primitives/aurora-bg",
      "installTarget": "src/remotion/primitives/aurora-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Plate behind the curtains. `transparent` layers them over footage."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "[\"#e4ac59\", \"#e07a5f\", \"#c2557a\"]",
          "description": "Curtain colours, cycled."
        },
        {
          "name": "ribbonCount",
          "type": "number",
          "default": "4",
          "description": "How many curtains."
        },
        {
          "name": "amplitude",
          "type": "number",
          "default": "9",
          "description": "Vertical travel of a fold, in percent of the frame."
        },
        {
          "name": "thickness",
          "type": "number",
          "default": "15",
          "description": "Curtain height at its thickest point, in percent."
        },
        {
          "name": "centerY",
          "type": "number",
          "default": "46",
          "description": "Where the band sits, in percent of the frame height."
        },
        {
          "name": "spread",
          "type": "number",
          "default": "34",
          "description": "How far the curtains spread around `centerY`."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Drift speed. 0 freezes the sky."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "14",
          "description": "Softness in px. Much above 20 and the folds become blobs."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1.3",
          "description": "Overall brightness."
        },
        {
          "name": "horizonGlow",
          "type": "number",
          "default": "0.5",
          "description": "Ground glow under the band. 0 removes it."
        },
        {
          "name": "striation",
          "type": "number",
          "default": "0.55",
          "description": "Vertical ray structure through the curtains, 0-1."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the fold layout without changing any other prop."
        }
      ],
      "usage": "import { AuroraBg } from \"@/remotion/primitives/aurora-bg\";\n\n<AbsoluteFill>\n  <AuroraBg ribbonCount={4} />\n  <YourScene />\n</AbsoluteFill>",
      "related": [
        "mesh-gradient-bg",
        "light-rays",
        "particle-field"
      ],
      "note": "Tapered paths whose shape changes every frame, not gradients that move. That is the line between this and `mesh-gradient-bg`. Two incommensurate fold clocks (2.3s against 1.1s) mean a curtain never repeats a shape. Background layer, so it has no entrance.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "particle-field",
      "type": "registry:ui",
      "description": "Ambient drifting particles with depth",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add particle-field",
      "docsUrl": "https://remotionui.com/docs/components/particle-field",
      "registryUrl": "https://remotionui.com/r/presets/default/particle-field.json",
      "detailUrl": "https://remotionui.com/ai/components/particle-field.json",
      "importPath": "@/remotion/primitives/particle-field",
      "installTarget": "src/remotion/primitives/particle-field",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#05070f\"",
          "description": "Plate behind the field. `transparent` layers it over footage."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Particle colour."
        },
        {
          "name": "count",
          "type": "number",
          "default": "70",
          "description": "How many particles."
        },
        {
          "name": "angle",
          "type": "number",
          "default": "8",
          "description": "Direction of travel in degrees. 0 drifts straight up."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Traverse speed. 1 crosses the frame in about eight seconds."
        },
        {
          "name": "size",
          "type": "number",
          "default": "14",
          "description": "Diameter of the nearest particle, in px."
        },
        {
          "name": "minSize",
          "type": "number",
          "default": "2",
          "description": "Diameter of the furthest particle, in px."
        },
        {
          "name": "depthBlur",
          "type": "number",
          "default": "3",
          "description": "Defocus on the furthest particles. 0 flattens the field."
        },
        {
          "name": "drift",
          "type": "number",
          "default": "4",
          "description": "Sideways wander, in percent of the frame."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Overall brightness."
        },
        {
          "name": "glow",
          "type": "number",
          "default": "1.6",
          "description": "Halo per particle, as a multiple of its size. 0 draws hard dots."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the layout without changing any other prop."
        }
      ],
      "usage": "import { ParticleField } from \"@/remotion/primitives/particle-field\";\n\n<AbsoluteFill>\n  <ParticleField count={70} angle={8} />\n  <YourScene />\n</AbsoluteFill>",
      "related": [
        "confetti-burst",
        "aurora-bg",
        "mesh-gradient-bg"
      ],
      "note": "Continuous, unlike `confetti-burst`, which is a single impulse. One depth value per particle drives size, speed, brightness and focus together, and that correlation is what makes a plane of divs read as volume. Travel wraps on a track whose ends sit outside the frame.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "topographic-lines-bg",
      "type": "registry:ui",
      "description": "Contour lines drifting",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add topographic-lines-bg",
      "docsUrl": "https://remotionui.com/docs/components/topographic-lines-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/topographic-lines-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/topographic-lines-bg.json",
      "importPath": "@/remotion/primitives/topographic-lines-bg",
      "installTarget": "src/remotion/primitives/topographic-lines-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Plate behind the contours. `transparent` layers them over footage."
        },
        {
          "name": "lineColor",
          "type": "string",
          "default": "\"rgba(232,184,109,0.5)\"",
          "description": "Contour colour."
        },
        {
          "name": "indexColor",
          "type": "string",
          "default": "\"rgba(232,184,109,0.95)\"",
          "description": "Colour of the heavier index contour."
        },
        {
          "name": "peaks",
          "type": "TopographicPeak[]",
          "default": "two peaks",
          "description": "Landforms: `{ x, y, size, roughness }` in percent. One peak reads as a target; two read as terrain."
        },
        {
          "name": "lineCount",
          "type": "number",
          "default": "12",
          "description": "Contours per landform."
        },
        {
          "name": "indexEvery",
          "type": "number",
          "default": "4",
          "description": "Every n-th contour is drawn heavier. 0 makes them uniform."
        },
        {
          "name": "lineWidth",
          "type": "number",
          "default": "1.4",
          "description": "Contour weight in px, independent of output size."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "How fast elevation rises. 0 freezes the map."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Overall brightness."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the terrain without changing any other prop."
        }
      ],
      "usage": "import { TopographicLinesBg } from \"@/remotion/primitives/topographic-lines-bg\";\n\n<AbsoluteFill>\n  <TopographicLinesBg speed={1} />\n  <YourScene />\n</AbsoluteFill>",
      "related": [
        "dynamic-grid",
        "map-canvas",
        "aurora-bg"
      ],
      "note": "Not marching squares: far too expensive per frame. Each landform is a stack of polar curves modulated by three harmonics, so the family is nested by construction. Contours travel outward and wrap, fading in at the peak and out at the rim.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caustics-bg",
      "type": "registry:ui",
      "description": "Underwater light caustics",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add caustics-bg",
      "docsUrl": "https://remotionui.com/docs/components/caustics-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/caustics-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/caustics-bg.json",
      "importPath": "@/remotion/primitives/caustics-bg",
      "installTarget": "src/remotion/primitives/caustics-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "deep water gradient",
          "description": "Water behind the light. `transparent` layers the caustics over footage."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#9fe8ff\"",
          "description": "Colour of the light itself."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "120",
          "description": "Cell size, in px."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Swim speed. 0 freezes the surface."
        },
        {
          "name": "contrast",
          "type": "number",
          "default": "3.4",
          "description": "How hard the cells threshold. Too low and the web dissolves into plaid."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "8",
          "description": "Softness of a cell edge, in px."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Overall brightness."
        },
        {
          "name": "falloff",
          "type": "number",
          "default": "0.55",
          "description": "Depth shading down the frame. 0 lights it evenly."
        }
      ],
      "usage": "import { CausticsBg } from \"@/remotion/primitives/caustics-bg\";\n\n<AbsoluteFill>\n  <CausticsBg scale={130} />\n  <YourScene />\n</AbsoluteFill>",
      "related": [
        "mesh-gradient-bg",
        "light-rays",
        "aurora-bg"
      ],
      "note": "Five wave trains at incommensurate angles, added with `plus-lighter`, dimmed in patches by a slow swell, then thresholded with `contrast()`. Three trains, at any wavelengths, make a lattice, and a lattice reads as wallpaper; five make the sum quasi-periodic. No shader and no per-frame noise.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "animated-noise-grain",
      "type": "registry:ui",
      "description": "Film grain overlay",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add animated-noise-grain",
      "docsUrl": "https://remotionui.com/docs/components/animated-noise-grain",
      "registryUrl": "https://remotionui.com/r/presets/default/animated-noise-grain.json",
      "detailUrl": "https://remotionui.com/ai/components/animated-noise-grain.json",
      "importPath": "@/remotion/primitives/animated-noise-grain",
      "installTarget": "src/remotion/primitives/animated-noise-grain",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "Content the grain sits over. Omit to use it as a bare overlay."
        },
        {
          "name": "opacity",
          "type": "number",
          "default": "0.18",
          "description": "Grain strength. Film sits around 0.12-0.25; above 0.4 reads as damage."
        },
        {
          "name": "size",
          "type": "number",
          "default": "220",
          "description": "Tile size on screen, in px. Larger grain is coarser and cheaper."
        },
        {
          "name": "density",
          "type": "number",
          "default": "0.85",
          "description": "Noise frequency inside the tile. Higher is finer."
        },
        {
          "name": "detail",
          "type": "number",
          "default": "3",
          "description": "Octaves of noise. 1 is smooth, 4 is gritty."
        },
        {
          "name": "holdInFrames",
          "type": "number",
          "default": "2",
          "description": "Frames each pattern is held. 2 gives the 15fps chatter of film."
        },
        {
          "name": "blendMode",
          "type": "CSS mix-blend-mode",
          "default": "\"overlay\"",
          "description": "How the grain composites. Use `screen` over a near-black plate: overlay pivots on mid grey and does nothing to blacks."
        },
        {
          "name": "colored",
          "type": "boolean",
          "default": "false",
          "description": "Keep the noise coloured instead of desaturating it to silver."
        },
        {
          "name": "vignette",
          "type": "number",
          "default": "0.35",
          "description": "Extra grain in the corners, where film grain actually lives."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the pattern without changing any other prop."
        }
      ],
      "usage": "import { AnimatedNoiseGrain } from \"@/remotion/primitives/animated-noise-grain\";\n\n<AnimatedNoiseGrain opacity={0.18}>\n  <YourScene />\n</AnimatedNoiseGrain>",
      "related": [
        "scanline-crt",
        "mesh-gradient-bg",
        "light-rays"
      ],
      "note": "The noise is one stitched `feTurbulence` tile baked into a data URI, so the browser rasterises it once for the whole render. Per-frame variation comes from a hashed sub-tile offset plus one of four mirrorings, never from regenerating noise. Rendering the preview costs about 3% more per frame than the same frame without it.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "light-rays",
      "type": "registry:ui",
      "description": "Volumetric god rays drifting across the stage",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "gpu"
      ],
      "installCommand": "npx remotion-ui@latest add light-rays",
      "docsUrl": "https://remotionui.com/docs/components/light-rays",
      "registryUrl": "https://remotionui.com/r/presets/default/light-rays.json",
      "detailUrl": "https://remotionui.com/ai/components/light-rays.json",
      "importPath": "@/remotion/primitives/light-rays",
      "installTarget": "src/remotion/primitives/light-rays",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#080810\"",
          "description": "Plate behind the rays. `transparent` layers them over footage."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Colour of the shafts."
        },
        {
          "name": "rayCount",
          "type": "number",
          "default": "11",
          "description": "How many shafts. Odd counts avoid a symmetric seam down the middle."
        },
        {
          "name": "spread",
          "type": "number",
          "default": "52",
          "description": "Total fan angle, in degrees."
        },
        {
          "name": "angle",
          "type": "number",
          "default": "22",
          "description": "Direction the fan points. 0 points straight down."
        },
        {
          "name": "originX",
          "type": "number",
          "default": "26",
          "description": "Source position in percent of the frame. Usually outside it."
        },
        {
          "name": "originY",
          "type": "number",
          "default": "-12",
          "description": "Source position in percent of the frame."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Overall brightness."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Sway speed. 0 freezes the fan into a poster frame."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "13",
          "description": "Softness of a shaft's edge, in px. A heavy blur swallows the sway."
        },
        {
          "name": "bloom",
          "type": "number",
          "default": "42",
          "description": "Bloom radius at the source, in percent. 0 removes it."
        }
      ],
      "usage": "import { LightRays } from \"@/remotion/primitives/light-rays\";\n\n<AbsoluteFill>\n  <LightRays originX={28} originY={-14} angle={20} spread={56} />\n  <YourScene />\n</AbsoluteFill>",
      "related": [
        "mesh-gradient-bg",
        "light-sweep-text",
        "aurora-bg"
      ],
      "note": "Tapered wedges on `screen`, with width, brightness and sway period hashed per index: an even fan reads as a printed sunburst. Background layer, so it has no entrance.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "parallax-layers",
      "type": "registry:ui",
      "description": "Depth-offset layers on one driver",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add parallax-layers",
      "docsUrl": "https://remotionui.com/docs/components/parallax-layers",
      "registryUrl": "https://remotionui.com/r/presets/default/parallax-layers.json",
      "detailUrl": "https://remotionui.com/ai/components/parallax-layers.json",
      "importPath": "@/remotion/primitives/parallax-layers",
      "installTarget": "src/remotion/primitives/parallax-layers",
      "category": "primitive",
      "props": [
        {
          "name": "layers",
          "type": "ParallaxLayer[]",
          "description": "Back to front. Each is `{ content, depth, blur, opacity, scale }`; depth 0 is the focal plane, 1 travels furthest, negative travels the other way."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "320",
          "description": "Travel of a depth-1 plane across the whole move, in px."
        },
        {
          "name": "angle",
          "type": "number",
          "default": "0",
          "description": "Direction of the camera move. 0 tracks right, 90 cranes down."
        },
        {
          "name": "zoom",
          "type": "number",
          "default": "0.12",
          "description": "Extra scale the nearest plane picks up. 0 is a flat track."
        },
        {
          "name": "progress",
          "type": "number",
          "description": "Drive the move yourself, 0-1. Overrides the frame-based sweep."
        },
        {
          "name": "startAtInFrames",
          "type": "number",
          "default": "0",
          "description": "Frame the sweep starts on."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "the composition",
          "description": "Length of the sweep."
        },
        {
          "name": "motion",
          "type": "\"ease\" | \"linear\"",
          "default": "\"ease\"",
          "description": "`ease` settles at both ends; `linear` is a constant-speed dolly."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#07080e\"",
          "description": "Plate behind every plane."
        }
      ],
      "usage": "import { ParallaxLayers } from \"@/remotion/primitives/parallax-layers\";\n\n<ParallaxLayers\n  travel={420}\n  layers={[\n    { content: <Sky />, depth: 0.2, blur: 2 },\n    { content: <Headline />, depth: 0.55 },\n    { content: <Foreground />, depth: 1, blur: 8 },\n  ]}\n/>",
      "related": [
        "zoom-pan-frame",
        "depth-of-field-blur",
        "bento-pan"
      ],
      "note": "Multi-layer, unlike `zoom-pan-frame`, which moves a camera over one still. Parallax is a relationship, so one driver feeds every plane and `depth` is the only number a caller sets. The sweep runs -0.5 to 0.5, so the middle of the window is the layout you composed.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "shake-emphasis",
      "type": "registry:ui",
      "description": "Short impact shake",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add shake-emphasis",
      "docsUrl": "https://remotionui.com/docs/components/shake-emphasis",
      "registryUrl": "https://remotionui.com/r/presets/default/shake-emphasis.json",
      "detailUrl": "https://remotionui.com/ai/components/shake-emphasis.json",
      "importPath": "@/remotion/primitives/shake-emphasis",
      "installTarget": "src/remotion/primitives/shake-emphasis",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What gets hit."
        },
        {
          "name": "startAtInFrames",
          "type": "number",
          "default": "0",
          "description": "Frame the impact lands on."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "18",
          "description": "How long the shake takes to die out. Impacts are short."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "16",
          "description": "Peak displacement, in px."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "1.6",
          "description": "Peak rotation in degrees. 3 already reads as violent."
        },
        {
          "name": "punch",
          "type": "number",
          "default": "0.05",
          "description": "Scale compression on impact. 0 shakes without a hit."
        },
        {
          "name": "frequency",
          "type": "number",
          "default": "22",
          "description": "Rattle rate, in shakes per second."
        },
        {
          "name": "axis",
          "type": "\"both\" | \"x\" | \"y\"",
          "default": "\"both\"",
          "description": "Which way it moves."
        },
        {
          "name": "decay",
          "type": "number",
          "default": "2.2",
          "description": "How fast the shake dies. 1 is even, 3 is a sharp hit."
        },
        {
          "name": "repeatEveryInFrames",
          "type": "number",
          "description": "Repeat the impact on this interval. Omit for a single hit."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the rattle without changing any other prop."
        }
      ],
      "usage": "import { ShakeEmphasis } from \"@/remotion/primitives/shake-emphasis\";\n\n<ShakeEmphasis startAtInFrames={24}>\n  <Headline />\n</ShakeEmphasis>",
      "related": [
        "squash-stretch",
        "glow-pulse",
        "rgb-glitch-text"
      ],
      "note": "Value noise, not a sine: every swing is a different size, which is the difference between an impact and a motor. The envelope decays to rest, so the element is still before and after: a shake that keeps going is a vibration.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "glow-pulse",
      "type": "registry:ui",
      "description": "Rhythmic glow for CTAs and live indicators",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add glow-pulse",
      "docsUrl": "https://remotionui.com/docs/components/glow-pulse",
      "registryUrl": "https://remotionui.com/r/presets/default/glow-pulse.json",
      "detailUrl": "https://remotionui.com/ai/components/glow-pulse.json",
      "importPath": "@/remotion/primitives/glow-pulse",
      "installTarget": "src/remotion/primitives/glow-pulse",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What glows."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Glow colour."
        },
        {
          "name": "radius",
          "type": "number",
          "default": "26",
          "description": "Glow radius at full brightness, in px."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Brightness at the top of the pulse."
        },
        {
          "name": "floor",
          "type": "number",
          "default": "0.28",
          "description": "Brightness at the bottom. Never 0 for a live indicator."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "36",
          "description": "Length of one pulse."
        },
        {
          "name": "mode",
          "type": "\"breathe\" | \"beat\"",
          "default": "\"breathe\"",
          "description": "`breathe` is a sine; `beat` is a fast attack and a long decay."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "0.04",
          "description": "Scale added at the top of the pulse. 0 glows without moving."
        },
        {
          "name": "halo",
          "type": "number",
          "default": "2.4",
          "description": "Halo behind the element, as a multiple of `radius`. 0 removes it."
        },
        {
          "name": "echo",
          "type": "number",
          "default": "0",
          "description": "Second, smaller tap per cycle: a heartbeat rather than a metronome."
        }
      ],
      "usage": "import { GlowPulse } from \"@/remotion/primitives/glow-pulse\";\n\n<GlowPulse mode=\"beat\" periodInFrames={36}>\n  <CtaPill />\n</GlowPulse>",
      "related": [
        "shake-emphasis",
        "neon-flicker-text",
        "end-card"
      ],
      "note": "The glow is a `drop-shadow` filter, so it follows the alpha of whatever it wraps (a pill, a ring, type, an SVG mark) rather than the bounding box. `floor` matters more than `intensity`: a live indicator that reaches zero reads as broken.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "motion-trail",
      "type": "registry:ui",
      "description": "Echo trails behind a moving element",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add motion-trail",
      "docsUrl": "https://remotionui.com/docs/components/motion-trail",
      "registryUrl": "https://remotionui.com/r/presets/default/motion-trail.json",
      "detailUrl": "https://remotionui.com/ai/components/motion-trail.json",
      "importPath": "@/remotion/primitives/motion-trail",
      "installTarget": "src/remotion/primitives/motion-trail",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "The moving element. It must animate from `useCurrentFrame()`."
        },
        {
          "name": "count",
          "type": "number",
          "default": "6",
          "description": "How many echoes trail behind."
        },
        {
          "name": "gapInFrames",
          "type": "number",
          "default": "3",
          "description": "Frames between echoes. Wider gaps stretch the trail for free."
        },
        {
          "name": "opacity",
          "type": "number",
          "default": "0.45",
          "description": "Opacity of the freshest echo."
        },
        {
          "name": "falloff",
          "type": "number",
          "default": "1.6",
          "description": "How fast echoes fade. 1 is linear, 2 keeps the tail short."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "0.82",
          "description": "Scale of the oldest echo. 1 keeps them all the same size."
        },
        {
          "name": "blur",
          "type": "number",
          "default": "4",
          "description": "Blur on the oldest echo, in px."
        },
        {
          "name": "color",
          "type": "string",
          "description": "Tint the echoes. Omit to echo the element's own colours."
        },
        {
          "name": "blendMode",
          "type": "CSS mix-blend-mode",
          "default": "\"screen\"",
          "description": "How echoes composite. `screen` is right on a dark stage."
        },
        {
          "name": "block",
          "type": "boolean",
          "default": "false",
          "description": "Fill the parent instead of shrink-wrapping the subject."
        }
      ],
      "usage": "import { MotionTrail } from \"@/remotion/primitives/motion-trail\";\n\n<MotionTrail count={6} gapInFrames={3}>\n  <TheMovingThing />\n</MotionTrail>",
      "related": [
        "cursor-path",
        "confetti-burst",
        "orbit-motion"
      ],
      "note": "An echo is not a copy of a position: it is the subject re-rendered at an earlier frame, via `<Sequence from={gap * i}>`. That makes the trail correct for any motion, including rotation and colour change, with no path to describe. It also costs `count + 1` renders of the subtree per frame, so prefer a wider gap over a higher count.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "squash-stretch",
      "type": "registry:ui",
      "description": "The animation principle as a primitive",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-wrapper"
      ],
      "installCommand": "npx remotion-ui@latest add squash-stretch",
      "docsUrl": "https://remotionui.com/docs/components/squash-stretch",
      "registryUrl": "https://remotionui.com/r/presets/default/squash-stretch.json",
      "detailUrl": "https://remotionui.com/ai/components/squash-stretch.json",
      "importPath": "@/remotion/primitives/squash-stretch",
      "installTarget": "src/remotion/primitives/squash-stretch",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What deforms."
        },
        {
          "name": "mode",
          "type": "\"bounce\" | \"pulse\" | \"impact\"",
          "default": "\"bounce\"",
          "description": "Travel and deform, breathe in place, or deform once."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "36",
          "description": "Length of one cycle."
        },
        {
          "name": "travel",
          "type": "number",
          "default": "90",
          "description": "Bounce height, in px. 0 deforms in place."
        },
        {
          "name": "squash",
          "type": "number",
          "default": "0.28",
          "description": "How hard it flattens on contact. Above 0.4 reads as cartoon."
        },
        {
          "name": "stretch",
          "type": "number",
          "default": "0.16",
          "description": "How far it elongates at speed."
        },
        {
          "name": "startAtInFrames",
          "type": "number",
          "default": "0",
          "description": "Frame the cycle starts on."
        },
        {
          "name": "contact",
          "type": "number",
          "default": "0.22",
          "description": "How much of the cycle the contact lasts, 0-1."
        },
        {
          "name": "origin",
          "type": "\"bottom\" | \"center\" | \"top\"",
          "default": "\"bottom\"",
          "description": "Pivot. `bottom` is the floor contact."
        }
      ],
      "usage": "import { SquashStretch } from \"@/remotion/primitives/squash-stretch\";\n\n<SquashStretch mode=\"bounce\" periodInFrames={36}>\n  <Ball />\n</SquashStretch>",
      "related": [
        "spring-in",
        "shake-emphasis",
        "counter"
      ],
      "note": "Volume is preserved: `scaleX` is the reciprocal square root of `scaleY`, because the eye tracks area and a one-axis squash reads as a scale bug. The pivot is the bottom by default; deforming around the centre lifts the element off its own baseline and the floor stops reading as a floor.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "orbit-motion",
      "type": "registry:ui",
      "description": "Element orbiting a center point",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add orbit-motion",
      "docsUrl": "https://remotionui.com/docs/components/orbit-motion",
      "registryUrl": "https://remotionui.com/r/presets/default/orbit-motion.json",
      "detailUrl": "https://remotionui.com/ai/components/orbit-motion.json",
      "importPath": "@/remotion/primitives/orbit-motion",
      "installTarget": "src/remotion/primitives/orbit-motion",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "Each child gets its own slot on the ring, evenly spaced."
        },
        {
          "name": "radiusX",
          "type": "number",
          "default": "210",
          "description": "Horizontal radius, in px."
        },
        {
          "name": "radiusY",
          "type": "number",
          "default": "78",
          "description": "Vertical radius. Smaller reads as a tilted ring."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "120",
          "description": "Frames for one revolution."
        },
        {
          "name": "phase",
          "type": "number",
          "default": "0",
          "description": "Where the first child starts, in degrees."
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "-12",
          "description": "Tilt of the whole ring, in degrees."
        },
        {
          "name": "direction",
          "type": "\"cw\" | \"ccw\"",
          "default": "\"cw\"",
          "description": "Which way it turns."
        },
        {
          "name": "centerX",
          "type": "number",
          "default": "50",
          "description": "Centre of the orbit, in percent of the frame."
        },
        {
          "name": "centerY",
          "type": "number",
          "default": "50",
          "description": "Centre of the orbit, in percent of the frame."
        },
        {
          "name": "depth",
          "type": "number",
          "default": "0.28",
          "description": "Scale difference between the near and far side. 0 is flat."
        },
        {
          "name": "depthFade",
          "type": "number",
          "default": "0.4",
          "description": "How much the far side dims."
        },
        {
          "name": "upright",
          "type": "boolean",
          "default": "true",
          "description": "Keep children upright instead of letting them ride the ring."
        },
        {
          "name": "showPath",
          "type": "boolean",
          "default": "false",
          "description": "Draw the ring itself."
        },
        {
          "name": "pathColor",
          "type": "string",
          "default": "\"rgba(255,255,255,0.14)\"",
          "description": "Colour of the drawn ring."
        },
        {
          "name": "center",
          "type": "ReactNode",
          "description": "What sits at the centre."
        }
      ],
      "usage": "import { OrbitMotion } from \"@/remotion/primitives/orbit-motion\";\n\n<OrbitMotion periodInFrames={120} center={<Logo />}>\n  <Chip label=\"One\" />\n  <Chip label=\"Two\" />\n</OrbitMotion>",
      "related": [
        "ecosystem-orbit",
        "motion-trail",
        "squash-stretch"
      ],
      "note": "The ellipse is the easy half; depth is what makes it an orbit. One sine drives scale, opacity and `zIndex` together, so a satellite passes behind whatever is at the centre by itself. Give satellites different content: identical ones make the ring repeat every revolution divided by their count.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "depth-of-field-blur",
      "type": "registry:ui",
      "description": "Rack focus between layers",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add depth-of-field-blur",
      "docsUrl": "https://remotionui.com/docs/components/depth-of-field-blur",
      "registryUrl": "https://remotionui.com/r/presets/default/depth-of-field-blur.json",
      "detailUrl": "https://remotionui.com/ai/components/depth-of-field-blur.json",
      "importPath": "@/remotion/primitives/depth-of-field-blur",
      "installTarget": "src/remotion/primitives/depth-of-field-blur",
      "category": "primitive",
      "props": [
        {
          "name": "layers",
          "type": "DepthOfFieldLayer[]",
          "description": "Back to front. Each is `{ content, depth }`, depth 0 nearest to 1 furthest."
        },
        {
          "name": "focusFrom",
          "type": "number",
          "default": "0",
          "description": "Depth the lens starts focused on."
        },
        {
          "name": "focusTo",
          "type": "number",
          "default": "1",
          "description": "Depth the lens racks to. Equal to `focusFrom` holds focus."
        },
        {
          "name": "startAtInFrames",
          "type": "number",
          "default": "6",
          "description": "Frame the rack starts on."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "78% of the window",
          "description": "Length of the rack."
        },
        {
          "name": "maxBlur",
          "type": "number",
          "default": "16",
          "description": "Blur at maximum defocus, in px."
        },
        {
          "name": "aperture",
          "type": "number",
          "default": "2.2",
          "description": "How fast focus falls off with distance. Higher is a wider aperture."
        },
        {
          "name": "dim",
          "type": "number",
          "default": "0.35",
          "description": "How much an out-of-focus plane darkens."
        },
        {
          "name": "breathe",
          "type": "number",
          "default": "0.03",
          "description": "Scale a defocused plane picks up (focus breathing)."
        },
        {
          "name": "progress",
          "type": "number",
          "description": "Drive the rack yourself, 0-1."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#07080e\"",
          "description": "Plate behind every plane."
        }
      ],
      "usage": "import { DepthOfFieldBlur } from \"@/remotion/primitives/depth-of-field-blur\";\n\n<DepthOfFieldBlur\n  focusFrom={1}\n  focusTo={0}\n  layers={[\n    { content: <Background />, depth: 1 },\n    { content: <Card />, depth: 0.4 },\n    { content: <Foreground />, depth: 0 },\n  ]}\n/>",
      "related": [
        "blur-focus-in",
        "parallax-layers",
        "zoom-pan-frame"
      ],
      "note": "Spatial, unlike `blur-focus-in`, which resolves one piece of type. Blur comes from each plane's distance to the focal plane, so racking pulls one layer in exactly as it pushes another out. Time the rack so it lands *on* planes: a rack that is between two planes at the moment anyone looks has nothing sharp in frame.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "scanline-crt",
      "type": "registry:ui",
      "description": "CRT scanlines and curvature overlay",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "atoms",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add scanline-crt",
      "docsUrl": "https://remotionui.com/docs/components/scanline-crt",
      "registryUrl": "https://remotionui.com/r/presets/default/scanline-crt.json",
      "detailUrl": "https://remotionui.com/ai/components/scanline-crt.json",
      "importPath": "@/remotion/primitives/scanline-crt",
      "installTarget": "src/remotion/primitives/scanline-crt",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What the tube is showing. Omit to use it as a bare overlay."
        },
        {
          "name": "lineCount",
          "type": "number",
          "default": "90",
          "description": "How many scanlines across the frame."
        },
        {
          "name": "lineOpacity",
          "type": "number",
          "default": "0.34",
          "description": "Darkness of a scanline."
        },
        {
          "name": "lineWidth",
          "type": "number",
          "default": "1.6",
          "description": "Scanline weight in px, independent of output size."
        },
        {
          "name": "curvature",
          "type": "number",
          "default": "0.55",
          "description": "How hard the tube face bows. 0 draws dead straight lines."
        },
        {
          "name": "cornerRadius",
          "type": "number",
          "default": "22",
          "description": "Corner radius of the tube face, in px."
        },
        {
          "name": "rollInFrames",
          "type": "number",
          "default": "96",
          "description": "Frames for the refresh bar to cross. 0 removes it."
        },
        {
          "name": "rollOpacity",
          "type": "number",
          "default": "0.16",
          "description": "Brightness of the refresh bar."
        },
        {
          "name": "flicker",
          "type": "number",
          "default": "0.05",
          "description": "Frame-to-frame brightness jitter."
        },
        {
          "name": "grille",
          "type": "number",
          "default": "0.22",
          "description": "Strength of the RGB aperture grille."
        },
        {
          "name": "vignette",
          "type": "number",
          "default": "0.55",
          "description": "Corner darkening."
        },
        {
          "name": "tint",
          "type": "string",
          "default": "\"transparent\"",
          "description": "Phosphor tint over the picture."
        },
        {
          "name": "tintBlend",
          "type": "CSS mix-blend-mode",
          "default": "\"overlay\"",
          "description": "How the tint composites."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Strength of every overlay at once."
        }
      ],
      "usage": "import { ScanlineCrt } from \"@/remotion/primitives/scanline-crt\";\n\n<ScanlineCrt curvature={0.6}>\n  <YourScene />\n</ScanlineCrt>",
      "related": [
        "animated-noise-grain",
        "rgb-glitch-text",
        "terminal-simulator"
      ],
      "note": "Curvature is drawn: each scanline is a quadratic whose midpoint is pushed away from the tube centre, so lines bow up at the top and down at the bottom. Content underneath is not geometrically warped. Every overlay here removes light, so over a near-black plate the component is invisible; give it a picture.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "bar-chart-race",
      "type": "registry:ui",
      "description": "Ranked bars reorder over time",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add bar-chart-race",
      "docsUrl": "https://remotionui.com/docs/components/bar-chart-race",
      "registryUrl": "https://remotionui.com/r/presets/default/bar-chart-race.json",
      "detailUrl": "https://remotionui.com/ai/components/bar-chart-race.json",
      "importPath": "@/remotion/primitives/bar-chart-race",
      "installTarget": "src/remotion/primitives/bar-chart-race",
      "category": "primitive",
      "props": [
        {
          "name": "series",
          "type": "RaceSeries[]",
          "default": "required",
          "description": "One entry per contender: `{ label, values, color? }`, one value per keyframe."
        },
        {
          "name": "steps",
          "type": "string[]",
          "default": "undefined",
          "description": "Keyframe captions, e.g. years. Shown as the running clock."
        },
        {
          "name": "framesPerStep",
          "type": "number",
          "default": "26",
          "description": "Frames spent travelling between two keyframes."
        },
        {
          "name": "visibleRows",
          "type": "number",
          "default": "6",
          "description": "How many rows stay on the board. Below that, series fade out."
        },
        {
          "name": "width",
          "type": "number",
          "default": "900",
          "description": "Overall width, label column included."
        },
        {
          "name": "rowHeight",
          "type": "number",
          "default": "66",
          "description": "Bar height. Type scales off it."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "14",
          "description": "Space between rows."
        },
        {
          "name": "labelWidth",
          "type": "number",
          "default": "200",
          "description": "Width reserved for the row labels."
        },
        {
          "name": "showStepLabel",
          "type": "boolean",
          "default": "true",
          "description": "Large step caption in the bottom-right corner."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "default": "compact",
          "description": "Formats the figure inside each bar."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the clock starts."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the bars collapse on. Omit to hold the final standings."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { BarChartRace } from \"@/remotion/primitives/bar-chart-race\";\n\n<BarChartRace\n  series={[\n    { label: \"Studio\", values: [42, 58, 66, 72, 78, 84] },\n    { label: \"Motion\", values: [18, 34, 57, 76, 92, 108] },\n  ]}\n  steps={[\"Q1\", \"Q2\", \"Q3\", \"Q4\", \"Q5\", \"Q6\"]}\n  framesPerStep={18}\n/>",
      "related": [
        "animated-bar-chart",
        "leaderboard-rows",
        "counter"
      ],
      "note": "Rank is fractional, not an integer sort position: each series measures how far above it the others sit, softened by a sigmoid. Integer ranks make bars teleport a full row the instant two values cross, the exact moment the format exists to show. Takes raw time series and interpolates them, not pre-computed rankings.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "donut-chart",
      "type": "registry:ui",
      "description": "Multi-segment donut with labels",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add donut-chart",
      "docsUrl": "https://remotionui.com/docs/components/donut-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/donut-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/donut-chart.json",
      "importPath": "@/remotion/primitives/donut-chart",
      "installTarget": "src/remotion/primitives/donut-chart",
      "category": "primitive",
      "props": [
        {
          "name": "segments",
          "type": "ChartDatum[]",
          "default": "required",
          "description": "`{ label, value, color? }`, drawn clockwise in the order given."
        },
        {
          "name": "size",
          "type": "number",
          "default": "360",
          "description": "Outer diameter in px. All type scales off it."
        },
        {
          "name": "thickness",
          "type": "number",
          "default": "46",
          "description": "Ring thickness. Below a tenth of `size` it reads as a hairline."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "gold / teal / pink / indigo",
          "description": "Fallback colours, cycled for segments with no `color`."
        },
        {
          "name": "showLegend",
          "type": "boolean",
          "default": "true",
          "description": "Legend rows beside the ring, arriving with their own slice."
        },
        {
          "name": "showTotal",
          "type": "boolean",
          "default": "true",
          "description": "Running total in the hole."
        },
        {
          "name": "totalLabel",
          "type": "string",
          "default": "\"Total\"",
          "description": "Caption under the total."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "default": "compact",
          "description": "Formats the centre total."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Length of one segment's sweep."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "9",
          "description": "Frames between one segment and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the chart is dismissed on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { DonutChart } from \"@/remotion/primitives/donut-chart\";\n\n<DonutChart\n  segments={[\n    { label: \"Direct\", value: 4820 },\n    { label: \"Search\", value: 3140 },\n    { label: \"Social\", value: 1960 },\n  ]}\n  totalLabel=\"Sessions\"\n  staggerInFrames={16}\n/>",
      "related": [
        "pie-slice-reveal",
        "stat-card",
        "progress-bar"
      ],
      "note": "The centre total counts the segments that have actually landed, so ring and number agree on every frame. Each segment is a dashed circle rotated to its own start angle, which keeps every arc on one radius. `stat-card` owns the single-value ring; this one is strictly multi-segment.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "pie-slice-reveal",
      "type": "registry:ui",
      "description": "Slices sweep in sequentially",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add pie-slice-reveal",
      "docsUrl": "https://remotionui.com/docs/components/pie-slice-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/pie-slice-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/pie-slice-reveal.json",
      "importPath": "@/remotion/primitives/pie-slice-reveal",
      "installTarget": "src/remotion/primitives/pie-slice-reveal",
      "category": "primitive",
      "props": [
        {
          "name": "slices",
          "type": "ChartDatum[]",
          "default": "required",
          "description": "`{ label, value, color? }`, swept clockwise from twelve o'clock."
        },
        {
          "name": "size",
          "type": "number",
          "default": "380",
          "description": "Diameter in px, offset for the explode included."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "gold / teal / pink / indigo / amber",
          "description": "Fallback colours, cycled."
        },
        {
          "name": "showLabels",
          "type": "boolean",
          "default": "true",
          "description": "Percentages inside each slice, from 70% of its sweep."
        },
        {
          "name": "explode",
          "type": "number",
          "default": "0.04",
          "description": "How far each slice sits off centre, as a share of the radius."
        },
        {
          "name": "gapInDegrees",
          "type": "number",
          "default": "1.4",
          "description": "Angular gap, taken off the end of each wedge."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Length of one slice's sweep."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "14",
          "description": "Frames between one slice and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the slices fan out on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { PieSliceReveal } from \"@/remotion/primitives/pie-slice-reveal\";\n\n<PieSliceReveal\n  slices={[\n    { label: \"Pro\", value: 44 },\n    { label: \"Team\", value: 26 },\n    { label: \"Free\", value: 18 },\n  ]}\n  staggerInFrames={18}\n/>",
      "related": [
        "donut-chart",
        "stat-card",
        "comparison-bars"
      ],
      "note": "The gap is cut out of the wedge rather than stroked between wedges: a stroked divider sits on top of whichever slice was painted last and nicks the outer edge of the circle. Solid wedges, so the whole is the point; use `donut-chart` when the centre should carry a number.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "scatter-plot-pop",
      "type": "registry:ui",
      "description": "Points pop in on stagger, optional trend line",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add scatter-plot-pop",
      "docsUrl": "https://remotionui.com/docs/components/scatter-plot-pop",
      "registryUrl": "https://remotionui.com/r/presets/default/scatter-plot-pop.json",
      "detailUrl": "https://remotionui.com/ai/components/scatter-plot-pop.json",
      "importPath": "@/remotion/primitives/scatter-plot-pop",
      "installTarget": "src/remotion/primitives/scatter-plot-pop",
      "category": "primitive",
      "props": [
        {
          "name": "points",
          "type": "ScatterPoint[]",
          "default": "required",
          "description": "`{ x, y, weight?, color? }` in data units."
        },
        {
          "name": "width",
          "type": "number",
          "default": "860",
          "description": "Drawing width. Type scales off it."
        },
        {
          "name": "height",
          "type": "number",
          "default": "480",
          "description": "Drawing height."
        },
        {
          "name": "minRadius",
          "type": "number",
          "default": "7",
          "description": "Dot radius at weight 0."
        },
        {
          "name": "maxRadius",
          "type": "number",
          "default": "20",
          "description": "Dot radius at the heaviest weight present."
        },
        {
          "name": "showTrend",
          "type": "boolean",
          "default": "true",
          "description": "Least-squares trend line, drawn after the last dot lands."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and value labels on both axes."
        },
        {
          "name": "xLabel",
          "type": "string",
          "default": "undefined",
          "description": "Caption under the x axis."
        },
        {
          "name": "yLabel",
          "type": "string",
          "default": "undefined",
          "description": "Rotated caption beside the y axis."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "16",
          "description": "Length of one dot's pop."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "2.5",
          "description": "Frames between dots, in ascending x order."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the cloud drains on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { ScatterPlotPop } from \"@/remotion/primitives/scatter-plot-pop\";\n\n<ScatterPlotPop\n  points={[{ x: 4, y: 24, weight: 0.8 }, { x: 11, y: 39 }]}\n  xLabel=\"Scenes per project\"\n  staggerInFrames={3}\n/>",
      "related": [
        "line-chart-draw",
        "bubble-chart-pack",
        "sparkline-row"
      ],
      "note": "The stagger follows ascending x, not array order, so the cloud fills the way the axis is read. The fit is least squares over the raw values and only then projected: fitting in screen space inverts the slope, since y grows downward there.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "bubble-chart-pack",
      "type": "registry:ui",
      "description": "Circle-packed values settling into place",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add bubble-chart-pack",
      "docsUrl": "https://remotionui.com/docs/components/bubble-chart-pack",
      "registryUrl": "https://remotionui.com/r/presets/default/bubble-chart-pack.json",
      "detailUrl": "https://remotionui.com/ai/components/bubble-chart-pack.json",
      "importPath": "@/remotion/primitives/bubble-chart-pack",
      "installTarget": "src/remotion/primitives/bubble-chart-pack",
      "category": "primitive",
      "props": [
        {
          "name": "bubbles",
          "type": "ChartDatum[]",
          "default": "required",
          "description": "`{ label, value, color? }`. Area is proportional to value."
        },
        {
          "name": "width",
          "type": "number",
          "default": "860",
          "description": "Box the cluster is scaled to fit."
        },
        {
          "name": "height",
          "type": "number",
          "default": "520",
          "description": "Box height."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "gold / teal / pink / indigo / amber",
          "description": "Fallback colours, cycled."
        },
        {
          "name": "showLabels",
          "type": "boolean",
          "default": "true",
          "description": "Labels inside bubbles large enough to hold them."
        },
        {
          "name": "showValues",
          "type": "boolean",
          "default": "true",
          "description": "Value line under the label, hidden on small bubbles."
        },
        {
          "name": "padding",
          "type": "number",
          "default": "6",
          "description": "Gap held between neighbours, in layout units."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Length of one bubble's settle."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "7",
          "description": "Frames between bubbles, largest first."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the cluster contracts on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { BubbleChartPack } from \"@/remotion/primitives/bubble-chart-pack\";\n\n<BubbleChartPack\n  bubbles={[\n    { label: \"Atoms\", value: 42 },\n    { label: \"Blocks\", value: 31 },\n    { label: \"Signals\", value: 26 },\n  ]}\n  staggerInFrames={12}\n/>",
      "related": [
        "scatter-plot-pop",
        "donut-chart",
        "treemap-blocks"
      ],
      "note": "Radius scales with the square root of the value, so area, what the eye compares, stays proportional. The pack is a deterministic spiral placement followed by a compaction pass toward the centre: the same data always produces the same arrangement, which is worth more here than density.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "gauge-dial",
      "type": "registry:ui",
      "description": "Needle sweeps to target",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts",
          "metrics"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add gauge-dial",
      "docsUrl": "https://remotionui.com/docs/components/gauge-dial",
      "registryUrl": "https://remotionui.com/r/presets/default/gauge-dial.json",
      "detailUrl": "https://remotionui.com/ai/components/gauge-dial.json",
      "importPath": "@/remotion/primitives/gauge-dial",
      "installTarget": "src/remotion/primitives/gauge-dial",
      "category": "primitive",
      "props": [
        {
          "name": "value",
          "type": "number",
          "default": "required",
          "description": "Target the needle sweeps to."
        },
        {
          "name": "min",
          "type": "number",
          "default": "0",
          "description": "Value at the start of the arc."
        },
        {
          "name": "max",
          "type": "number",
          "default": "100",
          "description": "Value at the end of the arc."
        },
        {
          "name": "size",
          "type": "number",
          "default": "360",
          "description": "Outer diameter in px. Type scales off it."
        },
        {
          "name": "thickness",
          "type": "number",
          "default": "26",
          "description": "Track and fill thickness."
        },
        {
          "name": "sweepInDegrees",
          "type": "number",
          "default": "250",
          "description": "Total travel, centred on twelve o'clock. 180 gives a half-moon meter."
        },
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Caption under the readout."
        },
        {
          "name": "unit",
          "type": "string",
          "default": "\"\"",
          "description": "Suffix on the readout, e.g. `\"%\"`."
        },
        {
          "name": "tickCount",
          "type": "number",
          "default": "9",
          "description": "Tick marks around the arc. 0 hides them."
        },
        {
          "name": "valueFormatter",
          "type": "(value: number) => string",
          "default": "rounded",
          "description": "Formats the readout."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "44",
          "description": "Length of the sweep."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the sweep starts."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the dial unwinds on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { GaugeDial } from \"@/remotion/primitives/gauge-dial\";\n\n<GaugeDial value={78} label=\"Render budget\" unit=\"%\" durationInFrames={70} />",
      "related": [
        "progress-bar",
        "stat-card",
        "counter"
      ],
      "note": "The needle rides the overshoot curve and the arc does not: a needle that settles back is instrument-like, while a coloured arc that retreats reads as the value changing its mind. The readout counts from the arc's progress, so number and fill never disagree.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "sparkline-row",
      "type": "registry:ui",
      "description": "Compact trend lines that read at small sizes",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts",
          "metrics"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens",
        "path-utils"
      ],
      "installCommand": "npx remotion-ui@latest add sparkline-row",
      "docsUrl": "https://remotionui.com/docs/components/sparkline-row",
      "registryUrl": "https://remotionui.com/r/presets/default/sparkline-row.json",
      "detailUrl": "https://remotionui.com/ai/components/sparkline-row.json",
      "importPath": "@/remotion/primitives/sparkline-row",
      "installTarget": "src/remotion/primitives/sparkline-row",
      "category": "primitive",
      "props": [
        {
          "name": "rows",
          "type": "SparklineSeries[]",
          "default": "required",
          "description": "`{ label, values, value?, delta?, color? }`, oldest value first."
        },
        {
          "name": "width",
          "type": "number",
          "default": "720",
          "description": "Overall width of the stack."
        },
        {
          "name": "rowHeight",
          "type": "number",
          "default": "96",
          "description": "Height of one row. Type scales off it."
        },
        {
          "name": "sparkWidth",
          "type": "number",
          "default": "260",
          "description": "Width of the spark itself."
        },
        {
          "name": "upColor",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Colour for a `+` delta."
        },
        {
          "name": "downColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Colour for a `-` delta."
        },
        {
          "name": "showArea",
          "type": "boolean",
          "default": "true",
          "description": "Gradient wash under each line."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "34",
          "description": "Length of one row's draw."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "12",
          "description": "Frames between one row and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the stack starts emptying on, top-down."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { SparklineRow } from \"@/remotion/primitives/sparkline-row\";\n\n<SparklineRow\n  rows={[\n    { label: \"Renders / day\", values: [180, 240, 320, 480, 610], delta: \"+24%\" },\n    { label: \"Median render\", values: [92, 86, 74, 66, 61], delta: \"-18%\" },\n  ]}\n  staggerInFrames={20}\n/>",
      "related": [
        "line-chart-draw",
        "stat-card",
        "scatter-plot-pop"
      ],
      "note": "Every row scales to its own domain: a sparkline is read for shape, and a shared axis would flatten a metric that moves between 4 and 6 next to one in the thousands. Only the spark is SVG; label, value and delta are CSS, so the row keeps tabular figures without fighting SVG text metrics.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "heatmap-grid",
      "type": "registry:ui",
      "description": "Cell grid filling by intensity, contribution-graph style",
      "tasks": [
        "data",
        "maps"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add heatmap-grid",
      "docsUrl": "https://remotionui.com/docs/components/heatmap-grid",
      "registryUrl": "https://remotionui.com/r/presets/default/heatmap-grid.json",
      "detailUrl": "https://remotionui.com/ai/components/heatmap-grid.json",
      "importPath": "@/remotion/primitives/heatmap-grid",
      "installTarget": "src/remotion/primitives/heatmap-grid",
      "category": "primitive",
      "props": [
        {
          "name": "cells",
          "type": "number[][]",
          "default": "required",
          "description": "Row-major intensities. Ragged rows are padded with empty cells."
        },
        {
          "name": "maxValue",
          "type": "number",
          "default": "busiest cell",
          "description": "Top of the ramp. Set it explicitly to compare two grids."
        },
        {
          "name": "cellSize",
          "type": "number",
          "default": "34",
          "description": "Cell edge length in px."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "8",
          "description": "Space between cells."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Colour at full intensity."
        },
        {
          "name": "emptyColor",
          "type": "string",
          "default": "rgba(250,250,250,0.07)",
          "description": "Colour of a zero cell."
        },
        {
          "name": "rowLabels",
          "type": "string[]",
          "default": "undefined",
          "description": "Labels down the left gutter, one per row."
        },
        {
          "name": "columnLabels",
          "type": "string[]",
          "default": "undefined",
          "description": "Labels along the top. Sparse arrays are fine."
        },
        {
          "name": "showLegend",
          "type": "boolean",
          "default": "true",
          "description": "\"Less → more\" ramp under the grid."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "14",
          "description": "Length of one cell's fill."
        },
        {
          "name": "columnStaggerInFrames",
          "type": "number",
          "default": "3",
          "description": "Frames added per column as the wave crosses."
        },
        {
          "name": "rowStaggerInFrames",
          "type": "number",
          "default": "1.5",
          "description": "Frames added per row. Keep it below the column stagger."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the grid drains on, along the same diagonal."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { HeatmapGrid } from \"@/remotion/primitives/heatmap-grid\";\n\n<HeatmapGrid\n  cells={weeks}\n  rowLabels={[\"Mon\", \"\", \"Wed\", \"\", \"Fri\", \"\", \"Sun\"]}\n  columnStaggerInFrames={3.4}\n/>",
      "related": [
        "commit-graph",
        "beat-pulse-grid",
        "treemap-blocks"
      ],
      "note": "Staggering by column plus row makes the fill sweep as a diagonal front; a flat index stagger snakes back to the left edge on every new row and reads as a glitch. Intensity drives colour and a small scale step together, since colour alone is hard to judge at cell size on a dark stage.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "comparison-bars",
      "type": "registry:ui",
      "description": "Two-series before/after with delta callout",
      "tasks": [
        "data",
        "scene-overlays"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add comparison-bars",
      "docsUrl": "https://remotionui.com/docs/components/comparison-bars",
      "registryUrl": "https://remotionui.com/r/presets/default/comparison-bars.json",
      "detailUrl": "https://remotionui.com/ai/components/comparison-bars.json",
      "importPath": "@/remotion/primitives/comparison-bars",
      "installTarget": "src/remotion/primitives/comparison-bars",
      "category": "primitive",
      "props": [
        {
          "name": "rows",
          "type": "ComparisonRowDatum[]",
          "default": "required",
          "description": "`{ label, before, after, delta? }`. The delta is computed when omitted."
        },
        {
          "name": "width",
          "type": "number",
          "default": "820",
          "description": "Overall width, label column included."
        },
        {
          "name": "rowHeight",
          "type": "number",
          "default": "74",
          "description": "Height of one pair, both bars and their gap included."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "26",
          "description": "Space between rows."
        },
        {
          "name": "labelWidth",
          "type": "number",
          "default": "190",
          "description": "Width reserved for the row labels."
        },
        {
          "name": "beforeColor",
          "type": "string",
          "default": "rgba(250,250,250,0.22)",
          "description": "Baseline bar. Muted on purpose: it is the thing being beaten."
        },
        {
          "name": "afterColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "New-value bar, and the colour of a rising delta."
        },
        {
          "name": "downColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Delta colour when the change is a fall."
        },
        {
          "name": "seriesLabels",
          "type": "[string, string]",
          "default": "undefined",
          "description": "Legend above the rows, e.g. `[\"Before\", \"After\"]`."
        },
        {
          "name": "showDelta",
          "type": "boolean",
          "default": "true",
          "description": "Percentage-change chip at the end of the second bar."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of one bar's growth."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "12",
          "description": "Frames between one row and the next."
        },
        {
          "name": "pairOffsetInFrames",
          "type": "number",
          "default": "6",
          "description": "Frames the second bar trails the first by."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the rows start leaving on, in arrival order."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { ComparisonBars } from \"@/remotion/primitives/comparison-bars\";\n\n<ComparisonBars\n  rows={[\n    { label: \"Time to first cut\", before: 240, after: 96 },\n    { label: \"Renders / week\", before: 120, after: 310 },\n  ]}\n  seriesLabels={[\"Before\", \"After\"]}\n  staggerInFrames={18}\n/>",
      "related": [
        "animated-bar-chart",
        "stat-card",
        "funnel-chart"
      ],
      "note": "Every bar is measured against the largest value in the whole set, so pairs stay comparable to each other and not only internally. The second bar trails the first by a few frames, which is what makes a pair read as one change rather than two adjacent bars.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "funnel-chart",
      "type": "registry:ui",
      "description": "Stage bars narrowing with drop-off percentages",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add funnel-chart",
      "docsUrl": "https://remotionui.com/docs/components/funnel-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/funnel-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/funnel-chart.json",
      "importPath": "@/remotion/primitives/funnel-chart",
      "installTarget": "src/remotion/primitives/funnel-chart",
      "category": "primitive",
      "props": [
        {
          "name": "stages",
          "type": "FunnelStage[]",
          "default": "required",
          "description": "`{ label, value, color? }`, top to bottom."
        },
        {
          "name": "width",
          "type": "number",
          "default": "820",
          "description": "Overall width: label gutter, funnel and drop-off gutter."
        },
        {
          "name": "height",
          "type": "number",
          "default": "420",
          "description": "Overall height. Bands split it evenly."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "10",
          "description": "Space between bands."
        },
        {
          "name": "tailOpacity",
          "type": "number",
          "default": "0.5",
          "description": "Opacity of the last band; earlier bands ramp toward 1."
        },
        {
          "name": "labelWidth",
          "type": "number",
          "default": "30% of width",
          "description": "Left gutter holding stage names and values."
        },
        {
          "name": "showDropoff",
          "type": "boolean",
          "default": "true",
          "description": "Drop-off chip between consecutive stages."
        },
        {
          "name": "showConversion",
          "type": "boolean",
          "default": "false",
          "description": "Share of the first stage, printed beside each value."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "22",
          "description": "Length of one band's wipe."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "12",
          "description": "Frames between one band and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the funnel drains on, narrow end first."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { FunnelChart } from \"@/remotion/primitives/funnel-chart\";\n\n<FunnelChart\n  stages={[\n    { label: \"Visited docs\", value: 42800 },\n    { label: \"Ran the CLI\", value: 18600 },\n    { label: \"Shipped it\", value: 1750 },\n  ]}\n  staggerInFrames={15}\n/>",
      "related": [
        "comparison-bars",
        "animated-bar-chart",
        "stat-card"
      ],
      "note": "Each band tapers from its own width to the next stage's, so the shape carries the loss before a label is read; the last band is a rectangle because there is no next stage to taper to. Names and values sit in a left gutter: a real funnel ends narrow, and type inside the last band would have to shrink until it was unreadable.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "radar-chart",
      "type": "registry:ui",
      "description": "Multi-axis spider chart drawing its polygon",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add radar-chart",
      "docsUrl": "https://remotionui.com/docs/components/radar-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/radar-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/radar-chart.json",
      "importPath": "@/remotion/primitives/radar-chart",
      "installTarget": "src/remotion/primitives/radar-chart",
      "category": "primitive",
      "props": [
        {
          "name": "axes",
          "type": "string[]",
          "default": "required",
          "description": "Axis names, clockwise from the top. Three minimum."
        },
        {
          "name": "series",
          "type": "RadarSeries[]",
          "default": "required",
          "description": "`{ label, values, color? }`, one value per axis in axis order."
        },
        {
          "name": "size",
          "type": "number",
          "default": "420",
          "description": "Diameter of the web. Labels sit outside it."
        },
        {
          "name": "maxValue",
          "type": "number",
          "default": "largest value",
          "description": "Value at the outer ring. Pin it when comparing two charts."
        },
        {
          "name": "ringCount",
          "type": "number",
          "default": "4",
          "description": "Concentric rings behind the polygons."
        },
        {
          "name": "showLabels",
          "type": "boolean",
          "default": "true",
          "description": "Axis names around the web."
        },
        {
          "name": "showVertices",
          "type": "boolean",
          "default": "true",
          "description": "Dot on each vertex."
        },
        {
          "name": "fillOpacity",
          "type": "number",
          "default": "0.22",
          "description": "Fill under each polygon."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "18",
          "description": "Length of one vertex's reach."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "5",
          "description": "Frames between axes, sweeping clockwise."
        },
        {
          "name": "seriesOffsetInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames one series trails the previous one by."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the polygons collapse to the centre on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { RadarChart } from \"@/remotion/primitives/radar-chart\";\n\n<RadarChart\n  axes={[\"Speed\", \"Polish\", \"Reuse\", \"Docs\", \"Types\", \"Motion\"]}\n  series={[\n    { label: \"Before\", values: [42, 38, 24, 30, 46, 34] },\n    { label: \"After\", values: [88, 92, 84, 78, 90, 86] },\n  ]}\n  maxValue={100}\n/>",
      "related": [
        "line-chart-draw",
        "comparison-bars",
        "scatter-plot-pop"
      ],
      "note": "Vertices reach out one axis at a time rather than the polygon scaling as a whole: a growing polygon says nothing about which axis is strong. The web arrives whole and ahead of the data: it is the instrument, and animating it would suggest the scale was changing. The box grows with the longest axis label so nothing clips.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "treemap-blocks",
      "type": "registry:ui",
      "description": "Nested rectangles sized by value",
      "tasks": [
        "data",
        "maps"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add treemap-blocks",
      "docsUrl": "https://remotionui.com/docs/components/treemap-blocks",
      "registryUrl": "https://remotionui.com/r/presets/default/treemap-blocks.json",
      "detailUrl": "https://remotionui.com/ai/components/treemap-blocks.json",
      "importPath": "@/remotion/primitives/treemap-blocks",
      "installTarget": "src/remotion/primitives/treemap-blocks",
      "category": "primitive",
      "props": [
        {
          "name": "blocks",
          "type": "ChartDatum[]",
          "default": "required",
          "description": "`{ label, value, color? }`. Area is proportional to value."
        },
        {
          "name": "width",
          "type": "number",
          "default": "820",
          "description": "Box the tiles fill."
        },
        {
          "name": "height",
          "type": "number",
          "default": "460",
          "description": "Box height."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "8",
          "description": "Space between tiles."
        },
        {
          "name": "cornerRadius",
          "type": "number",
          "default": "12",
          "description": "Tile corner radius, clamped on small tiles."
        },
        {
          "name": "showShare",
          "type": "boolean",
          "default": "true",
          "description": "Percentage of the total, printed beside the value."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one tile's arrival."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "6",
          "description": "Frames between tiles, largest first."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the map collapses on, smallest first."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { TreemapBlocks } from \"@/remotion/primitives/treemap-blocks\";\n\n<TreemapBlocks\n  blocks={[\n    { label: \"Atoms\", value: 46 },\n    { label: \"Blocks\", value: 31 },\n    { label: \"Signals\", value: 26 },\n  ]}\n  staggerInFrames={12}\n/>",
      "related": [
        "bubble-chart-pack",
        "heatmap-grid",
        "donut-chart"
      ],
      "note": "Squarified layout (Bruls, Huizing & van Wijk): rows grow along the shorter free side and close when the next value would worsen the aspect ratio. Slice-and-dice turns small values into unlabelable splinters. A tile prints its label only when it can hold it: overflowing type reads as a rendering fault, and the area still carries the small values.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "waterfall-chart",
      "type": "registry:ui",
      "description": "Cumulative bridge with positive/negative steps",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add waterfall-chart",
      "docsUrl": "https://remotionui.com/docs/components/waterfall-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/waterfall-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/waterfall-chart.json",
      "importPath": "@/remotion/primitives/waterfall-chart",
      "installTarget": "src/remotion/primitives/waterfall-chart",
      "category": "primitive",
      "props": [
        {
          "name": "steps",
          "type": "WaterfallStep[]",
          "default": "required",
          "description": "`{ label, value, isTotal?, color? }`. `value` is a signed change unless `isTotal`."
        },
        {
          "name": "width",
          "type": "number",
          "default": "860",
          "description": "Drawing width. Type scales off it."
        },
        {
          "name": "height",
          "type": "number",
          "default": "440",
          "description": "Drawing height."
        },
        {
          "name": "upColor",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Bars that add to the running total."
        },
        {
          "name": "downColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Bars that subtract."
        },
        {
          "name": "totalColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Subtotal columns drawn from the axis."
        },
        {
          "name": "showConnectors",
          "type": "boolean",
          "default": "true",
          "description": "Dashed rules from one bar's landing level to the next bar's base."
        },
        {
          "name": "showValues",
          "type": "boolean",
          "default": "true",
          "description": "Signed change printed above or below each bar."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and value labels down the left gutter."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "20",
          "description": "Length of one bar's growth."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames between one step and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the bridge starts clearing on, left to right."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { WaterfallChart } from \"@/remotion/primitives/waterfall-chart\";\n\n<WaterfallChart\n  steps={[\n    { label: \"Q1 open\", value: 320, isTotal: true },\n    { label: \"New\", value: 180 },\n    { label: \"Churn\", value: -74 },\n    { label: \"Q2 close\", value: 484, isTotal: true },\n  ]}\n  staggerInFrames={15}\n/>",
      "related": [
        "animated-bar-chart",
        "comparison-bars",
        "funnel-chart"
      ],
      "note": "Bars grow from the running total they start at, not from the axis: in a waterfall the position carries as much as the length. `isTotal` draws from the axis and resets the running total, which is how an opening or closing column stays honest. Connectors wait for their bar to stop before extending.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "stacked-area-chart",
      "type": "registry:ui",
      "description": "Multiple series stacking as they draw on",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add stacked-area-chart",
      "docsUrl": "https://remotionui.com/docs/components/stacked-area-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/stacked-area-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/stacked-area-chart.json",
      "importPath": "@/remotion/primitives/stacked-area-chart",
      "installTarget": "src/remotion/primitives/stacked-area-chart",
      "category": "primitive",
      "props": [
        {
          "name": "series",
          "type": "StackedSeries[]",
          "default": "required",
          "description": "`{ label, values, color? }`, first entry is the baseline band."
        },
        {
          "name": "labels",
          "type": "string[]",
          "default": "undefined",
          "description": "Category labels along the x axis, one per value."
        },
        {
          "name": "width",
          "type": "number",
          "default": "880",
          "description": "Drawing width. Type scales off it."
        },
        {
          "name": "height",
          "type": "number",
          "default": "460",
          "description": "Drawing height."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and value labels down the left gutter."
        },
        {
          "name": "showLegend",
          "type": "boolean",
          "default": "true",
          "description": "Series names above the plot, arriving with their band."
        },
        {
          "name": "showBoundaries",
          "type": "boolean",
          "default": "true",
          "description": "Hairline along the top of each band."
        },
        {
          "name": "fillOpacity",
          "type": "number",
          "default": "0.85",
          "description": "Band fill opacity."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "60",
          "description": "Length of the wipe across the whole plot."
        },
        {
          "name": "bandOffsetInFrames",
          "type": "number",
          "default": "8",
          "description": "Frames one band trails the band below it by."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the stack retreats on, top band first."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { StackedAreaChart } from \"@/remotion/primitives/stacked-area-chart\";\n\n<StackedAreaChart\n  series={[\n    { label: \"Reels\", values: [140, 210, 300, 430, 520] },\n    { label: \"Ads\", values: [90, 130, 210, 300, 340] },\n  ]}\n  labels={[\"Jan\", \"Mar\", \"May\", \"Jul\", \"Aug\"]}\n  durationInFrames={62}\n/>",
      "related": [
        "line-chart-draw",
        "sparkline-row",
        "animated-bar-chart"
      ],
      "note": "The reveal is a clip travelling across the plot, not a fade or a vertical grow: a stacked area is read as a history, so uncovering it in time order is the only reveal that agrees with the axis. Band edges share one spline and the lower edge is walked backwards to close the shape, so no sliver appears at the seam.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "candlestick-chart",
      "type": "registry:ui",
      "description": "OHLC financial series",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "chart-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add candlestick-chart",
      "docsUrl": "https://remotionui.com/docs/components/candlestick-chart",
      "registryUrl": "https://remotionui.com/r/presets/default/candlestick-chart.json",
      "detailUrl": "https://remotionui.com/ai/components/candlestick-chart.json",
      "importPath": "@/remotion/primitives/candlestick-chart",
      "installTarget": "src/remotion/primitives/candlestick-chart",
      "category": "primitive",
      "props": [
        {
          "name": "candles",
          "type": "Candle[]",
          "default": "required",
          "description": "`{ open, high, low, close, label? }`, oldest first."
        },
        {
          "name": "width",
          "type": "number",
          "default": "900",
          "description": "Drawing width. Type scales off it."
        },
        {
          "name": "height",
          "type": "number",
          "default": "460",
          "description": "Drawing height."
        },
        {
          "name": "upColor",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Candles that closed at or above their open."
        },
        {
          "name": "downColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Candles that closed below their open."
        },
        {
          "name": "movingAverage",
          "type": "number",
          "default": "7",
          "description": "Window for the simple moving average. 0 hides the line."
        },
        {
          "name": "showLastPrice",
          "type": "boolean",
          "default": "true",
          "description": "Final close pinned against the right edge."
        },
        {
          "name": "showAxis",
          "type": "boolean",
          "default": "true",
          "description": "Gridlines and price labels down the left gutter."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "12",
          "description": "Length of one candle's growth."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "3",
          "description": "Frames between one candle and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the tape clears on, oldest first."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { CandlestickChart } from \"@/remotion/primitives/candlestick-chart\";\n\n<CandlestickChart\n  candles={[{ open: 101, high: 106, low: 99, close: 104, label: \"W1\" }]}\n  movingAverage={6}\n  staggerInFrames={3.4}\n/>",
      "related": [
        "line-chart-draw",
        "sparkline-row",
        "stacked-area-chart"
      ],
      "note": "Candles grow out of their own open in both directions, so a half-drawn candle still tells the truth; the wick runs a little ahead of the body, as a real tape prints. The average is plotted only where a full window exists. The axis is not anchored at zero: price is read for range, and a zero baseline flattens the movement.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "gantt-timeline",
      "type": "registry:ui",
      "description": "Date-scaled schedule bars",
      "tasks": [
        "data"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "charts"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add gantt-timeline",
      "docsUrl": "https://remotionui.com/docs/components/gantt-timeline",
      "registryUrl": "https://remotionui.com/r/presets/default/gantt-timeline.json",
      "detailUrl": "https://remotionui.com/ai/components/gantt-timeline.json",
      "importPath": "@/remotion/primitives/gantt-timeline",
      "installTarget": "src/remotion/primitives/gantt-timeline",
      "category": "primitive",
      "props": [
        {
          "name": "tasks",
          "type": "GanttTask[]",
          "default": "required",
          "description": "`{ label, start, end, progress?, color?, milestone? }` in column units."
        },
        {
          "name": "columns",
          "type": "string[]",
          "default": "required",
          "description": "Column headings. Their count sets the span of the timeline."
        },
        {
          "name": "width",
          "type": "number",
          "default": "900",
          "description": "Overall width, label column included."
        },
        {
          "name": "rowHeight",
          "type": "number",
          "default": "48",
          "description": "Height of one task row. Type scales off it."
        },
        {
          "name": "gap",
          "type": "number",
          "default": "12",
          "description": "Space between rows."
        },
        {
          "name": "labelWidth",
          "type": "number",
          "default": "240",
          "description": "Width reserved for the task names."
        },
        {
          "name": "markerAt",
          "type": "number",
          "default": "undefined",
          "description": "Column position for a dashed vertical rule, e.g. today."
        },
        {
          "name": "markerLabel",
          "type": "string",
          "default": "undefined",
          "description": "Chip label on that rule."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "24",
          "description": "Length of one bar's wipe."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "8",
          "description": "Frames between one row and the next."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "default": "undefined",
          "description": "Frame the rows start leaving on, top-down."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { GanttTimeline } from \"@/remotion/primitives/gantt-timeline\";\n\n<GanttTimeline\n  tasks={[\n    { label: \"Registry build\", start: 1, end: 4, progress: 0.8 },\n    { label: \"Launch\", start: 7.6, end: 7.6, milestone: true },\n  ]}\n  columns={[\"W1\", \"W2\", \"W3\", \"W4\", \"W5\", \"W6\", \"W7\", \"W8\"]}\n  markerAt={5.5}\n  markerLabel=\"Today\"\n/>",
      "related": [
        "roadmap-lanes",
        "kanban-move",
        "changelog-entry"
      ],
      "note": "Positions are column units rather than pixels, so a task moves by editing one number and everything stays in register. Bars wipe out from their own start edge, never from the left margin, so the animation says when a task begins as well as how long it runs. The marker label sits on a filled chip because the rule can land through a column heading.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "word-pop-captions",
      "type": "registry:ui",
      "description": "Narrowed: one word at a time, alone on frame",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/captions"
      ],
      "registryDependencies": [
        "caption-utils",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add word-pop-captions",
      "docsUrl": "https://remotionui.com/docs/components/word-pop-captions",
      "registryUrl": "https://remotionui.com/r/presets/default/word-pop-captions.json",
      "detailUrl": "https://remotionui.com/ai/components/word-pop-captions.json",
      "importPath": "@/remotion/primitives/word-pop-captions",
      "installTarget": "src/remotion/primitives/word-pop-captions",
      "category": "primitive",
      "props": [
        {
          "name": "page",
          "type": "TikTokPage",
          "default": "required",
          "description": "Token page from `groupCaptionsIntoPages`. One token is shown at a time."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#fafafa\"",
          "description": "Word ink."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Ink for every nth word."
        },
        {
          "name": "accentEvery",
          "type": "number",
          "default": "3",
          "description": "Accent cadence. 0 keeps one colour throughout."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "scaled 120",
          "description": "Defaults to a width-scaled 120px."
        },
        {
          "name": "uppercase",
          "type": "boolean",
          "default": "true",
          "description": "Uppercase the word: the default look for this style."
        },
        {
          "name": "popScale",
          "type": "number",
          "default": "1.16",
          "description": "Peak scale on arrival before it settles to 1."
        },
        {
          "name": "tiltInDegrees",
          "type": "number",
          "default": "2.5",
          "description": "Arrival tilt. Alternates direction word to word."
        },
        {
          "name": "popInFrames",
          "type": "number",
          "default": "6",
          "description": "Frames the pop takes to settle."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "0",
          "description": "Chunky outline behind the word, as used on social captions."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { WordPopCaptions } from \"@/remotion/primitives/word-pop-captions\";\nimport { groupCaptionsIntoPages } from \"@/remotion/lib/caption-utils\";\n\nconst [page] = groupCaptionsIntoPages(captions, 4000);\n\n<WordPopCaptions page={page} strokeWidth={4} />",
      "related": [
        "karaoke-captions",
        "caption-highlight",
        "srt-caption-track"
      ],
      "note": "No line context at all, which is what separates it from `caption-highlight` and `karaoke-captions`. Between tokens it renders nothing rather than holding the last word: a word left standing through a pause attributes the silence to whoever spoke it. The tilt alternates because one direction at speed reads as a stutter.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "caption-emoji-beat",
      "type": "registry:ui",
      "description": "Emoji punctuation landing on beats",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions",
          "social"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add caption-emoji-beat",
      "docsUrl": "https://remotionui.com/docs/components/caption-emoji-beat",
      "registryUrl": "https://remotionui.com/r/presets/default/caption-emoji-beat.json",
      "detailUrl": "https://remotionui.com/ai/components/caption-emoji-beat.json",
      "importPath": "@/remotion/primitives/caption-emoji-beat",
      "installTarget": "src/remotion/primitives/caption-emoji-beat",
      "category": "primitive",
      "props": [
        {
          "name": "beats",
          "type": "EmojiBeat[]",
          "default": "required",
          "description": "`{ emoji, atInFrames, x, y, scale?, rotate? }`. x/y are percentages of the frame."
        },
        {
          "name": "text",
          "type": "string",
          "default": "undefined",
          "description": "Caption line the emoji punctuate. Omit for emoji alone."
        },
        {
          "name": "size",
          "type": "number",
          "default": "84",
          "description": "Base emoji size in px, overridable per beat."
        },
        {
          "name": "landInFrames",
          "type": "number",
          "default": "7",
          "description": "Frames an emoji takes to land."
        },
        {
          "name": "holdInFrames",
          "type": "number",
          "default": "26",
          "description": "Frames it holds at full size before releasing."
        },
        {
          "name": "overshoot",
          "type": "number",
          "default": "1.35",
          "description": "Scale overshoot on the way in. 1 lands flat."
        },
        {
          "name": "wobbleInDegrees",
          "type": "number",
          "default": "9",
          "description": "Swing after landing. Decays to nothing."
        },
        {
          "name": "textAtInFrames",
          "type": "number",
          "default": "0",
          "description": "Frame the caption line arrives on."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { CaptionEmojiBeat } from \"@/remotion/primitives/caption-emoji-beat\";\n\n<CaptionEmojiBeat\n  text=\"Punctuate the beat, not the sentence\"\n  beats={[\n    { emoji: \"🔥\", atInFrames: 10, x: 22, y: 26, rotate: -8 },\n    { emoji: \"🚀\", atInFrames: 80, x: 50, y: 16, scale: 96 },\n  ]}\n/>",
      "related": [
        "confetti-burst",
        "karaoke-captions",
        "beat-pulse-grid"
      ],
      "note": "Beats are scheduled on frames rather than detected from audio: the beats are known when the edit is cut, and a render-time detector drifts against the music it is meant to hit. The wobble is keyed to each stamp's own landing, so it decays to nothing and a held frame is still.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "speaker-label-captions",
      "type": "registry:ui",
      "description": "Narrowed: multi-speaker caption track with name tags and color coding",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "caption-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add speaker-label-captions",
      "docsUrl": "https://remotionui.com/docs/components/speaker-label-captions",
      "registryUrl": "https://remotionui.com/r/presets/default/speaker-label-captions.json",
      "detailUrl": "https://remotionui.com/ai/components/speaker-label-captions.json",
      "importPath": "@/remotion/primitives/speaker-label-captions",
      "installTarget": "src/remotion/primitives/speaker-label-captions",
      "category": "primitive",
      "props": [
        {
          "name": "cues",
          "type": "SubtitleCue[]",
          "default": "required",
          "description": "`{ text, startMs, endMs, speaker? }`, the shape `parseSubtitles` returns."
        },
        {
          "name": "speakers",
          "type": "SpeakerStyle[]",
          "default": "[]",
          "description": "`{ name, color?, align? }` per voice. Undeclared voices are assigned."
        },
        {
          "name": "defaultSpeaker",
          "type": "string",
          "default": "\"Speaker\"",
          "description": "Name for cues that carry none."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "42",
          "description": "Caption size. Tag and padding scale off it."
        },
        {
          "name": "cardColor",
          "type": "string",
          "default": "rgba(12,12,18,0.82)",
          "description": "Plate behind a line."
        },
        {
          "name": "maxWidth",
          "type": "number",
          "default": "0.7",
          "description": "Card width as a share of the frame."
        },
        {
          "name": "showPrevious",
          "type": "boolean",
          "default": "true",
          "description": "Keep the previous speaker's card on screen, dimmed."
        },
        {
          "name": "enterInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames a card takes to arrive."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { SpeakerLabelCaptions } from \"@/remotion/primitives/speaker-label-captions\";\nimport { parseSubtitles } from \"@/remotion/lib/caption-utils\";\n\n<SpeakerLabelCaptions\n  cues={parseSubtitles(vttSource)}\n  speakers={[\n    { name: \"Nadia\", color: \"#e8b86d\", align: \"left\" },\n    { name: \"Sam\", color: \"#2dd4bf\", align: \"right\" },\n  ]}\n/>",
      "related": [
        "srt-caption-track",
        "transcript-scroll",
        "talking-head-layout"
      ],
      "note": "Speaker identity is carried by tag, colour and side at once, because each fails alone: a tag is slow to read at caption speed, colour is invisible to many viewers, and alignment cannot separate three voices. Between cues the last card holds; blinking out in every pause is worse than waiting.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "transcript-scroll",
      "type": "registry:ui",
      "description": "Full readable transcript scrolling with the active line marked",
      "tasks": [
        "captions"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "caption-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add transcript-scroll",
      "docsUrl": "https://remotionui.com/docs/components/transcript-scroll",
      "registryUrl": "https://remotionui.com/r/presets/default/transcript-scroll.json",
      "detailUrl": "https://remotionui.com/ai/components/transcript-scroll.json",
      "importPath": "@/remotion/primitives/transcript-scroll",
      "installTarget": "src/remotion/primitives/transcript-scroll",
      "category": "primitive",
      "props": [
        {
          "name": "cues",
          "type": "SubtitleCue[]",
          "default": "required",
          "description": "`{ text, startMs, endMs, speaker? }`, in order."
        },
        {
          "name": "width",
          "type": "number",
          "default": "720",
          "description": "Block width. Wrapping is estimated at this measure."
        },
        {
          "name": "height",
          "type": "number",
          "default": "420",
          "description": "Visible height of the scrolling window."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "34",
          "description": "Body size. Tags and spacing scale off it."
        },
        {
          "name": "activeColor",
          "type": "string",
          "default": "\"#fafafa\"",
          "description": "Ink of the line being spoken."
        },
        {
          "name": "idleColor",
          "type": "string",
          "default": "rgba(250,250,250,0.3)",
          "description": "Ink of lines not yet reached."
        },
        {
          "name": "readColor",
          "type": "string",
          "default": "idleColor",
          "description": "Ink of lines already read, when it should differ."
        },
        {
          "name": "showSpeakers",
          "type": "boolean",
          "default": "true",
          "description": "Name printed above a line when the speaker changes."
        },
        {
          "name": "showMarker",
          "type": "boolean",
          "default": "true",
          "description": "Accent rule down the left edge of the active line."
        },
        {
          "name": "fadeEdges",
          "type": "number",
          "default": "90",
          "description": "Mask height at the top and bottom, in px. 0 disables it."
        },
        {
          "name": "settleInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the scroll takes to settle on a new line."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { TranscriptScroll } from \"@/remotion/primitives/transcript-scroll\";\nimport { parseSubtitles } from \"@/remotion/lib/caption-utils\";\n\n<TranscriptScroll cues={parseSubtitles(vttSource)} width={740} height={400} />",
      "related": [
        "srt-caption-track",
        "speaker-label-captions",
        "karaoke-captions"
      ],
      "note": "A document, not an overlay: surrounding lines stay on screen so a quote keeps its place in the conversation. Scroll position interpolates between the outgoing and incoming offsets rather than snapping to the active index, and every line's height is measured because a speaker tag would otherwise drift a fixed pitch out of register.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "subtitle-translate",
      "type": "registry:ui",
      "description": "Dual-language stacked subtitles",
      "tasks": [
        "captions",
        "product-intro"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "captions"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "caption-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add subtitle-translate",
      "docsUrl": "https://remotionui.com/docs/components/subtitle-translate",
      "registryUrl": "https://remotionui.com/r/presets/default/subtitle-translate.json",
      "detailUrl": "https://remotionui.com/ai/components/subtitle-translate.json",
      "importPath": "@/remotion/primitives/subtitle-translate",
      "installTarget": "src/remotion/primitives/subtitle-translate",
      "category": "primitive",
      "props": [
        {
          "name": "cues",
          "type": "TranslatedCue[]",
          "default": "required",
          "description": "A `SubtitleCue` plus `translation`."
        },
        {
          "name": "primary",
          "type": "\"source\" | \"translation\"",
          "default": "\"source\"",
          "description": "Which language leads. Swaps without touching the data."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "46",
          "description": "Size of the primary line."
        },
        {
          "name": "secondaryScale",
          "type": "number",
          "default": "0.72",
          "description": "Secondary size, as a share of `fontSize`."
        },
        {
          "name": "languageLabels",
          "type": "[string, string]",
          "default": "undefined",
          "description": "Fixed-width tags beside each line, e.g. `[\"EN\", \"ES\"]`."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "rgba(10,10,14,0.72)",
          "description": "Plate behind both lines. `transparent` drops it."
        },
        {
          "name": "maxWidth",
          "type": "number",
          "default": "0.78",
          "description": "Block width as a share of the frame."
        },
        {
          "name": "enterInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames a cue takes to arrive."
        },
        {
          "name": "secondaryOffsetInFrames",
          "type": "number",
          "default": "4",
          "description": "Frames the second line trails the first by."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { SubtitleTranslate } from \"@/remotion/primitives/subtitle-translate\";\n\n<SubtitleTranslate\n  cues={[\n    {\n      text: \"The transcript is the edit.\",\n      translation: \"La transcripción es el montaje.\",\n      startMs: 0,\n      endMs: 1450,\n    },\n  ]}\n  languageLabels={[\"EN\", \"ES\"]}\n/>",
      "related": [
        "srt-caption-track",
        "speaker-label-captions",
        "caption-highlight"
      ],
      "note": "The two lines are deliberately unequal in weight and ink: styled the same, the block reads as one four-line caption and the viewer has to work out which half is theirs. The secondary trails by a few frames so the eye is given an order. Nothing renders between cues; the block is tall enough that holding it would cover the shot.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "waveform-bars-radial",
      "type": "registry:ui",
      "description": "Circular bars around a center element",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add waveform-bars-radial",
      "docsUrl": "https://remotionui.com/docs/components/waveform-bars-radial",
      "registryUrl": "https://remotionui.com/r/presets/default/waveform-bars-radial.json",
      "detailUrl": "https://remotionui.com/ai/components/waveform-bars-radial.json",
      "importPath": "@/remotion/primitives/waveform-bars-radial",
      "installTarget": "src/remotion/primitives/waveform-bars-radial",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "default": "required",
          "description": "Audio source. `.wav` only; `useWindowedAudioData` accepts nothing else."
        },
        {
          "name": "children",
          "type": "ReactNode",
          "default": "undefined",
          "description": "Content in the middle of the ring: artwork, a logo, a title."
        },
        {
          "name": "radius",
          "type": "number",
          "default": "150",
          "description": "Radius of the circle the bars stand on."
        },
        {
          "name": "barCount",
          "type": "number",
          "default": "72",
          "description": "Bars around the ring."
        },
        {
          "name": "barWidth",
          "type": "number",
          "default": "5",
          "description": "Bar thickness in px."
        },
        {
          "name": "minLength",
          "type": "number",
          "default": "10",
          "description": "Bar length at silence."
        },
        {
          "name": "maxLength",
          "type": "number",
          "default": "90",
          "description": "Bar length at full level."
        },
        {
          "name": "peakColor",
          "type": "string",
          "default": "undefined",
          "description": "Second colour for bars above 75% level."
        },
        {
          "name": "mirror",
          "type": "boolean",
          "default": "true",
          "description": "Reflect the spectrum across the vertical axis."
        },
        {
          "name": "spinPerSecond",
          "type": "number",
          "default": "6",
          "description": "Degrees the ring turns per second. 0 holds it still."
        },
        {
          "name": "bidirectional",
          "type": "boolean",
          "default": "false",
          "description": "Bars grow inward as well as outward."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { WaveformBarsRadial } from \"@/remotion/primitives/waveform-bars-radial\";\n\n<WaveformBarsRadial src={audioSrc} radius={112} barCount={80}>\n  <CoverArt />\n</WaveformBarsRadial>",
      "related": [
        "audiogram-bars",
        "audio-pulse",
        "waveform-line"
      ],
      "note": "Mirroring is on by default because a ring running low-to-high all the way round puts every bit of energy on one side, so it wobbles rather than pulses; it also halves the bands needed. The slow spin matters: through a quiet passage a still ring is exactly what the preview audit reports as dead.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "vu-meter",
      "type": "registry:ui",
      "description": "Segmented level meter with peak hold",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add vu-meter",
      "docsUrl": "https://remotionui.com/docs/components/vu-meter",
      "registryUrl": "https://remotionui.com/r/presets/default/vu-meter.json",
      "detailUrl": "https://remotionui.com/ai/components/vu-meter.json",
      "importPath": "@/remotion/primitives/vu-meter",
      "installTarget": "src/remotion/primitives/vu-meter",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "default": "required",
          "description": "Audio source. `.wav` only."
        },
        {
          "name": "orientation",
          "type": "\"vertical\" | \"horizontal\"",
          "default": "\"vertical\"",
          "description": "Which way the segments stack."
        },
        {
          "name": "segments",
          "type": "number",
          "default": "18",
          "description": "Segments in one channel."
        },
        {
          "name": "channels",
          "type": "1 | 2",
          "default": "2",
          "description": "Second channel is weighted toward the upper spectrum."
        },
        {
          "name": "thickness",
          "type": "number",
          "default": "26",
          "description": "Segment size across the short axis."
        },
        {
          "name": "length",
          "type": "number",
          "default": "260",
          "description": "Meter length along its own axis."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#2dd4bf\"",
          "description": "Segments below the warm zone."
        },
        {
          "name": "warnColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Segments in the top third."
        },
        {
          "name": "peakColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Segments in the top eighth."
        },
        {
          "name": "showPeakHold",
          "type": "boolean",
          "default": "true",
          "description": "Peak marker that falls back slowly."
        },
        {
          "name": "peakFallPerFrame",
          "type": "number",
          "default": "0.018",
          "description": "How fast the peak marker drops."
        },
        {
          "name": "labels",
          "type": "[string, string]",
          "default": "undefined",
          "description": "Channel captions, e.g. `[\"L\", \"R\"]`."
        },
        {
          "name": "sensitivity",
          "type": "number",
          "default": "1",
          "description": "Lifts or lowers the reading before it hits the segments."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { VuMeter } from \"@/remotion/primitives/vu-meter\";\n\n<VuMeter src={audioSrc} orientation=\"vertical\" labels={[\"L\", \"R\"]} />",
      "related": [
        "audiogram-bars",
        "audio-pulse",
        "waveform-bars-radial"
      ],
      "note": "Level rather than spectrum: the reading that still works at 40px wide. The peak marker is reconstructed from the library's decaying peaks on every frame instead of being held in state: a render is stateless and may start on any frame, so a ref-held marker would differ between a preview scrub and a full render.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "voice-note-bubble",
      "type": "registry:ui",
      "description": "Chat-style audio message with waveform and playhead",
      "tasks": [
        "captions",
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "audio",
          "social"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add voice-note-bubble",
      "docsUrl": "https://remotionui.com/docs/components/voice-note-bubble",
      "registryUrl": "https://remotionui.com/r/presets/default/voice-note-bubble.json",
      "detailUrl": "https://remotionui.com/ai/components/voice-note-bubble.json",
      "importPath": "@/remotion/primitives/voice-note-bubble",
      "installTarget": "src/remotion/primitives/voice-note-bubble",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "required",
          "description": "Length of the note. The playhead crosses the bar over exactly this."
        },
        {
          "name": "waveform",
          "type": "number[]",
          "default": "generated",
          "description": "Bar heights 0–1. Omitted, a deterministic envelope is built from `seed`."
        },
        {
          "name": "barCount",
          "type": "number",
          "default": "42",
          "description": "Bars drawn when the waveform is generated."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the generated envelope and nothing else."
        },
        {
          "name": "barHeight",
          "type": "number",
          "default": "44",
          "description": "Tallest bar. Type and padding scale off it."
        },
        {
          "name": "avatar",
          "type": "string",
          "default": "undefined",
          "description": "Initial or emoji in the round badge."
        },
        {
          "name": "sender",
          "type": "string",
          "default": "undefined",
          "description": "Name above the waveform."
        },
        {
          "name": "showTime",
          "type": "boolean",
          "default": "true",
          "description": "Elapsed / total readout under the bar."
        },
        {
          "name": "align",
          "type": "\"left\" | \"right\"",
          "default": "\"left\"",
          "description": "Side of the frame the bubble sits on."
        },
        {
          "name": "showPlayhead",
          "type": "boolean",
          "default": "true",
          "description": "Dot riding the played/unplayed boundary."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the playhead starts moving."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { VoiceNoteBubble } from \"@/remotion/primitives/voice-note-bubble\";\n\n<VoiceNoteBubble durationInFrames={120} sender=\"Sam\" avatar=\"S\" />",
      "related": [
        "audio-scrubber",
        "audiogram-bars",
        "chat-bubble"
      ],
      "note": "The waveform is static and only the colour moves through it, as every messaging app draws it; animating bar heights would be a live spectrum, which contradicts the fact that a voice note's shape is known before playback. Position comes from frames, not analysis, so the bubble can front a note that is only described.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "beat-pulse-grid",
      "type": "registry:ui",
      "description": "Grid cells pulsing on detected beats",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "advanced",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/media-utils"
      ],
      "registryDependencies": [
        "audio-viz-utils"
      ],
      "installCommand": "npx remotion-ui@latest add beat-pulse-grid",
      "docsUrl": "https://remotionui.com/docs/components/beat-pulse-grid",
      "registryUrl": "https://remotionui.com/r/presets/default/beat-pulse-grid.json",
      "detailUrl": "https://remotionui.com/ai/components/beat-pulse-grid.json",
      "importPath": "@/remotion/primitives/beat-pulse-grid",
      "installTarget": "src/remotion/primitives/beat-pulse-grid",
      "category": "primitive",
      "props": [
        {
          "name": "src",
          "type": "string",
          "default": "required",
          "description": "Audio source. `.wav` only."
        },
        {
          "name": "columns",
          "type": "number",
          "default": "12",
          "description": "Cells across."
        },
        {
          "name": "rows",
          "type": "number",
          "default": "6",
          "description": "Cells down."
        },
        {
          "name": "cellSize",
          "type": "number",
          "default": "34",
          "description": "Cell edge length in px."
        },
        {
          "name": "mapping",
          "type": "\"column\" | \"radial\" | \"row\"",
          "default": "\"radial\"",
          "description": "How the spectrum is laid over the geometry."
        },
        {
          "name": "idleColor",
          "type": "string",
          "default": "rgba(250,250,250,0.07)",
          "description": "Cell colour at rest."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Cell colour at level."
        },
        {
          "name": "peakColor",
          "type": "string",
          "default": "\"#f472b6\"",
          "description": "Colour of the loudest cells."
        },
        {
          "name": "pulseScale",
          "type": "number",
          "default": "0.28",
          "description": "Extra scale a cell takes at full level."
        },
        {
          "name": "floor",
          "type": "number",
          "default": "0.06",
          "description": "Level below which a cell stays dark. Cuts the noise floor."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { BeatPulseGrid } from \"@/remotion/primitives/beat-pulse-grid\";\n\n<BeatPulseGrid src={audioSrc} columns={14} rows={7} mapping=\"radial\" />",
      "related": [
        "caption-emoji-beat",
        "audiogram-bars",
        "heatmap-grid"
      ],
      "note": "Each cell is bound to a band rather than the overall level: a grid where every cell agrees is one flashing rectangle. Cells carry their band's decaying peak under the live level, the same trick as a peak-hold meter, because a one-frame transient is invisible at 30fps.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "audio-scrubber",
      "type": "registry:ui",
      "description": "Waveform with traveling playhead and time labels",
      "tasks": [
        "audio"
      ],
      "atlas": {
        "lane": "signals",
        "drive": "data",
        "tier": "core",
        "tags": [
          "audio"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add audio-scrubber",
      "docsUrl": "https://remotionui.com/docs/components/audio-scrubber",
      "registryUrl": "https://remotionui.com/r/presets/default/audio-scrubber.json",
      "detailUrl": "https://remotionui.com/ai/components/audio-scrubber.json",
      "importPath": "@/remotion/primitives/audio-scrubber",
      "installTarget": "src/remotion/primitives/audio-scrubber",
      "category": "primitive",
      "props": [
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "required",
          "description": "Clip length. The playhead crosses the track over exactly this."
        },
        {
          "name": "waveform",
          "type": "number[]",
          "default": "generated",
          "description": "Bar heights 0–1. Omitted, a deterministic envelope is built from `seed`."
        },
        {
          "name": "barCount",
          "type": "number",
          "default": "96",
          "description": "Bars drawn when the waveform is generated."
        },
        {
          "name": "width",
          "type": "number",
          "default": "720",
          "description": "Overall width, time labels included."
        },
        {
          "name": "height",
          "type": "number",
          "default": "96",
          "description": "Track height. Type scales off it."
        },
        {
          "name": "playedColor",
          "type": "string",
          "default": "\"#e8b86d\"",
          "description": "Bars already played."
        },
        {
          "name": "unplayedColor",
          "type": "string",
          "default": "rgba(250,250,250,0.2)",
          "description": "Bars not yet reached."
        },
        {
          "name": "marks",
          "type": "{ atInFrames, label? }[]",
          "default": "undefined",
          "description": "Chapter rules at frame positions."
        },
        {
          "name": "mirrored",
          "type": "boolean",
          "default": "true",
          "description": "Centre the bars the way an editor draws them."
        },
        {
          "name": "showTime",
          "type": "boolean",
          "default": "true",
          "description": "Elapsed and total readouts either side of the track."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames before the playhead starts moving."
        },
        {
          "name": "frame",
          "type": "number",
          "default": "undefined",
          "description": "Frame override: pass the parent frame inside a `<Sequence>`."
        }
      ],
      "usage": "import { AudioScrubber } from \"@/remotion/primitives/audio-scrubber\";\n\n<AudioScrubber\n  durationInFrames={120}\n  marks={[{ atInFrames: 66, label: \"Quote\" }]}\n/>",
      "related": [
        "voice-note-bubble",
        "audiogram-bars",
        "waveform-line"
      ],
      "note": "Position comes from frames rather than audio analysis, so the playhead lands on the frame the edit says it should. The waveform is static and the colour boundary moves through it; animating the heights would make it a live spectrum, which is `audiogram-bars`. Marks sit under the playhead so it is never hidden behind one.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "poll-overlay",
      "type": "registry:block",
      "description": "Question with bars filling to results",
      "tasks": [
        "captions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "creator",
          "social"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add poll-overlay",
      "docsUrl": "https://remotionui.com/docs/components/poll-overlay",
      "registryUrl": "https://remotionui.com/r/presets/default/poll-overlay.json",
      "detailUrl": "https://remotionui.com/ai/components/poll-overlay.json",
      "importPath": "@/remotion/scenes/poll-overlay",
      "installTarget": "src/remotion/scenes/poll-overlay",
      "category": "scene",
      "props": [
        {
          "name": "question",
          "type": "string",
          "required": true,
          "description": "The question the card asks."
        },
        {
          "name": "options",
          "type": "PollOption[]",
          "required": true,
          "description": "Each option's label and raw vote tally. Shares are computed from the tallies."
        },
        {
          "name": "badge",
          "type": "string",
          "description": "Small tag above the question (POLL, AUDIENCE, EP 12)."
        },
        {
          "name": "align",
          "type": "\"left\" | \"right\" | \"center\"",
          "default": "\"left\"",
          "description": "Edge the card sits against."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the result holds before the card retreats. Omit to leave it up."
        },
        {
          "name": "totalLabel",
          "type": "string",
          "description": "Total-vote line under the options. Omit to hide it."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Colour the leading option takes."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { PollOverlay } from \"@/remotion/scenes/poll-overlay\";\n\n<PollOverlay\n  badge=\"Poll\"\n  question=\"Which should we build next?\"\n  options={[\n    { label: \"Timeline editor\", votes: 412 },\n    { label: \"Batch renders\", votes: 268 },\n    { label: \"Team presets\", votes: 143 },\n  ]}\n  totalLabel=\"823 votes · closes in 2m\"\n  holdSeconds={4}\n/>",
      "related": [
        "quiz-question",
        "reaction-burst",
        "comparison-bars"
      ],
      "note": "Transparent overlay scene designed to sit over footage. Unlike quiz-question there is no correct answer: the winner is whichever option the votes gave it.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "reaction-burst",
      "type": "registry:block",
      "description": "Narrowed: hearts/likes rising continuously",
      "tasks": [
        "captions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "creator",
          "social"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/google-fonts"
      ],
      "registryDependencies": [
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add reaction-burst",
      "docsUrl": "https://remotionui.com/docs/components/reaction-burst",
      "registryUrl": "https://remotionui.com/r/presets/default/reaction-burst.json",
      "detailUrl": "https://remotionui.com/ai/components/reaction-burst.json",
      "importPath": "@/remotion/scenes/reaction-burst",
      "installTarget": "src/remotion/scenes/reaction-burst",
      "category": "scene",
      "props": [
        {
          "name": "reactions",
          "type": "React.ReactNode[]",
          "default": "[\"❤️\", \"👍\", \"🔥\", \"😂\", \"✨\"]",
          "description": "Glyphs cycled through as reactions spawn. Strings render in Noto Color Emoji; pass elements to use your own marks."
        },
        {
          "name": "ratePerSecond",
          "type": "number",
          "default": "6",
          "description": "Reactions spawned per second."
        },
        {
          "name": "align",
          "type": "\"left\" | \"right\"",
          "default": "\"right\"",
          "description": "Edge the stream rises along."
        },
        {
          "name": "lifeSeconds",
          "type": "number",
          "default": "2.6",
          "description": "Seconds a single reaction takes to travel its arc."
        },
        {
          "name": "drift",
          "type": "number",
          "default": "46",
          "description": "Horizontal sway in units, peak to peak."
        },
        {
          "name": "size",
          "type": "number",
          "default": "56",
          "description": "Glyph size in units at full scale."
        },
        {
          "name": "rise",
          "type": "number",
          "default": "0.72",
          "description": "Fraction of the frame height a reaction climbs."
        },
        {
          "name": "stopAfterSeconds",
          "type": "number",
          "description": "Seconds after which no new reactions spawn. Ones in flight finish their arc."
        },
        {
          "name": "seed",
          "type": "string | number",
          "default": "\"reaction-burst\"",
          "description": "Seeds the per-reaction jitter. Two streams in one composition need different seeds."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ReactionBurst } from \"@/remotion/scenes/reaction-burst\";\n\n<ReactionBurst align=\"right\" ratePerSecond={7} />",
      "related": [
        "confetti-burst",
        "poll-overlay",
        "chat-bubble"
      ],
      "note": "Deliberately narrower than confetti-burst, which is a single impulse fired on one beat; here the reactions keep coming for as long as the scene runs. Jitter runs through Remotion's seeded random(), a pure function of seed and spawn index, so frames render identically in any order.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "countdown-timer",
      "type": "registry:block",
      "description": "Numeric or ring countdown to zero",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "creator"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add countdown-timer",
      "docsUrl": "https://remotionui.com/docs/components/countdown-timer",
      "registryUrl": "https://remotionui.com/r/presets/default/countdown-timer.json",
      "detailUrl": "https://remotionui.com/ai/components/countdown-timer.json",
      "importPath": "@/remotion/scenes/countdown-timer",
      "installTarget": "src/remotion/scenes/countdown-timer",
      "category": "scene",
      "props": [
        {
          "name": "from",
          "type": "number",
          "default": "5",
          "description": "Seconds on the clock when the scene opens."
        },
        {
          "name": "variant",
          "type": "\"ring\" | \"numeric\"",
          "default": "\"ring\"",
          "description": "Ring sweep with the number inside, or the number alone."
        },
        {
          "name": "label",
          "type": "string",
          "description": "Caption above the clock (STARTING IN, DOORS OPEN)."
        },
        {
          "name": "zeroLabel",
          "type": "string",
          "description": "Shown once the clock reaches zero. Omit to hold on 0."
        },
        {
          "name": "startDelaySeconds",
          "type": "number",
          "default": "0.35",
          "description": "Seconds before the clock starts running."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Ring colour above the urgent threshold."
        },
        {
          "name": "urgentColor",
          "type": "string",
          "default": "\"#F97362\"",
          "description": "Accent applied over the last urgentUnder seconds."
        },
        {
          "name": "urgentUnder",
          "type": "number",
          "default": "3",
          "description": "Seconds remaining at which the urgent accent takes over."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CountdownTimer } from \"@/remotion/scenes/countdown-timer\";\n\n<CountdownTimer from={5} label=\"Starting in\" zeroLabel=\"Live\" />",
      "related": [
        "metric-ticker",
        "sports-scorebug",
        "end-card"
      ],
      "note": "The ring drains continuously while the digit swaps on each whole second, so the clock reads as running rather than as a number that happens to change. It stops at zero instead of ticking into negative time.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "sports-scorebug",
      "type": "registry:block",
      "description": "Broadcast score furniture with clock",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add sports-scorebug",
      "docsUrl": "https://remotionui.com/docs/components/sports-scorebug",
      "registryUrl": "https://remotionui.com/r/presets/default/sports-scorebug.json",
      "detailUrl": "https://remotionui.com/ai/components/sports-scorebug.json",
      "importPath": "@/remotion/scenes/sports-scorebug",
      "installTarget": "src/remotion/scenes/sports-scorebug",
      "category": "scene",
      "props": [
        {
          "name": "home",
          "type": "ScorebugTeam",
          "required": true,
          "description": "Home side: abbreviation, score, colour, possession."
        },
        {
          "name": "away",
          "type": "ScorebugTeam",
          "required": true,
          "description": "Away side: abbreviation, score, colour, possession."
        },
        {
          "name": "period",
          "type": "string",
          "default": "\"Q3\"",
          "description": "Period furniture (Q3, 2ND HALF, SET 2)."
        },
        {
          "name": "clockSeconds",
          "type": "number",
          "default": "154",
          "description": "Game clock at the top of the scene, in seconds. Counts down."
        },
        {
          "name": "changes",
          "type": "ScoreChange[]",
          "default": "[]",
          "description": "Scores landing mid-scene. Each flashes its side and bumps the total."
        },
        {
          "name": "align",
          "type": "\"left\" | \"center\" | \"right\"",
          "default": "\"center\"",
          "description": "Edge the bug sits against."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Period label and possession dot colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the bug holds before it retreats. Omit to leave it up."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { SportsScorebug } from \"@/remotion/scenes/sports-scorebug\";\n\n<SportsScorebug\n  away={{ abbr: \"NOR\", score: 66, color: \"#7DD3E8\" }}\n  home={{ abbr: \"VAL\", score: 71, color: \"#E8B86D\", possession: true }}\n  period=\"Q4\"\n  clockSeconds={154}\n  changes={[{ side: \"away\", atSeconds: 1.1, points: 3 }]}\n/>",
      "related": [
        "countdown-timer",
        "lower-third",
        "news-ticker-bar"
      ],
      "note": "Transparent overlay scene designed to sit over footage. Points landing mid-scene bump the total and flash that side rather than silently swapping the number.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "news-ticker-bar",
      "type": "registry:block",
      "description": "Broadcast lower ticker with headlines",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add news-ticker-bar",
      "docsUrl": "https://remotionui.com/docs/components/news-ticker-bar",
      "registryUrl": "https://remotionui.com/r/presets/default/news-ticker-bar.json",
      "detailUrl": "https://remotionui.com/ai/components/news-ticker-bar.json",
      "importPath": "@/remotion/scenes/news-ticker-bar",
      "installTarget": "src/remotion/scenes/news-ticker-bar",
      "category": "scene",
      "props": [
        {
          "name": "headlines",
          "type": "string[]",
          "required": true,
          "description": "Headlines cycled through the crawl, separated by a bullet."
        },
        {
          "name": "flag",
          "type": "string",
          "default": "\"Breaking\"",
          "description": "Standing flag on the left (BREAKING, MARKETS, LIVE)."
        },
        {
          "name": "strapline",
          "type": "string",
          "description": "Second line under the crawl. Omit for a single-line bar."
        },
        {
          "name": "timestamp",
          "type": "string",
          "description": "Clock or dateline pinned to the right edge. Omit to hide it."
        },
        {
          "name": "pixelsPerSecond",
          "type": "number",
          "default": "118",
          "description": "Crawl speed in units per second."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#F97362\"",
          "description": "Flag fill and top rule colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the bar holds before it retreats. Omit to leave it up."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { NewsTickerBar } from \"@/remotion/scenes/news-ticker-bar\";\n\n<NewsTickerBar\n  flag=\"Breaking\"\n  headlines={[\"Registry crosses 165 components\", \"CLI adds batch install\"]}\n  strapline=\"Live from the newsroom\"\n  timestamp=\"21:04\"\n/>",
      "related": [
        "infinite-marquee",
        "lower-third",
        "sports-scorebug"
      ],
      "note": "Transparent overlay scene designed to sit over footage. infinite-marquee is the generic looping-text primitive; this is the dressed news bar with the chrome a broadcast frame needs.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "form-fill-sequence",
      "type": "registry:block",
      "description": "Fields typing and validating in order",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add form-fill-sequence",
      "docsUrl": "https://remotionui.com/docs/components/form-fill-sequence",
      "registryUrl": "https://remotionui.com/r/presets/default/form-fill-sequence.json",
      "detailUrl": "https://remotionui.com/ai/components/form-fill-sequence.json",
      "importPath": "@/remotion/scenes/form-fill-sequence",
      "installTarget": "src/remotion/scenes/form-fill-sequence",
      "category": "scene",
      "props": [
        {
          "name": "fields",
          "type": "FormField[]",
          "default": "3 sample fields",
          "description": "Label, typed value and placeholder for each field, filled in order."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"Create your workspace\"",
          "description": "Heading on the card. Omit to show the fields alone."
        },
        {
          "name": "subtitle",
          "type": "string",
          "default": "\"Takes about a minute.\"",
          "description": "Supporting line under the heading."
        },
        {
          "name": "submitLabel",
          "type": "string",
          "default": "\"Create workspace\"",
          "description": "Button text while the form is still filling."
        },
        {
          "name": "successLabel",
          "type": "string",
          "default": "\"Workspace created\"",
          "description": "Button text once every field has validated."
        },
        {
          "name": "charsPerSecond",
          "type": "number",
          "default": "34",
          "description": "Typing rate. Each field's duration is its value length divided by this."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the filled form holds before the card retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Focus ring and armed submit button."
        },
        {
          "name": "validColor",
          "type": "string",
          "default": "\"#7FD1A0\"",
          "description": "Tick and settled border. Kept off accentColor so focus and validation stay two states."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { FormFillSequence } from \"@/remotion/scenes/form-fill-sequence\";\n\n<FormFillSequence\n  title=\"Create your workspace\"\n  fields={[\n    { label: \"Full name\", value: \"Ada Lovelace\", placeholder: \"Your name\" },\n    { label: \"Work email\", value: \"ada@northstar.dev\" },\n  ]}\n  submitLabel=\"Create workspace\"\n  successLabel=\"Workspace created\"\n  holdSeconds={4}\n/>",
      "related": [
        "search-results-populate",
        "drag-drop-flow",
        "tab-switch-panel"
      ],
      "note": "Field beats are derived from each value's length, so the sequence lengthens with the content rather than running on fixed constants. The submit button stays disabled until the last field ticks. Typing is the subject here; when it is only setup for a result list, use search-results-populate.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "notification-stack",
      "type": "registry:block",
      "description": "Toasts stacking and dismissing",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add notification-stack",
      "docsUrl": "https://remotionui.com/docs/components/notification-stack",
      "registryUrl": "https://remotionui.com/r/presets/default/notification-stack.json",
      "detailUrl": "https://remotionui.com/ai/components/notification-stack.json",
      "importPath": "@/remotion/scenes/notification-stack",
      "installTarget": "src/remotion/scenes/notification-stack",
      "category": "scene",
      "props": [
        {
          "name": "toasts",
          "type": "Toast[]",
          "default": "4 sample toasts",
          "description": "Title, optional body and meta, tone, and optional per-toast arrival and dwell."
        },
        {
          "name": "align",
          "type": "\"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\"",
          "default": "\"top-right\"",
          "description": "Corner the stack anchors to. Bottom anchors grow upward."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.3",
          "description": "Second the first toast arrives."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.62",
          "description": "Seconds between arrivals, for toasts without their own atSeconds."
        },
        {
          "name": "lifeSeconds",
          "type": "number",
          "default": "2.3",
          "description": "Default seconds a toast stays up before dismissing itself."
        },
        {
          "name": "showProgress",
          "type": "boolean",
          "default": "true",
          "description": "Draining line along each toast's bottom edge."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Colour used by the warn tone."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { NotificationStack } from \"@/remotion/scenes/notification-stack\";\n\n<NotificationStack\n  align=\"top-right\"\n  toasts={[\n    { title: \"Render finished\", body: \"launch-teaser.mp4\", tone: \"success\", meta: \"now\" },\n    { title: \"Storage at 86%\", tone: \"warn\", meta: \"2m\" },\n  ]}\n  lifeSeconds={2.3}\n/>",
      "related": [
        "comment-callout",
        "callout-spotlight",
        "chat-bubble"
      ],
      "note": "Transparent overlay scene designed to sit over an app or capture. Each toast carries its own life, so there is no holdSeconds: the stack fills and drains on its own. Slot offsets are the sum of the live heights above, which is what makes the rows below travel up into a dismissal instead of jumping.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "tab-switch-panel",
      "type": "registry:block",
      "description": "Tab bar with cross-fading panels",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add tab-switch-panel",
      "docsUrl": "https://remotionui.com/docs/components/tab-switch-panel",
      "registryUrl": "https://remotionui.com/r/presets/default/tab-switch-panel.json",
      "detailUrl": "https://remotionui.com/ai/components/tab-switch-panel.json",
      "importPath": "@/remotion/scenes/tab-switch-panel",
      "installTarget": "src/remotion/scenes/tab-switch-panel",
      "category": "scene",
      "props": [
        {
          "name": "tabs",
          "type": "PanelTab[]",
          "default": "4 sample tabs",
          "description": "Tab label plus the panel's title, summary and label/value rows."
        },
        {
          "name": "windowTitle",
          "type": "string",
          "default": "\"Northstar Studio\"",
          "description": "Title bar text. Omit to drop the chrome header."
        },
        {
          "name": "startIndex",
          "type": "number",
          "default": "0",
          "description": "Tab shown when the scene opens."
        },
        {
          "name": "firstSwitchAtSeconds",
          "type": "number",
          "default": "0.95",
          "description": "Second the first switch fires."
        },
        {
          "name": "switchEverySeconds",
          "type": "number",
          "default": "0.9",
          "description": "Seconds between switches after the first."
        },
        {
          "name": "transitionSeconds",
          "type": "number",
          "default": "0.5",
          "description": "How long one tab-to-tab move takes."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the last panel holds before the window retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Indicator pill and active label."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the window. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { TabSwitchPanel } from \"@/remotion/scenes/tab-switch-panel\";\n\n<TabSwitchPanel\n  windowTitle=\"Northstar Studio\"\n  tabs={[\n    { label: \"Overview\", title: \"1,284 renders\", rows: [{ label: \"Queued\", value: \"12\" }] },\n    { label: \"Billing\", title: \"Studio plan\", rows: [{ label: \"Seats\", value: \"9 of 12\" }] },\n  ]}\n  switchEverySeconds={0.9}\n  holdSeconds={4}\n/>",
      "related": [
        "device-mockup-zoom",
        "chat-to-preview",
        "faq-accordion"
      ],
      "note": "Tabs share the bar width evenly so the pill's travel is arithmetic rather than measured text, so it can never drift out of register with its label. The scene walks forward to the last tab and stops; it does not wrap, so holdSeconds must clear firstSwitchAtSeconds + switchEverySeconds × (tabs.length - 1) + transitionSeconds.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "search-results-populate",
      "type": "registry:block",
      "description": "Query typed, results streaming in and ranking",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add search-results-populate",
      "docsUrl": "https://remotionui.com/docs/components/search-results-populate",
      "registryUrl": "https://remotionui.com/r/presets/default/search-results-populate.json",
      "detailUrl": "https://remotionui.com/ai/components/search-results-populate.json",
      "importPath": "@/remotion/scenes/search-results-populate",
      "installTarget": "src/remotion/scenes/search-results-populate",
      "category": "scene",
      "props": [
        {
          "name": "query",
          "type": "string",
          "default": "\"transition between scenes\"",
          "description": "Text typed into the field."
        },
        {
          "name": "results",
          "type": "SearchResult[]",
          "default": "5 sample results",
          "description": "Title, detail line and 0–1 score. Array order is arrival order; score decides the final rank."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "\"Search the docs\"",
          "description": "Greyed prompt shown before the first character lands."
        },
        {
          "name": "countLabel",
          "type": "string",
          "default": "\"{n} results\"",
          "description": "Line above the list. {n} is replaced with the result count."
        },
        {
          "name": "topLabel",
          "type": "string",
          "default": "\"Best match\"",
          "description": "Tag pinned to the top-ranked result once the list settles."
        },
        {
          "name": "charsPerSecond",
          "type": "number",
          "default": "30",
          "description": "Typing rate for the query."
        },
        {
          "name": "searchSeconds",
          "type": "number",
          "default": "0.34",
          "description": "Seconds the indeterminate bar runs between the query and the first row."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the ranked list holds before the card retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Active field border, top-result tag and score."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { SearchResultsPopulate } from \"@/remotion/scenes/search-results-populate\";\n\n<SearchResultsPopulate\n  query=\"transition between scenes\"\n  results={[\n    { title: \"Slide transition\", detail: \"docs/transitions/slide\", score: 0.64 },\n    { title: \"Cross-fade two compositions\", detail: \"docs/transitions/fade\", score: 0.98 },\n  ]}\n  holdSeconds={4}\n/>",
      "related": [
        "form-fill-sequence",
        "comparison-table",
        "file-tree-reveal"
      ],
      "note": "The re-rank is the payoff: give the highest score to something other than the first entry and a late arrival climbs past the rows above it. Rows interpolate from arrival slot to ranked slot rather than being re-sorted, so React never remounts one mid-flight.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "file-tree-reveal",
      "type": "registry:block",
      "description": "Directory tree expanding node by node",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add file-tree-reveal",
      "docsUrl": "https://remotionui.com/docs/components/file-tree-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/file-tree-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/file-tree-reveal.json",
      "importPath": "@/remotion/scenes/file-tree-reveal",
      "installTarget": "src/remotion/scenes/file-tree-reveal",
      "category": "scene",
      "props": [
        {
          "name": "nodes",
          "type": "FileNode[]",
          "default": "sample project tree",
          "description": "Recursive tree. A node with a children array is a folder; without one it is a file."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"northstar-studio\"",
          "description": "Title bar over the tree. Omit to drop the header."
        },
        {
          "name": "selectedPath",
          "type": "string",
          "default": "\"src/scenes/lower-third.tsx\"",
          "description": "Slash-joined path of the file that lights up at the end. Omit to select nothing."
        },
        {
          "name": "rowStagger",
          "type": "number",
          "default": "0.18",
          "description": "Seconds between one row appearing and the next."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished tree holds before the panel retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Selected row's bar, tint and label."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the panel. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { FileTreeReveal } from \"@/remotion/scenes/file-tree-reveal\";\n\n<FileTreeReveal\n  title=\"northstar-studio\"\n  nodes={[\n    { name: \"src\", children: [{ name: \"index.ts\" }] },\n    { name: \"package.json\" },\n  ]}\n  selectedPath=\"src/index.ts\"\n  holdSeconds={4}\n/>",
      "related": [
        "code-reveal",
        "code-diff-wipe",
        "terminal-simulator"
      ],
      "note": "Rows reveal in depth-first display order, so a folder is always on screen before its contents, and each row takes its own height as it arrives: the rows beneath are pushed down rather than cross-faded onto a fixed grid. File names take their colour from the extension using the code token palette. Shows structure; code-reveal and code-diff-wipe show the contents of a file.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "kanban-move",
      "type": "registry:block",
      "description": "Cards moving across columns",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add kanban-move",
      "docsUrl": "https://remotionui.com/docs/components/kanban-move",
      "registryUrl": "https://remotionui.com/r/presets/default/kanban-move.json",
      "detailUrl": "https://remotionui.com/ai/components/kanban-move.json",
      "importPath": "@/remotion/scenes/kanban-move",
      "installTarget": "src/remotion/scenes/kanban-move",
      "category": "scene",
      "props": [
        {
          "name": "columns",
          "type": "string[]",
          "default": "[\"Backlog\", \"In progress\", \"Shipped\"]",
          "description": "Column headings, left to right. Cards address columns by index."
        },
        {
          "name": "cards",
          "type": "KanbanCard[]",
          "default": "6 sample cards",
          "description": "Title, meta line, starting column, rail tint, and the one move the card makes."
        },
        {
          "name": "moveSeconds",
          "type": "number",
          "default": "0.62",
          "description": "How long a card takes to arc from column to column."
        },
        {
          "name": "dealStaggerSeconds",
          "type": "number",
          "default": "0.08",
          "description": "Seconds between each card's arrival during the opening deal."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the settled board holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Destination column glow, and the fallback card rail."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the board. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { KanbanMove } from \"@/remotion/scenes/kanban-move\";\n\n<KanbanMove\n  columns={[\"Backlog\", \"In progress\", \"Shipped\"]}\n  cards={[\n    { title: \"Caption presets\", meta: \"RUI-218 · Ana\", column: 0 },\n    {\n      title: \"Render queue retries\",\n      meta: \"RUI-204 · Piotr\",\n      column: 0,\n      moveTo: 1,\n      moveAtSeconds: 0.95,\n    },\n    { title: \"Theme tokens\", meta: \"RUI-177 · Kit\", column: 1 },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "drag-drop-flow",
        "tab-switch-panel",
        "notification-stack"
      ],
      "note": "Give a card `moveTo` and `moveAtSeconds` to send it across; leave both off for cards that hold. Slots are arithmetic: a card lands at the bottom of its destination as that column stands at the moment it arrives, and the cards it left behind close the gap over exactly the frames it is travelling. For a single file dropping into one target, use drag-drop-flow.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "commit-graph",
      "type": "registry:block",
      "description": "Branch/merge graph drawing itself",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "code"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add commit-graph",
      "docsUrl": "https://remotionui.com/docs/components/commit-graph",
      "registryUrl": "https://remotionui.com/r/presets/default/commit-graph.json",
      "detailUrl": "https://remotionui.com/ai/components/commit-graph.json",
      "importPath": "@/remotion/scenes/commit-graph",
      "installTarget": "src/remotion/scenes/commit-graph",
      "category": "scene",
      "props": [
        {
          "name": "commits",
          "type": "GraphCommit[]",
          "default": "6 sample commits",
          "description": "Message, hash, lane, parent index, optional mergeFrom lane and branch ref chip."
        },
        {
          "name": "windowTitle",
          "type": "string",
          "default": "\"git log --graph --oneline\"",
          "description": "Text in the title bar. Omit to drop the chrome header."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.34",
          "description": "Second the first commit lands."
        },
        {
          "name": "stepSeconds",
          "type": "number",
          "default": "0.36",
          "description": "Seconds between commits. Each edge draws over this same gap."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished graph holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Trunk colour, and the branch ref chip."
        },
        {
          "name": "laneColors",
          "type": "string[]",
          "default": "4 lane colours",
          "description": "Colours for branch lanes 1 and up. Lane 0 always takes accentColor."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the window. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CommitGraph } from \"@/remotion/scenes/commit-graph\";\n\n<CommitGraph\n  commits={[\n    { message: \"Seed the registry manifest\", hash: \"9c41f0a\" },\n    { message: \"Add render queue worker\", hash: \"3ab77e2\" },\n    { message: \"Branch: retry backoff\", hash: \"d0e91c4\", lane: 1, parent: 1 },\n    { message: \"Cap retries at five\", hash: \"51b2fa8\", lane: 1 },\n    { message: \"Ship caption presets\", hash: \"7f30dd1\", lane: 0, parent: 1 },\n    { message: \"Merge retry backoff\", hash: \"b8c4e05\", parent: 4, mergeFrom: 3, ref: \"main\" },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "code-diff-wipe",
        "file-tree-reveal",
        "terminal-simulator"
      ],
      "note": "`parent` defaults to the previous commit, so a straight run needs nothing; point it further back to fork and set `mergeFrom` to bring the fork home. Edges use pathLength={1}, so a long merge curve and a short vertical hop draw at the same apparent speed, and a commit dot only pops once the line feeding it has arrived.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "comparison-table",
      "type": "registry:block",
      "description": "Multi-column feature matrix",
      "tasks": [
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add comparison-table",
      "docsUrl": "https://remotionui.com/docs/components/comparison-table",
      "registryUrl": "https://remotionui.com/r/presets/default/comparison-table.json",
      "detailUrl": "https://remotionui.com/ai/components/comparison-table.json",
      "importPath": "@/remotion/scenes/comparison-table",
      "installTarget": "src/remotion/scenes/comparison-table",
      "category": "scene",
      "props": [
        {
          "name": "columns",
          "type": "string[]",
          "default": "[\"Free\", \"Studio\", \"Scale\"]",
          "description": "Column headings. The feature-label column is unnamed and sits ahead of these."
        },
        {
          "name": "rows",
          "type": "MatrixRow[]",
          "default": "6 sample rows",
          "description": "A label plus one cell per column: true ticks, false crosses, a string prints as-is."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"What you get\"",
          "description": "Heading above the table. Omit to drop it."
        },
        {
          "name": "highlightColumn",
          "type": "number",
          "default": "1",
          "description": "Column kept lit throughout. Pass -1 for a table with no favourite."
        },
        {
          "name": "highlightLabel",
          "type": "string",
          "default": "\"Most picked\"",
          "description": "Chip pinned beside the title, above the highlighted column."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.5",
          "description": "Second the first row wipes in."
        },
        {
          "name": "rowStaggerSeconds",
          "type": "number",
          "default": "0.26",
          "description": "Seconds between rows. Cells inside a row trail their label by another 0.07s each."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished table holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Highlight band, its header, and the ticks inside it."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ComparisonTable } from \"@/remotion/scenes/comparison-table\";\n\n<ComparisonTable\n  title=\"What you get\"\n  columns={[\"Free\", \"Studio\", \"Scale\"]}\n  rows={[\n    { label: \"Render minutes\", cells: [\"60\", \"2,000\", \"Unlimited\"] },\n    { label: \"4K exports\", cells: [false, true, true] },\n    { label: \"Priority queue\", cells: [false, false, true] },\n  ]}\n  highlightColumn={1}\n  highlightLabel=\"Most picked\"\n  holdSeconds={3.4}\n/>",
      "related": [
        "feature-list",
        "pricing-card",
        "pricing-focus"
      ],
      "note": "Ticks and crosses draw their own strokes rather than fading: a fading glyph spends most of its entrance as grey mush at matrix sizes. The highlighted column is one lit band behind the grid, so rows can never disagree about where its edges are. For a single ticked list rather than a matrix, use feature-list.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "pricing-card",
      "type": "registry:block",
      "description": "Tier card with price roll and features",
      "tasks": [
        "product-intro",
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add pricing-card",
      "docsUrl": "https://remotionui.com/docs/components/pricing-card",
      "registryUrl": "https://remotionui.com/r/presets/default/pricing-card.json",
      "detailUrl": "https://remotionui.com/ai/components/pricing-card.json",
      "importPath": "@/remotion/scenes/pricing-card",
      "installTarget": "src/remotion/scenes/pricing-card",
      "category": "scene",
      "props": [
        {
          "name": "tier",
          "type": "string",
          "default": "\"Studio\"",
          "description": "Tier name across the top of the card."
        },
        {
          "name": "price",
          "type": "number",
          "default": "32",
          "description": "The number the price rolls up to."
        },
        {
          "name": "currency",
          "type": "string",
          "default": "\"$\"",
          "description": "Symbol set ahead of the number."
        },
        {
          "name": "period",
          "type": "string",
          "default": "\"/mo\"",
          "description": "Cadence after the price: \"/mo\", \"per seat\", anything short."
        },
        {
          "name": "badge",
          "type": "string",
          "default": "\"Most picked\"",
          "description": "Chip beside the tier name. Omit to drop it."
        },
        {
          "name": "note",
          "type": "string",
          "default": "\"Billed annually. Cancel whenever.\"",
          "description": "Line under the price."
        },
        {
          "name": "wasPrice",
          "type": "number",
          "description": "Old price, struck through beside the new one. Omit when there is no before-and-after."
        },
        {
          "name": "features",
          "type": "string[]",
          "default": "5 sample features",
          "description": "Ticked lines under the price, revealed in order."
        },
        {
          "name": "ctaLabel",
          "type": "string",
          "default": "\"Start rendering\"",
          "description": "Button text. Omit to drop the button."
        },
        {
          "name": "priceAtSeconds",
          "type": "number",
          "default": "0.42",
          "description": "Second the price starts rolling."
        },
        {
          "name": "rollSeconds",
          "type": "number",
          "default": "0.9",
          "description": "How long the roll takes."
        },
        {
          "name": "featuresAtSeconds",
          "type": "number",
          "default": "1.05",
          "description": "Second the first feature ticks in."
        },
        {
          "name": "featureStaggerSeconds",
          "type": "number",
          "default": "0.22",
          "description": "Seconds between features. The CTA lands 0.16s after the last one."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished card holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Badge, ticks, card border wash and the CTA fill."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { PricingCard } from \"@/remotion/scenes/pricing-card\";\n\n<PricingCard\n  tier=\"Studio\"\n  badge=\"Most picked\"\n  price={32}\n  period=\"/mo\"\n  note=\"Billed annually. Cancel whenever.\"\n  features={[\"2,000 render minutes a month\", \"4K exports, no watermark\", \"9 team seats\"]}\n  ctaLabel=\"Start rendering\"\n  holdSeconds={3.4}\n/>",
      "related": [
        "pricing-focus",
        "comparison-table",
        "feature-list"
      ],
      "note": "The price is a counted number under a blur that clears as it settles, not a spinning digit strip: a strip has to guess glyph widths, a counted number stays in register with tabular-nums at any size. The CTA is scheduled off the last feature, so adding features pushes the button later rather than colliding with it. This is one card at block grain; for a full tier comparison beat, use pricing-focus.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "faq-accordion",
      "type": "registry:block",
      "description": "Narrowed: Q/A text rows expanding",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "ui"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add faq-accordion",
      "docsUrl": "https://remotionui.com/docs/components/faq-accordion",
      "registryUrl": "https://remotionui.com/r/presets/default/faq-accordion.json",
      "detailUrl": "https://remotionui.com/ai/components/faq-accordion.json",
      "importPath": "@/remotion/scenes/faq-accordion",
      "installTarget": "src/remotion/scenes/faq-accordion",
      "category": "scene",
      "props": [
        {
          "name": "items",
          "type": "FaqItem[]",
          "default": "4 sample questions",
          "description": "Question and answer for each row."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"Questions people ask\"",
          "description": "Heading above the list. Omit to drop it."
        },
        {
          "name": "openOrder",
          "type": "number[]",
          "default": "[0, 1, 2]",
          "description": "Row indices opened in turn; each closes the previous. Shorter than items leaves the tail closed."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.55",
          "description": "Second the first row opens."
        },
        {
          "name": "openEverySeconds",
          "type": "number",
          "default": "1",
          "description": "Seconds between one row opening and the next."
        },
        {
          "name": "transitionSeconds",
          "type": "number",
          "default": "0.55",
          "description": "How long a row takes to open or close. Opens and closes overlap, so the list never jumps height."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the list holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Open row's chevron and its background wash."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the list. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { FaqAccordion } from \"@/remotion/scenes/faq-accordion\";\n\n<FaqAccordion\n  title=\"Questions people ask\"\n  items={[\n    { question: \"Do I own the components?\", answer: \"Yes. The CLI copies the source into your repo.\" },\n    { question: \"Can I render on my own machine?\", answer: \"Renders run wherever Remotion runs.\" },\n  ]}\n  openOrder={[0, 1]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "code-accordion",
        "timeline-steps",
        "feature-list"
      ],
      "note": "Panel heights are estimated from the answer's length against the measured content width, because a headless render has no layout to interrogate mid-animation, and a height read from scrollHeight collapses to zero on exactly the frames that matter. Keep answers to two or three lines; long copy inflates the estimate's rounding slack. For code panels use code-accordion, for an ordered process use timeline-steps.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "team-grid",
      "type": "registry:block",
      "description": "Avatar grid with role labels on stagger",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add team-grid",
      "docsUrl": "https://remotionui.com/docs/components/team-grid",
      "registryUrl": "https://remotionui.com/r/presets/default/team-grid.json",
      "detailUrl": "https://remotionui.com/ai/components/team-grid.json",
      "importPath": "@/remotion/scenes/team-grid",
      "installTarget": "src/remotion/scenes/team-grid",
      "category": "scene",
      "props": [
        {
          "name": "members",
          "type": "TeamMember[]",
          "default": "8 sample people",
          "description": "Name, role, optional avatar tint and hand-written initials."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"The people behind it\"",
          "description": "Heading above the grid. Omit to drop it."
        },
        {
          "name": "subtitle",
          "type": "string",
          "default": "\"Eight of us, four timezones.\"",
          "description": "Line under the heading."
        },
        {
          "name": "columns",
          "type": "number",
          "default": "4",
          "description": "Members per row. Four keeps names on one line at 1080p."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.4",
          "description": "Second the first avatar arrives."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.2",
          "description": "Seconds between members, in reading order."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the settled grid holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Role line on the first member: the one you want read first."
        },
        {
          "name": "avatarColors",
          "type": "string[]",
          "default": "6 tints",
          "description": "Cycled by index for members with no colour of their own."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the grid. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { TeamGrid } from \"@/remotion/scenes/team-grid\";\n\n<TeamGrid\n  title=\"The people behind it\"\n  subtitle=\"Eight of us, four timezones.\"\n  members={[\n    { name: \"Ada Okonjo\", role: \"Founder\" },\n    { name: \"Piotr Nowak\", role: \"Rendering\" },\n    { name: \"Dai Nakamura\", role: \"Design systems\" },\n  ]}\n  columns={4}\n  holdSeconds={3.4}\n/>",
      "related": [
        "org-chart-build",
        "logo-wall",
        "feature-list"
      ],
      "note": "Initials are the first letters of the first two words: right for most Latin names and wrong for enough others that `initials` is worth passing by hand. The avatar springs up ahead of its name and role so each tile lands as one object with depth rather than three elements agreeing to fade.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "logo-wall",
      "type": "registry:block",
      "description": "Client logo grid, grayscale to color",
      "tasks": [
        "product-intro",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add logo-wall",
      "docsUrl": "https://remotionui.com/docs/components/logo-wall",
      "registryUrl": "https://remotionui.com/r/presets/default/logo-wall.json",
      "detailUrl": "https://remotionui.com/ai/components/logo-wall.json",
      "importPath": "@/remotion/scenes/logo-wall",
      "installTarget": "src/remotion/scenes/logo-wall",
      "category": "scene",
      "props": [
        {
          "name": "logos",
          "type": "WallLogo[]",
          "default": "8 sample brands",
          "description": "Wordmark, brand colour, and the glyph in the mark beside it."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "default": "\"Trusted by\"",
          "description": "Small line above the heading. Omit to drop it."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"Teams shipping with RemotionUI\"",
          "description": "Heading above the wall. Omit to drop it."
        },
        {
          "name": "columns",
          "type": "number",
          "default": "4",
          "description": "Tiles per row."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.32",
          "description": "Second the first tile arrives."
        },
        {
          "name": "arriveStaggerSeconds",
          "type": "number",
          "default": "0.06",
          "description": "Seconds between tiles arriving, in reading order. Deliberately fast."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.24",
          "description": "Seconds between diagonals of the colour sweep."
        },
        {
          "name": "warmSeconds",
          "type": "number",
          "default": "0.6",
          "description": "How long one tile takes to go from grey to brand colour."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished wall holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Eyebrow, and the fallback for logos with no colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the wall. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { LogoWall } from \"@/remotion/scenes/logo-wall\";\n\n<LogoWall\n  eyebrow=\"Trusted by\"\n  title=\"Teams shipping with RemotionUI\"\n  logos={[\n    { name: \"Northstar\", color: \"#E8B86D\" },\n    { name: \"Halcyon\", color: \"#7DD3E8\" },\n    { name: \"Fernweh\", color: \"#9BD4A0\" },\n    { name: \"Orbital\", color: \"#C99BE8\" },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "team-grid",
        "feature-list",
        "comparison-table"
      ],
      "note": "Arrival and colour are separate beats on purpose: tiles land fast so the wall is whole within a second, then the colour sweeps the diagonal across it. Grey is one saturate() on the tile rather than a second set of grey colours, so swapping in your own brand colours brings the monochrome stage with it. Wordmarks are text: no image assets to bundle or fail to load in a headless render.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "changelog-entry",
      "type": "registry:block",
      "description": "Version header with categorized change rows",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add changelog-entry",
      "docsUrl": "https://remotionui.com/docs/components/changelog-entry",
      "registryUrl": "https://remotionui.com/r/presets/default/changelog-entry.json",
      "detailUrl": "https://remotionui.com/ai/components/changelog-entry.json",
      "importPath": "@/remotion/scenes/changelog-entry",
      "installTarget": "src/remotion/scenes/changelog-entry",
      "category": "scene",
      "props": [
        {
          "name": "changes",
          "type": "ChangeRow[]",
          "default": "5 sample changes",
          "description": "A kind (added, fixed, changed or removed) and the sentence beside it."
        },
        {
          "name": "version",
          "type": "string",
          "default": "\"v2.4.0\"",
          "description": "Version string, set at display size."
        },
        {
          "name": "date",
          "type": "string",
          "default": "\"16 August\"",
          "description": "Date beside the version."
        },
        {
          "name": "summary",
          "type": "string",
          "default": "\"Captions, webhooks, and a queue that stops sulking.\"",
          "description": "Headline under the version. Omit for releases without one."
        },
        {
          "name": "kindColors",
          "type": "Partial<Record<ChangeKind, string>>",
          "default": "green / blue / amber / red",
          "description": "Override any tag colour without supplying the rest."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.66",
          "description": "Second the first change row arrives."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.28",
          "description": "Seconds between rows. Each sentence trails its own tag by 0.08s."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished entry holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Fallback tag colour for kinds with no colour set."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { ChangelogEntry } from \"@/remotion/scenes/changelog-entry\";\n\n<ChangelogEntry\n  version=\"v2.4.0\"\n  date=\"16 August\"\n  summary=\"Captions, webhooks, and a queue that stops sulking.\"\n  changes={[\n    { kind: \"added\", text: \"Caption presets for nine languages\" },\n    { kind: \"fixed\", text: \"Retry backoff no longer stalls the queue\" },\n    { kind: \"removed\", text: \"Legacy waveform atom\" },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "commit-graph",
        "feature-list",
        "roadmap-lanes"
      ],
      "note": "Tags are fixed width so every sentence shares a left edge: ragged text beside ragged tags is what makes a changelog look unmaintained. The tag lands before its sentence because the kind of change is what a viewer scans for. Five or six rows is the ceiling before the card outgrows a 1080p frame; split a larger release into two entries.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "roadmap-lanes",
      "type": "registry:block",
      "description": "Swimlanes of shipped/building/planned",
      "tasks": [
        "maps",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add roadmap-lanes",
      "docsUrl": "https://remotionui.com/docs/components/roadmap-lanes",
      "registryUrl": "https://remotionui.com/r/presets/default/roadmap-lanes.json",
      "detailUrl": "https://remotionui.com/ai/components/roadmap-lanes.json",
      "importPath": "@/remotion/scenes/roadmap-lanes",
      "installTarget": "src/remotion/scenes/roadmap-lanes",
      "category": "scene",
      "props": [
        {
          "name": "lanes",
          "type": "RoadmapLane[]",
          "default": "Shipped / Building / Planned",
          "description": "Title, colour, items, and the flags that set the lane's state: done, showProgress, dashed."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"What we are building\"",
          "description": "Heading above the lanes. Omit to drop it."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.42",
          "description": "Second the first lane's items arrive."
        },
        {
          "name": "laneStaggerSeconds",
          "type": "number",
          "default": "0.42",
          "description": "Seconds between lanes."
        },
        {
          "name": "itemStaggerSeconds",
          "type": "number",
          "default": "0.14",
          "description": "Seconds between items inside a lane."
        },
        {
          "name": "fillSeconds",
          "type": "number",
          "default": "0.8",
          "description": "How long a progress bar takes to reach its value, starting 0.3s after the pill lands."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the settled roadmap holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Fallback colour for lanes with none of their own."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the lanes. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { RoadmapLanes } from \"@/remotion/scenes/roadmap-lanes\";\n\n<RoadmapLanes\n  title=\"What we are building\"\n  lanes={[\n    { title: \"Shipped\", color: \"#9BD4A0\", done: true, items: [{ label: \"Render API\" }] },\n    {\n      title: \"Building\",\n      color: \"#E8B86D\",\n      showProgress: true,\n      items: [{ label: \"Timeline scrubber\", progress: 0.72 }],\n    },\n    { title: \"Planned\", color: \"#7A828F\", dashed: true, items: [{ label: \"Stem export\" }] },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "kanban-move",
        "timeline-steps",
        "changelog-entry"
      ],
      "note": "Lane appearance comes from flags, not from lane names: a blocked lane is `dashed` with a red colour, a next-up lane is `showProgress` with low values. The fill starts after the pill lands and takes longer than the arrival, so progress is a second beat rather than a blur inside the first. Three items per lane is the comfortable maximum at 1080p; item width divides the board rather than wrapping.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "org-chart-build",
      "type": "registry:block",
      "description": "Hierarchy assembling top-down",
      "tasks": [
        "data",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add org-chart-build",
      "docsUrl": "https://remotionui.com/docs/components/org-chart-build",
      "registryUrl": "https://remotionui.com/r/presets/default/org-chart-build.json",
      "detailUrl": "https://remotionui.com/ai/components/org-chart-build.json",
      "importPath": "@/remotion/scenes/org-chart-build",
      "installTarget": "src/remotion/scenes/org-chart-build",
      "category": "scene",
      "props": [
        {
          "name": "nodes",
          "type": "OrgNode[]",
          "default": "a 7-person tree",
          "description": "Name, role and a `parent` index. Omit parent for the root; parents must appear before their children."
        },
        {
          "name": "title",
          "type": "string",
          "default": "\"How the team is wired\"",
          "description": "Heading above the chart. Omit to drop it."
        },
        {
          "name": "startAtSeconds",
          "type": "number",
          "default": "0.34",
          "description": "Second the root lands."
        },
        {
          "name": "levelStaggerSeconds",
          "type": "number",
          "default": "0.62",
          "description": "Seconds between levels. Connectors lead their child by 0.34s inside that gap."
        },
        {
          "name": "siblingStaggerSeconds",
          "type": "number",
          "default": "0.12",
          "description": "Seconds between siblings, ordered left to right by position."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the finished chart holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Role line on the root."
        },
        {
          "name": "levelColors",
          "type": "string[]",
          "default": "3 depth colours",
          "description": "One colour per depth. Deeper levels reuse the last entry."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the chart. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { OrgChartBuild } from \"@/remotion/scenes/org-chart-build\";\n\n<OrgChartBuild\n  title=\"How the team is wired\"\n  nodes={[\n    { name: \"Ada Okonjo\", role: \"Founder\" },\n    { name: \"Piotr Nowak\", role: \"Engineering\", parent: 0 },\n    { name: \"Dai Nakamura\", role: \"Design\", parent: 0 },\n    { name: \"Sam Rhodes\", role: \"Infrastructure\", parent: 1 },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "team-grid",
        "commit-graph",
        "roadmap-lanes"
      ],
      "note": "Positions come from a leaf walk rather than a grid: leaves spread evenly and each parent centres over the span of its own children, so a lopsided tree stays balanced. Connectors are elbows, not diagonals: a straight line between two boxes reads as a different kind of relationship entirely. Three levels fits 1080p comfortably; a fourth wants a taller frame rather than a smaller node.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "quiz-question",
      "type": "registry:block",
      "description": "Question, options, correct-answer reveal",
      "tasks": [
        "captions",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core",
        "tags": [
          "social"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add quiz-question",
      "docsUrl": "https://remotionui.com/docs/components/quiz-question",
      "registryUrl": "https://remotionui.com/r/presets/default/quiz-question.json",
      "detailUrl": "https://remotionui.com/ai/components/quiz-question.json",
      "importPath": "@/remotion/scenes/quiz-question",
      "installTarget": "src/remotion/scenes/quiz-question",
      "category": "scene",
      "props": [
        {
          "name": "question",
          "type": "string",
          "default": "\"What does the RemotionUI CLI actually do?\"",
          "description": "The question, set at display size."
        },
        {
          "name": "options",
          "type": "string[]",
          "default": "4 sample answers",
          "description": "Answer options in display order. Four is the readable maximum at 1080p."
        },
        {
          "name": "correctIndex",
          "type": "number",
          "default": "1",
          "description": "Index of the right answer."
        },
        {
          "name": "pickedIndex",
          "type": "number",
          "default": "2",
          "description": "Index picked before the reveal. Set it to correctIndex for a right pick, -1 for none."
        },
        {
          "name": "eyebrow",
          "type": "string",
          "default": "\"Question 3 of 8\"",
          "description": "Small line above the question. Omit to drop it."
        },
        {
          "name": "optionsAtSeconds",
          "type": "number",
          "default": "0.55",
          "description": "Second the first option arrives."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.2",
          "description": "Seconds between options."
        },
        {
          "name": "pickAtSeconds",
          "type": "number",
          "default": "1.75",
          "description": "Second the pick lands."
        },
        {
          "name": "revealAtSeconds",
          "type": "number",
          "default": "2.35",
          "description": "Second the right answer is revealed."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the resolved question holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Eyebrow, and the picked-but-not-yet-resolved state."
        },
        {
          "name": "correctColor",
          "type": "string",
          "default": "\"#7FD1A0\"",
          "description": "The right answer on reveal."
        },
        {
          "name": "wrongColor",
          "type": "string",
          "default": "\"#E89B9B\"",
          "description": "A wrong pick on reveal."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { QuizQuestion } from \"@/remotion/scenes/quiz-question\";\n\n<QuizQuestion\n  question=\"What does the RemotionUI CLI actually do?\"\n  options={[\n    \"It bundles a runtime you ship\",\n    \"It copies the source into your repo\",\n    \"It renders on our servers\",\n  ]}\n  correctIndex={1}\n  pickedIndex={2}\n  holdSeconds={3.4}\n/>",
      "related": [
        "poll-overlay",
        "comparison-table",
        "reaction-burst"
      ],
      "note": "The pick and the reveal are deliberately separate beats: the eye has to settle on a choice before it can register being told it was wrong. On the reveal everything neither picked nor correct steps back rather than changing colour, so the resolution reads as focus narrowing. For audience voting with no right answer, use poll-overlay.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "weather-card",
      "type": "registry:block",
      "description": "Conditions with animated iconography",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add weather-card",
      "docsUrl": "https://remotionui.com/docs/components/weather-card",
      "registryUrl": "https://remotionui.com/r/presets/default/weather-card.json",
      "detailUrl": "https://remotionui.com/ai/components/weather-card.json",
      "importPath": "@/remotion/scenes/weather-card",
      "installTarget": "src/remotion/scenes/weather-card",
      "category": "scene",
      "props": [
        {
          "name": "place",
          "type": "string",
          "default": "\"Lisbon\"",
          "description": "Place name across the top."
        },
        {
          "name": "detail",
          "type": "string",
          "default": "\"Saturday · 14:20\"",
          "description": "Line under the place: a time, a date, a feels-like."
        },
        {
          "name": "temperature",
          "type": "number",
          "default": "24",
          "description": "The temperature the card counts up to."
        },
        {
          "name": "unit",
          "type": "string",
          "default": "\"°\"",
          "description": "Degree suffix, used on the headline and the forecast."
        },
        {
          "name": "condition",
          "type": "\"sun\" | \"cloud\" | \"rain\" | \"snow\"",
          "default": "\"sun\"",
          "description": "Which glyph runs beside the headline."
        },
        {
          "name": "conditionLabel",
          "type": "string",
          "default": "\"Clear, light breeze\"",
          "description": "Words under the temperature."
        },
        {
          "name": "forecast",
          "type": "ForecastDay[]",
          "default": "5 sample days",
          "description": "Label, condition, high and low per column."
        },
        {
          "name": "temperatureAtSeconds",
          "type": "number",
          "default": "0.4",
          "description": "Second the temperature starts counting."
        },
        {
          "name": "countSeconds",
          "type": "number",
          "default": "1",
          "description": "How long the count takes."
        },
        {
          "name": "forecastAtSeconds",
          "type": "number",
          "default": "1.4",
          "description": "Second the first forecast day arrives."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.34",
          "description": "Seconds between forecast days."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the card holds before it retreats. Omit to leave it up; the iconography keeps moving either way."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "The degree symbol. Kept off the condition colour on purpose."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { WeatherCard } from \"@/remotion/scenes/weather-card\";\n\n<WeatherCard\n  place=\"Lisbon\"\n  temperature={24}\n  condition=\"sun\"\n  conditionLabel=\"Clear, light breeze\"\n  forecast={[\n    { label: \"Sat\", condition: \"sun\", high: 24, low: 14 },\n    { label: \"Sun\", condition: \"cloud\", high: 22, low: 13 },\n    { label: \"Mon\", condition: \"rain\", high: 18, low: 12 },\n  ]}\n/>",
      "related": [
        "stat-card",
        "gauge-dial",
        "calendar-month-fill"
      ],
      "note": "Every moving part is a pure function of the frame (frame × rate wrapped into its own period, with per-particle offsets from the particle's index), so a frame rendered out of order on a render farm is identical to the same frame rendered in sequence. Each forecast column runs its own clock nine frames apart, so the row is never five glyphs in lockstep. The motion is real but small (a forecast glyph is only a few pixels tall), so pass holdSeconds when the card stands on its own.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "calendar-month-fill",
      "type": "registry:block",
      "description": "Month grid populating with events",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "blocks",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "code-syntax",
        "layout",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add calendar-month-fill",
      "docsUrl": "https://remotionui.com/docs/components/calendar-month-fill",
      "registryUrl": "https://remotionui.com/r/presets/default/calendar-month-fill.json",
      "detailUrl": "https://remotionui.com/ai/components/calendar-month-fill.json",
      "importPath": "@/remotion/scenes/calendar-month-fill",
      "installTarget": "src/remotion/scenes/calendar-month-fill",
      "category": "scene",
      "props": [
        {
          "name": "month",
          "type": "string",
          "default": "\"August\"",
          "description": "Month name in the header."
        },
        {
          "name": "year",
          "type": "string",
          "default": "\"2026\"",
          "description": "Year beside the month."
        },
        {
          "name": "daysInMonth",
          "type": "number",
          "default": "31",
          "description": "How many day cells the month has."
        },
        {
          "name": "startWeekday",
          "type": "number",
          "default": "5",
          "description": "Column the 1st falls in, counting from Monday as 0."
        },
        {
          "name": "todayDay",
          "type": "number",
          "default": "15",
          "description": "Day given the accent ring. Pass -1 when the month is a plan."
        },
        {
          "name": "events",
          "type": "CalendarEvent[]",
          "default": "7 sample events",
          "description": "Day number, label and chip colour. One chip per day."
        },
        {
          "name": "weekdayLabels",
          "type": "string[]",
          "default": "Mon–Sun",
          "description": "Column headings; their count sets the grid width."
        },
        {
          "name": "gridAtSeconds",
          "type": "number",
          "default": "0.3",
          "description": "Second the empty grid starts sweeping up."
        },
        {
          "name": "eventsAtSeconds",
          "type": "number",
          "default": "0.95",
          "description": "Second the first event drops."
        },
        {
          "name": "staggerSeconds",
          "type": "number",
          "default": "0.2",
          "description": "Seconds between events."
        },
        {
          "name": "holdSeconds",
          "type": "number",
          "description": "Seconds the filled month holds before it retreats. Omit to leave it up."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Today's ring, and the fallback chip colour."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Page behind the card. Defaults to the theme page colour."
        },
        {
          "name": "theme",
          "type": "\"dark\" | \"light\"",
          "default": "\"dark\"",
          "description": "Surface palette."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Animation speed multiplier."
        }
      ],
      "usage": "import { CalendarMonthFill } from \"@/remotion/scenes/calendar-month-fill\";\n\n<CalendarMonthFill\n  month=\"August\"\n  year=\"2026\"\n  daysInMonth={31}\n  startWeekday={5}\n  todayDay={15}\n  events={[\n    { day: 4, label: \"Kickoff\", color: \"#7DD3E8\" },\n    { day: 15, label: \"Render day\", color: \"#9BD4A0\" },\n  ]}\n  holdSeconds={3.4}\n/>",
      "related": [
        "gantt-timeline",
        "roadmap-lanes",
        "weather-card"
      ],
      "note": "The month comes from daysInMonth and startWeekday rather than from a date: a scene needs a month that looks right, not one correct for a particular year, and this keeps the component free of a date library and a timezone bug. Chips drop onto their day rather than fading in place, so a filling month reads as things being scheduled. One chip per day is the ceiling at 1080p.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "arrow-annotate",
      "type": "registry:ui",
      "description": "Hand-drawn arrow pointing at a target",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add arrow-annotate",
      "docsUrl": "https://remotionui.com/docs/components/arrow-annotate",
      "registryUrl": "https://remotionui.com/r/presets/default/arrow-annotate.json",
      "detailUrl": "https://remotionui.com/ai/components/arrow-annotate.json",
      "importPath": "@/remotion/primitives/arrow-annotate",
      "installTarget": "src/remotion/primitives/arrow-annotate",
      "category": "primitive",
      "props": [
        {
          "name": "from",
          "type": "{ x: number; y: number }",
          "default": "{ x: 0.08, y: 0.16 }",
          "description": "Start of the shaft, as a fraction of the box."
        },
        {
          "name": "to",
          "type": "{ x: number; y: number }",
          "default": "{ x: 0.82, y: 0.74 }",
          "description": "The point the head lands on, as a fraction of the box."
        },
        {
          "name": "bow",
          "type": "number",
          "default": "0.28",
          "description": "How far the shaft bows off the straight line, as a fraction of the distance. Negative bows the other way."
        },
        {
          "name": "label",
          "type": "string",
          "description": "Text set beside the start of the shaft."
        },
        {
          "name": "labelSize",
          "type": "number",
          "default": "16",
          "description": "Label type size in box units. The default suits a small annotation over a screenshot; raise it when the arrow is the subject of the frame."
        },
        {
          "name": "width",
          "type": "number",
          "default": "320",
          "description": "Box width in pixels."
        },
        {
          "name": "height",
          "type": "number",
          "default": "220",
          "description": "Box height in pixels."
        },
        {
          "name": "stroke",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Colour of the shaft, head and label."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "3",
          "description": "Shaft weight. The second sketch pass runs at 60% of it."
        },
        {
          "name": "headSize",
          "type": "number",
          "default": "18",
          "description": "Length of the head's barbs, in box units."
        },
        {
          "name": "sketch",
          "type": "boolean",
          "default": "true",
          "description": "Draws the shaft twice at a sub-pixel offset. False for a single clean stroke."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the shaft starts drawing."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "40",
          "description": "Frames the shaft takes. The head lands over the last quarter."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the arrow starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "14",
          "description": "Frames the exit takes."
        }
      ],
      "usage": "import { ArrowAnnotate } from \"@/remotion/primitives/arrow-annotate\";\n\n<ArrowAnnotate\n  from={{ x: 0.08, y: 0.16 }}\n  to={{ x: 0.82, y: 0.74 }}\n  bow={0.28}\n  label=\"this one\"\n  durationInFrames={70}\n  exitAtInFrames={92}\n/>",
      "related": [
        "path-draw",
        "handwriting-text",
        "cursor-path"
      ],
      "note": "The head is angled to the curve's own tangent, not to the straight line between the ends, so the arrow points where it is travelling. The hand-drawn quality is two passes at a sub-pixel offset, not a path whose points move per frame, which reads as a shaking arrow. The stroke draws on an editorial curve; a strong ease-out would finish in its first frames and then crawl.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "badge-stamp",
      "type": "registry:ui",
      "description": "Stamp/seal impact with rotation settle",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add badge-stamp",
      "docsUrl": "https://remotionui.com/docs/components/badge-stamp",
      "registryUrl": "https://remotionui.com/r/presets/default/badge-stamp.json",
      "detailUrl": "https://remotionui.com/ai/components/badge-stamp.json",
      "importPath": "@/remotion/primitives/badge-stamp",
      "installTarget": "src/remotion/primitives/badge-stamp",
      "category": "primitive",
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "\"APPROVED\"",
          "description": "The word in the middle of the seal."
        },
        {
          "name": "ringText",
          "type": "string",
          "default": "\"REMOTIONUI\"",
          "description": "Text curved around the top. Keep it short enough not to run past the sides."
        },
        {
          "name": "ringTextBottom",
          "type": "string",
          "default": "\"VERIFIED BUILD\"",
          "description": "Text curved around the bottom, on its own left-to-right arc so it reads upright."
        },
        {
          "name": "sublabel",
          "type": "string",
          "default": "\"2026\"",
          "description": "Line under the label."
        },
        {
          "name": "size",
          "type": "number",
          "default": "220",
          "description": "Rendered size in pixels."
        },
        {
          "name": "color",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Ink colour for every part of the seal."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "-9",
          "description": "Degrees the stamp settles at."
        },
        {
          "name": "windUp",
          "type": "number",
          "default": "16",
          "description": "How much further round it starts, in degrees."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "6",
          "description": "Frame the stamp lands on."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the stamp starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        },
        {
          "name": "impactRing",
          "type": "boolean",
          "default": "true",
          "description": "Shockwave thrown off on impact."
        }
      ],
      "usage": "import { BadgeStamp } from \"@/remotion/primitives/badge-stamp\";\n\n<BadgeStamp\n  label=\"APPROVED\"\n  ringText=\"REMOTIONUI\"\n  ringTextBottom=\"VERIFIED BUILD\"\n  sublabel=\"2026\"\n  delayInFrames={14}\n  exitAtInFrames={92}\n/>",
      "related": [
        "confetti-burst",
        "glow-pulse",
        "logo-reveal"
      ],
      "note": "Scale and rotation run on separate springs, so the rotation is still unwinding after the scale has stopped, and that offset is what sells the weight, and collapsing them onto one spring makes the seal read as a sticker being placed. The shockwave is thrown from the impact frame rather than from the start, so it cannot arrive before its cause. Ring text uses two half-arcs because letters stand up from the direction of travel.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "shape-morph",
      "type": "registry:ui",
      "description": "Path interpolation between two shapes",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens",
        "path-morph"
      ],
      "installCommand": "npx remotion-ui@latest add shape-morph",
      "docsUrl": "https://remotionui.com/docs/components/shape-morph",
      "registryUrl": "https://remotionui.com/r/presets/default/shape-morph.json",
      "detailUrl": "https://remotionui.com/ai/components/shape-morph.json",
      "importPath": "@/remotion/primitives/shape-morph",
      "installTarget": "src/remotion/primitives/shape-morph",
      "category": "primitive",
      "props": [
        {
          "name": "shapes",
          "type": "(MorphShapeName | string)[]",
          "default": "[\"circle\", \"squircle\", \"triangle\", \"diamond\"]",
          "description": "Shapes to travel through. Preset names, or raw d strings authored on a 0–100 box."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the morph starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "90",
          "description": "Frames the whole chain takes, end to end."
        },
        {
          "name": "loop",
          "type": "boolean",
          "default": "false",
          "description": "Returns to the first shape so a looping driver has no seam."
        },
        {
          "name": "size",
          "type": "number",
          "default": "220",
          "description": "Rendered size in pixels."
        },
        {
          "name": "fill",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Shape fill. Pass undefined for an outline only."
        },
        {
          "name": "stroke",
          "type": "string",
          "description": "Outline colour. Omit for a filled shape with no outline."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "3",
          "description": "Outline weight, when stroke is set."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "18",
          "description": "Degrees turned across the chain. Stops a symmetrical pair looking static."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the shape starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        }
      ],
      "usage": "import { ShapeMorph } from \"@/remotion/primitives/shape-morph\";\n\n<ShapeMorph\n  shapes={[\"circle\", \"squircle\", \"triangle\", \"diamond\"]}\n  size={300}\n  durationInFrames={96}\n  exitAtInFrames={92}\n/>",
      "related": [
        "blob-morph",
        "path-draw",
        "svg-mask-reveal"
      ],
      "note": "The chain is prepared once and evaluated per frame: preparation (parsing, winding alignment, box fitting) depends only on the d strings, so doing it in the render would re-parse every path 30 times a second. Steps inside the chain are linear on purpose: easing each hop puts a stall at every shape, which reads as a slideshow. Shapes morph cleanly when they reduce to a similar curve count; the presets are all four-curve closed paths.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "blob-morph",
      "type": "registry:ui",
      "description": "Organic blob continuously morphing",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "path-morph"
      ],
      "installCommand": "npx remotion-ui@latest add blob-morph",
      "docsUrl": "https://remotionui.com/docs/components/blob-morph",
      "registryUrl": "https://remotionui.com/r/presets/default/blob-morph.json",
      "detailUrl": "https://remotionui.com/ai/components/blob-morph.json",
      "importPath": "@/remotion/primitives/blob-morph",
      "installTarget": "src/remotion/primitives/blob-morph",
      "category": "primitive",
      "props": [
        {
          "name": "size",
          "type": "number",
          "default": "260",
          "description": "Rendered size in pixels."
        },
        {
          "name": "fill",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Blob fill. Pass undefined for an outline only."
        },
        {
          "name": "stroke",
          "type": "string",
          "description": "Outline colour. Omit for a filled blob."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "3",
          "description": "Outline weight, when stroke is set."
        },
        {
          "name": "periodInFrames",
          "type": "number",
          "default": "150",
          "description": "Frames for one full trip around the ring of shapes."
        },
        {
          "name": "states",
          "type": "number",
          "default": "4",
          "description": "How many shapes the loop travels through. Three to six reads as organic."
        },
        {
          "name": "points",
          "type": "number",
          "default": "10",
          "description": "Points around the outline. More points, more detail and more wobble."
        },
        {
          "name": "amplitude",
          "type": "number",
          "default": "0.22",
          "description": "How far the outline deviates from a circle, as a fraction of the radius."
        },
        {
          "name": "seed",
          "type": "number",
          "default": "1",
          "description": "Changes the shape family without changing anything else."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "12",
          "description": "Degrees per period. Continuous, so a seamless loop wants 0 or a multiple of 360."
        }
      ],
      "usage": "import { BlobMorph } from \"@/remotion/primitives/blob-morph\";\n\n<BlobMorph size={320} periodInFrames={96} amplitude={0.22} seed={1} />",
      "related": [
        "shape-morph",
        "aurora-bg",
        "svg-mask-reveal"
      ],
      "note": "Outlines are generated from three sine harmonics seeded by the seed prop: two alone leave a shape that reads as symmetrical. Every variant shares a point count so they reduce to the same curve commands and morph without invented segments. Control arms are computed from the point count, (4/3)·tan(π/2N) of the radius along the neighbours' chord: a guessed constant gives a polygon when short and scalloped bulges when long. No entrance or exit: it is alive from frame 0.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "dashed-path-travel",
      "type": "registry:ui",
      "description": "Narrowed: any element traveling any path with a dashed trail",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens",
        "path-utils"
      ],
      "installCommand": "npx remotion-ui@latest add dashed-path-travel",
      "docsUrl": "https://remotionui.com/docs/components/dashed-path-travel",
      "registryUrl": "https://remotionui.com/r/presets/default/dashed-path-travel.json",
      "detailUrl": "https://remotionui.com/ai/components/dashed-path-travel.json",
      "importPath": "@/remotion/primitives/dashed-path-travel",
      "installTarget": "src/remotion/primitives/dashed-path-travel",
      "category": "primitive",
      "props": [
        {
          "name": "d",
          "type": "string",
          "description": "The route as a path string. Give this or waypoints."
        },
        {
          "name": "waypoints",
          "type": "TravelPoint[]",
          "default": "4 sample points",
          "description": "Points the route passes through, in path units."
        },
        {
          "name": "smoothing",
          "type": "number",
          "default": "0.4",
          "description": "Corner rounding when building from waypoints. 0 gives straight hops."
        },
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What travels the path. Centred on the point; falls back to a dot."
        },
        {
          "name": "dotRadius",
          "type": "number",
          "default": "7",
          "description": "Radius of the default dot, used when no children are given."
        },
        {
          "name": "orient",
          "type": "boolean",
          "default": "false",
          "description": "Turns the traveller to the path's tangent."
        },
        {
          "name": "width",
          "type": "number",
          "default": "320",
          "description": "Box width in pixels."
        },
        {
          "name": "height",
          "type": "number",
          "default": "200",
          "description": "Box height in pixels."
        },
        {
          "name": "viewBox",
          "type": "string",
          "description": "Omit to frame the route automatically from its bounding box."
        },
        {
          "name": "trailColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "The dashed route behind the traveller."
        },
        {
          "name": "trackColor",
          "type": "string",
          "default": "\"rgba(255,255,255,0.12)\"",
          "description": "The route not yet travelled. Omit to hide where this is going."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "2.5",
          "description": "Weight of both the track and the trail."
        },
        {
          "name": "dash",
          "type": "number",
          "default": "9",
          "description": "Dash and gap length, in path units."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before setting off."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "70",
          "description": "Frames the trip takes."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the whole thing starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        }
      ],
      "usage": "import { DashedPathTravel } from \"@/remotion/primitives/dashed-path-travel\";\n\n<DashedPathTravel\n  waypoints={[\n    { x: 20, y: 150 },\n    { x: 90, y: 60 },\n    { x: 280, y: 40 },\n  ]}\n  orient\n  durationInFrames={86}\n  exitAtInFrames={92}\n/>",
      "related": [
        "cursor-path",
        "path-draw",
        "connector-lines"
      ],
      "note": "The trail is a fixed dash pattern revealed by a mask that grows with the head, not a dashed stroke that grows: growing the pattern slides every dash along the route, which reads as a stretching line rather than a road being marked. Position and angle come from arc-length sampling, so the traveller keeps a constant speed around corners. For a cursor with its own hardware shape and click beats, use cursor-path.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "connector-lines",
      "type": "registry:ui",
      "description": "Narrowed: primitive that draws edges between anchored elements",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add connector-lines",
      "docsUrl": "https://remotionui.com/docs/components/connector-lines",
      "registryUrl": "https://remotionui.com/r/presets/default/connector-lines.json",
      "detailUrl": "https://remotionui.com/ai/components/connector-lines.json",
      "importPath": "@/remotion/primitives/connector-lines",
      "installTarget": "src/remotion/primitives/connector-lines",
      "category": "primitive",
      "props": [
        {
          "name": "anchors",
          "type": "ConnectorAnchor[]",
          "default": "4 sample anchors",
          "description": "Named points as fractions of the box, so the same table drives your layout."
        },
        {
          "name": "edges",
          "type": "ConnectorEdge[]",
          "default": "4 sample edges",
          "description": "from / to anchor ids, plus shape, bow, colour and an optional arrival dot."
        },
        {
          "name": "width",
          "type": "number",
          "default": "420",
          "description": "Box width in pixels."
        },
        {
          "name": "height",
          "type": "number",
          "default": "240",
          "description": "Box height in pixels."
        },
        {
          "name": "stroke",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Default edge colour."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": "2",
          "description": "Edge weight."
        },
        {
          "name": "dashed",
          "type": "boolean",
          "default": "false",
          "description": "Dashes every edge: useful when the lines are a relationship rather than a flow. Dashed edges draw on through a mask, with the dashes marching as they go, so they animate exactly like solid ones."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the first edge draws."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "26",
          "description": "Frames one edge takes to draw."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "10",
          "description": "Frames between edges."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the lines start leaving. Omit to leave them on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        }
      ],
      "usage": "import { ConnectorLines } from \"@/remotion/primitives/connector-lines\";\n\n<ConnectorLines\n  anchors={[\n    { id: \"source\", x: 0.12, y: 0.5 },\n    { id: \"parse\", x: 0.44, y: 0.18 },\n    { id: \"output\", x: 0.86, y: 0.5 },\n  ]}\n  edges={[\n    { from: \"source\", to: \"parse\", shape: \"curve\", bow: 0.12, dot: true },\n    { from: \"parse\", to: \"output\", shape: \"curve\", bow: 0.12, dot: true },\n  ]}\n/>",
      "related": [
        "data-flow-pipes",
        "org-chart-build",
        "dashed-path-travel"
      ],
      "note": "This is the primitive under a diagram, not the diagram: position your own nodes at the same fractional anchors and the lines stay in register at any size. Each edge draws on its own pathLength={1}, so a long curve and a short hop take the same time. An edge naming a missing anchor is dropped rather than drawn to the origin. For a full scene with payloads travelling the edges, use data-flow-pipes.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "svg-mask-reveal",
      "type": "registry:ui",
      "description": "Arbitrary SVG shape as a reveal mask",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "vectors",
        "drive": "time",
        "tier": "core"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens",
        "path-morph"
      ],
      "installCommand": "npx remotion-ui@latest add svg-mask-reveal",
      "docsUrl": "https://remotionui.com/docs/components/svg-mask-reveal",
      "registryUrl": "https://remotionui.com/r/presets/default/svg-mask-reveal.json",
      "detailUrl": "https://remotionui.com/ai/components/svg-mask-reveal.json",
      "importPath": "@/remotion/primitives/svg-mask-reveal",
      "installTarget": "src/remotion/primitives/svg-mask-reveal",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "What the mask reveals: media, a scene, a gradient, another component."
        },
        {
          "name": "shape",
          "type": "MorphShapeName | string",
          "default": "\"circle\"",
          "description": "Mask shape: a preset name, or any d string authored on a 0–100 box."
        },
        {
          "name": "origin",
          "type": "{ x: number; y: number }",
          "default": "{ x: 0.5, y: 0.5 }",
          "description": "Where the shape opens from, as a fraction of the frame."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before the reveal starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "40",
          "description": "Frames the reveal takes."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "0",
          "description": "Degrees the shape turns as it opens."
        },
        {
          "name": "bouncy",
          "type": "boolean",
          "default": "false",
          "description": "Springs the growth instead of easing it."
        },
        {
          "name": "invert",
          "type": "boolean",
          "default": "false",
          "description": "Shrinks the shape back over the content, to close a scene with the figure that opened it."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "description": "Painted behind the masked content. Omit for transparency."
        }
      ],
      "usage": "import { SvgMaskReveal } from \"@/remotion/primitives/svg-mask-reveal\";\n\n<SvgMaskReveal\n  shape=\"squircle\"\n  origin={{ x: 0.32, y: 0.36 }}\n  durationInFrames={90}\n  rotation={40}\n>\n  <YourContent />\n</SvgMaskReveal>",
      "related": [
        "shape-morph",
        "blob-morph",
        "directional-wipe"
      ],
      "note": "The scale is computed from the distance to the furthest corner, not from the frame width: a shape opening from a corner has much further to travel, and a fixed multiplier either leaves a gap or spends half the animation doing nothing. It uses an SVG <mask> rather than a CSS clip-path, so any authored path drops in and the shape can carry soft edges. Custom paths must be authored on a 0–100 box, which is what the scale maths assumes.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "map-heat-overlay",
      "type": "registry:ui",
      "description": "Density overlay fading in over the basemap",
      "tasks": [
        "maps"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "map-utils",
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add map-heat-overlay",
      "docsUrl": "https://remotionui.com/docs/components/map-heat-overlay",
      "registryUrl": "https://remotionui.com/r/presets/default/map-heat-overlay.json",
      "detailUrl": "https://remotionui.com/ai/components/map-heat-overlay.json",
      "importPath": "@/remotion/primitives/map-heat-overlay",
      "installTarget": "src/remotion/primitives/map-heat-overlay",
      "category": "primitive",
      "props": [
        {
          "name": "map",
          "type": "Map | null",
          "description": "The map to paint on, from MapCanvas's onMapReady."
        },
        {
          "name": "points",
          "type": "FeatureCollection<Point>",
          "description": "Points to weigh."
        },
        {
          "name": "weightProperty",
          "type": "string",
          "default": "\"weight\"",
          "description": "Feature property holding each point's weight."
        },
        {
          "name": "radius",
          "type": "number",
          "default": "18",
          "description": "Kernel radius in screen pixels at radiusZoom. Roughly 12–24 for a few hundred points."
        },
        {
          "name": "radiusZoom",
          "type": "number",
          "default": "3",
          "description": "The zoom the radius is authored at; it ramps from there."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "0.85",
          "description": "Peak opacity once the overlay has faded up."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "5-stop cool-to-hot ramp",
          "description": "Density ramp, low first. The first stop must be transparent."
        },
        {
          "name": "beforeLayerId",
          "type": "string",
          "description": "Layer to sit under, so place labels stay legible through the heat."
        },
        {
          "name": "sourceId",
          "type": "string",
          "default": "\"heat-points\"",
          "description": "Source and layer id prefix, for more than one overlay on a map."
        },
        {
          "name": "revealProgress",
          "type": "number",
          "description": "Drive the fade yourself, 0–1. Omit for the built-in frame ramp."
        }
      ],
      "usage": "import { MapCanvas } from \"@/remotion/primitives/map-canvas\";\nimport { MapHeatOverlay } from \"@/remotion/primitives/map-heat-overlay\";\n\nconst [map, setMap] = useState<Map | null>(null);\n\n<AbsoluteFill>\n  <MapCanvas center={[2.2, 49.6]} zoom={4} onMapReady={setMap} />\n  <MapHeatOverlay map={map} points={points} radius={18} />\n</AbsoluteFill>",
      "related": [
        "map-canvas",
        "map-markers",
        "heatmap-grid"
      ],
      "note": "The paint holds the frame open with its own delayRender: layers are added a commit after the map reports ready, and without the hold the overlay drops out of the first captured frame and the still shows a bare basemap. Intensity climbs with the fade so hot cores arrive last. The first colour stop must be transparent: a heatmap ramp paints across the whole layer, so an opaque density-zero colour floods the viewport.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "globe-arc",
      "type": "registry:ui",
      "description": "Arcs between points on a globe",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add globe-arc",
      "docsUrl": "https://remotionui.com/docs/components/globe-arc",
      "registryUrl": "https://remotionui.com/r/presets/default/globe-arc.json",
      "detailUrl": "https://remotionui.com/ai/components/globe-arc.json",
      "importPath": "@/remotion/primitives/globe-arc",
      "installTarget": "src/remotion/primitives/globe-arc",
      "category": "primitive",
      "props": [
        {
          "name": "routes",
          "type": "GlobeArcRoute[]",
          "default": "4 sample routes",
          "description": "from / to coordinates with optional labels, colour and its own delay."
        },
        {
          "name": "size",
          "type": "number",
          "default": "420",
          "description": "Rendered size in pixels."
        },
        {
          "name": "spinPerSecond",
          "type": "number",
          "default": "14",
          "description": "Degrees of longitude turned per second. Above ~20 it reads as a loading spinner."
        },
        {
          "name": "startLongitude",
          "type": "number",
          "default": "-40",
          "description": "Longitude facing the viewer at frame 0."
        },
        {
          "name": "tilt",
          "type": "number",
          "default": "18",
          "description": "Camera latitude. Positive tilts the north pole toward you."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "6",
          "description": "Frames to wait before the first arc draws."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "34",
          "description": "Frames one arc takes to draw."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames between arcs, when a route sets no delay of its own."
        },
        {
          "name": "sphereColor",
          "type": "string",
          "default": "\"#0E1524\"",
          "description": "Fill of the globe itself."
        },
        {
          "name": "graticuleColor",
          "type": "string",
          "default": "\"rgba(125,211,232,0.22)\"",
          "description": "Meridians, parallels and the limb."
        },
        {
          "name": "arcColor",
          "type": "string",
          "default": "\"#E8B86D\"",
          "description": "Default route colour."
        },
        {
          "name": "cityColor",
          "type": "string",
          "default": "\"#7DD3E8\"",
          "description": "City dots and labels."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the globe starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        }
      ],
      "usage": "import { GlobeArc } from \"@/remotion/primitives/globe-arc\";\n\n<GlobeArc\n  size={380}\n  routes={[\n    { from: { lng: -74, lat: 40.7, label: \"NYC\" }, to: { lng: -0.1, lat: 51.5, label: \"London\" } },\n  ]}\n/>",
      "related": [
        "map-flight",
        "map-route",
        "connector-lines"
      ],
      "note": "Projected arithmetically rather than drawn from tiles, so there is no network dependency and no delayRender: every frame is a pure function of its number. Arcs are great circles clipped to the front hemisphere: without the visibility test, far-side points project onto the near side and routes fold across the disc, which is what makes a hand-rolled globe look wrong. For real coastlines and place names, use map-flight.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "multi-device-lineup",
      "type": "registry:ui",
      "description": "Phone + tablet + laptop showing one responsive design",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "spatial",
        "drive": "spatial",
        "tier": "advanced"
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "motion-tokens"
      ],
      "installCommand": "npx remotion-ui@latest add multi-device-lineup",
      "docsUrl": "https://remotionui.com/docs/components/multi-device-lineup",
      "registryUrl": "https://remotionui.com/r/presets/default/multi-device-lineup.json",
      "detailUrl": "https://remotionui.com/ai/components/multi-device-lineup.json",
      "importPath": "@/remotion/primitives/multi-device-lineup",
      "installTarget": "src/remotion/primitives/multi-device-lineup",
      "category": "primitive",
      "props": [
        {
          "name": "children",
          "type": "ReactNode",
          "description": "Rendered inside every device that has no content of its own: one responsive design at three widths."
        },
        {
          "name": "phone",
          "type": "LineupScreen",
          "description": "Optional content and caption for the phone."
        },
        {
          "name": "tablet",
          "type": "LineupScreen",
          "description": "Optional content and caption for the tablet."
        },
        {
          "name": "laptop",
          "type": "LineupScreen",
          "description": "Optional content and caption for the laptop."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "1",
          "description": "Overall size of the lineup. The first prop to reach for when it is wider than the frame."
        },
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "4",
          "description": "Frame the first device arrives."
        },
        {
          "name": "staggerInFrames",
          "type": "number",
          "default": "9",
          "description": "Frames between devices."
        },
        {
          "name": "exitAtInFrames",
          "type": "number",
          "description": "Frame the lineup starts leaving. Omit to leave it on screen."
        },
        {
          "name": "exitInFrames",
          "type": "number",
          "default": "16",
          "description": "Frames the exit takes."
        },
        {
          "name": "bezelColor",
          "type": "string",
          "default": "\"#15171D\"",
          "description": "Device body."
        },
        {
          "name": "screenColor",
          "type": "string",
          "default": "\"#0B0C11\"",
          "description": "Screen behind your content."
        },
        {
          "name": "labelColor",
          "type": "string",
          "default": "\"#7A828F\"",
          "description": "Captions under the devices."
        }
      ],
      "usage": "import { MultiDeviceLineup } from \"@/remotion/primitives/multi-device-lineup\";\n\n<MultiDeviceLineup\n  scale={0.72}\n  phone={{ label: \"Phone\" }}\n  tablet={{ label: \"Tablet\" }}\n  laptop={{ label: \"Laptop\" }}\n>\n  <YourResponsiveScreen />\n</MultiDeviceLineup>",
      "related": [
        "device-mockup-zoom",
        "tab-switch-panel",
        "notification-stack"
      ],
      "note": "Each screen is a real element at that device's own pixel size, not one screenshot scaled three ways: pass the same children and a responsive layout lays itself out per width, which is the only reason to show three devices. Devices land smallest first so the laptop arrives onto a lineup that already exists. Hardware ratios are the real ones, and the laptop's base and hinge are drawn as their own strip. For one device with a camera move into the screen, use device-mockup-zoom.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "device-mockup-3d",
      "type": "registry:block",
      "description": "Laptop product shot in real 3D: lid opens, then a turn and push-in over a lit floor",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "3d",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "device",
          "new"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/three",
        "three",
        "@react-three/fiber",
        "@react-three/drei"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add device-mockup-3d",
      "docsUrl": "https://remotionui.com/docs/components/device-mockup-3d",
      "registryUrl": "https://remotionui.com/r/presets/default/device-mockup-3d.json",
      "detailUrl": "https://remotionui.com/ai/components/device-mockup-3d.json",
      "importPath": "@/remotion/scenes/device-mockup-3d",
      "installTarget": "src/remotion/scenes/device-mockup-3d",
      "category": "scene",
      "props": [
        {
          "name": "src",
          "type": "string",
          "default": "hosted demo screenshot",
          "description": "Screenshot on the screen. A bright UI reads best; a mostly black image reads as a slab."
        },
        {
          "name": "screenAspect",
          "type": "number",
          "description": "Screen width / height. Omit to use the image's own ratio."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#0a0c11\"",
          "description": "Outer backdrop."
        },
        {
          "name": "glowColor",
          "type": "string",
          "default": "\"#1c212c\"",
          "description": "Soft glow behind the device."
        },
        {
          "name": "floorColor",
          "type": "string",
          "default": "\"#434a57\"",
          "description": "Lit floor pool the contact shadow falls on. Keep it lighter than the backdrop."
        },
        {
          "name": "bodyColor",
          "type": "string",
          "default": "\"#9ba1ab\"",
          "description": "Aluminium body."
        },
        {
          "name": "rimColor",
          "type": "string",
          "default": "\"#7aa2ff\"",
          "description": "Cool rim light from the left."
        },
        {
          "name": "accentColor",
          "type": "string",
          "default": "\"#ffb27a\"",
          "description": "Warm accent light from the right."
        },
        {
          "name": "glare",
          "type": "number",
          "default": "1",
          "description": "Strength of the glass reflection over the screen, 0–1."
        }
      ],
      "usage": "import { staticFile } from \"remotion\";\nimport { DeviceMockup3D } from \"@/remotion/scenes/device-mockup-3d\";\n\n// Render with --gl=angle\n<DeviceMockup3D src={staticFile(\"app.png\")} />",
      "related": [
        "device-mockup-zoom",
        "multi-device-lineup"
      ],
      "note": "A lit WebGL scene on @remotion/three; render with --gl=angle. The shot paces itself to the composition length: the laptop settles as the lid opens, then turns and pushes in, with a slow drift under both so the last frame never parks. Deterministic by construction: motion comes only from useCurrentFrame(), the screen image loads behind delayRender, and the environment is built from Lightformers instead of a CDN HDRI. For a CSS mockup with staged UI and no WebGL, use device-mockup-zoom.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "paper-shader",
      "type": "registry:lib",
      "description": "Deterministic frame driver and first-draw gate for Paper shader fields",
      "tasks": [
        "motion-primitives"
      ],
      "dependencies": [
        "remotion",
        "@paper-design/shaders-react"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add paper-shader",
      "docsUrl": "https://remotionui.com/docs/components/paper-shader",
      "registryUrl": "https://remotionui.com/r/presets/default/paper-shader.json",
      "detailUrl": "https://remotionui.com/ai/components/paper-shader.json",
      "importPath": "@/remotion/lib/paper-shader",
      "installTarget": "src/remotion/lib/paper-shader",
      "category": "utility",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "light-tunnel-bg",
      "type": "registry:ui",
      "description": "Flight down a twisting barrel of light with a defocused vanishing point",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "shaders",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "gpu"
      ],
      "installCommand": "npx remotion-ui@latest add light-tunnel-bg",
      "docsUrl": "https://remotionui.com/docs/components/light-tunnel-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/light-tunnel-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/light-tunnel-bg.json",
      "importPath": "@/remotion/primitives/light-tunnel-bg",
      "installTarget": "src/remotion/primitives/light-tunnel-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Plate behind the tunnel, and the colour the far centre falls off to."
        },
        {
          "name": "colors",
          "type": "[string, string, string]",
          "default": "[\"#e4ac59\", \"#e07a5f\", \"#c2557a\"]",
          "description": "Three ribbon tints, distributed around the barrel by ribbon index."
        },
        {
          "name": "ribbons",
          "type": "number",
          "default": "12",
          "description": "How many ribbons run down the barrel. Rounded to an integer: a fractional count leaves a seam where the angle wraps."
        },
        {
          "name": "twist",
          "type": "number",
          "default": "0.22",
          "description": "How hard the barrel twists with depth. 0 gives straight ribbons."
        },
        {
          "name": "ringDensity",
          "type": "number",
          "default": "3.2",
          "description": "Rings per unit of log-depth. Higher packs the folds tighter."
        },
        {
          "name": "defocus",
          "type": "number",
          "default": "0.035",
          "description": "Radius of the centre defocus, in frame heights. 0 leaves the vanishing point sharp."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "1",
          "description": "Overall brightness."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Flight speed down the barrel. 0 freezes the tunnel."
        }
      ],
      "usage": "import { LightTunnelBg } from \"@/remotion/primitives/light-tunnel-bg\";\n\n// Render with --gl=angle\n<LightTunnelBg ribbons={14} twist={0.16} />",
      "related": [
        "mesh-gradient-bg",
        "warp-bands-bg",
        "light-rays"
      ],
      "note": "Depth comes from the reciprocal radius and the angle from atan plus a depth-coupled twist, so this is the one background in the lane with a vanishing point. Two details carry it: rings are spaced evenly in log(r) rather than r, which keeps the folds the same apparent width all the way in instead of bunching at the centre; and the singularity at r=0 is resolved by a nine-tap Gaussian defocus that grows as the wall recedes, rather than by clamping the radius, which leaves a flat disc with a hard rim in the vanishing point. Hue is keyed to the ribbon index rather than the clock, so a ribbon keeps its colour instead of the barrel cycling. Render with --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-reveal-shader",
      "type": "registry:ui",
      "description": "Words condensing out of light into liquid chrome",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "shaders",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "text"
        ]
      },
      "dependencies": [
        "remotion"
      ],
      "registryDependencies": [
        "gpu"
      ],
      "installCommand": "npx remotion-ui@latest add text-reveal-shader",
      "docsUrl": "https://remotionui.com/docs/components/text-reveal-shader",
      "registryUrl": "https://remotionui.com/r/presets/default/text-reveal-shader.json",
      "detailUrl": "https://remotionui.com/ai/components/text-reveal-shader.json",
      "importPath": "@/remotion/primitives/text-reveal-shader",
      "installTarget": "src/remotion/primitives/text-reveal-shader",
      "category": "primitive",
      "props": [
        {
          "name": "text",
          "type": "string",
          "default": "\"LIQUID\\nCHROME\"",
          "description": "Copy to reveal. Newlines start a new line; the block stays centred."
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Plate behind the words."
        },
        {
          "name": "colors",
          "type": "[string, string]",
          "default": "[\"#e4ac59\", \"#f0abc0\"]",
          "description": "The two ends of the iridescent film the words condense out of."
        },
        {
          "name": "silverColor",
          "type": "string",
          "default": "\"#ded8cf\"",
          "description": "Colour the glyph interior settles to once the edge has passed."
        },
        {
          "name": "angle",
          "type": "number",
          "default": "34",
          "description": "Direction of the sweep, in degrees. 0 sweeps left to right."
        },
        {
          "name": "delay",
          "type": "number",
          "default": "0",
          "description": "Frame the reveal starts on."
        },
        {
          "name": "duration",
          "type": "number",
          "default": "78",
          "description": "How many frames the sweep takes to cross the frame."
        },
        {
          "name": "wobble",
          "type": "number",
          "default": "0.06",
          "description": "How far the two crossed sines bend the edge. 0 gives a straight wipe."
        },
        {
          "name": "bandWidth",
          "type": "number",
          "default": "0.022",
          "description": "Width of the refracting band at the edge, in frame widths. Wider becomes a general blur; narrower reads as a clean chromatic rim."
        },
        {
          "name": "refraction",
          "type": "number",
          "default": "0.055",
          "description": "How far the band displaces the glyph."
        },
        {
          "name": "settle",
          "type": "number",
          "default": "0.16",
          "description": "How long after the edge the interior takes to settle to flat silver."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "170",
          "description": "Type size in px, measured against the composition height."
        },
        {
          "name": "fontWeight",
          "type": "number",
          "default": "800",
          "description": "Weight passed to the canvas rasteriser."
        },
        {
          "name": "fontFamily",
          "type": "string",
          "default": "\"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\"",
          "description": "Worth pinning explicitly: the glyphs become a texture, so an unpinned stack resolves differently on a dev box and a render worker."
        },
        {
          "name": "letterSpacing",
          "type": "number",
          "default": "4",
          "description": "Extra tracking in px."
        },
        {
          "name": "lineHeight",
          "type": "number",
          "default": "1.02",
          "description": "Line height as a multiple of the type size."
        }
      ],
      "usage": "import { TextRevealShader } from \"@/remotion/primitives/text-reveal-shader\";\n\n// Render with --gl=angle\n<TextRevealShader text={\"LIQUID\\nCHROME\"} bandWidth={0.022} settle={0.16} />",
      "related": [
        "masked-slide-reveal",
        "light-sweep-text",
        "grain-gradient-bg"
      ],
      "note": "The type is rasterised once to an alpha texture and handed to a fragment shader as its source, which is what buys the refraction: a CSS or SVG mask can uncover letterforms but cannot bend them through a moving film, having no access to the pixels either side of its edge. The reveal threshold is perturbed by two crossed sines at unrelated periods so the edge reads as a wet meniscus rather than a wipe. bandWidth and settle are where the taste lives. Distinct from masked-slide-reveal (hard-edged mask over type) and light-sweep-text (specular pass over already-visible glyphs). Render with --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "dither-field-bg",
      "type": "registry:ui",
      "description": "Two-colour ordered-dither field quantised to a pixel grid",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "shaders",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion",
        "@paper-design/shaders-react"
      ],
      "registryDependencies": [
        "paper-shader"
      ],
      "installCommand": "npx remotion-ui@latest add dither-field-bg",
      "docsUrl": "https://remotionui.com/docs/components/dither-field-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/dither-field-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/dither-field-bg.json",
      "importPath": "@/remotion/primitives/dither-field-bg",
      "installTarget": "src/remotion/primitives/dither-field-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#070605\"",
          "description": "The unlit half of the two-tone field."
        },
        {
          "name": "inkColor",
          "type": "string",
          "default": "\"#e4ac59\"",
          "description": "The lit half. The field only ever holds these two colors."
        },
        {
          "name": "shape",
          "type": "\"simplex\" | \"warp\" | \"dots\" | \"wave\" | \"ripple\" | \"swirl\" | \"sphere\"",
          "default": "\"warp\"",
          "description": "Pattern the dither is sampled from before the grid quantises it. simplex, warp, dots and wave fill the frame; ripple, swirl and sphere are bounded shapes."
        },
        {
          "name": "pattern",
          "type": "\"random\" | \"2x2\" | \"4x4\" | \"8x8\"",
          "default": "\"4x4\"",
          "description": "Threshold matrix. Bayer sizes are ordered; random reads as film grain."
        },
        {
          "name": "pixelSize",
          "type": "number",
          "default": "2",
          "description": "Size of one dither cell in pixels, 0.5–20. Larger reads more retro."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "1",
          "description": "Zoom on the underlying pattern, 0.01–4. Below 1 a bounded shape stops covering the frame."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Multiplies how far the field travels per second."
        }
      ],
      "usage": "import { DitherFieldBg } from \"@/remotion/primitives/dither-field-bg\";\n\n// Render with --gl=angle\n<DitherFieldBg shape=\"warp\" pattern=\"4x4\" />",
      "related": [
        "grain-gradient-bg",
        "warp-bands-bg",
        "animated-noise-grain"
      ],
      "note": "The dither grid is measured in real pixels and ignores scale, so zooming moves the pattern underneath a grid that stays put. Deterministic by construction: the shader library's own requestAnimationFrame clock is switched off and the time is set from useCurrentFrame(). Render with --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "warp-bands-bg",
      "type": "registry:ui",
      "description": "Colour bands folded through noise and a swirl",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "shaders",
        "drive": "time",
        "tier": "core",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion",
        "@paper-design/shaders-react"
      ],
      "registryDependencies": [
        "paper-shader"
      ],
      "installCommand": "npx remotion-ui@latest add warp-bands-bg",
      "docsUrl": "https://remotionui.com/docs/components/warp-bands-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/warp-bands-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/warp-bands-bg.json",
      "importPath": "@/remotion/primitives/warp-bands-bg",
      "installTarget": "src/remotion/primitives/warp-bands-bg",
      "category": "primitive",
      "props": [
        {
          "name": "colors",
          "type": "string[]",
          "default": "[\"#0b0a08\", \"#e4ac59\", \"#0b0a08\", \"#c2557a\"]",
          "description": "Up to 10 colors, blended in order. Keep a dark one to hold the bands apart."
        },
        {
          "name": "pattern",
          "type": "\"checks\" | \"stripes\" | \"edge\"",
          "default": "\"checks\"",
          "description": "Base pattern the bands are laid over before distortion."
        },
        {
          "name": "proportion",
          "type": "number",
          "default": "0.45",
          "description": "Where one color gives way to the next, 0–1."
        },
        {
          "name": "softness",
          "type": "number",
          "default": "1",
          "description": "Edge hardness, 0 = hard band, 1 = full gradient. Changes its character most."
        },
        {
          "name": "distortion",
          "type": "number",
          "default": "0.25",
          "description": "Noise distortion across the bands, 0–1."
        },
        {
          "name": "swirl",
          "type": "number",
          "default": "0.8",
          "description": "Swirl strength, 0–1. This is what makes the bands read as marble."
        },
        {
          "name": "swirlIterations",
          "type": "number",
          "default": "10",
          "description": "Layered swirl passes, 0–20. More passes, more folding."
        },
        {
          "name": "patternScale",
          "type": "number",
          "default": "0.1",
          "description": "Zoom on the base pattern, 0–1."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "1",
          "description": "Overall zoom, 0.01–4."
        },
        {
          "name": "rotation",
          "type": "number",
          "default": "0",
          "description": "Rotation of the whole field in degrees."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Multiplies how far the field travels per second."
        }
      ],
      "usage": "import { WarpBandsBg } from \"@/remotion/primitives/warp-bands-bg\";\n\n// Render with --gl=angle\n<WarpBandsBg softness={1} swirl={0.8} />",
      "related": [
        "grain-gradient-bg",
        "dither-field-bg",
        "mesh-gradient-bg"
      ],
      "note": "No entrance and no loop point: the same motion at every point in the composition, so any window shows it. Deterministic by construction: the library's wall clock is switched off and the time is set from useCurrentFrame(). Render with --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "grain-gradient-bg",
      "type": "registry:ui",
      "description": "Multi-colour gradient with grain worked through it",
      "tasks": [
        "motion-primitives"
      ],
      "atlas": {
        "lane": "shaders",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "background"
        ]
      },
      "dependencies": [
        "remotion",
        "@paper-design/shaders-react"
      ],
      "registryDependencies": [
        "paper-shader"
      ],
      "installCommand": "npx remotion-ui@latest add grain-gradient-bg",
      "docsUrl": "https://remotionui.com/docs/components/grain-gradient-bg",
      "registryUrl": "https://remotionui.com/r/presets/default/grain-gradient-bg.json",
      "detailUrl": "https://remotionui.com/ai/components/grain-gradient-bg.json",
      "importPath": "@/remotion/primitives/grain-gradient-bg",
      "installTarget": "src/remotion/primitives/grain-gradient-bg",
      "category": "primitive",
      "props": [
        {
          "name": "backgroundColor",
          "type": "string",
          "default": "\"#050505\"",
          "description": "Stage the shape sits on."
        },
        {
          "name": "colors",
          "type": "string[]",
          "default": "[\"#e4ac59\", \"#e07a5f\", \"#f0c98a\"]",
          "description": "Up to 7 colors, blended across the shape."
        },
        {
          "name": "shape",
          "type": "\"wave\" | \"dots\" | \"truchet\" | \"corners\" | \"ripple\" | \"blob\" | \"sphere\"",
          "default": "\"wave\"",
          "description": "The form the gradient takes. Each is a different field, not a preset."
        },
        {
          "name": "softness",
          "type": "number",
          "default": "0.6",
          "description": "Edge hardness between colors, 0 = posterised, 1 = smooth."
        },
        {
          "name": "intensity",
          "type": "number",
          "default": "0.45",
          "description": "Distortion between the color bands, 0–1."
        },
        {
          "name": "noise",
          "type": "number",
          "default": "0.35",
          "description": "Grain overlay, 0–1. Measured in real pixels, so it ignores scale."
        },
        {
          "name": "scale",
          "type": "number",
          "default": "1",
          "description": "Overall zoom, 0.01–4."
        },
        {
          "name": "speed",
          "type": "number",
          "default": "1",
          "description": "Multiplies how far the field travels per second."
        }
      ],
      "usage": "import { GrainGradientBg } from \"@/remotion/primitives/grain-gradient-bg\";\n\n// Render with --gl=angle\n<GrainGradientBg shape=\"wave\" noise={0.35} />",
      "related": [
        "mesh-gradient-bg",
        "dither-field-bg",
        "warp-bands-bg"
      ],
      "note": "The grain is the point: a shallow ramp across a wide frame has only ~48 usable 8-bit levels and plateaus into visible bands, and noise is what breaks them up; set noise to 0 and the banding returns. Distinct from mesh-gradient-bg (three drifting blobs) and animated-noise-grain (a grain overlay with no gradient). Render with --gl=angle.",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "product-turntable-3d",
      "type": "registry:block",
      "description": "A product on a studio turntable: the model turns a full revolution under a soft key and rim while the camera holds, with a contact shadow anchoring it to the floor",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "3d",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "new"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/three",
        "three",
        "@react-three/fiber",
        "@react-three/drei"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add product-turntable-3d",
      "docsUrl": "https://remotionui.com/docs/components/product-turntable-3d",
      "registryUrl": "https://remotionui.com/r/presets/default/product-turntable-3d.json",
      "detailUrl": "https://remotionui.com/ai/components/product-turntable-3d.json",
      "importPath": "@/remotion/scenes/product-turntable-3d",
      "installTarget": "src/remotion/scenes/product-turntable-3d",
      "category": "scene",
      "props": [
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before this starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the entrance."
        }
      ],
      "usage": "import { ProductTurntable3d } from \"@/remotion/scenes/product-turntable-3d\";\n\n<ProductTurntable3d />",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "text-extrude-3d",
      "type": "registry:block",
      "description": "Extruded 3D headline with a lit bevel: the letters rise and settle as the camera pulls back across them",
      "tasks": [
        "scenes"
      ],
      "atlas": {
        "lane": "3d",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "new"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/three",
        "three",
        "@react-three/fiber",
        "@react-three/drei"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add text-extrude-3d",
      "docsUrl": "https://remotionui.com/docs/components/text-extrude-3d",
      "registryUrl": "https://remotionui.com/r/presets/default/text-extrude-3d.json",
      "detailUrl": "https://remotionui.com/ai/components/text-extrude-3d.json",
      "importPath": "@/remotion/scenes/text-extrude-3d",
      "installTarget": "src/remotion/scenes/text-extrude-3d",
      "category": "scene",
      "props": [
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before this starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the entrance."
        }
      ],
      "usage": "import { TextExtrude3d } from \"@/remotion/scenes/text-extrude-3d\";\n\n<TextExtrude3d />",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "card-stack-3d",
      "type": "registry:block",
      "description": "A stack of physical cards fanning out in depth, each with real thickness and an edge highlight, turning to face the camera",
      "tasks": [
        "scene-overlays",
        "scenes"
      ],
      "atlas": {
        "lane": "3d",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "new"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/three",
        "three",
        "@react-three/fiber",
        "@react-three/drei"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add card-stack-3d",
      "docsUrl": "https://remotionui.com/docs/components/card-stack-3d",
      "registryUrl": "https://remotionui.com/r/presets/default/card-stack-3d.json",
      "detailUrl": "https://remotionui.com/ai/components/card-stack-3d.json",
      "importPath": "@/remotion/scenes/card-stack-3d",
      "installTarget": "src/remotion/scenes/card-stack-3d",
      "category": "scene",
      "props": [
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before this starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the entrance."
        }
      ],
      "usage": "import { CardStack3d } from \"@/remotion/scenes/card-stack-3d\";\n\n<CardStack3d />",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    },
    {
      "name": "globe-points-3d",
      "type": "registry:block",
      "description": "Lit sphere with instanced city markers and arcs rising between them, turning slowly under a rim light",
      "tasks": [
        "maps",
        "scenes"
      ],
      "atlas": {
        "lane": "3d",
        "drive": "time",
        "tier": "advanced",
        "tags": [
          "new"
        ]
      },
      "dependencies": [
        "remotion",
        "@remotion/three",
        "three",
        "@react-three/fiber",
        "@react-three/drei"
      ],
      "registryDependencies": [],
      "installCommand": "npx remotion-ui@latest add globe-points-3d",
      "docsUrl": "https://remotionui.com/docs/components/globe-points-3d",
      "registryUrl": "https://remotionui.com/r/presets/default/globe-points-3d.json",
      "detailUrl": "https://remotionui.com/ai/components/globe-points-3d.json",
      "importPath": "@/remotion/scenes/globe-points-3d",
      "installTarget": "src/remotion/scenes/globe-points-3d",
      "category": "scene",
      "props": [
        {
          "name": "delayInFrames",
          "type": "number",
          "default": "0",
          "description": "Frames to wait before this starts."
        },
        {
          "name": "durationInFrames",
          "type": "number",
          "default": "30",
          "description": "Length of the entrance."
        }
      ],
      "usage": "import { GlobePoints3d } from \"@/remotion/scenes/globe-points-3d\";\n\n<GlobePoints3d />",
      "aiRules": [
        "Install with the CLI before importing.",
        "Import from local source paths, not from the remotion-ui npm package.",
        "Customize the copied source file directly when design changes are needed."
      ]
    }
  ]
}