F555 commited on
Commit
101f454
·
verified ·
1 Parent(s): b07bbd4

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +711 -19
index.html CHANGED
@@ -1,19 +1,711 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Nexus Dashboard | Modern UI Showcase</title>
7
+ <!-- Importing FontAwesome for Icons -->
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <!-- Importing Google Fonts -->
10
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
11
+
12
+ <style>
13
+ /* --- CSS VARIABLES & THEME SETUP --- */
14
+ :root {
15
+ /* Default: Cyberpunk Theme */
16
+ --bg-body: #050505;
17
+ --bg-panel: rgba(20, 20, 25, 0.6);
18
+ --bg-card: rgba(255, 255, 255, 0.03);
19
+ --primary: #00f2ff;
20
+ --secondary: #7000ff;
21
+ --accent: #ff0055;
22
+ --text-main: #ffffff;
23
+ --text-muted: #8888aa;
24
+ --border: 1px solid rgba(255, 255, 255, 0.1);
25
+ --shadow-glow: 0 0 20px rgba(0, 242, 255, 0.15);
26
+ --font-main: 'Outfit', sans-serif;
27
+ --font-mono: 'Space Mono', monospace;
28
+ --transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
29
+ --radius: 16px;
30
+ }
31
+
32
+ /* Light / Minimalist Theme */
33
+ [data-theme="light"] {
34
+ --bg-body: #f0f2f5;
35
+ --bg-panel: rgba(255, 255, 255, 0.8);
36
+ --bg-card: #ffffff;
37
+ --primary: #2563eb;
38
+ --secondary: #7c3aed;
39
+ --accent: #db2777;
40
+ --text-main: #1e293b;
41
+ --text-muted: #64748b;
42
+ --border: 1px solid rgba(0, 0, 0, 0.05);
43
+ --shadow-glow: 0 10px 30px rgba(0, 0, 0, 0.05);
44
+ }
45
+
46
+ /* --- GLOBAL RESET --- */
47
+ * {
48
+ margin: 0;
49
+ padding: 0;
50
+ box-sizing: border-box;
51
+ }
52
+
53
+ body {
54
+ font-family: var(--font-main);
55
+ background-color: var(--bg-body);
56
+ color: var(--text-main);
57
+ min-height: 100vh;
58
+ overflow-x: hidden;
59
+ transition: background-color 0.5s ease;
60
+ background-image:
61
+ radial-gradient(circle at 10% 20%, rgba(112, 0, 255, 0.1) 0%, transparent 40%),
62
+ radial-gradient(circle at 90% 80%, rgba(0, 242, 255, 0.1) 0%, transparent 40%);
63
+ background-attachment: fixed;
64
+ }
65
+
66
+ /* --- SCROLLBAR --- */
67
+ ::-webkit-scrollbar {
68
+ width: 8px;
69
+ }
70
+ ::-webkit-scrollbar-track {
71
+ background: var(--bg-body);
72
+ }
73
+ ::-webkit-scrollbar-thumb {
74
+ background: var(--primary);
75
+ border-radius: 4px;
76
+ }
77
+
78
+ /* --- LAYOUT UTILITIES --- */
79
+ .container {
80
+ max-width: 1400px;
81
+ margin: 0 auto;
82
+ padding: 2rem;
83
+ }
84
+
85
+ /* --- HEADER --- */
86
+ header {
87
+ display: flex;
88
+ justify-content: space-between;
89
+ align-items: center;
90
+ padding: 1.5rem 2rem;
91
+ margin-bottom: 2rem;
92
+ background: var(--bg-panel);
93
+ backdrop-filter: blur(12px);
94
+ -webkit-backdrop-filter: blur(12px);
95
+ border: var(--border);
96
+ border-radius: var(--radius);
97
+ position: sticky;
98
+ top: 20px;
99
+ z-index: 100;
100
+ box-shadow: var(--shadow-glow);
101
+ }
102
+
103
+ .brand {
104
+ display: flex;
105
+ align-items: center;
106
+ gap: 1rem;
107
+ }
108
+
109
+ .brand i {
110
+ font-size: 1.8rem;
111
+ color: var(--primary);
112
+ animation: pulse 3s infinite;
113
+ }
114
+
115
+ .brand h1 {
116
+ font-size: 1.5rem;
117
+ font-weight: 800;
118
+ letter-spacing: -0.5px;
119
+ background: linear-gradient(to right, var(--primary), var(--secondary));
120
+ -webkit-background-clip: text;
121
+ -webkit-text-fill-color: transparent;
122
+ }
123
+
124
+ .header-controls {
125
+ display: flex;
126
+ align-items: center;
127
+ gap: 1.5rem;
128
+ }
129
+
130
+ .anycoder-link {
131
+ font-family: var(--font-mono);
132
+ font-size: 0.85rem;
133
+ color: var(--text-muted);
134
+ text-decoration: none;
135
+ border: 1px dashed var(--text-muted);
136
+ padding: 0.4rem 0.8rem;
137
+ border-radius: 4px;
138
+ transition: var(--transition);
139
+ }
140
+
141
+ .anycoder-link:hover {
142
+ color: var(--primary);
143
+ border-color: var(--primary);
144
+ box-shadow: 0 0 10px rgba(0, 242, 255, 0.2);
145
+ }
146
+
147
+ .theme-toggle {
148
+ background: none;
149
+ border: none;
150
+ color: var(--text-main);
151
+ font-size: 1.2rem;
152
+ cursor: pointer;
153
+ transition: transform 0.3s ease;
154
+ }
155
+ .theme-toggle:hover {
156
+ transform: rotate(15deg) scale(1.1);
157
+ color: var(--primary);
158
+ }
159
+
160
+ /* --- DASHBOARD GRID --- */
161
+ .dashboard-grid {
162
+ display: grid;
163
+ grid-template-columns: repeat(12, 1fr);
164
+ grid-template-rows: auto auto;
165
+ gap: 1.5rem;
166
+ }
167
+
168
+ /* --- CARD STYLES --- */
169
+ .card {
170
+ background: var(--bg-card);
171
+ border: var(--border);
172
+ border-radius: var(--radius);
173
+ padding: 1.5rem;
174
+ position: relative;
175
+ overflow: hidden;
176
+ transition: var(--transition);
177
+ backdrop-filter: blur(5px);
178
+ }
179
+
180
+ .card::before {
181
+ content: '';
182
+ position: absolute;
183
+ top: 0;
184
+ left: 0;
185
+ width: 100%;
186
+ height: 2px;
187
+ background: linear-gradient(90deg, var(--primary), var(--secondary));
188
+ opacity: 0;
189
+ transition: opacity 0.3s ease;
190
+ }
191
+
192
+ .card:hover {
193
+ transform: translateY(-5px);
194
+ box-shadow: var(--shadow-glow);
195
+ border-color: rgba(255, 255, 255, 0.2);
196
+ }
197
+
198
+ .card:hover::before {
199
+ opacity: 1;
200
+ }
201
+
202
+ .card-header {
203
+ display: flex;
204
+ justify-content: space-between;
205
+ align-items: center;
206
+ margin-bottom: 1.5rem;
207
+ }
208
+
209
+ .card-title {
210
+ font-size: 1.1rem;
211
+ font-weight: 600;
212
+ color: var(--text-main);
213
+ display: flex;
214
+ align-items: center;
215
+ gap: 0.5rem;
216
+ }
217
+
218
+ .card-title i {
219
+ color: var(--secondary);
220
+ }
221
+
222
+ /* --- SECTION: HERO STATS (Top Row) --- */
223
+ .stat-card {
224
+ grid-column: span 3;
225
+ display: flex;
226
+ flex-direction: column;
227
+ justify-content: space-between;
228
+ min-height: 140px;
229
+ }
230
+
231
+ .stat-value {
232
+ font-size: 2.5rem;
233
+ font-weight: 800;
234
+ font-family: var(--font-mono);
235
+ color: var(--text-main);
236
+ }
237
+
238
+ .stat-trend {
239
+ font-size: 0.9rem;
240
+ display: flex;
241
+ align-items: center;
242
+ gap: 0.5rem;
243
+ }
244
+
245
+ .trend-up { color: var(--primary); }
246
+ .trend-down { color: var(--accent); }
247
+
248
+ /* --- SECTION: 3D VISUALIZER --- */
249
+ .visualizer-section {
250
+ grid-column: span 8;
251
+ min-height: 400px;
252
+ display: flex;
253
+ align-items: center;
254
+ justify-content: center;
255
+ position: relative;
256
+ }
257
+
258
+ canvas#particleCanvas {
259
+ position: absolute;
260
+ top: 0;
261
+ left: 0;
262
+ width: 100%;
263
+ height: 100%;
264
+ z-index: 1;
265
+ }
266
+
267
+ .visualizer-overlay {
268
+ z-index: 2;
269
+ text-align: center;
270
+ pointer-events: none; /* Let clicks pass to canvas */
271
+ }
272
+
273
+ .visualizer-overlay h2 {
274
+ font-size: 2rem;
275
+ text-shadow: 0 0 20px rgba(0,0,0,0.5);
276
+ }
277
+
278
+ /* --- SECTION: INTERACTIVE TILT CARDS --- */
279
+ .tilt-section {
280
+ grid-column: span 4;
281
+ display: flex;
282
+ flex-direction: column;
283
+ gap: 1rem;
284
+ }
285
+
286
+ .tilt-card {
287
+ flex: 1;
288
+ background: linear-gradient(135deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
289
+ border: 1px solid rgba(255,255,255,0.05);
290
+ border-radius: 12px;
291
+ display: flex;
292
+ align-items: center;
293
+ padding: 1.5rem;
294
+ cursor: pointer;
295
+ transform-style: preserve-3d;
296
+ transform: perspective(1000px);
297
+ transition: transform 0.1s; /* Fast for smooth mouse follow */
298
+ }
299
+
300
+ .tilt-icon {
301
+ width: 50px;
302
+ height: 50px;
303
+ background: rgba(0, 242, 255, 0.1);
304
+ border-radius: 12px;
305
+ display: flex;
306
+ align-items: center;
307
+ justify-content: center;
308
+ font-size: 1.5rem;
309
+ color: var(--primary);
310
+ margin-right: 1rem;
311
+ box-shadow: 0 0 15px rgba(0, 242, 255, 0.1);
312
+ }
313
+
314
+ .tilt-content h3 {
315
+ font-size: 1rem;
316
+ margin-bottom: 0.2rem;
317
+ }
318
+ .tilt-content p {
319
+ font-size: 0.8rem;
320
+ color: var(--text-muted);
321
+ }
322
+
323
+ /* --- SECTION: DATA TABLE --- */
324
+ .table-section {
325
+ grid-column: span 12;
326
+ overflow-x: auto;
327
+ }
328
+
329
+ table {
330
+ width: 100%;
331
+ border-collapse: collapse;
332
+ font-size: 0.95rem;
333
+ }
334
+
335
+ th {
336
+ text-align: left;
337
+ padding: 1rem;
338
+ color: var(--text-muted);
339
+ font-weight: 600;
340
+ border-bottom: 1px solid rgba(255,255,255,0.1);
341
+ }
342
+
343
+ td {
344
+ padding: 1rem;
345
+ border-bottom: 1px solid rgba(255,255,255,0.05);
346
+ color: var(--text-main);
347
+ }
348
+
349
+ tr:hover td {
350
+ background: rgba(255,255,255,0.02);
351
+ color: var(--primary);
352
+ }
353
+
354
+ .status-badge {
355
+ padding: 0.3rem 0.8rem;
356
+ border-radius: 20px;
357
+ font-size: 0.75rem;
358
+ font-weight: 600;
359
+ text-transform: uppercase;
360
+ }
361
+ .status-active { background: rgba(0, 242, 255, 0.15); color: var(--primary); }
362
+ .status-pending { background: rgba(255, 165, 0, 0.15); color: orange; }
363
+ .status-error { background: rgba(255, 0, 85, 0.15); color: var(--accent); }
364
+
365
+ /* --- ANIMATIONS --- */
366
+ @keyframes pulse {
367
+ 0% { opacity: 0.8; transform: scale(1); text-shadow: 0 0 10px var(--primary); }
368
+ 50% { opacity: 1; transform: scale(1.1); text-shadow: 0 0 20px var(--primary); }
369
+ 100% { opacity: 0.8; transform: scale(1); text-shadow: 0 0 10px var(--primary); }
370
+ }
371
+
372
+ @keyframes float {
373
+ 0% { transform: translateY(0px); }
374
+ 50% { transform: translateY(-10px); }
375
+ 100% { transform: translateY(0px); }
376
+ }
377
+
378
+ /* --- RESPONSIVE DESIGN --- */
379
+ @media (max-width: 1024px) {
380
+ .stat-card { grid-column: span 6; }
381
+ .visualizer-section { grid-column: span 12; min-height: 300px; }
382
+ .tilt-section { grid-column: span 12; flex-direction: row; }
383
+ .tilt-card { min-width: 250px; }
384
+ }
385
+
386
+ @media (max-width: 768px) {
387
+ .container { padding: 1rem; }
388
+ header { flex-direction: column; gap: 1rem; }
389
+ .stat-card { grid-column: span 12; }
390
+ .tilt-section { flex-direction: column; }
391
+ .brand h1 { font-size: 1.2rem; }
392
+ }
393
+ </style>
394
+ </head>
395
+ <body>
396
+
397
+ <div class="container">
398
+ <!-- HEADER -->
399
+ <header>
400
+ <div class="brand">
401
+ <i class="fa-solid fa-cube"></i>
402
+ <h1>NEXUS<span style="font-weight:300; opacity:0.7">DASH</span></h1>
403
+ </div>
404
+ <div class="header-controls">
405
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
406
+ Built with anycoder
407
+ </a>
408
+ <button class="theme-toggle" id="themeToggle" aria-label="Toggle Theme">
409
+ <i class="fa-solid fa-moon"></i>
410
+ </button>
411
+ </div>
412
+ </header>
413
+
414
+ <!-- MAIN DASHBOARD GRID -->
415
+ <main class="dashboard-grid">
416
+
417
+ <!-- STATS ROW -->
418
+ <div class="card stat-card">
419
+ <div class="card-header">
420
+ <span class="card-title"><i class="fa-solid fa-users"></i> Active Users</span>
421
+ </div>
422
+ <div>
423
+ <div class="stat-value" id="userCount">12,450</div>
424
+ <div class="stat-trend trend-up"><i class="fa-solid fa-arrow-trend-up"></i> +14% this week</div>
425
+ </div>
426
+ </div>
427
+
428
+ <div class="card stat-card">
429
+ <div class="card-header">
430
+ <span class="card-title"><i class="fa-solid fa-server"></i> Server Load</span>
431
+ </div>
432
+ <div>
433
+ <div class="stat-value" style="color: var(--accent)">42%</div>
434
+ <div class="stat-trend trend-down"><i class="fa-solid fa-check"></i> Stable</div>
435
+ </div>
436
+ </div>
437
+
438
+ <div class="card stat-card">
439
+ <div class="card-header">
440
+ <span class="card-title"><i class="fa-solid fa-wallet"></i> Revenue</span>
441
+ </div>
442
+ <div>
443
+ <div class="stat-value">$84.2k</div>
444
+ <div class="stat-trend trend-up"><i class="fa-solid fa-arrow-trend-up"></i> +5.2% vs yesterday</div>
445
+ </div>
446
+ </div>
447
+
448
+ <div class="card stat-card">
449
+ <div class="card-header">
450
+ <span class="card-title"><i class="fa-solid fa-bolt"></i> Efficiency</span>
451
+ </div>
452
+ <div>
453
+ <div class="stat-value" style="color: var(--primary)">98.9%</div>
454
+ <div class="stat-trend trend-up"><i class="fa-solid fa-caret-up"></i> Optimal</div>
455
+ </div>
456
+ </div>
457
+
458
+ <!-- VISUALIZER SECTION -->
459
+ <section class="card visualizer-section">
460
+ <canvas id="particleCanvas"></canvas>
461
+ <div class="visualizer-overlay">
462
+ <h2>Network Topology</h2>
463
+ <p style="color: var(--text-muted); margin-top: 0.5rem;">Real-time Node Visualization</p>
464
+ </div>
465
+ </section>
466
+
467
+ <!-- TILT CARDS SECTION -->
468
+ <section class="tilt-section">
469
+ <div class="tilt-card js-tilt">
470
+ <div class="tilt-icon"><i class="fa-solid fa-shield-halved"></i></div>
471
+ <div class="tilt-content">
472
+ <h3>Security</h3>
473
+ <p>Firewall Active</p>
474
+ </div>
475
+ </div>
476
+ <div class="tilt-card js-tilt">
477
+ <div class="tilt-icon"><i class="fa-solid fa-cloud-arrow-up"></i></div>
478
+ <div class="tilt-content">
479
+ <h3>Deployment</h3>
480
+ <p>Syncing...</p>
481
+ </div>
482
+ </div>
483
+ <div class="tilt-card js-tilt">
484
+ <div class="tilt-icon"><i class="fa-solid fa-code-branch"></i></div>
485
+ <div class="tilt-content">
486
+ <h3>Version</h3>
487
+ <p>v2.4.0-stable</p>
488
+ </div>
489
+ </div>
490
+ </section>
491
+
492
+ <!-- DATA TABLE SECTION -->
493
+ <section class="card table-section">
494
+ <div class="card-header">
495
+ <span class="card-title"><i class="fa-solid fa-list"></i> Recent Transactions</span>
496
+ <button style="background:none; border:none; color:var(--primary); cursor:pointer;">View All</button>
497
+ </div>
498
+ <table>
499
+ <thead>
500
+ <tr>
501
+ <th>ID</th>
502
+ <th>User</th>
503
+ <th>Date</th>
504
+ <th>Amount</th>
505
+ <th>Status</th>
506
+ <th>Action</th>
507
+ </tr>
508
+ </thead>
509
+ <tbody>
510
+ <tr>
511
+ <td>#TRX-9821</td>
512
+ <td>Alex Morgan</td>
513
+ <td>Oct 24, 2023</td>
514
+ <td>$120.50</td>
515
+ <td><span class="status-badge status-active">Completed</span></td>
516
+ <td><i class="fa-solid fa-ellipsis-vertical" style="color:var(--text-muted); cursor:pointer;"></i></td>
517
+ </tr>
518
+ <tr>
519
+ <td>#TRX-9822</td>
520
+ <td>Sarah Connor</td>
521
+ <td>Oct 24, 2023</td>
522
+ <td>$450.00</td>
523
+ <td><span class="status-badge status-pending">Processing</span></td>
524
+ <td><i class="fa-solid fa-ellipsis-vertical" style="color:var(--text-muted); cursor:pointer;"></i></td>
525
+ </tr>
526
+ <tr>
527
+ <td>#TRX-9823</td>
528
+ <td>John Doe</td>
529
+ <td>Oct 23, 2023</td>
530
+ <td>$32.00</td>
531
+ <td><span class="status-badge status-error">Failed</span></td>
532
+ <td><i class="fa-solid fa-ellipsis-vertical" style="color:var(--text-muted); cursor:pointer;"></i></td>
533
+ </tr>
534
+ <tr>
535
+ <td>#TRX-9824</td>
536
+ <td>Emily Blunt</td>
537
+ <td>Oct 23, 2023</td>
538
+ <td>$1,200.00</td>
539
+ <td><span class="status-badge status-active">Completed</span></td>
540
+ <td><i class="fa-solid fa-ellipsis-vertical" style="color:var(--text-muted); cursor:pointer;"></i></td>
541
+ </tr>
542
+ </tbody>
543
+ </table>
544
+ </section>
545
+
546
+ </main>
547
+ </div>
548
+
549
+ <script>
550
+ /**
551
+ * 1. THEME TOGGLE LOGIC
552
+ * Switches CSS variables between Dark (Default) and Light mode.
553
+ */
554
+ const themeToggleBtn = document.getElementById('themeToggle');
555
+ const themeIcon = themeToggleBtn.querySelector('i');
556
+ let isDarkMode = true;
557
+
558
+ themeToggleBtn.addEventListener('click', () => {
559
+ isDarkMode = !isDarkMode;
560
+ if (isDarkMode) {
561
+ document.documentElement.removeAttribute('data-theme');
562
+ themeIcon.classList.remove('fa-sun');
563
+ themeIcon.classList.add('fa-moon');
564
+ } else {
565
+ document.documentElement.setAttribute('data-theme', 'light');
566
+ themeIcon.classList.remove('fa-moon');
567
+ themeIcon.classList.add('fa-sun');
568
+ }
569
+ });
570
+
571
+ /**
572
+ * 2. 3D TILT EFFECT
573
+ * Calculates mouse position relative to the card center and applies a rotation transform.
574
+ */
575
+ const tiltCards = document.querySelectorAll('.js-tilt');
576
+
577
+ tiltCards.forEach(card => {
578
+ card.addEventListener('mousemove', (e) => {
579
+ const rect = card.getBoundingClientRect();
580
+ const x = e.clientX - rect.left;
581
+ const y = e.clientY - rect.top;
582
+
583
+ // Calculate rotation (center is 0,0)
584
+ const xPct = (x / rect.width) - 0.5;
585
+ const yPct = (y / rect.height) - 0.5;
586
+
587
+ // Max rotation degrees
588
+ const xRot = yPct * -20; // Rotate X axis based on Y position
589
+ const yRot = xPct * 20; // Rotate Y axis based on X position
590
+
591
+ card.style.transform = `perspective(1000px) rotateX(${xRot}deg) rotateY(${yRot}deg) scale(1.02)`;
592
+ });
593
+
594
+ // Reset on mouse leave
595
+ card.addEventListener('mouseleave', () => {
596
+ card.style.transform = `perspective(1000px) rotateX(0) rotateY(0) scale(1)`;
597
+ });
598
+ });
599
+
600
+ /**
601
+ * 3. PARTICLE NETWORK VISUALIZATION
602
+ * Draws nodes and connections on an HTML5 Canvas.
603
+ */
604
+ const canvas = document.getElementById('particleCanvas');
605
+ const ctx = canvas.getContext('2d');
606
+
607
+ let width, height;
608
+ let particles = [];
609
+ const particleCount = 60;
610
+ const connectionDistance = 120;
611
+
612
+ // Resize handling
613
+ function resize() {
614
+ width = canvas.parentElement.offsetWidth;
615
+ height = canvas.parentElement.offsetHeight;
616
+ canvas.width = width;
617
+ canvas.height = height;
618
+ }
619
+ window.addEventListener('resize', resize);
620
+ resize();
621
+
622
+ // Particle Class
623
+ class Particle {
624
+ constructor() {
625
+ this.x = Math.random() * width;
626
+ this.y = Math.random() * height;
627
+ this.vx = (Math.random() - 0.5) * 1.5;
628
+ this.vy = (Math.random() - 0.5) * 1.5;
629
+ this.size = Math.random() * 2 + 1;
630
+ }
631
+
632
+ update() {
633
+ this.x += this.vx;
634
+ this.y += this.vy;
635
+
636
+ // Bounce off edges
637
+ if (this.x < 0 || this.x > width) this.vx *= -1;
638
+ if (this.y < 0 || this.y > height) this.vy *= -1;
639
+ }
640
+
641
+ draw() {
642
+ ctx.beginPath();
643
+ ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
644
+ // Use CSS variable color logic by checking computed style or fallback
645
+ ctx.fillStyle = isDarkMode ? '#00f2ff' : '#2563eb';
646
+ ctx.fill();
647
+ }
648
+ }
649
+
650
+ // Initialize Particles
651
+ for (let i = 0; i < particleCount; i++) {
652
+ particles.push(new Particle());
653
+ }
654
+
655
+ // Animation Loop
656
+ function animate() {
657
+ ctx.clearRect(0, 0, width, height);
658
+
659
+ // Update and draw particles
660
+ particles.forEach(p => {
661
+ p.update();
662
+ p.draw();
663
+ });
664
+
665
+ // Draw connections
666
+ for (let i = 0; i < particles.length; i++) {
667
+ for (let j = i + 1; j < particles.length; j++) {
668
+ const dx = particles[i].x - particles[j].x;
669
+ const dy = particles[i].y - particles[j].y;
670
+ const distance = Math.sqrt(dx * dx + dy * dy);
671
+
672
+ if (distance < connectionDistance) {
673
+ ctx.beginPath();
674
+ const opacity = 1 - (distance / connectionDistance);
675
+ ctx.strokeStyle = isDarkMode
676
+ ? `rgba(0, 242, 255, ${opacity * 0.4})`
677
+ : `rgba(37, 99, 235, ${opacity * 0.2})`;
678
+ ctx.lineWidth = 1;
679
+ ctx.moveTo(particles[i].x, particles[i].y);
680
+ ctx.lineTo(particles[j].x, particles[j].y);
681
+ ctx.stroke();
682
+ }
683
+ }
684
+ }
685
+
686
+ requestAnimationFrame(animate);
687
+ }
688
+ animate();
689
+
690
+ /**
691
+ * 4. LIVE NUMBER SIMULATION
692
+ * Randomly increments the user count slightly to make the UI feel alive.
693
+ */
694
+ const userCountEl = document.getElementById('userCount');
695
+ let currentCount = 12450;
696
+
697
+ setInterval(() => {
698
+ const increment = Math.floor(Math.random() * 5);
699
+ currentCount += increment;
700
+ userCountEl.innerText = currentCount.toLocaleString();
701
+
702
+ // Visual flash effect
703
+ userCountEl.style.textShadow = "0 0 10px var(--primary)";
704
+ setTimeout(() => {
705
+ userCountEl.style.textShadow = "none";
706
+ }, 300);
707
+ }, 3000);
708
+
709
+ </script>
710
+ </body>
711
+ </html>