akhaliq HF Staff commited on
Commit
adc3dd6
·
verified ·
1 Parent(s): e1a2de4

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +940 -19
index.html CHANGED
@@ -1,19 +1,940 @@
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>HeroForce - Roster Manager</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+
10
+ <style>
11
+ :root {
12
+ --primary: #3b82f6;
13
+ --primary-dark: #2563eb;
14
+ --primary-light: #60a5fa;
15
+ --secondary: #8b5cf6;
16
+ --accent: #06b6d4;
17
+ --bg-dark: #0f172a;
18
+ --bg-card: #1e293b;
19
+ --bg-surface: rgba(30, 41, 59, 0.7);
20
+ --text-primary: #f1f5f9;
21
+ --text-secondary: #94a3b8;
22
+ --text-muted: #64748b;
23
+ --border: rgba(255, 255, 255, 0.1);
24
+ --success: #10b981;
25
+ --warning: #f59e0b;
26
+ --danger: #ef4444;
27
+ --shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
28
+ --shadow-lg: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
29
+ --radius: 12px;
30
+ --radius-lg: 16px;
31
+ --transition: all 0.2s ease-in-out;
32
+ }
33
+
34
+ * {
35
+ margin: 0;
36
+ padding: 0;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ body {
41
+ background: var(--bg-dark);
42
+ color: var(--text-primary);
43
+ font-family: 'Inter', sans-serif;
44
+ line-height: 1.6;
45
+ min-height: 100vh;
46
+ position: relative;
47
+ }
48
+
49
+ body::before {
50
+ content: '';
51
+ position: fixed;
52
+ top: 0;
53
+ left: 0;
54
+ width: 100%;
55
+ height: 100%;
56
+ background:
57
+ radial-gradient(circle at 20% 20%, rgba(59, 130, 246, 0.1) 0%, transparent 50%),
58
+ radial-gradient(circle at 80% 80%, rgba(139, 92, 246, 0.1) 0%, transparent 50%);
59
+ pointer-events: none;
60
+ z-index: -1;
61
+ }
62
+
63
+ /* Header */
64
+ .header {
65
+ background: var(--bg-surface);
66
+ backdrop-filter: blur(16px);
67
+ border-bottom: 1px solid var(--border);
68
+ position: sticky;
69
+ top: 0;
70
+ z-index: 100;
71
+ }
72
+
73
+ .header-container {
74
+ max-width: 1200px;
75
+ margin: 0 auto;
76
+ padding: 1rem 1.5rem;
77
+ display: flex;
78
+ justify-content: space-between;
79
+ align-items: center;
80
+ }
81
+
82
+ .logo {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: 0.75rem;
86
+ font-weight: 700;
87
+ font-size: 1.25rem;
88
+ background: linear-gradient(135deg, var(--primary), var(--secondary));
89
+ -webkit-background-clip: text;
90
+ background-clip: text;
91
+ color: transparent;
92
+ }
93
+
94
+ .logo-icon {
95
+ width: 32px;
96
+ height: 32px;
97
+ background: linear-gradient(135deg, var(--primary), var(--secondary));
98
+ border-radius: 8px;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ }
103
+
104
+ .anycoder-badge {
105
+ font-size: 0.75rem;
106
+ color: var(--text-muted);
107
+ text-decoration: none;
108
+ font-weight: 500;
109
+ transition: var(--transition);
110
+ }
111
+
112
+ .anycoder-badge:hover {
113
+ color: var(--primary);
114
+ }
115
+
116
+ /* Main Layout */
117
+ .main {
118
+ max-width: 1200px;
119
+ margin: 0 auto;
120
+ padding: 2rem 1.5rem;
121
+ }
122
+
123
+ /* Page Header */
124
+ .page-header {
125
+ margin-bottom: 2rem;
126
+ }
127
+
128
+ .page-title {
129
+ font-size: 2rem;
130
+ font-weight: 700;
131
+ margin-bottom: 0.5rem;
132
+ background: linear-gradient(135deg, var(--text-primary), var(--text-secondary));
133
+ -webkit-background-clip: text;
134
+ background-clip: text;
135
+ color: transparent;
136
+ }
137
+
138
+ .page-subtitle {
139
+ color: var(--text-secondary);
140
+ font-size: 1rem;
141
+ }
142
+
143
+ /* Controls */
144
+ .controls {
145
+ display: flex;
146
+ justify-content: space-between;
147
+ align-items: center;
148
+ margin-bottom: 2rem;
149
+ gap: 1rem;
150
+ }
151
+
152
+ .stats {
153
+ color: var(--text-muted);
154
+ font-size: 0.875rem;
155
+ font-weight: 500;
156
+ }
157
+
158
+ /* Buttons */
159
+ .btn {
160
+ display: inline-flex;
161
+ align-items: center;
162
+ gap: 0.5rem;
163
+ padding: 0.75rem 1.25rem;
164
+ border-radius: var(--radius);
165
+ border: none;
166
+ font-family: inherit;
167
+ font-size: 0.875rem;
168
+ font-weight: 500;
169
+ cursor: pointer;
170
+ transition: var(--transition);
171
+ text-decoration: none;
172
+ }
173
+
174
+ .btn-primary {
175
+ background: linear-gradient(135deg, var(--primary), var(--primary-dark));
176
+ color: white;
177
+ box-shadow: var(--shadow);
178
+ }
179
+
180
+ .btn-primary:hover {
181
+ transform: translateY(-1px);
182
+ box-shadow: var(--shadow-lg);
183
+ }
184
+
185
+ .btn-ghost {
186
+ background: transparent;
187
+ color: var(--text-secondary);
188
+ border: 1px solid var(--border);
189
+ }
190
+
191
+ .btn-ghost:hover {
192
+ background: rgba(255, 255, 255, 0.05);
193
+ color: var(--text-primary);
194
+ }
195
+
196
+ .btn-icon {
197
+ padding: 0.5rem;
198
+ width: 36px;
199
+ height: 36px;
200
+ justify-content: center;
201
+ }
202
+
203
+ /* Hero Grid */
204
+ .hero-grid {
205
+ display: grid;
206
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
207
+ gap: 1.5rem;
208
+ }
209
+
210
+ /* Hero Card */
211
+ .hero-card {
212
+ background: var(--bg-card);
213
+ border-radius: var(--radius-lg);
214
+ border: 1px solid var(--border);
215
+ transition: var(--transition);
216
+ overflow: hidden;
217
+ display: flex;
218
+ flex-direction: column;
219
+ }
220
+
221
+ .hero-card:hover {
222
+ transform: translateY(-4px);
223
+ border-color: var(--primary-light);
224
+ box-shadow: var(--shadow-lg);
225
+ }
226
+
227
+ .card-header {
228
+ height: 100px;
229
+ position: relative;
230
+ overflow: hidden;
231
+ }
232
+
233
+ .card-header::before {
234
+ content: '';
235
+ position: absolute;
236
+ top: 0;
237
+ left: 0;
238
+ width: 100%;
239
+ height: 100%;
240
+ background: linear-gradient(135deg, var(--primary), var(--secondary));
241
+ opacity: 0.8;
242
+ }
243
+
244
+ .hero-avatar {
245
+ position: absolute;
246
+ bottom: -24px;
247
+ left: 1.5rem;
248
+ width: 64px;
249
+ height: 64px;
250
+ border-radius: 12px;
251
+ border: 3px solid var(--bg-card);
252
+ display: flex;
253
+ align-items: center;
254
+ justify-content: center;
255
+ font-size: 1.5rem;
256
+ font-weight: 700;
257
+ background: rgba(255, 255, 255, 0.1);
258
+ backdrop-filter: blur(10px);
259
+ }
260
+
261
+ .card-content {
262
+ padding: 2rem 1.5rem 1.5rem;
263
+ flex-grow: 1;
264
+ }
265
+
266
+ .hero-name {
267
+ font-size: 1.25rem;
268
+ font-weight: 600;
269
+ margin-bottom: 0.25rem;
270
+ }
271
+
272
+ .hero-alias {
273
+ color: var(--accent);
274
+ font-size: 0.75rem;
275
+ font-weight: 500;
276
+ text-transform: uppercase;
277
+ letter-spacing: 0.5px;
278
+ margin-bottom: 1rem;
279
+ }
280
+
281
+ .hero-desc {
282
+ color: var(--text-secondary);
283
+ font-size: 0.875rem;
284
+ line-height: 1.5;
285
+ margin-bottom: 1.5rem;
286
+ display: -webkit-box;
287
+ -webkit-line-clamp: 3;
288
+ -webkit-box-orient: vertical;
289
+ overflow: hidden;
290
+ }
291
+
292
+ /* Stats */
293
+ .stats-container {
294
+ display: flex;
295
+ flex-direction: column;
296
+ gap: 0.75rem;
297
+ }
298
+
299
+ .stat-item {
300
+ display: flex;
301
+ align-items: center;
302
+ gap: 0.75rem;
303
+ }
304
+
305
+ .stat-label {
306
+ width: 60px;
307
+ color: var(--text-muted);
308
+ font-size: 0.75rem;
309
+ font-weight: 500;
310
+ }
311
+
312
+ .stat-bar {
313
+ flex: 1;
314
+ height: 6px;
315
+ background: rgba(255, 255, 255, 0.1);
316
+ border-radius: 3px;
317
+ overflow: hidden;
318
+ }
319
+
320
+ .stat-fill {
321
+ height: 100%;
322
+ border-radius: 3px;
323
+ background: var(--primary);
324
+ }
325
+
326
+ .stat-value {
327
+ width: 30px;
328
+ text-align: right;
329
+ color: var(--text-muted);
330
+ font-size: 0.75rem;
331
+ font-weight: 600;
332
+ }
333
+
334
+ /* Card Actions */
335
+ .card-actions {
336
+ padding: 1rem 1.5rem;
337
+ border-top: 1px solid var(--border);
338
+ display: flex;
339
+ justify-content: flex-end;
340
+ gap: 0.5rem;
341
+ background: rgba(0, 0, 0, 0.1);
342
+ }
343
+
344
+ /* Empty State */
345
+ .empty-state {
346
+ grid-column: 1 / -1;
347
+ text-align: center;
348
+ padding: 4rem 2rem;
349
+ background: rgba(255, 255, 255, 0.02);
350
+ border-radius: var(--radius-lg);
351
+ border: 2px dashed var(--border);
352
+ }
353
+
354
+ .empty-icon {
355
+ font-size: 3rem;
356
+ color: var(--text-muted);
357
+ margin-bottom: 1rem;
358
+ opacity: 0.5;
359
+ }
360
+
361
+ /* Modal */
362
+ .modal {
363
+ position: fixed;
364
+ top: 0;
365
+ left: 0;
366
+ width: 100%;
367
+ height: 100%;
368
+ background: rgba(0, 0, 0, 0.8);
369
+ backdrop-filter: blur(8px);
370
+ display: flex;
371
+ justify-content: center;
372
+ align-items: center;
373
+ z-index: 1000;
374
+ opacity: 0;
375
+ pointer-events: none;
376
+ transition: opacity 0.3s ease;
377
+ padding: 1.5rem;
378
+ }
379
+
380
+ .modal.active {
381
+ opacity: 1;
382
+ pointer-events: all;
383
+ }
384
+
385
+ .modal-content {
386
+ background: var(--bg-card);
387
+ border-radius: var(--radius-lg);
388
+ border: 1px solid var(--border);
389
+ width: 100%;
390
+ max-width: 480px;
391
+ max-height: 90vh;
392
+ overflow-y: auto;
393
+ transform: translateY(20px);
394
+ transition: transform 0.3s ease;
395
+ }
396
+
397
+ .modal.active .modal-content {
398
+ transform: translateY(0);
399
+ }
400
+
401
+ .modal-header {
402
+ padding: 1.5rem 1.5rem 0;
403
+ display: flex;
404
+ justify-content: space-between;
405
+ align-items: center;
406
+ margin-bottom: 1.5rem;
407
+ }
408
+
409
+ .modal-title {
410
+ font-size: 1.5rem;
411
+ font-weight: 600;
412
+ }
413
+
414
+ .modal-close {
415
+ background: none;
416
+ border: none;
417
+ color: var(--text-secondary);
418
+ font-size: 1.25rem;
419
+ cursor: pointer;
420
+ padding: 0.25rem;
421
+ border-radius: 4px;
422
+ }
423
+
424
+ .modal-close:hover {
425
+ background: rgba(255, 255, 255, 0.1);
426
+ color: var(--text-primary);
427
+ }
428
+
429
+ .modal-body {
430
+ padding: 0 1.5rem 1.5rem;
431
+ }
432
+
433
+ /* Form */
434
+ .form {
435
+ display: flex;
436
+ flex-direction: column;
437
+ gap: 1.25rem;
438
+ }
439
+
440
+ .form-group {
441
+ display: flex;
442
+ flex-direction: column;
443
+ gap: 0.5rem;
444
+ }
445
+
446
+ .form-label {
447
+ color: var(--text-secondary);
448
+ font-size: 0.875rem;
449
+ font-weight: 500;
450
+ }
451
+
452
+ .form-input,
453
+ .form-textarea {
454
+ background: rgba(255, 255, 255, 0.05);
455
+ border: 1px solid var(--border);
456
+ border-radius: var(--radius);
457
+ padding: 0.75rem;
458
+ color: var(--text-primary);
459
+ font-family: inherit;
460
+ font-size: 0.875rem;
461
+ transition: var(--transition);
462
+ }
463
+
464
+ .form-input:focus,
465
+ .form-textarea:focus {
466
+ outline: none;
467
+ border-color: var(--primary);
468
+ background: rgba(255, 255, 255, 0.08);
469
+ }
470
+
471
+ .form-textarea {
472
+ resize: vertical;
473
+ min-height: 80px;
474
+ }
475
+
476
+ .range-group {
477
+ display: flex;
478
+ align-items: center;
479
+ gap: 1rem;
480
+ }
481
+
482
+ .range-input {
483
+ flex: 1;
484
+ accent-color: var(--primary);
485
+ }
486
+
487
+ .range-value {
488
+ width: 30px;
489
+ text-align: right;
490
+ color: var(--primary);
491
+ font-weight: 600;
492
+ font-size: 0.875rem;
493
+ }
494
+
495
+ /* Notification */
496
+ .notification {
497
+ position: fixed;
498
+ bottom: 1.5rem;
499
+ right: 1.5rem;
500
+ background: var(--bg-card);
501
+ border: 1px solid var(--border);
502
+ border-radius: var(--radius);
503
+ padding: 0.75rem 1rem;
504
+ display: flex;
505
+ align-items: center;
506
+ gap: 0.5rem;
507
+ box-shadow: var(--shadow-lg);
508
+ transform: translateX(100%);
509
+ transition: transform 0.3s ease;
510
+ z-index: 1100;
511
+ }
512
+
513
+ .notification.show {
514
+ transform: translateX(0);
515
+ }
516
+
517
+ /* Responsive Design */
518
+ @media (max-width: 768px) {
519
+ .header-container {
520
+ padding: 0.75rem 1rem;
521
+ }
522
+
523
+ .main {
524
+ padding: 1.5rem 1rem;
525
+ }
526
+
527
+ .page-title {
528
+ font-size: 1.5rem;
529
+ }
530
+
531
+ .controls {
532
+ flex-direction: column;
533
+ align-items: stretch;
534
+ }
535
+
536
+ .btn {
537
+ width: 100%;
538
+ justify-content: center;
539
+ }
540
+
541
+ .hero-grid {
542
+ grid-template-columns: 1fr;
543
+ gap: 1rem;
544
+ }
545
+
546
+ .modal {
547
+ padding: 1rem;
548
+ }
549
+ }
550
+
551
+ @media (max-width: 480px) {
552
+ .card-content {
553
+ padding: 1.5rem 1rem 1rem;
554
+ }
555
+
556
+ .card-actions {
557
+ padding: 0.75rem 1rem;
558
+ }
559
+
560
+ .modal-content {
561
+ max-height: 95vh;
562
+ }
563
+ }
564
+ </style>
565
+ </head>
566
+ <body>
567
+ <!-- Header -->
568
+ <header class="header">
569
+ <div class="header-container">
570
+ <div class="logo">
571
+ <div class="logo-icon">
572
+ <i class="fa-solid fa-bolt" style="color: white; font-size: 0.875rem;"></i>
573
+ </div>
574
+ HeroForce
575
+ </div>
576
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-badge">Built with anycoder</a>
577
+ </div>
578
+ </header>
579
+
580
+ <!-- Main Content -->
581
+ <main class="main">
582
+ <div class="page-header">
583
+ <h1 class="page-title">Hero Roster</h1>
584
+ <p class="page-subtitle">Manage your team of extraordinary individuals</p>
585
+ </div>
586
+
587
+ <div class="controls">
588
+ <div class="stats" id="heroCount">0 Heroes Active</div>
589
+ <button class="btn btn-primary" onclick="openModal()">
590
+ <i class="fa-solid fa-plus"></i>
591
+ Add Hero
592
+ </button>
593
+ </div>
594
+
595
+ <div class="hero-grid" id="heroGrid">
596
+ <!-- Heroes will be dynamically added here -->
597
+ </div>
598
+ </main>
599
+
600
+ <!-- Modal -->
601
+ <div class="modal" id="heroModal">
602
+ <div class="modal-content">
603
+ <div class="modal-header">
604
+ <h2 class="modal-title" id="modalTitle">Add New Hero</h2>
605
+ <button class="modal-close" onclick="closeModal()">
606
+ <i class="fa-solid fa-xmark"></i>
607
+ </button>
608
+ </div>
609
+ <div class="modal-body">
610
+ <form class="form" id="heroForm">
611
+ <input type="hidden" id="heroId">
612
+
613
+ <div class="form-group">
614
+ <label class="form-label">Hero Name</label>
615
+ <input type="text" class="form-input" id="heroName" required placeholder="e.g. Captain Velocity">
616
+ </div>
617
+
618
+ <div class="form-group">
619
+ <label class="form-label">Secret Identity</label>
620
+ <input type="text" class="form-input" id="heroAlias" required placeholder="e.g. John Doe">
621
+ </div>
622
+
623
+ <div class="form-group">
624
+ <label class="form-label">Power Description</label>
625
+ <textarea class="form-textarea" id="heroDesc" rows="3" placeholder="Describe their abilities and powers..."></textarea>
626
+ </div>
627
+
628
+ <div class="form-group">
629
+ <label class="form-label">Strength</label>
630
+ <div class="range-group">
631
+ <input type="range" class="range-input" id="heroStrength" min="1" max="100" value="50" oninput="updateRangeValue(this)">
632
+ <span class="range-value">50</span>
633
+ </div>
634
+ </div>
635
+
636
+ <div class="form-group">
637
+ <label class="form-label">Speed</label>
638
+ <div class="range-group">
639
+ <input type="range" class="range-input" id="heroSpeed" min="1" max="100" value="50" oninput="updateRangeValue(this)">
640
+ <span class="range-value">50</span>
641
+ </div>
642
+ </div>
643
+
644
+ <div class="form-group">
645
+ <label class="form-label">Intelligence</label>
646
+ <div class="range-group">
647
+ <input type="range" class="range-input" id="heroIntel" min="1" max="100" value="50" oninput="updateRangeValue(this)">
648
+ <span class="range-value">50</span>
649
+ </div>
650
+ </div>
651
+
652
+ <button type="submit" class="btn btn-primary">
653
+ <i class="fa-solid fa-save"></i>
654
+ Save Hero
655
+ </button>
656
+ </form>
657
+ </div>
658
+ </div>
659
+
660
+ <!-- Notification -->
661
+ <div class="notification" id="notification">
662
+ <i class="fa-solid fa-check-circle" style="color: var(--success)"></i>
663
+ <span id="notificationMsg">Action successful</span>
664
+ </div>
665
+
666
+ <script>
667
+ // Initial Data
668
+ const defaultHeroes = [
669
+ {
670
+ id: '1',
671
+ name: 'Iron Guardian',
672
+ alias: 'Tony Stark-ish',
673
+ desc: 'A genius billionaire who built a high-tech suit of armor to protect the world from cosmic threats.',
674
+ strength: 85,
675
+ speed: 70,
676
+ intel: 95
677
+ },
678
+ {
679
+ id: '2',
680
+ name: 'Solar Flare',
681
+ alias: 'Elena Rodriguez',
682
+ desc: 'Capable of manipulating solar energy to fly and project intense beams of heat.',
683
+ strength: 75,
684
+ speed: 90,
685
+ intel: 60
686
+ },
687
+ {
688
+ id: '3',
689
+ name: 'Shadow Weaver',
690
+ alias: 'Damian Black',
691
+ desc: 'Can merge with shadows and teleport instantly between dark places. Master of stealth.',
692
+ strength: 50,
693
+ speed: 88,
694
+ intel: 80
695
+ },
696
+ {
697
+ id: '4',
698
+ name: 'Titanus',
699
+ alias: 'Marcus Steel',
700
+ desc: 'Possesses immense physical strength and invulnerability. The tank of the team.',
701
+ strength: 98,
702
+ speed: 40,
703
+ intel: 55
704
+ },
705
+ {
706
+ id: '5',
707
+ name: 'Mind Reader',
708
+ alias: 'Sarah Jean',
709
+ desc: 'A powerful telepath who can read thoughts and influence the actions of others.',
710
+ strength: 30,
711
+ speed: 45,
712
+ intel: 100
713
+ }
714
+ ];
715
+
716
+ // State Management
717
+ let heroes = JSON.parse(localStorage.getItem('heroes')) || defaultHeroes;
718
+
719
+ // DOM Elements
720
+ const grid = document.getElementById('heroGrid');
721
+ const modal = document.getElementById('heroModal');
722
+ const heroForm = document.getElementById('heroForm');
723
+ const heroCountLabel = document.getElementById('heroCount');
724
+
725
+ // Color Generation
726
+ function generateColors(name) {
727
+ const hue = name.split('').reduce((a, b) => a + b.charCodeAt(0), 0) % 360;
728
+ return {
729
+ header: `hsl(${hue}, 70%, 40%)',
730
+ avatar: `hsl(${hue}, 60%, 50%)'
731
+ };
732
+ }
733
+
734
+ // Render Function
735
+ function renderHeroes() {
736
+ grid.innerHTML = '';
737
+
738
+ if (heroes.length === 0) {
739
+ grid.innerHTML = `
740
+ <div class="empty-state">
741
+ <div class="empty-icon"><i class="fa-solid fa-user-plus"></i></div>
742
+ <h3>No Heroes Found</h3>
743
+ <p style="color: var(--text-muted); margin-top: 0.5rem;">The world needs saving! Add your first hero to start.</p>
744
+ </div>
745
+ `;
746
+ heroCountLabel.textContent = `0 Heroes Active`;
747
+ return;
748
+ }
749
+
750
+ heroCountLabel.textContent = `${heroes.length} Heroes Active`;
751
+
752
+ heroes.forEach(hero => {
753
+ const colors = generateColors(hero.name);
754
+
755
+ const card = document.createElement('div');
756
+ card.className = 'hero-card';
757
+
758
+ card.innerHTML = `
759
+ <div class="card-header" style="background: ${colors.header}">
760
+ <div class="hero-avatar" style="background: ${colors.avatar}">
761
+ ${hero.name.charAt(0)}
762
+ </div>
763
+ </div>
764
+ <div class="card-content">
765
+ <h3 class="hero-name">${hero.name}</h3>
766
+ <span class="hero-alias">${hero.alias}</span>
767
+ <p class="hero-desc">${hero.desc}</p>
768
+
769
+ <div class="stats-container">
770
+ <div class="stat-item">
771
+ <span class="stat-label">STR</span>
772
+ <div class="stat-bar">
773
+ <div class="stat-fill" style="width: ${hero.strength}%"></div>
774
+ </div>
775
+ <span class="stat-value">${hero.strength}</span>
776
+ </div>
777
+ <div class="stat-item">
778
+ <span class="stat-label">SPD</span>
779
+ <div class="stat-bar">
780
+ <div class="stat-fill" style="width: ${hero.speed}%; background: var(--secondary)"></div>
781
+ </div>
782
+ <span class="stat-value">${hero.speed}</span>
783
+ </div>
784
+ <div class="stat-item">
785
+ <span class="stat-label">INT</span>
786
+ <div class="stat-bar">
787
+ <div class="stat-fill" style="width: ${hero.intel}%; background: var(--success)"></div>
788
+ </div>
789
+ <span class="stat-value">${hero.intel}</span>
790
+ </div>
791
+ </div>
792
+ </div>
793
+ <div class="card-actions">
794
+ <button class="btn btn-ghost btn-icon" onclick="editHero('${hero.id}')">
795
+ <i class="fa-solid fa-pen"></i>
796
+ </button>
797
+ <button class="btn btn-ghost btn-icon" onclick="deleteHero('${hero.id}')">
798
+ <i class="fa-solid fa-trash"></i>
799
+ </button>
800
+ </div>
801
+ `;
802
+ grid.appendChild(card);
803
+ });
804
+ }
805
+
806
+ // Modal Functions
807
+ function openModal(isEdit = false) {
808
+ document.getElementById('modalTitle').textContent = isEdit ? 'Edit Hero' : 'Add New Hero';
809
+ modal.classList.add('active');
810
+
811
+ if (!isEdit) {
812
+ heroForm.reset();
813
+ document.getElementById('heroId').value = '';
814
+
815
+ // Reset range displays
816
+ document.querySelectorAll('.range-input').forEach(input => {
817
+ input.nextElementSibling.textContent = input.value;
818
+ });
819
+ }
820
+ }
821
+
822
+ function closeModal() {
823
+ modal.classList.remove('active');
824
+ }
825
+
826
+ // Range Value Update
827
+ function updateRangeValue(input) {
828
+ input.nextElementSibling.textContent = input.value;
829
+ }
830
+
831
+ // CRUD Operations
832
+ function saveHero(e) {
833
+ e.preventDefault();
834
+
835
+ const id = document.getElementById('heroId').value;
836
+ const name = document.getElementById('heroName').value;
837
+ const alias = document.getElementById('heroAlias').value;
838
+ const desc = document.getElementById('heroDesc').value;
839
+ const strength = parseInt(document.getElementById('heroStrength').value);
840
+ const speed = parseInt(document.getElementById('heroSpeed').value);
841
+ const intel = parseInt(document.getElementById('heroIntel').value);
842
+
843
+ if (id) {
844
+ // Update existing hero
845
+ const index = heroes.findIndex(h => h.id === id);
846
+ if (index !== -1) {
847
+ heroes[index] = {
848
+ ...heroes[index],
849
+ name, alias, desc, strength, speed, intel
850
+ };
851
+ showNotification('Hero updated successfully!');
852
+ }
853
+ } else {
854
+ // Create new hero
855
+ const newHero = {
856
+ id: Date.now().toString(),
857
+ name,
858
+ alias,
859
+ desc,
860
+ strength,
861
+ speed,
862
+ intel
863
+ };
864
+ heroes.push(newHero);
865
+ showNotification('New hero recruited!');
866
+ }
867
+
868
+ saveToStorage();
869
+ renderHeroes();
870
+ closeModal();
871
+ }
872
+
873
+ function editHero(id) {
874
+ const hero = heroes.find(h => h.id === id);
875
+ if (!hero) return;
876
+
877
+ document.getElementById('heroId').value = hero.id;
878
+ document.getElementById('heroName').value = hero.name;
879
+ document.getElementById('heroAlias').value = hero.alias;
880
+ document.getElementById('heroDesc').value = hero.desc;
881
+
882
+ const strengthInput = document.getElementById('heroStrength');
883
+ strengthInput.value = hero.strength;
884
+ updateRangeValue(strengthInput);
885
+
886
+ const speedInput = document.getElementById('heroSpeed');
887
+ speedInput.value = hero.speed;
888
+ updateRangeValue(speedInput);
889
+
890
+ const intelInput = document.getElementById('heroIntel');
891
+ intelInput.value = hero.intel;
892
+ updateRangeValue(intelInput);
893
+
894
+ openModal(true);
895
+ }
896
+
897
+ function deleteHero(id) {
898
+ if (confirm('Are you sure you want to remove this hero from the roster?')) {
899
+ heroes = heroes.filter(h => h.id !== id);
900
+ saveToStorage();
901
+ renderHeroes();
902
+ showNotification('Hero removed from roster.');
903
+ }
904
+ }
905
+
906
+ // Storage
907
+ function saveToStorage() {
908
+ localStorage.setItem('heroes', JSON.stringify(heroes));
909
+ }
910
+
911
+ // Notification
912
+ function showNotification(msg) {
913
+ const notif = document.getElementById('notification');
914
+ document.getElementById('notificationMsg').textContent = msg;
915
+ notif.classList.add('show');
916
+
917
+ setTimeout(() => {
918
+ notif.classList.remove('show');
919
+ }, 3000);
920
+ }
921
+
922
+ // Event Listeners
923
+ heroForm.addEventListener('submit', saveHero);
924
+
925
+ modal.addEventListener('click', (e) => {
926
+ if (e.target === modal) closeModal();
927
+ });
928
+
929
+ // Keyboard Events
930
+ document.addEventListener('keydown', (e) => {
931
+ if (e.key === 'Escape' && modal.classList.contains('active')) {
932
+ closeModal();
933
+ }
934
+ });
935
+
936
+ // Initial Load
937
+ renderHeroes();
938
+ </script>
939
+ </body>
940
+ </html>