@enact-ui/animate 0.1.0 → 0.2.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 (82) hide show
  1. package/api-schema.json +206 -0
  2. package/dist/components/CountUp.d.ts +84 -0
  3. package/dist/components/CountUp.d.ts.map +1 -0
  4. package/dist/components/CountUp.js +68 -0
  5. package/dist/components/CountUp.js.map +1 -0
  6. package/dist/components/MotionDiv.d.ts +159 -0
  7. package/dist/components/MotionDiv.d.ts.map +1 -0
  8. package/dist/components/MotionDiv.js +162 -0
  9. package/dist/components/MotionDiv.js.map +1 -0
  10. package/dist/components/StaggerContainer.d.ts +136 -0
  11. package/dist/components/StaggerContainer.d.ts.map +1 -0
  12. package/dist/components/StaggerContainer.js +166 -0
  13. package/dist/components/StaggerContainer.js.map +1 -0
  14. package/dist/hooks/use-component-animation.d.ts +156 -0
  15. package/dist/hooks/use-component-animation.d.ts.map +1 -0
  16. package/dist/hooks/use-component-animation.js +231 -0
  17. package/dist/hooks/use-component-animation.js.map +1 -0
  18. package/dist/hooks/use-count-up.d.ts +111 -0
  19. package/dist/hooks/use-count-up.d.ts.map +1 -0
  20. package/dist/hooks/use-count-up.js +246 -0
  21. package/dist/hooks/use-count-up.js.map +1 -0
  22. package/dist/hooks/use-draw-path.d.ts +96 -0
  23. package/dist/hooks/use-draw-path.d.ts.map +1 -0
  24. package/dist/hooks/use-draw-path.js +227 -0
  25. package/dist/hooks/use-draw-path.js.map +1 -0
  26. package/dist/hooks/use-motion-preset.d.ts.map +1 -1
  27. package/dist/hooks/use-motion-preset.js +17 -16
  28. package/dist/hooks/use-motion-preset.js.map +1 -1
  29. package/dist/hooks/use-stagger.d.ts +174 -0
  30. package/dist/hooks/use-stagger.d.ts.map +1 -0
  31. package/dist/hooks/use-stagger.js +256 -0
  32. package/dist/hooks/use-stagger.js.map +1 -0
  33. package/dist/index.d.ts +17 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2442 -26
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +2335 -25
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/presets/component-presets.d.ts +246 -0
  40. package/dist/presets/component-presets.d.ts.map +1 -0
  41. package/dist/presets/component-presets.js +472 -0
  42. package/dist/presets/component-presets.js.map +1 -0
  43. package/dist/presets/micro-interactions.d.ts +451 -0
  44. package/dist/presets/micro-interactions.d.ts.map +1 -0
  45. package/dist/presets/micro-interactions.js +856 -0
  46. package/dist/presets/micro-interactions.js.map +1 -0
  47. package/dist/presets/motion-presets.d.ts.map +1 -1
  48. package/dist/presets/motion-presets.js +0 -1
  49. package/dist/presets/motion-presets.js.map +1 -1
  50. package/dist/presets/motion-styles.d.ts +186 -0
  51. package/dist/presets/motion-styles.d.ts.map +1 -0
  52. package/dist/presets/motion-styles.js +204 -0
  53. package/dist/presets/motion-styles.js.map +1 -0
  54. package/dist/presets/stagger-presets.d.ts +378 -0
  55. package/dist/presets/stagger-presets.d.ts.map +1 -0
  56. package/dist/presets/stagger-presets.js +582 -0
  57. package/dist/presets/stagger-presets.js.map +1 -0
  58. package/dist/showcase/motion-presets.demo.d.ts +25 -0
  59. package/dist/showcase/motion-presets.demo.d.ts.map +1 -0
  60. package/dist/showcase/motion-presets.demo.js +96 -0
  61. package/dist/showcase/motion-presets.demo.js.map +1 -0
  62. package/dist/showcase/motion-presets.story.d.ts +37 -0
  63. package/dist/showcase/motion-presets.story.d.ts.map +1 -0
  64. package/dist/showcase/motion-presets.story.js +151 -0
  65. package/dist/showcase/motion-presets.story.js.map +1 -0
  66. package/dist/utils/easing.d.ts +294 -0
  67. package/dist/utils/easing.d.ts.map +1 -0
  68. package/dist/utils/easing.js +265 -0
  69. package/dist/utils/easing.js.map +1 -0
  70. package/dist/utils/reduced-motion.d.ts +322 -0
  71. package/dist/utils/reduced-motion.d.ts.map +1 -0
  72. package/dist/utils/reduced-motion.js +362 -0
  73. package/dist/utils/reduced-motion.js.map +1 -0
  74. package/dist/utils/select-preset.d.ts +186 -0
  75. package/dist/utils/select-preset.d.ts.map +1 -0
  76. package/dist/utils/select-preset.js +320 -0
  77. package/dist/utils/select-preset.js.map +1 -0
  78. package/dist/utils/spring-configs.d.ts +187 -0
  79. package/dist/utils/spring-configs.d.ts.map +1 -0
  80. package/dist/utils/spring-configs.js +169 -0
  81. package/dist/utils/spring-configs.js.map +1 -0
  82. package/package.json +4 -3
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hooks/use-motion-preset.ts","../src/presets/motion-presets.ts"],"sourcesContent":["// Copyright (c) 2025 Amsterdam Data Labs\n// @enact-ui/animate - Animation utilities and motion presets\n\n/**\n * @enact-ui/animate\n *\n * Animation utilities and motion presets for ENACT UI.\n * Only install if you need animation capabilities.\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// Hooks\n// =============================================================================\nexport {\n type ComputedPathsMotion,\n type ComputedRaysMotion,\n useMotionPreset,\n} from \"./hooks/use-motion-preset\";\n\n// =============================================================================\n// Motion Presets\n// =============================================================================\nexport {\n type AmbientPathsConfig,\n // Preset configurations\n ambientPaths,\n applyMotionPreset,\n type ComponentType,\n // Utility functions\n getPreset,\n type LightRaysConfig,\n lightRays,\n // Types\n type MotionPreset,\n type PresetConfig,\n} from \"./presets/motion-presets\";\n","// Copyright (c) 2025 Amsterdam Data Labs\n\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { type AmbientPathsConfig, type ComponentType, getPreset, type LightRaysConfig, type MotionPreset } from \"../presets/motion-presets\";\n\n/** CSS motion variables read from the theme */\ninterface MotionCSSVariables {\n /** Speed/duration multiplier (0 = no motion, 1 = normal) */\n durationMultiplier: number;\n /** Minimum opacity for motion animations */\n opacityMin: number;\n /** Maximum opacity for motion animations */\n opacityMax: number;\n}\n\n/** Computed motion configuration for paths component */\nexport interface ComputedPathsMotion {\n /** Computed base duration (preset * CSS multiplier) */\n baseDuration: number;\n /** Computed opacity keyframes respecting CSS bounds */\n opacity: [number, number, number];\n /** Easing function from preset */\n ease: \"linear\" | \"easeInOut\";\n /** Delay variation factor from preset */\n delayVariation: number;\n /** Duration variation factor from preset */\n durationVariation: number;\n /** Whether reduced motion is preferred */\n prefersReducedMotion: boolean;\n}\n\n/** Computed motion configuration for rays component */\nexport interface ComputedRaysMotion {\n /** Computed cycle duration (preset speed * CSS multiplier) */\n cycleDuration: number;\n /** Base intensity from preset */\n intensity: number;\n /** Swing variation from preset */\n swingVariation: number;\n /** Whether reduced motion is preferred */\n prefersReducedMotion: boolean;\n}\n\n/** Default CSS variable values (fallback if not in browser) */\nconst DEFAULT_CSS_VARS: MotionCSSVariables = {\n durationMultiplier: 1,\n opacityMin: 0.35,\n opacityMax: 0.6,\n};\n\n/**\n * Reads motion CSS variables from the document root.\n * Returns default values if not in browser environment.\n */\nfunction readCSSVariables(): MotionCSSVariables {\n if (typeof window === \"undefined\") {\n return DEFAULT_CSS_VARS;\n }\n\n const root = document.documentElement;\n const styles = getComputedStyle(root);\n\n const parseFloat_ = (value: string, fallback: number): number => {\n const parsed = parseFloat(value);\n return Number.isNaN(parsed) ? fallback : parsed;\n };\n\n return {\n durationMultiplier: parseFloat_(styles.getPropertyValue(\"--motion-duration-multiplier\"), DEFAULT_CSS_VARS.durationMultiplier),\n opacityMin: parseFloat_(styles.getPropertyValue(\"--motion-opacity-min\"), DEFAULT_CSS_VARS.opacityMin),\n opacityMax: parseFloat_(styles.getPropertyValue(\"--motion-opacity-max\"), DEFAULT_CSS_VARS.opacityMax),\n };\n}\n\n/**\n * Computes paths motion configuration from preset and CSS variables.\n */\nfunction computePathsMotion(preset: AmbientPathsConfig, cssVars: MotionCSSVariables, prefersReducedMotion: boolean): ComputedPathsMotion {\n if (prefersReducedMotion) {\n return {\n baseDuration: 0,\n opacity: [cssVars.opacityMin, cssVars.opacityMin, cssVars.opacityMin],\n ease: preset.ease,\n delayVariation: 0,\n durationVariation: 0,\n prefersReducedMotion: true,\n };\n }\n\n return {\n baseDuration: preset.duration * cssVars.durationMultiplier,\n opacity: [\n Math.max(preset.opacity[0], cssVars.opacityMin),\n Math.min(preset.opacity[1], cssVars.opacityMax),\n Math.max(preset.opacity[2], cssVars.opacityMin),\n ],\n ease: preset.ease,\n delayVariation: preset.delayVariation,\n durationVariation: preset.durationVariation,\n prefersReducedMotion: false,\n };\n}\n\n/**\n * Computes rays motion configuration from preset and CSS variables.\n */\nfunction computeRaysMotion(preset: LightRaysConfig, cssVars: MotionCSSVariables, prefersReducedMotion: boolean): ComputedRaysMotion {\n if (prefersReducedMotion) {\n return {\n cycleDuration: 0,\n intensity: 0,\n swingVariation: 0,\n prefersReducedMotion: true,\n };\n }\n\n return {\n cycleDuration: Math.max(preset.speed * cssVars.durationMultiplier, 0.1),\n intensity: preset.intensity,\n swingVariation: preset.swingVariation,\n prefersReducedMotion: false,\n };\n}\n\n/**\n * Hook for using motion presets with theme-aware CSS variables.\n *\n * Provides computed motion configuration that:\n * - Respects `prefers-reduced-motion` preference\n * - Reads and applies CSS motion variables from the theme\n * - Memoizes calculations to prevent unnecessary re-renders\n *\n * @param component - The component type (\"paths\" | \"rays\")\n * @param preset - The motion preset (\"slow\" | \"medium\" | \"fast\")\n * @returns Computed motion configuration for the component\n *\n * @example\n * ```tsx\n * // In BackgroundPaths component\n * const motion = useMotionPreset(\"paths\", \"medium\");\n * // Returns: { baseDuration: 20, opacity: [...], ... }\n *\n * // In LightRays component\n * const motion = useMotionPreset(\"rays\", \"fast\");\n * // Returns: { cycleDuration: 8, intensity: 0.7, ... }\n * ```\n */\nexport function useMotionPreset(component: \"paths\", preset: MotionPreset): ComputedPathsMotion;\nexport function useMotionPreset(component: \"rays\", preset: MotionPreset): ComputedRaysMotion;\nexport function useMotionPreset(component: ComponentType, preset: MotionPreset): ComputedPathsMotion | ComputedRaysMotion {\n // Track reduced motion preference with state for reactivity\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n // Track CSS variables (may change with theme)\n const [cssVars, setCssVars] = useState<MotionCSSVariables>(DEFAULT_CSS_VARS);\n\n // Listen for reduced motion preference changes\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => setPrefersReducedMotion(e.matches);\n mediaQuery.addEventListener(\"change\", handler);\n return () => mediaQuery.removeEventListener(\"change\", handler);\n }, []);\n\n // Read CSS variables on mount and when theme might change\n useEffect(() => {\n setCssVars(readCSSVariables());\n\n // Listen for theme changes via attribute mutations on document\n const observer = new MutationObserver(() => {\n setCssVars(readCSSVariables());\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\"],\n });\n\n return () => observer.disconnect();\n }, []);\n\n // Compute and memoize the motion configuration\n return useMemo(() => {\n if (component === \"paths\") {\n const presetConfig = getPreset(preset, \"paths\");\n return computePathsMotion(presetConfig, cssVars, prefersReducedMotion);\n }\n const presetConfig = getPreset(preset, \"rays\");\n return computeRaysMotion(presetConfig, cssVars, prefersReducedMotion);\n }, [component, preset, cssVars, prefersReducedMotion]);\n}\n","// Copyright (c) 2025 Amsterdam Data Labs\n/**\n * Motion Presets Utility\n *\n * Defines motion preset configurations for ambient animation components.\n * These presets provide consistent, theme-aware motion settings.\n */\n\n/** Available motion speed presets */\nexport type MotionPreset = \"slow\" | \"medium\" | \"fast\";\n\n/** Component types that support motion presets */\nexport type ComponentType = \"paths\" | \"rays\";\n\n/** Configuration for ambient paths animations */\nexport interface AmbientPathsConfig {\n /** Base duration in seconds */\n duration: number;\n /** Opacity keyframes [start, peak, end] */\n opacity: [number, number, number];\n /** Easing function */\n ease: \"linear\" | \"easeInOut\";\n /** Random delay variation factor (0-1) */\n delayVariation: number;\n /** Random duration variation factor (0-1) */\n durationVariation: number;\n}\n\n/** Configuration for light rays animations */\nexport interface LightRaysConfig {\n /** Base speed/cycle duration in seconds */\n speed: number;\n /** Base intensity multiplier (0-1) */\n intensity: number;\n /** Swing angle variation factor */\n swingVariation: number;\n}\n\n/** Union type for all preset configurations */\nexport type PresetConfig = AmbientPathsConfig | LightRaysConfig;\n\n/**\n * Preset configurations for BackgroundPaths component.\n * Each preset defines duration, opacity, and variation settings.\n */\nexport const ambientPaths: Record<MotionPreset, AmbientPathsConfig> = {\n slow: {\n duration: 30,\n opacity: [0.2, 0.4, 0.2],\n ease: \"easeInOut\",\n delayVariation: 0.3,\n durationVariation: 0.5,\n },\n medium: {\n duration: 20,\n opacity: [0.3, 0.6, 0.3],\n ease: \"easeInOut\",\n delayVariation: 0.25,\n durationVariation: 0.5,\n },\n fast: {\n duration: 12,\n opacity: [0.4, 0.8, 0.4],\n ease: \"linear\",\n delayVariation: 0.2,\n durationVariation: 0.4,\n },\n};\n\n/**\n * Preset configurations for LightRays component.\n * Each preset defines speed, intensity, and swing settings.\n */\nexport const lightRays: Record<MotionPreset, LightRaysConfig> = {\n slow: {\n speed: 20,\n intensity: 0.3,\n swingVariation: 1.8,\n },\n medium: {\n speed: 14,\n intensity: 0.5,\n swingVariation: 1.5,\n },\n fast: {\n speed: 8,\n intensity: 0.7,\n swingVariation: 1.2,\n },\n};\n\n/**\n * Retrieves a preset configuration for a specific component type.\n *\n * @param preset - The motion preset name (\"slow\" | \"medium\" | \"fast\")\n * @param component - The component type (\"paths\" | \"rays\")\n * @returns The preset configuration for the specified component\n *\n * @example\n * ```ts\n * const pathsPreset = getPreset(\"medium\", \"paths\");\n * // Returns: { duration: 20, opacity: [0.3, 0.6, 0.3], ... }\n *\n * const raysPreset = getPreset(\"fast\", \"rays\");\n * // Returns: { speed: 8, intensity: 0.7, swingVariation: 1.2 }\n * ```\n */\nexport function getPreset(preset: MotionPreset, component: \"paths\"): AmbientPathsConfig;\nexport function getPreset(preset: MotionPreset, component: \"rays\"): LightRaysConfig;\nexport function getPreset(preset: MotionPreset, component: ComponentType): PresetConfig {\n if (component === \"paths\") {\n return ambientPaths[preset];\n }\n return lightRays[preset];\n}\n\n/**\n * Merges a preset configuration with a base configuration.\n * Useful for combining preset values with component-specific overrides.\n *\n * @param preset - The preset configuration to apply\n * @param baseConfig - The base configuration to merge with\n * @returns Merged configuration with preset values taking precedence\n *\n * @example\n * ```ts\n * const preset = getPreset(\"medium\", \"paths\");\n * const result = applyMotionPreset(preset, { count: 36 });\n * // Returns: { duration: 20, opacity: [...], count: 36, ... }\n * ```\n */\nexport function applyMotionPreset<T extends Record<string, unknown>>(preset: PresetConfig, baseConfig: T): PresetConfig & T {\n return { ...baseConfig, ...preset };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,mBAA6C;;;AC0CtC,IAAM,eAAyD;AAAA,EAClE,MAAM;AAAA,IACF,UAAU;AAAA,IACV,SAAS,CAAC,KAAK,KAAK,GAAG;AAAA,IACvB,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACvB;AAAA,EACA,QAAQ;AAAA,IACJ,UAAU;AAAA,IACV,SAAS,CAAC,KAAK,KAAK,GAAG;AAAA,IACvB,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACvB;AAAA,EACA,MAAM;AAAA,IACF,UAAU;AAAA,IACV,SAAS,CAAC,KAAK,KAAK,GAAG;AAAA,IACvB,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACvB;AACJ;AAMO,IAAM,YAAmD;AAAA,EAC5D,MAAM;AAAA,IACF,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,EACpB;AAAA,EACA,QAAQ;AAAA,IACJ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,EACpB;AAAA,EACA,MAAM;AAAA,IACF,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,EACpB;AACJ;AAoBO,SAAS,UAAU,QAAsB,WAAwC;AACpF,MAAI,cAAc,SAAS;AACvB,WAAO,aAAa,MAAM;AAAA,EAC9B;AACA,SAAO,UAAU,MAAM;AAC3B;AAiBO,SAAS,kBAAqD,QAAsB,YAAiC;AACxH,SAAO,EAAE,GAAG,YAAY,GAAG,OAAO;AACtC;;;ADxFA,IAAM,mBAAuC;AAAA,EACzC,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,YAAY;AAChB;AAMA,SAAS,mBAAuC;AAC5C,MAAI,OAAO,WAAW,aAAa;AAC/B,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,SAAS;AACtB,QAAM,SAAS,iBAAiB,IAAI;AAEpC,QAAM,cAAc,CAAC,OAAe,aAA6B;AAC7D,UAAM,SAAS,WAAW,KAAK;AAC/B,WAAO,OAAO,MAAM,MAAM,IAAI,WAAW;AAAA,EAC7C;AAEA,SAAO;AAAA,IACH,oBAAoB,YAAY,OAAO,iBAAiB,8BAA8B,GAAG,iBAAiB,kBAAkB;AAAA,IAC5H,YAAY,YAAY,OAAO,iBAAiB,sBAAsB,GAAG,iBAAiB,UAAU;AAAA,IACpG,YAAY,YAAY,OAAO,iBAAiB,sBAAsB,GAAG,iBAAiB,UAAU;AAAA,EACxG;AACJ;AAKA,SAAS,mBAAmB,QAA4B,SAA6B,sBAAoD;AACrI,MAAI,sBAAsB;AACtB,WAAO;AAAA,MACH,cAAc;AAAA,MACd,SAAS,CAAC,QAAQ,YAAY,QAAQ,YAAY,QAAQ,UAAU;AAAA,MACpE,MAAM,OAAO;AAAA,MACb,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,sBAAsB;AAAA,IAC1B;AAAA,EACJ;AAEA,SAAO;AAAA,IACH,cAAc,OAAO,WAAW,QAAQ;AAAA,IACxC,SAAS;AAAA,MACL,KAAK,IAAI,OAAO,QAAQ,CAAC,GAAG,QAAQ,UAAU;AAAA,MAC9C,KAAK,IAAI,OAAO,QAAQ,CAAC,GAAG,QAAQ,UAAU;AAAA,MAC9C,KAAK,IAAI,OAAO,QAAQ,CAAC,GAAG,QAAQ,UAAU;AAAA,IAClD;AAAA,IACA,MAAM,OAAO;AAAA,IACb,gBAAgB,OAAO;AAAA,IACvB,mBAAmB,OAAO;AAAA,IAC1B,sBAAsB;AAAA,EAC1B;AACJ;AAKA,SAAS,kBAAkB,QAAyB,SAA6B,sBAAmD;AAChI,MAAI,sBAAsB;AACtB,WAAO;AAAA,MACH,eAAe;AAAA,MACf,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,sBAAsB;AAAA,IAC1B;AAAA,EACJ;AAEA,SAAO;AAAA,IACH,eAAe,KAAK,IAAI,OAAO,QAAQ,QAAQ,oBAAoB,GAAG;AAAA,IACtE,WAAW,OAAO;AAAA,IAClB,gBAAgB,OAAO;AAAA,IACvB,sBAAsB;AAAA,EAC1B;AACJ;AA2BO,SAAS,gBAAgB,WAA0B,QAAgE;AAEtH,QAAM,CAAC,sBAAsB,uBAAuB,QAAI,uBAAS,MAAM;AACnE,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,OAAO,WAAW,kCAAkC,EAAE;AAAA,EACjE,CAAC;AAGD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAA6B,gBAAgB;AAG3E,8BAAU,MAAM;AACZ,UAAM,aAAa,OAAO,WAAW,kCAAkC;AACvE,4BAAwB,WAAW,OAAO;AAE1C,UAAM,UAAU,CAAC,MAA2B,wBAAwB,EAAE,OAAO;AAC7E,eAAW,iBAAiB,UAAU,OAAO;AAC7C,WAAO,MAAM,WAAW,oBAAoB,UAAU,OAAO;AAAA,EACjE,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACZ,eAAW,iBAAiB,CAAC;AAG7B,UAAM,WAAW,IAAI,iBAAiB,MAAM;AACxC,iBAAW,iBAAiB,CAAC;AAAA,IACjC,CAAC;AAED,aAAS,QAAQ,SAAS,iBAAiB;AAAA,MACvC,YAAY;AAAA,MACZ,iBAAiB,CAAC,SAAS,YAAY;AAAA,IAC3C,CAAC;AAED,WAAO,MAAM,SAAS,WAAW;AAAA,EACrC,GAAG,CAAC,CAAC;AAGL,aAAO,sBAAQ,MAAM;AACjB,QAAI,cAAc,SAAS;AACvB,YAAMA,gBAAe,UAAU,QAAQ,OAAO;AAC9C,aAAO,mBAAmBA,eAAc,SAAS,oBAAoB;AAAA,IACzE;AACA,UAAM,eAAe,UAAU,QAAQ,MAAM;AAC7C,WAAO,kBAAkB,cAAc,SAAS,oBAAoB;AAAA,EACxE,GAAG,CAAC,WAAW,QAAQ,SAAS,oBAAoB,CAAC;AACzD;","names":["presetConfig"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/use-count-up.ts","../src/presets/motion-styles.ts","../src/components/CountUp.tsx","../src/components/MotionDiv.tsx","../src/hooks/use-component-animation.ts","../src/components/StaggerContainer.tsx","../src/hooks/use-stagger.ts","../src/hooks/use-draw-path.ts","../src/hooks/use-motion-preset.ts","../src/presets/motion-presets.ts","../src/presets/component-presets.ts","../src/presets/micro-interactions.ts","../src/presets/stagger-presets.ts","../src/utils/easing.ts","../src/utils/reduced-motion.ts","../src/utils/select-preset.ts","../src/utils/spring-configs.ts"],"sourcesContent":["// Copyright (c) 2026 Amsterdam Data Labs\n\n// @enact-ui/animate - Animation utilities and motion presets\n\n/**\n * @enact-ui/animate\n *\n * Animation utilities and motion presets for ENACT UI.\n * Provides a comprehensive motion preset system for AI-driven UI generation\n * with professional, accessible animations.\n *\n * @packageDocumentation\n */\n\nexport { CountUp, type CountUpProps } from \"./components/CountUp\";\nexport {\n createAccessibleMotionProps,\n createMotionProps,\n MotionDiv,\n type MotionDivProps,\n} from \"./components/MotionDiv\";\n// =============================================================================\n// Components\n// =============================================================================\nexport {\n StaggerContainer,\n type StaggerContainerProps,\n withStagger,\n} from \"./components/StaggerContainer\";\nexport {\n type ComponentAnimationResult,\n type UseComponentAnimationOptions,\n useAnimationVariants,\n useComponentAnimation,\n useDelayedAnimation,\n useReducedMotion,\n} from \"./hooks/use-component-animation\";\nexport {\n type CountUpEasing,\n type UseCountUpOptions,\n type UseCountUpResult,\n useCountUp,\n} from \"./hooks/use-count-up\";\nexport {\n type DrawPathEasing,\n type UseDrawPathOptions,\n type UseDrawPathResult,\n useDrawPath,\n} from \"./hooks/use-draw-path\";\n// =============================================================================\n// Hooks\n// =============================================================================\nexport {\n type ComputedPathsMotion,\n type ComputedRaysMotion,\n useMotionPreset,\n} from \"./hooks/use-motion-preset\";\nexport {\n cascadeStagger,\n explodeStagger,\n gridStagger,\n type StaggerDirection,\n type StaggerOptions,\n type StaggerResult,\n useStagger,\n waveStagger,\n} from \"./hooks/use-stagger\";\n// =============================================================================\n// Component Animation Presets\n// =============================================================================\nexport {\n type AnimationVariants,\n type ComponentAnimationProps,\n type ComponentPreset,\n type ComponentPresetName,\n componentPresets,\n expand,\n // Presets\n fadeIn,\n fadeOut,\n flip,\n // Utility functions\n getComponentPreset,\n getPresetsByContext,\n getPresetsByUseCase,\n type PresetContext,\n type PresetMetadata,\n type PresetOptions,\n // Types\n type PresetUseCase,\n rotate,\n scale,\n slideDown,\n slideLeft,\n slideRight,\n slideUp,\n slideUpScale,\n zoomIn,\n zoomOut,\n} from \"./presets/component-presets\";\n// =============================================================================\n// Micro-Interactions\n// =============================================================================\nexport {\n // Utility functions\n badgePop,\n // Presets\n buttonPress,\n cardHover,\n checkmarkDraw,\n findPresetsForUseCase,\n getMicroInteraction,\n getMicroInteractionNames,\n glowPulse,\n heartbeat,\n iconSpin,\n type MicroInteractionPreset,\n // Types\n type MicroInteractionProps,\n microInteractions,\n progressFill,\n pulse,\n rubberBand,\n // Micro-interaction scale (different from component-preset scale)\n // Use scaleMicro for checkbox/toggle selection feedback\n scale as scaleMicro,\n shake,\n shimmer,\n successFlash,\n wiggle,\n} from \"./presets/micro-interactions\";\n// =============================================================================\n// Background Motion Presets (Existing)\n// =============================================================================\nexport {\n type AmbientPathsConfig,\n ambientPaths,\n applyMotionPreset,\n type ComponentType,\n getPreset,\n type LightRaysConfig,\n lightRays,\n type MotionPreset,\n type PresetConfig,\n} from \"./presets/motion-presets\";\n// =============================================================================\n// Motion Styles\n// =============================================================================\nexport {\n boldStyle,\n type DurationConfig,\n type EasingConfig,\n getDuration,\n // Utility functions\n getMotionStyle,\n getSpringConfig,\n // Types\n type MotionStyle,\n type MotionStyleConfig,\n motionStyles,\n msToSeconds,\n playfulStyle,\n type SpringConfig,\n standardStyle,\n // Style configurations\n subtleStyle,\n} from \"./presets/motion-styles\";\n// =============================================================================\n// Stagger Presets\n// =============================================================================\nexport {\n // Types\n type ContainerVariants,\n calculateStaggerDelays,\n // Utility functions\n getStaggerPreset,\n type ItemVariants,\n type StaggerPreset,\n type StaggerPresetType,\n staggerCascade,\n staggerCenter,\n staggerGrid,\n staggerPresets,\n staggerRandom,\n staggerReverse,\n // Presets\n staggerSequential,\n staggerWave,\n} from \"./presets/stagger-presets\";\nexport {\n // Types\n type CubicBezier,\n // Factory functions\n createTween,\n createTweenFromParams,\n type DurationPresetName,\n // Duration presets\n durations,\n type EasingPresetName,\n easeIn,\n easeInOut,\n easeInOutCubic,\n easeInOutQuint,\n easeOut,\n easeOutBack,\n easeOutExpo,\n easeOutQuart,\n // Easing collections\n easingPresets,\n // Easing curves\n linear,\n type TweenParams,\n type TweenPresetName,\n type TweenTransition,\n tweenPresets,\n} from \"./utils/easing\";\n// =============================================================================\n// Utilities\n// =============================================================================\nexport {\n checkReducedMotion,\n createReducedMotionProps,\n // Functions\n getReducedMotionVariant,\n INSTANT_TRANSITION,\n type MotionProps,\n type MotionTransition,\n // Types\n type MotionVariant,\n // Constants\n REDUCED_MOTION_QUERY,\n type ReducedMotionOptions,\n} from \"./utils/reduced-motion\";\n// =============================================================================\n// AI Selection System\n// =============================================================================\nexport {\n getAllContexts,\n // Metadata utilities\n getAllPresetNames,\n getAllUseCases,\n getDefaultPreset,\n getPresetMetadata,\n getRecommendations,\n type PresetRecommendation,\n // Types\n type SelectionCriteria,\n type SelectionResult,\n // Selection functions\n selectPreset,\n suggestAnimations,\n} from \"./utils/select-preset\";\nexport {\n // Factory functions\n createSpring,\n createSpringFromParams,\n type SpringParams,\n type SpringPresetName,\n // Types\n type SpringTransition,\n springBouncy,\n // Spring presets\n springGentle,\n springPresets,\n springSnappy,\n springStiff,\n} from \"./utils/spring-configs\";\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * useCountUp Hook\n *\n * Animates a number from a start value to an end value with configurable\n * duration, easing, and formatting. Respects reduced motion preferences.\n *\n * @packageDocumentation\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\nimport { getDuration } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Easing function type for count-up animation.\n */\nexport type CountUpEasing = \"linear\" | \"easeOut\" | \"easeOutExpo\" | \"easeInOut\" | \"spring\";\n\n/**\n * Options for the useCountUp hook.\n */\nexport interface UseCountUpOptions {\n /** Starting value. Defaults to 0. */\n from?: number;\n /** Target value to count to. Required. */\n to: number;\n /** Duration in milliseconds. Defaults to motion style duration. */\n duration?: number;\n /** Motion style to use for timing. Defaults to \"standard\". */\n motionStyle?: MotionStyle;\n /** Easing function. Defaults to \"easeOutExpo\". */\n easing?: CountUpEasing;\n /** Number of decimal places. Defaults to 0. */\n decimals?: number;\n /** Whether to use locale-specific formatting (e.g., 1,234). Defaults to true. */\n useLocale?: boolean;\n /** Locale for formatting. Defaults to browser locale. */\n locale?: string;\n /** Custom formatter function. Overrides decimals and locale settings. */\n formatter?: (value: number) => string;\n /** Delay before starting animation in ms. Defaults to 0. */\n delay?: number;\n /** Whether to start animation immediately. Defaults to true. */\n autoStart?: boolean;\n /** Callback when animation completes. */\n onComplete?: () => void;\n /** Callback on each value update. */\n onUpdate?: (value: number) => void;\n /** Prefix to add before the number (e.g., \"$\"). */\n prefix?: string;\n /** Suffix to add after the number (e.g., \"%\"). */\n suffix?: string;\n /** Whether animation is enabled. Defaults to true. */\n enabled?: boolean;\n}\n\n/**\n * Return type for the useCountUp hook.\n */\nexport interface UseCountUpResult {\n /** Current animated value (raw number). */\n value: number;\n /** Formatted display string with prefix/suffix. */\n displayValue: string;\n /** Whether animation is currently running. */\n isAnimating: boolean;\n /** Whether animation has completed. */\n isComplete: boolean;\n /** Start or restart the animation. */\n start: () => void;\n /** Pause the animation at current value. */\n pause: () => void;\n /** Resume a paused animation. */\n resume: () => void;\n /** Reset to starting value. */\n reset: () => void;\n /** Update the target value (will animate to new value). */\n update: (newTo: number) => void;\n /** Whether reduced motion is preferred. */\n prefersReducedMotion: boolean;\n}\n\n// =============================================================================\n// Easing Functions\n// =============================================================================\n\nconst easingFunctions: Record<CountUpEasing, (t: number) => number> = {\n linear: (t) => t,\n easeOut: (t) => 1 - (1 - t) ** 3,\n easeOutExpo: (t) => (t === 1 ? 1 : 1 - 2 ** (-10 * t)),\n easeInOut: (t) => (t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2),\n spring: (t) => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0 ? 0 : t === 1 ? 1 : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;\n },\n};\n\n// =============================================================================\n// Reduced Motion Detection\n// =============================================================================\n\nfunction useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handler);\n return () => mediaQuery.removeEventListener(\"change\", handler);\n }, []);\n\n return prefersReducedMotion;\n}\n\n// =============================================================================\n// Default Formatter\n// =============================================================================\n\nfunction createDefaultFormatter(decimals: number, useLocale: boolean, locale?: string): (value: number) => string {\n return (value: number) => {\n if (useLocale) {\n return value.toLocaleString(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n }\n return value.toFixed(decimals);\n };\n}\n\n// =============================================================================\n// useCountUp Hook\n// =============================================================================\n\n/**\n * Hook for animating numbers from one value to another.\n *\n * Features:\n * - Configurable duration and easing\n * - Respects reduced motion preferences\n * - Locale-aware number formatting\n * - Start/pause/resume/reset controls\n * - Prefix and suffix support\n * - Custom formatter support\n *\n * @param options - Configuration options for the animation\n * @returns Object with current value, display string, and control functions\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { displayValue } = useCountUp({ to: 1000 });\n * return <span>{displayValue}</span>;\n *\n * // With formatting\n * const { displayValue } = useCountUp({\n * to: 99.5,\n * decimals: 1,\n * suffix: \"%\",\n * duration: 1500,\n * });\n *\n * // Currency\n * const { displayValue } = useCountUp({\n * to: 1234567,\n * prefix: \"$\",\n * useLocale: true,\n * });\n *\n * // Manual control\n * const { displayValue, start, reset, isAnimating } = useCountUp({\n * to: 500,\n * autoStart: false,\n * });\n * ```\n */\nexport function useCountUp(options: UseCountUpOptions): UseCountUpResult {\n const {\n from = 0,\n to,\n duration: customDuration,\n motionStyle = \"standard\",\n easing = \"easeOutExpo\",\n decimals = 0,\n useLocale = true,\n locale,\n formatter: customFormatter,\n delay = 0,\n autoStart = true,\n onComplete,\n onUpdate,\n prefix = \"\",\n suffix = \"\",\n enabled = true,\n } = options;\n\n // Get duration from motion style if not custom (use slow for count-up animations)\n const duration = customDuration ?? getDuration(motionStyle, \"slow\");\n\n // State\n const [value, setValue] = useState(from);\n const [isAnimating, setIsAnimating] = useState(false);\n const [isComplete, setIsComplete] = useState(false);\n\n // Refs for animation control\n const animationRef = useRef<number | null>(null);\n const startTimeRef = useRef<number | null>(null);\n const pausedTimeRef = useRef<number | null>(null);\n const currentFromRef = useRef(from);\n const currentToRef = useRef(to);\n\n // Reduced motion\n const prefersReducedMotion = useReducedMotion();\n\n // Formatter\n const formatter = customFormatter ?? createDefaultFormatter(decimals, useLocale, locale);\n\n // Format display value\n const displayValue = `${prefix}${formatter(value)}${suffix}`;\n\n // Cancel animation\n const cancelAnimation = useCallback(() => {\n if (animationRef.current !== null) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n }, []);\n\n // Animation frame handler\n const animate = useCallback(\n (timestamp: number) => {\n if (startTimeRef.current === null) {\n startTimeRef.current = timestamp;\n }\n\n const elapsed = timestamp - startTimeRef.current;\n const progress = Math.min(elapsed / duration, 1);\n const easedProgress = easingFunctions[easing](progress);\n\n const currentValue = currentFromRef.current + (currentToRef.current - currentFromRef.current) * easedProgress;\n setValue(currentValue);\n onUpdate?.(currentValue);\n\n if (progress < 1) {\n animationRef.current = requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n setIsComplete(true);\n onComplete?.();\n }\n },\n [duration, easing, onComplete, onUpdate],\n );\n\n // Start animation\n const start = useCallback(() => {\n if (!enabled) {\n setValue(currentToRef.current);\n setIsComplete(true);\n return;\n }\n\n // Handle reduced motion - jump to end value immediately\n if (prefersReducedMotion) {\n setValue(currentToRef.current);\n setIsComplete(true);\n onComplete?.();\n return;\n }\n\n cancelAnimation();\n setIsComplete(false);\n startTimeRef.current = null;\n pausedTimeRef.current = null;\n\n const startAnimation = () => {\n setIsAnimating(true);\n animationRef.current = requestAnimationFrame(animate);\n };\n\n if (delay > 0) {\n setTimeout(startAnimation, delay);\n } else {\n startAnimation();\n }\n }, [enabled, prefersReducedMotion, cancelAnimation, animate, delay, onComplete]);\n\n // Pause animation\n const pause = useCallback(() => {\n if (isAnimating && animationRef.current !== null) {\n pausedTimeRef.current = performance.now();\n cancelAnimation();\n setIsAnimating(false);\n }\n }, [isAnimating, cancelAnimation]);\n\n // Resume animation\n const resume = useCallback(() => {\n if (!isAnimating && !isComplete && pausedTimeRef.current !== null && startTimeRef.current !== null) {\n // Adjust start time to account for paused duration\n const pausedDuration = performance.now() - pausedTimeRef.current;\n startTimeRef.current += pausedDuration;\n pausedTimeRef.current = null;\n setIsAnimating(true);\n animationRef.current = requestAnimationFrame(animate);\n }\n }, [isAnimating, isComplete, animate]);\n\n // Reset to starting value\n const reset = useCallback(() => {\n cancelAnimation();\n setValue(currentFromRef.current);\n setIsAnimating(false);\n setIsComplete(false);\n startTimeRef.current = null;\n pausedTimeRef.current = null;\n }, [cancelAnimation]);\n\n // Update target value\n const update = useCallback(\n (newTo: number) => {\n currentFromRef.current = value;\n currentToRef.current = newTo;\n start();\n },\n [value, start],\n );\n\n // Auto-start on mount - intentionally only runs once\n // biome-ignore lint/correctness/useExhaustiveDependencies: We only want to start animation on mount, not on every dependency change\n useEffect(() => {\n if (autoStart) {\n currentFromRef.current = from;\n currentToRef.current = to;\n start();\n }\n\n return () => {\n cancelAnimation();\n };\n }, []);\n\n // Update target when `to` prop changes\n useEffect(() => {\n if (to !== currentToRef.current && isComplete) {\n update(to);\n }\n }, [to, isComplete, update]);\n\n return {\n value,\n displayValue,\n isAnimating,\n isComplete,\n start,\n pause,\n resume,\n reset,\n update,\n prefersReducedMotion,\n };\n}\n","/**\n * Motion Style Presets\n *\n * Defines four motion styles that control the overall feel of animations.\n * These styles can be used with any component animation preset to adjust\n * timing, spring physics, and easing characteristics.\n *\n * @packageDocumentation\n */\n\n/**\n * Motion style identifiers for animation presets.\n *\n * - `subtle`: Gentle, minimal animations ideal for professional/enterprise UIs\n * - `standard`: Balanced, professional animations suitable for most use cases\n * - `bold`: Dramatic, attention-grabbing animations for emphasis\n * - `playful`: Bouncy, fun animations with elastic spring physics\n *\n * @example\n * ```tsx\n * import { useComponentAnimation, fadeIn } from \"@enact-ui/animate\";\n *\n * function MyComponent() {\n * const animation = useComponentAnimation(fadeIn, \"standard\");\n * return <motion.div {...animation}>Content</motion.div>;\n * }\n * ```\n */\nexport type MotionStyle = \"subtle\" | \"standard\" | \"bold\" | \"playful\";\n\n/**\n * Duration configurations for different speed levels.\n * All values are in milliseconds.\n */\nexport interface DurationConfig {\n /** Fast animations (micro-interactions, hover states) */\n fast: number;\n /** Normal animations (most component transitions) */\n normal: number;\n /** Slow animations (page transitions, emphasis) */\n slow: number;\n}\n\n/**\n * Spring physics configuration for natural motion.\n * Used with Motion library's spring animations.\n */\nexport interface SpringConfig {\n /** Controls how \"snappy\" the spring is (higher = faster) */\n stiffness: number;\n /** Controls how much the spring oscillates (higher = less bounce) */\n damping: number;\n /** The mass of the animated element (affects momentum) */\n mass: number;\n}\n\n/**\n * Easing function configuration for tween animations.\n */\nexport interface EasingConfig {\n /** Easing for entrance animations */\n enter: string;\n /** Easing for exit animations */\n exit: string;\n /** Easing for interactive states (hover, press) */\n interactive: string;\n}\n\n/**\n * Complete motion style configuration.\n */\nexport interface MotionStyleConfig {\n /** Display name for the motion style */\n name: string;\n /** Description of when to use this style */\n description: string;\n /** Duration values for different animation speeds */\n duration: DurationConfig;\n /** Spring physics configuration */\n spring: SpringConfig;\n /** Easing function configuration */\n easing: EasingConfig;\n /** Stagger delay between items in lists (ms) */\n staggerDelay: number;\n}\n\n/**\n * Subtle motion style - gentle, minimal animations.\n *\n * Best for:\n * - Enterprise/professional applications\n * - Users who prefer reduced motion\n * - Secondary UI elements\n * - Frequent, repeated interactions\n *\n * @ai-hint Use \"subtle\" for professional enterprise UIs or when animations\n * should be barely noticeable. Good default for accessibility.\n */\nexport const subtleStyle: MotionStyleConfig = {\n name: \"Subtle\",\n description: \"Gentle, minimal animations ideal for professional UIs\",\n duration: {\n fast: 150,\n normal: 200,\n slow: 300,\n },\n spring: {\n stiffness: 400,\n damping: 35,\n mass: 0.8,\n },\n easing: {\n enter: \"easeOut\",\n exit: \"easeIn\",\n interactive: \"easeInOut\",\n },\n staggerDelay: 30,\n};\n\n/**\n * Standard motion style - balanced, professional animations.\n *\n * Best for:\n * - Most applications (recommended default)\n * - General-purpose UI components\n * - Modals, dropdowns, tooltips\n * - List animations\n *\n * @ai-hint Use \"standard\" as the default motion style. It provides\n * professional, polished animations that work in most contexts.\n */\nexport const standardStyle: MotionStyleConfig = {\n name: \"Standard\",\n description: \"Balanced, professional animations for general use\",\n duration: {\n fast: 200,\n normal: 300,\n slow: 400,\n },\n spring: {\n stiffness: 300,\n damping: 28,\n mass: 1,\n },\n easing: {\n enter: \"easeOut\",\n exit: \"easeIn\",\n interactive: \"easeInOut\",\n },\n staggerDelay: 50,\n};\n\n/**\n * Bold motion style - dramatic, attention-grabbing animations.\n *\n * Best for:\n * - Hero sections and landing pages\n * - Important notifications or alerts\n * - Onboarding flows\n * - Feature showcases\n *\n * @ai-hint Use \"bold\" when you want animations to be noticeable and\n * make an impact. Good for marketing pages and feature highlights.\n */\nexport const boldStyle: MotionStyleConfig = {\n name: \"Bold\",\n description: \"Dramatic, attention-grabbing animations for emphasis\",\n duration: {\n fast: 250,\n normal: 400,\n slow: 600,\n },\n spring: {\n stiffness: 250,\n damping: 22,\n mass: 1.2,\n },\n easing: {\n enter: \"easeOut\",\n exit: \"easeIn\",\n interactive: \"easeInOut\",\n },\n staggerDelay: 80,\n};\n\n/**\n * Playful motion style - bouncy, fun animations with elastic springs.\n *\n * Best for:\n * - Consumer apps and games\n * - Celebration/success states\n * - Interactive tutorials\n * - Child-friendly interfaces\n *\n * @ai-hint Use \"playful\" for fun, engaging interfaces. The elastic\n * spring creates a bouncy feel. Best for consumer apps and celebrations.\n */\nexport const playfulStyle: MotionStyleConfig = {\n name: \"Playful\",\n description: \"Bouncy, fun animations with elastic spring physics\",\n duration: {\n fast: 200,\n normal: 350,\n slow: 500,\n },\n spring: {\n stiffness: 200,\n damping: 15,\n mass: 1,\n },\n easing: {\n enter: \"easeOut\",\n exit: \"easeIn\",\n interactive: \"easeInOut\",\n },\n staggerDelay: 60,\n};\n\n/**\n * All motion style configurations indexed by style name.\n */\nexport const motionStyles: Record<MotionStyle, MotionStyleConfig> = {\n subtle: subtleStyle,\n standard: standardStyle,\n bold: boldStyle,\n playful: playfulStyle,\n};\n\n/**\n * Gets the configuration for a specific motion style.\n *\n * @param style - The motion style to retrieve\n * @returns The complete motion style configuration\n *\n * @example\n * ```ts\n * const config = getMotionStyle(\"standard\");\n * console.log(config.duration.normal); // 300\n * ```\n */\nexport function getMotionStyle(style: MotionStyle): MotionStyleConfig {\n return motionStyles[style];\n}\n\n/**\n * Gets the spring configuration for a motion style in Motion library format.\n *\n * @param style - The motion style\n * @returns Spring configuration compatible with Motion library\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n *\n * const spring = getSpringConfig(\"playful\");\n * <motion.div animate={{ x: 100 }} transition={{ type: \"spring\", ...spring }} />\n * ```\n */\nexport function getSpringConfig(style: MotionStyle): SpringConfig {\n return motionStyles[style].spring;\n}\n\n/**\n * Gets the duration for a specific speed level and motion style.\n *\n * @param style - The motion style\n * @param speed - The speed level (\"fast\" | \"normal\" | \"slow\")\n * @returns Duration in milliseconds\n *\n * @example\n * ```ts\n * const duration = getDuration(\"standard\", \"normal\");\n * // Returns 300 (ms)\n * ```\n */\nexport function getDuration(style: MotionStyle, speed: keyof DurationConfig): number {\n return motionStyles[style].duration[speed];\n}\n\n/**\n * Converts milliseconds to seconds for Motion library.\n *\n * @param ms - Duration in milliseconds\n * @returns Duration in seconds\n */\nexport function msToSeconds(ms: number): number {\n return ms / 1000;\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * CountUp Component\n *\n * Renders an animated number that counts from one value to another.\n * Uses useCountUp hook internally with a convenient component API.\n *\n * @packageDocumentation\n */\n\nimport type { FC, HTMLAttributes } from \"react\";\nimport { type CountUpEasing, type UseCountUpOptions, useCountUp } from \"../hooks/use-count-up\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CountUpProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n /** Target value to count to. Required. */\n to: number;\n /** Starting value. Defaults to 0. */\n from?: number;\n /** Duration in milliseconds. */\n duration?: number;\n /** Motion style for timing. Defaults to \"standard\". */\n motionStyle?: MotionStyle;\n /** Easing function. Defaults to \"easeOutExpo\". */\n easing?: CountUpEasing;\n /** Number of decimal places. Defaults to 0. */\n decimals?: number;\n /** Whether to use locale-specific formatting. Defaults to true. */\n useLocale?: boolean;\n /** Locale for formatting. */\n locale?: string;\n /** Custom formatter function. */\n formatter?: (value: number) => string;\n /** Delay before starting in ms. */\n delay?: number;\n /** Whether to start automatically. Defaults to true. */\n autoStart?: boolean;\n /** Callback when animation completes. */\n onComplete?: () => void;\n /** Callback on each value update. */\n onUpdate?: (value: number) => void;\n /** Prefix before the number (e.g., \"$\"). */\n prefix?: string;\n /** Suffix after the number (e.g., \"%\"). */\n suffix?: string;\n /** Whether animation is enabled. Defaults to true. */\n enabled?: boolean;\n /** Render prop for custom rendering. Receives value and displayValue. */\n children?: (props: { value: number; displayValue: string; isAnimating: boolean }) => React.ReactNode;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * CountUp - Animated number counter component\n *\n * Displays a number that animates from a starting value to a target value.\n * Supports formatting, prefixes, suffixes, and custom rendering.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <CountUp to={1000} />\n *\n * // With formatting\n * <CountUp to={99.5} decimals={1} suffix=\"%\" />\n *\n * // Currency\n * <CountUp to={1234567} prefix=\"$\" useLocale />\n *\n * // Custom duration and easing\n * <CountUp to={500} duration={2000} easing=\"spring\" />\n *\n * // Render prop for custom styling\n * <CountUp to={100}>\n * {({ displayValue, isAnimating }) => (\n * <span className={isAnimating ? \"text-blue-500\" : \"text-green-500\"}>\n * {displayValue}\n * </span>\n * )}\n * </CountUp>\n * ```\n */\nexport const CountUp: FC<CountUpProps> = ({\n to,\n from = 0,\n duration,\n motionStyle = \"standard\",\n easing = \"easeOutExpo\",\n decimals = 0,\n useLocale = true,\n locale,\n formatter,\n delay = 0,\n autoStart = true,\n onComplete,\n onUpdate,\n prefix = \"\",\n suffix = \"\",\n enabled = true,\n children,\n ...spanProps\n}) => {\n // Build hook options, only including defined optional values\n const hookOptions: UseCountUpOptions = {\n from,\n to,\n motionStyle,\n easing,\n decimals,\n useLocale,\n delay,\n autoStart,\n prefix,\n suffix,\n enabled,\n // Only include optional props if they are defined\n ...(duration !== undefined && { duration }),\n ...(locale !== undefined && { locale }),\n ...(formatter !== undefined && { formatter }),\n ...(onComplete !== undefined && { onComplete }),\n ...(onUpdate !== undefined && { onUpdate }),\n };\n\n const { value, displayValue, isAnimating } = useCountUp(hookOptions);\n\n // Render prop pattern\n if (typeof children === \"function\") {\n return <>{children({ value, displayValue, isAnimating })}</>;\n }\n\n // Default rendering\n return <span {...spanProps}>{displayValue}</span>;\n};\n\nexport default CountUp;\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * MotionDiv Component\n *\n * A typed wrapper around motion.div that integrates with the preset system.\n * Provides a convenient way to apply animation presets without manually\n * spreading props.\n *\n * @packageDocumentation\n */\n\nimport { motion } from \"motion/react\";\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\";\nimport { useComponentAnimation } from \"../hooks/use-component-animation\";\nimport type { ComponentPreset, PresetOptions } from \"../presets/component-presets\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\n\n// Use a compatible type for exit to avoid depending on motion's internal TargetAndTransition export\ntype ExitPropType = Record<string, unknown>;\n\n// =============================================================================\n// Polymorphic Types\n// =============================================================================\n\n/**\n * Supported HTML elements for the `as` prop.\n * Motion components are created dynamically for these elements.\n */\ntype MotionElements = \"div\" | \"span\" | \"section\" | \"article\" | \"main\" | \"aside\" | \"header\" | \"footer\" | \"nav\" | \"ul\" | \"ol\" | \"li\" | \"button\" | \"a\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Props for the MotionDiv component.\n */\nexport interface MotionDivProps extends Omit<ComponentPropsWithoutRef<typeof motion.div>, \"initial\" | \"animate\" | \"exit\" | \"transition\"> {\n /** The animation preset to apply */\n preset: ComponentPreset;\n /**\n * Exit animation preset (for use with AnimatePresence).\n * If not provided, uses the main preset's exit animation.\n */\n exit?: ComponentPreset;\n /**\n * Render as a different HTML element.\n * Supports semantic HTML elements for accessibility.\n * @default \"div\"\n */\n as?: MotionElements;\n /** Motion style (subtle, standard, bold, playful) */\n motionStyle?: MotionStyle;\n /** Preset customization options */\n presetOptions?: PresetOptions;\n /** Whether animation is enabled */\n enabled?: boolean;\n /** Skip initial animation (useful for SSR) */\n skipInitial?: boolean;\n /** Child content */\n children?: ReactNode;\n}\n\n// =============================================================================\n// MotionDiv Component\n// =============================================================================\n\n/**\n * A motion.div wrapper that integrates with animation presets.\n *\n * This component simplifies the use of animation presets by handling\n * the hook usage internally and providing a clean component API.\n *\n * Note: This component requires motion/react to be installed.\n * It's a convenience wrapper that re-exports motion.div with preset support.\n *\n * @ai-hint Use MotionDiv when you want a simple way to animate a div\n * with a preset. For more control, use useComponentAnimation directly.\n *\n * @example\n * ```tsx\n * import { MotionDiv, fadeIn } from \"@enact-ui/animate\";\n *\n * function AnimatedCard() {\n * return (\n * <MotionDiv preset={fadeIn} motionStyle=\"standard\">\n * <Card>Content</Card>\n * </MotionDiv>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom options\n * <MotionDiv\n * preset={slideUp}\n * motionStyle=\"bold\"\n * presetOptions={{ distance: 40, delay: 100 }}\n * className=\"my-class\"\n * >\n * Content\n * </MotionDiv>\n * ```\n *\n * @example\n * ```tsx\n * // With AnimatePresence for exit animations\n * import { AnimatePresence } from \"motion/react\";\n *\n * function Modal({ isOpen }) {\n * return (\n * <AnimatePresence>\n * {isOpen && (\n * <MotionDiv preset={scale} motionStyle=\"standard\">\n * Modal content\n * </MotionDiv>\n * )}\n * </AnimatePresence>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With separate exit animation\n * <MotionDiv preset={slideUp} exit={fadeOut}>\n * Content that slides up on enter, fades out on exit\n * </MotionDiv>\n * ```\n *\n * @example\n * ```tsx\n * // Polymorphic - render as semantic HTML element\n * <MotionDiv preset={fadeIn} as=\"section\" className=\"my-section\">\n * <h2>Section Title</h2>\n * <p>Section content...</p>\n * </MotionDiv>\n * ```\n */\nexport function MotionDiv({\n preset,\n exit: exitPreset,\n as = \"div\",\n motionStyle = \"standard\",\n presetOptions,\n enabled = true,\n skipInitial = false,\n children,\n ...motionProps\n}: MotionDivProps): ReactElement {\n const animation = useComponentAnimation(preset, motionStyle, {\n ...presetOptions,\n enabled,\n skipInitial,\n });\n\n // Get exit animation if a separate exit preset is provided\n // Validate that exitPreset is actually a ComponentPreset with getProps method\n const exitAnimation =\n exitPreset && typeof exitPreset === \"object\" && \"getProps\" in exitPreset && typeof exitPreset.getProps === \"function\"\n ? exitPreset.getProps(motionStyle, presetOptions)\n : null;\n\n // Extract animation props without metadata\n const { prefersReducedMotion, isEnabled, ...animationProps } = animation;\n\n // Build exit props - use separate exit preset's initial state as exit animation\n // (exit animations typically reverse the enter animation)\n const exitValue: ExitPropType | undefined = exitAnimation ? (exitAnimation.initial as ExitPropType) : undefined;\n\n // Get the motion component for the specified element\n const MotionComponent = motion[as] as typeof motion.div;\n\n // Build props object, conditionally including exit.\n // Cast to motion.div props so exit (ExitPropType) is accepted with exactOptionalPropertyTypes.\n const finalProps = {\n ...motionProps,\n ...(animationProps as Parameters<typeof motion.div>[0]),\n ...(exitValue !== undefined && { exit: exitValue }),\n \"data-reduced-motion\": prefersReducedMotion,\n \"data-animation-enabled\": isEnabled,\n } as ComponentPropsWithoutRef<typeof motion.div>;\n\n return <MotionComponent {...finalProps}>{children}</MotionComponent>;\n}\n\n/**\n * Factory function to create motion props from a preset.\n *\n * Use this when you need the animation props without a component wrapper.\n * This is useful when you want to spread props onto your own motion element.\n *\n * @param preset - The animation preset\n * @param style - Motion style\n * @param options - Preset options\n * @returns Props object to spread on motion.div\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { createMotionProps, fadeIn } from \"@enact-ui/animate\";\n *\n * function MyComponent() {\n * const props = createMotionProps(fadeIn, \"standard\");\n *\n * return (\n * <motion.div {...props}>\n * Content\n * </motion.div>\n * );\n * }\n * ```\n */\nexport function createMotionProps(preset: ComponentPreset, style: MotionStyle = \"standard\", options?: PresetOptions) {\n return preset.getProps(style, options);\n}\n\n/**\n * Alias for createMotionProps. Use createMotionProps directly.\n *\n * @param preset - The animation preset\n * @param style - Motion style\n * @param options - Preset options\n * @returns Props object to spread on motion.div\n */\nexport function createAccessibleMotionProps(preset: ComponentPreset, style: MotionStyle = \"standard\", options?: PresetOptions) {\n return preset.getProps(style, options);\n}\n\nexport default MotionDiv;\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * useComponentAnimation Hook\n *\n * Hook for applying component animation presets with motion style support.\n * Provides a clean API for animating components with Motion library.\n *\n * @packageDocumentation\n */\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { ComponentAnimationProps, ComponentPreset, PresetOptions } from \"../presets/component-presets\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for the useComponentAnimation hook.\n */\nexport interface UseComponentAnimationOptions extends PresetOptions {\n /** Whether the animation is enabled. Defaults to true. */\n enabled?: boolean;\n /** Whether to skip the initial animation. Useful for SSR. */\n skipInitial?: boolean;\n}\n\n/**\n * Return type for the useComponentAnimation hook.\n */\nexport interface ComponentAnimationResult extends ComponentAnimationProps {\n /** Whether reduced motion is preferred by the user */\n prefersReducedMotion: boolean;\n /** Whether the animation is enabled */\n isEnabled: boolean;\n}\n\n// =============================================================================\n// Reduced Motion Detection\n// =============================================================================\n\n/**\n * Hook to detect if user prefers reduced motion.\n * Updates reactively when the preference changes.\n */\nfunction useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handler);\n return () => mediaQuery.removeEventListener(\"change\", handler);\n }, []);\n\n return prefersReducedMotion;\n}\n\n// =============================================================================\n// Reduced Motion Variants\n// =============================================================================\n\n/**\n * Creates disabled animation props (no animation).\n */\nfunction createDisabledProps(skipInitial: boolean): ComponentAnimationProps {\n return {\n initial: skipInitial ? false : { opacity: 1 },\n animate: { opacity: 1 },\n exit: { opacity: 1 },\n transition: { type: \"tween\", duration: 0 },\n };\n}\n\n// =============================================================================\n// Main Hook\n// =============================================================================\n\n/**\n * Hook for applying component animation presets.\n *\n * Provides Motion library compatible animation props that:\n * - Apply the selected motion style (subtle, standard, bold, playful)\n * - Support customization via options\n *\n * @param preset - The component animation preset to use\n * @param style - The motion style to apply (defaults to \"standard\")\n * @param options - Additional customization options\n * @returns Animation props for Motion library components\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { useComponentAnimation, fadeIn } from \"@enact-ui/animate\";\n *\n * function MyComponent() {\n * const animation = useComponentAnimation(fadeIn, \"standard\");\n *\n * return (\n * <motion.div {...animation}>\n * Content\n * </motion.div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With AnimatePresence for exit animations\n * import { AnimatePresence, motion } from \"motion/react\";\n * import { useComponentAnimation, slideUp } from \"@enact-ui/animate\";\n *\n * function Modal({ isOpen, children }) {\n * const animation = useComponentAnimation(slideUp, \"bold\");\n *\n * return (\n * <AnimatePresence>\n * {isOpen && (\n * <motion.div {...animation}>\n * {children}\n * </motion.div>\n * )}\n * </AnimatePresence>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom options\n * const animation = useComponentAnimation(slideUp, \"playful\", {\n * distance: 40,\n * delay: 100,\n * useSpring: true,\n * });\n * ```\n */\nexport function useComponentAnimation(\n preset: ComponentPreset,\n style: MotionStyle = \"standard\",\n options: UseComponentAnimationOptions = {},\n): ComponentAnimationResult {\n const { enabled = true, skipInitial = false, ...presetOptions } = options;\n const prefersReducedMotion = useReducedMotion();\n\n // Memoize presetOptions to avoid unnecessary re-renders\n // biome-ignore lint/correctness/useExhaustiveDependencies: Using JSON.stringify for deep comparison\n const memoizedPresetOptions = useMemo(() => presetOptions, [JSON.stringify(presetOptions)]);\n\n const animationProps = useMemo(() => {\n if (!enabled) {\n return createDisabledProps(skipInitial);\n }\n\n const props = preset.getProps(style, memoizedPresetOptions);\n\n if (skipInitial) {\n return {\n ...props,\n initial: false,\n };\n }\n\n return props;\n }, [preset, style, memoizedPresetOptions, enabled, skipInitial]);\n\n return {\n ...animationProps,\n prefersReducedMotion,\n isEnabled: enabled,\n };\n}\n\n/**\n * Hook for applying animation props with a delay.\n *\n * Useful for staggering animations without using variants.\n *\n * @param preset - The component animation preset to use\n * @param style - The motion style to apply\n * @param index - The index of this item (for calculating delay)\n * @param options - Additional customization options\n * @returns Animation props with calculated delay\n *\n * @example\n * ```tsx\n * function ListItem({ index, children }) {\n * const animation = useDelayedAnimation(fadeIn, \"standard\", index, {\n * delayMultiplier: 50, // 50ms between each item\n * });\n *\n * return (\n * <motion.li {...animation}>\n * {children}\n * </motion.li>\n * );\n * }\n * ```\n */\nexport function useDelayedAnimation(\n preset: ComponentPreset,\n style: MotionStyle = \"standard\",\n index: number,\n options: UseComponentAnimationOptions & {\n /** Delay multiplier per item in ms. Defaults to 50. */\n delayMultiplier?: number;\n /** Maximum delay in ms. Defaults to 500. */\n maxDelay?: number;\n } = {},\n): ComponentAnimationResult {\n const { delayMultiplier = 50, maxDelay = 500, ...restOptions } = options;\n\n const calculatedDelay = Math.min(index * delayMultiplier, maxDelay);\n\n return useComponentAnimation(preset, style, {\n ...restOptions,\n delay: (restOptions.delay ?? 0) + calculatedDelay,\n });\n}\n\n/**\n * Hook that returns animation props as a function for use with variants.\n *\n * Useful when you need to pass animation config to Motion's variants system.\n *\n * @param preset - The component animation preset to use\n * @param style - The motion style to apply\n * @param options - Additional customization options\n * @returns Object containing variants and transition\n *\n * @example\n * ```tsx\n * function Container({ children }) {\n * const { variants, transition } = useAnimationVariants(fadeIn, \"standard\");\n *\n * return (\n * <motion.div\n * initial=\"initial\"\n * animate=\"animate\"\n * exit=\"exit\"\n * variants={variants}\n * transition={transition}\n * >\n * {children}\n * </motion.div>\n * );\n * }\n * ```\n */\nexport function useAnimationVariants(\n preset: ComponentPreset,\n style: MotionStyle = \"standard\",\n options: UseComponentAnimationOptions = {},\n): {\n variants: {\n initial: Record<string, unknown>;\n animate: Record<string, unknown>;\n exit: Record<string, unknown>;\n };\n transition: Record<string, unknown>;\n} {\n const { enabled = true, ...presetOptions } = options;\n\n // Memoize presetOptions to avoid unnecessary re-renders\n // biome-ignore lint/correctness/useExhaustiveDependencies: Using JSON.stringify for deep comparison\n const memoizedPresetOptions = useMemo(() => presetOptions, [JSON.stringify(presetOptions)]);\n\n return useMemo(() => {\n if (!enabled) {\n return {\n variants: {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n },\n transition: { type: \"tween\", duration: 0.15 },\n };\n }\n\n const props = preset.getProps(style, memoizedPresetOptions);\n\n return {\n variants: {\n initial: props.initial as Record<string, unknown>,\n animate: props.animate as Record<string, unknown>,\n exit: (props.exit ?? props.initial) as Record<string, unknown>,\n },\n transition: props.transition,\n };\n }, [preset, style, memoizedPresetOptions, enabled]);\n}\n\n// =============================================================================\n// Re-exports for convenience\n// =============================================================================\n\nexport { useReducedMotion };\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * StaggerContainer Component\n *\n * A container component that orchestrates staggered animations for its children.\n * Works with Motion library to provide smooth, coordinated entrance animations.\n *\n * @packageDocumentation\n */\n\nimport { Children, cloneElement, isValidElement, type ReactElement, type ReactNode } from \"react\";\nimport { type ItemVariants, type StaggerDirection, type StaggerOptions, useStagger } from \"../hooks/use-stagger\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Props for the StaggerContainer component.\n */\nexport interface StaggerContainerProps {\n /** The child elements to animate */\n children: ReactNode;\n /** Motion style to apply */\n style?: MotionStyle;\n /** Stagger direction pattern */\n direction?: StaggerDirection;\n /** Custom delay between items in ms */\n delay?: number;\n /** Maximum total delay in ms */\n maxDelay?: number;\n /** Use spring physics for item animations */\n useSpring?: boolean;\n /** Custom delay function */\n getDelay?: (index: number, total: number) => number;\n /** Additional class name for the container */\n className?: string;\n /** HTML element to render as (default: div) */\n as?: \"div\" | \"ul\" | \"ol\" | \"section\" | \"article\" | \"nav\";\n /** Whether to animate (useful for conditional rendering) */\n animate?: boolean;\n /** Callback when all animations complete */\n onAnimationComplete?: () => void;\n}\n\n/**\n * Props passed to each stagger item.\n */\ninterface StaggerItemProps {\n /** The original child element */\n children: ReactElement;\n /** Index of the item */\n index: number;\n /** Item variants from useStagger */\n variants: ItemVariants;\n}\n\n// =============================================================================\n// StaggerItem Component\n// =============================================================================\n\n/**\n * Internal component that wraps each child with animation props.\n * This is used to inject the stagger animation without requiring\n * motion.* wrapper elements in the child components.\n */\nfunction StaggerItem({ children, index, variants }: StaggerItemProps) {\n // Clone the child element and add motion props\n // The child must be a motion.* element for this to work\n if (!isValidElement(children)) {\n return children;\n }\n\n // Cast to any because motion props aren't in standard React element types\n const motionProps = {\n variants,\n custom: index,\n initial: \"hidden\",\n animate: \"visible\",\n exit: \"hidden\",\n } as unknown as Record<string, unknown>;\n\n return cloneElement(children, motionProps);\n}\n\n// =============================================================================\n// StaggerContainer Component\n// =============================================================================\n\n/**\n * Container component that orchestrates staggered animations.\n *\n * Wraps children in a motion container that coordinates their entrance\n * animations using the Motion library's variants system.\n *\n * @ai-hint Use StaggerContainer when you have a list or grid of items\n * that should animate in sequence. Works with any motion.* children.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { StaggerContainer } from \"@enact-ui/animate\";\n *\n * function AnimatedCards({ cards }) {\n * return (\n * <StaggerContainer style=\"standard\" direction=\"forward\">\n * {cards.map((card) => (\n * <motion.div key={card.id}>\n * <Card {...card} />\n * </motion.div>\n * ))}\n * </StaggerContainer>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Center-out animation pattern\n * <StaggerContainer\n * style=\"bold\"\n * direction=\"center\"\n * delay={80}\n * >\n * {items.map((item) => (\n * <motion.li key={item.id}>{item.name}</motion.li>\n * ))}\n * </StaggerContainer>\n * ```\n *\n * @example\n * ```tsx\n * // As a navigation menu\n * <StaggerContainer\n * as=\"nav\"\n * style=\"subtle\"\n * direction=\"forward\"\n * delay={30}\n * >\n * {menuItems.map((item) => (\n * <motion.a key={item.href} href={item.href}>\n * {item.label}\n * </motion.a>\n * ))}\n * </StaggerContainer>\n * ```\n */\nexport function StaggerContainer({\n children,\n style = \"standard\",\n direction = \"forward\",\n delay,\n maxDelay = 1000,\n useSpring = true,\n getDelay,\n className,\n as: Element = \"div\",\n animate = true,\n}: StaggerContainerProps): ReactElement {\n // Count children for stagger calculations\n const childArray = Children.toArray(children);\n const totalItems = childArray.length;\n\n // Configure stagger options - filter out undefined values\n const staggerOptions: StaggerOptions = {\n direction,\n totalItems,\n ...(delay !== undefined && { delayMultiplier: delay }),\n maxDelay,\n useSpring,\n ...(getDelay !== undefined && { getDelay }),\n };\n\n // Get stagger configuration\n const { itemVariants } = useStagger(style, staggerOptions);\n\n // If animation is disabled, render without motion\n if (!animate) {\n return <Element className={className}>{children}</Element>;\n }\n\n // We need to import motion dynamically or expect it to be used with motion elements\n // For now, we'll render a regular element and expect children to be motion elements\n return (\n <Element className={className}>\n {childArray.map((child, index) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n return (\n <StaggerItem key={child.key ?? index} index={index} variants={itemVariants}>\n {child}\n </StaggerItem>\n );\n })}\n </Element>\n );\n}\n\n// =============================================================================\n// HOC for creating staggered lists\n// =============================================================================\n\n/**\n * Props for items in a stagger list.\n */\nexport interface StaggerListItemProps {\n /** Index of the item in the list */\n index: number;\n /** Style configuration */\n style: MotionStyle;\n /** Stagger options */\n options: StaggerOptions;\n}\n\n/**\n * Higher-order component for creating custom stagger containers.\n *\n * @param WrappedComponent - The list container component\n * @returns A stagger-enabled version of the component\n *\n * @example\n * ```tsx\n * const StaggeredGrid = withStagger(Grid);\n *\n * function MyGrid({ items }) {\n * return (\n * <StaggeredGrid style=\"playful\" direction=\"center\">\n * {items.map((item, index) => (\n * <GridItem key={item.id} index={index}>\n * {item.content}\n * </GridItem>\n * ))}\n * </StaggeredGrid>\n * );\n * }\n * ```\n */\nexport function withStagger<P extends { children?: ReactNode }>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P & Pick<StaggerContainerProps, \"style\" | \"direction\" | \"delay\" | \"maxDelay\" | \"useSpring\" | \"getDelay\">> {\n return function StaggerWrapper({\n style = \"standard\",\n direction = \"forward\",\n delay,\n maxDelay,\n useSpring,\n getDelay,\n children,\n ...props\n }: P & Pick<StaggerContainerProps, \"style\" | \"direction\" | \"delay\" | \"maxDelay\" | \"useSpring\" | \"getDelay\">) {\n // Build props object with only defined values\n const staggerProps: StaggerContainerProps = {\n children: <WrappedComponent {...(props as unknown as P)}>{children}</WrappedComponent>,\n style,\n direction,\n ...(delay !== undefined && { delay }),\n ...(maxDelay !== undefined && { maxDelay }),\n ...(useSpring !== undefined && { useSpring }),\n ...(getDelay !== undefined && { getDelay }),\n };\n\n return <StaggerContainer {...staggerProps} />;\n };\n}\n\nexport default StaggerContainer;\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * useStagger Hook\n *\n * Hook for creating staggered animations for lists and grids.\n * Provides both container and item animation configurations.\n *\n * @packageDocumentation\n */\n\nimport { useMemo } from \"react\";\nimport { getMotionStyle, type MotionStyle, msToSeconds } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Stagger direction patterns.\n */\nexport type StaggerDirection = \"forward\" | \"reverse\" | \"center\" | \"edges\" | \"random\";\n\n/**\n * Options for configuring stagger behavior.\n */\nexport interface StaggerOptions {\n /** Direction of the stagger effect */\n direction?: StaggerDirection;\n /** Total number of items (required for some patterns) */\n totalItems?: number;\n /** Custom delay multiplier (overrides motion style) */\n delayMultiplier?: number;\n /** Maximum total stagger delay in ms */\n maxDelay?: number;\n /** Whether to use spring physics for items */\n useSpring?: boolean;\n /** Custom delay function for advanced patterns */\n getDelay?: (index: number, total: number) => number;\n}\n\n/**\n * Container animation variants.\n */\nexport interface ContainerVariants {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown>;\n}\n\n/**\n * Item animation variants.\n * Visible can be a function for custom delays based on index.\n */\nexport interface ItemVariants {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown> | ((custom: number) => Record<string, unknown>);\n}\n\n/**\n * Result of the useStagger hook.\n */\nexport interface StaggerResult {\n /** Variants for the container element */\n containerVariants: ContainerVariants;\n /** Variants for child items */\n itemVariants: ItemVariants;\n /** Props to spread on the container */\n containerProps: {\n initial: string;\n animate: string;\n exit?: string;\n variants: ContainerVariants;\n };\n /** Function to get props for an item at a specific index */\n getItemProps: (index: number) => {\n variants: ItemVariants;\n custom: number;\n };\n}\n\n// =============================================================================\n// Delay Calculation Functions\n// =============================================================================\n\n/**\n * Calculates stagger delay based on direction pattern.\n */\nfunction calculateDelay(index: number, total: number, direction: StaggerDirection, baseDelay: number): number {\n switch (direction) {\n case \"forward\":\n return index * baseDelay;\n\n case \"reverse\":\n return (total - 1 - index) * baseDelay;\n\n case \"center\": {\n const center = (total - 1) / 2;\n const distanceFromCenter = Math.abs(index - center);\n return distanceFromCenter * baseDelay;\n }\n\n case \"edges\": {\n const center = (total - 1) / 2;\n const distanceFromCenter = Math.abs(index - center);\n const maxDistance = center;\n return (maxDistance - distanceFromCenter) * baseDelay;\n }\n\n case \"random\":\n return Math.random() * total * baseDelay * 0.5;\n\n default:\n return index * baseDelay;\n }\n}\n\n// =============================================================================\n// Main Hook\n// =============================================================================\n\n/**\n * Hook for creating staggered animations.\n *\n * Creates container and item variants for Motion library that orchestrate\n * staggered entrance animations for lists and grids.\n *\n * @param style - The motion style to apply\n * @param options - Stagger configuration options\n * @returns Stagger animation configuration\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { useStagger } from \"@enact-ui/animate\";\n *\n * function AnimatedList({ items }) {\n * const { containerProps, getItemProps } = useStagger(\"standard\");\n *\n * return (\n * <motion.ul {...containerProps}>\n * {items.map((item, index) => (\n * <motion.li key={item.id} {...getItemProps(index)}>\n * {item.content}\n * </motion.li>\n * ))}\n * </motion.ul>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Center-out stagger pattern\n * const { containerProps, getItemProps } = useStagger(\"bold\", {\n * direction: \"center\",\n * totalItems: items.length,\n * });\n * ```\n *\n * @example\n * ```tsx\n * // Custom delay function for grid layouts\n * const { containerProps, getItemProps } = useStagger(\"playful\", {\n * getDelay: (index, total) => {\n * const row = Math.floor(index / columns);\n * const col = index % columns;\n * return (row + col) * 50; // Diagonal wave\n * },\n * });\n * ```\n */\nexport function useStagger(style: MotionStyle = \"standard\", options: StaggerOptions = {}): StaggerResult {\n const { direction = \"forward\", totalItems = 10, delayMultiplier, maxDelay = 1000, useSpring = true, getDelay: customGetDelay } = options;\n\n const styleConfig = getMotionStyle(style);\n const baseDelay = delayMultiplier ?? styleConfig.staggerDelay;\n\n const result = useMemo(() => {\n // Calculate the delay for each item\n const getDelayForIndex = (index: number): number => {\n if (customGetDelay) {\n return Math.min(customGetDelay(index, totalItems), maxDelay);\n }\n return Math.min(calculateDelay(index, totalItems, direction, baseDelay), maxDelay);\n };\n\n // Container variants\n const containerVariants: ContainerVariants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(baseDelay),\n delayChildren: 0,\n when: \"beforeChildren\",\n },\n },\n };\n\n // Item variants with spring or tween\n const itemTransition = useSpring\n ? {\n type: \"spring\",\n stiffness: styleConfig.spring.stiffness,\n damping: styleConfig.spring.damping,\n mass: styleConfig.spring.mass,\n }\n : {\n type: \"tween\",\n duration: msToSeconds(styleConfig.duration.normal),\n ease: [0.25, 0.1, 0.25, 1],\n };\n\n const itemVariants: ItemVariants = {\n hidden: {\n opacity: 0,\n y: 20,\n },\n visible: (custom: number) => ({\n opacity: 1,\n y: 0,\n transition: {\n ...itemTransition,\n delay: msToSeconds(getDelayForIndex(custom)),\n },\n }),\n };\n\n // Container props\n const containerProps = {\n initial: \"hidden\" as const,\n animate: \"visible\" as const,\n exit: \"hidden\" as const,\n variants: containerVariants,\n };\n\n // Item props factory\n const getItemProps = (index: number) => ({\n variants: itemVariants,\n custom: index,\n });\n\n return {\n containerVariants,\n itemVariants,\n containerProps,\n getItemProps,\n };\n }, [direction, totalItems, baseDelay, maxDelay, useSpring, customGetDelay, styleConfig]);\n\n return result;\n}\n\n// =============================================================================\n// Preset Stagger Patterns\n// =============================================================================\n\n/**\n * Creates a grid stagger pattern (diagonal wave).\n *\n * @param columns - Number of columns in the grid\n * @param baseDelay - Base delay between items in ms\n * @returns Delay function for useStagger\n *\n * @example\n * ```tsx\n * const { containerProps, getItemProps } = useStagger(\"standard\", {\n * getDelay: gridStagger(4, 50),\n * });\n * ```\n */\nexport function gridStagger(columns: number, baseDelay: number = 50): (index: number, total: number) => number {\n return (index: number) => {\n const row = Math.floor(index / columns);\n const col = index % columns;\n return (row + col) * baseDelay;\n };\n}\n\n/**\n * Creates a wave stagger pattern (sine-based).\n *\n * @param amplitude - Wave amplitude (higher = more variation)\n * @param frequency - Wave frequency\n * @param baseDelay - Base delay in ms\n * @returns Delay function for useStagger\n *\n * @example\n * ```tsx\n * const { containerProps, getItemProps } = useStagger(\"playful\", {\n * getDelay: waveStagger(100, 0.5, 30),\n * });\n * ```\n */\nexport function waveStagger(amplitude: number = 100, frequency: number = 0.5, baseDelay: number = 30): (index: number, total: number) => number {\n return (index: number) => {\n const wave = Math.sin(index * frequency) * amplitude;\n return index * baseDelay + Math.abs(wave);\n };\n}\n\n/**\n * Creates a cascade stagger pattern (accelerating).\n *\n * Items start slow and speed up as the animation progresses.\n *\n * @param baseDelay - Base delay in ms\n * @param acceleration - Acceleration factor (0-1)\n * @returns Delay function for useStagger\n *\n * @example\n * ```tsx\n * const { containerProps, getItemProps } = useStagger(\"bold\", {\n * getDelay: cascadeStagger(80, 0.8),\n * });\n * ```\n */\nexport function cascadeStagger(baseDelay: number = 80, acceleration: number = 0.8): (index: number, total: number) => number {\n return (index: number) => {\n const factor = acceleration ** index;\n return baseDelay * (1 - factor) * (1 / (1 - acceleration));\n };\n}\n\n/**\n * Creates an explode stagger pattern (from center outward, fast).\n *\n * @param baseDelay - Base delay in ms\n * @returns Delay function for useStagger\n *\n * @example\n * ```tsx\n * const { containerProps, getItemProps } = useStagger(\"playful\", {\n * direction: \"center\",\n * getDelay: explodeStagger(20),\n * });\n * ```\n */\nexport function explodeStagger(baseDelay: number = 20): (index: number, total: number) => number {\n return (index: number, total: number) => {\n const center = (total - 1) / 2;\n const distance = Math.abs(index - center);\n return distance * baseDelay;\n };\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * useDrawPath Hook\n *\n * Animates SVG path/arc drawing by animating pathLength from 0 to 1.\n * Perfect for trust score rings, progress arcs, and SVG path drawing animations.\n * Respects reduced motion preferences.\n *\n * @packageDocumentation\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\nimport { getDuration } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Easing function type for path drawing animation.\n */\nexport type DrawPathEasing = \"linear\" | \"easeOut\" | \"easeOutExpo\" | \"easeInOut\" | \"spring\";\n\n/**\n * Options for the useDrawPath hook.\n */\nexport interface UseDrawPathOptions {\n /** Starting path length (0-1). Defaults to 0. */\n from?: number;\n /** Target path length (0-1). Required. */\n to: number;\n /** Duration in milliseconds. Defaults to motion style duration. */\n duration?: number;\n /** Motion style to use for timing. Defaults to \"standard\". */\n motionStyle?: MotionStyle;\n /** Easing function. Defaults to \"easeOutExpo\". */\n easing?: DrawPathEasing;\n /** Delay before starting animation in ms. Defaults to 0. */\n delay?: number;\n /** Whether to start animation immediately. Defaults to true. */\n autoStart?: boolean;\n /** Callback when animation completes. */\n onComplete?: () => void;\n /** Callback on each value update. */\n onUpdate?: (pathLength: number) => void;\n /** Whether animation is enabled. Defaults to true. */\n enabled?: boolean;\n}\n\n/**\n * Return type for the useDrawPath hook.\n */\nexport interface UseDrawPathResult {\n /** Current path length (0-1) for strokeDasharray/strokeDashoffset. */\n pathLength: number;\n /** Whether animation is currently running. */\n isAnimating: boolean;\n /** Whether animation has completed. */\n isComplete: boolean;\n /** Start or restart the animation. */\n start: () => void;\n /** Pause the animation at current value. */\n pause: () => void;\n /** Resume a paused animation. */\n resume: () => void;\n /** Reset to starting value. */\n reset: () => void;\n /** Update the target value (will animate to new value). */\n update: (newTo: number) => void;\n /** Whether reduced motion is preferred. */\n prefersReducedMotion: boolean;\n}\n\n// =============================================================================\n// Easing Functions\n// =============================================================================\n\nconst easingFunctions: Record<DrawPathEasing, (t: number) => number> = {\n linear: (t) => t,\n easeOut: (t) => 1 - (1 - t) ** 3,\n easeOutExpo: (t) => (t === 1 ? 1 : 1 - 2 ** (-10 * t)),\n easeInOut: (t) => (t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2),\n spring: (t) => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0 ? 0 : t === 1 ? 1 : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;\n },\n};\n\n// =============================================================================\n// Reduced Motion Detection\n// =============================================================================\n\nfunction useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handler);\n return () => mediaQuery.removeEventListener(\"change\", handler);\n }, []);\n\n return prefersReducedMotion;\n}\n\n// =============================================================================\n// useDrawPath Hook\n// =============================================================================\n\n/**\n * Hook for animating SVG path/arc drawing.\n *\n * Features:\n * - Animates pathLength from 0 to 1 (for strokeDasharray/strokeDashoffset)\n * - Configurable duration and easing\n * - Respects reduced motion preferences\n * - Start/pause/resume/reset controls\n *\n * @param options - Configuration options for the animation\n * @returns Object with current pathLength (0-1) and control functions\n *\n * @example\n * ```tsx\n * // Basic usage for circular progress\n * const { pathLength } = useDrawPath({ to: 0.75 }); // 75% drawn\n * return (\n * <circle\n * strokeDasharray=\"100\"\n * strokeDashoffset={100 - pathLength * 100}\n * pathLength=\"100\"\n * />\n * );\n *\n * // With motion/react\n * const { pathLength } = useDrawPath({ to: 0.9, duration: 1500 });\n * return (\n * <motion.circle\n * strokeDasharray=\"100\"\n * strokeDashoffset={100 - pathLength * 100}\n * pathLength=\"100\"\n * />\n * );\n *\n * // Manual control\n * const { pathLength, start, reset } = useDrawPath({\n * to: 1,\n * autoStart: false,\n * });\n * ```\n */\nexport function useDrawPath(options: UseDrawPathOptions): UseDrawPathResult {\n const {\n from = 0,\n to,\n duration: customDuration,\n motionStyle = \"standard\",\n easing = \"easeOutExpo\",\n delay = 0,\n autoStart = true,\n onComplete,\n onUpdate,\n enabled = true,\n } = options;\n\n // Get duration from motion style if not custom\n const duration = customDuration ?? getDuration(motionStyle, \"slow\");\n\n // State\n const [pathLength, setPathLength] = useState(from);\n const [isAnimating, setIsAnimating] = useState(false);\n const [isComplete, setIsComplete] = useState(false);\n\n // Refs for animation control\n const animationRef = useRef<number | null>(null);\n const startTimeRef = useRef<number | null>(null);\n const pausedTimeRef = useRef<number | null>(null);\n const currentFromRef = useRef(from);\n const currentToRef = useRef(to);\n\n // Reduced motion\n const prefersReducedMotion = useReducedMotion();\n\n // Cancel animation\n const cancelAnimation = useCallback(() => {\n if (animationRef.current !== null) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n }, []);\n\n // Animation frame handler\n const animate = useCallback(\n (timestamp: number) => {\n if (startTimeRef.current === null) {\n startTimeRef.current = timestamp;\n }\n\n const elapsed = timestamp - startTimeRef.current;\n const progress = Math.min(elapsed / duration, 1);\n const easedProgress = easingFunctions[easing](progress);\n\n const currentPathLength = currentFromRef.current + (currentToRef.current - currentFromRef.current) * easedProgress;\n setPathLength(currentPathLength);\n onUpdate?.(currentPathLength);\n\n if (progress < 1) {\n animationRef.current = requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n setIsComplete(true);\n onComplete?.();\n }\n },\n [duration, easing, onComplete, onUpdate],\n );\n\n // Start animation\n const start = useCallback(() => {\n if (!enabled) {\n setPathLength(currentToRef.current);\n setIsComplete(true);\n return;\n }\n\n // Handle reduced motion - jump to end value immediately\n if (prefersReducedMotion) {\n setPathLength(currentToRef.current);\n setIsComplete(true);\n onComplete?.();\n return;\n }\n\n cancelAnimation();\n setIsComplete(false);\n startTimeRef.current = null;\n pausedTimeRef.current = null;\n\n const startAnimation = () => {\n setIsAnimating(true);\n animationRef.current = requestAnimationFrame(animate);\n };\n\n if (delay > 0) {\n setTimeout(startAnimation, delay);\n } else {\n startAnimation();\n }\n }, [enabled, prefersReducedMotion, cancelAnimation, animate, delay, onComplete]);\n\n // Pause animation\n const pause = useCallback(() => {\n if (isAnimating && animationRef.current !== null) {\n pausedTimeRef.current = performance.now();\n cancelAnimation();\n setIsAnimating(false);\n }\n }, [isAnimating, cancelAnimation]);\n\n // Resume animation\n const resume = useCallback(() => {\n if (!isAnimating && !isComplete && pausedTimeRef.current !== null && startTimeRef.current !== null) {\n // Adjust start time to account for paused duration\n const pausedDuration = performance.now() - pausedTimeRef.current;\n startTimeRef.current += pausedDuration;\n pausedTimeRef.current = null;\n setIsAnimating(true);\n animationRef.current = requestAnimationFrame(animate);\n }\n }, [isAnimating, isComplete, animate]);\n\n // Reset to starting value\n const reset = useCallback(() => {\n cancelAnimation();\n setPathLength(currentFromRef.current);\n setIsAnimating(false);\n setIsComplete(false);\n startTimeRef.current = null;\n pausedTimeRef.current = null;\n }, [cancelAnimation]);\n\n // Update target value\n const update = useCallback(\n (newTo: number) => {\n currentFromRef.current = pathLength;\n currentToRef.current = newTo;\n start();\n },\n [pathLength, start],\n );\n\n // Auto-start on mount - intentionally only runs once\n // biome-ignore lint/correctness/useExhaustiveDependencies: We only want to start animation on mount, not on every dependency change\n useEffect(() => {\n if (autoStart) {\n currentFromRef.current = from;\n currentToRef.current = to;\n start();\n }\n\n return () => {\n cancelAnimation();\n };\n }, []);\n\n // Update target when `to` prop changes\n useEffect(() => {\n if (to !== currentToRef.current && isComplete) {\n update(to);\n }\n }, [to, isComplete, update]);\n\n return {\n pathLength,\n isAnimating,\n isComplete,\n start,\n pause,\n resume,\n reset,\n update,\n prefersReducedMotion,\n };\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { type AmbientPathsConfig, type ComponentType, getPreset, type LightRaysConfig, type MotionPreset } from \"../presets/motion-presets\";\n\n/** CSS motion variables read from the theme */\ninterface MotionCSSVariables {\n /** Speed/duration multiplier (0 = no motion, 1 = normal) */\n durationMultiplier: number;\n /** Minimum opacity for motion animations */\n opacityMin: number;\n /** Maximum opacity for motion animations */\n opacityMax: number;\n}\n\n/** Computed motion configuration for paths component */\nexport interface ComputedPathsMotion {\n /** Computed base duration (preset * CSS multiplier) */\n baseDuration: number;\n /** Computed opacity keyframes respecting CSS bounds */\n opacity: [number, number, number];\n /** Easing function from preset */\n ease: \"linear\" | \"easeInOut\";\n /** Delay variation factor from preset */\n delayVariation: number;\n /** Duration variation factor from preset */\n durationVariation: number;\n /** Whether reduced motion is preferred */\n prefersReducedMotion: boolean;\n}\n\n/** Computed motion configuration for rays component */\nexport interface ComputedRaysMotion {\n /** Computed cycle duration (preset speed * CSS multiplier) */\n cycleDuration: number;\n /** Base intensity from preset */\n intensity: number;\n /** Swing variation from preset */\n swingVariation: number;\n /** Whether reduced motion is preferred */\n prefersReducedMotion: boolean;\n}\n\n/**\n * Reads motion CSS variables from the document root.\n * Throws when not in a browser environment or when required CSS variables are missing/invalid.\n */\nfunction readCSSVariables(): MotionCSSVariables {\n if (typeof window === \"undefined\") {\n throw new Error(\"useMotionPreset/readCSSVariables requires a browser environment\");\n }\n\n const root = document.documentElement;\n const styles = getComputedStyle(root);\n\n const parseMotionVar = (value: string): number => {\n const parsed = parseFloat(value);\n if (Number.isNaN(parsed)) {\n throw new Error(\"Motion CSS variable could not be parsed as a number\");\n }\n return parsed;\n };\n\n return {\n durationMultiplier: parseMotionVar(styles.getPropertyValue(\"--motion-duration-multiplier\")),\n opacityMin: parseMotionVar(styles.getPropertyValue(\"--motion-opacity-min\")),\n opacityMax: parseMotionVar(styles.getPropertyValue(\"--motion-opacity-max\")),\n };\n}\n\n/**\n * Computes paths motion configuration from preset and CSS variables.\n */\nfunction computePathsMotion(preset: AmbientPathsConfig, cssVars: MotionCSSVariables, prefersReducedMotion: boolean): ComputedPathsMotion {\n if (prefersReducedMotion) {\n return {\n baseDuration: 0,\n opacity: [cssVars.opacityMin, cssVars.opacityMin, cssVars.opacityMin],\n ease: preset.ease,\n delayVariation: 0,\n durationVariation: 0,\n prefersReducedMotion: true,\n };\n }\n\n return {\n baseDuration: preset.duration * cssVars.durationMultiplier,\n opacity: [\n Math.max(preset.opacity[0], cssVars.opacityMin),\n Math.min(preset.opacity[1], cssVars.opacityMax),\n Math.max(preset.opacity[2], cssVars.opacityMin),\n ],\n ease: preset.ease,\n delayVariation: preset.delayVariation,\n durationVariation: preset.durationVariation,\n prefersReducedMotion: false,\n };\n}\n\n/**\n * Computes rays motion configuration from preset and CSS variables.\n */\nfunction computeRaysMotion(preset: LightRaysConfig, cssVars: MotionCSSVariables, prefersReducedMotion: boolean): ComputedRaysMotion {\n if (prefersReducedMotion) {\n return {\n cycleDuration: 0,\n intensity: 0,\n swingVariation: 0,\n prefersReducedMotion: true,\n };\n }\n\n return {\n cycleDuration: Math.max(preset.speed * cssVars.durationMultiplier, 0.1),\n intensity: preset.intensity,\n swingVariation: preset.swingVariation,\n prefersReducedMotion: false,\n };\n}\n\n/**\n * Hook for using motion presets with theme-aware CSS variables.\n *\n * Provides computed motion configuration that:\n * - Respects `prefers-reduced-motion` preference\n * - Reads and applies CSS motion variables from the theme\n * - Memoizes calculations to prevent unnecessary re-renders\n *\n * @param component - The component type (\"paths\" | \"rays\")\n * @param preset - The motion preset (\"slow\" | \"medium\" | \"fast\")\n * @returns Computed motion configuration for the component\n *\n * @example\n * ```tsx\n * // In BackgroundPaths component\n * const motion = useMotionPreset(\"paths\", \"medium\");\n * // Returns: { baseDuration: 20, opacity: [...], ... }\n *\n * // In LightRays component\n * const motion = useMotionPreset(\"rays\", \"fast\");\n * // Returns: { cycleDuration: 8, intensity: 0.7, ... }\n * ```\n */\nexport function useMotionPreset(component: \"paths\", preset: MotionPreset): ComputedPathsMotion;\nexport function useMotionPreset(component: \"rays\", preset: MotionPreset): ComputedRaysMotion;\nexport function useMotionPreset(component: ComponentType, preset: MotionPreset): ComputedPathsMotion | ComputedRaysMotion {\n // Track reduced motion preference with state for reactivity\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n // Track CSS variables (read from document; throws in SSR or when vars are invalid)\n const [cssVars, setCssVars] = useState<MotionCSSVariables>(() => {\n if (typeof window === \"undefined\") {\n throw new Error(\"useMotionPreset requires a browser environment\");\n }\n return readCSSVariables();\n });\n\n // Listen for reduced motion preference changes\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => setPrefersReducedMotion(e.matches);\n mediaQuery.addEventListener(\"change\", handler);\n return () => mediaQuery.removeEventListener(\"change\", handler);\n }, []);\n\n // Read CSS variables on mount and when theme might change\n useEffect(() => {\n setCssVars(readCSSVariables());\n\n // Listen for theme changes via attribute mutations on document\n const observer = new MutationObserver(() => {\n setCssVars(readCSSVariables());\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\"],\n });\n\n return () => observer.disconnect();\n }, []);\n\n // Compute and memoize the motion configuration\n return useMemo(() => {\n if (component === \"paths\") {\n const presetConfig = getPreset(preset, \"paths\");\n return computePathsMotion(presetConfig, cssVars, prefersReducedMotion);\n }\n const presetConfig = getPreset(preset, \"rays\");\n return computeRaysMotion(presetConfig, cssVars, prefersReducedMotion);\n }, [component, preset, cssVars, prefersReducedMotion]);\n}\n","/**\n * Motion Presets Utility\n *\n * Defines motion preset configurations for ambient animation components.\n * These presets provide consistent, theme-aware motion settings.\n */\n\n/** Available motion speed presets */\nexport type MotionPreset = \"slow\" | \"medium\" | \"fast\";\n\n/** Component types that support motion presets */\nexport type ComponentType = \"paths\" | \"rays\";\n\n/** Configuration for ambient paths animations */\nexport interface AmbientPathsConfig {\n /** Base duration in seconds */\n duration: number;\n /** Opacity keyframes [start, peak, end] */\n opacity: [number, number, number];\n /** Easing function */\n ease: \"linear\" | \"easeInOut\";\n /** Random delay variation factor (0-1) */\n delayVariation: number;\n /** Random duration variation factor (0-1) */\n durationVariation: number;\n}\n\n/** Configuration for light rays animations */\nexport interface LightRaysConfig {\n /** Base speed/cycle duration in seconds */\n speed: number;\n /** Base intensity multiplier (0-1) */\n intensity: number;\n /** Swing angle variation factor */\n swingVariation: number;\n}\n\n/** Union type for all preset configurations */\nexport type PresetConfig = AmbientPathsConfig | LightRaysConfig;\n\n/**\n * Preset configurations for BackgroundPaths component.\n * Each preset defines duration, opacity, and variation settings.\n */\nexport const ambientPaths: Record<MotionPreset, AmbientPathsConfig> = {\n slow: {\n duration: 30,\n opacity: [0.2, 0.4, 0.2],\n ease: \"easeInOut\",\n delayVariation: 0.3,\n durationVariation: 0.5,\n },\n medium: {\n duration: 20,\n opacity: [0.3, 0.6, 0.3],\n ease: \"easeInOut\",\n delayVariation: 0.25,\n durationVariation: 0.5,\n },\n fast: {\n duration: 12,\n opacity: [0.4, 0.8, 0.4],\n ease: \"linear\",\n delayVariation: 0.2,\n durationVariation: 0.4,\n },\n};\n\n/**\n * Preset configurations for LightRays component.\n * Each preset defines speed, intensity, and swing settings.\n */\nexport const lightRays: Record<MotionPreset, LightRaysConfig> = {\n slow: {\n speed: 20,\n intensity: 0.3,\n swingVariation: 1.8,\n },\n medium: {\n speed: 14,\n intensity: 0.5,\n swingVariation: 1.5,\n },\n fast: {\n speed: 8,\n intensity: 0.7,\n swingVariation: 1.2,\n },\n};\n\n/**\n * Retrieves a preset configuration for a specific component type.\n *\n * @param preset - The motion preset name (\"slow\" | \"medium\" | \"fast\")\n * @param component - The component type (\"paths\" | \"rays\")\n * @returns The preset configuration for the specified component\n *\n * @example\n * ```ts\n * const pathsPreset = getPreset(\"medium\", \"paths\");\n * // Returns: { duration: 20, opacity: [0.3, 0.6, 0.3], ... }\n *\n * const raysPreset = getPreset(\"fast\", \"rays\");\n * // Returns: { speed: 8, intensity: 0.7, swingVariation: 1.2 }\n * ```\n */\nexport function getPreset(preset: MotionPreset, component: \"paths\"): AmbientPathsConfig;\nexport function getPreset(preset: MotionPreset, component: \"rays\"): LightRaysConfig;\nexport function getPreset(preset: MotionPreset, component: ComponentType): PresetConfig {\n if (component === \"paths\") {\n return ambientPaths[preset];\n }\n return lightRays[preset];\n}\n\n/**\n * Merges a preset configuration with a base configuration.\n * Useful for combining preset values with component-specific overrides.\n *\n * @param preset - The preset configuration to apply\n * @param baseConfig - The base configuration to merge with\n * @returns Merged configuration with preset values taking precedence\n *\n * @example\n * ```ts\n * const preset = getPreset(\"medium\", \"paths\");\n * const result = applyMotionPreset(preset, { count: 36 });\n * // Returns: { duration: 20, opacity: [...], count: 36, ... }\n * ```\n */\nexport function applyMotionPreset<T extends Record<string, unknown>>(preset: PresetConfig, baseConfig: T): PresetConfig & T {\n return { ...baseConfig, ...preset };\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * Component Animation Presets\n *\n * Defines animation presets for component entrance, exit, and transition animations.\n * Each preset provides Motion library compatible configurations that work with\n * the motion style system.\n *\n * @packageDocumentation\n */\n\nimport { getDuration, getSpringConfig, type MotionStyle, msToSeconds } from \"./motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Use case categories for component presets.\n * Used by AI tools to select appropriate animations.\n */\nexport type PresetUseCase = \"entrance\" | \"exit\" | \"transition\" | \"emphasis\" | \"reveal\";\n\n/**\n * Context hints for where the animation will be used.\n * Helps AI tools make appropriate selections.\n */\nexport type PresetContext = \"modal\" | \"dropdown\" | \"tooltip\" | \"drawer\" | \"card\" | \"list-item\" | \"notification\" | \"page\" | \"section\" | \"hero\";\n\n/**\n * Animation variants for Motion library's AnimatePresence.\n */\nexport interface AnimationVariants {\n /** Initial/hidden state */\n initial: Record<string, unknown>;\n /** Animated/visible state */\n animate: Record<string, unknown>;\n /** Exit state (optional, defaults to initial) */\n exit?: Record<string, unknown>;\n}\n\n/**\n * Complete animation props for Motion library components.\n */\nexport interface ComponentAnimationProps {\n initial: boolean | Record<string, unknown>;\n animate: Record<string, unknown>;\n exit?: Record<string, unknown>;\n transition: Record<string, unknown>;\n}\n\n/**\n * Metadata for component presets, used by AI selection system.\n */\nexport interface PresetMetadata {\n /** Unique identifier for the preset */\n id: string;\n /** Human-readable name */\n name: string;\n /** Description of the animation effect */\n description: string;\n /** Primary use cases */\n useCase: PresetUseCase[];\n /** Recommended contexts */\n context: PresetContext[];\n /** Intensity level (1-5, where 3 is standard) */\n intensity: number;\n /** Whether this preset involves movement */\n hasMovement: boolean;\n /** Direction of movement (if applicable) */\n direction?: \"up\" | \"down\" | \"left\" | \"right\" | \"in\" | \"out\";\n}\n\n/**\n * A component animation preset with metadata.\n */\nexport interface ComponentPreset {\n /** Preset metadata for AI selection */\n metadata: PresetMetadata;\n /**\n * Gets the animation props for a given motion style.\n * @param style - The motion style to apply\n * @param options - Optional customization options\n */\n getProps: (style: MotionStyle, options?: PresetOptions) => ComponentAnimationProps;\n}\n\n/**\n * Options for customizing preset behavior.\n */\nexport interface PresetOptions {\n /** Override the default duration */\n duration?: number;\n /** Override the default delay */\n delay?: number;\n /** Custom distance for slide animations (px) */\n distance?: number;\n /** Custom scale factor */\n scale?: number;\n /** Custom rotation angle (degrees) */\n rotation?: number;\n /** Use spring physics instead of tween */\n useSpring?: boolean;\n}\n\n// =============================================================================\n// Preset Factory Helpers\n// =============================================================================\n\n/**\n * Creates a tween transition configuration.\n */\nfunction createTweenTransition(style: MotionStyle, options?: PresetOptions): Record<string, unknown> {\n const duration = options?.duration ?? getDuration(style, \"normal\");\n return {\n type: \"tween\",\n duration: msToSeconds(duration),\n ease: [0.25, 0.1, 0.25, 1], // cubic-bezier ease-out\n delay: options?.delay ? msToSeconds(options.delay) : 0,\n };\n}\n\n/**\n * Creates a spring transition configuration.\n */\nfunction createSpringTransition(style: MotionStyle, options?: PresetOptions): Record<string, unknown> {\n const spring = getSpringConfig(style);\n return {\n type: \"spring\",\n stiffness: spring.stiffness,\n damping: spring.damping,\n mass: spring.mass,\n delay: options?.delay ? msToSeconds(options.delay) : 0,\n };\n}\n\n/**\n * Selects the appropriate transition based on options.\n */\nfunction getTransition(style: MotionStyle, preferSpring: boolean, options?: PresetOptions): Record<string, unknown> {\n const useSpring = options?.useSpring ?? preferSpring;\n return useSpring ? createSpringTransition(style, options) : createTweenTransition(style, options);\n}\n\n// =============================================================================\n// Fade Presets\n// =============================================================================\n\n/**\n * Fade in animation - opacity transition from 0 to 1.\n *\n * @ai-hint Use for subtle entrances. Works well for tooltips, dropdowns,\n * and any content that should appear without drawing too much attention.\n * Combines well with other presets for compound animations.\n */\nexport const fadeIn: ComponentPreset = {\n metadata: {\n id: \"fadeIn\",\n name: \"Fade In\",\n description: \"Smooth opacity transition from invisible to visible\",\n useCase: [\"entrance\", \"reveal\"],\n context: [\"tooltip\", \"dropdown\", \"modal\", \"notification\"],\n intensity: 2,\n hasMovement: false,\n },\n getProps: (style, options) => ({\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: createTweenTransition(style, options),\n }),\n};\n\n/**\n * Fade out animation - opacity transition from 1 to 0.\n *\n * @ai-hint Use for gentle exits. Best when paired with fadeIn for\n * symmetrical enter/exit animations.\n */\nexport const fadeOut: ComponentPreset = {\n metadata: {\n id: \"fadeOut\",\n name: \"Fade Out\",\n description: \"Smooth opacity transition from visible to invisible\",\n useCase: [\"exit\"],\n context: [\"tooltip\", \"dropdown\", \"modal\", \"notification\"],\n intensity: 2,\n hasMovement: false,\n },\n getProps: (style, options) => ({\n initial: { opacity: 1 },\n animate: { opacity: 0 },\n transition: createTweenTransition(style, options),\n }),\n};\n\n// =============================================================================\n// Slide Presets\n// =============================================================================\n\nconst DEFAULT_SLIDE_DISTANCE = 20;\n\n/**\n * Slide up animation - element moves upward while fading in.\n *\n * @ai-hint Use for content that appears from below. Great for modals,\n * bottom sheets, list items, and card reveals. Creates a natural\n * \"rising\" feeling.\n */\nexport const slideUp: ComponentPreset = {\n metadata: {\n id: \"slideUp\",\n name: \"Slide Up\",\n description: \"Element slides upward while fading in\",\n useCase: [\"entrance\", \"reveal\"],\n context: [\"modal\", \"card\", \"list-item\", \"notification\"],\n intensity: 3,\n hasMovement: true,\n direction: \"up\",\n },\n getProps: (style, options) => {\n const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;\n return {\n initial: { opacity: 0, y: distance },\n animate: { opacity: 1, y: 0 },\n exit: { opacity: 0, y: distance },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Slide down animation - element moves downward while fading in.\n *\n * @ai-hint Use for dropdowns, menus, and content appearing from above.\n * Creates a natural \"falling\" or \"dropping\" feeling.\n */\nexport const slideDown: ComponentPreset = {\n metadata: {\n id: \"slideDown\",\n name: \"Slide Down\",\n description: \"Element slides downward while fading in\",\n useCase: [\"entrance\", \"reveal\"],\n context: [\"dropdown\", \"tooltip\", \"notification\"],\n intensity: 3,\n hasMovement: true,\n direction: \"down\",\n },\n getProps: (style, options) => {\n const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;\n return {\n initial: { opacity: 0, y: -distance },\n animate: { opacity: 1, y: 0 },\n exit: { opacity: 0, y: -distance },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Slide left animation - element moves leftward while fading in.\n *\n * @ai-hint Use for side panels closing, content sliding out,\n * or navigation transitions moving backward.\n */\nexport const slideLeft: ComponentPreset = {\n metadata: {\n id: \"slideLeft\",\n name: \"Slide Left\",\n description: \"Element slides leftward while fading in\",\n useCase: [\"entrance\", \"transition\"],\n context: [\"drawer\", \"page\", \"section\"],\n intensity: 3,\n hasMovement: true,\n direction: \"left\",\n },\n getProps: (style, options) => {\n const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;\n return {\n initial: { opacity: 0, x: distance },\n animate: { opacity: 1, x: 0 },\n exit: { opacity: 0, x: -distance },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Slide right animation - element moves rightward while fading in.\n *\n * @ai-hint Use for side panels opening, drawers, and navigation\n * transitions moving forward.\n */\nexport const slideRight: ComponentPreset = {\n metadata: {\n id: \"slideRight\",\n name: \"Slide Right\",\n description: \"Element slides rightward while fading in\",\n useCase: [\"entrance\", \"transition\"],\n context: [\"drawer\", \"page\", \"section\"],\n intensity: 3,\n hasMovement: true,\n direction: \"right\",\n },\n getProps: (style, options) => {\n const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;\n return {\n initial: { opacity: 0, x: -distance },\n animate: { opacity: 1, x: 0 },\n exit: { opacity: 0, x: distance },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n// =============================================================================\n// Scale Presets\n// =============================================================================\n\nconst DEFAULT_SCALE_FROM = 0.95;\nconst DEFAULT_ZOOM_SCALE = 0.5;\n\n/**\n * Scale animation - subtle scale with fade.\n *\n * @ai-hint Use for modals, dialogs, and content that should appear\n * to \"pop\" into view. More subtle than zoom animations.\n */\nexport const scale: ComponentPreset = {\n metadata: {\n id: \"scale\",\n name: \"Scale\",\n description: \"Subtle scale transition with fade\",\n useCase: [\"entrance\", \"emphasis\"],\n context: [\"modal\", \"card\", \"notification\"],\n intensity: 3,\n hasMovement: true,\n direction: \"in\",\n },\n getProps: (style, options) => {\n const scaleFrom = options?.scale ?? DEFAULT_SCALE_FROM;\n return {\n initial: { opacity: 0, scale: scaleFrom },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, scale: scaleFrom },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Zoom in animation - dramatic scale from small to full size.\n *\n * @ai-hint Use for hero elements, feature highlights, and content\n * that needs strong visual emphasis. More dramatic than scale.\n */\nexport const zoomIn: ComponentPreset = {\n metadata: {\n id: \"zoomIn\",\n name: \"Zoom In\",\n description: \"Dramatic zoom from small to full size\",\n useCase: [\"entrance\", \"emphasis\"],\n context: [\"hero\", \"modal\", \"card\"],\n intensity: 4,\n hasMovement: true,\n direction: \"in\",\n },\n getProps: (style, options) => {\n const scaleFrom = options?.scale ?? DEFAULT_ZOOM_SCALE;\n return {\n initial: { opacity: 0, scale: scaleFrom },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, scale: scaleFrom },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Zoom out animation - scale from large to normal size.\n *\n * @ai-hint Use for content appearing to \"approach\" the user,\n * or for dramatic entrances that start larger than final size.\n */\nexport const zoomOut: ComponentPreset = {\n metadata: {\n id: \"zoomOut\",\n name: \"Zoom Out\",\n description: \"Scale from larger to normal size\",\n useCase: [\"entrance\", \"emphasis\"],\n context: [\"hero\", \"modal\"],\n intensity: 4,\n hasMovement: true,\n direction: \"out\",\n },\n getProps: (style, options) => {\n const scaleTo = options?.scale ?? 1.1;\n return {\n initial: { opacity: 0, scale: scaleTo },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, scale: scaleTo },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n// =============================================================================\n// Rotation Presets\n// =============================================================================\n\nconst DEFAULT_ROTATION = 10;\n\n/**\n * Rotate animation - subtle rotation with fade.\n *\n * @ai-hint Use sparingly for playful interfaces or to add visual interest.\n * Best with playful motion style. Can cause motion sickness if overused.\n */\nexport const rotate: ComponentPreset = {\n metadata: {\n id: \"rotate\",\n name: \"Rotate\",\n description: \"Subtle rotation animation with fade\",\n useCase: [\"entrance\", \"emphasis\"],\n context: [\"card\", \"notification\"],\n intensity: 4,\n hasMovement: true,\n },\n getProps: (style, options) => {\n const rotation = options?.rotation ?? DEFAULT_ROTATION;\n return {\n initial: { opacity: 0, rotate: -rotation },\n animate: { opacity: 1, rotate: 0 },\n exit: { opacity: 0, rotate: rotation },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n// =============================================================================\n// Compound Presets\n// =============================================================================\n\n/**\n * Slide and scale animation - combines slide up with scale.\n *\n * @ai-hint Use for important content that needs extra visual emphasis.\n * Great for hero sections, feature cards, and call-to-action elements.\n */\nexport const slideUpScale: ComponentPreset = {\n metadata: {\n id: \"slideUpScale\",\n name: \"Slide Up & Scale\",\n description: \"Combines upward slide with subtle scale\",\n useCase: [\"entrance\", \"emphasis\"],\n context: [\"hero\", \"card\", \"section\"],\n intensity: 4,\n hasMovement: true,\n direction: \"up\",\n },\n getProps: (style, options) => {\n const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;\n const scaleFrom = options?.scale ?? 0.98;\n return {\n initial: { opacity: 0, y: distance, scale: scaleFrom },\n animate: { opacity: 1, y: 0, scale: 1 },\n exit: { opacity: 0, y: distance, scale: scaleFrom },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Flip animation - 3D flip effect.\n *\n * @ai-hint Use for card flips, reveals, and playful interactions.\n * Works best with playful motion style. Use with perspective.\n */\nexport const flip: ComponentPreset = {\n metadata: {\n id: \"flip\",\n name: \"Flip\",\n description: \"3D flip animation on the X axis\",\n useCase: [\"entrance\", \"transition\"],\n context: [\"card\"],\n intensity: 5,\n hasMovement: true,\n },\n getProps: (style, options) => {\n const rotation = options?.rotation ?? 90;\n return {\n initial: { opacity: 0, rotateX: rotation },\n animate: { opacity: 1, rotateX: 0 },\n exit: { opacity: 0, rotateX: -rotation },\n transition: getTransition(style, true, options),\n };\n },\n};\n\n/**\n * Expand animation - height expansion for accordions and collapsibles.\n *\n * @ai-hint Use for accordions, collapsible sections, and expandable content.\n * Animates height from 0 to auto.\n */\nexport const expand: ComponentPreset = {\n metadata: {\n id: \"expand\",\n name: \"Expand\",\n description: \"Height expansion animation\",\n useCase: [\"entrance\", \"reveal\"],\n context: [\"section\"],\n intensity: 2,\n hasMovement: true,\n direction: \"down\",\n },\n getProps: (style, options) => ({\n initial: { opacity: 0, height: 0 },\n animate: { opacity: 1, height: \"auto\" },\n exit: { opacity: 0, height: 0 },\n transition: createTweenTransition(style, options),\n }),\n};\n\n// =============================================================================\n// Preset Registry\n// =============================================================================\n\n/**\n * All available component presets.\n */\nexport const componentPresets = {\n fadeIn,\n fadeOut,\n slideUp,\n slideDown,\n slideLeft,\n slideRight,\n scale,\n zoomIn,\n zoomOut,\n rotate,\n slideUpScale,\n flip,\n expand,\n} as const;\n\n/**\n * Type for preset names.\n */\nexport type ComponentPresetName = keyof typeof componentPresets;\n\n/**\n * Gets a component preset by name.\n *\n * @param name - The preset name\n * @returns The component preset\n *\n * @example\n * ```ts\n * const preset = getComponentPreset(\"fadeIn\");\n * const props = preset.getProps(\"standard\");\n * ```\n */\nexport function getComponentPreset(name: ComponentPresetName): ComponentPreset {\n return componentPresets[name];\n}\n\n/**\n * Gets all presets matching a use case.\n *\n * @param useCase - The use case to filter by\n * @returns Array of matching presets\n *\n * @example\n * ```ts\n * const entrancePresets = getPresetsByUseCase(\"entrance\");\n * // Returns: [fadeIn, slideUp, slideDown, ...]\n * ```\n */\nexport function getPresetsByUseCase(useCase: PresetUseCase): ComponentPreset[] {\n return Object.values(componentPresets).filter((preset) => preset.metadata.useCase.includes(useCase));\n}\n\n/**\n * Gets all presets suitable for a context.\n *\n * @param context - The context to filter by\n * @returns Array of matching presets\n *\n * @example\n * ```ts\n * const modalPresets = getPresetsByContext(\"modal\");\n * // Returns: [fadeIn, slideUp, scale, zoomIn]\n * ```\n */\nexport function getPresetsByContext(context: PresetContext): ComponentPreset[] {\n return Object.values(componentPresets).filter((preset) => preset.metadata.context.includes(context));\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * Micro-Interaction Animation Presets\n *\n * Provides a collection of reusable micro-interaction animations for common UI patterns.\n * Each preset adapts to the chosen MotionStyle, respecting user preferences including\n * reduced motion settings.\n *\n * @packageDocumentation\n */\n\nimport type { MotionStyle } from \"./motion-styles\";\nimport { getMotionStyle, msToSeconds } from \"./motion-styles\";\n\n/**\n * Props returned by micro-interaction preset functions.\n * Compatible with Motion library's component props.\n */\nexport interface MicroInteractionProps {\n /** Animation values applied on hover */\n whileHover?: Record<string, unknown>;\n /** Animation values applied while pressed/tapped */\n whileTap?: Record<string, unknown>;\n /** Animation values applied while focused */\n whileFocus?: Record<string, unknown>;\n /** Transition configuration for the animation */\n transition?: Record<string, unknown>;\n /** Initial animation state */\n initial?: Record<string, unknown>;\n /** Target animation state */\n animate?: Record<string, unknown>;\n}\n\n/**\n * Definition for a micro-interaction preset.\n * Includes metadata for documentation and AI-assisted selection.\n */\nexport interface MicroInteractionPreset {\n /** Unique identifier for the preset */\n name: string;\n /** Human-readable description of the animation effect */\n description: string;\n /** Suggested use cases for this animation */\n useCase: string[];\n /** Function that generates Motion props based on the motion style */\n getProps: (style: MotionStyle) => MicroInteractionProps;\n}\n\n/**\n * Checks if the user prefers reduced motion.\n * Returns true if reduced motion is preferred, false otherwise.\n *\n * @returns Whether reduced motion is preferred\n */\nfunction prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/**\n * Returns empty props for reduced motion scenarios.\n * Animations are disabled while maintaining component functionality.\n */\nfunction getReducedMotionProps(): MicroInteractionProps {\n return {};\n}\n\n// =============================================================================\n// BUTTON PRESS PRESET\n// =============================================================================\n\n/**\n * Button Press Micro-Interaction\n *\n * Creates a subtle press effect where the element scales down slightly when clicked\n * and springs back to its original size on release. Provides tactile feedback for\n * interactive elements.\n *\n * @ai-hint Use buttonPress for clickable elements like buttons, cards, or list items\n * that need tactile feedback. Best for primary actions and interactive controls.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { buttonPress } from \"@enact-ui/animate\";\n *\n * function Button({ children }) {\n * const props = buttonPress.getProps(\"standard\");\n * return <motion.button {...props}>{children}</motion.button>;\n * }\n * ```\n */\nexport const buttonPress: MicroInteractionPreset = {\n name: \"buttonPress\",\n description: \"Scale down slightly on press, spring back on release\",\n useCase: [\"buttons\", \"clickable cards\", \"list items\", \"interactive elements\", \"call-to-action\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const scaleAmount = style === \"subtle\" ? 0.98 : style === \"playful\" ? 0.92 : 0.95;\n\n return {\n whileTap: {\n scale: scaleAmount,\n },\n whileHover: {\n scale: style === \"subtle\" ? 1.01 : 1.02,\n },\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n };\n },\n};\n\n// =============================================================================\n// CARD HOVER PRESET\n// =============================================================================\n\n/**\n * Card Hover Micro-Interaction\n *\n * Creates a subtle lift effect with shadow enhancement when hovering over card-like\n * elements. Provides visual depth and indicates interactivity.\n *\n * @ai-hint Use cardHover for cards, tiles, or panels that are clickable or expandable.\n * Creates a \"lifting\" effect that suggests the element can be interacted with.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { cardHover } from \"@enact-ui/animate\";\n *\n * function Card({ children }) {\n * const props = cardHover.getProps(\"standard\");\n * return <motion.article {...props}>{children}</motion.article>;\n * }\n * ```\n */\nexport const cardHover: MicroInteractionPreset = {\n name: \"cardHover\",\n description: \"Subtle lift with shadow enhancement on hover\",\n useCase: [\"cards\", \"tiles\", \"panels\", \"content blocks\", \"media items\", \"product listings\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const liftAmount = style === \"subtle\" ? -2 : style === \"playful\" ? -8 : -4;\n const shadowIntensity = style === \"subtle\" ? 0.08 : style === \"playful\" ? 0.2 : 0.12;\n\n return {\n whileHover: {\n y: liftAmount,\n boxShadow: `0 ${Math.abs(liftAmount) * 2}px ${Math.abs(liftAmount) * 4}px rgba(0, 0, 0, ${shadowIntensity})`,\n },\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n };\n },\n};\n\n// =============================================================================\n// ICON SPIN PRESET\n// =============================================================================\n\n/**\n * Icon Spin Micro-Interaction\n *\n * Performs a full 360-degree rotation, ideal for refresh icons, loading indicators,\n * or interactive feedback on icon clicks.\n *\n * @ai-hint Use iconSpin for refresh buttons, sync icons, or loading states.\n * Good for indicating an action is in progress or for playful icon interactions.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { iconSpin } from \"@enact-ui/animate\";\n *\n * function RefreshButton() {\n * const props = iconSpin.getProps(\"standard\");\n * return (\n * <motion.button {...props}>\n * <RefreshIcon />\n * </motion.button>\n * );\n * }\n * ```\n */\nexport const iconSpin: MicroInteractionPreset = {\n name: \"iconSpin\",\n description: \"360 degree rotation animation\",\n useCase: [\"refresh buttons\", \"sync icons\", \"loading indicators\", \"settings icons\", \"interactive icons\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n\n return {\n whileTap: {\n rotate: 360,\n },\n whileHover: {\n rotate: style === \"playful\" ? 15 : 5,\n },\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness * 0.8,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n };\n },\n};\n\n// =============================================================================\n// PULSE PRESET\n// =============================================================================\n\n/**\n * Pulse Micro-Interaction\n *\n * Creates a breathing/pulsing scale animation. Can be used for attention-grabbing\n * elements, loading states, or to indicate something is active/live.\n *\n * @ai-hint Use pulse for notifications, live indicators, or elements needing attention.\n * The breathing effect draws the eye without being too distracting.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { pulse } from \"@enact-ui/animate\";\n *\n * function LiveIndicator() {\n * const props = pulse.getProps(\"standard\");\n * return <motion.span {...props} className=\"live-dot\" />;\n * }\n * ```\n */\nexport const pulse: MicroInteractionPreset = {\n name: \"pulse\",\n description: \"Scale pulse animation with breathing effect\",\n useCase: [\"notifications\", \"live indicators\", \"attention grabbers\", \"status badges\", \"loading states\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const scaleRange = style === \"subtle\" ? 1.03 : style === \"playful\" ? 1.12 : 1.06;\n\n return {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, scaleRange, 1],\n },\n transition: {\n duration: msToSeconds(config.duration.slow),\n repeat: Infinity,\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// SHAKE PRESET\n// =============================================================================\n\n/**\n * Shake Micro-Interaction\n *\n * Horizontal shake animation commonly used for error states, invalid input,\n * or to indicate that an action cannot be completed.\n *\n * @ai-hint Use shake for error states, invalid form inputs, or denied actions.\n * The horizontal movement mimics the \"no\" head shake gesture.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { shake } from \"@enact-ui/animate\";\n *\n * function FormInput({ error }) {\n * const props = error ? shake.getProps(\"standard\") : {};\n * return <motion.input {...props} />;\n * }\n * ```\n */\nexport const shake: MicroInteractionPreset = {\n name: \"shake\",\n description: \"Horizontal shake animation for error states\",\n useCase: [\"error states\", \"invalid inputs\", \"denied actions\", \"form validation\", \"authentication failures\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const shakeDistance = style === \"subtle\" ? 4 : style === \"playful\" ? 12 : 8;\n\n return {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -shakeDistance, shakeDistance, -shakeDistance, shakeDistance, 0],\n },\n transition: {\n duration: msToSeconds(config.duration.fast),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// WIGGLE PRESET\n// =============================================================================\n\n/**\n * Wiggle Micro-Interaction\n *\n * Playful rotation wiggle animation. Great for drawing attention to elements\n * in a fun, non-intrusive way. Often used in gamified interfaces or\n * celebratory moments.\n *\n * @ai-hint Use wiggle for playful interfaces, gamification, or to draw attention\n * to elements in a fun way. Works well for icons, badges, or decorative elements.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { wiggle } from \"@enact-ui/animate\";\n *\n * function AchievementBadge() {\n * const props = wiggle.getProps(\"playful\");\n * return <motion.div {...props}><BadgeIcon /></motion.div>;\n * }\n * ```\n */\nexport const wiggle: MicroInteractionPreset = {\n name: \"wiggle\",\n description: \"Playful rotation wiggle animation\",\n useCase: [\"playful interfaces\", \"gamification\", \"attention indicators\", \"celebration elements\", \"decorative icons\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const wiggleAngle = style === \"subtle\" ? 3 : style === \"playful\" ? 12 : 6;\n\n return {\n whileHover: {\n rotate: [0, -wiggleAngle, wiggleAngle, -wiggleAngle, wiggleAngle, 0],\n },\n transition: {\n duration: msToSeconds(config.duration.normal),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// HEARTBEAT PRESET\n// =============================================================================\n\n/**\n * Heartbeat Micro-Interaction\n *\n * Double-pulse heartbeat pattern that creates a realistic heartbeat effect.\n * Perfect for health apps, like buttons, or emphasizing something \"alive\".\n *\n * @ai-hint Use heartbeat for health/fitness apps, like/love buttons, or to indicate\n * something is active/alive. The double-pulse mimics a real heartbeat rhythm.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { heartbeat } from \"@enact-ui/animate\";\n *\n * function LikeButton({ isLiked }) {\n * const props = isLiked ? heartbeat.getProps(\"playful\") : {};\n * return <motion.button {...props}><HeartIcon /></motion.button>;\n * }\n * ```\n */\nexport const heartbeat: MicroInteractionPreset = {\n name: \"heartbeat\",\n description: \"Double-pulse heartbeat pattern animation\",\n useCase: [\"like buttons\", \"health apps\", \"love reactions\", \"favorite indicators\", \"activity monitors\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const pulseScale = style === \"subtle\" ? 1.1 : style === \"playful\" ? 1.3 : 1.2;\n\n return {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, pulseScale, 1, pulseScale * 0.95, 1],\n },\n transition: {\n duration: msToSeconds(config.duration.slow * 1.5),\n repeat: Infinity,\n repeatDelay: msToSeconds(config.duration.normal),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// RUBBER BAND PRESET\n// =============================================================================\n\n/**\n * Rubber Band Micro-Interaction\n *\n * Elastic stretch and snap back animation inspired by the classic rubber band effect.\n * Creates a bouncy, playful feel that's perfect for attention-grabbing elements.\n *\n * @ai-hint Use rubberBand for emphasis animations, attention grabbers, or playful\n * interfaces. The elastic effect creates a memorable, tactile impression.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { rubberBand } from \"@enact-ui/animate\";\n *\n * function BouncyButton({ children }) {\n * const props = rubberBand.getProps(\"playful\");\n * return <motion.button {...props}>{children}</motion.button>;\n * }\n * ```\n */\nexport const rubberBand: MicroInteractionPreset = {\n name: \"rubberBand\",\n description: \"Elastic stretch and snap back animation\",\n useCase: [\"emphasis animations\", \"attention grabbers\", \"playful buttons\", \"celebration effects\", \"interactive feedback\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const stretchX = style === \"subtle\" ? 1.05 : style === \"playful\" ? 1.25 : 1.15;\n const stretchY = style === \"subtle\" ? 0.95 : style === \"playful\" ? 0.75 : 0.85;\n\n return {\n whileTap: {\n scaleX: [1, stretchX, 0.95, 1.05, 1],\n scaleY: [1, stretchY, 1.05, 0.95, 1],\n },\n whileHover: {\n scaleX: 1.02,\n scaleY: 0.98,\n },\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness * 0.6,\n damping: config.spring.damping * 0.5,\n mass: config.spring.mass,\n },\n };\n },\n};\n\n// =============================================================================\n// SCALE PRESET (Micro-Interaction)\n// =============================================================================\n\n/**\n * Scale Micro-Interaction\n *\n * Creates a scale animation effect for selection feedback. The element scales up\n * briefly when activated, providing satisfying tactile feedback for toggles,\n * checkboxes, and selection states.\n *\n * @ai-hint Use scale for checkboxes, toggles, radio buttons, or any selection\n * feedback. The scale effect provides clear visual confirmation of state change.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { scale } from \"@enact-ui/animate\";\n *\n * function Checkbox({ isSelected }) {\n * const props = isSelected ? scale.getProps(\"standard\") : {};\n * return <motion.div {...props}>{isSelected && <Check />}</motion.div>;\n * }\n * ```\n */\nexport const scale: MicroInteractionPreset = {\n name: \"scale\",\n description: \"Scale up animation for selection feedback\",\n useCase: [\"checkboxes\", \"toggles\", \"radio buttons\", \"selection states\", \"activation feedback\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const scaleAmount = style === \"subtle\" ? 1.05 : style === \"playful\" ? 1.2 : 1.1;\n\n return {\n initial: {\n scale: 0.8,\n opacity: 0,\n },\n animate: {\n scale: [0.8, scaleAmount, 1],\n opacity: 1,\n },\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n };\n },\n};\n\n// =============================================================================\n// SHIMMER PRESET\n// =============================================================================\n\n/**\n * Shimmer Micro-Interaction\n *\n * Creates a gradient shimmer effect that slides across the element.\n * Perfect for loading skeletons, progress indicators, or placeholder content.\n *\n * @ai-hint Use shimmer for skeleton loading states, progress bars, or placeholder\n * content. Creates a polished \"loading\" appearance that indicates content is coming.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { shimmer } from \"@enact-ui/animate\";\n *\n * function SkeletonCard() {\n * const props = shimmer.getProps(\"standard\");\n * return (\n * <motion.div\n * {...props}\n * className=\"h-20 bg-gray-200 rounded overflow-hidden relative\"\n * style={{\n * background: \"linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%)\",\n * backgroundSize: \"200% 100%\",\n * }}\n * />\n * );\n * }\n * ```\n */\nexport const shimmer: MicroInteractionPreset = {\n name: \"shimmer\",\n description: \"Gradient shimmer effect that slides across the element\",\n useCase: [\"skeleton loading\", \"placeholder content\", \"progress indicators\", \"loading states\", \"content placeholders\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const duration = style === \"subtle\" ? 2 : style === \"playful\" ? 1.2 : 1.5;\n\n return {\n initial: {\n backgroundPosition: \"200% 0\",\n },\n animate: {\n backgroundPosition: [\"-200% 0\", \"200% 0\"],\n },\n transition: {\n duration,\n repeat: Infinity,\n ease: config.easing.exit,\n repeatDelay: 0.5,\n },\n };\n },\n};\n\n// =============================================================================\n// GLOW PULSE PRESET\n// =============================================================================\n\n/**\n * Glow Pulse Micro-Interaction\n *\n * Creates a glowing pulse effect using box-shadow. Perfect for AI-generated\n * content indicators, special items, or elements that need extra emphasis.\n *\n * @ai-hint Use glowPulse for AI content indicators, featured items, or elements\n * needing premium emphasis. The glow effect creates a \"magical\" or \"special\" feel.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { glowPulse } from \"@enact-ui/animate\";\n *\n * function AIGeneratedBadge() {\n * const props = glowPulse.getProps(\"standard\");\n * return <motion.span {...props} className=\"ai-badge\">AI</motion.span>;\n * }\n * ```\n */\nexport const glowPulse: MicroInteractionPreset = {\n name: \"glowPulse\",\n description: \"Glowing pulse effect for emphasis and AI indicators\",\n useCase: [\"AI content indicators\", \"featured items\", \"premium elements\", \"special badges\", \"magical effects\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const glowIntensity = style === \"subtle\" ? 8 : style === \"playful\" ? 20 : 12;\n const glowColor = \"rgba(99, 102, 241, 0.6)\"; // Indigo glow\n\n return {\n initial: {\n boxShadow: `0 0 0 rgba(99, 102, 241, 0)`,\n },\n animate: {\n boxShadow: [`0 0 0 rgba(99, 102, 241, 0)`, `0 0 ${glowIntensity}px ${glowColor}`, `0 0 0 rgba(99, 102, 241, 0)`],\n },\n transition: {\n duration: msToSeconds(config.duration.slow * 1.5),\n repeat: Infinity,\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// PROGRESS FILL PRESET\n// =============================================================================\n\n/**\n * Progress Fill Micro-Interaction\n *\n * Animates width from 0% to the target value. Perfect for progress bars,\n * completion indicators, and skill bars.\n *\n * Note: This preset returns a function that takes the target percentage\n * and returns animation props. Use with scaleX transform for best performance.\n *\n * @ai-hint Use progressFill for progress bars, skill meters, or completion\n * indicators. Animates smoothly from 0 to the target percentage.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { progressFill } from \"@enact-ui/animate\";\n *\n * function ProgressBar({ value }: { value: number }) {\n * const props = progressFill.getProps(\"standard\");\n * return (\n * <div className=\"h-2 bg-gray-200 rounded overflow-hidden\">\n * <motion.div\n * {...props}\n * className=\"h-full bg-blue-500 origin-left\"\n * style={{ width: `${value}%` }}\n * />\n * </div>\n * );\n * }\n * ```\n */\nexport const progressFill: MicroInteractionPreset = {\n name: \"progressFill\",\n description: \"Animated fill from 0% to target width for progress bars\",\n useCase: [\"progress bars\", \"completion indicators\", \"skill bars\", \"loading progress\", \"data visualization\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const duration = style === \"subtle\" ? 0.6 : style === \"playful\" ? 1.2 : 0.8;\n\n return {\n initial: {\n scaleX: 0,\n },\n animate: {\n scaleX: 1,\n },\n transition: {\n duration,\n ease: config.easing.exit,\n },\n };\n },\n};\n\n// =============================================================================\n// PRESET COLLECTION\n// =============================================================================\n\n/**\n * All available micro-interaction presets indexed by name.\n *\n * @ai-hint Use this collection to iterate over all presets or to access\n * presets by name dynamically. Each preset adapts to the motion style.\n *\n * @example\n * ```tsx\n * import { microInteractions } from \"@enact-ui/animate\";\n *\n * // Get a specific preset by name\n * const pressProps = microInteractions.buttonPress.getProps(\"standard\");\n *\n * // List all available presets\n * Object.keys(microInteractions).forEach(name => {\n * console.log(microInteractions[name].description);\n * });\n * ```\n */\n// =============================================================================\n// CHECKMARK DRAW PRESET\n// =============================================================================\n\n/**\n * Checkmark Draw Micro-Interaction\n *\n * Animated checkmark draw effect, commonly used for success states,\n * completed tasks, or confirmation feedback.\n *\n * @ai-hint Use checkmarkDraw for success confirmations, completed checkboxes,\n * or any \"done\" state indication. The drawing animation provides satisfying feedback.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { checkmarkDraw } from \"@enact-ui/animate\";\n *\n * function SuccessIcon() {\n * const props = checkmarkDraw.getProps(\"standard\");\n * return <motion.svg {...props}><path d=\"M5 13l4 4L19 7\" /></motion.svg>;\n * }\n * ```\n */\nexport const checkmarkDraw: MicroInteractionPreset = {\n name: \"checkmarkDraw\",\n description: \"Animated checkmark draw effect for success states\",\n useCase: [\"success confirmations\", \"completed tasks\", \"checkboxes\", \"form submissions\", \"achievement unlocks\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const duration = style === \"subtle\" ? config.duration.fast : style === \"playful\" ? config.duration.slow : config.duration.normal;\n\n return {\n initial: {\n pathLength: 0,\n opacity: 0,\n },\n animate: {\n pathLength: 1,\n opacity: 1,\n },\n transition: {\n duration: msToSeconds(duration),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// SUCCESS FLASH PRESET\n// =============================================================================\n\n/**\n * Success Flash Micro-Interaction\n *\n * Brief highlight flash animation for success feedback. Creates a quick\n * visual confirmation without being distracting.\n *\n * @ai-hint Use successFlash for brief success highlights, toast notifications,\n * or inline success messages. The flash draws attention without lingering.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { successFlash } from \"@enact-ui/animate\";\n *\n * function SuccessMessage() {\n * const props = successFlash.getProps(\"standard\");\n * return <motion.div {...props}>Saved!</motion.div>;\n * }\n * ```\n */\nexport const successFlash: MicroInteractionPreset = {\n name: \"successFlash\",\n description: \"Brief success highlight flash animation\",\n useCase: [\"success toasts\", \"inline confirmations\", \"save indicators\", \"completion feedback\", \"achievement notifications\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const scale = style === \"subtle\" ? 1.02 : style === \"playful\" ? 1.08 : 1.05;\n\n return {\n initial: {\n scale: 1,\n backgroundColor: \"transparent\",\n },\n animate: {\n scale: [1, scale, 1],\n backgroundColor: [\"transparent\", \"var(--color-surface-success-subtle)\", \"transparent\"],\n },\n transition: {\n duration: msToSeconds(config.duration.fast),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// BADGE POP PRESET\n// =============================================================================\n\n/**\n * Badge Pop Micro-Interaction\n *\n * Pop animation for badge count changes. Provides satisfying feedback\n * when numbers update, drawing attention to the change.\n *\n * @ai-hint Use badgePop for notification badges, count indicators, or any\n * numeric value that changes. The pop effect highlights the update.\n *\n * @example\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { badgePop } from \"@enact-ui/animate\";\n *\n * function NotificationBadge({ count }) {\n * const props = badgePop.getProps(\"standard\");\n * return <motion.span {...props} key={count}>{count}</motion.span>;\n * }\n * ```\n */\nexport const badgePop: MicroInteractionPreset = {\n name: \"badgePop\",\n description: \"Pop animation for badge count changes\",\n useCase: [\"notification badges\", \"count indicators\", \"numeric updates\", \"inventory changes\", \"score updates\"],\n getProps: (style: MotionStyle): MicroInteractionProps => {\n if (prefersReducedMotion()) return getReducedMotionProps();\n\n const config = getMotionStyle(style);\n const scale = style === \"subtle\" ? 1.15 : style === \"playful\" ? 1.4 : 1.25;\n\n return {\n initial: {\n scale: 0,\n opacity: 0,\n },\n animate: {\n scale: [0, scale, 1],\n opacity: [0, 1, 1],\n },\n transition: {\n duration: msToSeconds(config.duration.fast),\n ease: config.easing.interactive,\n },\n };\n },\n};\n\n// =============================================================================\n// PRESET COLLECTION\n// =============================================================================\n\nexport const microInteractions: Record<string, MicroInteractionPreset> = {\n buttonPress,\n cardHover,\n iconSpin,\n pulse,\n scale,\n shake,\n wiggle,\n heartbeat,\n rubberBand,\n shimmer,\n glowPulse,\n progressFill,\n checkmarkDraw,\n successFlash,\n badgePop,\n};\n\n/**\n * Gets a micro-interaction preset by name.\n *\n * @param name - The name of the preset to retrieve\n * @returns The micro-interaction preset, or undefined if not found\n *\n * @example\n * ```ts\n * const preset = getMicroInteraction(\"buttonPress\");\n * if (preset) {\n * const props = preset.getProps(\"standard\");\n * }\n * ```\n */\nexport function getMicroInteraction(name: string): MicroInteractionPreset | undefined {\n return microInteractions[name];\n}\n\n/**\n * Gets all micro-interaction preset names.\n *\n * @returns Array of all preset names\n *\n * @example\n * ```ts\n * const names = getMicroInteractionNames();\n * // [\"buttonPress\", \"cardHover\", \"iconSpin\", ...]\n * ```\n */\nexport function getMicroInteractionNames(): string[] {\n return Object.keys(microInteractions);\n}\n\n/**\n * Finds micro-interaction presets suitable for a given use case.\n *\n * @param useCase - The use case to search for (case-insensitive)\n * @returns Array of presets that match the use case\n *\n * @ai-hint Use this function to find appropriate presets based on your component's\n * purpose. It searches the useCase arrays of all presets for matches.\n *\n * @example\n * ```ts\n * const errorPresets = findPresetsForUseCase(\"error\");\n * // Returns [shake] preset since it includes \"error states\" in its use cases\n *\n * const buttonPresets = findPresetsForUseCase(\"button\");\n * // Returns [buttonPress, rubberBand] presets\n * ```\n */\nexport function findPresetsForUseCase(useCase: string): MicroInteractionPreset[] {\n const searchTerm = useCase.toLowerCase();\n return Object.values(microInteractions).filter((preset) => preset.useCase.some((uc) => uc.toLowerCase().includes(searchTerm)));\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * Stagger Animation Presets\n *\n * Defines stagger animation presets for animating lists and grids of items.\n * These presets control the timing and order in which child elements animate,\n * creating visually appealing sequential or patterned animations.\n *\n * Each preset includes:\n * - A delay calculation function based on item index\n * - Container variants for orchestrating child animations\n * - Item variants for individual element animations\n * - Metadata for documentation and AI tool selection\n *\n * @packageDocumentation\n *\n * @example Basic list animation with sequential stagger\n * ```tsx\n * import { motion } from \"motion/react\";\n * import { staggerSequential } from \"@enact-ui/animate\";\n *\n * function AnimatedList({ items }) {\n * const { getContainerVariants, getItemVariants } = staggerSequential;\n *\n * return (\n * <motion.ul\n * variants={getContainerVariants(\"standard\")}\n * initial=\"hidden\"\n * animate=\"visible\"\n * >\n * {items.map((item, index) => (\n * <motion.li key={item.id} variants={getItemVariants(\"standard\")}>\n * {item.content}\n * </motion.li>\n * ))}\n * </motion.ul>\n * );\n * }\n * ```\n *\n * @example Grid animation with diagonal wave\n * ```tsx\n * import { staggerGrid } from \"@enact-ui/animate\";\n *\n * function AnimatedGrid({ items, columns = 4 }) {\n * return (\n * <motion.div\n * className=\"grid grid-cols-4\"\n * variants={staggerGrid.getContainerVariants(\"bold\")}\n * initial=\"hidden\"\n * animate=\"visible\"\n * >\n * {items.map((item, index) => (\n * <motion.div\n * key={item.id}\n * variants={staggerGrid.getItemVariants(\"bold\")}\n * custom={{ index, columns }}\n * >\n * {item.content}\n * </motion.div>\n * ))}\n * </motion.div>\n * );\n * }\n * ```\n */\n\nimport type { MotionStyle } from \"./motion-styles\";\nimport { getMotionStyle, msToSeconds } from \"./motion-styles\";\n\n/**\n * Container animation variants for stagger orchestration.\n * The container coordinates when children should animate.\n */\nexport interface ContainerVariants {\n /** Hidden state before animation starts */\n hidden: Record<string, unknown>;\n /** Visible state with stagger children configuration */\n visible: Record<string, unknown>;\n}\n\n/**\n * Item animation variants for individual elements.\n * Applied to each child element in the staggered animation.\n */\nexport interface ItemVariants {\n /** Hidden state (typically opacity: 0, transform offset) */\n hidden: Record<string, unknown>;\n /** Visible state (typically opacity: 1, transform reset) */\n visible: Record<string, unknown>;\n}\n\n/**\n * Complete stagger preset configuration.\n *\n * @ai-hint Stagger presets control how lists and grids of items animate.\n * Choose based on the visual effect needed: sequential for simple lists,\n * center for focus effects, grid for 2D layouts, wave for organic feels.\n */\nexport interface StaggerPreset {\n /** Display name of the stagger preset */\n name: string;\n /** Description of the animation effect */\n description: string;\n /** Recommended use cases for this preset */\n useCase: string[];\n /**\n * Calculates the delay for a specific item.\n *\n * @param index - The item's index in the list (0-based)\n * @param total - Total number of items in the list\n * @param style - The motion style to use for timing\n * @returns Delay in seconds before this item animates\n */\n getDelay: (index: number, total: number, style: MotionStyle) => number;\n /**\n * Gets container variants for Motion library.\n *\n * @param style - The motion style for timing configuration\n * @returns Container variants with stagger configuration\n */\n getContainerVariants: (style: MotionStyle) => ContainerVariants;\n /**\n * Gets item variants for Motion library.\n *\n * @param style - The motion style for animation configuration\n * @returns Item variants for individual elements\n */\n getItemVariants: (style: MotionStyle) => ItemVariants;\n}\n\n/**\n * Creates base item variants used across all stagger presets.\n *\n * @param style - The motion style for animation configuration\n * @returns Base item variants with fade and slide effect\n */\nfunction createBaseItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n y: 20,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n}\n\n/**\n * Sequential Stagger - Items animate one after another from top to bottom.\n *\n * The most common stagger pattern where items appear in their natural order.\n * Creates a clean, predictable animation flow that guides the eye downward.\n *\n * @ai-hint Use staggerSequential for standard lists, menus, and vertical\n * content where you want items to appear in reading order (top to bottom).\n *\n * @example\n * ```tsx\n * import { staggerSequential } from \"@enact-ui/animate\";\n *\n * // Navigation menu items\n * <motion.nav variants={staggerSequential.getContainerVariants(\"standard\")}>\n * {menuItems.map((item) => (\n * <motion.a variants={staggerSequential.getItemVariants(\"standard\")}>\n * {item.label}\n * </motion.a>\n * ))}\n * </motion.nav>\n * ```\n */\nexport const staggerSequential: StaggerPreset = {\n name: \"Sequential\",\n description: \"Items animate one after another from top to bottom\",\n useCase: [\"Navigation menus\", \"Vertical lists\", \"Table rows\", \"Form fields\", \"Sidebar items\"],\n\n getDelay(index: number, _total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n return msToSeconds(config.staggerDelay * index);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay),\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants: createBaseItemVariants,\n};\n\n/**\n * Reverse Stagger - Items animate from bottom to top.\n *\n * Creates an upward flow effect, useful for content that should draw\n * attention upward or create a \"rising\" visual metaphor.\n *\n * @ai-hint Use staggerReverse for toast notifications, chat messages\n * (newest first), or any content where bottom-to-top flow makes sense.\n *\n * @example\n * ```tsx\n * import { staggerReverse } from \"@enact-ui/animate\";\n *\n * // Toast notification stack\n * <motion.div variants={staggerReverse.getContainerVariants(\"standard\")}>\n * {toasts.map((toast) => (\n * <motion.div variants={staggerReverse.getItemVariants(\"standard\")}>\n * {toast.message}\n * </motion.div>\n * ))}\n * </motion.div>\n * ```\n */\nexport const staggerReverse: StaggerPreset = {\n name: \"Reverse\",\n description: \"Items animate from bottom to top\",\n useCase: [\"Toast notifications\", \"Chat messages (newest first)\", \"Bottom-anchored content\", \"Rising effect animations\", \"Upward reveals\"],\n\n getDelay(index: number, total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n const reverseIndex = total - 1 - index;\n return msToSeconds(config.staggerDelay * reverseIndex);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay),\n staggerDirection: -1,\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n y: -20,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n },\n};\n\n/**\n * Center Stagger - Items animate from center outward.\n *\n * Creates a radial expansion effect where the middle item(s) appear first,\n * then items progressively reveal outward. Great for focus-based UIs.\n *\n * @ai-hint Use staggerCenter for hero sections, featured content, or any\n * UI where you want to draw attention to the center element first.\n *\n * @example\n * ```tsx\n * import { staggerCenter } from \"@enact-ui/animate\";\n *\n * // Feature cards with center focus\n * <motion.div\n * className=\"flex gap-4\"\n * variants={staggerCenter.getContainerVariants(\"bold\")}\n * >\n * {features.map((feature, i) => (\n * <motion.div\n * variants={staggerCenter.getItemVariants(\"bold\")}\n * custom={{ index: i, total: features.length }}\n * >\n * {feature.title}\n * </motion.div>\n * ))}\n * </motion.div>\n * ```\n */\nexport const staggerCenter: StaggerPreset = {\n name: \"Center\",\n description: \"Items animate from center outward\",\n useCase: [\"Hero sections\", \"Featured content\", \"Pricing cards\", \"Centered navigation\", \"Focus-based reveals\"],\n\n getDelay(index: number, total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n const centerIndex = (total - 1) / 2;\n const distanceFromCenter = Math.abs(index - centerIndex);\n return msToSeconds(config.staggerDelay * distanceFromCenter);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay),\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n scale: 0.8,\n },\n visible: {\n opacity: 1,\n scale: 1,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n },\n};\n\n/**\n * Random Stagger - Items animate in random order.\n *\n * Creates an organic, unpredictable animation pattern. Each render\n * produces the same \"random\" order using a seeded approach based on index.\n *\n * @ai-hint Use staggerRandom for photo galleries, tag clouds, or creative\n * UIs where a playful, organic feel is desired. Avoid for data-heavy UIs.\n *\n * @example\n * ```tsx\n * import { staggerRandom } from \"@enact-ui/animate\";\n *\n * // Photo gallery with organic reveal\n * <motion.div\n * className=\"grid grid-cols-3\"\n * variants={staggerRandom.getContainerVariants(\"playful\")}\n * >\n * {photos.map((photo) => (\n * <motion.img\n * src={photo.url}\n * variants={staggerRandom.getItemVariants(\"playful\")}\n * />\n * ))}\n * </motion.div>\n * ```\n */\nexport const staggerRandom: StaggerPreset = {\n name: \"Random\",\n description: \"Items animate in random order\",\n useCase: [\"Photo galleries\", \"Tag clouds\", \"Creative portfolios\", \"Playful interfaces\", \"Organic reveals\"],\n\n getDelay(index: number, total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n // Use a deterministic pseudo-random based on index for consistency\n const seed = ((index * 7919) % total) / total;\n const maxDelay = config.staggerDelay * total;\n return msToSeconds(seed * maxDelay);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay * 0.3),\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n scale: 0.9,\n rotate: -5,\n },\n visible: {\n opacity: 1,\n scale: 1,\n rotate: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n },\n};\n\n/**\n * Grid Stagger - 2D diagonal wave pattern for grid layouts.\n *\n * Creates a diagonal wave effect where items animate based on their\n * row + column position. Perfect for image grids and card layouts.\n *\n * @ai-hint Use staggerGrid for 2D layouts like image galleries, card grids,\n * or dashboards. Pass columns count for accurate diagonal calculation.\n *\n * @example\n * ```tsx\n * import { staggerGrid } from \"@enact-ui/animate\";\n *\n * const COLUMNS = 4;\n *\n * // Image grid with diagonal wave\n * <motion.div\n * className=\"grid grid-cols-4\"\n * variants={staggerGrid.getContainerVariants(\"standard\")}\n * >\n * {images.map((image, index) => (\n * <motion.div\n * key={image.id}\n * variants={staggerGrid.getItemVariants(\"standard\")}\n * style={{\n * // Custom delay based on grid position\n * transitionDelay: `${staggerGrid.getDelay(\n * index,\n * images.length,\n * \"standard\"\n * )}s`,\n * }}\n * >\n * <img src={image.url} alt={image.alt} />\n * </motion.div>\n * ))}\n * </motion.div>\n * ```\n */\nexport const staggerGrid: StaggerPreset = {\n name: \"Grid\",\n description: \"2D diagonal wave pattern for grid layouts\",\n useCase: [\"Image galleries\", \"Card grids\", \"Dashboard widgets\", \"Product catalogs\", \"Portfolio items\"],\n\n getDelay(index: number, _total: number, style: MotionStyle, columns = 4): number {\n const config = getMotionStyle(style);\n const row = Math.floor(index / columns);\n const col = index % columns;\n // Diagonal wave: items with same row+col sum animate together\n const diagonalIndex = row + col;\n return msToSeconds(config.staggerDelay * diagonalIndex);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay * 0.8),\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n scale: 0.9,\n y: 10,\n },\n visible: {\n opacity: 1,\n scale: 1,\n y: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n },\n};\n\n/**\n * Wave Stagger - Sine-wave based stagger pattern.\n *\n * Creates an organic wave effect using sinusoidal timing. Items\n * animate in a flowing pattern that feels natural and rhythmic.\n *\n * @ai-hint Use staggerWave for music/audio UIs, timeline visualizations,\n * or any interface that benefits from organic, flowing motion.\n *\n * @example\n * ```tsx\n * import { staggerWave } from \"@enact-ui/animate\";\n *\n * // Audio equalizer bars\n * <motion.div\n * className=\"flex items-end gap-1\"\n * variants={staggerWave.getContainerVariants(\"playful\")}\n * >\n * {bars.map((bar, index) => (\n * <motion.div\n * key={index}\n * className=\"bg-primary\"\n * style={{ height: bar.height }}\n * variants={staggerWave.getItemVariants(\"playful\")}\n * />\n * ))}\n * </motion.div>\n * ```\n */\nexport const staggerWave: StaggerPreset = {\n name: \"Wave\",\n description: \"Sine-wave based stagger pattern for organic motion\",\n useCase: [\"Audio visualizers\", \"Timeline animations\", \"Organic reveals\", \"Music interfaces\", \"Flowing sequences\"],\n\n getDelay(index: number, total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n // Create a sine wave pattern across all items\n const wavePosition = (index / total) * Math.PI * 2;\n const waveOffset = (Math.sin(wavePosition) + 1) / 2; // Normalize to 0-1\n const baseDelay = config.staggerDelay * index;\n const waveDelay = config.staggerDelay * waveOffset * 2;\n return msToSeconds(baseDelay + waveDelay);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay * 0.6),\n delayChildren: msToSeconds(config.duration.fast * 0.5),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n y: 15,\n x: -5,\n },\n visible: {\n opacity: 1,\n y: 0,\n x: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness,\n damping: config.spring.damping,\n mass: config.spring.mass,\n },\n },\n };\n },\n};\n\n/**\n * Cascade Stagger - Fast initial items, progressively slower.\n *\n * Creates an accelerating cascade effect where early items appear quickly\n * and later items take longer. Great for emphasizing quantity.\n *\n * @ai-hint Use staggerCascade for long lists, data tables, or anywhere\n * you want to convey \"there's more\" by slowing down the reveal.\n *\n * @example\n * ```tsx\n * import { staggerCascade } from \"@enact-ui/animate\";\n *\n * // Long data table rows\n * <motion.tbody variants={staggerCascade.getContainerVariants(\"subtle\")}>\n * {rows.map((row) => (\n * <motion.tr\n * key={row.id}\n * variants={staggerCascade.getItemVariants(\"subtle\")}\n * >\n * {row.cells.map((cell) => (\n * <td key={cell.id}>{cell.value}</td>\n * ))}\n * </motion.tr>\n * ))}\n * </motion.tbody>\n * ```\n */\nexport const staggerCascade: StaggerPreset = {\n name: \"Cascade\",\n description: \"Fast initial items, progressively slower later ones\",\n useCase: [\"Long lists\", \"Data tables\", \"Search results\", \"Infinite scroll content\", \"Progressive reveals\"],\n\n getDelay(index: number, total: number, style: MotionStyle): number {\n const config = getMotionStyle(style);\n // Exponential slowdown: sqrt creates the cascade effect\n const normalizedIndex = index / Math.max(total - 1, 1);\n const cascadeFactor = Math.sqrt(normalizedIndex);\n const maxDuration = config.staggerDelay * total;\n return msToSeconds(cascadeFactor * maxDuration);\n },\n\n getContainerVariants(style: MotionStyle): ContainerVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: msToSeconds(config.staggerDelay * 0.4),\n delayChildren: msToSeconds(config.duration.fast * 0.3),\n },\n },\n };\n },\n\n getItemVariants(style: MotionStyle): ItemVariants {\n const config = getMotionStyle(style);\n\n return {\n hidden: {\n opacity: 0,\n x: -10,\n },\n visible: {\n opacity: 1,\n x: 0,\n transition: {\n type: \"spring\",\n stiffness: config.spring.stiffness + 50, // Slightly snappier\n damping: config.spring.damping + 5,\n mass: config.spring.mass * 0.9,\n },\n },\n };\n },\n};\n\n/**\n * All stagger presets indexed by name.\n *\n * @ai-hint Use this map to dynamically select stagger presets based on\n * user preferences or component configuration.\n */\nexport const staggerPresets: Record<string, StaggerPreset> = {\n sequential: staggerSequential,\n reverse: staggerReverse,\n center: staggerCenter,\n random: staggerRandom,\n grid: staggerGrid,\n wave: staggerWave,\n cascade: staggerCascade,\n};\n\n/**\n * Stagger preset type identifier.\n */\nexport type StaggerPresetType = keyof typeof staggerPresets;\n\n/**\n * Gets a stagger preset by name.\n *\n * @param name - The preset name to retrieve\n * @returns The stagger preset configuration\n * @throws Error if preset name is not found\n *\n * @example\n * ```ts\n * const preset = getStaggerPreset(\"center\");\n * const containerVariants = preset.getContainerVariants(\"standard\");\n * ```\n */\nexport function getStaggerPreset(name: StaggerPresetType): StaggerPreset {\n const preset = staggerPresets[name];\n if (!preset) {\n throw new Error(`Unknown stagger preset: ${name}. Available: ${Object.keys(staggerPresets).join(\", \")}`);\n }\n return preset;\n}\n\n/**\n * Creates custom delay values for a list of items using a specific preset.\n *\n * Useful when you need to calculate delays outside of Motion's variants\n * system, such as for CSS animations or manual timing control.\n *\n * @param preset - The stagger preset to use\n * @param total - Total number of items\n * @param style - The motion style for timing\n * @returns Array of delay values in seconds for each item\n *\n * @example\n * ```ts\n * const delays = calculateStaggerDelays(\"cascade\", 10, \"standard\");\n * // Returns: [0, 0.05, 0.071, 0.087, 0.1, ...]\n *\n * // Use with CSS custom properties\n * items.forEach((item, index) => {\n * item.style.setProperty(\"--delay\", `${delays[index]}s`);\n * });\n * ```\n */\nexport function calculateStaggerDelays(preset: StaggerPresetType, total: number, style: MotionStyle): number[] {\n const staggerPreset = getStaggerPreset(preset);\n return Array.from({ length: total }, (_, index) => staggerPreset.getDelay(index, total, style));\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * @fileoverview Easing functions and tween configurations for Motion library.\n *\n * @ai-hint This module provides easing curves for duration-based (tween) animations.\n * Use tweens when you need precise timing control or for CSS-property animations\n * that don't work well with springs (e.g., color, opacity fades).\n *\n * @example\n * ```tsx\n * import { easeOutQuart, createTween, easeInOut } from './easing';\n *\n * // Use a preset curve\n * <motion.div animate={{ opacity: 1 }} transition={{ duration: 0.3, ease: easeOutQuart }} />\n *\n * // Use the tween helper\n * <motion.div animate={{ x: 100 }} transition={createTween(0.4, easeOutQuart)} />\n * ```\n */\n\n/**\n * Cubic bezier curve represented as four control points.\n * Format: [x1, y1, x2, y2] matching CSS cubic-bezier().\n *\n * @ai-hint These values map directly to CSS cubic-bezier(x1, y1, x2, y2).\n * x values must be between 0 and 1, y values can exceed that range for overshoot.\n */\nexport type CubicBezier = readonly [number, number, number, number];\n\n/**\n * Configuration object for tween-based (duration) animations.\n *\n * @ai-hint TweenTransition provides predictable, time-based animations.\n * Unlike springs, tweens always take exactly the specified duration.\n */\nexport interface TweenTransition {\n /** Animation type identifier */\n readonly type: \"tween\";\n /** Duration in seconds */\n readonly duration: number;\n /** Easing curve (cubic bezier or named easing) */\n readonly ease?: CubicBezier | string;\n}\n\n/**\n * Parameters for creating tween transitions.\n */\nexport interface TweenParams {\n /** Duration in seconds */\n duration: number;\n /** Optional easing curve */\n ease?: CubicBezier | string;\n /** Optional delay before animation starts */\n delay?: number;\n}\n\n// =============================================================================\n// STANDARD EASING CURVES\n// =============================================================================\n\n/**\n * Linear easing - constant speed with no acceleration.\n *\n * @ai-hint Use for progress indicators, loading bars, or when you need\n * mechanical, uniform motion. Rarely suitable for UI transitions.\n *\n * @example\n * ```tsx\n * <motion.div animate={{ width: \"100%\" }} transition={{ duration: 2, ease: linear }} />\n * ```\n */\nexport const linear: CubicBezier = [0, 0, 1, 1] as const;\n\n/**\n * Ease-in - starts slow, accelerates toward end.\n *\n * @ai-hint Use for elements exiting the screen or fading out.\n * Creates anticipation but can feel sluggish if overused.\n *\n * @example\n * ```tsx\n * <motion.div exit={{ opacity: 0, x: -100 }} transition={{ duration: 0.3, ease: easeIn }} />\n * ```\n */\nexport const easeIn: CubicBezier = [0.4, 0, 1, 1] as const;\n\n/**\n * Ease-out - starts fast, decelerates toward end.\n *\n * @ai-hint The most natural-feeling easing for UI. Use for elements\n * entering the screen or appearing. Mimics real-world deceleration.\n *\n * @example\n * ```tsx\n * <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3, ease: easeOut }} />\n * ```\n */\nexport const easeOut: CubicBezier = [0, 0, 0.2, 1] as const;\n\n/**\n * Ease-in-out - slow start and end, fast middle.\n *\n * @ai-hint Good for elements that transform in place (scale, rotate)\n * or move between two visible positions. Symmetric and balanced.\n *\n * @example\n * ```tsx\n * <motion.div animate={{ rotate: 180 }} transition={{ duration: 0.5, ease: easeInOut }} />\n * ```\n */\nexport const easeInOut: CubicBezier = [0.4, 0, 0.2, 1] as const;\n\n// =============================================================================\n// EXPRESSIVE EASING CURVES\n// =============================================================================\n\n/**\n * Quart ease-out - more dramatic deceleration than standard ease-out.\n *\n * @ai-hint Use for hero animations, page transitions, or anywhere you want\n * motion to feel more dynamic and expressive. Popular in modern UI design.\n *\n * @example\n * ```tsx\n * <motion.section\n * initial={{ y: 50, opacity: 0 }}\n * animate={{ y: 0, opacity: 1 }}\n * transition={{ duration: 0.6, ease: easeOutQuart }}\n * />\n * ```\n */\nexport const easeOutQuart: CubicBezier = [0.25, 1, 0.5, 1] as const;\n\n/**\n * Cubic ease-in-out - smooth acceleration and deceleration.\n *\n * @ai-hint A balanced, professional curve suitable for most transitions.\n * Less aggressive than quart, more refined than standard ease-in-out.\n *\n * @example\n * ```tsx\n * <motion.div\n * animate={{ height: isOpen ? \"auto\" : 0 }}\n * transition={{ duration: 0.4, ease: easeInOutCubic }}\n * />\n * ```\n */\nexport const easeInOutCubic: CubicBezier = [0.65, 0, 0.35, 1] as const;\n\n/**\n * Back ease-out - slight overshoot before settling.\n *\n * @ai-hint Use for playful, attention-grabbing animations. The overshoot\n * creates a \"bounce back\" effect. Use sparingly in professional UIs.\n *\n * @example\n * ```tsx\n * <motion.div\n * initial={{ scale: 0 }}\n * animate={{ scale: 1 }}\n * transition={{ duration: 0.5, ease: easeOutBack }}\n * />\n * ```\n */\nexport const easeOutBack: CubicBezier = [0.34, 1.56, 0.64, 1] as const;\n\n/**\n * Expo ease-out - very fast start with long, smooth deceleration.\n *\n * @ai-hint Creates a snappy feel while maintaining smoothness.\n * Great for modals, popovers, and navigation transitions.\n *\n * @example\n * ```tsx\n * <motion.dialog\n * initial={{ scale: 0.95, opacity: 0 }}\n * animate={{ scale: 1, opacity: 1 }}\n * transition={{ duration: 0.3, ease: easeOutExpo }}\n * />\n * ```\n */\nexport const easeOutExpo: CubicBezier = [0.16, 1, 0.3, 1] as const;\n\n/**\n * Quint ease-in-out - dramatic but smooth transition.\n *\n * @ai-hint Use for large-scale transitions like page changes or\n * full-screen reveals. The aggressive curve makes motion feel purposeful.\n *\n * @example\n * ```tsx\n * <motion.main\n * initial={{ opacity: 0 }}\n * animate={{ opacity: 1 }}\n * transition={{ duration: 0.8, ease: easeInOutQuint }}\n * />\n * ```\n */\nexport const easeInOutQuint: CubicBezier = [0.83, 0, 0.17, 1] as const;\n\n// =============================================================================\n// TWEEN FACTORIES\n// =============================================================================\n\n/**\n * Creates a tween transition with specified duration and optional easing.\n *\n * @ai-hint Primary factory for duration-based animations. Provides\n * consistent, predictable timing. Default easing is easeOut.\n *\n * @param duration - Animation duration in seconds\n * @param ease - Optional cubic bezier curve or easing name\n * @returns A TweenTransition configuration object\n *\n * @example\n * ```tsx\n * // Quick fade\n * <motion.div animate={{ opacity: 1 }} transition={createTween(0.2)} />\n *\n * // Expressive entrance\n * <motion.div animate={{ y: 0 }} transition={createTween(0.5, easeOutQuart)} />\n *\n * // Using named easing\n * <motion.div animate={{ x: 100 }} transition={createTween(0.3, \"easeInOut\")} />\n * ```\n */\nexport function createTween(duration: number, ease?: CubicBezier | string): TweenTransition {\n return {\n type: \"tween\",\n duration,\n ease: ease ?? easeOut,\n } as const;\n}\n\n/**\n * Creates a tween transition from a params object.\n *\n * @ai-hint Alternative factory accepting an object, useful when\n * animation parameters come from configuration or are computed.\n *\n * @param params - Tween parameters object\n * @returns A TweenTransition configuration object\n *\n * @example\n * ```tsx\n * const config = { duration: 0.4, ease: easeOutQuart };\n * const tween = createTweenFromParams(config);\n * ```\n */\nexport function createTweenFromParams(params: TweenParams): TweenTransition {\n const result: TweenTransition = {\n type: \"tween\",\n duration: params.duration,\n };\n\n if (params.ease !== undefined) {\n return { ...result, ease: params.ease };\n }\n\n return result;\n}\n\n// =============================================================================\n// DURATION PRESETS\n// =============================================================================\n\n/**\n * Standard duration values for consistent timing across the application.\n *\n * @ai-hint Use these durations to maintain rhythm and consistency.\n * Faster durations for small, frequent interactions; longer for emphasis.\n */\nexport const durations = {\n /** Micro-interactions: hover states, small toggles (100ms) */\n instant: 0.1,\n /** Quick feedback: button clicks, checkboxes (200ms) */\n fast: 0.2,\n /** Standard transitions: most UI elements (300ms) */\n normal: 0.3,\n /** Emphasized transitions: modals, drawers (400ms) */\n slow: 0.4,\n /** Dramatic transitions: page changes, reveals (600ms) */\n slower: 0.6,\n} as const;\n\n/**\n * Type representing valid duration preset names.\n */\nexport type DurationPresetName = keyof typeof durations;\n\n// =============================================================================\n// PRESET COLLECTIONS\n// =============================================================================\n\n/**\n * Collection of all easing curves for iteration or dynamic selection.\n *\n * @ai-hint Use this map when you need to select easings dynamically\n * based on theme or user preferences.\n *\n * @example\n * ```tsx\n * const easingName = theme.animationEasing; // 'easeOutQuart' | 'easeInOut' | etc.\n * const easing = easingPresets[easingName];\n * ```\n */\nexport const easingPresets = {\n linear,\n easeIn,\n easeOut,\n easeInOut,\n easeOutQuart,\n easeInOutCubic,\n easeOutBack,\n easeOutExpo,\n easeInOutQuint,\n} as const;\n\n/**\n * Type representing valid easing preset names.\n */\nexport type EasingPresetName = keyof typeof easingPresets;\n\n// =============================================================================\n// CONVENIENCE TRANSITIONS\n// =============================================================================\n\n/**\n * Pre-configured tween transitions for common use cases.\n *\n * @ai-hint Ready-to-use transitions that combine duration and easing\n * for typical scenarios. Use these for consistent animation behavior.\n *\n * @example\n * ```tsx\n * <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={tweenPresets.fadeIn} />\n * ```\n */\nexport const tweenPresets = {\n /** Quick fade for hover states and micro-interactions */\n instant: createTween(durations.instant, easeOut),\n /** Snappy transition for interactive elements */\n fast: createTween(durations.fast, easeOut),\n /** Balanced transition for most UI elements */\n normal: createTween(durations.normal, easeOutQuart),\n /** Smooth transition for modals and overlays */\n slow: createTween(durations.slow, easeOutQuart),\n /** Dramatic transition for page-level changes */\n slower: createTween(durations.slower, easeInOutCubic),\n} as const;\n\n/**\n * Type representing valid tween preset names.\n */\nexport type TweenPresetName = keyof typeof tweenPresets;\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n\"use client\";\n\n/**\n * Reduced Motion Utilities\n *\n * @ai-hint This module provides utilities for handling the `prefers-reduced-motion`\n * media query. Use these utilities to ensure animations are accessible and respect\n * user preferences for reduced motion.\n *\n * @packageDocumentation\n */\n\nimport { useEffect, useState } from \"react\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Motion variant configuration for animations.\n *\n * @ai-hint This type represents animation variant objects used by Motion library.\n * Variants define the animation states (initial, animate, exit, etc.).\n */\nexport type MotionVariant = Record<string, unknown>;\n\n/**\n * Props that can be passed to Motion components.\n *\n * @ai-hint This type represents the common props used in Motion components\n * including animation configuration, transition settings, and variants.\n */\nexport interface MotionProps {\n /** Initial animation state or variant name */\n initial?: MotionVariant | string | boolean | undefined;\n /** Target animation state or variant name */\n animate?: MotionVariant | string | undefined;\n /** Exit animation state or variant name */\n exit?: MotionVariant | string | undefined;\n /** Animation variants object */\n variants?: Record<string, MotionVariant> | undefined;\n /** Transition configuration */\n transition?: MotionTransition | undefined;\n /** Whether animations should be active */\n whileHover?: MotionVariant | string | undefined;\n /** Animation when element is in view */\n whileInView?: MotionVariant | string | undefined;\n /** Animation while element is pressed */\n whileTap?: MotionVariant | string | undefined;\n /** Animation while element is focused */\n whileFocus?: MotionVariant | string | undefined;\n /** Animation while dragging */\n whileDrag?: MotionVariant | string | undefined;\n}\n\n/**\n * Transition configuration for Motion animations.\n *\n * @ai-hint This type represents the transition object in Motion library.\n * It controls duration, easing, delay, and other timing aspects.\n */\nexport interface MotionTransition {\n /** Duration in seconds */\n duration?: number;\n /** Delay before animation starts in seconds */\n delay?: number;\n /** Easing function or curve */\n ease?: string | number[];\n /** Type of animation (tween, spring, inertia) */\n type?: \"tween\" | \"spring\" | \"inertia\";\n /** Spring stiffness (for spring type) */\n stiffness?: number;\n /** Spring damping (for spring type) */\n damping?: number;\n /** Spring mass (for spring type) */\n mass?: number;\n /** Number of times to repeat (-1 for infinite) */\n repeat?: number;\n /** Type of repeat behavior */\n repeatType?: \"loop\" | \"reverse\" | \"mirror\";\n /** Delay between repeats */\n repeatDelay?: number;\n}\n\n/**\n * Options for creating reduced motion props.\n *\n * @ai-hint Use these options to customize how motion props are transformed\n * when reduced motion is preferred.\n */\nexport interface ReducedMotionOptions {\n /**\n * Whether to preserve opacity transitions even in reduced motion mode.\n * Opacity changes are generally considered acceptable for accessibility.\n * @default true\n */\n preserveOpacity?: boolean;\n /**\n * Whether to preserve color transitions in reduced motion mode.\n * Color changes without movement are typically accessibility-safe.\n * @default true\n */\n preserveColors?: boolean;\n /**\n * Custom transition to use when reduced motion is preferred.\n * If not provided, uses instant transition (duration: 0).\n */\n reducedTransition?: MotionTransition;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Media query string for detecting reduced motion preference.\n *\n * @ai-hint Use this constant when you need to directly query the media feature\n * outside of the provided hooks.\n */\nexport const REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\n\n/**\n * Default transition for reduced motion mode.\n * Provides instant transitions without animation.\n *\n * @ai-hint This transition effectively disables animation while still\n * allowing the final state to be applied immediately.\n */\nexport const INSTANT_TRANSITION: MotionTransition = {\n duration: 0,\n delay: 0,\n};\n\n// =============================================================================\n// Hooks\n// =============================================================================\n\n/**\n * Hook that returns whether the user prefers reduced motion.\n *\n * @ai-hint This hook reactively tracks the `prefers-reduced-motion` media query.\n * It updates automatically when the user changes their system preference.\n * Use this hook to conditionally apply or skip animations.\n *\n * @returns `true` if the user prefers reduced motion, `false` otherwise\n *\n * @example\n * ```tsx\n * function AnimatedComponent() {\n * const prefersReducedMotion = useReducedMotion();\n *\n * return (\n * <motion.div\n * animate={{ x: 100 }}\n * transition={prefersReducedMotion ? { duration: 0 } : { duration: 0.5 }}\n * >\n * Content\n * </motion.div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Skip animation entirely when reduced motion is preferred\n * function FadeInComponent({ children }: { children: React.ReactNode }) {\n * const prefersReducedMotion = useReducedMotion();\n *\n * if (prefersReducedMotion) {\n * return <div>{children}</div>;\n * }\n *\n * return (\n * <motion.div\n * initial={{ opacity: 0 }}\n * animate={{ opacity: 1 }}\n * transition={{ duration: 0.3 }}\n * >\n * {children}\n * </motion.div>\n * );\n * }\n * ```\n */\nexport function useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>(() => {\n // Return false during SSR\n if (typeof window === \"undefined\") {\n return false;\n }\n return window.matchMedia(REDUCED_MOTION_QUERY).matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);\n\n // Set initial value (handles hydration mismatch)\n setPrefersReducedMotion(mediaQuery.matches);\n\n // Listen for changes to the preference\n const handleChange = (event: MediaQueryListEvent): void => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handleChange);\n\n return () => {\n mediaQuery.removeEventListener(\"change\", handleChange);\n };\n }, []);\n\n return prefersReducedMotion;\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Returns the appropriate variant based on reduced motion preference.\n *\n * @ai-hint Use this function to provide alternative animation variants for users\n * who prefer reduced motion. The reduced variant should avoid or minimize\n * movement-based animations while potentially preserving opacity/color changes.\n *\n * @param normalVariant - The variant to use when motion is allowed\n * @param reducedVariant - The variant to use when reduced motion is preferred\n * @returns The appropriate variant based on the current reduced motion preference\n *\n * @example\n * ```tsx\n * function SlideInCard() {\n * const prefersReducedMotion = useReducedMotion();\n *\n * const normalVariant = {\n * hidden: { x: -100, opacity: 0 },\n * visible: { x: 0, opacity: 1 },\n * };\n *\n * const reducedVariant = {\n * hidden: { opacity: 0 },\n * visible: { opacity: 1 },\n * };\n *\n * const variants = getReducedMotionVariant(\n * normalVariant,\n * reducedVariant,\n * prefersReducedMotion\n * );\n *\n * return (\n * <motion.div\n * variants={variants}\n * initial=\"hidden\"\n * animate=\"visible\"\n * >\n * Card Content\n * </motion.div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with a hook for reactive updates\n * function AnimatedList({ items }: { items: string[] }) {\n * const prefersReducedMotion = useReducedMotion();\n *\n * const itemVariant = getReducedMotionVariant(\n * { hidden: { y: 20, opacity: 0 }, visible: { y: 0, opacity: 1 } },\n * { hidden: { opacity: 0 }, visible: { opacity: 1 } },\n * prefersReducedMotion\n * );\n *\n * return (\n * <motion.ul>\n * {items.map((item, i) => (\n * <motion.li\n * key={item}\n * variants={itemVariant}\n * initial=\"hidden\"\n * animate=\"visible\"\n * transition={{ delay: i * 0.1 }}\n * >\n * {item}\n * </motion.li>\n * ))}\n * </motion.ul>\n * );\n * }\n * ```\n */\nexport function getReducedMotionVariant<T extends MotionVariant | Record<string, MotionVariant>>(\n normalVariant: T,\n reducedVariant: T,\n prefersReducedMotion: boolean,\n): T {\n return prefersReducedMotion ? reducedVariant : normalVariant;\n}\n\n/**\n * Properties that are considered safe for reduced motion mode.\n * These typically don't involve movement and are accessibility-friendly.\n *\n * @ai-hint Opacity and color changes are generally acceptable even for users\n * who prefer reduced motion, as they don't cause vestibular issues.\n */\nconst _SAFE_ANIMATION_PROPERTIES = new Set([\"opacity\", \"color\", \"backgroundColor\", \"borderColor\", \"fill\", \"stroke\"]);\n\n/**\n * Filters a variant to only include safe properties for reduced motion.\n *\n * @param variant - The variant to filter\n * @param options - Options for filtering\n * @returns Filtered variant with only safe properties\n */\nfunction filterVariantForReducedMotion(variant: MotionVariant, options: ReducedMotionOptions): MotionVariant {\n const { preserveOpacity = true, preserveColors = true } = options;\n\n const filtered: MotionVariant = {};\n\n for (const [key, value] of Object.entries(variant)) {\n const isOpacityProperty = key === \"opacity\";\n const isColorProperty = key === \"color\" || key === \"backgroundColor\" || key === \"borderColor\" || key === \"fill\" || key === \"stroke\";\n\n if ((preserveOpacity && isOpacityProperty) || (preserveColors && isColorProperty)) {\n filtered[key] = value;\n }\n }\n\n return filtered;\n}\n\n/**\n * Wraps Motion props to respect the user's reduced motion preference.\n *\n * @ai-hint This function transforms Motion component props to be accessibility-friendly.\n * When reduced motion is preferred, it either disables animations or preserves\n * only safe properties (like opacity) based on the options provided.\n *\n * @param props - The original Motion props\n * @param prefersReducedMotion - Whether reduced motion is preferred\n * @param options - Options for customizing reduced motion behavior\n * @returns Transformed props that respect reduced motion preference\n *\n * @example\n * ```tsx\n * function AccessibleMotionDiv({ children }: { children: React.ReactNode }) {\n * const prefersReducedMotion = useReducedMotion();\n *\n * const baseProps: MotionProps = {\n * initial: { x: -50, opacity: 0 },\n * animate: { x: 0, opacity: 1 },\n * transition: { duration: 0.5 },\n * };\n *\n * const accessibleProps = createReducedMotionProps(\n * baseProps,\n * prefersReducedMotion\n * );\n *\n * return <motion.div {...accessibleProps}>{children}</motion.div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Preserve opacity transitions in reduced motion mode\n * function FadeSlideComponent() {\n * const prefersReducedMotion = useReducedMotion();\n *\n * const props = createReducedMotionProps(\n * {\n * initial: { y: 20, opacity: 0 },\n * animate: { y: 0, opacity: 1 },\n * transition: { duration: 0.3 },\n * },\n * prefersReducedMotion,\n * { preserveOpacity: true }\n * );\n *\n * // In reduced motion: only opacity animates, y is instant\n * return <motion.div {...props}>Content</motion.div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Custom reduced transition\n * function CustomReducedMotion() {\n * const prefersReducedMotion = useReducedMotion();\n *\n * const props = createReducedMotionProps(\n * {\n * animate: { scale: 1.1 },\n * transition: { duration: 0.5 },\n * },\n * prefersReducedMotion,\n * {\n * reducedTransition: { duration: 0.1, ease: \"linear\" },\n * }\n * );\n *\n * return <motion.button {...props}>Hover me</motion.button>;\n * }\n * ```\n */\nexport function createReducedMotionProps(props: MotionProps, prefersReducedMotion: boolean, options: ReducedMotionOptions = {}): MotionProps {\n // If reduced motion is not preferred, return props as-is\n if (!prefersReducedMotion) {\n return props;\n }\n\n const { preserveOpacity = true, preserveColors = true, reducedTransition } = options;\n\n // Use provided reduced transition or default to instant\n const transition: MotionTransition = reducedTransition ?? INSTANT_TRANSITION;\n\n // Helper to process variant-like objects\n const processVariant = (variant: MotionVariant | string | boolean | undefined): MotionVariant | string | boolean | undefined => {\n if (variant === undefined || typeof variant === \"string\" || typeof variant === \"boolean\") {\n return variant;\n }\n return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });\n };\n\n // Helper to process variants object\n const processVariants = (variants: Record<string, MotionVariant> | undefined): Record<string, MotionVariant> | undefined => {\n if (!variants) {\n return undefined;\n }\n\n const processed: Record<string, MotionVariant> = {};\n for (const [key, variant] of Object.entries(variants)) {\n processed[key] = filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });\n }\n return processed;\n };\n\n // Process animate/exit/whileInView - these don't accept boolean\n const processNonBooleanVariant = (variant: MotionVariant | string | undefined): MotionVariant | string | undefined => {\n if (variant === undefined || typeof variant === \"string\") {\n return variant;\n }\n return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });\n };\n\n return {\n ...props,\n initial: processVariant(props.initial),\n animate: processNonBooleanVariant(props.animate),\n exit: processNonBooleanVariant(props.exit),\n variants: processVariants(props.variants),\n transition,\n // Disable hover/tap/focus animations in reduced motion mode\n // as they often involve movement\n whileHover: undefined,\n whileTap: undefined,\n whileFocus: undefined,\n whileDrag: undefined,\n whileInView: processNonBooleanVariant(props.whileInView),\n };\n}\n\n/**\n * Checks if reduced motion is preferred (non-reactive, for one-time checks).\n *\n * @ai-hint Use this function for one-time checks outside of React components.\n * For reactive behavior within components, prefer the `useReducedMotion` hook.\n *\n * @returns `true` if reduced motion is preferred, `false` otherwise (including SSR)\n *\n * @example\n * ```ts\n * // In a utility function\n * function getAnimationDuration(baseDuration: number): number {\n * if (checkReducedMotion()) {\n * return 0;\n * }\n * return baseDuration;\n * }\n * ```\n */\nexport function checkReducedMotion(): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n return window.matchMedia(REDUCED_MOTION_QUERY).matches;\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * AI-Driven Preset Selection\n *\n * Utilities for intelligently selecting animation presets based on\n * context, use case, and preferences. Designed to be used by AI tools\n * for automatic animation selection.\n *\n * @packageDocumentation\n */\n\nimport {\n type ComponentPreset,\n type ComponentPresetName,\n componentPresets,\n getPresetsByContext,\n type PresetContext,\n type PresetUseCase,\n} from \"../presets/component-presets\";\nimport type { MotionStyle } from \"../presets/motion-styles\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Criteria for selecting a preset.\n */\nexport interface SelectionCriteria {\n /** Primary use case for the animation */\n useCase?: PresetUseCase;\n /** Context where the animation will be used */\n context?: PresetContext;\n /** Preferred motion style */\n style?: MotionStyle;\n /** Maximum intensity level (1-5) */\n maxIntensity?: number;\n /** Minimum intensity level (1-5) */\n minIntensity?: number;\n /** Whether movement is desired */\n preferMovement?: boolean;\n /** Preferred direction of movement */\n direction?: \"up\" | \"down\" | \"left\" | \"right\" | \"in\" | \"out\";\n /** Whether to prioritize accessibility */\n prioritizeAccessibility?: boolean;\n}\n\n/**\n * Result of preset selection with reasoning.\n */\nexport interface SelectionResult {\n /** The selected preset */\n preset: ComponentPreset;\n /** Name of the selected preset */\n presetName: ComponentPresetName;\n /** Recommended motion style */\n style: MotionStyle;\n /** Confidence score (0-1) */\n confidence: number;\n /** Reasoning for the selection */\n reasoning: string;\n /** Alternative presets that could work */\n alternatives: ComponentPresetName[];\n}\n\n/**\n * Preset recommendation for a specific context.\n */\nexport interface PresetRecommendation {\n /** Recommended preset */\n preset: ComponentPreset;\n /** Preset name */\n name: ComponentPresetName;\n /** Why this preset is recommended */\n reason: string;\n /** Score (0-1) */\n score: number;\n}\n\n// =============================================================================\n// Selection Logic\n// =============================================================================\n\n/**\n * Calculates a match score between criteria and a preset.\n */\nfunction calculateMatchScore(preset: ComponentPreset, criteria: SelectionCriteria): number {\n let score = 0;\n let factors = 0;\n\n // Use case match\n if (criteria.useCase) {\n factors++;\n if (preset.metadata.useCase.includes(criteria.useCase)) {\n score += 1;\n }\n }\n\n // Context match\n if (criteria.context) {\n factors++;\n if (preset.metadata.context.includes(criteria.context)) {\n score += 1;\n }\n }\n\n // Intensity range\n if (criteria.maxIntensity !== undefined) {\n factors++;\n if (preset.metadata.intensity <= criteria.maxIntensity) {\n score += 1;\n }\n }\n\n if (criteria.minIntensity !== undefined) {\n factors++;\n if (preset.metadata.intensity >= criteria.minIntensity) {\n score += 1;\n }\n }\n\n // Movement preference\n if (criteria.preferMovement !== undefined) {\n factors++;\n if (preset.metadata.hasMovement === criteria.preferMovement) {\n score += 1;\n }\n }\n\n // Direction match\n if (criteria.direction && preset.metadata.direction) {\n factors++;\n if (preset.metadata.direction === criteria.direction) {\n score += 1;\n }\n }\n\n // Accessibility preference (lower intensity = more accessible)\n if (criteria.prioritizeAccessibility) {\n factors++;\n // Favor lower intensity presets\n score += (5 - preset.metadata.intensity) / 5;\n }\n\n return factors > 0 ? score / factors : 0;\n}\n\n/**\n * Determines the best motion style based on criteria.\n */\nfunction determineStyle(criteria: SelectionCriteria): MotionStyle {\n if (criteria.style) {\n return criteria.style;\n }\n\n if (criteria.prioritizeAccessibility) {\n return \"subtle\";\n }\n\n if (criteria.context === \"hero\" || criteria.context === \"page\") {\n return \"bold\";\n }\n\n if (criteria.context === \"tooltip\" || criteria.context === \"dropdown\") {\n return \"subtle\";\n }\n\n return \"standard\";\n}\n\n/**\n * Generates reasoning for a selection.\n */\nfunction generateReasoning(preset: ComponentPreset, criteria: SelectionCriteria, score: number): string {\n const reasons: string[] = [];\n\n if (criteria.useCase && preset.metadata.useCase.includes(criteria.useCase)) {\n reasons.push(`matches use case \"${criteria.useCase}\"`);\n }\n\n if (criteria.context && preset.metadata.context.includes(criteria.context)) {\n reasons.push(`suitable for \"${criteria.context}\" context`);\n }\n\n if (criteria.direction && preset.metadata.direction === criteria.direction) {\n reasons.push(`provides \"${criteria.direction}\" movement`);\n }\n\n if (criteria.prioritizeAccessibility && preset.metadata.intensity <= 2) {\n reasons.push(\"has low intensity for accessibility\");\n }\n\n if (reasons.length === 0) {\n reasons.push(\"general-purpose animation\");\n }\n\n return `Selected \"${preset.metadata.name}\" (${Math.round(score * 100)}% match): ${reasons.join(\", \")}.`;\n}\n\n// =============================================================================\n// Main Selection Functions\n// =============================================================================\n\n/**\n * Selects the best preset based on criteria.\n *\n * This function analyzes the given criteria and returns the most\n * appropriate animation preset along with reasoning.\n *\n * @ai-hint Use this function to automatically select animations based on\n * the component's context and requirements. Pass as much information as\n * possible for better selection.\n *\n * @param criteria - Selection criteria\n * @returns Selection result with preset and reasoning\n *\n * @example\n * ```ts\n * const result = selectPreset({\n * useCase: \"entrance\",\n * context: \"modal\",\n * prioritizeAccessibility: true,\n * });\n *\n * console.log(result.presetName); // \"fadeIn\"\n * console.log(result.reasoning); // \"Selected 'Fade In' (95% match): ...\"\n * ```\n *\n * @example\n * ```ts\n * // For a hero section with bold animation\n * const result = selectPreset({\n * useCase: \"entrance\",\n * context: \"hero\",\n * preferMovement: true,\n * direction: \"up\",\n * });\n *\n * console.log(result.presetName); // \"slideUpScale\"\n * console.log(result.style); // \"bold\"\n * ```\n */\nexport function selectPreset(criteria: SelectionCriteria): SelectionResult {\n const allPresets = Object.entries(componentPresets) as Array<[ComponentPresetName, ComponentPreset]>;\n\n // Calculate scores for all presets\n const scoredPresets = allPresets.map(([name, preset]) => ({\n name,\n preset,\n score: calculateMatchScore(preset, criteria),\n }));\n\n // Sort by score descending\n scoredPresets.sort((a, b) => b.score - a.score);\n\n const best = scoredPresets[0];\n const style = determineStyle(criteria);\n\n if (!best) {\n throw new Error(\"selectPreset: no presets available; cannot select a preset.\");\n }\n\n const alternatives = scoredPresets\n .slice(1, 4)\n .filter((p) => p.score > 0.3)\n .map((p) => p.name);\n\n return {\n preset: best.preset,\n presetName: best.name,\n style,\n confidence: best.score,\n reasoning: generateReasoning(best.preset, criteria, best.score),\n alternatives,\n };\n}\n\n/**\n * Gets recommendations for a specific context.\n *\n * Returns multiple preset options ranked by suitability.\n *\n * @param context - The UI context\n * @param options - Additional filtering options\n * @returns Array of recommendations\n *\n * @example\n * ```ts\n * const recommendations = getRecommendations(\"modal\");\n * // Returns: [\n * // { preset: scale, name: \"scale\", reason: \"...\", score: 0.9 },\n * // { preset: fadeIn, name: \"fadeIn\", reason: \"...\", score: 0.8 },\n * // ...\n * // ]\n * ```\n */\nexport function getRecommendations(\n context: PresetContext,\n options: {\n maxResults?: number;\n minScore?: number;\n } = {},\n): PresetRecommendation[] {\n const { maxResults = 5, minScore = 0.3 } = options;\n\n const contextPresets = getPresetsByContext(context);\n\n const recommendations: PresetRecommendation[] = contextPresets.map((preset) => {\n const name = Object.entries(componentPresets).find(([_, p]) => p === preset)?.[0] as ComponentPresetName;\n\n // Score based on how well the preset fits the context\n const contextFit = preset.metadata.context.indexOf(context) === 0 ? 1 : 0.7;\n const intensityFit = 1 - Math.abs(preset.metadata.intensity - 3) / 4;\n const score = (contextFit + intensityFit) / 2;\n\n return {\n preset,\n name,\n reason: `${preset.metadata.description}. Ideal for ${preset.metadata.context.slice(0, 2).join(\", \")}.`,\n score,\n };\n });\n\n return recommendations\n .filter((r) => r.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n}\n\n/**\n * Gets the default preset for a context.\n *\n * Quick helper for getting a sensible default animation.\n *\n * @param context - The UI context\n * @returns The default preset for that context\n *\n * @example\n * ```ts\n * const modalPreset = getDefaultPreset(\"modal\");\n * // Returns: scale preset\n *\n * const tooltipPreset = getDefaultPreset(\"tooltip\");\n * // Returns: fadeIn preset\n * ```\n */\nexport function getDefaultPreset(context: PresetContext): ComponentPreset {\n // Define sensible defaults for each context\n const defaults: Record<PresetContext, ComponentPresetName> = {\n modal: \"scale\",\n dropdown: \"slideDown\",\n tooltip: \"fadeIn\",\n drawer: \"slideRight\",\n card: \"fadeIn\",\n \"list-item\": \"slideUp\",\n notification: \"slideRight\",\n page: \"fadeIn\",\n section: \"slideUp\",\n hero: \"slideUpScale\",\n };\n\n return componentPresets[defaults[context]];\n}\n\n/**\n * Suggests animation combinations for a component.\n *\n * Returns entrance, exit, and interaction animations that work together.\n *\n * @param context - The UI context\n * @param style - Preferred motion style\n * @returns Object with suggested animations\n *\n * @example\n * ```ts\n * const suggestions = suggestAnimations(\"card\", \"standard\");\n * // Returns: {\n * // entrance: slideUp,\n * // exit: fadeOut,\n * // interaction: cardHover (from micro-interactions)\n * // }\n * ```\n */\nexport function suggestAnimations(\n context: PresetContext,\n style: MotionStyle = \"standard\",\n): {\n entrance: ComponentPreset;\n entranceName: ComponentPresetName;\n exit: ComponentPreset;\n exitName: ComponentPresetName;\n style: MotionStyle;\n} {\n // Get the best entrance animation\n const entranceResult = selectPreset({\n useCase: \"entrance\",\n context,\n style,\n });\n\n // Get a matching exit animation\n const exitResult = selectPreset({\n useCase: \"exit\",\n context,\n style,\n });\n\n return {\n entrance: entranceResult.preset,\n entranceName: entranceResult.presetName,\n exit: exitResult.preset,\n exitName: exitResult.presetName,\n style,\n };\n}\n\n// =============================================================================\n// Preset Metadata Utilities\n// =============================================================================\n\n/**\n * Gets all available preset names.\n */\nexport function getAllPresetNames(): ComponentPresetName[] {\n return Object.keys(componentPresets) as ComponentPresetName[];\n}\n\n/**\n * Gets all available contexts.\n */\nexport function getAllContexts(): PresetContext[] {\n return [\"modal\", \"dropdown\", \"tooltip\", \"drawer\", \"card\", \"list-item\", \"notification\", \"page\", \"section\", \"hero\"];\n}\n\n/**\n * Gets all available use cases.\n */\nexport function getAllUseCases(): PresetUseCase[] {\n return [\"entrance\", \"exit\", \"transition\", \"emphasis\", \"reveal\"];\n}\n\n/**\n * Gets preset metadata by name.\n */\nexport function getPresetMetadata(name: ComponentPresetName) {\n return componentPresets[name].metadata;\n}\n","// Copyright (c) 2026 Amsterdam Data Labs\n\n/**\n * @fileoverview Spring configuration presets for Motion library animations.\n *\n * @ai-hint This module provides pre-configured spring physics parameters for\n * smooth, natural-feeling animations. Springs are preferred over duration-based\n * animations for interactive UI elements as they respond naturally to interruption.\n *\n * @example\n * ```tsx\n * import { springGentle, springSnappy, createSpring } from './spring-configs';\n *\n * // Use a preset\n * <motion.div animate={{ x: 100 }} transition={springGentle} />\n *\n * // Create custom spring\n * const customSpring = createSpring(300, 25, 0.8);\n * ```\n */\n\n/**\n * Configuration object for spring-based animations.\n *\n * @ai-hint SpringTransition defines physics-based animation parameters.\n * Higher stiffness = faster movement, higher damping = less oscillation,\n * higher mass = more inertia and slower response.\n */\nexport interface SpringTransition {\n /** Animation type identifier */\n readonly type: \"spring\";\n /**\n * Spring stiffness coefficient.\n * Higher values create faster, more aggressive animations.\n * @default 100\n */\n readonly stiffness: number;\n /**\n * Damping coefficient to reduce oscillation.\n * Higher values reduce bounciness.\n * @default 10\n */\n readonly damping: number;\n /**\n * Mass of the animated object.\n * Higher values create more inertia.\n * @default 1\n */\n readonly mass: number;\n}\n\n/**\n * Parameters for creating a custom spring configuration.\n */\nexport interface SpringParams {\n /** Spring stiffness (tension) */\n stiffness: number;\n /** Damping (friction) */\n damping: number;\n /** Mass of the object */\n mass: number;\n}\n\n// =============================================================================\n// SPRING PRESETS\n// =============================================================================\n\n/**\n * Gentle spring with smooth, relaxed motion.\n *\n * @ai-hint Use for subtle transitions, fades, and non-interactive elements.\n * Creates a calm, professional feel without drawing attention.\n *\n * @example\n * ```tsx\n * <motion.div\n * initial={{ opacity: 0 }}\n * animate={{ opacity: 1 }}\n * transition={springGentle}\n * />\n * ```\n */\nexport const springGentle: SpringTransition = {\n type: \"spring\",\n stiffness: 200,\n damping: 30,\n mass: 1,\n} as const;\n\n/**\n * Snappy spring with quick, responsive motion.\n *\n * @ai-hint Use for buttons, toggles, and interactive elements that need\n * immediate feedback. Feels responsive without being jarring.\n *\n * @example\n * ```tsx\n * <motion.button\n * whileHover={{ scale: 1.05 }}\n * whileTap={{ scale: 0.95 }}\n * transition={springSnappy}\n * />\n * ```\n */\nexport const springSnappy: SpringTransition = {\n type: \"spring\",\n stiffness: 400,\n damping: 30,\n mass: 0.8,\n} as const;\n\n/**\n * Bouncy spring with playful oscillation.\n *\n * @ai-hint Use sparingly for celebratory moments, notifications, or\n * elements that should draw attention. Too much bounce can feel unpolished.\n *\n * @example\n * ```tsx\n * <motion.div\n * initial={{ scale: 0 }}\n * animate={{ scale: 1 }}\n * transition={springBouncy}\n * />\n * ```\n */\nexport const springBouncy: SpringTransition = {\n type: \"spring\",\n stiffness: 300,\n damping: 15,\n mass: 1,\n} as const;\n\n/**\n * Stiff spring with minimal oscillation and fast settling.\n *\n * @ai-hint Use for UI elements that need to feel solid and immediate,\n * like modals, dropdowns, or navigation. Minimal overshoot.\n *\n * @example\n * ```tsx\n * <motion.nav\n * initial={{ x: -300 }}\n * animate={{ x: 0 }}\n * transition={springStiff}\n * />\n * ```\n */\nexport const springStiff: SpringTransition = {\n type: \"spring\",\n stiffness: 500,\n damping: 35,\n mass: 0.6,\n} as const;\n\n// =============================================================================\n// SPRING FACTORY\n// =============================================================================\n\n/**\n * Creates a custom spring configuration with specified physics parameters.\n *\n * @ai-hint Use this factory when presets don't match your needs. Start with\n * a preset and adjust from there. Common adjustments:\n * - Increase stiffness for faster animations\n * - Increase damping to reduce bounce\n * - Decrease mass for quicker response\n *\n * @param stiffness - Spring stiffness (tension). Range: 100-1000. Higher = faster.\n * @param damping - Damping coefficient (friction). Range: 10-50. Higher = less bounce.\n * @param mass - Mass of the object. Range: 0.5-2. Higher = more inertia.\n * @returns A SpringTransition configuration object.\n *\n * @example\n * ```tsx\n * // Create a very snappy spring for micro-interactions\n * const microSpring = createSpring(600, 40, 0.5);\n *\n * // Create a heavy, slow spring for large elements\n * const heavySpring = createSpring(150, 25, 1.5);\n *\n * <motion.div transition={createSpring(350, 28, 0.9)} />\n * ```\n */\nexport function createSpring(stiffness: number, damping: number, mass: number): SpringTransition {\n return {\n type: \"spring\",\n stiffness,\n damping,\n mass,\n } as const;\n}\n\n/**\n * Creates a spring configuration from a params object.\n *\n * @ai-hint Alternative factory that accepts an object, useful when\n * spring parameters come from configuration or theme.\n *\n * @param params - Spring parameters object\n * @returns A SpringTransition configuration object.\n *\n * @example\n * ```tsx\n * const themeSpring = { stiffness: 250, damping: 22, mass: 1 };\n * const spring = createSpringFromParams(themeSpring);\n * ```\n */\nexport function createSpringFromParams(params: SpringParams): SpringTransition {\n return {\n type: \"spring\",\n stiffness: params.stiffness,\n damping: params.damping,\n mass: params.mass,\n } as const;\n}\n\n// =============================================================================\n// PRESET COLLECTIONS\n// =============================================================================\n\n/**\n * Collection of all spring presets for iteration or dynamic selection.\n *\n * @ai-hint Use this map when you need to select springs dynamically\n * based on user preference or theme configuration.\n *\n * @example\n * ```tsx\n * const springName = userPreference.animationStyle; // 'gentle' | 'snappy' | etc.\n * const spring = springPresets[springName];\n * ```\n */\nexport const springPresets = {\n gentle: springGentle,\n snappy: springSnappy,\n bouncy: springBouncy,\n stiff: springStiff,\n} as const;\n\n/**\n * Type representing valid spring preset names.\n */\nexport type SpringPresetName = keyof typeof springPresets;\n"],"mappings":"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","names":["scale","useReducedMotion","prefersReducedMotion","import_react","import_react","useReducedMotion","prefersReducedMotion","import_jsx_runtime","prefersReducedMotion","import_react","import_react","import_jsx_runtime","import_react","easingFunctions","useReducedMotion","prefersReducedMotion","import_react","prefersReducedMotion","presetConfig","scale","import_react","prefersReducedMotion","prefersReducedMotion"]}