@contractspec/lib.video-gen 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/browser/compositions/api-overview.js +645 -0
  2. package/dist/browser/compositions/index.js +1133 -0
  3. package/dist/browser/compositions/primitives/animated-text.js +144 -0
  4. package/dist/browser/compositions/primitives/brand-frame.js +181 -0
  5. package/dist/browser/compositions/primitives/code-block.js +226 -0
  6. package/dist/browser/compositions/primitives/index.js +656 -0
  7. package/dist/browser/compositions/primitives/progress-bar.js +59 -0
  8. package/dist/browser/compositions/primitives/terminal.js +265 -0
  9. package/dist/browser/compositions/primitives/transition.js +98 -0
  10. package/dist/browser/compositions/social-clip.js +500 -0
  11. package/dist/browser/compositions/terminal-demo.js +558 -0
  12. package/dist/browser/design/index.js +155 -0
  13. package/dist/browser/design/layouts.js +50 -0
  14. package/dist/browser/design/motion.js +43 -0
  15. package/dist/browser/design/tokens.js +28 -0
  16. package/dist/browser/design/typography.js +61 -0
  17. package/dist/browser/docs/compositions.docblock.js +182 -0
  18. package/dist/browser/docs/design.docblock.js +187 -0
  19. package/dist/browser/docs/generators.docblock.js +187 -0
  20. package/dist/browser/docs/rendering.docblock.js +197 -0
  21. package/dist/browser/docs/video-gen.docblock.js +141 -0
  22. package/dist/browser/generators/index.js +416 -0
  23. package/dist/browser/generators/scene-planner.js +205 -0
  24. package/dist/browser/generators/script-generator.js +147 -0
  25. package/dist/browser/generators/video-generator.js +414 -0
  26. package/dist/browser/index.js +1550 -0
  27. package/dist/browser/player/demo-player.js +1136 -0
  28. package/dist/browser/player/index.js +1136 -0
  29. package/dist/browser/remotion/Root.js +1189 -0
  30. package/dist/browser/remotion/index.js +1190 -0
  31. package/dist/browser/renderers/config.js +40 -0
  32. package/dist/browser/renderers/index.js +160 -0
  33. package/dist/browser/renderers/local.js +156 -0
  34. package/dist/browser/types.js +13 -0
  35. package/dist/compositions/api-overview.d.ts +16 -0
  36. package/dist/compositions/api-overview.js +640 -0
  37. package/dist/compositions/index.d.ts +7 -0
  38. package/dist/compositions/index.js +1128 -0
  39. package/dist/compositions/primitives/animated-text.d.ts +22 -0
  40. package/dist/compositions/primitives/animated-text.js +139 -0
  41. package/dist/compositions/primitives/brand-frame.d.ts +14 -0
  42. package/dist/compositions/primitives/brand-frame.js +176 -0
  43. package/dist/compositions/primitives/code-block.d.ts +18 -0
  44. package/dist/compositions/primitives/code-block.js +221 -0
  45. package/dist/compositions/primitives/index.d.ts +12 -0
  46. package/dist/compositions/primitives/index.js +651 -0
  47. package/dist/compositions/primitives/progress-bar.d.ts +12 -0
  48. package/dist/compositions/primitives/progress-bar.js +54 -0
  49. package/dist/compositions/primitives/terminal.d.ts +24 -0
  50. package/dist/compositions/primitives/terminal.js +260 -0
  51. package/dist/compositions/primitives/transition.d.ts +14 -0
  52. package/dist/compositions/primitives/transition.js +93 -0
  53. package/dist/compositions/social-clip.d.ts +16 -0
  54. package/dist/compositions/social-clip.js +495 -0
  55. package/dist/compositions/terminal-demo.d.ts +17 -0
  56. package/dist/compositions/terminal-demo.js +553 -0
  57. package/dist/design/index.d.ts +4 -0
  58. package/dist/design/index.js +150 -0
  59. package/dist/design/layouts.d.ts +69 -0
  60. package/dist/design/layouts.js +45 -0
  61. package/dist/design/motion.d.ts +72 -0
  62. package/dist/design/motion.js +38 -0
  63. package/dist/design/tokens.d.ts +31 -0
  64. package/dist/design/tokens.js +23 -0
  65. package/dist/design/typography.d.ts +61 -0
  66. package/dist/design/typography.js +56 -0
  67. package/dist/docs/compositions.docblock.d.ts +1 -0
  68. package/dist/docs/compositions.docblock.js +183 -0
  69. package/dist/docs/design.docblock.d.ts +1 -0
  70. package/dist/docs/design.docblock.js +188 -0
  71. package/dist/docs/generators.docblock.d.ts +1 -0
  72. package/dist/docs/generators.docblock.js +188 -0
  73. package/dist/docs/rendering.docblock.d.ts +1 -0
  74. package/dist/docs/rendering.docblock.js +198 -0
  75. package/dist/docs/video-gen.docblock.d.ts +1 -0
  76. package/dist/docs/video-gen.docblock.js +142 -0
  77. package/dist/generators/index.d.ts +5 -0
  78. package/dist/generators/index.js +411 -0
  79. package/dist/generators/scene-planner.d.ts +23 -0
  80. package/dist/generators/scene-planner.js +200 -0
  81. package/dist/generators/script-generator.d.ts +49 -0
  82. package/dist/generators/script-generator.js +142 -0
  83. package/dist/generators/video-generator.d.ts +20 -0
  84. package/dist/generators/video-generator.js +409 -0
  85. package/dist/index.d.ts +6 -0
  86. package/dist/index.js +1545 -0
  87. package/dist/node/compositions/api-overview.js +640 -0
  88. package/dist/node/compositions/index.js +1128 -0
  89. package/dist/node/compositions/primitives/animated-text.js +139 -0
  90. package/dist/node/compositions/primitives/brand-frame.js +176 -0
  91. package/dist/node/compositions/primitives/code-block.js +221 -0
  92. package/dist/node/compositions/primitives/index.js +651 -0
  93. package/dist/node/compositions/primitives/progress-bar.js +54 -0
  94. package/dist/node/compositions/primitives/terminal.js +260 -0
  95. package/dist/node/compositions/primitives/transition.js +93 -0
  96. package/dist/node/compositions/social-clip.js +495 -0
  97. package/dist/node/compositions/terminal-demo.js +553 -0
  98. package/dist/node/design/index.js +150 -0
  99. package/dist/node/design/layouts.js +45 -0
  100. package/dist/node/design/motion.js +38 -0
  101. package/dist/node/design/tokens.js +23 -0
  102. package/dist/node/design/typography.js +56 -0
  103. package/dist/node/docs/compositions.docblock.js +182 -0
  104. package/dist/node/docs/design.docblock.js +187 -0
  105. package/dist/node/docs/generators.docblock.js +187 -0
  106. package/dist/node/docs/rendering.docblock.js +197 -0
  107. package/dist/node/docs/video-gen.docblock.js +141 -0
  108. package/dist/node/generators/index.js +411 -0
  109. package/dist/node/generators/scene-planner.js +200 -0
  110. package/dist/node/generators/script-generator.js +142 -0
  111. package/dist/node/generators/video-generator.js +409 -0
  112. package/dist/node/index.js +1545 -0
  113. package/dist/node/player/demo-player.js +1131 -0
  114. package/dist/node/player/index.js +1131 -0
  115. package/dist/node/remotion/Root.js +1184 -0
  116. package/dist/node/remotion/index.js +1185 -0
  117. package/dist/node/renderers/config.js +35 -0
  118. package/dist/node/renderers/index.js +155 -0
  119. package/dist/node/renderers/local.js +151 -0
  120. package/dist/node/types.js +8 -0
  121. package/dist/player/demo-player.d.ts +55 -0
  122. package/dist/player/demo-player.js +1131 -0
  123. package/dist/player/index.d.ts +2 -0
  124. package/dist/player/index.js +1131 -0
  125. package/dist/remotion/Root.d.ts +2 -0
  126. package/dist/remotion/Root.js +1184 -0
  127. package/dist/remotion/index.d.ts +1 -0
  128. package/dist/remotion/index.js +1185 -0
  129. package/dist/renderers/config.d.ts +28 -0
  130. package/dist/renderers/config.js +35 -0
  131. package/dist/renderers/index.d.ts +3 -0
  132. package/dist/renderers/index.js +155 -0
  133. package/dist/renderers/local.d.ts +17 -0
  134. package/dist/renderers/local.js +151 -0
  135. package/dist/types.d.ts +63 -0
  136. package/dist/types.js +8 -0
  137. package/package.json +637 -0
@@ -0,0 +1,50 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/design/layouts.ts
10
+ import { VIDEO_FORMATS } from "@contractspec/lib.contracts-integrations/integrations/providers/video";
11
+ var DEFAULT_FPS = 30;
12
+ var videoSafeZone = {
13
+ horizontal: 120,
14
+ vertical: 80,
15
+ contentWidth: 1680,
16
+ contentHeight: 920
17
+ };
18
+ function scaleSafeZone(format) {
19
+ const scaleX = format.width / 1920;
20
+ const scaleY = format.height / 1080;
21
+ return {
22
+ horizontal: Math.round(videoSafeZone.horizontal * scaleX),
23
+ vertical: Math.round(videoSafeZone.vertical * scaleY),
24
+ contentWidth: Math.round(videoSafeZone.contentWidth * scaleX),
25
+ contentHeight: Math.round(videoSafeZone.contentHeight * scaleY)
26
+ };
27
+ }
28
+ var videoPositions = {
29
+ center: { x: 960, y: 540 },
30
+ topLeft: { x: 120, y: 80 },
31
+ topRight: { x: 1800, y: 80 },
32
+ bottomLeft: { x: 120, y: 1000 },
33
+ bottomRight: { x: 1800, y: 1000 },
34
+ bottomCenter: { x: 960, y: 960 }
35
+ };
36
+ function getAllFormatVariants() {
37
+ return [
38
+ VIDEO_FORMATS.landscape,
39
+ VIDEO_FORMATS.square,
40
+ VIDEO_FORMATS.portrait
41
+ ];
42
+ }
43
+ export {
44
+ videoSafeZone,
45
+ videoPositions,
46
+ scaleSafeZone,
47
+ getAllFormatVariants,
48
+ VIDEO_FORMATS,
49
+ DEFAULT_FPS
50
+ };
@@ -0,0 +1,43 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/design/motion.ts
10
+ import { Easing } from "remotion";
11
+ var videoEasing = {
12
+ entrance: Easing.out(Easing.exp),
13
+ exit: Easing.in(Easing.exp),
14
+ emphasis: Easing.out(Easing.back(1.4)),
15
+ linear: Easing.linear,
16
+ gentle: Easing.bezier(0.25, 0.1, 0.25, 1),
17
+ spring: Easing.out(Easing.back(1.7))
18
+ };
19
+ var videoDurations = {
20
+ sceneTransition: 20,
21
+ textEntrance: 15,
22
+ textExit: 12,
23
+ codeTypingPerChar: 2,
24
+ sectionPause: 30,
25
+ emphasisPause: 15,
26
+ brandReveal: 25,
27
+ minScene: 60,
28
+ shortScene: 60,
29
+ mediumScene: 120,
30
+ longScene: 240
31
+ };
32
+ var videoTransitions = {
33
+ fade: { type: "fade", durationInFrames: 20 },
34
+ slideLeft: { type: "slide-left", durationInFrames: 20 },
35
+ slideRight: { type: "slide-right", durationInFrames: 20 },
36
+ wipe: { type: "wipe", durationInFrames: 15 },
37
+ none: { type: "none", durationInFrames: 0 }
38
+ };
39
+ export {
40
+ videoTransitions,
41
+ videoEasing,
42
+ videoDurations
43
+ };
@@ -0,0 +1,28 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/design/tokens.ts
10
+ import { defaultTokens } from "@contractspec/lib.design-system";
11
+ var defaultVideoColors = {
12
+ canvasBackground: defaultTokens.colors.background,
13
+ codeBackground: "#1e1e2e",
14
+ terminalBackground: "#0d1117",
15
+ terminalForeground: "#c9d1d9",
16
+ highlight: defaultTokens.colors.accent,
17
+ gradientStart: defaultTokens.colors.primary,
18
+ gradientEnd: defaultTokens.colors.accent
19
+ };
20
+ var defaultVideoTheme = {
21
+ ...defaultTokens,
22
+ video: defaultVideoColors
23
+ };
24
+ export {
25
+ defaultVideoTheme,
26
+ defaultVideoColors,
27
+ defaultTokens
28
+ };
@@ -0,0 +1,61 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/design/typography.ts
10
+ var videoTypography = {
11
+ title: {
12
+ fontSize: 72,
13
+ lineHeight: 1.1,
14
+ fontWeight: 700,
15
+ letterSpacing: -1
16
+ },
17
+ heading: {
18
+ fontSize: 56,
19
+ lineHeight: 1.2,
20
+ fontWeight: 600,
21
+ letterSpacing: -0.5
22
+ },
23
+ subheading: {
24
+ fontSize: 40,
25
+ lineHeight: 1.25,
26
+ fontWeight: 500
27
+ },
28
+ body: {
29
+ fontSize: 32,
30
+ lineHeight: 1.5,
31
+ fontWeight: 400
32
+ },
33
+ code: {
34
+ fontSize: 28,
35
+ lineHeight: 1.6,
36
+ fontWeight: 400
37
+ },
38
+ caption: {
39
+ fontSize: 24,
40
+ lineHeight: 1.4,
41
+ fontWeight: 400
42
+ },
43
+ label: {
44
+ fontSize: 20,
45
+ lineHeight: 1.3,
46
+ fontWeight: 600,
47
+ letterSpacing: 1
48
+ }
49
+ };
50
+ function scaleTypography(style, targetWidth) {
51
+ const scale = targetWidth / 1920;
52
+ return {
53
+ ...style,
54
+ fontSize: Math.round(style.fontSize * scale),
55
+ letterSpacing: style.letterSpacing ? Math.round(style.letterSpacing * scale * 10) / 10 : undefined
56
+ };
57
+ }
58
+ export {
59
+ videoTypography,
60
+ scaleTypography
61
+ };
@@ -0,0 +1,182 @@
1
+ // src/docs/compositions.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
+ var compositionsDocBlocks = [
4
+ {
5
+ id: "docs.video-gen.compositions",
6
+ title: "Video Compositions & Primitives",
7
+ summary: "Remotion composition components and reusable primitives for building programmatic videos.",
8
+ kind: "reference",
9
+ visibility: "public",
10
+ route: "/docs/video-gen/compositions",
11
+ tags: ["video", "remotion", "compositions", "primitives", "react"],
12
+ owners: ["@contractspec/lib.video-gen"],
13
+ body: `# Video Compositions & Primitives
14
+
15
+ Compositions are React components rendered by Remotion. They use \`useCurrentFrame()\`, \`useVideoConfig()\`, and \`interpolate()\` to produce frame-accurate animations. All compositions must be **deterministic**: same props = same visual output.
16
+
17
+ ## Primitive Components
18
+
19
+ Primitives are reusable building blocks for constructing full compositions.
20
+
21
+ \`\`\`ts
22
+ import {
23
+ AnimatedText,
24
+ CodeBlock,
25
+ Terminal,
26
+ BrandFrame,
27
+ ProgressBar,
28
+ SceneTransitionWrapper,
29
+ } from "@contractspec/lib.video-gen/compositions/primitives";
30
+ \`\`\`
31
+
32
+ ### AnimatedText
33
+
34
+ Text with entrance/exit slide + fade animations.
35
+
36
+ | Prop | Type | Default | Description |
37
+ |------|------|---------|-------------|
38
+ | \`text\` | \`string\` | -- | Text content |
39
+ | \`variant\` | \`keyof videoTypography\` | \`"body"\` | Typography preset (title, heading, subheading, body, code, caption, label) |
40
+ | \`enterAt\` | \`number\` | \`0\` | Frame at which text enters |
41
+ | \`exitAt\` | \`number\` | -- | Frame at which text exits (omit to keep visible) |
42
+ | \`color\` | \`string\` | \`"#ffffff"\` | Text color |
43
+ | \`align\` | \`"left" \\| "center" \\| "right"\` | \`"left"\` | Text alignment |
44
+
45
+ ### CodeBlock
46
+
47
+ Syntax-aware code display with typing animation and macOS-style title bar.
48
+
49
+ | Prop | Type | Default | Description |
50
+ |------|------|---------|-------------|
51
+ | \`code\` | \`string\` | -- | Code string to display |
52
+ | \`language\` | \`string\` | \`"typescript"\` | Language label in the title bar |
53
+ | \`startAt\` | \`number\` | \`0\` | Frame at which typing starts |
54
+ | \`typeAnimation\` | \`boolean\` | \`true\` | Animate character-by-character typing |
55
+ | \`filename\` | \`string\` | -- | Filename in the title bar (overrides language) |
56
+
57
+ ### Terminal
58
+
59
+ CLI simulator with command typing, output lines, and cursor animation.
60
+
61
+ | Prop | Type | Default | Description |
62
+ |------|------|---------|-------------|
63
+ | \`lines\` | \`TerminalLine[]\` | -- | Lines to display in sequence |
64
+ | \`startAt\` | \`number\` | \`0\` | Frame at which terminal appears |
65
+ | \`prompt\` | \`string\` | \`"$ "\` | Prompt string before commands |
66
+ | \`title\` | \`string\` | \`"Terminal"\` | Title bar text |
67
+ | \`typingSpeed\` | \`number\` | \`2\` | Frames per character for commands |
68
+
69
+ \`TerminalLine\` types: \`command\` (typed), \`output\` (faded in), \`error\` (red), \`success\` (green), \`comment\` (dimmed with \`#\` prefix).
70
+
71
+ ### BrandFrame
72
+
73
+ Branded container with safe-zone padding, gradient/solid/dark backgrounds, and optional watermark.
74
+
75
+ | Prop | Type | Default | Description |
76
+ |------|------|---------|-------------|
77
+ | \`variant\` | \`"solid" \\| "gradient" \\| "dark"\` | \`"gradient"\` | Background style |
78
+ | \`showBranding\` | \`boolean\` | \`true\` | Show "ContractSpec" watermark |
79
+ | \`animateEntrance\` | \`boolean\` | \`true\` | Fade-in on first frames |
80
+ | \`styleOverrides\` | \`VideoStyleOverrides\` | -- | Override colors, fonts, dark mode |
81
+
82
+ ### ProgressBar
83
+
84
+ Thin progress indicator at the top or bottom of the frame.
85
+
86
+ | Prop | Type | Default | Description |
87
+ |------|------|---------|-------------|
88
+ | \`height\` | \`number\` | \`4\` | Bar height in pixels |
89
+ | \`color\` | \`string\` | primary color | Bar fill color |
90
+ | \`position\` | \`"top" \\| "bottom"\` | \`"bottom"\` | Placement |
91
+
92
+ ### SceneTransitionWrapper
93
+
94
+ Wraps children with entrance/exit transitions (fade, slide-left, slide-right, wipe).
95
+
96
+ | Prop | Type | Default | Description |
97
+ |------|------|---------|-------------|
98
+ | \`type\` | \`SceneTransitionType\` | -- | Transition type |
99
+ | \`durationInFrames\` | \`number\` | -- | Transition duration |
100
+ | \`direction\` | \`"in" \\| "out"\` | -- | Entering or exiting |
101
+
102
+ ## Full Compositions
103
+
104
+ Full compositions combine primitives into complete video templates. They are registered in Remotion Studio via \`RemotionRoot\`.
105
+
106
+ ### ApiOverview
107
+
108
+ Visualizes a ContractSpec definition generating a full API surface. Used for homepage demos and documentation.
109
+
110
+ \`\`\`tsx
111
+ import { ApiOverview } from "@contractspec/lib.video-gen/compositions/api-overview";
112
+
113
+ <ApiOverview
114
+ specName="CreateUser"
115
+ method="POST"
116
+ endpoint="/api/users"
117
+ specCode={\`export const createUser = defineCommand({...})\`}
118
+ generatedOutputs={["REST Endpoint", "GraphQL Mutation", "Prisma Model"]}
119
+ tagline="One spec. Every surface."
120
+ />
121
+ \`\`\`
122
+
123
+ **Scenes**: Title + method badge -> Code typing animation -> Generated outputs fan-out -> Tagline.
124
+
125
+ ### SocialClip
126
+
127
+ Short-form marketing content for LinkedIn, X, YouTube Shorts. Adapts layout for landscape (16:9), square (1:1), and portrait (9:16).
128
+
129
+ \`\`\`tsx
130
+ import { SocialClip } from "@contractspec/lib.video-gen/compositions/social-clip";
131
+
132
+ <SocialClip
133
+ hook="Stop rewriting the same API logic."
134
+ message="Generate REST, GraphQL, DB, SDK from a single spec."
135
+ points={["Deterministic output", "Fully ejectable", "No lock-in"]}
136
+ cta="Try ContractSpec"
137
+ ctaUrl="contractspec.dev"
138
+ />
139
+ \`\`\`
140
+
141
+ **Scenes**: Hook (attention grabber) -> Main message -> Supporting points -> CTA button.
142
+
143
+ ### TerminalDemo
144
+
145
+ CLI command walkthrough with animated terminal. Used in documentation and tutorial videos.
146
+
147
+ \`\`\`tsx
148
+ import { TerminalDemo } from "@contractspec/lib.video-gen/compositions/terminal-demo";
149
+
150
+ <TerminalDemo
151
+ title="Getting Started with ContractSpec"
152
+ subtitle="Define once, generate everything."
153
+ lines={[
154
+ { type: "command", text: "npx contractspec init my-api" },
155
+ { type: "output", text: "Created my-api/ with 3 sample contracts" },
156
+ { type: "command", text: "npx contractspec build" },
157
+ { type: "success", text: "Built 3 contracts -> 18 generated files" },
158
+ ]}
159
+ summary="Ship faster. Stay coherent."
160
+ />
161
+ \`\`\`
162
+
163
+ **Scenes**: Title + subtitle -> Terminal typing animation -> Summary.
164
+
165
+ ## Creating New Compositions
166
+
167
+ 1. Create a new \`.tsx\` file in \`src/compositions/\`.
168
+ 2. Use primitives from \`./primitives/\` and design tokens from \`../design/\`.
169
+ 3. Use \`useCurrentFrame()\` and \`interpolate()\` for frame-based animations.
170
+ 4. Register in \`src/remotion/Root.tsx\` with a \`<Composition>\` entry.
171
+ 5. Export from \`src/compositions/index.ts\`.
172
+ 6. Add the export path to \`package.json\` (both workspace and publishConfig).
173
+
174
+ ### Guardrails
175
+
176
+ - Keep compositions **pure**: no side effects, no network calls, no randomness.
177
+ - Use \`scaleSafeZone()\` and \`scaleTypography()\` to support multiple formats.
178
+ - All timing should be frame-based (not time-based) for deterministic output.
179
+ `
180
+ }
181
+ ];
182
+ registerDocBlocks(compositionsDocBlocks);
@@ -0,0 +1,187 @@
1
+ // src/docs/design.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
+ var designDocBlocks = [
4
+ {
5
+ id: "docs.video-gen.design",
6
+ title: "Video Design System",
7
+ summary: "Design tokens, motion primitives, typography scale, and layout system optimized for programmatic video.",
8
+ kind: "reference",
9
+ visibility: "public",
10
+ route: "/docs/video-gen/design",
11
+ tags: ["video", "design-tokens", "motion", "typography", "layout"],
12
+ owners: ["@contractspec/lib.video-gen"],
13
+ body: `# Video Design System
14
+
15
+ The design layer bridges \`@contractspec/lib.design-system\` brand tokens with video-specific extensions for motion, typography, and spatial layout. All values are optimized for 1920x1080 (landscape) and scale proportionally for other formats.
16
+
17
+ \`\`\`ts
18
+ import {
19
+ defaultVideoTheme,
20
+ videoEasing,
21
+ videoDurations,
22
+ videoTypography,
23
+ videoSafeZone,
24
+ scaleSafeZone,
25
+ } from "@contractspec/lib.video-gen/design";
26
+ \`\`\`
27
+
28
+ ## Tokens
29
+
30
+ ### Brand Bridge
31
+
32
+ \`VideoThemeTokens\` extends the design-system \`ThemeTokens\` with a \`video\` namespace for video-specific colors:
33
+
34
+ \`\`\`ts
35
+ import { defaultVideoTheme } from "@contractspec/lib.video-gen/design/tokens";
36
+
37
+ // Brand tokens (from @contractspec/lib.design-system)
38
+ defaultVideoTheme.colors.primary; // brand primary
39
+ defaultVideoTheme.colors.accent; // brand accent
40
+
41
+ // Video-specific extensions
42
+ defaultVideoTheme.video.canvasBackground; // frame background
43
+ defaultVideoTheme.video.codeBackground; // "#1e1e2e"
44
+ defaultVideoTheme.video.terminalBackground; // "#0d1117"
45
+ defaultVideoTheme.video.terminalForeground; // "#c9d1d9"
46
+ defaultVideoTheme.video.highlight; // accent color
47
+ defaultVideoTheme.video.gradientStart; // primary
48
+ defaultVideoTheme.video.gradientEnd; // accent
49
+ \`\`\`
50
+
51
+ > Do not duplicate brand color values. Import and extend from \`@contractspec/lib.design-system\`.
52
+
53
+ ## Motion
54
+
55
+ ### Easing Functions
56
+
57
+ Pre-configured easing curves for use with Remotion's \`interpolate()\`:
58
+
59
+ | Key | Easing | Use Case |
60
+ |-----|--------|----------|
61
+ | \`entrance\` | \`Easing.out(Easing.exp)\` | Objects appearing |
62
+ | \`exit\` | \`Easing.in(Easing.exp)\` | Objects disappearing |
63
+ | \`emphasis\` | \`Easing.out(Easing.back(1.4))\` | Drawing attention, bounce |
64
+ | \`linear\` | \`Easing.linear\` | Progress bars, typing |
65
+ | \`gentle\` | \`Easing.bezier(0.25, 0.1, 0.25, 1)\` | Subtle movements |
66
+ | \`spring\` | \`Easing.out(Easing.back(1.7))\` | Playful movements |
67
+
68
+ \`\`\`ts
69
+ import { interpolate } from "remotion";
70
+ import { videoEasing } from "@contractspec/lib.video-gen/design/motion";
71
+
72
+ const opacity = interpolate(frame, [0, 15], [0, 1], {
73
+ easing: videoEasing.entrance,
74
+ extrapolateLeft: "clamp",
75
+ extrapolateRight: "clamp",
76
+ });
77
+ \`\`\`
78
+
79
+ ### Durations (frames at 30fps)
80
+
81
+ | Key | Frames | Seconds | Use Case |
82
+ |-----|--------|---------|----------|
83
+ | \`sceneTransition\` | 20 | 0.67s | Between scenes |
84
+ | \`textEntrance\` | 15 | 0.5s | Text slide-in |
85
+ | \`textExit\` | 12 | 0.4s | Text slide-out |
86
+ | \`codeTypingPerChar\` | 2 | 0.07s | Code typing speed |
87
+ | \`sectionPause\` | 30 | 1.0s | Pause after concept |
88
+ | \`emphasisPause\` | 15 | 0.5s | Brief emphasis |
89
+ | \`brandReveal\` | 25 | 0.83s | Logo/watermark |
90
+ | \`minScene\` | 60 | 2.0s | Minimum scene length |
91
+ | \`shortScene\` | 60 | 2.0s | Short scene |
92
+ | \`mediumScene\` | 120 | 4.0s | Medium scene |
93
+ | \`longScene\` | 240 | 8.0s | Long scene |
94
+
95
+ ### Transition Presets
96
+
97
+ \`\`\`ts
98
+ import { videoTransitions } from "@contractspec/lib.video-gen/design/motion";
99
+
100
+ // { type: "fade", durationInFrames: 20 }
101
+ videoTransitions.fade;
102
+
103
+ // { type: "slide-left", durationInFrames: 20 }
104
+ videoTransitions.slideLeft;
105
+ \`\`\`
106
+
107
+ ## Typography
108
+
109
+ ### Type Scale (1920x1080 baseline)
110
+
111
+ | Key | Size | Weight | Use Case |
112
+ |-----|------|--------|----------|
113
+ | \`title\` | 72px | 700 | Main title |
114
+ | \`heading\` | 56px | 600 | Section heading |
115
+ | \`subheading\` | 40px | 500 | Subheading |
116
+ | \`body\` | 32px | 400 | Body text |
117
+ | \`code\` | 28px | 400 | Monospace code |
118
+ | \`caption\` | 24px | 400 | Small caption |
119
+ | \`label\` | 20px | 600 | Badge / label |
120
+
121
+ ### Scaling for Other Formats
122
+
123
+ Use \`scaleTypography()\` to proportionally scale for non-landscape formats:
124
+
125
+ \`\`\`ts
126
+ import {
127
+ videoTypography,
128
+ scaleTypography,
129
+ } from "@contractspec/lib.video-gen/design/typography";
130
+
131
+ // Scale heading for 1080x1080 (square)
132
+ const squareHeading = scaleTypography(videoTypography.heading, 1080);
133
+ // -> fontSize: 32, lineHeight: 1.2, fontWeight: 600
134
+ \`\`\`
135
+
136
+ ## Layouts
137
+
138
+ ### Safe Zones
139
+
140
+ Content-safe padding for text within video frames (1920x1080 baseline):
141
+
142
+ \`\`\`ts
143
+ import {
144
+ videoSafeZone,
145
+ scaleSafeZone,
146
+ } from "@contractspec/lib.video-gen/design/layouts";
147
+
148
+ videoSafeZone.horizontal; // 120px
149
+ videoSafeZone.vertical; // 80px
150
+ videoSafeZone.contentWidth; // 1680px
151
+ videoSafeZone.contentHeight; // 920px
152
+
153
+ // Scale for portrait (1080x1920)
154
+ const portrait = scaleSafeZone({ type: "portrait", width: 1080, height: 1920 });
155
+ \`\`\`
156
+
157
+ ### Standard Positions
158
+
159
+ \`\`\`ts
160
+ import { videoPositions } from "@contractspec/lib.video-gen/design/layouts";
161
+
162
+ videoPositions.center; // { x: 960, y: 540 }
163
+ videoPositions.topLeft; // { x: 120, y: 80 }
164
+ videoPositions.bottomRight; // { x: 1800, y: 1000 } -- logos, watermarks
165
+ videoPositions.bottomCenter; // { x: 960, y: 960 } -- captions
166
+ \`\`\`
167
+
168
+ ### Format Variants
169
+
170
+ \`\`\`ts
171
+ import {
172
+ VIDEO_FORMATS,
173
+ getAllFormatVariants,
174
+ DEFAULT_FPS,
175
+ } from "@contractspec/lib.video-gen/design/layouts";
176
+
177
+ VIDEO_FORMATS.landscape; // { type: "landscape", width: 1920, height: 1080 }
178
+ VIDEO_FORMATS.portrait; // { type: "portrait", width: 1080, height: 1920 }
179
+ VIDEO_FORMATS.square; // { type: "square", width: 1080, height: 1080 }
180
+
181
+ getAllFormatVariants(); // [landscape, square, portrait]
182
+ DEFAULT_FPS; // 30
183
+ \`\`\`
184
+ `
185
+ }
186
+ ];
187
+ registerDocBlocks(designDocBlocks);