Variants from one file
One cut rendered for many brands or markets: copy, look, colour and logo are schema props, and a variant is defaults with overrides.
What the manifest gives it
The product footage and the logo image are shared; everything that changes is a prop.
What the file shows
- The look is a built-in theme named by the
themeprop, and the brand colour is that theme'sprimary; the headline and the captions use it as$primary, the titles take their fonts from presets (h1,h2). - Titles bind their text to the schema;
src={logo}binds the card's asset. collectModule(file, overrides)renders a variant without touching the file; the tweaks panel edits the same props.- No
<Caption>cues and nosrc: the captions element is a styled placeholder for the voice-over each market records.
The file
tsx
import { z } from "zod";
import { Captions, Clip, Composition, THEME_NAMES, Title, Track } from "@cutcraft/kit";
/**
* One cut, many variants. Everything that changes between a brand, a market
* or an A/B test is a schema prop: the copy, the look, the brand colour, the
* logo asset. The look is a built-in theme and the brand colour its primary,
* so titles and captions take both through tokens. A variant is `defaults`
* with overrides:
*
* resolve(collectModule(file, { headline: "Software pequeño, nube real", theme: "paper", accent: "#ffcc00" }), manifest)
*
* The editor's tweaks panel edits the same props; a change folds into `defaults`.
*/
export const schema = z.object({
headline: z.string().describe("Headline over the opening shot"),
cta: z.string().describe("Closing line"),
theme: z.enum(THEME_NAMES).describe("The look: a built-in theme"),
accent: z.string().describe("Brand colour (the theme's primary)"),
logo: z.string().describe("Logo asset reference"),
});
export const defaults = {
headline: "Small software, real cloud",
cta: "Try it today",
theme: "midnight",
accent: "#ff5a1f",
logo: "asset:logo",
};
export default function Video({ headline, cta, theme, accent, logo }: z.infer<typeof schema>) {
return (
<Composition
fps={30}
width={1920}
height={1080}
theme={{ extends: theme, palette: { primary: accent }, motion: "none" }}
>
<Track id="main" name="Footage">
<Clip id="open" src="asset:product" in="shot:0" out="shot:0.end" fit="cover" />
<Clip id="detail" src="asset:product" in="shot:2" out="shot:2.end" fit="cover" />
<Clip id="card" src={logo} duration={3} fit="contain" transform={{ scale: 0.3 }} />
</Track>
<Track id="copy" name="Copy">
<Title
id="headline"
anchor="open"
offset={0.4}
duration={4}
style="h1"
size={104}
color="$primary"
animation={{ preset: "slide-up", in: 0.4, out: 0.3 }}
>
{headline}
</Title>
<Title
id="cta"
anchor="card"
offset={0.3}
duration={2.5}
style="h2"
weight={500}
valign="bottom"
transform={{ position: { x: 0, y: -160 } }}
animation={{ preset: "fade", in: 0.3, out: 0.3 }}
>
{cta}
</Title>
</Track>
<Captions id="captions" style={{ position: "bottom", size: 40, highlight: "$primary" }} />
</Composition>
);
}What the editor can do
- Every tweak folds into
defaults, so the file stays one source for all variants. - Everything else (timing, shots) is shared and edited once.
What to check
- No lint warnings expected.
captureSheet([0.8, 7, 12.5])per variant: the headline in the brand colour and the theme's heading font, the detail shot, the card.