@vanillaskyai/video 0.8.8 → 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 +30 -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 +590 -833
  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 +1 -1
  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 -22
  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
@@ -0,0 +1,20 @@
1
+ import {
2
+ editorialFont,
3
+ fade
4
+ } from "./chunk-4YM2M62S.js";
5
+
6
+ // src/visual-system/scene-templates/focus-cards.tsx
7
+ import { jsx } from "react/jsx-runtime";
8
+ function CardsScene({ variables, width, height, progress, motionProgress = progress, safeZone }) {
9
+ const items = (Array.isArray(variables.items) ? variables.items : []).filter((v) => typeof v === "string" && !!v.trim()).slice(0, 4);
10
+ const u = Math.min(width, height), n = Math.max(1, items.length);
11
+ const side = Math.max(width * 0.12, safeZone.left, safeZone.right), available = width - side * 2;
12
+ const top = Math.max(height * 0.18, safeZone.top), bottom = height - Math.max(height * 0.22, safeZone.bottom);
13
+ const font = u * 0.057, slot = Math.min(u * 0.17, (bottom - top) / n), groupHeight = slot * n;
14
+ const listTop = top + (bottom - top - groupHeight) / 2;
15
+ return /* @__PURE__ */ jsx("div", { "data-template": "cards", style: { position: "absolute", inset: 0, overflow: "hidden", background: "#000", color: "#fff", fontFamily: editorialFont }, children: items.map((text, i) => /* @__PURE__ */ jsx("div", { "data-template-item": "cardList", style: { position: "absolute", left: side, top: listTop + i * slot, width: available, height: slot, display: "flex", alignItems: "center", justifyContent: "center", textAlign: "center", fontSize: Math.min(font, slot / (Math.max(1, Math.ceil(text.length * font * 0.52 / available)) * 1.6)), fontWeight: 500, lineHeight: 1.22, letterSpacing: "-.025em", textWrap: "balance", overflowWrap: "anywhere", opacity: fade((motionProgress - 0.04 - i * 0.14) / 0.18) }, children: text }, i)) });
16
+ }
17
+ var CardsSceneTemplate = CardsScene;
18
+ export {
19
+ CardsSceneTemplate
20
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as Video, h as VideoBrandInput, i as VideoBrand, e as VideoScene, j as VideoTemplatePacing } from './types-CEh9eUFu.js';
2
- export { d as VideoAudio, k as VideoBackground, b as VideoOrientation, V as VideoStyle, l as VideoStyleOptions } from './types-CEh9eUFu.js';
1
+ import { c as Video, e as VideoScene, g as VideoTemplatePacing } from './types-DdZw4GRQ.js';
2
+ export { d as VideoAudio, h as VideoNarrationGroup, b as VideoOrientation, V as VideoStyle, i as VideoStyleOptions } from './types-DdZw4GRQ.js';
3
3
 
4
4
  type VideoStatus = "idle" | "streaming" | "complete" | "error" | "aborted";
5
5
 
@@ -8,13 +8,11 @@ declare class VideoValidationError extends Error {
8
8
  readonly code: VideoValidationErrorCode;
9
9
  constructor(message: string, code?: VideoValidationErrorCode);
10
10
  }
11
- /** Parse a persisted Video using the current-only 0.1 schema policy. */
11
+ /** Parse a persisted Video using the current-only 0.2 schema policy. */
12
12
  declare function parseVideo(value: unknown): Video;
13
13
 
14
14
  declare function getVideoDuration(config: Video): number;
15
15
 
16
- declare function resolveVideoBrand(input?: VideoBrandInput): VideoBrand;
17
-
18
16
  interface SceneDurationBounds {
19
17
  /**
20
18
  * The least this scene survives being shown for.
@@ -38,4 +36,4 @@ declare function getSceneDurationBounds(scene: Pick<VideoScene, "variables">, me
38
36
  declare function getSpokenDuration(narration: string): number;
39
37
  declare function getSceneDuration(scene: Pick<VideoScene, "variables" | "narration">, metadata: VideoTemplatePacing | undefined): number;
40
38
 
41
- export { type SceneDurationBounds, Video, VideoBrand, VideoBrandInput, VideoScene, type VideoStatus, VideoValidationError, type VideoValidationErrorCode, getSceneDuration, getSceneDurationBounds, getSpokenDuration, getVideoDuration, parseVideo, resolveVideoBrand };
39
+ export { type SceneDurationBounds, Video, VideoScene, type VideoStatus, VideoValidationError, type VideoValidationErrorCode, getSceneDuration, getSceneDurationBounds, getSpokenDuration, getVideoDuration, parseVideo };
package/dist/index.js CHANGED
@@ -6,21 +6,17 @@ import {
6
6
  import {
7
7
  VideoValidationError,
8
8
  parseVideo
9
- } from "./chunk-2DOLF4QN.js";
10
- import "./chunk-AOWSXU2K.js";
9
+ } from "./chunk-AUPC6MDK.js";
10
+ import "./chunk-7NZOMTAL.js";
11
11
  import "./chunk-3O7OMMMF.js";
12
12
  import {
13
13
  getVideoDuration
14
14
  } from "./chunk-SPVTJH3F.js";
15
- import {
16
- resolveVideoBrand
17
- } from "./chunk-XGRA2MUV.js";
18
15
  export {
19
16
  VideoValidationError,
20
17
  getSceneDuration,
21
18
  getSceneDurationBounds,
22
19
  getSpokenDuration,
23
20
  getVideoDuration,
24
- parseVideo,
25
- resolveVideoBrand
21
+ parseVideo
26
22
  };
@@ -0,0 +1,20 @@
1
+ import {
2
+ editorialFont,
3
+ editorialLabel,
4
+ fade
5
+ } from "./chunk-4YM2M62S.js";
6
+
7
+ // src/visual-system/scene-templates/key-figure.tsx
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function KeyFigureScene({ variables, width, height, progress, motionProgress = progress, safeZone }) {
10
+ const u = Math.min(width, height), side = Math.max(width * 0.13, safeZone.left, safeZone.right), available = width - side * 2;
11
+ const top = Math.max(height * 0.16, safeZone.top), bottom = height - Math.max(height * 0.23, safeZone.bottom), value = String(variables.value ?? "");
12
+ return /* @__PURE__ */ jsx("div", { "data-template": "keyFigure", style: { position: "absolute", inset: 0, background: "#000", color: "#fff", fontFamily: editorialFont, overflow: "hidden" }, children: /* @__PURE__ */ jsxs("div", { style: { position: "absolute", left: side, top: (top + bottom) / 2, width: available, transform: "translateY(-50%)", textAlign: "center", opacity: fade((motionProgress - 0.03) / 0.22) }, children: [
13
+ /* @__PURE__ */ jsx("div", { style: { fontSize: Math.min(u * 0.22, available / Math.max(1, value.length * 0.6)), fontWeight: 500, lineHeight: 1.05, letterSpacing: "-.045em", fontVariantNumeric: "tabular-nums" }, children: value }),
14
+ /* @__PURE__ */ jsx("div", { style: { ...editorialLabel(u), marginTop: u * 0.045, textWrap: "balance", overflowWrap: "anywhere" }, children: String(variables.label ?? "") })
15
+ ] }) });
16
+ }
17
+ var KeyFigureSceneTemplate = KeyFigureScene;
18
+ export {
19
+ KeyFigureSceneTemplate
20
+ };
@@ -1,6 +1,6 @@
1
- import { V as VideoStyle, a as VideoCapabilities } from './types-CEh9eUFu.js';
1
+ import { V as VideoStyle, a as VideoCapabilities } from './types-DdZw4GRQ.js';
2
2
  import { ComponentType } from 'react';
3
- import { S as SceneTemplateMetadata, d as TemplateJsonSchema, f as TemplateJsonSchemaProperty } from './catalog-types-BIhSpOWK.js';
3
+ import { S as SceneTemplateMetadata, T as TemplateJsonSchema, d as TemplateJsonSchemaProperty } from './catalog-types-WTbLP6Jh.js';
4
4
 
5
5
  interface TemplateSafeZone {
6
6
  top: number;
@@ -0,0 +1,49 @@
1
+ import {
2
+ MediaScene
3
+ } from "./chunk-G7IZBBWF.js";
4
+ import {
5
+ spring
6
+ } from "./chunk-77VY4O7A.js";
7
+ import {
8
+ editorialFont
9
+ } from "./chunk-4YM2M62S.js";
10
+ import "./chunk-UDIODEDK.js";
11
+ import "./chunk-TVIU23OM.js";
12
+
13
+ // src/visual-system/scene-templates/mobile-message.tsx
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ var clamp = (value) => Math.max(0, Math.min(1, value));
16
+ function NotificationScene(props) {
17
+ const { variables, progress, motionProgress = progress, sceneDuration = 6, width, height, safeZone } = props;
18
+ const message = String(variables.message ?? "");
19
+ const app = String(variables.app ?? "Messages");
20
+ const unit = Math.min(width, height);
21
+ const cardWidth = Math.min(width * 0.88, unit * 1.12, width - safeZone.left - safeZone.right - unit * 0.06);
22
+ const inset = unit * 0.038;
23
+ const elapsed = clamp(motionProgress) * Math.max(2, Math.min(sceneDuration, 8));
24
+ const entrance = clamp((elapsed - 0.18) / 0.82);
25
+ const arrival = entrance >= 1 ? 1 : spring(entrance, { damping: 22, stiffness: 220 });
26
+ const opacity = clamp((elapsed - 0.18) / 0.08);
27
+ const contentWidth = cardWidth - inset * 2;
28
+ const messageSize = unit * (message.length > 100 ? 0.038 : 0.043);
29
+ const longestWord = Math.max(1, ...message.split(/\s+/).map((word) => word.length));
30
+ const fittedMessageSize = Math.min(messageSize, contentWidth / (longestWord * 0.57));
31
+ const bannerTop = Math.max(safeZone.top, height * 0.08) + unit * 0.025;
32
+ const travel = bannerTop + unit * 0.65;
33
+ const iconSize = unit * 0.049;
34
+ return /* @__PURE__ */ jsxs("div", { "data-template": "notification", style: { position: "absolute", inset: 0, overflow: "hidden", background: "var(--vanillasky-template-surface, #000)", fontFamily: editorialFont }, children: [
35
+ /* @__PURE__ */ jsx(MediaScene, { ...props }),
36
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { position: "absolute", inset: 0, background: "rgba(0,0,0,.16)" } }),
37
+ /* @__PURE__ */ jsxs("div", { "data-notification-card": "true", style: { position: "absolute", left: (width - cardWidth) / 2, top: bannerTop, width: cardWidth, boxSizing: "border-box", transform: `translateY(${-(1 - arrival) * travel}px) scale(${0.985 + arrival * 0.015})`, opacity, transformOrigin: "50% 0%", padding: inset, borderRadius: unit * 0.042, background: "rgba(245,247,250,.64)", backdropFilter: `blur(${unit * 0.034}px) saturate(135%)`, WebkitBackdropFilter: `blur(${unit * 0.034}px) saturate(135%)`, border: `${unit * 1e-3}px solid rgba(255,255,255,.72)`, boxShadow: `0 ${unit * 0.018}px ${unit * 0.065}px rgba(0,0,0,.2), inset 0 ${unit * 1e-3}px 0 rgba(255,255,255,.8)`, color: "#202025" }, children: [
38
+ /* @__PURE__ */ jsxs("div", { "data-notification-header": "true", style: { display: "flex", alignItems: "center", gap: unit * 0.014, marginBottom: unit * 0.024 }, children: [
39
+ /* @__PURE__ */ jsx("div", { style: { width: iconSize, height: iconSize, borderRadius: iconSize * 0.25, display: "grid", placeItems: "center", background: "linear-gradient(#5bd978, #25b749)", flexShrink: 0 }, children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 40 40", width: iconSize * 0.78, height: iconSize * 0.78, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M34 18c0 7-6 12-14 12-2 0-4 0-6-1l-7 3 2-7c-2-2-3-4-3-7C6 11 12 6 20 6s14 5 14 12Z", fill: "white" }) }) }),
40
+ /* @__PURE__ */ jsx("div", { style: { fontSize: unit * 0.029, fontWeight: 500, color: "#5b565f", minWidth: 0, overflowWrap: "anywhere" }, children: app })
41
+ ] }),
42
+ /* @__PURE__ */ jsx("div", { style: { fontSize: fittedMessageSize, lineHeight: 1.26, letterSpacing: "-.016em", overflowWrap: "anywhere" }, children: message })
43
+ ] })
44
+ ] });
45
+ }
46
+ var NotificationSceneTemplate = NotificationScene;
47
+ export {
48
+ NotificationSceneTemplate
49
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  limitsConcurrentVideoDecoders,
3
3
  resolveMediaType
4
- } from "./chunk-224QNWRA.js";
4
+ } from "./chunk-UDIODEDK.js";
5
5
 
6
6
  // src/player/preload-media.ts
7
7
  var warmed = /* @__PURE__ */ new Set();
@@ -0,0 +1,23 @@
1
+ import {
2
+ editorialFont,
3
+ fade
4
+ } from "./chunk-4YM2M62S.js";
5
+
6
+ // src/visual-system/scene-templates/quote.tsx
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function QuoteScene({ variables, width, height, progress, motionProgress = progress, safeZone }) {
9
+ const u = Math.min(width, height), top = Math.max(height * 0.16, safeZone.top), bottom = height - Math.max(height * 0.23, safeZone.bottom);
10
+ const side = Math.max(width * 0.13, safeZone.left, safeZone.right);
11
+ return /* @__PURE__ */ jsx("div", { "data-template": "quote", style: { position: "absolute", inset: 0, background: "#000", color: "#fff", fontFamily: editorialFont, overflow: "hidden" }, children: /* @__PURE__ */ jsxs("div", { style: { position: "absolute", left: side, top: (top + bottom) / 2, width: width - side * 2, transform: "translateY(-50%)", textAlign: "center", opacity: fade((motionProgress - 0.03) / 0.24) }, children: [
12
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: u * 0.067, fontWeight: 500, lineHeight: 1.25, letterSpacing: "-.025em", textWrap: "balance", overflowWrap: "anywhere" }, children: [
13
+ "\u201C",
14
+ String(variables.quote ?? ""),
15
+ "\u201D"
16
+ ] }),
17
+ /* @__PURE__ */ jsx("div", { style: { fontSize: u * 0.041, fontWeight: 400, color: "#b7b7bc", lineHeight: 1.3, marginTop: u * 0.065, textWrap: "balance", overflowWrap: "anywhere" }, children: String(variables.attribution ?? "") })
18
+ ] }) });
19
+ }
20
+ var QuoteSceneTemplate = QuoteScene;
21
+ export {
22
+ QuoteSceneTemplate
23
+ };
package/dist/react.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties, ReactElement, ReactNode } from 'react';
3
- import { b as VideoEvent } from './events-BQ6z264n.js';
4
- import { b as VideoOrientation, c as Video, e as VideoScene, h as VideoBrandInput, l as VideoStyleOptions } from './types-CEh9eUFu.js';
5
- import { T as TemplateRegistry } from './kit-tQnCPMOM.js';
6
- import { V as VideoChatMode, a as VideoChatAskOptions, b as VideoChatMedia, c as VideoChatSuggestion, d as VideoChatCapabilities, e as VideoChatWelcome } from './types-DWFO6qca.js';
7
- import './catalog-types-BIhSpOWK.js';
3
+ import { b as VideoEvent } from './events-B4YCc4vc.js';
4
+ import { b as VideoOrientation, e as VideoScene, c as Video, i as VideoStyleOptions } from './types-DdZw4GRQ.js';
5
+ import { T as TemplateRegistry } from './kit-DrRpdn0p.js';
6
+ import { V as VideoChatMode, a as VideoChatAskOptions, b as VideoChatMedia, c as VideoChatSuggestion, d as VideoChatCapabilities, e as VideoChatWelcome } from './types-CdBmNTGD.js';
7
+ import './catalog-types-WTbLP6Jh.js';
8
8
 
9
9
  type VideoPlaybackMode = "manual" | "muted-autoplay" | "autoplay-with-sound" | "autoplay-after-interaction";
10
10
 
@@ -40,6 +40,10 @@ interface VideoPlayerSharedProps {
40
40
  * where a replay scrim would cover the answer the moment it finished.
41
41
  */
42
42
  controls?: boolean;
43
+ /** Optional synchronous onset handshake from useNarration.isReady. Does not pause audio or prevent the first scene cue. */
44
+ narrationReady?: () => boolean;
45
+ /** Active audio time: paragraph-relative for a narration group, scene-relative otherwise. Undefined resumes the normal clock. */
46
+ narrationTime?: (scene: VideoScene) => number | undefined;
43
47
  /**
44
48
  * Hold the playhead where it is, and release it again.
45
49
  *
@@ -63,6 +67,8 @@ interface VideoPlayerSharedProps {
63
67
  onError?: (error: Error) => void;
64
68
  /** First active scene committed, observed at the next animation frame; excludes idle posters. */
65
69
  onFramePresented?: () => unknown;
70
+ /** First actual mounted video frame; excludes graphics, posters and safe fallbacks. */
71
+ onMediaFramePresented?: () => unknown;
66
72
  /** Stream playback has reached its available scenes; excludes initial waiting and deliberate pauses. */
67
73
  onStallChange?: (stalled: boolean) => unknown;
68
74
  /** Fires when the scene under the playhead changes, including on a loop wrap. */
@@ -122,7 +128,12 @@ interface NarrationVoice {
122
128
  * scene is worse than being cut off. Report onStart only when speech actually
123
129
  * begins playing; leave it uncalled when onset cannot be observed.
124
130
  */
131
+ /** True only when the provider can start prepared audio at an exact offset. */
132
+ supportsOffsets?: boolean;
133
+ /** Active prepared audio time in seconds, including any requested seek offset. */
134
+ getCurrentTime?: () => number | undefined;
125
135
  speak(text: string, options: {
136
+ offsetSeconds?: number;
126
137
  signal: AbortSignal;
127
138
  onStart?: (source?: "browser" | "generated") => void;
128
139
  }): void | Promise<void>;
@@ -131,6 +142,8 @@ interface NarrationVoice {
131
142
  interface VideoChatPreparedSpeech {
132
143
  /** Measured or conservatively estimated spoken duration, in seconds. */
133
144
  seconds: number;
145
+ /** True only for decoded audio with seek support, never duration estimates. */
146
+ supportsOffsets?: boolean;
134
147
  }
135
148
  interface VideoChatVoice extends NarrationVoice {
136
149
  prepare(text: string, options?: {
@@ -182,7 +195,6 @@ interface UseVideoChatOptions {
182
195
  templates?: TemplateRegistry;
183
196
  mode?: VideoChatMode;
184
197
  orientation?: VideoOrientation;
185
- brand?: VideoBrandInput;
186
198
  style?: VideoStyleOptions;
187
199
  headers?: HeadersInit;
188
200
  credentials?: RequestCredentials;
@@ -203,6 +215,8 @@ type VideoChatPlaybackMetric = {
203
215
  elapsedMs: number;
204
216
  } & ({
205
217
  type: "first-frame";
218
+ } | {
219
+ type: "first-media-frame";
206
220
  } | {
207
221
  type: "first-speech";
208
222
  source: "browser" | "generated" | "custom";
@@ -256,14 +270,10 @@ interface VideoChatProps {
256
270
  className?: string;
257
271
  /** Replaces the default two-line welcome heading without changing the interaction. */
258
272
  welcomeTitle?: ReactNode;
259
- /** Host-owned name for the generated-video choice in Settings. Does not change server capabilities. */
260
- generatedVideoLabel?: string;
261
- /** Explain the host's generated-video offering, including preview limits. */
262
- generatedVideoDescription?: string;
263
273
  /** Show a dismissible safe notice when generated visuals fall back. Defaults to false. */
264
274
  showRecoveryNotice?: boolean;
265
275
  }
266
276
  /** A complete voice-and-video chat interface backed by createVideoChatHandler. */
267
- declare function VideoChat({ options, className, welcomeTitle, generatedVideoLabel, generatedVideoDescription, showRecoveryNotice }: VideoChatProps): react.JSX.Element;
277
+ declare function VideoChat({ options, className, welcomeTitle, showRecoveryNotice }: VideoChatProps): react.JSX.Element;
268
278
 
269
279
  export { type CreateVideoChatVoiceOptions, type UseVideoChatOptions, type UseVideoChatResult, VideoChat, VideoChatAskOptions, VideoChatCapabilities, type VideoChatFirstFrameMetric, VideoChatMedia, VideoChatMode, type VideoChatPlaybackMetric, type VideoChatPreparedSpeech, type VideoChatProps, type VideoChatStatus, VideoChatSuggestion, type VideoChatTurn, type VideoChatVoice, VideoChatWelcome, VideoError, type VideoErrorOptions, type VideoPlaybackMode, VideoPlayer, type VideoPlayerProps, createVideoChatVoice, useVideoChat };