snow-flow 3.4.36 → 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 (49) 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/queen/agent-factory.js +134 -52
  6. package/dist/queen/servicenow-queen.d.ts +127 -2
  7. package/dist/queen/servicenow-queen.js +978 -618
  8. package/dist/services/widget-deployment-service.d.ts +1 -1
  9. package/dist/services/widget-deployment-service.js +1 -1
  10. package/dist/templates/claude-md-template.d.ts +1 -1
  11. package/dist/templates/claude-md-template.js +2 -2
  12. package/dist/types/servicenow.types.d.ts +1 -1
  13. package/dist/utils/dependency-detector.d.ts +1 -1
  14. package/dist/utils/dependency-detector.js +1 -1
  15. package/dist/utils/servicenow-client.d.ts +1 -1
  16. package/dist/utils/servicenow-client.js +4 -8
  17. package/package.json +1 -1
  18. package/website/components/README.md +419 -0
  19. package/website/components/code-display/CodeDisplay.css +583 -0
  20. package/website/components/code-display/CodeDisplay.html +200 -0
  21. package/website/components/code-display/CodeDisplay.js +375 -0
  22. package/website/components/code-display/CodeDisplay.jsx +268 -0
  23. package/website/components/demo/ComponentLibraryDemo.html +845 -0
  24. package/website/components/feature-cards/FeatureCards.css +573 -0
  25. package/website/components/feature-cards/FeatureCards.html +247 -0
  26. package/website/components/feature-cards/FeatureCards.js +382 -0
  27. package/website/components/feature-cards/FeatureCards.jsx +235 -0
  28. package/website/components/hero/Hero.css +558 -0
  29. package/website/components/hero/Hero.html +98 -0
  30. package/website/components/hero/Hero.js +415 -0
  31. package/website/components/hero/Hero.jsx +214 -0
  32. package/website/components/interactive/InteractiveElements.css +776 -0
  33. package/website/components/interactive/InteractiveElements.html +283 -0
  34. package/website/components/interactive/InteractiveElements.js +489 -0
  35. package/website/components/interactive/InteractiveElements.jsx +444 -0
  36. package/website/components/layout/LayoutComponents.css +697 -0
  37. package/website/components/layout/LayoutComponents.html +374 -0
  38. package/website/components/layout/LayoutComponents.js +447 -0
  39. package/website/components/layout/LayoutComponents.jsx +379 -0
  40. package/website/components/navigation/Navigation.css +383 -0
  41. package/website/components/navigation/Navigation.html +89 -0
  42. package/website/components/navigation/Navigation.js +248 -0
  43. package/website/components/navigation/Navigation.jsx +124 -0
  44. package/website/css/animations.css +854 -0
  45. package/website/css/style.css +916 -948
  46. package/website/index.html +394 -424
  47. package/website/js/animations.js +707 -0
  48. package/website/js/main.js +310 -383
  49. package/website/mcp-servers.html +310 -0
@@ -0,0 +1,247 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Snow-Flow Feature Cards Component</title>
7
+ <link rel="stylesheet" href="FeatureCards.css">
8
+ </head>
9
+ <body>
10
+ <!-- Feature Cards Section Component -->
11
+ <section class="sf-feature-cards" id="sf-feature-cards">
12
+ <div class="sf-feature-cards__container">
13
+ <!-- Header -->
14
+ <div class="sf-feature-cards__header">
15
+ <h2 class="sf-feature-cards__title">Features</h2>
16
+ <p class="sf-feature-cards__subtitle">Discover what makes our platform unique and powerful</p>
17
+ </div>
18
+
19
+ <!-- Feature Grid -->
20
+ <div class="sf-feature-cards__grid" id="sf-feature-grid">
21
+ <!-- Feature Card 1 -->
22
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#performance" data-index="0">
23
+ <!-- 3D Border Effect -->
24
+ <div class="sf-feature-card__border">
25
+ <div class="sf-feature-card__border-top"></div>
26
+ <div class="sf-feature-card__border-right"></div>
27
+ <div class="sf-feature-card__border-bottom"></div>
28
+ <div class="sf-feature-card__border-left"></div>
29
+ </div>
30
+
31
+ <!-- Background Glow -->
32
+ <div class="sf-feature-card__glow"></div>
33
+
34
+ <!-- Content -->
35
+ <div class="sf-feature-card__content">
36
+ <!-- Icon -->
37
+ <div class="sf-feature-card__icon-wrapper">
38
+ <div class="sf-feature-card__icon">
39
+ <span role="img" aria-hidden="true">⚡</span>
40
+ </div>
41
+ </div>
42
+
43
+ <!-- Text Content -->
44
+ <div class="sf-feature-card__text">
45
+ <h3 class="sf-feature-card__title">Lightning Fast</h3>
46
+ <p class="sf-feature-card__description">Optimized performance with cutting-edge technology for instant results and seamless user experience.</p>
47
+ </div>
48
+
49
+ <!-- Hover Arrow -->
50
+ <div class="sf-feature-card__arrow">
51
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
52
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
53
+ </svg>
54
+ </div>
55
+ </div>
56
+
57
+ <!-- Ripple Effect -->
58
+ <div class="sf-feature-card__ripple"></div>
59
+ </div>
60
+
61
+ <!-- Feature Card 2 -->
62
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#security" data-index="1">
63
+ <div class="sf-feature-card__border">
64
+ <div class="sf-feature-card__border-top"></div>
65
+ <div class="sf-feature-card__border-right"></div>
66
+ <div class="sf-feature-card__border-bottom"></div>
67
+ <div class="sf-feature-card__border-left"></div>
68
+ </div>
69
+ <div class="sf-feature-card__glow"></div>
70
+ <div class="sf-feature-card__content">
71
+ <div class="sf-feature-card__icon-wrapper">
72
+ <div class="sf-feature-card__icon">
73
+ <span role="img" aria-hidden="true">🔒</span>
74
+ </div>
75
+ </div>
76
+ <div class="sf-feature-card__text">
77
+ <h3 class="sf-feature-card__title">Secure by Design</h3>
78
+ <p class="sf-feature-card__description">Enterprise-grade security with end-to-end encryption and compliance standards built-in.</p>
79
+ </div>
80
+ <div class="sf-feature-card__arrow">
81
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
82
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
83
+ </svg>
84
+ </div>
85
+ </div>
86
+ <div class="sf-feature-card__ripple"></div>
87
+ </div>
88
+
89
+ <!-- Feature Card 3 -->
90
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#integration" data-index="2">
91
+ <div class="sf-feature-card__border">
92
+ <div class="sf-feature-card__border-top"></div>
93
+ <div class="sf-feature-card__border-right"></div>
94
+ <div class="sf-feature-card__border-bottom"></div>
95
+ <div class="sf-feature-card__border-left"></div>
96
+ </div>
97
+ <div class="sf-feature-card__glow"></div>
98
+ <div class="sf-feature-card__content">
99
+ <div class="sf-feature-card__icon-wrapper">
100
+ <div class="sf-feature-card__icon">
101
+ <span role="img" aria-hidden="true">🚀</span>
102
+ </div>
103
+ </div>
104
+ <div class="sf-feature-card__text">
105
+ <h3 class="sf-feature-card__title">Easy Integration</h3>
106
+ <p class="sf-feature-card__description">Seamless integration with your existing tools and workflows, no complex setup required.</p>
107
+ </div>
108
+ <div class="sf-feature-card__arrow">
109
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
110
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
111
+ </svg>
112
+ </div>
113
+ </div>
114
+ <div class="sf-feature-card__ripple"></div>
115
+ </div>
116
+
117
+ <!-- Feature Card 4 -->
118
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#analytics" data-index="3">
119
+ <div class="sf-feature-card__border">
120
+ <div class="sf-feature-card__border-top"></div>
121
+ <div class="sf-feature-card__border-right"></div>
122
+ <div class="sf-feature-card__border-bottom"></div>
123
+ <div class="sf-feature-card__border-left"></div>
124
+ </div>
125
+ <div class="sf-feature-card__glow"></div>
126
+ <div class="sf-feature-card__content">
127
+ <div class="sf-feature-card__icon-wrapper">
128
+ <div class="sf-feature-card__icon">
129
+ <span role="img" aria-hidden="true">📊</span>
130
+ </div>
131
+ </div>
132
+ <div class="sf-feature-card__text">
133
+ <h3 class="sf-feature-card__title">Real-time Analytics</h3>
134
+ <p class="sf-feature-card__description">Comprehensive insights and analytics to drive informed decisions with real-time data.</p>
135
+ </div>
136
+ <div class="sf-feature-card__arrow">
137
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
138
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
139
+ </svg>
140
+ </div>
141
+ </div>
142
+ <div class="sf-feature-card__ripple"></div>
143
+ </div>
144
+
145
+ <!-- Feature Card 5 -->
146
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#control" data-index="4">
147
+ <div class="sf-feature-card__border">
148
+ <div class="sf-feature-card__border-top"></div>
149
+ <div class="sf-feature-card__border-right"></div>
150
+ <div class="sf-feature-card__border-bottom"></div>
151
+ <div class="sf-feature-card__border-left"></div>
152
+ </div>
153
+ <div class="sf-feature-card__glow"></div>
154
+ <div class="sf-feature-card__content">
155
+ <div class="sf-feature-card__icon-wrapper">
156
+ <div class="sf-feature-card__icon">
157
+ <span role="img" aria-hidden="true">🎯</span>
158
+ </div>
159
+ </div>
160
+ <div class="sf-feature-card__text">
161
+ <h3 class="sf-feature-card__title">Precision Control</h3>
162
+ <p class="sf-feature-card__description">Granular control over every aspect of your system operations with advanced configuration options.</p>
163
+ </div>
164
+ <div class="sf-feature-card__arrow">
165
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
166
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
167
+ </svg>
168
+ </div>
169
+ </div>
170
+ <div class="sf-feature-card__ripple"></div>
171
+ </div>
172
+
173
+ <!-- Feature Card 6 -->
174
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="#updates" data-index="5">
175
+ <div class="sf-feature-card__border">
176
+ <div class="sf-feature-card__border-top"></div>
177
+ <div class="sf-feature-card__border-right"></div>
178
+ <div class="sf-feature-card__border-bottom"></div>
179
+ <div class="sf-feature-card__border-left"></div>
180
+ </div>
181
+ <div class="sf-feature-card__glow"></div>
182
+ <div class="sf-feature-card__content">
183
+ <div class="sf-feature-card__icon-wrapper">
184
+ <div class="sf-feature-card__icon">
185
+ <span role="img" aria-hidden="true">🔄</span>
186
+ </div>
187
+ </div>
188
+ <div class="sf-feature-card__text">
189
+ <h3 class="sf-feature-card__title">Auto Updates</h3>
190
+ <p class="sf-feature-card__description">Stay current with automatic updates and feature enhancements, zero maintenance required.</p>
191
+ </div>
192
+ <div class="sf-feature-card__arrow">
193
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
194
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
195
+ </svg>
196
+ </div>
197
+ </div>
198
+ <div class="sf-feature-card__ripple"></div>
199
+ </div>
200
+ </div>
201
+
202
+ <!-- Optional CTA -->
203
+ <div class="sf-feature-cards__cta" id="sf-feature-cta">
204
+ <button class="sf-feature-cards__cta-button">
205
+ View All Features
206
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
207
+ <path d="M5 12H19M12 5L19 12L12 19"/>
208
+ </svg>
209
+ </button>
210
+ </div>
211
+ </div>
212
+
213
+ <!-- Background Elements -->
214
+ <div class="sf-feature-cards__background">
215
+ <div class="sf-feature-cards__bg-grid"></div>
216
+ <div class="sf-feature-cards__bg-gradient"></div>
217
+ </div>
218
+ </section>
219
+
220
+ <!-- Demo Sections for Link Testing -->
221
+ <section id="performance" style="height: 100vh; background: linear-gradient(135deg, #f0f0f0, #e0e0e0); display: flex; align-items: center; justify-content: center;">
222
+ <h2>Performance Section</h2>
223
+ </section>
224
+
225
+ <section id="security" style="height: 100vh; background: linear-gradient(135deg, #e0e0e0, #d0d0d0); display: flex; align-items: center; justify-content: center;">
226
+ <h2>Security Section</h2>
227
+ </section>
228
+
229
+ <section id="integration" style="height: 100vh; background: linear-gradient(135deg, #d0d0d0, #c0c0c0); display: flex; align-items: center; justify-content: center;">
230
+ <h2>Integration Section</h2>
231
+ </section>
232
+
233
+ <section id="analytics" style="height: 100vh; background: linear-gradient(135deg, #c0c0c0, #b0b0b0); display: flex; align-items: center; justify-content: center;">
234
+ <h2>Analytics Section</h2>
235
+ </section>
236
+
237
+ <section id="control" style="height: 100vh; background: linear-gradient(135deg, #b0b0b0, #a0a0a0); display: flex; align-items: center; justify-content: center;">
238
+ <h2>Control Section</h2>
239
+ </section>
240
+
241
+ <section id="updates" style="height: 100vh; background: linear-gradient(135deg, #a0a0a0, #909090); display: flex; align-items: center; justify-content: center;">
242
+ <h2>Updates Section</h2>
243
+ </section>
244
+
245
+ <script src="FeatureCards.js"></script>
246
+ </body>
247
+ </html>
@@ -0,0 +1,382 @@
1
+ // Snow-Flow Feature Cards Component JavaScript
2
+
3
+ class SnowFlowFeatureCards {
4
+ constructor(options = {}) {
5
+ // Configuration
6
+ this.config = {
7
+ containerId: options.containerId || 'sf-feature-cards',
8
+ gridId: options.gridId || 'sf-feature-grid',
9
+ ctaId: options.ctaId || 'sf-feature-cta',
10
+
11
+ // Animation settings
12
+ staggerDelay: options.staggerDelay || 150,
13
+ intersectionThreshold: options.intersectionThreshold || 0.1,
14
+
15
+ // State
16
+ isVisible: false,
17
+ visibleCards: new Set(),
18
+ cardElements: []
19
+ };
20
+
21
+ // DOM elements
22
+ this.elements = {
23
+ container: document.getElementById(this.config.containerId),
24
+ grid: document.getElementById(this.config.gridId),
25
+ cta: document.getElementById(this.config.ctaId)
26
+ };
27
+
28
+ this.init();
29
+ }
30
+
31
+ init() {
32
+ if (!this.elements.container) {
33
+ console.warn('SnowFlowFeatureCards: Container element not found');
34
+ return;
35
+ }
36
+
37
+ this.setupCards();
38
+ this.setupIntersectionObserver();
39
+ this.setupEventListeners();
40
+ }
41
+
42
+ setupCards() {
43
+ // Get all card elements
44
+ this.config.cardElements = Array.from(
45
+ this.elements.container.querySelectorAll('.sf-feature-card')
46
+ );
47
+
48
+ // Setup each card
49
+ this.config.cardElements.forEach((card, index) => {
50
+ card.style.animationDelay = `${index * this.config.staggerDelay}ms`;
51
+ card.setAttribute('data-index', index.toString());
52
+ });
53
+ }
54
+
55
+ setupIntersectionObserver() {
56
+ const observer = new IntersectionObserver(
57
+ (entries) => {
58
+ entries.forEach(entry => {
59
+ if (entry.isIntersecting && !this.config.isVisible) {
60
+ this.config.isVisible = true;
61
+ this.startAnimations();
62
+ }
63
+ });
64
+ },
65
+ { threshold: this.config.intersectionThreshold }
66
+ );
67
+
68
+ observer.observe(this.elements.container);
69
+ }
70
+
71
+ setupEventListeners() {
72
+ // Card click handlers
73
+ this.config.cardElements.forEach((card, index) => {
74
+ // Mouse events
75
+ card.addEventListener('mouseenter', () => this.handleCardHover(card, true));
76
+ card.addEventListener('mouseleave', () => this.handleCardHover(card, false));
77
+ card.addEventListener('click', (e) => this.handleCardClick(e, card, index));
78
+
79
+ // Touch events for mobile
80
+ card.addEventListener('touchstart', () => this.handleCardHover(card, true), { passive: true });
81
+ card.addEventListener('touchend', () => {
82
+ setTimeout(() => this.handleCardHover(card, false), 300);
83
+ }, { passive: true });
84
+
85
+ // Keyboard events
86
+ card.addEventListener('keydown', (e) => {
87
+ if (e.key === 'Enter' || e.key === ' ') {
88
+ e.preventDefault();
89
+ this.handleCardClick(e, card, index);
90
+ }
91
+ });
92
+
93
+ // Focus events
94
+ card.addEventListener('focus', () => this.handleCardFocus(card, true));
95
+ card.addEventListener('blur', () => this.handleCardFocus(card, false));
96
+ });
97
+
98
+ // CTA button
99
+ if (this.elements.cta) {
100
+ const ctaButton = this.elements.cta.querySelector('.sf-feature-cards__cta-button');
101
+ if (ctaButton) {
102
+ ctaButton.addEventListener('click', () => this.handleCTAClick());
103
+ }
104
+ }
105
+
106
+ // Resize handler
107
+ window.addEventListener('resize', () => this.handleResize());
108
+ }
109
+
110
+ startAnimations() {
111
+ // Add visible class to container
112
+ this.elements.container.classList.add('sf-feature-cards--visible');
113
+
114
+ // Stagger card animations
115
+ this.config.cardElements.forEach((card, index) => {
116
+ setTimeout(() => {
117
+ this.config.visibleCards.add(index);
118
+ card.classList.add('sf-feature-card--visible');
119
+ this.animateCardAppearance(card, index);
120
+ }, index * this.config.staggerDelay);
121
+ });
122
+
123
+ // Show CTA after all cards are visible
124
+ if (this.elements.cta) {
125
+ const totalDelay = this.config.cardElements.length * this.config.staggerDelay + 500;
126
+ setTimeout(() => {
127
+ this.elements.cta.classList.add('sf-feature-cards__cta--visible');
128
+ }, totalDelay);
129
+ }
130
+ }
131
+
132
+ animateCardAppearance(card, index) {
133
+ // Optional: Add additional entrance effects
134
+ const icon = card.querySelector('.sf-feature-card__icon');
135
+ if (icon) {
136
+ setTimeout(() => {
137
+ icon.style.transform = 'scale(1.1)';
138
+ setTimeout(() => {
139
+ icon.style.transform = '';
140
+ }, 200);
141
+ }, 100);
142
+ }
143
+ }
144
+
145
+ handleCardHover(card, isEntering) {
146
+ const icon = card.querySelector('.sf-feature-card__icon');
147
+ const arrow = card.querySelector('.sf-feature-card__arrow');
148
+
149
+ if (isEntering) {
150
+ if (icon) {
151
+ icon.classList.add('sf-feature-card__icon--animated');
152
+ }
153
+ if (arrow) {
154
+ arrow.classList.add('sf-feature-card__arrow--visible');
155
+ }
156
+ } else {
157
+ if (icon) {
158
+ icon.classList.remove('sf-feature-card__icon--animated');
159
+ }
160
+ if (arrow) {
161
+ arrow.classList.remove('sf-feature-card__arrow--visible');
162
+ }
163
+ }
164
+ }
165
+
166
+ handleCardFocus(card, isFocused) {
167
+ // Handle focus state for accessibility
168
+ if (isFocused) {
169
+ card.style.outline = '2px solid #000000';
170
+ card.style.outlineOffset = '2px';
171
+ this.handleCardHover(card, true);
172
+ } else {
173
+ card.style.outline = '';
174
+ card.style.outlineOffset = '';
175
+ this.handleCardHover(card, false);
176
+ }
177
+ }
178
+
179
+ handleCardClick(e, card, index) {
180
+ const link = card.getAttribute('data-link');
181
+
182
+ if (link) {
183
+ // Add ripple effect
184
+ this.createRippleEffect(card, e);
185
+
186
+ // Navigate after short delay for ripple effect
187
+ setTimeout(() => {
188
+ if (link.startsWith('#')) {
189
+ this.scrollToSection(link);
190
+ } else {
191
+ window.open(link, '_blank', 'noopener,noreferrer');
192
+ }
193
+ }, 150);
194
+ }
195
+
196
+ // Optional: Trigger custom event
197
+ const event = new CustomEvent('cardClick', {
198
+ detail: {
199
+ index,
200
+ card,
201
+ link,
202
+ title: card.querySelector('.sf-feature-card__title')?.textContent
203
+ }
204
+ });
205
+ this.elements.container.dispatchEvent(event);
206
+ }
207
+
208
+ createRippleEffect(card, clickEvent) {
209
+ const ripple = card.querySelector('.sf-feature-card__ripple');
210
+ if (!ripple) return;
211
+
212
+ // Reset ripple
213
+ ripple.style.width = '0';
214
+ ripple.style.height = '0';
215
+
216
+ // Calculate ripple position for click events
217
+ if (clickEvent && clickEvent.type === 'click') {
218
+ const rect = card.getBoundingClientRect();
219
+ const x = clickEvent.clientX - rect.left;
220
+ const y = clickEvent.clientY - rect.top;
221
+
222
+ ripple.style.left = `${x}px`;
223
+ ripple.style.top = `${y}px`;
224
+ ripple.style.transform = 'translate(-50%, -50%)';
225
+ }
226
+
227
+ // Trigger ripple animation
228
+ setTimeout(() => {
229
+ ripple.style.width = '300px';
230
+ ripple.style.height = '300px';
231
+ }, 10);
232
+
233
+ // Reset after animation
234
+ setTimeout(() => {
235
+ ripple.style.width = '0';
236
+ ripple.style.height = '0';
237
+ ripple.style.left = '50%';
238
+ ripple.style.top = '50%';
239
+ }, 600);
240
+ }
241
+
242
+ scrollToSection(target) {
243
+ const element = document.querySelector(target);
244
+ if (element) {
245
+ const offset = 80; // Account for fixed navbar
246
+ const targetPosition = element.offsetTop - offset;
247
+
248
+ window.scrollTo({
249
+ top: targetPosition,
250
+ behavior: 'smooth'
251
+ });
252
+ }
253
+ }
254
+
255
+ handleCTAClick() {
256
+ // Optional: Implement show all features logic
257
+ console.log('View All Features clicked');
258
+
259
+ // Example: Could expand to show more cards or navigate to features page
260
+ const event = new CustomEvent('ctaClick', {
261
+ detail: {
262
+ action: 'viewAllFeatures'
263
+ }
264
+ });
265
+ this.elements.container.dispatchEvent(event);
266
+ }
267
+
268
+ handleResize() {
269
+ // Handle responsive behavior if needed
270
+ // Could recalculate positions or update layout
271
+ }
272
+
273
+ // Public API methods
274
+ addFeature(featureData) {
275
+ const { icon, title, description, link } = featureData;
276
+
277
+ const cardHTML = `
278
+ <div class="sf-feature-card sf-feature-card--clickable" data-link="${link || ''}" data-index="${this.config.cardElements.length}">
279
+ <div class="sf-feature-card__border">
280
+ <div class="sf-feature-card__border-top"></div>
281
+ <div class="sf-feature-card__border-right"></div>
282
+ <div class="sf-feature-card__border-bottom"></div>
283
+ <div class="sf-feature-card__border-left"></div>
284
+ </div>
285
+ <div class="sf-feature-card__glow"></div>
286
+ <div class="sf-feature-card__content">
287
+ <div class="sf-feature-card__icon-wrapper">
288
+ <div class="sf-feature-card__icon">
289
+ <span role="img" aria-hidden="true">${icon}</span>
290
+ </div>
291
+ </div>
292
+ <div class="sf-feature-card__text">
293
+ <h3 class="sf-feature-card__title">${title}</h3>
294
+ <p class="sf-feature-card__description">${description}</p>
295
+ </div>
296
+ ${link ? `
297
+ <div class="sf-feature-card__arrow">
298
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
299
+ <path d="M7 17L17 7M17 7H7M17 7V17"/>
300
+ </svg>
301
+ </div>
302
+ ` : ''}
303
+ </div>
304
+ <div class="sf-feature-card__ripple"></div>
305
+ </div>
306
+ `;
307
+
308
+ this.elements.grid.insertAdjacentHTML('beforeend', cardHTML);
309
+ this.setupCards(); // Re-setup cards with new element
310
+ }
311
+
312
+ updateFeature(index, featureData) {
313
+ const card = this.config.cardElements[index];
314
+ if (!card) return;
315
+
316
+ const { icon, title, description, link } = featureData;
317
+
318
+ if (icon) {
319
+ const iconElement = card.querySelector('.sf-feature-card__icon span');
320
+ if (iconElement) iconElement.textContent = icon;
321
+ }
322
+
323
+ if (title) {
324
+ const titleElement = card.querySelector('.sf-feature-card__title');
325
+ if (titleElement) titleElement.textContent = title;
326
+ }
327
+
328
+ if (description) {
329
+ const descElement = card.querySelector('.sf-feature-card__description');
330
+ if (descElement) descElement.textContent = description;
331
+ }
332
+
333
+ if (link !== undefined) {
334
+ card.setAttribute('data-link', link);
335
+ }
336
+ }
337
+
338
+ removeFeature(index) {
339
+ const card = this.config.cardElements[index];
340
+ if (card) {
341
+ card.remove();
342
+ this.setupCards(); // Re-setup after removal
343
+ }
344
+ }
345
+
346
+ resetAnimations() {
347
+ this.config.isVisible = false;
348
+ this.config.visibleCards.clear();
349
+
350
+ this.elements.container.classList.remove('sf-feature-cards--visible');
351
+ this.config.cardElements.forEach(card => {
352
+ card.classList.remove('sf-feature-card--visible');
353
+ });
354
+
355
+ if (this.elements.cta) {
356
+ this.elements.cta.classList.remove('sf-feature-cards__cta--visible');
357
+ }
358
+ }
359
+
360
+ destroy() {
361
+ // Cleanup method
362
+ this.resetAnimations();
363
+ // Remove event listeners if needed
364
+ }
365
+ }
366
+
367
+ // Auto-initialize on DOM content loaded
368
+ document.addEventListener('DOMContentLoaded', () => {
369
+ // Check if feature cards exist before initializing
370
+ const featureCardsElement = document.getElementById('sf-feature-cards');
371
+ if (featureCardsElement) {
372
+ window.snowFlowFeatureCards = new SnowFlowFeatureCards();
373
+ }
374
+ });
375
+
376
+ // Export for module usage
377
+ if (typeof module !== 'undefined' && module.exports) {
378
+ module.exports = SnowFlowFeatureCards;
379
+ }
380
+
381
+ // Global access
382
+ window.SnowFlowFeatureCards = SnowFlowFeatureCards;