@vanillaskyai/video 0.8.7 → 0.9.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 (175) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/PUBLIC-API.md +5 -8
  3. package/dist/{builtin-server-CUYPIDE7.js → builtin-server-HW6HGXCZ.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 +6 -15
  7. package/dist/{chunk-2USVB3CY.js → chunk-3ZTEFJIR.js} +285 -178
  8. package/dist/chunk-4YM2M62S.js +13 -0
  9. package/dist/chunk-77VY4O7A.js +390 -0
  10. package/dist/{chunk-MMUXVA47.js → chunk-7M56IUUX.js} +9 -8
  11. package/dist/chunk-7NZOMTAL.js +63 -0
  12. package/dist/{chunk-2DOLF4QN.js → chunk-AUPC6MDK.js} +12 -14
  13. package/dist/{chunk-352ZZCET.js → chunk-EGVQODKU.js} +2 -2
  14. package/dist/chunk-EWWCQFTI.js +18 -0
  15. package/dist/{chunk-MXZSDGZQ.js → chunk-G7IZBBWF.js} +14 -9
  16. package/dist/{chunk-KT3M7KDL.js → chunk-HKUI5BTB.js} +3 -3
  17. package/dist/{chunk-LMG3GHLL.js → chunk-IQMYK5DX.js} +29 -3
  18. package/dist/chunk-LH4BPALA.js +564 -0
  19. package/dist/{chunk-OWBT45EN.js → chunk-MQILEEXC.js} +1 -1
  20. package/dist/chunk-MXEYPK7M.js +552 -0
  21. package/dist/{chunk-AITKH6QT.js → chunk-OR52UMSF.js} +13 -39
  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-224QNWRA.js → chunk-UDIODEDK.js} +1 -5
  28. package/dist/{chunk-3VRMKFM7.js → chunk-ZDJNFA52.js} +11 -24
  29. package/dist/cinema-media-YQHSIFDA.js +11 -0
  30. package/dist/cli.js +18 -9
  31. package/dist/comparison-RZMMHZR2.js +27 -0
  32. package/dist/compose-video-TBFTONUC.js +12 -0
  33. package/dist/editorial-timeline-OZX7OS6G.js +36 -0
  34. package/dist/{events-BQ6z264n.d.ts → events-B4YCc4vc.d.ts} +1 -1
  35. package/dist/focus-cards-TJ72BT7U.js +20 -0
  36. package/dist/index.d.ts +4 -6
  37. package/dist/index.js +3 -7
  38. package/dist/key-figure-GYENXKH3.js +20 -0
  39. package/dist/{kit-tQnCPMOM.d.ts → kit-DrRpdn0p.d.ts} +2 -2
  40. package/dist/mobile-message-UZUPIKHD.js +49 -0
  41. package/dist/{preload-media-LJXWKTWG.js → preload-media-CFTZIMZL.js} +1 -1
  42. package/dist/quote-EW5HQA6H.js +23 -0
  43. package/dist/react.d.ts +21 -11
  44. package/dist/react.js +608 -851
  45. package/dist/scene-video-backdrop-PCTARAAJ.js +7 -0
  46. package/dist/server.d.ts +7 -8
  47. package/dist/server.js +91 -74
  48. package/dist/{system-prompt-RRXIWDDD.js → system-prompt-SYRT5DWM.js} +1 -1
  49. package/dist/template-catalog.d.ts +257 -16
  50. package/dist/template-catalog.js +1 -1
  51. package/dist/templates.d.ts +5 -5
  52. package/dist/test.d.ts +3 -3
  53. package/dist/test.js +18 -18
  54. package/dist/text-stream-LD364KBI.js +9 -0
  55. package/dist/{types-DWFO6qca.d.ts → types-CdBmNTGD.d.ts} +1 -1
  56. package/dist/{types-CEh9eUFu.d.ts → types-DdZw4GRQ.d.ts} +17 -48
  57. package/dist/validate-4OUD2CLX.js +10 -0
  58. package/docs/architecture.md +1 -1
  59. package/docs/concepts.md +1 -1
  60. package/docs/custom-templates.md +13 -28
  61. package/docs/customization.md +11 -59
  62. package/docs/getting-started.md +2 -2
  63. package/docs/immersive-interface.md +3 -4
  64. package/docs/maintainers/cinematic-migration.md +34 -0
  65. package/docs/media-and-audio.md +14 -14
  66. package/docs/motion-and-effects.md +6 -14
  67. package/docs/persistence.md +3 -3
  68. package/docs/production.md +11 -9
  69. package/docs/provider-integration.md +9 -16
  70. package/docs/reference/design-system.html +3 -3
  71. package/docs/reference/protocol.md +14 -4
  72. package/docs/testing.md +1 -1
  73. package/package.json +6 -3
  74. package/registry/items/backgrounds.json +1 -1
  75. package/registry/items/chapterTitle.json +80 -0
  76. package/registry/items/cinemaMedia.json +136 -0
  77. package/registry/items/comparison.json +101 -0
  78. package/registry/items/editorialTimeline.json +105 -0
  79. package/registry/items/focusCards.json +90 -0
  80. package/registry/items/keyFigure.json +97 -0
  81. package/registry/items/mobileMessage.json +153 -0
  82. package/registry/items/quote.json +94 -0
  83. package/registry/items/template-context.json +1 -1
  84. package/registry/items/theme.json +1 -1
  85. package/starters/video-chat/README.md +24 -26
  86. package/starters/video-chat/package.json +1 -1
  87. package/starters/video-chat/providers/video.ts +6 -5
  88. package/starters/video-chat/stock.ts +35 -151
  89. package/styles/fonts/OFL.txt +93 -0
  90. package/styles/fonts/manifest.json +66 -0
  91. package/styles/fonts/roboto-v51-cyrillic-ext.woff2 +0 -0
  92. package/styles/fonts/roboto-v51-cyrillic.woff2 +0 -0
  93. package/styles/fonts/roboto-v51-greek-ext.woff2 +0 -0
  94. package/styles/fonts/roboto-v51-greek.woff2 +0 -0
  95. package/styles/fonts/roboto-v51-latin-ext.woff2 +0 -0
  96. package/styles/fonts/roboto-v51-latin.woff2 +0 -0
  97. package/styles/fonts/roboto-v51-math.woff2 +0 -0
  98. package/styles/fonts/roboto-v51-symbols.woff2 +0 -0
  99. package/styles/fonts/roboto-v51-vietnamese.woff2 +0 -0
  100. package/styles/fonts/roboto.css +91 -0
  101. package/styles/video-chat.css +30 -23
  102. package/dist/bg-confetti-HITCGLGD.js +0 -89
  103. package/dist/bg-emoji-VU4UZYZN.js +0 -150
  104. package/dist/bg-media-L34PDQXJ.js +0 -106
  105. package/dist/brand-message-FUJ4STFO.js +0 -256
  106. package/dist/chart-bar-EGPHJATL.js +0 -310
  107. package/dist/chart-counter-5FFWQNZO.js +0 -306
  108. package/dist/chart-progress-ring-JMXQLMLC.js +0 -302
  109. package/dist/chunk-4UNKZEAT.js +0 -3575
  110. package/dist/chunk-5CDAM24P.js +0 -31
  111. package/dist/chunk-AOWSXU2K.js +0 -18
  112. package/dist/chunk-CJ7F2CE6.js +0 -104
  113. package/dist/chunk-FRN6WKHA.js +0 -185
  114. package/dist/chunk-G5JPHBX7.js +0 -336
  115. package/dist/chunk-L5BTTCZV.js +0 -97
  116. package/dist/chunk-P22HHFDK.js +0 -43
  117. package/dist/chunk-PP3MCPN4.js +0 -1998
  118. package/dist/chunk-QAAO7OAY.js +0 -19
  119. package/dist/chunk-S7HFLYNN.js +0 -35
  120. package/dist/chunk-W3VDIBGR.js +0 -217
  121. package/dist/chunk-XGRA2MUV.js +0 -242
  122. package/dist/chunk-XTOXFMLM.js +0 -105
  123. package/dist/chunk-YJJC4N4D.js +0 -761
  124. package/dist/compose-video-2NFH4DZY.js +0 -13
  125. package/dist/cta-logo-YR7LYUR5.js +0 -212
  126. package/dist/cta-media-DQJBKUO2.js +0 -221
  127. package/dist/incoming-call-54KQ7O5A.js +0 -323
  128. package/dist/infographic-before-after-ROS52GOW.js +0 -460
  129. package/dist/infographic-feature-list-E7MGUDAN.js +0 -272
  130. package/dist/infographic-problem-solution-3S6NGO5N.js +0 -343
  131. package/dist/infographic-stat-row-SYB7AB7H.js +0 -247
  132. package/dist/infographic-steps-KCE6JWE2.js +0 -406
  133. package/dist/prompt-input-MHX4O42G.js +0 -239
  134. package/dist/reaction-SLEGR3BE.js +0 -122
  135. package/dist/scene-video-backdrop-XFPX4O3I.js +0 -10
  136. package/dist/showcase-code-2HLAVKBM.js +0 -357
  137. package/dist/showcase-phone-Q4HEO4LH.js +0 -278
  138. package/dist/showcase-terminal-DL45LUFG.js +0 -312
  139. package/dist/showcase-web-2QZO73FZ.js +0 -396
  140. package/dist/social-conversation-75SD2637.js +0 -695
  141. package/dist/social-milestone-GEFUQSBF.js +0 -296
  142. package/dist/social-notification-FJ5VHVLK.js +0 -247
  143. package/dist/social-review-stack-KXQCKFRP.js +0 -242
  144. package/dist/social-testimonial-JZ7CHC7S.js +0 -287
  145. package/dist/social-tweet-UCDXM25F.js +0 -298
  146. package/dist/text-stream-54LXABJW.js +0 -10
  147. package/dist/validate-T7GBU2YF.js +0 -8
  148. package/registry/items/barChart.json +0 -245
  149. package/registry/items/beforeAfter.json +0 -180
  150. package/registry/items/bigNumber.json +0 -232
  151. package/registry/items/brandMessage.json +0 -164
  152. package/registry/items/cardList.json +0 -214
  153. package/registry/items/chatMessenger.json +0 -151
  154. package/registry/items/chatWhatsapp.json +0 -151
  155. package/registry/items/codeEditor.json +0 -191
  156. package/registry/items/confetti.json +0 -107
  157. package/registry/items/ctaLogo.json +0 -167
  158. package/registry/items/ctaMedia.json +0 -200
  159. package/registry/items/emojiBurst.json +0 -101
  160. package/registry/items/incomingCall.json +0 -177
  161. package/registry/items/media.json +0 -187
  162. package/registry/items/milestone.json +0 -212
  163. package/registry/items/notification.json +0 -189
  164. package/registry/items/phoneMockup.json +0 -261
  165. package/registry/items/problemSolution.json +0 -193
  166. package/registry/items/progressRing.json +0 -206
  167. package/registry/items/promptInput.json +0 -155
  168. package/registry/items/reaction.json +0 -176
  169. package/registry/items/reviewStack.json +0 -231
  170. package/registry/items/steps.json +0 -215
  171. package/registry/items/terminal.json +0 -219
  172. package/registry/items/testimonial.json +0 -171
  173. package/registry/items/tripleStats.json +0 -235
  174. package/registry/items/tweet.json +0 -210
  175. package/registry/items/webMockup.json +0 -280
@@ -1,150 +0,0 @@
1
- import {
2
- getCelebrationParticleTiming
3
- } from "./chunk-QAAO7OAY.js";
4
- import {
5
- TemplateText
6
- } from "./chunk-YJJC4N4D.js";
7
- import {
8
- Emoji
9
- } from "./chunk-L5BTTCZV.js";
10
- import {
11
- BrandGradientOverlay
12
- } from "./chunk-W3VDIBGR.js";
13
- import "./chunk-XTOXFMLM.js";
14
- import {
15
- resolveTokens
16
- } from "./chunk-XWWLKRNU.js";
17
-
18
- // src/visual-system/scene-templates/bg-emoji.tsx
19
- import { jsx, jsxs } from "react/jsx-runtime";
20
- function seededRandom(seed) {
21
- const x = Math.sin(seed * 12.9898 + seed * 78.233) * 43758.5453;
22
- return x - Math.floor(x);
23
- }
24
- var EMOJI_LIST = [
25
- "\u2764\uFE0F",
26
- // red heart
27
- "\u2B50",
28
- // star
29
- "\u{1F389}",
30
- // party popper
31
- "\u{1F984}",
32
- // unicorn
33
- "\u{1F525}",
34
- // fire
35
- "\u2728",
36
- // sparkles
37
- "\u{1F680}",
38
- // rocket
39
- "\u{1F49C}"
40
- // purple heart
41
- ];
42
- var PARTICLE_COUNT = 100;
43
- function easeOutQuad(p) {
44
- return 1 - (1 - p) * (1 - p);
45
- }
46
- var BgEmojiTemplate = ({
47
- variables,
48
- style,
49
- progress,
50
- motionProgress = progress,
51
- beatIntensity,
52
- width,
53
- height,
54
- textArchetype,
55
- safeZone,
56
- sceneDuration
57
- }) => {
58
- const s = Math.min(width, height) / 1080;
59
- const BURST_RADIUS = Math.max(width, height) * 0.95;
60
- const { foreground, font } = resolveTokens(style);
61
- const textColor = foreground;
62
- return /* @__PURE__ */ jsxs(
63
- "div",
64
- {
65
- style: {
66
- width,
67
- height,
68
- backgroundColor: "var(--vanillasky-template-surface, #000)",
69
- position: "relative",
70
- overflow: "hidden",
71
- fontFamily: font
72
- },
73
- children: [
74
- /* @__PURE__ */ jsx(BrandGradientOverlay, { style, progress, sceneDuration, seed: String(variables.texts || "").split("").reduce((acc, c) => acc + c.charCodeAt(0), 0) }),
75
- Array.from({ length: PARTICLE_COUNT }, (_, i) => {
76
- const seed = i + 1;
77
- const angle = i / PARTICLE_COUNT * Math.PI * 2;
78
- const forceFactor = 0.75 + seededRandom(seed * 1) * 0.5;
79
- const durationFactor = 1.1 + seededRandom(seed * 3) * 0.6;
80
- const emoji = EMOJI_LIST[i % EMOJI_LIST.length];
81
- const startRot = seededRandom(seed * 5) * 60 - 30;
82
- const rotSpeed = (seededRandom(seed * 6) - 0.5) * 540;
83
- const sizeJitter = 0.7 + seededRandom(seed * 7) * 0.7;
84
- const timing = getCelebrationParticleTiming(motionProgress, i, durationFactor);
85
- if (!timing) return null;
86
- const p = timing.progress;
87
- const reach = BURST_RADIUS * forceFactor;
88
- const radialP = easeOutQuad(p);
89
- const gravity = height * 0.08 * p * p;
90
- const x = width * 0.5 + Math.cos(angle) * reach * radialP;
91
- const y = height * 0.5 + Math.sin(angle) * reach * radialP + gravity;
92
- const baseSize = (28 + seededRandom(seed * 11) * 24) * s;
93
- const size = baseSize * sizeJitter;
94
- const popScale = Math.min(1, p * 30);
95
- const particleOpacity = p < 0.85 ? 1 : Math.max(0, 1 - (p - 0.85) / 0.15);
96
- const opacity = particleOpacity * timing.opacity;
97
- const beatPulse = 1 + beatIntensity * 0.2;
98
- const rot = startRot + rotSpeed * p;
99
- if (opacity <= 0) return null;
100
- if (y > height + 100 || y < -100 || x < -100 || x > width + 100) return null;
101
- return /* @__PURE__ */ jsx(
102
- "div",
103
- {
104
- style: {
105
- position: "absolute",
106
- left: x - size / 2,
107
- top: y - size / 2,
108
- width: size,
109
- height: size,
110
- fontSize: size * 0.8,
111
- lineHeight: 1,
112
- textAlign: "center",
113
- opacity,
114
- transform: `rotate(${rot}deg) scale(${popScale * beatPulse})`,
115
- pointerEvents: "none",
116
- display: "flex",
117
- alignItems: "center",
118
- justifyContent: "center"
119
- },
120
- children: /* @__PURE__ */ jsx(Emoji, { char: emoji, size: size * 0.8, verticalAlign: "baseline" })
121
- },
122
- i
123
- );
124
- }),
125
- /* @__PURE__ */ jsx(
126
- TemplateText,
127
- {
128
- motionProgress,
129
- typeTreatment: resolveTokens(style).preset.type,
130
- archetype: textArchetype ?? "subtle",
131
- text: String(variables.texts ?? ""),
132
- progress,
133
- sceneDuration: sceneDuration ?? 3,
134
- width,
135
- height,
136
- position: "center",
137
- sizeRole: "headline",
138
- safeZone,
139
- font,
140
- color: textColor,
141
- beatIntensity
142
- }
143
- )
144
- ]
145
- }
146
- );
147
- };
148
- export {
149
- BgEmojiTemplate
150
- };
@@ -1,106 +0,0 @@
1
- import {
2
- ConfettiLayer
3
- } from "./chunk-CJ7F2CE6.js";
4
- import "./chunk-QAAO7OAY.js";
5
- import {
6
- SceneBackground,
7
- getMediaBackgroundProps
8
- } from "./chunk-MXZSDGZQ.js";
9
- import {
10
- TemplateText
11
- } from "./chunk-YJJC4N4D.js";
12
- import "./chunk-L5BTTCZV.js";
13
- import "./chunk-FRN6WKHA.js";
14
- import "./chunk-W3VDIBGR.js";
15
- import "./chunk-XTOXFMLM.js";
16
- import {
17
- hasSceneMedia
18
- } from "./chunk-224QNWRA.js";
19
- import "./chunk-5CDAM24P.js";
20
- import {
21
- resolveTokens
22
- } from "./chunk-XWWLKRNU.js";
23
-
24
- // src/visual-system/scene-templates/bg-media.tsx
25
- import { jsx, jsxs } from "react/jsx-runtime";
26
- var BgMediaTemplate = ({
27
- variables,
28
- style,
29
- progress,
30
- motionProgress = progress,
31
- beatIntensity,
32
- width,
33
- height,
34
- textArchetype,
35
- backgroundEffect,
36
- safeZone,
37
- sceneDuration,
38
- isPlaying = true
39
- }) => {
40
- const { font, foreground, background } = resolveTokens(style);
41
- const text = foreground;
42
- return /* @__PURE__ */ jsxs(
43
- "div",
44
- {
45
- style: {
46
- width,
47
- height,
48
- backgroundColor: "var(--vanillasky-template-surface, #000)",
49
- position: "relative",
50
- overflow: "hidden",
51
- fontFamily: font
52
- },
53
- children: [
54
- /* @__PURE__ */ jsx(
55
- SceneBackground,
56
- {
57
- style,
58
- progress,
59
- sceneDuration,
60
- width,
61
- height,
62
- ...getMediaBackgroundProps(variables),
63
- textAnchor: "center",
64
- backgroundEffect,
65
- seed: String(variables.texts || ""),
66
- isPlaying,
67
- beatIntensity
68
- }
69
- ),
70
- variables.confetti === true && /* @__PURE__ */ jsx(
71
- ConfettiLayer,
72
- {
73
- progress: motionProgress,
74
- width,
75
- height,
76
- beatIntensity,
77
- bgColor: String(variables.mediaUrl || "").trim() === "" ? background.type === "solid" ? background.color : background.colors[1] : void 0
78
- }
79
- ),
80
- /* @__PURE__ */ jsx(
81
- TemplateText,
82
- {
83
- overMedia: hasSceneMedia(variables),
84
- motionProgress,
85
- typeTreatment: resolveTokens(style).preset.type,
86
- archetype: textArchetype ?? "subtle",
87
- text: String(variables.texts ?? ""),
88
- progress,
89
- sceneDuration: sceneDuration ?? 3,
90
- width,
91
- height,
92
- position: "center",
93
- sizeRole: "headline",
94
- safeZone,
95
- font,
96
- color: text,
97
- beatIntensity
98
- }
99
- )
100
- ]
101
- }
102
- );
103
- };
104
- export {
105
- BgMediaTemplate
106
- };
@@ -1,256 +0,0 @@
1
- import {
2
- stripPipe
3
- } from "./chunk-S7HFLYNN.js";
4
- import {
5
- SceneBackground,
6
- getMediaBackgroundProps
7
- } from "./chunk-MXZSDGZQ.js";
8
- import {
9
- renderWithEmoji
10
- } from "./chunk-L5BTTCZV.js";
11
- import "./chunk-FRN6WKHA.js";
12
- import "./chunk-W3VDIBGR.js";
13
- import {
14
- interpolate
15
- } from "./chunk-XTOXFMLM.js";
16
- import "./chunk-224QNWRA.js";
17
- import "./chunk-5CDAM24P.js";
18
- import "./chunk-XWWLKRNU.js";
19
-
20
- // src/visual-system/primitives/typography/BrandMessageBubble.tsx
21
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
- var CLAMP = { extrapolateLeft: "clamp", extrapolateRight: "clamp" };
23
- var BUBBLE_BG = "rgba(245,242,238,0.92)";
24
- var BUBBLE_TEXT = "#1c1c1e";
25
- var DOT_COLOR = "#8C8C92";
26
- function easeOutBack(t) {
27
- const c1 = 1.70158;
28
- const c3 = c1 + 1;
29
- return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
30
- }
31
- var TAIL_WITH_EMOJI = /(\S+)(\s+)([\p{Extended_Pictographic}\p{Emoji_Modifier}\u{FE0E}\u{FE0F}\u{200D}]+)\s*$/u;
32
- function renderMessageWithEmojiTail(text, fontSizePx) {
33
- const match = TAIL_WITH_EMOJI.exec(text);
34
- if (!match || match.index === void 0) {
35
- return renderWithEmoji(text, fontSizePx);
36
- }
37
- const [, lastWord, space, emoji] = match;
38
- const leading = text.slice(0, match.index);
39
- return /* @__PURE__ */ jsxs(Fragment, { children: [
40
- renderWithEmoji(leading, fontSizePx),
41
- /* @__PURE__ */ jsxs("span", { style: { whiteSpace: "nowrap" }, children: [
42
- lastWord,
43
- space,
44
- renderWithEmoji(emoji, fontSizePx)
45
- ] })
46
- ] });
47
- }
48
- function popIn(t, start, dur = 0.4) {
49
- if (t <= start) return 0;
50
- if (t >= start + dur) return 1;
51
- return easeOutBack((t - start) / dur);
52
- }
53
- var BrandMessageBubble = ({
54
- progress,
55
- sceneDuration,
56
- brandName: rawBrandName,
57
- message: rawMessage,
58
- width,
59
- height,
60
- safeZone
61
- }) => {
62
- const isLandscape = width > height;
63
- const s = isLandscape ? Math.min(width, height) / 534 * 1.3 : width / 534;
64
- const brandName = stripPipe(rawBrandName);
65
- const message = stripPipe(rawMessage);
66
- const realTimeSeconds = progress * sceneDuration;
67
- const typingStart = 0.1;
68
- const bubbleStart = 0.38;
69
- const typingPop = popIn(progress, typingStart, 0.1);
70
- const typingFade = interpolate(progress, [bubbleStart - 0.06, bubbleStart], [1, 0], CLAMP);
71
- const showTyping = progress >= typingStart && progress < bubbleStart;
72
- const bubblePop = popIn(progress, bubbleStart, 0.18);
73
- const showBubble = progress >= bubbleStart;
74
- const topPad = Math.max(safeZone.top, height * 0.25);
75
- const sidePad = Math.max(safeZone.left, width * 0.06);
76
- return /* @__PURE__ */ jsxs(
77
- "div",
78
- {
79
- style: {
80
- position: "absolute",
81
- top: topPad,
82
- left: sidePad,
83
- right: sidePad,
84
- display: "flex",
85
- justifyContent: "flex-end"
86
- },
87
- children: [
88
- showTyping && /* @__PURE__ */ jsx(
89
- "div",
90
- {
91
- style: {
92
- opacity: typingPop * typingFade,
93
- transform: `translateY(${(1 - typingPop) * 8 * s}px)`,
94
- background: BUBBLE_BG,
95
- borderRadius: 18 * s,
96
- padding: `${12 * s}px ${16 * s}px`,
97
- display: "flex",
98
- gap: 5 * s,
99
- alignItems: "center",
100
- boxShadow: `0 ${1 * s}px ${4 * s}px rgba(0,0,0,0.10)`
101
- },
102
- children: [0, 1, 2].map((j) => {
103
- const phase = (realTimeSeconds * 1.6 + j * 0.2) % 1;
104
- const y = Math.sin(phase * Math.PI * 2) * 2.5 * s;
105
- const op = 0.45 + 0.55 * Math.max(0, Math.sin(phase * Math.PI));
106
- return /* @__PURE__ */ jsx(
107
- "div",
108
- {
109
- style: {
110
- width: 7 * s,
111
- height: 7 * s,
112
- borderRadius: 3.5 * s,
113
- background: DOT_COLOR,
114
- transform: `translateY(${-y}px)`,
115
- opacity: op
116
- }
117
- },
118
- j
119
- );
120
- })
121
- }
122
- ),
123
- showBubble && /* @__PURE__ */ jsxs(
124
- "div",
125
- {
126
- style: {
127
- // `width: max-content` forces the bubble to size to its
128
- // natural one-line content width up to `maxWidth`. Without
129
- // this, modern-screenshot's foreignObject text shaping (the
130
- // export path) was using an intrinsic width well below
131
- // `maxWidth`, breaking text that would have fit on one line
132
- // in the live DOM — even after the NBSP fix glued the
133
- // trailing emoji to the last word. With `max-content` +
134
- // `maxWidth`, the bubble grows up to the cap on a single
135
- // line, then wraps naturally inside the cap for genuinely
136
- // long messages.
137
- width: "max-content",
138
- maxWidth: width * 0.86,
139
- // Render with native system fonts in BOTH paths. The export
140
- // pipeline turns the iframe DOM into an SVG and loads it via
141
- // <img src="data:image/svg+xml,…">, and SVG-as-image is a
142
- // sandboxed graphics context that does NOT load @font-face
143
- // resources (data: or otherwise — this is a browser security
144
- // model, not a CSP issue). Inter therefore never resolves in
145
- // the export; the SVG falls back to Helvetica/Helvetica Neue,
146
- // which is wider at the same point size, and "We built this
147
- // for you ❤️" wraps inside the pinned bubble box even though
148
- // the iframe's Inter rendering fit on one line. Naming the
149
- // system font explicitly here makes the iframe ALSO use that
150
- // same OS-native font, so preview and export compute identical
151
- // widths and both fit on one line. See PRs #598/#599/#604 for
152
- // the months of font-embed work that this finally closes out.
153
- fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
154
- background: BUBBLE_BG,
155
- color: BUBBLE_TEXT,
156
- borderRadius: `${22 * s}px ${22 * s}px 0 ${22 * s}px`,
157
- padding: `${14 * s}px ${18 * s}px ${12 * s}px`,
158
- fontSize: 23 * s,
159
- lineHeight: `${29 * s}px`,
160
- fontWeight: 400,
161
- opacity: bubblePop,
162
- transform: `translateY(${(1 - bubblePop) * 8 * s}px) scale(${0.96 + 0.04 * bubblePop})`,
163
- transformOrigin: "right top",
164
- boxShadow: `0 ${2 * s}px ${10 * s}px rgba(0,0,0,0.14)`
165
- },
166
- children: [
167
- /* @__PURE__ */ jsx(
168
- "div",
169
- {
170
- style: {
171
- fontSize: 14 * s,
172
- fontStyle: "italic",
173
- fontWeight: 400,
174
- color: "rgba(0,0,0,0.45)",
175
- lineHeight: 1.2,
176
- marginBottom: 6 * s
177
- },
178
- children: brandName
179
- }
180
- ),
181
- renderMessageWithEmojiTail(message, 23 * s)
182
- ]
183
- }
184
- )
185
- ]
186
- }
187
- );
188
- };
189
-
190
- // src/visual-system/scene-templates/brand-message.tsx
191
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
192
- var BrandMessageTemplate = ({
193
- variables,
194
- style,
195
- progress,
196
- beatIntensity,
197
- width,
198
- height,
199
- sceneDuration,
200
- isPlaying = true,
201
- safeZone,
202
- backgroundEffect
203
- }) => {
204
- const brandName = stripPipe(style.brand.name ?? "Your brand");
205
- const message = stripPipe(String(variables.message || ""));
206
- const seed = (brandName + message).split("").reduce((acc, c) => acc + c.charCodeAt(0), 0);
207
- return /* @__PURE__ */ jsxs2(
208
- "div",
209
- {
210
- style: {
211
- width,
212
- height,
213
- backgroundColor: "var(--vanillasky-template-surface, #000)",
214
- position: "relative",
215
- overflow: "hidden",
216
- // System fonts only — see BrandMessageBubble for the why
217
- // (SVG-as-image can't load @font-face data: URLs, so the only
218
- // way to get preview/export parity is to use a font the OS
219
- // already has natively).
220
- fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif'
221
- },
222
- children: [
223
- /* @__PURE__ */ jsx2(
224
- SceneBackground,
225
- {
226
- style,
227
- progress,
228
- sceneDuration,
229
- width,
230
- height,
231
- ...getMediaBackgroundProps(variables),
232
- backgroundEffect,
233
- seed,
234
- isPlaying,
235
- beatIntensity
236
- }
237
- ),
238
- /* @__PURE__ */ jsx2(
239
- BrandMessageBubble,
240
- {
241
- progress,
242
- sceneDuration: sceneDuration ?? 4,
243
- brandName,
244
- message,
245
- width,
246
- height,
247
- safeZone
248
- }
249
- )
250
- ]
251
- }
252
- );
253
- };
254
- export {
255
- BrandMessageTemplate
256
- };