snow-flow 3.4.35 → 3.4.39

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 (50) hide show
  1. package/README.md +412 -287
  2. package/dist/cli/deploy-artifact.js +2 -2
  3. package/dist/mcp/servicenow-deployment-mcp.js +1 -1
  4. package/dist/mcp/servicenow-mcp-server.js +2 -2
  5. package/dist/mcp/shared/mcp-logger.js +6 -12
  6. package/dist/queen/agent-factory.js +134 -52
  7. package/dist/queen/servicenow-queen.d.ts +127 -2
  8. package/dist/queen/servicenow-queen.js +978 -618
  9. package/dist/services/widget-deployment-service.d.ts +1 -1
  10. package/dist/services/widget-deployment-service.js +1 -1
  11. package/dist/templates/claude-md-template.d.ts +1 -1
  12. package/dist/templates/claude-md-template.js +2 -2
  13. package/dist/types/servicenow.types.d.ts +1 -1
  14. package/dist/utils/dependency-detector.d.ts +1 -1
  15. package/dist/utils/dependency-detector.js +1 -1
  16. package/dist/utils/servicenow-client.d.ts +1 -1
  17. package/dist/utils/servicenow-client.js +4 -8
  18. package/package.json +1 -1
  19. package/website/components/README.md +419 -0
  20. package/website/components/code-display/CodeDisplay.css +583 -0
  21. package/website/components/code-display/CodeDisplay.html +200 -0
  22. package/website/components/code-display/CodeDisplay.js +375 -0
  23. package/website/components/code-display/CodeDisplay.jsx +268 -0
  24. package/website/components/demo/ComponentLibraryDemo.html +845 -0
  25. package/website/components/feature-cards/FeatureCards.css +573 -0
  26. package/website/components/feature-cards/FeatureCards.html +247 -0
  27. package/website/components/feature-cards/FeatureCards.js +382 -0
  28. package/website/components/feature-cards/FeatureCards.jsx +235 -0
  29. package/website/components/hero/Hero.css +558 -0
  30. package/website/components/hero/Hero.html +98 -0
  31. package/website/components/hero/Hero.js +415 -0
  32. package/website/components/hero/Hero.jsx +214 -0
  33. package/website/components/interactive/InteractiveElements.css +776 -0
  34. package/website/components/interactive/InteractiveElements.html +283 -0
  35. package/website/components/interactive/InteractiveElements.js +489 -0
  36. package/website/components/interactive/InteractiveElements.jsx +444 -0
  37. package/website/components/layout/LayoutComponents.css +697 -0
  38. package/website/components/layout/LayoutComponents.html +374 -0
  39. package/website/components/layout/LayoutComponents.js +447 -0
  40. package/website/components/layout/LayoutComponents.jsx +379 -0
  41. package/website/components/navigation/Navigation.css +383 -0
  42. package/website/components/navigation/Navigation.html +89 -0
  43. package/website/components/navigation/Navigation.js +248 -0
  44. package/website/components/navigation/Navigation.jsx +124 -0
  45. package/website/css/animations.css +854 -0
  46. package/website/css/style.css +916 -948
  47. package/website/index.html +394 -424
  48. package/website/js/animations.js +707 -0
  49. package/website/js/main.js +310 -383
  50. package/website/mcp-servers.html +310 -0
@@ -0,0 +1,707 @@
1
+ /**
2
+ * SNOW-FLOW ADVANCED ANIMATION SYSTEM
3
+ * Sophisticated animations and interactions using modern APIs
4
+ * Optimized for performance with IntersectionObserver
5
+ */
6
+
7
+ class SnowFlowAnimations {
8
+ constructor() {
9
+ this.init();
10
+ this.observers = [];
11
+ this.animationQueue = [];
12
+ this.isAnimating = false;
13
+ this.scrollProgress = 0;
14
+ this.lastScrollPosition = 0;
15
+ }
16
+
17
+ init() {
18
+ // Wait for DOM to be ready
19
+ if (document.readyState === 'loading') {
20
+ document.addEventListener('DOMContentLoaded', () => this.setupAnimations());
21
+ } else {
22
+ this.setupAnimations();
23
+ }
24
+ }
25
+
26
+ setupAnimations() {
27
+ this.createScrollProgress();
28
+ this.setupScrollAnimations();
29
+ this.setupParallaxEffects();
30
+ this.setupHoverAnimations();
31
+ this.setupLoadingAnimations();
32
+ this.setupMicroInteractions();
33
+ this.setupBackgroundAnimations();
34
+ this.setupPerformanceOptimizations();
35
+ this.handleReducedMotion();
36
+
37
+ // Initialize on load
38
+ window.addEventListener('load', () => {
39
+ this.triggerEntranceAnimations();
40
+ this.optimizeAnimations();
41
+ });
42
+
43
+ console.log('🎭 Snow-Flow Animation System Initialized');
44
+ }
45
+
46
+ /**
47
+ * SCROLL PROGRESS INDICATOR
48
+ */
49
+ createScrollProgress() {
50
+ // Create progress bar element
51
+ const progressBar = document.createElement('div');
52
+ progressBar.className = 'scroll-progress';
53
+ progressBar.innerHTML = '<div class="scroll-progress-fill"></div>';
54
+ document.body.appendChild(progressBar);
55
+
56
+ const progressFill = progressBar.querySelector('.scroll-progress-fill');
57
+
58
+ // Update progress on scroll
59
+ const updateProgress = () => {
60
+ const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
61
+ const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
62
+ const scrolled = (winScroll / height) * 100;
63
+
64
+ progressFill.style.width = `${scrolled}%`;
65
+ this.scrollProgress = scrolled;
66
+ };
67
+
68
+ // Throttled scroll listener
69
+ let ticking = false;
70
+ window.addEventListener('scroll', () => {
71
+ if (!ticking) {
72
+ requestAnimationFrame(() => {
73
+ updateProgress();
74
+ ticking = false;
75
+ });
76
+ ticking = true;
77
+ }
78
+ });
79
+ }
80
+
81
+ /**
82
+ * SCROLL ANIMATIONS WITH INTERSECTION OBSERVER
83
+ */
84
+ setupScrollAnimations() {
85
+ // Enhanced intersection observer options
86
+ const observerOptions = {
87
+ root: null,
88
+ rootMargin: '-50px 0px -100px 0px',
89
+ threshold: [0.1, 0.3, 0.5, 0.7, 1.0]
90
+ };
91
+
92
+ // Main scroll animation observer
93
+ const scrollObserver = new IntersectionObserver((entries) => {
94
+ entries.forEach(entry => {
95
+ const element = entry.target;
96
+ const intersectionRatio = entry.intersectionRatio;
97
+
98
+ if (entry.isIntersecting) {
99
+ // Add reveal class with stagger timing
100
+ const delay = this.calculateStaggerDelay(element);
101
+ setTimeout(() => {
102
+ element.classList.add('revealed');
103
+ this.triggerCustomAnimation(element);
104
+ }, delay);
105
+
106
+ // Progressive reveal based on intersection ratio
107
+ element.style.opacity = Math.min(intersectionRatio * 2, 1);
108
+ }
109
+ });
110
+ }, observerOptions);
111
+
112
+ // Observe scroll reveal elements
113
+ const scrollElements = document.querySelectorAll([
114
+ '.scroll-reveal',
115
+ '.scroll-reveal-left',
116
+ '.scroll-reveal-right',
117
+ '.feature',
118
+ '.mcp-card',
119
+ '.what-is-card',
120
+ '.workflow-step',
121
+ '.example-card',
122
+ '.practice'
123
+ ].join(','));
124
+
125
+ scrollElements.forEach(el => {
126
+ el.classList.add('gpu-accelerated');
127
+ scrollObserver.observe(el);
128
+ });
129
+
130
+ this.observers.push(scrollObserver);
131
+ }
132
+
133
+ /**
134
+ * PARALLAX EFFECTS
135
+ */
136
+ setupParallaxEffects() {
137
+ const parallaxElements = document.querySelectorAll('.hero-parallax, .gradient-mesh, .particles');
138
+
139
+ const updateParallax = () => {
140
+ const scrolled = window.pageYOffset;
141
+ const rate = scrolled * -0.5;
142
+
143
+ parallaxElements.forEach(element => {
144
+ if (this.isInViewport(element)) {
145
+ const speed = element.dataset.speed || 0.5;
146
+ const yPos = -(scrolled * speed);
147
+ element.style.transform = `translate3d(0, ${yPos}px, 0)`;
148
+ }
149
+ });
150
+ };
151
+
152
+ // Optimized scroll handler for parallax
153
+ let parallaxTicking = false;
154
+ window.addEventListener('scroll', () => {
155
+ if (!parallaxTicking) {
156
+ requestAnimationFrame(() => {
157
+ updateParallax();
158
+ parallaxTicking = false;
159
+ });
160
+ parallaxTicking = true;
161
+ }
162
+ });
163
+ }
164
+
165
+ /**
166
+ * ENTRANCE ANIMATIONS
167
+ */
168
+ triggerEntranceAnimations() {
169
+ // Hero section animation
170
+ const heroContent = document.querySelector('.hero-content');
171
+ if (heroContent) {
172
+ heroContent.classList.add('animate-fade-in-up');
173
+ }
174
+
175
+ // Stagger navigation items
176
+ const navItems = document.querySelectorAll('.nav-link');
177
+ navItems.forEach((item, index) => {
178
+ setTimeout(() => {
179
+ item.classList.add('animate-fade-in-down');
180
+ }, index * 100);
181
+ });
182
+
183
+ // Stats counter animation
184
+ this.animateCounters();
185
+ }
186
+
187
+ /**
188
+ * HOVER ANIMATIONS AND EFFECTS
189
+ */
190
+ setupHoverAnimations() {
191
+ // Enhanced button animations
192
+ const buttons = document.querySelectorAll('.btn, button, .nav-link');
193
+ buttons.forEach(btn => {
194
+ btn.classList.add('btn-animated', 'ripple-effect');
195
+
196
+ // Add magnetic effect for larger screens
197
+ if (window.innerWidth > 768) {
198
+ this.addMagneticEffect(btn);
199
+ }
200
+ });
201
+
202
+ // Card hover effects
203
+ const cards = document.querySelectorAll('.feature, .mcp-card, .what-is-card, .example-card, .practice');
204
+ cards.forEach(card => {
205
+ card.classList.add('card-hover', 'gpu-accelerated');
206
+
207
+ // Add tilt effect
208
+ this.addTiltEffect(card);
209
+ });
210
+
211
+ // Text gradient animations
212
+ const gradientTexts = document.querySelectorAll('.hero-title, .section-title, .brand-name');
213
+ gradientTexts.forEach(text => {
214
+ text.classList.add('text-gradient-animated');
215
+ });
216
+
217
+ // Icon animations
218
+ const icons = document.querySelectorAll('.feature-icon, .card-icon');
219
+ icons.forEach(icon => {
220
+ icon.classList.add('icon-scale');
221
+ });
222
+ }
223
+
224
+ /**
225
+ * LOADING STATES AND SKELETON SCREENS
226
+ */
227
+ setupLoadingAnimations() {
228
+ // Create skeleton loading for dynamic content
229
+ this.createSkeletonLoaders();
230
+
231
+ // Progress bar animations
232
+ const progressBars = document.querySelectorAll('.progress-bar');
233
+ progressBars.forEach(bar => {
234
+ const fill = bar.querySelector('.progress-fill');
235
+ if (fill) {
236
+ const observer = new IntersectionObserver((entries) => {
237
+ entries.forEach(entry => {
238
+ if (entry.isIntersecting) {
239
+ fill.style.width = fill.dataset.width || '100%';
240
+ }
241
+ });
242
+ });
243
+ observer.observe(bar);
244
+ }
245
+ });
246
+
247
+ // Spinner variations for async operations
248
+ this.createSpinners();
249
+ }
250
+
251
+ /**
252
+ * MICRO-INTERACTIONS
253
+ */
254
+ setupMicroInteractions() {
255
+ // Form field animations
256
+ const inputs = document.querySelectorAll('input, textarea, select');
257
+ inputs.forEach(input => {
258
+ input.classList.add('input-animated');
259
+
260
+ // Focus animations
261
+ input.addEventListener('focus', () => {
262
+ input.parentElement?.classList.add('focused');
263
+ });
264
+
265
+ input.addEventListener('blur', () => {
266
+ input.parentElement?.classList.remove('focused');
267
+ });
268
+ });
269
+
270
+ // Toggle switches
271
+ this.setupToggleSwitches();
272
+
273
+ // Tooltip interactions
274
+ this.setupTooltips();
275
+
276
+ // Copy code interactions
277
+ this.enhanceCopyButtons();
278
+ }
279
+
280
+ /**
281
+ * BACKGROUND ANIMATIONS
282
+ */
283
+ setupBackgroundAnimations() {
284
+ // Add gradient mesh to hero
285
+ const hero = document.querySelector('.hero');
286
+ if (hero && !hero.querySelector('.gradient-mesh')) {
287
+ const mesh = document.createElement('div');
288
+ mesh.className = 'gradient-mesh';
289
+ hero.appendChild(mesh);
290
+ }
291
+
292
+ // Add particles to sections
293
+ this.addParticleEffects();
294
+
295
+ // Wave patterns for section breaks
296
+ this.addWavePatterns();
297
+
298
+ // Noise overlay for texture
299
+ this.addNoiseOverlay();
300
+ }
301
+
302
+ /**
303
+ * PERFORMANCE OPTIMIZATIONS
304
+ */
305
+ setupPerformanceOptimizations() {
306
+ // Use Intersection Observer for expensive animations
307
+ const expensiveAnimations = document.querySelectorAll('.morphing, .text-glow, .particles');
308
+
309
+ const performanceObserver = new IntersectionObserver((entries) => {
310
+ entries.forEach(entry => {
311
+ if (entry.isIntersecting) {
312
+ entry.target.classList.add('animate');
313
+ } else {
314
+ entry.target.classList.remove('animate');
315
+ }
316
+ });
317
+ }, { rootMargin: '50px' });
318
+
319
+ expensiveAnimations.forEach(el => {
320
+ performanceObserver.observe(el);
321
+ });
322
+
323
+ // Throttle resize events
324
+ this.setupResponsiveAnimations();
325
+
326
+ // Preload critical animations
327
+ this.preloadAnimations();
328
+ }
329
+
330
+ /**
331
+ * UTILITY METHODS
332
+ */
333
+
334
+ calculateStaggerDelay(element) {
335
+ const parent = element.parentElement;
336
+ if (!parent) return 0;
337
+
338
+ const siblings = Array.from(parent.children);
339
+ const index = siblings.indexOf(element);
340
+ return Math.min(index * 100, 800); // Max 800ms delay
341
+ }
342
+
343
+ triggerCustomAnimation(element) {
344
+ const animationType = element.dataset.animation;
345
+ if (!animationType) return;
346
+
347
+ const animations = {
348
+ 'bounce': () => element.classList.add('animate-bounce'),
349
+ 'scale': () => element.classList.add('animate-scale-in'),
350
+ 'slide-up': () => element.classList.add('animate-slide-in-bottom'),
351
+ 'slide-down': () => element.classList.add('animate-slide-in-top'),
352
+ 'fade-left': () => element.classList.add('animate-fade-in-left'),
353
+ 'fade-right': () => element.classList.add('animate-fade-in-right')
354
+ };
355
+
356
+ if (animations[animationType]) {
357
+ animations[animationType]();
358
+ }
359
+ }
360
+
361
+ isInViewport(element) {
362
+ const rect = element.getBoundingClientRect();
363
+ return (
364
+ rect.top < window.innerHeight &&
365
+ rect.bottom > 0
366
+ );
367
+ }
368
+
369
+ addMagneticEffect(element) {
370
+ element.addEventListener('mousemove', (e) => {
371
+ const rect = element.getBoundingClientRect();
372
+ const x = e.clientX - rect.left - rect.width / 2;
373
+ const y = e.clientY - rect.top - rect.height / 2;
374
+
375
+ element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px)`;
376
+ });
377
+
378
+ element.addEventListener('mouseleave', () => {
379
+ element.style.transform = '';
380
+ });
381
+ }
382
+
383
+ addTiltEffect(card) {
384
+ card.addEventListener('mousemove', (e) => {
385
+ const rect = card.getBoundingClientRect();
386
+ const x = e.clientX - rect.left;
387
+ const y = e.clientY - rect.top;
388
+
389
+ const centerX = rect.width / 2;
390
+ const centerY = rect.height / 2;
391
+
392
+ const rotateX = (y - centerY) / 10;
393
+ const rotateY = (centerX - x) / 10;
394
+
395
+ card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
396
+ });
397
+
398
+ card.addEventListener('mouseleave', () => {
399
+ card.style.transform = '';
400
+ });
401
+ }
402
+
403
+ animateCounters() {
404
+ const counters = document.querySelectorAll('.stat-number');
405
+
406
+ const counterObserver = new IntersectionObserver((entries) => {
407
+ entries.forEach(entry => {
408
+ if (entry.isIntersecting && !entry.target.classList.contains('counted')) {
409
+ this.animateCounter(entry.target);
410
+ }
411
+ });
412
+ }, { threshold: 0.5 });
413
+
414
+ counters.forEach(counter => {
415
+ counterObserver.observe(counter);
416
+ });
417
+ }
418
+
419
+ animateCounter(counter) {
420
+ counter.classList.add('counted');
421
+ const target = parseInt(counter.textContent.replace(/\D/g, ''));
422
+ const suffix = counter.textContent.replace(/\d/g, '');
423
+ const duration = 2000;
424
+ const increment = target / (duration / 16);
425
+ let current = 0;
426
+
427
+ const updateCounter = () => {
428
+ current += increment;
429
+ if (current >= target) {
430
+ counter.textContent = target + suffix;
431
+ } else {
432
+ counter.textContent = Math.floor(current) + suffix;
433
+ requestAnimationFrame(updateCounter);
434
+ }
435
+ };
436
+
437
+ updateCounter();
438
+ }
439
+
440
+ createSkeletonLoaders() {
441
+ const skeletonContainer = document.createElement('div');
442
+ skeletonContainer.className = 'skeleton-container';
443
+ skeletonContainer.innerHTML = `
444
+ <div class="skeleton skeleton-card"></div>
445
+ <div class="skeleton skeleton-text"></div>
446
+ <div class="skeleton skeleton-text"></div>
447
+ <div class="skeleton skeleton-text" style="width: 60%;"></div>
448
+ `;
449
+
450
+ // Add to body but keep hidden initially
451
+ skeletonContainer.style.display = 'none';
452
+ document.body.appendChild(skeletonContainer);
453
+ }
454
+
455
+ createSpinners() {
456
+ // Dots spinner
457
+ const dotsSpinner = document.createElement('div');
458
+ dotsSpinner.className = 'spinner-dots';
459
+ dotsSpinner.innerHTML = '<div></div><div></div><div></div>';
460
+
461
+ // Rotate spinner
462
+ const rotateSpinner = document.createElement('div');
463
+ rotateSpinner.className = 'spinner-rotate';
464
+
465
+ // Store references for later use
466
+ this.spinners = { dots: dotsSpinner, rotate: rotateSpinner };
467
+ }
468
+
469
+ setupToggleSwitches() {
470
+ const toggles = document.querySelectorAll('.toggle-switch, [data-toggle]');
471
+ toggles.forEach(toggle => {
472
+ toggle.addEventListener('click', () => {
473
+ toggle.classList.toggle('active');
474
+
475
+ // Trigger custom event
476
+ toggle.dispatchEvent(new CustomEvent('toggle', {
477
+ detail: { active: toggle.classList.contains('active') }
478
+ }));
479
+ });
480
+ });
481
+ }
482
+
483
+ setupTooltips() {
484
+ const tooltipElements = document.querySelectorAll('[data-tooltip]');
485
+ tooltipElements.forEach(element => {
486
+ element.classList.add('tooltip');
487
+ });
488
+ }
489
+
490
+ enhanceCopyButtons() {
491
+ const copyButtons = document.querySelectorAll('.copy-btn');
492
+ copyButtons.forEach(btn => {
493
+ btn.addEventListener('click', () => {
494
+ // Add success animation
495
+ btn.classList.add('success-animation');
496
+ setTimeout(() => {
497
+ btn.classList.remove('success-animation');
498
+ }, 2000);
499
+ });
500
+ });
501
+ }
502
+
503
+ addParticleEffects() {
504
+ const sections = document.querySelectorAll('.hero, .features');
505
+ sections.forEach(section => {
506
+ if (!section.querySelector('.particles')) {
507
+ const particles = document.createElement('div');
508
+ particles.className = 'particles';
509
+ particles.innerHTML = `
510
+ <div class="particle particle-1"></div>
511
+ <div class="particle particle-2"></div>
512
+ <div class="particle particle-3"></div>
513
+ `;
514
+ section.appendChild(particles);
515
+ }
516
+ });
517
+ }
518
+
519
+ addWavePatterns() {
520
+ const sections = document.querySelectorAll('section');
521
+ sections.forEach((section, index) => {
522
+ if (index % 2 === 1 && !section.querySelector('.wave-bg')) {
523
+ const wave = document.createElement('div');
524
+ wave.className = 'wave-bg';
525
+ section.appendChild(wave);
526
+ }
527
+ });
528
+ }
529
+
530
+ addNoiseOverlay() {
531
+ const hero = document.querySelector('.hero');
532
+ if (hero && !hero.querySelector('.noise-overlay')) {
533
+ const noise = document.createElement('div');
534
+ noise.className = 'noise-overlay';
535
+ hero.appendChild(noise);
536
+ }
537
+ }
538
+
539
+ setupResponsiveAnimations() {
540
+ let resizeTimer;
541
+ window.addEventListener('resize', () => {
542
+ clearTimeout(resizeTimer);
543
+ resizeTimer = setTimeout(() => {
544
+ this.handleResponsiveAnimations();
545
+ }, 250);
546
+ });
547
+ }
548
+
549
+ handleResponsiveAnimations() {
550
+ const isMobile = window.innerWidth < 768;
551
+ const animations = document.querySelectorAll('[class*="animate"]');
552
+
553
+ animations.forEach(element => {
554
+ if (isMobile) {
555
+ element.style.animationDuration = '0.4s';
556
+ } else {
557
+ element.style.animationDuration = '';
558
+ }
559
+ });
560
+ }
561
+
562
+ preloadAnimations() {
563
+ // Preload critical CSS animations
564
+ const link = document.createElement('link');
565
+ link.rel = 'preload';
566
+ link.href = 'css/animations.css';
567
+ link.as = 'style';
568
+ document.head.appendChild(link);
569
+ }
570
+
571
+ optimizeAnimations() {
572
+ // Enable GPU acceleration for animated elements
573
+ const animatedElements = document.querySelectorAll([
574
+ '[class*="animate"]',
575
+ '.card-hover',
576
+ '.btn-animated',
577
+ '.scroll-reveal'
578
+ ].join(','));
579
+
580
+ animatedElements.forEach(element => {
581
+ element.classList.add('gpu-accelerated');
582
+ });
583
+ }
584
+
585
+ handleReducedMotion() {
586
+ // Respect user's motion preferences
587
+ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
588
+
589
+ if (prefersReducedMotion.matches) {
590
+ document.documentElement.style.setProperty('--animation-duration', '0.01ms');
591
+ document.documentElement.style.setProperty('--transition-duration', '0.01ms');
592
+ }
593
+
594
+ // Listen for changes
595
+ prefersReducedMotion.addEventListener('change', () => {
596
+ if (prefersReducedMotion.matches) {
597
+ document.documentElement.style.setProperty('--animation-duration', '0.01ms');
598
+ } else {
599
+ document.documentElement.style.removeProperty('--animation-duration');
600
+ }
601
+ });
602
+ }
603
+
604
+ /**
605
+ * PUBLIC API METHODS
606
+ */
607
+
608
+ // Show loading spinner
609
+ showSpinner(type = 'rotate', container = document.body) {
610
+ const spinner = this.spinners[type].cloneNode(true);
611
+ spinner.classList.add('active-spinner');
612
+ container.appendChild(spinner);
613
+ return spinner;
614
+ }
615
+
616
+ // Hide spinner
617
+ hideSpinner(spinner) {
618
+ if (spinner && spinner.parentNode) {
619
+ spinner.remove();
620
+ }
621
+ }
622
+
623
+ // Trigger custom animation on element
624
+ animate(element, animation, options = {}) {
625
+ const { delay = 0, duration = 600, easing = 'ease' } = options;
626
+
627
+ element.style.animationDelay = `${delay}ms`;
628
+ element.style.animationDuration = `${duration}ms`;
629
+ element.style.animationTimingFunction = easing;
630
+
631
+ element.classList.add(`animate-${animation}`);
632
+
633
+ // Return promise that resolves when animation ends
634
+ return new Promise(resolve => {
635
+ element.addEventListener('animationend', resolve, { once: true });
636
+ });
637
+ }
638
+
639
+ // Batch animate multiple elements
640
+ animateBatch(elements, animation, stagger = 100) {
641
+ const promises = [];
642
+ elements.forEach((element, index) => {
643
+ const promise = this.animate(element, animation, { delay: index * stagger });
644
+ promises.push(promise);
645
+ });
646
+ return Promise.all(promises);
647
+ }
648
+
649
+ // Destroy animations and observers
650
+ destroy() {
651
+ this.observers.forEach(observer => observer.disconnect());
652
+ this.observers = [];
653
+
654
+ // Remove event listeners
655
+ window.removeEventListener('scroll', this.updateProgress);
656
+ window.removeEventListener('resize', this.handleResponsiveAnimations);
657
+
658
+ console.log('🎭 Snow-Flow Animation System Destroyed');
659
+ }
660
+ }
661
+
662
+ // Initialize the animation system
663
+ const snowFlowAnimations = new SnowFlowAnimations();
664
+
665
+ // Export for global access
666
+ window.SnowFlowAnimations = snowFlowAnimations;
667
+
668
+ // Add some additional CSS styles dynamically for the scroll progress
669
+ const additionalStyles = `
670
+ .scroll-progress {
671
+ position: fixed;
672
+ top: 0;
673
+ left: 0;
674
+ width: 100%;
675
+ height: 4px;
676
+ background: rgba(0, 102, 204, 0.1);
677
+ z-index: 9999;
678
+ pointer-events: none;
679
+ }
680
+
681
+ .scroll-progress-fill {
682
+ height: 100%;
683
+ background: linear-gradient(90deg, #0066cc, #00d4ff);
684
+ width: 0%;
685
+ transition: width 0.1s ease;
686
+ box-shadow: 0 0 10px rgba(0, 102, 204, 0.3);
687
+ }
688
+
689
+ .success-animation {
690
+ animation: pulse 0.3s ease-in-out;
691
+ background: #48bb78 !important;
692
+ border-color: #48bb78 !important;
693
+ }
694
+
695
+ .active-spinner {
696
+ position: fixed;
697
+ top: 50%;
698
+ left: 50%;
699
+ transform: translate(-50%, -50%);
700
+ z-index: 10000;
701
+ }
702
+ `;
703
+
704
+ // Inject additional styles
705
+ const styleSheet = document.createElement('style');
706
+ styleSheet.textContent = additionalStyles;
707
+ document.head.appendChild(styleSheet);