@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,4 +1,4 @@
1
- import { b as VideoOrientation, V as VideoStyle, c as Video, a as VideoCapabilities, d as VideoAudio, e as VideoScene, f as VIDEO_PROTOCOL_VERSION } from './types-CEh9eUFu.js';
1
+ import { b as VideoOrientation, V as VideoStyle, c as Video, a as VideoCapabilities, d as VideoAudio, e as VideoScene, f as VIDEO_PROTOCOL_VERSION } from './types-DdZw4GRQ.js';
2
2
 
3
3
  type VideoWarningCategory = "validation" | "readability" | "grounding" | "provider" | "media" | "protocol";
4
4
  type VideoWarningCode = "scene_duration_adjusted" | "scene_omitted_unreadable" | "scene_omitted_for_closer" | "scene_variable_clipped" | "chart_scale_imbalance" | "plan_incomplete" | "plan_missing_closer" | "provider_warning" | "provider_diagnostics_unavailable" | "media_budget_reached";
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,30 @@
1
+ import {
2
+ EditorialSurface
3
+ } from "./chunk-XX4GXKTX.js";
4
+ import "./chunk-NMFDC2W2.js";
5
+ import "./chunk-77VY4O7A.js";
6
+ import {
7
+ editorialLabel,
8
+ fade
9
+ } from "./chunk-4YM2M62S.js";
10
+ import {
11
+ hasSceneMedia
12
+ } from "./chunk-224QNWRA.js";
13
+ import "./chunk-TVIU23OM.js";
14
+
15
+ // src/visual-system/scene-templates/key-figure.tsx
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ function KeyFigureScene(props) {
18
+ const { variables, width, height, progress, motionProgress = progress, safeZone } = props;
19
+ const overMedia = hasSceneMedia(variables);
20
+ const u = Math.min(width, height), side = Math.max(width * 0.13, safeZone.left, safeZone.right), available = width - side * 2;
21
+ const top = Math.max(height * 0.16, safeZone.top), bottom = height - Math.max(height * 0.23, safeZone.bottom), value = String(variables.value ?? "");
22
+ return /* @__PURE__ */ jsx(EditorialSurface, { ...props, template: "keyFigure", 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: [
23
+ /* @__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 }),
24
+ /* @__PURE__ */ jsx("div", { style: { ...editorialLabel(u), color: overMedia ? "#fff" : "#b7b7bc", marginTop: u * 0.045, textWrap: "balance", overflowWrap: "anywhere" }, children: String(variables.label ?? "") })
25
+ ] }) });
26
+ }
27
+ var KeyFigureSceneTemplate = KeyFigureScene;
28
+ export {
29
+ KeyFigureSceneTemplate
30
+ };
@@ -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,50 @@
1
+ import {
2
+ MediaScene
3
+ } from "./chunk-Z67Q5KUW.js";
4
+ import "./chunk-NMFDC2W2.js";
5
+ import {
6
+ spring
7
+ } from "./chunk-77VY4O7A.js";
8
+ import {
9
+ editorialFont
10
+ } from "./chunk-4YM2M62S.js";
11
+ import "./chunk-224QNWRA.js";
12
+ import "./chunk-TVIU23OM.js";
13
+
14
+ // src/visual-system/scene-templates/mobile-message.tsx
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ var clamp = (value) => Math.max(0, Math.min(1, value));
17
+ function NotificationScene(props) {
18
+ const { variables, progress, motionProgress = progress, sceneDuration = 6, width, height, safeZone } = props;
19
+ const message = String(variables.message ?? "");
20
+ const app = String(variables.app ?? "Messages");
21
+ const unit = Math.min(width, height);
22
+ const cardWidth = Math.min(width * 0.88, unit * 1.12, width - safeZone.left - safeZone.right - unit * 0.06);
23
+ const inset = unit * 0.038;
24
+ const elapsed = clamp(motionProgress) * Math.max(2, Math.min(sceneDuration, 8));
25
+ const entrance = clamp((elapsed - 0.18) / 0.82);
26
+ const arrival = entrance >= 1 ? 1 : spring(entrance, { damping: 22, stiffness: 220 });
27
+ const opacity = clamp((elapsed - 0.18) / 0.08);
28
+ const contentWidth = cardWidth - inset * 2;
29
+ const messageSize = unit * (message.length > 100 ? 0.038 : 0.043);
30
+ const longestWord = Math.max(1, ...message.split(/\s+/).map((word) => word.length));
31
+ const fittedMessageSize = Math.min(messageSize, contentWidth / (longestWord * 0.57));
32
+ const bannerTop = Math.max(safeZone.top, height * 0.08) + unit * 0.025;
33
+ const travel = bannerTop + unit * 0.65;
34
+ const iconSize = unit * 0.049;
35
+ return /* @__PURE__ */ jsxs("div", { "data-template": "notification", style: { position: "absolute", inset: 0, overflow: "hidden", background: "var(--vanillasky-template-surface, #000)", fontFamily: editorialFont }, children: [
36
+ /* @__PURE__ */ jsx(MediaScene, { ...props }),
37
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { position: "absolute", inset: 0, background: "rgba(0,0,0,.16)" } }),
38
+ /* @__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: [
39
+ /* @__PURE__ */ jsxs("div", { "data-notification-header": "true", style: { display: "flex", alignItems: "center", gap: unit * 0.014, marginBottom: unit * 0.024 }, children: [
40
+ /* @__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" }) }) }),
41
+ /* @__PURE__ */ jsx("div", { style: { fontSize: unit * 0.029, fontWeight: 500, color: "#5b565f", minWidth: 0, overflowWrap: "anywhere" }, children: app })
42
+ ] }),
43
+ /* @__PURE__ */ jsx("div", { style: { fontSize: fittedMessageSize, lineHeight: 1.26, letterSpacing: "-.016em", overflowWrap: "anywhere" }, children: message })
44
+ ] })
45
+ ] });
46
+ }
47
+ var NotificationSceneTemplate = NotificationScene;
48
+ export {
49
+ NotificationSceneTemplate
50
+ };
@@ -0,0 +1,33 @@
1
+ import {
2
+ EditorialSurface
3
+ } from "./chunk-XX4GXKTX.js";
4
+ import "./chunk-NMFDC2W2.js";
5
+ import "./chunk-77VY4O7A.js";
6
+ import {
7
+ fade
8
+ } from "./chunk-4YM2M62S.js";
9
+ import {
10
+ hasSceneMedia
11
+ } from "./chunk-224QNWRA.js";
12
+ import "./chunk-TVIU23OM.js";
13
+
14
+ // src/visual-system/scene-templates/quote.tsx
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ function QuoteScene(props) {
17
+ const { variables, width, height, progress, motionProgress = progress, safeZone } = props;
18
+ const overMedia = hasSceneMedia(variables);
19
+ const u = Math.min(width, height), top = Math.max(height * 0.16, safeZone.top), bottom = height - Math.max(height * 0.23, safeZone.bottom);
20
+ const side = Math.max(width * 0.13, safeZone.left, safeZone.right);
21
+ return /* @__PURE__ */ jsx(EditorialSurface, { ...props, template: "quote", 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: [
22
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: u * 0.067, fontWeight: 500, lineHeight: 1.25, letterSpacing: "-.025em", textWrap: "balance", overflowWrap: "anywhere" }, children: [
23
+ "\u201C",
24
+ String(variables.quote ?? ""),
25
+ "\u201D"
26
+ ] }),
27
+ /* @__PURE__ */ jsx("div", { style: { fontSize: u * 0.041, fontWeight: 400, color: overMedia ? "#fff" : "#b7b7bc", lineHeight: 1.3, marginTop: u * 0.065, textWrap: "balance", overflowWrap: "anywhere" }, children: String(variables.attribution ?? "") })
28
+ ] }) });
29
+ }
30
+ var QuoteSceneTemplate = QuoteScene;
31
+ export {
32
+ QuoteSceneTemplate
33
+ };
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 };