Lee6x commited on
Commit
3795476
·
verified ·
1 Parent(s): ffaeccf

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +803 -461
index.html CHANGED
@@ -2,9 +2,14 @@
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>GNOSIS Sigil Grimoire</title>
7
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 
 
 
 
 
8
  <style>
9
  * {
10
  margin: 0;
@@ -13,28 +18,29 @@
13
  }
14
 
15
  :root {
16
- --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
- --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
18
- --dark-bg: #0f0f1e;
19
- --card-bg: rgba(255, 255, 255, 0.05);
 
 
20
  --text-primary: #ffffff;
21
- --text-secondary: #a0a0b8;
22
- --accent: #7c3aed;
23
- --accent-hover: #6d28d9;
24
- --border: rgba(255, 255, 255, 0.1);
25
- --shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
26
- --glass: rgba(255, 255, 255, 0.1);
27
- backdrop-filter: blur(4px);
28
- -webkit-backdrop-filter: blur(4px);
29
  }
30
 
31
  body {
32
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
33
- background: var(--dark-bg);
34
  color: var(--text-primary);
35
  min-height: 100vh;
36
- position: relative;
37
  overflow-x: hidden;
 
38
  }
39
 
40
  body::before {
@@ -42,135 +48,261 @@
42
  position: fixed;
43
  top: 0;
44
  left: 0;
45
- width: 100%;
46
- height: 100%;
47
  background:
48
- radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3), transparent 50%),
49
- radial-gradient(circle at 80% 80%, rgba(255, 119, 198, 0.3), transparent 50%),
50
- radial-gradient(circle at 40% 20%, rgba(255, 219, 98, 0.2), transparent 50%);
51
- z-index: -1;
52
- animation: float 20s ease-in-out infinite;
53
  }
54
 
55
- @keyframes float {
56
- 0%, 100% { transform: translate(0, 0) rotate(0deg); }
57
- 33% { transform: translate(30px, -30px) rotate(1deg); }
58
- 66% { transform: translate(-20px, 20px) rotate(-1deg); }
 
 
 
59
  }
60
 
61
- header {
62
- padding: 2rem;
63
- text-align: center;
64
- position: relative;
 
 
 
 
 
65
  }
66
 
67
- h1 {
68
- font-size: 3rem;
69
- font-weight: 800;
70
- background: var(--primary-gradient);
71
- -webkit-background-clip: text;
72
- -webkit-text-fill-color: transparent;
73
- background-clip: text;
74
- margin-bottom: 0.5rem;
75
- letter-spacing: -1px;
76
- animation: shimmer 3s ease-in-out infinite;
77
  }
78
 
79
- @keyframes shimmer {
80
- 0%, 100% { opacity: 1; }
81
- 50% { opacity: 0.8; }
 
82
  }
83
 
84
- .subtitle {
85
- color: var(--text-secondary);
86
- font-size: 1.1rem;
 
 
87
  }
88
 
89
- .credit {
90
- margin-top: 1rem;
91
- font-size: 0.9rem;
92
- color: var(--text-secondary);
 
 
93
  }
94
 
95
- .credit a {
96
- color: var(--accent);
97
- text-decoration: none;
98
- transition: color 0.3s;
99
  }
100
 
101
- .credit a:hover {
102
- color: var(--accent-hover);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
 
105
- main {
 
 
106
  max-width: 1200px;
107
  margin: 0 auto;
108
- padding: 2rem;
109
  }
110
 
111
- .card {
112
- background: var(--glass);
113
- border: 1px solid var(--border);
 
 
 
 
 
 
 
 
 
 
 
 
114
  border-radius: 20px;
115
- padding: 2rem;
116
- margin-bottom: 2rem;
117
- backdrop-filter: blur(10px);
118
- -webkit-backdrop-filter: blur(10px);
119
- box-shadow: var(--shadow);
120
- transition: transform 0.3s, box-shadow 0.3s;
121
  }
122
 
123
- .card:hover {
124
- transform: translateY(-5px);
125
- box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.5);
 
 
126
  }
127
 
128
- .section-title {
129
- font-size: 1.5rem;
130
- margin-bottom: 1.5rem;
131
  display: flex;
132
  align-items: center;
133
  gap: 0.5rem;
134
  }
135
 
136
- .icon {
137
- width: 24px;
138
- height: 24px;
139
- fill: currentColor;
140
  }
141
 
142
- .input-group {
143
- margin-bottom: 1.5rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
 
146
- label {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  display: block;
148
  margin-bottom: 0.5rem;
149
  color: var(--text-secondary);
150
- font-weight: 500;
151
  }
152
 
153
- input[type="text"] {
154
  width: 100%;
155
- padding: 1rem;
156
  background: rgba(255, 255, 255, 0.05);
157
- border: 1px solid var(--border);
158
  border-radius: 12px;
159
  color: var(--text-primary);
160
  font-size: 1rem;
161
  transition: all 0.3s;
162
  }
163
 
164
- input[type="text"]:focus {
165
  outline: none;
166
- border-color: var(--accent);
167
  background: rgba(255, 255, 255, 0.08);
168
- box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
 
171
- .btn {
172
- padding: 1rem 2rem;
173
- background: var(--primary-gradient);
 
174
  border: none;
175
  border-radius: 12px;
176
  color: white;
@@ -182,7 +314,7 @@
182
  overflow: hidden;
183
  }
184
 
185
- .btn::before {
186
  content: '';
187
  position: absolute;
188
  top: 0;
@@ -193,489 +325,699 @@
193
  transition: left 0.5s;
194
  }
195
 
196
- .btn:hover::before {
197
  left: 100%;
198
  }
199
 
200
- .btn:hover {
201
  transform: translateY(-2px);
202
- box-shadow: 0 10px 20px rgba(124, 58, 237, 0.3);
203
  }
204
 
205
- .btn:active {
206
  transform: translateY(0);
207
  }
208
 
209
- .sigil-result {
210
- margin-top: 1.5rem;
 
 
 
 
 
 
211
  padding: 1.5rem;
212
- background: linear-gradient(135deg, rgba(124, 58, 237, 0.1), rgba(147, 51, 234, 0.1));
213
- border: 1px solid rgba(124, 58, 237, 0.3);
214
- border-radius: 12px;
215
- text-align: center;
216
- font-family: 'Courier New', monospace;
217
- font-size: 1.5rem;
218
- letter-spacing: 0.2em;
219
- min-height: 60px;
 
220
  display: flex;
221
- align-items: center;
222
- justify-content: center;
223
- position: relative;
224
- overflow: hidden;
225
  }
226
 
227
- .sigil-result::before {
228
- content: '';
229
- position: absolute;
230
- top: -50%;
231
- left: -50%;
232
- width: 200%;
233
- height: 200%;
234
- background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
235
- animation: shimmer 2s infinite;
236
  }
237
 
238
- .archive-table {
239
- width: 100%;
240
- overflow-x: auto;
241
  }
242
 
243
- table {
244
  width: 100%;
245
- border-collapse: collapse;
 
 
 
 
246
  }
247
 
248
- th {
249
- background: rgba(124, 58, 237, 0.2);
250
- padding: 1rem;
251
- text-align: left;
252
- font-weight: 600;
253
- color: var(--text-primary);
254
- border-bottom: 2px solid var(--border);
 
 
255
  }
256
 
257
- td {
258
- padding: 1rem;
259
- border-bottom: 1px solid var(--border);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  color: var(--text-secondary);
 
 
 
261
  }
262
 
263
- tr {
264
- transition: background 0.3s;
 
265
  }
266
 
267
- tr:hover {
268
- background: rgba(124, 58, 237, 0.1);
269
  }
270
 
271
- .sigil-cell {
272
- font-family: 'Courier New', monospace;
273
- font-weight: 600;
274
- color: var(--accent);
275
- letter-spacing: 0.1em;
276
  }
277
 
278
- .empty-state {
279
- text-align: center;
280
- padding: 3rem;
281
- color: var(--text-secondary);
282
  }
283
 
284
- .modal {
 
 
 
 
285
  display: none;
 
 
 
286
  position: fixed;
287
  top: 0;
288
  left: 0;
289
- width: 100%;
290
- height: 100%;
291
  background: rgba(0, 0, 0, 0.8);
292
- z-index: 1000;
293
- justify-content: center;
294
  align-items: center;
 
 
295
  backdrop-filter: blur(5px);
296
  }
297
 
298
- .modal.active {
299
- display: flex;
300
- animation: fadeIn 0.3s;
301
- }
302
-
303
- @keyframes fadeIn {
304
- from { opacity: 0; }
305
- to { opacity: 1; }
306
- }
307
-
308
- .modal-content {
309
- background: var(--glass);
310
- border: 1px solid var(--border);
311
- border-radius: 20px;
312
- padding: 2rem;
313
- max-width: 90%;
314
- max-height: 90%;
315
- overflow-y: auto;
316
- position: relative;
317
- animation: slideUp 0.3s;
318
  }
319
 
320
- @keyframes slideUp {
321
- from { transform: translateY(50px); opacity: 0; }
322
- to { transform: translateY(0); opacity: 1; }
 
 
 
 
 
323
  }
324
 
325
- .modal-header {
326
- display: flex;
327
- justify-content: space-between;
328
- align-items: center;
329
- margin-bottom: 1.5rem;
330
  }
331
 
332
- .close-btn {
333
- background: none;
334
- border: none;
335
  color: var(--text-secondary);
336
- font-size: 1.5rem;
337
- cursor: pointer;
338
- transition: color 0.3s;
339
- }
340
-
341
- .close-btn:hover {
342
- color: var(--text-primary);
343
  }
344
 
345
  .toast {
346
  position: fixed;
347
- bottom: 2rem;
348
- right: 2rem;
349
- background: var(--glass);
350
- border: 1px solid var(--border);
 
351
  border-radius: 12px;
352
  padding: 1rem 1.5rem;
353
  backdrop-filter: blur(10px);
354
- transform: translateX(400px);
355
  transition: transform 0.3s;
356
  z-index: 2000;
357
  }
358
 
359
  .toast.show {
360
- transform: translateX(0);
361
  }
362
 
363
  .toast.success {
364
- border-color: rgba(72, 187, 120, 0.5);
365
- background: rgba(72, 187, 120, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  }
367
 
368
- .toast.warning {
369
- border-color: rgba(245, 158, 11, 0.5);
370
- background: rgba(245, 158, 11, 0.1);
371
  }
372
 
373
  @media (max-width: 768px) {
374
- h1 {
375
- font-size: 2rem;
376
  }
377
-
378
- .card {
379
- padding: 1.5rem;
380
  }
381
-
382
- th, td {
383
- padding: 0.75rem;
384
- font-size: 0.9rem;
385
  }
386
-
387
- .sigil-result {
388
- font-size: 1.2rem;
389
  }
390
  }
391
  </style>
392
  </head>
393
  <body>
394
- <header>
395
- <h1>GNOSIS Sigil Grimoire</h1>
396
- <p class="subtitle">Transform your intentions into mystical symbols</p>
397
- <p class="credit">Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder">anycoder</a></p>
398
- </header>
399
-
400
- <main>
401
- <section class="card">
402
- <h2 class="section-title">
403
- <svg class="icon" viewBox="0 0 24 24"><path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z" fill="currentColor"/></svg>
404
- Sigil Compiler
405
- </h2>
406
- <div class="input-group">
407
- <label for="phraseInput">Enter your intent phrase:</label>
408
- <input type="text" id="phraseInput" placeholder="I am confident and successful...">
409
  </div>
410
- <button class="btn" onclick="compileSigil()">Compile Sigil</button>
411
- <div class="sigil-result" id="sigilResult">
412
- Your sigil will appear here...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  </div>
414
- </section>
415
-
416
- <section class="card">
417
- <h2 class="section-title">
418
- <svg class="icon" viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z" fill="currentColor"/></svg>
419
- Sigil Archive
420
- </h2>
421
- <div class="archive-table">
422
- <table id="archiveTable">
423
- <thead>
424
- <tr>
425
- <th>Timestamp</th>
426
- <th>Phrase</th>
427
- <th>Sigil</th>
428
- </tr>
429
- </thead>
430
- <tbody id="archiveBody">
431
- <!-- Dynamic content -->
432
- </tbody>
433
- </table>
434
- <div class="empty-state" id="emptyState" style="display: none;">
435
- <p>No sigils compiled yet. Create your first sigil above!</p>
436
  </div>
437
  </div>
438
- <button class="btn" onclick="showTimeline()" style="margin-top: 1.5rem;">Show Sigil Timeline</button>
439
- </section>
440
- </main>
441
-
442
- <div class="modal" id="timelineModal">
443
- <div class="modal-content">
444
- <div class="modal-header">
445
- <h2 class="section-title">Sigil Timeline Visualization</h2>
446
- <button class="close-btn" onclick="closeModal()">&times;</button>
 
 
447
  </div>
448
- <canvas id="timelineChart"></canvas>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  </div>
450
  </div>
451
 
452
- <div class="toast" id="toast"></div>
 
 
 
 
 
 
453
 
454
  <script>
455
- // Sigil compilation and storage logic
456
- const STORAGE_KEY = 'gnosis_sigils';
 
 
457
 
458
- function compileSigil() {
459
- const phrase = document.getElementById('phraseInput').value.trim();
460
-
461
- if (!phrase) {
462
- showToast('Please enter a phrase.', 'warning');
463
- return;
464
- }
465
 
466
- const sigil = generateSigil(phrase);
467
- const resultDiv = document.getElementById('sigilResult');
468
- resultDiv.textContent = sigil;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
 
470
- // Add animation
471
- resultDiv.style.animation = 'none';
472
- setTimeout(() => {
473
- resultDiv.style.animation = 'shimmer 0.5s ease-in-out';
474
- }, 10);
475
-
476
- saveSigil(sigil, phrase);
477
- updateArchive();
478
- showToast('Sigil saved to archive!', 'success');
479
- }
480
-
481
- function generateSigil(phrase) {
482
- phrase = phrase.toUpperCase();
483
- const cleaned = phrase.replace(/[^A-Z]/g, '');
484
- const seen = new Set();
485
- let sigil = '';
486
 
487
- for (const char of cleaned) {
488
- if (!seen.has(char)) {
489
- sigil += char;
490
- seen.add(char);
491
- }
492
  }
493
 
494
- return sigil;
 
 
 
 
 
495
  }
496
 
497
- function saveSigil(sigil, phrase) {
498
- const timestamp = new Date().toISOString();
499
- const sigils = loadSigils();
500
- sigils.push({ timestamp, phrase, sigil });
501
- localStorage.setItem(STORAGE_KEY, JSON.stringify(sigils));
502
- }
 
 
 
 
 
 
503
 
504
- function loadSigils() {
505
- const stored = localStorage.getItem(STORAGE_KEY);
506
- return stored ? JSON.parse(stored) : [];
 
 
 
 
 
507
  }
508
 
509
- function updateArchive() {
510
- const sigils = loadSigils();
511
- const tbody = document.getElementById('archiveBody');
512
- const emptyState = document.getElementById('emptyState');
513
-
514
- tbody.innerHTML = '';
515
 
516
- if (sigils.length === 0) {
517
- emptyState.style.display = 'block';
518
- return;
519
- }
520
 
521
- emptyState.style.display = 'none';
522
 
523
- sigils.reverse().forEach(entry => {
524
- const row = tbody.insertRow();
525
- const date = new Date(entry.timestamp);
526
- const formattedDate = date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
527
-
528
- row.innerHTML = `
529
- <td>${formattedDate}</td>
530
- <td>"${entry.phrase}"</td>
531
- <td class="sigil-cell">${entry.sigil}</td>
532
- `;
533
- });
 
 
 
 
534
  }
535
 
536
- function showTimeline() {
537
- const sigils = loadSigils();
 
 
538
 
539
- if (sigils.length === 0) {
540
- showToast('No sigils to plot.', 'warning');
541
- return;
 
542
  }
 
 
 
 
 
 
 
543
 
544
- document.getElementById('timelineModal').classList.add('active');
 
 
 
545
 
546
- const ctx = document.getElementById('timelineChart').getContext('2d');
 
 
 
 
 
 
 
 
 
 
 
547
 
548
- // Clear previous chart
549
- Chart.getChart(ctx)?.destroy();
 
550
 
551
- const labels = sigils.map(s => {
552
- const date = new Date(s.timestamp);
553
- return date.toLocaleDateString() + '\n' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
554
- });
 
555
 
556
- const data = sigils.map((s, i) => ({
557
- x: i,
558
- y: s.sigil.length,
559
- label: s.sigil,
560
- phrase: s.phrase
561
- }));
562
-
563
- new Chart(ctx, {
564
- type: 'line',
565
- data: {
566
- labels: labels,
567
- datasets: [{
568
- label: 'Sigil Complexity',
569
- data: data,
570
- borderColor: 'rgb(124, 58, 237)',
571
- backgroundColor: 'rgba(124, 58, 237, 0.1)',
572
- tension: 0.4,
573
- fill: true,
574
- pointRadius: 6,
575
- pointHoverRadius: 8,
576
- pointBackgroundColor: 'rgb(124, 58, 237)',
577
- pointBorderColor: '#fff',
578
- pointBorderWidth: 2
579
- }]
580
- },
581
- options: {
582
- responsive: true,
583
- maintainAspectRatio: false,
584
- plugins: {
585
- title: {
586
- display: true,
587
- text: 'Sigil Creation Timeline',
588
- color: '#fff',
589
- font: {
590
- size: 16
591
- }
592
- },
593
- legend: {
594
- display: true,
595
- labels: {
596
- color: '#a0a0b8'
597
- }
598
- },
599
- tooltip: {
600
- callbacks: {
601
- label: function(context) {
602
- const dataPoint = context.raw;
603
- return [
604
- `Sigil: ${dataPoint.label}`,
605
- `Phrase: "${dataPoint.phrase}"`,
606
- `Complexity: ${dataPoint.y} characters`
607
- ];
608
- }
609
- }
610
- }
611
- },
612
- scales: {
613
- y: {
614
- beginAtZero: true,
615
- title: {
616
- display: true,
617
- text: 'Sigil Length',
618
- color: '#a0a0b8'
619
- },
620
- ticks: {
621
- color: '#a0a0b8'
622
- },
623
- grid: {
624
- color: 'rgba(255, 255, 255, 0.1)'
625
- }
626
- },
627
- x: {
628
- title: {
629
- display: true,
630
- text: 'Time',
631
- color: '#a0a0b8'
632
- },
633
- ticks: {
634
- color: '#a0a0b8',
635
- maxRotation: 45,
636
- minRotation: 45
637
- },
638
- grid: {
639
- color: 'rgba(255, 255, 255, 0.1)'
640
- }
641
- }
642
- }
643
- }
644
- });
645
  }
646
 
647
- function closeModal() {
648
- document.getElementById('timelineModal').classList.remove('active');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  }
650
 
651
- function showToast(message, type = 'success') {
652
- const toast = document.getElementById('toast');
653
- toast.textContent = message;
654
- toast.className = `toast ${type} show`;
655
 
656
- setTimeout(() => {
657
- toast.classList.remove('show');
658
- }, 3000);
 
 
 
 
 
659
  }
660
 
661
- // Event listeners
662
- document.getElementById('phraseInput').addEventListener('keypress', function(e) {
663
- if (e.key === 'Enter') {
664
- compileSigil();
665
- }
666
- });
667
 
668
- // Close modal on outside click
669
- document.getElementById('timelineModal').addEventListener('click', function(e) {
670
- if (e.target === this) {
671
- closeModal();
672
- }
673
- });
674
 
675
- // Initialize archive on load
676
- document.addEventListener('DOMContentLoaded', function() {
677
- updateArchive();
678
- });
679
- </script>
680
- </body>
681
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>AI Image Editor - Text Prompt Magic</title>
7
+ <meta name="theme-color" content="#6366f1">
8
+ <meta name="apple-mobile-web-app-capable" content="yes">
9
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
10
+ <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiQUkgSW1hZ2UgRWRpdG9yIiwic2hvcnRfbmFtZSI6IkltYWdlRWRpdCIsInN0YXJ0X3VybCI6Ii8iLCJkaXNwbGF5Ijoic3RhbmRhbG9uZSIsImJhY2tncm91bmRfY29sb3IiOiIjMWUxYjI0IiwidGhlbWVfY29sb3IiOiIjNjM2NmYxIn0=">
11
+ <link rel="icon" type="image/png" sizes="192x192" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHKSURBVHic7cExAQAAAMKg9U9tCF+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOL/AP8gBMEBVEiBQwABmWWL6QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDFPgAAFfEJdQAAAAASUVORK5CYII=">
12
+
13
  <style>
14
  * {
15
  margin: 0;
 
18
  }
19
 
20
  :root {
21
+ --primary: #6366f1;
22
+ --primary-dark: #4f46e5;
23
+ --secondary: #ec4899;
24
+ --surface: #1e1b2e;
25
+ --surface-light: #2d2a3e;
26
+ --surface-lighter: #3a3652;
27
  --text-primary: #ffffff;
28
+ --text-secondary: #a8a3b8;
29
+ --accent: #22d3ee;
30
+ --success: #10b981;
31
+ --warning: #f59e0b;
32
+ --error: #ef4444;
33
+ --gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
34
+ --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
 
35
  }
36
 
37
  body {
38
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
39
+ background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
40
  color: var(--text-primary);
41
  min-height: 100vh;
 
42
  overflow-x: hidden;
43
+ position: relative;
44
  }
45
 
46
  body::before {
 
48
  position: fixed;
49
  top: 0;
50
  left: 0;
51
+ right: 0;
52
+ bottom: 0;
53
  background:
54
+ radial-gradient(circle at 20% 80%, rgba(99, 102, 241, 0.2) 0%, transparent 50%),
55
+ radial-gradient(circle at 80% 20%, rgba(236, 72, 153, 0.2) 0%, transparent 50%),
56
+ radial-gradient(circle at 40% 40%, rgba(34, 211, 238, 0.1) 0%, transparent 50%);
57
+ pointer-events: none;
58
+ z-index: 1;
59
  }
60
 
61
+ .app-container {
62
+ position: relative;
63
+ z-index: 2;
64
+ max-width: 100vw;
65
+ min-height: 100vh;
66
+ display: flex;
67
+ flex-direction: column;
68
  }
69
 
70
+ .status-bar {
71
+ background: rgba(30, 27, 46, 0.95);
72
+ backdrop-filter: blur(20px);
73
+ padding: 0.5rem 1rem;
74
+ display: flex;
75
+ justify-content: space-between;
76
+ align-items: center;
77
+ font-size: 0.85rem;
78
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
79
  }
80
 
81
+ .status-bar-left {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 0.5rem;
 
 
 
 
 
 
85
  }
86
 
87
+ .status-bar-right {
88
+ display: flex;
89
+ align-items: center;
90
+ gap: 0.5rem;
91
  }
92
 
93
+ .main-header {
94
+ background: rgba(30, 27, 46, 0.9);
95
+ backdrop-filter: blur(20px);
96
+ padding: 1rem;
97
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
98
  }
99
 
100
+ .header-content {
101
+ display: flex;
102
+ justify-content: space-between;
103
+ align-items: center;
104
+ max-width: 1200px;
105
+ margin: 0 auto;
106
  }
107
 
108
+ .logo {
109
+ display: flex;
110
+ align-items: center;
111
+ gap: 0.75rem;
112
  }
113
 
114
+ .logo-icon {
115
+ width: 40px;
116
+ height: 40px;
117
+ background: var(--gradient);
118
+ border-radius: 12px;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ font-size: 1.5rem;
123
+ }
124
+
125
+ .logo-text {
126
+ font-size: 1.25rem;
127
+ font-weight: 700;
128
+ background: var(--gradient);
129
+ -webkit-background-clip: text;
130
+ -webkit-text-fill-color: transparent;
131
  }
132
 
133
+ .main-content {
134
+ flex: 1;
135
+ padding: 1rem;
136
  max-width: 1200px;
137
  margin: 0 auto;
138
+ width: 100%;
139
  }
140
 
141
+ .editor-workspace {
142
+ display: grid;
143
+ grid-template-columns: 1fr;
144
+ gap: 1rem;
145
+ margin-bottom: 1rem;
146
+ }
147
+
148
+ @media (min-width: 768px) {
149
+ .editor-workspace {
150
+ grid-template-columns: 2fr 1fr;
151
+ }
152
+ }
153
+
154
+ .canvas-section {
155
+ background: var(--surface-light);
156
  border-radius: 20px;
157
+ padding: 1.5rem;
158
+ border: 1px solid rgba(255, 255, 255, 0.1);
159
+ min-height: 400px;
160
+ display: flex;
161
+ flex-direction: column;
 
162
  }
163
 
164
+ .canvas-header {
165
+ display: flex;
166
+ justify-content: space-between;
167
+ align-items: center;
168
+ margin-bottom: 1rem;
169
  }
170
 
171
+ .canvas-title {
172
+ font-size: 1.1rem;
173
+ font-weight: 600;
174
  display: flex;
175
  align-items: center;
176
  gap: 0.5rem;
177
  }
178
 
179
+ .canvas-actions {
180
+ display: flex;
181
+ gap: 0.5rem;
 
182
  }
183
 
184
+ .icon-btn {
185
+ width: 36px;
186
+ height: 36px;
187
+ border-radius: 10px;
188
+ border: 1px solid rgba(255, 255, 255, 0.1);
189
+ background: rgba(255, 255, 255, 0.05);
190
+ color: var(--text-secondary);
191
+ display: flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ cursor: pointer;
195
+ transition: all 0.3s;
196
+ }
197
+
198
+ .icon-btn:hover {
199
+ background: rgba(255, 255, 255, 0.1);
200
+ color: var(--text-primary);
201
+ transform: translateY(-2px);
202
  }
203
 
204
+ .canvas-container {
205
+ flex: 1;
206
+ background: rgba(0, 0, 0, 0.3);
207
+ border-radius: 16px;
208
+ display: flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ position: relative;
212
+ overflow: hidden;
213
+ min-height: 300px;
214
+ }
215
+
216
+ #imageCanvas {
217
+ max-width: 100%;
218
+ max-height: 100%;
219
+ border-radius: 12px;
220
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
221
+ }
222
+
223
+ .upload-prompt {
224
+ text-align: center;
225
+ color: var(--text-secondary);
226
+ }
227
+
228
+ .upload-icon {
229
+ font-size: 4rem;
230
+ margin-bottom: 1rem;
231
+ opacity: 0.5;
232
+ }
233
+
234
+ .prompt-section {
235
+ background: var(--surface-light);
236
+ border-radius: 20px;
237
+ padding: 1.5rem;
238
+ border: 1px solid rgba(255, 255, 255, 0.1);
239
+ }
240
+
241
+ .prompt-header {
242
+ font-size: 1.1rem;
243
+ font-weight: 600;
244
+ margin-bottom: 1rem;
245
+ display: flex;
246
+ align-items: center;
247
+ gap: 0.5rem;
248
+ }
249
+
250
+ .prompt-input-group {
251
+ margin-bottom: 1rem;
252
+ }
253
+
254
+ .prompt-label {
255
  display: block;
256
  margin-bottom: 0.5rem;
257
  color: var(--text-secondary);
258
+ font-size: 0.9rem;
259
  }
260
 
261
+ .prompt-input {
262
  width: 100%;
263
+ padding: 0.75rem;
264
  background: rgba(255, 255, 255, 0.05);
265
+ border: 2px solid rgba(255, 255, 255, 0.1);
266
  border-radius: 12px;
267
  color: var(--text-primary);
268
  font-size: 1rem;
269
  transition: all 0.3s;
270
  }
271
 
272
+ .prompt-input:focus {
273
  outline: none;
274
+ border-color: var(--primary);
275
  background: rgba(255, 255, 255, 0.08);
276
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
277
+ }
278
+
279
+ .prompt-suggestions {
280
+ display: flex;
281
+ flex-wrap: wrap;
282
+ gap: 0.5rem;
283
+ margin-bottom: 1rem;
284
+ }
285
+
286
+ .suggestion-chip {
287
+ padding: 0.5rem 1rem;
288
+ background: rgba(255, 255, 255, 0.05);
289
+ border: 1px solid rgba(255, 255, 255, 0.1);
290
+ border-radius: 20px;
291
+ font-size: 0.85rem;
292
+ cursor: pointer;
293
+ transition: all 0.3s;
294
+ }
295
+
296
+ .suggestion-chip:hover {
297
+ background: var(--primary);
298
+ border-color: var(--primary);
299
+ transform: translateY(-2px);
300
  }
301
 
302
+ .action-btn {
303
+ width: 100%;
304
+ padding: 1rem;
305
+ background: var(--gradient);
306
  border: none;
307
  border-radius: 12px;
308
  color: white;
 
314
  overflow: hidden;
315
  }
316
 
317
+ .action-btn::before {
318
  content: '';
319
  position: absolute;
320
  top: 0;
 
325
  transition: left 0.5s;
326
  }
327
 
328
+ .action-btn:hover::before {
329
  left: 100%;
330
  }
331
 
332
+ .action-btn:hover {
333
  transform: translateY(-2px);
334
+ box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3);
335
  }
336
 
337
+ .action-btn:active {
338
  transform: translateY(0);
339
  }
340
 
341
+ .action-btn:disabled {
342
+ opacity: 0.5;
343
+ cursor: not-allowed;
344
+ }
345
+
346
+ .adjustments-section {
347
+ background: var(--surface-light);
348
+ border-radius: 20px;
349
  padding: 1.5rem;
350
+ border: 1px solid rgba(255, 255, 255, 0.1);
351
+ margin-top: 1rem;
352
+ }
353
+
354
+ .adjustment-slider {
355
+ margin-bottom: 1.5rem;
356
+ }
357
+
358
+ .slider-header {
359
  display: flex;
360
+ justify-content: space-between;
361
+ margin-bottom: 0.5rem;
 
 
362
  }
363
 
364
+ .slider-label {
365
+ color: var(--text-secondary);
366
+ font-size: 0.9rem;
 
 
 
 
 
 
367
  }
368
 
369
+ .slider-value {
370
+ color: var(--primary);
371
+ font-weight: 600;
372
  }
373
 
374
+ .slider {
375
  width: 100%;
376
+ height: 6px;
377
+ border-radius: 3px;
378
+ background: rgba(255, 255, 255, 0.1);
379
+ outline: none;
380
+ -webkit-appearance: none;
381
  }
382
 
383
+ .slider::-webkit-slider-thumb {
384
+ -webkit-appearance: none;
385
+ appearance: none;
386
+ width: 20px;
387
+ height: 20px;
388
+ border-radius: 50%;
389
+ background: var(--primary);
390
+ cursor: pointer;
391
+ transition: all 0.3s;
392
  }
393
 
394
+ .slider::-webkit-slider-thumb:hover {
395
+ transform: scale(1.2);
396
+ box-shadow: 0 0 10px rgba(99, 102, 241, 0.5);
397
+ }
398
+
399
+ .slider::-moz-range-thumb {
400
+ width: 20px;
401
+ height: 20px;
402
+ border-radius: 50%;
403
+ background: var(--primary);
404
+ cursor: pointer;
405
+ transition: all 0.3s;
406
+ }
407
+
408
+ .bottom-nav {
409
+ background: rgba(30, 27, 46, 0.95);
410
+ backdrop-filter: blur(20px);
411
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
412
+ display: flex;
413
+ justify-content: space-around;
414
+ padding: 0.5rem 0;
415
+ }
416
+
417
+ .nav-item {
418
+ display: flex;
419
+ flex-direction: column;
420
+ align-items: center;
421
+ padding: 0.5rem 1rem;
422
  color: var(--text-secondary);
423
+ cursor: pointer;
424
+ transition: all 0.3s;
425
+ border-radius: 12px;
426
  }
427
 
428
+ .nav-item:hover {
429
+ color: var(--text-primary);
430
+ background: rgba(255, 255, 255, 0.05);
431
  }
432
 
433
+ .nav-item.active {
434
+ color: var(--primary);
435
  }
436
 
437
+ .nav-icon {
438
+ font-size: 1.5rem;
439
+ margin-bottom: 0.25rem;
 
 
440
  }
441
 
442
+ .nav-label {
443
+ font-size: 0.75rem;
 
 
444
  }
445
 
446
+ .hidden {
447
+ display: none !important;
448
+ }
449
+
450
+ .file-input {
451
  display: none;
452
+ }
453
+
454
+ .loading-overlay {
455
  position: fixed;
456
  top: 0;
457
  left: 0;
458
+ right: 0;
459
+ bottom: 0;
460
  background: rgba(0, 0, 0, 0.8);
461
+ display: flex;
 
462
  align-items: center;
463
+ justify-content: center;
464
+ z-index: 1000;
465
  backdrop-filter: blur(5px);
466
  }
467
 
468
+ .loading-content {
469
+ text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  }
471
 
472
+ .loading-spinner {
473
+ width: 60px;
474
+ height: 60px;
475
+ border: 4px solid rgba(255, 255, 255, 0.1);
476
+ border-top: 4px solid var(--primary);
477
+ border-radius: 50%;
478
+ animation: spin 1s linear infinite;
479
+ margin: 0 auto 1rem;
480
  }
481
 
482
+ @keyframes spin {
483
+ 0% { transform: rotate(0deg); }
484
+ 100% { transform: rotate(360deg); }
 
 
485
  }
486
 
487
+ .loading-text {
 
 
488
  color: var(--text-secondary);
 
 
 
 
 
 
 
489
  }
490
 
491
  .toast {
492
  position: fixed;
493
+ bottom: 5rem;
494
+ left: 50%;
495
+ transform: translateX(-50%) translateY(100px);
496
+ background: var(--surface-light);
497
+ border: 1px solid rgba(255, 255, 255, 0.2);
498
  border-radius: 12px;
499
  padding: 1rem 1.5rem;
500
  backdrop-filter: blur(10px);
 
501
  transition: transform 0.3s;
502
  z-index: 2000;
503
  }
504
 
505
  .toast.show {
506
+ transform: translateX(-50%) translateY(0);
507
  }
508
 
509
  .toast.success {
510
+ border-color: var(--success);
511
+ background: rgba(16, 185, 129, 0.1);
512
+ }
513
+
514
+ .toast.error {
515
+ border-color: var(--error);
516
+ background: rgba(239, 68, 68, 0.1);
517
+ }
518
+
519
+ .gallery-grid {
520
+ display: grid;
521
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
522
+ gap: 1rem;
523
+ padding: 1rem;
524
+ }
525
+
526
+ .gallery-item {
527
+ aspect-ratio: 1;
528
+ background: var(--surface-light);
529
+ border-radius: 12px;
530
+ overflow: hidden;
531
+ cursor: pointer;
532
+ transition: all 0.3s;
533
+ position: relative;
534
+ }
535
+
536
+ .gallery-item:hover {
537
+ transform: scale(1.05);
538
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
539
+ }
540
+
541
+ .gallery-item img {
542
+ width: 100%;
543
+ height: 100%;
544
+ object-fit: cover;
545
+ }
546
+
547
+ .gallery-item-overlay {
548
+ position: absolute;
549
+ bottom: 0;
550
+ left: 0;
551
+ right: 0;
552
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent);
553
+ padding: 0.5rem;
554
+ color: white;
555
+ font-size: 0.75rem;
556
+ }
557
+
558
+ .credit {
559
+ position: fixed;
560
+ bottom: 1rem;
561
+ left: 1rem;
562
+ font-size: 0.75rem;
563
+ color: var(--text-secondary);
564
+ z-index: 10;
565
+ }
566
+
567
+ .credit a {
568
+ color: var(--primary);
569
+ text-decoration: none;
570
  }
571
 
572
+ .credit a:hover {
573
+ text-decoration: underline;
 
574
  }
575
 
576
  @media (max-width: 768px) {
577
+ .logo-text {
578
+ display: none;
579
  }
580
+
581
+ .canvas-section {
582
+ padding: 1rem;
583
  }
584
+
585
+ .prompt-section {
586
+ padding: 1rem;
 
587
  }
588
+
589
+ .adjustments-section {
590
+ padding: 1rem;
591
  }
592
  }
593
  </style>
594
  </head>
595
  <body>
596
+ <div class="app-container">
597
+ <!-- Status Bar -->
598
+ <div class="status-bar">
599
+ <div class="status-bar-left">
600
+ <span id="time">9:41 AM</span>
601
+ </div>
602
+ <div class="status-bar-right">
603
+ <span>📶</span>
604
+ <span>📶</span>
605
+ <span>🔋 100%</span>
 
 
 
 
 
606
  </div>
607
+ </div>
608
+
609
+ <!-- Main Header -->
610
+ <header class="main-header">
611
+ <div class="header-content">
612
+ <div class="logo">
613
+ <div class="logo-icon">🎨</div>
614
+ <div class="logo-text">AI Image Editor</div>
615
+ </div>
616
+ <button class="icon-btn" onclick="showInfo()">
617
+ <span>ℹ️</span>
618
+ </button>
619
+ </div>
620
+ </header>
621
+
622
+ <!-- Main Content -->
623
+ <main class="main-content">
624
+ <!-- Editor Tab -->
625
+ <div id="editorTab" class="tab-content">
626
+ <div class="editor-workspace">
627
+ <!-- Canvas Section -->
628
+ <div class="canvas-section">
629
+ <div class="canvas-header">
630
+ <div class="canvas-title">
631
+ <span>📸</span>
632
+ <span>Canvas</span>
633
+ </div>
634
+ <div class="canvas-actions">
635
+ <button class="icon-btn" onclick="resetImage()">
636
+ <span>🔄</span>
637
+ </button>
638
+ <button class="icon-btn" onclick="saveImage()">
639
+ <span>💾</span>
640
+ </button>
641
+ </div>
642
+ </div>
643
+ <div class="canvas-container">
644
+ <div id="uploadPrompt" class="upload-prompt">
645
+ <div class="upload-icon">📷</div>
646
+ <p>Upload an image to start editing</p>
647
+ <button class="action-btn" style="margin-top: 1rem; max-width: 200px;" onclick="document.getElementById('fileInput').click()">
648
+ Choose Image
649
+ </button>
650
+ </div>
651
+ <canvas id="imageCanvas" class="hidden"></canvas>
652
+ </div>
653
+ </div>
654
+
655
+ <!-- Prompt Section -->
656
+ <div class="prompt-section">
657
+ <div class="prompt-header">
658
+ <span>✨</span>
659
+ <span>AI Magic Prompt</span>
660
+ </div>
661
+
662
+ <div class="prompt-input-group">
663
+ <label class="prompt-label">Describe your edit:</label>
664
+ <input type="text" id="promptInput" class="prompt-input" placeholder="e.g., make it look like a painting...">
665
+ </div>
666
+
667
+ <div class="prompt-suggestions">
668
+ <div class="suggestion-chip" onclick="setPrompt('make it vintage')">🎞️ Vintage</div>
669
+ <div class="suggestion-chip" onclick="setPrompt('add neon lights')">💫 Neon</div>
670
+ <div class="suggestion-chip" onclick="setPrompt('cartoon style')">🎨 Cartoon</div>
671
+ <div class="suggestion-chip" onclick="setPrompt('cyberpunk')">🤖 Cyberpunk</div>
672
+ <div class="suggestion-chip" onclick="setPrompt('black and white')">⚫ B&W</div>
673
+ </div>
674
+
675
+ <button class="action-btn" id="applyBtn" onclick="applyPrompt()" disabled>
676
+ Apply Magic ✨
677
+ </button>
678
+ </div>
679
+ </div>
680
+
681
+ <!-- Adjustments Section -->
682
+ <div class="adjustments-section">
683
+ <div class="prompt-header">
684
+ <span>🎛️</span>
685
+ <span>Quick Adjustments</span>
686
+ </div>
687
+
688
+ <div class="adjustment-slider">
689
+ <div class="slider-header">
690
+ <span class="slider-label">Brightness</span>
691
+ <span class="slider-value" id="brightnessValue">100%</span>
692
+ </div>
693
+ <input type="range" class="slider" id="brightnessSlider" min="0" max="200" value="100" oninput="adjustImage()">
694
+ </div>
695
+
696
+ <div class="adjustment-slider">
697
+ <div class="slider-header">
698
+ <span class="slider-label">Contrast</span>
699
+ <span class="slider-value" id="contrastValue">100%</span>
700
+ </div>
701
+ <input type="range" class="slider" id="contrastSlider" min="0" max="200" value="100" oninput="adjustImage()">
702
+ </div>
703
+
704
+ <div class="adjustment-slider">
705
+ <div class="slider-header">
706
+ <span class="slider-label">Saturation</span>
707
+ <span class="slider-value" id="saturationValue">100%</span>
708
+ </div>
709
+ <input type="range" class="slider" id="saturationSlider" min="0" max="200" value="100" oninput="adjustImage()">
710
+ </div>
711
+
712
+ <div class="adjustment-slider">
713
+ <div class="slider-header">
714
+ <span class="slider-label">Blur</span>
715
+ <span class="slider-value" id="blurValue">0px</span>
716
+ </div>
717
+ <input type="range" class="slider" id="blurSlider" min="0" max="10" value="0" oninput="adjustImage()">
718
+ </div>
719
+ </div>
720
  </div>
721
+
722
+ <!-- Gallery Tab -->
723
+ <div id="galleryTab" class="tab-content hidden">
724
+ <div class="gallery-grid" id="galleryGrid">
725
+ <!-- Gallery items will be added dynamically -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
  </div>
727
  </div>
728
+ </main>
729
+
730
+ <!-- Bottom Navigation -->
731
+ <nav class="bottom-nav">
732
+ <div class="nav-item active" onclick="switchTab('editor')">
733
+ <span class="nav-icon">🎨</span>
734
+ <span class="nav-label">Edit</span>
735
+ </div>
736
+ <div class="nav-item" onclick="switchTab('gallery')">
737
+ <span class="nav-icon">🖼️</span>
738
+ <span class="nav-label">Gallery</span>
739
  </div>
740
+ <div class="nav-item" onclick="switchTab('templates')">
741
+ <span class="nav-icon">📋</span>
742
+ <span class="nav-label">Templates</span>
743
+ </div>
744
+ <div class="nav-item" onclick="switchTab('settings')">
745
+ <span class="nav-icon">⚙️</span>
746
+ <span class="nav-label">Settings</span>
747
+ </div>
748
+ </nav>
749
+ </div>
750
+
751
+ <!-- Hidden File Input -->
752
+ <input type="file" id="fileInput" class="file-input" accept="image/*" onchange="handleImageUpload(event)">
753
+
754
+ <!-- Loading Overlay -->
755
+ <div id="loadingOverlay" class="loading-overlay hidden">
756
+ <div class="loading-content">
757
+ <div class="loading-spinner"></div>
758
+ <div class="loading-text">Applying magic...</div>
759
  </div>
760
  </div>
761
 
762
+ <!-- Toast Notification -->
763
+ <div id="toast" class="toast"></div>
764
+
765
+ <!-- Credit -->
766
+ <div class="credit">
767
+ Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder">anycoder</a>
768
+ </div>
769
 
770
  <script>
771
+ // Global variables
772
+ let currentImage = null;
773
+ let originalImageData = null;
774
+ let galleryImages = [];
775
 
776
+ // Initialize app
777
+ document.addEventListener('DOMContentLoaded', function() {
778
+ updateTime();
779
+ setInterval(updateTime, 60000);
780
+ loadGallery();
781
+ initializeCanvas();
782
+ });
783
 
784
+ // Update time in status bar
785
+ function updateTime() {
786
+ const now = new Date();
787
+ const time = now.toLocaleTimeString('en-US', {
788
+ hour: 'numeric',
789
+ minute: '2-digit',
790
+ hour12: true
791
+ });
792
+ document.getElementById('time').textContent = time;
793
+ }
794
+
795
+ // Initialize canvas
796
+ function initializeCanvas() {
797
+ const canvas = document.getElementById('imageCanvas');
798
+ const ctx = canvas.getContext('2d');
799
+ ctx.imageSmoothingEnabled = true;
800
+ ctx.imageSmoothingQuality = 'high';
801
+ }
802
+
803
+ // Handle image upload
804
+ function handleImageUpload(event) {
805
+ const file = event.target.files[0];
806
+ if (!file) return;
807
+
808
+ const reader = new FileReader();
809
+ reader.onload = function(e) {
810
+ const img = new Image();
811
+ img.onload = function() {
812
+ currentImage = img;
813
+ displayImage(img);
814
+ document.getElementById('uploadPrompt').classList.add('hidden');
815
+ document.getElementById('imageCanvas').classList.remove('hidden');
816
+ document.getElementById('applyBtn').disabled = false;
817
+ showToast('Image loaded successfully!', 'success');
818
+ };
819
+ img.src = e.target.result;
820
+ };
821
+ reader.readAsDataURL(file);
822
+ }
823
+
824
+ // Display image on canvas
825
+ function displayImage(img) {
826
+ const canvas = document.getElementById('imageCanvas');
827
+ const container = canvas.parentElement;
828
+ const ctx = canvas.getContext('2d');
829
 
830
+ // Calculate size to fit container
831
+ const maxWidth = container.clientWidth - 40;
832
+ const maxHeight = container.clientHeight - 40;
833
+ let width = img.width;
834
+ let height = img.height;
 
 
 
 
 
 
 
 
 
 
 
835
 
836
+ if (width > maxWidth || height > maxHeight) {
837
+ const ratio = Math.min(maxWidth / width, maxHeight / height);
838
+ width *= ratio;
839
+ height *= ratio;
 
840
  }
841
 
842
+ canvas.width = width;
843
+ canvas.height = height;
844
+ ctx.drawImage(img, 0, 0, width, height);
845
+
846
+ // Store original image data
847
+ originalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
848
  }
849
 
850
+ // Apply text prompt (simulated)
851
+ function applyPrompt() {
852
+ if (!currentImage) {
853
+ showToast('Please upload an image first', 'error');
854
+ return;
855
+ }
856
+
857
+ const prompt = document.getElementById('promptInput').value.trim();
858
+ if (!prompt) {
859
+ showToast('Please enter a prompt', 'error');
860
+ return;
861
+ }
862
 
863
+ showLoading(true);
864
+
865
+ // Simulate AI processing
866
+ setTimeout(() => {
867
+ applyFilter(prompt);
868
+ showLoading(false);
869
+ showToast('Magic applied successfully!', 'success');
870
+ }, 2000);
871
  }
872
 
873
+ // Apply filter based on prompt
874
+ function applyFilter(prompt) {
875
+ const canvas = document.getElementById('imageCanvas');
876
+ const ctx = canvas.getContext('2d');
 
 
877
 
878
+ // Reset to original
879
+ ctx.putImageData(originalImageData, 0, 0);
 
 
880
 
881
+ const lowerPrompt = prompt.toLowerCase();
882
 
883
+ if (lowerPrompt.includes('vintage') || lowerPrompt.includes('old')) {
884
+ applyVintageFilter(ctx, canvas);
885
+ } else if (lowerPrompt.includes('neon') || lowerPrompt.includes('glow')) {
886
+ applyNeonFilter(ctx, canvas);
887
+ } else if (lowerPrompt.includes('cartoon') || lowerPrompt.includes('anime')) {
888
+ applyCartoonFilter(ctx, canvas);
889
+ } else if (lowerPrompt.includes('cyberpunk')) {
890
+ applyCyberpunkFilter(ctx, canvas);
891
+ } else if (lowerPrompt.includes('black and white') || lowerPrompt.includes('bw')) {
892
+ applyBlackWhiteFilter(ctx, canvas);
893
+ } else {
894
+ // Apply random filter
895
+ const filters = [applyVintageFilter, applyNeonFilter, applyCartoonFilter, applyCyberpunkFilter];
896
+ filters[Math.floor(Math.random() * filters.length)](ctx, canvas);
897
+ }
898
  }
899
 
900
+ // Filter implementations
901
+ function applyVintageFilter(ctx, canvas) {
902
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
903
+ const data = imageData.data;
904
 
905
+ for (let i = 0; i < data.length; i += 4) {
906
+ data[i] = Math.min(255, data[i] * 1.2); // Red
907
+ data[i + 1] = Math.min(255, data[i + 1] * 0.8); // Green
908
+ data[i + 2] = Math.min(255, data[i + 2] * 0.5); // Blue
909
  }
910
+
911
+ ctx.putImageData(imageData, 0, 0);
912
+ ctx.globalCompositeOperation = 'overlay';
913
+ ctx.fillStyle = 'rgba(139, 69, 19, 0.1)';
914
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
915
+ ctx.globalCompositeOperation = 'source-over';
916
+ }
917
 
918
+ function applyNeonFilter(ctx, canvas) {
919
+ ctx.filter = 'contrast(2) saturate(2) brightness(1.2)';
920
+ ctx.drawImage(canvas, 0, 0);
921
+ ctx.filter = 'none';
922
 
923
+ // Add glow effect
924
+ ctx.shadowBlur = 20;
925
+ ctx.shadowColor = '#00ffff';
926
+ ctx.globalCompositeOperation = 'screen';
927
+ ctx.drawImage(canvas, 0, 0);
928
+ ctx.globalCompositeOperation = 'source-over';
929
+ ctx.shadowBlur = 0;
930
+ }
931
+
932
+ function applyCartoonFilter(ctx, canvas) {
933
+ ctx.filter = 'contrast(1.5) saturate(1.5)';
934
+ ctx.drawImage(canvas, 0, 0);
935
 
936
+ // Simplify colors
937
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
938
+ const data = imageData.data;
939
 
940
+ for (let i = 0; i < data.length; i += 4) {
941
+ data[i] = Math.round(data[i] / 50) * 50;
942
+ data[i + 1] = Math.round(data[i + 1] / 50) * 50;
943
+ data[i + 2] = Math.round(data[i + 2] / 50) * 50;
944
+ }
945
 
946
+ ctx.putImageData(imageData, 0, 0);
947
+ ctx.filter = 'none';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
948
  }
949
 
950
+ function applyCyberpunkFilter(ctx, canvas) {
951
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
952
+ const data = imageData.data;
953
+
954
+ for (let i = 0; i < data.length; i += 4) {
955
+ data[i] = data[i] * 0.5; // Reduce red
956
+ data[i + 1] = data[i + 1] * 0.3; // Reduce green
957
+ data[i + 2] = data[i + 2] * 1.5; // Enhance blue
958
+ }
959
+
960
+ ctx.putImageData(imageData, 0, 0);
961
+
962
+ // Add scan lines
963
+ ctx.strokeStyle = 'rgba(0, 255, 255, 0.1)';
964
+ ctx.lineWidth = 1;
965
+ for (let y = 0; y < canvas.height; y += 4) {
966
+ ctx.beginPath();
967
+ ctx.moveTo(0, y);
968
+ ctx.lineTo(canvas.width, y);
969
+ ctx.stroke();
970
+ }
971
  }
972
 
973
+ function applyBlackWhiteFilter(ctx, canvas) {
974
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
975
+ const data = imageData.data;
 
976
 
977
+ for (let i = 0; i < data.length; i += 4) {
978
+ const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114;
979
+ data[i] = gray;
980
+ data[i + 1] = gray;
981
+ data[i + 2] = gray;
982
+ }
983
+
984
+ ctx.putImageData(imageData, 0, 0);
985
  }
986
 
987
+ // Adjust image with sliders
988
+ function adjustImage() {
989
+ if (!currentImage) return;
 
 
 
990
 
991
+ const brightness = document.getElementById('brightnessSlider').value;
992
+ const contrast = document.getElementById('contrastSlider').value;
993
+ const saturation = document.getElementById('saturationSlider').value;
994
+ const blur = document.getElementById('blurSlider').value;
 
 
995
 
996
+ document.getElementById('brightnessValue').textContent = brightness + '%';
997
+ document.getElementById('contrastValue').textContent = contrast + '%';
998
+ document.getElementById('saturationValue').textContent = saturation + '%';
999
+ document.getElementById('blurValue').textContent = blur + 'px';
1000
+
1001
+ const canvas = document.getElementById('imageCanvas');
1002
+ const ctx = canvas.getContext('2d');
1003
+
1004
+ // Reset to original
1005
+ ctx.putImageData(originalImageData, 0, 0);
1006
+
1007
+ // Apply filters
1008
+ ctx.filter = `brightness(${brightness}%) contrast(${contrast}%) saturate(${saturation}%) blur(${blur}px)`;
1009
+ ctx.drawImage(canvas, 0, 0);
1010
+ ctx.filter = 'none';
1011
+ }
1012
+
1013
+ // Reset image
1014
+ function resetImage() {
1015
+ if (!currentImage) return;
1016
+
1017
+ const canvas = document.getElementById('imageCanvas');
1018
+ const ctx = canvas.getContext('2d');
1019
+ ctx.putImageData(originalImageData, 0, 0);
1020
+
1021
+ // Reset sliders
1022
+ document.getElementById('brightnessSlider').value = 100;
1023
+ document.getElementById('contrastSlider').value = 100;