domotion-svg 0.23.0 → 0.27.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 (346) hide show
  1. package/FEATURES.md +22 -2
  2. package/README.md +48 -21
  3. package/dist/animation/animator.d.ts +6 -175
  4. package/dist/animation/animator.js +6 -2636
  5. package/dist/animation/caret-track.js +1 -2
  6. package/dist/animation/compressed-run.js +36 -10
  7. package/dist/animation/frame-timeline.d.ts +17 -0
  8. package/dist/animation/frame-timeline.js +22 -0
  9. package/dist/animation/overlay-schema.d.ts +9 -4
  10. package/dist/animation/overlay-schema.js +10 -2
  11. package/dist/animation/svg-generator.d.ts +178 -0
  12. package/dist/animation/svg-generator.js +2679 -0
  13. package/dist/animation/transition-schema.d.ts +2 -2
  14. package/dist/capture/animated-image-static-frame.d.ts +58 -0
  15. package/dist/capture/animated-image-static-frame.js +237 -0
  16. package/dist/capture/animation-frame.d.ts +59 -0
  17. package/dist/capture/animation-frame.js +351 -0
  18. package/dist/capture/authenticated-animated-image-bytes.d.ts +78 -0
  19. package/dist/capture/authenticated-animated-image-bytes.js +365 -0
  20. package/dist/capture/backdrop-composite-raster.d.ts +61 -0
  21. package/dist/capture/backdrop-composite-raster.js +552 -0
  22. package/dist/capture/backdrop-effect-neutralization.d.ts +20 -0
  23. package/dist/capture/backdrop-effect-neutralization.js +162 -0
  24. package/dist/capture/backdrop-effect-space.d.ts +38 -0
  25. package/dist/capture/backdrop-effect-space.js +93 -0
  26. package/dist/capture/backdrop-isolation.d.ts +39 -0
  27. package/dist/capture/backdrop-isolation.js +112 -0
  28. package/dist/capture/backdrop-layer-space.d.ts +29 -0
  29. package/dist/capture/backdrop-layer-space.js +52 -0
  30. package/dist/capture/background-image-sizing.d.ts +56 -0
  31. package/dist/capture/background-image-sizing.js +598 -0
  32. package/dist/capture/broken-image-fallback.d.ts +47 -0
  33. package/dist/capture/broken-image-fallback.js +557 -0
  34. package/dist/capture/broken-image-icon-raster.d.ts +31 -0
  35. package/dist/capture/broken-image-icon-raster.js +198 -0
  36. package/dist/capture/collapsed-border-fragment-cdp.d.ts +15 -0
  37. package/dist/capture/collapsed-border-fragment-cdp.js +697 -0
  38. package/dist/capture/collapsed-border-fragment-record.d.ts +191 -0
  39. package/dist/capture/collapsed-border-fragment-record.js +768 -0
  40. package/dist/capture/debug-bundle.d.ts +36 -0
  41. package/dist/capture/debug-bundle.js +31 -0
  42. package/dist/capture/effective-appearance-cdp.d.ts +21 -0
  43. package/dist/capture/effective-appearance-cdp.js +119 -0
  44. package/dist/capture/effective-appearance.d.ts +76 -0
  45. package/dist/capture/effective-appearance.js +458 -0
  46. package/dist/capture/embed.d.ts +9 -0
  47. package/dist/capture/embed.js +23 -2
  48. package/dist/capture/emoji.d.ts +43 -1
  49. package/dist/capture/emoji.js +427 -35
  50. package/dist/capture/frame-scroll-state.d.ts +61 -0
  51. package/dist/capture/frame-scroll-state.js +866 -0
  52. package/dist/capture/generic-font-probe.d.ts +41 -6
  53. package/dist/capture/generic-font-probe.js +356 -92
  54. package/dist/capture/index.d.ts +153 -24
  55. package/dist/capture/index.js +1275 -256
  56. package/dist/capture/input-value-geometry.d.ts +14 -0
  57. package/dist/capture/input-value-geometry.js +40 -0
  58. package/dist/capture/line-clamp.d.ts +9 -0
  59. package/dist/capture/line-clamp.js +324 -0
  60. package/dist/capture/native-control-decoration-raster.d.ts +37 -0
  61. package/dist/capture/native-control-decoration-raster.js +526 -0
  62. package/dist/capture/native-control-decoration.d.ts +33 -0
  63. package/dist/capture/native-control-decoration.js +83 -0
  64. package/dist/capture/native-control-raster.d.ts +103 -0
  65. package/dist/capture/native-control-raster.js +488 -0
  66. package/dist/capture/native-scrollbar-raster.d.ts +37 -0
  67. package/dist/capture/native-scrollbar-raster.js +273 -0
  68. package/dist/capture/paged-collapsed-table-cdp.d.ts +67 -0
  69. package/dist/capture/paged-collapsed-table-cdp.js +88 -0
  70. package/dist/capture/paged-collapsed-table-record.d.ts +170 -0
  71. package/dist/capture/paged-collapsed-table-record.js +487 -0
  72. package/dist/capture/projective-owner.d.ts +84 -0
  73. package/dist/capture/projective-owner.js +85 -0
  74. package/dist/capture/pseudo-backdrop-isolation.d.ts +30 -0
  75. package/dist/capture/pseudo-backdrop-isolation.js +64 -0
  76. package/dist/capture/pseudo-fragment-cdp.d.ts +23 -0
  77. package/dist/capture/pseudo-fragment-cdp.js +1110 -0
  78. package/dist/capture/pseudo-fragment-protocol.d.ts +146 -0
  79. package/dist/capture/pseudo-fragment-protocol.js +399 -0
  80. package/dist/capture/pseudo-style-cdp.d.ts +68 -0
  81. package/dist/capture/pseudo-style-cdp.js +714 -0
  82. package/dist/capture/raf-clock.d.ts +31 -0
  83. package/dist/capture/raf-clock.js +177 -0
  84. package/dist/capture/replaced-element-raster.d.ts +44 -0
  85. package/dist/capture/replaced-element-raster.js +580 -0
  86. package/dist/capture/replaced-media-frame.d.ts +66 -0
  87. package/dist/capture/replaced-media-frame.js +451 -0
  88. package/dist/capture/replaced-snapshot-geometry.d.ts +60 -0
  89. package/dist/capture/replaced-snapshot-geometry.js +123 -0
  90. package/dist/capture/script/dotted-circle-detect.d.ts +2 -0
  91. package/dist/capture/script/dotted-circle-detect.js +29 -16
  92. package/dist/capture/script/emoji-detect.d.ts +5 -2
  93. package/dist/capture/script/emoji-detect.js +185 -446
  94. package/dist/capture/script/font-family-default.d.ts +1 -0
  95. package/dist/capture/script/font-family-default.js +139 -13
  96. package/dist/capture/script/font-feature-values.d.ts +12 -2
  97. package/dist/capture/script/font-feature-values.js +151 -44
  98. package/dist/capture/script/font-metrics.d.ts +1 -1
  99. package/dist/capture/script/font-metrics.js +9 -9
  100. package/dist/capture/script/font-palette.d.ts +19 -0
  101. package/dist/capture/script/font-palette.js +217 -0
  102. package/dist/capture/script/index.js +1216 -435
  103. package/dist/capture/script/line-clamp.d.ts +61 -0
  104. package/dist/capture/script/line-clamp.js +395 -0
  105. package/dist/capture/script/pseudo-rules.d.ts +2 -12
  106. package/dist/capture/script/pseudo-rules.js +26 -218
  107. package/dist/capture/script/vertical-orientation.generated.d.ts +8 -0
  108. package/dist/capture/script/vertical-orientation.generated.js +490 -0
  109. package/dist/capture/script/walker/background-attachment.d.ts +39 -0
  110. package/dist/capture/script/walker/background-attachment.js +203 -0
  111. package/dist/capture/script/walker/borders-backgrounds.d.ts +268 -25
  112. package/dist/capture/script/walker/borders-backgrounds.js +757 -414
  113. package/dist/capture/script/walker/capture-phases.d.ts +56 -0
  114. package/dist/capture/script/walker/capture-phases.js +233 -0
  115. package/dist/capture/script/walker/collapsed-border.d.ts +79 -0
  116. package/dist/capture/script/walker/collapsed-border.js +294 -0
  117. package/dist/capture/script/walker/form-controls.d.ts +6 -20
  118. package/dist/capture/script/walker/form-controls.js +58 -25
  119. package/dist/capture/script/walker/fragmentation.js +143 -43
  120. package/dist/capture/script/walker/inline-svg.d.ts +4 -1
  121. package/dist/capture/script/walker/inline-svg.js +344 -73
  122. package/dist/capture/script/walker/input-value.d.ts +5 -1
  123. package/dist/capture/script/walker/input-value.js +29 -1
  124. package/dist/capture/script/walker/lists-counters.d.ts +3 -1
  125. package/dist/capture/script/walker/lists-counters.js +2 -1
  126. package/dist/capture/script/walker/masks-clips.d.ts +10 -4
  127. package/dist/capture/script/walker/masks-clips.js +548 -43
  128. package/dist/capture/script/walker/pseudo-content.d.ts +15 -2
  129. package/dist/capture/script/walker/pseudo-content.js +184 -74
  130. package/dist/capture/script/walker/pseudo-inject.d.ts +4 -0
  131. package/dist/capture/script/walker/pseudo-inject.js +10 -2
  132. package/dist/capture/script/walker/replaced-elements.js +4 -3
  133. package/dist/capture/script/walker/resize-handle.d.ts +28 -0
  134. package/dist/capture/script/walker/resize-handle.js +95 -0
  135. package/dist/capture/script/walker/text-segments.d.ts +4 -117
  136. package/dist/capture/script/walker/text-segments.js +131 -81
  137. package/dist/capture/script/walker/transforms.d.ts +1 -0
  138. package/dist/capture/script/walker/transforms.js +7 -1
  139. package/dist/capture/script.generated.js +1 -1
  140. package/dist/capture/scrollbar-capture.d.ts +109 -0
  141. package/dist/capture/scrollbar-capture.js +1137 -0
  142. package/dist/capture/summary-marker-cdp.d.ts +19 -0
  143. package/dist/capture/summary-marker-cdp.js +222 -0
  144. package/dist/capture/svg-affine-freeze.d.ts +42 -0
  145. package/dist/capture/svg-affine-freeze.js +91 -0
  146. package/dist/capture/text-fragment-geometry.d.ts +43 -0
  147. package/dist/capture/text-fragment-geometry.js +197 -0
  148. package/dist/capture/text-fragment-spans.d.ts +48 -0
  149. package/dist/capture/text-fragment-spans.js +418 -0
  150. package/dist/capture/text-line-origin.d.ts +48 -0
  151. package/dist/capture/text-line-origin.js +132 -0
  152. package/dist/capture/text-paint-geometry-cdp.d.ts +22 -0
  153. package/dist/capture/text-paint-geometry-cdp.js +542 -0
  154. package/dist/capture/tree-envelope.d.ts +23 -0
  155. package/dist/capture/tree-envelope.js +144 -0
  156. package/dist/capture/types.d.ts +1612 -49
  157. package/dist/capture/types.js +0 -17
  158. package/dist/cli/animate-artifact.d.ts +20 -0
  159. package/dist/cli/animate-artifact.js +17 -0
  160. package/dist/cli/animate-capture-session.d.ts +25 -0
  161. package/dist/cli/animate-capture-session.js +41 -0
  162. package/dist/cli/animate-command.d.ts +2 -0
  163. package/dist/cli/animate-command.js +101 -0
  164. package/dist/cli/animate-debug.d.ts +35 -0
  165. package/dist/cli/animate-debug.js +72 -0
  166. package/dist/cli/animate-frame-capture.d.ts +22 -0
  167. package/dist/cli/animate-frame-capture.js +21 -0
  168. package/dist/cli/animate-orchestrator.d.ts +2168 -0
  169. package/dist/cli/animate-orchestrator.js +3457 -0
  170. package/dist/cli/animate.d.ts +6 -2156
  171. package/dist/cli/animate.js +6 -3525
  172. package/dist/cli/capture.js +5 -30
  173. package/dist/cli/common.d.ts +1 -0
  174. package/dist/cli/common.js +24 -0
  175. package/dist/cli/composite.d.ts +2 -2
  176. package/dist/cli/debug-bundle.d.ts +13 -0
  177. package/dist/cli/debug-bundle.js +30 -0
  178. package/dist/cli/index.js +10 -0
  179. package/dist/cli/storyboard.d.ts +7 -7
  180. package/dist/cli/svg-to-video-core.js +5 -45
  181. package/dist/font-family-stack.d.ts +51 -0
  182. package/dist/font-family-stack.js +190 -0
  183. package/dist/font-feature-values-cascade.d.ts +26 -0
  184. package/dist/font-feature-values-cascade.js +48 -0
  185. package/dist/generated/mathml-operator-dictionary.d.ts +3 -0
  186. package/dist/generated/mathml-operator-dictionary.js +9 -0
  187. package/dist/index.d.ts +11 -3
  188. package/dist/index.js +5 -1
  189. package/dist/post-processing/hoist-image-payloads.js +5 -0
  190. package/dist/render/advanced-gradient-raster.d.ts +16 -0
  191. package/dist/render/advanced-gradient-raster.js +101 -0
  192. package/dist/render/background-attachment.d.ts +19 -0
  193. package/dist/render/background-attachment.js +76 -0
  194. package/dist/render/borders.d.ts +120 -0
  195. package/dist/render/borders.js +593 -102
  196. package/dist/render/broken-image-fallback.d.ts +18 -0
  197. package/dist/render/broken-image-fallback.js +176 -0
  198. package/dist/render/cjk-ideograph-or-symbol-ranges.generated.d.ts +3 -0
  199. package/dist/render/cjk-ideograph-or-symbol-ranges.generated.js +140 -0
  200. package/dist/render/clip-path.d.ts +71 -0
  201. package/dist/render/clip-path.js +72 -1
  202. package/dist/render/cluster-fallback.d.ts +26 -22
  203. package/dist/render/cluster-fallback.js +170 -267
  204. package/dist/render/colors.js +16 -2
  205. package/dist/render/conic-raster.d.ts +20 -12
  206. package/dist/render/conic-raster.js +37 -14
  207. package/dist/render/culling-geometry.d.ts +65 -0
  208. package/dist/render/culling-geometry.js +749 -0
  209. package/dist/render/custom-scrollbar.d.ts +36 -0
  210. package/dist/render/custom-scrollbar.js +112 -0
  211. package/dist/render/decoration-fragment-ownership.d.ts +40 -0
  212. package/dist/render/decoration-fragment-ownership.js +54 -0
  213. package/dist/render/element-tree-to-svg.d.ts +42 -30
  214. package/dist/render/element-tree-to-svg.js +2084 -1078
  215. package/dist/render/embedded-font-builder.d.ts +34 -4
  216. package/dist/render/embedded-font-builder.js +94 -39
  217. package/dist/render/embolden-outline.d.ts +52 -91
  218. package/dist/render/embolden-outline.js +105 -337
  219. package/dist/render/emoji-presentation-priority.d.ts +22 -0
  220. package/dist/render/emoji-presentation-priority.js +114 -0
  221. package/dist/render/font-resolution.d.ts +265 -76
  222. package/dist/render/font-resolution.js +822 -393
  223. package/dist/render/form-controls.d.ts +20 -47
  224. package/dist/render/form-controls.js +405 -985
  225. package/dist/render/glyph-helper-font.d.ts +144 -0
  226. package/dist/render/glyph-helper-font.js +452 -0
  227. package/dist/render/glyph-helper-outline.d.ts +135 -0
  228. package/dist/render/glyph-helper-outline.js +117 -0
  229. package/dist/render/glyph-helper-protocol.d.ts +237 -0
  230. package/dist/render/glyph-helper-protocol.js +7 -0
  231. package/dist/render/glyph-helper-transport.d.ts +28 -0
  232. package/dist/render/glyph-helper-transport.js +452 -0
  233. package/dist/render/glyph-helper.d.ts +68 -312
  234. package/dist/render/glyph-helper.js +118 -1010
  235. package/dist/render/gradient-defs.d.ts +11 -0
  236. package/dist/render/gradient-defs.js +298 -83
  237. package/dist/render/gradients.d.ts +66 -1
  238. package/dist/render/gradients.js +273 -62
  239. package/dist/render/harfbuzz-shaper.d.ts +10 -1
  240. package/dist/render/harfbuzz-shaper.js +7 -4
  241. package/dist/render/hb-subset.d.ts +45 -11
  242. package/dist/render/hb-subset.js +166 -55
  243. package/dist/render/helper-acquire.js +1 -1
  244. package/dist/render/helper-availability-contract.d.ts +44 -0
  245. package/dist/render/helper-availability-contract.js +85 -0
  246. package/dist/render/host-platform.d.ts +5 -2
  247. package/dist/render/host-platform.js +5 -32
  248. package/dist/render/icu-helper-acquire.d.ts +25 -0
  249. package/dist/render/icu-helper-acquire.js +150 -0
  250. package/dist/render/icu-helper.d.ts +40 -0
  251. package/dist/render/icu-helper.js +126 -0
  252. package/dist/render/image-pattern.d.ts +84 -17
  253. package/dist/render/image-pattern.js +566 -227
  254. package/dist/render/index.d.ts +3 -0
  255. package/dist/render/index.js +2 -0
  256. package/dist/render/linux-target-strike.d.ts +30 -0
  257. package/dist/render/linux-target-strike.js +89 -0
  258. package/dist/render/list-marker-geometry.d.ts +41 -0
  259. package/dist/render/list-marker-geometry.js +92 -0
  260. package/dist/render/mask-origin-clip.d.ts +49 -0
  261. package/dist/render/mask-origin-clip.js +72 -0
  262. package/dist/render/mask-position.d.ts +47 -0
  263. package/dist/render/mask-position.js +192 -0
  264. package/dist/render/mask.d.ts +106 -30
  265. package/dist/render/mask.js +724 -217
  266. package/dist/render/native-scrollbar-raster.d.ts +15 -0
  267. package/dist/render/native-scrollbar-raster.js +50 -0
  268. package/dist/render/overflow-clip.d.ts +69 -0
  269. package/dist/render/overflow-clip.js +157 -0
  270. package/dist/render/pseudo-filter.d.ts +25 -0
  271. package/dist/render/pseudo-filter.js +45 -0
  272. package/dist/render/pseudo-fragments.d.ts +46 -0
  273. package/dist/render/pseudo-fragments.js +488 -0
  274. package/dist/render/resize-handle.d.ts +74 -0
  275. package/dist/render/resize-handle.js +112 -0
  276. package/dist/render/script-segmentation.d.ts +24 -23
  277. package/dist/render/script-segmentation.js +135 -45
  278. package/dist/render/stacking.d.ts +11 -9
  279. package/dist/render/stacking.js +103 -48
  280. package/dist/render/svg-inline.js +18 -3
  281. package/dist/render/synchronous-scope.d.ts +15 -0
  282. package/dist/render/synchronous-scope.js +15 -0
  283. package/dist/render/synthesis-decision.d.ts +1 -1
  284. package/dist/render/synthesis-decision.js +4 -5
  285. package/dist/render/text-affine.d.ts +37 -0
  286. package/dist/render/text-affine.js +267 -0
  287. package/dist/render/text-run-provenance.d.ts +106 -0
  288. package/dist/render/text-run-provenance.js +130 -0
  289. package/dist/render/text-to-path.d.ts +186 -30
  290. package/dist/render/text-to-path.js +1165 -436
  291. package/dist/render/text.d.ts +113 -6
  292. package/dist/render/text.js +248 -394
  293. package/dist/render/unicode-classification.d.ts +22 -14
  294. package/dist/render/unicode-classification.js +133 -113
  295. package/dist/render/unicode-font-routing.darwin.generated.d.ts +1 -0
  296. package/dist/render/unicode-font-routing.darwin.generated.js +2 -2
  297. package/dist/render/vertical-text.d.ts +26 -1
  298. package/dist/render/vertical-text.js +179 -81
  299. package/dist/render/win-font-fallback.d.ts +0 -78
  300. package/dist/render/win-font-fallback.js +41 -0
  301. package/dist/review/client.bundle.generated.js +1 -1
  302. package/dist/review/client.js +30 -0
  303. package/dist/review/compare-pngs.d.ts +12 -10
  304. package/dist/review/compare-pngs.js +1 -1
  305. package/dist/review/linux-unicode-evidence.d.ts +63 -0
  306. package/dist/review/linux-unicode-evidence.js +213 -0
  307. package/dist/review/logical-classification.d.ts +30 -0
  308. package/dist/review/logical-classification.js +36 -0
  309. package/dist/review/region-overlay.d.ts +2 -0
  310. package/dist/review/region-overlay.js +5 -1
  311. package/dist/review/roll-differential.d.ts +44 -0
  312. package/dist/review/roll-differential.js +23 -0
  313. package/dist/review/server.js +11 -7
  314. package/dist/review/source-drift-gate.d.ts +36 -0
  315. package/dist/review/source-drift-gate.js +32 -0
  316. package/dist/review/stage-evidence.d.ts +44 -0
  317. package/dist/review/stage-evidence.js +42 -0
  318. package/dist/scroll/composer.d.ts +5 -0
  319. package/dist/scroll/composer.js +134 -0
  320. package/dist/scroll/executor.d.ts +21 -1
  321. package/dist/scroll/executor.js +85 -22
  322. package/dist/scroll/index.d.ts +1 -1
  323. package/dist/scroll/index.js +1 -1
  324. package/dist/scrubber/client.bundle.generated.js +1 -1
  325. package/dist/scrubber/client.js +30 -12
  326. package/dist/scrubber/server.d.ts +1 -1
  327. package/dist/templates/builtin/device-mockup.d.ts +1 -1
  328. package/dist/terminal/render.js +1 -1
  329. package/dist/tree-ops/decoration-propagation.d.ts +8 -7
  330. package/dist/tree-ops/decoration-propagation.js +43 -27
  331. package/dist/tree-ops/resize-embedded-images.d.ts +20 -1
  332. package/dist/tree-ops/resize-embedded-images.js +30 -1
  333. package/dist/tree-ops/swept-transform-bounds.d.ts +49 -0
  334. package/dist/tree-ops/swept-transform-bounds.js +691 -0
  335. package/dist/tree-ops/viewbox-culling.d.ts +14 -48
  336. package/dist/tree-ops/viewbox-culling.js +121 -440
  337. package/dist/vertical-orientation.d.ts +32 -0
  338. package/dist/vertical-orientation.js +96 -0
  339. package/llms.txt +25 -7
  340. package/package.json +110 -3
  341. package/schemas/animate-config.schema.json +27 -0
  342. package/vendor/harfbuzzjs/README.md +8 -5
  343. package/vendor/harfbuzzjs/build/config-override-subset.h +14 -0
  344. package/vendor/harfbuzzjs/dist/harfbuzz-subset.wasm +0 -0
  345. package/dist/render/text-parity-diagnostics.d.ts +0 -13
  346. package/dist/render/text-parity-diagnostics.js +0 -18
package/FEATURES.md CHANGED
@@ -21,7 +21,8 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
21
21
  - [x] **bg-solid**: Solid background colors
22
22
  - [x] **bg-transparent**: Semi-transparent backgrounds (rgba)
23
23
  - [x] **bg-nested**: Nested backgrounds (child on top of parent)
24
- - [x] **bg-conic-gradient** (DM-547, doc 28): `conic-gradient` / `repeating-conic-gradient` background layers via pattern-raster pre-pass — covers `bg-conic-smooth`, `bg-conic-checkerboard`, `bg-conic-from-at`, `bg-conic-multilayer` fixtures
24
+ - [x] **bg-conic-gradient** (DM-547, DM-2327, doc 28): `conic-gradient` / `repeating-conic-gradient` background layers via Chromium-painted pattern tiles — covers smooth, checkerboard, from/at, multilayer, and advanced-color effective-zoom fixtures; CPU rasterization is helper-absent best effort only
25
+ - [x] **bg-legacy-webkit-gradient** (DM-2528, doc 223): exact deprecated linear endpoints and two-circle radial geometry, including unitless effective zoom, physical writing-mode axes, stable-sort-before-clamp stop domains, and unchanged modern/repeating routes
25
26
  - [ ] **bg-dark-mode** (DM-455, doc 29): Dark-mode capture support — caller-chosen `colorScheme`, dark form-control palette, scheme-aware transparent-root fallback
26
27
 
27
28
  ### Borders
@@ -38,6 +39,8 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
38
39
  - [ ] **layout-absolute**: Absolute positioning
39
40
  - [x] **layout-padding**: Padding affecting content position
40
41
  - [x] **float-paint-order-context-wide** (doc 01 § Stacking): a stacking context paints in CSS 2.1 Appendix E phases — every in-flow block's background + border (step 3), then every non-positioned float (step 4), then all inline content (step 5). So a float paints above a later block sibling's background and below the text of every paragraph in the context, and an `inline-block` / flex item keeps its own floats (it paints atomically).
42
+ - [x] **perspective-fixed-containing-block-ownership** (DM-2385, doc 06): computed `perspective` creates a real stacking context and fixed-position containing block; asymmetric `perspective-origin` is captured as resolved pixels but has no ownership effect by itself. Computed `transform-style: preserve-3d` still traps fixed descendants when `overflow:hidden` flattens its used 3D style, while `perspective:none` remains the viewport-fixed negative control.
43
+ - [x] **animated-projective-frame-state** (DM-2359/DM-2356/DM-2492/DM-2493, docs 186/189): `animationTimeMs` exactly pauses document timelines before all capture prepasses and exposes the CDP quad, composed 3D state, residual, and selected atomic raster owner without a fitted 2D approximation. Same-frame used-preserve facts select Blink's direct-parent rendering-context root; a strict 25-family/four-profile native three-OS DPR-1/2 gate rejects larger crops, warnings, restoration drift, incomplete evidence, and nine ownership mutations.
41
44
 
42
45
  ### Components
43
46
  - [x] **comp-button**: Button with background, border, padding, text
@@ -46,14 +49,20 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
46
49
  - [x] **comp-card-badge**: Card with inline badge (flex row with mixed components)
47
50
  - [x] **comp-input**: Form input with border and placeholder-style text
48
51
  - [x] **comp-input-value**: Native `<input>` element with value attribute
52
+ - [x] **native-control-decoration-split** (DM-2455, doc 171): styled select/temporal/search/number hosts and value text remain structural while exact Chromium menulist-arrow and closed-shadow picker/cancel/spin layers are isolated into fail-closed transparent overlays; base-select remains fully vector.
49
53
  - [x] **comp-code-block**: Code block with monospace, background, border
50
54
  - [ ] **comp-nav**: Navigation bar with logo and links
51
55
 
52
56
  ### SVG
53
- - [ ] **svg-inline**: Inline SVG elements (icons) positioned correctly
57
+ - [x] **svg-inline**: Inline SVG elements are cloned as self-contained vectors; CSS-only clip/mask effects preserve native fill-box, stroke-box, and view-box resolution (DM-2328)
58
+ - [x] **clip-path-url-reference-ownership** (DM-2362, docs 39/130): bare same-document/external URL clips preserve HTML border/object-bounding-box and SVG forced-fill ownership; Blink-invalid URL-plus-box declarations stay inactive, including stale captured trees and nested frames.
59
+
60
+ ### Masks
61
+ - [x] **mask-contain-cover-arbitrary-position** (DM-2379, doc 20): URL masks capture Chromium-decoded intrinsic ratios and emit concrete Blink-fitted rectangles for percentage, length, and calc positions; zoom/DPR, physical writing axes, multilayer, and slice/clone fragment controls reject the retired SVG Min/Mid/Max buckets.
54
62
 
55
63
  ### Text effects
56
64
  - [x] **text-bg-clip-gradient** (DM-462): `background-clip: text` + `-webkit-text-fill-color: transparent` — gradient fills the glyph shapes via SVG `<mask>` over the bg-color rect
65
+ - [x] **pseudo-filter-functions** (DM-2367, doc 38): generated empty/text/image paint supports blur, drop-shadow, brightness, contrast, grayscale, hue-rotate, invert, opacity, saturate, sepia, and ordered lists through Chromium's native SVG CSS-filter pipeline; identity/none, transform, clip, stack slot, zoom, DPR, and filter-stripped mutation controls are browser-gated.
57
66
 
58
67
  ### Replaced elements (rasterized as static snapshot — DM-457)
59
68
  - [x] **replaced-canvas-shape**: `<canvas>` with drawn shapes — bitmap survives via `page.screenshot`
@@ -64,7 +73,9 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
64
73
  - [x] **iframe-recursion-bordered** (DM-1441): same-origin iframe recursion through a non-zero border + padding on the iframe — inner document's origin lands at the iframe **content box** and the inner subtree clips to it.
65
74
  - [x] **iframe-canvas-bg-fill** (DM-1448): recursed iframe **taller than its content** — the inner document's propagated canvas background (html-bg-or-else-body-bg) fills the whole inner viewport, so the strip below the content paints the canvas color instead of showing through to the outer page.
66
75
  - [x] **iframe-inner-clip-mask** (DM-1446): recursed iframe whose inner content uses `clip-path: url(#id)` + `mask-image: url(#id)` defined in the **iframe's own** `<defs>` — fragment refs resolve against `el.ownerDocument`, so the `<clipPath>`/`<mask>` defs hoist and paint (clipped circle + masked square-with-hole, 0.00%). (Inner `element(#id)` paint refs are frame-aware — DM-1447 — though CSS `element()` itself is unsupported in Chromium / dormant, DM-1450; tall-iframe canvas-bg fill shipped in DM-1448.)
76
+ - [x] **multi-layer-fragment-mask** (DM-2520): ordered local SVG mask layers keep per-layer TreeScope, units/region, mode, composite, and consumer zoom across duplicate outer/iframe ids; two-/three-layer add/intersect/subtract/exclude output is raw-RGBA exact to Chromium at DPR 1/2, with destructive scope/operator/mode/zoom controls.
67
77
  - [x] **cross-origin iframe recursion** (DM-1442): `--cross-origin-frames "*"|host[:port],…` (config: `captureCrossOriginFrames`) recurses **allowlisted** cross-origin frames into native SVG by launching Chromium with web security disabled; non-allowlisted frames stay raster. Default off + a stderr security warning (disabling web security disables CORS). Unit + e2e tested (`tests/cross-origin-iframe-recursion.e2e.test.ts`). See [docs/81](docs/81-iframe-recursion.md).
78
+ - [x] **cross-origin frame scroll ownership** (DM-2537): each scroll anchor carries a fresh Chromium `FrameId` graph, parent-relative allowlist/reachability decisions, exact frame-local scrollbar owners and raw RTL/vertical offsets; denied ancestors leak no descendant state and composition destructively rejects stale/omitted/wrong-frame authority. See [docs/217](docs/217-cross-origin-frame-scroll-ownership.md).
68
79
  - [x] **snapshot-isolation-pseudo-overlay** (DM-458, `tests/snapshot-isolation.tsx`): canvas covered by a sibling's `::after` pseudo overlay. Inspection-style — decodes the captured snapshot's PNG data URI and asserts no overlay-color pixels leaked through. Catches regressions in the hide-everything-else stylesheet that a comparison-style fixture wouldn't.
69
80
 
70
81
  ### Showcase Integration Tests
@@ -72,6 +83,15 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
72
83
  - [x] **showcase-cards**: Card list with badges, buttons, metadata
73
84
  - [x] **showcase-forms**: Publish form with labels, inputs, pre block, button
74
85
 
86
+ ### Composed Parity Integration Tests
87
+ - [x] **composed-multilingual-flex-grid**: Platform fallback and bidi isolation inside flex/grid messaging UI, with neutral-wrapper and node-split relations
88
+ - [x] **composed-responsive-fragmented-controls**: Native controls inside responsive multicol layout with equivalent grid syntax
89
+ - [x] **composed-gradient-mask-clip-stacking**: Gradients, masks, and clips under explicit stacking ownership and reversed DOM order
90
+ - [x] **composed-svg-effects-translation**: Inline SVG filter/clip/marker effects under translation covariance
91
+ - [x] **composed-zoom-transform-scale**: Effective zoom, nested transforms, and scale-normalized geometry
92
+ - [x] **composed-same-origin-iframe**: Native same-origin recursion containing fallback, bidi, gradient, mask, and clip decisions
93
+ - [x] **composed-dynamic-replaced-freeze**: Transformed canvas pixels frozen at capture under an independently stacked vector overlay
94
+
75
95
  ## Testing Approach
76
96
 
77
97
  Tests are defined in `tests/features.ts` (26 feature tests) and `tests/showcase.ts` (3 integration tests). Both use the shared runner in `tests/runner.ts`.
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://github.com/brianwestphal/domotion">GitHub</a>
13
13
  </p>
14
14
 
15
- **Domotion turns real HTML/CSS into one self-contained, animated SVG** — an accurate reproduction of the rendered page, with optional animation and simulated interaction built in. Text is emitted as real glyph paths, so it looks identical across browsers; the output scales crisply at any size and embeds anywhere with a plain `<img>`, no external assets.
15
+ **Domotion turns real HTML/CSS into one self-contained, animated SVG** — an accurate reproduction of the rendered page, with optional animation and simulated interaction built in. It embeds the exact captured glyph data and positioning, so playback never falls back to a viewer's system fonts; the output scales crisply at any size and embeds anywhere with a plain `<img>`, no external assets.
16
16
 
17
17
  Beyond raw capture it ships a **template library** that turns a few flags into a polished animated SVG, **terminal-session capture** (a recording → an animated terminal), **scroll capture** (a long page replayed as one self-contained scrolling SVG), multi-frame **animation** with parameterized and custom transitions, overlays, and simulated interaction, **scene storyboarding** (sequence distinct scenes end-to-end), **brand kits** and **social-format presets** (reel / square / portrait / landscape), **device-chrome** framing, **nested compositing** (animated layers inside animated layers), one-command **SVG → MP4/WebM**, and a fidelity **review** tool.
18
18
 
@@ -38,41 +38,51 @@ Actively developed, with a broad shipped surface — capture, multi-frame animat
38
38
 
39
39
  ## Platform support
40
40
 
41
- Domotion runs on **macOS, Linux, and Windows**, and all three are calibrated. It renders text by extracting real system-font glyph outlines and matching how the browser falls back between fonts on the platform you run it on (CoreText on macOS, fontconfig on Linux, DirectWrite on Windows). macOS is held to pixel-exact parity; Linux and Windows match the browser's glyph selection and metrics within a small native-hinting margin (the residual is unhinted-outline-vs-native-raster rasterization, not missing calibration), and both are gated by visual-regression CI.
41
+ Domotion runs on **macOS, Linux, and Windows**, and all three are calibrated. It renders text by extracting the glyphs Chromium selected on the platform you run it on (CoreText on macOS, fontconfig on Linux, DirectWrite on Windows), then embeds those glyphs instead of asking the viewer's machine to perform font fallback. macOS is held to pixel-exact parity; Linux and Windows match Chromium's glyph selection and metrics within a documented native-hinting margin. Linux fidelity is a required CI check; Windows has first-class native validation and release checks, with its slower broad suites dispatched on demand.
42
42
 
43
43
  Issues, fixes, and platform feedback are welcome on [GitHub](https://github.com/brianwestphal/domotion).
44
44
 
45
- ## Install
45
+ ## Quick start
46
46
 
47
47
  ```bash
48
48
  npm install domotion-svg
49
+ npx domotion capture https://example.com -o example.svg
49
50
  ```
50
51
 
51
- That's it — Domotion auto-installs Playwright's Chromium binary on first use
52
- (via `npx playwright install chromium`). On CI you may want to pre-install it
53
- yourself to keep the first job's runtime down.
52
+ Open `example.svg` in a browser. You should see a self-contained, scalable
53
+ capture of the page with no external fonts, images, or scripts.
54
54
 
55
- ## Usage
55
+ Domotion installs Playwright's Chromium binary on first use. CI jobs can run
56
+ `npx playwright install chromium` ahead of time to keep capture runtime
57
+ predictable. For a zero-install trial, run
58
+ `npx -p domotion-svg domotion capture https://example.com -o example.svg`.
56
59
 
57
- The fastest way in is the `domotion` CLI — no TypeScript, no Playwright bring-up. Point it at a URL or HTML file:
60
+ ## Choose your task
58
61
 
59
- ```bash
60
- # Zero-install: run the published CLI straight from npm. The package name is
61
- # domotion-svg; -p installs it and `domotion` selects the bin (the package ships
62
- # several bins, so the bin must be named explicitly).
63
- npx -p domotion-svg domotion capture https://example.com -o example.svg
62
+ - **Capture one page:** use `domotion capture`; see the
63
+ [capture guide](https://brianwestphal.github.io/domotion/usage/capture/).
64
+ - **Animate a product flow:** use `domotion animate`; follow the
65
+ [animation guide](https://brianwestphal.github.io/domotion/usage/animate/).
66
+ - **Generate a polished asset from flags:** use `domotion template`; browse the
67
+ [template guide](https://brianwestphal.github.io/domotion/usage/templates/).
68
+
69
+ The [Quick start](https://brianwestphal.github.io/domotion/start/quickstart/)
70
+ walks through the first capture and animation end to end.
64
71
 
65
- # Capture a URL as SVG.
66
- domotion capture https://example.com -o example.svg
72
+ ## More capture inputs
67
73
 
68
- # Capture a local HTML file at a specific viewport, only the .hero region, optimized.
74
+ After the first capture works, the same CLI accepts local files, stdin, element
75
+ selection, custom viewports, optimization, and scrolling pages:
76
+
77
+ ```bash
78
+ # Capture one element from a local file at a specific viewport.
69
79
  domotion capture ./demo.html \
70
80
  --width 1200 --height 600 \
71
81
  --selector ".hero" \
72
82
  --optimize \
73
83
  -o hero.svg
74
84
 
75
- # Capture HTML piped on stdin.
85
+ # Capture HTML from stdin.
76
86
  cat demo.html | domotion capture - -o demo.svg
77
87
 
78
88
  # Capture a long page as one animated scrolling SVG (scrolls to the bottom over 8s).
@@ -85,15 +95,18 @@ into Playwright's stricter network-idle heuristic with `--network-idle`; it is
85
95
  off by default because analytics, long polling, and streaming requests may
86
96
  never become idle.
87
97
 
88
- Same-origin `<iframe>` content is recursed into the capture as native, selectable SVG rather than flattened to a screenshot; opt into cross-origin frames you trust with `--cross-origin-frames "<hosts>"`.
98
+ Same-origin `<iframe>` content is recursed into the capture as native SVG rather than flattened to a screenshot; opt into cross-origin frames you trust with `--cross-origin-frames "<hosts>"`.
89
99
 
90
- For a multi-frame animated SVG, write a small JSON config and run `domotion animate`:
100
+ For a multi-frame animated SVG, write a JSON config and run:
91
101
 
92
102
  ```bash
93
103
  domotion animate ./demo.json
94
104
  ```
95
105
 
96
- The config describes each frame (input, duration, transition) plus a declarative surface for interaction demos: continuous-session frames that carry client-side state across steps (omit `input` / set `"continue": true`), DOM-mutation and interaction actions, richer readiness waits (`waitForText` / `waitForGone` / `waitForCount`), typing / tap / svg / blink / shine / interact overlays that can anchor to an element's box (typing supports per-keystroke reveal, `kern`, caret shapes, and a high-fidelity `typeResample` mode), real interaction-state capture (`forceState` / `hoverReveal` / `hoverDetect` / `jsReveal`), an on-screen `cursor` (explicit or `"auto"`), `vars` + `${}` interpolation, and a small `evaluate` escape hatch. See `domotion --help` for the full grammar and the [Quick start](https://brianwestphal.github.io/domotion/start/quickstart/) for a walkthrough.
106
+ The config describes frames, timing, transitions, waits, overlays, and simulated
107
+ interaction. See `domotion --help` for the full grammar and the
108
+ [animation guide](https://brianwestphal.github.io/domotion/usage/animate/) for
109
+ examples ranging from simple transitions to continuous interactive sessions.
97
110
 
98
111
  Transitions are not limited to fixed presets. Parameterized `push`, `reveal`,
99
112
  `zoom`, and `shine` forms control direction/angle, distance, origin, radius, and
@@ -164,6 +177,15 @@ svg-review --expected example.debug/expected.png --actual example.debug/actual.s
164
177
 
165
178
  The browser opens a single review card showing the expected / actual / diff PNGs. Arrow keys cycle through the three at full size; drag on any image to mark a problem region and caption it. The side panel builds a GitHub-issue-ready Markdown block as you go — copy it, then file the issue at <https://github.com/brianwestphal/domotion/issues/new> and attach `expected.png` + `actual.svg` so a maintainer can reproduce.
166
179
 
180
+ For automation, pass `--no-open` (or set `DOMOTION_NO_OPEN=1`) and drive the
181
+ printed local URL headlessly; Review and Scrubber otherwise open the system
182
+ browser for interactive use.
183
+
184
+ Animation runs have the same evidence path. `domotion animate demo.json --debug`
185
+ writes the final `actual.svg`, one shared HAR, and an `expected.png` plus
186
+ `captured-tree.json` for each composed frame. Use `--debug-dir <path>` to choose
187
+ the bundle location.
188
+
167
189
  For an *animated* SVG, the package also ships `svg-scrubber` — a local video-style bench to play / pause / scrub / mark an in-out range, export the current frame as PNG, export the range as MP4, or trim it to a new self-contained animated SVG. Add `--review` to file a focused issue against a moment in the timeline: it writes an importable `.ticket` (frame time, range, and drawn regions) the same way `svg-review` builds a report for a still.
168
190
 
169
191
  ### Scripting API
@@ -186,6 +208,11 @@ await browser.close();
186
208
 
187
209
  For animated demos, capture multiple frames and pass them to `generateAnimatedSvg` (see `examples/`).
188
210
 
211
+ Library callers can collect a reproduction entirely in memory with
212
+ `captureElementTreeWithDebug()` and `assembleCaptureDebugBundle()`. The caller
213
+ keeps ownership of the browser, files, and optional HAR lifecycle; see the
214
+ [scripting API](https://brianwestphal.github.io/domotion/developer/api/).
215
+
189
216
  ## Scripts
190
217
 
191
218
  ```bash
@@ -201,7 +228,7 @@ npm run demos:examples # run the bundled example demo scripts
201
228
 
202
229
  - `FEATURES.md` — per-feature support checklist with links to test fixtures.
203
230
  - `docs/` — requirements docs covering rendering fidelity, supported CSS features, and known caveats.
204
- - [`llms.txt`](llms.txt) — a concise, self-contained guide for **AI agents using Domotion as a tool** (Claude, Cursor, etc.): the CLIs, the config schema, the template library, the API, and the gotchas. Point your agent at it.
231
+ - [`llms.txt`](llms.txt) — a concise, self-contained guide for **AI agents using Domotion as a tool** (Claude, Cursor, etc.): the CLIs, config schema, template library, API, gotchas, and a required rendered-pixel/video review gate before an SVG is handed back. Point your agent at it.
205
232
  - `CLAUDE.md` — guidance for AI assistants working *on this repo's* source (different audience from `llms.txt`).
206
233
 
207
234
  ## License
@@ -1,178 +1,9 @@
1
1
  /**
2
- * SVG Animation Composer
2
+ * Stable public facade for animated SVG composition.
3
3
  *
4
- * Takes captured SVG frame content and composes them into a single
5
- * animated SVG with CSS keyframe transitions.
4
+ * The implementation lives in `svg-generator.ts`; timeline arithmetic is
5
+ * isolated in `frame-timeline.ts`. Keeping this facade preserves existing
6
+ * imports while preventing CLI/capture plumbing from becoming part of the SVG
7
+ * generator's ownership boundary.
6
8
  */
7
- import { type CursorAtResolver, type CursorOverlay, type SelectorResolver } from "./cursor-overlay.js";
8
- import type { MagicMove } from "./magic-move.js";
9
- import type { AnimationOverlay, TypingOverlay, TapOverlay, SvgOverlay, BlinkOverlay, ShineOverlay, InteractOverlay, IntraFrameAnimation } from "./overlay-schema.js";
10
- import { type ResolvedTextTrack } from "./caret-track.js";
11
- import { type Transition } from "./transition-schema.js";
12
- export interface AnimationFrame {
13
- /** SVG content for this frame (from dom-to-svg) */
14
- svgContent: string;
15
- /**
16
- * Per-element viewBox-cull keyframes CSS (DM-603). The caller runs
17
- * `cullElementsOutsideViewBox()` on the captured tree before `elementTreeToSvg()` — that
18
- * mutates `displayNone` / `cullClass` on each element (which the renderer
19
- * surfaces) and returns the keyframes blocks that map each window-derived
20
- * `cull-<start>-<end>` class to its visible window. The animator splices
21
- * this CSS into the scene-wide `<style>` block, deduping blocks whose class
22
- * (= window) repeats across frames.
23
- *
24
- * When omitted, no culling happens — callers passing pre-rendered
25
- * `svgContent` strings without the cull CSS get unchanged behavior.
26
- */
27
- cullCss?: string;
28
- /** Duration this frame is shown (ms) */
29
- duration: number;
30
- /**
31
- * DM-1319: this frame's `svgContent` is itself a self-contained *animated* SVG
32
- * (a `cast` / `template` frame) whose internal timeline should start when the
33
- * frame becomes visible, not at the master-loop origin. Set to the embedded
34
- * content's own play length (ms); the animator re-anchors its keyframes into
35
- * the `[frameStart, frameStart + period]` window of the master loop (see
36
- * `offsetEmbeddedAnimatedSvgTimeline`). Omit for ordinary captured frames.
37
- */
38
- embeddedAnimationPeriodMs?: number;
39
- /** Transition to the next frame. The type is derived from the canonical zod schema. */
40
- transition?: Transition;
41
- /**
42
- * Magic-move bridge layer for this frame's transition to the next, built by
43
- * the caller via `buildMagicMove(prevTree, nextTree, …)`. Present only when
44
- * `transition.type === "magic-move"` and both frames' element trees were
45
- * available; the animator shows it during the transition window (moved
46
- * elements slide, added fade in, removed fade out) between the hard-cut prev
47
- * and next frame blobs. When `transition.type` is `magic-move` but this is
48
- * null, the animator falls back to `crossfade`.
49
- */
50
- magicMove?: MagicMove | null;
51
- /** Overlays: typing, tap ripple */
52
- overlays?: AnimationOverlay[];
53
- /**
54
- * Intra-frame property animations. Run during this frame's hold time.
55
- * The CLI / `DemoRecorder` resolves selectors against the DOM at capture
56
- * and sets `data-domotion-anim` on matching elements; this list is the
57
- * post-resolution form referencing those ids. See `IntraFrameAnimation`.
58
- */
59
- animations?: IntraFrameAnimation[];
60
- }
61
- export type { TypingOverlay, TapOverlay, SvgOverlay, BlinkOverlay, ShineOverlay, InteractOverlay, AnimationOverlay, IntraFrameAnimation };
62
- export interface AnimationConfig {
63
- width: number;
64
- height: number;
65
- frames: AnimationFrame[];
66
- /** DM-1488: accessible name → `role="img"` + `<title>` on the root `<svg>`
67
- * (for inline-`<svg>` embedding). Omit to leave the output unchanged. */
68
- title?: string;
69
- /** DM-1488: accessible long description → `<desc>` on the root `<svg>`. */
70
- desc?: string;
71
- /**
72
- * Markup (e.g. `<path id="g0" d="..."/>...`) hoisted into the top-level
73
- * `<defs>`. Frames can reference these IDs via `<use href="#...">`. Use for
74
- * glyph paths and other assets that repeat across frames — avoids duplicating
75
- * them in every frame's local defs.
76
- */
77
- sharedDefs?: string;
78
- /**
79
- * DM-839: embedded-font `@font-face` rules collected once across all frames
80
- * (the caller renders each frame with `includeEmbeddedFontCss=false` and
81
- * passes the accumulated `getEmbeddedFontFaceCss()` here). Injected into the
82
- * top-level `<style>` so the base64 font bytes appear once, not per frame.
83
- */
84
- fontFaceCss?: string;
85
- /**
86
- * Optional cursor / click overlay (DM-277). Renders a macOS-style cursor
87
- * moving along the script timeline with QuickTime-style click pulses.
88
- * Off by default; opt-in per animation. See `docs/13-cursor-overlay.md`.
89
- */
90
- cursorOverlay?: CursorOverlay;
91
- /**
92
- * Resolver for selector-based cursor move events. Required if any event
93
- * uses `selector`; otherwise pass undefined / null.
94
- */
95
- resolveSelector?: SelectorResolver;
96
- /**
97
- * DM-1106: auto cursor-TYPE hit-tester — given a viewport point and frame
98
- * index, returns the cursor keyword under it (the caller builds this from the
99
- * per-frame captured trees via `cursorAtPoint`). When provided, the overlay
100
- * paints the matching glyph per element and switches at boundary crossings;
101
- * when omitted, the overlay paints the single arrow.
102
- */
103
- resolveCursorAt?: CursorAtResolver;
104
- /**
105
- * Caret + selection tracks (docs/101): declarative caret / selection
106
- * rendering anchored to captured text, resolved caller-side against the
107
- * frame's captured tree via `resolveTextTrack` (the magic-move precedent —
108
- * built from the element trees, consumed here as resolved geometry). Layered
109
- * above every frame group and below the cursor overlay. Times inside each
110
- * track are ms on the animation's global timeline.
111
- */
112
- textTracks?: ResolvedTextTrack[];
113
- /**
114
- * Canvas background color painted behind every frame (a full-viewport
115
- * `<rect>`). Mirrors the single-frame path's `transparentRootBgRect`
116
- * (DM-554): pass the captured page's root background so animated output
117
- * matches `capture` output. Omitted / `"transparent"` / `"rgba(0, 0, 0, 0)"`
118
- * → no rect, i.e. a transparent SVG that composites over a host background.
119
- */
120
- background?: string;
121
- /**
122
- * DM-1148: whether the LAST frame fades out (over its transition window) to
123
- * dissolve back into the loop's frame 0. Default `false` — the last frame
124
- * HOLDS solid to 100% and the loop hard-cuts to frame 0, so a one-shot video
125
- * ends on the final frame rather than fading to nothing. Set `true` to restore
126
- * the cross-dissolve loop (e.g. for a seamless background-loop SVG). Only
127
- * affects the crossfade path; cut transitions already hold-then-cut.
128
- */
129
- loopFade?: boolean;
130
- }
131
- /**
132
- * DM-1145: re-namespace element ids that COLLIDE across frames. A caller that
133
- * reuses identical `svgContent` for multiple frames — e.g. caching a captured
134
- * frame and replaying it for a long hold — emits the same baked-in ids in two
135
- * frame groups. Duplicate ids are invalid SVG: a `clip-path="url(#id)"` / filter
136
- * / `<use href="#id">` resolves to the FIRST match, which for the later frame
137
- * lives in an earlier (now `visibility:hidden`) frame group. Chromium renders
138
- * that fine during continuous playback, but CLIPS THE ELEMENT AWAY when the
139
- * timeline is SEEKED to that frame (paused + `currentTime` set) — exactly what
140
- * svg-to-video does, so the element vanishes in the rendered video although the
141
- * SVG looks fine when played. Rename each frame's colliding ids (and their
142
- * in-frame references) to a frame-unique form. ONLY collisions are touched, so
143
- * frames whose ids are already unique are emitted byte-for-byte unchanged.
144
- */
145
- export declare function dedupeFrameIds(frames: AnimationFrame[]): AnimationFrame[];
146
- /** A rectangular half-plane reveal sampled to a fixed vertex count so angled
147
- * wipe polygons remain CSS-interpolable on every supported engine. */
148
- export declare function linearWipeClip(f: number, width: number, height: number, angleDeg: number): string;
149
- /**
150
- * DM-1767 (docs/104): resolve an overlay's WINDOW END, in ms from frame start.
151
- *
152
- * Historically every overlay's window ended with its frame. `endAt` makes that
153
- * explicit and lets an overlay end EARLY — clamped to the frame's duration, so
154
- * it can still never leak past the cut into the next frame. Returns the frame's
155
- * own duration when the overlay declares nothing, which is why every existing
156
- * config emits byte-identical CSS.
157
- *
158
- * Exported for unit tests.
159
- */
160
- export declare function overlayWindowEndMs(overlay: AnimationOverlay, frameDurationMs: number): number;
161
- /**
162
- * Collapse repeated numeric offsets inside whole-layer CSS `@keyframes` blocks.
163
- * Later declarations win per property, matching CSS source-order cascading,
164
- * but each offset is emitted once so boundary behavior is engine-independent.
165
- * Blocks without repeated offsets remain byte-identical.
166
- */
167
- export declare function consolidateKeyframeOffsets(svg: string): string;
168
- export declare function generateAnimatedSvg(config: AnimationConfig): string;
169
- /**
170
- * DM-1767: each overlay kind's default `delay` — the ms after frame start at
171
- * which it begins when the author sets none. Published because SHIFTING an
172
- * overlay onto a different origin (a per-state overlay inside a compressed run
173
- * moving from "its own state's start" to "the collapsed run's start" —
174
- * docs/104) must add the offset to the EFFECTIVE delay; adding it to a bare
175
- * `delay ?? 0` would silently drop the kind's own lead-in and the overlay would
176
- * fire early relative to how it behaved as its own frame.
177
- */
178
- export declare const OVERLAY_DEFAULT_DELAY_MS: Record<AnimationOverlay["kind"], number>;
9
+ export * from "./svg-generator.js";