Product launch
A framed source excerpt that reveals line by line.
Customize
import {Scene, Video} from "odori";
import {CodeProof} from "../components/code-proof/code-proof";
<Video>
<Scene id="code-proof" duration="6s">
<CodeProof
code={`export const metadata = defineVideoMetadata({
id: "launch",
title: "Product launch",
duration: "12s",
});`}
language="tsx"
title="videos/launch/video.tsx"
caption="Static metadata, ordinary JSX."
/>
</Scene>
</Video>Installation
pnpm odori add component code-proofnpx odori add component code-proofbunx odori add component code-proofEdit the source in videos/components/code-proof/. Use odori diff to compare upstream changes and odori update to apply updates.
Copy these files into your project
videos/components/code-proof/code-proof.tsx
import {Fill, Easing, interpolate, useBrand, useFrame, useDesignScale} from "odori";
export type CodeProofProps = {
code: string;
language?: string;
title?: string;
/** One-based line numbers to emphasize. Other lines dim. */
focus?: number[];
caption?: string;
};
type Token = {pattern: RegExp; role: "comment" | "keyword" | "string" | "number" | "type" | "punctuation"};
const TOKENS: Token[] = [
{pattern: /(\/\/[^\n]*)/g, role: "comment"},
{pattern: /("[^"]*"|'[^']*'|`[^`]*`)/g, role: "string"},
{
pattern: /\b(import|export|from|const|let|var|return|function|default|await|async|type|interface|new|class)\b/g,
role: "keyword",
},
{pattern: /\b([A-Z][A-Za-z0-9]*)\b/g, role: "type"},
{pattern: /\b(\d+(?:\.\d+)?)\b/g, role: "number"},
];
const PALETTE: Record<Token["role"], string> = {
comment: "#6f6f6f",
keyword: "#c586ff",
string: "#7ee787",
number: "#ffc86b",
type: "#79c0ff",
punctuation: "#8b8b8b",
};
const highlight = (line: string) => {
const marks: Array<{start: number; end: number; color: string}> = [];
for (const token of TOKENS) {
for (const match of line.matchAll(token.pattern)) {
const start = match.index ?? 0;
const end = start + match[0].length;
if (marks.some((mark) => start < mark.end && end > mark.start)) continue;
marks.push({start, end, color: PALETTE[token.role]});
}
}
marks.sort((left, right) => left.start - right.start);
const parts: Array<{text: string; color?: string}> = [];
let cursor = 0;
for (const mark of marks) {
if (mark.start > cursor) parts.push({text: line.slice(cursor, mark.start)});
parts.push({text: line.slice(mark.start, mark.end), color: mark.color});
cursor = mark.end;
}
if (cursor < line.length) parts.push({text: line.slice(cursor)});
return parts;
};
/**
* A source excerpt in a product-grade window. Lines resolve from a small blur
* so the eye lands on the code rather than on the motion.
*/
export const CodeProof = ({code, language = "tsx", title, focus = [], caption}: CodeProofProps) => {
const frame = useFrame();
const brand = useBrand();
const scale = useDesignScale();
const lines = code.replace(/\n+$/, "").split("\n");
const enter = interpolate(frame, [0, 22], [0, 1], {easing: Easing.standard});
return (
<Fill style={{alignItems: "center", gap: 30 * scale, justifyContent: "center", padding: 110 * scale}}>
<div
style={{
background: brand.colors.surface,
border: `1px solid ${brand.colors.border}`,
borderRadius: 16 * scale,
boxShadow: `0 ${30 * scale}px ${90 * scale}px ${brand.colors.shadow}`,
maxWidth: 1440 * scale,
opacity: enter,
overflow: "hidden",
transform: `translateY(${(1 - enter) * 28 * scale}px)`,
width: "100%",
}}
>
<div
style={{
alignItems: "center",
background: "rgba(255,255,255,0.02)",
borderBottom: `1px solid ${brand.colors.border}`,
display: "flex",
gap: 14 * scale,
padding: `${18 * scale}px ${24 * scale}px`,
}}
>
<div style={{display: "flex", gap: 9 * scale}}>
{["#2a2a2a", "#2a2a2a", "#2a2a2a"].map((color, index) => (
<span key={index} style={{background: color, borderRadius: 999, height: 12 * scale, width: 12 * scale}} />
))}
</div>
{title ? (
<span
style={{
color: brand.colors.muted,
fontFamily: brand.typography.mono,
fontSize: 21 * scale,
letterSpacing: "-0.01em",
marginLeft: 8 * scale,
}}
>
{title}
</span>
) : null}
<span
style={{
border: `1px solid ${brand.colors.border}`,
borderRadius: 6 * scale,
color: brand.colors.muted,
fontFamily: brand.typography.mono,
fontSize: 21 * scale,
marginLeft: "auto",
padding: `${4 * scale}px ${12 * scale}px`,
textTransform: "uppercase",
}}
>
{language}
</span>
</div>
<pre
style={{
color: brand.colors.foreground,
fontFamily: brand.typography.mono,
fontSize: 28 * scale,
lineHeight: 1.65,
margin: 0,
padding: `${30 * scale}px ${28 * scale}px`,
}}
>
{lines.map((line, index) => {
const delay = 10 + index * 3;
const appear = interpolate(frame, [delay, delay + 14], [0, 1], {easing: Easing.standard});
const focused = focus.length === 0 || focus.includes(index + 1);
return (
<div
key={`${line}-${index}`}
style={{
display: "flex",
filter: `blur(${(1 - appear) * 6}px)`,
gap: 24 * scale,
opacity: appear * (focused ? 1 : 0.32),
transform: `translateY(${(1 - appear) * 8 * scale}px)`,
}}
>
<span style={{color: "#3a3a3a", minWidth: 32 * scale, textAlign: "right", userSelect: "none"}}>
{index + 1}
</span>
<span style={{whiteSpace: "pre"}}>
{highlight(line).map((part, partIndex) => (
<span key={partIndex} style={{color: part.color}}>
{part.text}
</span>
))}
</span>
</div>
);
})}
</pre>
</div>
{caption ? (
<div
style={{
color: brand.colors.muted,
fontSize: 30 * scale,
letterSpacing: "-0.01em",
opacity: interpolate(frame, [24, 40], [0, 1], {easing: Easing.standard}),
}}
>
{caption}
</div>
) : null}
</Fill>
);
};
videos/components/code-proof/code-proof.preview.tsx
import {defineComponentPreview} from "odori/preview";
import {CodeProof} from "./code-proof";
const SAMPLE = `export const metadata = defineVideoMetadata({
id: "launch",
title: "Product launch",
duration: "12s",
});`;
export default defineComponentPreview({
title: "Code proof",
category: "Developer proof/Code",
description: "A framed source excerpt that reveals line by line.",
component: CodeProof,
canvas: {width: 1920, height: 1080, duration: "5s"},
controls: {
code: {type: "text", defaultValue: SAMPLE, multiline: true},
language: {type: "select", defaultValue: "tsx", options: ["tsx", "ts", "shell", "json"]},
title: {type: "text", defaultValue: "videos/launch/video.tsx"},
caption: {type: "text", defaultValue: "Static metadata, ordinary JSX."},
},
examples: [
{name: "Default", props: {code: SAMPLE, title: "videos/launch/video.tsx"}},
{name: "Focused line", props: {code: SAMPLE, focus: [3]}},
],
});
Add it to a scene
import {Scene, Video} from "odori";
import {CodeProof} from "../components/code-proof/code-proof";
<Video>
<Scene id="code-proof" duration="6s">
<CodeProof
code={`export const metadata = defineVideoMetadata({
id: "launch",
title: "Product launch",
duration: "12s",
});`}
language="tsx"
title="videos/launch/video.tsx"
caption="Static metadata, ordinary JSX."
/>
</Scene>
</Video>Timing contract
Use these durations and content limits when composing a scene. Run odori test to check your video.
- Family
- Developer proof
- Recommended duration
- 180 frames · 6s
- Minimum duration
- 90 frames · 3s
- Entrance
- 18 frames
- Exit
- 12 frames
- Reduced motion
- reveals all lines immediately
- Requires
- mono font
- Content limits
- lines ≤ 14, lineLength ≤ 62
Props
| Prop | Type | Default | Required |
|---|---|---|---|
code | string | — | Yes |
language | string | "tsx" | — |
title | string | — | — |
focusOne-based line numbers to emphasize. Other lines dim. | number[] | [] | — |
caption | string | — | — |
Related components
All componentsCode walkthroughProgressive code reveal with authored focal regions.Dependency graphPackages and modules connected as a readable graph.Diff proofBefore and after source changes with semantic emphasis.File treeProgressive repository navigation with active file state.Log streamPaced runtime logs with levels and bounded scrolling.TerminalA typed command session with deterministic output reveals.