@vanillaskyai/video 0.8.8 → 0.10.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 (173) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/PUBLIC-API.md +5 -8
  3. package/dist/{builtin-server-CUYPIDE7.js → builtin-server-W4PLJUZ5.js} +2 -2
  4. package/dist/{catalog-types-BIhSpOWK.d.ts → catalog-types-WTbLP6Jh.d.ts} +5 -1
  5. package/dist/chapter-title-YRLIQY3V.js +7 -0
  6. package/dist/check-runtime.js +5 -14
  7. package/dist/{chunk-AITKH6QT.js → chunk-2HFO22K2.js} +15 -40
  8. package/dist/chunk-4YM2M62S.js +13 -0
  9. package/dist/chunk-4ZJLPHBV.js +684 -0
  10. package/dist/chunk-77VY4O7A.js +390 -0
  11. package/dist/{chunk-MMUXVA47.js → chunk-7M56IUUX.js} +9 -8
  12. package/dist/chunk-7NZOMTAL.js +63 -0
  13. package/dist/{chunk-2DOLF4QN.js → chunk-AUPC6MDK.js} +12 -14
  14. package/dist/{chunk-352ZZCET.js → chunk-EGVQODKU.js} +2 -2
  15. package/dist/{chunk-2USVB3CY.js → chunk-ELVOT2FQ.js} +284 -177
  16. package/dist/chunk-EWWCQFTI.js +18 -0
  17. package/dist/{chunk-KT3M7KDL.js → chunk-HKUI5BTB.js} +3 -3
  18. package/dist/chunk-IIN5M5HW.js +697 -0
  19. package/dist/{chunk-LMG3GHLL.js → chunk-IQMYK5DX.js} +29 -3
  20. package/dist/{chunk-OWBT45EN.js → chunk-IR44XKBI.js} +1 -1
  21. package/dist/{chunk-MXZSDGZQ.js → chunk-NMFDC2W2.js} +4 -6
  22. package/dist/{chunk-5SLENAJW.js → chunk-PAJ44TFW.js} +1 -2
  23. package/dist/{chunk-L7QGGKJ2.js → chunk-PDQFQIQW.js} +1 -1
  24. package/dist/{chunk-WJ6FLKNC.js → chunk-R3XAOMKP.js} +14 -0
  25. package/dist/{chunk-2OKB27TG.js → chunk-RXTN2CW6.js} +2 -2
  26. package/dist/{chunk-XWWLKRNU.js → chunk-TVIU23OM.js} +38 -49
  27. package/dist/chunk-XX4GXKTX.js +35 -0
  28. package/dist/chunk-Z67Q5KUW.js +16 -0
  29. package/dist/{chunk-3VRMKFM7.js → chunk-ZDJNFA52.js} +11 -24
  30. package/dist/cinema-media-C7OUPNSH.js +12 -0
  31. package/dist/cli.js +18 -9
  32. package/dist/comparison-GNZOR7MF.js +37 -0
  33. package/dist/compose-video-TBFTONUC.js +12 -0
  34. package/dist/editorial-timeline-EMV5335S.js +43 -0
  35. package/dist/{events-BQ6z264n.d.ts → events-B4YCc4vc.d.ts} +1 -1
  36. package/dist/index.d.ts +4 -6
  37. package/dist/index.js +3 -7
  38. package/dist/key-figure-P37VK425.js +30 -0
  39. package/dist/{kit-tQnCPMOM.d.ts → kit-DrRpdn0p.d.ts} +2 -2
  40. package/dist/mobile-message-OF7T62B7.js +50 -0
  41. package/dist/quote-T6WYLN7A.js +33 -0
  42. package/dist/react.d.ts +21 -11
  43. package/dist/react.js +585 -826
  44. package/dist/scene-video-backdrop-PCTARAAJ.js +7 -0
  45. package/dist/server.d.ts +7 -8
  46. package/dist/server.js +179 -84
  47. package/dist/{system-prompt-RRXIWDDD.js → system-prompt-SYRT5DWM.js} +1 -1
  48. package/dist/template-catalog.d.ts +392 -16
  49. package/dist/template-catalog.js +1 -1
  50. package/dist/templates.d.ts +5 -5
  51. package/dist/test.d.ts +3 -3
  52. package/dist/test.js +18 -18
  53. package/dist/text-stream-LD364KBI.js +9 -0
  54. package/dist/{types-DWFO6qca.d.ts → types-CdBmNTGD.d.ts} +1 -1
  55. package/dist/{types-CEh9eUFu.d.ts → types-DdZw4GRQ.d.ts} +17 -48
  56. package/dist/validate-4OUD2CLX.js +10 -0
  57. package/docs/architecture.md +1 -1
  58. package/docs/concepts.md +1 -1
  59. package/docs/custom-templates.md +13 -28
  60. package/docs/customization.md +11 -59
  61. package/docs/getting-started.md +2 -2
  62. package/docs/immersive-interface.md +3 -4
  63. package/docs/maintainers/cinematic-migration.md +38 -0
  64. package/docs/media-and-audio.md +14 -14
  65. package/docs/motion-and-effects.md +6 -14
  66. package/docs/persistence.md +3 -3
  67. package/docs/production.md +11 -9
  68. package/docs/provider-integration.md +9 -16
  69. package/docs/reference/design-system.html +1 -1
  70. package/docs/reference/protocol.md +14 -4
  71. package/docs/testing.md +1 -1
  72. package/package.json +6 -3
  73. package/registry/items/backgrounds.json +1 -1
  74. package/registry/items/chapterTitle.json +80 -0
  75. package/registry/items/cinemaMedia.json +136 -0
  76. package/registry/items/comparison.json +168 -0
  77. package/registry/items/editorialTimeline.json +172 -0
  78. package/registry/items/keyFigure.json +162 -0
  79. package/registry/items/mobileMessage.json +153 -0
  80. package/registry/items/quote.json +161 -0
  81. package/registry/items/template-context.json +1 -1
  82. package/registry/items/theme.json +1 -1
  83. package/starters/video-chat/README.md +24 -26
  84. package/starters/video-chat/package.json +1 -1
  85. package/starters/video-chat/providers/video.ts +6 -5
  86. package/starters/video-chat/stock.ts +35 -151
  87. package/styles/fonts/OFL.txt +93 -0
  88. package/styles/fonts/manifest.json +66 -0
  89. package/styles/fonts/roboto-v51-cyrillic-ext.woff2 +0 -0
  90. package/styles/fonts/roboto-v51-cyrillic.woff2 +0 -0
  91. package/styles/fonts/roboto-v51-greek-ext.woff2 +0 -0
  92. package/styles/fonts/roboto-v51-greek.woff2 +0 -0
  93. package/styles/fonts/roboto-v51-latin-ext.woff2 +0 -0
  94. package/styles/fonts/roboto-v51-latin.woff2 +0 -0
  95. package/styles/fonts/roboto-v51-math.woff2 +0 -0
  96. package/styles/fonts/roboto-v51-symbols.woff2 +0 -0
  97. package/styles/fonts/roboto-v51-vietnamese.woff2 +0 -0
  98. package/styles/fonts/roboto.css +91 -0
  99. package/styles/video-chat.css +30 -22
  100. package/dist/bg-confetti-HITCGLGD.js +0 -89
  101. package/dist/bg-emoji-VU4UZYZN.js +0 -150
  102. package/dist/bg-media-L34PDQXJ.js +0 -106
  103. package/dist/brand-message-FUJ4STFO.js +0 -256
  104. package/dist/chart-bar-EGPHJATL.js +0 -310
  105. package/dist/chart-counter-5FFWQNZO.js +0 -306
  106. package/dist/chart-progress-ring-JMXQLMLC.js +0 -302
  107. package/dist/chunk-4UNKZEAT.js +0 -3575
  108. package/dist/chunk-5CDAM24P.js +0 -31
  109. package/dist/chunk-AOWSXU2K.js +0 -18
  110. package/dist/chunk-CJ7F2CE6.js +0 -104
  111. package/dist/chunk-FRN6WKHA.js +0 -185
  112. package/dist/chunk-G5JPHBX7.js +0 -336
  113. package/dist/chunk-L5BTTCZV.js +0 -97
  114. package/dist/chunk-P22HHFDK.js +0 -43
  115. package/dist/chunk-PP3MCPN4.js +0 -1998
  116. package/dist/chunk-QAAO7OAY.js +0 -19
  117. package/dist/chunk-S7HFLYNN.js +0 -35
  118. package/dist/chunk-W3VDIBGR.js +0 -217
  119. package/dist/chunk-XGRA2MUV.js +0 -242
  120. package/dist/chunk-XTOXFMLM.js +0 -105
  121. package/dist/chunk-YJJC4N4D.js +0 -761
  122. package/dist/compose-video-2NFH4DZY.js +0 -13
  123. package/dist/cta-logo-YR7LYUR5.js +0 -212
  124. package/dist/cta-media-DQJBKUO2.js +0 -221
  125. package/dist/incoming-call-54KQ7O5A.js +0 -323
  126. package/dist/infographic-before-after-ROS52GOW.js +0 -460
  127. package/dist/infographic-feature-list-E7MGUDAN.js +0 -272
  128. package/dist/infographic-problem-solution-3S6NGO5N.js +0 -343
  129. package/dist/infographic-stat-row-SYB7AB7H.js +0 -247
  130. package/dist/infographic-steps-KCE6JWE2.js +0 -406
  131. package/dist/prompt-input-MHX4O42G.js +0 -239
  132. package/dist/reaction-SLEGR3BE.js +0 -122
  133. package/dist/scene-video-backdrop-XFPX4O3I.js +0 -10
  134. package/dist/showcase-code-2HLAVKBM.js +0 -357
  135. package/dist/showcase-phone-Q4HEO4LH.js +0 -278
  136. package/dist/showcase-terminal-DL45LUFG.js +0 -312
  137. package/dist/showcase-web-2QZO73FZ.js +0 -396
  138. package/dist/social-conversation-75SD2637.js +0 -695
  139. package/dist/social-milestone-GEFUQSBF.js +0 -296
  140. package/dist/social-notification-FJ5VHVLK.js +0 -247
  141. package/dist/social-review-stack-KXQCKFRP.js +0 -242
  142. package/dist/social-testimonial-JZ7CHC7S.js +0 -287
  143. package/dist/social-tweet-UCDXM25F.js +0 -298
  144. package/dist/text-stream-54LXABJW.js +0 -10
  145. package/dist/validate-T7GBU2YF.js +0 -8
  146. package/registry/items/barChart.json +0 -245
  147. package/registry/items/beforeAfter.json +0 -180
  148. package/registry/items/bigNumber.json +0 -232
  149. package/registry/items/brandMessage.json +0 -164
  150. package/registry/items/cardList.json +0 -214
  151. package/registry/items/chatMessenger.json +0 -151
  152. package/registry/items/chatWhatsapp.json +0 -151
  153. package/registry/items/codeEditor.json +0 -191
  154. package/registry/items/confetti.json +0 -107
  155. package/registry/items/ctaLogo.json +0 -167
  156. package/registry/items/ctaMedia.json +0 -200
  157. package/registry/items/emojiBurst.json +0 -101
  158. package/registry/items/incomingCall.json +0 -177
  159. package/registry/items/media.json +0 -187
  160. package/registry/items/milestone.json +0 -212
  161. package/registry/items/notification.json +0 -189
  162. package/registry/items/phoneMockup.json +0 -261
  163. package/registry/items/problemSolution.json +0 -193
  164. package/registry/items/progressRing.json +0 -206
  165. package/registry/items/promptInput.json +0 -155
  166. package/registry/items/reaction.json +0 -176
  167. package/registry/items/reviewStack.json +0 -231
  168. package/registry/items/steps.json +0 -215
  169. package/registry/items/terminal.json +0 -219
  170. package/registry/items/testimonial.json +0 -171
  171. package/registry/items/tripleStats.json +0 -235
  172. package/registry/items/tweet.json +0 -210
  173. package/registry/items/webMockup.json +0 -280
@@ -1,247 +0,0 @@
1
- import {
2
- SceneBackground,
3
- getMediaBackgroundProps
4
- } from "./chunk-MXZSDGZQ.js";
5
- import {
6
- TemplateText
7
- } from "./chunk-YJJC4N4D.js";
8
- import "./chunk-L5BTTCZV.js";
9
- import "./chunk-FRN6WKHA.js";
10
- import {
11
- TOP_TEXT_AREA_RATIO,
12
- withOpacity
13
- } from "./chunk-W3VDIBGR.js";
14
- import {
15
- interpolate,
16
- spring
17
- } from "./chunk-XTOXFMLM.js";
18
- import {
19
- hasSceneMedia
20
- } from "./chunk-224QNWRA.js";
21
- import "./chunk-5CDAM24P.js";
22
- import {
23
- TOKEN_DEFAULTS,
24
- resolveTokens
25
- } from "./chunk-XWWLKRNU.js";
26
-
27
- // src/visual-system/primitives/typography/StatBadgeRow.tsx
28
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
- var SPRING_STAT = { damping: 12, stiffness: 170 };
30
- var StatBadgeRow = ({
31
- progress,
32
- stats: rawStats,
33
- width,
34
- height,
35
- font = TOKEN_DEFAULTS.font,
36
- textColor = "#ffffff"
37
- }) => {
38
- const s = Math.min(width, height) / 1080;
39
- const stats = rawStats.filter((st) => st.value);
40
- const isLandscape = width > height;
41
- const textAreaHeight = height * TOP_TEXT_AREA_RATIO;
42
- const statsAreaTop = textAreaHeight;
43
- const statsAreaHeight = height - statsAreaTop;
44
- const valueFontSize = isLandscape ? 72 * s : 100 * s;
45
- const labelFontSize = isLandscape ? 28 * s : 38 * s;
46
- const statCount = stats.length;
47
- const getStatPosition = (i) => {
48
- if (isLandscape) {
49
- const spacing = width / (statCount + 1);
50
- return {
51
- x: spacing * (i + 1),
52
- y: statsAreaTop + statsAreaHeight * 0.4
53
- };
54
- }
55
- const sectionH = statsAreaHeight / (statCount + 0.5);
56
- return {
57
- x: width / 2,
58
- y: statsAreaTop + sectionH * (i + 0.5)
59
- };
60
- };
61
- return /* @__PURE__ */ jsx(Fragment, { children: stats.map((stat, i) => {
62
- const pos = getStatPosition(i);
63
- const itemStart = 0.1 + i * 0.12;
64
- const statP = spring(
65
- interpolate(progress, [itemStart, itemStart + 0.12], [0, 1], {
66
- extrapolateLeft: "clamp",
67
- extrapolateRight: "clamp"
68
- }),
69
- SPRING_STAT
70
- );
71
- const scaleVal = interpolate(statP, [0, 1], [0.5, 1]);
72
- const opacity = interpolate(progress, [itemStart, itemStart + 0.06], [0, 1], {
73
- extrapolateLeft: "clamp",
74
- extrapolateRight: "clamp"
75
- });
76
- const labelDelay = itemStart + 0.06;
77
- const labelOpacity = interpolate(progress, [labelDelay, labelDelay + 0.05], [0, 1], {
78
- extrapolateLeft: "clamp",
79
- extrapolateRight: "clamp"
80
- });
81
- const labelSlideY = interpolate(progress, [labelDelay, labelDelay + 0.06], [10 * s, 0], {
82
- extrapolateLeft: "clamp",
83
- extrapolateRight: "clamp"
84
- });
85
- const EXIT_START = 0.78;
86
- const EXIT_DURATION = 0.1;
87
- const EXIT_STAGGER = 0.04;
88
- const exitStart = EXIT_START + i * EXIT_STAGGER;
89
- const exitEnd = exitStart + EXIT_DURATION;
90
- const exitRaw = interpolate(progress, [exitStart, exitEnd], [0, 1], {
91
- extrapolateLeft: "clamp",
92
- extrapolateRight: "clamp"
93
- });
94
- const exitEased = exitRaw * exitRaw;
95
- const exitTranslateX = -90 * s * exitEased;
96
- const exitFade = 1 - exitEased;
97
- return /* @__PURE__ */ jsxs(
98
- "div",
99
- {
100
- style: {
101
- position: "absolute",
102
- left: pos.x,
103
- top: pos.y,
104
- transform: `translate(-50%, -50%) translate(${exitTranslateX}px, 0) scale(${scaleVal})`,
105
- opacity: opacity * exitFade,
106
- display: "flex",
107
- flexDirection: "column",
108
- alignItems: "center",
109
- justifyContent: "center",
110
- gap: isLandscape ? 12 * s : 24 * s,
111
- backgroundColor: "rgba(255,255,255,0.15)",
112
- border: "1.5px solid rgba(255,255,255,0.2)",
113
- borderRadius: isLandscape ? 20 * s : 28 * s,
114
- padding: isLandscape ? `${28 * s}px ${24 * s}px` : `${48 * s}px ${56 * s}px`,
115
- width: isLandscape ? width / (statCount + 1) * 0.85 : void 0,
116
- maxWidth: isLandscape ? width * 0.28 : void 0,
117
- minWidth: isLandscape ? void 0 : width * 0.6
118
- },
119
- children: [
120
- /* @__PURE__ */ jsx(
121
- "div",
122
- {
123
- style: {
124
- fontSize: valueFontSize,
125
- fontWeight: 800,
126
- color: textColor,
127
- fontFamily: font,
128
- lineHeight: 1,
129
- whiteSpace: "nowrap"
130
- },
131
- children: stat.value
132
- }
133
- ),
134
- /* @__PURE__ */ jsx(
135
- "div",
136
- {
137
- style: {
138
- fontSize: labelFontSize,
139
- fontWeight: 500,
140
- color: withOpacity(textColor, 0.8),
141
- fontFamily: font,
142
- lineHeight: 1.2,
143
- whiteSpace: isLandscape ? "normal" : "nowrap",
144
- textAlign: "center",
145
- textTransform: "uppercase",
146
- letterSpacing: isLandscape ? 1 * s : 2 * s,
147
- opacity: labelOpacity,
148
- transform: `translateY(${labelSlideY}px)`
149
- },
150
- children: stat.label
151
- }
152
- )
153
- ]
154
- },
155
- i
156
- );
157
- }) });
158
- };
159
-
160
- // src/visual-system/scene-templates/infographic-stat-row.tsx
161
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
162
- var InfographicStatRowTemplate = ({
163
- variables,
164
- style,
165
- progress,
166
- motionProgress = progress,
167
- beatIntensity,
168
- width,
169
- height,
170
- safeZone,
171
- sceneDuration,
172
- backgroundEffect,
173
- isPlaying = true
174
- }) => {
175
- const { foreground, font } = resolveTokens(style);
176
- const textColor = foreground;
177
- const textsRaw = String(variables.texts || "");
178
- const stats = [
179
- { value: String(variables.stat1Value || ""), label: String(variables.stat1Label || "") },
180
- { value: String(variables.stat2Value || ""), label: String(variables.stat2Label || "") },
181
- { value: String(variables.stat3Value || ""), label: String(variables.stat3Label || "") }
182
- ];
183
- return /* @__PURE__ */ jsxs2(
184
- "div",
185
- {
186
- style: {
187
- width,
188
- height,
189
- backgroundColor: "var(--vanillasky-template-surface, #000)",
190
- position: "relative",
191
- overflow: "hidden",
192
- fontFamily: font
193
- },
194
- children: [
195
- /* @__PURE__ */ jsx2(
196
- SceneBackground,
197
- {
198
- style,
199
- progress,
200
- sceneDuration,
201
- width,
202
- height,
203
- ...getMediaBackgroundProps(variables),
204
- backgroundEffect,
205
- seed: textsRaw,
206
- isPlaying,
207
- beatIntensity
208
- }
209
- ),
210
- /* @__PURE__ */ jsx2(
211
- TemplateText,
212
- {
213
- overMedia: hasSceneMedia(variables),
214
- motionProgress,
215
- typeTreatment: resolveTokens(style).preset.type,
216
- archetype: "subtle",
217
- text: String(variables.texts ?? ""),
218
- progress,
219
- sceneDuration: sceneDuration ?? 3,
220
- width,
221
- height,
222
- position: "top",
223
- sizeRole: "headline",
224
- safeZone,
225
- font,
226
- color: textColor,
227
- beatIntensity
228
- }
229
- ),
230
- /* @__PURE__ */ jsx2(
231
- StatBadgeRow,
232
- {
233
- progress: motionProgress,
234
- stats,
235
- width,
236
- height,
237
- font,
238
- textColor
239
- }
240
- )
241
- ]
242
- }
243
- );
244
- };
245
- export {
246
- InfographicStatRowTemplate
247
- };
@@ -1,406 +0,0 @@
1
- import {
2
- parseList
3
- } from "./chunk-P22HHFDK.js";
4
- import {
5
- fitTextSize,
6
- stripPipe
7
- } from "./chunk-S7HFLYNN.js";
8
- import {
9
- SceneBackground,
10
- getMediaBackgroundProps
11
- } from "./chunk-MXZSDGZQ.js";
12
- import {
13
- TemplateText
14
- } from "./chunk-YJJC4N4D.js";
15
- import {
16
- Emoji
17
- } from "./chunk-L5BTTCZV.js";
18
- import "./chunk-FRN6WKHA.js";
19
- import {
20
- TOP_TEXT_AREA_RATIO,
21
- autoTextColor,
22
- withOpacity
23
- } from "./chunk-W3VDIBGR.js";
24
- import {
25
- interpolate,
26
- spring
27
- } from "./chunk-XTOXFMLM.js";
28
- import {
29
- hasSceneMedia
30
- } from "./chunk-224QNWRA.js";
31
- import "./chunk-5CDAM24P.js";
32
- import {
33
- TOKEN_DEFAULTS,
34
- resolveTokens
35
- } from "./chunk-XWWLKRNU.js";
36
-
37
- // src/visual-system/primitives/infographic/StepsList.tsx
38
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
39
- var SPRING_POP = { damping: 8, stiffness: 200 };
40
- var SPRING_TITLE = { damping: 18, stiffness: 200 };
41
- function computeStepsLayout({
42
- width,
43
- height,
44
- labels,
45
- safeZone = { top: 0, right: 0, bottom: 0, left: 0 }
46
- }) {
47
- const stepCount = Math.max(1, Math.min(labels.length, 4));
48
- const s = Math.min(width, height) / 1080;
49
- const textAreaBottom = Math.max(height * TOP_TEXT_AREA_RATIO, safeZone.top);
50
- if (width > height) {
51
- const availableWidth = Math.max(1, width - safeZone.left - safeZone.right);
52
- const sectionWidth = availableWidth / stepCount;
53
- const circleRadius2 = Math.min(104 * s, sectionWidth * 0.25);
54
- const y = Math.min(
55
- height * 0.55,
56
- height - safeZone.bottom - circleRadius2 - 86 * s
57
- );
58
- return {
59
- mode: "landscape-row",
60
- items: labels.slice(0, 4).map((label, index) => {
61
- const x2 = safeZone.left + sectionWidth * (index + 0.5);
62
- const labelWidth2 = sectionWidth * 0.76;
63
- return {
64
- x: x2,
65
- y,
66
- circleRadius: circleRadius2,
67
- labelLeft: x2 - labelWidth2 / 2,
68
- labelTop: y + circleRadius2 + 20 * s,
69
- labelWidth: labelWidth2,
70
- labelFontSize: fitTextSize(label, 42 * s, labelWidth2, { minScale: 0.72 })
71
- };
72
- })
73
- };
74
- }
75
- const contentTop = textAreaBottom;
76
- const contentBottom = Math.max(contentTop + 1, height - safeZone.bottom);
77
- const rowHeight = (contentBottom - contentTop) / stepCount;
78
- const circleRadius = Math.min(82 * s, rowHeight * 0.27);
79
- const x = safeZone.left + circleRadius + 48 * s;
80
- const labelLeft = x + circleRadius + 42 * s;
81
- const labelWidth = Math.max(1, width - safeZone.right - labelLeft);
82
- return {
83
- mode: "portrait-timeline",
84
- items: labels.slice(0, 4).map((label, index) => {
85
- const y = contentTop + rowHeight * (index + 0.5);
86
- return {
87
- x,
88
- y,
89
- circleRadius,
90
- labelLeft,
91
- labelTop: y - circleRadius,
92
- labelWidth,
93
- labelFontSize: fitTextSize(label, 50 * s, labelWidth, { minScale: 0.68 })
94
- };
95
- })
96
- };
97
- }
98
- var StepsList = ({
99
- progress,
100
- width,
101
- height,
102
- steps,
103
- stepEmojis = [],
104
- accent = TOKEN_DEFAULTS.primary,
105
- textColor = "#ffffff",
106
- font = TOKEN_DEFAULTS.font,
107
- beatIntensity = 0,
108
- safeZone
109
- }) => {
110
- void beatIntensity;
111
- const s = Math.min(width, height) / 1080;
112
- const stepLabels = steps.slice(0, 4).map((st) => stripPipe(String(st.title || "")));
113
- const hasEmojis = stepEmojis.some((e) => (e || "").length > 0);
114
- const isLandscape = width > height;
115
- const layout = computeStepsLayout({ width, height, labels: stepLabels, safeZone });
116
- const connectorPairs = layout.items.slice(0, -1).map((item, index) => ({
117
- item,
118
- next: layout.items[index + 1]
119
- }));
120
- const lineProgress = interpolate(progress, [0.07, 0.62], [0, 1], {
121
- extrapolateLeft: "clamp",
122
- extrapolateRight: "clamp"
123
- });
124
- const firstStep = 0.08;
125
- const EXIT_START = 0.78;
126
- const EXIT_DURATION = 0.1;
127
- const EXIT_STAGGER = 0.04;
128
- const exitForIndex = (i) => {
129
- const start = EXIT_START + i * EXIT_STAGGER;
130
- const raw = interpolate(progress, [start, start + EXIT_DURATION], [0, 1], {
131
- extrapolateLeft: "clamp",
132
- extrapolateRight: "clamp"
133
- });
134
- const eased = raw * raw;
135
- return { translateX: -90 * s * eased, fade: 1 - eased };
136
- };
137
- return /* @__PURE__ */ jsxs(Fragment, { children: [
138
- connectorPairs.map(({ item, next }, index) => {
139
- const exit = exitForIndex(index);
140
- const segmentProgress = interpolate(
141
- lineProgress,
142
- [index / connectorPairs.length, (index + 1) / connectorPairs.length],
143
- [0, 1],
144
- { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
145
- );
146
- return /* @__PURE__ */ jsx(
147
- "div",
148
- {
149
- style: layout.mode === "portrait-timeline" ? {
150
- position: "absolute",
151
- left: item.x - 2 * s,
152
- top: item.y + item.circleRadius,
153
- width: 4 * s,
154
- height: Math.max(
155
- 0,
156
- next.y - next.circleRadius - (item.y + item.circleRadius)
157
- ),
158
- borderRadius: 999,
159
- background: `linear-gradient(to bottom, ${withOpacity(accent, 0.9)}, ${withOpacity(textColor, 0.22)})`,
160
- transform: `translateX(${exit.translateX}px) scaleY(${segmentProgress})`,
161
- transformOrigin: "top",
162
- opacity: 0.75 * exit.fade
163
- } : {
164
- position: "absolute",
165
- left: item.x + item.circleRadius,
166
- top: item.y - 2 * s,
167
- width: Math.max(
168
- 0,
169
- next.x - next.circleRadius - (item.x + item.circleRadius)
170
- ),
171
- height: 4 * s,
172
- borderRadius: 999,
173
- background: `linear-gradient(to right, ${withOpacity(accent, 0.9)}, ${withOpacity(textColor, 0.22)})`,
174
- transform: `translateX(${exit.translateX}px) scaleX(${segmentProgress})`,
175
- transformOrigin: "left",
176
- opacity: 0.75 * exit.fade
177
- }
178
- },
179
- `step-connector-${index}`
180
- );
181
- }),
182
- layout.items.map((pos, i) => {
183
- const circleRadius = pos.circleRadius;
184
- const circleSize = circleRadius * 2;
185
- const emojiFontSize = circleRadius * (isLandscape ? 0.9 : 0.8);
186
- const numberFontSize = circleRadius * 0.7;
187
- const itemStart = firstStep;
188
- const circleP = spring(
189
- interpolate(progress, [itemStart, itemStart + 0.12], [0, 1], {
190
- extrapolateLeft: "clamp",
191
- extrapolateRight: "clamp"
192
- }),
193
- SPRING_POP
194
- );
195
- const circleScale = interpolate(circleP, [0, 1], [0, 1]);
196
- const contentDelay = itemStart + 0.03;
197
- const contentOpacity = interpolate(progress, [contentDelay, contentDelay + 0.05], [0, 1], {
198
- extrapolateLeft: "clamp",
199
- extrapolateRight: "clamp"
200
- });
201
- const titleDelay = itemStart + 0.05;
202
- const titleP = spring(
203
- interpolate(progress, [titleDelay, titleDelay + 0.1], [0, 1], {
204
- extrapolateLeft: "clamp",
205
- extrapolateRight: "clamp"
206
- }),
207
- SPRING_TITLE
208
- );
209
- const titleSlide = isLandscape ? (1 - titleP) * 40 * s : (1 - titleP) * 120 * s;
210
- const titleOpacity = interpolate(progress, [titleDelay, titleDelay + 0.05], [0, 1], {
211
- extrapolateLeft: "clamp",
212
- extrapolateRight: "clamp"
213
- });
214
- const emoji = hasEmojis ? stepEmojis[i] || "" : "";
215
- const glowOpacity = circleScale * 0.2;
216
- const exit = exitForIndex(i);
217
- return /* @__PURE__ */ jsxs(
218
- "div",
219
- {
220
- "data-template-item": "steps",
221
- style: {
222
- position: "absolute",
223
- top: pos.y - circleRadius,
224
- left: 0,
225
- width,
226
- height: circleSize,
227
- transform: `translateX(${exit.translateX}px)`,
228
- opacity: exit.fade
229
- },
230
- children: [
231
- /* @__PURE__ */ jsx(
232
- "div",
233
- {
234
- style: {
235
- position: "absolute",
236
- top: -circleRadius * 0.6,
237
- left: pos.x - circleRadius * 1.75,
238
- width: circleRadius * 3.5,
239
- height: circleRadius * 3.5,
240
- borderRadius: "50%",
241
- background: `radial-gradient(circle, ${withOpacity(accent, 0.4)} 0%, transparent 70%)`,
242
- opacity: glowOpacity,
243
- pointerEvents: "none"
244
- }
245
- }
246
- ),
247
- /* @__PURE__ */ jsx(
248
- "div",
249
- {
250
- style: {
251
- position: "absolute",
252
- left: pos.x - circleRadius,
253
- top: 0,
254
- width: circleSize,
255
- height: circleSize,
256
- borderRadius: "50%",
257
- backgroundColor: emoji ? "rgba(255,255,255,0.15)" : accent,
258
- border: "2px solid rgba(255,255,255,0.2)",
259
- display: "flex",
260
- justifyContent: "center",
261
- alignItems: "center",
262
- transform: `scale(${circleScale})`,
263
- boxShadow: `0 0 ${20 * s}px ${withOpacity(accent, glowOpacity)}`
264
- },
265
- children: emoji ? /* @__PURE__ */ jsx(Emoji, { char: emoji, size: emojiFontSize, verticalAlign: "middle", style: { opacity: contentOpacity } }) : /* @__PURE__ */ jsx(
266
- "span",
267
- {
268
- style: {
269
- fontSize: numberFontSize,
270
- fontWeight: 800,
271
- color: autoTextColor(accent),
272
- fontFamily: font,
273
- lineHeight: 1,
274
- opacity: contentOpacity
275
- },
276
- children: i + 1
277
- }
278
- )
279
- }
280
- ),
281
- /* @__PURE__ */ jsx(
282
- "div",
283
- {
284
- style: {
285
- position: "absolute",
286
- left: pos.labelLeft,
287
- top: pos.labelTop - (pos.y - circleRadius),
288
- width: pos.labelWidth,
289
- height: isLandscape ? 80 * s : circleSize,
290
- display: "flex",
291
- alignItems: isLandscape ? "flex-start" : "center",
292
- justifyContent: isLandscape ? "center" : "flex-start",
293
- fontSize: pos.labelFontSize,
294
- fontWeight: 600,
295
- color: textColor,
296
- fontFamily: font,
297
- letterSpacing: -0.3,
298
- textAlign: isLandscape ? "center" : "left",
299
- opacity: titleOpacity,
300
- transform: isLandscape ? `translateY(${titleSlide}px)` : `translateX(${titleSlide}px)`,
301
- textShadow: "0 1px 6px rgba(0,0,0,0.1)",
302
- lineHeight: 1.12,
303
- whiteSpace: "normal"
304
- },
305
- children: stepLabels[i]
306
- }
307
- )
308
- ]
309
- },
310
- `step-${i}`
311
- );
312
- })
313
- ] });
314
- };
315
-
316
- // src/visual-system/scene-templates/infographic-steps.tsx
317
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
318
- var InfographicStepsTemplate = ({
319
- variables,
320
- style,
321
- progress,
322
- motionProgress = progress,
323
- beatIntensity,
324
- width,
325
- height,
326
- textArchetype,
327
- safeZone,
328
- sceneDuration,
329
- backgroundEffect,
330
- isPlaying
331
- }) => {
332
- const { primary, foreground, font } = resolveTokens(style);
333
- const textColor = foreground;
334
- const textsRaw = String(variables.texts || "");
335
- const stepLabels = parseList(variables.steps, 3);
336
- const stepEmojis = parseList(variables.stepEmojis, 3);
337
- void textArchetype;
338
- return /* @__PURE__ */ jsxs2(
339
- "div",
340
- {
341
- style: {
342
- width,
343
- height,
344
- backgroundColor: "var(--vanillasky-template-surface, #000)",
345
- position: "relative",
346
- overflow: "hidden",
347
- fontFamily: font
348
- },
349
- children: [
350
- /* @__PURE__ */ jsx2(
351
- SceneBackground,
352
- {
353
- style,
354
- progress,
355
- sceneDuration,
356
- width,
357
- height,
358
- ...getMediaBackgroundProps(variables),
359
- backgroundEffect,
360
- seed: textsRaw,
361
- isPlaying,
362
- beatIntensity
363
- }
364
- ),
365
- /* @__PURE__ */ jsx2(
366
- TemplateText,
367
- {
368
- overMedia: hasSceneMedia(variables),
369
- motionProgress,
370
- typeTreatment: resolveTokens(style).preset.type,
371
- archetype: "subtle",
372
- text: String(variables.texts ?? ""),
373
- progress,
374
- sceneDuration: sceneDuration ?? 3,
375
- width,
376
- height,
377
- position: "top",
378
- sizeRole: "headline",
379
- safeZone,
380
- font,
381
- color: textColor,
382
- beatIntensity
383
- }
384
- ),
385
- /* @__PURE__ */ jsx2(
386
- StepsList,
387
- {
388
- progress: motionProgress,
389
- width,
390
- height,
391
- steps: stepLabels.map((title) => ({ title })),
392
- stepEmojis,
393
- accent: primary,
394
- textColor,
395
- font,
396
- beatIntensity,
397
- safeZone
398
- }
399
- )
400
- ]
401
- }
402
- );
403
- };
404
- export {
405
- InfographicStepsTemplate
406
- };