move.gl 0.0.1 → 0.0.2

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 (463) hide show
  1. package/README.md +185 -11
  2. package/dist/LICENSE +21 -0
  3. package/dist/README.md +212 -0
  4. package/dist/css/move.gl.css +43859 -0
  5. package/dist/css/move.gl.min.css +19 -0
  6. package/dist/js/index.cjs +1171 -0
  7. package/dist/js/index.cjs.map +1 -0
  8. package/dist/js/index.d.cts +184 -0
  9. package/dist/js/index.d.ts +184 -0
  10. package/dist/js/index.mjs +1135 -0
  11. package/dist/js/index.mjs.map +1 -0
  12. package/dist/package.json +68 -0
  13. package/{scss → dist/scss}/classes/_animations.scss +33 -14
  14. package/dist/scss/classes/_controls.scss +314 -0
  15. package/dist/scss/classes/_effects.scss +283 -0
  16. package/dist/scss/classes/_index.scss +28 -0
  17. package/dist/scss/classes/_loaders.scss +779 -0
  18. package/dist/scss/classes/_transforms.scss +138 -0
  19. package/dist/scss/classes/_transitions.scss +264 -0
  20. package/{scss → dist/scss}/dev/_deprecation.scss +6 -3
  21. package/{scss → dist/scss}/dev/_modules.scss +5 -6
  22. package/dist/scss/docs.scss +2344 -0
  23. package/dist/scss/docs.scss.bak +3133 -0
  24. package/dist/scss/functions/_index.scss +22 -0
  25. package/dist/scss/functions/scenes/_bubble.scss +32 -0
  26. package/dist/scss/functions/scenes/_index.scss +21 -0
  27. package/dist/scss/index.scss +17 -0
  28. package/dist/scss/maps/_controls.scss +85 -0
  29. package/dist/scss/maps/_index.scss +22 -0
  30. package/{scss → dist/scss}/mixins/_accessibility.scss +24 -3
  31. package/{scss → dist/scss}/mixins/_boot.scss +4 -4
  32. package/dist/scss/mixins/_index.scss +41 -0
  33. package/dist/scss/mixins/_screensaver.scss +228 -0
  34. package/dist/scss/mixins/_shape.scss +315 -0
  35. package/dist/scss/mixins/animations/_base.scss +403 -0
  36. package/dist/scss/mixins/animations/_beat.scss +137 -0
  37. package/{scss → dist/scss}/mixins/animations/_blink.scss +60 -52
  38. package/dist/scss/mixins/animations/_bounce.scss +306 -0
  39. package/{scss → dist/scss}/mixins/animations/_elastic.scss +26 -22
  40. package/dist/scss/mixins/animations/_fade.scss +393 -0
  41. package/{scss → dist/scss}/mixins/animations/_flash.scss +53 -61
  42. package/dist/scss/mixins/animations/_flip.scss +251 -0
  43. package/{scss → dist/scss}/mixins/animations/_float.scss +47 -32
  44. package/{scss → dist/scss}/mixins/animations/_glow.scss +69 -58
  45. package/dist/scss/mixins/animations/_heartbeat.scss +195 -0
  46. package/dist/scss/mixins/animations/_hinge.scss +118 -0
  47. package/dist/scss/mixins/animations/_index.scss +97 -0
  48. package/dist/scss/mixins/animations/_jello.scss +123 -0
  49. package/dist/scss/mixins/animations/_jiggle.scss +162 -0
  50. package/dist/scss/mixins/animations/_lightspeed.scss +135 -0
  51. package/{scss → dist/scss}/mixins/animations/_nod.scss +57 -65
  52. package/dist/scss/mixins/animations/_pop.scss +153 -0
  53. package/dist/scss/mixins/animations/_pulse.scss +275 -0
  54. package/{scss → dist/scss}/mixins/animations/_ripple.scss +47 -55
  55. package/dist/scss/mixins/animations/_roll.scss +217 -0
  56. package/dist/scss/mixins/animations/_rotate.scss +728 -0
  57. package/dist/scss/mixins/animations/_rubber.scss +115 -0
  58. package/dist/scss/mixins/animations/_scale.scss +382 -0
  59. package/dist/scss/mixins/animations/_shake.scss +233 -0
  60. package/dist/scss/mixins/animations/_slide.scss +501 -0
  61. package/dist/scss/mixins/animations/_spin.scss +322 -0
  62. package/{scss → dist/scss}/mixins/animations/_sway.scss +32 -49
  63. package/{scss → dist/scss}/mixins/animations/_swing.scss +47 -49
  64. package/{scss → dist/scss}/mixins/animations/_tada.scss +44 -42
  65. package/{scss → dist/scss}/mixins/animations/_twist.scss +40 -55
  66. package/{scss → dist/scss}/mixins/animations/_wave.scss +36 -53
  67. package/dist/scss/mixins/animations/_wobble.scss +283 -0
  68. package/dist/scss/mixins/animations/_zoom.scss +394 -0
  69. package/{scss/mixins/mouse → dist/scss/mixins/controls}/_cursor.scss +60 -39
  70. package/dist/scss/mixins/controls/_hover.scss +625 -0
  71. package/dist/scss/mixins/controls/_index.scss +30 -0
  72. package/dist/scss/mixins/controls/_keyboard.scss +300 -0
  73. package/{scss/mixins/mouse → dist/scss/mixins/controls}/_pointer.scss +81 -72
  74. package/dist/scss/mixins/controls/_scroll.scss +460 -0
  75. package/{scss/mixins/scroll → dist/scss/mixins/controls}/_scrollbar.scss +50 -16
  76. package/dist/scss/mixins/controls/_selection.scss +208 -0
  77. package/dist/scss/mixins/controls/_touch.scss +401 -0
  78. package/dist/scss/mixins/effects/_blend.scss +128 -0
  79. package/dist/scss/mixins/effects/_filter.scss +470 -0
  80. package/dist/scss/mixins/effects/_focus.scss +83 -0
  81. package/dist/scss/mixins/effects/_gradient.scss +130 -0
  82. package/dist/scss/mixins/effects/_index.scss +28 -0
  83. package/dist/scss/mixins/effects/_mask.scss +76 -0
  84. package/dist/scss/mixins/effects/_opacity.scss +376 -0
  85. package/dist/scss/mixins/effects/_shadow.scss +429 -0
  86. package/dist/scss/mixins/keyframes/_base.scss +199 -0
  87. package/dist/scss/mixins/keyframes/_index.scss +24 -0
  88. package/dist/scss/mixins/keyframes/animations/_beat.scss +280 -0
  89. package/dist/scss/mixins/keyframes/animations/_blink.scss +82 -0
  90. package/dist/scss/mixins/keyframes/animations/_bounce.scss +292 -0
  91. package/dist/scss/mixins/keyframes/animations/_fade.scss +311 -0
  92. package/dist/scss/mixins/keyframes/animations/_flash.scss +165 -0
  93. package/dist/scss/mixins/keyframes/animations/_flip.scss +266 -0
  94. package/{scss/mixins → dist/scss/mixins/keyframes}/animations/_index.scss +19 -10
  95. package/dist/scss/mixins/keyframes/animations/_jiggle.scss +85 -0
  96. package/dist/scss/mixins/keyframes/animations/_lightspeed.scss +73 -0
  97. package/dist/scss/mixins/keyframes/animations/_nod.scss +79 -0
  98. package/dist/scss/mixins/keyframes/animations/_pop.scss +78 -0
  99. package/dist/scss/mixins/keyframes/animations/_pulse.scss +225 -0
  100. package/dist/scss/mixins/keyframes/animations/_ripple.scss +94 -0
  101. package/dist/scss/mixins/keyframes/animations/_roll.scss +124 -0
  102. package/dist/scss/mixins/keyframes/animations/_rotate.scss +360 -0
  103. package/dist/scss/mixins/keyframes/animations/_rubber.scss +81 -0
  104. package/dist/scss/mixins/keyframes/animations/_scale.scss +308 -0
  105. package/dist/scss/mixins/keyframes/animations/_shake.scss +270 -0
  106. package/dist/scss/mixins/keyframes/animations/_slide.scss +345 -0
  107. package/dist/scss/mixins/keyframes/animations/_spin.scss +270 -0
  108. package/dist/scss/mixins/keyframes/animations/_sway.scss +83 -0
  109. package/dist/scss/mixins/keyframes/animations/_twist.scss +89 -0
  110. package/dist/scss/mixins/keyframes/animations/_wave.scss +90 -0
  111. package/dist/scss/mixins/keyframes/animations/_wobble.scss +293 -0
  112. package/dist/scss/mixins/keyframes/animations/_zoom.scss +345 -0
  113. package/dist/scss/mixins/loaders/_bars.scss +128 -0
  114. package/dist/scss/mixins/loaders/_base.scss +39 -0
  115. package/dist/scss/mixins/loaders/_bubble.scss +395 -0
  116. package/dist/scss/mixins/loaders/_circle.scss +456 -0
  117. package/dist/scss/mixins/loaders/_dots.scss +248 -0
  118. package/dist/scss/mixins/loaders/_graph.scss +542 -0
  119. package/dist/scss/mixins/loaders/_index.scss +77 -0
  120. package/dist/scss/mixins/loaders/_line.scss +471 -0
  121. package/dist/scss/mixins/loaders/_objects.scss +563 -0
  122. package/dist/scss/mixins/loaders/_progress.scss +477 -0
  123. package/dist/scss/mixins/loaders/_rect.scss +480 -0
  124. package/dist/scss/mixins/loaders/_rings.scss +377 -0
  125. package/dist/scss/mixins/loaders/_skeleton.scss +461 -0
  126. package/dist/scss/mixins/loaders/_special.scss +611 -0
  127. package/dist/scss/mixins/loaders/_spinner.scss +175 -0
  128. package/dist/scss/mixins/loaders/_text.scss +446 -0
  129. package/{scss → dist/scss}/mixins/transforms/_flip.scss +16 -18
  130. package/dist/scss/mixins/transforms/_index.scss +28 -0
  131. package/dist/scss/mixins/transforms/_matrix.scss +18 -0
  132. package/{scss → dist/scss}/mixins/transforms/_perspective.scss +18 -1
  133. package/{scss → dist/scss}/mixins/transforms/_rotate.scss +9 -14
  134. package/{scss → dist/scss}/mixins/transforms/_scale.scss +16 -1
  135. package/{scss → dist/scss}/mixins/transforms/_skew.scss +16 -2
  136. package/{scss → dist/scss}/mixins/transforms/_translate.scss +16 -2
  137. package/dist/scss/mixins/transitions/_index.scss +22 -0
  138. package/dist/scss/mixins/transitions/_transition.scss +43 -0
  139. package/dist/scss/variables/_animations.scss +300 -0
  140. package/dist/scss/variables/_controls.scss +178 -0
  141. package/dist/scss/variables/_effects.scss +87 -0
  142. package/dist/scss/variables/_index.scss +27 -0
  143. package/dist/scss/variables/_keyframes.scss +28 -0
  144. package/dist/scss/variables/_loaders.scss +75 -0
  145. package/dist/scss/variables/_transforms.scss +85 -0
  146. package/dist/scss/variables/_transitions.scss +80 -0
  147. package/dist/ts/Draggable.ts +143 -0
  148. package/dist/ts/Gesture.ts +226 -0
  149. package/dist/ts/Keyboard.ts +195 -0
  150. package/dist/ts/LoaderManager.ts +662 -0
  151. package/dist/ts/Screensaver.ts +192 -0
  152. package/dist/ts/VideoOverlay.ts +205 -0
  153. package/dist/ts/demo.ts +1108 -0
  154. package/dist/ts/index.ts +58 -0
  155. package/package.json +90 -53
  156. package/src/html/_base.html +138 -0
  157. package/src/html/base.html +147 -0
  158. package/src/html/core-concepts.html +282 -0
  159. package/src/html/demo_base.html +171 -0
  160. package/src/html/demo_draggable.html +250 -0
  161. package/src/html/demo_gesture.html +264 -0
  162. package/src/html/demo_keyboard.html +224 -0
  163. package/src/html/demo_screensaver.html +258 -0
  164. package/src/html/demo_video_overlay.html +291 -0
  165. package/src/html/getting-started.html +242 -0
  166. package/src/html/index.html +400 -0
  167. package/src/html/keyboard.html +14 -0
  168. package/src/html/partials/_demo_links.html +21 -0
  169. package/src/html/partials/_footer.html +18 -0
  170. package/src/html/partials/_head.html +21 -0
  171. package/src/html/partials/_nav.html +84 -0
  172. package/src/html/partials/_theme_toggle.html +11 -0
  173. package/src/html/screensaver.html +20 -0
  174. package/src/html/test_animations.html +813 -0
  175. package/src/html/test_attention.html +281 -0
  176. package/src/html/test_bounce.html +201 -0
  177. package/src/html/test_effects.html +1348 -0
  178. package/src/html/test_fade.html +213 -0
  179. package/src/html/test_flip.html +208 -0
  180. package/src/html/test_keyframes.html +415 -0
  181. package/src/html/test_loaders.html +1489 -0
  182. package/src/html/test_mouse.html +516 -0
  183. package/src/html/test_overview.html +1444 -0
  184. package/src/html/test_pulse.html +212 -0
  185. package/src/html/test_scale.html +204 -0
  186. package/src/html/test_shake.html +232 -0
  187. package/src/html/test_slide.html +212 -0
  188. package/src/html/test_special.html +257 -0
  189. package/src/html/test_spin.html +216 -0
  190. package/src/html/test_transforms.html +332 -0
  191. package/src/html/test_transitions.html +245 -0
  192. package/src/html/test_zoom.html +188 -0
  193. package/src/html/video_overlay.html +27 -0
  194. package/src/jinja/_base.html.jinja +50 -0
  195. package/src/jinja/base.html.jinja +48 -0
  196. package/src/jinja/core-concepts.html.jinja +148 -0
  197. package/src/jinja/demo_draggable.html.jinja +114 -0
  198. package/src/jinja/demo_gesture.html.jinja +128 -0
  199. package/src/jinja/demo_keyboard.html.jinja +88 -0
  200. package/src/jinja/demo_screensaver.html.jinja +122 -0
  201. package/src/jinja/demo_video_overlay.html.jinja +155 -0
  202. package/src/jinja/getting-started.html.jinja +108 -0
  203. package/src/jinja/index.html.jinja +268 -0
  204. package/src/jinja/index.json +5 -0
  205. package/src/jinja/move.gl.css +7741 -0
  206. package/src/jinja/partials/_code_block.html.jinja +17 -0
  207. package/src/jinja/partials/_demo_links.html.jinja +41 -0
  208. package/src/jinja/partials/_feature_card.html.jinja +20 -0
  209. package/src/jinja/partials/_footer.html.jinja +22 -0
  210. package/src/jinja/partials/_head.html.jinja +27 -0
  211. package/src/jinja/partials/_nav.html.jinja +79 -0
  212. package/src/jinja/partials/_theme_toggle.html.jinja +15 -0
  213. package/src/jinja/test_animations.html.jinja +679 -0
  214. package/src/jinja/test_attention.html.jinja +147 -0
  215. package/src/jinja/test_bounce.html.jinja +67 -0
  216. package/src/jinja/test_effects.html.jinja +1218 -0
  217. package/src/jinja/test_fade.html.jinja +79 -0
  218. package/src/jinja/test_flip.html.jinja +74 -0
  219. package/src/jinja/test_keyframes.html.jinja +281 -0
  220. package/src/jinja/test_loaders.html.jinja +1358 -0
  221. package/src/jinja/test_mouse.html.jinja +382 -0
  222. package/src/jinja/test_overview.html.jinja +1313 -0
  223. package/src/jinja/test_pulse.html.jinja +78 -0
  224. package/src/jinja/test_scale.html.jinja +70 -0
  225. package/src/jinja/test_shake.html.jinja +98 -0
  226. package/src/jinja/test_slide.html.jinja +78 -0
  227. package/src/jinja/test_special.html.jinja +123 -0
  228. package/src/jinja/test_spin.html.jinja +82 -0
  229. package/src/jinja/test_transforms.html.jinja +198 -0
  230. package/src/jinja/test_transitions.html.jinja +111 -0
  231. package/src/jinja/test_zoom.html.jinja +54 -0
  232. package/src/scss/classes/_animations.scss +595 -0
  233. package/src/scss/classes/_controls.scss +314 -0
  234. package/src/scss/classes/_effects.scss +283 -0
  235. package/src/scss/classes/_index.scss +28 -0
  236. package/src/scss/classes/_loaders.scss +779 -0
  237. package/src/scss/classes/_transforms.scss +138 -0
  238. package/src/scss/classes/_transitions.scss +264 -0
  239. package/src/scss/dev/_banner.scss +36 -0
  240. package/src/scss/dev/_debug.scss +18 -0
  241. package/src/scss/dev/_deprecation.scss +13 -0
  242. package/src/scss/dev/_index.scss +8 -0
  243. package/src/scss/dev/_modules.scss +23 -0
  244. package/src/scss/docs.scss +2344 -0
  245. package/src/scss/docs.scss.bak +3133 -0
  246. package/src/scss/functions/_index.scss +22 -0
  247. package/src/scss/functions/scenes/_bubble.scss +32 -0
  248. package/src/scss/functions/scenes/_index.scss +21 -0
  249. package/src/scss/index.scss +17 -0
  250. package/src/scss/maps/_controls.scss +85 -0
  251. package/src/scss/maps/_index.scss +22 -0
  252. package/src/scss/mixins/_accessibility.scss +91 -0
  253. package/src/scss/mixins/_boot.scss +51 -0
  254. package/src/scss/mixins/_index.scss +41 -0
  255. package/src/scss/mixins/_screensaver.scss +228 -0
  256. package/src/scss/mixins/_shape.scss +315 -0
  257. package/src/scss/mixins/animations/_base.scss +403 -0
  258. package/src/scss/mixins/animations/_beat.scss +137 -0
  259. package/src/scss/mixins/animations/_blink.scss +159 -0
  260. package/src/scss/mixins/animations/_bounce.scss +306 -0
  261. package/src/scss/mixins/animations/_elastic.scss +69 -0
  262. package/src/scss/mixins/animations/_fade.scss +393 -0
  263. package/src/scss/mixins/animations/_flash.scss +169 -0
  264. package/src/scss/mixins/animations/_flip.scss +251 -0
  265. package/src/scss/mixins/animations/_float.scss +141 -0
  266. package/src/scss/mixins/animations/_glow.scss +190 -0
  267. package/src/scss/mixins/animations/_heartbeat.scss +195 -0
  268. package/src/scss/mixins/animations/_hinge.scss +118 -0
  269. package/src/scss/mixins/animations/_index.scss +97 -0
  270. package/src/scss/mixins/animations/_jello.scss +123 -0
  271. package/src/scss/mixins/animations/_jiggle.scss +162 -0
  272. package/src/scss/mixins/animations/_lightspeed.scss +135 -0
  273. package/src/scss/mixins/animations/_nod.scss +153 -0
  274. package/src/scss/mixins/animations/_pop.scss +153 -0
  275. package/src/scss/mixins/animations/_pulse.scss +275 -0
  276. package/src/scss/mixins/animations/_ripple.scss +161 -0
  277. package/src/scss/mixins/animations/_roll.scss +217 -0
  278. package/src/scss/mixins/animations/_rotate.scss +728 -0
  279. package/src/scss/mixins/animations/_rubber.scss +115 -0
  280. package/src/scss/mixins/animations/_scale.scss +382 -0
  281. package/src/scss/mixins/animations/_shake.scss +233 -0
  282. package/src/scss/mixins/animations/_slide.scss +501 -0
  283. package/src/scss/mixins/animations/_spin.scss +322 -0
  284. package/src/scss/mixins/animations/_sway.scss +150 -0
  285. package/src/scss/mixins/animations/_swing.scss +245 -0
  286. package/src/scss/mixins/animations/_tada.scss +235 -0
  287. package/src/scss/mixins/animations/_twist.scss +162 -0
  288. package/src/scss/mixins/animations/_wave.scss +149 -0
  289. package/src/scss/mixins/animations/_wobble.scss +283 -0
  290. package/src/scss/mixins/animations/_zoom.scss +394 -0
  291. package/src/scss/mixins/controls/_cursor.scss +203 -0
  292. package/src/scss/mixins/controls/_hover.scss +625 -0
  293. package/src/scss/mixins/controls/_index.scss +30 -0
  294. package/src/scss/mixins/controls/_keyboard.scss +300 -0
  295. package/src/scss/mixins/controls/_pointer.scss +267 -0
  296. package/src/scss/mixins/controls/_scroll.scss +460 -0
  297. package/src/scss/mixins/controls/_scrollbar.scss +283 -0
  298. package/src/scss/mixins/controls/_selection.scss +208 -0
  299. package/src/scss/mixins/controls/_touch.scss +401 -0
  300. package/src/scss/mixins/effects/_blend.scss +128 -0
  301. package/src/scss/mixins/effects/_filter.scss +470 -0
  302. package/src/scss/mixins/effects/_focus.scss +83 -0
  303. package/src/scss/mixins/effects/_gradient.scss +130 -0
  304. package/src/scss/mixins/effects/_index.scss +28 -0
  305. package/src/scss/mixins/effects/_mask.scss +76 -0
  306. package/src/scss/mixins/effects/_opacity.scss +376 -0
  307. package/src/scss/mixins/effects/_shadow.scss +429 -0
  308. package/src/scss/mixins/keyframes/_base.scss +199 -0
  309. package/src/scss/mixins/keyframes/_index.scss +24 -0
  310. package/src/scss/mixins/keyframes/animations/_beat.scss +280 -0
  311. package/src/scss/mixins/keyframes/animations/_blink.scss +82 -0
  312. package/src/scss/mixins/keyframes/animations/_bounce.scss +292 -0
  313. package/src/scss/mixins/keyframes/animations/_fade.scss +311 -0
  314. package/src/scss/mixins/keyframes/animations/_flash.scss +165 -0
  315. package/src/scss/mixins/keyframes/animations/_flip.scss +266 -0
  316. package/src/scss/mixins/keyframes/animations/_index.scss +46 -0
  317. package/src/scss/mixins/keyframes/animations/_jiggle.scss +85 -0
  318. package/src/scss/mixins/keyframes/animations/_lightspeed.scss +73 -0
  319. package/src/scss/mixins/keyframes/animations/_nod.scss +79 -0
  320. package/src/scss/mixins/keyframes/animations/_pop.scss +78 -0
  321. package/src/scss/mixins/keyframes/animations/_pulse.scss +225 -0
  322. package/src/scss/mixins/keyframes/animations/_ripple.scss +94 -0
  323. package/src/scss/mixins/keyframes/animations/_roll.scss +124 -0
  324. package/src/scss/mixins/keyframes/animations/_rotate.scss +360 -0
  325. package/src/scss/mixins/keyframes/animations/_rubber.scss +81 -0
  326. package/src/scss/mixins/keyframes/animations/_scale.scss +308 -0
  327. package/src/scss/mixins/keyframes/animations/_shake.scss +270 -0
  328. package/src/scss/mixins/keyframes/animations/_slide.scss +345 -0
  329. package/src/scss/mixins/keyframes/animations/_spin.scss +270 -0
  330. package/src/scss/mixins/keyframes/animations/_sway.scss +83 -0
  331. package/src/scss/mixins/keyframes/animations/_twist.scss +89 -0
  332. package/src/scss/mixins/keyframes/animations/_wave.scss +90 -0
  333. package/src/scss/mixins/keyframes/animations/_wobble.scss +293 -0
  334. package/src/scss/mixins/keyframes/animations/_zoom.scss +345 -0
  335. package/src/scss/mixins/loaders/_bars.scss +128 -0
  336. package/src/scss/mixins/loaders/_base.scss +39 -0
  337. package/src/scss/mixins/loaders/_bubble.scss +395 -0
  338. package/src/scss/mixins/loaders/_circle.scss +456 -0
  339. package/src/scss/mixins/loaders/_dots.scss +248 -0
  340. package/src/scss/mixins/loaders/_graph.scss +542 -0
  341. package/src/scss/mixins/loaders/_index.scss +77 -0
  342. package/src/scss/mixins/loaders/_line.scss +471 -0
  343. package/src/scss/mixins/loaders/_objects.scss +563 -0
  344. package/src/scss/mixins/loaders/_progress.scss +477 -0
  345. package/src/scss/mixins/loaders/_rect.scss +480 -0
  346. package/src/scss/mixins/loaders/_rings.scss +377 -0
  347. package/src/scss/mixins/loaders/_skeleton.scss +461 -0
  348. package/src/scss/mixins/loaders/_special.scss +611 -0
  349. package/src/scss/mixins/loaders/_spinner.scss +175 -0
  350. package/src/scss/mixins/loaders/_text.scss +446 -0
  351. package/src/scss/mixins/transforms/_flip.scss +74 -0
  352. package/src/scss/mixins/transforms/_index.scss +28 -0
  353. package/src/scss/mixins/transforms/_matrix.scss +18 -0
  354. package/src/scss/mixins/transforms/_perspective.scss +28 -0
  355. package/src/scss/mixins/transforms/_rotate.scss +96 -0
  356. package/src/scss/mixins/transforms/_scale.scss +26 -0
  357. package/src/scss/mixins/transforms/_skew.scss +27 -0
  358. package/src/scss/mixins/transforms/_translate.scss +27 -0
  359. package/src/scss/mixins/transitions/_index.scss +22 -0
  360. package/src/scss/mixins/transitions/_transition.scss +43 -0
  361. package/src/scss/variables/_animations.scss +300 -0
  362. package/src/scss/variables/_controls.scss +178 -0
  363. package/src/scss/variables/_effects.scss +87 -0
  364. package/src/scss/variables/_index.scss +27 -0
  365. package/src/scss/variables/_keyframes.scss +28 -0
  366. package/src/scss/variables/_loaders.scss +75 -0
  367. package/src/scss/variables/_transforms.scss +85 -0
  368. package/src/scss/variables/_transitions.scss +80 -0
  369. package/src/ts/Draggable.ts +143 -0
  370. package/src/ts/Gesture.ts +226 -0
  371. package/src/ts/Keyboard.ts +195 -0
  372. package/src/ts/LoaderManager.ts +662 -0
  373. package/src/ts/Screensaver.ts +192 -0
  374. package/src/ts/VideoOverlay.ts +205 -0
  375. package/src/ts/demo.ts +1108 -0
  376. package/src/ts/index.ts +58 -0
  377. package/css/move.gl.css +0 -2
  378. package/css/move.gl.min.css +0 -2
  379. package/scss/classes/_transforms.scss +0 -124
  380. package/scss/classes/keyboard.scss +0 -18
  381. package/scss/classes/screensaver.scss +0 -15
  382. package/scss/effects/_filter.scss +0 -176
  383. package/scss/effects/_index.scss +0 -23
  384. package/scss/effects/_opacity.scss +0 -62
  385. package/scss/effects/_shadow.scss +0 -175
  386. package/scss/functions/scenes/_bubble.scss +0 -19
  387. package/scss/functions/scenes/_index.scss +0 -20
  388. package/scss/index.scss +0 -0
  389. package/scss/keyframes/_beat.scss +0 -26
  390. package/scss/keyframes/_index.scss +0 -0
  391. package/scss/maps/_index.scss +0 -0
  392. package/scss/maps/_mouse.scss +0 -96
  393. package/scss/mixins/_hover.scss +0 -51
  394. package/scss/mixins/_index.scss +0 -0
  395. package/scss/mixins/_selection.scss +0 -321
  396. package/scss/mixins/_shape.scss +0 -44
  397. package/scss/mixins/_touch.scss +0 -95
  398. package/scss/mixins/animations/--hover.scss +0 -107
  399. package/scss/mixins/animations/_base.scss +0 -337
  400. package/scss/mixins/animations/_beat.scss +0 -119
  401. package/scss/mixins/animations/_bounce.scss +0 -192
  402. package/scss/mixins/animations/_fade.scss +0 -154
  403. package/scss/mixins/animations/_flip.scss +0 -72
  404. package/scss/mixins/animations/_heartbeat.scss +0 -175
  405. package/scss/mixins/animations/_hinge.scss +0 -119
  406. package/scss/mixins/animations/_jello.scss +0 -129
  407. package/scss/mixins/animations/_jiggle.scss +0 -163
  408. package/scss/mixins/animations/_lightspeed.scss +0 -130
  409. package/scss/mixins/animations/_pop.scss +0 -150
  410. package/scss/mixins/animations/_pulse.scss +0 -213
  411. package/scss/mixins/animations/_roll.scss +0 -261
  412. package/scss/mixins/animations/_rotate.scss +0 -428
  413. package/scss/mixins/animations/_rubber.scss +0 -116
  414. package/scss/mixins/animations/_scale.scss +0 -113
  415. package/scss/mixins/animations/_shake.scss +0 -182
  416. package/scss/mixins/animations/_slide.scss +0 -294
  417. package/scss/mixins/animations/_spin.scss +0 -219
  418. package/scss/mixins/animations/_wobble.scss +0 -254
  419. package/scss/mixins/animations/_zoom.scss +0 -166
  420. package/scss/mixins/effects/_filter.scss +0 -148
  421. package/scss/mixins/effects/_index.scss +0 -0
  422. package/scss/mixins/effects/_shadow.scss +0 -21
  423. package/scss/mixins/loaders/_index.scss +0 -0
  424. package/scss/mixins/loaders/_progress.scss +0 -174
  425. package/scss/mixins/loaders/_spinner.scss +0 -101
  426. package/scss/mixins/loaders/circle_01.scss +0 -22
  427. package/scss/mixins/loaders/circle_02.scss +0 -19
  428. package/scss/mixins/loaders/circle_03.scss +0 -29
  429. package/scss/mixins/loaders/circle_inner_01.scss +0 -33
  430. package/scss/mixins/loaders/circle_inner_02.scss +0 -33
  431. package/scss/mixins/loaders/circle_inner_03.scss +0 -34
  432. package/scss/mixins/mouse/_index.scss +0 -0
  433. package/scss/mixins/scroll/_index.scss +0 -0
  434. package/scss/mixins/scroll/_scroll.scss +0 -104
  435. package/scss/mixins/transforms/_index.scss +0 -23
  436. package/scss/mixins/transforms/_matrix.scss +0 -1
  437. package/scss/mixins/transitions/_index.scss +0 -0
  438. package/scss/mixins/transitions/_transition.scss +0 -13
  439. package/scss/variables/_animation.scss +0 -91
  440. package/scss/variables/_index.scss +0 -0
  441. package/ts/ARContent.ts +0 -27
  442. package/ts/ARInteraction.ts +0 -34
  443. package/ts/AdaptiveUI.ts +0 -25
  444. package/ts/ContentStreaming.ts +0 -20
  445. package/ts/Draggable.ts +0 -71
  446. package/ts/DynamicEnvironment.ts +0 -60
  447. package/ts/Gesture.ts +0 -168
  448. package/ts/ImmersiveAudio.ts +0 -40
  449. package/ts/InteractiveCanvas.ts +0 -177
  450. package/ts/InteractiveVideo.ts +0 -29
  451. package/ts/Keyboard.ts +0 -162
  452. package/ts/RealTimeCollaboration.ts +0 -25
  453. package/ts/Screensaver.ts +0 -140
  454. package/ts/SpatialNavigation.ts +0 -38
  455. package/ts/UserProfile.ts +0 -27
  456. package/ts/VRExperience.ts +0 -58
  457. package/ts/VideoOverlay.ts +0 -116
  458. package/ts/index.ts +0 -0
  459. /package/{scss → dist/scss}/dev/_banner.scss +0 -0
  460. /package/{scss → dist/scss}/dev/_debug.scss +0 -0
  461. /package/{scss → dist/scss}/dev/_index.scss +0 -0
  462. /package/{scss/classes/_index.scss → src/html/partials/_code_block.html} +0 -0
  463. /package/{scss/functions/_index.scss → src/html/partials/_feature_card.html} +0 -0
@@ -0,0 +1,3133 @@
1
+ // =============================================================================
2
+ // move.gl Docs Styles
3
+ // =============================================================================
4
+ // Styles for the documentation site.
5
+
6
+ // Note: unit.gl would be imported via: @use "unit.gl" as *;
7
+ // For now, we're using standalone styles for the demo
8
+
9
+ // -----------------------------------------------------------------------------
10
+ // Variables
11
+ // -----------------------------------------------------------------------------
12
+
13
+ :root {
14
+ --color-bg: #ffffff;
15
+ --color-text: #1a1a1a;
16
+ --color-text-muted: #666666;
17
+ --color-border: #e5e5e5;
18
+ --color-primary: #3b82f6;
19
+ --color-primary-hover: #2563eb;
20
+ --color-surface: #f5f5f5;
21
+ --color-code-bg: #1e1e1e;
22
+ --color-code-text: #d4d4d4;
23
+ --nav-height: 60px;
24
+ }
25
+
26
+ [data-theme="dark"] {
27
+ --color-bg: #0a0a0a;
28
+ --color-text: #fafafa;
29
+ --color-text-muted: #a3a3a3;
30
+ --color-border: #262626;
31
+ --color-surface: #171717;
32
+ --color-code-bg: #0d0d0d;
33
+ }
34
+
35
+ // -----------------------------------------------------------------------------
36
+ // Base
37
+ // -----------------------------------------------------------------------------
38
+
39
+ *,
40
+ *::before,
41
+ *::after {
42
+ box-sizing: border-box;
43
+ }
44
+
45
+ html {
46
+ font-size: 16px;
47
+ scroll-behavior: smooth;
48
+ }
49
+
50
+ body {
51
+ margin: 0;
52
+ padding: 0;
53
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
54
+ font-size: 1rem;
55
+ line-height: 1.6;
56
+ color: var(--color-text);
57
+ background-color: var(--color-bg);
58
+ -webkit-font-smoothing: antialiased;
59
+ }
60
+
61
+ // -----------------------------------------------------------------------------
62
+ // Navigation
63
+ // -----------------------------------------------------------------------------
64
+
65
+ .nav-wrapper {
66
+ position: fixed;
67
+ top: 0;
68
+ left: 0;
69
+ right: 0;
70
+ z-index: 100;
71
+ background: var(--color-bg);
72
+ border-bottom: 1px solid var(--color-border);
73
+ backdrop-filter: blur(10px);
74
+ }
75
+
76
+ .nav {
77
+ max-width: 1200px;
78
+ margin: 0 auto;
79
+ padding: 0 24px;
80
+ }
81
+
82
+ .nav__inner {
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: space-between;
86
+ height: var(--nav-height);
87
+ }
88
+
89
+ .nav__logo {
90
+ display: flex;
91
+ align-items: center;
92
+ gap: 8px;
93
+ text-decoration: none;
94
+ color: var(--color-text);
95
+ }
96
+
97
+ .nav__logo-text {
98
+ font-weight: 600;
99
+ font-size: 1.125rem;
100
+ }
101
+
102
+ .nav__version {
103
+ font-size: 0.75rem;
104
+ padding: 2px 6px;
105
+ background: var(--color-surface);
106
+ border-radius: 4px;
107
+ color: var(--color-text-muted);
108
+ }
109
+
110
+ .nav__right {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 16px;
114
+ }
115
+
116
+ .nav__github {
117
+ color: var(--color-text);
118
+ opacity: 0.7;
119
+ transition: opacity 0.2s;
120
+
121
+ &:hover {
122
+ opacity: 1;
123
+ }
124
+ }
125
+
126
+ // Theme toggle
127
+ .theme-toggle {
128
+ display: flex;
129
+ align-items: center;
130
+ justify-content: center;
131
+ width: 36px;
132
+ height: 36px;
133
+ padding: 0;
134
+ background: transparent;
135
+ border: 1px solid var(--color-border);
136
+ border-radius: 8px;
137
+ cursor: pointer;
138
+ color: var(--color-text);
139
+ transition: background 0.2s, border-color 0.2s;
140
+
141
+ &:hover {
142
+ background: var(--color-surface);
143
+ }
144
+ }
145
+
146
+ .theme-icon--dark {
147
+ display: none;
148
+ }
149
+
150
+ [data-theme="dark"] {
151
+ .theme-icon--light { display: none; }
152
+ .theme-icon--dark { display: block; }
153
+ }
154
+
155
+ // Dropdown
156
+ .nav__dropdown {
157
+ position: relative;
158
+ }
159
+
160
+ .nav__dropdown-toggle {
161
+ display: flex;
162
+ align-items: center;
163
+ gap: 6px;
164
+ padding: 8px 12px;
165
+ background: transparent;
166
+ border: 1px solid var(--color-border);
167
+ border-radius: 8px;
168
+ cursor: pointer;
169
+ font-size: 0.875rem;
170
+ color: var(--color-text);
171
+ transition: background 0.2s;
172
+
173
+ &:hover {
174
+ background: var(--color-surface);
175
+ }
176
+ }
177
+
178
+ .nav__dropdown-menu {
179
+ position: absolute;
180
+ top: calc(100% + 8px);
181
+ right: 0;
182
+ min-width: 220px;
183
+ max-height: calc(100vh - var(--nav-height) - 40px);
184
+ overflow-y: auto;
185
+ padding: 8px;
186
+ background: var(--color-bg);
187
+ border: 1px solid var(--color-border);
188
+ border-radius: 12px;
189
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1);
190
+ opacity: 0;
191
+ visibility: hidden;
192
+ transform: translateY(-8px);
193
+ transition: all 0.2s;
194
+
195
+ // Custom scrollbar for dropdown
196
+ &::-webkit-scrollbar {
197
+ width: 6px;
198
+ }
199
+ &::-webkit-scrollbar-track {
200
+ background: transparent;
201
+ }
202
+ &::-webkit-scrollbar-thumb {
203
+ background: var(--color-border);
204
+ border-radius: 3px;
205
+ }
206
+ &::-webkit-scrollbar-thumb:hover {
207
+ background: var(--color-text-muted);
208
+ }
209
+ }
210
+
211
+ .nav__dropdown.open .nav__dropdown-menu {
212
+ opacity: 1;
213
+ visibility: visible;
214
+ transform: translateY(0);
215
+ }
216
+
217
+ .nav__dropdown-section {
218
+ padding: 8px 0;
219
+
220
+ &:not(:last-child) {
221
+ border-bottom: 1px solid var(--color-border);
222
+ }
223
+ }
224
+
225
+ .nav__dropdown-label {
226
+ display: block;
227
+ padding: 4px 12px;
228
+ font-size: 0.75rem;
229
+ font-weight: 600;
230
+ text-transform: uppercase;
231
+ letter-spacing: 0.05em;
232
+ color: var(--color-text-muted);
233
+ }
234
+
235
+ .nav__dropdown-menu a {
236
+ display: block;
237
+ padding: 8px 12px;
238
+ color: var(--color-text);
239
+ text-decoration: none;
240
+ border-radius: 6px;
241
+ font-size: 0.875rem;
242
+ transition: background 0.15s;
243
+
244
+ &:hover {
245
+ background: var(--color-surface);
246
+ }
247
+ }
248
+
249
+ // -----------------------------------------------------------------------------
250
+ // Container & Layout
251
+ // -----------------------------------------------------------------------------
252
+
253
+ .container {
254
+ max-width: 1200px;
255
+ margin: 0 auto;
256
+ padding: calc(var(--nav-height) + 40px) 24px 80px;
257
+ }
258
+
259
+ .header {
260
+ margin-bottom: 48px;
261
+ }
262
+
263
+ .header--hero {
264
+ text-align: center;
265
+ padding: 60px 0;
266
+ }
267
+
268
+ .eyebrow {
269
+ font-size: 0.875rem;
270
+ font-weight: 500;
271
+ text-transform: uppercase;
272
+ letter-spacing: 0.1em;
273
+ color: var(--color-primary);
274
+ margin-bottom: 8px;
275
+ }
276
+
277
+ h1 {
278
+ font-size: 3rem;
279
+ font-weight: 700;
280
+ line-height: 1.1;
281
+ margin: 0 0 16px;
282
+ }
283
+
284
+ .lead {
285
+ font-size: 1.25rem;
286
+ color: var(--color-text-muted);
287
+ max-width: 600px;
288
+ margin: 0 auto 32px;
289
+ }
290
+
291
+ h2 {
292
+ font-size: 1.75rem;
293
+ font-weight: 600;
294
+ margin: 0 0 24px;
295
+ }
296
+
297
+ h3 {
298
+ font-size: 1.25rem;
299
+ font-weight: 600;
300
+ margin: 0 0 12px;
301
+ }
302
+
303
+ section {
304
+ margin-bottom: 64px;
305
+ }
306
+
307
+ // -----------------------------------------------------------------------------
308
+ // Buttons
309
+ // -----------------------------------------------------------------------------
310
+
311
+ .btn {
312
+ display: inline-flex;
313
+ align-items: center;
314
+ gap: 8px;
315
+ padding: 12px 24px;
316
+ font-size: 0.875rem;
317
+ font-weight: 500;
318
+ text-decoration: none;
319
+ border-radius: 8px;
320
+ cursor: pointer;
321
+ transition: all 0.2s;
322
+ border: none;
323
+ }
324
+
325
+ .btn--primary {
326
+ background: var(--color-primary);
327
+ color: white;
328
+
329
+ &:hover {
330
+ background: var(--color-primary-hover);
331
+ }
332
+ }
333
+
334
+ .btn--secondary {
335
+ background: var(--color-surface);
336
+ color: var(--color-text);
337
+ border: 1px solid var(--color-border);
338
+
339
+ &:hover {
340
+ border-color: var(--color-text-muted);
341
+ }
342
+ }
343
+
344
+ .hero-actions {
345
+ display: flex;
346
+ gap: 16px;
347
+ justify-content: center;
348
+ flex-wrap: wrap;
349
+ }
350
+
351
+ // -----------------------------------------------------------------------------
352
+ // Feature Grid
353
+ // -----------------------------------------------------------------------------
354
+
355
+ .feature-grid {
356
+ display: grid;
357
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
358
+ gap: 24px;
359
+ }
360
+
361
+ .feature-card {
362
+ padding: 24px;
363
+ background: var(--color-surface);
364
+ border-radius: 12px;
365
+ border: 1px solid var(--color-border);
366
+ }
367
+
368
+ .feature-card__icon {
369
+ font-size: 2rem;
370
+ margin-bottom: 12px;
371
+ }
372
+
373
+ .feature-card__title {
374
+ font-size: 1.125rem;
375
+ font-weight: 600;
376
+ margin: 0 0 8px;
377
+ }
378
+
379
+ .feature-card__desc {
380
+ font-size: 0.875rem;
381
+ color: var(--color-text-muted);
382
+ margin: 0;
383
+ line-height: 1.5;
384
+ }
385
+
386
+ // -----------------------------------------------------------------------------
387
+ // Demo Grid
388
+ // -----------------------------------------------------------------------------
389
+
390
+ .demo-grid {
391
+ display: grid;
392
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
393
+ gap: 24px;
394
+ }
395
+
396
+ .demo-card {
397
+ padding: 24px;
398
+ background: var(--color-surface);
399
+ border-radius: 12px;
400
+ border: 1px solid var(--color-border);
401
+ text-align: center;
402
+ }
403
+
404
+ .demo-card__preview {
405
+ height: 80px;
406
+ display: flex;
407
+ align-items: center;
408
+ justify-content: center;
409
+ margin-bottom: 16px;
410
+ }
411
+
412
+ .demo-card__title {
413
+ font-size: 1rem;
414
+ margin: 0 0 4px;
415
+ }
416
+
417
+ .demo-card__desc {
418
+ font-size: 0.75rem;
419
+ color: var(--color-text-muted);
420
+ margin: 0 0 12px;
421
+ }
422
+
423
+ .demo-card__link {
424
+ font-size: 0.875rem;
425
+ color: var(--color-primary);
426
+ text-decoration: none;
427
+
428
+ &:hover {
429
+ text-decoration: underline;
430
+ }
431
+ }
432
+
433
+ // -----------------------------------------------------------------------------
434
+ // Demo Row
435
+ // -----------------------------------------------------------------------------
436
+
437
+ .demo-row {
438
+ display: flex;
439
+ flex-wrap: wrap;
440
+ gap: 48px;
441
+ margin-bottom: 32px;
442
+ padding: 24px;
443
+ }
444
+
445
+ .demo-item {
446
+ text-align: center;
447
+ min-width: 100px;
448
+ padding: 20px;
449
+
450
+ p {
451
+ margin: 12px 0 0;
452
+ font-size: 0.875rem;
453
+ color: var(--color-text-muted);
454
+ }
455
+ }
456
+
457
+ .demo-box {
458
+ width: 60px;
459
+ height: 60px;
460
+ background: var(--color-primary);
461
+ border-radius: 8px;
462
+ }
463
+
464
+ .perspective-container {
465
+ perspective: 500px;
466
+ }
467
+
468
+ // -----------------------------------------------------------------------------
469
+ // Code Block
470
+ // -----------------------------------------------------------------------------
471
+
472
+ .code-block {
473
+ background: var(--color-code-bg);
474
+ color: var(--color-code-text);
475
+ padding: 24px;
476
+ border-radius: 12px;
477
+ font-family: 'JetBrains Mono', monospace;
478
+ font-size: 0.875rem;
479
+ line-height: 1.6;
480
+ overflow-x: auto;
481
+ white-space: pre;
482
+ }
483
+
484
+ .code-block .comment {
485
+ color: #6a9955;
486
+ }
487
+
488
+ .code-block .class {
489
+ color: #4ec9b0;
490
+ }
491
+
492
+ code {
493
+ font-family: 'JetBrains Mono', monospace;
494
+ font-size: 0.875em;
495
+ background: var(--color-surface);
496
+ padding: 2px 6px;
497
+ border-radius: 4px;
498
+ }
499
+
500
+ // -----------------------------------------------------------------------------
501
+ // Documentation Sections
502
+ // -----------------------------------------------------------------------------
503
+
504
+ .doc-sections {
505
+ display: grid;
506
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
507
+ gap: 32px;
508
+ }
509
+
510
+ .doc-section h3 {
511
+ font-size: 0.875rem;
512
+ font-weight: 600;
513
+ text-transform: uppercase;
514
+ letter-spacing: 0.05em;
515
+ color: var(--color-text-muted);
516
+ margin-bottom: 16px;
517
+ }
518
+
519
+ .doc-section ul {
520
+ list-style: none;
521
+ padding: 0;
522
+ margin: 0;
523
+ }
524
+
525
+ .doc-section li {
526
+ margin-bottom: 8px;
527
+ }
528
+
529
+ .doc-section a {
530
+ color: var(--color-text);
531
+ text-decoration: none;
532
+
533
+ &:hover {
534
+ color: var(--color-primary);
535
+ }
536
+ }
537
+
538
+ // -----------------------------------------------------------------------------
539
+ // Footer
540
+ // -----------------------------------------------------------------------------
541
+
542
+ .footer {
543
+ margin-top: 80px;
544
+ padding: 32px 0;
545
+ border-top: 1px solid var(--color-border);
546
+ }
547
+
548
+ .footer__content {
549
+ display: flex;
550
+ justify-content: space-between;
551
+ align-items: center;
552
+ flex-wrap: wrap;
553
+ gap: 24px;
554
+ }
555
+
556
+ .footer__brand {
557
+ font-weight: 600;
558
+ }
559
+
560
+ .footer__tagline {
561
+ color: var(--color-text-muted);
562
+ margin-left: 8px;
563
+ }
564
+
565
+ .footer__right {
566
+ display: flex;
567
+ align-items: center;
568
+ gap: 24px;
569
+ }
570
+
571
+ .footer__links {
572
+ display: flex;
573
+ gap: 16px;
574
+ }
575
+
576
+ .footer__link {
577
+ color: var(--color-text-muted);
578
+ text-decoration: none;
579
+ font-size: 0.875rem;
580
+
581
+ &:hover {
582
+ color: var(--color-text);
583
+ }
584
+ }
585
+
586
+ .footer__copyright {
587
+ color: var(--color-text-muted);
588
+ font-size: 0.75rem;
589
+ }
590
+
591
+ // -----------------------------------------------------------------------------
592
+ // Demo Animations (for the index page showcase)
593
+ // -----------------------------------------------------------------------------
594
+
595
+ @keyframes fade-in-loop {
596
+ 0%, 100% { opacity: 0; }
597
+ 50% { opacity: 1; }
598
+ }
599
+
600
+ @keyframes slide-loop {
601
+ 0%, 100% { transform: translateY(20px); opacity: 0; }
602
+ 50% { transform: translateY(0); opacity: 1; }
603
+ }
604
+
605
+ @keyframes bounce-loop {
606
+ 0%, 100% { transform: translateY(0); }
607
+ 50% { transform: translateY(-15px); }
608
+ }
609
+
610
+ @keyframes zoom-loop {
611
+ 0%, 100% { transform: scale(0.8); opacity: 0.5; }
612
+ 50% { transform: scale(1); opacity: 1; }
613
+ }
614
+
615
+ @keyframes flip-loop {
616
+ 0% { transform: rotateY(0); }
617
+ 100% { transform: rotateY(360deg); }
618
+ }
619
+
620
+ @keyframes spin-loop {
621
+ from { transform: rotate(0deg); }
622
+ to { transform: rotate(360deg); }
623
+ }
624
+
625
+ .animate-fade-in-loop {
626
+ animation: fade-in-loop 2s ease-in-out infinite;
627
+ }
628
+
629
+ .animate-slide-loop {
630
+ animation: slide-loop 2s ease-in-out infinite;
631
+ }
632
+
633
+ .animate-bounce-loop {
634
+ animation: bounce-loop 1s ease-in-out infinite;
635
+ }
636
+
637
+ .animate-zoom-loop {
638
+ animation: zoom-loop 2s ease-in-out infinite;
639
+ }
640
+
641
+ .animate-flip-loop {
642
+ animation: flip-loop 2s linear infinite;
643
+ }
644
+
645
+ .animate-spin-loop {
646
+ animation: spin-loop 1s linear infinite;
647
+ }
648
+
649
+ // -----------------------------------------------------------------------------
650
+ // Demo Page Animations
651
+ // -----------------------------------------------------------------------------
652
+
653
+ // Fade demos
654
+ @keyframes fade-in-demo {
655
+ from { opacity: 0; }
656
+ to { opacity: 1; }
657
+ }
658
+
659
+ @keyframes fade-in-up-demo {
660
+ from { opacity: 0; transform: translateY(20px); }
661
+ to { opacity: 1; transform: translateY(0); }
662
+ }
663
+
664
+ @keyframes fade-in-down-demo {
665
+ from { opacity: 0; transform: translateY(-20px); }
666
+ to { opacity: 1; transform: translateY(0); }
667
+ }
668
+
669
+ @keyframes fade-in-left-demo {
670
+ from { opacity: 0; transform: translateX(-20px); }
671
+ to { opacity: 1; transform: translateX(0); }
672
+ }
673
+
674
+ @keyframes fade-in-right-demo {
675
+ from { opacity: 0; transform: translateX(20px); }
676
+ to { opacity: 1; transform: translateX(0); }
677
+ }
678
+
679
+ .animate-fade-in-demo { animation: fade-in-demo 0.5s ease-out forwards; }
680
+ .animate-fade-in-up-demo { animation: fade-in-up-demo 0.5s ease-out forwards; }
681
+ .animate-fade-in-down-demo { animation: fade-in-down-demo 0.5s ease-out forwards; }
682
+ .animate-fade-in-left-demo { animation: fade-in-left-demo 0.5s ease-out forwards; }
683
+ .animate-fade-in-right-demo { animation: fade-in-right-demo 0.5s ease-out forwards; }
684
+
685
+ @keyframes fade-out-demo {
686
+ from { opacity: 1; }
687
+ to { opacity: 0; }
688
+ }
689
+
690
+ @keyframes fade-out-up-demo {
691
+ from { opacity: 1; transform: translateY(0); }
692
+ to { opacity: 0; transform: translateY(-20px); }
693
+ }
694
+
695
+ @keyframes fade-out-down-demo {
696
+ from { opacity: 1; transform: translateY(0); }
697
+ to { opacity: 0; transform: translateY(20px); }
698
+ }
699
+
700
+ .animate-fade-out-demo { animation: fade-out-demo 0.5s ease-out forwards; animation-delay: 1s; }
701
+ .animate-fade-out-up-demo { animation: fade-out-up-demo 0.5s ease-out forwards; animation-delay: 1s; }
702
+ .animate-fade-out-down-demo { animation: fade-out-down-demo 0.5s ease-out forwards; animation-delay: 1s; }
703
+
704
+ // Slide demos
705
+ @keyframes slide-up-demo {
706
+ from { transform: translateY(30px); opacity: 0; }
707
+ to { transform: translateY(0); opacity: 1; }
708
+ }
709
+
710
+ @keyframes slide-down-demo {
711
+ from { transform: translateY(-30px); opacity: 0; }
712
+ to { transform: translateY(0); opacity: 1; }
713
+ }
714
+
715
+ @keyframes slide-left-demo {
716
+ from { transform: translateX(30px); opacity: 0; }
717
+ to { transform: translateX(0); opacity: 1; }
718
+ }
719
+
720
+ @keyframes slide-right-demo {
721
+ from { transform: translateX(-30px); opacity: 0; }
722
+ to { transform: translateX(0); opacity: 1; }
723
+ }
724
+
725
+ .animate-slide-up-demo { animation: slide-up-demo 0.5s ease-out forwards; }
726
+ .animate-slide-down-demo { animation: slide-down-demo 0.5s ease-out forwards; }
727
+ .animate-slide-left-demo { animation: slide-left-demo 0.5s ease-out forwards; }
728
+ .animate-slide-right-demo { animation: slide-right-demo 0.5s ease-out forwards; }
729
+
730
+ // Bounce demos
731
+ @keyframes bounce-demo {
732
+ 0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
733
+ 40% { transform: translateY(-20px); }
734
+ 60% { transform: translateY(-10px); }
735
+ }
736
+
737
+ @keyframes bounce-in-demo {
738
+ 0% { opacity: 0; transform: scale(0.3); }
739
+ 50% { opacity: 1; transform: scale(1.05); }
740
+ 70% { transform: scale(0.9); }
741
+ 100% { transform: scale(1); }
742
+ }
743
+
744
+ @keyframes bounce-out-demo {
745
+ 0% { transform: scale(1); }
746
+ 25% { transform: scale(0.95); }
747
+ 50% { opacity: 1; transform: scale(1.1); }
748
+ 100% { opacity: 0; transform: scale(0.3); }
749
+ }
750
+
751
+ .animate-bounce-demo { animation: bounce-demo 1s ease forwards; }
752
+ .animate-bounce-in-demo { animation: bounce-in-demo 0.6s ease forwards; }
753
+ .animate-bounce-out-demo { animation: bounce-out-demo 0.6s ease forwards; animation-delay: 1s; }
754
+
755
+ @keyframes pulse-demo {
756
+ 0%, 100% { transform: scale(1); opacity: 1; }
757
+ 50% { transform: scale(1.1); opacity: 0.7; }
758
+ }
759
+
760
+ .animate-pulse-demo { animation: pulse-demo 1.5s ease-in-out infinite; }
761
+
762
+ // Zoom demos
763
+ @keyframes zoom-in-demo {
764
+ from { transform: scale(0.5); opacity: 0; }
765
+ to { transform: scale(1); opacity: 1; }
766
+ }
767
+
768
+ @keyframes zoom-in-up-demo {
769
+ from { transform: scale(0.5) translateY(20px); opacity: 0; }
770
+ to { transform: scale(1) translateY(0); opacity: 1; }
771
+ }
772
+
773
+ @keyframes zoom-in-down-demo {
774
+ from { transform: scale(0.5) translateY(-20px); opacity: 0; }
775
+ to { transform: scale(1) translateY(0); opacity: 1; }
776
+ }
777
+
778
+ @keyframes zoom-out-demo {
779
+ from { transform: scale(1); opacity: 1; }
780
+ to { transform: scale(0.5); opacity: 0; }
781
+ }
782
+
783
+ .animate-zoom-in-demo { animation: zoom-in-demo 0.5s ease-out forwards; }
784
+ .animate-zoom-in-up-demo { animation: zoom-in-up-demo 0.5s ease-out forwards; }
785
+ .animate-zoom-in-down-demo { animation: zoom-in-down-demo 0.5s ease-out forwards; }
786
+ .animate-zoom-out-demo { animation: zoom-out-demo 0.5s ease-out forwards; animation-delay: 1s; }
787
+
788
+ // Flip demos
789
+ @keyframes flip-x-demo {
790
+ from { transform: perspective(400px) rotateX(90deg); opacity: 0; }
791
+ to { transform: perspective(400px) rotateX(0); opacity: 1; }
792
+ }
793
+
794
+ @keyframes flip-y-demo {
795
+ from { transform: perspective(400px) rotateY(90deg); opacity: 0; }
796
+ to { transform: perspective(400px) rotateY(0); opacity: 1; }
797
+ }
798
+
799
+ .animate-flip-x-demo { animation: flip-x-demo 0.6s ease-out forwards; }
800
+ .animate-flip-y-demo { animation: flip-y-demo 0.6s ease-out forwards; }
801
+
802
+ // -----------------------------------------------------------------------------
803
+ // Loaders
804
+ // -----------------------------------------------------------------------------
805
+
806
+ .loader {
807
+ display: inline-flex;
808
+ align-items: center;
809
+ justify-content: center;
810
+ }
811
+
812
+ .loader--spinner {
813
+ width: 40px;
814
+ height: 40px;
815
+ border: 3px solid var(--color-border);
816
+ border-top-color: var(--color-primary);
817
+ border-radius: 50%;
818
+ animation: spin-loop 0.8s linear infinite;
819
+ }
820
+
821
+ .loader--spinner-dots {
822
+ width: 40px;
823
+ height: 40px;
824
+ border: 3px dotted var(--color-primary);
825
+ border-radius: 50%;
826
+ animation: spin-loop 1.5s linear infinite;
827
+ }
828
+
829
+ .loader--dots {
830
+ display: flex;
831
+ gap: 6px;
832
+
833
+ span {
834
+ width: 10px;
835
+ height: 10px;
836
+ background: var(--color-primary);
837
+ border-radius: 50%;
838
+ animation: dots-pulse 1.4s ease-in-out infinite;
839
+
840
+ &:nth-child(2) { animation-delay: 0.2s; }
841
+ &:nth-child(3) { animation-delay: 0.4s; }
842
+ }
843
+ }
844
+
845
+ @keyframes dots-pulse {
846
+ 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
847
+ 40% { opacity: 1; transform: scale(1); }
848
+ }
849
+
850
+ .loader--dots-bounce {
851
+ display: flex;
852
+ gap: 6px;
853
+
854
+ span {
855
+ width: 10px;
856
+ height: 10px;
857
+ background: var(--color-primary);
858
+ border-radius: 50%;
859
+ animation: dots-bounce 1.4s ease-in-out infinite;
860
+
861
+ &:nth-child(2) { animation-delay: 0.16s; }
862
+ &:nth-child(3) { animation-delay: 0.32s; }
863
+ }
864
+ }
865
+
866
+ @keyframes dots-bounce {
867
+ 0%, 80%, 100% { transform: translateY(0); }
868
+ 40% { transform: translateY(-12px); }
869
+ }
870
+
871
+ .loader--bars {
872
+ display: flex;
873
+ gap: 4px;
874
+ height: 30px;
875
+ align-items: flex-end;
876
+
877
+ span {
878
+ width: 6px;
879
+ background: var(--color-primary);
880
+ border-radius: 2px;
881
+ animation: bars-wave 1.2s ease-in-out infinite;
882
+
883
+ &:nth-child(1) { animation-delay: 0s; }
884
+ &:nth-child(2) { animation-delay: 0.1s; }
885
+ &:nth-child(3) { animation-delay: 0.2s; }
886
+ &:nth-child(4) { animation-delay: 0.3s; }
887
+ }
888
+ }
889
+
890
+ @keyframes bars-wave {
891
+ 0%, 40%, 100% { height: 10px; }
892
+ 20% { height: 30px; }
893
+ }
894
+
895
+ .loader--progress {
896
+ width: 100px;
897
+ height: 4px;
898
+ background: var(--color-border);
899
+ border-radius: 2px;
900
+ overflow: hidden;
901
+
902
+ &::after {
903
+ content: '';
904
+ display: block;
905
+ width: 40%;
906
+ height: 100%;
907
+ background: var(--color-primary);
908
+ border-radius: 2px;
909
+ animation: progress-slide 1.5s ease-in-out infinite;
910
+ }
911
+ }
912
+
913
+ @keyframes progress-slide {
914
+ 0% { transform: translateX(-100%); }
915
+ 100% { transform: translateX(350%); }
916
+ }
917
+
918
+ .loader--pulse {
919
+ width: 40px;
920
+ height: 40px;
921
+ background: var(--color-primary);
922
+ border-radius: 50%;
923
+ animation: loader-pulse 1.5s ease-in-out infinite;
924
+ }
925
+
926
+ @keyframes loader-pulse {
927
+ 0% { transform: scale(0.8); opacity: 1; }
928
+ 50% { transform: scale(1); opacity: 0.5; }
929
+ 100% { transform: scale(0.8); opacity: 1; }
930
+ }
931
+
932
+ .loader--ripple {
933
+ position: relative;
934
+ width: 40px;
935
+ height: 40px;
936
+
937
+ span {
938
+ position: absolute;
939
+ inset: 0;
940
+ border: 3px solid var(--color-primary);
941
+ border-radius: 50%;
942
+ animation: ripple 1.5s ease-out infinite;
943
+
944
+ &:nth-child(2) {
945
+ animation-delay: 0.5s;
946
+ }
947
+ }
948
+ }
949
+
950
+ @keyframes ripple {
951
+ 0% { transform: scale(0.5); opacity: 1; }
952
+ 100% { transform: scale(1.5); opacity: 0; }
953
+ }
954
+
955
+ // Dual Ring Loader
956
+ .loader--dual-ring {
957
+ width: 40px;
958
+ height: 40px;
959
+ border: 3px solid transparent;
960
+ border-top-color: var(--color-primary);
961
+ border-bottom-color: var(--color-primary);
962
+ border-radius: 50%;
963
+ animation: spin-loop 1s linear infinite;
964
+ }
965
+
966
+ // Hourglass Loader
967
+ .loader--hourglass {
968
+ width: 40px;
969
+ height: 40px;
970
+ border: 3px solid var(--color-primary);
971
+ border-radius: 50%;
972
+ border-top-color: transparent;
973
+ border-bottom-color: transparent;
974
+ animation: spin-loop 1.2s linear infinite;
975
+ }
976
+
977
+ // Circle Notch Loader
978
+ .loader--circle-notch {
979
+ width: 40px;
980
+ height: 40px;
981
+ border: 3px solid var(--color-border);
982
+ border-radius: 50%;
983
+ position: relative;
984
+
985
+ &::after {
986
+ content: '';
987
+ position: absolute;
988
+ top: -3px;
989
+ left: -3px;
990
+ right: -3px;
991
+ bottom: -3px;
992
+ border: 3px solid transparent;
993
+ border-top-color: var(--color-primary);
994
+ border-radius: 50%;
995
+ animation: spin-loop 0.8s linear infinite;
996
+ }
997
+ }
998
+
999
+ // Dots Wave Loader
1000
+ .loader--dots-wave {
1001
+ display: flex;
1002
+ gap: 4px;
1003
+ align-items: center;
1004
+
1005
+ span {
1006
+ width: 8px;
1007
+ height: 8px;
1008
+ background: var(--color-primary);
1009
+ border-radius: 50%;
1010
+ animation: dots-wave-anim 1.2s ease-in-out infinite;
1011
+
1012
+ &:nth-child(2) { animation-delay: 0.1s; }
1013
+ &:nth-child(3) { animation-delay: 0.2s; }
1014
+ &:nth-child(4) { animation-delay: 0.3s; }
1015
+ &:nth-child(5) { animation-delay: 0.4s; }
1016
+ }
1017
+ }
1018
+
1019
+ @keyframes dots-wave-anim {
1020
+ 0%, 100% { transform: translateY(0); opacity: 0.5; }
1021
+ 50% { transform: translateY(-10px); opacity: 1; }
1022
+ }
1023
+
1024
+ // Dots Fade Loader
1025
+ .loader--dots-fade {
1026
+ display: flex;
1027
+ gap: 6px;
1028
+
1029
+ span {
1030
+ width: 10px;
1031
+ height: 10px;
1032
+ background: var(--color-primary);
1033
+ border-radius: 50%;
1034
+ animation: dots-fade-anim 1.4s ease-in-out infinite;
1035
+
1036
+ &:nth-child(2) { animation-delay: 0.2s; }
1037
+ &:nth-child(3) { animation-delay: 0.4s; }
1038
+ }
1039
+ }
1040
+
1041
+ @keyframes dots-fade-anim {
1042
+ 0%, 100% { opacity: 0.2; }
1043
+ 50% { opacity: 1; }
1044
+ }
1045
+
1046
+ // Dots Grow Loader
1047
+ .loader--dots-grow {
1048
+ display: flex;
1049
+ gap: 6px;
1050
+ align-items: center;
1051
+
1052
+ span {
1053
+ width: 10px;
1054
+ height: 10px;
1055
+ background: var(--color-primary);
1056
+ border-radius: 50%;
1057
+ animation: dots-grow-anim 1s ease-in-out infinite;
1058
+
1059
+ &:nth-child(2) { animation-delay: 0.15s; }
1060
+ &:nth-child(3) { animation-delay: 0.3s; }
1061
+ }
1062
+ }
1063
+
1064
+ @keyframes dots-grow-anim {
1065
+ 0%, 100% { transform: scale(0.6); }
1066
+ 50% { transform: scale(1.2); }
1067
+ }
1068
+
1069
+ // Square Loader
1070
+ .loader--square {
1071
+ width: 30px;
1072
+ height: 30px;
1073
+ background: var(--color-primary);
1074
+ animation: square-rotate 1.2s ease-in-out infinite;
1075
+ }
1076
+
1077
+ @keyframes square-rotate {
1078
+ 0% { transform: rotate(0deg); }
1079
+ 25% { transform: rotate(90deg); }
1080
+ 50% { transform: rotate(180deg); }
1081
+ 75% { transform: rotate(270deg); }
1082
+ 100% { transform: rotate(360deg); }
1083
+ }
1084
+
1085
+ // Cube Flip Loader
1086
+ .loader--cube {
1087
+ width: 30px;
1088
+ height: 30px;
1089
+ background: var(--color-primary);
1090
+ animation: cube-flip 1.2s ease-in-out infinite;
1091
+ perspective: 100px;
1092
+ }
1093
+
1094
+ @keyframes cube-flip {
1095
+ 0% { transform: perspective(100px) rotateX(0) rotateY(0); }
1096
+ 50% { transform: perspective(100px) rotateX(180deg) rotateY(0); }
1097
+ 100% { transform: perspective(100px) rotateX(180deg) rotateY(180deg); }
1098
+ }
1099
+
1100
+ // Ring Loader
1101
+ .loader--ring {
1102
+ width: 40px;
1103
+ height: 40px;
1104
+ border: 4px solid var(--color-border);
1105
+ border-radius: 50%;
1106
+ position: relative;
1107
+
1108
+ &::before {
1109
+ content: '';
1110
+ position: absolute;
1111
+ top: -4px;
1112
+ left: -4px;
1113
+ width: 40px;
1114
+ height: 40px;
1115
+ border: 4px solid transparent;
1116
+ border-top-color: var(--color-primary);
1117
+ border-radius: 50%;
1118
+ animation: spin-loop 1s ease-in-out infinite;
1119
+ }
1120
+ }
1121
+
1122
+ // Ellipsis Loader
1123
+ .loader--ellipsis {
1124
+ display: flex;
1125
+ gap: 4px;
1126
+ align-items: center;
1127
+
1128
+ span {
1129
+ width: 10px;
1130
+ height: 10px;
1131
+ background: var(--color-primary);
1132
+ border-radius: 50%;
1133
+ animation: ellipsis-anim 1.4s ease-in-out infinite;
1134
+
1135
+ &:nth-child(1) { animation-delay: 0s; }
1136
+ &:nth-child(2) { animation-delay: 0.2s; }
1137
+ &:nth-child(3) { animation-delay: 0.4s; }
1138
+ &:nth-child(4) { animation-delay: 0.6s; }
1139
+ }
1140
+ }
1141
+
1142
+ @keyframes ellipsis-anim {
1143
+ 0% { transform: scale(1); }
1144
+ 50% { transform: scale(0.5); }
1145
+ 100% { transform: scale(1); }
1146
+ }
1147
+
1148
+ // Orbit Loader
1149
+ .loader--orbit {
1150
+ width: 40px;
1151
+ height: 40px;
1152
+ position: relative;
1153
+
1154
+ &::before,
1155
+ &::after {
1156
+ content: '';
1157
+ position: absolute;
1158
+ width: 12px;
1159
+ height: 12px;
1160
+ background: var(--color-primary);
1161
+ border-radius: 50%;
1162
+ }
1163
+
1164
+ &::before {
1165
+ top: 0;
1166
+ left: 50%;
1167
+ transform: translateX(-50%);
1168
+ animation: orbit-top 1s ease-in-out infinite;
1169
+ }
1170
+
1171
+ &::after {
1172
+ bottom: 0;
1173
+ left: 50%;
1174
+ transform: translateX(-50%);
1175
+ animation: orbit-bottom 1s ease-in-out infinite;
1176
+ }
1177
+ }
1178
+
1179
+ @keyframes orbit-top {
1180
+ 0%, 100% { top: 0; }
1181
+ 50% { top: calc(100% - 12px); }
1182
+ }
1183
+
1184
+ @keyframes orbit-bottom {
1185
+ 0%, 100% { bottom: 0; }
1186
+ 50% { bottom: calc(100% - 12px); }
1187
+ }
1188
+
1189
+ // Heartbeat Loader
1190
+ .loader--heartbeat {
1191
+ width: 40px;
1192
+ height: 40px;
1193
+ background: var(--color-primary);
1194
+ border-radius: 50%;
1195
+ animation: loader-heartbeat 1.2s ease-in-out infinite;
1196
+ }
1197
+
1198
+ @keyframes loader-heartbeat {
1199
+ 0%, 100% { transform: scale(1); }
1200
+ 14% { transform: scale(1.3); }
1201
+ 28% { transform: scale(1); }
1202
+ 42% { transform: scale(1.3); }
1203
+ 70% { transform: scale(1); }
1204
+ }
1205
+
1206
+ // Gradient Spinner
1207
+ .loader--gradient {
1208
+ width: 40px;
1209
+ height: 40px;
1210
+ border-radius: 50%;
1211
+ background: conic-gradient(from 0deg, transparent, var(--color-primary));
1212
+ animation: spin-loop 1s linear infinite;
1213
+ position: relative;
1214
+
1215
+ &::after {
1216
+ content: '';
1217
+ position: absolute;
1218
+ inset: 4px;
1219
+ background: var(--color-bg);
1220
+ border-radius: 50%;
1221
+ }
1222
+ }
1223
+
1224
+ // Bounce Loader
1225
+ .loader--bounce {
1226
+ display: flex;
1227
+ gap: 8px;
1228
+ align-items: flex-end;
1229
+ height: 40px;
1230
+
1231
+ span {
1232
+ width: 12px;
1233
+ height: 12px;
1234
+ background: var(--color-primary);
1235
+ border-radius: 50%;
1236
+ animation: bounce-loader 0.6s ease-in-out infinite alternate;
1237
+
1238
+ &:nth-child(2) { animation-delay: 0.2s; }
1239
+ &:nth-child(3) { animation-delay: 0.4s; }
1240
+ }
1241
+ }
1242
+
1243
+ @keyframes bounce-loader {
1244
+ 0% { transform: translateY(0); }
1245
+ 100% { transform: translateY(-20px); }
1246
+ }
1247
+
1248
+ // Typing Loader
1249
+ .loader--typing {
1250
+ display: flex;
1251
+ gap: 4px;
1252
+ align-items: center;
1253
+ padding: 8px 12px;
1254
+ background: var(--color-surface);
1255
+ border-radius: 16px;
1256
+
1257
+ span {
1258
+ width: 8px;
1259
+ height: 8px;
1260
+ background: var(--color-primary);
1261
+ border-radius: 50%;
1262
+ animation: typing-anim 1.4s ease-in-out infinite;
1263
+
1264
+ &:nth-child(2) { animation-delay: 0.2s; }
1265
+ &:nth-child(3) { animation-delay: 0.4s; }
1266
+ }
1267
+ }
1268
+
1269
+ @keyframes typing-anim {
1270
+ 0%, 60%, 100% { transform: translateY(0); }
1271
+ 30% { transform: translateY(-6px); }
1272
+ }
1273
+
1274
+ // Clock Loader
1275
+ .loader--clock {
1276
+ width: 40px;
1277
+ height: 40px;
1278
+ border: 3px solid var(--color-border);
1279
+ border-radius: 50%;
1280
+ position: relative;
1281
+
1282
+ &::before {
1283
+ content: '';
1284
+ position: absolute;
1285
+ top: 50%;
1286
+ left: 50%;
1287
+ width: 2px;
1288
+ height: 14px;
1289
+ background: var(--color-primary);
1290
+ transform-origin: center bottom;
1291
+ transform: translate(-50%, -100%) rotate(0deg);
1292
+ animation: clock-minute 2s linear infinite;
1293
+ }
1294
+
1295
+ &::after {
1296
+ content: '';
1297
+ position: absolute;
1298
+ top: 50%;
1299
+ left: 50%;
1300
+ width: 2px;
1301
+ height: 10px;
1302
+ background: var(--color-text);
1303
+ transform-origin: center bottom;
1304
+ transform: translate(-50%, -100%) rotate(0deg);
1305
+ animation: clock-hour 24s linear infinite;
1306
+ }
1307
+ }
1308
+
1309
+ @keyframes clock-minute {
1310
+ 0% { transform: translate(-50%, -100%) rotate(0deg); }
1311
+ 100% { transform: translate(-50%, -100%) rotate(360deg); }
1312
+ }
1313
+
1314
+ @keyframes clock-hour {
1315
+ 0% { transform: translate(-50%, -100%) rotate(0deg); }
1316
+ 100% { transform: translate(-50%, -100%) rotate(360deg); }
1317
+ }
1318
+
1319
+ // DNA Helix Loader
1320
+ .loader--dna {
1321
+ width: 40px;
1322
+ height: 40px;
1323
+ position: relative;
1324
+
1325
+ span {
1326
+ position: absolute;
1327
+ width: 8px;
1328
+ height: 8px;
1329
+ background: var(--color-primary);
1330
+ border-radius: 50%;
1331
+ left: 50%;
1332
+ transform: translateX(-50%);
1333
+
1334
+ &:nth-child(1) { top: 0; animation: dna-top 1s ease-in-out infinite; }
1335
+ &:nth-child(2) { bottom: 0; animation: dna-bottom 1s ease-in-out infinite; }
1336
+ }
1337
+ }
1338
+
1339
+ @keyframes dna-top {
1340
+ 0%, 100% { transform: translateX(-50%) scale(1); opacity: 1; }
1341
+ 50% { transform: translateX(-50%) scale(0.5); opacity: 0.5; }
1342
+ }
1343
+
1344
+ @keyframes dna-bottom {
1345
+ 0%, 100% { transform: translateX(-50%) scale(0.5); opacity: 0.5; }
1346
+ 50% { transform: translateX(-50%) scale(1); opacity: 1; }
1347
+ }
1348
+
1349
+ // Infinity Loader
1350
+ .loader--infinity {
1351
+ width: 60px;
1352
+ height: 30px;
1353
+ position: relative;
1354
+
1355
+ &::before,
1356
+ &::after {
1357
+ content: '';
1358
+ position: absolute;
1359
+ width: 20px;
1360
+ height: 20px;
1361
+ border: 3px solid var(--color-primary);
1362
+ border-radius: 50%;
1363
+ top: 50%;
1364
+ transform: translateY(-50%);
1365
+ }
1366
+
1367
+ &::before {
1368
+ left: 0;
1369
+ animation: infinity-left 1.5s ease-in-out infinite;
1370
+ }
1371
+
1372
+ &::after {
1373
+ right: 0;
1374
+ animation: infinity-right 1.5s ease-in-out infinite;
1375
+ }
1376
+ }
1377
+
1378
+ @keyframes infinity-left {
1379
+ 0%, 100% { transform: translateY(-50%) translateX(0); }
1380
+ 50% { transform: translateY(-50%) translateX(20px); }
1381
+ }
1382
+
1383
+ @keyframes infinity-right {
1384
+ 0%, 100% { transform: translateY(-50%) translateX(0); }
1385
+ 50% { transform: translateY(-50%) translateX(-20px); }
1386
+ }
1387
+
1388
+ // Gear Loader
1389
+ .loader--gear {
1390
+ width: 40px;
1391
+ height: 40px;
1392
+ border: 4px solid var(--color-primary);
1393
+ border-radius: 50%;
1394
+ position: relative;
1395
+ animation: spin-loop 2s linear infinite;
1396
+
1397
+ &::before,
1398
+ &::after {
1399
+ content: '';
1400
+ position: absolute;
1401
+ background: var(--color-primary);
1402
+ }
1403
+
1404
+ &::before {
1405
+ width: 6px;
1406
+ height: 12px;
1407
+ top: -8px;
1408
+ left: 50%;
1409
+ transform: translateX(-50%);
1410
+ box-shadow:
1411
+ 0 48px 0 var(--color-primary),
1412
+ -17px -9px 0 var(--color-primary),
1413
+ 17px -9px 0 var(--color-primary),
1414
+ -17px 41px 0 var(--color-primary),
1415
+ 17px 41px 0 var(--color-primary);
1416
+ }
1417
+ }
1418
+
1419
+ // Windmill Loader
1420
+ .loader--windmill {
1421
+ width: 40px;
1422
+ height: 40px;
1423
+ position: relative;
1424
+ animation: spin-loop 1.5s linear infinite;
1425
+
1426
+ span {
1427
+ position: absolute;
1428
+ width: 4px;
1429
+ height: 16px;
1430
+ background: var(--color-primary);
1431
+ left: 50%;
1432
+ top: 50%;
1433
+ transform-origin: center bottom;
1434
+
1435
+ &:nth-child(1) { transform: translate(-50%, -100%) rotate(0deg); }
1436
+ &:nth-child(2) { transform: translate(-50%, -100%) rotate(90deg); }
1437
+ &:nth-child(3) { transform: translate(-50%, -100%) rotate(180deg); }
1438
+ &:nth-child(4) { transform: translate(-50%, -100%) rotate(270deg); }
1439
+ }
1440
+ }
1441
+
1442
+ // Atom Loader
1443
+ .loader--atom {
1444
+ width: 40px;
1445
+ height: 40px;
1446
+ position: relative;
1447
+
1448
+ &::before {
1449
+ content: '';
1450
+ position: absolute;
1451
+ top: 50%;
1452
+ left: 50%;
1453
+ width: 8px;
1454
+ height: 8px;
1455
+ background: var(--color-primary);
1456
+ border-radius: 50%;
1457
+ transform: translate(-50%, -50%);
1458
+ }
1459
+
1460
+ span {
1461
+ position: absolute;
1462
+ inset: 0;
1463
+ border: 2px solid transparent;
1464
+ border-top-color: var(--color-primary);
1465
+ border-radius: 50%;
1466
+
1467
+ &:nth-child(1) { animation: atom-orbit 1s linear infinite; }
1468
+ &:nth-child(2) { transform: rotate(60deg); animation: atom-orbit 1s linear infinite; }
1469
+ &:nth-child(3) { transform: rotate(120deg); animation: atom-orbit 1s linear infinite; }
1470
+ }
1471
+ }
1472
+
1473
+ @keyframes atom-orbit {
1474
+ 0% { transform: rotate(0deg); }
1475
+ 100% { transform: rotate(360deg); }
1476
+ }
1477
+
1478
+ // Wifi Loader
1479
+ .loader--wifi {
1480
+ width: 40px;
1481
+ height: 30px;
1482
+ position: relative;
1483
+
1484
+ span {
1485
+ position: absolute;
1486
+ bottom: 0;
1487
+ left: 50%;
1488
+ border: 3px solid transparent;
1489
+ border-top-color: var(--color-primary);
1490
+ border-radius: 50%;
1491
+ transform: translateX(-50%);
1492
+ opacity: 0;
1493
+ animation: wifi-pulse 1.5s ease-out infinite;
1494
+
1495
+ &:nth-child(1) { width: 10px; height: 10px; animation-delay: 0s; }
1496
+ &:nth-child(2) { width: 22px; height: 22px; animation-delay: 0.3s; }
1497
+ &:nth-child(3) { width: 34px; height: 34px; animation-delay: 0.6s; }
1498
+ }
1499
+ }
1500
+
1501
+ @keyframes wifi-pulse {
1502
+ 0% { opacity: 0; }
1503
+ 30% { opacity: 1; }
1504
+ 60%, 100% { opacity: 0; }
1505
+ }
1506
+
1507
+ // Battery Loader
1508
+ .loader--battery {
1509
+ width: 50px;
1510
+ height: 24px;
1511
+ border: 3px solid var(--color-border);
1512
+ border-radius: 4px;
1513
+ position: relative;
1514
+
1515
+ &::before {
1516
+ content: '';
1517
+ position: absolute;
1518
+ right: -6px;
1519
+ top: 50%;
1520
+ transform: translateY(-50%);
1521
+ width: 4px;
1522
+ height: 10px;
1523
+ background: var(--color-border);
1524
+ border-radius: 0 2px 2px 0;
1525
+ }
1526
+
1527
+ &::after {
1528
+ content: '';
1529
+ position: absolute;
1530
+ left: 3px;
1531
+ top: 3px;
1532
+ bottom: 3px;
1533
+ width: 0%;
1534
+ background: var(--color-primary);
1535
+ border-radius: 2px;
1536
+ animation: battery-charge 2s ease-in-out infinite;
1537
+ }
1538
+ }
1539
+
1540
+ @keyframes battery-charge {
1541
+ 0% { width: 0%; }
1542
+ 50% { width: calc(100% - 6px); }
1543
+ 100% { width: 0%; }
1544
+ }
1545
+
1546
+ // Pendulum Loader
1547
+ .loader--pendulum {
1548
+ width: 50px;
1549
+ height: 40px;
1550
+ position: relative;
1551
+
1552
+ span {
1553
+ position: absolute;
1554
+ bottom: 0;
1555
+ width: 10px;
1556
+ height: 10px;
1557
+ background: var(--color-primary);
1558
+ border-radius: 50%;
1559
+
1560
+ &:nth-child(1) { left: 0; animation: pendulum-left 0.6s ease-in-out infinite alternate; }
1561
+ &:nth-child(2) { left: 13px; }
1562
+ &:nth-child(3) { left: 26px; }
1563
+ &:nth-child(4) { right: 0; animation: pendulum-right 0.6s ease-in-out infinite alternate; }
1564
+ }
1565
+ }
1566
+
1567
+ @keyframes pendulum-left {
1568
+ 0% { transform: translateX(-15px) translateY(-10px); }
1569
+ 100% { transform: translateX(0) translateY(0); }
1570
+ }
1571
+
1572
+ @keyframes pendulum-right {
1573
+ 0% { transform: translateX(0) translateY(0); }
1574
+ 100% { transform: translateX(15px) translateY(-10px); }
1575
+ }
1576
+
1577
+ // Seesaw Loader
1578
+ .loader--seesaw {
1579
+ width: 50px;
1580
+ height: 20px;
1581
+ position: relative;
1582
+
1583
+ &::before {
1584
+ content: '';
1585
+ position: absolute;
1586
+ bottom: 0;
1587
+ left: 50%;
1588
+ transform: translateX(-50%);
1589
+ border-left: 8px solid transparent;
1590
+ border-right: 8px solid transparent;
1591
+ border-bottom: 10px solid var(--color-border);
1592
+ }
1593
+
1594
+ &::after {
1595
+ content: '';
1596
+ position: absolute;
1597
+ top: 5px;
1598
+ left: 0;
1599
+ right: 0;
1600
+ height: 4px;
1601
+ background: var(--color-primary);
1602
+ border-radius: 2px;
1603
+ transform-origin: center center;
1604
+ animation: seesaw-anim 1s ease-in-out infinite;
1605
+ }
1606
+ }
1607
+
1608
+ @keyframes seesaw-anim {
1609
+ 0%, 100% { transform: rotate(-15deg); }
1610
+ 50% { transform: rotate(15deg); }
1611
+ }
1612
+
1613
+ // Hourglass Sand Loader
1614
+ .loader--sand {
1615
+ width: 30px;
1616
+ height: 40px;
1617
+ border: 3px solid var(--color-border);
1618
+ border-radius: 2px;
1619
+ position: relative;
1620
+ animation: sand-flip 2s ease-in-out infinite;
1621
+
1622
+ &::before {
1623
+ content: '';
1624
+ position: absolute;
1625
+ top: 3px;
1626
+ left: 3px;
1627
+ right: 3px;
1628
+ height: 0;
1629
+ background: var(--color-primary);
1630
+ animation: sand-fill 2s ease-in-out infinite;
1631
+ }
1632
+ }
1633
+
1634
+ @keyframes sand-flip {
1635
+ 0%, 45% { transform: rotate(0deg); }
1636
+ 50%, 95% { transform: rotate(180deg); }
1637
+ 100% { transform: rotate(360deg); }
1638
+ }
1639
+
1640
+ @keyframes sand-fill {
1641
+ 0%, 45% { height: 14px; top: auto; bottom: 3px; }
1642
+ 50%, 95% { height: 14px; top: 3px; bottom: auto; }
1643
+ }
1644
+
1645
+ // Folding Squares Loader
1646
+ .loader--folding {
1647
+ width: 40px;
1648
+ height: 40px;
1649
+ position: relative;
1650
+
1651
+ span {
1652
+ position: absolute;
1653
+ width: 18px;
1654
+ height: 18px;
1655
+ background: var(--color-primary);
1656
+ animation: folding-anim 2s ease infinite;
1657
+
1658
+ &:nth-child(1) { top: 0; left: 0; animation-delay: 0s; }
1659
+ &:nth-child(2) { top: 0; right: 0; animation-delay: 0.5s; }
1660
+ &:nth-child(3) { bottom: 0; right: 0; animation-delay: 1s; }
1661
+ &:nth-child(4) { bottom: 0; left: 0; animation-delay: 1.5s; }
1662
+ }
1663
+ }
1664
+
1665
+ @keyframes folding-anim {
1666
+ 0%, 10% { transform: scale(1); opacity: 1; }
1667
+ 20%, 100% { transform: scale(0); opacity: 0; }
1668
+ }
1669
+
1670
+ // Circle Chase Loader
1671
+ .loader--chase {
1672
+ width: 40px;
1673
+ height: 40px;
1674
+ position: relative;
1675
+ animation: spin-loop 1.5s linear infinite;
1676
+
1677
+ span {
1678
+ position: absolute;
1679
+ width: 8px;
1680
+ height: 8px;
1681
+ background: var(--color-primary);
1682
+ border-radius: 50%;
1683
+
1684
+ &:nth-child(1) { top: 0; left: 50%; transform: translateX(-50%); opacity: 1; }
1685
+ &:nth-child(2) { top: 15%; right: 15%; opacity: 0.85; }
1686
+ &:nth-child(3) { top: 50%; right: 0; transform: translateY(-50%); opacity: 0.7; }
1687
+ &:nth-child(4) { bottom: 15%; right: 15%; opacity: 0.55; }
1688
+ &:nth-child(5) { bottom: 0; left: 50%; transform: translateX(-50%); opacity: 0.4; }
1689
+ &:nth-child(6) { bottom: 15%; left: 15%; opacity: 0.25; }
1690
+ }
1691
+ }
1692
+
1693
+ // Morphing Loader
1694
+ .loader--morph {
1695
+ width: 40px;
1696
+ height: 40px;
1697
+ background: var(--color-primary);
1698
+ animation: morph-anim 2s ease-in-out infinite;
1699
+ }
1700
+
1701
+ @keyframes morph-anim {
1702
+ 0%, 100% { border-radius: 0; transform: rotate(0deg); }
1703
+ 25% { border-radius: 50% 0 50% 0; transform: rotate(90deg); }
1704
+ 50% { border-radius: 50%; transform: rotate(180deg); }
1705
+ 75% { border-radius: 0 50% 0 50%; transform: rotate(270deg); }
1706
+ }
1707
+
1708
+ // Wave Bar Loader
1709
+ .loader--wave-bar {
1710
+ width: 60px;
1711
+ height: 30px;
1712
+ display: flex;
1713
+ gap: 3px;
1714
+ align-items: center;
1715
+
1716
+ span {
1717
+ flex: 1;
1718
+ background: var(--color-primary);
1719
+ border-radius: 2px;
1720
+ animation: wave-bar-anim 1s ease-in-out infinite;
1721
+
1722
+ &:nth-child(1) { animation-delay: 0s; }
1723
+ &:nth-child(2) { animation-delay: 0.1s; }
1724
+ &:nth-child(3) { animation-delay: 0.2s; }
1725
+ &:nth-child(4) { animation-delay: 0.3s; }
1726
+ &:nth-child(5) { animation-delay: 0.4s; }
1727
+ }
1728
+ }
1729
+
1730
+ @keyframes wave-bar-anim {
1731
+ 0%, 100% { height: 10px; }
1732
+ 50% { height: 30px; }
1733
+ }
1734
+
1735
+ // Flip Card Loader
1736
+ .loader--flip-card {
1737
+ width: 40px;
1738
+ height: 40px;
1739
+ perspective: 100px;
1740
+
1741
+ span {
1742
+ width: 100%;
1743
+ height: 100%;
1744
+ display: block;
1745
+ background: var(--color-primary);
1746
+ animation: flip-card-anim 1.2s ease-in-out infinite;
1747
+ }
1748
+ }
1749
+
1750
+ @keyframes flip-card-anim {
1751
+ 0% { transform: rotateX(0) rotateY(0); }
1752
+ 25% { transform: rotateX(180deg) rotateY(0); }
1753
+ 50% { transform: rotateX(180deg) rotateY(180deg); }
1754
+ 75% { transform: rotateX(0) rotateY(180deg); }
1755
+ 100% { transform: rotateX(0) rotateY(360deg); }
1756
+ }
1757
+
1758
+ // -----------------------------------------------------------------------------
1759
+ // Transitions Demo
1760
+ // -----------------------------------------------------------------------------
1761
+
1762
+ .transition-opacity {
1763
+ transition: opacity 0.3s ease;
1764
+ &:hover { opacity: 0.5; }
1765
+ }
1766
+
1767
+ .transition-scale {
1768
+ transition: transform 0.3s ease;
1769
+ &:hover { transform: scale(1.2); }
1770
+ }
1771
+
1772
+ .transition-translate {
1773
+ transition: transform 0.3s ease;
1774
+ &:hover { transform: translateY(-10px); }
1775
+ }
1776
+
1777
+ .transition-rotate {
1778
+ transition: transform 0.3s ease;
1779
+ &:hover { transform: rotate(15deg); }
1780
+ }
1781
+
1782
+ .transition-color {
1783
+ transition: background-color 0.3s ease;
1784
+ &:hover { background-color: #ef4444; }
1785
+ }
1786
+
1787
+ .transition-shadow {
1788
+ transition: box-shadow 0.3s ease;
1789
+ &:hover { box-shadow: 0 10px 30px rgba(59, 130, 246, 0.4); }
1790
+ }
1791
+
1792
+ // Timing demos
1793
+ .timing-linear,
1794
+ .timing-ease,
1795
+ .timing-ease-in,
1796
+ .timing-ease-out,
1797
+ .timing-ease-in-out,
1798
+ .timing-bounce {
1799
+ transition: transform 0.6s;
1800
+
1801
+ &.active {
1802
+ transform: translateX(100px);
1803
+ }
1804
+ }
1805
+
1806
+ .timing-linear { transition-timing-function: linear; }
1807
+ .timing-ease { transition-timing-function: ease; }
1808
+ .timing-ease-in { transition-timing-function: ease-in; }
1809
+ .timing-ease-out { transition-timing-function: ease-out; }
1810
+ .timing-ease-in-out { transition-timing-function: ease-in-out; }
1811
+ .timing-bounce { transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); }
1812
+
1813
+ // -----------------------------------------------------------------------------
1814
+ // Transforms Demo
1815
+ // -----------------------------------------------------------------------------
1816
+
1817
+ .transform-translate-x {
1818
+ transition: transform 0.3s ease;
1819
+ &:hover { transform: translateX(20px); }
1820
+ }
1821
+
1822
+ .transform-translate-y {
1823
+ transition: transform 0.3s ease;
1824
+ &:hover { transform: translateY(-20px); }
1825
+ }
1826
+
1827
+ .transform-scale {
1828
+ transition: transform 0.3s ease;
1829
+ &:hover { transform: scale(1.3); }
1830
+ }
1831
+
1832
+ .transform-rotate {
1833
+ transition: transform 0.3s ease;
1834
+ &:hover { transform: rotate(45deg); }
1835
+ }
1836
+
1837
+ .transform-skew-x {
1838
+ transition: transform 0.3s ease;
1839
+ &:hover { transform: skewX(15deg); }
1840
+ }
1841
+
1842
+ .transform-skew-y {
1843
+ transition: transform 0.3s ease;
1844
+ &:hover { transform: skewY(15deg); }
1845
+ }
1846
+
1847
+ .transform-rotate-x {
1848
+ transition: transform 0.3s ease;
1849
+ &:hover { transform: rotateX(45deg); }
1850
+ }
1851
+
1852
+ .transform-rotate-y {
1853
+ transition: transform 0.3s ease;
1854
+ &:hover { transform: rotateY(45deg); }
1855
+ }
1856
+
1857
+ .transform-rotate-z {
1858
+ transition: transform 0.3s ease;
1859
+ &:hover { transform: rotateZ(45deg); }
1860
+ }
1861
+
1862
+ .transform-combined-1 {
1863
+ transition: transform 0.3s ease;
1864
+ &:hover { transform: scale(1.2) rotate(10deg); }
1865
+ }
1866
+
1867
+ .transform-combined-2 {
1868
+ transition: transform 0.3s ease;
1869
+ &:hover { transform: translateY(-10px) scale(1.1); }
1870
+ }
1871
+
1872
+ .transform-combined-3 {
1873
+ transition: transform 0.3s ease;
1874
+ &:hover { transform: rotateY(30deg) rotateX(15deg) scale(1.1); }
1875
+ }
1876
+
1877
+ // -----------------------------------------------------------------------------
1878
+ // Additional Animation Demos
1879
+ // -----------------------------------------------------------------------------
1880
+
1881
+ // Pulse demos
1882
+ @keyframes pulse-slow-demo {
1883
+ 0%, 100% { transform: scale(1); }
1884
+ 50% { transform: scale(1.05); }
1885
+ }
1886
+
1887
+ @keyframes pulse-fast-demo {
1888
+ 0%, 100% { transform: scale(1); }
1889
+ 50% { transform: scale(1.15); }
1890
+ }
1891
+
1892
+ @keyframes heartbeat-demo {
1893
+ 0%, 100% { transform: scale(1); }
1894
+ 14% { transform: scale(1.3); }
1895
+ 28% { transform: scale(1); }
1896
+ 42% { transform: scale(1.3); }
1897
+ 70% { transform: scale(1); }
1898
+ }
1899
+
1900
+ .animate-pulse-slow-demo { animation: pulse-slow-demo 2s ease-in-out infinite; }
1901
+ .animate-pulse-fast-demo { animation: pulse-fast-demo 0.5s ease-in-out infinite; }
1902
+ .animate-heartbeat-demo { animation: heartbeat-demo 1.5s ease-in-out infinite; }
1903
+
1904
+ // Shake demos
1905
+ @keyframes shake-demo {
1906
+ 0%, 100% { transform: rotate(0); }
1907
+ 10%, 30%, 50%, 70%, 90% { transform: rotate(-10deg); }
1908
+ 20%, 40%, 60%, 80% { transform: rotate(10deg); }
1909
+ }
1910
+
1911
+ @keyframes shake-slow-demo {
1912
+ 0%, 100% { transform: rotate(0); }
1913
+ 25%, 75% { transform: rotate(-5deg); }
1914
+ 50% { transform: rotate(5deg); }
1915
+ }
1916
+
1917
+ @keyframes shake-horizontal-demo {
1918
+ 0%, 100% { transform: translateX(0); }
1919
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
1920
+ 20%, 40%, 60%, 80% { transform: translateX(5px); }
1921
+ }
1922
+
1923
+ @keyframes shake-vertical-demo {
1924
+ 0%, 100% { transform: translateY(0); }
1925
+ 10%, 30%, 50%, 70%, 90% { transform: translateY(-5px); }
1926
+ 20%, 40%, 60%, 80% { transform: translateY(5px); }
1927
+ }
1928
+
1929
+ @keyframes wobble-demo {
1930
+ 0%, 100% { transform: translateX(0) rotate(0); }
1931
+ 15% { transform: translateX(-15px) rotate(-5deg); }
1932
+ 30% { transform: translateX(10px) rotate(3deg); }
1933
+ 45% { transform: translateX(-10px) rotate(-3deg); }
1934
+ 60% { transform: translateX(5px) rotate(2deg); }
1935
+ 75% { transform: translateX(-5px) rotate(-1deg); }
1936
+ }
1937
+
1938
+ @keyframes jiggle-demo {
1939
+ 0%, 100% { transform: scale(1); }
1940
+ 25% { transform: scale(0.9, 1.1); }
1941
+ 50% { transform: scale(1.1, 0.9); }
1942
+ 75% { transform: scale(0.95, 1.05); }
1943
+ }
1944
+
1945
+ @keyframes jello-demo {
1946
+ 0%, 100% { transform: skewX(0) skewY(0); }
1947
+ 22% { transform: skewX(-12.5deg) skewY(-12.5deg); }
1948
+ 33% { transform: skewX(6.25deg) skewY(6.25deg); }
1949
+ 44% { transform: skewX(-3.125deg) skewY(-3.125deg); }
1950
+ 55% { transform: skewX(1.5625deg) skewY(1.5625deg); }
1951
+ 66% { transform: skewX(-0.78deg) skewY(-0.78deg); }
1952
+ 77% { transform: skewX(0.39deg) skewY(0.39deg); }
1953
+ }
1954
+
1955
+ .animate-shake-demo { animation: shake-demo 0.8s ease-in-out infinite; }
1956
+ .animate-shake-slow-demo { animation: shake-slow-demo 1.5s ease-in-out infinite; }
1957
+ .animate-shake-horizontal-demo { animation: shake-horizontal-demo 0.8s ease-in-out infinite; }
1958
+ .animate-shake-vertical-demo { animation: shake-vertical-demo 0.8s ease-in-out infinite; }
1959
+ .animate-wobble-demo { animation: wobble-demo 1s ease-in-out infinite; }
1960
+ .animate-jiggle-demo { animation: jiggle-demo 0.5s ease-in-out infinite; }
1961
+ .animate-jello-demo { animation: jello-demo 1s ease-in-out infinite; }
1962
+
1963
+ // Spin demos
1964
+ @keyframes spin-demo {
1965
+ from { transform: rotate(0deg); }
1966
+ to { transform: rotate(360deg); }
1967
+ }
1968
+
1969
+ @keyframes spin-slow-demo {
1970
+ from { transform: rotate(0deg); }
1971
+ to { transform: rotate(360deg); }
1972
+ }
1973
+
1974
+ @keyframes spin-reverse-demo {
1975
+ from { transform: rotate(360deg); }
1976
+ to { transform: rotate(0deg); }
1977
+ }
1978
+
1979
+ @keyframes rotate-in-demo {
1980
+ from { transform: rotate(-200deg); opacity: 0; }
1981
+ to { transform: rotate(0); opacity: 1; }
1982
+ }
1983
+
1984
+ @keyframes rotate-in-up-demo {
1985
+ from { transform: rotate(45deg) translateY(20px); opacity: 0; }
1986
+ to { transform: rotate(0) translateY(0); opacity: 1; }
1987
+ }
1988
+
1989
+ @keyframes rotate-in-down-demo {
1990
+ from { transform: rotate(-45deg) translateY(-20px); opacity: 0; }
1991
+ to { transform: rotate(0) translateY(0); opacity: 1; }
1992
+ }
1993
+
1994
+ @keyframes roll-in-demo {
1995
+ from { transform: translateX(-100%) rotate(-120deg); opacity: 0; }
1996
+ to { transform: translateX(0) rotate(0); opacity: 1; }
1997
+ }
1998
+
1999
+ @keyframes roll-out-demo {
2000
+ from { transform: translateX(0) rotate(0); opacity: 1; }
2001
+ to { transform: translateX(100%) rotate(120deg); opacity: 0; }
2002
+ }
2003
+
2004
+ .animate-spin-demo { animation: spin-demo 1s linear infinite; }
2005
+ .animate-spin-slow-demo { animation: spin-slow-demo 3s linear infinite; }
2006
+ .animate-spin-reverse-demo { animation: spin-reverse-demo 1s linear infinite; }
2007
+ .animate-rotate-in-demo { animation: rotate-in-demo 0.6s ease-out forwards; }
2008
+ .animate-rotate-in-up-demo { animation: rotate-in-up-demo 0.6s ease-out forwards; }
2009
+ .animate-rotate-in-down-demo { animation: rotate-in-down-demo 0.6s ease-out forwards; }
2010
+ .animate-roll-in-demo { animation: roll-in-demo 0.8s ease-out forwards; }
2011
+ .animate-roll-out-demo { animation: roll-out-demo 0.8s ease-out forwards; animation-delay: 1s; }
2012
+
2013
+ // Attention seekers demos
2014
+ @keyframes flash-demo {
2015
+ 0%, 50%, 100% { opacity: 1; }
2016
+ 25%, 75% { opacity: 0; }
2017
+ }
2018
+
2019
+ @keyframes blink-demo {
2020
+ 0%, 100% { opacity: 1; }
2021
+ 50% { opacity: 0; }
2022
+ }
2023
+
2024
+ @keyframes beat-demo {
2025
+ 0%, 100% { transform: scale(1); }
2026
+ 25% { transform: scale(1.25); }
2027
+ }
2028
+
2029
+ @keyframes beat-fade-demo {
2030
+ 0%, 100% { transform: scale(1); opacity: 1; }
2031
+ 25% { transform: scale(1.25); opacity: 0.5; }
2032
+ }
2033
+
2034
+ @keyframes tada-demo {
2035
+ 0%, 100% { transform: scale(1) rotate(0); }
2036
+ 10%, 20% { transform: scale(0.9) rotate(-3deg); }
2037
+ 30%, 50%, 70%, 90% { transform: scale(1.1) rotate(3deg); }
2038
+ 40%, 60%, 80% { transform: scale(1.1) rotate(-3deg); }
2039
+ }
2040
+
2041
+ @keyframes pop-demo {
2042
+ 0% { transform: scale(0); opacity: 0; }
2043
+ 50% { transform: scale(1.2); }
2044
+ 100% { transform: scale(1); opacity: 1; }
2045
+ }
2046
+
2047
+ @keyframes rubber-demo {
2048
+ 0%, 100% { transform: scale(1, 1); }
2049
+ 30% { transform: scale(1.25, 0.75); }
2050
+ 40% { transform: scale(0.75, 1.25); }
2051
+ 50% { transform: scale(1.15, 0.85); }
2052
+ 65% { transform: scale(0.95, 1.05); }
2053
+ 75% { transform: scale(1.05, 0.95); }
2054
+ }
2055
+
2056
+ @keyframes swing-demo {
2057
+ 20% { transform: rotate(15deg); }
2058
+ 40% { transform: rotate(-10deg); }
2059
+ 60% { transform: rotate(5deg); }
2060
+ 80% { transform: rotate(-5deg); }
2061
+ 100% { transform: rotate(0deg); }
2062
+ }
2063
+
2064
+ @keyframes sway-demo {
2065
+ 0%, 100% { transform: rotate(0deg); }
2066
+ 25% { transform: rotate(3deg); }
2067
+ 75% { transform: rotate(-3deg); }
2068
+ }
2069
+
2070
+ @keyframes nod-demo {
2071
+ 0%, 100% { transform: rotateX(0); }
2072
+ 25% { transform: rotateX(15deg); }
2073
+ 75% { transform: rotateX(-15deg); }
2074
+ }
2075
+
2076
+ .animate-flash-demo { animation: flash-demo 1s infinite; }
2077
+ .animate-blink-demo { animation: blink-demo 1s infinite; }
2078
+ .animate-beat-demo { animation: beat-demo 1s ease-in-out infinite; }
2079
+ .animate-beat-fade-demo { animation: beat-fade-demo 1s ease-in-out infinite; }
2080
+ .animate-tada-demo { animation: tada-demo 1s ease-in-out forwards; }
2081
+ .animate-pop-demo { animation: pop-demo 0.5s ease-out forwards; }
2082
+ .animate-rubber-demo { animation: rubber-demo 1s ease-in-out forwards; }
2083
+ .animate-swing-demo { animation: swing-demo 1s ease-in-out infinite; transform-origin: top center; }
2084
+ .animate-sway-demo { animation: sway-demo 2s ease-in-out infinite; }
2085
+ .animate-nod-demo { animation: nod-demo 1s ease-in-out infinite; }
2086
+
2087
+ // Special effects demos
2088
+ @keyframes elastic-in-demo {
2089
+ 0% { transform: scale(0); opacity: 0; }
2090
+ 55% { transform: scale(1.1); }
2091
+ 75% { transform: scale(0.95); }
2092
+ 100% { transform: scale(1); opacity: 1; }
2093
+ }
2094
+
2095
+ @keyframes elastic-out-demo {
2096
+ 0% { transform: scale(1); opacity: 1; }
2097
+ 25% { transform: scale(1.05); }
2098
+ 45% { transform: scale(0.9); }
2099
+ 100% { transform: scale(0); opacity: 0; }
2100
+ }
2101
+
2102
+ @keyframes lightspeed-in-demo {
2103
+ 0% { transform: translateX(100%) skewX(-30deg); opacity: 0; }
2104
+ 60% { transform: translateX(-10%) skewX(20deg); }
2105
+ 80% { transform: translateX(5%) skewX(-5deg); }
2106
+ 100% { transform: translateX(0) skewX(0); opacity: 1; }
2107
+ }
2108
+
2109
+ @keyframes lightspeed-out-demo {
2110
+ 0% { transform: translateX(0) skewX(0); opacity: 1; }
2111
+ 100% { transform: translateX(100%) skewX(30deg); opacity: 0; }
2112
+ }
2113
+
2114
+ @keyframes hinge-demo {
2115
+ 0% { transform: rotate(0); transform-origin: top left; }
2116
+ 20%, 60% { transform: rotate(80deg); transform-origin: top left; }
2117
+ 40%, 80% { transform: rotate(60deg); transform-origin: top left; }
2118
+ 100% { transform: translateY(100px) rotate(90deg); opacity: 0; }
2119
+ }
2120
+
2121
+ @keyframes float-demo {
2122
+ 0%, 100% { transform: translateY(0); }
2123
+ 50% { transform: translateY(-10px); }
2124
+ }
2125
+
2126
+ @keyframes glow-demo {
2127
+ 0%, 100% { box-shadow: 0 0 5px var(--color-primary); }
2128
+ 50% { box-shadow: 0 0 20px var(--color-primary), 0 0 30px var(--color-primary); }
2129
+ }
2130
+
2131
+ @keyframes ripple-demo {
2132
+ 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
2133
+ 100% { box-shadow: 0 0 0 20px rgba(59, 130, 246, 0); }
2134
+ }
2135
+
2136
+ @keyframes wave-demo {
2137
+ 0%, 100% { transform: translateY(0); }
2138
+ 25% { transform: translateY(-5px) rotate(5deg); }
2139
+ 75% { transform: translateY(5px) rotate(-5deg); }
2140
+ }
2141
+
2142
+ @keyframes twist-demo {
2143
+ 0%, 100% { transform: rotateY(0) rotateX(0); }
2144
+ 25% { transform: rotateY(20deg) rotateX(10deg); }
2145
+ 75% { transform: rotateY(-20deg) rotateX(-10deg); }
2146
+ }
2147
+
2148
+ .animate-elastic-in-demo { animation: elastic-in-demo 0.8s ease-out forwards; }
2149
+ .animate-elastic-out-demo { animation: elastic-out-demo 0.8s ease-in forwards; animation-delay: 1s; }
2150
+ .animate-lightspeed-in-demo { animation: lightspeed-in-demo 0.6s ease-out forwards; }
2151
+ .animate-lightspeed-out-demo { animation: lightspeed-out-demo 0.6s ease-in forwards; animation-delay: 1s; }
2152
+ .animate-hinge-demo { animation: hinge-demo 2s ease-in-out forwards; }
2153
+ .animate-float-demo { animation: float-demo 2s ease-in-out infinite; }
2154
+ .animate-glow-demo { animation: glow-demo 2s ease-in-out infinite; }
2155
+ .animate-ripple-demo { animation: ripple-demo 1.5s ease-out infinite; }
2156
+ .animate-wave-demo { animation: wave-demo 1s ease-in-out infinite; }
2157
+ .animate-twist-demo { animation: twist-demo 1.5s ease-in-out infinite; }
2158
+
2159
+ // Scale demos
2160
+ @keyframes scale-in-demo {
2161
+ from { transform: scale(0); opacity: 0; }
2162
+ to { transform: scale(1); opacity: 1; }
2163
+ }
2164
+
2165
+ @keyframes scale-in-up-demo {
2166
+ from { transform: scale(0.5) translateY(20px); opacity: 0; }
2167
+ to { transform: scale(1) translateY(0); opacity: 1; }
2168
+ }
2169
+
2170
+ @keyframes scale-in-down-demo {
2171
+ from { transform: scale(0.5) translateY(-20px); opacity: 0; }
2172
+ to { transform: scale(1) translateY(0); opacity: 1; }
2173
+ }
2174
+
2175
+ @keyframes scale-in-left-demo {
2176
+ from { transform: scale(0.5) translateX(-20px); opacity: 0; }
2177
+ to { transform: scale(1) translateX(0); opacity: 1; }
2178
+ }
2179
+
2180
+ @keyframes scale-in-right-demo {
2181
+ from { transform: scale(0.5) translateX(20px); opacity: 0; }
2182
+ to { transform: scale(1) translateX(0); opacity: 1; }
2183
+ }
2184
+
2185
+ @keyframes scale-out-demo {
2186
+ from { transform: scale(1); opacity: 1; }
2187
+ to { transform: scale(0); opacity: 0; }
2188
+ }
2189
+
2190
+ @keyframes scale-out-up-demo {
2191
+ from { transform: scale(1) translateY(0); opacity: 1; }
2192
+ to { transform: scale(0.5) translateY(-20px); opacity: 0; }
2193
+ }
2194
+
2195
+ @keyframes scale-out-down-demo {
2196
+ from { transform: scale(1) translateY(0); opacity: 1; }
2197
+ to { transform: scale(0.5) translateY(20px); opacity: 0; }
2198
+ }
2199
+
2200
+ .animate-scale-in-demo { animation: scale-in-demo 0.5s ease-out forwards; }
2201
+ .animate-scale-in-up-demo { animation: scale-in-up-demo 0.5s ease-out forwards; }
2202
+ .animate-scale-in-down-demo { animation: scale-in-down-demo 0.5s ease-out forwards; }
2203
+ .animate-scale-in-left-demo { animation: scale-in-left-demo 0.5s ease-out forwards; }
2204
+ .animate-scale-in-right-demo { animation: scale-in-right-demo 0.5s ease-out forwards; }
2205
+ .animate-scale-out-demo { animation: scale-out-demo 0.5s ease-out forwards; animation-delay: 1s; }
2206
+ .animate-scale-out-up-demo { animation: scale-out-up-demo 0.5s ease-out forwards; animation-delay: 1s; }
2207
+ .animate-scale-out-down-demo { animation: scale-out-down-demo 0.5s ease-out forwards; animation-delay: 1s; }
2208
+
2209
+ // -----------------------------------------------------------------------------
2210
+ // Overview Page Looping Animations
2211
+ // -----------------------------------------------------------------------------
2212
+
2213
+ // Fade loops
2214
+ @keyframes anim-fade-in-loop {
2215
+ 0%, 100% { opacity: 0; }
2216
+ 20%, 80% { opacity: 1; }
2217
+ }
2218
+ @keyframes anim-fade-in-up-loop {
2219
+ 0%, 100% { opacity: 0; transform: translateY(15px); }
2220
+ 20%, 80% { opacity: 1; transform: translateY(0); }
2221
+ }
2222
+ @keyframes anim-fade-in-down-loop {
2223
+ 0%, 100% { opacity: 0; transform: translateY(-15px); }
2224
+ 20%, 80% { opacity: 1; transform: translateY(0); }
2225
+ }
2226
+ @keyframes anim-fade-in-left-loop {
2227
+ 0%, 100% { opacity: 0; transform: translateX(-15px); }
2228
+ 20%, 80% { opacity: 1; transform: translateX(0); }
2229
+ }
2230
+ @keyframes anim-fade-in-right-loop {
2231
+ 0%, 100% { opacity: 0; transform: translateX(15px); }
2232
+ 20%, 80% { opacity: 1; transform: translateX(0); }
2233
+ }
2234
+
2235
+ .anim-fade-in-loop { animation: anim-fade-in-loop 2s ease-in-out infinite; }
2236
+ .anim-fade-in-up-loop { animation: anim-fade-in-up-loop 2s ease-in-out infinite; }
2237
+ .anim-fade-in-down-loop { animation: anim-fade-in-down-loop 2s ease-in-out infinite; }
2238
+ .anim-fade-in-left-loop { animation: anim-fade-in-left-loop 2s ease-in-out infinite; }
2239
+ .anim-fade-in-right-loop { animation: anim-fade-in-right-loop 2s ease-in-out infinite; }
2240
+
2241
+ // Slide loops
2242
+ @keyframes anim-slide-up-loop {
2243
+ 0%, 100% { transform: translateY(20px); opacity: 0; }
2244
+ 20%, 80% { transform: translateY(0); opacity: 1; }
2245
+ }
2246
+ @keyframes anim-slide-down-loop {
2247
+ 0%, 100% { transform: translateY(-20px); opacity: 0; }
2248
+ 20%, 80% { transform: translateY(0); opacity: 1; }
2249
+ }
2250
+ @keyframes anim-slide-left-loop {
2251
+ 0%, 100% { transform: translateX(20px); opacity: 0; }
2252
+ 20%, 80% { transform: translateX(0); opacity: 1; }
2253
+ }
2254
+ @keyframes anim-slide-right-loop {
2255
+ 0%, 100% { transform: translateX(-20px); opacity: 0; }
2256
+ 20%, 80% { transform: translateX(0); opacity: 1; }
2257
+ }
2258
+
2259
+ .anim-slide-up-loop { animation: anim-slide-up-loop 2s ease-in-out infinite; }
2260
+ .anim-slide-down-loop { animation: anim-slide-down-loop 2s ease-in-out infinite; }
2261
+ .anim-slide-left-loop { animation: anim-slide-left-loop 2s ease-in-out infinite; }
2262
+ .anim-slide-right-loop { animation: anim-slide-right-loop 2s ease-in-out infinite; }
2263
+
2264
+ // Bounce loops
2265
+ @keyframes anim-bounce-loop {
2266
+ 0%, 100% { transform: translateY(0); }
2267
+ 50% { transform: translateY(-15px); }
2268
+ }
2269
+ @keyframes anim-bounce-in-loop {
2270
+ 0%, 100% { transform: scale(0.8); opacity: 0.5; }
2271
+ 50% { transform: scale(1.05); opacity: 1; }
2272
+ 70% { transform: scale(1); }
2273
+ }
2274
+ @keyframes anim-bounce-subtle-loop {
2275
+ 0%, 100% { transform: translateY(0); }
2276
+ 50% { transform: translateY(-8px); }
2277
+ }
2278
+
2279
+ .anim-bounce-loop { animation: anim-bounce-loop 1s ease-in-out infinite; }
2280
+ .anim-bounce-in-loop { animation: anim-bounce-in-loop 1.5s ease-in-out infinite; }
2281
+ .anim-bounce-subtle-loop { animation: anim-bounce-subtle-loop 1.5s ease-in-out infinite; }
2282
+
2283
+ // Zoom loops
2284
+ @keyframes anim-zoom-in-loop {
2285
+ 0%, 100% { transform: scale(0.5); opacity: 0; }
2286
+ 20%, 80% { transform: scale(1); opacity: 1; }
2287
+ }
2288
+ @keyframes anim-zoom-in-up-loop {
2289
+ 0%, 100% { transform: scale(0.5) translateY(15px); opacity: 0; }
2290
+ 20%, 80% { transform: scale(1) translateY(0); opacity: 1; }
2291
+ }
2292
+ @keyframes anim-zoom-in-down-loop {
2293
+ 0%, 100% { transform: scale(0.5) translateY(-15px); opacity: 0; }
2294
+ 20%, 80% { transform: scale(1) translateY(0); opacity: 1; }
2295
+ }
2296
+
2297
+ .anim-zoom-in-loop { animation: anim-zoom-in-loop 2s ease-in-out infinite; }
2298
+ .anim-zoom-in-up-loop { animation: anim-zoom-in-up-loop 2s ease-in-out infinite; }
2299
+ .anim-zoom-in-down-loop { animation: anim-zoom-in-down-loop 2s ease-in-out infinite; }
2300
+
2301
+ // Flip loops
2302
+ @keyframes anim-flip-x-loop {
2303
+ 0%, 100% { transform: perspective(400px) rotateX(90deg); opacity: 0; }
2304
+ 20%, 80% { transform: perspective(400px) rotateX(0); opacity: 1; }
2305
+ }
2306
+ @keyframes anim-flip-y-loop {
2307
+ 0%, 100% { transform: perspective(400px) rotateY(90deg); opacity: 0; }
2308
+ 20%, 80% { transform: perspective(400px) rotateY(0); opacity: 1; }
2309
+ }
2310
+ @keyframes anim-flip-loop {
2311
+ from { transform: rotateY(0); }
2312
+ to { transform: rotateY(360deg); }
2313
+ }
2314
+
2315
+ .anim-flip-x-loop { animation: anim-flip-x-loop 2.5s ease-in-out infinite; }
2316
+ .anim-flip-y-loop { animation: anim-flip-y-loop 2.5s ease-in-out infinite; }
2317
+ .anim-flip-loop { animation: anim-flip-loop 2s linear infinite; }
2318
+
2319
+ // Scale loops
2320
+ @keyframes anim-scale-in-loop {
2321
+ 0%, 100% { transform: scale(0); opacity: 0; }
2322
+ 20%, 80% { transform: scale(1); opacity: 1; }
2323
+ }
2324
+ @keyframes anim-scale-up-loop {
2325
+ 0%, 100% { transform: scale(0.8); }
2326
+ 50% { transform: scale(1.1); }
2327
+ }
2328
+ @keyframes anim-scale-down-loop {
2329
+ 0%, 100% { transform: scale(1.1); }
2330
+ 50% { transform: scale(0.9); }
2331
+ }
2332
+
2333
+ .anim-scale-in-loop { animation: anim-scale-in-loop 2s ease-in-out infinite; }
2334
+ .anim-scale-up-loop { animation: anim-scale-up-loop 1.5s ease-in-out infinite; }
2335
+ .anim-scale-down-loop { animation: anim-scale-down-loop 1.5s ease-in-out infinite; }
2336
+
2337
+ // Spin loops
2338
+ @keyframes anim-spin-loop { from { transform: rotate(0); } to { transform: rotate(360deg); } }
2339
+ @keyframes anim-spin-slow-loop { from { transform: rotate(0); } to { transform: rotate(360deg); } }
2340
+ @keyframes anim-spin-reverse-loop { from { transform: rotate(360deg); } to { transform: rotate(0); } }
2341
+ @keyframes anim-rotate-in-loop {
2342
+ 0%, 100% { transform: rotate(-180deg); opacity: 0; }
2343
+ 20%, 80% { transform: rotate(0); opacity: 1; }
2344
+ }
2345
+ @keyframes anim-roll-loop {
2346
+ 0%, 100% { transform: translateX(-30px) rotate(-120deg); opacity: 0; }
2347
+ 20%, 80% { transform: translateX(0) rotate(0); opacity: 1; }
2348
+ }
2349
+
2350
+ .anim-spin-loop { animation: anim-spin-loop 1s linear infinite; }
2351
+ .anim-spin-slow-loop { animation: anim-spin-slow-loop 3s linear infinite; }
2352
+ .anim-spin-reverse-loop { animation: anim-spin-reverse-loop 1s linear infinite; }
2353
+ .anim-rotate-in-loop { animation: anim-rotate-in-loop 2s ease-in-out infinite; }
2354
+ .anim-roll-loop { animation: anim-roll-loop 2s ease-in-out infinite; }
2355
+
2356
+ // Pulse loops
2357
+ @keyframes anim-pulse-loop {
2358
+ 0%, 100% { transform: scale(1); }
2359
+ 50% { transform: scale(1.1); }
2360
+ }
2361
+ @keyframes anim-pulse-slow-loop {
2362
+ 0%, 100% { transform: scale(1); }
2363
+ 50% { transform: scale(1.05); }
2364
+ }
2365
+ @keyframes anim-heartbeat-loop {
2366
+ 0%, 100% { transform: scale(1); }
2367
+ 14% { transform: scale(1.3); }
2368
+ 28% { transform: scale(1); }
2369
+ 42% { transform: scale(1.3); }
2370
+ 70% { transform: scale(1); }
2371
+ }
2372
+ @keyframes anim-beat-loop {
2373
+ 0%, 100% { transform: scale(1); }
2374
+ 25% { transform: scale(1.25); }
2375
+ }
2376
+
2377
+ .anim-pulse-loop { animation: anim-pulse-loop 1s ease-in-out infinite; }
2378
+ .anim-pulse-slow-loop { animation: anim-pulse-slow-loop 2s ease-in-out infinite; }
2379
+ .anim-heartbeat-loop { animation: anim-heartbeat-loop 1.5s ease-in-out infinite; }
2380
+ .anim-beat-loop { animation: anim-beat-loop 1s ease-in-out infinite; }
2381
+
2382
+ // Shake loops
2383
+ @keyframes anim-shake-loop {
2384
+ 0%, 100% { transform: rotate(0); }
2385
+ 10%, 30%, 50%, 70%, 90% { transform: rotate(-10deg); }
2386
+ 20%, 40%, 60%, 80% { transform: rotate(10deg); }
2387
+ }
2388
+ @keyframes anim-shake-horizontal-loop {
2389
+ 0%, 100% { transform: translateX(0); }
2390
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
2391
+ 20%, 40%, 60%, 80% { transform: translateX(5px); }
2392
+ }
2393
+ @keyframes anim-shake-vertical-loop {
2394
+ 0%, 100% { transform: translateY(0); }
2395
+ 10%, 30%, 50%, 70%, 90% { transform: translateY(-5px); }
2396
+ 20%, 40%, 60%, 80% { transform: translateY(5px); }
2397
+ }
2398
+ @keyframes anim-wobble-loop {
2399
+ 0%, 100% { transform: translateX(0) rotate(0); }
2400
+ 15% { transform: translateX(-10px) rotate(-5deg); }
2401
+ 30% { transform: translateX(8px) rotate(3deg); }
2402
+ 45% { transform: translateX(-6px) rotate(-3deg); }
2403
+ 60% { transform: translateX(4px) rotate(2deg); }
2404
+ 75% { transform: translateX(-2px) rotate(-1deg); }
2405
+ }
2406
+ @keyframes anim-jiggle-loop {
2407
+ 0%, 100% { transform: scale(1); }
2408
+ 25% { transform: scale(0.9, 1.1); }
2409
+ 50% { transform: scale(1.1, 0.9); }
2410
+ 75% { transform: scale(0.95, 1.05); }
2411
+ }
2412
+ @keyframes anim-jello-loop {
2413
+ 0%, 100% { transform: skewX(0) skewY(0); }
2414
+ 22% { transform: skewX(-8deg) skewY(-8deg); }
2415
+ 33% { transform: skewX(4deg) skewY(4deg); }
2416
+ 44% { transform: skewX(-2deg) skewY(-2deg); }
2417
+ 55% { transform: skewX(1deg) skewY(1deg); }
2418
+ }
2419
+
2420
+ .anim-shake-loop { animation: anim-shake-loop 0.8s ease-in-out infinite; }
2421
+ .anim-shake-horizontal-loop { animation: anim-shake-horizontal-loop 0.8s ease-in-out infinite; }
2422
+ .anim-shake-vertical-loop { animation: anim-shake-vertical-loop 0.8s ease-in-out infinite; }
2423
+ .anim-wobble-loop { animation: anim-wobble-loop 1s ease-in-out infinite; }
2424
+ .anim-jiggle-loop { animation: anim-jiggle-loop 0.5s ease-in-out infinite; }
2425
+ .anim-jello-loop { animation: anim-jello-loop 1s ease-in-out infinite; }
2426
+
2427
+ // Attention seeker loops
2428
+ @keyframes anim-flash-loop {
2429
+ 0%, 50%, 100% { opacity: 1; }
2430
+ 25%, 75% { opacity: 0; }
2431
+ }
2432
+ @keyframes anim-blink-loop {
2433
+ 0%, 100% { opacity: 1; }
2434
+ 50% { opacity: 0; }
2435
+ }
2436
+ @keyframes anim-tada-loop {
2437
+ 0%, 100% { transform: scale(1) rotate(0); }
2438
+ 10%, 20% { transform: scale(0.9) rotate(-3deg); }
2439
+ 30%, 50%, 70%, 90% { transform: scale(1.1) rotate(3deg); }
2440
+ 40%, 60%, 80% { transform: scale(1.1) rotate(-3deg); }
2441
+ }
2442
+ @keyframes anim-pop-loop {
2443
+ 0%, 100% { transform: scale(0.8); opacity: 0.5; }
2444
+ 50% { transform: scale(1.1); opacity: 1; }
2445
+ 70% { transform: scale(1); }
2446
+ }
2447
+ @keyframes anim-rubber-loop {
2448
+ 0%, 100% { transform: scale(1, 1); }
2449
+ 30% { transform: scale(1.25, 0.75); }
2450
+ 40% { transform: scale(0.75, 1.25); }
2451
+ 50% { transform: scale(1.15, 0.85); }
2452
+ 65% { transform: scale(0.95, 1.05); }
2453
+ 75% { transform: scale(1.05, 0.95); }
2454
+ }
2455
+
2456
+ .anim-flash-loop { animation: anim-flash-loop 1s infinite; }
2457
+ .anim-blink-loop { animation: anim-blink-loop 1s infinite; }
2458
+ .anim-tada-loop { animation: anim-tada-loop 1.5s ease-in-out infinite; }
2459
+ .anim-pop-loop { animation: anim-pop-loop 1.5s ease-in-out infinite; }
2460
+ .anim-rubber-loop { animation: anim-rubber-loop 1.2s ease-in-out infinite; }
2461
+
2462
+ // Swing loops
2463
+ @keyframes anim-swing-loop {
2464
+ 20% { transform: rotate(15deg); }
2465
+ 40% { transform: rotate(-10deg); }
2466
+ 60% { transform: rotate(5deg); }
2467
+ 80% { transform: rotate(-5deg); }
2468
+ 100% { transform: rotate(0deg); }
2469
+ }
2470
+ @keyframes anim-sway-loop {
2471
+ 0%, 100% { transform: rotate(0deg); }
2472
+ 25% { transform: rotate(3deg); }
2473
+ 75% { transform: rotate(-3deg); }
2474
+ }
2475
+ @keyframes anim-nod-loop {
2476
+ 0%, 100% { transform: rotateX(0); }
2477
+ 25% { transform: rotateX(15deg); }
2478
+ 75% { transform: rotateX(-15deg); }
2479
+ }
2480
+
2481
+ .anim-swing-loop { animation: anim-swing-loop 1s ease-in-out infinite; transform-origin: top center; }
2482
+ .anim-sway-loop { animation: anim-sway-loop 2s ease-in-out infinite; }
2483
+ .anim-nod-loop { animation: anim-nod-loop 1.5s ease-in-out infinite; }
2484
+
2485
+ // Float and glow loops
2486
+ @keyframes anim-float-loop {
2487
+ 0%, 100% { transform: translateY(0); }
2488
+ 50% { transform: translateY(-10px); }
2489
+ }
2490
+ @keyframes anim-glow-loop {
2491
+ 0%, 100% { box-shadow: 0 0 5px var(--color-primary); }
2492
+ 50% { box-shadow: 0 0 20px var(--color-primary), 0 0 30px var(--color-primary); }
2493
+ }
2494
+ @keyframes anim-ripple-loop {
2495
+ 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
2496
+ 100% { box-shadow: 0 0 0 15px rgba(59, 130, 246, 0); }
2497
+ }
2498
+
2499
+ .anim-float-loop { animation: anim-float-loop 2s ease-in-out infinite; }
2500
+ .anim-glow-loop { animation: anim-glow-loop 2s ease-in-out infinite; }
2501
+ .anim-ripple-loop { animation: anim-ripple-loop 1.5s ease-out infinite; }
2502
+
2503
+ // Special effects loops
2504
+ @keyframes anim-elastic-loop {
2505
+ 0%, 100% { transform: scale(0.8); opacity: 0.5; }
2506
+ 40% { transform: scale(1.1); }
2507
+ 60% { transform: scale(0.95); }
2508
+ 80% { transform: scale(1); opacity: 1; }
2509
+ }
2510
+ @keyframes anim-lightspeed-loop {
2511
+ 0%, 100% { transform: translateX(50px) skewX(-20deg); opacity: 0; }
2512
+ 20%, 80% { transform: translateX(0) skewX(0); opacity: 1; }
2513
+ }
2514
+ @keyframes anim-hinge-loop {
2515
+ 0%, 100% { transform: rotate(0); opacity: 1; }
2516
+ 20%, 60% { transform: rotate(20deg); transform-origin: top left; }
2517
+ 40%, 80% { transform: rotate(10deg); transform-origin: top left; }
2518
+ }
2519
+ @keyframes anim-wave-loop {
2520
+ 0%, 100% { transform: translateY(0); }
2521
+ 25% { transform: translateY(-5px) rotate(3deg); }
2522
+ 75% { transform: translateY(5px) rotate(-3deg); }
2523
+ }
2524
+ @keyframes anim-twist-loop {
2525
+ 0%, 100% { transform: rotateY(0) rotateX(0); }
2526
+ 25% { transform: rotateY(15deg) rotateX(10deg); }
2527
+ 75% { transform: rotateY(-15deg) rotateX(-10deg); }
2528
+ }
2529
+
2530
+ .anim-elastic-loop { animation: anim-elastic-loop 1.5s ease-in-out infinite; }
2531
+ .anim-lightspeed-loop { animation: anim-lightspeed-loop 2s ease-in-out infinite; }
2532
+ .anim-hinge-loop { animation: anim-hinge-loop 2s ease-in-out infinite; }
2533
+ .anim-wave-loop { animation: anim-wave-loop 1s ease-in-out infinite; }
2534
+ .anim-twist-loop { animation: anim-twist-loop 1.5s ease-in-out infinite; }
2535
+
2536
+ // -----------------------------------------------------------------------------
2537
+ // Effects Demo
2538
+ // -----------------------------------------------------------------------------
2539
+
2540
+ .effect-demo {
2541
+ .effect-box {
2542
+ width: 120px;
2543
+ height: 80px;
2544
+ background: #f8fafc;
2545
+ border-radius: 8px;
2546
+ display: flex;
2547
+ align-items: center;
2548
+ justify-content: center;
2549
+ overflow: hidden;
2550
+ font-size: 0.875rem;
2551
+ font-weight: 500;
2552
+ color: #1e293b;
2553
+ border: 1px solid rgba(0, 0, 0, 0.1);
2554
+
2555
+ img {
2556
+ width: 100%;
2557
+ height: 100%;
2558
+ object-fit: cover;
2559
+ }
2560
+ }
2561
+
2562
+ .color-block {
2563
+ width: 100%;
2564
+ height: 100%;
2565
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
2566
+ }
2567
+ }
2568
+
2569
+ // Original (no filter) - for comparison
2570
+ .effect--original img {
2571
+ filter: none;
2572
+ border: 2px solid #10b981;
2573
+ }
2574
+
2575
+ // Basic Filter Effects
2576
+ .effect--blur img { filter: blur(3px); }
2577
+ .effect--blur-light img { filter: blur(1px); }
2578
+ .effect--blur-heavy img { filter: blur(6px); }
2579
+ .effect--grayscale img { filter: grayscale(100%); }
2580
+ .effect--grayscale-50 img { filter: grayscale(50%); }
2581
+ .effect--brightness img { filter: brightness(150%); }
2582
+ .effect--brightness-low img { filter: brightness(50%); }
2583
+ .effect--contrast img { filter: contrast(150%); }
2584
+ .effect--sepia img { filter: sepia(100%); }
2585
+ .effect--invert img { filter: invert(100%); }
2586
+ .effect--hue-rotate img { filter: hue-rotate(90deg); }
2587
+ .effect--hue-rotate-180 img { filter: hue-rotate(180deg); }
2588
+ .effect--saturate img { filter: saturate(200%); }
2589
+ .effect--desaturate img { filter: saturate(25%); }
2590
+ .effect--drop-shadow img { filter: drop-shadow(4px 4px 6px rgba(0, 0, 0, 0.4)); }
2591
+
2592
+ // Filter Presets - Combined filters
2593
+ .effect--vintage img { filter: sepia(60%) brightness(90%) contrast(110%); }
2594
+ .effect--dramatic img { filter: contrast(150%) brightness(80%) saturate(120%); }
2595
+ .effect--cold img { filter: hue-rotate(180deg) saturate(80%) brightness(110%); }
2596
+ .effect--warm img { filter: sepia(30%) brightness(110%) saturate(130%); }
2597
+ .effect--faded img { filter: saturate(70%) contrast(85%) brightness(110%); }
2598
+ .effect--vivid img { filter: saturate(180%) contrast(120%) brightness(105%); }
2599
+ .effect--noir img { filter: grayscale(100%) contrast(130%) brightness(90%); }
2600
+ .effect--dreamy img { filter: blur(1px) brightness(110%) saturate(120%); }
2601
+ .effect--xray img { filter: invert(100%) grayscale(100%) brightness(120%); }
2602
+
2603
+ // Duotone Effects
2604
+ .effect--duotone-blue img { filter: grayscale(100%) sepia(100%) hue-rotate(180deg) saturate(200%); }
2605
+ .effect--duotone-purple img { filter: grayscale(100%) sepia(100%) hue-rotate(230deg) saturate(300%); }
2606
+ .effect--duotone-orange img { filter: grayscale(100%) sepia(100%) hue-rotate(330deg) saturate(200%); }
2607
+
2608
+ // Interactive filters
2609
+ .effect--hover-blur img { transition: filter 0.3s ease; }
2610
+ .effect--hover-blur:hover img { filter: blur(4px); }
2611
+ .effect--hover-grayscale img { filter: grayscale(100%); transition: filter 0.3s ease; }
2612
+ .effect--hover-grayscale:hover img { filter: grayscale(0%); }
2613
+ .effect--hover-saturate img { transition: filter 0.3s ease; }
2614
+ .effect--hover-saturate:hover img { filter: saturate(200%); }
2615
+ .effect--hover-brightness img { transition: filter 0.3s ease; }
2616
+ .effect--hover-brightness:hover img { filter: brightness(130%); }
2617
+
2618
+ // Opacity Effects
2619
+ .opacity--100 .color-block { opacity: 1; }
2620
+ .opacity--75 .color-block { opacity: 0.75; }
2621
+ .opacity--50 .color-block { opacity: 0.5; }
2622
+ .opacity--25 .color-block { opacity: 0.25; }
2623
+
2624
+ // Shadow Effects
2625
+ .shadow--light { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); }
2626
+ .shadow--medium { box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15); }
2627
+ .shadow--dark { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); }
2628
+ .shadow--large { box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); }
2629
+ .shadow--soft { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); }
2630
+ .shadow--inset { box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2); }
2631
+ .shadow--colored { box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4); }
2632
+ .shadow--intense { box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35); }
2633
+
2634
+ // Directional Shadows
2635
+ .shadow--top { box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.15); }
2636
+ .shadow--right { box-shadow: 4px 0 8px rgba(0, 0, 0, 0.15); }
2637
+ .shadow--bottom { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); }
2638
+ .shadow--left { box-shadow: -4px 0 8px rgba(0, 0, 0, 0.15); }
2639
+
2640
+ // Elevation Levels
2641
+ .elevation--1 { box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.12), 0px 1px 2px rgba(0, 0, 0, 0.24); }
2642
+ .elevation--2 { box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16), 0px 3px 6px rgba(0, 0, 0, 0.23); }
2643
+ .elevation--3 { box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.19), 0px 6px 6px rgba(0, 0, 0, 0.23); }
2644
+ .elevation--4 { box-shadow: 0px 14px 28px rgba(0, 0, 0, 0.25), 0px 10px 10px rgba(0, 0, 0, 0.22); }
2645
+ .elevation--5 { box-shadow: 0px 19px 38px rgba(0, 0, 0, 0.30), 0px 15px 12px rgba(0, 0, 0, 0.22); }
2646
+
2647
+ // Embossed Effects
2648
+ .embossed--light {
2649
+ border: 1px solid rgba(0, 0, 0, 0.1);
2650
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
2651
+ }
2652
+ .embossed--heavy {
2653
+ border: 1px solid rgba(0, 0, 0, 0.1);
2654
+ box-shadow: inset 0 2px 3px rgba(255, 255, 255, 0.3), inset 0 -2px 3px rgba(0, 0, 0, 0.3), 0 1px 1px rgba(255, 255, 255, 0.9);
2655
+ }
2656
+ .shadow--emphasize-dark { box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.35); }
2657
+ .shadow--border { box-shadow: inset 0 0 0 3px rgba(59, 130, 246, 0.5); }
2658
+
2659
+ // Backdrop Blur
2660
+ .backdrop-container {
2661
+ position: relative;
2662
+
2663
+ .backdrop-bg {
2664
+ position: absolute;
2665
+ inset: 0;
2666
+ background: linear-gradient(135deg, #f472b6 0%, #8b5cf6 50%, #3b82f6 100%);
2667
+ border-radius: 8px;
2668
+ }
2669
+
2670
+ .backdrop--blur {
2671
+ position: relative;
2672
+ backdrop-filter: blur(8px);
2673
+ -webkit-backdrop-filter: blur(8px);
2674
+ background: rgba(255, 255, 255, 0.2);
2675
+ }
2676
+ }
2677
+
2678
+ // -----------------------------------------------------------------------------
2679
+ // Keyframes Demo
2680
+ // -----------------------------------------------------------------------------
2681
+
2682
+ .keyframe-box {
2683
+ width: 80px;
2684
+ height: 80px;
2685
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
2686
+ border-radius: 8px;
2687
+ display: flex;
2688
+ align-items: center;
2689
+ justify-content: center;
2690
+ font-size: 1.5rem;
2691
+ color: white;
2692
+ font-weight: 600;
2693
+ }
2694
+
2695
+ // Beat Animations
2696
+ @keyframes beat {
2697
+ 0%, 90% { transform: scale(1); }
2698
+ 45% { transform: scale(1.25); }
2699
+ }
2700
+ @keyframes beat-fade {
2701
+ 0%, 100% { opacity: 0.5; transform: scale(1); }
2702
+ 50% { opacity: 1; transform: scale(1.125); }
2703
+ }
2704
+ @keyframes beat-double {
2705
+ 0%, 100% { transform: scale(1); }
2706
+ 25% { transform: scale(1.1); }
2707
+ 50% { transform: scale(1.2); }
2708
+ 75% { transform: scale(1.1); }
2709
+ }
2710
+
2711
+ .keyframe--beat { animation: beat 1s ease-in-out infinite; }
2712
+ .keyframe--beat-fade { animation: beat-fade 1.5s ease infinite; }
2713
+ .keyframe--beat-double { animation: beat-double 1s ease infinite; }
2714
+
2715
+ // Flash Animations
2716
+ @keyframes flash {
2717
+ 0%, 50%, 100% { opacity: 1; }
2718
+ 25%, 75% { opacity: 0; }
2719
+ }
2720
+ .keyframe--flash { animation: flash 1s ease infinite; }
2721
+ .keyframe--flash-slow { animation: flash 2s ease infinite; }
2722
+ .keyframe--flash-fast { animation: flash 0.5s ease infinite; }
2723
+
2724
+ // Pulse Variations
2725
+ @keyframes pulse-soft {
2726
+ 0%, 100% { transform: scale(1); opacity: 1; }
2727
+ 50% { transform: scale(1.05); opacity: 0.9; }
2728
+ }
2729
+ @keyframes pulse-strong {
2730
+ 0%, 100% { transform: scale(1); }
2731
+ 50% { transform: scale(1.15); }
2732
+ }
2733
+ .keyframe--pulse { animation: pulse 1.5s ease infinite; }
2734
+ .keyframe--pulse-soft { animation: pulse-soft 2s ease infinite; }
2735
+ .keyframe--pulse-strong { animation: pulse-strong 1s ease infinite; }
2736
+
2737
+ // Scale Keyframes
2738
+ @keyframes scale-up {
2739
+ 0%, 100% { transform: scale(1); }
2740
+ 50% { transform: scale(1.2); }
2741
+ }
2742
+ @keyframes scale-down {
2743
+ 0%, 100% { transform: scale(1); }
2744
+ 50% { transform: scale(0.8); }
2745
+ }
2746
+ @keyframes scale-bounce {
2747
+ 0%, 100% { transform: scale(1); }
2748
+ 30% { transform: scale(1.25); }
2749
+ 50% { transform: scale(0.9); }
2750
+ 70% { transform: scale(1.1); }
2751
+ }
2752
+ .keyframe--scale-up { animation: scale-up 1s ease infinite; }
2753
+ .keyframe--scale-down { animation: scale-down 1s ease infinite; }
2754
+ .keyframe--scale-bounce { animation: scale-bounce 1s ease infinite; }
2755
+
2756
+ // Rotation Keyframes
2757
+ @keyframes rotate-reverse {
2758
+ from { transform: rotate(0deg); }
2759
+ to { transform: rotate(-360deg); }
2760
+ }
2761
+ @keyframes rotate-90 {
2762
+ 0%, 100% { transform: rotate(0deg); }
2763
+ 50% { transform: rotate(90deg); }
2764
+ }
2765
+ @keyframes wobble-anim {
2766
+ 0%, 100% { transform: rotate(0deg); }
2767
+ 25% { transform: rotate(-15deg); }
2768
+ 75% { transform: rotate(15deg); }
2769
+ }
2770
+ .keyframe--rotate { animation: rotate 2s linear infinite; }
2771
+ .keyframe--rotate-reverse { animation: rotate-reverse 2s linear infinite; }
2772
+ .keyframe--rotate-90 { animation: rotate-90 1s ease infinite; }
2773
+ .keyframe--wobble { animation: wobble-anim 0.5s ease-in-out infinite; }
2774
+
2775
+ // Translate Keyframes
2776
+ @keyframes slide-x {
2777
+ 0%, 100% { transform: translateX(0); }
2778
+ 50% { transform: translateX(15px); }
2779
+ }
2780
+ @keyframes slide-y {
2781
+ 0%, 100% { transform: translateY(0); }
2782
+ 50% { transform: translateY(15px); }
2783
+ }
2784
+ @keyframes float-anim {
2785
+ 0%, 100% { transform: translateY(0); }
2786
+ 50% { transform: translateY(-10px); }
2787
+ }
2788
+ @keyframes bounce-y {
2789
+ 0%, 100% { transform: translateY(0); }
2790
+ 50% { transform: translateY(-20px); }
2791
+ }
2792
+ .keyframe--slide-x { animation: slide-x 1s ease infinite; }
2793
+ .keyframe--slide-y { animation: slide-y 1s ease infinite; }
2794
+ .keyframe--float { animation: float-anim 2s ease infinite; }
2795
+ .keyframe--bounce-y { animation: bounce-y 0.6s ease infinite; }
2796
+
2797
+ // Fade Keyframes
2798
+ @keyframes fade-kf {
2799
+ 0%, 100% { opacity: 1; }
2800
+ 50% { opacity: 0.3; }
2801
+ }
2802
+ @keyframes fade-in-out {
2803
+ 0%, 100% { opacity: 0; }
2804
+ 50% { opacity: 1; }
2805
+ }
2806
+ @keyframes blink {
2807
+ 0%, 100% { opacity: 1; }
2808
+ 50% { opacity: 0; }
2809
+ }
2810
+ .keyframe--fade { animation: fade-kf 1.5s ease infinite; }
2811
+ .keyframe--fade-in-out { animation: fade-in-out 2s ease infinite; }
2812
+ .keyframe--blink { animation: blink 1s step-end infinite; }
2813
+
2814
+ // Skew Keyframes
2815
+ @keyframes skew-x {
2816
+ 0%, 100% { transform: skewX(0deg); }
2817
+ 50% { transform: skewX(15deg); }
2818
+ }
2819
+ @keyframes skew-y {
2820
+ 0%, 100% { transform: skewY(0deg); }
2821
+ 50% { transform: skewY(10deg); }
2822
+ }
2823
+ @keyframes jello {
2824
+ 0%, 100% { transform: scale3d(1, 1, 1); }
2825
+ 30% { transform: scale3d(1.25, 0.75, 1); }
2826
+ 40% { transform: scale3d(0.75, 1.25, 1); }
2827
+ 50% { transform: scale3d(1.15, 0.85, 1); }
2828
+ 65% { transform: scale3d(0.95, 1.05, 1); }
2829
+ 75% { transform: scale3d(1.05, 0.95, 1); }
2830
+ }
2831
+ .keyframe--skew-x { animation: skew-x 1s ease infinite; }
2832
+ .keyframe--skew-y { animation: skew-y 1s ease infinite; }
2833
+ .keyframe--jello { animation: jello 1s ease infinite; }
2834
+
2835
+ // 3D Keyframes
2836
+ @keyframes flip-x-kf {
2837
+ 0% { transform: perspective(400px) rotateX(0); }
2838
+ 100% { transform: perspective(400px) rotateX(360deg); }
2839
+ }
2840
+ @keyframes flip-y-kf {
2841
+ 0% { transform: perspective(400px) rotateY(0); }
2842
+ 100% { transform: perspective(400px) rotateY(360deg); }
2843
+ }
2844
+ @keyframes swing-kf {
2845
+ 20% { transform: rotate3d(0, 0, 1, 15deg); }
2846
+ 40% { transform: rotate3d(0, 0, 1, -10deg); }
2847
+ 60% { transform: rotate3d(0, 0, 1, 5deg); }
2848
+ 80% { transform: rotate3d(0, 0, 1, -5deg); }
2849
+ 100% { transform: rotate3d(0, 0, 1, 0deg); }
2850
+ }
2851
+ @keyframes tada-kf {
2852
+ 0%, 100% { transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 0deg); }
2853
+ 10%, 20% { transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); }
2854
+ 30%, 50%, 70%, 90% { transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); }
2855
+ 40%, 60%, 80% { transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); }
2856
+ }
2857
+ .keyframe--flip-x { animation: flip-x-kf 2s ease infinite; }
2858
+ .keyframe--flip-y { animation: flip-y-kf 2s ease infinite; }
2859
+ .keyframe--swing { animation: swing-kf 1s ease infinite; transform-origin: top center; }
2860
+ .keyframe--tada { animation: tada-kf 1s ease infinite; }
2861
+
2862
+ // Custom Keyframes
2863
+ @keyframes custom-bounce-kf {
2864
+ 0%, 100% { transform: translateY(0) scaleY(1); }
2865
+ 30% { transform: translateY(-30px) scaleY(1.1); }
2866
+ 50% { transform: translateY(0) scaleY(0.9); }
2867
+ 70% { transform: translateY(-15px) scaleY(1.05); }
2868
+ }
2869
+ @keyframes custom-shake-kf {
2870
+ 0%, 100% { transform: translateX(0); }
2871
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
2872
+ 20%, 40%, 60%, 80% { transform: translateX(5px); }
2873
+ }
2874
+ @keyframes custom-rubber {
2875
+ 0% { transform: scale3d(1, 1, 1); }
2876
+ 30% { transform: scale3d(1.25, 0.75, 1); }
2877
+ 40% { transform: scale3d(0.75, 1.25, 1); }
2878
+ 50% { transform: scale3d(1.15, 0.85, 1); }
2879
+ 65% { transform: scale3d(0.95, 1.05, 1); }
2880
+ 75% { transform: scale3d(1.05, 0.95, 1); }
2881
+ 100% { transform: scale3d(1, 1, 1); }
2882
+ }
2883
+ .keyframe--custom-bounce { animation: custom-bounce-kf 1s ease infinite; }
2884
+ .keyframe--custom-shake { animation: custom-shake-kf 0.8s ease infinite; }
2885
+ .keyframe--custom-rubber { animation: custom-rubber 1s ease infinite; }
2886
+
2887
+ // -----------------------------------------------------------------------------
2888
+ // Mouse Demo
2889
+ // -----------------------------------------------------------------------------
2890
+
2891
+ .mouse-box {
2892
+ width: 100%;
2893
+ min-width: 100px;
2894
+ height: 80px;
2895
+ background: #f8fafc;
2896
+ border: 1px solid rgba(0, 0, 0, 0.1);
2897
+ border-radius: 8px;
2898
+ display: flex;
2899
+ align-items: center;
2900
+ justify-content: center;
2901
+ font-size: 0.875rem;
2902
+ font-weight: 500;
2903
+ color: #1e293b;
2904
+ transition: all 0.3s ease;
2905
+ }
2906
+
2907
+ button.mouse-box {
2908
+ appearance: none;
2909
+ font-family: inherit;
2910
+ }
2911
+
2912
+ // Cursor Styles
2913
+ .cursor--default { cursor: default; }
2914
+ .cursor--pointer { cursor: pointer; }
2915
+ .cursor--text { cursor: text; }
2916
+ .cursor--move { cursor: move; }
2917
+ .cursor--grab { cursor: grab; }
2918
+ .cursor--grabbing { cursor: grabbing; }
2919
+ .cursor--not-allowed { cursor: not-allowed; background: #fee2e2; }
2920
+ .cursor--wait { cursor: wait; }
2921
+ .cursor--help { cursor: help; }
2922
+ .cursor--crosshair { cursor: crosshair; }
2923
+ .cursor--zoom-in { cursor: zoom-in; }
2924
+ .cursor--zoom-out { cursor: zoom-out; }
2925
+
2926
+ // Resize Cursors
2927
+ .cursor--n-resize { cursor: n-resize; }
2928
+ .cursor--e-resize { cursor: e-resize; }
2929
+ .cursor--s-resize { cursor: s-resize; }
2930
+ .cursor--w-resize { cursor: w-resize; }
2931
+ .cursor--ne-resize { cursor: ne-resize; }
2932
+ .cursor--se-resize { cursor: se-resize; }
2933
+ .cursor--sw-resize { cursor: sw-resize; }
2934
+ .cursor--nw-resize { cursor: nw-resize; }
2935
+ .cursor--ew-resize { cursor: ew-resize; }
2936
+ .cursor--ns-resize { cursor: ns-resize; }
2937
+ .cursor--col-resize { cursor: col-resize; }
2938
+ .cursor--row-resize { cursor: row-resize; }
2939
+
2940
+ // Hover Effects
2941
+ .hover--scale {
2942
+ cursor: pointer;
2943
+ &:hover { transform: scale(1.1); }
2944
+ }
2945
+ .hover--lift {
2946
+ cursor: pointer;
2947
+ &:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15); }
2948
+ }
2949
+ .hover--glow {
2950
+ cursor: pointer;
2951
+ &:hover { box-shadow: 0 0 20px rgba(59, 130, 246, 0.5); }
2952
+ }
2953
+ .hover--shadow {
2954
+ cursor: pointer;
2955
+ &:hover { box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2); }
2956
+ }
2957
+ .hover--brighten {
2958
+ cursor: pointer;
2959
+ &:hover { background: #e0f2fe; }
2960
+ }
2961
+ .hover--darken {
2962
+ cursor: pointer;
2963
+ &:hover { background: #cbd5e1; }
2964
+ }
2965
+ .hover--rotate {
2966
+ cursor: pointer;
2967
+ &:hover { transform: rotate(5deg); }
2968
+ }
2969
+ @keyframes shake-hover {
2970
+ 0%, 100% { transform: translateX(0); }
2971
+ 25% { transform: translateX(-3px); }
2972
+ 75% { transform: translateX(3px); }
2973
+ }
2974
+ .hover--shake {
2975
+ cursor: pointer;
2976
+ &:hover { animation: shake-hover 0.3s ease infinite; }
2977
+ }
2978
+
2979
+ // Pointer Events
2980
+ .pointer--auto { pointer-events: auto; }
2981
+ .pointer--none {
2982
+ pointer-events: none;
2983
+ opacity: 0.5;
2984
+ &::after {
2985
+ content: ' (click passes through)';
2986
+ font-size: 0.7rem;
2987
+ }
2988
+ }
2989
+
2990
+ // Text Selection
2991
+ .selection--default { user-select: auto; }
2992
+ .selection--none { user-select: none; }
2993
+ .selection--all { user-select: all; }
2994
+ .selection--custom {
2995
+ &::selection {
2996
+ background-color: #8b5cf6;
2997
+ color: white;
2998
+ }
2999
+ }
3000
+
3001
+ // Scroll Containers
3002
+ .scroll-demo {
3003
+ .scroll-container {
3004
+ width: 100%;
3005
+ height: 120px;
3006
+ overflow-y: auto;
3007
+ background: #f8fafc;
3008
+ border: 1px solid rgba(0, 0, 0, 0.1);
3009
+ border-radius: 8px;
3010
+ padding: 12px;
3011
+ }
3012
+
3013
+ .scroll-content p {
3014
+ margin: 0 0 24px 0;
3015
+ color: #64748b;
3016
+ }
3017
+ }
3018
+
3019
+ .scroll--smooth {
3020
+ scroll-behavior: smooth;
3021
+ -webkit-overflow-scrolling: touch;
3022
+ }
3023
+
3024
+ .scroll--snap {
3025
+ scroll-snap-type: y mandatory;
3026
+
3027
+ .scroll-snap-item {
3028
+ height: 100%;
3029
+ display: flex;
3030
+ align-items: center;
3031
+ justify-content: center;
3032
+ scroll-snap-align: start;
3033
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
3034
+ color: white;
3035
+ font-weight: 600;
3036
+ border-radius: 4px;
3037
+ margin-bottom: 8px;
3038
+
3039
+ &:last-child { margin-bottom: 0; }
3040
+ }
3041
+ }
3042
+
3043
+ // Custom Scrollbar
3044
+ .scrollbar--custom {
3045
+ &::-webkit-scrollbar {
3046
+ width: 8px;
3047
+ }
3048
+ &::-webkit-scrollbar-track {
3049
+ background: #e2e8f0;
3050
+ border-radius: 4px;
3051
+ }
3052
+ &::-webkit-scrollbar-thumb {
3053
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
3054
+ border-radius: 4px;
3055
+ }
3056
+ }
3057
+
3058
+ .scrollbar--hidden {
3059
+ scrollbar-width: none;
3060
+ -ms-overflow-style: none;
3061
+ &::-webkit-scrollbar {
3062
+ display: none;
3063
+ }
3064
+ }
3065
+
3066
+ // Touch Interactions
3067
+ .touch--target {
3068
+ min-width: 44px;
3069
+ min-height: 44px;
3070
+ font-size: 0.75rem;
3071
+ }
3072
+
3073
+ .touch--feedback {
3074
+ cursor: pointer;
3075
+ &:active {
3076
+ transform: scale(0.95);
3077
+ background: #e0f2fe;
3078
+ }
3079
+ }
3080
+
3081
+ .touch--scroll {
3082
+ -webkit-overflow-scrolling: touch;
3083
+ overflow-y: auto;
3084
+ }
3085
+
3086
+ // Focus States
3087
+ .focus--default:focus {
3088
+ outline: 2px solid #3b82f6;
3089
+ outline-offset: 2px;
3090
+ }
3091
+
3092
+ .focus--ring:focus {
3093
+ outline: none;
3094
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
3095
+ }
3096
+
3097
+ .focus--glow:focus {
3098
+ outline: none;
3099
+ box-shadow: 0 0 15px rgba(59, 130, 246, 0.6);
3100
+ }
3101
+
3102
+ .focus--outline:focus {
3103
+ outline: 3px dashed #8b5cf6;
3104
+ outline-offset: 3px;
3105
+ }
3106
+
3107
+ // -----------------------------------------------------------------------------
3108
+ // Responsive
3109
+ // -----------------------------------------------------------------------------
3110
+
3111
+ @media (max-width: 768px) {
3112
+ h1 {
3113
+ font-size: 2rem;
3114
+ }
3115
+
3116
+ .lead {
3117
+ font-size: 1rem;
3118
+ }
3119
+
3120
+ .hero-actions {
3121
+ flex-direction: column;
3122
+ align-items: center;
3123
+ }
3124
+
3125
+ .footer__content {
3126
+ flex-direction: column;
3127
+ text-align: center;
3128
+ }
3129
+
3130
+ .footer__right {
3131
+ flex-direction: column;
3132
+ }
3133
+ }