@flikk/ui 1.0.0-beta.13 → 1.0.0-beta.15

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 (283) hide show
  1. package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
  2. package/dist/components/ai/PromptInput/PromptInput.js +4 -2
  3. package/dist/components/ai/PromptInput/VoiceRecorder.js +1 -1
  4. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +4 -4
  5. package/dist/components/ai/StreamingResponse/StreamingResponse.js +6 -0
  6. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.js +3 -14
  7. package/dist/components/ai/index.d.ts +0 -5
  8. package/dist/components/ai/index.js +8 -4
  9. package/dist/components/charts/DonutChart/DonutChart.js +1 -1
  10. package/dist/components/charts/DonutChart/MultiSegmentDonutChart.js +1 -1
  11. package/dist/components/charts/FunnelChart/FunnelChart.js +2 -2
  12. package/dist/components/charts/shared/ChartLegend/ChartLegend.types.d.ts +13 -1
  13. package/dist/components/charts/shared/ChartLegend/ChartLegendContent.js +1 -1
  14. package/dist/components/charts/shared/ChartTooltip/ChartTooltip.types.d.ts +13 -2
  15. package/dist/components/core/Accordion/AccordionItem.js +1 -1
  16. package/dist/components/core/Accordion/AccordionTrigger.js +1 -1
  17. package/dist/components/core/Alert/Alert.animations.d.ts +11 -0
  18. package/dist/components/core/Alert/Alert.animations.js +44 -0
  19. package/dist/components/core/Alert/Alert.js +16 -3
  20. package/dist/components/core/Avatar/Avatar.js +12 -7
  21. package/dist/components/core/Avatar/Avatar.theme.d.ts +4 -6
  22. package/dist/components/core/Avatar/Avatar.theme.js +22 -12
  23. package/dist/components/core/Avatar/Avatar.types.d.ts +9 -0
  24. package/dist/components/core/AvatarGroup/AvatarGroup.animations.js +2 -2
  25. package/dist/components/core/AvatarGroup/AvatarGroup.js +1 -2
  26. package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +1 -1
  27. package/dist/components/core/Badge/Badge.animations.js +1 -1
  28. package/dist/components/core/Badge/Badge.js +26 -50
  29. package/dist/components/core/Badge/Badge.theme.js +49 -63
  30. package/dist/components/core/Badge/Badge.types.d.ts +6 -30
  31. package/dist/components/core/Button/Button.js +2 -2
  32. package/dist/components/core/Button/Button.ripple.js +1 -1
  33. package/dist/components/core/Button/Button.theme.d.ts +1 -1
  34. package/dist/components/core/Button/Button.theme.js +5 -5
  35. package/dist/components/core/Button/Button.types.d.ts +1 -1
  36. package/dist/components/core/ButtonGroup/ButtonGroup.theme.js +6 -6
  37. package/dist/components/core/ButtonGroup/ButtonGroupText.js +1 -3
  38. package/dist/components/core/Calendar/Calendar.js +29 -3
  39. package/dist/components/core/Calendar/Calendar.theme.js +11 -7
  40. package/dist/components/core/Calendar/Calendar.types.d.ts +3 -0
  41. package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +2 -2
  42. package/dist/components/core/Carousel/CarouselBody.js +0 -1
  43. package/dist/components/core/CommandPalette/CommandItem.js +1 -1
  44. package/dist/components/core/CommandPalette/CommandPalette.js +6 -4
  45. package/dist/components/core/CommandPalette/CommandPalette.theme.js +1 -0
  46. package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +6 -0
  47. package/dist/components/core/ContextMenu/ContextMenu.js +5 -4
  48. package/dist/components/core/ContextMenu/ContextMenuTrigger.js +5 -6
  49. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  50. package/dist/components/core/Drawer/Drawer.js +25 -2
  51. package/dist/components/core/Drawer/Drawer.theme.js +2 -2
  52. package/dist/components/core/Drawer/Drawer.types.d.ts +6 -0
  53. package/dist/components/core/Drawer/DrawerHeader.js +1 -1
  54. package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
  55. package/dist/components/core/Dropdown/Dropdown.js +5 -1
  56. package/dist/components/core/Dropdown/Dropdown.types.d.ts +1 -0
  57. package/dist/components/core/Dropdown/DropdownItem.js +1 -1
  58. package/dist/components/core/Dropdown/DropdownMenu.js +4 -4
  59. package/dist/components/core/Dropdown/DropdownSection.js +1 -1
  60. package/dist/components/core/Dropdown/DropdownSeparator.js +1 -1
  61. package/dist/components/core/Dropdown/DropdownTrigger.d.ts +6 -1
  62. package/dist/components/core/Dropdown/DropdownTrigger.js +10 -8
  63. package/dist/components/core/Kbd/Kbd.theme.js +3 -3
  64. package/dist/components/core/Link/Link.js +4 -2
  65. package/dist/components/core/Message/Message.d.ts +9 -0
  66. package/dist/components/core/Message/Message.js +44 -3
  67. package/dist/components/core/Message/Message.theme.js +22 -0
  68. package/dist/components/core/Message/Message.types.d.ts +115 -0
  69. package/dist/components/core/Message/MessageAudio.d.ts +8 -0
  70. package/dist/components/core/Message/MessageAudio.js +11 -0
  71. package/dist/components/core/Message/MessageContext.d.ts +3 -1
  72. package/dist/components/core/Message/MessageDateDivider.d.ts +6 -0
  73. package/dist/components/core/Message/MessageDateDivider.js +10 -0
  74. package/dist/components/core/Message/MessageFile.d.ts +9 -0
  75. package/dist/components/core/Message/MessageFile.js +15 -0
  76. package/dist/components/core/Message/MessageImage.d.ts +11 -0
  77. package/dist/components/core/Message/MessageImage.js +13 -0
  78. package/dist/components/core/Message/MessageLink.d.ts +10 -0
  79. package/dist/components/core/Message/MessageLink.js +15 -0
  80. package/dist/components/core/Message/MessageReactions.d.ts +8 -0
  81. package/dist/components/core/Message/MessageReactions.js +12 -0
  82. package/dist/components/core/Message/MessageReply.d.ts +8 -0
  83. package/dist/components/core/Message/MessageReply.js +10 -0
  84. package/dist/components/core/Message/MessageSenderName.d.ts +6 -0
  85. package/dist/components/core/Message/MessageSenderName.js +10 -0
  86. package/dist/components/core/Message/MessageStatusIndicator.d.ts +9 -0
  87. package/dist/components/core/Message/MessageStatusIndicator.js +45 -0
  88. package/dist/components/core/Message/index.d.ts +19 -1
  89. package/dist/components/core/Modal/Modal.animations.d.ts +1 -0
  90. package/dist/components/core/Modal/Modal.animations.js +14 -11
  91. package/dist/components/core/Modal/ModalHeader.js +1 -1
  92. package/dist/components/core/NavItem/NavItem.js +100 -52
  93. package/dist/components/core/NavItem/NavItem.theme.js +6 -3
  94. package/dist/components/core/NavItem/NavItem.types.d.ts +44 -30
  95. package/dist/components/core/NavItem/index.d.ts +1 -1
  96. package/dist/components/core/Pagination/Pagination.theme.js +1 -1
  97. package/dist/components/core/Pill/Pill.theme.js +1 -1
  98. package/dist/components/core/Popover/Popover.d.ts +1 -1
  99. package/dist/components/core/Popover/PopoverBody.js +2 -2
  100. package/dist/components/core/Popover/PopoverTrigger.d.ts +1 -1
  101. package/dist/components/core/Popover/PopoverTrigger.js +11 -11
  102. package/dist/components/core/Progress/Progress.d.ts +9 -8
  103. package/dist/components/core/Progress/Progress.js +16 -16
  104. package/dist/components/core/Progress/Progress.theme.js +5 -16
  105. package/dist/components/core/Progress/Progress.types.d.ts +2 -20
  106. package/dist/components/core/Progress/index.d.ts +1 -1
  107. package/dist/components/core/ScrollArea/ScrollArea.js +49 -7
  108. package/dist/components/core/ScrollArea/ScrollArea.types.d.ts +12 -3
  109. package/dist/components/core/ScrollArea/index.d.ts +1 -1
  110. package/dist/components/core/Segmented/SegmentedItem.js +1 -1
  111. package/dist/components/core/Sidebar/Sidebar.d.ts +11 -1
  112. package/dist/components/core/Sidebar/Sidebar.js +51 -17
  113. package/dist/components/core/Sidebar/Sidebar.theme.js +9 -7
  114. package/dist/components/core/Sidebar/Sidebar.types.d.ts +57 -0
  115. package/dist/components/core/Sidebar/SidebarContent.js +3 -1
  116. package/dist/components/core/Sidebar/SidebarContext.d.ts +14 -0
  117. package/dist/components/core/Sidebar/SidebarContext.js +63 -11
  118. package/dist/components/core/Sidebar/SidebarFooter.js +3 -1
  119. package/dist/components/core/Sidebar/SidebarHeader.js +6 -2
  120. package/dist/components/core/Sidebar/SidebarMobileTrigger.d.ts +3 -0
  121. package/dist/components/core/Sidebar/SidebarMobileTrigger.js +29 -0
  122. package/dist/components/core/Sidebar/SidebarNav.js +3 -2
  123. package/dist/components/core/Sidebar/SidebarNavGroup.js +4 -2
  124. package/dist/components/core/Sidebar/SidebarToggle.js +2 -1
  125. package/dist/components/core/Sidebar/SidebarUserProfile.d.ts +3 -0
  126. package/dist/components/core/Sidebar/SidebarUserProfile.js +35 -0
  127. package/dist/components/core/Sidebar/index.d.ts +3 -1
  128. package/dist/components/core/SocialIcon/SocialIcon.js +1 -1
  129. package/dist/components/core/Sortable/Sortable.js +2 -2
  130. package/dist/components/core/Sortable/Sortable.theme.js +1 -1
  131. package/dist/components/core/Sortable/Sortable.types.d.ts +7 -5
  132. package/dist/components/core/Tabs/Tabs.theme.d.ts +1 -1
  133. package/dist/components/core/Tabs/Tabs.theme.js +3 -3
  134. package/dist/components/core/Tabs/TabsBody.js +1 -1
  135. package/dist/components/core/Tabs/TabsTrigger.js +1 -1
  136. package/dist/components/core/Tag/Tag.js +2 -2
  137. package/dist/components/core/Toast/Toast.d.ts +2 -2
  138. package/dist/components/core/Toast/Toast.js +30 -21
  139. package/dist/components/core/Toast/Toast.theme.js +4 -9
  140. package/dist/components/core/Toast/Toast.types.d.ts +4 -21
  141. package/dist/components/core/Toast/index.d.ts +1 -1
  142. package/dist/components/core/Tooltip/Tooltip.js +1 -1
  143. package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
  144. package/dist/components/core/index.js +11 -0
  145. package/dist/components/data-display/GanttChart/GanttChart.types.d.ts +2 -2
  146. package/dist/components/data-display/GanttChart/GanttToolbar.js +1 -1
  147. package/dist/components/data-display/Table/Table.types.d.ts +8 -8
  148. package/dist/components/effects/CustomCursor/CustomCursor.js +2 -2
  149. package/dist/components/effects/GlassSurface/GlassSurface.d.ts +1 -1
  150. package/dist/components/effects/GlassSurface/GlassSurface.js +12 -4
  151. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.d.ts +39 -0
  152. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.js +98 -0
  153. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.d.ts +3 -0
  154. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.js +104 -0
  155. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.types.d.ts +30 -0
  156. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.d.ts +3 -0
  157. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.js +36 -0
  158. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.d.ts +3 -0
  159. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.js +36 -0
  160. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.d.ts +3 -0
  161. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.js +37 -0
  162. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.d.ts +14 -0
  163. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.js +41 -0
  164. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.d.ts +25 -0
  165. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.js +84 -0
  166. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.d.ts +18 -0
  167. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.js +35 -0
  168. package/dist/components/effects/InteractiveCharacters/index.d.ts +2 -0
  169. package/dist/components/effects/MorphingText/MorphingText.d.ts +1 -1
  170. package/dist/components/effects/MorphingText/MorphingText.js +6 -5
  171. package/dist/components/effects/Neumorphic/InsetCircleButton.d.ts +9 -0
  172. package/dist/components/effects/Neumorphic/InsetCircleButton.js +10 -0
  173. package/dist/components/effects/Neumorphic/InsetPill.d.ts +7 -0
  174. package/dist/components/effects/Neumorphic/InsetPill.js +7 -0
  175. package/dist/components/effects/Neumorphic/index.d.ts +4 -0
  176. package/dist/components/effects/NoiseOverlay/NoiseOverlay.d.ts +1 -1
  177. package/dist/components/effects/NoiseOverlay/NoiseOverlay.js +4 -4
  178. package/dist/components/effects/Overlay/Overlay.js +6 -4
  179. package/dist/components/effects/PageTransition/PageTransition.animations.d.ts +8 -0
  180. package/dist/components/effects/PageTransition/PageTransition.animations.js +53 -0
  181. package/dist/components/effects/PageTransition/PageTransition.d.ts +3 -0
  182. package/dist/components/effects/PageTransition/PageTransition.js +71 -0
  183. package/dist/components/effects/PageTransition/PageTransition.types.d.ts +15 -0
  184. package/dist/components/effects/PageTransition/index.d.ts +2 -0
  185. package/dist/components/effects/index.d.ts +6 -0
  186. package/dist/components/effects/index.js +4 -0
  187. package/dist/components/forms/Checkbox/Checkbox.animations.d.ts +14 -0
  188. package/dist/components/forms/Checkbox/Checkbox.animations.js +53 -0
  189. package/dist/components/forms/Checkbox/Checkbox.js +4 -2
  190. package/dist/components/forms/Checkbox/Checkbox.theme.js +3 -3
  191. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +1 -1
  192. package/dist/components/forms/ColorPicker/ColorPickerBody.js +3 -3
  193. package/dist/components/forms/Combobox/Combobox.js +5 -3
  194. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
  195. package/dist/components/forms/DateRangePicker/DateRangePicker.animations.d.ts +1 -0
  196. package/dist/components/forms/DateRangePicker/DateRangePicker.d.ts +37 -0
  197. package/dist/components/forms/DateRangePicker/DateRangePicker.js +110 -0
  198. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.d.ts +5 -0
  199. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +52 -0
  200. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +154 -0
  201. package/dist/components/forms/DateRangePicker/DateRangePickerBody.d.ts +6 -0
  202. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +208 -0
  203. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.d.ts +6 -0
  204. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +41 -0
  205. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.d.ts +6 -0
  206. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +32 -0
  207. package/dist/components/forms/DateRangePicker/dateRangePresets.d.ts +5 -0
  208. package/dist/components/forms/DateRangePicker/dateRangePresets.js +59 -0
  209. package/dist/components/forms/DateRangePicker/index.d.ts +4 -0
  210. package/dist/components/forms/FileUpload/FileUploadProgress.animations.d.ts +36 -0
  211. package/dist/components/forms/FileUpload/FileUploadProgress.animations.js +22 -0
  212. package/dist/components/forms/FileUpload/FileUploadProgress.d.ts +3 -0
  213. package/dist/components/forms/FileUpload/FileUploadProgress.js +111 -0
  214. package/dist/components/forms/FileUpload/FileUploadProgress.theme.d.ts +19 -0
  215. package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +27 -0
  216. package/dist/components/forms/FileUpload/FileUploadProgress.types.d.ts +33 -0
  217. package/dist/components/forms/FileUpload/index.d.ts +3 -0
  218. package/dist/components/forms/Input/Input.js +8 -13
  219. package/dist/components/forms/Input/Input.types.d.ts +6 -0
  220. package/dist/components/forms/InputAddress/InputAddress.theme.js +1 -1
  221. package/dist/components/forms/InputCounter/InputCounter.js +1 -1
  222. package/dist/components/forms/InputCreditCard/InputCreditCard.theme.js +1 -1
  223. package/dist/components/forms/InputOTP/InputOTP.theme.js +1 -1
  224. package/dist/components/forms/Radio/Radio.animations.d.ts +10 -0
  225. package/dist/components/forms/Radio/Radio.animations.js +33 -0
  226. package/dist/components/forms/Radio/Radio.js +11 -2
  227. package/dist/components/forms/Radio/Radio.theme.js +3 -3
  228. package/dist/components/forms/RichTextEditor/RichTextEditor.js +23 -14
  229. package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +2 -2
  230. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +11 -0
  231. package/dist/components/forms/Select/Select.d.ts +1 -1
  232. package/dist/components/forms/Select/Select.js +7 -7
  233. package/dist/components/forms/Select/Select.types.d.ts +3 -3
  234. package/dist/components/forms/SelectableCard/SelectableCard.js +1 -1
  235. package/dist/components/forms/Slider/Slider.theme.js +1 -1
  236. package/dist/components/forms/Switch/Switch.theme.js +3 -3
  237. package/dist/components/forms/forms.theme.js +1 -1
  238. package/dist/components/forms/index.d.ts +6 -0
  239. package/dist/components/forms/index.js +8 -0
  240. package/dist/hooks/index.d.ts +1 -0
  241. package/dist/hooks/useMediaQuery.d.ts +5 -0
  242. package/dist/hooks/useMediaQuery.js +21 -0
  243. package/dist/index.js +23 -0
  244. package/dist/styles.css +1 -1
  245. package/dist/utils/dateUtils.js +56 -5
  246. package/dist/utils/formatUtils.d.ts +10 -0
  247. package/dist/utils/formatUtils.js +24 -0
  248. package/dist/utils/index.d.ts +1 -1
  249. package/package.json +12 -4
  250. package/src/global.scss +320 -39
  251. package/src/styles/theme.css +151 -62
  252. package/src/theme-plugin.css +13 -0
  253. package/dist/components/ai/ApprovalCard/ApprovalCard.d.ts +0 -3
  254. package/dist/components/ai/ApprovalCard/ApprovalCard.js +0 -16
  255. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.d.ts +0 -13
  256. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.js +0 -15
  257. package/dist/components/ai/ApprovalCard/ApprovalCard.types.d.ts +0 -43
  258. package/dist/components/ai/ApprovalCard/index.d.ts +0 -2
  259. package/dist/components/ai/MessageHistory/MessageHistory.d.ts +0 -18
  260. package/dist/components/ai/MessageHistory/MessageHistory.js +0 -98
  261. package/dist/components/ai/MessageHistory/MessageHistory.theme.d.ts +0 -2
  262. package/dist/components/ai/MessageHistory/MessageHistory.theme.js +0 -8
  263. package/dist/components/ai/MessageHistory/MessageHistory.types.d.ts +0 -94
  264. package/dist/components/ai/MessageHistory/index.d.ts +0 -3
  265. package/dist/icons/Icon.d.ts +0 -24
  266. package/dist/icons/Icon.js +0 -30
  267. package/dist/icons/Index.d.ts +0 -16
  268. package/dist/icons/core/ChevronUpDown.d.ts +0 -1
  269. package/dist/icons/core/ChevronUpDown.js +0 -7
  270. package/dist/icons/core/DollarIcon.d.ts +0 -1
  271. package/dist/icons/core/DollarIcon.js +0 -5
  272. package/dist/icons/core/LockIcon.d.ts +0 -1
  273. package/dist/icons/core/LockIcon.js +0 -5
  274. package/dist/icons/core/MinusIcon.d.ts +0 -1
  275. package/dist/icons/core/MinusIcon.js +0 -7
  276. package/dist/icons/core/PlusIcon.d.ts +0 -1
  277. package/dist/icons/core/PlusIcon.js +0 -7
  278. package/dist/icons/core/SearchIcon.d.ts +0 -1
  279. package/dist/icons/core/SearchIcon.js +0 -7
  280. package/dist/icons/core/TickIcon.d.ts +0 -1
  281. package/dist/icons/core/TickIcon.js +0 -5
  282. package/dist/icons/core/User.d.ts +0 -1
  283. package/dist/utils/useClickOutside.d.ts +0 -1
@@ -1,7 +1,7 @@
1
1
  const tooltipTheme = {
2
2
  // Base style for the tooltip - using fixed positioning for portal rendering
3
3
  baseStyle: "fixed z-[99] rounded-[var(--tooltip-radius)] py-1 px-2 text-sm text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 pointer-events-none bg-white/60 backdrop-blur-md outline outline-[var(--color-border)] shadow-lg border-t-[1px] border-white " +
4
- "dark:bg-neutral-800/80 dark:outline-[var(--color-border)]/80 dark:border-[var(--color-border)]",
4
+ "dark:bg-[var(--color-neutral-800)]/80 dark:outline-[var(--color-border)]/80 dark:border-[var(--color-border)]",
5
5
  };
6
6
 
7
7
  export { tooltipTheme };
@@ -74,6 +74,15 @@ export { messageTheme } from './Message/Message.theme.js';
74
74
  export { messageListTheme } from './Message/MessageList.theme.js';
75
75
  export { TypeWriter } from './Message/TypeWriter.js';
76
76
  export { MessageBody } from './Message/MessageBody.js';
77
+ export { MessageStatusIndicator } from './Message/MessageStatusIndicator.js';
78
+ export { MessageSenderName } from './Message/MessageSenderName.js';
79
+ export { MessageFile } from './Message/MessageFile.js';
80
+ export { MessageImage } from './Message/MessageImage.js';
81
+ export { MessageAudio } from './Message/MessageAudio.js';
82
+ export { MessageLink } from './Message/MessageLink.js';
83
+ export { MessageReply } from './Message/MessageReply.js';
84
+ export { MessageReactions } from './Message/MessageReactions.js';
85
+ export { MessageDateDivider } from './Message/MessageDateDivider.js';
77
86
  export { Empty } from './Empty/Empty.js';
78
87
  export { emptyTheme } from './Empty/Empty.theme.js';
79
88
  export { Masonry } from './Masonry/Masonry.js';
@@ -89,6 +98,8 @@ export { SidebarNav } from './Sidebar/SidebarNav.js';
89
98
  export { SidebarNavGroup } from './Sidebar/SidebarNavGroup.js';
90
99
  export { SidebarSubmenu } from './Sidebar/SidebarSubmenu.js';
91
100
  export { SidebarToggle } from './Sidebar/SidebarToggle.js';
101
+ export { SidebarMobileTrigger } from './Sidebar/SidebarMobileTrigger.js';
102
+ export { SidebarUserProfile } from './Sidebar/SidebarUserProfile.js';
92
103
  export { useSidebarContext } from './Sidebar/SidebarContext.js';
93
104
  export { OfflineIndicator } from './OfflineIndicator/OfflineIndicator.js';
94
105
  export { offlineIndicatorTheme } from './OfflineIndicator/OfflineIndicator.theme.js';
@@ -14,7 +14,7 @@ export interface GanttTask {
14
14
  completed?: boolean;
15
15
  dependencies?: string[];
16
16
  milestone?: boolean;
17
- [key: string]: any;
17
+ [key: string]: unknown;
18
18
  }
19
19
  export interface GanttHoliday {
20
20
  date: Date | string;
@@ -30,7 +30,7 @@ export interface GanttGroup {
30
30
  export interface GanttColumn<T extends GanttTask = GanttTask> {
31
31
  id: string;
32
32
  header: string;
33
- accessor: keyof T | ((task: T) => any);
33
+ accessor: keyof T | ((task: T) => ReactNode | string | number | boolean | null | undefined);
34
34
  cell?: (task: T, group: GanttGroup) => ReactNode;
35
35
  width?: number;
36
36
  align?: "left" | "center" | "right";
@@ -23,7 +23,7 @@ const GanttToolbar = () => {
23
23
  const targetScroll = todayOffset * dayWidth - container.clientWidth / 2;
24
24
  container.scrollTo({ left: targetScroll, behavior: "smooth" });
25
25
  };
26
- return (jsxs("div", { className: cn(theme.toolbarStyle), children: [jsxs("div", { className: "flex items-center gap-3", children: [todayOffset !== null && (jsxs(Button, { variant: "outline", color: "neutral", size: "sm", onClick: handleScrollToToday, children: [jsx(CalendarIcon, { className: "size-4" }), "Today"] })), jsx(Segmented, { value: zoom, onChange: (val) => setZoom(val), size: "sm", children: ZOOM_OPTIONS.map((opt) => (jsx(Segmented.Item, { value: opt.value, children: opt.label }, opt.value))) }), jsx(Checkbox, { id: "gantt-hide-completed", name: "hideCompleted", value: "hideCompleted", checked: hideCompleted, onChange: (checked) => setHideCompleted(checked), label: "Hide completed", size: "sm" })] }), jsx("div", { className: "flex items-center gap-2", children: onGroupAdd && !readonly && (jsxs(Button, { variant: "ghost", size: "sm", onClick: onGroupAdd, children: [jsx(PlusIcon, { className: "size-3.5" }), "Add group"] })) })] }));
26
+ return (jsxs("div", { className: cn(theme.toolbarStyle), children: [jsxs("div", { className: "flex items-center gap-3", children: [todayOffset !== null && (jsxs(Button, { variant: "outline", color: "neutral", size: "sm", onClick: handleScrollToToday, children: [jsx(CalendarIcon, { className: "size-4" }), "Today"] })), jsx(Segmented, { value: zoom, onChange: (val) => setZoom(val), size: "sm", children: ZOOM_OPTIONS.map((opt) => (jsx(Segmented.Item, { value: opt.value, children: opt.label }, opt.value))) }), jsx(Checkbox, { id: "gantt-hide-completed", name: "hideCompleted", value: "hideCompleted", checked: hideCompleted, onChange: (checked) => setHideCompleted(checked), label: "Hide completed", size: "sm" })] }), jsx("div", { className: "flex items-center gap-2", children: onGroupAdd && !readonly && (jsxs(Button, { variant: "soft", size: "sm", onClick: onGroupAdd, children: [jsx(PlusIcon, { className: "size-3.5" }), "Add group"] })) })] }));
27
27
  };
28
28
 
29
29
  export { GanttToolbar };
@@ -38,13 +38,13 @@ export interface FilterOption {
38
38
  /**
39
39
  * Column definition for table data display and behavior
40
40
  */
41
- export interface Column<T = any> {
41
+ export interface Column<T = unknown> {
42
42
  /** Unique identifier for the column */
43
43
  id: string;
44
44
  /** Header content - can be string or React element */
45
45
  header: string | ReactNode;
46
46
  /** Property key or function to extract cell data from row object */
47
- accessor: keyof T | ((row: T) => any);
47
+ accessor: keyof T | ((row: T) => ReactNode | string | number | boolean | null | undefined);
48
48
  /** Optional custom renderer for cell content */
49
49
  cell?: (row: T) => ReactNode;
50
50
  /** Enable sorting for this column */
@@ -134,7 +134,7 @@ export interface TableContextType {
134
134
  *
135
135
  * @template T The type of data objects in each table row
136
136
  */
137
- export interface TableProps<T = any> {
137
+ export interface TableProps<T = unknown> {
138
138
  /** Array of data objects to display - required for data-driven API */
139
139
  data?: T[];
140
140
  /** Column definitions for data display and behavior - required for data-driven API */
@@ -287,7 +287,7 @@ export interface InternalTableCellProps<T> {
287
287
  }
288
288
  export type ActionVariant = 'default' | 'danger';
289
289
  export type ActionPriority = 'high' | 'normal';
290
- export interface ActionItem<T = any> {
290
+ export interface ActionItem<T = unknown> {
291
291
  /** Unique identifier for the action */
292
292
  id: string;
293
293
  /** Display label for the action */
@@ -305,7 +305,7 @@ export interface ActionItem<T = any> {
305
305
  /** Function to determine if action should be disabled */
306
306
  disabled?: (row: T) => boolean;
307
307
  }
308
- export interface TableActionsProps<T = any> {
308
+ export interface TableActionsProps<T = unknown> {
309
309
  /** Array of action items to display */
310
310
  actions: ActionItem<T>[];
311
311
  /** Row data to pass to action handlers */
@@ -315,7 +315,7 @@ export interface TableActionsProps<T = any> {
315
315
  /** Additional CSS class name */
316
316
  className?: string;
317
317
  }
318
- export interface TableActionsMenuProps<T = any> {
318
+ export interface TableActionsMenuProps<T = unknown> {
319
319
  /** Array of action items to display in menu */
320
320
  actions: ActionItem<T>[];
321
321
  /** Row data to pass to action handlers */
@@ -351,7 +351,7 @@ export interface TableSelectionHeaderProps {
351
351
  onClearSelection: () => void;
352
352
  className?: string;
353
353
  }
354
- export interface TableColumnManagerProps<T = any> {
354
+ export interface TableColumnManagerProps<T = unknown> {
355
355
  columns: Column<T>[];
356
356
  visibleColumns: string[];
357
357
  columnOrder: string[];
@@ -359,7 +359,7 @@ export interface TableColumnManagerProps<T = any> {
359
359
  onResetToDefault: () => void;
360
360
  onColumnReorder?: (fromIndex: number, toIndex: number) => void;
361
361
  }
362
- export interface TableFilterProps<T = any> {
362
+ export interface TableFilterProps<T = unknown> {
363
363
  columns: Column<T>[];
364
364
  filterConfig: FilterConfig[];
365
365
  onFilterChange: (filterConfig: FilterConfig[]) => void;
@@ -125,7 +125,7 @@ CustomCursorProvider.displayName = "CustomCursorProvider";
125
125
  * </CustomCursor>
126
126
  * ```
127
127
  */
128
- const CustomCursor = React.forwardRef(({ children, size = "md", color = "primary", variant = "default", shape = "arrow", className, style, ...props }, ref) => {
128
+ const CustomCursor = React.forwardRef(({ children, size = "md", color = "primary", variant = "default", shape = "arrow", className, style, onAnimationStart: _onAnimationStart, onAnimationEnd: _onAnimationEnd, onDrag: _onDrag, onDragStart: _onDragStart, onDragEnd: _onDragEnd, ...props }, ref) => {
129
129
  const { cursorPos, isActive, containerRef, cursorRef } = useCustomCursor();
130
130
  React.useImperativeHandle(ref, () => cursorRef.current);
131
131
  const x = useMotionValue(0);
@@ -200,7 +200,7 @@ const userVariantColors = [
200
200
  "warning",
201
201
  "danger",
202
202
  ];
203
- const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align = "bottom-right", transition, variant = "default", avatar, name, color, className, style, ...props }, ref) => {
203
+ const CustomCursorFollow = React.forwardRef(({ children, sideOffset = 15, align = "bottom-right", transition, variant = "default", avatar, name, color, className, style, onAnimationStart: _onAnimationStart2, onAnimationEnd: _onAnimationEnd2, onDrag: _onDrag2, onDragStart: _onDragStart2, onDragEnd: _onDragEnd2, ...props }, ref) => {
204
204
  const { cursorPos, isActive, cursorRef } = useCustomCursor();
205
205
  const cursorFollowRef = React.useRef(null);
206
206
  const shouldReduceMotion = useReducedMotion();
@@ -5,4 +5,4 @@ import { GlassSurfaceProps } from "./GlassSurface.types";
5
5
  * Creates a realistic chromatic aberration glass effect using SVG filters.
6
6
  * Works as a wrapper for any content.
7
7
  */
8
- export declare const GlassSurface: React.FC<GlassSurfaceProps>;
8
+ export declare const GlassSurface: React.ForwardRefExoticComponent<GlassSurfaceProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useId, useState, useRef, useMemo, useEffect } from 'react';
2
+ import React__default, { useId, useState, useRef, useMemo, useEffect, useCallback } from 'react';
3
3
  import { cn } from '../../../utils/cn.js';
4
4
 
5
5
  /**
@@ -23,7 +23,7 @@ const useDarkMode = () => {
23
23
  * Creates a realistic chromatic aberration glass effect using SVG filters.
24
24
  * Works as a wrapper for any content.
25
25
  */
26
- const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", frosted = false, className = "", style = {}, }) => {
26
+ const GlassSurface = React__default.forwardRef(({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", frosted = false, className = "", style = {}, }, forwardedRef) => {
27
27
  const uniqueId = useId().replace(/:/g, "-");
28
28
  const filterId = `glass-filter-${uniqueId}`;
29
29
  const redGradId = `red-grad-${uniqueId}`;
@@ -250,7 +250,15 @@ const GlassSurface = ({ children, width, height, borderRadius = 20, borderWidth
250
250
  const focusVisibleClasses = resolvedDark
251
251
  ? "focus-visible:outline-2 focus-visible:outline-[#0A84FF] focus-visible:outline-offset-2"
252
252
  : "focus-visible:outline-2 focus-visible:outline-[#007AFF] focus-visible:outline-offset-2";
253
- return (jsxs("div", { ref: containerRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", id: "redchannel", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", id: "greenchannel", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", id: "bluechannel", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
254
- };
253
+ const mergedRef = useCallback((node) => {
254
+ containerRef.current = node;
255
+ if (typeof forwardedRef === "function")
256
+ forwardedRef(node);
257
+ else if (forwardedRef)
258
+ forwardedRef.current = node;
259
+ }, [forwardedRef]);
260
+ return (jsxs("div", { ref: mergedRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", id: "redchannel", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", id: "greenchannel", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", id: "bluechannel", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
261
+ });
262
+ GlassSurface.displayName = "GlassSurface";
255
263
 
256
264
  export { GlassSurface };
@@ -0,0 +1,39 @@
1
+ import type { Variants } from 'motion/react';
2
+ import type { CharacterState } from './InteractiveCharacters.types';
3
+ export declare const eyelidVariants: Record<CharacterState, {
4
+ scaleY: number;
5
+ }>;
6
+ export declare const blobBodyVariants: Variants;
7
+ export declare const tallBodyVariants: Variants;
8
+ export declare const smallBodyVariants: Variants;
9
+ export declare const blobMouthPaths: Record<CharacterState, string>;
10
+ export declare const tallMouthPaths: Record<CharacterState, string>;
11
+ export declare const smallMouthPaths: Record<CharacterState, string>;
12
+ export declare const eyebrowVariants: Record<CharacterState, {
13
+ rotate: number;
14
+ y: number;
15
+ }>;
16
+ export declare const springConfigs: {
17
+ readonly small: {
18
+ readonly stiffness: 300;
19
+ readonly damping: 20;
20
+ };
21
+ readonly blob: {
22
+ readonly stiffness: 150;
23
+ readonly damping: 25;
24
+ };
25
+ readonly tall: {
26
+ readonly stiffness: 80;
27
+ readonly damping: 30;
28
+ };
29
+ };
30
+ export declare const bodyTransition: {
31
+ type: "spring";
32
+ stiffness: number;
33
+ damping: number;
34
+ };
35
+ export declare const clickTransition: {
36
+ type: "spring";
37
+ stiffness: number;
38
+ damping: number;
39
+ };
@@ -0,0 +1,98 @@
1
+ // Eyelid variants — controls how much the eye is covered
2
+ // scaleY: 0 = fully open, 1 = fully closed
3
+ const eyelidVariants = {
4
+ idle: { scaleY: 0 },
5
+ email: { scaleY: 0 },
6
+ password: { scaleY: 1 },
7
+ peek: { scaleY: 0.6 },
8
+ surprised: { scaleY: 0 }, // wide open
9
+ love: { scaleY: 0.65 }, // happy squint ^_^
10
+ excited: { scaleY: 0 }, // wide open
11
+ };
12
+ // Body sway variants per character
13
+ const blobBodyVariants = {
14
+ idle: { rotate: 0, y: 0 },
15
+ email: { rotate: 2, y: -2 },
16
+ password: { rotate: -1, y: 2, scale: 0.97 },
17
+ peek: { rotate: 3, y: -1 },
18
+ surprised: { rotate: 0, y: -8, scale: 1.05 }, // jump up, puff out
19
+ love: { rotate: 0, y: 0 },
20
+ excited: { rotate: 0, y: 0 },
21
+ };
22
+ const tallBodyVariants = {
23
+ idle: { rotate: 0, y: 0 },
24
+ email: { rotate: -1.5, y: 0 },
25
+ password: { rotate: 0, y: 3, scale: 0.96 },
26
+ peek: { rotate: 2, y: -2 },
27
+ surprised: { rotate: 0, y: 0 },
28
+ love: { rotate: -2, y: -3, scale: 1.03 }, // slight lean, puff up
29
+ excited: { rotate: 0, y: 0 },
30
+ };
31
+ const smallBodyVariants = {
32
+ idle: { rotate: 0, y: 0 },
33
+ email: { rotate: 3, y: -3 },
34
+ password: { rotate: -2, y: 1, scale: 0.95 },
35
+ peek: { rotate: -3, y: -2 },
36
+ surprised: { rotate: 0, y: 0 },
37
+ love: { rotate: 0, y: 0 },
38
+ excited: { rotate: 5, y: -10, scale: 1.08 }, // big bounce, spin
39
+ };
40
+ // Mouth paths for each character per state
41
+ // All paths use M + Q for smooth interpolation between states
42
+ const blobMouthPaths = {
43
+ idle: 'M -10 0 Q 0 8 10 0', // wide gentle smile
44
+ email: 'M -12 -2 Q 0 12 12 -2', // big happy smile
45
+ password: 'M -6 0 Q 0 2 6 0', // flat/neutral
46
+ peek: 'M -8 0 Q 0 5 8 0', // small smirk
47
+ surprised: 'M -5 -4 Q 0 10 5 -4', // round "O" mouth
48
+ love: 'M -10 0 Q 0 8 10 0', // gentle smile
49
+ excited: 'M -12 -2 Q 0 12 12 -2', // big grin
50
+ };
51
+ const tallMouthPaths = {
52
+ idle: 'M -6 0 Q 0 3 6 0', // subtle relaxed smile
53
+ email: 'M -10 -1 Q 0 10 10 -1', // big happy smile
54
+ password: 'M -5 0 Q 0 0 5 0', // flat line (Q-based for animation)
55
+ peek: 'M -5 0 Q 2 6 7 -1', // asymmetric smirk
56
+ surprised: 'M -5 -3 Q 0 8 5 -3', // small O
57
+ love: 'M -10 -2 Q 0 12 10 -2', // wide beaming smile
58
+ excited: 'M -8 -1 Q 0 10 8 -1', // happy grin
59
+ };
60
+ const smallMouthPaths = {
61
+ idle: 'M -7 0 Q 0 6 7 0', // sweet smile
62
+ email: 'M -9 -1 Q 0 9 9 -1', // big grin
63
+ password: 'M -4 0 Q 0 1 4 0', // tiny neutral
64
+ peek: 'M -4 1 Q 1 6 6 0', // cheeky smirk
65
+ surprised: 'M -4 -3 Q 0 8 4 -3', // little O
66
+ love: 'M -7 0 Q 0 6 7 0', // sweet smile
67
+ excited: 'M -10 -3 Q 0 14 10 -3', // huge open grin
68
+ };
69
+ // Eyebrow angles for Tall character
70
+ const eyebrowVariants = {
71
+ idle: { rotate: 0, y: 0 },
72
+ email: { rotate: -5, y: -2 },
73
+ password: { rotate: 8, y: 2 },
74
+ peek: { rotate: -10, y: -1 },
75
+ surprised: { rotate: -12, y: -4 }, // raised high
76
+ love: { rotate: -6, y: -2 }, // gently raised
77
+ excited: { rotate: -8, y: -3 }, // raised
78
+ };
79
+ // Spring configs per character for mouse tracking
80
+ const springConfigs = {
81
+ small: { stiffness: 300, damping: 20 },
82
+ blob: { stiffness: 150, damping: 25 },
83
+ tall: { stiffness: 80, damping: 30 },
84
+ };
85
+ // Body spring for state transitions
86
+ const bodyTransition = {
87
+ type: 'spring',
88
+ stiffness: 200,
89
+ damping: 20,
90
+ };
91
+ // Bouncier transition for click reactions
92
+ const clickTransition = {
93
+ type: 'spring',
94
+ stiffness: 300,
95
+ damping: 15,
96
+ };
97
+
98
+ export { blobBodyVariants, blobMouthPaths, bodyTransition, clickTransition, eyebrowVariants, eyelidVariants, smallBodyVariants, smallMouthPaths, springConfigs, tallBodyVariants, tallMouthPaths };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { InteractiveCharactersProps } from './InteractiveCharacters.types';
3
+ export declare const InteractiveCharacters: React.FC<InteractiveCharactersProps>;
@@ -0,0 +1,104 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useRef, useState, useCallback, useEffect } from 'react';
3
+ import { useReducedMotion } from 'motion/react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ import { springConfigs } from './InteractiveCharacters.animations.js';
6
+ import { useMouseTracking } from './hooks/useMouseTracking.js';
7
+ import { useIdleAnimation } from './hooks/useIdleAnimation.js';
8
+ import { useBlink } from './hooks/useBlink.js';
9
+ import { BlobCharacter } from './characters/BlobCharacter.js';
10
+ import { TallCharacter } from './characters/TallCharacter.js';
11
+ import { SmallCharacter } from './characters/SmallCharacter.js';
12
+
13
+ const sizeMap = {
14
+ sm: 'w-[200px]',
15
+ md: 'w-[320px]',
16
+ lg: 'w-[400px]',
17
+ };
18
+ /** Click reaction states per character */
19
+ const CLICK_REACTIONS = {
20
+ blob: 'surprised',
21
+ tall: 'love',
22
+ small: 'excited',
23
+ };
24
+ /** How long click reactions last (ms) */
25
+ const CLICK_DURATION = 1500;
26
+ const InteractiveCharacters = ({ state = 'idle', trackMouse = true, size = 'md', className, }) => {
27
+ const svgRef = useRef(null);
28
+ const shouldReduceMotion = useReducedMotion();
29
+ const clickTimeoutRef = useRef(null);
30
+ const [clickedChar, setClickedChar] = useState(null);
31
+ const handleCharacterClick = useCallback((character) => {
32
+ if (clickTimeoutRef.current)
33
+ clearTimeout(clickTimeoutRef.current);
34
+ setClickedChar(character);
35
+ clickTimeoutRef.current = setTimeout(() => setClickedChar(null), CLICK_DURATION);
36
+ }, []);
37
+ // Cleanup timeout on unmount
38
+ useEffect(() => {
39
+ return () => {
40
+ if (clickTimeoutRef.current)
41
+ clearTimeout(clickTimeoutRef.current);
42
+ };
43
+ }, []);
44
+ // Determine effective state per character (click overrides form state)
45
+ const blobState = clickedChar === 'blob' ? CLICK_REACTIONS.blob : state;
46
+ const tallState = clickedChar === 'tall' ? CLICK_REACTIONS.tall : state;
47
+ const smallState = clickedChar === 'small' ? CLICK_REACTIONS.small : state;
48
+ const isTrackingEnabled = trackMouse && state !== 'password' && !shouldReduceMotion;
49
+ const isIdleAnimated = !shouldReduceMotion;
50
+ // Mouse tracking — different spring configs per character
51
+ const blobEye = useMouseTracking({
52
+ containerRef: svgRef,
53
+ enabled: isTrackingEnabled,
54
+ ...springConfigs.blob,
55
+ });
56
+ const tallEye = useMouseTracking({
57
+ containerRef: svgRef,
58
+ enabled: isTrackingEnabled,
59
+ ...springConfigs.tall,
60
+ });
61
+ const smallEye = useMouseTracking({
62
+ containerRef: svgRef,
63
+ enabled: isTrackingEnabled,
64
+ ...springConfigs.small,
65
+ });
66
+ // Idle sway/breathing/head — each character at different rates & phase offsets
67
+ const blobIdle = useIdleAnimation({
68
+ enabled: isIdleAnimated,
69
+ swayAmount: 1.5,
70
+ swaySpeed: 0.8,
71
+ breathAmount: 0.008,
72
+ headTiltAmount: 3,
73
+ headNudgeAmount: 1.5,
74
+ phaseOffset: 0,
75
+ });
76
+ const tallIdle = useIdleAnimation({
77
+ enabled: isIdleAnimated,
78
+ swayAmount: 1,
79
+ swaySpeed: 0.6,
80
+ breathAmount: 0.006,
81
+ headTiltAmount: 2,
82
+ headNudgeAmount: 1,
83
+ phaseOffset: 2.5,
84
+ });
85
+ const smallIdle = useIdleAnimation({
86
+ enabled: isIdleAnimated,
87
+ swayAmount: 2.5,
88
+ swaySpeed: 1.2,
89
+ breathAmount: 0.012,
90
+ headTiltAmount: 4,
91
+ headNudgeAmount: 2,
92
+ phaseOffset: 5,
93
+ });
94
+ // Blink — disable during password/peek and click reactions
95
+ const canBlinkBlob = blobState === 'idle' || blobState === 'email';
96
+ const canBlinkTall = tallState === 'idle' || tallState === 'email';
97
+ const canBlinkSmall = smallState === 'idle' || smallState === 'email';
98
+ const blobBlink = useBlink({ enabled: canBlinkBlob, minInterval: 2500, maxInterval: 5000 });
99
+ const tallBlink = useBlink({ enabled: canBlinkTall, minInterval: 3000, maxInterval: 6000 });
100
+ const smallBlink = useBlink({ enabled: canBlinkSmall, minInterval: 1800, maxInterval: 4000 });
101
+ return (jsx("div", { className: cn(sizeMap[size], className), "data-state": state, children: jsxs("svg", { ref: svgRef, viewBox: "0 0 400 180", xmlns: "http://www.w3.org/2000/svg", className: "w-full h-auto", role: "img", "aria-label": "Interactive characters that react to form input", children: [jsx("g", { transform: "translate(200, 170)", className: "cursor-pointer", children: jsx(TallCharacter, { state: tallState, eyeOffset: { x: tallEye.x, y: tallEye.y }, idle: tallIdle, blinkAmount: tallBlink, onClick: () => handleCharacterClick('tall') }) }), jsx("g", { transform: "translate(100, 170)", className: "cursor-pointer", children: jsx(BlobCharacter, { state: blobState, eyeOffset: { x: blobEye.x, y: blobEye.y }, idle: blobIdle, blinkAmount: blobBlink, onClick: () => handleCharacterClick('blob') }) }), jsx("g", { transform: "translate(310, 170)", className: "cursor-pointer", children: jsx(SmallCharacter, { state: smallState, eyeOffset: { x: smallEye.x, y: smallEye.y }, idle: smallIdle, blinkAmount: smallBlink, onClick: () => handleCharacterClick('small') }) })] }) }));
102
+ };
103
+
104
+ export { InteractiveCharacters };
@@ -0,0 +1,30 @@
1
+ import type { MotionValue } from 'motion/react';
2
+ export type CharacterState = 'idle' | 'email' | 'password' | 'peek' | 'surprised' | 'love' | 'excited';
3
+ export type CharacterSize = 'sm' | 'md' | 'lg';
4
+ export interface InteractiveCharactersProps {
5
+ /** Current character state — controls expressions and animations */
6
+ state?: CharacterState;
7
+ /** Enable mouse/cursor tracking for eye movement (default: true) */
8
+ trackMouse?: boolean;
9
+ /** Size preset (default: 'md') */
10
+ size?: CharacterSize;
11
+ /** Additional class names for the container */
12
+ className?: string;
13
+ }
14
+ export interface CharacterProps {
15
+ state: CharacterState;
16
+ eyeOffset: {
17
+ x: MotionValue<number>;
18
+ y: MotionValue<number>;
19
+ };
20
+ idle: {
21
+ sway: MotionValue<number>;
22
+ bob: MotionValue<number>;
23
+ breath: MotionValue<number>;
24
+ headTilt: MotionValue<number>;
25
+ headX: MotionValue<number>;
26
+ headY: MotionValue<number>;
27
+ };
28
+ blinkAmount: MotionValue<number>;
29
+ onClick?: () => void;
30
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { CharacterProps } from '../InteractiveCharacters.types';
3
+ export declare const BlobCharacter: React.FC<CharacterProps>;
@@ -0,0 +1,36 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTransform, motion } from 'motion/react';
3
+ import { eyelidVariants, clickTransition, bodyTransition, blobBodyVariants, blobMouthPaths } from '../InteractiveCharacters.animations.js';
4
+
5
+ const LEFT_EYE = { cx: 32, cy: -50 };
6
+ const RIGHT_EYE = { cx: 68, cy: -50 };
7
+ const CLICK_STATES = new Set(['surprised', 'love', 'excited']);
8
+ const BlobCharacter = ({ state, eyeOffset, idle, blinkAmount, onClick, }) => {
9
+ const leftPupilX = useTransform(eyeOffset.x, (v) => LEFT_EYE.cx + v);
10
+ const leftPupilY = useTransform(eyeOffset.y, (v) => LEFT_EYE.cy + v);
11
+ const rightPupilX = useTransform(eyeOffset.x, (v) => RIGHT_EYE.cx + v);
12
+ const rightPupilY = useTransform(eyeOffset.y, (v) => RIGHT_EYE.cy + v);
13
+ // Combine idle head movement with cursor tracking for head turning
14
+ const combinedHeadX = useTransform([idle.headX, eyeOffset.x], ([idleX, cursorX]) => idleX + cursorX * 0.5);
15
+ const combinedHeadY = useTransform([idle.headY, eyeOffset.y], ([idleY, cursorY]) => idleY + cursorY * 0.3);
16
+ const combinedHeadRotate = useTransform([idle.headTilt, eyeOffset.x], ([tilt, cursorX]) => tilt + cursorX * 0.5);
17
+ const stateEyelid = eyelidVariants[state].scaleY;
18
+ const eyelidScale = useTransform(blinkAmount, (blink) => Math.max(stateEyelid, blink));
19
+ const isClickReaction = CLICK_STATES.has(state);
20
+ const transition = isClickReaction ? clickTransition : bodyTransition;
21
+ return (jsxs(motion.g, { animate: state, variants: blobBodyVariants, transition: transition, style: {
22
+ originX: '50%',
23
+ originY: '100%',
24
+ x: idle.sway,
25
+ y: idle.bob,
26
+ scale: idle.breath,
27
+ }, onClick: onClick, children: [jsx("path", { d: "M 0 0 Q 0 -95 65 -95 Q 100 -95 100 -50 Q 100 0 100 0 Z", fill: "#F97316" }), jsxs(motion.g, { style: {
28
+ originX: '50px',
29
+ originY: '-50px',
30
+ rotate: combinedHeadRotate,
31
+ x: combinedHeadX,
32
+ y: combinedHeadY,
33
+ }, children: [jsxs("g", { children: [jsx("clipPath", { id: "blob-eye-l", children: jsx("ellipse", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, rx: 14, ry: 16 }) }), jsx("ellipse", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, rx: 14, ry: 16, fill: "white" }), jsx(motion.circle, { cx: leftPupilX, cy: leftPupilY, r: 8.5, fill: "#1E293B", clipPath: "url(#blob-eye-l)" }), jsx("circle", { cx: LEFT_EYE.cx + 4, cy: LEFT_EYE.cy - 5.5, r: 3, fill: "white", opacity: 0.95 }), jsx("circle", { cx: LEFT_EYE.cx - 3, cy: LEFT_EYE.cy + 4, r: 1.5, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: LEFT_EYE.cx - 14, y: LEFT_EYE.cy - 16, width: 28, height: 32, fill: "#F97316", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsxs("g", { children: [jsx("clipPath", { id: "blob-eye-r", children: jsx("ellipse", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, rx: 14, ry: 16 }) }), jsx("ellipse", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, rx: 14, ry: 16, fill: "white" }), jsx(motion.circle, { cx: rightPupilX, cy: rightPupilY, r: 8.5, fill: "#1E293B", clipPath: "url(#blob-eye-r)" }), jsx("circle", { cx: RIGHT_EYE.cx + 4, cy: RIGHT_EYE.cy - 5.5, r: 3, fill: "white", opacity: 0.95 }), jsx("circle", { cx: RIGHT_EYE.cx - 3, cy: RIGHT_EYE.cy + 4, r: 1.5, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: RIGHT_EYE.cx - 14, y: RIGHT_EYE.cy - 16, width: 28, height: 32, fill: "#F97316", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsx("ellipse", { cx: 18, cy: -28, rx: 8, ry: 5.5, fill: "#FB923C", opacity: state === 'surprised' ? 0.7 : 0.5 }), jsx("ellipse", { cx: 82, cy: -28, rx: 8, ry: 5.5, fill: "#FB923C", opacity: state === 'surprised' ? 0.7 : 0.5 }), jsx(motion.path, { d: blobMouthPaths[state], fill: "none", stroke: "#1E293B", strokeWidth: 2.5, strokeLinecap: "round", animate: { d: blobMouthPaths[state] }, transition: transition, transform: "translate(50, -24)" })] })] }));
34
+ };
35
+
36
+ export { BlobCharacter };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { CharacterProps } from '../InteractiveCharacters.types';
3
+ export declare const SmallCharacter: React.FC<CharacterProps>;
@@ -0,0 +1,36 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTransform, motion } from 'motion/react';
3
+ import { eyelidVariants, clickTransition, bodyTransition, smallBodyVariants, smallMouthPaths } from '../InteractiveCharacters.animations.js';
4
+
5
+ const LEFT_EYE = { cx: -14, cy: -32 };
6
+ const RIGHT_EYE = { cx: 14, cy: -32 };
7
+ const CLICK_STATES = new Set(['surprised', 'love', 'excited']);
8
+ const SmallCharacter = ({ state, eyeOffset, idle, blinkAmount, onClick, }) => {
9
+ const leftPupilX = useTransform(eyeOffset.x, (v) => LEFT_EYE.cx + v);
10
+ const leftPupilY = useTransform(eyeOffset.y, (v) => LEFT_EYE.cy + v);
11
+ const rightPupilX = useTransform(eyeOffset.x, (v) => RIGHT_EYE.cx + v);
12
+ const rightPupilY = useTransform(eyeOffset.y, (v) => RIGHT_EYE.cy + v);
13
+ // Combine idle head movement with cursor tracking for head turning
14
+ const combinedHeadX = useTransform([idle.headX, eyeOffset.x], ([idleX, cursorX]) => idleX + cursorX * 0.6);
15
+ const combinedHeadY = useTransform([idle.headY, eyeOffset.y], ([idleY, cursorY]) => idleY + cursorY * 0.35);
16
+ const combinedHeadRotate = useTransform([idle.headTilt, eyeOffset.x], ([tilt, cursorX]) => tilt + cursorX * 0.6);
17
+ const stateEyelid = eyelidVariants[state].scaleY;
18
+ const eyelidScale = useTransform(blinkAmount, (blink) => Math.max(stateEyelid, blink));
19
+ const isClickReaction = CLICK_STATES.has(state);
20
+ const transition = isClickReaction ? clickTransition : bodyTransition;
21
+ return (jsxs(motion.g, { animate: state, variants: smallBodyVariants, transition: transition, style: {
22
+ originX: '50%',
23
+ originY: '100%',
24
+ x: idle.sway,
25
+ y: idle.bob,
26
+ scale: idle.breath,
27
+ }, onClick: onClick, children: [jsx("path", { d: "M -45 0 Q -45 -60 0 -60 Q 45 -60 45 0 Z", fill: "#FACC15" }), jsxs(motion.g, { style: {
28
+ originX: '0px',
29
+ originY: '-30px',
30
+ rotate: combinedHeadRotate,
31
+ x: combinedHeadX,
32
+ y: combinedHeadY,
33
+ }, children: [jsxs("g", { children: [jsx("clipPath", { id: "small-eye-l", children: jsx("circle", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, r: 10 }) }), jsx("circle", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, r: 10, fill: "white" }), jsx(motion.circle, { cx: leftPupilX, cy: leftPupilY, r: 6, fill: "#1E293B", clipPath: "url(#small-eye-l)" }), jsx("circle", { cx: LEFT_EYE.cx + 3, cy: LEFT_EYE.cy - 4, r: 2.2, fill: "white", opacity: 0.95 }), jsx("circle", { cx: LEFT_EYE.cx - 2, cy: LEFT_EYE.cy + 3, r: 1.1, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: LEFT_EYE.cx - 10, y: LEFT_EYE.cy - 10, width: 20, height: 20, fill: "#FACC15", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsxs("g", { children: [jsx("clipPath", { id: "small-eye-r", children: jsx("circle", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, r: 10 }) }), jsx("circle", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, r: 10, fill: "white" }), jsx(motion.circle, { cx: rightPupilX, cy: rightPupilY, r: 6, fill: "#1E293B", clipPath: "url(#small-eye-r)" }), jsx("circle", { cx: RIGHT_EYE.cx + 3, cy: RIGHT_EYE.cy - 4, r: 2.2, fill: "white", opacity: 0.95 }), jsx("circle", { cx: RIGHT_EYE.cx - 2, cy: RIGHT_EYE.cy + 3, r: 1.1, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: RIGHT_EYE.cx - 10, y: RIGHT_EYE.cy - 10, width: 20, height: 20, fill: "#FACC15", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsx("ellipse", { cx: -22, cy: -18, rx: 6, ry: 4, fill: "#FDE68A", opacity: state === 'excited' ? 0.85 : 0.6 }), jsx("ellipse", { cx: 22, cy: -18, rx: 6, ry: 4, fill: "#FDE68A", opacity: state === 'excited' ? 0.85 : 0.6 }), jsx(motion.path, { d: smallMouthPaths[state], fill: "none", stroke: "#1E293B", strokeWidth: 2, strokeLinecap: "round", animate: { d: smallMouthPaths[state] }, transition: transition, transform: "translate(0, -14)" })] })] }));
34
+ };
35
+
36
+ export { SmallCharacter };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { CharacterProps } from '../InteractiveCharacters.types';
3
+ export declare const TallCharacter: React.FC<CharacterProps>;
@@ -0,0 +1,37 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTransform, motion } from 'motion/react';
3
+ import { eyelidVariants, clickTransition, bodyTransition, tallBodyVariants, eyebrowVariants, tallMouthPaths } from '../InteractiveCharacters.animations.js';
4
+
5
+ const LEFT_EYE = { cx: -12, cy: -82 };
6
+ const RIGHT_EYE = { cx: 12, cy: -82 };
7
+ const CLICK_STATES = new Set(['surprised', 'love', 'excited']);
8
+ const TallCharacter = ({ state, eyeOffset, idle, blinkAmount, onClick, }) => {
9
+ const leftPupilX = useTransform(eyeOffset.x, (v) => LEFT_EYE.cx + v);
10
+ const leftPupilY = useTransform(eyeOffset.y, (v) => LEFT_EYE.cy + v);
11
+ const rightPupilX = useTransform(eyeOffset.x, (v) => RIGHT_EYE.cx + v);
12
+ const rightPupilY = useTransform(eyeOffset.y, (v) => RIGHT_EYE.cy + v);
13
+ // Combine idle head movement with cursor tracking for head turning
14
+ const combinedHeadX = useTransform([idle.headX, eyeOffset.x], ([idleX, cursorX]) => idleX + cursorX * 0.4);
15
+ const combinedHeadY = useTransform([idle.headY, eyeOffset.y], ([idleY, cursorY]) => idleY + cursorY * 0.25);
16
+ const combinedHeadRotate = useTransform([idle.headTilt, eyeOffset.x], ([tilt, cursorX]) => tilt + cursorX * 0.4);
17
+ const stateEyelid = eyelidVariants[state].scaleY;
18
+ const eyelidScale = useTransform(blinkAmount, (blink) => Math.max(stateEyelid, blink));
19
+ const eyebrow = eyebrowVariants[state];
20
+ const isClickReaction = CLICK_STATES.has(state);
21
+ const transition = isClickReaction ? clickTransition : bodyTransition;
22
+ return (jsxs(motion.g, { animate: state, variants: tallBodyVariants, transition: transition, style: {
23
+ originX: '50%',
24
+ originY: '100%',
25
+ x: idle.sway,
26
+ y: idle.bob,
27
+ scale: idle.breath,
28
+ }, onClick: onClick, children: [jsx("rect", { x: -30, y: -140, width: 60, height: 140, rx: 22, fill: "#8B5CF6" }), jsxs(motion.g, { style: {
29
+ originX: '0px',
30
+ originY: '-70px',
31
+ rotate: combinedHeadRotate,
32
+ x: combinedHeadX,
33
+ y: combinedHeadY,
34
+ }, children: [jsx(motion.line, { x1: -22, y1: -103, x2: -4, y2: -103, stroke: "#1E293B", strokeWidth: 2.5, strokeLinecap: "round", animate: { rotate: eyebrow.rotate, y: eyebrow.y }, transition: transition, style: { originX: '50%', originY: '50%', transformBox: 'fill-box' } }), jsx(motion.line, { x1: 4, y1: -103, x2: 22, y2: -103, stroke: "#1E293B", strokeWidth: 2.5, strokeLinecap: "round", animate: { rotate: -eyebrow.rotate, y: eyebrow.y }, transition: transition, style: { originX: '50%', originY: '50%', transformBox: 'fill-box' } }), jsxs("g", { children: [jsx("clipPath", { id: "tall-eye-l", children: jsx("ellipse", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, rx: 11, ry: 14 }) }), jsx("ellipse", { cx: LEFT_EYE.cx, cy: LEFT_EYE.cy, rx: 11, ry: 14, fill: "white" }), jsx(motion.circle, { cx: leftPupilX, cy: leftPupilY, r: 6.5, fill: "#1E293B", clipPath: "url(#tall-eye-l)" }), jsx("circle", { cx: LEFT_EYE.cx + 3.5, cy: LEFT_EYE.cy - 5, r: 2.5, fill: "white", opacity: 0.95 }), jsx("circle", { cx: LEFT_EYE.cx - 2.5, cy: LEFT_EYE.cy + 3, r: 1.2, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: LEFT_EYE.cx - 11, y: LEFT_EYE.cy - 14, width: 22, height: 28, fill: "#8B5CF6", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsxs("g", { children: [jsx("clipPath", { id: "tall-eye-r", children: jsx("ellipse", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, rx: 11, ry: 14 }) }), jsx("ellipse", { cx: RIGHT_EYE.cx, cy: RIGHT_EYE.cy, rx: 11, ry: 14, fill: "white" }), jsx(motion.circle, { cx: rightPupilX, cy: rightPupilY, r: 6.5, fill: "#1E293B", clipPath: "url(#tall-eye-r)" }), jsx("circle", { cx: RIGHT_EYE.cx + 3.5, cy: RIGHT_EYE.cy - 5, r: 2.5, fill: "white", opacity: 0.95 }), jsx("circle", { cx: RIGHT_EYE.cx - 2.5, cy: RIGHT_EYE.cy + 3, r: 1.2, fill: "white", opacity: 0.7 }), jsx(motion.rect, { x: RIGHT_EYE.cx - 11, y: RIGHT_EYE.cy - 14, width: 22, height: 28, fill: "#8B5CF6", rx: 2, style: { scaleY: eyelidScale, originX: '50%', originY: '0%', transformBox: 'fill-box' } })] }), jsx("ellipse", { cx: -22, cy: -62, rx: 7, ry: 5, fill: "#F9A8D4", opacity: state === 'love' ? 0.65 : 0.45 }), jsx("ellipse", { cx: 22, cy: -62, rx: 7, ry: 5, fill: "#F9A8D4", opacity: state === 'love' ? 0.65 : 0.45 }), jsx(motion.path, { d: tallMouthPaths[state], fill: "none", stroke: "#1E293B", strokeWidth: 2, strokeLinecap: "round", animate: { d: tallMouthPaths[state] }, transition: transition, transform: "translate(0, -55)" })] })] }));
35
+ };
36
+
37
+ export { TallCharacter };