Knives567 commited on
Commit
59e0592
·
verified ·
1 Parent(s): d3734b9

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +1270 -19
index.html CHANGED
@@ -1,19 +1,1270 @@
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>AI Image Generator</title>
7
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ :root {
16
+ --primary: #6366f1;
17
+ --primary-dark: #4f46e5;
18
+ --secondary: #ec4899;
19
+ --bg-dark: #0f0f1a;
20
+ --bg-card: #1a1a2e;
21
+ --bg-input: #252542;
22
+ --text-primary: #ffffff;
23
+ --text-secondary: #a0a0b8;
24
+ --border: #2d2d4a;
25
+ --success: #10b981;
26
+ --warning: #f59e0b;
27
+ --gradient: linear-gradient(135deg, #6366f1 0%, #ec4899 100%);
28
+ }
29
+
30
+ body {
31
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
32
+ background: var(--bg-dark);
33
+ color: var(--text-primary);
34
+ min-height: 100vh;
35
+ overflow-x: hidden;
36
+ }
37
+
38
+ /* Animated Background */
39
+ .bg-animation {
40
+ position: fixed;
41
+ top: 0;
42
+ left: 0;
43
+ width: 100%;
44
+ height: 100%;
45
+ z-index: -1;
46
+ overflow: hidden;
47
+ }
48
+
49
+ .bg-animation::before {
50
+ content: '';
51
+ position: absolute;
52
+ width: 200%;
53
+ height: 200%;
54
+ background:
55
+ radial-gradient(circle at 20% 50%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
56
+ radial-gradient(circle at 80% 20%, rgba(236, 72, 153, 0.1) 0%, transparent 40%);
57
+ animation: bgPulse 15s ease-in-out infinite;
58
+ }
59
+
60
+ @keyframes bgPulse {
61
+ 0%, 100% { transform: translate(0, 0) scale(1); }
62
+ 50% { transform: translate(-5%, -5%) scale(1.1); }
63
+ }
64
+
65
+ /* Header */
66
+ header {
67
+ display: flex;
68
+ justify-content: space-between;
69
+ align-items: center;
70
+ padding: 1.5rem 2rem;
71
+ background: rgba(26, 26, 46, 0.8);
72
+ backdrop-filter: blur(10px);
73
+ border-bottom: 1px solid var(--border);
74
+ position: sticky;
75
+ top: 0;
76
+ z-index: 100;
77
+ }
78
+
79
+ .logo {
80
+ display: flex;
81
+ align-items: center;
82
+ gap: 0.75rem;
83
+ font-size: 1.5rem;
84
+ font-weight: 700;
85
+ background: var(--gradient);
86
+ -webkit-background-clip: text;
87
+ -webkit-text-fill-color: transparent;
88
+ background-clip: text;
89
+ }
90
+
91
+ .logo i {
92
+ -webkit-text-fill-color: var(--primary);
93
+ }
94
+
95
+ .anycoder-link {
96
+ color: var(--text-secondary);
97
+ text-decoration: none;
98
+ font-size: 0.9rem;
99
+ transition: color 0.3s ease;
100
+ }
101
+
102
+ .anycoder-link:hover {
103
+ color: var(--primary);
104
+ }
105
+
106
+ .anycoder-link span {
107
+ background: var(--gradient);
108
+ -webkit-background-clip: text;
109
+ -webkit-text-fill-color: transparent;
110
+ background-clip: text;
111
+ font-weight: 600;
112
+ }
113
+
114
+ /* Main Container */
115
+ .container {
116
+ max-width: 1400px;
117
+ margin: 0 auto;
118
+ padding: 2rem;
119
+ }
120
+
121
+ /* Generator Section */
122
+ .generator-section {
123
+ display: grid;
124
+ grid-template-columns: 1fr 320px;
125
+ gap: 2rem;
126
+ margin-bottom: 3rem;
127
+ }
128
+
129
+ @media (max-width: 1024px) {
130
+ .generator-section {
131
+ grid-template-columns: 1fr;
132
+ }
133
+ }
134
+
135
+ /* Input Card */
136
+ .input-card {
137
+ background: var(--bg-card);
138
+ border-radius: 20px;
139
+ padding: 2rem;
140
+ border: 1px solid var(--border);
141
+ position: relative;
142
+ overflow: hidden;
143
+ }
144
+
145
+ .input-card::before {
146
+ content: '';
147
+ position: absolute;
148
+ top: 0;
149
+ left: 0;
150
+ right: 0;
151
+ height: 3px;
152
+ background: var(--gradient);
153
+ }
154
+
155
+ .input-label {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 0.5rem;
159
+ font-size: 0.9rem;
160
+ color: var(--text-secondary);
161
+ margin-bottom: 1rem;
162
+ }
163
+
164
+ .prompt-input-container {
165
+ position: relative;
166
+ margin-bottom: 1.5rem;
167
+ }
168
+
169
+ .prompt-input {
170
+ width: 100%;
171
+ min-height: 120px;
172
+ padding: 1.25rem;
173
+ background: var(--bg-input);
174
+ border: 2px solid var(--border);
175
+ border-radius: 12px;
176
+ color: var(--text-primary);
177
+ font-size: 1rem;
178
+ resize: vertical;
179
+ transition: all 0.3s ease;
180
+ }
181
+
182
+ .prompt-input:focus {
183
+ outline: none;
184
+ border-color: var(--primary);
185
+ box-shadow: 0 0 20px rgba(99, 102, 241, 0.2);
186
+ }
187
+
188
+ .prompt-input::placeholder {
189
+ color: var(--text-secondary);
190
+ }
191
+
192
+ .char-count {
193
+ position: absolute;
194
+ bottom: 0.75rem;
195
+ right: 1rem;
196
+ font-size: 0.8rem;
197
+ color: var(--text-secondary);
198
+ }
199
+
200
+ /* Settings Grid */
201
+ .settings-grid {
202
+ display: grid;
203
+ grid-template-columns: repeat(3, 1fr);
204
+ gap: 1rem;
205
+ margin-bottom: 1.5rem;
206
+ }
207
+
208
+ @media (max-width: 768px) {
209
+ .settings-grid {
210
+ grid-template-columns: repeat(2, 1fr);
211
+ }
212
+ }
213
+
214
+ .setting-item {
215
+ display: flex;
216
+ flex-direction: column;
217
+ gap: 0.5rem;
218
+ }
219
+
220
+ .setting-label {
221
+ font-size: 0.85rem;
222
+ color: var(--text-secondary);
223
+ display: flex;
224
+ align-items: center;
225
+ gap: 0.5rem;
226
+ }
227
+
228
+ .setting-select {
229
+ padding: 0.75rem 1rem;
230
+ background: var(--bg-input);
231
+ border: 2px solid var(--border);
232
+ border-radius: 8px;
233
+ color: var(--text-primary);
234
+ font-size: 0.9rem;
235
+ cursor: pointer;
236
+ transition: all 0.3s ease;
237
+ }
238
+
239
+ .setting-select:focus {
240
+ outline: none;
241
+ border-color: var(--primary);
242
+ }
243
+
244
+ /* Generate Button */
245
+ .generate-btn {
246
+ width: 100%;
247
+ padding: 1rem 2rem;
248
+ background: var(--gradient);
249
+ border: none;
250
+ border-radius: 12px;
251
+ color: white;
252
+ font-size: 1.1rem;
253
+ font-weight: 600;
254
+ cursor: pointer;
255
+ display: flex;
256
+ align-items: center;
257
+ justify-content: center;
258
+ gap: 0.75rem;
259
+ transition: all 0.3s ease;
260
+ position: relative;
261
+ overflow: hidden;
262
+ }
263
+
264
+ .generate-btn::before {
265
+ content: '';
266
+ position: absolute;
267
+ top: 0;
268
+ left: -100%;
269
+ width: 100%;
270
+ height: 100%;
271
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
272
+ transition: left 0.5s ease;
273
+ }
274
+
275
+ .generate-btn:hover::before {
276
+ left: 100%;
277
+ }
278
+
279
+ .generate-btn:hover {
280
+ transform: translateY(-2px);
281
+ box-shadow: 0 10px 30px rgba(99, 102, 241, 0.4);
282
+ }
283
+
284
+ .generate-btn:active {
285
+ transform: translateY(0);
286
+ }
287
+
288
+ .generate-btn:disabled {
289
+ opacity: 0.6;
290
+ cursor: not-allowed;
291
+ transform: none;
292
+ }
293
+
294
+ .generate-btn .spinner {
295
+ display: none;
296
+ width: 20px;
297
+ height: 20px;
298
+ border: 2px solid rgba(255,255,255,0.3);
299
+ border-top-color: white;
300
+ border-radius: 50%;
301
+ animation: spin 0.8s linear infinite;
302
+ }
303
+
304
+ @keyframes spin {
305
+ to { transform: rotate(360deg); }
306
+ }
307
+
308
+ .generate-btn.loading .spinner {
309
+ display: block;
310
+ }
311
+
312
+ .generate-btn.loading .btn-text {
313
+ display: none;
314
+ }
315
+
316
+ /* Side Panel */
317
+ .side-panel {
318
+ display: flex;
319
+ flex-direction: column;
320
+ gap: 1rem;
321
+ }
322
+
323
+ .panel-card {
324
+ background: var(--bg-card);
325
+ border-radius: 16px;
326
+ padding: 1.5rem;
327
+ border: 1px solid var(--border);
328
+ }
329
+
330
+ .panel-title {
331
+ font-size: 1rem;
332
+ font-weight: 600;
333
+ margin-bottom: 1rem;
334
+ display: flex;
335
+ align-items: center;
336
+ gap: 0.5rem;
337
+ }
338
+
339
+ .style-tags {
340
+ display: flex;
341
+ flex-wrap: wrap;
342
+ gap: 0.5rem;
343
+ }
344
+
345
+ .style-tag {
346
+ padding: 0.5rem 1rem;
347
+ background: var(--bg-input);
348
+ border: 2px solid var(--border);
349
+ border-radius: 20px;
350
+ font-size: 0.85rem;
351
+ cursor: pointer;
352
+ transition: all 0.3s ease;
353
+ color: var(--text-secondary);
354
+ }
355
+
356
+ .style-tag:hover {
357
+ border-color: var(--primary);
358
+ color: var(--primary);
359
+ }
360
+
361
+ .style-tag.active {
362
+ background: var(--primary);
363
+ border-color: var(--primary);
364
+ color: white;
365
+ }
366
+
367
+ /* Gallery Section */
368
+ .gallery-section {
369
+ margin-top: 2rem;
370
+ }
371
+
372
+ .gallery-header {
373
+ display: flex;
374
+ justify-content: space-between;
375
+ align-items: center;
376
+ margin-bottom: 1.5rem;
377
+ }
378
+
379
+ .gallery-title {
380
+ font-size: 1.5rem;
381
+ font-weight: 700;
382
+ display: flex;
383
+ align-items: center;
384
+ gap: 0.75rem;
385
+ }
386
+
387
+ .gallery-actions {
388
+ display: flex;
389
+ gap: 0.75rem;
390
+ }
391
+
392
+ .gallery-btn {
393
+ padding: 0.75rem 1.25rem;
394
+ background: var(--bg-card);
395
+ border: 1px solid var(--border);
396
+ border-radius: 8px;
397
+ color: var(--text-primary);
398
+ font-size: 0.9rem;
399
+ cursor: pointer;
400
+ display: flex;
401
+ align-items: center;
402
+ gap: 0.5rem;
403
+ transition: all 0.3s ease;
404
+ }
405
+
406
+ .gallery-btn:hover {
407
+ border-color: var(--primary);
408
+ color: var(--primary);
409
+ }
410
+
411
+ /* Gallery Grid */
412
+ .gallery-grid {
413
+ display: grid;
414
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
415
+ gap: 1.5rem;
416
+ }
417
+
418
+ .gallery-item {
419
+ background: var(--bg-card);
420
+ border-radius: 16px;
421
+ overflow: hidden;
422
+ border: 1px solid var(--border);
423
+ transition: all 0.3s ease;
424
+ position: relative;
425
+ }
426
+
427
+ .gallery-item:hover {
428
+ transform: translateY(-5px);
429
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
430
+ border-color: var(--primary);
431
+ }
432
+
433
+ .gallery-image {
434
+ width: 100%;
435
+ aspect-ratio: 1;
436
+ object-fit: cover;
437
+ background: var(--bg-input);
438
+ display: flex;
439
+ align-items: center;
440
+ justify-content: center;
441
+ color: var(--text-secondary);
442
+ font-size: 3rem;
443
+ }
444
+
445
+ .gallery-image img {
446
+ width: 100%;
447
+ height: 100%;
448
+ object-fit: cover;
449
+ }
450
+
451
+ .gallery-info {
452
+ padding: 1rem;
453
+ }
454
+
455
+ .gallery-prompt {
456
+ font-size: 0.9rem;
457
+ color: var(--text-secondary);
458
+ margin-bottom: 0.75rem;
459
+ display: -webkit-box;
460
+ -webkit-line-clamp: 2;
461
+ -webkit-box-orient: vertical;
462
+ overflow: hidden;
463
+ }
464
+
465
+ .gallery-meta {
466
+ display: flex;
467
+ justify-content: space-between;
468
+ align-items: center;
469
+ font-size: 0.8rem;
470
+ color: var(--text-secondary);
471
+ }
472
+
473
+ .gallery-actions-small {
474
+ display: flex;
475
+ gap: 0.5rem;
476
+ }
477
+
478
+ .action-icon {
479
+ width: 32px;
480
+ height: 32px;
481
+ display: flex;
482
+ align-items: center;
483
+ justify-content: center;
484
+ background: var(--bg-input);
485
+ border-radius: 8px;
486
+ cursor: pointer;
487
+ transition: all 0.3s ease;
488
+ border: none;
489
+ color: var(--text-secondary);
490
+ }
491
+
492
+ .action-icon:hover {
493
+ background: var(--primary);
494
+ color: white;
495
+ }
496
+
497
+ .action-icon.download:hover {
498
+ background: var(--success);
499
+ }
500
+
501
+ .action-icon.delete:hover {
502
+ background: #ef4444;
503
+ }
504
+
505
+ /* Loading Overlay */
506
+ .loading-overlay {
507
+ position: fixed;
508
+ top: 0;
509
+ left: 0;
510
+ width: 100%;
511
+ height: 100%;
512
+ background: rgba(15, 15, 26, 0.9);
513
+ display: none;
514
+ justify-content: center;
515
+ align-items: center;
516
+ z-index: 1000;
517
+ flex-direction: column;
518
+ gap: 1.5rem;
519
+ }
520
+
521
+ .loading-overlay.active {
522
+ display: flex;
523
+ }
524
+
525
+ .loading-progress {
526
+ width: 300px;
527
+ height: 6px;
528
+ background: var(--bg-input);
529
+ border-radius: 3px;
530
+ overflow: hidden;
531
+ }
532
+
533
+ .loading-progress-bar {
534
+ height: 100%;
535
+ background: var(--gradient);
536
+ border-radius: 3px;
537
+ width: 0%;
538
+ transition: width 0.3s ease;
539
+ }
540
+
541
+ .loading-text {
542
+ font-size: 1.1rem;
543
+ color: var(--text-secondary);
544
+ }
545
+
546
+ /* Toast Notification */
547
+ .toast-container {
548
+ position: fixed;
549
+ bottom: 2rem;
550
+ right: 2rem;
551
+ z-index: 1000;
552
+ display: flex;
553
+ flex-direction: column;
554
+ gap: 0.75rem;
555
+ }
556
+
557
+ .toast {
558
+ background: var(--bg-card);
559
+ border: 1px solid var(--border);
560
+ border-radius: 12px;
561
+ padding: 1rem 1.5rem;
562
+ display: flex;
563
+ align-items: center;
564
+ gap: 0.75rem;
565
+ animation: slideIn 0.3s ease;
566
+ min-width: 300px;
567
+ }
568
+
569
+ @keyframes slideIn {
570
+ from {
571
+ transform: translateX(100%);
572
+ opacity: 0;
573
+ }
574
+ to {
575
+ transform: translateX(0);
576
+ opacity: 1;
577
+ }
578
+ }
579
+
580
+ .toast.success {
581
+ border-left: 4px solid var(--success);
582
+ }
583
+
584
+ .toast.error {
585
+ border-left: 4px solid #ef4444;
586
+ }
587
+
588
+ .toast.info {
589
+ border-left: 4px solid var(--primary);
590
+ }
591
+
592
+ /* Empty State */
593
+ .empty-state {
594
+ text-align: center;
595
+ padding: 4rem 2rem;
596
+ color: var(--text-secondary);
597
+ }
598
+
599
+ .empty-state i {
600
+ font-size: 4rem;
601
+ margin-bottom: 1rem;
602
+ opacity: 0.5;
603
+ }
604
+
605
+ .empty-state h3 {
606
+ font-size: 1.25rem;
607
+ margin-bottom: 0.5rem;
608
+ color: var(--text-primary);
609
+ }
610
+
611
+ /* Responsive Adjustments */
612
+ @media (max-width: 768px) {
613
+ header {
614
+ padding: 1rem;
615
+ }
616
+
617
+ .logo {
618
+ font-size: 1.2rem;
619
+ }
620
+
621
+ .container {
622
+ padding: 1rem;
623
+ }
624
+
625
+ .input-card, .panel-card {
626
+ padding: 1.5rem;
627
+ }
628
+
629
+ .gallery-header {
630
+ flex-direction: column;
631
+ gap: 1rem;
632
+ align-items: flex-start;
633
+ }
634
+
635
+ .toast-container {
636
+ left: 1rem;
637
+ right: 1rem;
638
+ bottom: 1rem;
639
+ }
640
+
641
+ .toast {
642
+ min-width: auto;
643
+ }
644
+ }
645
+
646
+ /* Image Preview Modal */
647
+ .modal {
648
+ position: fixed;
649
+ top: 0;
650
+ left: 0;
651
+ width: 100%;
652
+ height: 100%;
653
+ background: rgba(0, 0, 0, 0.9);
654
+ display: none;
655
+ justify-content: center;
656
+ align-items: center;
657
+ z-index: 2000;
658
+ padding: 2rem;
659
+ }
660
+
661
+ .modal.active {
662
+ display: flex;
663
+ }
664
+
665
+ .modal-content {
666
+ max-width: 90%;
667
+ max-height: 90%;
668
+ position: relative;
669
+ }
670
+
671
+ .modal-content img {
672
+ max-width: 100%;
673
+ max-height: 80vh;
674
+ border-radius: 12px;
675
+ }
676
+
677
+ .modal-close {
678
+ position: absolute;
679
+ top: -50px;
680
+ right: 0;
681
+ background: none;
682
+ border: none;
683
+ color: white;
684
+ font-size: 2rem;
685
+ cursor: pointer;
686
+ transition: transform 0.3s ease;
687
+ }
688
+
689
+ .modal-close:hover {
690
+ transform: scale(1.1);
691
+ }
692
+
693
+ .modal-actions {
694
+ display: flex;
695
+ justify-content: center;
696
+ gap: 1rem;
697
+ margin-top: 1.5rem;
698
+ }
699
+
700
+ .modal-btn {
701
+ padding: 0.75rem 2rem;
702
+ background: var(--bg-card);
703
+ border: 1px solid var(--border);
704
+ border-radius: 8px;
705
+ color: white;
706
+ cursor: pointer;
707
+ display: flex;
708
+ align-items: center;
709
+ gap: 0.5rem;
710
+ transition: all 0.3s ease;
711
+ }
712
+
713
+ .modal-btn:hover {
714
+ border-color: var(--primary);
715
+ }
716
+
717
+ .modal-btn.primary {
718
+ background: var(--primary);
719
+ border-color: var(--primary);
720
+ }
721
+
722
+ .modal-btn.primary:hover {
723
+ background: var(--primary-dark);
724
+ }
725
+ </style>
726
+ </head>
727
+ <body>
728
+ <div class="bg-animation"></div>
729
+
730
+ <header>
731
+ <div class="logo">
732
+ <i class="fas fa-cube"></i>
733
+ <span>DreamGen</span>
734
+ </div>
735
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
736
+ Built with <span>anycoder</span>
737
+ </a>
738
+ </header>
739
+
740
+ <div class="container">
741
+ <section class="generator-section">
742
+ <div class="input-card">
743
+ <div class="input-label">
744
+ <i class="fas fa-wand-magic-sparkles"></i>
745
+ Describe your image
746
+ </div>
747
+ <div class="prompt-input-container">
748
+ <textarea
749
+ class="prompt-input"
750
+ id="promptInput"
751
+ placeholder="A futuristic city with flying cars, neon lights, and towering skyscrapers at sunset..."
752
+ ></textarea>
753
+ <span class="char-count"><span id="charCount">0</span>/500</span>
754
+ </div>
755
+
756
+ <div class="settings-grid">
757
+ <div class="setting-item">
758
+ <label class="setting-label">
759
+ <i class="fas fa-expand"></i> Aspect Ratio
760
+ </label>
761
+ <select class="setting-select" id="aspectRatio">
762
+ <option value="1:1">Square (1:1)</option>
763
+ <option value="3:4">Portrait (3:4)</option>
764
+ <option value="4:3">Landscape (4:3)</option>
765
+ <option value="16:9">Wide (16:9)</option>
766
+ </select>
767
+ </div>
768
+ <div class="setting-item">
769
+ <label class="setting-label">
770
+ <i class="fas fa-palette"></i> Style
771
+ </label>
772
+ <select class="setting-select" id="imageStyle">
773
+ <option value="realistic">Realistic</option>
774
+ <option value="anime">Anime</option>
775
+ <option value="oil">Oil Painting</option>
776
+ <option value="watercolor">Watercolor</option>
777
+ <option value="3d">3D Render</option>
778
+ <option value="cyberpunk">Cyberpunk</option>
779
+ </select>
780
+ </div>
781
+ <div class="setting-item">
782
+ <label class="setting-label">
783
+ <i class="fas fa-layer-group"></i> Quality
784
+ </label>
785
+ <select class="setting-select" id="imageQuality">
786
+ <option value="standard">Standard</option>
787
+ <option value="hd">HD</option>
788
+ <option value="ultra">Ultra HD</option>
789
+ </select>
790
+ </div>
791
+ </div>
792
+
793
+ <button class="generate-btn" id="generateBtn" onclick="generateImage()">
794
+ <span class="btn-text">
795
+ <i class="fas fa-bolt"></i>
796
+ Generate Image
797
+ </span>
798
+ <div class="spinner"></div>
799
+ </button>
800
+ </div>
801
+
802
+ <div class="side-panel">
803
+ <div class="panel-card">
804
+ <h3 class="panel-title">
805
+ <i class="fas fa-paintbrush"></i>
806
+ Quick Styles
807
+ </h3>
808
+ <div class="style-tags">
809
+ <span class="style-tag active" onclick="selectStyle(this, 'photorealistic')">Photorealistic</span>
810
+ <span class="style-tag" onclick="selectStyle(this, 'digital art')">Digital Art</span>
811
+ <span class="style-tag" onclick="selectStyle(this, 'minimalist')">Minimalist</span>
812
+ <span class="style-tag" onclick="selectStyle(this, 'fantasy')">Fantasy</span>
813
+ <span class="style-tag" onclick="selectStyle(this, 'sci-fi')">Sci-Fi</span>
814
+ <span class="style-tag" onclick="selectStyle(this, 'vintage')">Vintage</span>
815
+ </div>
816
+ </div>
817
+
818
+ <div class="panel-card">
819
+ <h3 class="panel-title">
820
+ <i class="fas fa-lightbulb"></i>
821
+ Tips
822
+ </h3>
823
+ <ul style="color: var(--text-secondary); font-size: 0.9rem; line-height: 1.8; padding-left: 1.25rem;">
824
+ <li>Be specific about lighting</li>
825
+ <li>Mention camera angles</li>
826
+ <li>Include color palettes</li>
827
+ <li>Describe textures</li>
828
+ </ul>
829
+ </div>
830
+ </div>
831
+ </section>
832
+
833
+ <section class="gallery-section">
834
+ <div class="gallery-header">
835
+ <h2 class="gallery-title">
836
+ <i class="fas fa-images"></i>
837
+ Generated Images
838
+ </h2>
839
+ <div class="gallery-actions">
840
+ <button class="gallery-btn" onclick="clearGallery()">
841
+ <i class="fas fa-trash-can"></i>
842
+ Clear All
843
+ </button>
844
+ <button class="gallery-btn" onclick="downloadAll()">
845
+ <i class="fas fa-download"></i>
846
+ Download All
847
+ </button>
848
+ </div>
849
+ </div>
850
+
851
+ <div class="gallery-grid" id="galleryGrid">
852
+ <div class="empty-state">
853
+ <i class="fas fa-palette"></i>
854
+ <h3>No images yet</h3>
855
+ <p>Start generating amazing images with your prompts!</p>
856
+ </div>
857
+ </div>
858
+ </section>
859
+ </div>
860
+
861
+ <!-- Loading Overlay -->
862
+ <div class="loading-overlay" id="loadingOverlay">
863
+ <div class="loading-text" id="loadingText">Generating your image...</div>
864
+ <div class="loading-progress">
865
+ <div class="loading-progress-bar" id="progressBar"></div>
866
+ </div>
867
+ <div style="color: var(--text-secondary); font-size: 0.9rem;">This may take a moment</div>
868
+ </div>
869
+
870
+ <!-- Modal -->
871
+ <div class="modal" id="imageModal">
872
+ <div class="modal-content">
873
+ <button class="modal-close" onclick="closeModal()">&times;</button>
874
+ <img id="modalImage" src="" alt="Preview">
875
+ <div class="modal-actions">
876
+ <button class="modal-btn" onclick="closeModal()">
877
+ <i class="fas fa-xmark"></i> Close
878
+ </button>
879
+ <button class="modal-btn primary" id="modalDownloadBtn" onclick="downloadCurrentImage()">
880
+ <i class="fas fa-download"></i> Download
881
+ </button>
882
+ </div>
883
+ </div>
884
+ </div>
885
+
886
+ <!-- Toast Container -->
887
+ <div class="toast-container" id="toastContainer"></div>
888
+
889
+ <script>
890
+ // State management
891
+ let images = [];
892
+ let currentImageId = null;
893
+ let selectedStyle = 'photorealistic';
894
+
895
+ // DOM Elements
896
+ const promptInput = document.getElementById('promptInput');
897
+ const charCount = document.getElementById('charCount');
898
+ const generateBtn = document.getElementById('generateBtn');
899
+ const galleryGrid = document.getElementById('galleryGrid');
900
+ const loadingOverlay = document.getElementById('loadingOverlay');
901
+ const progressBar = document.getElementById('progressBar');
902
+ const loadingText = document.getElementById('loadingText');
903
+ const imageModal = document.getElementById('imageModal');
904
+ const modalImage = document.getElementById('modalImage');
905
+
906
+ // Character count
907
+ promptInput.addEventListener('input', function() {
908
+ const count = this.value.length;
909
+ charCount.textContent = count;
910
+
911
+ if (count > 500) {
912
+ charCount.style.color = '#ef4444';
913
+ } else {
914
+ charCount.style.color = 'var(--text-secondary)';
915
+ }
916
+ });
917
+
918
+ // Style selection
919
+ function selectStyle(element, style) {
920
+ document.querySelectorAll('.style-tag').forEach(tag => tag.classList.remove('active'));
921
+ element.classList.add('active');
922
+ selectedStyle = style;
923
+ }
924
+
925
+ // Add style to prompt
926
+ document.querySelectorAll('.style-tag').forEach(tag => {
927
+ tag.addEventListener('click', function() {
928
+ if (promptInput.value && !promptInput.value.includes(this.textContent)) {
929
+ promptInput.value += `, ${this.textContent} style`;
930
+ promptInput.dispatchEvent(new Event('input'));
931
+ }
932
+ });
933
+ });
934
+
935
+ // Generate Image
936
+ async function generateImage() {
937
+ const prompt = promptInput.value.trim();
938
+
939
+ if (!prompt) {
940
+ showToast('Please enter a prompt', 'error');
941
+ return;
942
+ }
943
+
944
+ if (prompt.length > 500) {
945
+ showToast('Prompt is too long (max 500 characters)', 'error');
946
+ return;
947
+ }
948
+
949
+ generateBtn.classList.add('loading');
950
+ generateBtn.disabled = true;
951
+ loadingOverlay.classList.add('active');
952
+
953
+ const aspectRatio = document.getElementById('aspectRatio').value;
954
+ const style = document.getElementById('imageStyle').value;
955
+ const quality = document.getElementById('imageQuality').value;
956
+
957
+ // Simulate generation progress
958
+ let progress = 0;
959
+ const progressInterval = setInterval(() => {
960
+ progress += Math.random() * 15;
961
+ if (progress > 90) progress = 90;
962
+ progressBar.style.width = progress + '%';
963
+ loadingText.textContent = getLoadingMessage(progress);
964
+ }, 200);
965
+
966
+ // Simulate API call delay
967
+ await new Promise(resolve => setTimeout(resolve, 3000 + Math.random() * 2000));
968
+
969
+ clearInterval(progressInterval);
970
+ progressBar.style.width = '100%';
971
+ loadingText.textContent = 'Complete!';
972
+
973
+ // Generate placeholder image
974
+ const seed = Date.now();
975
+ const width = aspectRatio === '16:9' ? 768 : aspectRatio === '3:4' ? 480 : aspectRatio === '4:3' ? 640 : 512;
976
+ const height = aspectRatio === '16:9' ? 432 : aspectRatio === '3:4' ? 640 : aspectRatio === '4:3' ? 480 : 512;
977
+
978
+ // Create a colored placeholder with text
979
+ const canvas = document.createElement('canvas');
980
+ canvas.width = width;
981
+ canvas.height = height;
982
+ const ctx = canvas.getContext('2d');
983
+
984
+ // Generate gradient based on prompt hash
985
+ const hue = Math.abs(hashString(prompt)) % 360;
986
+ const gradient = ctx.createLinearGradient(0, 0, width, height);
987
+ gradient.addColorStop(0, `hsl(${hue}, 60%, 20%)`);
988
+ gradient.addColorStop(1, `hsl(${(hue + 60) % 360}, 60%, 30%)`);
989
+ ctx.fillStyle = gradient;
990
+ ctx.fillRect(0, 0, width, height);
991
+
992
+ // Add decorative elements
993
+ for (let i = 0; i < 20; i++) {
994
+ ctx.beginPath();
995
+ ctx.arc(
996
+ Math.random() * width,
997
+ Math.random() * height,
998
+ Math.random() * 50 + 10,
999
+ 0,
1000
+ Math.PI * 2
1001
+ );
1002
+ ctx.fillStyle = `hsla(${(hue + Math.random() * 60) % 360}, 70%, 50%, 0.1)`;
1003
+ ctx.fill();
1004
+ }
1005
+
1006
+ // Add text
1007
+ ctx.font = 'bold 24px Arial';
1008
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
1009
+ ctx.textAlign = 'center';
1010
+ ctx.fillText('AI Generated', width / 2, height / 2 - 20);
1011
+ ctx.font = '16px Arial';
1012
+ ctx.fillText(`Style: ${style}`, width / 2, height / 2 + 20);
1013
+
1014
+ const imageData = canvas.toDataURL('image/png');
1015
+ const newImage = {
1016
+ id: seed,
1017
+ prompt: prompt,
1018
+ style: style,
1019
+ aspectRatio: aspectRatio,
1020
+ quality: quality,
1021
+ timestamp: new Date(),
1022
+ src: imageData
1023
+ };
1024
+
1025
+ images.unshift(newImage);
1026
+
1027
+ // Reset UI
1028
+ await new Promise(resolve => setTimeout(resolve, 500));
1029
+ loadingOverlay.classList.remove('active');
1030
+ generateBtn.classList.remove('loading');
1031
+ generateBtn.disabled = false;
1032
+ progressBar.style.width = '0%';
1033
+
1034
+ renderGallery();
1035
+ showToast('Image generated successfully!', 'success');
1036
+ }
1037
+
1038
+ function hashString(str) {
1039
+ let hash = 0;
1040
+ for (let i = 0; i < str.length; i++) {
1041
+ const char = str.charCodeAt(i);
1042
+ hash = ((hash << 5) - hash) + char;
1043
+ hash = hash & hash;
1044
+ }
1045
+ return Math.abs(hash);
1046
+ }
1047
+
1048
+ function getLoadingMessage(progress) {
1049
+ if (progress < 25) return 'Analyzing prompt...';
1050
+ if (progress < 50) return 'Creating composition...';
1051
+ if (progress < 75) return 'Adding details...';
1052
+ if (progress < 90) return 'Refining image...';
1053
+ return 'Finalizing...';
1054
+ }
1055
+
1056
+ // Render Gallery
1057
+ function renderGallery() {
1058
+ if (images.length === 0) {
1059
+ galleryGrid.innerHTML = `
1060
+ <div class="empty-state">
1061
+ <i class="fas fa-palette"></i>
1062
+ <h3>No images yet</h3>
1063
+ <p>Start generating amazing images with your prompts!</p>
1064
+ </div>
1065
+ `;
1066
+ return;
1067
+ }
1068
+
1069
+ galleryGrid.innerHTML = images.map(img => `
1070
+ <div class="gallery-item" data-id="${img.id}">
1071
+ <div class="gallery-image" onclick="openModal(${img.id})">
1072
+ <img src="${img.src}" alt="${img.prompt}" loading="lazy">
1073
+ </div>
1074
+ <div class="gallery-info">
1075
+ <p class="gallery-prompt">${img.prompt}</p>
1076
+ <div class="gallery-meta">
1077
+ <span><i class="fas fa-clock"></i> ${formatTime(img.timestamp)}</span>
1078
+ <div class="gallery-actions-small">
1079
+ <button class="action-icon" onclick="openModal(${img.id})" title="Preview">
1080
+ <i class="fas fa-eye"></i>
1081
+ </button>
1082
+ <button class="action-icon download" onclick="downloadImage(${img.id})" title="Download">
1083
+ <i class="fas fa-download"></i>
1084
+ </button>
1085
+ <button class="action-icon delete" onclick="deleteImage(${img.id})" title="Delete">
1086
+ <i class="fas fa-trash"></i>
1087
+ </button>
1088
+ </div>
1089
+ </div>
1090
+ </div>
1091
+ </div>
1092
+ `).join('');
1093
+ }
1094
+
1095
+ function formatTime(date) {
1096
+ const now = new Date();
1097
+ const diff = now - date;
1098
+ const minutes = Math.floor(diff / 60000);
1099
+ if (minutes < 1) return 'Just now';
1100
+ if (minutes < 60) return `${minutes}m ago`;
1101
+ return `${Math.floor(minutes / 60)}h ago`;
1102
+ }
1103
+
1104
+ // Image Actions
1105
+ function openModal(id) {
1106
+ const img = images.find(i => i.id === id);
1107
+ if (img) {
1108
+ currentImageId = id;
1109
+ modalImage.src = img.src;
1110
+ imageModal.classList.add('active');
1111
+ }
1112
+ }
1113
+
1114
+ function closeModal() {
1115
+ imageModal.classList.remove('active');
1116
+ currentImageId = null;
1117
+ }
1118
+
1119
+ function downloadImage(id) {
1120
+ const img = images.find(i => i.id === id);
1121
+ if (img) {
1122
+ const link = document.createElement('a');
1123
+ link.download = `dreamgen_${id}.png`;
1124
+ link.href = img.src;
1125
+ link.click();
1126
+ showToast('Image downloaded!', 'success');
1127
+ }
1128
+ }
1129
+
1130
+ function downloadCurrentImage() {
1131
+ if (currentImageId) {
1132
+ downloadImage(currentImageId);
1133
+ }
1134
+ }
1135
+
1136
+ function deleteImage(id) {
1137
+ images = images.filter(i => i.id !== id);
1138
+ renderGallery();
1139
+ showToast('Image deleted', 'info');
1140
+ }
1141
+
1142
+ function clearGallery() {
1143
+ if (images.length > 0 && confirm('Are you sure you want to delete all images?')) {
1144
+ images = [];
1145
+ renderGallery();
1146
+ showToast('All images cleared', 'info');
1147
+ }
1148
+ }
1149
+
1150
+ function downloadAll() {
1151
+ if (images.length === 0) {
1152
+ showToast('No images to download', 'error');
1153
+ return;
1154
+ }
1155
+
1156
+ images.forEach((img, index) => {
1157
+ setTimeout(() => {
1158
+ const link = document.createElement('a');
1159
+ link.download = `dreamgen_${img.id}.png`;
1160
+ link.href = img.src;
1161
+ link.click();
1162
+ }, index * 500);
1163
+ });
1164
+
1165
+ showToast('Downloading all images...', 'success');
1166
+ }
1167
+
1168
+ // Toast Notifications
1169
+ function showToast(message, type = 'info') {
1170
+ const container = document.getElementById('toastContainer');
1171
+ const toast = document.createElement('div');
1172
+ toast.className = `toast ${type}`;
1173
+
1174
+ const icon = type === 'success' ? 'fa-check-circle' :
1175
+ type === 'error' ? 'fa-exclamation-circle' :
1176
+ 'fa-info-circle';
1177
+
1178
+ toast.innerHTML = `
1179
+ <i class="fas ${icon}"></i>
1180
+ <span>${message}</span>
1181
+ `;
1182
+
1183
+ container.appendChild(toast);
1184
+
1185
+ setTimeout(() => {
1186
+ toast.style.animation = 'slideIn 0.3s ease reverse';
1187
+ setTimeout(() => toast.remove(), 300);
1188
+ }, 3000);
1189
+ }
1190
+
1191
+ // Close modal on outside click
1192
+ imageModal.addEventListener('click', function(e) {
1193
+ if (e.target === imageModal) {
1194
+ closeModal();
1195
+ }
1196
+ });
1197
+
1198
+ // Keyboard shortcuts
1199
+ document.addEventListener('keydown', function(e) {
1200
+ if (e.key === 'Escape' && imageModal.classList.contains('active')) {
1201
+ closeModal();
1202
+ }
1203
+ if (e.ctrlKey && e.key === 'Enter') {
1204
+ generateImage();
1205
+ }
1206
+ });
1207
+
1208
+ // Initial render
1209
+ renderGallery();
1210
+
1211
+ // Add some demo images on first load
1212
+ window.addEventListener('load', function() {
1213
+ setTimeout(() => {
1214
+ const demoPrompts = [
1215
+ 'A majestic dragon flying over misty mountains at golden hour',
1216
+ 'Cyberpunk city street at night with neon signs and rain',
1217
+ 'A cozy coffee shop interior with warm lighting and plants',
1218
+ 'Abstract geometric patterns in vibrant colors'
1219
+ ];
1220
+
1221
+ demoPrompts.forEach((prompt, i) => {
1222
+ setTimeout(() => {
1223
+ const canvas = document.createElement('canvas');
1224
+ canvas.width = 512;
1225
+ canvas.height = 512;
1226
+ const ctx = canvas.getContext('2d');
1227
+
1228
+ const hue = (i * 90) % 360;
1229
+ const gradient = ctx.createLinearGradient(0, 0, 512, 512);
1230
+ gradient.addColorStop(0, `hsl(${hue}, 50%, 15%)`);
1231
+ gradient.addColorStop(1, `hsl(${(hue + 60) % 360}, 50%, 25%)`);
1232
+ ctx.fillStyle = gradient;
1233
+ ctx.fillRect(0, 0, 512, 512);
1234
+
1235
+ for (let j = 0; j < 15; j++) {
1236
+ ctx.beginPath();
1237
+ ctx.arc(
1238
+ Math.random() * 512,
1239
+ Math.random() * 512,
1240
+ Math.random() * 80 + 20,
1241
+ 0,
1242
+ Math.PI * 2
1243
+ );
1244
+ ctx.fillStyle = `hsla(${(hue + Math.random() * 60) % 360}, 70%, 50%, 0.15)`;
1245
+ ctx.fill();
1246
+ }
1247
+
1248
+ ctx.font = 'bold 20px Arial';
1249
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
1250
+ ctx.textAlign = 'center';
1251
+ ctx.fillText('Demo Image', 256, 256);
1252
+
1253
+ images.push({
1254
+ id: Date.now() + i,
1255
+ prompt: prompt,
1256
+ style: 'realistic',
1257
+ aspectRatio: '1:1',
1258
+ quality: 'standard',
1259
+ timestamp: new Date(Date.now() - i * 60000),
1260
+ src: canvas.toDataURL('image/png')
1261
+ });
1262
+
1263
+ renderGallery();
1264
+ }, i * 200);
1265
+ });
1266
+ }, 1000);
1267
+ });
1268
+ </script>
1269
+ </body>
1270
+ </html>