@yewdiel21/motion-kit 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. package/NOTICE +3 -35
  2. package/README.md +93 -81
  3. package/dist/auto/index.d.ts +22 -3
  4. package/dist/auto/index.js +43 -5
  5. package/dist/auto/index.js.map +1 -1
  6. package/dist/{chunk-KLY5BRRI.js → chunk-34EZ7DF4.js} +1 -1
  7. package/dist/chunk-34EZ7DF4.js.map +1 -0
  8. package/dist/{chunk-RFDIZYFX.js → chunk-DOOMULVV.js} +20 -20
  9. package/dist/chunk-DOOMULVV.js.map +1 -0
  10. package/dist/{chunk-ABNRDDO7.js → chunk-I3DXF2KQ.js} +2 -2
  11. package/dist/{chunk-Q4LVFNLN.js → chunk-IKQ5FODN.js} +4 -4
  12. package/dist/chunk-IKQ5FODN.js.map +1 -0
  13. package/dist/{chunk-2BQGFOA7.js → chunk-J6OCFNGU.js} +2 -2
  14. package/dist/chunk-J6OCFNGU.js.map +1 -0
  15. package/dist/{chunk-6OJAP6ZL.js → chunk-QFBOHPWZ.js} +3 -3
  16. package/dist/chunk-QFBOHPWZ.js.map +1 -0
  17. package/dist/{chunk-J27KH2A2.js → chunk-RVSKEBIC.js} +1 -1
  18. package/dist/chunk-RVSKEBIC.js.map +1 -0
  19. package/dist/{chunk-34XYOXHG.js → chunk-TFNRIZHU.js} +1615 -12
  20. package/dist/chunk-TFNRIZHU.js.map +1 -0
  21. package/dist/{chunk-FS2HJVVY.js → chunk-XAKC2QY7.js} +1204 -5
  22. package/dist/chunk-XAKC2QY7.js.map +1 -0
  23. package/dist/css/components/calendar.css +159 -0
  24. package/dist/css/components/chat-background.css +2 -2
  25. package/dist/css/components/chat.css +1 -1
  26. package/dist/css/components/cursor.css +3 -3
  27. package/dist/css/components/dialog.css +3 -3
  28. package/dist/css/components/hover-card.css +14 -0
  29. package/dist/css/components/input-otp.css +10 -0
  30. package/dist/css/components/island.css +1 -1
  31. package/dist/css/components/menu.css +1 -1
  32. package/dist/css/components/nav.css +1 -5
  33. package/dist/css/components/pagination.css +11 -0
  34. package/dist/css/components/quantity.css +16 -0
  35. package/dist/css/components/slot-picker.css +126 -0
  36. package/dist/css/components/steps.css +2 -2
  37. package/dist/css/components/studio-dock.css +35 -0
  38. package/dist/css/components/theme-picker.css +1 -1
  39. package/dist/css/components/toast.css +1 -1
  40. package/dist/css/components/trailer.css +37 -0
  41. package/dist/css/controls.css +78 -13
  42. package/dist/css/effects.css +8 -8
  43. package/dist/css/fonts.css +1 -1
  44. package/dist/css/themes/black-green.css +1 -1
  45. package/dist/css/themes/black.css +1 -1
  46. package/dist/css/themes/blue.css +1 -1
  47. package/dist/css/themes/brown.css +1 -1
  48. package/dist/css/themes/cold-blue.css +1 -1
  49. package/dist/css/themes/funny.css +1 -1
  50. package/dist/css/themes/gray.css +1 -1
  51. package/dist/css/themes/green.css +1 -1
  52. package/dist/css/themes/modern-1.css +1 -1
  53. package/dist/css/themes/neogreen.css +1 -1
  54. package/dist/css/themes/new.css +1 -1
  55. package/dist/css/themes/new2.css +1 -1
  56. package/dist/css/themes/oled.css +1 -1
  57. package/dist/css/themes/orange.css +1 -1
  58. package/dist/css/themes/pastel-pink.css +1 -1
  59. package/dist/css/themes/pink.css +1 -1
  60. package/dist/css/themes/purple.css +1 -1
  61. package/dist/css/themes/red.css +1 -1
  62. package/dist/css/themes/super-blue.css +1 -1
  63. package/dist/css/themes.css +19 -19
  64. package/dist/css/tokens.css +9 -9
  65. package/dist/elements/index.d.ts +75 -7
  66. package/dist/elements/index.js +172 -6
  67. package/dist/elements/index.js.map +1 -1
  68. package/dist/{engine-CUr9QijM.d.ts → engine-GDGwQnJE.d.ts} +2 -2
  69. package/dist/gl/index.js +3 -3
  70. package/dist/index.css +1076 -63
  71. package/dist/index.d.ts +17 -17
  72. package/dist/index.js +49 -7
  73. package/dist/index.js.map +1 -1
  74. package/dist/react/index.d.ts +139 -40
  75. package/dist/react/index.js +355 -8
  76. package/dist/react/index.js.map +1 -1
  77. package/dist/{reduced-BM4Ls0g5.d.ts → reduced-BmBzKH94.d.ts} +215 -18
  78. package/dist/{reveal-WFUWDrei.d.ts → reveal-jsX-uwUz.d.ts} +233 -24
  79. package/dist/{store-Bqy_obnD.d.ts → store-DYb3tTsZ.d.ts} +5 -5
  80. package/dist/theme/generate.d.ts +1 -1
  81. package/dist/theme/generate.js +2 -2
  82. package/dist/theme/generate.js.map +1 -1
  83. package/dist/theme/index.d.ts +2 -2
  84. package/dist/theme/index.js +2 -2
  85. package/dist/{theme-BFMoCzi6.d.ts → theme-Bjf9qIIy.d.ts} +1 -1
  86. package/package.json +2 -2
  87. package/registry.json +230 -156
  88. package/skills/motion-kit/SKILL.md +209 -189
  89. package/skills/motion-kit/reference/components.md +5 -5
  90. package/skills/motion-kit/reference/design.md +14 -14
  91. package/skills/motion-kit/reference/recipes.md +48 -49
  92. package/src/auto/auto-init.ts +38 -0
  93. package/src/components/calendar/README.md +82 -0
  94. package/src/components/calendar/calendar.css +158 -0
  95. package/src/components/calendar/element.ts +27 -0
  96. package/src/components/calendar/engine.ts +412 -0
  97. package/src/components/calendar/react.tsx +69 -0
  98. package/src/components/chat/README.md +1 -3
  99. package/src/components/chat/chat.css +1 -1
  100. package/src/components/chat/engine.ts +1 -1
  101. package/src/components/chat/react.tsx +1 -1
  102. package/src/components/chat-background/README.md +1 -3
  103. package/src/components/chat-background/audio.ts +1 -1
  104. package/src/components/chat-background/chat-background.css +2 -2
  105. package/src/components/chat-background/engine.ts +1 -1
  106. package/src/components/chat-background/react.tsx +1 -1
  107. package/src/components/cursor/README.md +3 -5
  108. package/src/components/cursor/cursor.css +3 -3
  109. package/src/components/cursor/element.ts +2 -2
  110. package/src/components/cursor/engine.ts +5 -5
  111. package/src/components/cursor/react.tsx +1 -1
  112. package/src/components/dialog/README.md +4 -8
  113. package/src/components/dialog/dialog.css +3 -3
  114. package/src/components/dialog/engine.ts +2 -2
  115. package/src/components/dialog/react.tsx +1 -1
  116. package/src/components/hover-card/README.md +16 -0
  117. package/src/components/hover-card/element.ts +8 -0
  118. package/src/components/hover-card/engine.ts +69 -0
  119. package/src/components/hover-card/hover-card.css +13 -0
  120. package/src/components/hover-card/react.tsx +19 -0
  121. package/src/components/input-otp/README.md +18 -0
  122. package/src/components/input-otp/element.ts +14 -0
  123. package/src/components/input-otp/engine.ts +106 -0
  124. package/src/components/input-otp/input-otp.css +9 -0
  125. package/src/components/input-otp/react.tsx +21 -0
  126. package/src/components/island/README.md +7 -7
  127. package/src/components/island/engine.ts +3 -3
  128. package/src/components/island/island.css +1 -1
  129. package/src/components/island/react.tsx +3 -3
  130. package/src/components/menu/README.md +2 -4
  131. package/src/components/menu/engine.ts +1 -1
  132. package/src/components/menu/menu.css +1 -1
  133. package/src/components/menu/react.tsx +1 -1
  134. package/src/components/nav/README.md +12 -14
  135. package/src/components/nav/engine.ts +5 -5
  136. package/src/components/nav/nav.css +1 -5
  137. package/src/components/nav/react.tsx +3 -3
  138. package/src/components/pagination/README.md +17 -0
  139. package/src/components/pagination/element.ts +14 -0
  140. package/src/components/pagination/engine.ts +102 -0
  141. package/src/components/pagination/pagination.css +10 -0
  142. package/src/components/pagination/react.tsx +22 -0
  143. package/src/components/quantity/README.md +20 -0
  144. package/src/components/quantity/element.ts +14 -0
  145. package/src/components/quantity/engine.ts +85 -0
  146. package/src/components/quantity/quantity.css +15 -0
  147. package/src/components/quantity/react.tsx +21 -0
  148. package/src/components/slot-picker/README.md +68 -0
  149. package/src/components/slot-picker/element.ts +27 -0
  150. package/src/components/slot-picker/engine.ts +412 -0
  151. package/src/components/slot-picker/react.tsx +76 -0
  152. package/src/components/slot-picker/slot-picker.css +125 -0
  153. package/src/components/steps/README.md +1 -3
  154. package/src/components/steps/engine.ts +3 -3
  155. package/src/components/steps/react.tsx +2 -2
  156. package/src/components/steps/steps.css +2 -2
  157. package/src/components/studio-dock/README.md +44 -0
  158. package/src/components/studio-dock/element.ts +11 -0
  159. package/src/components/studio-dock/engine.ts +212 -0
  160. package/src/components/studio-dock/react.tsx +23 -0
  161. package/src/components/studio-dock/studio-dock.css +34 -0
  162. package/src/components/theme-picker/README.md +3 -5
  163. package/src/components/theme-picker/engine.ts +2 -2
  164. package/src/components/theme-picker/react.tsx +1 -1
  165. package/src/components/theme-picker/theme-picker.css +1 -1
  166. package/src/components/toast/README.md +1 -3
  167. package/src/components/toast/engine.ts +2 -2
  168. package/src/components/toast/react.tsx +1 -1
  169. package/src/components/toast/store.ts +1 -2
  170. package/src/components/toast/toast.css +1 -1
  171. package/src/components/trailer/README.md +28 -0
  172. package/src/components/trailer/element.ts +13 -0
  173. package/src/components/trailer/engine.ts +189 -0
  174. package/src/components/trailer/react.tsx +16 -0
  175. package/src/components/trailer/trailer.css +36 -0
  176. package/src/core/channels.ts +3 -3
  177. package/src/core/curves.ts +3 -3
  178. package/src/core/dates.ts +98 -0
  179. package/src/core/gsap.ts +2 -2
  180. package/src/core/loop.ts +1 -1
  181. package/src/core/math.ts +1 -1
  182. package/src/core/physics-spring.ts +2 -2
  183. package/src/core/scroll-track.ts +2 -4
  184. package/src/core/spring.ts +1 -1
  185. package/src/core/timing.ts +21 -22
  186. package/src/css/controls/README.md +24 -20
  187. package/src/css/controls/burger.css +1 -1
  188. package/src/css/controls/button.css +4 -4
  189. package/src/css/controls/checkbox.css +1 -1
  190. package/src/css/controls/chip.css +1 -1
  191. package/src/css/controls/field.css +2 -2
  192. package/src/css/controls/glass.css +4 -4
  193. package/src/css/controls/status.css +63 -0
  194. package/src/css/default-theme.css +1 -1
  195. package/src/css/effects/README.md +19 -21
  196. package/src/css/effects/anim.css +1 -1
  197. package/src/css/effects/fade.css +1 -1
  198. package/src/css/effects/float.css +1 -1
  199. package/src/css/effects/frost.css +1 -1
  200. package/src/css/effects/grain.css +1 -1
  201. package/src/css/effects/loading.css +1 -1
  202. package/src/css/effects/success.css +1 -1
  203. package/src/css/effects/text.css +1 -1
  204. package/src/css/fonts.css +1 -1
  205. package/src/css/states.css +1 -1
  206. package/src/css/themes/black-green.css +1 -1
  207. package/src/css/themes/black.css +1 -1
  208. package/src/css/themes/blue.css +1 -1
  209. package/src/css/themes/brown.css +1 -1
  210. package/src/css/themes/cold-blue.css +1 -1
  211. package/src/css/themes/funny.css +1 -1
  212. package/src/css/themes/gray.css +1 -1
  213. package/src/css/themes/green.css +1 -1
  214. package/src/css/themes/modern-1.css +1 -1
  215. package/src/css/themes/neogreen.css +1 -1
  216. package/src/css/themes/new.css +1 -1
  217. package/src/css/themes/new2.css +1 -1
  218. package/src/css/themes/oled.css +1 -1
  219. package/src/css/themes/orange.css +1 -1
  220. package/src/css/themes/pastel-pink.css +1 -1
  221. package/src/css/themes/pink.css +1 -1
  222. package/src/css/themes/purple.css +1 -1
  223. package/src/css/themes/red.css +1 -1
  224. package/src/css/themes/super-blue.css +1 -1
  225. package/src/css/tokens.css +8 -8
  226. package/src/elements/index.ts +24 -0
  227. package/src/gl/liquid-blend/README.md +3 -3
  228. package/src/gl/matcap/README.md +3 -3
  229. package/src/gl/particle-hero/README.md +1 -1
  230. package/src/gl/particle-hero/create-particle-hero.ts +3 -5
  231. package/src/gl/particle-hero/shaders.ts +1 -1
  232. package/src/gl/shader-blur/README.md +3 -3
  233. package/src/gl/shader-grain/README.md +3 -3
  234. package/src/index.ts +25 -0
  235. package/src/motion/chat.ts +2 -2
  236. package/src/motion/confetti.ts +1 -1
  237. package/src/motion/count.ts +1 -1
  238. package/src/motion/details.ts +1 -1
  239. package/src/motion/drag-dismiss.ts +1 -1
  240. package/src/motion/effects.ts +1 -1
  241. package/src/motion/entrances.ts +1 -1
  242. package/src/motion/floating.ts +1 -1
  243. package/src/motion/flow.ts +2 -2
  244. package/src/motion/indicator.ts +1 -1
  245. package/src/motion/layout.ts +1 -1
  246. package/src/motion/liquid.ts +1 -1
  247. package/src/motion/morph.ts +2 -2
  248. package/src/motion/reveal.ts +1 -1
  249. package/src/motion/sheet.ts +1 -1
  250. package/src/motion/surface.ts +1 -1
  251. package/src/react/animated-number.tsx +2 -2
  252. package/src/react/flip-group.tsx +1 -1
  253. package/src/react/frost.tsx +1 -1
  254. package/src/react/index.ts +21 -0
  255. package/src/react/slot-text.tsx +1 -1
  256. package/src/react/use-action-button.ts +6 -0
  257. package/src/react/use-card-dock.ts +1 -1
  258. package/src/react/use-cascade.ts +1 -1
  259. package/src/react/use-contrast.ts +1 -1
  260. package/src/react/use-depth-grid.ts +1 -1
  261. package/src/react/use-editorial-reveal.ts +7 -0
  262. package/src/react/use-fill-text.ts +1 -1
  263. package/src/react/use-film-hero.ts +6 -0
  264. package/src/react/use-font-cycle.ts +7 -0
  265. package/src/react/use-frame-zoom.ts +1 -1
  266. package/src/react/use-image-zoom.ts +5 -0
  267. package/src/react/use-joined-cta.ts +5 -0
  268. package/src/react/use-letters.ts +1 -1
  269. package/src/react/use-local-clock.ts +5 -0
  270. package/src/react/use-marquee.ts +1 -1
  271. package/src/react/use-mask-text.ts +1 -1
  272. package/src/react/use-parallax.ts +1 -1
  273. package/src/react/use-particle-hero.ts +1 -1
  274. package/src/react/use-scroll-dock.ts +5 -0
  275. package/src/react/use-snap-strip.ts +1 -1
  276. package/src/react/use-sticker.ts +5 -0
  277. package/src/react/use-studio-dock.ts +8 -0
  278. package/src/react/use-text-roll.ts +1 -1
  279. package/src/react/use-thumbnail-nav.ts +7 -0
  280. package/src/react/use-trailer.ts +6 -0
  281. package/src/react/use-weight-hover.ts +5 -0
  282. package/src/recipes/action-button/README.md +31 -0
  283. package/src/recipes/action-button/action-button.css +113 -0
  284. package/src/recipes/action-button/create-action-button.ts +56 -0
  285. package/src/recipes/card-dock/README.md +1 -1
  286. package/src/recipes/card-dock/card-dock.css +1 -1
  287. package/src/recipes/card-dock/create-card-dock.ts +2 -2
  288. package/src/recipes/cascade/README.md +1 -3
  289. package/src/recipes/cascade/create-cascade.ts +3 -3
  290. package/src/recipes/contrast/README.md +0 -2
  291. package/src/recipes/contrast/create-contrast.ts +1 -1
  292. package/src/recipes/counter/README.md +0 -2
  293. package/src/recipes/counter/create-counter.ts +1 -1
  294. package/src/recipes/curved-carousel/README.md +0 -2
  295. package/src/recipes/curved-carousel/create-curved-carousel.ts +2 -2
  296. package/src/recipes/curved-carousel/curved-carousel.css +1 -1
  297. package/src/recipes/depth-grid/README.md +0 -2
  298. package/src/recipes/depth-grid/create-depth-grid.ts +3 -4
  299. package/src/recipes/details/README.md +0 -2
  300. package/src/recipes/details/create-details.ts +1 -1
  301. package/src/recipes/dock-pill/README.md +3 -3
  302. package/src/recipes/drag-ruler/README.md +3 -3
  303. package/src/recipes/editorial-reveal/README.md +35 -0
  304. package/src/recipes/editorial-reveal/create-editorial-reveal.ts +91 -0
  305. package/src/recipes/editorial-reveal/editorial-reveal.css +17 -0
  306. package/src/recipes/fill-text/README.md +1 -1
  307. package/src/recipes/fill-text/create-fill-text.ts +1 -1
  308. package/src/recipes/film-hero/README.md +23 -0
  309. package/src/recipes/film-hero/create-film-hero.ts +65 -0
  310. package/src/recipes/film-hero/film-hero.css +29 -0
  311. package/src/recipes/fit-text/README.md +0 -2
  312. package/src/recipes/flow/README.md +0 -2
  313. package/src/recipes/flow/create-flow.ts +1 -1
  314. package/src/recipes/font-cycle/README.md +11 -0
  315. package/src/recipes/font-cycle/create-font-cycle.ts +126 -0
  316. package/src/recipes/font-cycle/font-cycle.css +36 -0
  317. package/src/recipes/frame-zoom/README.md +1 -3
  318. package/src/recipes/frame-zoom/create-frame-zoom.ts +2 -2
  319. package/src/recipes/image-zoom/README.md +16 -0
  320. package/src/recipes/image-zoom/create-image-zoom.ts +27 -0
  321. package/src/recipes/image-zoom/image-zoom.css +7 -0
  322. package/src/recipes/infinite-reel/README.md +3 -3
  323. package/src/recipes/joined-cta/README.md +13 -0
  324. package/src/recipes/joined-cta/create-joined-cta.ts +22 -0
  325. package/src/recipes/joined-cta/joined-cta.css +17 -0
  326. package/src/recipes/letters/README.md +2 -4
  327. package/src/recipes/letters/create-letters.ts +3 -3
  328. package/src/recipes/local-clock/README.md +31 -0
  329. package/src/recipes/local-clock/create-local-clock.ts +61 -0
  330. package/src/recipes/marquee/README.md +0 -2
  331. package/src/recipes/marquee/create-marquee.ts +3 -3
  332. package/src/recipes/marquee/marquee.css +1 -1
  333. package/src/recipes/mask-text/README.md +3 -5
  334. package/src/recipes/mask-text/create-mask-text.ts +4 -4
  335. package/src/recipes/parallax/README.md +1 -3
  336. package/src/recipes/parallax/create-parallax.ts +1 -1
  337. package/src/recipes/pile/README.md +0 -2
  338. package/src/recipes/pile/create-pile.ts +1 -1
  339. package/src/recipes/pile/pile-math.ts +1 -1
  340. package/src/recipes/pile/pile.css +1 -1
  341. package/src/recipes/pill/README.md +0 -2
  342. package/src/recipes/pill/pill.css +2 -2
  343. package/src/recipes/pop/README.md +0 -2
  344. package/src/recipes/pop/create-pop.ts +1 -1
  345. package/src/recipes/radial-menu/README.md +0 -2
  346. package/src/recipes/radial-menu/create-radial-menu.ts +1 -1
  347. package/src/recipes/radial-menu/radial-menu.css +1 -1
  348. package/src/recipes/reflow/README.md +3 -5
  349. package/src/recipes/reflow/create-reflow.ts +1 -1
  350. package/src/recipes/repel-bento/README.md +3 -3
  351. package/src/recipes/reveal/README.md +0 -2
  352. package/src/recipes/reveal/create-reveal.ts +1 -1
  353. package/src/recipes/rotator/README.md +3 -3
  354. package/src/recipes/scroll-dock/README.md +46 -0
  355. package/src/recipes/scroll-dock/create-scroll-dock.ts +72 -0
  356. package/src/recipes/scroll-dock/scroll-dock.css +70 -0
  357. package/src/recipes/slot-text/README.md +0 -2
  358. package/src/recipes/slot-text/create-slot-text.ts +1 -1
  359. package/src/recipes/snap-strip/README.md +1 -1
  360. package/src/recipes/snap-strip/create-snap-strip.ts +5 -6
  361. package/src/recipes/snap-strip/snap-strip.css +1 -1
  362. package/src/recipes/sortable/README.md +3 -5
  363. package/src/recipes/sortable/create-sortable.ts +4 -4
  364. package/src/recipes/sortable/sortable.css +1 -1
  365. package/src/recipes/spring-cards/README.md +0 -2
  366. package/src/recipes/spring-cards/create-spring-cards.ts +1 -1
  367. package/src/recipes/spring-cards/spring-cards.css +1 -1
  368. package/src/recipes/sticker/README.md +59 -0
  369. package/src/recipes/sticker/create-sticker.ts +490 -0
  370. package/src/recipes/sticker/sticker.css +112 -0
  371. package/src/recipes/stretch-footer/README.md +0 -2
  372. package/src/recipes/stretch-footer/create-stretch-footer.ts +1 -1
  373. package/src/recipes/stretch-footer/stretch-footer.css +1 -1
  374. package/src/recipes/tabs/README.md +0 -2
  375. package/src/recipes/tabs/create-tabs.ts +1 -1
  376. package/src/recipes/text-roll/README.md +1 -3
  377. package/src/recipes/text-roll/create-text-roll.ts +3 -3
  378. package/src/recipes/text-roll/text-roll.css +1 -1
  379. package/src/recipes/thumbnail-nav/README.md +16 -0
  380. package/src/recipes/thumbnail-nav/create-thumbnail-nav.ts +165 -0
  381. package/src/recipes/thumbnail-nav/thumbnail-nav.css +108 -0
  382. package/src/recipes/ticket-menu/README.md +3 -3
  383. package/src/recipes/weight-hover/README.md +37 -0
  384. package/src/recipes/weight-hover/create-weight-hover.ts +136 -0
  385. package/src/recipes/weight-hover/weight-hover.css +7 -0
  386. package/src/recipes/words/README.md +0 -2
  387. package/src/recipes/words/create-words.ts +1 -1
  388. package/src/theme/generate.ts +1 -1
  389. package/src/theme/presets.ts +2 -2
  390. package/src/theme/theme.ts +1 -2
  391. package/dist/chunk-2BQGFOA7.js.map +0 -1
  392. package/dist/chunk-34XYOXHG.js.map +0 -1
  393. package/dist/chunk-6OJAP6ZL.js.map +0 -1
  394. package/dist/chunk-FS2HJVVY.js.map +0 -1
  395. package/dist/chunk-J27KH2A2.js.map +0 -1
  396. package/dist/chunk-KLY5BRRI.js.map +0 -1
  397. package/dist/chunk-Q4LVFNLN.js.map +0 -1
  398. package/dist/chunk-RFDIZYFX.js.map +0 -1
  399. /package/dist/{chunk-ABNRDDO7.js.map → chunk-I3DXF2KQ.js.map} +0 -0
@@ -1,20 +1,20 @@
1
- # Recipe parameters and origin
1
+ # Recipe parameters
2
2
 
3
- Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed with REA on 2026-10-14) and Stepbro Tasks/Money, then re-implemented. No third-party code is shipped.
3
+ Parameters, defaults and behavior for the motion recipes.
4
4
 
5
5
  ## Shared
6
6
 
7
- | Name | Value | Origin |
8
- |---|---|---|
9
- | Spring | `v = v·friction^dt + (target − x)·stiffness·dt; x += v·dt`, stiffness .05, friction .8 | spencergabor.com `useSpring` |
10
- | Frame loop | one `gsap.ticker` callback, `dt = Δms / (1000/60)`, capped at 3; recipes subscribe only while visible | spencergabor.com shared rAF loop |
11
- | `--mk-ease-elastic` | `linear(0, .5737 7.6%, … 1.0011 81.26%, 1)` | spencergabor.com `--ease-out-elastic` |
12
- | `--mk-ease-elastic-hover` | `linear(0, .2178 2.1%, … .9981 86.66%, 1)` | spencergabor.com `--ease-out-elastic-100-30` |
13
- | `ELASTIC` (GSAP) | `elastic.out(1, 0.45)` | visual match of `--mk-ease-elastic` |
14
- | `mk-signature` | `M0,0 C0.308,0.19 0.107,0.633 0.288,0.866 0.382,0.987 0.656,1 1,1` | Stepbro signature curve |
15
- | `mk-flow` | `M0,0 C0.25,0.1 0.25,1 1,1` | Stepbro flowSoft |
16
- | `mk-close` | `.56,.27,0,1` | Stepbro close fade |
17
- | `--mk-shadow` | `0 9px 21px rgb(0 0 0/.1), 0 38px 38px rgb(0 0 0/.09), 0 85px 51px rgb(0 0 0/.05)` | spencergabor.com `--shadow` |
7
+ | Name | Value |
8
+ |---|---|
9
+ | Spring | `v = v·friction^dt + (target − x)·stiffness·dt; x += v·dt`, stiffness .05, friction .8 |
10
+ | Frame loop | one `gsap.ticker` callback, `dt = Δms / (1000/60)`, capped at 3; recipes subscribe only while visible |
11
+ | `--mk-ease-elastic` | `linear(0, .5737 7.6%, … 1.0011 81.26%, 1)` |
12
+ | `--mk-ease-elastic-hover` | `linear(0, .2178 2.1%, … .9981 86.66%, 1)` |
13
+ | `ELASTIC` (GSAP) | `elastic.out(1, 0.45)` |
14
+ | `mk-signature` | `M0,0 C0.308,0.19 0.107,0.633 0.288,0.866 0.382,0.987 0.656,1 1,1` |
15
+ | `mk-flow` | `M0,0 C0.25,0.1 0.25,1 1,1` |
16
+ | `mk-close` | `.56,.27,0,1` |
17
+ | `--mk-shadow` | `0 9px 21px rgb(0 0 0/.1), 0 38px 38px rgb(0 0 0/.09), 0 85px 51px rgb(0 0 0/.05)` |
18
18
 
19
19
  ## spring-cards
20
20
 
@@ -22,12 +22,12 @@ Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed w
22
22
  - Pointer push: `dx = (px − cx)/innerWidth·2`, `dy = (py − cy)/innerHeight·2`, `k = max(0, 1 − hypot(dx, dy))^6 · .4`, `push += movement·k`, `push *= .9^dt`.
23
23
  - CSS: `rotate: calc(tilt − velocity·.25deg)`; tilts 2°, −3°, 6°, −2°; vertical offsets 5 %, −6 %, 5 %, −4 %.
24
24
  - Entrance: `scale 0 → 1`, 1 s, elastic, `i·.08s + .4s`.
25
- - Portfolio change: 4:3 cards and −1.5 % overlap (Spencer: square, −6 %) so text on covers stays readable.
25
+ - Layout: 4:3 cards and −1.5 % overlap so text on covers stays readable.
26
26
 
27
27
  ## curved-carousel
28
28
 
29
29
  - Friction .85; drag velocity = pointer movement per frame; on release `v·2`, rest `x − v·f/(1−f)`, snap to the nearest slide, approach `x += (target − x)(1 − f^dt)`.
30
- - Tap: under 6 px of travel (Spencer: < 10 px and < 100 ms).
30
+ - Tap: under 6 px of travel.
31
31
  - Wheel: `v −= deltaX·.2` when horizontal; snap 150 ms after the last wheel event.
32
32
  - Arc: `rotate: t·.03deg`, origin `50% 70vw`, `translateY: cos(t·π/1000)·−3rem + 3rem`, title opacity `cos(t·π/600)`; `t` = slide centre − viewport centre in px.
33
33
  - Entrance: media from `scale .8; translate 0 20%`, 1.4 s elastic, delay `sin(k·π/2)·.12s`.
@@ -35,15 +35,15 @@ Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed w
35
35
  ## pile
36
36
 
37
37
  - Layers: `rotation = rand(2,5)·(±1 alternating)`, `offsetX = rand(4,10)·random sign`, `offsetY = (n − i)·5`; seeded (mulberry32) so SSR and client match.
38
- - CSS: `rotate: rot·.6deg`, `translate: px·.3% py·.3%` (Spencer: .5deg / .25%).
38
+ - CSS: `rotate: rot·.6deg`, `translate: px·.3% py·.3%`.
39
39
  - In view: media `scale .7 → 1`, shadow `0 → 1`, .8 s elastic; hover 1.01/1.02/1.03, active .97/.98/.99.
40
40
 
41
41
  ## words
42
42
 
43
43
  - `scaleY 0 → 1`, `yPercent 25 → 0`, origin bottom, .8 s, `ELASTIC`, 100 ms between words, 60 ms between letters.
44
- - Spencer did this with CSS transitions and `@starting-style`; the package uses GSAP SplitText so reduced motion and text replacement work.
44
+ - Uses GSAP SplitText with reduced-motion support and text replacement.
45
45
 
46
- ## flow (Stepbro)
46
+ ## flow
47
47
 
48
48
  - From `y −20`, `blur(16px)`, opacity 0 → 0, 0.5 s, 50 ms stagger, `mk-flow`.
49
49
 
@@ -62,21 +62,21 @@ Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed w
62
62
 
63
63
  ## radial-menu
64
64
 
65
- - Item position: `translate(sin(i·.9 + 1.5708)·−r, cos(i·.9 + 1.5708)·r)`, r = 3.6rem (Spencer: spacing .75, start 1.25).
65
+ - Item position: `translate(sin(i·.9 + 1.5708)·−r, cos(i·.9 + 1.5708)·r)`, r = 3.6rem.
66
66
  - Open: `scale .5 → 1`, .5 s elastic, `i·.05s`; close: .15 s `cubic-bezier(.55,.055,.675,.19)`.
67
67
 
68
68
  ## pill
69
69
 
70
70
  - Hover `scale 1.05` + shadow, active `.95`, .8 s elastic; `.mk-stretch` hover `scaleY(1.2)`, 1 s elastic-hover.
71
71
 
72
- ## Stepbro v0.2 (Tasks `especificacion-replicacion.json`, Money `replication-catalog.json`)
72
+ ## Core motion and surfaces
73
73
 
74
- | Name | Value | Kit id |
75
- |---|---|---|
76
- | `mk-fade-away` / `mk-blur-away` | `.56,.27,0,1` / `.37,.35,0,1` | modal-close-origin |
77
- | `mk-chat-scroll` | `M0,0 C0.308,0.19 0.318,0.567 0.5,0.8 0.593,0.921 0.656,1 1,1` | chat-scroll |
78
- | `mk-layout-reflow` / `mk-sortable-land` | spring path `FA(.52)` / `FA(.62)` (stiffness 5.6, sampled 72 steps) | task-layout, task-drag |
79
- | `--mk-ease-signature` | Stepbro's own `linear()` sampling of the signature (its backdrop tint) | tasks-modal-backdrop |
74
+ | Name | Value |
75
+ |---|---|
76
+ | `mk-fade-away` / `mk-blur-away` | `.56,.27,0,1` / `.37,.35,0,1` |
77
+ | `mk-chat-scroll` | `M0,0 C0.308,0.19 0.318,0.567 0.5,0.8 0.593,0.921 0.656,1 1,1` |
78
+ | `mk-layout-reflow` / `mk-sortable-land` | spring path `FA(.52)` / `FA(.62)` (stiffness 5.6, sampled 72 steps) |
79
+ | `--mk-ease-signature` | own `linear()` sampling of the signature (its backdrop tint) |
80
80
 
81
81
  ### flowIn / flowOut / stepChange
82
82
 
@@ -86,7 +86,7 @@ Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed w
86
86
 
87
87
  ### tabs
88
88
 
89
- - Indicator to the selected tab's box (Flip.fit in the original), 0.45 s, signature; centres a scrolling list; reduced: instant.
89
+ - Indicator to the selected tab's box, 0.45 s, signature; centres a scrolling list; reduced: instant.
90
90
 
91
91
  ### counter
92
92
 
@@ -115,48 +115,47 @@ Values were read from the public bundles of spencergabor.com (Nuxt 3, analysed w
115
115
 
116
116
  ### sortable
117
117
 
118
- - Stepbro Tasks `useDragReorder` ("transform" mode). Threshold 6 px; floating copy (cloned into the item's own list, `position: fixed`, so the list's CSS still styles it) follows a spring 1100/38 with mass `clamp(√(w·h / 24000), 1, 2.5)`; tilt spring 170/13 toward `14·tanh(torque / 14)`, torque from smoothed velocity (×2e-3) and acceleration (×45e-5) about the grab point (arm Y ≥ .4). Lift 0.18 s `power2.out`, scale `1 + .03·lift`, shadow `0 12·lift 32·lift rgb(0 0 0 / .22·lift)`.
118
+ - Drag threshold 6 px; floating copy (cloned into the item's own list, `position: fixed`, so the list's CSS still styles it) follows a spring 1100/38 with mass `clamp(√(w·h / 24000), 1, 2.5)`; tilt spring 170/13 toward `14·tanh(torque / 14)`, torque from smoothed velocity (×2e-3) and acceleration (×45e-5) about the grab point (arm Y ≥ .4). Lift 0.18 s `power2.out`, scale `1 + .03·lift`, shadow `0 12·lift 32·lift rgb(0 0 0 / .22·lift)`.
119
119
  - Neighbours: `y` by the item's height + the space to its neighbour, 0.62 s `mk-layout-reflow` (FA .52); insertion index by the pointer against item midpoints; group by pointer x (then y). Land 0.42 s `mk-sortable-land` (FA .62) to the slot, cross-fade 0.277 s `power1.inOut` to a copy styled by the destination list.
120
120
  - Auto-scroll: scrollable ancestors (and the page) within 56 px of an edge, `ceil(16 · min(1, d / 56))` px a frame. Touch (`pointer: coarse`): handle only. Escape / pointercancel: back. Keyboard (added): Space/Enter, arrows, Escape; reflow 0.62 s; `aria-live` announcements.
121
121
 
122
- ## iyo.ai (v0.7, REA research `REA - iyo.ai`)
122
+ ## Floating navigation and cards
123
123
 
124
- ### island (navbar `nav`/`d3`)
124
+ ### island
125
125
 
126
126
  - Shell fixed top 2rem, 23.5rem wide (28rem ≥ 1920 px; 1rem / 5vw side margins ≤ 767 / 479 px), radius 3em → 2em (0.4 s `cubic-bezier(.4,0,.2,1)`, closing 0.45 s late). Glass `blur(20px)` on `#38383899` + `linear-gradient(141deg, #a9c2f214, #62718c24)`.
127
127
  - Content `grid-template-rows 0fr → 1fr`, 0.6 s `cubic-bezier(.625,.05,0,1)`, 0.125 s late. Backdrop black 0 → .4, 0.7 s `cubic-bezier(.5,.5,0,1)`, 0.1 s late. Rows `opacity 0 → 1`, `translateY 3em → 0`, 0.6 s, delay `0.15 + i·0.025` s.
128
128
  - Entrance `yPercent −300 → 0`, 1.8 s (no ease given, so GSAP's `power1.out`). Card hover: siblings 20 % (0.15 s ease-out), picture 1.04 (0.4 s, back 0.3 s `cubic-bezier(.25,.46,.45,.94)`). Closes on a scroll > 1 px after wheel / touchmove.
129
129
 
130
- ### card-dock (`product-cards`, `PM`)
130
+ ### card-dock
131
131
 
132
132
  - Stack, from the end: `translateY(90 % / 180 % / 270 % / 360 %) scale(.93 / .87 / .8 / .73)`; open 0.8 s, close 0.64 s, `cubic-bezier(.48,.01,0,1.08)`. Card 4rem → 4.5rem, 0.6 s `cubic-bezier(.77,0,.175,1)`; surface `#38383899 → #555555b0` 0.3 s `cubic-bezier(.65,0,.35,1)`; `blur(19px)`, border `#8a8a8a1a`, radius .9rem.
133
133
  - Title opacity 0.5 s, `translateX(−15 % → −120 %)` 0.4 s. Intro: spread 1600 ms from the call, then the CTA fades in. Tablet (768–1024 px, `hover: none`): the first tap opens.
134
134
 
135
- ### snap-strip (`product-card-mobile`, `CM`)
135
+ ### snap-strip
136
136
 
137
- - 5000 ms a card, 2000 ms wait after mousedown / touchstart / wheel, `data-delay 500`, cards 68vw. iyo uses Smooothy (snap physics, cloned loop); here native scroll-snap.
137
+ - 5000 ms a card, 2000 ms wait after mousedown / touchstart / wheel, `data-delay 500`, cards 68vw. Uses native scroll-snap.
138
138
 
139
- ### fill-text (`GM`)
139
+ ### fill-text
140
140
 
141
141
  - SplitText `words, chars`; `fromTo(chars, { autoAlpha: .2 }, { autoAlpha: 1, stagger: .1, ease: 'linear' })` (0.5 s each), scrubbed `top 90%` → `center 40%`.
142
142
 
143
- ### particle-hero (`wK` / `YW` / `dE`, adapted)
143
+ ### particle-hero
144
144
 
145
- - iyo: 1280² points, RGBA float ping-pong, Newton step .4 × 4 toward the field's zeros, Chladni `sin(mπx/a)·sin(nπy/b)`, destination by hash vs `texturePercent`, damping `.985^dt60`, pointer radius .16 / force .0225 × smoothed speed (`min(d·5, 1)`, `.8 old + .2 new`), fade in 1 s after .3 s `power2.out`. Timeline: modes m, n ∈ {3, 5, 7} every 6–12 s; frequency 20–45 every 5–10 s; Chladni 0–5 over 1.2–3 s `power2.inOut`; word cycle N = 3–6 s (out .4N, in .6N to .4–.8, hold 2–4 s).
146
- - Kit: own shaders, size² points (128² by default), damping .91, pointer radius .28, words drawn locally (dark pixels < 120 of a 640 × 320 canvas), Canvas2D fallback (~1800 points).
145
+ - GPU simulation: `size²` points (128² by default), damping .91, pointer radius .28, Chladni modes 3/5/7 and word morph cycles, words drawn locally (dark pixels < 120 of a 640 × 320 canvas), Canvas2D fallback (~1800 points).
147
146
 
148
147
  ## Collections and menu (v0.8)
149
148
 
150
149
  All six have a `createX(root, options)` factory in the main entry, `useX(ref, options, deps)` in `/react`, CLI entry and vanilla/React playground page. `autoInit()` supports all six. Destroy restores the host and clears timers, tweens, listeners, observers and generated markup.
151
150
 
152
- | Name | Markup | Options and controls | Source |
151
+ | Name | Markup | Options and controls | Motion |
153
152
  |---|---|---|---|
154
- | ticket-menu | `.mk-dialog.mk-menu` dialog with `[data-mk-item]` | `MenuOptions`; `open`, `close`, `toggle`, `items`, `isOpen`; also `<Menu.Root ticket>` / `<mk-menu ticket>` | Siena: .9 s opening, 1.1 s rows from 150%, stagger .02; clip-path adapts the site's grid panels |
155
- | infinite-reel | `.mk-infinite-reel > [data-mk-reel-track]` | `axis x/y`, `speed 0`, `friction .95`; `moveBy`, `position`, `pause`, `resume` | Siena: DOM/inertia adaptation, without original scene or snap |
156
- | repel-bento | `.mk-repel-bento` with cards | `distance 30`, `breakpoint 1024`; `play`, `reset` | Dousan: entry spring 60/15, stagger .006, .6 vector; neighbours min(5000/d,30), spring 300/25 |
157
- | rotator | `.mk-rotator` with one item per child | `interval 8000`, `autoplay true`, `index`, `onChange`; `select`, `next`, `previous`, `index` | Dousan testimonials: .25 s, y 5→0 |
158
- | drag-ruler | `.mk-drag-ruler[aria-label]` | `min 0`, `max 8`, `step .1`, `value max`, `pixelsPerUnit 60`, `onChange`; `set`, `value`; `mk:change` | Dousan's years ruler |
159
- | dock-pill | `.mk-dock-pill` with `[data-mk-dock-item]` links/buttons | `index`, `onSelect`; `select`, `index`; `mk:select` | Dousan's activeTabPill, spring 380/30 |
153
+ | ticket-menu | `.mk-dialog.mk-menu` dialog with `[data-mk-item]` | `MenuOptions`; `open`, `close`, `toggle`, `items`, `isOpen`; also `<Menu.Root ticket>` / `<mk-menu ticket>` | .9 s opening, 1.1 s rows from 150%, stagger .02 |
154
+ | infinite-reel | `.mk-infinite-reel > [data-mk-reel-track]` | `axis x/y`, `speed 0`, `friction .95`; `moveBy`, `position`, `pause`, `resume` | Continuous DOM track with inertial scrolling |
155
+ | repel-bento | `.mk-repel-bento` with cards | `distance 30`, `breakpoint 1024`; `play`, `reset` | Entry spring 60/15, stagger .006, .6 vector; neighbours min(5000/d,30), spring 300/25 |
156
+ | rotator | `.mk-rotator` with one item per child | `interval 8000`, `autoplay true`, `index`, `onChange`; `select`, `next`, `previous`, `index` | .25 s, y 5→0 |
157
+ | drag-ruler | `.mk-drag-ruler[aria-label]` | `min 0`, `max 8`, `step .1`, `value max`, `pixelsPerUnit 60`, `onChange`; `set`, `value`; `mk:change` | Numeric marks with drag and keyboard input |
158
+ | dock-pill | `.mk-dock-pill` with `[data-mk-dock-item]` links/buttons | `index`, `onSelect`; `select`, `index`; `mk:select` | Spring 380/30 |
160
159
 
161
160
  Reduced motion disables inertia, autoplay, entry and repulsion, keeping manual navigation. Reel copies are inert, aria-hidden and have no duplicate IDs. Ruler supports arrows, Home/End and PageUp/PageDown. Dock supports arrows/Home/End and skips disabled items. Keep rotator controls outside its child list.
162
161
 
@@ -164,9 +163,9 @@ Reduced motion disables inertia, autoplay, entry and repulsion, keeping manual n
164
163
 
165
164
  `createLiquidBlend`, `createMatcap`, `createShaderGrain`, `createShaderBlur` share `{ images?, progress?, amount?, maxDpr? }` and return `{ setProgress, setAmount, pause, resume, mode, destroy }`. Images default to the host's first two `<img>` elements; one image is repeated. Same-origin or CORS-enabled images; loading is observed. A host with explicit dimensions is required. React hooks have the corresponding `use…` names. These factories are not exported from the main entry or registered with autoInit.
166
165
 
167
- - Liquid: `amount .15`, progress 0→1 blends the two textures with centre-weighted UV waves. OFFFICE `liquid-swap` mechanism adapted to images without models or render targets.
168
- - Matcap: analytic sphere, normal UV .495+.5, hemispheric light and gain .15; optional image used as matcap. OFFFICE's model renderer is not included.
169
- - Grain: own temporal hash, amount .07 from Siena's postprocess; 24 Hz grain, fixed frame for reduced motion.
170
- - Blur: amount 5 image pixels, seven weighted samples with Siena's .19648255/.29690696/.09447040/.01038136 weights and 1.41176471/3.29411765/5.17647059 offsets. Progress rotates the direction x→y.
166
+ - Liquid: `amount .15`, progress 0→1 blends the two textures with centre-weighted UV waves.
167
+ - Matcap: analytic sphere, normal UV .495+.5, hemispheric light and gain .15; optional image used as matcap. It does not load models.
168
+ - Grain: own temporal hash, amount .07 from postprocess; 24 Hz grain, fixed frame for reduced motion.
169
+ - Blur: amount 5 image pixels, seven weighted samples with .19648255/.29690696/.09447040/.01038136 weights and 1.41176471/3.29411765/5.17647059 offsets. Progress rotates the direction x→y.
171
170
 
172
- WebGL unsupported, compilation/texture error or context loss leaves the original HTML available. Context restoration rebuilds resources. The canvas is decorative; loops pause offscreen and in hidden tabs. No Three/OGL dependency and no shaders/assets copied from the researched sites.
171
+ WebGL unsupported, compilation/texture error or context loss leaves the original HTML available. Context restoration rebuilds resources. The canvas is decorative; loops pause offscreen and in hidden tabs. No additional rendering library is required.
@@ -1,3 +1,22 @@
1
+ import { createQuantity } from '../components/quantity/engine';
2
+ import { createPagination } from '../components/pagination/engine';
3
+ import { createHoverCard } from '../components/hover-card/engine';
4
+ import { createInputOtp } from '../components/input-otp/engine';
5
+ import { createJoinedCta } from '../recipes/joined-cta/create-joined-cta';
6
+ import { createImageZoom } from '../recipes/image-zoom/create-image-zoom';
7
+ import { createFontCycle } from '../recipes/font-cycle/create-font-cycle';
8
+ import { createThumbnailNav } from '../recipes/thumbnail-nav/create-thumbnail-nav';
9
+ import { createActionButton } from '../recipes/action-button/create-action-button';
10
+ import { createFilmHero } from '../recipes/film-hero/create-film-hero';
11
+ import { createEditorialReveal } from '../recipes/editorial-reveal/create-editorial-reveal';
12
+ import { createStudioDock } from '../components/studio-dock/engine';
13
+ import { createCalendar } from '../components/calendar/engine';
14
+ import { createSlotPicker } from '../components/slot-picker/engine';
15
+ import { createWeightHover } from '../recipes/weight-hover/create-weight-hover';
16
+ import { createSticker } from '../recipes/sticker/create-sticker';
17
+ import { createScrollDock } from '../recipes/scroll-dock/create-scroll-dock';
18
+ import { createLocalClock } from '../recipes/local-clock/create-local-clock';
19
+ import { createTrailer } from '../components/trailer/engine';
1
20
  import { ScrollTrigger } from '../core/gsap';
2
21
  import { warnOnce, type Instance } from '../core/types';
3
22
  import { createSpringCards } from '../recipes/spring-cards/create-spring-cards';
@@ -39,6 +58,25 @@ import { createDockPill } from '../recipes/dock-pill/create-dock-pill';
39
58
  type Factory = (el: HTMLElement, options: Record<string, unknown>) => Instance;
40
59
 
41
60
  const factories = {
61
+ 'joined-cta': createJoinedCta,
62
+ 'image-zoom': createImageZoom,
63
+ 'font-cycle': createFontCycle,
64
+ 'thumbnail-nav': createThumbnailNav,
65
+ 'action-button': createActionButton,
66
+ 'film-hero': createFilmHero,
67
+ 'editorial-reveal': createEditorialReveal,
68
+ 'studio-dock': createStudioDock,
69
+ 'trailer': createTrailer,
70
+ 'quantity': createQuantity,
71
+ 'pagination': createPagination,
72
+ 'hover-card': createHoverCard,
73
+ 'input-otp': createInputOtp,
74
+ 'calendar': createCalendar,
75
+ 'slot-picker': createSlotPicker,
76
+ 'weight-hover': createWeightHover,
77
+ 'sticker': createSticker,
78
+ 'scroll-dock': createScrollDock,
79
+ 'local-clock': createLocalClock,
42
80
  'spring-cards': createSpringCards,
43
81
  'curved-carousel': (el, options) =>
44
82
  createCurvedCarousel(el, {
@@ -0,0 +1,82 @@
1
+ # calendar
2
+
3
+ El calendario de Melon Mind. Tiene vista de mes y de semana, día de hoy marcado y eventos como chips con estado (pendiente, completado o cancelado), hora y color propio.
4
+
5
+ - **Al cargar:** los días entran desde arriba con blur (y −20 px, blur 16 → 0, 0.5 s), 5 ms uno tras otro, y después los eventos, 20 ms uno tras otro. Es el `flowChilds` del `CalendarComponent` original.
6
+ - **Cambiar de mes o semana:** la rejilla vieja sale 30 px hacia un lado (0.12 s) y, cuando ya casi no se ve, la nueva entra 30 px desde el otro (0.25 s `ease-out`), como los horarios de su selector de citas. Van en secuencia, sin fundido cruzado, para que no se mezclen dos meses llenos de eventos. Luego vuelven a entrar los eventos.
7
+ - **Hover:** el fondo del día cambia en 0.3 s y el número tiene resorte de radio y escala (`cubic-bezier(.38,.49,0,2)`).
8
+
9
+ Origen: patrón observado en la app de Melon Mind.
10
+
11
+ ## HTML / Astro
12
+
13
+ ```html
14
+ <mk-calendar class="mk-calendar" locale="es" first-day="0"
15
+ events='[{"id":1,"title":"Ana","start":"2026-10-23T10:00","status":"pending"}]'>
16
+ <div class="mk-calendar__header">
17
+ <h3 class="mk-calendar__title" data-mk-calendar-title>Calendario</h3>
18
+ <div class="mk-calendar__views" role="group" aria-label="Vista">
19
+ <button type="button" data-mk-calendar-view="month">Mes</button>
20
+ <button type="button" data-mk-calendar-view="week">Semana</button>
21
+ </div>
22
+ <button type="button" class="mk-calendar__nav" data-mk-calendar-prev aria-label="Anterior">←</button>
23
+ <button type="button" class="mk-calendar__nav" data-mk-calendar-today>Hoy</button>
24
+ <button type="button" class="mk-calendar__nav" data-mk-calendar-next aria-label="Siguiente">→</button>
25
+ </div>
26
+ <div data-mk-calendar-grid></div>
27
+ </mk-calendar>
28
+ <script>
29
+ import { defineElements } from '@yewdiel21/motion-kit/elements';
30
+ defineElements(['mk-calendar']);
31
+ </script>
32
+ ```
33
+
34
+ Sólo `[data-mk-calendar-grid]` es obligatorio. Las demás piezas del header son opcionales. Si cambias el atributo `events`, los eventos se actualizan sin perder el mes ni el foco. Sin custom element: `createCalendar(root, opciones)`.
35
+
36
+ ## React
37
+
38
+ ```tsx
39
+ <Calendar
40
+ events={citas}
41
+ onSelect={(day) => abrirDia(day)}
42
+ onEventClick={(event) => abrirCita(event.id)}
43
+ />
44
+ ```
45
+
46
+ `events` y `selected` se actualizan en el sitio. `date` y `view` son iniciales: el usuario navega libremente.
47
+
48
+ ## Opciones
49
+
50
+ | Opción | Atributo | Por defecto | Qué hace |
51
+ |---|---|---|---|
52
+ | `date` | `date` | hoy | Mes o semana inicial (`Date` o `"2026-10-23"`) |
53
+ | `view` | `view` | `'month'` | `'month'` o `'week'` |
54
+ | `firstDay` | `first-day` | `0` | Primer día de la semana (0 = domingo) |
55
+ | `locale` | `locale` | `'es'` | Nombres de mes y día, formato de hora |
56
+ | `events` | `events` (JSON) | `[]` | `{ id, title, start, end?, allDay?, status?, color? }` |
57
+ | `maxEvents` | `max-events` | `3` | Chips por día en la vista de mes antes de «+N más» |
58
+ | `selected` | `selected` | — | Día seleccionado |
59
+ | `today` | `today` | — | Fija «hoy» (demos, pruebas) |
60
+ | `labels` | — | español | `more(n)`, `events(n)`, `status` |
61
+ | `onSelect(date)`, `onEventClick(event)`, `onNavigate({start, end, view})` | — | — | Callbacks |
62
+
63
+ API: `next()`, `prev()`, `goToday()`, `setDate(d)`, `setView(v)`, `setEvents(list)`, `select(d | null, notify)`, `date`, `view`, `selected`, `range`, `destroy()`. Eventos DOM: `mk:select` `{date, key}`, `mk:event` `{event}` y `mk:navigate` `{start, end, view}`.
64
+
65
+ Un evento con `end` en otro día aparece en cada día que cubre, hasta dos meses.
66
+
67
+ ## Variables CSS
68
+
69
+ `--mk-calendar-gap`, `--mk-calendar-radius`, `--mk-calendar-day-height` y `--mk-calendar-event-color` (por evento, con `color`).
70
+
71
+ ## Accesibilidad
72
+
73
+ Rejilla ARIA (`grid` / `row` / `columnheader` / `gridcell`) con un solo botón de día en el orden de tabulación:
74
+
75
+ | Tecla | Acción |
76
+ |---|---|
77
+ | Flechas | Día anterior/siguiente, misma semana anterior/siguiente |
78
+ | Inicio / Fin | Principio/fin de semana |
79
+ | RePág / AvPág | Mes anterior/siguiente (con Mayúsculas, año) |
80
+ | Enter / Espacio | Seleccionar el día |
81
+
82
+ Cada día anuncia la fecha completa y cuántos eventos tiene. Hoy lleva `aria-current="date"`. Los chips son botones con título, hora y estado. En móvil (< 680 px) los chips del mes se reducen a puntos de color. Con movimiento reducido no hay entradas, deslizamiento ni transiciones.
@@ -0,0 +1,158 @@
1
+ /* calendar — Melon Mind's month/week grid on the --mk-* tokens; parts are .mk-calendar__*. */
2
+ .mk-calendar,
3
+ mk-calendar {
4
+ --mk-calendar-gap: 6px;
5
+ --mk-calendar-radius: var(--mk-radius-lg);
6
+ --mk-calendar-day-height: 112px;
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--mk-space-3);
10
+ color: var(--mk-text);
11
+ }
12
+ .mk-calendar__header {
13
+ display: flex;
14
+ flex-wrap: wrap;
15
+ align-items: center;
16
+ gap: var(--mk-space-2);
17
+ }
18
+ .mk-calendar__title { margin: 0 auto 0 0; font-size: clamp(1.4rem, 2.6vw, 2rem); font-weight: 400; letter-spacing: -0.01em; }
19
+ .mk-calendar__views { display: inline-flex; padding: 4px; gap: 2px; border-radius: var(--mk-radius-full); background: var(--mk-surface-3); }
20
+ .mk-calendar__views button,
21
+ .mk-calendar__nav {
22
+ display: inline-grid;
23
+ place-items: center;
24
+ min-width: 44px;
25
+ height: 44px;
26
+ padding: 0 12px;
27
+ border: 0;
28
+ border-radius: var(--mk-radius-full);
29
+ background: transparent;
30
+ color: var(--mk-muted);
31
+ font: inherit;
32
+ cursor: pointer;
33
+ transition: background 0.2s, color 0.2s, transform 0.3s var(--mk-ease-nav-move);
34
+ }
35
+ .mk-calendar__views button[aria-pressed='true'] { background: var(--mk-surface-5); color: var(--mk-text); }
36
+ .mk-calendar__nav { background: var(--mk-surface-3); color: var(--mk-text); }
37
+ .mk-calendar__nav:active { transform: scale(0.92); }
38
+ :is(.mk-calendar__views button, .mk-calendar__nav):focus-visible { outline: 2px solid var(--mk-accent); outline-offset: 2px; }
39
+
40
+ [data-mk-calendar-grid] { position: relative; display: flex; flex-direction: column; gap: var(--mk-calendar-gap); }
41
+ .mk-calendar__head,
42
+ .mk-calendar__week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--mk-calendar-gap); }
43
+ .mk-calendar__body { display: flex; flex-direction: column; gap: var(--mk-calendar-gap); }
44
+ .mk-calendar__body--leaving { position: absolute; left: 0; right: 0; pointer-events: none; }
45
+ .mk-calendar__weekday {
46
+ padding: 8px 4px;
47
+ border-radius: var(--mk-radius-md);
48
+ background: var(--mk-surface-2);
49
+ text-align: center;
50
+ font-size: 0.95rem;
51
+ }
52
+ .mk-calendar__weekday-narrow { display: none; }
53
+
54
+ .mk-calendar__day {
55
+ position: relative;
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 4px;
59
+ min-width: 0;
60
+ min-height: var(--mk-calendar-day-height);
61
+ padding: 6px;
62
+ border-radius: var(--mk-calendar-radius);
63
+ background: var(--mk-surface-3);
64
+ transition: background 0.3s, box-shadow 0.3s;
65
+ container-type: inline-size;
66
+ }
67
+ .mk-calendar__body[data-view='week'] .mk-calendar__day { min-height: calc(var(--mk-calendar-day-height) * 3); }
68
+ .mk-calendar__day[data-outside] { background: var(--mk-surface-1); color: var(--mk-muted); }
69
+ .mk-calendar__day:hover { background: var(--mk-surface-4); }
70
+ .mk-calendar__day[aria-selected='true'] { box-shadow: inset 0 0 0 2px var(--mk-accent); }
71
+ .mk-calendar__number {
72
+ align-self: flex-end;
73
+ min-width: 2.2rem;
74
+ height: 2.2rem;
75
+ padding: 0 0.4rem;
76
+ border: 0;
77
+ border-radius: var(--mk-radius-full);
78
+ background: transparent;
79
+ color: inherit;
80
+ font: inherit;
81
+ font-size: 1.15rem;
82
+ cursor: pointer;
83
+ transition: background 0.3s, color 0.3s, border-radius 0.3s var(--mk-ease-nav-radius), transform 0.3s var(--mk-ease-nav-radius);
84
+ }
85
+ .mk-calendar__number:hover { background: var(--mk-surface-5); }
86
+ .mk-calendar__number:active { transform: scale(0.9); }
87
+ .mk-calendar__number:focus-visible { outline: 2px solid var(--mk-accent); outline-offset: 2px; }
88
+ .mk-calendar__day[data-today] .mk-calendar__number { background: var(--mk-accent); color: var(--mk-on-accent); }
89
+
90
+ .mk-calendar__events { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
91
+ .mk-calendar__event,
92
+ .mk-calendar__more {
93
+ --mk-calendar-event-color: var(--mk-accent);
94
+ display: flex;
95
+ align-items: center;
96
+ gap: 6px;
97
+ width: 100%;
98
+ min-width: 0;
99
+ padding: 5px 8px;
100
+ border: 0;
101
+ border-radius: 10px;
102
+ background: var(--mk-surface-4);
103
+ color: var(--mk-text);
104
+ font: inherit;
105
+ font-size: 0.85rem;
106
+ text-align: left;
107
+ cursor: pointer;
108
+ transition: background 0.2s, transform 0.3s var(--mk-ease-nav-move);
109
+ }
110
+ .mk-calendar__event[data-state='pending'] {
111
+ background: color-mix(in srgb, var(--mk-calendar-event-color) 30%, var(--mk-surface-3));
112
+ }
113
+ .mk-calendar__event:hover,
114
+ .mk-calendar__more:hover { transform: translateY(-1px); background: var(--mk-surface-5); }
115
+ .mk-calendar__event:focus-visible,
116
+ .mk-calendar__more:focus-visible { outline: 2px solid var(--mk-accent); outline-offset: 1px; }
117
+ .mk-calendar__status {
118
+ flex: none;
119
+ width: 0.8rem;
120
+ height: 0.8rem;
121
+ border: 2px solid currentColor;
122
+ border-radius: 50%;
123
+ }
124
+ .mk-calendar__event[data-state='done'] .mk-calendar__status { background: currentColor; box-shadow: inset 0 0 0 2px var(--mk-surface-4); }
125
+ .mk-calendar__event[data-state='cancelled'] .mk-calendar__event-title { text-decoration: line-through; opacity: 0.6; }
126
+ .mk-calendar__event-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
127
+ .mk-calendar__event-time { flex: none; font-variant-numeric: tabular-nums; opacity: 0.85; }
128
+ .mk-calendar__more { justify-content: center; background: transparent; color: var(--mk-muted); }
129
+
130
+ /* Narrow day cells: the month keeps the title (the time stays in the label); the week stacks the time under it. */
131
+ @container (max-width: 150px) {
132
+ .mk-calendar__body[data-view='month'] .mk-calendar__event-time { display: none; }
133
+ .mk-calendar__body[data-view='week'] .mk-calendar__event { flex-wrap: wrap; column-gap: 5px; row-gap: 1px; }
134
+ .mk-calendar__body[data-view='week'] .mk-calendar__event-title { flex: 1 1 0; }
135
+ .mk-calendar__body[data-view='week'] .mk-calendar__event-time { flex-basis: 100%; padding-left: calc(0.8rem + 5px); font-size: 0.72rem; }
136
+ }
137
+ @media (max-width: 680px) {
138
+ .mk-calendar,
139
+ mk-calendar { --mk-calendar-day-height: 64px; --mk-calendar-gap: 4px; --mk-calendar-radius: var(--mk-radius-sm); }
140
+ .mk-calendar__weekday-long { display: none; }
141
+ .mk-calendar__weekday-narrow { display: inline; }
142
+ .mk-calendar__number { align-self: center; font-size: 0.95rem; }
143
+ .mk-calendar__body[data-view='month'] .mk-calendar__events { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 3px; }
144
+ .mk-calendar__body[data-view='month'] :is(.mk-calendar__event, .mk-calendar__more) {
145
+ width: 7px;
146
+ height: 7px;
147
+ padding: 0;
148
+ border-radius: 50%;
149
+ background: var(--mk-calendar-event-color);
150
+ font-size: 0;
151
+ }
152
+ .mk-calendar__body[data-view='month'] .mk-calendar__status { display: none; }
153
+ .mk-calendar__body[data-view='week'] .mk-calendar__event-time { display: none; }
154
+ }
155
+ @media (prefers-reduced-motion: reduce) {
156
+ .mk-calendar *,
157
+ mk-calendar * { transition: none !important; }
158
+ }
@@ -0,0 +1,27 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createCalendar, type CalendarEvent, type CalendarInstance } from './engine';
3
+
4
+ /** Light DOM: supply the header and the [data-mk-calendar-grid] shown in the README. */
5
+ export class MkCalendarElement extends MkElement<CalendarInstance> {
6
+ static options: Record<string, OptionType> = {
7
+ date: 'string', view: 'string', firstDay: 'number', locale: 'string', maxEvents: 'number', events: 'json', selected: 'string', today: 'string',
8
+ };
9
+
10
+ protected create(options: Record<string, unknown>) {
11
+ return createCalendar(this, options);
12
+ }
13
+
14
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
15
+ if (previous === next || !this.isConnected || !this.instance) return;
16
+ if (name === 'events') {
17
+ this.instance.setEvents((this.options.events as CalendarEvent[] | undefined) ?? []);
18
+ return;
19
+ }
20
+ // Keep where the visitor is unless the changed attribute says otherwise.
21
+ const { date, view, selected } = this.instance;
22
+ this.instance.destroy();
23
+ this.instance = this.create({ date, view, selected, ...this.options });
24
+ }
25
+ }
26
+
27
+ export const defineCalendar = () => defineElement('mk-calendar', MkCalendarElement);