protae5544 commited on
Commit
01bd9b2
·
verified ·
1 Parent(s): 53c9b7d

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +1126 -12
index.html CHANGED
@@ -1,13 +1,1127 @@
1
  <!DOCTYPE html>
2
- <html lang="">
3
- <head>
4
- <meta charset="UTF-8">
5
- <link rel="icon" href="/favicon.ico">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Vite App</title>
8
- </head>
9
- <body>
10
- <div id="app"></div>
11
- <script type="module" src="/src/main.ts"></script>
12
- </body>
13
- </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 Chatbot with HuggingFace API - Enhanced</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
8
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <style>
11
+ :root {
12
+ --bg-primary: #0a0a0a;
13
+ --bg-secondary: #1a1a1a;
14
+ --bg-tertiary: #2a2a2a;
15
+ --text-primary: #ffffff;
16
+ --text-secondary: #b0b0b0;
17
+ --accent-primary: #00d4ff;
18
+ --accent-secondary: #ff6b35;
19
+ --accent-tertiary: #7c4dff;
20
+ --error: #ff4757;
21
+ --success: #2ed573;
22
+ --warning: #ffa502;
23
+ --glass-bg: rgba(255, 255, 255, 0.05);
24
+ --glass-border: rgba(255, 255, 255, 0.1);
25
+ --shadow-lg: 0 20px 40px rgba(0, 0, 0, 0.6);
26
+ --shadow-xl: 0 25px 50px rgba(0, 0, 0, 0.8);
27
+ --gradient-primary: linear-gradient(135deg, var(--accent-primary), var(--accent-tertiary));
28
+ --gradient-secondary: linear-gradient(135deg, var(--accent-secondary), var(--accent-primary));
29
+ --gradient-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
30
+ }
31
+
32
+ * {
33
+ box-sizing: border-box;
34
+ }
35
+
36
+ body {
37
+ margin: 0;
38
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Inter', sans-serif;
39
+ background: var(--bg-primary);
40
+ background-image:
41
+ radial-gradient(ellipse at top left, rgba(0, 212, 255, 0.05) 0%, transparent 50%),
42
+ radial-gradient(ellipse at bottom right, rgba(124, 77, 255, 0.05) 0%, transparent 50%);
43
+ color: var(--text-primary);
44
+ display: flex;
45
+ justify-content: center;
46
+ align-items: center;
47
+ min-height: 100vh;
48
+ overflow: hidden;
49
+ -webkit-tap-highlight-color: transparent;
50
+ backdrop-filter: blur(10px);
51
+ }
52
+
53
+ .app-container {
54
+ width: 95%;
55
+ max-width: 1400px;
56
+ background: var(--glass-bg);
57
+ backdrop-filter: blur(20px);
58
+ border: 1px solid var(--glass-border);
59
+ border-radius: 20px;
60
+ box-shadow: var(--shadow-xl);
61
+ display: flex;
62
+ overflow: hidden;
63
+ height: 90vh;
64
+ position: relative;
65
+ animation: slideIn 0.8s cubic-bezier(0.23, 1, 0.32, 1);
66
+ }
67
+
68
+ @keyframes slideIn {
69
+ from {
70
+ opacity: 0;
71
+ transform: translateY(50px) scale(0.95);
72
+ }
73
+ to {
74
+ opacity: 1;
75
+ transform: translateY(0) scale(1);
76
+ }
77
+ }
78
+
79
+ .settings-panel {
80
+ width: 320px;
81
+ padding: 24px;
82
+ background: var(--bg-secondary);
83
+ backdrop-filter: blur(15px);
84
+ border-right: 1px solid var(--glass-border);
85
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
86
+ overflow-y: auto;
87
+ scrollbar-width: thin;
88
+ scrollbar-color: var(--accent-primary) transparent;
89
+ }
90
+
91
+ .settings-panel::-webkit-scrollbar {
92
+ width: 6px;
93
+ }
94
+
95
+ .settings-panel::-webkit-scrollbar-track {
96
+ background: transparent;
97
+ }
98
+
99
+ .settings-panel::-webkit-scrollbar-thumb {
100
+ background: var(--accent-primary);
101
+ border-radius: 3px;
102
+ }
103
+
104
+ .settings-panel.collapsed {
105
+ width: 0;
106
+ padding: 0;
107
+ overflow: hidden;
108
+ }
109
+
110
+ .main-content {
111
+ flex: 1;
112
+ display: flex;
113
+ flex-direction: column;
114
+ position: relative;
115
+ background: var(--bg-primary);
116
+ }
117
+
118
+ .form-field {
119
+ margin-bottom: 20px;
120
+ animation: fadeInUp 0.6s cubic-bezier(0.23, 1, 0.32, 1);
121
+ }
122
+
123
+ .form-field label {
124
+ display: block;
125
+ margin-bottom: 8px;
126
+ font-size: 1rem;
127
+ font-weight: 600;
128
+ color: var(--text-secondary);
129
+ text-transform: uppercase;
130
+ letter-spacing: 0.5px;
131
+ }
132
+
133
+ .form-field select, .form-field textarea {
134
+ width: 100%;
135
+ padding: 12px 16px;
136
+ border: 2px solid transparent;
137
+ border-radius: 12px;
138
+ background: var(--bg-tertiary);
139
+ color: var(--text-primary);
140
+ font-size: 1rem;
141
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
142
+ backdrop-filter: blur(10px);
143
+ }
144
+
145
+ .form-field select:focus, .form-field textarea:focus {
146
+ outline: none;
147
+ border-color: var(--accent-primary);
148
+ box-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
149
+ transform: translateY(-2px);
150
+ }
151
+
152
+ .form-field textarea {
153
+ resize: vertical;
154
+ min-height: 100px;
155
+ }
156
+
157
+ button {
158
+ padding: 12px 24px;
159
+ border: none;
160
+ border-radius: 12px;
161
+ background: var(--gradient-primary);
162
+ color: var(--text-primary);
163
+ cursor: pointer;
164
+ font-size: 1rem;
165
+ font-weight: 600;
166
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
167
+ touch-action: manipulation;
168
+ position: relative;
169
+ overflow: hidden;
170
+ }
171
+
172
+ button::before {
173
+ content: '';
174
+ position: absolute;
175
+ top: 0;
176
+ left: -100%;
177
+ width: 100%;
178
+ height: 100%;
179
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
180
+ transition: left 0.5s;
181
+ }
182
+
183
+ button:hover::before {
184
+ left: 100%;
185
+ }
186
+
187
+ button:hover {
188
+ transform: translateY(-3px);
189
+ box-shadow: 0 10px 25px rgba(0, 212, 255, 0.4);
190
+ }
191
+
192
+ button:active {
193
+ transform: translateY(-1px);
194
+ }
195
+
196
+ .material-icons {
197
+ font-family: 'Material Icons';
198
+ font-size: 28px;
199
+ vertical-align: middle;
200
+ }
201
+
202
+ .chat-container {
203
+ flex: 1;
204
+ padding: 24px;
205
+ overflow-y: auto;
206
+ display: flex;
207
+ flex-direction: column;
208
+ gap: 16px;
209
+ scrollbar-width: thin;
210
+ scrollbar-color: var(--accent-primary) transparent;
211
+ }
212
+
213
+ .chat-container::-webkit-scrollbar {
214
+ width: 8px;
215
+ }
216
+
217
+ .chat-container::-webkit-scrollbar-track {
218
+ background: transparent;
219
+ }
220
+
221
+ .chat-container::-webkit-scrollbar-thumb {
222
+ background: var(--accent-primary);
223
+ border-radius: 4px;
224
+ }
225
+
226
+ .message {
227
+ max-width: 80%;
228
+ padding: 16px 20px;
229
+ border-radius: 20px;
230
+ font-size: 1rem;
231
+ line-height: 1.6;
232
+ position: relative;
233
+ animation: messageSlide 0.5s cubic-bezier(0.23, 1, 0.32, 1);
234
+ backdrop-filter: blur(10px);
235
+ }
236
+
237
+ @keyframes messageSlide {
238
+ from {
239
+ opacity: 0;
240
+ transform: translateY(20px);
241
+ }
242
+ to {
243
+ opacity: 1;
244
+ transform: translateY(0);
245
+ }
246
+ }
247
+
248
+ .message.user {
249
+ background: var(--gradient-primary);
250
+ align-self: flex-end;
251
+ box-shadow: 0 8px 20px rgba(0, 212, 255, 0.3);
252
+ }
253
+
254
+ .message.ai {
255
+ background: var(--glass-bg);
256
+ border: 1px solid var(--glass-border);
257
+ align-self: flex-start;
258
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
259
+ }
260
+
261
+ .input-container {
262
+ display: flex;
263
+ gap: 12px;
264
+ padding: 20px;
265
+ background: var(--glass-bg);
266
+ backdrop-filter: blur(20px);
267
+ border-top: 1px solid var(--glass-border);
268
+ align-items: center;
269
+ }
270
+
271
+ #userInput {
272
+ flex: 1;
273
+ padding: 16px 20px;
274
+ border: 2px solid transparent;
275
+ border-radius: 20px;
276
+ background: var(--bg-secondary);
277
+ color: var(--text-primary);
278
+ resize: none;
279
+ min-height: 60px;
280
+ max-height: 150px;
281
+ font-size: 1rem;
282
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
283
+ backdrop-filter: blur(10px);
284
+ }
285
+
286
+ #userInput:focus {
287
+ outline: none;
288
+ border-color: var(--accent-primary);
289
+ box-shadow: 0 0 25px rgba(0, 212, 255, 0.3);
290
+ transform: translateY(-2px);
291
+ }
292
+
293
+ #sendButton, #attachButton {
294
+ display: flex;
295
+ align-items: center;
296
+ justify-content: center;
297
+ width: 60px;
298
+ height: 60px;
299
+ border-radius: 50%;
300
+ background: var(--gradient-primary);
301
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
302
+ }
303
+
304
+ #sendButton:hover, #attachButton:hover {
305
+ transform: translateY(-3px) scale(1.05);
306
+ box-shadow: 0 12px 30px rgba(0, 212, 255, 0.5);
307
+ }
308
+
309
+ #sendButton:disabled {
310
+ background: var(--bg-tertiary);
311
+ cursor: not-allowed;
312
+ transform: none;
313
+ box-shadow: none;
314
+ }
315
+
316
+ .spinner {
317
+ width: 28px;
318
+ height: 28px;
319
+ border: 3px solid rgba(255, 255, 255, 0.3);
320
+ border-top: 3px solid var(--accent-primary);
321
+ border-radius: 50%;
322
+ animation: spin 1s linear infinite;
323
+ }
324
+
325
+ @keyframes spin {
326
+ to { transform: rotate(360deg); }
327
+ }
328
+
329
+ .notification {
330
+ position: fixed;
331
+ top: 24px;
332
+ right: 24px;
333
+ padding: 16px 24px;
334
+ border-radius: 12px;
335
+ color: #fff;
336
+ font-size: 1rem;
337
+ font-weight: 600;
338
+ z-index: 1000;
339
+ display: none;
340
+ backdrop-filter: blur(15px);
341
+ animation: notificationSlide 0.5s cubic-bezier(0.23, 1, 0.32, 1);
342
+ }
343
+
344
+ @keyframes notificationSlide {
345
+ from {
346
+ opacity: 0;
347
+ transform: translateX(100px);
348
+ }
349
+ to {
350
+ opacity: 1;
351
+ transform: translateX(0);
352
+ }
353
+ }
354
+
355
+ .error-message {
356
+ background: linear-gradient(135deg, var(--error), #ff6b6b);
357
+ box-shadow: 0 10px 25px rgba(255, 71, 87, 0.4);
358
+ }
359
+
360
+ .success-message {
361
+ background: linear-gradient(135deg, var(--success), #5af78e);
362
+ box-shadow: 0 10px 25px rgba(46, 213, 115, 0.4);
363
+ }
364
+
365
+ .carousel-container {
366
+ perspective: 1200px;
367
+ height: 100%;
368
+ display: flex;
369
+ flex-direction: column;
370
+ align-items: center;
371
+ justify-content: center;
372
+ position: relative;
373
+ user-select: none;
374
+ padding: 24px;
375
+ }
376
+
377
+ .carousel {
378
+ position: relative;
379
+ width: 90%;
380
+ max-width: 500px;
381
+ height: 300px;
382
+ transform-style: preserve-3d;
383
+ transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1);
384
+ cursor: grab;
385
+ }
386
+
387
+ .carousel.dragging {
388
+ cursor: grabbing;
389
+ }
390
+
391
+ .carousel-card {
392
+ position: absolute;
393
+ width: 100%;
394
+ height: 100%;
395
+ background: var(--glass-bg);
396
+ backdrop-filter: blur(20px);
397
+ border: 1px solid var(--glass-border);
398
+ border-radius: 16px;
399
+ padding: 24px;
400
+ box-shadow: var(--shadow-lg);
401
+ display: flex;
402
+ flex-direction: column;
403
+ gap: 12px;
404
+ transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
405
+ }
406
+
407
+ .carousel-controls, .carousel-indicator {
408
+ display: flex;
409
+ gap: 16px;
410
+ margin-top: 24px;
411
+ }
412
+
413
+ .carousel-dot {
414
+ width: 14px;
415
+ height: 14px;
416
+ background: var(--bg-tertiary);
417
+ border-radius: 50%;
418
+ cursor: pointer;
419
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
420
+ border: 2px solid transparent;
421
+ }
422
+
423
+ .carousel-dot.active {
424
+ background: var(--accent-primary);
425
+ box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
426
+ transform: scale(1.2);
427
+ }
428
+
429
+ .carousel-dot:hover {
430
+ transform: scale(1.1);
431
+ border-color: var(--accent-primary);
432
+ }
433
+
434
+ .mode-toggle {
435
+ display: flex;
436
+ background: var(--bg-secondary);
437
+ backdrop-filter: blur(15px);
438
+ border-radius: 20px;
439
+ padding: 4px;
440
+ position: relative;
441
+ margin-bottom: 20px;
442
+ border: 1px solid var(--glass-border);
443
+ }
444
+
445
+ .mode-toggle button {
446
+ flex: 1;
447
+ padding: 12px 20px;
448
+ background: none;
449
+ border: none;
450
+ color: var(--text-secondary);
451
+ cursor: pointer;
452
+ z-index: 1;
453
+ font-size: 1rem;
454
+ font-weight: 600;
455
+ border-radius: 16px;
456
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
457
+ }
458
+
459
+ .mode-toggle button.active {
460
+ color: var(--text-primary);
461
+ }
462
+
463
+ .mode-toggle-slider {
464
+ position: absolute;
465
+ top: 4px;
466
+ left: 4px;
467
+ height: calc(100% - 8px);
468
+ background: var(--gradient-primary);
469
+ border-radius: 16px;
470
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
471
+ box-shadow: 0 4px 15px rgba(0, 212, 255, 0.3);
472
+ }
473
+
474
+ .dropzone {
475
+ position: absolute;
476
+ top: 0;
477
+ left: 0;
478
+ right: 0;
479
+ bottom: 0;
480
+ background: rgba(0, 212, 255, 0.1);
481
+ backdrop-filter: blur(20px);
482
+ border: 3px dashed var(--accent-primary);
483
+ display: none;
484
+ align-items: center;
485
+ justify-content: center;
486
+ color: var(--text-primary);
487
+ font-size: 1.4rem;
488
+ font-weight: 600;
489
+ z-index: 10;
490
+ border-radius: 20px;
491
+ }
492
+
493
+ .dropzone.active {
494
+ display: flex;
495
+ animation: pulse 2s infinite;
496
+ }
497
+
498
+ @keyframes pulse {
499
+ 0%, 100% { opacity: 0.7; }
500
+ 50% { opacity: 1; }
501
+ }
502
+
503
+ .file-name {
504
+ font-size: 1rem;
505
+ color: var(--accent-primary);
506
+ margin-left: 12px;
507
+ align-self: center;
508
+ max-width: 200px;
509
+ white-space: nowrap;
510
+ overflow: hidden;
511
+ text-overflow: ellipsis;
512
+ font-weight: 600;
513
+ }
514
+
515
+ .chip-container {
516
+ display: flex;
517
+ gap: 12px;
518
+ margin-bottom: 20px;
519
+ flex-wrap: wrap;
520
+ padding: 0 24px;
521
+ }
522
+
523
+ .chip {
524
+ padding: 10px 18px;
525
+ background: var(--glass-bg);
526
+ backdrop-filter: blur(15px);
527
+ border: 1px solid var(--glass-border);
528
+ border-radius: 20px;
529
+ font-size: 0.9rem;
530
+ font-weight: 600;
531
+ cursor: pointer;
532
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
533
+ color: var(--text-secondary);
534
+ }
535
+
536
+ .chip:hover {
537
+ background: var(--accent-primary);
538
+ color: var(--text-primary);
539
+ transform: translateY(-2px);
540
+ box-shadow: 0 6px 20px rgba(0, 212, 255, 0.4);
541
+ }
542
+
543
+ .floating-buttons {
544
+ position: absolute;
545
+ top: 20px;
546
+ right: 20px;
547
+ display: flex;
548
+ gap: 12px;
549
+ z-index: 100;
550
+ }
551
+
552
+ .floating-btn {
553
+ width: 48px;
554
+ height: 48px;
555
+ border-radius: 50%;
556
+ background: var(--glass-bg);
557
+ backdrop-filter: blur(15px);
558
+ border: 1px solid var(--glass-border);
559
+ display: flex;
560
+ align-items: center;
561
+ justify-content: center;
562
+ transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
563
+ padding: 0;
564
+ }
565
+
566
+ .floating-btn:hover {
567
+ background: var(--accent-primary);
568
+ transform: translateY(-3px) scale(1.05);
569
+ box-shadow: 0 8px 25px rgba(0, 212, 255, 0.4);
570
+ }
571
+
572
+ .code-tools {
573
+ position: absolute;
574
+ top: 12px;
575
+ right: 12px;
576
+ display: flex;
577
+ gap: 8px;
578
+ }
579
+
580
+ .code-tools button {
581
+ padding: 6px 12px;
582
+ font-size: 0.85rem;
583
+ background: var(--glass-bg);
584
+ backdrop-filter: blur(10px);
585
+ border: 1px solid var(--glass-border);
586
+ }
587
+
588
+ pre {
589
+ position: relative;
590
+ background: var(--bg-secondary);
591
+ border: 1px solid var(--glass-border);
592
+ padding: 20px;
593
+ border-radius: 12px;
594
+ overflow-x: auto;
595
+ backdrop-filter: blur(10px);
596
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
597
+ }
598
+
599
+ code {
600
+ font-family: 'Fira Code', 'Consolas', monospace;
601
+ font-size: 0.9rem;
602
+ }
603
+
604
+ .image-preview {
605
+ max-width: 100%;
606
+ max-height: 300px;
607
+ border-radius: 12px;
608
+ margin-top: 12px;
609
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
610
+ }
611
+
612
+ @keyframes fadeInUp {
613
+ from {
614
+ opacity: 0;
615
+ transform: translateY(30px);
616
+ }
617
+ to {
618
+ opacity: 1;
619
+ transform: translateY(0);
620
+ }
621
+ }
622
+
623
+ @media (max-width: 768px) {
624
+ .app-container {
625
+ flex-direction: column;
626
+ height: auto;
627
+ min-height: 100vh;
628
+ border-radius: 0;
629
+ width: 100%;
630
+ }
631
+
632
+ .settings-panel {
633
+ width: 100%;
634
+ max-height: 40vh;
635
+ border-right: none;
636
+ border-bottom: 1px solid var(--glass-border);
637
+ }
638
+
639
+ .settings-panel.collapsed {
640
+ max-height: 0;
641
+ }
642
+
643
+ .chat-container {
644
+ max-height: 50vh;
645
+ padding: 16px;
646
+ }
647
+
648
+ .input-container {
649
+ flex-wrap: wrap;
650
+ gap: 12px;
651
+ padding: 16px;
652
+ }
653
+
654
+ #userInput {
655
+ width: 100%;
656
+ margin-bottom: 12px;
657
+ min-height: 50px;
658
+ }
659
+
660
+ #sendButton, #attachButton {
661
+ width: 56px;
662
+ height: 56px;
663
+ }
664
+
665
+ .carousel {
666
+ width: 95%;
667
+ height: 250px;
668
+ }
669
+
670
+ .floating-buttons {
671
+ top: 12px;
672
+ right: 12px;
673
+ }
674
+
675
+ .floating-btn {
676
+ width: 44px;
677
+ height: 44px;
678
+ }
679
+
680
+ .material-icons {
681
+ font-size: 24px;
682
+ }
683
+ }
684
+
685
+ @media (max-width: 480px) {
686
+ .chip-container {
687
+ padding: 0 16px;
688
+ }
689
+
690
+ .chip {
691
+ font-size: 0.8rem;
692
+ padding: 8px 14px;
693
+ }
694
+
695
+ .form-field select, .form-field textarea, #userInput {
696
+ font-size: 16px;
697
+ }
698
+ }
699
+ </style>
700
+ </head>
701
+ <body>
702
+ <div class="app-container" id="appContainer">
703
+ <div class="settings-panel" id="settingsPanel">
704
+ <h2 style="font-size: 1.4rem; margin-bottom: 24px; background: var(--gradient-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">⚙️ Settings</h2>
705
+ <div class="form-field">
706
+ <label>🤖 Main Model:</label>
707
+ <select id="modelSelect">
708
+ <option value="mistralai/Mistral-7B-Instruct-v0.1">Mistral-7B-Instruct (Text)</option>
709
+ <option value="meta-llama/Llama-2-7b-chat-hf">Llama-2-7b-chat (Text)</option>
710
+ <option value="google/gemma-7b-it">Gemma-7b-it (Text)</option>
711
+ <option value="HuggingFaceH4/zephyr-7b-beta">Zephyr-7b-beta (Text)</option>
712
+ <option value="microsoft/phi-2">Phi-2 (Text)</option>
713
+ </select>
714
+ <p style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 8px;">
715
+ 💡 Choose a model. Smaller models (7B) are faster but less capable.
716
+ </p>
717
+ </div>
718
+ <div class="form-field">
719
+ <label>🔑 API Key:</label>
720
+ <input type="password" id="apiKeyInput" class="w-full p-3 rounded-lg bg-gray-800 text-white border border-gray-700 focus:border-blue-500 focus:ring-2 focus:ring-blue-500" placeholder="Enter your HuggingFace API key">
721
+ <p style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 8px;">
722
+ 🔒 Your API key is stored locally only
723
+ </p>
724
+ </div>
725
+ <div class="form-field">
726
+ <label>⚡ Max Tokens:</label>
727
+ <input type="number" id="maxTokensInput" class="w-full p-3 rounded-lg bg-gray-800 text-white border border-gray-700 focus:border-blue-500 focus:ring-2 focus:ring-blue-500" value="512" min="100" max="2048">
728
+ </div>
729
+ <button id="saveSettingsBtn">💾 Save Settings</button>
730
+ </div>
731
+ <div class="main-content">
732
+ <div class="floating-buttons">
733
+ <button id="settingsToggle" class="floating-btn">
734
+ <span class="material-icons">settings</span>
735
+ </button>
736
+ <button id="fullscreenToggle" class="floating-btn">
737
+ <span class="material-icons">fullscreen</span>
738
+ </button>
739
+ <button id="refreshBtn" class="floating-btn">
740
+ <span class="material-icons">refresh</span>
741
+ </button>
742
+ </div>
743
+
744
+ <div class="mode-toggle">
745
+ <button id="carouselModeBtn" class="active">🎛️ Prompt Editor</button>
746
+ <button id="chatModeBtn">💬 Chat</button>
747
+ <div class="mode-toggle-slider" id="modeToggleSlider"></div>
748
+ </div>
749
+
750
+ <div id="carouselMode">
751
+ <div class="carousel-container">
752
+ <div class="carousel" id="promptCarousel">
753
+ <div class="carousel-card" style="transform: rotateY(0deg) translateZ(500px);">
754
+ <label>🎯 Primary System Prompt:</label>
755
+ <textarea id="primarySystemPrompt" placeholder="Enter primary system prompt for the AI assistant...">You are a helpful AI assistant that provides clear, accurate, and helpful responses. Focus on practical solutions and detailed explanations.</textarea>
756
+ </div>
757
+ <div class="carousel-card" style="transform: rotateY(60deg) translateZ(500px); opacity: 0.8;">
758
+ <label>💻 Code Template:</label>
759
+ <textarea id="codeTemplate" placeholder="Enter code formatting template...">```javascript
760
+ // Code implementation
761
+ function solution() {
762
+ // Your code here
763
+ return result;
764
+ }
765
+ ```</textarea>
766
+ </div>
767
+ <div class="carousel-card" style="transform: rotateY(120deg) translateZ(500px); opacity: 0.8;">
768
+ <label>📋 Additional Instructions:</label>
769
+ <textarea id="additionalInstructions" placeholder="Enter additional instructions for the AI...">Provide working code examples when possible. Explain complex concepts step by step. Use modern best practices.</textarea>
770
+ </div>
771
+ </div>
772
+ <div class="carousel-controls">
773
+ <button id="prevCard"><span class="material-icons">chevron_left</span></button>
774
+ <button id="nextCard"><span class="material-icons">chevron_right</span></button>
775
+ </div>
776
+ <div class="carousel-indicator" id="carouselIndicator">
777
+ <div class="carousel-dot active" data-index="0"></div>
778
+ <div class="carousel-dot" data-index="1"></div>
779
+ <div class="carousel-dot" data-index="2"></div>
780
+ </div>
781
+ <button id="applyPromptBtn" style="margin-top: 24px;">✅ Apply Prompts & Switch to Chat</button>
782
+ </div>
783
+ </div>
784
+
785
+ <div id="chatMode" style="display: none;">
786
+ <div class="chip-container" id="quickPrompts">
787
+ <span class="chip" data-prompt="Explain this code in detail">🔍 Explain Code</span>
788
+ <span class="chip" data-prompt="Generate a complete function">⚡ Generate Function</span>
789
+ <span class="chip" data-prompt="Debug and fix this issue">🐛 Debug Code</span>
790
+ <span class="chip" data-prompt="Optimize this for performance">🚀 Optimize</span>
791
+ </div>
792
+ <div class="chat-container" id="chatContainer"></div>
793
+ <div class="input-container">
794
+ <textarea id="userInput" placeholder="Type your message here... (Shift+Enter for new line)"></textarea>
795
+ <button id="sendButton"><span class="material-icons">send</span></button>
796
+ </div>
797
+ </div>
798
+
799
+ <div class="notification error-message" id="errorMessage">
800
+ <span id="errorText"></span>
801
+ </div>
802
+ <div class="notification success-message" id="successMessage">
803
+ <span id="successText"></span>
804
+ </div>
805
+ </div>
806
+ </div>
807
+
808
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
809
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
810
+ <script>
811
+ // Global variables
812
+ let isLoading = false;
813
+ let currentCarouselIndex = 0;
814
+
815
+ // Initialize the application
816
+ document.addEventListener('DOMContentLoaded', function() {
817
+ loadSettings();
818
+ setupEventListeners();
819
+ setupCarousel();
820
+ hljs.highlightAll();
821
+ });
822
+
823
+ // Settings management
824
+ function loadSettings() {
825
+ const settings = {
826
+ model: localStorage.getItem('selectedModel') || 'mistralai/Mistral-7B-Instruct-v0.1',
827
+ apiKey: localStorage.getItem('apiKey') || '',
828
+ maxTokens: localStorage.getItem('maxTokens') || '512',
829
+ primarySystemPrompt: localStorage.getItem('primarySystemPrompt') || 'You are a helpful AI assistant that provides clear, accurate, and helpful responses. Focus on practical solutions and detailed explanations.',
830
+ codeTemplate: localStorage.getItem('codeTemplate') || '```javascript\n// Code implementation\nfunction solution() {\n // Your code here\n return result;\n}\n```',
831
+ additionalInstructions: localStorage.getItem('additionalInstructions') || 'Provide working code examples when possible. Explain complex concepts step by step. Use modern best practices.'
832
+ };
833
+
834
+ document.getElementById('modelSelect').value = settings.model;
835
+ document.getElementById('apiKeyInput').value = settings.apiKey;
836
+ document.getElementById('maxTokensInput').value = settings.maxTokens;
837
+ document.getElementById('primarySystemPrompt').value = settings.primarySystemPrompt;
838
+ document.getElementById('codeTemplate').value = settings.codeTemplate;
839
+ document.getElementById('additionalInstructions').value = settings.additionalInstructions;
840
+ }
841
+
842
+ function saveSettings() {
843
+ localStorage.setItem('selectedModel', document.getElementById('modelSelect').value);
844
+ localStorage.setItem('apiKey', document.getElementById('apiKeyInput').value);
845
+ localStorage.setItem('maxTokens', document.getElementById('maxTokensInput').value);
846
+ localStorage.setItem('primarySystemPrompt', document.getElementById('primarySystemPrompt').value);
847
+ localStorage.setItem('codeTemplate', document.getElementById('codeTemplate').value);
848
+ localStorage.setItem('additionalInstructions', document.getElementById('additionalInstructions').value);
849
+ showNotification('Settings saved successfully!', 'success');
850
+ }
851
+
852
+ // Event listeners setup
853
+ function setupEventListeners() {
854
+ // Mode toggle
855
+ document.getElementById('carouselModeBtn').addEventListener('click', () => switchMode('carousel'));
856
+ document.getElementById('chatModeBtn').addEventListener('click', () => switchMode('chat'));
857
+
858
+ // Settings
859
+ document.getElementById('saveSettingsBtn').addEventListener('click', saveSettings);
860
+ document.getElementById('settingsToggle').addEventListener('click', toggleSettings);
861
+
862
+ // Carousel controls
863
+ document.getElementById('prevCard').addEventListener('click', () => rotateCarousel(-1));
864
+ document.getElementById('nextCard').addEventListener('click', () => rotateCarousel(1));
865
+ document.getElementById('applyPromptBtn').addEventListener('click', applyPromptsAndSwitchToChat);
866
+
867
+ // Chat controls
868
+ document.getElementById('sendButton').addEventListener('click', sendMessage);
869
+ document.getElementById('userInput').addEventListener('keydown', handleKeyDown);
870
+
871
+ // Other controls
872
+ document.getElementById('fullscreenToggle').addEventListener('click', toggleFullscreen);
873
+ document.getElementById('refreshBtn').addEventListener('click', refreshApp);
874
+
875
+ // Quick prompts
876
+ document.querySelectorAll('.chip').forEach(chip => {
877
+ chip.addEventListener('click', (e) => {
878
+ const prompt = e.target.getAttribute('data-prompt');
879
+ document.getElementById('userInput').value = prompt;
880
+ document.getElementById('userInput').focus();
881
+ });
882
+ });
883
+
884
+ // Carousel dots
885
+ document.querySelectorAll('.carousel-dot').forEach(dot => {
886
+ dot.addEventListener('click', (e) => {
887
+ const index = parseInt(e.target.getAttribute('data-index'));
888
+ goToCarouselIndex(index);
889
+ });
890
+ });
891
+ }
892
+
893
+ // Mode switching
894
+ function switchMode(mode) {
895
+ const carouselMode = document.getElementById('carouselMode');
896
+ const chatMode = document.getElementById('chatMode');
897
+ const carouselBtn = document.getElementById('carouselModeBtn');
898
+ const chatBtn = document.getElementById('chatModeBtn');
899
+ const slider = document.getElementById('modeToggleSlider');
900
+
901
+ if (mode === 'carousel') {
902
+ carouselMode.style.display = 'block';
903
+ chatMode.style.display = 'none';
904
+ carouselBtn.classList.add('active');
905
+ chatBtn.classList.remove('active');
906
+ slider.style.width = '50%';
907
+ slider.style.left = '4px';
908
+ } else {
909
+ carouselMode.style.display = 'none';
910
+ chatMode.style.display = 'block';
911
+ carouselBtn.classList.remove('active');
912
+ chatBtn.classList.add('active');
913
+ slider.style.width = '50%';
914
+ slider.style.left = '50%';
915
+ }
916
+ }
917
+
918
+ // Carousel functionality
919
+ function setupCarousel() {
920
+ updateCarouselPosition();
921
+ }
922
+
923
+ function rotateCarousel(direction) {
924
+ const totalCards = 3;
925
+ currentCarouselIndex = (currentCarouselIndex + direction + totalCards) % totalCards;
926
+ updateCarouselPosition();
927
+ }
928
+
929
+ function goToCarouselIndex(index) {
930
+ currentCarouselIndex = index;
931
+ updateCarouselPosition();
932
+ }
933
+
934
+ function updateCarouselPosition() {
935
+ const carousel = document.getElementById('promptCarousel');
936
+ const cards = carousel.querySelectorAll('.carousel-card');
937
+ const dots = document.querySelectorAll('.carousel-dot');
938
+
939
+ cards.forEach((card, index) => {
940
+ const angle = (index - currentCarouselIndex) * 60;
941
+ const isActive = index === currentCarouselIndex;
942
+
943
+ card.style.transform = `rotateY(${angle}deg) translateZ(500px)`;
944
+ card.style.opacity = isActive ? '1' : '0.6';
945
+ card.style.zIndex = isActive ? '10' : '1';
946
+ });
947
+
948
+ dots.forEach((dot, index) => {
949
+ dot.classList.toggle('active', index === currentCarouselIndex);
950
+ });
951
+ }
952
+
953
+ function applyPromptsAndSwitchToChat() {
954
+ saveSettings();
955
+ switchMode('chat');
956
+ showNotification('Prompts applied successfully!', 'success');
957
+ }
958
+
959
+ // Chat functionality
960
+ function handleKeyDown(e) {
961
+ if (e.key === 'Enter' && !e.shiftKey) {
962
+ e.preventDefault();
963
+ sendMessage();
964
+ }
965
+ }
966
+
967
+ async function sendMessage() {
968
+ const userInput = document.getElementById('userInput');
969
+ const message = userInput.value.trim();
970
+
971
+ if (!message) return;
972
+ if (isLoading) return;
973
+
974
+ const chatContainer = document.getElementById('chatContainer');
975
+
976
+ // Add user message
977
+ addMessage(message, 'user');
978
+
979
+ userInput.value = '';
980
+ setLoading(true);
981
+
982
+ try {
983
+ const response = await callHuggingFaceAPI(message);
984
+ addMessage(response, 'ai');
985
+ } catch (error) {
986
+ console.error('Error:', error);
987
+ addMessage('Sorry, there was an error processing your request. Please try again.', 'ai');
988
+ showNotification('Error: ' + error.message, 'error');
989
+ } finally {
990
+ setLoading(false);
991
+ }
992
+
993
+ chatContainer.scrollTop = chatContainer.scrollHeight;
994
+ }
995
+
996
+ async function callHuggingFaceAPI(message) {
997
+ const model = document.getElementById('modelSelect').value;
998
+ const apiKey = document.getElementById('apiKeyInput').value;
999
+ const maxTokens = parseInt(document.getElementById('maxTokensInput').value);
1000
+ const primaryPrompt = document.getElementById('primarySystemPrompt').value;
1001
+
1002
+ if (!apiKey) {
1003
+ throw new Error('Please enter your HuggingFace API key in settings');
1004
+ }
1005
+
1006
+ const fullPrompt = `${primaryPrompt}\n\nUser: ${message}\n\nAssistant:`;
1007
+
1008
+ const response = await fetch(`https://api-inference.huggingface.co/models/${model}`, {
1009
+ method: 'POST',
1010
+ headers: {
1011
+ 'Authorization': `Bearer ${apiKey}`,
1012
+ 'Content-Type': 'application/json',
1013
+ },
1014
+ body: JSON.stringify({
1015
+ inputs: fullPrompt,
1016
+ parameters: {
1017
+ max_new_tokens: maxTokens,
1018
+ temperature: 0.7,
1019
+ top_p: 0.9,
1020
+ do_sample: true,
1021
+ return_full_text: false
1022
+ }
1023
+ })
1024
+ });
1025
+
1026
+ if (!response.ok) {
1027
+ const errorData = await response.json();
1028
+ throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
1029
+ }
1030
+
1031
+ const data = await response.json();
1032
+
1033
+ if (data.error) {
1034
+ throw new Error(data.error);
1035
+ }
1036
+
1037
+ return data[0]?.generated_text || 'No response generated';
1038
+ }
1039
+
1040
+ function addMessage(content, sender) {
1041
+ const chatContainer = document.getElementById('chatContainer');
1042
+ const messageDiv = document.createElement('div');
1043
+ messageDiv.className = `message ${sender}`;
1044
+
1045
+ if (sender === 'ai') {
1046
+ messageDiv.innerHTML = marked.parse(content);
1047
+ // Re-highlight code blocks
1048
+ messageDiv.querySelectorAll('pre code').forEach(block => {
1049
+ hljs.highlightElement(block);
1050
+ addCodeTools(block.parentElement);
1051
+ });
1052
+ } else {
1053
+ messageDiv.textContent = content;
1054
+ }
1055
+
1056
+ chatContainer.appendChild(messageDiv);
1057
+ chatContainer.scrollTop = chatContainer.scrollHeight;
1058
+ }
1059
+
1060
+ function addCodeTools(preElement) {
1061
+ const toolsDiv = document.createElement('div');
1062
+ toolsDiv.className = 'code-tools';
1063
+
1064
+ const copyBtn = document.createElement('button');
1065
+ copyBtn.textContent = 'Copy';
1066
+ copyBtn.onclick = () => {
1067
+ navigator.clipboard.writeText(preElement.textContent);
1068
+ showNotification('Code copied to clipboard!', 'success');
1069
+ };
1070
+
1071
+ toolsDiv.appendChild(copyBtn);
1072
+ preElement.style.position = 'relative';
1073
+ preElement.appendChild(toolsDiv);
1074
+ }
1075
+
1076
+ function setLoading(loading) {
1077
+ isLoading = loading;
1078
+ const sendButton = document.getElementById('sendButton');
1079
+ const spinner = sendButton.querySelector('.spinner');
1080
+ const icon = sendButton.querySelector('.material-icons');
1081
+
1082
+ if (loading) {
1083
+ if (!spinner) {
1084
+ const spinnerDiv = document.createElement('div');
1085
+ spinnerDiv.className = 'spinner';
1086
+ sendButton.innerHTML = '';
1087
+ sendButton.appendChild(spinnerDiv);
1088
+ }
1089
+ sendButton.disabled = true;
1090
+ } else {
1091
+ sendButton.innerHTML = '<span class="material-icons">send</span>';
1092
+ sendButton.disabled = false;
1093
+ }
1094
+ }
1095
+
1096
+ // Utility functions
1097
+ function toggleSettings() {
1098
+ const settingsPanel = document.getElementById('settingsPanel');
1099
+ settingsPanel.classList.toggle('collapsed');
1100
+ }
1101
+
1102
+ function toggleFullscreen() {
1103
+ if (!document.fullscreenElement) {
1104
+ document.documentElement.requestFullscreen();
1105
+ } else {
1106
+ document.exitFullscreen();
1107
+ }
1108
+ }
1109
+
1110
+ function refreshApp() {
1111
+ location.reload();
1112
+ }
1113
+
1114
+ function showNotification(message, type) {
1115
+ const notification = document.getElementById(type === 'error' ? 'errorMessage' : 'successMessage');
1116
+ const textElement = document.getElementById(type === 'error' ? 'errorText' : 'successText');
1117
+
1118
+ textElement.textContent = message;
1119
+ notification.style.display = 'block';
1120
+
1121
+ setTimeout(() => {
1122
+ notification.style.display = 'none';
1123
+ }, 3000);
1124
+ }
1125
+ </script>
1126
+ </body>
1127
+ </html>