samirerty commited on
Commit
c5d8270
·
verified ·
1 Parent(s): c018f7f

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +470 -321
index.html CHANGED
@@ -3,231 +3,288 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Minimal Glassmorphism Chat</title>
7
- <!-- Importing Inter font for clean typography -->
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&display=swap" rel="stylesheet">
11
- <!-- Importing Phosphor Icons for minimal iconography -->
12
- <script src="https://unpkg.com/@phosphor-icons/web"></script>
13
 
14
  <style>
15
  :root {
16
- /* Color Palette - Soft, Neutral, Calm */
17
  --bg-gradient-start: #fdfbfb;
18
  --bg-gradient-end: #ebedee;
19
- --glass-bg: rgba(255, 255, 255, 0.65);
20
- --glass-border: rgba(255, 255, 255, 0.5);
21
- --glass-blur: 16px;
22
 
23
- --text-primary: #334155;
24
- --text-secondary: #64748b;
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- --bubble-sent: #3b82f6; /* Soft blue */
27
- --bubble-sent-text: #ffffff;
28
- --bubble-received: #ffffff;
29
- --bubble-received-text: #334155;
30
-
31
- --input-bg: rgba(255, 255, 255, 0.8);
32
- --input-focus-border: #94a3b8;
33
-
34
- --shadow-soft: 0 4px 20px -2px rgba(0, 0, 0, 0.05);
35
-
36
- --spacing-unit: 1rem;
37
- --radius-bubble: 18px;
38
- --radius-container: 0px; /* Full screen on mobile */
39
  }
40
 
41
  * {
42
- box-sizing: border-box;
43
  margin: 0;
44
  padding: 0;
45
- -webkit-tap-highlight-color: transparent;
46
  }
47
 
48
  body {
49
- font-family: 'Inter', sans-serif;
50
- background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
51
  height: 100vh;
52
- display: flex;
53
- justify-content: center;
54
  color: var(--text-primary);
55
- overflow: hidden; /* Prevent body scroll, handle inside app */
56
  }
57
 
58
- /* App Container - Mobile First, Centered on Desktop */
59
- .app-container {
 
 
 
 
 
 
60
  width: 100%;
61
  height: 100%;
62
- display: flex;
63
- flex-direction: column;
64
- position: relative;
65
- background: transparent;
66
- }
67
-
68
- @media (min-width: 768px) {
69
- .app-container {
70
- max-width: 600px;
71
- height: 90vh;
72
- margin-top: 5vh;
73
- border-radius: 24px;
74
- background: rgba(255, 255, 255, 0.4);
75
- box-shadow: var(--shadow-soft);
76
- border: 1px solid var(--glass-border);
77
- overflow: hidden;
78
- backdrop-filter: blur(var(--glass-blur));
79
- }
80
  }
81
 
82
- /* --- Header --- */
83
- header {
84
- flex-shrink: 0;
85
- height: 60px;
86
  display: flex;
87
- align-items: center;
88
- justify-content: space-between;
89
- padding: 0 20px;
 
90
  background: var(--glass-bg);
91
- backdrop-filter: blur(var(--glass-blur));
92
- -webkit-backdrop-filter: blur(var(--glass-blur));
93
- border-bottom: 1px solid rgba(0, 0, 0, 0.03);
94
- z-index: 10;
 
 
 
95
  }
96
 
97
- .chat-title {
98
- font-size: 1.1rem;
99
- font-weight: 500;
100
- letter-spacing: -0.01em;
101
- color: var(--text-primary);
102
  display: flex;
103
- align-items: center;
104
- gap: 10px;
 
 
105
  }
106
 
107
- .status-dot {
108
- width: 8px;
109
- height: 8px;
110
- background-color: #10b981;
111
- border-radius: 50%;
 
 
112
  }
113
 
114
- .header-actions {
 
 
 
 
 
 
 
 
 
115
  display: flex;
116
  align-items: center;
 
 
 
 
 
 
117
  }
118
 
119
- /* Mandatory Link Styling */
120
- .built-with-link {
121
- font-size: 0.75rem;
122
- color: var(--text-secondary);
123
- text-decoration: none;
124
- font-weight: 400;
125
- transition: color 0.2s ease;
126
- opacity: 0.8;
127
  }
128
 
129
- .built-with-link:hover {
130
- color: var(--bubble-sent);
131
- opacity: 1;
132
  }
133
 
134
- /* --- Chat Body --- */
135
- #chat-body {
136
- flex-grow: 1;
137
- overflow-y: auto;
138
- padding: 20px;
 
 
 
 
 
 
139
  display: flex;
140
  flex-direction: column;
141
- gap: 16px;
142
- scroll-behavior: smooth;
143
  }
144
 
145
- /* Scrollbar Styling */
146
- #chat-body::-webkit-scrollbar {
147
- width: 6px;
 
148
  }
149
- #chat-body::-webkit-scrollbar-track {
150
- background: transparent;
 
 
 
 
 
 
151
  }
152
- #chat-body::-webkit-scrollbar-thumb {
153
- background-color: rgba(0, 0, 0, 0.1);
154
- border-radius: 10px;
 
 
 
 
155
  }
156
 
157
- /* Message Bubbles */
158
- .message-row {
 
 
159
  display: flex;
160
- width: 100%;
161
- opacity: 0;
162
- animation: fadeIn 0.4s ease forwards;
 
 
163
  }
164
 
165
- @keyframes fadeIn {
166
- to { opacity: 1; transform: translateY(0); }
167
- from { opacity: 0; transform: translateY(10px); }
 
168
  }
169
 
170
- .message-row.sent {
171
- justify-content: flex-end;
 
 
 
172
  }
173
 
174
- .message-row.received {
175
- justify-content: flex-start;
 
 
 
 
 
 
 
 
 
 
176
  }
177
 
178
- .message-bubble {
179
- max-width: 75%;
180
- padding: 12px 18px;
181
- font-size: 0.95rem;
 
 
 
 
 
 
 
 
 
 
182
  line-height: 1.5;
183
  position: relative;
184
- word-wrap: break-word;
 
 
185
  }
186
 
187
- .received .message-bubble {
188
- background-color: var(--bubble-received);
189
- color: var(--bubble-received-text);
190
- border-radius: var(--radius-bubble);
191
- border-top-left-radius: 4px;
192
- box-shadow: 0 2px 5px rgba(0,0,0,0.02);
 
 
 
 
 
 
 
193
  }
194
 
195
- .sent .message-bubble {
196
- background-color: var(--bubble-sent);
197
- color: var(--bubble-sent-text);
198
- border-radius: var(--radius-bubble);
199
- border-bottom-right-radius: 4px;
200
- box-shadow: 0 2px 8px rgba(59, 130, 246, 0.2);
201
  }
202
 
203
- .message-meta {
204
  display: block;
205
- font-size: 0.7rem;
206
  margin-top: 4px;
207
- opacity: 0.7;
208
  text-align: right;
209
- }
210
-
211
- .received .message-meta {
212
- color: var(--text-secondary);
213
- text-align: left;
214
  }
215
 
216
  /* --- Input Area --- */
217
  .input-area {
218
- flex-shrink: 0;
219
- padding: 16px 20px;
220
- background: var(--glass-bg);
221
- backdrop-filter: blur(var(--glass-blur));
222
- -webkit-backdrop-filter: blur(var(--glass-blur));
223
- border-top: 1px solid rgba(0, 0, 0, 0.03);
224
  display: flex;
225
  align-items: center;
226
  gap: 12px;
227
  }
228
 
229
  .input-wrapper {
230
- flex-grow: 1;
231
  position: relative;
232
  }
233
 
@@ -235,242 +292,334 @@
235
  width: 100%;
236
  padding: 14px 20px;
237
  border-radius: 30px;
238
- border: 1px solid transparent;
239
- background: var(--input-bg);
240
- color: var(--text-primary);
241
- font-family: inherit;
242
  font-size: 0.95rem;
 
243
  outline: none;
244
  transition: all 0.2s ease;
245
- box-shadow: inset 0 1px 3px rgba(0,0,0,0.02);
246
  }
247
 
248
- input[type="text"]::placeholder {
249
- color: #94a3b8;
 
 
250
  }
251
 
252
- input[type="text"]:focus {
253
- background: #ffffff;
254
- border-color: var(--input-focus-border);
255
- box-shadow: 0 4px 12px rgba(0,0,0,0.03);
256
  }
257
 
258
  .send-btn {
259
- background-color: var(--bubble-sent);
260
- color: white;
261
- border: none;
262
  width: 46px;
263
  height: 46px;
264
  border-radius: 50%;
 
 
 
265
  display: flex;
266
  align-items: center;
267
  justify-content: center;
268
  cursor: pointer;
269
- transition: transform 0.1s ease, background-color 0.2s ease;
270
- flex-shrink: 0;
271
  }
272
 
273
  .send-btn:hover {
274
- background-color: #2563eb;
 
275
  }
276
 
277
  .send-btn:active {
278
  transform: scale(0.95);
279
  }
280
 
281
- .send-btn i {
282
- font-size: 1.2rem;
283
- margin-left: 2px; /* Visual centering adjustment */
284
- }
285
-
286
- /* Typing Indicator */
287
- .typing-indicator {
288
- display: none; /* Hidden by default */
289
- padding: 12px 16px;
290
- background: var(--bubble-received);
291
- border-radius: var(--radius-bubble);
292
- border-top-left-radius: 4px;
293
- width: fit-content;
294
- margin-bottom: 16px;
295
- box-shadow: 0 2px 5px rgba(0,0,0,0.02);
296
- }
297
 
298
- .typing-dots {
299
- display: flex;
300
- gap: 4px;
301
- }
 
 
 
 
 
 
302
 
303
- .typing-dot {
304
- width: 6px;
305
- height: 6px;
306
- background-color: #cbd5e1;
307
- border-radius: 50%;
308
- animation: bounce 1.4s infinite ease-in-out both;
309
- }
310
 
311
- .typing-dot:nth-child(1) { animation-delay: -0.32s; }
312
- .typing-dot:nth-child(2) { animation-delay: -0.16s; }
 
313
 
314
- @keyframes bounce {
315
- 0%, 80%, 100% { transform: scale(0); }
316
- 40% { transform: scale(1); }
 
 
 
 
 
 
 
 
 
 
317
  }
318
-
319
  </style>
320
  </head>
321
  <body>
322
 
 
 
323
  <div class="app-container">
324
- <!-- Header -->
325
- <header>
326
- <div class="chat-title">
327
- <span class="status-dot"></span>
328
- Sarah Design
329
- </div>
330
- <div class="header-actions">
331
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with-link">
332
- Built with anycoder
333
- </a>
334
- </div>
335
- </header>
336
-
337
- <!-- Chat Body -->
338
- <main id="chat-body">
339
- <!-- Initial Messages -->
340
- <div class="message-row received">
341
- <div class="message-bubble">
342
- Hey! Did you get a chance to review the new glassmorphism concepts?
343
- <span class="message-meta">10:23 AM</span>
344
  </div>
345
- </div>
346
-
347
- <div class="message-row sent">
348
- <div class="message-bubble">
349
- Yes, I just looked them over. I really like the minimal approach. It feels much cleaner now.
350
- <span class="message-meta">10:25 AM</span>
351
  </div>
352
- </div>
353
 
354
- <div class="message-row received">
355
- <div class="message-bubble">
356
- Great! I'll refine the blur effects a bit more and send the final files by tonight.
357
- <span class="message-meta">10:26 AM</span>
 
358
  </div>
359
  </div>
360
-
361
- <!-- Typing Indicator (Hidden by default) -->
362
- <div class="typing-indicator" id="typing-indicator">
363
- <div class="typing-dots">
364
- <div class="typing-dot"></div>
365
- <div class="typing-dot"></div>
366
- <div class="typing-dot"></div>
367
  </div>
 
 
 
368
  </div>
369
  </main>
370
-
371
- <!-- Input Area -->
372
- <footer class="input-area">
373
- <div class="input-wrapper">
374
- <form id="chat-form">
375
- <input type="text" id="message-input" placeholder="Type a message..." autocomplete="off">
376
- </form>
377
- </div>
378
- <button type="button" id="send-btn" class="send-btn" aria-label="Send Message">
379
- <i class="ph ph-paper-plane-right"></i>
380
- </button>
381
- </footer>
382
  </div>
383
 
384
  <script>
385
- document.addEventListener('DOMContentLoaded', () => {
386
- const chatBody = document.getElementById('chat-body');
387
- const messageInput = document.getElementById('message-input');
388
- const sendBtn = document.getElementById('send-btn');
389
- const chatForm = document.getElementById('chat-form');
390
- const typingIndicator = document.getElementById('typing-indicator');
391
-
392
- // Helper to get current time
393
- function getCurrentTime() {
394
- const now = new Date();
395
- return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
396
- }
397
-
398
- // Helper to scroll to bottom
399
- function scrollToBottom() {
400
- chatBody.scrollTop = chatBody.scrollHeight;
401
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
 
403
- // Add message to DOM
404
- function addMessage(text, type) {
405
- const rowDiv = document.createElement('div');
406
- rowDiv.classList.add('message-row', type);
 
 
 
 
 
407
 
408
- const bubbleDiv = document.createElement('div');
409
- bubbleDiv.classList.add('message-bubble');
410
-
411
- // Prevent HTML injection but allow line breaks
412
- bubbleDiv.textContent = text;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
 
414
- const metaSpan = document.createElement('span');
415
- metaSpan.classList.add('message-meta');
416
- metaSpan.textContent = getCurrentTime();
 
 
417
 
418
- bubbleDiv.appendChild(metaSpan);
419
- rowDiv.appendChild(bubbleDiv);
420
-
421
- // Insert before typing indicator
422
- chatBody.insertBefore(rowDiv, typingIndicator);
423
- scrollToBottom();
 
 
 
 
 
 
 
 
 
 
 
424
  }
 
 
 
425
 
426
- // Handle sending logic
427
- function handleSend() {
428
- const text = messageInput.value.trim();
429
- if (!text) return;
430
-
431
- // 1. Add user message
432
- addMessage(text, 'sent');
433
- messageInput.value = '';
434
- messageInput.focus();
435
-
436
- // 2. Simulate bot typing
437
- showTyping();
438
-
439
- // 3. Simulate bot response after delay
440
- setTimeout(() => {
441
- hideTyping();
442
- const responses = [
443
- "That sounds perfect!",
444
- "I agree, less is definitely more here.",
445
- "Can you send me the updated specs?",
446
- "Looks good to me. Let's proceed.",
447
- "Nice, keep me posted."
448
- ];
449
- const randomResponse = responses[Math.floor(Math.random() * responses.length)];
450
- addMessage(randomResponse, 'received');
451
- }, 1500 + Math.random() * 1000); // Random delay between 1.5s and 2.5s
452
  }
453
 
454
- function showTyping() {
455
- typingIndicator.style.display = 'block';
456
- scrollToBottom();
457
- }
458
 
459
- function hideTyping() {
460
- typingIndicator.style.display = 'none';
461
- }
 
462
 
463
- // Event Listeners
464
- sendBtn.addEventListener('click', handleSend);
 
 
465
 
466
- chatForm.addEventListener('submit', (e) => {
467
- e.preventDefault();
468
- handleSend();
469
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
 
471
- // Initial scroll to bottom
472
- scrollToBottom();
 
 
473
  });
 
 
 
 
474
  </script>
475
  </body>
476
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Minimal Glass Chat</title>
7
+ <!-- Import Google Fonts: Nunito for that airy, soft feel -->
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600&display=swap" rel="stylesheet">
11
+ <!-- Import FontAwesome for Icons -->
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
13
 
14
  <style>
15
  :root {
16
+ /* Palette: Soft Pastels & Glass */
17
  --bg-gradient-start: #fdfbfb;
18
  --bg-gradient-end: #ebedee;
 
 
 
19
 
20
+ /* Soft Blob Colors */
21
+ --blob-1: #e0c3fc;
22
+ --blob-2: #8ec5fc;
23
+
24
+ /* Glass Variables - Restrained */
25
+ --glass-bg: rgba(255, 255, 255, 0.45);
26
+ --glass-border: rgba(255, 255, 255, 0.4);
27
+ --glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.05);
28
+ --glass-blur: blur(12px);
29
+
30
+ /* Typography */
31
+ --font-main: 'Nunito', sans-serif;
32
+ --text-primary: #4a4a4a; /* Darker gray for contrast but softer than black */
33
+ --text-secondary: #7a7a7a;
34
 
35
+ /* Message Bubbles */
36
+ --msg-sent-bg: rgba(179, 209, 255, 0.5); /* Very soft blue */
37
+ --msg-received-bg: rgba(255, 255, 255, 0.5);
38
+ --msg-text: #444;
39
+
40
+ /* Spacing */
41
+ --spacing-sm: 8px;
42
+ --spacing-md: 16px;
43
+ --spacing-lg: 24px;
 
 
 
 
44
  }
45
 
46
  * {
 
47
  margin: 0;
48
  padding: 0;
49
+ box-sizing: border-box;
50
  }
51
 
52
  body {
53
+ font-family: var(--font-main);
54
+ background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);
55
  height: 100vh;
56
+ width: 100vw;
57
+ overflow: hidden;
58
  color: var(--text-primary);
59
+ position: relative;
60
  }
61
 
62
+ /*
63
+ Background: Single subtle gradient/blob
64
+ Removed extra animated blobs
65
+ */
66
+ .ambient-bg {
67
+ position: absolute;
68
+ top: 0;
69
+ left: 0;
70
  width: 100%;
71
  height: 100%;
72
+ z-index: -1;
73
+ /* One soft, static gradient */
74
+ background: radial-gradient(circle at 10% 20%, rgba(224, 195, 252, 0.3) 0%, transparent 40%),
75
+ radial-gradient(circle at 90% 80%, rgba(142, 197, 252, 0.3) 0%, transparent 40%);
76
+ pointer-events: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
+ /* Layout Container */
80
+ .app-container {
 
 
81
  display: flex;
82
+ width: 95%;
83
+ height: 92%;
84
+ max-width: 1400px;
85
+ margin: 4vh auto;
86
  background: var(--glass-bg);
87
+ backdrop-filter: var(--glass-blur);
88
+ -webkit-backdrop-filter: var(--glass-blur);
89
+ border: 1px solid var(--glass-border);
90
+ border-radius: 24px;
91
+ box-shadow: var(--glass-shadow);
92
+ overflow: hidden;
93
+ position: relative;
94
  }
95
 
96
+ /* --- Sidebar --- */
97
+ .sidebar {
98
+ width: 280px;
99
+ min-width: 280px;
100
+ border-right: 1px solid rgba(255, 255, 255, 0.3);
101
  display: flex;
102
+ flex-direction: column;
103
+ padding: var(--spacing-md);
104
+ background: rgba(255,255,255,0.1);
105
+ transition: transform 0.3s ease;
106
  }
107
 
108
+ /* Removed Search Bar as requested */
109
+
110
+ .contact-list {
111
+ list-style: none;
112
+ margin-top: var(--spacing-md);
113
+ overflow-y: auto;
114
+ flex-grow: 1;
115
  }
116
 
117
+ /* Custom Scrollbar for minimal look */
118
+ .contact-list::-webkit-scrollbar {
119
+ width: 4px;
120
+ }
121
+ .contact-list::-webkit-scrollbar-thumb {
122
+ background: rgba(0,0,0,0.05);
123
+ border-radius: 4px;
124
+ }
125
+
126
+ .contact-item {
127
  display: flex;
128
  align-items: center;
129
+ padding: 10px;
130
+ margin-bottom: 4px;
131
+ border-radius: 12px;
132
+ cursor: pointer;
133
+ transition: background 0.2s ease;
134
+ position: relative;
135
  }
136
 
137
+ /* Reduced hover effects */
138
+ .contact-item:hover {
139
+ background: rgba(255, 255, 255, 0.3);
 
 
 
 
 
140
  }
141
 
142
+ .contact-item.active {
143
+ background: rgba(255, 255, 255, 0.5);
 
144
  }
145
 
146
+ /* Smaller avatars */
147
+ .avatar {
148
+ width: 40px;
149
+ height: 40px;
150
+ border-radius: 50%;
151
+ object-fit: cover;
152
+ margin-right: 12px;
153
+ border: 1px solid rgba(255,255,255,0.5);
154
+ }
155
+
156
+ .contact-info {
157
  display: flex;
158
  flex-direction: column;
159
+ overflow: hidden;
 
160
  }
161
 
162
+ .contact-name {
163
+ font-size: 0.95rem;
164
+ font-weight: 500;
165
+ color: var(--text-primary);
166
  }
167
+
168
+ .last-msg {
169
+ font-size: 0.8rem;
170
+ color: var(--text-secondary);
171
+ white-space: nowrap;
172
+ overflow: hidden;
173
+ text-overflow: ellipsis;
174
+ font-weight: 300; /* Reduced weight variation */
175
  }
176
+
177
+ /* --- Main Chat Area --- */
178
+ .chat-area {
179
+ flex: 1;
180
+ display: flex;
181
+ flex-direction: column;
182
+ position: relative;
183
  }
184
 
185
+ /* --- Header --- */
186
+ header {
187
+ height: 60px; /* Reduced height */
188
+ min-height: 60px;
189
  display: flex;
190
+ align-items: center;
191
+ justify-content: space-between;
192
+ padding: 0 var(--spacing-lg);
193
+ border-bottom: 1px solid rgba(255, 255, 255, 0.3);
194
+ background: rgba(255, 255, 255, 0.2);
195
  }
196
 
197
+ .chat-title h2 {
198
+ font-size: 1.1rem;
199
+ font-weight: 600;
200
+ color: var(--text-primary);
201
  }
202
 
203
+ .chat-title span {
204
+ font-size: 0.8rem;
205
+ color: var(--text-secondary);
206
+ font-weight: 400;
207
+ margin-left: 8px;
208
  }
209
 
210
+ /* Branding */
211
+ .branding {
212
+ font-size: 0.75rem;
213
+ font-weight: 500;
214
+ }
215
+ .branding a {
216
+ text-decoration: none;
217
+ color: var(--text-secondary);
218
+ transition: color 0.2s;
219
+ }
220
+ .branding a:hover {
221
+ color: #6a82fb;
222
  }
223
 
224
+ /* --- Messages Area --- */
225
+ .messages-container {
226
+ flex: 1;
227
+ padding: var(--spacing-lg);
228
+ overflow-y: auto;
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: 12px; /* Tighter spacing */
232
+ }
233
+
234
+ .message {
235
+ max-width: 70%;
236
+ padding: 10px 16px; /* Tighter padding */
237
+ font-size: 0.95rem; /* Slightly smaller text */
238
  line-height: 1.5;
239
  position: relative;
240
+ animation: slideUpFade 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
241
+ opacity: 0;
242
+ transform: translateY(10px);
243
  }
244
 
245
+ @keyframes slideUpFade {
246
+ to {
247
+ opacity: 1;
248
+ transform: translateY(0);
249
+ }
250
+ }
251
+
252
+ .message.received {
253
+ align-self: flex-start;
254
+ background: var(--msg-received-bg);
255
+ color: var(--msg-text);
256
+ /* No border as requested */
257
+ border-radius: 18px 18px 18px 4px; /* Asymmetry */
258
  }
259
 
260
+ .message.sent {
261
+ align-self: flex-end;
262
+ background: var(--msg-sent-bg);
263
+ color: var(--msg-text);
264
+ /* No border as requested */
265
+ border-radius: 18px 18px 4px 18px; /* Asymmetry */
266
  }
267
 
268
+ .message-time {
269
  display: block;
270
+ font-size: 0.65rem;
271
  margin-top: 4px;
 
272
  text-align: right;
273
+ opacity: 0.6;
 
 
 
 
274
  }
275
 
276
  /* --- Input Area --- */
277
  .input-area {
278
+ padding: var(--spacing-md) var(--spacing-lg);
279
+ background: rgba(255, 255, 255, 0.25);
280
+ border-top: 1px solid rgba(255, 255, 255, 0.3);
 
 
 
281
  display: flex;
282
  align-items: center;
283
  gap: 12px;
284
  }
285
 
286
  .input-wrapper {
287
+ flex: 1;
288
  position: relative;
289
  }
290
 
 
292
  width: 100%;
293
  padding: 14px 20px;
294
  border-radius: 30px;
295
+ border: 1px solid rgba(255, 255, 255, 0.5);
296
+ background: rgba(255, 255, 255, 0.6);
297
+ font-family: var(--font-main);
 
298
  font-size: 0.95rem;
299
+ color: var(--text-primary);
300
  outline: none;
301
  transition: all 0.2s ease;
302
+ /* Remove attachment button means we have space */
303
  }
304
 
305
+ input[type="text"]:focus {
306
+ background: rgba(255, 255, 255, 0.8);
307
+ border-color: rgba(255, 255, 255, 0.8);
308
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
309
  }
310
 
311
+ input[type="text"]::placeholder {
312
+ color: #9ca3af;
 
 
313
  }
314
 
315
  .send-btn {
 
 
 
316
  width: 46px;
317
  height: 46px;
318
  border-radius: 50%;
319
+ border: none;
320
+ background: #6a82fb; /* Slightly more saturated accent for action */
321
+ color: white;
322
  display: flex;
323
  align-items: center;
324
  justify-content: center;
325
  cursor: pointer;
326
+ transition: transform 0.1s ease, background 0.2s;
327
+ box-shadow: 0 4px 12px rgba(106, 130, 251, 0.3);
328
  }
329
 
330
  .send-btn:hover {
331
+ background: #5a72eb;
332
+ transform: scale(1.02); /* Subtle scale, not floating */
333
  }
334
 
335
  .send-btn:active {
336
  transform: scale(0.95);
337
  }
338
 
339
+ /* Responsive Design */
340
+ @media (max-width: 768px) {
341
+ .app-container {
342
+ width: 100%;
343
+ height: 100%;
344
+ border-radius: 0;
345
+ border: none;
346
+ margin: 0;
347
+ }
 
 
 
 
 
 
 
348
 
349
+ .sidebar {
350
+ position: absolute;
351
+ left: 0;
352
+ top: 0;
353
+ bottom: 0;
354
+ z-index: 10;
355
+ background: rgba(255,255,255,0.95);
356
+ transform: translateX(-100%);
357
+ box-shadow: 2px 0 10px rgba(0,0,0,0.05);
358
+ }
359
 
360
+ .sidebar.open {
361
+ transform: translateX(0);
362
+ }
 
 
 
 
363
 
364
+ header {
365
+ padding: 0 var(--spacing-md);
366
+ }
367
 
368
+ .mobile-menu-toggle {
369
+ display: block;
370
+ margin-right: 12px;
371
+ color: var(--text-primary);
372
+ cursor: pointer;
373
+ font-size: 1.2rem;
374
+ }
375
+ }
376
+
377
+ @media (min-width: 769px) {
378
+ .mobile-menu-toggle {
379
+ display: none;
380
+ }
381
  }
 
382
  </style>
383
  </head>
384
  <body>
385
 
386
+ <div class="ambient-bg"></div>
387
+
388
  <div class="app-container">
389
+ <!-- Sidebar -->
390
+ <aside class="sidebar" id="sidebar">
391
+ <!-- Contacts -->
392
+ <ul class="contact-list" id="contactList">
393
+ <!-- Contacts generated by JS -->
394
+ </ul>
395
+ </aside>
396
+
397
+ <!-- Main Chat -->
398
+ <main class="chat-area">
399
+ <!-- Header -->
400
+ <header>
401
+ <div style="display: flex; align-items: center;">
402
+ <i class="fas fa-bars mobile-menu-toggle" id="menuToggle"></i>
403
+ <div class="chat-title">
404
+ <h2 id="activeChatName">Select a chat</h2>
405
+ <span id="activeChatStatus"></span>
406
+ </div>
 
 
407
  </div>
408
+
409
+ <div class="branding">
410
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
 
 
 
411
  </div>
412
+ </header>
413
 
414
+ <!-- Messages -->
415
+ <div class="messages-container" id="messagesContainer">
416
+ <!-- Messages generated by JS -->
417
+ <div class="message received">
418
+ Hello! Select a friend to start chatting with the minimal glass interface.
419
  </div>
420
  </div>
421
+
422
+ <!-- Input -->
423
+ <div class="input-area">
424
+ <div class="input-wrapper">
425
+ <input type="text" id="messageInput" placeholder="Type a message..." autocomplete="off">
 
 
426
  </div>
427
+ <button class="send-btn" id="sendBtn">
428
+ <i class="fas fa-paper-plane"></i>
429
+ </button>
430
  </div>
431
  </main>
 
 
 
 
 
 
 
 
 
 
 
 
432
  </div>
433
 
434
  <script>
435
+ // Data Mockup
436
+ const contacts = [
437
+ { id: 1, name: "Alice Moore", avatar: "https://picsum.photos/seed/alice/100/100", lastMsg: "See you tomorrow!", status: "Online" },
438
+ { id: 2, name: "Bob Smith", avatar: "https://picsum.photos/seed/bob/100/100", lastMsg: "Is the project ready?", status: "Away" },
439
+ { id: 3, name: "Clara Oswald", avatar: "https://picsum.photos/seed/clara/100/100", lastMsg: "That looks amazing.", status: "Online" },
440
+ { id: 4, name: "David Tennant", avatar: "https://picsum.photos/seed/david/100/100", lastMsg: "Fantastic!", status: "Offline" },
441
+ { id: 5, name: "Emma Watson", avatar: "https://picsum.photos/seed/emma/100/100", lastMsg: "Book club is on Friday.", status: "Online" }
442
+ ];
443
+
444
+ const chatHistory = {
445
+ 1: [
446
+ { type: 'received', text: "Hey! How are you doing?", time: "10:00 AM" },
447
+ { type: 'sent', text: "I'm doing great, thanks! Just redesigning this UI.", time: "10:02 AM" },
448
+ { type: 'received', text: "Oh nice, is it the glassmorphism one?", time: "10:03 AM" },
449
+ { type: 'sent', text: "Yeah, making it much more restrained and minimal.", time: "10:05 AM" },
450
+ { type: 'received', text: "See you tomorrow!", time: "10:06 AM" }
451
+ ],
452
+ 2: [
453
+ { type: 'received', text: "Is the project ready?", time: "09:30 AM" }
454
+ ],
455
+ 3: [
456
+ { type: 'sent', text: "I sent you the new mockups.", time: "Yesterday" },
457
+ { type: 'received', text: "That looks amazing.", time: "Yesterday" }
458
+ ]
459
+ };
460
+
461
+ let activeContactId = 1;
462
+
463
+ // DOM Elements
464
+ const contactListEl = document.getElementById('contactList');
465
+ const messagesContainerEl = document.getElementById('messagesContainer');
466
+ const activeChatNameEl = document.getElementById('activeChatName');
467
+ const activeChatStatusEl = document.getElementById('activeChatStatus');
468
+ const messageInput = document.getElementById('messageInput');
469
+ const sendBtn = document.getElementById('sendBtn');
470
+ const sidebar = document.getElementById('sidebar');
471
+ const menuToggle = document.getElementById('menuToggle');
472
+
473
+ // Initialize
474
+ function init() {
475
+ renderContacts();
476
+ loadChat(activeContactId);
477
+
478
+ // Mobile Menu Toggle
479
+ menuToggle.addEventListener('click', () => {
480
+ sidebar.classList.toggle('open');
481
+ });
482
 
483
+ // Close sidebar when clicking outside on mobile
484
+ document.addEventListener('click', (e) => {
485
+ if (window.innerWidth <= 768) {
486
+ if (!sidebar.contains(e.target) && !menuToggle.contains(e.target)) {
487
+ sidebar.classList.remove('open');
488
+ }
489
+ }
490
+ });
491
+ }
492
 
493
+ // Render Sidebar
494
+ function renderContacts() {
495
+ contactListEl.innerHTML = '';
496
+ contacts.forEach(contact => {
497
+ const li = document.createElement('li');
498
+ li.className = `contact-item ${contact.id === activeContactId ? 'active' : ''}`;
499
+ li.onclick = () => {
500
+ activeContactId = contact.id;
501
+ renderContacts(); // Re-render to update active state
502
+ loadChat(contact.id);
503
+ if (window.innerWidth <= 768) sidebar.classList.remove('open');
504
+ };
505
+
506
+ li.innerHTML = `
507
+ <img src="${contact.avatar}" alt="${contact.name}" class="avatar">
508
+ <div class="contact-info">
509
+ <span class="contact-name">${contact.name}</span>
510
+ <span class="last-msg">${contact.lastMsg}</span>
511
+ </div>
512
+ `;
513
+ contactListEl.appendChild(li);
514
+ });
515
+ }
516
 
517
+ // Load Chat Messages
518
+ function loadChat(id) {
519
+ const contact = contacts.find(c => c.id === id);
520
+ activeChatNameEl.textContent = contact.name;
521
+ activeChatStatusEl.textContent = contact.status;
522
 
523
+ messagesContainerEl.innerHTML = '';
524
+
525
+ const messages = chatHistory[id] || [];
526
+
527
+ if (messages.length === 0) {
528
+ const emptyState = document.createElement('div');
529
+ emptyState.className = 'message received';
530
+ emptyState.style.textAlign = 'center';
531
+ emptyState.style.alignSelf = 'center';
532
+ emptyState.style.background = 'transparent';
533
+ emptyState.style.color = '#999';
534
+ emptyState.textContent = "Start a conversation with " + contact.name;
535
+ messagesContainerEl.appendChild(emptyState);
536
+ } else {
537
+ messages.forEach(msg => {
538
+ appendMessage(msg.text, msg.type, msg.time, false);
539
+ });
540
  }
541
+
542
+ scrollToBottom();
543
+ }
544
 
545
+ // Append Message to DOM
546
+ function appendMessage(text, type, time = null, animate = true) {
547
+ const div = document.createElement('div');
548
+ div.className = `message ${type}`;
549
+
550
+ // Format time if not provided
551
+ const now = new Date();
552
+ const timeString = time || now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
553
+
554
+ div.innerHTML = `
555
+ ${text}
556
+ <span class="message-time">${timeString}</span>
557
+ `;
558
+
559
+ // Disable animation if loading history
560
+ if (!animate) {
561
+ div.style.animation = 'none';
562
+ div.style.opacity = '1';
563
+ div.style.transform = 'translateY(0)';
 
 
 
 
 
 
 
564
  }
565
 
566
+ messagesContainerEl.appendChild(div);
567
+ scrollToBottom();
568
+ }
 
569
 
570
+ // Scroll Helper
571
+ function scrollToBottom() {
572
+ messagesContainerEl.scrollTop = messagesContainerEl.scrollHeight;
573
+ }
574
 
575
+ // Send Message Logic
576
+ function handleSend() {
577
+ const text = messageInput.value.trim();
578
+ if (!text) return;
579
 
580
+ // Add user message
581
+ appendMessage(text, 'sent');
582
+
583
+ // Update history (mock)
584
+ if (!chatHistory[activeContactId]) chatHistory[activeContactId] = [];
585
+ chatHistory[activeContactId].push({ type: 'sent', text: text, time: new Date().toLocaleTimeString() });
586
+
587
+ // Update sidebar preview
588
+ const contact = contacts.find(c => c.id === activeContactId);
589
+ contact.lastMsg = "You: " + text;
590
+ renderContacts();
591
+
592
+ messageInput.value = '';
593
+ messageInput.focus();
594
+
595
+ // Mock Reply
596
+ setTimeout(() => {
597
+ const replies = [
598
+ "That sounds interesting!",
599
+ "I'll have to check that out.",
600
+ "Cool.",
601
+ "Can you tell me more?",
602
+ "Okay, noted."
603
+ ];
604
+ const randomReply = replies[Math.floor(Math.random() * replies.length)];
605
+
606
+ appendMessage(randomReply, 'received');
607
+ chatHistory[activeContactId].push({ type: 'received', text: randomReply, time: new Date().toLocaleTimeString() });
608
+
609
+ contact.lastMsg = randomReply;
610
+ renderContacts();
611
+ }, 1500 + Math.random() * 1000);
612
+ }
613
 
614
+ // Event Listeners
615
+ sendBtn.addEventListener('click', handleSend);
616
+ messageInput.addEventListener('keypress', (e) => {
617
+ if (e.key === 'Enter') handleSend();
618
  });
619
+
620
+ // Start App
621
+ init();
622
+
623
  </script>
624
  </body>
625
  </html>