bubble-chart-js 1.0.19 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +1 -1
  2. package/demo/glassmorphism.html +323 -0
  3. package/demo/index.html +739 -0
  4. package/dist/bubbleChart.cjs.js +1 -1
  5. package/dist/bubbleChart.esm.js +1 -1
  6. package/dist/bubbleChart.umd.js +1 -1
  7. package/docs/documentation.html +438 -0
  8. package/docs/examples.html +689 -0
  9. package/docs/index.html +432 -0
  10. package/docs/landing_test.html +337 -0
  11. package/docs/playground.html +345 -0
  12. package/docs/process_html.js +105 -0
  13. package/docs/temp/5a86d.html +248 -0
  14. package/docs/temp/b0cbe.html +276 -0
  15. package/docs/temp/docs_desktop.html +341 -0
  16. package/docs/temp/docs_mobile.html +291 -0
  17. package/docs/temp/examples_desktop.html +372 -0
  18. package/docs/temp/examples_mobile.html +317 -0
  19. package/docs/temp/landing_desktop.html +337 -0
  20. package/docs/temp/landing_mobile.html +270 -0
  21. package/docs/temp/playground_desktop.html +283 -0
  22. package/docs/temp/playground_mobile.html +236 -0
  23. package/examples/test.html +194 -0
  24. package/examples/test2.html +103 -0
  25. package/package.json +7 -3
  26. package/scripts/generate-fixtures.ts +45 -0
  27. package/spec/config-defaults.json +16 -0
  28. package/spec/fixtures/3-bubbles.expected.json +27 -0
  29. package/spec/fixtures/3-bubbles.input.json +10 -0
  30. package/spec/fixtures/equal-values.expected.json +34 -0
  31. package/spec/fixtures/equal-values.input.json +11 -0
  32. package/spec/fixtures/many-bubbles.expected.json +76 -0
  33. package/spec/fixtures/many-bubbles.input.json +17 -0
  34. package/spec/fixtures/single-bubble.expected.json +13 -0
  35. package/spec/fixtures/single-bubble.input.json +8 -0
  36. package/spec/physics.json +11 -0
  37. package/tsconfig.scripts.json +8 -0
  38. package/dist/canvas.d.ts +0 -5
  39. package/dist/constants/app-constants.d.ts +0 -3
  40. package/dist/constants/physics.d.ts +0 -10
  41. package/dist/core/renderer.d.ts +0 -2
  42. package/dist/features/text-wrapper.d.ts +0 -2
  43. package/dist/features/tooltip.d.ts +0 -6
  44. package/dist/index.d.ts +0 -8
  45. package/dist/models/internal/data-item-info.d.ts +0 -7
  46. package/dist/models/public/bubble-chart.d.ts +0 -6
  47. package/dist/models/public/config/bubble-appearance.d.ts +0 -26
  48. package/dist/models/public/config/font-options.d.ts +0 -46
  49. package/dist/models/public/config/interaction-options.d.ts +0 -6
  50. package/dist/models/public/config/tooltip-config.d.ts +0 -4
  51. package/dist/models/public/config/tooltip-options.d.ts +0 -170
  52. package/dist/models/public/configuration.d.ts +0 -30
  53. package/dist/models/public/data-item.d.ts +0 -8
  54. package/dist/services/chart-service.d.ts +0 -5
  55. package/dist/services/render-service.d.ts +0 -3
  56. package/dist/utils/config.d.ts +0 -12
  57. package/dist/utils/helper.d.ts +0 -2
  58. package/dist/utils/validation.d.ts +0 -5
@@ -0,0 +1,372 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html class="dark" lang="en">
4
+
5
+ <head>
6
+ <meta charset="utf-8" />
7
+ <meta content="width=device-width, initial-scale=1.0" name="viewport" />
8
+ <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
9
+ <link
10
+ href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;700;800&amp;family=Inter:wght@400;500;600&amp;family=Space+Grotesk:wght@500;700&amp;display=swap"
11
+ rel="stylesheet" />
12
+ <link
13
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap"
14
+ rel="stylesheet" />
15
+ <link
16
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap"
17
+ rel="stylesheet" />
18
+ <script id="tailwind-config">
19
+ tailwind.config = {
20
+ darkMode: "class",
21
+ theme: {
22
+ extend: {
23
+ colors: {
24
+ "surface": "#090e1c",
25
+ "on-tertiary-container": "#005b29",
26
+ "on-error": "#490006",
27
+ "on-surface-variant": "#a6aabf",
28
+ "outline-variant": "#434759",
29
+ "surface-tint": "#72dcff",
30
+ "on-secondary-fixed": "#580078",
31
+ "surface-container": "#13192b",
32
+ "tertiary-fixed-dim": "#33ec7b",
33
+ "surface-container-highest": "#1e253b",
34
+ "error-container": "#9f0519",
35
+ "on-primary-fixed-variant": "#004c5e",
36
+ "on-tertiary-fixed-variant": "#00662e",
37
+ "inverse-surface": "#faf8ff",
38
+ "on-secondary-container": "#f1bfff",
39
+ "primary-fixed": "#00d2ff",
40
+ "on-surface": "#e1e4fa",
41
+ "secondary": "#dd8bfb",
42
+ "surface-variant": "#1e253b",
43
+ "primary-fixed-dim": "#00c3ed",
44
+ "surface-bright": "#242b43",
45
+ "on-primary-fixed": "#002c38",
46
+ "error-dim": "#d7383b",
47
+ "surface-dim": "#090e1c",
48
+ "on-secondary": "#4c0068",
49
+ "tertiary-dim": "#33ec7b",
50
+ "background": "#090e1c",
51
+ "secondary-dim": "#ce7eec",
52
+ "inverse-on-surface": "#505466",
53
+ "secondary-fixed-dim": "#ebadff",
54
+ "inverse-primary": "#00687f",
55
+ "tertiary": "#a6ffb5",
56
+ "on-error-container": "#ffa8a3",
57
+ "on-tertiary-fixed": "#00461e",
58
+ "tertiary-container": "#49fb87",
59
+ "surface-container-high": "#181f33",
60
+ "error": "#ff716c",
61
+ "primary-dim": "#00c3ed",
62
+ "secondary-container": "#6e208c",
63
+ "on-tertiary": "#00652e",
64
+ "on-primary": "#004c5e",
65
+ "surface-container-low": "#0d1323",
66
+ "on-primary-container": "#004253",
67
+ "outline": "#707588",
68
+ "on-background": "#e1e4fa",
69
+ "surface-container-lowest": "#000000",
70
+ "primary-container": "#00d2ff",
71
+ "on-secondary-fixed-variant": "#792c97",
72
+ "primary": "#72dcff",
73
+ "tertiary-fixed": "#49fb87",
74
+ "secondary-fixed": "#f2c1ff"
75
+ },
76
+ fontFamily: {
77
+ "headline": ["Manrope"],
78
+ "body": ["Inter"],
79
+ "label": ["Space Grotesk"]
80
+ },
81
+ borderRadius: { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" },
82
+ },
83
+ },
84
+ }
85
+ </script>
86
+ <style>
87
+ .glass-panel {
88
+ background: rgba(30, 37, 59, 0.6);
89
+ backdrop-filter: blur(12px);
90
+ }
91
+
92
+ .neon-glow-primary:hover {
93
+ box-shadow: 0 0 15px rgba(114, 220, 255, 0.4);
94
+ }
95
+
96
+ .neon-gradient {
97
+ background: linear-gradient(135deg, #72dcff 0%, #00d2ff 100%);
98
+ }
99
+
100
+ .material-symbols-outlined {
101
+ font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
102
+ }
103
+ </style>
104
+ </head>
105
+
106
+ <body class="bg-background text-on-surface font-body selection:bg-primary/30">
107
+ <!-- TopNavBar -->
108
+ <nav class="fixed top-0 w-full z-50 bg-[#090e1c]/60 backdrop-blur-xl shadow-[0_20px_40px_rgba(0,0,0,0.4)]">
109
+ <div class="flex justify-between items-center h-16 px-8 max-w-7xl mx-auto">
110
+ <div class="flex items-center gap-2">
111
+ <span class="material-symbols-outlined text-primary"
112
+ style="font-variation-settings: 'FILL' 1;">bubble_chart</span>
113
+ <span class="text-xl font-black text-[#72dcff] tracking-tighter font-headline">bubble-chart-js</span>
114
+ </div>
115
+ <div class="hidden md:flex items-center gap-8 font-headline font-bold tracking-tight">
116
+ <a class="text-[#e1e4fa] opacity-80 hover:text-[#dd8bfb] transition-colors duration-300" href="#">Docs</a>
117
+ <a class="text-[#72dcff] border-b-2 border-[#72dcff] pb-1 hover:text-[#dd8bfb] transition-colors duration-300"
118
+ href="#">Examples</a>
119
+ <a class="text-[#e1e4fa] opacity-80 hover:text-[#dd8bfb] transition-colors duration-300" href="#">Playground</a>
120
+ <a class="text-[#e1e4fa] opacity-80 hover:text-[#dd8bfb] transition-colors duration-300" href="#">GitHub</a>
121
+ </div>
122
+ <div class="flex items-center gap-4">
123
+ <button class="material-symbols-outlined text-[#e1e4fa] opacity-80 hover:text-[#dd8bfb]">dark_mode</button>
124
+ <button
125
+ class="neon-gradient text-on-primary-fixed px-5 py-2 rounded-xl font-headline font-bold text-sm active:scale-95 duration-200 transition-all">Get
126
+ Started</button>
127
+ </div>
128
+ </div>
129
+ </nav>
130
+ <main class="pt-32 pb-24 px-8 max-w-7xl mx-auto">
131
+ <!-- Header Section -->
132
+ <header class="mb-20 max-w-2xl">
133
+ <div
134
+ class="inline-block px-3 py-1 rounded-full bg-surface-container-highest border border-outline-variant/15 mb-6">
135
+ <span class="font-label text-xs uppercase tracking-[0.2em] text-secondary font-bold">Showcase</span>
136
+ </div>
137
+ <h1
138
+ class="text-5xl md:text-7xl font-headline font-extrabold tracking-tight mb-6 bg-clip-text text-transparent bg-gradient-to-b from-on-surface to-on-surface-variant">
139
+ Examples Gallery
140
+ </h1>
141
+ <p class="text-on-surface-variant text-lg leading-relaxed">
142
+ Explore our curated collection of atmospheric data visualizations. From basic clusters to complex physics-based
143
+ simulations, everything is customizable.
144
+ </p>
145
+ </header>
146
+ <!-- Bento Grid Gallery -->
147
+ <div class="grid grid-cols-1 md:grid-cols-12 gap-6">
148
+ <!-- Featured: Basic Bubble Chart -->
149
+ <div
150
+ class="md:col-span-8 group relative overflow-hidden rounded-xl bg-surface-container-high border border-outline-variant/10 shadow-[0_20px_40px_rgba(0,0,0,0.4)]">
151
+ <div class="aspect-[16/9] relative bg-surface-container-lowest overflow-hidden">
152
+ <div
153
+ class="absolute inset-0 opacity-40 bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-primary/20 via-transparent to-transparent">
154
+ </div>
155
+ <!-- Live Demo Placeholder -->
156
+ <div class="absolute inset-0 flex items-center justify-center">
157
+ <div class="w-full h-full flex items-center justify-center"
158
+ data-alt="Abstract blue floating bubbles visualization">
159
+ <div class="relative w-64 h-64">
160
+ <div class="absolute top-0 left-0 w-32 h-32 rounded-full bg-primary/40 blur-xl animate-pulse"></div>
161
+ <div class="absolute bottom-10 right-10 w-48 h-48 rounded-full bg-secondary/30 blur-2xl"></div>
162
+ <div
163
+ class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-40 h-40 border border-primary/20 rounded-full flex items-center justify-center">
164
+ <div class="w-4 h-4 rounded-full bg-primary shadow-[0_0_10px_#72dcff]"></div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ <div class="absolute top-4 left-4">
170
+ <span
171
+ class="font-label text-[10px] font-bold px-2 py-1 rounded bg-surface-bright/80 text-on-surface-variant border border-outline-variant/15 backdrop-blur-md">SVG
172
+ - AUTO</span>
173
+ </div>
174
+ </div>
175
+ <div class="p-8 glass-panel border-t border-outline-variant/10">
176
+ <div class="flex justify-between items-start mb-4">
177
+ <div>
178
+ <h3 class="text-2xl font-headline font-bold text-primary mb-1">Basic bubble chart</h3>
179
+ <p class="text-on-surface-variant text-sm">The foundation of every visualization. Optimized for clarity
180
+ and performance.</p>
181
+ </div>
182
+ <button
183
+ class="flex items-center gap-2 px-4 py-2 bg-surface-variant/40 hover:bg-surface-variant/80 rounded-lg text-sm font-label font-bold transition-all border border-outline-variant/15">
184
+ <span class="material-symbols-outlined text-sm">code</span> View Code
185
+ </button>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ <!-- Side Card: Glass Theme -->
190
+ <div
191
+ class="md:col-span-4 group relative overflow-hidden rounded-xl bg-surface-container-high border border-outline-variant/10">
192
+ <div class="aspect-square relative bg-surface-container-lowest">
193
+ <div class="absolute inset-0 bg-gradient-to-tr from-secondary/10 to-transparent"></div>
194
+ <div class="absolute inset-0 flex items-center justify-center"
195
+ data-alt="Purple glassmorphism bubble clusters">
196
+ <div
197
+ class="w-32 h-32 rounded-full glass-panel border border-outline-variant/20 shadow-xl flex items-center justify-center">
198
+ <div class="w-16 h-16 rounded-full bg-secondary/20 border border-secondary/40"></div>
199
+ </div>
200
+ </div>
201
+ <div class="absolute top-4 left-4">
202
+ <span
203
+ class="font-label text-[10px] font-bold px-2 py-1 rounded bg-surface-bright/80 text-on-surface-variant border border-outline-variant/15 backdrop-blur-md">CANVAS
204
+ - AUTO</span>
205
+ </div>
206
+ </div>
207
+ <div class="p-6">
208
+ <h3 class="text-xl font-headline font-bold text-on-surface mb-2">Glass theme</h3>
209
+ <p class="text-on-surface-variant text-sm mb-6">Utilizing backdrop-filters for immersive depth in your data.
210
+ </p>
211
+ <button
212
+ class="w-full flex items-center justify-center gap-2 px-4 py-2 bg-surface-variant/20 hover:bg-surface-variant/40 rounded-lg text-xs font-label font-bold transition-all border border-outline-variant/15">
213
+ <span class="material-symbols-outlined text-sm">code</span> VIEW SOURCE
214
+ </button>
215
+ </div>
216
+ </div>
217
+ <!-- Row 2: Physics, Dataset, Custom Colors, Interactive -->
218
+ <div class="md:col-span-4 rounded-xl bg-surface-container-high border border-outline-variant/10 overflow-hidden">
219
+ <div class="h-48 relative bg-surface-container-lowest flex items-center justify-center overflow-hidden"
220
+ data-alt="Dynamic physics simulation of moving bubbles">
221
+ <div class="w-full px-8 flex justify-around items-end h-32">
222
+ <div class="w-4 h-12 bg-tertiary/40 rounded-full animate-bounce"></div>
223
+ <div class="w-4 h-24 bg-tertiary/60 rounded-full animate-bounce [animation-delay:0.2s]"></div>
224
+ <div class="w-4 h-16 bg-tertiary/20 rounded-full animate-bounce [animation-delay:0.4s]"></div>
225
+ <div class="w-4 h-28 bg-tertiary/80 rounded-full animate-bounce [animation-delay:0.1s]"></div>
226
+ </div>
227
+ <div class="absolute top-4 left-4">
228
+ <span
229
+ class="font-label text-[10px] font-bold px-2 py-1 rounded bg-surface-bright/80 text-on-surface-variant border border-outline-variant/15">CANVAS</span>
230
+ </div>
231
+ </div>
232
+ <div class="p-6">
233
+ <h3 class="font-headline font-bold text-tertiary mb-2">Physics layout</h3>
234
+ <p class="text-on-surface-variant text-sm mb-4">Collision detection and gravitational fields for organic
235
+ motion.</p>
236
+ <button
237
+ class="text-xs font-label font-bold text-on-surface-variant hover:text-primary transition-colors flex items-center gap-1 uppercase tracking-wider">
238
+ Quick Preview <span class="material-symbols-outlined text-[16px]">arrow_outward</span>
239
+ </button>
240
+ </div>
241
+ </div>
242
+ <div class="md:col-span-4 rounded-xl bg-surface-container-high border border-outline-variant/10 overflow-hidden">
243
+ <div class="h-48 relative bg-surface-container-lowest flex items-center justify-center"
244
+ data-alt="Grid of many small colorful bubbles representing large dataset">
245
+ <div class="grid grid-cols-8 gap-1 opacity-40">
246
+ <div class="w-2 h-2 rounded-full bg-primary-fixed"></div>
247
+ <div class="w-2 h-2 rounded-full bg-secondary"></div>
248
+ <div class="w-2 h-2 rounded-full bg-tertiary"></div>
249
+ <div class="w-2 h-2 rounded-full bg-primary"></div>
250
+ <div class="w-2 h-2 rounded-full bg-on-surface-variant"></div>
251
+ <div class="w-2 h-2 rounded-full bg-primary-fixed"></div>
252
+ <div class="w-2 h-2 rounded-full bg-secondary"></div>
253
+ <div class="w-2 h-2 rounded-full bg-tertiary"></div>
254
+ <!-- ... more bubbles visual ... -->
255
+ </div>
256
+ <div class="absolute top-4 left-4">
257
+ <span
258
+ class="font-label text-[10px] font-bold px-2 py-1 rounded bg-surface-bright/80 text-on-surface-variant border border-outline-variant/15">CANVAS</span>
259
+ </div>
260
+ </div>
261
+ <div class="p-6">
262
+ <h3 class="font-headline font-bold text-on-surface mb-2">Large dataset (100+)</h3>
263
+ <p class="text-on-surface-variant text-sm mb-4">Stress-testing the engine with high-volume data points.</p>
264
+ <button
265
+ class="text-xs font-label font-bold text-on-surface-variant hover:text-primary transition-colors flex items-center gap-1 uppercase tracking-wider">
266
+ Quick Preview <span class="material-symbols-outlined text-[16px]">arrow_outward</span>
267
+ </button>
268
+ </div>
269
+ </div>
270
+ <div class="md:col-span-4 rounded-xl bg-surface-container-high border border-outline-variant/10 overflow-hidden">
271
+ <div class="h-48 relative bg-surface-container-lowest overflow-hidden flex items-center justify-center"
272
+ data-alt="Multicolor glowing bubbles on dark background">
273
+ <div class="flex gap-4">
274
+ <div class="w-12 h-12 rounded-full bg-error/40 border-2 border-error blur-sm"></div>
275
+ <div class="w-12 h-12 rounded-full bg-secondary/40 border-2 border-secondary blur-sm"></div>
276
+ <div class="w-12 h-12 rounded-full bg-primary/40 border-2 border-primary blur-sm"></div>
277
+ </div>
278
+ <div class="absolute top-4 left-4">
279
+ <span
280
+ class="font-label text-[10px] font-bold px-2 py-1 rounded bg-surface-bright/80 text-on-surface-variant border border-outline-variant/15">SVG</span>
281
+ </div>
282
+ </div>
283
+ <div class="p-6">
284
+ <h3 class="font-headline font-bold text-secondary mb-2">Custom colors</h3>
285
+ <p class="text-on-surface-variant text-sm mb-4">Gradient mappings and per-node styling for branded charts.</p>
286
+ <button
287
+ class="text-xs font-label font-bold text-on-surface-variant hover:text-primary transition-colors flex items-center gap-1 uppercase tracking-wider">
288
+ Quick Preview <span class="material-symbols-outlined text-[16px]">arrow_outward</span>
289
+ </button>
290
+ </div>
291
+ </div>
292
+ <!-- Bottom Wide Card -->
293
+ <div
294
+ class="md:col-span-12 group relative overflow-hidden rounded-xl bg-surface-container-high border border-outline-variant/10 mt-6">
295
+ <div class="flex flex-col md:flex-row items-stretch">
296
+ <div class="w-full md:w-1/2 aspect-video bg-surface-container-lowest relative"
297
+ data-alt="Hand hovering over a bubble chart node indicating interactivity">
298
+ <div class="absolute inset-0 flex items-center justify-center">
299
+ <div class="relative">
300
+ <div
301
+ class="w-32 h-32 rounded-full border-2 border-dashed border-primary/40 animate-[spin_10s_linear_infinite]">
302
+ </div>
303
+ <div
304
+ class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-16 h-16 rounded-full bg-primary shadow-[0_0_30px_#72dcff]">
305
+ </div>
306
+ <div class="absolute -top-10 -right-10 glass-panel p-2 rounded border border-outline-variant/20">
307
+ <div class="font-label text-[10px] text-primary">onBubbleClick: (e) =&gt; {...}</div>
308
+ </div>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ <div class="w-full md:w-1/2 p-8 md:p-12 flex flex-col justify-center glass-panel">
313
+ <span class="font-label text-xs text-primary font-bold uppercase tracking-widest mb-4">Developer
314
+ Experience</span>
315
+ <h3 class="text-3xl font-headline font-bold text-on-surface mb-4">Interactive events</h3>
316
+ <p class="text-on-surface-variant text-base mb-8">Full control over mouse and touch events. Hook into click,
317
+ hover, drag, and collision lifecycle events with standard JS syntax.</p>
318
+ <div class="flex gap-4">
319
+ <button
320
+ class="neon-gradient text-on-primary-fixed px-6 py-3 rounded-lg font-headline font-bold transition-transform hover:scale-105">View
321
+ Example</button>
322
+ <button
323
+ class="px-6 py-3 rounded-lg border border-outline-variant/20 font-headline font-bold hover:bg-surface-bright transition-colors">Documentation</button>
324
+ </div>
325
+ </div>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ </main>
330
+ <!-- Footer -->
331
+ <footer class="bg-[#090e1c] w-full py-12 px-8 border-t border-[#434759]/15">
332
+ <div class="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-4 gap-8">
333
+ <div class="col-span-1">
334
+ <div class="text-lg font-bold text-[#72dcff] mb-4 font-headline">bubble-chart-js</div>
335
+ <p class="font-['Inter'] text-sm text-[#e1e4fa]/60 leading-relaxed">
336
+ © 2024 bubble-chart-js. Built for atmospheric data visualization. Precision engineering meets fluid
337
+ aesthetics.
338
+ </p>
339
+ </div>
340
+ <div>
341
+ <h4 class="font-label text-xs uppercase font-bold text-on-surface mb-6 tracking-[0.2em]">Resources</h4>
342
+ <ul class="space-y-3 font-['Inter'] text-sm text-[#e1e4fa]/60">
343
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">Docs</a></li>
344
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">Examples</a></li>
345
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">GitHub</a></li>
346
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="https://www.npmjs.com/package/bubble-chart-js"
347
+ target="_blank" rel="noopener noreferrer">NPM</a></li>
348
+ </ul>
349
+ </div>
350
+ <div>
351
+ <h4 class="font-label text-xs uppercase font-bold text-on-surface mb-6 tracking-[0.2em]">Community</h4>
352
+ <ul class="space-y-3 font-['Inter'] text-sm text-[#e1e4fa]/60">
353
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">Twitter</a></li>
354
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">Discord</a></li>
355
+ <li><a class="hover:text-[#dd8bfb] transition-opacity" href="#">License</a></li>
356
+ </ul>
357
+ </div>
358
+ <div>
359
+ <h4 class="font-label text-xs uppercase font-bold text-on-surface mb-6 tracking-[0.2em]">Newsletter</h4>
360
+ <div class="flex gap-2">
361
+ <input
362
+ class="bg-surface-container border-none rounded-lg px-4 py-2 text-sm focus:ring-1 focus:ring-primary w-full"
363
+ placeholder="email@example.com" type="email" />
364
+ <button
365
+ class="material-symbols-outlined bg-primary text-on-primary-fixed p-2 rounded-lg">arrow_forward</button>
366
+ </div>
367
+ </div>
368
+ </div>
369
+ </footer>
370
+ </body>
371
+
372
+ </html>