@vanillaskyai/video 0.1.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 (162) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +201 -0
  3. package/PUBLIC-API.md +276 -0
  4. package/README.md +152 -0
  5. package/SECURITY.md +22 -0
  6. package/SUPPORT.md +28 -0
  7. package/bin/vanillasky.js +3 -0
  8. package/dist/bg-confetti-WNQXS7ZS.js +89 -0
  9. package/dist/bg-emoji-ETI47GLS.js +150 -0
  10. package/dist/bg-media-SVUZAMGX.js +99 -0
  11. package/dist/brand-message-F3RD4P3P.js +253 -0
  12. package/dist/builtin-server-F7YXRVCH.js +8 -0
  13. package/dist/catalog-types-BIhSpOWK.d.ts +74 -0
  14. package/dist/chart-bar-CNSC7BNK.js +304 -0
  15. package/dist/chart-counter-MCRHKN77.js +299 -0
  16. package/dist/chart-progress-ring-RMI4A7ZK.js +296 -0
  17. package/dist/check-runtime.d.ts +15 -0
  18. package/dist/check-runtime.js +102 -0
  19. package/dist/chunk-2E6T633S.js +27 -0
  20. package/dist/chunk-352ZZCET.js +83 -0
  21. package/dist/chunk-73NTSFFI.js +81 -0
  22. package/dist/chunk-A2X45FET.js +46 -0
  23. package/dist/chunk-ABPKM4GK.js +187 -0
  24. package/dist/chunk-ABZACD4G.js +216 -0
  25. package/dist/chunk-BCRUUJ6A.js +756 -0
  26. package/dist/chunk-CHLGW22F.js +3551 -0
  27. package/dist/chunk-CJ7F2CE6.js +104 -0
  28. package/dist/chunk-CR7FE7BW.js +109 -0
  29. package/dist/chunk-E7CL7UPB.js +109 -0
  30. package/dist/chunk-EE6PK6XC.js +18 -0
  31. package/dist/chunk-ERY4S6QV.js +385 -0
  32. package/dist/chunk-EVG2ZYIY.js +125 -0
  33. package/dist/chunk-FNAEQ7QO.js +155 -0
  34. package/dist/chunk-FQ47WXAJ.js +38 -0
  35. package/dist/chunk-FSG2PYWG.js +336 -0
  36. package/dist/chunk-GHJEAP4O.js +504 -0
  37. package/dist/chunk-GRMUV7QY.js +262 -0
  38. package/dist/chunk-IFOW65Z6.js +205 -0
  39. package/dist/chunk-IXCUY3B3.js +786 -0
  40. package/dist/chunk-L5BTTCZV.js +97 -0
  41. package/dist/chunk-LMG3GHLL.js +107 -0
  42. package/dist/chunk-OOPIETLW.js +101 -0
  43. package/dist/chunk-P22HHFDK.js +43 -0
  44. package/dist/chunk-QAAO7OAY.js +19 -0
  45. package/dist/chunk-S7HFLYNN.js +35 -0
  46. package/dist/chunk-SPVTJH3F.js +24 -0
  47. package/dist/chunk-W2XJKG6C.js +3177 -0
  48. package/dist/chunk-XB7LH4J2.js +301 -0
  49. package/dist/chunk-XGRA2MUV.js +242 -0
  50. package/dist/chunk-XTOXFMLM.js +105 -0
  51. package/dist/chunk-YC5MFXA5.js +132 -0
  52. package/dist/cli.d.ts +1 -0
  53. package/dist/cli.js +1681 -0
  54. package/dist/compose-video-CN3VSWST.js +13 -0
  55. package/dist/cta-logo-SVA5GP2A.js +209 -0
  56. package/dist/cta-media-E7VLLK42.js +215 -0
  57. package/dist/events-_wfjbmEp.d.ts +81 -0
  58. package/dist/incoming-call-62MFZL3Z.js +320 -0
  59. package/dist/index.d.ts +15 -0
  60. package/dist/index.js +14 -0
  61. package/dist/infographic-before-after-AXCDAWND.js +460 -0
  62. package/dist/infographic-feature-list-GW5GUE6O.js +266 -0
  63. package/dist/infographic-problem-solution-7NURJANA.js +340 -0
  64. package/dist/infographic-stat-row-J7IZR6ZN.js +241 -0
  65. package/dist/infographic-steps-VSZM6F5M.js +400 -0
  66. package/dist/kit-BMNcHqa9.d.ts +79 -0
  67. package/dist/prompt-input-LOUCRXCY.js +236 -0
  68. package/dist/react.d.ts +81 -0
  69. package/dist/react.js +835 -0
  70. package/dist/reaction-QG4CYZLQ.js +119 -0
  71. package/dist/server.d.ts +141 -0
  72. package/dist/server.js +498 -0
  73. package/dist/showcase-code-RUTFZR3H.js +351 -0
  74. package/dist/showcase-phone-6CP6XEU5.js +272 -0
  75. package/dist/showcase-terminal-MGAEQWPR.js +306 -0
  76. package/dist/showcase-web-Y4W2HVRJ.js +390 -0
  77. package/dist/social-conversation-75SD2637.js +695 -0
  78. package/dist/social-milestone-XI2QE5BO.js +292 -0
  79. package/dist/social-notification-2UOHQCUY.js +244 -0
  80. package/dist/social-review-stack-FDYZGZTJ.js +239 -0
  81. package/dist/social-testimonial-OQ7N52GJ.js +284 -0
  82. package/dist/social-tweet-5OLCNPPC.js +295 -0
  83. package/dist/state-DZcKuS32.d.ts +3 -0
  84. package/dist/system-prompt-A6UXNTPK.js +8 -0
  85. package/dist/template-catalog.d.ts +24 -0
  86. package/dist/template-catalog.js +6 -0
  87. package/dist/templates.d.ts +25 -0
  88. package/dist/templates.js +19 -0
  89. package/dist/test.d.ts +149 -0
  90. package/dist/test.js +272 -0
  91. package/dist/text-stream-6XHC7J47.js +10 -0
  92. package/dist/types-B-PZR6G_.d.ts +208 -0
  93. package/dist/validate-T7GBU2YF.js +8 -0
  94. package/docs/agent-integration.md +39 -0
  95. package/docs/architecture.md +84 -0
  96. package/docs/branding-and-personalization.md +87 -0
  97. package/docs/concepts.md +106 -0
  98. package/docs/custom-templates.md +329 -0
  99. package/docs/customization.md +141 -0
  100. package/docs/errors.md +70 -0
  101. package/docs/getting-started.md +111 -0
  102. package/docs/input-and-first-scene.md +41 -0
  103. package/docs/integrate-nextjs.md +79 -0
  104. package/docs/media-and-audio.md +69 -0
  105. package/docs/motion-and-effects.md +107 -0
  106. package/docs/persistence.md +95 -0
  107. package/docs/production.md +122 -0
  108. package/docs/prompt-and-input.md +185 -0
  109. package/docs/provider-integration.md +115 -0
  110. package/docs/reference/protocol.md +96 -0
  111. package/docs/reference/provider-adapters.md +158 -0
  112. package/docs/responsive-orientation.md +37 -0
  113. package/docs/security.md +38 -0
  114. package/docs/streaming-protocol.md +15 -0
  115. package/docs/testing.md +137 -0
  116. package/docs/use-cases.md +59 -0
  117. package/examples/custom-template/README.md +19 -0
  118. package/examples/custom-template/minimal-text.tsx +82 -0
  119. package/examples/custom-template/structured-data.tsx +104 -0
  120. package/examples/custom-template/supplied-media.tsx +92 -0
  121. package/examples/nextjs-quickstart/.env.example +2 -0
  122. package/examples/nextjs-quickstart/README.md +22 -0
  123. package/examples/nextjs-quickstart/next-env.d.ts +4 -0
  124. package/examples/nextjs-quickstart/package.json +24 -0
  125. package/examples/nextjs-quickstart/src/app/api/video/route.ts +22 -0
  126. package/examples/nextjs-quickstart/src/app/layout.tsx +5 -0
  127. package/examples/nextjs-quickstart/src/app/page.tsx +31 -0
  128. package/examples/nextjs-quickstart/tsconfig.json +26 -0
  129. package/package.json +167 -0
  130. package/registry/items/backgrounds.json +52 -0
  131. package/registry/items/barChart.json +237 -0
  132. package/registry/items/beforeAfter.json +180 -0
  133. package/registry/items/bigNumber.json +225 -0
  134. package/registry/items/brandMessage.json +158 -0
  135. package/registry/items/cardList.json +206 -0
  136. package/registry/items/chatMessenger.json +151 -0
  137. package/registry/items/chatWhatsapp.json +151 -0
  138. package/registry/items/codeEditor.json +184 -0
  139. package/registry/items/confetti.json +107 -0
  140. package/registry/items/ctaLogo.json +160 -0
  141. package/registry/items/ctaMedia.json +193 -0
  142. package/registry/items/emojiBurst.json +101 -0
  143. package/registry/items/incomingCall.json +170 -0
  144. package/registry/items/media.json +179 -0
  145. package/registry/items/milestone.json +205 -0
  146. package/registry/items/motion.json +45 -0
  147. package/registry/items/notification.json +182 -0
  148. package/registry/items/phoneMockup.json +254 -0
  149. package/registry/items/problemSolution.json +186 -0
  150. package/registry/items/progressRing.json +199 -0
  151. package/registry/items/promptInput.json +148 -0
  152. package/registry/items/reaction.json +170 -0
  153. package/registry/items/reviewStack.json +224 -0
  154. package/registry/items/steps.json +207 -0
  155. package/registry/items/template-context.json +31 -0
  156. package/registry/items/terminal.json +212 -0
  157. package/registry/items/testimonial.json +164 -0
  158. package/registry/items/theme.json +47 -0
  159. package/registry/items/tripleStats.json +228 -0
  160. package/registry/items/tweet.json +203 -0
  161. package/registry/items/typography.json +47 -0
  162. package/registry/items/webMockup.json +273 -0
@@ -0,0 +1,239 @@
1
+ import {
2
+ stripPipe
3
+ } from "./chunk-S7HFLYNN.js";
4
+ import {
5
+ SceneBackground,
6
+ getMediaBackgroundProps
7
+ } from "./chunk-IFOW65Z6.js";
8
+ import {
9
+ accessibleTextColor,
10
+ withOpacity
11
+ } from "./chunk-ABZACD4G.js";
12
+ import {
13
+ SPRING_SNAPPY,
14
+ interpolate,
15
+ spring
16
+ } from "./chunk-XTOXFMLM.js";
17
+ import {
18
+ lighten,
19
+ resolveTokens
20
+ } from "./chunk-FNAEQ7QO.js";
21
+
22
+ // src/visual-system/primitives/social/ReviewStack.tsx
23
+ import { jsx, jsxs } from "react/jsx-runtime";
24
+ var CLAMP = {
25
+ extrapolateLeft: "clamp",
26
+ extrapolateRight: "clamp"
27
+ };
28
+ var ROTATIONS = [-1.4, 0.8, -0.7, 1.1, -0.9];
29
+ var ReviewStack = ({
30
+ progress,
31
+ width,
32
+ height,
33
+ reviews,
34
+ starColor = "#facc15",
35
+ surfaceElevated,
36
+ foreground,
37
+ muted,
38
+ beatIntensity = 0
39
+ }) => {
40
+ const dim = Math.min(width, height);
41
+ const s = dim / 1080;
42
+ const cardBg = surfaceElevated || lighten("#0a0a0f", 0.08);
43
+ const borderColor = lighten("#0a0a0f", 0.15);
44
+ const textPrimary = accessibleTextColor(cardBg, foreground);
45
+ const textSecondary = accessibleTextColor(cardBg, muted);
46
+ const isPortrait = height > width;
47
+ const cardWidth = Math.min(
48
+ width * (isPortrait ? 0.82 : 0.64),
49
+ dim * (isPortrait ? 0.78 : 0.9)
50
+ );
51
+ const cardPad = dim * 0.028;
52
+ const rowGap = Math.min(
53
+ dim * 0.28,
54
+ height * 0.55 / Math.max(reviews.length - 1, 1)
55
+ );
56
+ const beatScale = 1 + beatIntensity * 0.01;
57
+ return /* @__PURE__ */ jsx(
58
+ "div",
59
+ {
60
+ style: {
61
+ position: "absolute",
62
+ inset: 0,
63
+ display: "flex",
64
+ alignItems: "center",
65
+ justifyContent: "center"
66
+ },
67
+ children: reviews.map((review, i) => {
68
+ const cardStart = 0.02 + i * 0.1;
69
+ const cardEnd = cardStart + 0.16;
70
+ const cardP = spring(
71
+ interpolate(progress, [cardStart, cardEnd], [0, 1], CLAMP),
72
+ SPRING_SNAPPY
73
+ );
74
+ const cardScale = interpolate(cardP, [0, 1], [0.9, 1]);
75
+ const cardOpacity = Math.min(1, cardP);
76
+ const cardX = interpolate(cardP, [0, 1], [(i % 2 === 0 ? -1 : 1) * 54 * s, 0]);
77
+ const rotation = ROTATIONS[i % ROTATIONS.length];
78
+ const rowOffset = (i - (reviews.length - 1) / 2) * rowGap;
79
+ const stars = review.stars == null ? 5 : Math.max(0, Math.min(5, Math.round(review.stars)));
80
+ const title = stripPipe(review.title || review.quote || "");
81
+ const body = stripPipe(review.body || "");
82
+ const author = stripPipe(review.author || "");
83
+ return /* @__PURE__ */ jsxs(
84
+ "div",
85
+ {
86
+ "data-review-card": i,
87
+ style: {
88
+ position: "absolute",
89
+ width: cardWidth,
90
+ padding: cardPad,
91
+ backgroundColor: cardBg,
92
+ borderRadius: dim * 0.018,
93
+ border: `1px solid ${borderColor}`,
94
+ boxShadow: `0 ${dim * 0.01}px ${dim * 0.04}px rgba(0,0,0,0.4)`,
95
+ transform: `translateX(${cardX}px) translateY(${rowOffset}px) rotate(${rotation}deg) scale(${cardScale * beatScale})`,
96
+ opacity: cardOpacity,
97
+ zIndex: i,
98
+ top: "50%",
99
+ left: "50%",
100
+ marginLeft: -(cardWidth / 2),
101
+ marginTop: -(dim * 0.11)
102
+ },
103
+ children: [
104
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 3 * s, marginBottom: dim * 0.011 }, children: Array.from({ length: 5 }).map((_, si) => /* @__PURE__ */ jsx(
105
+ "span",
106
+ {
107
+ style: {
108
+ color: si < stars ? starColor : withOpacity(textPrimary, 0.15),
109
+ fontSize: dim * 0.03,
110
+ lineHeight: 1
111
+ },
112
+ children: "\u2605"
113
+ },
114
+ si
115
+ )) }),
116
+ /* @__PURE__ */ jsx(
117
+ "div",
118
+ {
119
+ style: {
120
+ fontSize: dim * 0.034,
121
+ fontWeight: 700,
122
+ color: textPrimary,
123
+ marginBottom: dim * 9e-3,
124
+ lineHeight: 1.3
125
+ },
126
+ children: title
127
+ }
128
+ ),
129
+ body && /* @__PURE__ */ jsx(
130
+ "div",
131
+ {
132
+ style: {
133
+ fontSize: dim * 0.026,
134
+ color: textSecondary,
135
+ lineHeight: 1.5,
136
+ marginBottom: dim * 0.014
137
+ },
138
+ children: body
139
+ }
140
+ ),
141
+ author && /* @__PURE__ */ jsx(
142
+ "div",
143
+ {
144
+ style: {
145
+ fontSize: dim * 0.024,
146
+ color: textSecondary,
147
+ fontWeight: 500
148
+ },
149
+ children: author
150
+ }
151
+ )
152
+ ]
153
+ },
154
+ i
155
+ );
156
+ })
157
+ }
158
+ );
159
+ };
160
+
161
+ // src/visual-system/scene-templates/social-review-stack.tsx
162
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
163
+ function buildReviews(variables) {
164
+ const reviews = [];
165
+ for (let i = 1; i <= 3; i++) {
166
+ const title = String(variables[`review${i}Title`] || "");
167
+ if (!title) continue;
168
+ reviews.push({
169
+ title,
170
+ body: String(variables[`review${i}Body`] || ""),
171
+ author: String(variables[`review${i}Author`] || "")
172
+ });
173
+ }
174
+ return reviews;
175
+ }
176
+ var SocialReviewStackTemplate = ({
177
+ variables,
178
+ style,
179
+ progress,
180
+ beatIntensity,
181
+ width,
182
+ height,
183
+ sceneDuration,
184
+ isPlaying = true
185
+ }) => {
186
+ const { font, foreground, surfaceElevated, muted } = resolveTokens(style);
187
+ const starColor = "#facc15";
188
+ const reviews = buildReviews(variables);
189
+ const gradSeed = String(variables.review1Title || "review").split("").reduce((acc, c) => acc + c.charCodeAt(0), 0);
190
+ return /* @__PURE__ */ jsxs2(
191
+ "div",
192
+ {
193
+ style: {
194
+ width,
195
+ height,
196
+ backgroundColor: "#000",
197
+ position: "relative",
198
+ overflow: "hidden",
199
+ fontFamily: font,
200
+ display: "flex",
201
+ alignItems: "center",
202
+ justifyContent: "center"
203
+ },
204
+ children: [
205
+ /* @__PURE__ */ jsx2(
206
+ SceneBackground,
207
+ {
208
+ style,
209
+ progress,
210
+ sceneDuration,
211
+ width,
212
+ height,
213
+ ...getMediaBackgroundProps(variables),
214
+ seed: gradSeed,
215
+ isPlaying,
216
+ beatIntensity
217
+ }
218
+ ),
219
+ /* @__PURE__ */ jsx2(
220
+ ReviewStack,
221
+ {
222
+ progress,
223
+ width,
224
+ height,
225
+ reviews,
226
+ starColor,
227
+ surfaceElevated,
228
+ foreground,
229
+ muted,
230
+ beatIntensity
231
+ }
232
+ )
233
+ ]
234
+ }
235
+ );
236
+ };
237
+ export {
238
+ SocialReviewStackTemplate
239
+ };
@@ -0,0 +1,284 @@
1
+ import {
2
+ stripPipe
3
+ } from "./chunk-S7HFLYNN.js";
4
+ import {
5
+ SceneBackground,
6
+ getMediaBackgroundProps
7
+ } from "./chunk-IFOW65Z6.js";
8
+ import {
9
+ accessibleTextColor,
10
+ autoTextColor,
11
+ withOpacity
12
+ } from "./chunk-ABZACD4G.js";
13
+ import {
14
+ SPRING_SMOOTH,
15
+ SPRING_SNAPPY,
16
+ interpolate,
17
+ spring
18
+ } from "./chunk-XTOXFMLM.js";
19
+ import {
20
+ TOKEN_DEFAULTS,
21
+ lighten,
22
+ resolveTokens
23
+ } from "./chunk-FNAEQ7QO.js";
24
+
25
+ // src/visual-system/primitives/social/TestimonialCard.tsx
26
+ import { jsx, jsxs } from "react/jsx-runtime";
27
+ var CLAMP = { extrapolateLeft: "clamp", extrapolateRight: "clamp" };
28
+ var TestimonialCard = ({
29
+ progress,
30
+ quote: rawQuote,
31
+ authorName: rawAuthorName,
32
+ authorRole: rawAuthorRole = "",
33
+ avatarColor = "#ec4899",
34
+ accent = TOKEN_DEFAULTS.primary,
35
+ surfaceElevated,
36
+ foreground,
37
+ muted,
38
+ width,
39
+ height,
40
+ beatIntensity = 0
41
+ }) => {
42
+ const dim = Math.min(width, height);
43
+ const s = dim / 1080;
44
+ const quote = stripPipe(rawQuote || "");
45
+ const authorName = stripPipe(rawAuthorName || "");
46
+ const authorRole = stripPipe(rawAuthorRole || "");
47
+ const initialChar = authorName.charAt(0).toUpperCase();
48
+ const cardBg = surfaceElevated || lighten("#0a0a0f", 0.08);
49
+ const borderColor = lighten("#0a0a0f", 0.15);
50
+ const textPrimary = accessibleTextColor(cardBg, foreground);
51
+ const textSecondary = accessibleTextColor(cardBg, muted);
52
+ const quoteMarkP = spring(interpolate(progress, [0.02, 0.2], [0, 1], CLAMP), SPRING_SNAPPY);
53
+ const quoteMarkScale = interpolate(quoteMarkP, [0, 1], [0.3, 1]);
54
+ const quoteMarkOpacity = quoteMarkP;
55
+ const lineWidth = interpolate(progress, [0.35, 0.55], [0, 100], CLAMP);
56
+ const authorP = spring(interpolate(progress, [0.45, 0.7], [0, 1], CLAMP), SPRING_SMOOTH);
57
+ const authorY = interpolate(authorP, [0, 1], [20 * s, 0]);
58
+ const authorOpacity = authorP;
59
+ const cardWidth = Math.min(width * 0.75, dim * 0.85);
60
+ const cardPad = dim * 0.045;
61
+ const avatarSize = dim * 0.055;
62
+ const cardP = spring(interpolate(progress, [0, 0.15], [0, 1], CLAMP), SPRING_SMOOTH);
63
+ const cardScale = interpolate(cardP, [0, 1], [0.92, 1]);
64
+ const cardOpacity = interpolate(cardP, [0, 1], [0, 1]);
65
+ const beatScale = 1 + beatIntensity * 0.01;
66
+ return /* @__PURE__ */ jsx(
67
+ "div",
68
+ {
69
+ style: {
70
+ position: "absolute",
71
+ inset: 0,
72
+ display: "flex",
73
+ alignItems: "center",
74
+ justifyContent: "center"
75
+ },
76
+ children: /* @__PURE__ */ jsxs(
77
+ "div",
78
+ {
79
+ style: {
80
+ width: cardWidth,
81
+ padding: cardPad,
82
+ backgroundColor: cardBg,
83
+ borderRadius: dim * 0.02,
84
+ border: `1px solid ${borderColor}`,
85
+ boxShadow: `0 ${dim * 0.01}px ${dim * 0.04}px rgba(0,0,0,0.4)`,
86
+ position: "relative",
87
+ zIndex: 1,
88
+ transform: `scale(${cardScale * beatScale})`,
89
+ opacity: cardOpacity
90
+ },
91
+ children: [
92
+ /* @__PURE__ */ jsx(
93
+ "div",
94
+ {
95
+ style: {
96
+ fontSize: dim * 0.08,
97
+ lineHeight: 0.8,
98
+ color: accent,
99
+ fontWeight: 700,
100
+ marginBottom: dim * 0.018,
101
+ transform: `scale(${quoteMarkScale})`,
102
+ opacity: quoteMarkOpacity,
103
+ transformOrigin: "left top"
104
+ },
105
+ children: "\u201C"
106
+ }
107
+ ),
108
+ /* @__PURE__ */ jsx(
109
+ "div",
110
+ {
111
+ style: {
112
+ fontSize: dim * 0.038,
113
+ lineHeight: 1.6,
114
+ color: textPrimary,
115
+ fontWeight: 500,
116
+ marginBottom: dim * 0.032,
117
+ display: "flex",
118
+ flexWrap: "wrap",
119
+ gap: `0 ${dim * 7e-3}px`
120
+ },
121
+ children: quote.split(/\s+/).filter(Boolean).map((word, i, arr) => {
122
+ const wStart = 0.2 + i * (0.3 / Math.max(arr.length, 1));
123
+ const wEnd = Math.min(wStart + 0.08, 0.55);
124
+ const wordOpacity = interpolate(progress, [wStart, wEnd], [0, 1], CLAMP);
125
+ const wordY = interpolate(progress, [wStart, wEnd], [8 * s, 0], CLAMP);
126
+ return /* @__PURE__ */ jsx(
127
+ "span",
128
+ {
129
+ style: {
130
+ opacity: wordOpacity,
131
+ transform: `translateY(${wordY}px)`,
132
+ display: "inline-block"
133
+ },
134
+ children: word
135
+ },
136
+ i
137
+ );
138
+ })
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", marginBottom: dim * 0.028 }, children: /* @__PURE__ */ jsx("div", { style: { height: 1, width: `${lineWidth}%`, backgroundColor: borderColor } }) }),
142
+ /* @__PURE__ */ jsxs(
143
+ "div",
144
+ {
145
+ style: {
146
+ display: "flex",
147
+ alignItems: "center",
148
+ gap: dim * 0.016,
149
+ opacity: authorOpacity,
150
+ transform: `translateY(${authorY}px)`
151
+ },
152
+ children: [
153
+ /* @__PURE__ */ jsx(
154
+ "div",
155
+ {
156
+ style: {
157
+ width: avatarSize,
158
+ height: avatarSize,
159
+ borderRadius: "50%",
160
+ backgroundColor: avatarColor,
161
+ display: "flex",
162
+ alignItems: "center",
163
+ justifyContent: "center",
164
+ fontSize: avatarSize * 0.45,
165
+ fontWeight: 700,
166
+ color: autoTextColor(avatarColor),
167
+ flexShrink: 0
168
+ },
169
+ children: initialChar
170
+ }
171
+ ),
172
+ /* @__PURE__ */ jsxs("div", { children: [
173
+ /* @__PURE__ */ jsx(
174
+ "div",
175
+ {
176
+ style: {
177
+ fontSize: dim * 0.032,
178
+ fontWeight: 600,
179
+ color: textPrimary,
180
+ marginBottom: dim * 3e-3
181
+ },
182
+ children: authorName
183
+ }
184
+ ),
185
+ authorRole && /* @__PURE__ */ jsx("div", { style: { fontSize: dim * 0.024, color: textSecondary }, children: authorRole })
186
+ ] })
187
+ ]
188
+ }
189
+ )
190
+ ]
191
+ }
192
+ )
193
+ }
194
+ );
195
+ };
196
+
197
+ // src/visual-system/scene-templates/social-testimonial.tsx
198
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
199
+ var SocialTestimonialTemplate = ({
200
+ variables,
201
+ style,
202
+ progress,
203
+ beatIntensity,
204
+ width,
205
+ height,
206
+ sceneDuration,
207
+ isPlaying = true
208
+ }) => {
209
+ const dim = Math.min(width, height);
210
+ const { primary, foreground, font, surfaceElevated, muted } = resolveTokens(style);
211
+ const quote = stripPipe(String(variables.quote || ""));
212
+ const gradSeed = quote.split("").reduce((acc, c) => acc + c.charCodeAt(0), 0);
213
+ const authorName = String(variables.authorName || "Jessica Torres");
214
+ const authorRole = String(variables.authorRole || "");
215
+ const avatarBg = primary;
216
+ return /* @__PURE__ */ jsxs2(
217
+ "div",
218
+ {
219
+ style: {
220
+ width,
221
+ height,
222
+ backgroundColor: "#000",
223
+ position: "relative",
224
+ overflow: "hidden",
225
+ fontFamily: font,
226
+ display: "flex",
227
+ alignItems: "center",
228
+ justifyContent: "center"
229
+ },
230
+ children: [
231
+ /* @__PURE__ */ jsx2(
232
+ SceneBackground,
233
+ {
234
+ style,
235
+ progress,
236
+ sceneDuration,
237
+ width,
238
+ height,
239
+ ...getMediaBackgroundProps(variables),
240
+ seed: gradSeed,
241
+ isPlaying,
242
+ beatIntensity
243
+ }
244
+ ),
245
+ /* @__PURE__ */ jsx2(
246
+ "div",
247
+ {
248
+ style: {
249
+ position: "absolute",
250
+ width: dim * 0.9,
251
+ height: dim * 0.7,
252
+ borderRadius: "50%",
253
+ background: `radial-gradient(ellipse, ${withOpacity(primary, 0.15)} 0%, ${withOpacity(primary, 0.05)} 40%, transparent 70%)`,
254
+ top: "50%",
255
+ left: "50%",
256
+ transform: "translate(-50%, -50%)",
257
+ pointerEvents: "none"
258
+ }
259
+ }
260
+ ),
261
+ /* @__PURE__ */ jsx2(
262
+ TestimonialCard,
263
+ {
264
+ progress,
265
+ quote,
266
+ authorName,
267
+ authorRole,
268
+ avatarColor: avatarBg,
269
+ accent: primary,
270
+ surfaceElevated,
271
+ foreground,
272
+ muted,
273
+ width,
274
+ height,
275
+ beatIntensity
276
+ }
277
+ )
278
+ ]
279
+ }
280
+ );
281
+ };
282
+ export {
283
+ SocialTestimonialTemplate
284
+ };