motionary 7.9.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +1 -1
  3. package/README_ja.md +1 -1
  4. package/README_zh.md +1 -1
  5. package/dist/chunks/{audio-DcPvT2Kh.js → audio-CynhhWDi.js} +3 -3
  6. package/dist/chunks/{audio-DcPvT2Kh.js.map → audio-CynhhWDi.js.map} +1 -1
  7. package/dist/chunks/{audio-EXUoijsG.cjs → audio-cgWbDkoY.cjs} +3 -3
  8. package/dist/chunks/{audio-EXUoijsG.cjs.map → audio-cgWbDkoY.cjs.map} +1 -1
  9. package/dist/chunks/{base-2-yYc93C.js → base-CLuqlLfG.js} +63 -6
  10. package/dist/chunks/base-CLuqlLfG.js.map +1 -0
  11. package/dist/chunks/{base-BaQV-2ha.cjs → base-DoRUZBy-.cjs} +66 -5
  12. package/dist/chunks/base-DoRUZBy-.cjs.map +1 -0
  13. package/dist/chunks/{builtins-HlqAkK0f.js → builtins-Bs4smevg.js} +3 -3
  14. package/dist/chunks/{builtins-HlqAkK0f.js.map → builtins-Bs4smevg.js.map} +1 -1
  15. package/dist/chunks/{builtins-xalxV2d5.cjs → builtins-ClXshqj-.cjs} +3 -3
  16. package/dist/chunks/{builtins-xalxV2d5.cjs.map → builtins-ClXshqj-.cjs.map} +1 -1
  17. package/dist/chunks/{core-DuO-AVXL.js → core-C3Taz-ew.js} +2 -2
  18. package/dist/chunks/{core-DuO-AVXL.js.map → core-C3Taz-ew.js.map} +1 -1
  19. package/dist/chunks/{core-D5rU0CV6.js → core-CiN5sqxB.js} +2 -2
  20. package/dist/chunks/{core-D5rU0CV6.js.map → core-CiN5sqxB.js.map} +1 -1
  21. package/dist/chunks/{core-BGAyaY6L.cjs → core-CwO835Wm.cjs} +2 -2
  22. package/dist/chunks/{core-BGAyaY6L.cjs.map → core-CwO835Wm.cjs.map} +1 -1
  23. package/dist/chunks/{core-zq17EeCI.cjs → core-O4grKHSa.cjs} +2 -2
  24. package/dist/chunks/{core-zq17EeCI.cjs.map → core-O4grKHSa.cjs.map} +1 -1
  25. package/dist/chunks/{fx-lBGVtQO1.cjs → fx-C-XjLOTc.cjs} +2 -2
  26. package/dist/chunks/{fx-lBGVtQO1.cjs.map → fx-C-XjLOTc.cjs.map} +1 -1
  27. package/dist/chunks/{fx-CMxWNwH8.js → fx-CQv3IxMf.js} +2 -2
  28. package/dist/chunks/{fx-CMxWNwH8.js.map → fx-CQv3IxMf.js.map} +1 -1
  29. package/dist/chunks/{gpu-DLPghVWr.js → gpu-CB8frFOD.js} +2 -2
  30. package/dist/chunks/{gpu-DLPghVWr.js.map → gpu-CB8frFOD.js.map} +1 -1
  31. package/dist/chunks/{gpu-Dx0H875w.cjs → gpu-CcdA2D2i.cjs} +2 -2
  32. package/dist/chunks/{gpu-Dx0H875w.cjs.map → gpu-CcdA2D2i.cjs.map} +1 -1
  33. package/dist/chunks/{index-tags-C04JP8g4.js → index-tags-B-JBecYg.js} +2 -2
  34. package/dist/chunks/index-tags-B-JBecYg.js.map +1 -0
  35. package/dist/chunks/{index-tags-BTMwrfgV.cjs → index-tags-hLIF2Clq.cjs} +2 -2
  36. package/dist/chunks/index-tags-hLIF2Clq.cjs.map +1 -0
  37. package/dist/chunks/{player-PS6_FzNw.cjs → player-C2n17sdH.cjs} +4 -4
  38. package/dist/chunks/{player-PS6_FzNw.cjs.map → player-C2n17sdH.cjs.map} +1 -1
  39. package/dist/chunks/{player-DxvCYo7Q.js → player-YzQGkKaW.js} +4 -4
  40. package/dist/chunks/{player-DxvCYo7Q.js.map → player-YzQGkKaW.js.map} +1 -1
  41. package/dist/chunks/{registry-DehBVRDV.cjs → registry-BVklOepd.cjs} +2 -2
  42. package/dist/chunks/{registry-DehBVRDV.cjs.map → registry-BVklOepd.cjs.map} +1 -1
  43. package/dist/chunks/{registry-CyKExAmE.js → registry-CnO7ZVPK.js} +2 -2
  44. package/dist/chunks/{registry-CyKExAmE.js.map → registry-CnO7ZVPK.js.map} +1 -1
  45. package/dist/chunks/{spring-BK8DiezC.js → spring-BFKNHmfl.js} +2 -2
  46. package/dist/chunks/{spring-BK8DiezC.js.map → spring-BFKNHmfl.js.map} +1 -1
  47. package/dist/chunks/{spring-Dgx187Vh.cjs → spring-uQMVJTj9.cjs} +2 -2
  48. package/dist/chunks/{spring-Dgx187Vh.cjs.map → spring-uQMVJTj9.cjs.map} +1 -1
  49. package/dist/chunks/{variants-BQ6bhzn4.js → variants-B-zKORvt.js} +2 -2
  50. package/dist/chunks/{variants-BQ6bhzn4.js.map → variants-B-zKORvt.js.map} +1 -1
  51. package/dist/chunks/{variants-BhjyddG8.cjs → variants-DagykrKH.cjs} +2 -2
  52. package/dist/chunks/{variants-BhjyddG8.cjs.map → variants-DagykrKH.cjs.map} +1 -1
  53. package/dist/components/a11y.cjs +2 -2
  54. package/dist/components/a11y.d.cts +1 -1
  55. package/dist/components/a11y.d.ts +1 -1
  56. package/dist/components/a11y.js +3 -3
  57. package/dist/components/angular.cjs +9 -9
  58. package/dist/components/angular.d.cts +2 -18
  59. package/dist/components/angular.d.ts +2 -18
  60. package/dist/components/angular.js +9 -9
  61. package/dist/components/background.cjs +2 -2
  62. package/dist/components/background.js +2 -2
  63. package/dist/components/bridge.cjs +1 -1
  64. package/dist/components/bridge.js +1 -1
  65. package/dist/components/cards.cjs +2 -2
  66. package/dist/components/cards.js +2 -2
  67. package/dist/components/click.cjs +3 -3
  68. package/dist/components/click.js +3 -3
  69. package/dist/components/depth.cjs +3 -3
  70. package/dist/components/depth.js +3 -3
  71. package/dist/components/effects.cjs +7 -7
  72. package/dist/components/effects.js +9 -9
  73. package/dist/components/engine.cjs +266 -0
  74. package/dist/components/engine.cjs.map +1 -0
  75. package/dist/components/engine.d.cts +105 -0
  76. package/dist/components/engine.d.ts +105 -0
  77. package/dist/components/engine.js +255 -0
  78. package/dist/components/engine.js.map +1 -0
  79. package/dist/components/feedback.cjs +1 -1
  80. package/dist/components/feedback.js +1 -1
  81. package/dist/components/fx-3d.cjs +2 -2
  82. package/dist/components/fx-3d.js +2 -2
  83. package/dist/components/fx-ai.cjs +2 -2
  84. package/dist/components/fx-ai.js +2 -2
  85. package/dist/components/fx-chart.cjs +2 -2
  86. package/dist/components/fx-chart.js +2 -2
  87. package/dist/components/fx-festival.cjs +121 -0
  88. package/dist/components/fx-festival.cjs.map +1 -0
  89. package/dist/components/fx-festival.d.cts +69 -0
  90. package/dist/components/fx-festival.d.ts +69 -0
  91. package/dist/components/fx-festival.js +117 -0
  92. package/dist/components/fx-festival.js.map +1 -0
  93. package/dist/components/fx-focus.cjs +2 -2
  94. package/dist/components/fx-focus.js +2 -2
  95. package/dist/components/fx-form.cjs +2 -2
  96. package/dist/components/fx-form.js +2 -2
  97. package/dist/components/fx-game.cjs +2 -2
  98. package/dist/components/fx-game.js +2 -2
  99. package/dist/components/fx-geo.cjs +2 -2
  100. package/dist/components/fx-geo.js +2 -2
  101. package/dist/components/fx-gpu.cjs +3 -3
  102. package/dist/components/fx-gpu.js +3 -3
  103. package/dist/components/fx-light.cjs +2 -2
  104. package/dist/components/fx-light.js +2 -2
  105. package/dist/components/fx-morph.cjs +2 -2
  106. package/dist/components/fx-morph.js +2 -2
  107. package/dist/components/fx-music.cjs +3 -3
  108. package/dist/components/fx-music.js +3 -3
  109. package/dist/components/fx-physics.cjs +2 -2
  110. package/dist/components/fx-physics.js +2 -2
  111. package/dist/components/fx-shop.cjs +2 -2
  112. package/dist/components/fx-shop.js +2 -2
  113. package/dist/components/fx-social.cjs +2 -2
  114. package/dist/components/fx-social.js +2 -2
  115. package/dist/components/fx-text.cjs +2 -2
  116. package/dist/components/fx-text.js +2 -2
  117. package/dist/components/fx-transitions.cjs +3 -3
  118. package/dist/components/fx-transitions.js +3 -3
  119. package/dist/components/fx-weather.cjs +2 -2
  120. package/dist/components/fx-weather.js +2 -2
  121. package/dist/components/fx.cjs +5 -5
  122. package/dist/components/fx.js +6 -6
  123. package/dist/components/fx2.cjs +10 -4
  124. package/dist/components/fx2.cjs.map +1 -1
  125. package/dist/components/fx2.d.cts +26 -1
  126. package/dist/components/fx2.d.ts +26 -1
  127. package/dist/components/fx2.js +10 -6
  128. package/dist/components/fx2.js.map +1 -1
  129. package/dist/components/gesture.cjs +3 -3
  130. package/dist/components/gesture.js +4 -4
  131. package/dist/components/interaction.cjs +1 -1
  132. package/dist/components/interaction.js +1 -1
  133. package/dist/components/jsx.d.cts +1 -1
  134. package/dist/components/jsx.d.ts +1 -1
  135. package/dist/components/layout.cjs +1 -1
  136. package/dist/components/layout.js +1 -1
  137. package/dist/components/lazy.cjs +1 -1
  138. package/dist/components/lazy.d.cts +1 -1
  139. package/dist/components/lazy.d.ts +1 -1
  140. package/dist/components/lazy.js +1 -1
  141. package/dist/components/lite.cjs +151 -206
  142. package/dist/components/lite.cjs.map +1 -1
  143. package/dist/components/lite.js +152 -206
  144. package/dist/components/lite.js.map +1 -1
  145. package/dist/components/marketplace.cjs +2 -2
  146. package/dist/components/marketplace.js +2 -2
  147. package/dist/components/packs.cjs +1 -1
  148. package/dist/components/packs.js +1 -1
  149. package/dist/components/page.cjs +2 -2
  150. package/dist/components/page.js +3 -3
  151. package/dist/components/perf.cjs +2 -2
  152. package/dist/components/perf.d.cts +1 -1
  153. package/dist/components/perf.d.ts +1 -1
  154. package/dist/components/perf.js +3 -3
  155. package/dist/components/physics.cjs +2 -2
  156. package/dist/components/physics.js +3 -3
  157. package/dist/components/react.cjs +1 -1
  158. package/dist/components/react.js +1 -1
  159. package/dist/components/reveal.cjs +1 -1
  160. package/dist/components/reveal.js +1 -1
  161. package/dist/components/solid.cjs +9 -9
  162. package/dist/components/solid.d.cts +2 -18
  163. package/dist/components/solid.d.ts +2 -18
  164. package/dist/components/solid.js +9 -9
  165. package/dist/components/svelte.cjs +9 -9
  166. package/dist/components/svelte.d.cts +2 -18
  167. package/dist/components/svelte.d.ts +2 -18
  168. package/dist/components/svelte.js +9 -9
  169. package/dist/components/svg.cjs +1 -1
  170. package/dist/components/svg.js +1 -1
  171. package/dist/components/text.cjs +2 -2
  172. package/dist/components/text.js +2 -2
  173. package/dist/components/timeline.cjs +2 -2
  174. package/dist/components/timeline.js +3 -3
  175. package/dist/components/transitions.cjs +1 -1
  176. package/dist/components/transitions.js +1 -1
  177. package/dist/components/ui.cjs +17 -108
  178. package/dist/components/ui.cjs.map +1 -1
  179. package/dist/components/ui.css +0 -1
  180. package/dist/components/ui.d.cts +3 -20
  181. package/dist/components/ui.d.ts +3 -20
  182. package/dist/components/ui.js +19 -109
  183. package/dist/components/ui.js.map +1 -1
  184. package/dist/components/vue.cjs +9 -9
  185. package/dist/components/vue.d.cts +2 -18
  186. package/dist/components/vue.d.ts +2 -18
  187. package/dist/components/vue.js +9 -9
  188. package/dist/components/webgl.cjs +1 -1
  189. package/dist/components/webgl.js +1 -1
  190. package/dist/components/widgets.cjs +373 -146
  191. package/dist/components/widgets.cjs.map +1 -1
  192. package/dist/components/widgets.d.cts +110 -2
  193. package/dist/components/widgets.d.ts +110 -2
  194. package/dist/components/widgets.js +369 -147
  195. package/dist/components/widgets.js.map +1 -1
  196. package/dist/components.cjs +9 -10
  197. package/dist/components.cjs.map +1 -1
  198. package/dist/components.css +0 -1
  199. package/dist/components.d.cts +4 -21
  200. package/dist/components.d.ts +4 -21
  201. package/dist/components.js +12 -12
  202. package/dist/components.umd.js +2 -2
  203. package/dist/components.umd.js.map +1 -1
  204. package/dist/index.cjs +2 -2
  205. package/dist/index.js +2 -2
  206. package/dist/index.umd.js +2 -2
  207. package/dist/index.umd.js.map +1 -1
  208. package/dist/widgets.umd.js +1 -1
  209. package/dist/widgets.umd.js.map +1 -1
  210. package/docs/ROADMAP.md +14 -12
  211. package/docs/accessibility.md +1 -2
  212. package/docs/components.md +44 -1
  213. package/docs/deprecations.md +1 -1
  214. package/docs/upgrading-8.md +9 -6
  215. package/package.json +41 -1
  216. package/dist/chunks/base-2-yYc93C.js.map +0 -1
  217. package/dist/chunks/base-BaQV-2ha.cjs.map +0 -1
  218. package/dist/chunks/index-tags-BTMwrfgV.cjs.map +0 -1
  219. package/dist/chunks/index-tags-C04JP8g4.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/presets.ts","../src/core.ts","../src/stagger.ts","../src/components/base.ts","../src/components/tokens/index.ts","../src/components/timeline/core.ts","../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * motionary - Animation Presets\n * Defines keyframes for all built-in animation presets\n */\n\nimport type { AnimationPreset, CorePreset, CustomAnimation, EasingType, ExtendedPreset, PresetKeyframes } from './types';\n\ntype KeyframeMap = PresetKeyframes;\n\nconst CORE: Record<CorePreset, KeyframeMap> = {\n 'fade-in': {\n from: { opacity: 0 },\n to: { opacity: 1 },\n },\n 'fade-in-up': {\n from: { opacity: 0, transform: 'translateY(40px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'fade-in-down': {\n from: { opacity: 0, transform: 'translateY(-40px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'fade-in-left': {\n from: { opacity: 0, transform: 'translateX(-40px)' },\n to: { opacity: 1, transform: 'translateX(0px)' },\n },\n 'fade-in-right': {\n from: { opacity: 0, transform: 'translateX(40px)' },\n to: { opacity: 1, transform: 'translateX(0px)' },\n },\n 'zoom-in': {\n from: { opacity: 0, transform: 'scale(0.8)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'zoom-out': {\n from: { opacity: 0, transform: 'scale(1.2)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'flip-x': {\n from: { opacity: 0, transform: 'rotateX(-90deg)' },\n to: { opacity: 1, transform: 'rotateX(0deg)' },\n },\n 'flip-y': {\n from: { opacity: 0, transform: 'rotateY(-90deg)' },\n to: { opacity: 1, transform: 'rotateY(0deg)' },\n },\n 'slide-up': {\n from: { transform: 'translateY(100%)' },\n to: { transform: 'translateY(0px)' },\n },\n 'slide-down': {\n from: { transform: 'translateY(-100%)' },\n to: { transform: 'translateY(0px)' },\n },\n 'slide-left': {\n from: { transform: 'translateX(-100%)' },\n to: { transform: 'translateX(0px)' },\n },\n 'slide-right': {\n from: { transform: 'translateX(100%)' },\n to: { transform: 'translateX(0px)' },\n },\n 'bounce': {\n from: { opacity: 0, transform: 'translateY(-60px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'rotate-in': {\n from: { opacity: 0, transform: 'rotate(-180deg) scale(0.5)' },\n to: { opacity: 1, transform: 'rotate(0deg) scale(1)' },\n },\n 'blur-in': {\n from: { opacity: 0, filter: 'blur(12px)' },\n to: { opacity: 1, filter: 'blur(0px)' },\n },\n 'skew-in': {\n from: { opacity: 0, transform: 'skewX(20deg) translateX(30px)' },\n to: { opacity: 1, transform: 'skewX(0deg) translateX(0px)' },\n },\n 'scale-x': {\n from: { transform: 'scaleX(0)' },\n to: { transform: 'scaleX(1)' },\n },\n 'scale-y': {\n from: { transform: 'scaleY(0)' },\n to: { transform: 'scaleY(1)' },\n },\n 'shimmer': {\n from: { opacity: 0.5, filter: 'brightness(1)' },\n to: { opacity: 1, filter: 'brightness(1.5)' },\n },\n 'pulse': {\n from: { transform: 'scale(1)' },\n to: { transform: 'scale(1.05)' },\n },\n 'swing': {\n from: { transform: 'rotate(-10deg)' },\n to: { transform: 'rotate(10deg)' },\n },\n 'scale-up': {\n from: { opacity: 0, transform: 'scale(0.5)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'blur-in-up': {\n from: { opacity: 0, filter: 'blur(12px)', transform: 'translateY(40px)' },\n to: { opacity: 1, filter: 'blur(0px)', transform: 'translateY(0px)' },\n },\n 'flip-up': {\n from: { opacity: 0, transform: 'perspective(800px) rotateX(60deg)' },\n to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },\n },\n 'flip-down': {\n from: { opacity: 0, transform: 'perspective(800px) rotateX(-60deg)' },\n to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },\n },\n 'rotate-left': {\n from: { opacity: 0, transform: 'rotate(-15deg) translateX(-40px)' },\n to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },\n },\n 'rotate-right': {\n from: { opacity: 0, transform: 'rotate(15deg) translateX(40px)' },\n to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },\n },\n // clip-path reveals: content is uncovered without moving or fading\n 'clip-up': {\n from: { clipPath: 'inset(100% 0% 0% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-down': {\n from: { clipPath: 'inset(0% 0% 100% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-left': {\n from: { clipPath: 'inset(0% 0% 0% 100%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-right': {\n from: { clipPath: 'inset(0% 100% 0% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-circle': {\n from: { clipPath: 'circle(0% at 50% 50%)' },\n to: { clipPath: 'circle(75% at 50% 50%)' },\n },\n};\n\n/**\n * One preset table per page, shared through a global symbol so every copy of\n * the library (ESM entries, the UMD bundle, `presets/extended`) sees presets\n * registered by any other copy. `<usa-reveal>` / `<usa-stagger>` read it too.\n */\nconst share = (core: Record<string, KeyframeMap>): Record<string, KeyframeMap> => {\n const g = globalThis as any;\n const key = Symbol.for('use-scroll-animate.presets');\n return (g[key] = Object.assign(g[key] || {}, core));\n};\n\n/**\n * Every registered preset: the 33 core presets, plus the 6.1 extended set once\n * `motionary/presets/extended` is loaded, plus your own.\n */\nexport const PRESETS = /*#__PURE__*/ share(CORE) as Record<CorePreset, KeyframeMap> & Partial<Record<ExtendedPreset, KeyframeMap>>;\n\n/**\n * Add (or replace) presets by name: `registerPresets({ 'my-pop': { from, to, frames? } })`.\n * They work everywhere a preset name does (`animation`, `exit`, `data-sa-animation`,\n * `<scroll-animate>`, `<usa-reveal effect>`).\n */\nexport function registerPresets(presets: Record<string, PresetKeyframes>): void {\n Object.assign(PRESETS, presets);\n}\n\n/** The same keyframes played backwards (exit animations). */\nexport function reversePreset(p: KeyframeMap): KeyframeMap {\n return { from: p.to, to: p.from, frames: p.frames && p.frames.map((f) => ({ ...f, offset: 1 - f.offset })).reverse() };\n}\n\nconst lookup = (name: string): KeyframeMap | undefined => (PRESETS as Record<string, KeyframeMap>)[name.trim()];\n\nexport function resolvePreset(animation: AnimationPreset | AnimationPreset[] | CustomAnimation): KeyframeMap {\n if (typeof animation === 'string') {\n return lookup(animation) ?? PRESETS['fade-in-up'];\n }\n \n if (Array.isArray(animation)) {\n const combined: KeyframeMap = { from: {}, to: {} };\n animation.forEach(name => {\n const preset = lookup(name);\n if (preset) {\n Object.entries(preset.from).forEach(([key, val]) => {\n if (key === 'transform' && combined.from[key]) {\n combined.from[key] = `${combined.from[key]} ${val}`;\n } else {\n combined.from[key] = val;\n }\n });\n Object.entries(preset.to).forEach(([key, val]) => {\n if (key === 'transform' && combined.to[key]) {\n combined.to[key] = `${combined.to[key]} ${val}`;\n } else {\n combined.to[key] = val;\n }\n });\n }\n });\n return combined;\n }\n \n return animation;\n}\n\n/** Easing to CSS cubic-bezier mapping */\nexport const EASING_MAP: Record<string, string> = {\n linear: 'linear',\n ease: 'ease',\n 'ease-in': 'ease-in',\n 'ease-out': 'ease-out',\n 'ease-in-out': 'ease-in-out',\n spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n 'soft-spring': 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n 'heavy-bounce': 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n};\n\nexport function resolveEasing(easing: EasingType): string {\n if (typeof easing === 'string') {\n return EASING_MAP[easing] ?? easing;\n }\n if (Array.isArray(easing)) {\n return `cubic-bezier(${easing.join(', ')})`;\n }\n if (typeof easing === 'function') {\n // Functions cannot be expressed as a CSS easing string; the core samples\n // them into a `linear()` easing (or keyframes on older browsers).\n return 'linear';\n }\n return 'ease';\n}\n","/**\n * motionary - Core Implementation\n * Uses IntersectionObserver + Web Animations API for zero-dependency,\n * high-performance scroll-triggered animations.\n */\n\nimport type {\n AnimateOptions,\n AnimatedElement,\n ScrollAnimateConfig,\n ScrollAnimateInstance,\n} from './types';\nimport { resolvePreset, resolveEasing, reversePreset } from './presets';\n\ntype KeyframeMap = ReturnType<typeof resolvePreset>;\ntype Target = string | Element | NodeList | Element[];\ntype Root = Element | Document | null;\n\nconst DEFAULT_CONFIG: Required<ScrollAnimateConfig> = {\n defaultAnimation: 'fade-in-up',\n defaultDuration: 600,\n defaultDelay: 0,\n defaultEasing: 'ease',\n defaultThreshold: 0.1,\n defaultRootMargin: '0px',\n defaultRepeat: false,\n defaultOnce: true,\n defaultOffset: 0,\n hiddenClass: 'sa-hidden',\n visibleClass: 'sa-visible',\n useClassNames: false,\n disabled: false,\n root: null,\n autoUnregister: true,\n defaultEngine: 'auto',\n};\n\nconst noop = () => undefined;\n\n/* ------------------------------------------------------------------ */\n/* Environment helpers (all SSR-safe: never touch globals at import) */\n/* ------------------------------------------------------------------ */\n\nconst hasDOM = (): boolean => typeof window !== 'undefined' && typeof document !== 'undefined';\n\n/** @internal */\nexport const supportsObserver = (): boolean => hasDOM() && typeof IntersectionObserver !== 'undefined';\n\nlet reducedMotionQuery: MediaQueryList | null | undefined;\n\n/** @internal Whether the user asked the OS/browser to reduce motion. */\nexport function prefersReducedMotion(): boolean {\n if (!hasDOM()) return false;\n if (reducedMotionQuery === undefined) {\n reducedMotionQuery =\n typeof window.matchMedia === 'function' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n }\n return !!reducedMotionQuery && reducedMotionQuery.matches;\n}\n\nlet scrollTimelineSupported: boolean | undefined;\n\n/**\n * Whether the browser can run presets on a native scroll-driven timeline:\n * `CSS.supports('animation-timeline: view()')` plus the `ViewTimeline`\n * constructor used to attach it from JavaScript. Cached. SSR-safe.\n */\nexport function supportsScrollTimeline(): boolean {\n if (scrollTimelineSupported === undefined) {\n scrollTimelineSupported =\n hasDOM() &&\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('animation-timeline: view()') &&\n typeof (globalThis as any).ViewTimeline === 'function';\n }\n return scrollTimelineSupported;\n}\n\n/** @internal Reset the cached feature checks (tests). */\nexport function resetFeatureCache(): void {\n scrollTimelineSupported = undefined;\n linearSupported = undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* Option parsing */\n/* ------------------------------------------------------------------ */\n\nfunction num(value: string | undefined): number | undefined {\n if (value === undefined || value.trim() === '') return undefined;\n const n = parseFloat(value);\n return Number.isFinite(n) ? n : undefined;\n}\n\n\nconst DEFAULT_PROGRESS_VAR = '--sa-progress';\nconst DEFAULT_VIEW_RANGE: [string, string] = ['entry 0%', 'entry 100%'];\n\n/** `''` (bare attribute) -> default name; `sa-progress` -> `--sa-progress`. */\nfunction normalizeVar(name: string): string {\n const v = name.trim();\n if (!v) return DEFAULT_PROGRESS_VAR;\n return v.startsWith('--') ? v : `--${v}`;\n}\n\n/**\n * @internal Read options from string attributes. `get(name)` returns the raw\n * value of the attribute `name` (kebab-case, e.g. `root-margin`), `''` for a\n * bare attribute and `undefined` when absent. Shared by `data-sa-*` and the\n * `<scroll-animate>` element.\n */\nexport function readOptions(get: (name: string) => string | undefined): AnimateOptions {\n const opts: AnimateOptions = {};\n\n const anim = get('animation');\n if (anim) {\n opts.animation = (anim.includes(',') ? anim.split(',').map((s) => s.trim()) : anim.trim()) as any;\n }\n opts.duration = num(get('duration'));\n opts.delay = num(get('delay'));\n const easing = get('easing');\n if (easing) {\n const e = easing.trim();\n if (e.startsWith('[')) {\n try {\n opts.easing = JSON.parse(e);\n } catch {\n // Malformed JSON: fall back to the default easing instead of throwing\n }\n } else {\n opts.easing = e;\n }\n }\n const t = get('threshold');\n if (t) {\n opts.threshold = t.includes(',') ? t.split(',').map(parseFloat).filter(Number.isFinite) : num(t);\n }\n const rootMargin = get('root-margin');\n if (rootMargin) opts.rootMargin = rootMargin;\n const repeat = get('repeat');\n if (repeat !== undefined) opts.repeat = repeat !== 'false';\n const once = get('once');\n if (once !== undefined) opts.once = once !== 'false';\n opts.offset = num(get('offset'));\n opts.stagger = num(get('stagger'));\n const progressVar = get('progress-var');\n if (progressVar !== undefined) opts.progressVar = normalizeVar(progressVar);\n const engine = get('engine')?.trim();\n if (engine === 'auto' || engine === 'js' || engine === 'css') opts.engine = engine;\n const range = get('view-range');\n if (range) {\n const [start, end] = range.split(',').map((s) => s.trim());\n if (start && end) opts.viewRange = [start, end];\n }\n const exit = get('exit');\n if (exit !== undefined) {\n const e = exit.trim();\n opts.exit = e === '' || e === 'true' ? true : e === 'false' ? false : ((e.includes(',') ? e.split(',').map((s) => s.trim()) : e) as any);\n }\n const progress = get('progress');\n if (progress) opts.progressMode = progress.trim() === 'scroll' ? 'scroll' : 'ratio';\n\n // Drop keys that were not set, so they don't override defaults when spread.\n (Object.keys(opts) as Array<keyof AnimateOptions>).forEach((k) => opts[k] === undefined && delete opts[k]);\n return opts;\n}\n\nfunction parseDataAttributes(el: Element, config: Required<ScrollAnimateConfig>): Required<AnimateOptions> {\n return mergeOptions(\n readOptions((name) => {\n const v = el.getAttribute(`data-sa-${name}`);\n return v === null ? undefined : v;\n }),\n config\n );\n}\n\nfunction mergeOptions(opts: AnimateOptions, config: Required<ScrollAnimateConfig>): Required<AnimateOptions> {\n let engine = opts.engine ?? config.defaultEngine;\n // 'auto' keeps time-based semantics when the element asks for them explicitly.\n if (engine === 'auto' && (opts.duration !== undefined || opts.delay !== undefined || opts.offset !== undefined || (opts.stagger ?? 0) > 0)) {\n engine = 'js';\n }\n const exit = opts.exit ?? false;\n const repeat = opts.repeat ?? (exit ? true : config.defaultRepeat);\n const threshold = opts.threshold ?? config.defaultThreshold;\n return {\n animation: opts.animation ?? config.defaultAnimation,\n duration: opts.duration ?? config.defaultDuration,\n delay: opts.delay ?? config.defaultDelay,\n easing: opts.easing ?? config.defaultEasing,\n threshold: Array.isArray(threshold) && threshold.length === 0 ? config.defaultThreshold : threshold,\n rootMargin: opts.rootMargin ?? config.defaultRootMargin,\n repeat,\n once: opts.once ?? (repeat ? false : config.defaultOnce),\n offset: opts.offset ?? config.defaultOffset,\n stagger: opts.stagger ?? 0,\n onStart: opts.onStart ?? noop,\n onComplete: opts.onComplete ?? noop,\n onEnter: opts.onEnter ?? noop,\n onLeave: opts.onLeave ?? noop,\n onProgress: opts.onProgress ?? noop,\n progressMode: opts.progressMode ?? 'ratio',\n progressVar: opts.progressVar ? normalizeVar(opts.progressVar) : '',\n engine,\n viewRange: opts.viewRange ?? DEFAULT_VIEW_RANGE,\n exit,\n };\n}\n\nfunction resolveTargets(target: Target | null | undefined): Element[] {\n if (!target || !hasDOM()) return [];\n if (typeof target === 'string') return Array.from(document.querySelectorAll(target));\n if (target instanceof Element) return [target];\n if (Array.isArray(target) || target instanceof NodeList) {\n return (Array.from(target as ArrayLike<Node>) as Element[]).filter((el) => el instanceof Element);\n }\n return [];\n}\n\n/**\n * Apply `offset` to the bottom edge of a rootMargin, preserving the other\n * three sides. `offset: 100` means \"trigger 100px later\" (bottom -100px).\n * @internal\n */\nexport function applyOffset(rootMargin: string, offset: number): string {\n if (!offset) return rootMargin;\n const parts = (rootMargin || '0px').trim().split(/\\s+/);\n const top = parts[0];\n const right = parts[1] ?? top;\n const bottom = parts[2] ?? top;\n const left = parts[3] ?? right;\n const m = /^(-?\\d*\\.?\\d+)(px)?$/.exec(bottom);\n const base = m ? parseFloat(m[1]) : 0; // non-px bottoms (e.g. %) cannot be combined; offset wins\n return `${top} ${right} ${base - offset}px ${left}`;\n}\n\nfunction needsProgress(opts: Required<AnimateOptions>): boolean {\n return opts.onProgress !== noop || !!opts.progressVar;\n}\n\n/**\n * True scroll progress of `el` through the viewport (or `root`): 0 when its top\n * edge reaches the bottom of the viewport, 1 when its bottom edge passes the top.\n * Works for elements taller than the viewport. Returns 0 without a DOM.\n */\nexport function getScrollProgress(el: Element, root?: Element | null): number {\n if (!hasDOM()) return 0;\n const rect = el.getBoundingClientRect();\n let top = 0;\n let height = window.innerHeight || document.documentElement.clientHeight || 0;\n if (root) {\n const r = root.getBoundingClientRect();\n top = r.top;\n height = r.height;\n }\n const total = height + rect.height;\n if (total <= 0) return 0;\n const p = (top + height - rect.top) / total;\n return p < 0 ? 0 : p > 1 ? 1 : p;\n}\n\n/* ------------------------------------------------------------------ */\n/* Animation */\n/* ------------------------------------------------------------------ */\n\n/** The animation currently running on an element, so it can be cancelled/replaced. */\nconst running = new WeakMap<Element, Animation>();\n/** Native engine: the scroll-linked exit animation, next to the entrance in `running`. */\nconst exits = new WeakMap<Element, Animation>();\nconst timers = new WeakMap<Element, ReturnType<typeof setTimeout>>();\n\nfunction cancelRunning(el: Element): void {\n const exitAnim = exits.get(el);\n if (exitAnim) {\n exits.delete(el);\n exitAnim.cancel();\n }\n const anim = running.get(el);\n if (anim) {\n running.delete(el);\n anim.onfinish = null;\n anim.cancel();\n }\n const timer = timers.get(el);\n if (timer !== undefined) {\n clearTimeout(timer);\n timers.delete(el);\n }\n}\n\nfunction setStyles(el: Element, styles: Record<string, string | number>): void {\n const style = (el as HTMLElement).style;\n if (!style) return;\n Object.keys(styles).forEach((prop) => {\n (style as any)[prop] = String(styles[prop]);\n });\n}\n\nconst NUM_UNIT = /(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?)([a-z%]*)/gi;\n\n/**\n * Interpolate two CSS values at `t`. Numbers interpolate directly; strings\n * interpolate when they share the same structure (e.g. `translateY(40px)` ->\n * `translateY(0px)`, or `scale(0.8)` -> `scale(1)`). Otherwise snaps at 0.5.\n * @internal\n */\nexport function interpolateValue(from: string | number, to: string | number, t: number): string | number {\n if (typeof from === 'number' && typeof to === 'number') return from + (to - from) * t;\n const a = String(from);\n const b = String(to);\n const ta: Array<[number, string]> = [];\n const tb: Array<[number, string]> = [];\n const skA = a.replace(NUM_UNIT, (_, n, u) => (ta.push([parseFloat(n), u]), '#'));\n const skB = b.replace(NUM_UNIT, (_, n, u) => (tb.push([parseFloat(n), u]), '#'));\n if (skA !== skB || ta.length !== tb.length) return t < 0.5 ? from : to;\n let i = 0;\n let ok = true;\n const out = skA.replace(/#/g, () => {\n const [na, ua] = ta[i];\n const [nb, ub] = tb[i++];\n if (ua !== ub && na !== 0 && nb !== 0 && ua && ub) ok = false;\n const unit = ua || ub;\n return `${+(na + (nb - na) * t).toFixed(4)}${unit}`;\n });\n return ok ? out : t < 0.5 ? from : to;\n}\n\nconst EASING_SAMPLES = 30;\nlet linearSupported: boolean | undefined;\n\nfunction supportsLinearEasing(): boolean {\n if (linearSupported === undefined) {\n linearSupported =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('animation-timing-function', 'linear(0, 1)');\n }\n return linearSupported;\n}\n\nfunction sampleEasing(fn: (t: number) => number): number[] {\n const values: number[] = [];\n for (let i = 0; i <= EASING_SAMPLES; i++) {\n const v = fn(i / EASING_SAMPLES);\n values.push(Number.isFinite(v) ? +v.toFixed(4) : i / EASING_SAMPLES);\n }\n return values;\n}\n\nfunction buildAnimation(\n preset: KeyframeMap,\n easing: Required<AnimateOptions>['easing']\n): { keyframes: Keyframe[]; easing: string } {\n // `frames`: intermediate keyframes (overshoot, bounce, glitch …) between from and to\n const list = [preset.from, ...(preset.frames || []), preset.to] as Keyframe[];\n if (typeof easing !== 'function') {\n return { keyframes: list, easing: resolveEasing(easing) };\n }\n const samples = sampleEasing(easing);\n // Modern browsers: an exact, property-agnostic `linear()` easing curve.\n if (supportsLinearEasing() || preset.frames) {\n return { keyframes: list, easing: supportsLinearEasing() ? `linear(${samples.join(', ')})` : 'ease' };\n }\n // Fallback: approximate the curve with interpolated keyframes.\n const props = Object.keys(preset.from).filter((p) => p in preset.to);\n const keyframes = samples.map((eased, i) => {\n const frame: Keyframe = { offset: i / EASING_SAMPLES };\n props.forEach((prop) => {\n frame[prop] = interpolateValue(preset.from[prop], preset.to[prop], eased);\n });\n return frame;\n });\n return { keyframes, easing: 'linear' };\n}\n\n/** Make an element visible without animating (reduced motion / disabled / no WAAPI). */\nfunction reveal(el: Element, config: Required<ScrollAnimateConfig>): void {\n cancelRunning(el);\n if (config.useClassNames) {\n el.classList.remove(config.hiddenClass);\n el.classList.add(config.visibleClass);\n } else {\n const style = (el as HTMLElement).style;\n if (style) style.opacity = '';\n }\n}\n\n/** @internal Cancel a running/pending animation and make the element visible. */\nexport function stopAnimation(el: Element, config: ScrollAnimateConfig = {}): void {\n reveal(el, { ...DEFAULT_CONFIG, ...config });\n}\n\n/** @internal Resolve a selector / Element / NodeList / Element[] to elements (SSR-safe). */\nexport { resolveTargets, hasDOM };\n\n/** @internal Whether animations should be skipped entirely. */\nexport function motionDisabled(config: Pick<ScrollAnimateConfig, 'disabled'>): boolean {\n return !!config.disabled || prefersReducedMotion();\n}\n\nfunction runAnimation(\n el: Element,\n opts: Required<AnimateOptions>,\n config: Required<ScrollAnimateConfig>,\n staggerIndex = 0,\n pending?: Set<Element>\n): void {\n const { duration, delay, stagger, onStart, onComplete } = opts;\n const totalDelay = Math.max(0, delay + staggerIndex * stagger);\n cancelRunning(el);\n\n if (motionDisabled(config)) {\n reveal(el, config);\n onStart(el);\n onComplete(el);\n return;\n }\n\n if (config.useClassNames) {\n if (totalDelay > 0) (el as HTMLElement).style.animationDelay = `${totalDelay}ms`;\n el.classList.remove(config.hiddenClass);\n el.classList.add(config.visibleClass);\n onStart(el);\n pending?.add(el);\n timers.set(\n el,\n setTimeout(() => {\n timers.delete(el);\n pending?.delete(el);\n onComplete(el);\n }, duration + totalDelay)\n );\n return;\n }\n\n const preset = resolvePreset(opts.animation);\n // Presets that don't animate opacity (slide-*, clip-*, scale-x, ...) would\n // otherwise stay at the `opacity: 0` applied while waiting to enter.\n if (!('opacity' in preset.to)) {\n const style = (el as HTMLElement).style;\n if (style && style.opacity === '0') style.opacity = '';\n }\n\n if (typeof el.animate !== 'function') {\n setStyles(el, preset.to);\n onStart(el);\n onComplete(el);\n return;\n }\n\n const built = buildAnimation(preset, opts.easing);\n const timing: KeyframeAnimationOptions = { duration, delay: totalDelay, easing: built.easing, fill: 'both' };\n let anim: Animation;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n // Invalid user easing string (WAAPI throws a TypeError): fall back to 'ease'\n anim = el.animate(built.keyframes, { ...timing, easing: 'ease' });\n }\n running.set(el, anim);\n onStart(el);\n anim.onfinish = () => {\n if (running.get(el) === anim) {\n running.delete(el);\n // Persist the end state inline and drop the filling animation. This frees\n // the Animation object and lets later inline styles (parallax, user code)\n // take effect instead of being masked by `fill: forwards`.\n try {\n anim.commitStyles();\n } catch {\n setStyles(el, preset.to);\n }\n anim.cancel();\n }\n onComplete(el);\n };\n}\n\n/**\n * Native engine: attach the preset to a `ViewTimeline` of the element, so the\n * browser drives it from scroll position. Returns `null` when that fails\n * (caller falls back to the JS engine).\n */\nfunction startNative(el: Element, opts: Required<AnimateOptions>, onFrozen?: () => void): Animation | null {\n if (typeof el.animate !== 'function') return null;\n const preset = resolvePreset(opts.animation);\n const built = buildAnimation(preset, opts.easing);\n let anim: Animation;\n try {\n const timeline = new (globalThis as any).ViewTimeline({ subject: el, axis: 'block' });\n const timing = {\n fill: 'both',\n easing: built.easing,\n timeline,\n rangeStart: opts.viewRange[0],\n rangeEnd: opts.viewRange[1],\n } as KeyframeAnimationOptions;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n anim = el.animate(built.keyframes, { ...timing, easing: 'linear' });\n }\n } catch {\n return null;\n }\n running.set(el, anim);\n if (opts.exit) {\n // Reverse keyframes over the `exit` range; `fill: 'forwards'` so it has\n // no effect before the element starts leaving.\n const leave = resolvePreset(opts.exit === true ? opts.animation : opts.exit);\n const out = buildAnimation(reversePreset(leave), opts.easing);\n try {\n const timeline = new (globalThis as any).ViewTimeline({ subject: el, axis: 'block' });\n const timing = { fill: 'forwards', easing: out.easing, timeline, rangeStart: 'exit 0%', rangeEnd: 'exit 100%' };\n exits.set(el, el.animate(out.keyframes, timing as KeyframeAnimationOptions));\n } catch {\n // Exit is cosmetic: ignore if unsupported.\n }\n }\n const keep = opts.repeat || !opts.once;\n anim.onfinish = () => {\n // `once`: freeze the end state, so scrolling back up does not reverse it.\n if (!keep && running.get(el) === anim) {\n running.delete(el);\n try {\n anim.commitStyles();\n } catch {\n setStyles(el, preset.to);\n }\n anim.cancel();\n onFrozen?.();\n }\n opts.onComplete(el);\n };\n return anim;\n}\n\n/** Play the exit animation (entrance or `exit` preset, reversed), ending hidden. */\nfunction runExit(el: Element, opts: Required<AnimateOptions>, config: Required<ScrollAnimateConfig>): void {\n if (config.useClassNames || typeof el.animate !== 'function') {\n hideElement(el, config);\n return;\n }\n cancelRunning(el);\n const preset = resolvePreset(opts.exit === true ? opts.animation : (opts.exit as Exclude<typeof opts.exit, boolean>));\n const built = buildAnimation(reversePreset(preset), opts.easing);\n const timing: KeyframeAnimationOptions = { duration: opts.duration, easing: built.easing, fill: 'forwards' };\n let anim: Animation;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n anim = el.animate(built.keyframes, { ...timing, easing: 'ease' });\n }\n // Kept (filling) until the next entrance cancels it.\n running.set(el, anim);\n}\n\nfunction hideElement(el: Element, config: Required<ScrollAnimateConfig>): void {\n cancelRunning(el);\n if (config.useClassNames) {\n el.classList.add(config.hiddenClass);\n el.classList.remove(config.visibleClass);\n } else {\n const style = (el as HTMLElement).style;\n if (style) style.opacity = '0';\n }\n}\n\n/** @internal Hide an element before its entrance animation, unless motion is off. */\nexport function prepareElement(el: Element, config: ScrollAnimateConfig = {}): void {\n const full = { ...DEFAULT_CONFIG, ...config };\n if (!motionDisabled(full)) hideElement(el, full);\n}\n\nlet progressThresholds: number[] | undefined;\nfunction getProgressThresholds(): number[] {\n if (!progressThresholds) {\n progressThresholds = [];\n for (let i = 0; i <= 100; i++) progressThresholds.push(i / 100);\n }\n return progressThresholds;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/* ------------------------------------------------------------------ */\n/* Instance */\n/* ------------------------------------------------------------------ */\n\nexport function createScrollAnimate(userConfig: ScrollAnimateConfig = {}): ScrollAnimateInstance {\n let config: Required<ScrollAnimateConfig> = { ...DEFAULT_CONFIG, ...userConfig };\n const registry = new Map<Element, AnimatedElement>();\n // `once` elements that finished and were dropped from the registry (autoUnregister).\n let finished = new WeakSet<Element>();\n // Elements in `progressMode: 'scroll'` that are currently inside the viewport.\n const scrolling = new Set<Element>();\n let frame = 0;\n let listening: EventTarget | null = null;\n // Active watch() MutationObservers, disconnected by destroy().\n const watchers = new Set<MutationObserver>();\n // Elements with a pending class-name completion timer started by this instance.\n const pending = new Set<Element>();\n // Elements whose entrance runs on a native scroll-driven timeline.\n const natives = new Set<Element>();\n\n // Observers are shared between elements with the same root/threshold/rootMargin,\n // instead of one (or two) IntersectionObservers per element.\n const pools = new Map<Root, Map<string, IntersectionObserver>>();\n\n function pooled(root: Root, key: string, create: () => IntersectionObserver): IntersectionObserver {\n let pool = pools.get(root);\n if (!pool) pools.set(root, (pool = new Map()));\n let io = pool.get(key);\n if (!io) pool.set(key, (io = create()));\n return io;\n }\n\n function teardown(el: Element, restore: boolean): void {\n const record = registry.get(el);\n if (!record) return;\n record.observer.unobserve(el);\n record.progressObserver?.unobserve(el);\n registry.delete(el);\n untrack(el);\n if (record.engine === 'css') {\n // A scroll-linked animation would keep following the scroll: stop it and\n // show the element (unless it finished and is just being released).\n if (restore) {\n natives.delete(el);\n reveal(el, config);\n } else if (el.isConnected === false) {\n // Left the DOM: drop it too, or the instance keeps it alive (and\n // destroy() touches it) for its whole lifetime.\n natives.delete(el);\n }\n return;\n }\n // An element that never animated would otherwise stay invisible forever.\n if (restore && !record.animated) reveal(el, config);\n }\n\n function pruneDetached(): void {\n registry.forEach((record, el) => {\n if (el.isConnected === false) teardown(el, false);\n });\n }\n\n function emitProgress(el: Element, record: AnimatedElement, progress: number): void {\n const opts = record.options;\n opts.onProgress(el, progress);\n if (opts.progressVar) {\n const style = (el as HTMLElement).style;\n if (style) style.setProperty(opts.progressVar, String(+progress.toFixed(4)));\n }\n }\n\n function update(): void {\n frame = 0;\n scrolling.forEach((el) => {\n const record = registry.get(el);\n if (record) emitProgress(el, record, getScrollProgress(el, config.root));\n });\n }\n\n // rAF-throttled; IntersectionObserver-capable browsers all have rAF.\n const schedule = () => frame || (frame = requestAnimationFrame(update));\n\n function listen(on: boolean): void {\n if (on === !!listening) return;\n const method = on ? 'addEventListener' : 'removeEventListener';\n const target: EventTarget = listening || (config.root as EventTarget | null) || window;\n target[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n listening = on ? target : null;\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n }\n\n function untrack(el: Element): void {\n if (scrolling.delete(el) && !scrolling.size) listen(false);\n }\n\n function onScrollIntersect(entries: IntersectionObserverEntry[]): void {\n entries.forEach((entry) => {\n const el = entry.target;\n const record = registry.get(el);\n if (!record) return;\n if (entry.isIntersecting) {\n scrolling.add(el);\n listen(true);\n } else {\n untrack(el);\n }\n // Emit right away so the edges (0 / 1) are reported even on fast scrolls.\n emitProgress(el, record, getScrollProgress(el, config.root));\n });\n }\n\n function onIntersect(entries: IntersectionObserverEntry[]): void {\n const staggerCounts = new Map<Element | null, number>();\n entries.forEach((entry) => {\n const el = entry.target;\n const record = registry.get(el);\n if (!record) return;\n const opts = record.options;\n\n if (el.isConnected === false) {\n teardown(el, false);\n return;\n }\n\n if (record.engine === 'css') {\n // The browser drives the animation; only lifecycle bookkeeping here.\n if (entry.isIntersecting) {\n opts.onEnter(el);\n if (!record.animated) {\n record.animated = true;\n opts.onStart(el);\n }\n if (opts.once && !opts.repeat) {\n record.observer.unobserve(el);\n if (config.autoUnregister && !record.progressObserver) {\n finished.add(el);\n teardown(el, false);\n }\n }\n } else {\n opts.onLeave(el);\n if (opts.repeat) record.animated = false;\n }\n return;\n }\n\n if (entry.isIntersecting) {\n opts.onEnter(el);\n if (record.animated && !opts.repeat) return;\n\n // Stagger relative to siblings revealed in the same batch, so elements\n // scrolled into view later don't inherit an ever-growing delay.\n let staggerIndex = 0;\n if (opts.stagger > 0) {\n const parent = el.parentElement;\n staggerIndex = staggerCounts.get(parent) ?? 0;\n staggerCounts.set(parent, staggerIndex + 1);\n }\n\n runAnimation(el, opts, config, staggerIndex, pending);\n record.animated = true;\n\n if (opts.once && !opts.repeat) {\n // Keep the progress observer: parallax/onProgress must keep working.\n record.observer.unobserve(el);\n if (config.autoUnregister && !record.progressObserver) {\n // Nothing left to watch: free the record (the running animation\n // keeps its own reference until it finishes).\n finished.add(el);\n teardown(el, false);\n }\n }\n } else {\n opts.onLeave(el);\n if (opts.repeat && record.animated) {\n if (!motionDisabled(config)) {\n if (opts.exit) runExit(el, opts, config);\n else hideElement(el, config);\n }\n record.animated = false;\n }\n }\n });\n }\n\n function onProgress(entries: IntersectionObserverEntry[]): void {\n entries.forEach((entry) => {\n const record = registry.get(entry.target);\n if (!record) return;\n emitProgress(entry.target, record, entry.intersectionRatio);\n });\n }\n\n function getObserver(opts: Required<AnimateOptions>): IntersectionObserver {\n const rootMargin = applyOffset(opts.rootMargin, opts.offset);\n const threshold = opts.threshold;\n const root = config.root;\n return pooled(root, `m|${rootMargin}|${String(threshold)}`, () =>\n new IntersectionObserver(onIntersect, { threshold, rootMargin, root: root as Element | null })\n );\n }\n\n function getProgressObserver(opts: Required<AnimateOptions>): IntersectionObserver {\n const root = config.root;\n if (opts.progressMode === 'scroll') {\n // Only used to know when to start/stop measuring; progress itself comes\n // from a single shared, rAF-throttled passive scroll listener.\n return pooled(root, `s|${opts.rootMargin}`, () =>\n new IntersectionObserver(onScrollIntersect, { threshold: 0, rootMargin: opts.rootMargin, root: root as Element | null })\n );\n }\n return pooled(root, `p|${opts.rootMargin}`, () =>\n new IntersectionObserver(onProgress, {\n threshold: getProgressThresholds(),\n rootMargin: opts.rootMargin,\n root: root as Element | null,\n })\n );\n }\n\n function attach(el: Element, record: AnimatedElement, observeMain: boolean): void {\n record.observer = getObserver(record.options);\n if (observeMain) record.observer.observe(el);\n record.progressObserver = needsProgress(record.options) ? getProgressObserver(record.options) : undefined;\n record.progressObserver?.observe(el);\n }\n\n function wantsNative(opts: Required<AnimateOptions>): boolean {\n return opts.engine !== 'js' && !config.useClassNames && !motionDisabled(config) && supportsScrollTimeline();\n }\n\n function observeElement(el: Element, opts: Required<AnimateOptions>): void {\n if (registry.has(el) || finished.has(el)) return;\n\n if (!supportsObserver()) {\n // No IntersectionObserver (very old browser): never leave content hidden.\n reveal(el, config);\n return;\n }\n\n const record = { element: el, options: opts, animated: false, engine: 'js' } as AnimatedElement;\n if (wantsNative(opts)) {\n cancelRunning(el);\n if (startNative(el, opts, () => natives.delete(el))) {\n record.engine = 'css';\n natives.add(el);\n }\n }\n if (record.engine === 'js' && !motionDisabled(config)) hideElement(el, config);\n\n registry.set(el, record);\n attach(el, record, true);\n }\n\n function observeDataElement(el: Element): void {\n if (!registry.has(el)) observeElement(el, parseDataAttributes(el, config));\n }\n\n const instance: ScrollAnimateInstance = {\n observe(target, options = {}) {\n pruneDetached();\n const opts = mergeOptions(options, config);\n resolveTargets(target).forEach((el) => observeElement(el, opts));\n },\n\n unobserve(target) {\n resolveTargets(target).forEach((el) => {\n finished.delete(el);\n teardown(el, true);\n });\n },\n\n init(rootElement) {\n const scope = rootElement ?? (hasDOM() ? document : null);\n if (!scope) return;\n pruneDetached();\n scope.querySelectorAll('[data-sa]').forEach(observeDataElement);\n },\n\n watch(rootElement) {\n const scope = rootElement ?? (hasDOM() ? document : null);\n if (!scope || typeof MutationObserver === 'undefined') return noop;\n instance.init(scope);\n const observeTree = (node: Element) => {\n if (node.hasAttribute('data-sa')) observeDataElement(node);\n node.querySelectorAll('[data-sa]').forEach(observeDataElement);\n };\n const mo = new MutationObserver((records) => {\n let removed = false;\n records.forEach((record) => {\n if (record.type === 'attributes') {\n const target = record.target as Element;\n if (target.isConnected !== false) observeTree(target);\n return;\n }\n record.addedNodes.forEach((node) => {\n if (node instanceof Element && node.isConnected !== false) observeTree(node);\n });\n if (record.removedNodes.length) removed = true;\n });\n // Free elements that left the DOM (they can't animate any more).\n if (removed) pruneDetached();\n });\n mo.observe(scope, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-sa'] });\n watchers.add(mo);\n return () => {\n mo.disconnect();\n watchers.delete(mo);\n };\n },\n\n destroy() {\n watchers.forEach((mo) => mo.disconnect());\n watchers.clear();\n // Class-name mode: drop completion timers so onComplete never fires after destroy().\n pending.forEach((el) => {\n const timer = timers.get(el);\n if (timer !== undefined) {\n clearTimeout(timer);\n timers.delete(el);\n }\n });\n pending.clear();\n registry.forEach((record, el) => {\n if (!record.animated && record.engine !== 'css') reveal(el, config);\n });\n // Native scroll-linked animations still running: stop them, show content.\n natives.forEach((el) => {\n if (running.has(el)) reveal(el, config);\n });\n natives.clear();\n pools.forEach((pool) => pool.forEach((io) => io.disconnect()));\n pools.clear();\n registry.clear();\n scrolling.clear();\n listen(false);\n finished = new WeakSet();\n },\n\n refresh() {\n // Rebuild observers (e.g. after configure({ root })) without re-hiding or\n // replaying elements that have already animated.\n pools.forEach((pool) => pool.forEach((io) => io.disconnect()));\n pools.clear();\n scrolling.clear();\n listen(false);\n pruneDetached();\n if (!supportsObserver()) return;\n registry.forEach((record, el) => {\n const done = record.animated && record.options.once && !record.options.repeat;\n attach(el, record, !done);\n });\n },\n\n animate(target, options = {}) {\n const opts = mergeOptions(options, config);\n resolveTargets(target).forEach((el) => runAnimation(el, opts, config, 0, pending));\n },\n\n getObservedElements() {\n return Array.from(registry.values());\n },\n\n configure(newConfig) {\n config = { ...config, ...newConfig };\n },\n };\n\n return instance;\n}\n","/**\n * motionary - Staggered children\n * Reveal a container's children one after another when the container scrolls\n * into view, optionally also animating children that are added later.\n */\n\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate, hasDOM, prepareElement, stopAnimation, supportsObserver } from './core';\n\nexport interface StaggerOptions extends AnimateOptions {\n /** Delay between consecutive children in ms (default: 80) */\n stagger?: number;\n /**\n * Watch the container with a MutationObserver and animate children added\n * later (e.g. infinite lists). Children added after the container was\n * revealed animate when they scroll into view, staggered per batch.\n * (default: false)\n */\n observeChildren?: boolean;\n}\n\nlet fallback: ScrollAnimateInstance | null = null;\n\n/**\n * Animate the children of `container` with a stagger once it enters the\n * viewport. Returns a cleanup function. SSR-safe (no-op without a DOM).\n *\n * @example\n * const stop = staggerChildren(document.querySelector('ul'), { stagger: 60, observeChildren: true });\n */\nexport function staggerChildren(\n container: Element | null | undefined,\n options: StaggerOptions = {},\n instance?: ScrollAnimateInstance\n): () => void {\n if (!container || !hasDOM() || !supportsObserver()) return () => undefined; // leave content visible\n const sa = instance || fallback || (fallback = createScrollAnimate());\n const { stagger = 80, delay = 0, threshold = 0.1, rootMargin = '0px', observeChildren = false, ...rest } = options;\n\n let items = Array.from(container.children);\n let revealed = false;\n const late: Element[] = [];\n items.forEach((child) => prepareElement(child));\n\n const io = new IntersectionObserver(\n (entries) => {\n if (revealed || !entries.some((entry) => entry.isIntersecting)) return;\n revealed = true;\n io.disconnect();\n items.forEach((child, i) => {\n if (child.parentNode === container) sa.animate(child, { ...rest, delay: delay + i * stagger });\n });\n items = [];\n },\n { threshold, rootMargin }\n );\n io.observe(container);\n\n let mo: MutationObserver | undefined;\n if (observeChildren && typeof MutationObserver !== 'undefined') {\n mo = new MutationObserver((records) => {\n records.forEach((record) => {\n record.addedNodes.forEach((node) => {\n if (!(node instanceof Element) || node.parentNode !== container) return;\n if (!revealed) {\n prepareElement(node);\n items.push(node);\n } else {\n // The core engine staggers siblings relative to the batch that\n // enters the viewport together.\n late.push(node);\n sa.observe(node, { ...rest, delay, stagger, threshold, rootMargin });\n }\n });\n record.removedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n items = items.filter((el) => el !== node);\n const i = late.indexOf(node);\n if (i >= 0) {\n late.splice(i, 1);\n sa.unobserve(node);\n }\n });\n });\n });\n mo.observe(container, { childList: true });\n }\n\n return () => {\n io.disconnect();\n mo?.disconnect();\n // Stopped before the container was revealed: never leave the children hidden.\n if (!revealed) {\n revealed = true;\n items.forEach((child) => stopAnimation(child));\n items = [];\n }\n late.forEach((el) => sa.unobserve(el));\n late.length = 0;\n };\n}\n","/**\n * motionary/components — shared base for the `<usa-*>` custom elements.\n *\n * Everything here is lazy: nothing touches `window`, `document`,\n * `HTMLElement` or `matchMedia` at import time, so the components can be\n * imported during SSR (Next, Nuxt, Astro…) and in Electron/Tauri preload\n * scripts. Classes are created the first time a `define*()` function runs.\n */\n\nexport interface ComponentsConfig {\n /**\n * Inject each component's CSS when it is defined (default `true`). Uses a\n * constructable stylesheet (`document.adoptedStyleSheets`, which a strict\n * `style-src` CSP does not block) and falls back to a `<style>` tag. Set\n * to `false` when you load `motionary/components.css` yourself.\n */\n injectStyles?: boolean;\n /**\n * `'user'` (default) follows `prefers-reduced-motion`; `'reduce'` always\n * uses the reduced variants (e.g. a kiosk / battery-saver mode). 5.0: the\n * OS setting can no longer be ignored (`'no-preference'` was removed).\n */\n reducedMotion?: 'user' | 'reduce';\n /**\n * Global motion intensity (v2.7): `'low'` (shorter, calmer), `'normal'`\n * (default) or `'high'`. Scales every component animation's duration and\n * sets `--usa-motion` (0.6 / 1 / 1.25) on `<html>` for your own CSS. 5.0:\n * `'off'` was removed — use `motionSensitivity: 'minimal'`.\n */\n motionIntensity?: MotionIntensity;\n /**\n * Motion-sensitivity level (v4.4), finer than reduced motion:\n * `'full'` (default) · `'gentle'` (no spins, zooms, skews or parallax —\n * translations and fades only, safe for vestibular disorders) ·\n * `'minimal'` (fades only; components use their reduced-motion variants) ·\n * `'static'` (no animation: every component shows its static alternative).\n * See `setMotionSensitivity()` in `motionary/components/a11y`.\n */\n motionSensitivity?: MotionSensitivity;\n}\n\nexport type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';\nexport const MOTION_SENSITIVITY_LEVELS: readonly MotionSensitivity[] = ['full', 'gentle', 'minimal', 'static'];\n\nexport type MotionIntensity = 'low' | 'normal' | 'high';\nexport const MOTION_SCALE: Record<MotionIntensity, number> = { low: 0.6, normal: 1, high: 1.25 };\n\nconst config: Required<ComponentsConfig> = { injectStyles: true, reducedMotion: 'user', motionIntensity: 'normal', motionSensitivity: 'full' };\n\n/** Change global component settings (call before `define*()` for `injectStyles`). */\nexport function configureComponents(options: ComponentsConfig): void {\n options = { ...options };\n // 5.0: removed values are ignored (see docs/upgrading-5.md)\n if (options.motionIntensity && !(options.motionIntensity in MOTION_SCALE)) delete options.motionIntensity;\n if (options.reducedMotion && options.reducedMotion !== 'reduce') options.reducedMotion = 'user';\n Object.assign(config, options);\n if (options.motionIntensity && typeof document !== 'undefined') {\n document.documentElement.style.setProperty('--usa-motion', String(MOTION_SCALE[options.motionIntensity] ?? 1));\n document.documentElement.setAttribute('data-usa-motion', options.motionIntensity);\n }\n if (options.motionSensitivity && typeof document !== 'undefined') {\n if (options.motionSensitivity === 'full') document.documentElement.removeAttribute('data-usa-sensitivity');\n else document.documentElement.setAttribute('data-usa-sensitivity', options.motionSensitivity);\n }\n}\n\n/** The current motion-sensitivity level (v4.4). */\nexport function getMotionSensitivity(): MotionSensitivity {\n return config.motionSensitivity;\n}\n\nconst VESTIBULAR = /rotate|scale|skew|perspective|matrix3d/;\n/**\n * Adapt keyframes to the sensitivity level: `gentle` drops transforms that\n * spin, zoom or skew (and 3D), `minimal` keeps opacity only, `static` keeps\n * just the final frame. `full` returns them unchanged.\n */\nexport function adaptKeyframes(frames: Keyframe[], level: MotionSensitivity = config.motionSensitivity): Keyframe[] {\n if (level === 'full' || !frames.length) return frames;\n if (level === 'static') return [frames[frames.length - 1]];\n return frames.map((f) => {\n const out: Keyframe = {};\n for (const [k, v] of Object.entries(f)) {\n if (k === 'offset' || k === 'easing' || k === 'composite') out[k] = v as any;\n else if (level === 'minimal') {\n if (k === 'opacity') out[k] = v as any;\n } else if (k === 'rotate' || k === 'scale' || (k === 'transform' && VESTIBULAR.test(String(v)))) continue;\n else out[k] = v as any;\n }\n return out;\n });\n}\n\nlet quiet = 0;\n/** Run `fn` without 4.9 deprecation warnings (library-internal calls). */\nexport function withoutDeprecations<T>(fn: () => T): T {\n quiet++;\n try {\n return fn();\n } finally {\n quiet--;\n }\n}\n\n/** The current global motion intensity. */\nexport function getMotionIntensity(): MotionIntensity {\n return config.motionIntensity;\n}\n\n/** Duration multiplier for the current intensity (1 when `normal`). */\nexport function motionScale(): number {\n return MOTION_SCALE[config.motionIntensity] ?? 1;\n}\n\nexport const canDefine = (): boolean => typeof customElements !== 'undefined' && typeof HTMLElement !== 'undefined';\n\n/** `true` when animations should be reduced (OS setting or `configureComponents`). */\nexport function prefersReducedMotion(): boolean {\n if (config.motionSensitivity === 'minimal' || config.motionSensitivity === 'static') return true;\n if (config.reducedMotion === 'reduce') return true;\n return typeof matchMedia === 'function' && !!matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\nconst injected = new Set<string>();\n\n/** Add a component's stylesheet to the document once. */\nexport function adoptStyles(id: string, css: string): void {\n if (!config.injectStyles || !css || injected.has(id) || typeof document === 'undefined') return;\n injected.add(id);\n try {\n if (typeof CSSStyleSheet === 'function' && 'adoptedStyleSheets' in document) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(css);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];\n return;\n }\n } catch {\n /* fall through to <style> */\n }\n const style = document.createElement('style');\n style.setAttribute('data-usa', id);\n style.textContent = css;\n (document.head || document.documentElement).appendChild(style);\n}\n\n/** Attach `css` to a shadow root (constructable sheet where supported, else `<style>`). */\nexport function shadowStyles(root: ShadowRoot, css: string): void {\n try {\n if (typeof CSSStyleSheet === 'function' && 'adoptedStyleSheets' in root) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(css);\n root.adoptedStyleSheets = [sheet];\n return;\n }\n } catch {\n /* fall through */\n }\n const style = document.createElement('style');\n style.textContent = css;\n root.prepend(style);\n}\n\nexport type Cleanup = () => void;\n\n/**\n * Members shared by every `<usa-*>` element. Attribute helpers, a cleanup\n * bag that is emptied on disconnect, and motion helpers that degrade to the\n * final state without WAAPI or under reduced motion.\n */\nexport interface UsaElement extends HTMLElement {\n /** `true` while reduced motion applies to this element. */\n readonly reduced: boolean;\n}\n\nexport interface UsaBase extends UsaElement {\n mount(): void;\n changed(name: string): void;\n unmount(): void;\n str(name: string, fallback?: string): string;\n num(name: string, fallback: number): number;\n flag(name: string): boolean;\n setFlag(name: string, on: boolean): void;\n onCleanup(fn: Cleanup): void;\n listen<K extends keyof HTMLElementEventMap>(\n target: EventTarget,\n type: K | string,\n fn: (e: any) => void,\n options?: AddEventListenerOptions\n ): void;\n inView(cb: (visible: boolean, entry?: IntersectionObserverEntry) => void, init?: IntersectionObserverInit, target?: Element): void;\n motion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;\n emit(type: string, detail?: unknown): boolean;\n}\n\ntype BaseCtor = new () => UsaBase;\nlet baseClass: BaseCtor | null = null;\n\n/** The lazily created base class (needs `HTMLElement`). */\nexport function getBase(): BaseCtor {\n if (baseClass) return baseClass;\n class Base extends HTMLElement {\n private _cleanups: Cleanup[] = [];\n private _connected = false;\n\n get reduced(): boolean {\n return prefersReducedMotion();\n }\n\n connectedCallback(): void {\n if (this._connected) return;\n this._connected = true;\n styleLoader?.(this.localName);\n // Upgraded while the parser is still inside us (a <script> in <head>\n // defined the element): children/text are not there yet, so wait.\n if (typeof document !== 'undefined' && document.readyState === 'loading' && !this.nextSibling && !this.childNodes.length) {\n const go = () => {\n if (this._connected && this.isConnected) this.mount();\n };\n document.addEventListener('DOMContentLoaded', go, { once: true });\n this._cleanups.push(() => document.removeEventListener('DOMContentLoaded', go));\n return;\n }\n this.mount();\n }\n\n disconnectedCallback(): void {\n this._connected = false;\n this.teardown();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, value: string | null): void {\n if (!this._connected || oldValue === value) return;\n this.changed(_name);\n }\n\n /** Re-mount on attribute change (override for finer updates). */\n changed(_name: string): void {\n this.teardown();\n this.mount();\n }\n\n private teardown(): void {\n this._cleanups.splice(0).reverse().forEach((fn) => fn());\n this.unmount();\n }\n\n mount(): void {}\n unmount(): void {}\n\n str(name: string, fallback = ''): string {\n const v = this.getAttribute(name);\n return v === null ? fallback : v;\n }\n\n num(name: string, fallback: number): number {\n const v = this.getAttribute(name);\n const n = v === null || v.trim() === '' ? NaN : Number(v);\n return Number.isFinite(n) ? n : fallback;\n }\n\n /** Boolean attribute: present and not `\"false\"`. */\n flag(name: string): boolean {\n const v = this.getAttribute(name);\n return v !== null && v !== 'false';\n }\n\n setFlag(name: string, on: boolean): void {\n if (on) this.setAttribute(name, '');\n else this.removeAttribute(name);\n }\n\n onCleanup(fn: Cleanup): void {\n this._cleanups.push(fn);\n }\n\n listen(target: EventTarget, type: string, fn: (e: any) => void, options?: AddEventListenerOptions): void {\n target.addEventListener(type, fn, options);\n this.onCleanup(() => target.removeEventListener(type, fn, options));\n }\n\n /** Calls `cb(true/false)` as the element enters / leaves the viewport. */\n inView(cb: (visible: boolean, entry?: IntersectionObserverEntry) => void, init?: IntersectionObserverInit, target: Element = this): void {\n if (typeof IntersectionObserver === 'undefined') {\n cb(true);\n return;\n }\n const io = new IntersectionObserver((entries) => {\n for (const e of entries) cb(e.isIntersecting, e);\n }, init);\n io.observe(target);\n this.onCleanup(() => io.disconnect());\n }\n\n /** `el.animate()` that returns `null` (and applies the last frame) without WAAPI. */\n motion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null {\n return animateWithMotion(el, keyframes, options);\n }\n\n emit(type: string, detail?: unknown): boolean {\n return this.dispatchEvent(new CustomEvent(`usa:${type}`, { detail, bubbles: true, cancelable: true }));\n }\n }\n baseClass = Base as unknown as BaseCtor;\n return baseClass;\n}\n\n/**\n * `el.animate()` with the library's motion rules (5.0, shared by elements and\n * registered effects): motion sensitivity (keyframes adapted, `static` →\n * final frame), intensity (duration scale) and the animation budget. Returns\n * `null` (final frame applied) when nothing should animate.\n */\nexport function animateWithMotion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null {\n if (typeof (el as HTMLElement).animate !== 'function' || config.motionSensitivity === 'static') {\n applyFrame(el as HTMLElement, keyframes[keyframes.length - 1]);\n return null;\n }\n keyframes = adaptKeyframes(keyframes);\n if (active >= maxActive) {\n applyFrame(el as HTMLElement, keyframes[keyframes.length - 1]);\n return null;\n }\n const k = motionScale();\n if (k !== 1 && k > 0 && typeof options.duration === 'number') options = { ...options, duration: options.duration * k, delay: (options.delay || 0) * k };\n const a = (el as HTMLElement).animate(keyframes, options);\n if (options.iterations !== Infinity) {\n active++;\n let done = false;\n const end = () => {\n if (!done) {\n done = true;\n active--;\n }\n };\n a?.finished?.then(end, end);\n }\n return a;\n}\n\n/** Write a keyframe's properties as inline styles (no-WAAPI fallback). */\nexport function applyFrame(el: HTMLElement, frame?: Keyframe): void {\n if (!frame) return;\n for (const [k, v] of Object.entries(frame)) {\n if (k === 'offset' || k === 'easing' || k === 'composite' || v == null) continue;\n (el.style as any)[k] = String(v);\n }\n}\n\n/**\n * Register `tag` with the class built by `make(Base)`. Returns the\n * constructor, the already registered one, or `undefined` without DOM.\n */\nexport function defineElement(\n tag: string,\n make: (Base: BaseCtor) => CustomElementConstructor,\n css?: { id: string; text: string }\n): CustomElementConstructor | undefined {\n if (!canDefine()) return undefined;\n adoptStyles('base', BASE_CSS);\n if (css) adoptStyles(css.id, css.text);\n const existing = customElements.get(tag);\n if (existing) return existing;\n const ctor = make(getBase());\n customElements.define(tag, ctor);\n return ctor;\n}\n\nconst BASE_CSS = '.usa-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}';\n\n/** A visually hidden copy of `text` for screen readers (the animated copy is `aria-hidden`). */\nexport function srText(text: string): HTMLSpanElement {\n const s = document.createElement('span');\n s.className = 'usa-sr';\n s.textContent = text;\n return s;\n}\n\n// --- shared rAF scheduler (4.5) ----------------------------------------------\n// Every component loop goes through one requestAnimationFrame per frame\n// instead of one per element: callbacks are batched, run in order, and a\n// throwing callback no longer starves the others (the first error is rethrown).\nconst frameQueue = new Map<number, FrameRequestCallback>();\nlet frameSeq = 1;\nlet frameHandle: number | ReturnType<typeof setTimeout> | 0 = 0;\nlet frameVia: unknown = null;\nconst frameStats = { frames: 0, callbacks: 0, peak: 0, last: 0 };\nconst frameListeners = new Set<(t: number, dt: number) => void>();\n\nfunction flushFrame(t: number): void {\n frameHandle = 0;\n const dt = frameStats.last && t > frameStats.last ? t - frameStats.last : 16.7;\n frameStats.last = t;\n frameStats.frames++;\n const cbs = Array.from(frameQueue.values());\n frameQueue.clear();\n frameStats.callbacks += cbs.length;\n frameStats.peak = Math.max(frameStats.peak, cbs.length);\n let error: unknown = null;\n for (const cb of cbs) {\n try {\n cb(t);\n } catch (e) {\n error ??= e;\n }\n }\n frameListeners.forEach((fn) => fn(t, dt));\n if (frameListeners.size) requestFlush();\n if (error) throw error;\n}\n\nfunction requestFlush(): void {\n const native = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : null;\n // A stale handle from a replaced requestAnimationFrame (tests, iframes) is dropped.\n if (frameHandle && frameVia === native) return;\n frameVia = native;\n frameHandle = native ? native(flushFrame) : setTimeout(() => flushFrame(now()), 16);\n}\n\n/** requestAnimationFrame through the shared scheduler (timeout fallback in jsdom / hidden documents). */\nexport const raf = (cb: FrameRequestCallback): number => {\n const id = frameSeq++;\n frameQueue.set(id, cb);\n requestFlush();\n return id;\n};\n/** Monotonic time in ms (rAF callback timestamps differ between environments, so loops use this). */\nexport const now = (): number => (typeof performance !== 'undefined' ? performance.now() : Date.now());\nexport const caf = (id: number): void => {\n frameQueue.delete(id);\n};\n\n/** Run `fn(time, dt)` every frame on the shared scheduler until the returned function is called. */\nexport function onFrame(fn: (t: number, dt: number) => void): () => void {\n frameListeners.add(fn);\n requestFlush();\n return () => frameListeners.delete(fn);\n}\n\n/** Scheduler counters: frames flushed, callbacks run, peak callbacks in one frame, pending now. */\nexport function schedulerStats(): { frames: number; callbacks: number; peak: number; pending: number; loops: number } {\n return { frames: frameStats.frames, callbacks: frameStats.callbacks, peak: frameStats.peak, pending: frameQueue.size, loops: frameListeners.size };\n}\n\n// --- active animation budget (4.5) ---------------------------------------------\nlet active = 0;\nlet maxActive = Infinity;\n/** Number of component animations running right now. */\nexport const activeAnimations = (): number => active;\n/** Cap concurrent component animations; extra ones jump to their final frame (`Infinity` = no cap). */\nexport function setAnimationBudget(max: number): void {\n maxActive = max > 0 ? max : Infinity;\n}\n/** The current cap. */\nexport const animationBudget = (): number => maxActive;\n\n// --- on-demand styles (4.5) -----------------------------------------------------\nlet styleLoader: ((tag: string) => void) | null = null;\n/** Called with each element's tag the first time one connects (used by the `lite` build to load CSS on demand). */\nexport function setStyleLoader(fn: ((tag: string) => void) | null): void {\n styleLoader = fn;\n}\n\nexport const EASE_OUT = 'cubic-bezier(0.22, 1, 0.36, 1)';\nexport const EASE_SPRING = 'cubic-bezier(0.34, 1.56, 0.64, 1)';\n/** Windows Fluent \"decelerate\" / \"point-to-point\" curves. */\nexport const FLUENT_DECELERATE = 'cubic-bezier(0.1, 0.9, 0.2, 1)';\n\nconst warned = new Set<string>();\n/** Log a deprecation once per key (console.warn). */\nexport function deprecate(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n if (typeof console !== 'undefined') console.warn(`[motionary] ${message}`);\n}\n\n/**\n * The `kind` attribute of `<usa-spinner>`, `<usa-check>`, `<usa-dialog>` and\n * `<usa-acrylic>` (3.0: `variant` only selects a style variant).\n */\nexport function kindOf(el: Element, valid: readonly string[] | Record<string, unknown>, fallback: string): string {\n const k = el.getAttribute('kind');\n return k && (Array.isArray(valid) ? valid.includes(k) : k in (valid as object)) ? k : fallback;\n}\n\nexport const clamp = (v: number, min: number, max: number): number => Math.min(max, Math.max(min, v));\n","/**\n * motionary/components/tokens — motion design tokens (4.2).\n *\n * One source of truth for durations, easings and springs: as CSS custom\n * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,\n * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable\n * from Figma Tokens (Tokens Studio) or Style Dictionary exports.\n *\n * ```ts\n * import { applyMotionTokens, importMotionTokens, motionToken } from 'motionary/components/tokens';\n * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));\n * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });\n * ```\n */\n\nexport interface SpringToken {\n stiffness: number;\n damping: number;\n mass: number;\n}\n\nexport interface MotionTokens {\n /** Durations in ms. */\n duration: Record<string, number>;\n /** CSS easing strings. */\n easing: Record<string, string>;\n /** Spring physics parameters. */\n spring: Record<string, SpringToken>;\n}\n\n/** The default motion scale (Material / Fluent-inspired). */\nexport const MOTION_TOKENS: MotionTokens = {\n duration: { instant: 0, fast: 150, normal: 300, slow: 600, slower: 900, slowest: 1400 },\n easing: {\n linear: 'linear',\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n emphasized: 'cubic-bezier(0.22, 1, 0.36, 1)',\n decelerate: 'cubic-bezier(0, 0, 0, 1)',\n accelerate: 'cubic-bezier(0.3, 0, 1, 1)',\n spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n },\n spring: {\n gentle: { stiffness: 120, damping: 14, mass: 1 },\n snappy: { stiffness: 300, damping: 30, mass: 1 },\n bouncy: { stiffness: 260, damping: 12, mass: 1 },\n wobbly: { stiffness: 180, damping: 8, mass: 1 },\n stiff: { stiffness: 500, damping: 40, mass: 1 },\n },\n};\n\nexport type MotionTokenGroup = keyof MotionTokens;\nexport type DeepPartialTokens = { [K in keyof MotionTokens]?: Partial<MotionTokens[K]> };\n\nlet active: MotionTokens = clone(MOTION_TOKENS);\n\nfunction clone(t: MotionTokens): MotionTokens {\n return { duration: { ...t.duration }, easing: { ...t.easing }, spring: Object.fromEntries(Object.entries(t.spring).map(([k, v]) => [k, { ...v }])) };\n}\n\n/** Merge partial tokens over a base (defaults: the built-in scale). */\nexport function mergeMotionTokens(partial: DeepPartialTokens, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const out = clone(base);\n Object.assign(out.duration, partial.duration || {});\n Object.assign(out.easing, partial.easing || {});\n for (const [k, v] of Object.entries(partial.spring || {})) out.spring[k] = { ...(out.spring[k] || { stiffness: 170, damping: 26, mass: 1 }), ...v };\n return out;\n}\n\nconst kebab = (s: string) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[\\s_.]+/g, '-').toLowerCase();\n\n/** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */\nexport function motionTokensToVars(tokens: MotionTokens = active, prefix = '--usa'): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [k, v] of Object.entries(tokens.duration)) vars[`${prefix}-duration-${kebab(k)}`] = `${v}ms`;\n for (const [k, v] of Object.entries(tokens.easing)) vars[`${prefix}-easing-${kebab(k)}`] = v;\n for (const [k, v] of Object.entries(tokens.spring)) {\n vars[`${prefix}-spring-${kebab(k)}-stiffness`] = String(v.stiffness);\n vars[`${prefix}-spring-${kebab(k)}-damping`] = String(v.damping);\n vars[`${prefix}-spring-${kebab(k)}-mass`] = String(v.mass);\n }\n return vars;\n}\n\n/** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */\nexport function motionTokensToCss(tokens: MotionTokens = active, selector = ':root', prefix = '--usa'): string {\n const body = Object.entries(motionTokensToVars(tokens, prefix)).map(([k, v]) => ` ${k}: ${v};`).join('\\n');\n return `${selector} {\\n${body}\\n}\\n`;\n}\n\n/** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */\nexport function motionTokensToJSON(tokens: MotionTokens = active): Record<string, unknown> {\n const grp = <T>(o: Record<string, T>, f: (v: T) => unknown) => Object.fromEntries(Object.entries(o).map(([k, v]) => [k, f(v)]));\n return {\n motion: {\n duration: grp(tokens.duration, (v) => ({ $type: 'duration', $value: `${v}ms` })),\n easing: grp(tokens.easing, (v) => {\n const m = /^cubic-bezier\\(([^)]+)\\)$/.exec(v);\n return m ? { $type: 'cubicBezier', $value: m[1].split(',').map(Number) } : { $type: 'string', $value: v };\n }),\n spring: grp(tokens.spring, (v) => ({ $type: 'spring', $value: { ...v } })),\n },\n };\n}\n\n/** Parse `150ms`, `0.15s`, `150` → ms. */\nexport function parseDuration(v: unknown): number | undefined {\n if (typeof v === 'number' && isFinite(v)) return v;\n if (typeof v === 'object' && v && 'value' in (v as any) && 'unit' in (v as any)) return parseDuration(`${(v as any).value}${(v as any).unit}`);\n const m = /^\\s*(-?\\d*\\.?\\d+)\\s*(ms|s)?\\s*$/.exec(String(v ?? ''));\n if (!m) return undefined;\n return m[2] === 's' ? Number(m[1]) * 1000 : Number(m[1]);\n}\n\n/** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */\nexport function parseEasing(v: unknown): string | undefined {\n if (Array.isArray(v) && v.length === 4 && v.every((n) => typeof n === 'number')) return `cubic-bezier(${v.join(', ')})`;\n if (typeof v !== 'string' || !v.trim()) return undefined;\n const s = v.trim();\n if (/^-?\\d*\\.?\\d+(\\s*,\\s*-?\\d*\\.?\\d+){3}$/.test(s)) return `cubic-bezier(${s.split(/\\s*,\\s*/).join(', ')})`;\n return s;\n}\n\nconst isLeaf = (o: any) => o && typeof o === 'object' && ('$value' in o || 'value' in o);\nconst leafValue = (o: any) => ('$value' in o ? o.$value : o.value);\nconst leafType = (o: any) => String(o.$type ?? o.type ?? '').toLowerCase();\n\n/**\n * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio\n * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything\n * under a `duration` / `easing` / `spring` group (any depth, e.g.\n * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves\n * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are\n * skipped; the result is merged over the defaults.\n */\nexport function importMotionTokens(json: unknown, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const partial: Required<DeepPartialTokens> = { duration: {}, easing: {}, spring: {} };\n const walk = (node: any, path: string[]) => {\n if (!node || typeof node !== 'object') return;\n if (isLeaf(node)) {\n const name = path[path.length - 1];\n const type = leafType(node);\n const group = path.slice(0, -1).map((p) => p.toLowerCase());\n const val = leafValue(node);\n const inGroup = (g: string[]) => group.some((p) => g.includes(p));\n if (type === 'duration' || (!type && inGroup(['duration', 'durations'])) || (type !== 'cubicbezier' && inGroup(['duration', 'durations']))) {\n const ms = parseDuration(val);\n if (ms !== undefined) partial.duration[name] = ms;\n } else if (type === 'cubicbezier' || type === 'easing' || inGroup(['easing', 'easings', 'ease'])) {\n const e = parseEasing(val);\n if (e) partial.easing[name] = e;\n } else if (type === 'spring' || inGroup(['spring', 'springs'])) {\n if (val && typeof val === 'object') partial.spring[name] = { stiffness: Number(val.stiffness ?? 170), damping: Number(val.damping ?? 26), mass: Number(val.mass ?? 1) };\n } else if (type === 'transition' && val && typeof val === 'object') {\n const ms = parseDuration(val.duration);\n if (ms !== undefined) partial.duration[name] = ms;\n const e = parseEasing(val.timingFunction);\n if (e) partial.easing[name] = e;\n }\n return;\n }\n for (const [k, v] of Object.entries(node)) if (!k.startsWith('$')) walk(v, [...path, k]);\n };\n walk(json, []);\n return mergeMotionTokens(partial, base);\n}\n\n/** The tokens currently applied (via `applyMotionTokens`), or the defaults. */\nexport function getMotionTokens(): MotionTokens {\n return clone(active);\n}\n\n/**\n * Write tokens as CSS custom properties on `root` (default `<html>`) and make\n * them the active set for `motionToken()`. Returns an undo function.\n */\nexport function applyMotionTokens(tokens: DeepPartialTokens | MotionTokens = MOTION_TOKENS, root?: HTMLElement, prefix = '--usa'): () => void {\n const prev = active;\n active = mergeMotionTokens(tokens as DeepPartialTokens, MOTION_TOKENS);\n const el = root || (typeof document !== 'undefined' ? document.documentElement : null);\n const vars = motionTokensToVars(active, prefix);\n const old: Record<string, string> = {};\n if (el) for (const [k, v] of Object.entries(vars)) ((old[k] = el.style.getPropertyValue(k)), el.style.setProperty(k, v));\n return () => {\n active = prev;\n if (el) for (const [k, v] of Object.entries(old)) v ? el.style.setProperty(k, v) : el.style.removeProperty(k);\n };\n}\n\n/** Look up a token: `motionToken('duration', 'fast')` → `150`; `motionToken('easing', 'emphasized')` → CSS easing. */\nexport function motionToken(group: 'duration', name: string): number;\nexport function motionToken(group: 'easing', name: string): string;\nexport function motionToken(group: 'spring', name: string): SpringToken;\nexport function motionToken(group: MotionTokenGroup, name: string): number | string | SpringToken | undefined {\n const g = active[group] as Record<string, any>;\n return g[name] ?? (MOTION_TOKENS[group] as Record<string, any>)[name];\n}\n\n/** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */\nexport function motionVar(group: MotionTokenGroup, name: string, prop?: 'stiffness' | 'damping' | 'mass', prefix = '--usa'): string {\n if (group === 'spring') {\n const s = motionToken('spring', name);\n const p = prop || 'stiffness';\n return `var(${prefix}-spring-${kebab(name)}-${p}, ${s ? s[p] : ''})`;\n }\n const v = group === 'duration' ? `${motionToken('duration', name)}ms` : motionToken('easing', name);\n return `var(${prefix}-${group}-${kebab(name)}, ${v})`;\n}\n\n/** Resolve a duration that may be a token name (`'fast'`) or ms. */\nexport function resolveDurationToken(v: number | string | undefined, fallback: number): number {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') return (active.duration[v] ?? parseDuration(v)) ?? fallback;\n return fallback;\n}\n\n/** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */\nexport function resolveEasingToken(v: string | undefined, fallback: string): string {\n if (!v) return fallback;\n return active.easing[v] ?? v;\n}\n","import { prefersReducedMotion, motionScale, applyFrame, raf, caf, now, clamp } from '../base';\nimport { resolveDurationToken, resolveEasingToken } from '../tokens/index';\n\n/**\n * Where a step starts on a timeline:\n * - a number: absolute time in ms\n * - `'>'` (default): when the previous step ends · `'<'`: when it starts\n * - `'+=200'` / `'-=200'`: after / overlapping the previous end\n * - `'<+=100'`: 100ms after the previous step's start\n * - `'intro'` / `'intro+=150'`: at (or relative to) a label\n */\nexport type TimelinePosition = number | string;\n\nexport interface TimelineStepOptions {\n /** Duration in ms or a motion token name (`'fast'`, `'slow'`…; 4.2). Default: timeline default, 600. */\n duration?: number | string;\n /** CSS easing or a motion token name (`'emphasized'`, `'spring'`…; 4.2). Default `cubic-bezier(0.22, 1, 0.36, 1)`. */\n easing?: string;\n /** Start position, see `TimelinePosition`. */\n at?: TimelinePosition;\n /** ms between targets when the selector matches several elements. */\n stagger?: number;\n}\n\nexport interface TimelineOptions {\n /** Defaults for every step. */\n defaults?: Pick<TimelineStepOptions, 'duration' | 'easing' | 'stagger'>;\n /** Playback rate (1 = normal). */\n speed?: number;\n /** Called after `play()` reaches the end (or the start when reversed). */\n onComplete?: () => void;\n /** Called on every frame with progress 0–1. */\n onUpdate?: (progress: number) => void;\n}\n\nexport interface ScrubOptions {\n /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts (JS engine only). */\n offset?: number;\n /** Smoothing 0–1 (0 = immediate, default 0). Smoothing needs the JS engine. */\n smooth?: number;\n /**\n * 4.1: which progress source drives the timeline.\n * - `'view'` (default): `source` moving through the viewport (CSS `ViewTimeline`, range `cover`).\n * - `'scroll'`: the scroll position of `source` itself (a scroll container; CSS `ScrollTimeline`).\n */\n source?: 'view' | 'scroll';\n /** 4.1: `'auto'` (default) uses the browser's native scroll-driven animations when available, `'js'` forces the fallback. */\n engine?: 'auto' | 'native' | 'js';\n /** 4.1: scroll axis, `'block'` (default) · `'inline'` · `'x'` · `'y'`. */\n axis?: 'block' | 'inline' | 'x' | 'y';\n}\n\n/** The function `scrub()` returns: call it to stop. `native` tells which engine runs it. */\nexport interface ScrubHandle {\n (): void;\n /** `true` when the browser's ScrollTimeline / ViewTimeline drives it (compositor, no JS per frame). */\n readonly native: boolean;\n}\n\n/** 4.1: whether `scrub()` can use native ScrollTimeline / ViewTimeline here. */\nexport function supportsNativeScrub(source: 'view' | 'scroll' = 'view'): boolean {\n const g = globalThis as any;\n return typeof g[source === 'scroll' ? 'ScrollTimeline' : 'ViewTimeline'] === 'function' && typeof g.Element?.prototype?.animate === 'function';\n}\n\nconst handle = (stop: () => void, native: boolean): ScrubHandle => Object.assign(stop, { native }) as ScrubHandle;\n\nexport interface Timeline {\n /** Total length in ms. */\n readonly duration: number;\n /** Label positions in ms. */\n readonly labels: Readonly<Record<string, number>>;\n /** Current playhead in ms. */\n readonly time: number;\n /** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */\n to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;\n /** Name a position (default: the current end). */\n label(name: string, at?: TimelinePosition): Timeline;\n /** Run `fn` when the playhead passes `at`. */\n call(fn: () => void, at?: TimelinePosition): Timeline;\n /** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */\n play(from?: TimelinePosition): Promise<void>;\n /** Play backwards to 0. */\n reverse(): Promise<void>;\n pause(): Timeline;\n /** Jump to a time (ms) or label. */\n seek(to: TimelinePosition): Timeline;\n /** Get or set progress 0–1. */\n progress(p?: number): number;\n /**\n * Tie progress to scroll: `source` moving through the viewport (or, with\n * `{ source: 'scroll' }`, a scroll container's own position). Runs on native\n * ScrollTimeline / ViewTimeline when available (and no `smooth`, `offset`,\n * `call()` cues or `onUpdate` need JS), else on a rAF-throttled listener.\n * Returns a stop function with a `native` flag.\n */\n scrub(source: Element, options?: ScrubOptions): ScrubHandle;\n /** Stop and drop every animation (elements keep their last frame). */\n cancel(): void;\n}\n\n/** Keyframe presets usable by name in `to()` and `data-tl`. */\nexport const TIMELINE_PRESETS: Record<string, Keyframe[]> = {\n fade: [{ opacity: 0 }, { opacity: 1 }],\n 'fade-up': [{ opacity: 0, transform: 'translateY(24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-down': [{ opacity: 0, transform: 'translateY(-24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-left': [{ opacity: 0, transform: 'translateX(24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-right': [{ opacity: 0, transform: 'translateX(-24px)' }, { opacity: 1, transform: 'none' }],\n scale: [{ opacity: 0, transform: 'scale(0.85)' }, { opacity: 1, transform: 'none' }],\n blur: [{ opacity: 0, filter: 'blur(12px)' }, { opacity: 1, filter: 'blur(0)' }],\n rotate: [{ opacity: 0, transform: 'rotate(-12deg) scale(0.9)' }, { opacity: 1, transform: 'none' }],\n 'clip-up': [{ clipPath: 'inset(100% 0 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],\n 'clip-right': [{ clipPath: 'inset(0 100% 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],\n};\n\n/** Resolve a position against the previous step and labels (pure). */\nexport function resolvePosition(\n pos: TimelinePosition | undefined,\n end: number,\n prevStart: number,\n labels: Record<string, number> = {}\n): number {\n if (pos === undefined || pos === '' || pos === '>') return end;\n if (typeof pos === 'number') return Math.max(0, pos);\n const s = String(pos).trim();\n if (/^-?\\d+(\\.\\d+)?$/.test(s)) return Math.max(0, Number(s));\n const m = /^(<|>|[A-Za-z_][\\w-]*)?\\s*(?:([+-])=\\s*(\\d+(?:\\.\\d+)?))?$/.exec(s);\n if (!m) return end;\n const base = m[1] === '<' ? prevStart : m[1] === '>' || !m[1] ? end : labels[m[1]] ?? end;\n const delta = m[2] ? (m[2] === '-' ? -1 : 1) * Number(m[3]) : 0;\n return Math.max(0, base + delta);\n}\n\nconst toEls = (t: string | Element | Element[] | NodeList): Element[] =>\n typeof t === 'string' ? (typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(t))) : t instanceof Element ? [t] : Array.from(t as ArrayLike<Element>);\n\ninterface Step { el: Element; frames: Keyframe[]; start: number; duration: number; easing: string; anim?: Animation | null }\ninterface Cue { fn: () => void; at: number }\n\n/**\n * Choreograph animations on one clock: chain, overlap, label, seek, reverse and\n * scrub them with scroll. Built on WAAPI (paused animations driven by one\n * playhead); without WAAPI or under reduced motion it jumps to the end state.\n *\n * @example\n * const tl = timeline({ defaults: { duration: 500 } })\n * .to('.title', 'fade-up')\n * .label('cards')\n * .to('.card', 'scale', { stagger: 80, at: '-=200' })\n * .to('.cta', [{ opacity: 0 }, { opacity: 1 }], { at: 'cards+=400' });\n * tl.play(); // or tl.scrub(document.querySelector('.hero'))\n */\nexport function timeline(options: TimelineOptions = {}): Timeline {\n const d = { duration: 600, easing: 'cubic-bezier(0.22, 1, 0.36, 1)', stagger: 0, ...options.defaults };\n const steps: Step[] = [];\n const cues: Cue[] = [];\n const labels: Record<string, number> = {};\n let end = 0;\n let prevStart = 0;\n let t = 0;\n let frame = 0;\n let dir = 1;\n let settle: (() => void) | undefined;\n let built = false;\n\n const total = () => Math.max(end, ...cues.map((c) => c.at), 0);\n const build = () => {\n if (built) return;\n built = true;\n for (const s of steps) {\n if (typeof (s.el as HTMLElement).animate !== 'function') { s.anim = null; continue; }\n s.anim = (s.el as HTMLElement).animate(s.frames, { duration: s.duration, delay: s.start, easing: s.easing, fill: 'both' });\n s.anim.pause?.();\n }\n };\n const render = (to: number, from: number) => {\n build();\n t = clamp(to, 0, total());\n for (const s of steps) {\n if (s.anim) s.anim.currentTime = t;\n else applyFrame(s.el as HTMLElement, s.frames[t >= s.start ? s.frames.length - 1 : 0]);\n }\n for (const c of cues) if ((from < c.at && t >= c.at) || (from > c.at && t <= c.at)) c.fn();\n options.onUpdate?.(total() ? t / total() : 1);\n };\n const stop = () => {\n if (frame) caf(frame);\n frame = 0;\n };\n const run = (direction: number): Promise<void> => {\n stop();\n settle?.();\n dir = direction;\n const target = dir > 0 ? total() : 0;\n const k = motionScale();\n if (prefersReducedMotion() || k === 0 || !total()) {\n render(target, t);\n options.onComplete?.();\n return Promise.resolve();\n }\n const rate = (options.speed ?? 1) / k;\n return new Promise<void>((resolve) => {\n settle = () => { settle = undefined; resolve(); };\n let last = now();\n const loop = () => {\n const n = now();\n const next = t + (n - last) * rate * dir;\n last = n;\n render(next, t);\n if ((dir > 0 && t >= target) || (dir < 0 && t <= 0)) {\n frame = 0;\n options.onComplete?.();\n settle?.();\n return;\n }\n frame = raf(loop);\n };\n frame = raf(loop);\n });\n };\n\n const api: Timeline = {\n get duration() { return total(); },\n get labels() { return { ...labels }; },\n get time() { return t; },\n to(target, frames, o = {}) {\n const kf = typeof frames === 'string' ? TIMELINE_PRESETS[frames] || TIMELINE_PRESETS.fade : frames;\n const start = resolvePosition(o.at, end, prevStart, labels);\n const duration = resolveDurationToken(o.duration ?? d.duration, 600);\n const stagger = o.stagger ?? d.stagger;\n let last = start;\n toEls(target).forEach((el, i) => {\n const s = start + i * stagger;\n steps.push({ el, frames: kf, start: s, duration, easing: resolveEasingToken(o.easing ?? d.easing, 'cubic-bezier(0.22, 1, 0.36, 1)') });\n last = Math.max(last, s + duration);\n });\n prevStart = start;\n end = Math.max(end, last);\n built = false;\n steps.forEach((s) => s.anim?.cancel?.());\n return api;\n },\n label(name, at) {\n labels[name] = resolvePosition(at, end, prevStart, labels);\n return api;\n },\n call(fn, at) {\n cues.push({ fn, at: resolvePosition(at, end, prevStart, labels) });\n return api;\n },\n play(from) {\n if (from !== undefined) render(resolvePosition(from, 0, 0, labels), t);\n else if (t >= total()) render(0, -1);\n return run(1);\n },\n reverse() {\n return run(-1);\n },\n pause() {\n stop();\n return api;\n },\n seek(to) {\n stop();\n render(resolvePosition(to, 0, 0, labels), t);\n return api;\n },\n progress(p) {\n if (p !== undefined) api.seek(clamp(p, 0, 1) * total());\n return total() ? t / total() : 0;\n },\n scrub(source, o = {}) {\n stop();\n if (prefersReducedMotion() || typeof window === 'undefined') {\n render(total(), t);\n return handle(() => {}, false);\n }\n const mode = o.source ?? 'view';\n const axis = o.axis ?? 'block';\n const needsJs = !!o.smooth || !!o.offset || cues.length > 0 || !!options.onUpdate || o.engine === 'js';\n if (!needsJs && total() > 0 && supportsNativeScrub(mode) && steps.every((st) => typeof (st.el as HTMLElement).animate === 'function')) {\n // Native: one scroll-driven animation per step, its slice of the\n // timeline mapped onto the scroll range (`cover` for a view timeline).\n const g = globalThis as any;\n const tl = mode === 'scroll' ? new g.ScrollTimeline({ source, axis }) : new g.ViewTimeline({ subject: source, axis });\n const T = total();\n steps.forEach((st) => st.anim?.cancel?.());\n built = false;\n const pct = (ms: number) => `${((ms / T) * 100).toFixed(3)}%`;\n const live = steps.map((st) => {\n const range = mode === 'view' ? { rangeStart: `cover ${pct(st.start)}`, rangeEnd: `cover ${pct(st.start + st.duration)}` } : {};\n const timing: any = { easing: st.easing, fill: 'both', timeline: tl, ...range };\n if (mode === 'scroll') Object.assign(timing, { duration: 'auto', rangeStart: pct(st.start), rangeEnd: pct(st.start + st.duration) });\n return (st.el as HTMLElement).animate(st.frames, timing);\n });\n return handle(() => {\n live.forEach((a) => a.cancel());\n render(t, t);\n }, true);\n }\n let id = 0;\n let cur = t;\n const scroller = mode === 'scroll' ? (source as HTMLElement) : null;\n const progressNow = () => {\n const x = axis === 'x' || axis === 'inline';\n if (scroller) {\n const max = x ? scroller.scrollWidth - scroller.clientWidth : scroller.scrollHeight - scroller.clientHeight;\n return clamp((x ? scroller.scrollLeft : scroller.scrollTop) / (max || 1), 0, 1);\n }\n const r = source.getBoundingClientRect();\n const vh = (x ? window.innerWidth : window.innerHeight) || 1;\n const start = x ? r.left : r.top;\n const size = x ? r.width : r.height;\n return clamp((vh + (o.offset ?? 0) - start) / (vh + size || 1), 0, 1);\n };\n const update = () => {\n id = 0;\n const goal = progressNow() * total();\n const sm = clamp(o.smooth ?? 0, 0, 0.95);\n cur = sm ? cur + (goal - cur) * (1 - sm) : goal;\n render(cur, t);\n if (sm && Math.abs(goal - cur) > 0.5) id = raf(update);\n };\n const onScroll = () => { if (!id) id = raf(update); };\n const target: EventTarget = scroller || window;\n target.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onScroll, { passive: true });\n update();\n return handle(() => {\n target.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onScroll);\n if (id) caf(id);\n }, false);\n },\n cancel() {\n stop();\n settle?.();\n steps.forEach((s) => s.anim?.cancel?.());\n built = false;\n },\n };\n return api;\n}\n","/**\n * motionary - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * motionary\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `motionary/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/Motionary\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { timeline, resolvePosition, TIMELINE_PRESETS, supportsNativeScrub } from './components/timeline/core';\nexport { parallax } from './parallax';\nexport { PRESETS, registerPresets, reversePreset, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n CorePreset,\n ExtendedPreset,\n PresetKeyframes,\n AnimationFrame,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions, ScrubHandle } from './components/timeline/core';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'motionary';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":["PRESETS","core","g","globalThis","key","Symbol","for","Object","assign","share","from","opacity","to","transform","bounce","filter","shimmer","pulse","swing","clipPath","reversePreset","p","frames","map","f","offset","reverse","lookup","name","trim","resolvePreset","animation","Array","isArray","combined","forEach","preset","entries","val","EASING_MAP","linear","ease","spring","resolveEasing","easing","join","DEFAULT_CONFIG","defaultAnimation","defaultDuration","defaultDelay","defaultEasing","defaultThreshold","defaultRootMargin","defaultRepeat","defaultOnce","defaultOffset","hiddenClass","visibleClass","useClassNames","disabled","root","autoUnregister","defaultEngine","noop","hasDOM","window","document","supportsObserver","IntersectionObserver","reducedMotionQuery","scrollTimelineSupported","prefersReducedMotion","undefined","matchMedia","matches","supportsScrollTimeline","CSS","supports","ViewTimeline","num","value","n","parseFloat","Number","isFinite","DEFAULT_VIEW_RANGE","normalizeVar","v","startsWith","parseDataAttributes","el","config","mergeOptions","get","opts","anim","includes","split","s","duration","delay","e","JSON","parse","t","threshold","rootMargin","repeat","once","stagger","progressVar","engine","range","start","end","viewRange","exit","progress","progressMode","keys","k","readOptions","getAttribute","length","onStart","onComplete","onEnter","onLeave","onProgress","resolveTargets","target","querySelectorAll","Element","NodeList","getScrollProgress","rect","getBoundingClientRect","top","height","innerHeight","documentElement","clientHeight","r","total","running","WeakMap","exits","timers","cancelRunning","exitAnim","delete","cancel","onfinish","timer","clearTimeout","setStyles","styles","style","prop","String","NUM_UNIT","linearSupported","progressThresholds","supportsLinearEasing","buildAnimation","list","keyframes","samples","fn","values","i","push","toFixed","sampleEasing","props","eased","frame","a","b","ta","tb","skA","replace","_","u","ok","out","na","ua","nb","ub","unit","interpolateValue","reveal","classList","remove","add","motionDisabled","runAnimation","staggerIndex","pending","totalDelay","Math","max","animationDelay","set","setTimeout","animate","built","timing","fill","commitStyles","hideElement","prepareElement","full","getProgressThresholds","PASSIVE","passive","createScrollAnimate","userConfig","registry","Map","finished","WeakSet","scrolling","Set","listening","watchers","natives","pools","pooled","create","pool","io","teardown","restore","record","observer","unobserve","progressObserver","untrack","animated","isConnected","pruneDetached","emitProgress","options","setProperty","update","schedule","requestAnimationFrame","listen","on","method","cancelAnimationFrame","size","onScrollIntersect","entry","isIntersecting","onIntersect","staggerCounts","parent","parentElement","runExit","intersectionRatio","getObserver","parts","right","bottom","left","m","exec","applyOffset","attach","observeMain","observe","getProgressObserver","observeElement","has","element","wantsNative","onFrozen","timeline","subject","axis","rangeStart","rangeEnd","keep","startNative","observeDataElement","instance","init","rootElement","scope","watch","MutationObserver","observeTree","node","hasAttribute","mo","records","removed","type","addedNodes","removedNodes","childList","subtree","attributes","attributeFilter","disconnect","destroy","clear","refresh","getObservedElements","configure","newConfig","fallback","MOTION_SCALE","low","normal","high","applyFrame","frameQueue","frameSeq","frameHandle","frameVia","frameStats","callbacks","peak","last","frameListeners","flushFrame","dt","cbs","error","cb","requestFlush","native","now","raf","id","performance","Date","caf","clamp","min","active","instant","fast","slow","slower","slowest","standard","emphasized","decelerate","accelerate","gentle","stiffness","damping","mass","snappy","bouncy","wobbly","stiff","fromEntries","parseDuration","resolveDurationToken","resolveEasingToken","supportsNativeScrub","source","prototype","handle","stop","TIMELINE_PRESETS","fade","scale","blur","rotate","resolvePosition","pos","prevStart","labels","test","base","delta","ScrollAnimate","els","speed","respectReducedMotion","visible","scroller","apply","removeProperty","presets","container","sa","observeChildren","rest","items","children","revealed","late","child","some","parentNode","indexOf","splice","stopAnimation","d","defaults","steps","cues","settle","dir","c","at","render","pause","build","currentTime","onUpdate","run","direction","Promise","resolve","rate","loop","next","api","time","o","kf","toEls","label","call","play","seek","scrub","mode","smooth","every","st","tl","ScrollTimeline","T","pct","ms","live","cur","goal","x","scrollWidth","clientWidth","scrollHeight","scrollLeft","scrollTop","vh","innerWidth","width","progressNow","sm","abs","onScroll","addEventListener","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/presets.ts","../src/core.ts","../src/stagger.ts","../src/components/base.ts","../src/components/tokens/index.ts","../src/components/timeline/core.ts","../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * motionary - Animation Presets\n * Defines keyframes for all built-in animation presets\n */\n\nimport type { AnimationPreset, CorePreset, CustomAnimation, EasingType, ExtendedPreset, PresetKeyframes } from './types';\n\ntype KeyframeMap = PresetKeyframes;\n\nconst CORE: Record<CorePreset, KeyframeMap> = {\n 'fade-in': {\n from: { opacity: 0 },\n to: { opacity: 1 },\n },\n 'fade-in-up': {\n from: { opacity: 0, transform: 'translateY(40px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'fade-in-down': {\n from: { opacity: 0, transform: 'translateY(-40px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'fade-in-left': {\n from: { opacity: 0, transform: 'translateX(-40px)' },\n to: { opacity: 1, transform: 'translateX(0px)' },\n },\n 'fade-in-right': {\n from: { opacity: 0, transform: 'translateX(40px)' },\n to: { opacity: 1, transform: 'translateX(0px)' },\n },\n 'zoom-in': {\n from: { opacity: 0, transform: 'scale(0.8)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'zoom-out': {\n from: { opacity: 0, transform: 'scale(1.2)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'flip-x': {\n from: { opacity: 0, transform: 'rotateX(-90deg)' },\n to: { opacity: 1, transform: 'rotateX(0deg)' },\n },\n 'flip-y': {\n from: { opacity: 0, transform: 'rotateY(-90deg)' },\n to: { opacity: 1, transform: 'rotateY(0deg)' },\n },\n 'slide-up': {\n from: { transform: 'translateY(100%)' },\n to: { transform: 'translateY(0px)' },\n },\n 'slide-down': {\n from: { transform: 'translateY(-100%)' },\n to: { transform: 'translateY(0px)' },\n },\n 'slide-left': {\n from: { transform: 'translateX(-100%)' },\n to: { transform: 'translateX(0px)' },\n },\n 'slide-right': {\n from: { transform: 'translateX(100%)' },\n to: { transform: 'translateX(0px)' },\n },\n 'bounce': {\n from: { opacity: 0, transform: 'translateY(-60px)' },\n to: { opacity: 1, transform: 'translateY(0px)' },\n },\n 'rotate-in': {\n from: { opacity: 0, transform: 'rotate(-180deg) scale(0.5)' },\n to: { opacity: 1, transform: 'rotate(0deg) scale(1)' },\n },\n 'blur-in': {\n from: { opacity: 0, filter: 'blur(12px)' },\n to: { opacity: 1, filter: 'blur(0px)' },\n },\n 'skew-in': {\n from: { opacity: 0, transform: 'skewX(20deg) translateX(30px)' },\n to: { opacity: 1, transform: 'skewX(0deg) translateX(0px)' },\n },\n 'scale-x': {\n from: { transform: 'scaleX(0)' },\n to: { transform: 'scaleX(1)' },\n },\n 'scale-y': {\n from: { transform: 'scaleY(0)' },\n to: { transform: 'scaleY(1)' },\n },\n 'shimmer': {\n from: { opacity: 0.5, filter: 'brightness(1)' },\n to: { opacity: 1, filter: 'brightness(1.5)' },\n },\n 'pulse': {\n from: { transform: 'scale(1)' },\n to: { transform: 'scale(1.05)' },\n },\n 'swing': {\n from: { transform: 'rotate(-10deg)' },\n to: { transform: 'rotate(10deg)' },\n },\n 'scale-up': {\n from: { opacity: 0, transform: 'scale(0.5)' },\n to: { opacity: 1, transform: 'scale(1)' },\n },\n 'blur-in-up': {\n from: { opacity: 0, filter: 'blur(12px)', transform: 'translateY(40px)' },\n to: { opacity: 1, filter: 'blur(0px)', transform: 'translateY(0px)' },\n },\n 'flip-up': {\n from: { opacity: 0, transform: 'perspective(800px) rotateX(60deg)' },\n to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },\n },\n 'flip-down': {\n from: { opacity: 0, transform: 'perspective(800px) rotateX(-60deg)' },\n to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },\n },\n 'rotate-left': {\n from: { opacity: 0, transform: 'rotate(-15deg) translateX(-40px)' },\n to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },\n },\n 'rotate-right': {\n from: { opacity: 0, transform: 'rotate(15deg) translateX(40px)' },\n to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },\n },\n // clip-path reveals: content is uncovered without moving or fading\n 'clip-up': {\n from: { clipPath: 'inset(100% 0% 0% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-down': {\n from: { clipPath: 'inset(0% 0% 100% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-left': {\n from: { clipPath: 'inset(0% 0% 0% 100%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-right': {\n from: { clipPath: 'inset(0% 100% 0% 0%)' },\n to: { clipPath: 'inset(0% 0% 0% 0%)' },\n },\n 'clip-circle': {\n from: { clipPath: 'circle(0% at 50% 50%)' },\n to: { clipPath: 'circle(75% at 50% 50%)' },\n },\n};\n\n/**\n * One preset table per page, shared through a global symbol so every copy of\n * the library (ESM entries, the UMD bundle, `presets/extended`) sees presets\n * registered by any other copy. `<usa-reveal>` / `<usa-stagger>` read it too.\n */\nconst share = (core: Record<string, KeyframeMap>): Record<string, KeyframeMap> => {\n const g = globalThis as any;\n const key = Symbol.for('use-scroll-animate.presets');\n return (g[key] = Object.assign(g[key] || {}, core));\n};\n\n/**\n * Every registered preset: the 33 core presets, plus the 6.1 extended set once\n * `motionary/presets/extended` is loaded, plus your own.\n */\nexport const PRESETS = /*#__PURE__*/ share(CORE) as Record<CorePreset, KeyframeMap> & Partial<Record<ExtendedPreset, KeyframeMap>>;\n\n/**\n * Add (or replace) presets by name: `registerPresets({ 'my-pop': { from, to, frames? } })`.\n * They work everywhere a preset name does (`animation`, `exit`, `data-sa-animation`,\n * `<scroll-animate>`, `<usa-reveal effect>`).\n */\nexport function registerPresets(presets: Record<string, PresetKeyframes>): void {\n Object.assign(PRESETS, presets);\n}\n\n/** The same keyframes played backwards (exit animations). */\nexport function reversePreset(p: KeyframeMap): KeyframeMap {\n return { from: p.to, to: p.from, frames: p.frames && p.frames.map((f) => ({ ...f, offset: 1 - f.offset })).reverse() };\n}\n\nconst lookup = (name: string): KeyframeMap | undefined => (PRESETS as Record<string, KeyframeMap>)[name.trim()];\n\nexport function resolvePreset(animation: AnimationPreset | AnimationPreset[] | CustomAnimation): KeyframeMap {\n if (typeof animation === 'string') {\n return lookup(animation) ?? PRESETS['fade-in-up'];\n }\n \n if (Array.isArray(animation)) {\n const combined: KeyframeMap = { from: {}, to: {} };\n animation.forEach(name => {\n const preset = lookup(name);\n if (preset) {\n Object.entries(preset.from).forEach(([key, val]) => {\n if (key === 'transform' && combined.from[key]) {\n combined.from[key] = `${combined.from[key]} ${val}`;\n } else {\n combined.from[key] = val;\n }\n });\n Object.entries(preset.to).forEach(([key, val]) => {\n if (key === 'transform' && combined.to[key]) {\n combined.to[key] = `${combined.to[key]} ${val}`;\n } else {\n combined.to[key] = val;\n }\n });\n }\n });\n return combined;\n }\n \n return animation;\n}\n\n/** Easing to CSS cubic-bezier mapping */\nexport const EASING_MAP: Record<string, string> = {\n linear: 'linear',\n ease: 'ease',\n 'ease-in': 'ease-in',\n 'ease-out': 'ease-out',\n 'ease-in-out': 'ease-in-out',\n spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n 'soft-spring': 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n 'heavy-bounce': 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n};\n\nexport function resolveEasing(easing: EasingType): string {\n if (typeof easing === 'string') {\n return EASING_MAP[easing] ?? easing;\n }\n if (Array.isArray(easing)) {\n return `cubic-bezier(${easing.join(', ')})`;\n }\n if (typeof easing === 'function') {\n // Functions cannot be expressed as a CSS easing string; the core samples\n // them into a `linear()` easing (or keyframes on older browsers).\n return 'linear';\n }\n return 'ease';\n}\n","/**\n * motionary - Core Implementation\n * Uses IntersectionObserver + Web Animations API for zero-dependency,\n * high-performance scroll-triggered animations.\n */\n\nimport type {\n AnimateOptions,\n AnimatedElement,\n ScrollAnimateConfig,\n ScrollAnimateInstance,\n} from './types';\nimport { resolvePreset, resolveEasing, reversePreset } from './presets';\n\ntype KeyframeMap = ReturnType<typeof resolvePreset>;\ntype Target = string | Element | NodeList | Element[];\ntype Root = Element | Document | null;\n\nconst DEFAULT_CONFIG: Required<ScrollAnimateConfig> = {\n defaultAnimation: 'fade-in-up',\n defaultDuration: 600,\n defaultDelay: 0,\n defaultEasing: 'ease',\n defaultThreshold: 0.1,\n defaultRootMargin: '0px',\n defaultRepeat: false,\n defaultOnce: true,\n defaultOffset: 0,\n hiddenClass: 'sa-hidden',\n visibleClass: 'sa-visible',\n useClassNames: false,\n disabled: false,\n root: null,\n autoUnregister: true,\n defaultEngine: 'auto',\n};\n\nconst noop = () => undefined;\n\n/* ------------------------------------------------------------------ */\n/* Environment helpers (all SSR-safe: never touch globals at import) */\n/* ------------------------------------------------------------------ */\n\nconst hasDOM = (): boolean => typeof window !== 'undefined' && typeof document !== 'undefined';\n\n/** @internal */\nexport const supportsObserver = (): boolean => hasDOM() && typeof IntersectionObserver !== 'undefined';\n\nlet reducedMotionQuery: MediaQueryList | null | undefined;\n\n/** @internal Whether the user asked the OS/browser to reduce motion. */\nexport function prefersReducedMotion(): boolean {\n if (!hasDOM()) return false;\n if (reducedMotionQuery === undefined) {\n reducedMotionQuery =\n typeof window.matchMedia === 'function' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;\n }\n return !!reducedMotionQuery && reducedMotionQuery.matches;\n}\n\nlet scrollTimelineSupported: boolean | undefined;\n\n/**\n * Whether the browser can run presets on a native scroll-driven timeline:\n * `CSS.supports('animation-timeline: view()')` plus the `ViewTimeline`\n * constructor used to attach it from JavaScript. Cached. SSR-safe.\n */\nexport function supportsScrollTimeline(): boolean {\n if (scrollTimelineSupported === undefined) {\n scrollTimelineSupported =\n hasDOM() &&\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('animation-timeline: view()') &&\n typeof (globalThis as any).ViewTimeline === 'function';\n }\n return scrollTimelineSupported;\n}\n\n/** @internal Reset the cached feature checks (tests). */\nexport function resetFeatureCache(): void {\n scrollTimelineSupported = undefined;\n linearSupported = undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* Option parsing */\n/* ------------------------------------------------------------------ */\n\nfunction num(value: string | undefined): number | undefined {\n if (value === undefined || value.trim() === '') return undefined;\n const n = parseFloat(value);\n return Number.isFinite(n) ? n : undefined;\n}\n\n\nconst DEFAULT_PROGRESS_VAR = '--sa-progress';\nconst DEFAULT_VIEW_RANGE: [string, string] = ['entry 0%', 'entry 100%'];\n\n/** `''` (bare attribute) -> default name; `sa-progress` -> `--sa-progress`. */\nfunction normalizeVar(name: string): string {\n const v = name.trim();\n if (!v) return DEFAULT_PROGRESS_VAR;\n return v.startsWith('--') ? v : `--${v}`;\n}\n\n/**\n * @internal Read options from string attributes. `get(name)` returns the raw\n * value of the attribute `name` (kebab-case, e.g. `root-margin`), `''` for a\n * bare attribute and `undefined` when absent. Shared by `data-sa-*` and the\n * `<scroll-animate>` element.\n */\nexport function readOptions(get: (name: string) => string | undefined): AnimateOptions {\n const opts: AnimateOptions = {};\n\n const anim = get('animation');\n if (anim) {\n opts.animation = (anim.includes(',') ? anim.split(',').map((s) => s.trim()) : anim.trim()) as any;\n }\n opts.duration = num(get('duration'));\n opts.delay = num(get('delay'));\n const easing = get('easing');\n if (easing) {\n const e = easing.trim();\n if (e.startsWith('[')) {\n try {\n opts.easing = JSON.parse(e);\n } catch {\n // Malformed JSON: fall back to the default easing instead of throwing\n }\n } else {\n opts.easing = e;\n }\n }\n const t = get('threshold');\n if (t) {\n opts.threshold = t.includes(',') ? t.split(',').map(parseFloat).filter(Number.isFinite) : num(t);\n }\n const rootMargin = get('root-margin');\n if (rootMargin) opts.rootMargin = rootMargin;\n const repeat = get('repeat');\n if (repeat !== undefined) opts.repeat = repeat !== 'false';\n const once = get('once');\n if (once !== undefined) opts.once = once !== 'false';\n opts.offset = num(get('offset'));\n opts.stagger = num(get('stagger'));\n const progressVar = get('progress-var');\n if (progressVar !== undefined) opts.progressVar = normalizeVar(progressVar);\n const engine = get('engine')?.trim();\n if (engine === 'auto' || engine === 'js' || engine === 'css') opts.engine = engine;\n const range = get('view-range');\n if (range) {\n const [start, end] = range.split(',').map((s) => s.trim());\n if (start && end) opts.viewRange = [start, end];\n }\n const exit = get('exit');\n if (exit !== undefined) {\n const e = exit.trim();\n opts.exit = e === '' || e === 'true' ? true : e === 'false' ? false : ((e.includes(',') ? e.split(',').map((s) => s.trim()) : e) as any);\n }\n const progress = get('progress');\n if (progress) opts.progressMode = progress.trim() === 'scroll' ? 'scroll' : 'ratio';\n\n // Drop keys that were not set, so they don't override defaults when spread.\n (Object.keys(opts) as Array<keyof AnimateOptions>).forEach((k) => opts[k] === undefined && delete opts[k]);\n return opts;\n}\n\nfunction parseDataAttributes(el: Element, config: Required<ScrollAnimateConfig>): Required<AnimateOptions> {\n return mergeOptions(\n readOptions((name) => {\n const v = el.getAttribute(`data-sa-${name}`);\n return v === null ? undefined : v;\n }),\n config\n );\n}\n\nfunction mergeOptions(opts: AnimateOptions, config: Required<ScrollAnimateConfig>): Required<AnimateOptions> {\n let engine = opts.engine ?? config.defaultEngine;\n // 'auto' keeps time-based semantics when the element asks for them explicitly.\n if (engine === 'auto' && (opts.duration !== undefined || opts.delay !== undefined || opts.offset !== undefined || (opts.stagger ?? 0) > 0)) {\n engine = 'js';\n }\n const exit = opts.exit ?? false;\n const repeat = opts.repeat ?? (exit ? true : config.defaultRepeat);\n const threshold = opts.threshold ?? config.defaultThreshold;\n return {\n animation: opts.animation ?? config.defaultAnimation,\n duration: opts.duration ?? config.defaultDuration,\n delay: opts.delay ?? config.defaultDelay,\n easing: opts.easing ?? config.defaultEasing,\n threshold: Array.isArray(threshold) && threshold.length === 0 ? config.defaultThreshold : threshold,\n rootMargin: opts.rootMargin ?? config.defaultRootMargin,\n repeat,\n once: opts.once ?? (repeat ? false : config.defaultOnce),\n offset: opts.offset ?? config.defaultOffset,\n stagger: opts.stagger ?? 0,\n onStart: opts.onStart ?? noop,\n onComplete: opts.onComplete ?? noop,\n onEnter: opts.onEnter ?? noop,\n onLeave: opts.onLeave ?? noop,\n onProgress: opts.onProgress ?? noop,\n progressMode: opts.progressMode ?? 'ratio',\n progressVar: opts.progressVar ? normalizeVar(opts.progressVar) : '',\n engine,\n viewRange: opts.viewRange ?? DEFAULT_VIEW_RANGE,\n exit,\n };\n}\n\nfunction resolveTargets(target: Target | null | undefined): Element[] {\n if (!target || !hasDOM()) return [];\n if (typeof target === 'string') return Array.from(document.querySelectorAll(target));\n if (target instanceof Element) return [target];\n if (Array.isArray(target) || target instanceof NodeList) {\n return (Array.from(target as ArrayLike<Node>) as Element[]).filter((el) => el instanceof Element);\n }\n return [];\n}\n\n/**\n * Apply `offset` to the bottom edge of a rootMargin, preserving the other\n * three sides. `offset: 100` means \"trigger 100px later\" (bottom -100px).\n * @internal\n */\nexport function applyOffset(rootMargin: string, offset: number): string {\n if (!offset) return rootMargin;\n const parts = (rootMargin || '0px').trim().split(/\\s+/);\n const top = parts[0];\n const right = parts[1] ?? top;\n const bottom = parts[2] ?? top;\n const left = parts[3] ?? right;\n const m = /^(-?\\d*\\.?\\d+)(px)?$/.exec(bottom);\n const base = m ? parseFloat(m[1]) : 0; // non-px bottoms (e.g. %) cannot be combined; offset wins\n return `${top} ${right} ${base - offset}px ${left}`;\n}\n\nfunction needsProgress(opts: Required<AnimateOptions>): boolean {\n return opts.onProgress !== noop || !!opts.progressVar;\n}\n\n/**\n * True scroll progress of `el` through the viewport (or `root`): 0 when its top\n * edge reaches the bottom of the viewport, 1 when its bottom edge passes the top.\n * Works for elements taller than the viewport. Returns 0 without a DOM.\n */\nexport function getScrollProgress(el: Element, root?: Element | null): number {\n if (!hasDOM()) return 0;\n const rect = el.getBoundingClientRect();\n let top = 0;\n let height = window.innerHeight || document.documentElement.clientHeight || 0;\n if (root) {\n const r = root.getBoundingClientRect();\n top = r.top;\n height = r.height;\n }\n const total = height + rect.height;\n if (total <= 0) return 0;\n const p = (top + height - rect.top) / total;\n return p < 0 ? 0 : p > 1 ? 1 : p;\n}\n\n/* ------------------------------------------------------------------ */\n/* Animation */\n/* ------------------------------------------------------------------ */\n\n/** The animation currently running on an element, so it can be cancelled/replaced. */\nconst running = new WeakMap<Element, Animation>();\n/** Native engine: the scroll-linked exit animation, next to the entrance in `running`. */\nconst exits = new WeakMap<Element, Animation>();\nconst timers = new WeakMap<Element, ReturnType<typeof setTimeout>>();\n\nfunction cancelRunning(el: Element): void {\n const exitAnim = exits.get(el);\n if (exitAnim) {\n exits.delete(el);\n exitAnim.cancel();\n }\n const anim = running.get(el);\n if (anim) {\n running.delete(el);\n anim.onfinish = null;\n anim.cancel();\n }\n const timer = timers.get(el);\n if (timer !== undefined) {\n clearTimeout(timer);\n timers.delete(el);\n }\n}\n\nfunction setStyles(el: Element, styles: Record<string, string | number>): void {\n const style = (el as HTMLElement).style;\n if (!style) return;\n Object.keys(styles).forEach((prop) => {\n (style as any)[prop] = String(styles[prop]);\n });\n}\n\nconst NUM_UNIT = /(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?)([a-z%]*)/gi;\n\n/**\n * Interpolate two CSS values at `t`. Numbers interpolate directly; strings\n * interpolate when they share the same structure (e.g. `translateY(40px)` ->\n * `translateY(0px)`, or `scale(0.8)` -> `scale(1)`). Otherwise snaps at 0.5.\n * @internal\n */\nexport function interpolateValue(from: string | number, to: string | number, t: number): string | number {\n if (typeof from === 'number' && typeof to === 'number') return from + (to - from) * t;\n const a = String(from);\n const b = String(to);\n const ta: Array<[number, string]> = [];\n const tb: Array<[number, string]> = [];\n const skA = a.replace(NUM_UNIT, (_, n, u) => (ta.push([parseFloat(n), u]), '#'));\n const skB = b.replace(NUM_UNIT, (_, n, u) => (tb.push([parseFloat(n), u]), '#'));\n if (skA !== skB || ta.length !== tb.length) return t < 0.5 ? from : to;\n let i = 0;\n let ok = true;\n const out = skA.replace(/#/g, () => {\n const [na, ua] = ta[i];\n const [nb, ub] = tb[i++];\n if (ua !== ub && na !== 0 && nb !== 0 && ua && ub) ok = false;\n const unit = ua || ub;\n return `${+(na + (nb - na) * t).toFixed(4)}${unit}`;\n });\n return ok ? out : t < 0.5 ? from : to;\n}\n\nconst EASING_SAMPLES = 30;\nlet linearSupported: boolean | undefined;\n\nfunction supportsLinearEasing(): boolean {\n if (linearSupported === undefined) {\n linearSupported =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('animation-timing-function', 'linear(0, 1)');\n }\n return linearSupported;\n}\n\nfunction sampleEasing(fn: (t: number) => number): number[] {\n const values: number[] = [];\n for (let i = 0; i <= EASING_SAMPLES; i++) {\n const v = fn(i / EASING_SAMPLES);\n values.push(Number.isFinite(v) ? +v.toFixed(4) : i / EASING_SAMPLES);\n }\n return values;\n}\n\nfunction buildAnimation(\n preset: KeyframeMap,\n easing: Required<AnimateOptions>['easing']\n): { keyframes: Keyframe[]; easing: string } {\n // `frames`: intermediate keyframes (overshoot, bounce, glitch …) between from and to\n const list = [preset.from, ...(preset.frames || []), preset.to] as Keyframe[];\n if (typeof easing !== 'function') {\n return { keyframes: list, easing: resolveEasing(easing) };\n }\n const samples = sampleEasing(easing);\n // Modern browsers: an exact, property-agnostic `linear()` easing curve.\n if (supportsLinearEasing() || preset.frames) {\n return { keyframes: list, easing: supportsLinearEasing() ? `linear(${samples.join(', ')})` : 'ease' };\n }\n // Fallback: approximate the curve with interpolated keyframes.\n const props = Object.keys(preset.from).filter((p) => p in preset.to);\n const keyframes = samples.map((eased, i) => {\n const frame: Keyframe = { offset: i / EASING_SAMPLES };\n props.forEach((prop) => {\n frame[prop] = interpolateValue(preset.from[prop], preset.to[prop], eased);\n });\n return frame;\n });\n return { keyframes, easing: 'linear' };\n}\n\n/** Make an element visible without animating (reduced motion / disabled / no WAAPI). */\nfunction reveal(el: Element, config: Required<ScrollAnimateConfig>): void {\n cancelRunning(el);\n if (config.useClassNames) {\n el.classList.remove(config.hiddenClass);\n el.classList.add(config.visibleClass);\n } else {\n const style = (el as HTMLElement).style;\n if (style) style.opacity = '';\n }\n}\n\n/** @internal Cancel a running/pending animation and make the element visible. */\nexport function stopAnimation(el: Element, config: ScrollAnimateConfig = {}): void {\n reveal(el, { ...DEFAULT_CONFIG, ...config });\n}\n\n/** @internal Resolve a selector / Element / NodeList / Element[] to elements (SSR-safe). */\nexport { resolveTargets, hasDOM };\n\n/** @internal Whether animations should be skipped entirely. */\nexport function motionDisabled(config: Pick<ScrollAnimateConfig, 'disabled'>): boolean {\n return !!config.disabled || prefersReducedMotion();\n}\n\nfunction runAnimation(\n el: Element,\n opts: Required<AnimateOptions>,\n config: Required<ScrollAnimateConfig>,\n staggerIndex = 0,\n pending?: Set<Element>\n): void {\n const { duration, delay, stagger, onStart, onComplete } = opts;\n const totalDelay = Math.max(0, delay + staggerIndex * stagger);\n cancelRunning(el);\n\n if (motionDisabled(config)) {\n reveal(el, config);\n onStart(el);\n onComplete(el);\n return;\n }\n\n if (config.useClassNames) {\n if (totalDelay > 0) (el as HTMLElement).style.animationDelay = `${totalDelay}ms`;\n el.classList.remove(config.hiddenClass);\n el.classList.add(config.visibleClass);\n onStart(el);\n pending?.add(el);\n timers.set(\n el,\n setTimeout(() => {\n timers.delete(el);\n pending?.delete(el);\n onComplete(el);\n }, duration + totalDelay)\n );\n return;\n }\n\n const preset = resolvePreset(opts.animation);\n // Presets that don't animate opacity (slide-*, clip-*, scale-x, ...) would\n // otherwise stay at the `opacity: 0` applied while waiting to enter.\n if (!('opacity' in preset.to)) {\n const style = (el as HTMLElement).style;\n if (style && style.opacity === '0') style.opacity = '';\n }\n\n if (typeof el.animate !== 'function') {\n setStyles(el, preset.to);\n onStart(el);\n onComplete(el);\n return;\n }\n\n const built = buildAnimation(preset, opts.easing);\n const timing: KeyframeAnimationOptions = { duration, delay: totalDelay, easing: built.easing, fill: 'both' };\n let anim: Animation;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n // Invalid user easing string (WAAPI throws a TypeError): fall back to 'ease'\n anim = el.animate(built.keyframes, { ...timing, easing: 'ease' });\n }\n running.set(el, anim);\n onStart(el);\n anim.onfinish = () => {\n if (running.get(el) === anim) {\n running.delete(el);\n // Persist the end state inline and drop the filling animation. This frees\n // the Animation object and lets later inline styles (parallax, user code)\n // take effect instead of being masked by `fill: forwards`.\n try {\n anim.commitStyles();\n } catch {\n setStyles(el, preset.to);\n }\n anim.cancel();\n }\n onComplete(el);\n };\n}\n\n/**\n * Native engine: attach the preset to a `ViewTimeline` of the element, so the\n * browser drives it from scroll position. Returns `null` when that fails\n * (caller falls back to the JS engine).\n */\nfunction startNative(el: Element, opts: Required<AnimateOptions>, onFrozen?: () => void): Animation | null {\n if (typeof el.animate !== 'function') return null;\n const preset = resolvePreset(opts.animation);\n const built = buildAnimation(preset, opts.easing);\n let anim: Animation;\n try {\n const timeline = new (globalThis as any).ViewTimeline({ subject: el, axis: 'block' });\n const timing = {\n fill: 'both',\n easing: built.easing,\n timeline,\n rangeStart: opts.viewRange[0],\n rangeEnd: opts.viewRange[1],\n } as KeyframeAnimationOptions;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n anim = el.animate(built.keyframes, { ...timing, easing: 'linear' });\n }\n } catch {\n return null;\n }\n running.set(el, anim);\n if (opts.exit) {\n // Reverse keyframes over the `exit` range; `fill: 'forwards'` so it has\n // no effect before the element starts leaving.\n const leave = resolvePreset(opts.exit === true ? opts.animation : opts.exit);\n const out = buildAnimation(reversePreset(leave), opts.easing);\n try {\n const timeline = new (globalThis as any).ViewTimeline({ subject: el, axis: 'block' });\n const timing = { fill: 'forwards', easing: out.easing, timeline, rangeStart: 'exit 0%', rangeEnd: 'exit 100%' };\n exits.set(el, el.animate(out.keyframes, timing as KeyframeAnimationOptions));\n } catch {\n // Exit is cosmetic: ignore if unsupported.\n }\n }\n const keep = opts.repeat || !opts.once;\n anim.onfinish = () => {\n // `once`: freeze the end state, so scrolling back up does not reverse it.\n if (!keep && running.get(el) === anim) {\n running.delete(el);\n try {\n anim.commitStyles();\n } catch {\n setStyles(el, preset.to);\n }\n anim.cancel();\n onFrozen?.();\n }\n opts.onComplete(el);\n };\n return anim;\n}\n\n/** Play the exit animation (entrance or `exit` preset, reversed), ending hidden. */\nfunction runExit(el: Element, opts: Required<AnimateOptions>, config: Required<ScrollAnimateConfig>): void {\n if (config.useClassNames || typeof el.animate !== 'function') {\n hideElement(el, config);\n return;\n }\n cancelRunning(el);\n const preset = resolvePreset(opts.exit === true ? opts.animation : (opts.exit as Exclude<typeof opts.exit, boolean>));\n const built = buildAnimation(reversePreset(preset), opts.easing);\n const timing: KeyframeAnimationOptions = { duration: opts.duration, easing: built.easing, fill: 'forwards' };\n let anim: Animation;\n try {\n anim = el.animate(built.keyframes, timing);\n } catch {\n anim = el.animate(built.keyframes, { ...timing, easing: 'ease' });\n }\n // Kept (filling) until the next entrance cancels it.\n running.set(el, anim);\n}\n\nfunction hideElement(el: Element, config: Required<ScrollAnimateConfig>): void {\n cancelRunning(el);\n if (config.useClassNames) {\n el.classList.add(config.hiddenClass);\n el.classList.remove(config.visibleClass);\n } else {\n const style = (el as HTMLElement).style;\n if (style) style.opacity = '0';\n }\n}\n\n/** @internal Hide an element before its entrance animation, unless motion is off. */\nexport function prepareElement(el: Element, config: ScrollAnimateConfig = {}): void {\n const full = { ...DEFAULT_CONFIG, ...config };\n if (!motionDisabled(full)) hideElement(el, full);\n}\n\nlet progressThresholds: number[] | undefined;\nfunction getProgressThresholds(): number[] {\n if (!progressThresholds) {\n progressThresholds = [];\n for (let i = 0; i <= 100; i++) progressThresholds.push(i / 100);\n }\n return progressThresholds;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/* ------------------------------------------------------------------ */\n/* Instance */\n/* ------------------------------------------------------------------ */\n\nexport function createScrollAnimate(userConfig: ScrollAnimateConfig = {}): ScrollAnimateInstance {\n let config: Required<ScrollAnimateConfig> = { ...DEFAULT_CONFIG, ...userConfig };\n const registry = new Map<Element, AnimatedElement>();\n // `once` elements that finished and were dropped from the registry (autoUnregister).\n let finished = new WeakSet<Element>();\n // Elements in `progressMode: 'scroll'` that are currently inside the viewport.\n const scrolling = new Set<Element>();\n let frame = 0;\n let listening: EventTarget | null = null;\n // Active watch() MutationObservers, disconnected by destroy().\n const watchers = new Set<MutationObserver>();\n // Elements with a pending class-name completion timer started by this instance.\n const pending = new Set<Element>();\n // Elements whose entrance runs on a native scroll-driven timeline.\n const natives = new Set<Element>();\n\n // Observers are shared between elements with the same root/threshold/rootMargin,\n // instead of one (or two) IntersectionObservers per element.\n const pools = new Map<Root, Map<string, IntersectionObserver>>();\n\n function pooled(root: Root, key: string, create: () => IntersectionObserver): IntersectionObserver {\n let pool = pools.get(root);\n if (!pool) pools.set(root, (pool = new Map()));\n let io = pool.get(key);\n if (!io) pool.set(key, (io = create()));\n return io;\n }\n\n function teardown(el: Element, restore: boolean): void {\n const record = registry.get(el);\n if (!record) return;\n record.observer.unobserve(el);\n record.progressObserver?.unobserve(el);\n registry.delete(el);\n untrack(el);\n if (record.engine === 'css') {\n // A scroll-linked animation would keep following the scroll: stop it and\n // show the element (unless it finished and is just being released).\n if (restore) {\n natives.delete(el);\n reveal(el, config);\n } else if (el.isConnected === false) {\n // Left the DOM: drop it too, or the instance keeps it alive (and\n // destroy() touches it) for its whole lifetime.\n natives.delete(el);\n }\n return;\n }\n // An element that never animated would otherwise stay invisible forever.\n if (restore && !record.animated) reveal(el, config);\n }\n\n function pruneDetached(): void {\n registry.forEach((record, el) => {\n if (el.isConnected === false) teardown(el, false);\n });\n }\n\n function emitProgress(el: Element, record: AnimatedElement, progress: number): void {\n const opts = record.options;\n opts.onProgress(el, progress);\n if (opts.progressVar) {\n const style = (el as HTMLElement).style;\n if (style) style.setProperty(opts.progressVar, String(+progress.toFixed(4)));\n }\n }\n\n function update(): void {\n frame = 0;\n scrolling.forEach((el) => {\n const record = registry.get(el);\n if (record) emitProgress(el, record, getScrollProgress(el, config.root));\n });\n }\n\n // rAF-throttled; IntersectionObserver-capable browsers all have rAF.\n const schedule = () => frame || (frame = requestAnimationFrame(update));\n\n function listen(on: boolean): void {\n if (on === !!listening) return;\n const method = on ? 'addEventListener' : 'removeEventListener';\n const target: EventTarget = listening || (config.root as EventTarget | null) || window;\n target[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n listening = on ? target : null;\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n }\n\n function untrack(el: Element): void {\n if (scrolling.delete(el) && !scrolling.size) listen(false);\n }\n\n function onScrollIntersect(entries: IntersectionObserverEntry[]): void {\n entries.forEach((entry) => {\n const el = entry.target;\n const record = registry.get(el);\n if (!record) return;\n if (entry.isIntersecting) {\n scrolling.add(el);\n listen(true);\n } else {\n untrack(el);\n }\n // Emit right away so the edges (0 / 1) are reported even on fast scrolls.\n emitProgress(el, record, getScrollProgress(el, config.root));\n });\n }\n\n function onIntersect(entries: IntersectionObserverEntry[]): void {\n const staggerCounts = new Map<Element | null, number>();\n entries.forEach((entry) => {\n const el = entry.target;\n const record = registry.get(el);\n if (!record) return;\n const opts = record.options;\n\n if (el.isConnected === false) {\n teardown(el, false);\n return;\n }\n\n if (record.engine === 'css') {\n // The browser drives the animation; only lifecycle bookkeeping here.\n if (entry.isIntersecting) {\n opts.onEnter(el);\n if (!record.animated) {\n record.animated = true;\n opts.onStart(el);\n }\n if (opts.once && !opts.repeat) {\n record.observer.unobserve(el);\n if (config.autoUnregister && !record.progressObserver) {\n finished.add(el);\n teardown(el, false);\n }\n }\n } else {\n opts.onLeave(el);\n if (opts.repeat) record.animated = false;\n }\n return;\n }\n\n if (entry.isIntersecting) {\n opts.onEnter(el);\n if (record.animated && !opts.repeat) return;\n\n // Stagger relative to siblings revealed in the same batch, so elements\n // scrolled into view later don't inherit an ever-growing delay.\n let staggerIndex = 0;\n if (opts.stagger > 0) {\n const parent = el.parentElement;\n staggerIndex = staggerCounts.get(parent) ?? 0;\n staggerCounts.set(parent, staggerIndex + 1);\n }\n\n runAnimation(el, opts, config, staggerIndex, pending);\n record.animated = true;\n\n if (opts.once && !opts.repeat) {\n // Keep the progress observer: parallax/onProgress must keep working.\n record.observer.unobserve(el);\n if (config.autoUnregister && !record.progressObserver) {\n // Nothing left to watch: free the record (the running animation\n // keeps its own reference until it finishes).\n finished.add(el);\n teardown(el, false);\n }\n }\n } else {\n opts.onLeave(el);\n if (opts.repeat && record.animated) {\n if (!motionDisabled(config)) {\n if (opts.exit) runExit(el, opts, config);\n else hideElement(el, config);\n }\n record.animated = false;\n }\n }\n });\n }\n\n function onProgress(entries: IntersectionObserverEntry[]): void {\n entries.forEach((entry) => {\n const record = registry.get(entry.target);\n if (!record) return;\n emitProgress(entry.target, record, entry.intersectionRatio);\n });\n }\n\n function getObserver(opts: Required<AnimateOptions>): IntersectionObserver {\n const rootMargin = applyOffset(opts.rootMargin, opts.offset);\n const threshold = opts.threshold;\n const root = config.root;\n return pooled(root, `m|${rootMargin}|${String(threshold)}`, () =>\n new IntersectionObserver(onIntersect, { threshold, rootMargin, root: root as Element | null })\n );\n }\n\n function getProgressObserver(opts: Required<AnimateOptions>): IntersectionObserver {\n const root = config.root;\n if (opts.progressMode === 'scroll') {\n // Only used to know when to start/stop measuring; progress itself comes\n // from a single shared, rAF-throttled passive scroll listener.\n return pooled(root, `s|${opts.rootMargin}`, () =>\n new IntersectionObserver(onScrollIntersect, { threshold: 0, rootMargin: opts.rootMargin, root: root as Element | null })\n );\n }\n return pooled(root, `p|${opts.rootMargin}`, () =>\n new IntersectionObserver(onProgress, {\n threshold: getProgressThresholds(),\n rootMargin: opts.rootMargin,\n root: root as Element | null,\n })\n );\n }\n\n function attach(el: Element, record: AnimatedElement, observeMain: boolean): void {\n record.observer = getObserver(record.options);\n if (observeMain) record.observer.observe(el);\n record.progressObserver = needsProgress(record.options) ? getProgressObserver(record.options) : undefined;\n record.progressObserver?.observe(el);\n }\n\n function wantsNative(opts: Required<AnimateOptions>): boolean {\n return opts.engine !== 'js' && !config.useClassNames && !motionDisabled(config) && supportsScrollTimeline();\n }\n\n function observeElement(el: Element, opts: Required<AnimateOptions>): void {\n if (registry.has(el) || finished.has(el)) return;\n\n if (!supportsObserver()) {\n // No IntersectionObserver (very old browser): never leave content hidden.\n reveal(el, config);\n return;\n }\n\n const record = { element: el, options: opts, animated: false, engine: 'js' } as AnimatedElement;\n if (wantsNative(opts)) {\n cancelRunning(el);\n if (startNative(el, opts, () => natives.delete(el))) {\n record.engine = 'css';\n natives.add(el);\n }\n }\n if (record.engine === 'js' && !motionDisabled(config)) hideElement(el, config);\n\n registry.set(el, record);\n attach(el, record, true);\n }\n\n function observeDataElement(el: Element): void {\n if (!registry.has(el)) observeElement(el, parseDataAttributes(el, config));\n }\n\n const instance: ScrollAnimateInstance = {\n observe(target, options = {}) {\n pruneDetached();\n const opts = mergeOptions(options, config);\n resolveTargets(target).forEach((el) => observeElement(el, opts));\n },\n\n unobserve(target) {\n resolveTargets(target).forEach((el) => {\n finished.delete(el);\n teardown(el, true);\n });\n },\n\n init(rootElement) {\n const scope = rootElement ?? (hasDOM() ? document : null);\n if (!scope) return;\n pruneDetached();\n scope.querySelectorAll('[data-sa]').forEach(observeDataElement);\n },\n\n watch(rootElement) {\n const scope = rootElement ?? (hasDOM() ? document : null);\n if (!scope || typeof MutationObserver === 'undefined') return noop;\n instance.init(scope);\n const observeTree = (node: Element) => {\n if (node.hasAttribute('data-sa')) observeDataElement(node);\n node.querySelectorAll('[data-sa]').forEach(observeDataElement);\n };\n const mo = new MutationObserver((records) => {\n let removed = false;\n records.forEach((record) => {\n if (record.type === 'attributes') {\n const target = record.target as Element;\n if (target.isConnected !== false) observeTree(target);\n return;\n }\n record.addedNodes.forEach((node) => {\n if (node instanceof Element && node.isConnected !== false) observeTree(node);\n });\n if (record.removedNodes.length) removed = true;\n });\n // Free elements that left the DOM (they can't animate any more).\n if (removed) pruneDetached();\n });\n mo.observe(scope, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-sa'] });\n watchers.add(mo);\n return () => {\n mo.disconnect();\n watchers.delete(mo);\n };\n },\n\n destroy() {\n watchers.forEach((mo) => mo.disconnect());\n watchers.clear();\n // Class-name mode: drop completion timers so onComplete never fires after destroy().\n pending.forEach((el) => {\n const timer = timers.get(el);\n if (timer !== undefined) {\n clearTimeout(timer);\n timers.delete(el);\n }\n });\n pending.clear();\n registry.forEach((record, el) => {\n if (!record.animated && record.engine !== 'css') reveal(el, config);\n });\n // Native scroll-linked animations still running: stop them, show content.\n natives.forEach((el) => {\n if (running.has(el)) reveal(el, config);\n });\n natives.clear();\n pools.forEach((pool) => pool.forEach((io) => io.disconnect()));\n pools.clear();\n registry.clear();\n scrolling.clear();\n listen(false);\n finished = new WeakSet();\n },\n\n refresh() {\n // Rebuild observers (e.g. after configure({ root })) without re-hiding or\n // replaying elements that have already animated.\n pools.forEach((pool) => pool.forEach((io) => io.disconnect()));\n pools.clear();\n scrolling.clear();\n listen(false);\n pruneDetached();\n if (!supportsObserver()) return;\n registry.forEach((record, el) => {\n const done = record.animated && record.options.once && !record.options.repeat;\n attach(el, record, !done);\n });\n },\n\n animate(target, options = {}) {\n const opts = mergeOptions(options, config);\n resolveTargets(target).forEach((el) => runAnimation(el, opts, config, 0, pending));\n },\n\n getObservedElements() {\n return Array.from(registry.values());\n },\n\n configure(newConfig) {\n config = { ...config, ...newConfig };\n },\n };\n\n return instance;\n}\n","/**\n * motionary - Staggered children\n * Reveal a container's children one after another when the container scrolls\n * into view, optionally also animating children that are added later.\n */\n\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate, hasDOM, prepareElement, stopAnimation, supportsObserver } from './core';\n\nexport interface StaggerOptions extends AnimateOptions {\n /** Delay between consecutive children in ms (default: 80) */\n stagger?: number;\n /**\n * Watch the container with a MutationObserver and animate children added\n * later (e.g. infinite lists). Children added after the container was\n * revealed animate when they scroll into view, staggered per batch.\n * (default: false)\n */\n observeChildren?: boolean;\n}\n\nlet fallback: ScrollAnimateInstance | null = null;\n\n/**\n * Animate the children of `container` with a stagger once it enters the\n * viewport. Returns a cleanup function. SSR-safe (no-op without a DOM).\n *\n * @example\n * const stop = staggerChildren(document.querySelector('ul'), { stagger: 60, observeChildren: true });\n */\nexport function staggerChildren(\n container: Element | null | undefined,\n options: StaggerOptions = {},\n instance?: ScrollAnimateInstance\n): () => void {\n if (!container || !hasDOM() || !supportsObserver()) return () => undefined; // leave content visible\n const sa = instance || fallback || (fallback = createScrollAnimate());\n const { stagger = 80, delay = 0, threshold = 0.1, rootMargin = '0px', observeChildren = false, ...rest } = options;\n\n let items = Array.from(container.children);\n let revealed = false;\n const late: Element[] = [];\n items.forEach((child) => prepareElement(child));\n\n const io = new IntersectionObserver(\n (entries) => {\n if (revealed || !entries.some((entry) => entry.isIntersecting)) return;\n revealed = true;\n io.disconnect();\n items.forEach((child, i) => {\n if (child.parentNode === container) sa.animate(child, { ...rest, delay: delay + i * stagger });\n });\n items = [];\n },\n { threshold, rootMargin }\n );\n io.observe(container);\n\n let mo: MutationObserver | undefined;\n if (observeChildren && typeof MutationObserver !== 'undefined') {\n mo = new MutationObserver((records) => {\n records.forEach((record) => {\n record.addedNodes.forEach((node) => {\n if (!(node instanceof Element) || node.parentNode !== container) return;\n if (!revealed) {\n prepareElement(node);\n items.push(node);\n } else {\n // The core engine staggers siblings relative to the batch that\n // enters the viewport together.\n late.push(node);\n sa.observe(node, { ...rest, delay, stagger, threshold, rootMargin });\n }\n });\n record.removedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n items = items.filter((el) => el !== node);\n const i = late.indexOf(node);\n if (i >= 0) {\n late.splice(i, 1);\n sa.unobserve(node);\n }\n });\n });\n });\n mo.observe(container, { childList: true });\n }\n\n return () => {\n io.disconnect();\n mo?.disconnect();\n // Stopped before the container was revealed: never leave the children hidden.\n if (!revealed) {\n revealed = true;\n items.forEach((child) => stopAnimation(child));\n items = [];\n }\n late.forEach((el) => sa.unobserve(el));\n late.length = 0;\n };\n}\n","/**\n * motionary/components — shared base for the `<usa-*>` custom elements.\n *\n * Everything here is lazy: nothing touches `window`, `document`,\n * `HTMLElement` or `matchMedia` at import time, so the components can be\n * imported during SSR (Next, Nuxt, Astro…) and in Electron/Tauri preload\n * scripts. Classes are created the first time a `define*()` function runs.\n */\n\nexport interface ComponentsConfig {\n /**\n * Inject each component's CSS when it is defined (default `true`). Uses a\n * constructable stylesheet (`document.adoptedStyleSheets`, which a strict\n * `style-src` CSP does not block) and falls back to a `<style>` tag. Set\n * to `false` when you load `motionary/components.css` yourself.\n */\n injectStyles?: boolean;\n /**\n * `'user'` (default) follows `prefers-reduced-motion`; `'reduce'` always\n * uses the reduced variants (e.g. a kiosk / battery-saver mode). 5.0: the\n * OS setting can no longer be ignored (`'no-preference'` was removed).\n */\n reducedMotion?: 'user' | 'reduce';\n /**\n * Global motion intensity (v2.7): `'low'` (shorter, calmer), `'normal'`\n * (default) or `'high'`. Scales every component animation's duration and\n * sets `--usa-motion` (0.6 / 1 / 1.25) on `<html>` for your own CSS. 5.0:\n * `'off'` was removed — use `motionSensitivity: 'minimal'`.\n */\n motionIntensity?: MotionIntensity;\n /**\n * Motion-sensitivity level (v4.4), finer than reduced motion:\n * `'full'` (default) · `'gentle'` (no spins, zooms, skews or parallax —\n * translations and fades only, safe for vestibular disorders) ·\n * `'minimal'` (fades only; components use their reduced-motion variants) ·\n * `'static'` (no animation: every component shows its static alternative).\n * See `setMotionSensitivity()` in `motionary/components/a11y`.\n */\n motionSensitivity?: MotionSensitivity;\n}\n\nexport type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';\nexport const MOTION_SENSITIVITY_LEVELS: readonly MotionSensitivity[] = ['full', 'gentle', 'minimal', 'static'];\n\nexport type MotionIntensity = 'low' | 'normal' | 'high';\nexport const MOTION_SCALE: Record<MotionIntensity, number> = { low: 0.6, normal: 1, high: 1.25 };\n\nconst config: Required<ComponentsConfig> = { injectStyles: true, reducedMotion: 'user', motionIntensity: 'normal', motionSensitivity: 'full' };\n\n/** Change global component settings (call before `define*()` for `injectStyles`). */\nexport function configureComponents(options: ComponentsConfig): void {\n options = { ...options };\n // 5.0: removed values are ignored (see docs/upgrading-5.md)\n if (options.motionIntensity && !(options.motionIntensity in MOTION_SCALE)) delete options.motionIntensity;\n if (options.reducedMotion && options.reducedMotion !== 'reduce') options.reducedMotion = 'user';\n Object.assign(config, options);\n if (options.motionIntensity && typeof document !== 'undefined') {\n document.documentElement.style.setProperty('--usa-motion', String(MOTION_SCALE[options.motionIntensity] ?? 1));\n document.documentElement.setAttribute('data-usa-motion', options.motionIntensity);\n }\n if (options.motionSensitivity && typeof document !== 'undefined') {\n if (options.motionSensitivity === 'full') document.documentElement.removeAttribute('data-usa-sensitivity');\n else document.documentElement.setAttribute('data-usa-sensitivity', options.motionSensitivity);\n }\n}\n\n/** The current motion-sensitivity level (v4.4). */\nexport function getMotionSensitivity(): MotionSensitivity {\n return config.motionSensitivity;\n}\n\nconst VESTIBULAR = /rotate|scale|skew|perspective|matrix3d/;\n/**\n * Adapt keyframes to the sensitivity level: `gentle` drops transforms that\n * spin, zoom or skew (and 3D), `minimal` keeps opacity only, `static` keeps\n * just the final frame. `full` returns them unchanged.\n */\nexport function adaptKeyframes(frames: Keyframe[], level: MotionSensitivity = config.motionSensitivity): Keyframe[] {\n if (level === 'full' || !frames.length) return frames;\n if (level === 'static') return [frames[frames.length - 1]];\n return frames.map((f) => {\n const out: Keyframe = {};\n for (const [k, v] of Object.entries(f)) {\n if (k === 'offset' || k === 'easing' || k === 'composite') out[k] = v as any;\n else if (level === 'minimal') {\n if (k === 'opacity') out[k] = v as any;\n } else if (k === 'rotate' || k === 'scale' || (k === 'transform' && VESTIBULAR.test(String(v)))) continue;\n else out[k] = v as any;\n }\n return out;\n });\n}\n\nlet quiet = 0;\n/** Run `fn` without 4.9 deprecation warnings (library-internal calls). */\nexport function withoutDeprecations<T>(fn: () => T): T {\n quiet++;\n try {\n return fn();\n } finally {\n quiet--;\n }\n}\n\n/** The current global motion intensity. */\nexport function getMotionIntensity(): MotionIntensity {\n return config.motionIntensity;\n}\n\n/** Duration multiplier for the current intensity (1 when `normal`). */\nexport function motionScale(): number {\n return MOTION_SCALE[config.motionIntensity] ?? 1;\n}\n\nexport const canDefine = (): boolean => typeof customElements !== 'undefined' && typeof HTMLElement !== 'undefined';\n\n/** `true` when animations should be reduced (OS setting or `configureComponents`). */\nexport function prefersReducedMotion(): boolean {\n if (config.motionSensitivity === 'minimal' || config.motionSensitivity === 'static') return true;\n if (config.reducedMotion === 'reduce') return true;\n return typeof matchMedia === 'function' && !!matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\nconst injected = new Set<string>();\n\n/** Add a component's stylesheet to the document once. */\nexport function adoptStyles(id: string, css: string): void {\n if (!config.injectStyles || !css || injected.has(id) || typeof document === 'undefined') return;\n injected.add(id);\n try {\n if (typeof CSSStyleSheet === 'function' && 'adoptedStyleSheets' in document) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(css);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];\n return;\n }\n } catch {\n /* fall through to <style> */\n }\n const style = document.createElement('style');\n style.setAttribute('data-usa', id);\n style.textContent = css;\n (document.head || document.documentElement).appendChild(style);\n}\n\n/** Attach `css` to a shadow root (constructable sheet where supported, else `<style>`). */\nexport function shadowStyles(root: ShadowRoot, css: string): void {\n try {\n if (typeof CSSStyleSheet === 'function' && 'adoptedStyleSheets' in root) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(css);\n root.adoptedStyleSheets = [sheet];\n return;\n }\n } catch {\n /* fall through */\n }\n const style = document.createElement('style');\n style.textContent = css;\n root.prepend(style);\n}\n\nexport type Cleanup = () => void;\n\n/**\n * Members shared by every `<usa-*>` element. Attribute helpers, a cleanup\n * bag that is emptied on disconnect, and motion helpers that degrade to the\n * final state without WAAPI or under reduced motion.\n */\nexport interface UsaElement extends HTMLElement {\n /** `true` while reduced motion applies to this element. */\n readonly reduced: boolean;\n}\n\nexport interface UsaBase extends UsaElement {\n mount(): void;\n changed(name: string): void;\n unmount(): void;\n str(name: string, fallback?: string): string;\n num(name: string, fallback: number): number;\n flag(name: string): boolean;\n setFlag(name: string, on: boolean): void;\n onCleanup(fn: Cleanup): void;\n listen<K extends keyof HTMLElementEventMap>(\n target: EventTarget,\n type: K | string,\n fn: (e: any) => void,\n options?: AddEventListenerOptions\n ): void;\n inView(cb: (visible: boolean, entry?: IntersectionObserverEntry) => void, init?: IntersectionObserverInit, target?: Element): void;\n motion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;\n emit(type: string, detail?: unknown): boolean;\n}\n\ntype BaseCtor = new () => UsaBase;\nlet baseClass: BaseCtor | null = null;\n\n/** The lazily created base class (needs `HTMLElement`). */\nexport function getBase(): BaseCtor {\n if (baseClass) return baseClass;\n class Base extends HTMLElement {\n private _cleanups: Cleanup[] = [];\n private _connected = false;\n\n get reduced(): boolean {\n return prefersReducedMotion();\n }\n\n connectedCallback(): void {\n if (this._connected) return;\n this._connected = true;\n styleLoader?.(this.localName);\n // Upgraded while the parser is still inside us (a <script> in <head>\n // defined the element): children/text are not there yet, so wait.\n if (typeof document !== 'undefined' && document.readyState === 'loading' && !this.nextSibling && !this.childNodes.length) {\n const go = () => {\n if (this._connected && this.isConnected) this.mount();\n };\n document.addEventListener('DOMContentLoaded', go, { once: true });\n this._cleanups.push(() => document.removeEventListener('DOMContentLoaded', go));\n return;\n }\n this.mount();\n }\n\n disconnectedCallback(): void {\n this._connected = false;\n this.teardown();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, value: string | null): void {\n if (!this._connected || oldValue === value) return;\n this.changed(_name);\n }\n\n /** Re-mount on attribute change (override for finer updates). */\n changed(_name: string): void {\n this.teardown();\n this.mount();\n }\n\n private teardown(): void {\n this._cleanups.splice(0).reverse().forEach((fn) => fn());\n this.unmount();\n }\n\n mount(): void {}\n unmount(): void {}\n\n str(name: string, fallback = ''): string {\n const v = this.getAttribute(name);\n return v === null ? fallback : v;\n }\n\n num(name: string, fallback: number): number {\n const v = this.getAttribute(name);\n const n = v === null || v.trim() === '' ? NaN : Number(v);\n return Number.isFinite(n) ? n : fallback;\n }\n\n /** Boolean attribute: present and not `\"false\"`. */\n flag(name: string): boolean {\n const v = this.getAttribute(name);\n return v !== null && v !== 'false';\n }\n\n setFlag(name: string, on: boolean): void {\n if (on) this.setAttribute(name, '');\n else this.removeAttribute(name);\n }\n\n onCleanup(fn: Cleanup): void {\n this._cleanups.push(fn);\n }\n\n listen(target: EventTarget, type: string, fn: (e: any) => void, options?: AddEventListenerOptions): void {\n target.addEventListener(type, fn, options);\n this.onCleanup(() => target.removeEventListener(type, fn, options));\n }\n\n /** Calls `cb(true/false)` as the element enters / leaves the viewport. */\n inView(cb: (visible: boolean, entry?: IntersectionObserverEntry) => void, init?: IntersectionObserverInit, target: Element = this): void {\n if (typeof IntersectionObserver === 'undefined') {\n cb(true);\n return;\n }\n const io = new IntersectionObserver((entries) => {\n for (const e of entries) cb(e.isIntersecting, e);\n }, init);\n io.observe(target);\n this.onCleanup(() => io.disconnect());\n }\n\n /** `el.animate()` that returns `null` (and applies the last frame) without WAAPI. */\n motion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null {\n return animateWithMotion(el, keyframes, options);\n }\n\n emit(type: string, detail?: unknown): boolean {\n return this.dispatchEvent(new CustomEvent(`usa:${type}`, { detail, bubbles: true, cancelable: true }));\n }\n }\n baseClass = Base as unknown as BaseCtor;\n return baseClass;\n}\n\n/**\n * `el.animate()` with the library's motion rules (5.0, shared by elements and\n * registered effects): motion sensitivity (keyframes adapted, `static` →\n * final frame), intensity (duration scale) and the animation budget. Returns\n * `null` (final frame applied) when nothing should animate.\n */\nexport function animateWithMotion(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null {\n if (typeof (el as HTMLElement).animate !== 'function' || config.motionSensitivity === 'static') {\n applyFrame(el as HTMLElement, keyframes[keyframes.length - 1]);\n return null;\n }\n keyframes = adaptKeyframes(keyframes);\n if (active >= maxActive) {\n applyFrame(el as HTMLElement, keyframes[keyframes.length - 1]);\n return null;\n }\n const k = motionScale();\n if (k !== 1 && k > 0 && typeof options.duration === 'number') options = { ...options, duration: options.duration * k, delay: (options.delay || 0) * k };\n const a = (el as HTMLElement).animate(keyframes, options);\n trackAnimation(a);\n if (options.iterations !== Infinity) {\n active++;\n let done = false;\n const end = () => {\n if (!done) {\n done = true;\n active--;\n }\n };\n a?.finished?.then(end, end);\n }\n return a;\n}\n\n/** Write a keyframe's properties as inline styles (no-WAAPI fallback). */\nexport function applyFrame(el: HTMLElement, frame?: Keyframe): void {\n if (!frame) return;\n for (const [k, v] of Object.entries(frame)) {\n if (k === 'offset' || k === 'easing' || k === 'composite' || v == null) continue;\n (el.style as any)[k] = String(v);\n }\n}\n\n/**\n * Register `tag` with the class built by `make(Base)`. Returns the\n * constructor, the already registered one, or `undefined` without DOM.\n */\nexport function defineElement(\n tag: string,\n make: (Base: BaseCtor) => CustomElementConstructor,\n css?: { id: string; text: string }\n): CustomElementConstructor | undefined {\n if (!canDefine()) return undefined;\n adoptStyles('base', BASE_CSS);\n if (css) adoptStyles(css.id, css.text);\n const existing = customElements.get(tag);\n if (existing) return existing;\n const ctor = make(getBase());\n customElements.define(tag, ctor);\n return ctor;\n}\n\nconst BASE_CSS = '.usa-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}';\n\n/** A visually hidden copy of `text` for screen readers (the animated copy is `aria-hidden`). */\nexport function srText(text: string): HTMLSpanElement {\n const s = document.createElement('span');\n s.className = 'usa-sr';\n s.textContent = text;\n return s;\n}\n\n// --- shared rAF scheduler (4.5) ----------------------------------------------\n// Every component loop goes through one requestAnimationFrame per frame\n// instead of one per element: callbacks are batched, run in order, and a\n// throwing callback no longer starves the others (the first error is rethrown).\nconst frameQueue = new Map<number, FrameRequestCallback>();\nlet frameSeq = 1;\nlet frameHandle: number | ReturnType<typeof setTimeout> | 0 = 0;\nlet frameVia: unknown = null;\nconst frameStats = { frames: 0, callbacks: 0, peak: 0, last: 0 };\nconst frameListeners = new Set<(t: number, dt: number) => void>();\n\nfunction flushFrame(t: number): void {\n frameHandle = 0;\n const dt = frameStats.last && t > frameStats.last ? t - frameStats.last : 16.7;\n frameStats.last = t;\n frameStats.frames++;\n const cbs = Array.from(frameQueue.values());\n frameQueue.clear();\n frameStats.callbacks += cbs.length;\n frameStats.peak = Math.max(frameStats.peak, cbs.length);\n let error: unknown = null;\n for (const cb of cbs) {\n try {\n cb(t);\n } catch (e) {\n error ??= e;\n }\n }\n // 8.0: loops run on the unified motion clock — dt scaled by its rate, frozen while paused\n if (!clockState.paused) {\n const cdt = dt * clockState.rate;\n clockState.time += cdt;\n frameListeners.forEach((fn) => fn(t, cdt));\n if (frameListeners.size) requestFlush();\n }\n if (error) throw error;\n}\n\nfunction requestFlush(): void {\n const native = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : null;\n // A stale handle from a replaced requestAnimationFrame (tests, iframes) is dropped.\n if (frameHandle && frameVia === native) return;\n frameVia = native;\n frameHandle = native ? native(flushFrame) : setTimeout(() => flushFrame(now()), 16);\n}\n\n/** requestAnimationFrame through the shared scheduler (timeout fallback in jsdom / hidden documents). */\nexport const raf = (cb: FrameRequestCallback): number => {\n const id = frameSeq++;\n frameQueue.set(id, cb);\n requestFlush();\n return id;\n};\n/** Monotonic time in ms (rAF callback timestamps differ between environments, so loops use this). */\nexport const now = (): number => (typeof performance !== 'undefined' ? performance.now() : Date.now());\nexport const caf = (id: number): void => {\n frameQueue.delete(id);\n};\n\n/** Run `fn(time, dt)` every frame on the shared scheduler until the returned function is called. */\nexport function onFrame(fn: (t: number, dt: number) => void): () => void {\n frameListeners.add(fn);\n if (!clockState.paused) requestFlush();\n return () => frameListeners.delete(fn);\n}\n\n/** Scheduler counters: frames flushed, callbacks run, peak callbacks in one frame, pending now. */\nexport function schedulerStats(): { frames: number; callbacks: number; peak: number; pending: number; loops: number } {\n return { frames: frameStats.frames, callbacks: frameStats.callbacks, peak: frameStats.peak, pending: frameQueue.size, loops: frameListeners.size };\n}\n\n// --- unified motion clock (8.0) --------------------------------------------------\n// One clock drives every component, effect and frame loop: its rate scales\n// all WAAPI animations started through animateWithMotion() and the dt of the\n// shared frame loop; pausing it pauses them all. Shared across bundles via a\n// global symbol so the ESM, CJS and UMD builds on one page agree.\ninterface ClockState {\n rate: number;\n paused: boolean;\n time: number;\n anims: Set<Animation>;\n subs: Set<() => void>;\n}\nconst CLOCK_KEY = Symbol.for('motionary.clock');\nconst clockState: ClockState = ((globalThis as any)[CLOCK_KEY] ||= { rate: 1, paused: false, time: 0, anims: new Set(), subs: new Set() });\n\nfunction applyClock(a: Animation): void {\n try {\n if (typeof (a as any).updatePlaybackRate === 'function') (a as any).updatePlaybackRate(clockState.rate);\n else if (clockState.rate !== 1 || (a as any).playbackRate !== undefined) (a as any).playbackRate = clockState.rate;\n if (clockState.paused) a.pause?.();\n else if (a.playState === 'paused' && (a as any)._usaClockPaused) a.play?.();\n (a as any)._usaClockPaused = clockState.paused;\n } catch {\n /* finished / detached animation */\n }\n}\n\n/** Put an animation on the shared motion clock (animateWithMotion does this for every component / effect animation). */\nexport function trackAnimation(a: Animation | null | undefined): void {\n if (!a) return;\n if (clockState.rate !== 1 || clockState.paused) applyClock(a);\n clockState.anims.add(a);\n const drop = () => clockState.anims.delete(a);\n a.finished?.then(drop, drop);\n}\n\n/** The motion clock's state: `rate` (1 = normal), `paused`, `time` (clock ms elapsed, scaled by rate). */\nexport function getClock(): { rate: number; paused: boolean; time: number; tracked: number } {\n return { rate: clockState.rate, paused: clockState.paused, time: clockState.time, tracked: clockState.anims.size };\n}\n\n/** Change the shared clock: `{ rate }` (0.05–8) and / or `{ paused }`. Applies to running animations and loops. */\nexport function setClock(next: { rate?: number; paused?: boolean }): void {\n const wasPaused = clockState.paused;\n if (typeof next.rate === 'number' && Number.isFinite(next.rate)) clockState.rate = Math.min(8, Math.max(0.05, next.rate));\n if (typeof next.paused === 'boolean') clockState.paused = next.paused;\n clockState.anims.forEach(applyClock);\n if (wasPaused && !clockState.paused && frameListeners.size) requestFlush();\n clockState.subs.forEach((fn) => fn());\n}\n\n/** Subscribe to clock changes; returns an unsubscribe. */\nexport function onClockChange(fn: () => void): () => void {\n clockState.subs.add(fn);\n return () => clockState.subs.delete(fn);\n}\n\n// --- active animation budget (4.5) ---------------------------------------------\nlet active = 0;\nlet maxActive = Infinity;\n/** Number of component animations running right now. */\nexport const activeAnimations = (): number => active;\n/** Cap concurrent component animations; extra ones jump to their final frame (`Infinity` = no cap). */\nexport function setAnimationBudget(max: number): void {\n maxActive = max > 0 ? max : Infinity;\n}\n/** The current cap. */\nexport const animationBudget = (): number => maxActive;\n\n// --- on-demand styles (4.5) -----------------------------------------------------\nlet styleLoader: ((tag: string) => void) | null = null;\n/** Called with each element's tag the first time one connects (used by the `lite` build to load CSS on demand). */\nexport function setStyleLoader(fn: ((tag: string) => void) | null): void {\n styleLoader = fn;\n}\n\nexport const EASE_OUT = 'cubic-bezier(0.22, 1, 0.36, 1)';\nexport const EASE_SPRING = 'cubic-bezier(0.34, 1.56, 0.64, 1)';\n/** Windows Fluent \"decelerate\" / \"point-to-point\" curves. */\nexport const FLUENT_DECELERATE = 'cubic-bezier(0.1, 0.9, 0.2, 1)';\n\nconst warned = new Set<string>();\n/** Log a deprecation once per key (console.warn). */\nexport function deprecate(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n if (typeof console !== 'undefined') console.warn(`[motionary] ${message}`);\n}\n\n/**\n * The `kind` attribute of `<usa-spinner>`, `<usa-check>`, `<usa-dialog>` and\n * `<usa-acrylic>` (3.0: `variant` only selects a style variant).\n */\nexport function kindOf(el: Element, valid: readonly string[] | Record<string, unknown>, fallback: string): string {\n const k = el.getAttribute('kind');\n return k && (Array.isArray(valid) ? valid.includes(k) : k in (valid as object)) ? k : fallback;\n}\n\nexport const clamp = (v: number, min: number, max: number): number => Math.min(max, Math.max(min, v));\n","/**\n * motionary/components/tokens — motion design tokens (4.2).\n *\n * One source of truth for durations, easings and springs: as CSS custom\n * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,\n * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable\n * from Figma Tokens (Tokens Studio) or Style Dictionary exports.\n *\n * ```ts\n * import { applyMotionTokens, importMotionTokens, motionToken } from 'motionary/components/tokens';\n * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));\n * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });\n * ```\n */\n\nexport interface SpringToken {\n stiffness: number;\n damping: number;\n mass: number;\n}\n\nexport interface MotionTokens {\n /** Durations in ms. */\n duration: Record<string, number>;\n /** CSS easing strings. */\n easing: Record<string, string>;\n /** Spring physics parameters. */\n spring: Record<string, SpringToken>;\n}\n\n/** The default motion scale (Material / Fluent-inspired). */\nexport const MOTION_TOKENS: MotionTokens = {\n duration: { instant: 0, fast: 150, normal: 300, slow: 600, slower: 900, slowest: 1400 },\n easing: {\n linear: 'linear',\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n emphasized: 'cubic-bezier(0.22, 1, 0.36, 1)',\n decelerate: 'cubic-bezier(0, 0, 0, 1)',\n accelerate: 'cubic-bezier(0.3, 0, 1, 1)',\n spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n },\n spring: {\n gentle: { stiffness: 120, damping: 14, mass: 1 },\n snappy: { stiffness: 300, damping: 30, mass: 1 },\n bouncy: { stiffness: 260, damping: 12, mass: 1 },\n wobbly: { stiffness: 180, damping: 8, mass: 1 },\n stiff: { stiffness: 500, damping: 40, mass: 1 },\n },\n};\n\nexport type MotionTokenGroup = keyof MotionTokens;\nexport type DeepPartialTokens = { [K in keyof MotionTokens]?: Partial<MotionTokens[K]> };\n\nlet active: MotionTokens = clone(MOTION_TOKENS);\n\nfunction clone(t: MotionTokens): MotionTokens {\n return { duration: { ...t.duration }, easing: { ...t.easing }, spring: Object.fromEntries(Object.entries(t.spring).map(([k, v]) => [k, { ...v }])) };\n}\n\n/** Merge partial tokens over a base (defaults: the built-in scale). */\nexport function mergeMotionTokens(partial: DeepPartialTokens, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const out = clone(base);\n Object.assign(out.duration, partial.duration || {});\n Object.assign(out.easing, partial.easing || {});\n for (const [k, v] of Object.entries(partial.spring || {})) out.spring[k] = { ...(out.spring[k] || { stiffness: 170, damping: 26, mass: 1 }), ...v };\n return out;\n}\n\nconst kebab = (s: string) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[\\s_.]+/g, '-').toLowerCase();\n\n/** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */\nexport function motionTokensToVars(tokens: MotionTokens = active, prefix = '--usa'): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [k, v] of Object.entries(tokens.duration)) vars[`${prefix}-duration-${kebab(k)}`] = `${v}ms`;\n for (const [k, v] of Object.entries(tokens.easing)) vars[`${prefix}-easing-${kebab(k)}`] = v;\n for (const [k, v] of Object.entries(tokens.spring)) {\n vars[`${prefix}-spring-${kebab(k)}-stiffness`] = String(v.stiffness);\n vars[`${prefix}-spring-${kebab(k)}-damping`] = String(v.damping);\n vars[`${prefix}-spring-${kebab(k)}-mass`] = String(v.mass);\n }\n return vars;\n}\n\n/** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */\nexport function motionTokensToCss(tokens: MotionTokens = active, selector = ':root', prefix = '--usa'): string {\n const body = Object.entries(motionTokensToVars(tokens, prefix)).map(([k, v]) => ` ${k}: ${v};`).join('\\n');\n return `${selector} {\\n${body}\\n}\\n`;\n}\n\n/** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */\nexport function motionTokensToJSON(tokens: MotionTokens = active): Record<string, unknown> {\n const grp = <T>(o: Record<string, T>, f: (v: T) => unknown) => Object.fromEntries(Object.entries(o).map(([k, v]) => [k, f(v)]));\n return {\n motion: {\n duration: grp(tokens.duration, (v) => ({ $type: 'duration', $value: `${v}ms` })),\n easing: grp(tokens.easing, (v) => {\n const m = /^cubic-bezier\\(([^)]+)\\)$/.exec(v);\n return m ? { $type: 'cubicBezier', $value: m[1].split(',').map(Number) } : { $type: 'string', $value: v };\n }),\n spring: grp(tokens.spring, (v) => ({ $type: 'spring', $value: { ...v } })),\n },\n };\n}\n\n/** Parse `150ms`, `0.15s`, `150` → ms. */\nexport function parseDuration(v: unknown): number | undefined {\n if (typeof v === 'number' && isFinite(v)) return v;\n if (typeof v === 'object' && v && 'value' in (v as any) && 'unit' in (v as any)) return parseDuration(`${(v as any).value}${(v as any).unit}`);\n const m = /^\\s*(-?\\d*\\.?\\d+)\\s*(ms|s)?\\s*$/.exec(String(v ?? ''));\n if (!m) return undefined;\n return m[2] === 's' ? Number(m[1]) * 1000 : Number(m[1]);\n}\n\n/** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */\nexport function parseEasing(v: unknown): string | undefined {\n if (Array.isArray(v) && v.length === 4 && v.every((n) => typeof n === 'number')) return `cubic-bezier(${v.join(', ')})`;\n if (typeof v !== 'string' || !v.trim()) return undefined;\n const s = v.trim();\n if (/^-?\\d*\\.?\\d+(\\s*,\\s*-?\\d*\\.?\\d+){3}$/.test(s)) return `cubic-bezier(${s.split(/\\s*,\\s*/).join(', ')})`;\n return s;\n}\n\nconst isLeaf = (o: any) => o && typeof o === 'object' && ('$value' in o || 'value' in o);\nconst leafValue = (o: any) => ('$value' in o ? o.$value : o.value);\nconst leafType = (o: any) => String(o.$type ?? o.type ?? '').toLowerCase();\n\n/**\n * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio\n * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything\n * under a `duration` / `easing` / `spring` group (any depth, e.g.\n * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves\n * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are\n * skipped; the result is merged over the defaults.\n */\nexport function importMotionTokens(json: unknown, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const partial: Required<DeepPartialTokens> = { duration: {}, easing: {}, spring: {} };\n const walk = (node: any, path: string[]) => {\n if (!node || typeof node !== 'object') return;\n if (isLeaf(node)) {\n const name = path[path.length - 1];\n const type = leafType(node);\n const group = path.slice(0, -1).map((p) => p.toLowerCase());\n const val = leafValue(node);\n const inGroup = (g: string[]) => group.some((p) => g.includes(p));\n if (type === 'duration' || (!type && inGroup(['duration', 'durations'])) || (type !== 'cubicbezier' && inGroup(['duration', 'durations']))) {\n const ms = parseDuration(val);\n if (ms !== undefined) partial.duration[name] = ms;\n } else if (type === 'cubicbezier' || type === 'easing' || inGroup(['easing', 'easings', 'ease'])) {\n const e = parseEasing(val);\n if (e) partial.easing[name] = e;\n } else if (type === 'spring' || inGroup(['spring', 'springs'])) {\n if (val && typeof val === 'object') partial.spring[name] = { stiffness: Number(val.stiffness ?? 170), damping: Number(val.damping ?? 26), mass: Number(val.mass ?? 1) };\n } else if (type === 'transition' && val && typeof val === 'object') {\n const ms = parseDuration(val.duration);\n if (ms !== undefined) partial.duration[name] = ms;\n const e = parseEasing(val.timingFunction);\n if (e) partial.easing[name] = e;\n }\n return;\n }\n for (const [k, v] of Object.entries(node)) if (!k.startsWith('$')) walk(v, [...path, k]);\n };\n walk(json, []);\n return mergeMotionTokens(partial, base);\n}\n\n/** The tokens currently applied (via `applyMotionTokens`), or the defaults. */\nexport function getMotionTokens(): MotionTokens {\n return clone(active);\n}\n\n/**\n * Write tokens as CSS custom properties on `root` (default `<html>`) and make\n * them the active set for `motionToken()`. Returns an undo function.\n */\nexport function applyMotionTokens(tokens: DeepPartialTokens | MotionTokens = MOTION_TOKENS, root?: HTMLElement, prefix = '--usa'): () => void {\n const prev = active;\n active = mergeMotionTokens(tokens as DeepPartialTokens, MOTION_TOKENS);\n const el = root || (typeof document !== 'undefined' ? document.documentElement : null);\n const vars = motionTokensToVars(active, prefix);\n const old: Record<string, string> = {};\n if (el) for (const [k, v] of Object.entries(vars)) ((old[k] = el.style.getPropertyValue(k)), el.style.setProperty(k, v));\n return () => {\n active = prev;\n if (el) for (const [k, v] of Object.entries(old)) v ? el.style.setProperty(k, v) : el.style.removeProperty(k);\n };\n}\n\n/** Look up a token: `motionToken('duration', 'fast')` → `150`; `motionToken('easing', 'emphasized')` → CSS easing. */\nexport function motionToken(group: 'duration', name: string): number;\nexport function motionToken(group: 'easing', name: string): string;\nexport function motionToken(group: 'spring', name: string): SpringToken;\nexport function motionToken(group: MotionTokenGroup, name: string): number | string | SpringToken | undefined {\n const g = active[group] as Record<string, any>;\n return g[name] ?? (MOTION_TOKENS[group] as Record<string, any>)[name];\n}\n\n/** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */\nexport function motionVar(group: MotionTokenGroup, name: string, prop?: 'stiffness' | 'damping' | 'mass', prefix = '--usa'): string {\n if (group === 'spring') {\n const s = motionToken('spring', name);\n const p = prop || 'stiffness';\n return `var(${prefix}-spring-${kebab(name)}-${p}, ${s ? s[p] : ''})`;\n }\n const v = group === 'duration' ? `${motionToken('duration', name)}ms` : motionToken('easing', name);\n return `var(${prefix}-${group}-${kebab(name)}, ${v})`;\n}\n\n/** Resolve a duration that may be a token name (`'fast'`) or ms. */\nexport function resolveDurationToken(v: number | string | undefined, fallback: number): number {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') return (active.duration[v] ?? parseDuration(v)) ?? fallback;\n return fallback;\n}\n\n/** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */\nexport function resolveEasingToken(v: string | undefined, fallback: string): string {\n if (!v) return fallback;\n return active.easing[v] ?? v;\n}\n","import { prefersReducedMotion, motionScale, applyFrame, raf, caf, now, clamp } from '../base';\nimport { resolveDurationToken, resolveEasingToken } from '../tokens/index';\n\n/**\n * Where a step starts on a timeline:\n * - a number: absolute time in ms\n * - `'>'` (default): when the previous step ends · `'<'`: when it starts\n * - `'+=200'` / `'-=200'`: after / overlapping the previous end\n * - `'<+=100'`: 100ms after the previous step's start\n * - `'intro'` / `'intro+=150'`: at (or relative to) a label\n */\nexport type TimelinePosition = number | string;\n\nexport interface TimelineStepOptions {\n /** Duration in ms or a motion token name (`'fast'`, `'slow'`…; 4.2). Default: timeline default, 600. */\n duration?: number | string;\n /** CSS easing or a motion token name (`'emphasized'`, `'spring'`…; 4.2). Default `cubic-bezier(0.22, 1, 0.36, 1)`. */\n easing?: string;\n /** Start position, see `TimelinePosition`. */\n at?: TimelinePosition;\n /** ms between targets when the selector matches several elements. */\n stagger?: number;\n}\n\nexport interface TimelineOptions {\n /** Defaults for every step. */\n defaults?: Pick<TimelineStepOptions, 'duration' | 'easing' | 'stagger'>;\n /** Playback rate (1 = normal). */\n speed?: number;\n /** Called after `play()` reaches the end (or the start when reversed). */\n onComplete?: () => void;\n /** Called on every frame with progress 0–1. */\n onUpdate?: (progress: number) => void;\n}\n\nexport interface ScrubOptions {\n /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts (JS engine only). */\n offset?: number;\n /** Smoothing 0–1 (0 = immediate, default 0). Smoothing needs the JS engine. */\n smooth?: number;\n /**\n * 4.1: which progress source drives the timeline.\n * - `'view'` (default): `source` moving through the viewport (CSS `ViewTimeline`, range `cover`).\n * - `'scroll'`: the scroll position of `source` itself (a scroll container; CSS `ScrollTimeline`).\n */\n source?: 'view' | 'scroll';\n /** 4.1: `'auto'` (default) uses the browser's native scroll-driven animations when available, `'js'` forces the fallback. */\n engine?: 'auto' | 'native' | 'js';\n /** 4.1: scroll axis, `'block'` (default) · `'inline'` · `'x'` · `'y'`. */\n axis?: 'block' | 'inline' | 'x' | 'y';\n}\n\n/** The function `scrub()` returns: call it to stop. `native` tells which engine runs it. */\nexport interface ScrubHandle {\n (): void;\n /** `true` when the browser's ScrollTimeline / ViewTimeline drives it (compositor, no JS per frame). */\n readonly native: boolean;\n}\n\n/** 4.1: whether `scrub()` can use native ScrollTimeline / ViewTimeline here. */\nexport function supportsNativeScrub(source: 'view' | 'scroll' = 'view'): boolean {\n const g = globalThis as any;\n return typeof g[source === 'scroll' ? 'ScrollTimeline' : 'ViewTimeline'] === 'function' && typeof g.Element?.prototype?.animate === 'function';\n}\n\nconst handle = (stop: () => void, native: boolean): ScrubHandle => Object.assign(stop, { native }) as ScrubHandle;\n\nexport interface Timeline {\n /** Total length in ms. */\n readonly duration: number;\n /** Label positions in ms. */\n readonly labels: Readonly<Record<string, number>>;\n /** Current playhead in ms. */\n readonly time: number;\n /** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */\n to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;\n /** Name a position (default: the current end). */\n label(name: string, at?: TimelinePosition): Timeline;\n /** Run `fn` when the playhead passes `at`. */\n call(fn: () => void, at?: TimelinePosition): Timeline;\n /** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */\n play(from?: TimelinePosition): Promise<void>;\n /** Play backwards to 0. */\n reverse(): Promise<void>;\n pause(): Timeline;\n /** Jump to a time (ms) or label. */\n seek(to: TimelinePosition): Timeline;\n /** Get or set progress 0–1. */\n progress(p?: number): number;\n /**\n * Tie progress to scroll: `source` moving through the viewport (or, with\n * `{ source: 'scroll' }`, a scroll container's own position). Runs on native\n * ScrollTimeline / ViewTimeline when available (and no `smooth`, `offset`,\n * `call()` cues or `onUpdate` need JS), else on a rAF-throttled listener.\n * Returns a stop function with a `native` flag.\n */\n scrub(source: Element, options?: ScrubOptions): ScrubHandle;\n /** Stop and drop every animation (elements keep their last frame). */\n cancel(): void;\n}\n\n/** Keyframe presets usable by name in `to()` and `data-tl`. */\nexport const TIMELINE_PRESETS: Record<string, Keyframe[]> = {\n fade: [{ opacity: 0 }, { opacity: 1 }],\n 'fade-up': [{ opacity: 0, transform: 'translateY(24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-down': [{ opacity: 0, transform: 'translateY(-24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-left': [{ opacity: 0, transform: 'translateX(24px)' }, { opacity: 1, transform: 'none' }],\n 'fade-right': [{ opacity: 0, transform: 'translateX(-24px)' }, { opacity: 1, transform: 'none' }],\n scale: [{ opacity: 0, transform: 'scale(0.85)' }, { opacity: 1, transform: 'none' }],\n blur: [{ opacity: 0, filter: 'blur(12px)' }, { opacity: 1, filter: 'blur(0)' }],\n rotate: [{ opacity: 0, transform: 'rotate(-12deg) scale(0.9)' }, { opacity: 1, transform: 'none' }],\n 'clip-up': [{ clipPath: 'inset(100% 0 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],\n 'clip-right': [{ clipPath: 'inset(0 100% 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],\n};\n\n/** Resolve a position against the previous step and labels (pure). */\nexport function resolvePosition(\n pos: TimelinePosition | undefined,\n end: number,\n prevStart: number,\n labels: Record<string, number> = {}\n): number {\n if (pos === undefined || pos === '' || pos === '>') return end;\n if (typeof pos === 'number') return Math.max(0, pos);\n const s = String(pos).trim();\n if (/^-?\\d+(\\.\\d+)?$/.test(s)) return Math.max(0, Number(s));\n const m = /^(<|>|[A-Za-z_][\\w-]*)?\\s*(?:([+-])=\\s*(\\d+(?:\\.\\d+)?))?$/.exec(s);\n if (!m) return end;\n const base = m[1] === '<' ? prevStart : m[1] === '>' || !m[1] ? end : labels[m[1]] ?? end;\n const delta = m[2] ? (m[2] === '-' ? -1 : 1) * Number(m[3]) : 0;\n return Math.max(0, base + delta);\n}\n\nconst toEls = (t: string | Element | Element[] | NodeList): Element[] =>\n typeof t === 'string' ? (typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(t))) : t instanceof Element ? [t] : Array.from(t as ArrayLike<Element>);\n\ninterface Step { el: Element; frames: Keyframe[]; start: number; duration: number; easing: string; anim?: Animation | null }\ninterface Cue { fn: () => void; at: number }\n\n/**\n * Choreograph animations on one clock: chain, overlap, label, seek, reverse and\n * scrub them with scroll. Built on WAAPI (paused animations driven by one\n * playhead); without WAAPI or under reduced motion it jumps to the end state.\n *\n * @example\n * const tl = timeline({ defaults: { duration: 500 } })\n * .to('.title', 'fade-up')\n * .label('cards')\n * .to('.card', 'scale', { stagger: 80, at: '-=200' })\n * .to('.cta', [{ opacity: 0 }, { opacity: 1 }], { at: 'cards+=400' });\n * tl.play(); // or tl.scrub(document.querySelector('.hero'))\n */\nexport function timeline(options: TimelineOptions = {}): Timeline {\n const d = { duration: 600, easing: 'cubic-bezier(0.22, 1, 0.36, 1)', stagger: 0, ...options.defaults };\n const steps: Step[] = [];\n const cues: Cue[] = [];\n const labels: Record<string, number> = {};\n let end = 0;\n let prevStart = 0;\n let t = 0;\n let frame = 0;\n let dir = 1;\n let settle: (() => void) | undefined;\n let built = false;\n\n const total = () => Math.max(end, ...cues.map((c) => c.at), 0);\n const build = () => {\n if (built) return;\n built = true;\n for (const s of steps) {\n if (typeof (s.el as HTMLElement).animate !== 'function') { s.anim = null; continue; }\n s.anim = (s.el as HTMLElement).animate(s.frames, { duration: s.duration, delay: s.start, easing: s.easing, fill: 'both' });\n s.anim.pause?.();\n }\n };\n const render = (to: number, from: number) => {\n build();\n t = clamp(to, 0, total());\n for (const s of steps) {\n if (s.anim) s.anim.currentTime = t;\n else applyFrame(s.el as HTMLElement, s.frames[t >= s.start ? s.frames.length - 1 : 0]);\n }\n for (const c of cues) if ((from < c.at && t >= c.at) || (from > c.at && t <= c.at)) c.fn();\n options.onUpdate?.(total() ? t / total() : 1);\n };\n const stop = () => {\n if (frame) caf(frame);\n frame = 0;\n };\n const run = (direction: number): Promise<void> => {\n stop();\n settle?.();\n dir = direction;\n const target = dir > 0 ? total() : 0;\n const k = motionScale();\n if (prefersReducedMotion() || k === 0 || !total()) {\n render(target, t);\n options.onComplete?.();\n return Promise.resolve();\n }\n const rate = (options.speed ?? 1) / k;\n return new Promise<void>((resolve) => {\n settle = () => { settle = undefined; resolve(); };\n let last = now();\n const loop = () => {\n const n = now();\n const next = t + (n - last) * rate * dir;\n last = n;\n render(next, t);\n if ((dir > 0 && t >= target) || (dir < 0 && t <= 0)) {\n frame = 0;\n options.onComplete?.();\n settle?.();\n return;\n }\n frame = raf(loop);\n };\n frame = raf(loop);\n });\n };\n\n const api: Timeline = {\n get duration() { return total(); },\n get labels() { return { ...labels }; },\n get time() { return t; },\n to(target, frames, o = {}) {\n const kf = typeof frames === 'string' ? TIMELINE_PRESETS[frames] || TIMELINE_PRESETS.fade : frames;\n const start = resolvePosition(o.at, end, prevStart, labels);\n const duration = resolveDurationToken(o.duration ?? d.duration, 600);\n const stagger = o.stagger ?? d.stagger;\n let last = start;\n toEls(target).forEach((el, i) => {\n const s = start + i * stagger;\n steps.push({ el, frames: kf, start: s, duration, easing: resolveEasingToken(o.easing ?? d.easing, 'cubic-bezier(0.22, 1, 0.36, 1)') });\n last = Math.max(last, s + duration);\n });\n prevStart = start;\n end = Math.max(end, last);\n built = false;\n steps.forEach((s) => s.anim?.cancel?.());\n return api;\n },\n label(name, at) {\n labels[name] = resolvePosition(at, end, prevStart, labels);\n return api;\n },\n call(fn, at) {\n cues.push({ fn, at: resolvePosition(at, end, prevStart, labels) });\n return api;\n },\n play(from) {\n if (from !== undefined) render(resolvePosition(from, 0, 0, labels), t);\n else if (t >= total()) render(0, -1);\n return run(1);\n },\n reverse() {\n return run(-1);\n },\n pause() {\n stop();\n return api;\n },\n seek(to) {\n stop();\n render(resolvePosition(to, 0, 0, labels), t);\n return api;\n },\n progress(p) {\n if (p !== undefined) api.seek(clamp(p, 0, 1) * total());\n return total() ? t / total() : 0;\n },\n scrub(source, o = {}) {\n stop();\n if (prefersReducedMotion() || typeof window === 'undefined') {\n render(total(), t);\n return handle(() => {}, false);\n }\n const mode = o.source ?? 'view';\n const axis = o.axis ?? 'block';\n const needsJs = !!o.smooth || !!o.offset || cues.length > 0 || !!options.onUpdate || o.engine === 'js';\n if (!needsJs && total() > 0 && supportsNativeScrub(mode) && steps.every((st) => typeof (st.el as HTMLElement).animate === 'function')) {\n // Native: one scroll-driven animation per step, its slice of the\n // timeline mapped onto the scroll range (`cover` for a view timeline).\n const g = globalThis as any;\n const tl = mode === 'scroll' ? new g.ScrollTimeline({ source, axis }) : new g.ViewTimeline({ subject: source, axis });\n const T = total();\n steps.forEach((st) => st.anim?.cancel?.());\n built = false;\n const pct = (ms: number) => `${((ms / T) * 100).toFixed(3)}%`;\n const live = steps.map((st) => {\n const range = mode === 'view' ? { rangeStart: `cover ${pct(st.start)}`, rangeEnd: `cover ${pct(st.start + st.duration)}` } : {};\n const timing: any = { easing: st.easing, fill: 'both', timeline: tl, ...range };\n if (mode === 'scroll') Object.assign(timing, { duration: 'auto', rangeStart: pct(st.start), rangeEnd: pct(st.start + st.duration) });\n return (st.el as HTMLElement).animate(st.frames, timing);\n });\n return handle(() => {\n live.forEach((a) => a.cancel());\n render(t, t);\n }, true);\n }\n let id = 0;\n let cur = t;\n const scroller = mode === 'scroll' ? (source as HTMLElement) : null;\n const progressNow = () => {\n const x = axis === 'x' || axis === 'inline';\n if (scroller) {\n const max = x ? scroller.scrollWidth - scroller.clientWidth : scroller.scrollHeight - scroller.clientHeight;\n return clamp((x ? scroller.scrollLeft : scroller.scrollTop) / (max || 1), 0, 1);\n }\n const r = source.getBoundingClientRect();\n const vh = (x ? window.innerWidth : window.innerHeight) || 1;\n const start = x ? r.left : r.top;\n const size = x ? r.width : r.height;\n return clamp((vh + (o.offset ?? 0) - start) / (vh + size || 1), 0, 1);\n };\n const update = () => {\n id = 0;\n const goal = progressNow() * total();\n const sm = clamp(o.smooth ?? 0, 0, 0.95);\n cur = sm ? cur + (goal - cur) * (1 - sm) : goal;\n render(cur, t);\n if (sm && Math.abs(goal - cur) > 0.5) id = raf(update);\n };\n const onScroll = () => { if (!id) id = raf(update); };\n const target: EventTarget = scroller || window;\n target.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onScroll, { passive: true });\n update();\n return handle(() => {\n target.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onScroll);\n if (id) caf(id);\n }, false);\n },\n cancel() {\n stop();\n settle?.();\n steps.forEach((s) => s.anim?.cancel?.());\n built = false;\n },\n };\n return api;\n}\n","/**\n * motionary - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * motionary\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `motionary/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/Motionary\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { timeline, resolvePosition, TIMELINE_PRESETS, supportsNativeScrub } from './components/timeline/core';\nexport { parallax } from './parallax';\nexport { PRESETS, registerPresets, reversePreset, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n CorePreset,\n ExtendedPreset,\n PresetKeyframes,\n AnimationFrame,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions, ScrubHandle } from './components/timeline/core';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'motionary';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":["PRESETS","core","g","globalThis","key","Symbol","for","Object","assign","share","from","opacity","to","transform","bounce","filter","shimmer","pulse","swing","clipPath","reversePreset","p","frames","map","f","offset","reverse","lookup","name","trim","resolvePreset","animation","Array","isArray","combined","forEach","preset","entries","val","EASING_MAP","linear","ease","spring","resolveEasing","easing","join","DEFAULT_CONFIG","defaultAnimation","defaultDuration","defaultDelay","defaultEasing","defaultThreshold","defaultRootMargin","defaultRepeat","defaultOnce","defaultOffset","hiddenClass","visibleClass","useClassNames","disabled","root","autoUnregister","defaultEngine","noop","hasDOM","window","document","supportsObserver","IntersectionObserver","reducedMotionQuery","scrollTimelineSupported","prefersReducedMotion","undefined","matchMedia","matches","supportsScrollTimeline","CSS","supports","ViewTimeline","num","value","n","parseFloat","Number","isFinite","DEFAULT_VIEW_RANGE","normalizeVar","v","startsWith","parseDataAttributes","el","config","mergeOptions","get","opts","anim","includes","split","s","duration","delay","e","JSON","parse","t","threshold","rootMargin","repeat","once","stagger","progressVar","engine","range","start","end","viewRange","exit","progress","progressMode","keys","k","readOptions","getAttribute","length","onStart","onComplete","onEnter","onLeave","onProgress","resolveTargets","target","querySelectorAll","Element","NodeList","getScrollProgress","rect","getBoundingClientRect","top","height","innerHeight","documentElement","clientHeight","r","total","running","WeakMap","exits","timers","cancelRunning","exitAnim","delete","cancel","onfinish","timer","clearTimeout","setStyles","styles","style","prop","String","NUM_UNIT","linearSupported","progressThresholds","supportsLinearEasing","buildAnimation","list","keyframes","samples","fn","values","i","push","toFixed","sampleEasing","props","eased","frame","a","b","ta","tb","skA","replace","_","u","ok","out","na","ua","nb","ub","unit","interpolateValue","reveal","classList","remove","add","motionDisabled","runAnimation","staggerIndex","pending","totalDelay","Math","max","animationDelay","set","setTimeout","animate","built","timing","fill","commitStyles","hideElement","prepareElement","full","getProgressThresholds","PASSIVE","passive","createScrollAnimate","userConfig","registry","Map","finished","WeakSet","scrolling","Set","listening","watchers","natives","pools","pooled","create","pool","io","teardown","restore","record","observer","unobserve","progressObserver","untrack","animated","isConnected","pruneDetached","emitProgress","options","setProperty","update","schedule","requestAnimationFrame","listen","on","method","cancelAnimationFrame","size","onScrollIntersect","entry","isIntersecting","onIntersect","staggerCounts","parent","parentElement","runExit","intersectionRatio","getObserver","parts","right","bottom","left","m","exec","applyOffset","attach","observeMain","observe","getProgressObserver","observeElement","has","element","wantsNative","onFrozen","timeline","subject","axis","rangeStart","rangeEnd","keep","startNative","observeDataElement","instance","init","rootElement","scope","watch","MutationObserver","observeTree","node","hasAttribute","mo","records","removed","type","addedNodes","removedNodes","childList","subtree","attributes","attributeFilter","disconnect","destroy","clear","refresh","getObservedElements","configure","newConfig","fallback","MOTION_SCALE","low","normal","high","applyFrame","frameQueue","frameSeq","frameHandle","frameVia","frameStats","callbacks","peak","last","frameListeners","flushFrame","dt","cbs","error","cb","clockState","paused","cdt","rate","time","requestFlush","native","now","raf","id","performance","Date","caf","CLOCK_KEY","_a","anims","subs","clamp","min","active","instant","fast","slow","slower","slowest","standard","emphasized","decelerate","accelerate","gentle","stiffness","damping","mass","snappy","bouncy","wobbly","stiff","fromEntries","parseDuration","resolveDurationToken","resolveEasingToken","supportsNativeScrub","source","prototype","handle","stop","TIMELINE_PRESETS","fade","scale","blur","rotate","resolvePosition","pos","prevStart","labels","test","base","delta","ScrollAnimate","els","speed","respectReducedMotion","visible","scroller","apply","removeProperty","presets","container","sa","observeChildren","rest","items","children","revealed","late","child","some","parentNode","indexOf","splice","stopAnimation","d","defaults","steps","cues","settle","dir","c","at","render","pause","build","currentTime","onUpdate","run","direction","Promise","resolve","loop","next","api","o","kf","toEls","label","call","play","seek","scrub","mode","smooth","every","st","tl","ScrollTimeline","T","pct","ms","live","cur","goal","x","scrollWidth","clientWidth","scrollHeight","scrollLeft","scrollTop","vh","innerWidth","width","progressNow","sm","abs","onScroll","addEventListener","removeEventListener"],"mappings":"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"}