@fuzionx/framework 0.1.46 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +29 -2
  2. package/cli/index.js +57 -18
  3. package/cli/templates/make/app-spa/controllers/AuthController.js +114 -0
  4. package/cli/templates/make/app-spa/controllers/HomeController.js +66 -0
  5. package/cli/templates/make/app-spa/controllers/PostController.js +191 -0
  6. package/cli/templates/make/app-spa/controllers/UserController.js +43 -0
  7. package/cli/templates/make/app-spa/public/css/style.css +1011 -0
  8. package/cli/templates/make/app-spa/routes/api.js +31 -0
  9. package/cli/templates/make/app-spa/routes/web.js +19 -0
  10. package/cli/templates/make/app-spa/services/AuthService.js +48 -0
  11. package/cli/templates/make/app-spa/services/PostService.js +372 -0
  12. package/cli/templates/make/app-spa/services/UserService.js +48 -0
  13. package/cli/templates/make/app-spa/views/default/errors/404.html +11 -0
  14. package/cli/templates/make/app-spa/views/default/errors/500.html +11 -0
  15. package/cli/templates/make/app-spa/views/default/layouts/main.html +34 -0
  16. package/cli/templates/make/app-spa/views/default/pages/home.html +22 -0
  17. package/cli/templates/make/app-spa/views/default/spa/index.html +13 -0
  18. package/cli/templates/make/app-spa/views/default/spa/package.json +20 -0
  19. package/cli/templates/make/app-spa/views/default/spa/src/App.vue +41 -0
  20. package/cli/templates/make/app-spa/views/default/spa/src/assets/landing.css +220 -0
  21. package/cli/templates/make/app-spa/views/default/spa/src/assets/style.css +1156 -0
  22. package/cli/templates/make/app-spa/views/default/spa/src/components/AlertDialog.vue +179 -0
  23. package/cli/templates/make/app-spa/views/default/spa/src/components/CodeBlock.vue +33 -0
  24. package/cli/templates/make/app-spa/views/default/spa/src/components/EditorToolbar.vue +54 -0
  25. package/cli/templates/make/app-spa/views/default/spa/src/components/FileUpload.vue +161 -0
  26. package/cli/templates/make/app-spa/views/default/spa/src/components/FlashMessage.vue +39 -0
  27. package/cli/templates/make/app-spa/views/default/spa/src/components/LanguageSwitcher.vue +108 -0
  28. package/cli/templates/make/app-spa/views/default/spa/src/components/Lightbox.vue +62 -0
  29. package/cli/templates/make/app-spa/views/default/spa/src/components/Navbar.vue +68 -0
  30. package/cli/templates/make/app-spa/views/default/spa/src/components/Pagination.vue +166 -0
  31. package/cli/templates/make/app-spa/views/default/spa/src/components/ToastContainer.vue +135 -0
  32. package/cli/templates/make/app-spa/views/default/spa/src/composables/useApi.js +129 -0
  33. package/cli/templates/make/app-spa/views/default/spa/src/composables/useClipboard.js +44 -0
  34. package/cli/templates/make/app-spa/views/default/spa/src/composables/useDate.js +73 -0
  35. package/cli/templates/make/app-spa/views/default/spa/src/composables/useDebounce.js +59 -0
  36. package/cli/templates/make/app-spa/views/default/spa/src/composables/useFlash.js +46 -0
  37. package/cli/templates/make/app-spa/views/default/spa/src/composables/useHeartbeat.js +45 -0
  38. package/cli/templates/make/app-spa/views/default/spa/src/composables/useLocalStorage.js +43 -0
  39. package/cli/templates/make/app-spa/views/default/spa/src/composables/useLocale.js +79 -0
  40. package/cli/templates/make/app-spa/views/default/spa/src/composables/useWebSocket.js +93 -0
  41. package/cli/templates/make/app-spa/views/default/spa/src/main.js +106 -0
  42. package/cli/templates/make/app-spa/views/default/spa/src/plugins/alert.js +96 -0
  43. package/cli/templates/make/app-spa/views/default/spa/src/plugins/toast.js +79 -0
  44. package/cli/templates/make/app-spa/views/default/spa/src/router/index.js +29 -0
  45. package/cli/templates/make/app-spa/views/default/spa/src/stores/auth.js +58 -0
  46. package/cli/templates/make/app-spa/views/default/spa/src/views/BoardDetail.vue +169 -0
  47. package/cli/templates/make/app-spa/views/default/spa/src/views/BoardForm.vue +192 -0
  48. package/cli/templates/make/app-spa/views/default/spa/src/views/BoardList.vue +129 -0
  49. package/cli/templates/make/app-spa/views/default/spa/src/views/ChatView.vue +317 -0
  50. package/cli/templates/make/app-spa/views/default/spa/src/views/FeaturesView.vue +242 -0
  51. package/cli/templates/make/app-spa/views/default/spa/src/views/HomeView.vue +215 -0
  52. package/cli/templates/make/app-spa/views/default/spa/src/views/Login.vue +82 -0
  53. package/cli/templates/make/app-spa/views/default/spa/src/views/Profile.vue +85 -0
  54. package/cli/templates/make/app-spa/views/default/spa/src/views/Register.vue +84 -0
  55. package/cli/templates/make/app-spa/views/default/spa/vite.config.js +28 -0
  56. package/cli/templates/make/app-spa/views/default/spa/yarn.lock +633 -0
  57. package/cli/templates/make/app-spa/ws/ChatHandler.js +138 -0
  58. package/cli/templates/make/app-ssr/controllers/AuthController.js +119 -0
  59. package/cli/templates/make/app-ssr/controllers/ChatController.js +15 -0
  60. package/cli/templates/make/app-ssr/controllers/FeaturesController.js +15 -0
  61. package/cli/templates/make/app-ssr/controllers/HomeController.js +21 -0
  62. package/cli/templates/make/app-ssr/controllers/PostController.js +214 -0
  63. package/cli/templates/make/app-ssr/controllers/UserController.js +48 -0
  64. package/cli/templates/make/app-ssr/public/css/fx-ui.css +43 -0
  65. package/cli/templates/make/app-ssr/public/css/landing.css +220 -0
  66. package/cli/templates/make/app-ssr/public/css/style.css +1011 -0
  67. package/cli/templates/make/app-ssr/public/js/fx-client.js +107 -0
  68. package/cli/templates/make/app-ssr/public/js/fx-ui.js +124 -0
  69. package/cli/templates/make/app-ssr/routes/web.js +46 -0
  70. package/cli/templates/make/app-ssr/services/AuthService.js +48 -0
  71. package/cli/templates/make/app-ssr/services/PostService.js +372 -0
  72. package/cli/templates/make/app-ssr/services/UserService.js +48 -0
  73. package/cli/templates/make/app-ssr/views/default/errors/404.html +11 -0
  74. package/cli/templates/make/app-ssr/views/default/errors/500.html +48 -0
  75. package/cli/templates/make/app-ssr/views/default/layouts/main.html +96 -0
  76. package/cli/templates/make/app-ssr/views/default/pages/board/form.html +240 -0
  77. package/cli/templates/make/app-ssr/views/default/pages/board/index.html +73 -0
  78. package/cli/templates/make/app-ssr/views/default/pages/board/show.html +148 -0
  79. package/cli/templates/make/app-ssr/views/default/pages/chat.html +288 -0
  80. package/cli/templates/make/app-ssr/views/default/pages/features.html +373 -0
  81. package/cli/templates/make/app-ssr/views/default/pages/home.html +258 -0
  82. package/cli/templates/make/app-ssr/views/default/pages/login.html +27 -0
  83. package/cli/templates/make/app-ssr/views/default/pages/profile.html +36 -0
  84. package/cli/templates/make/app-ssr/views/default/pages/register.html +35 -0
  85. package/cli/templates/make/app-ssr/views/default/partials/pagination.html +75 -0
  86. package/cli/templates/make/app-ssr/ws/ChatHandler.js +138 -0
  87. package/package.json +2 -2
@@ -0,0 +1,1156 @@
1
+ /* ═══════════════════════════════════════════════
2
+ * FuzionX — Glassmorphism Dark Theme
3
+ * ═══════════════════════════════════════════════ */
4
+
5
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
6
+
7
+ /* ── Reset ───────────────────────────────────── */
8
+ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
9
+
10
+ /* ── Root Variables ──────────────────────────── */
11
+ :root {
12
+ --bg-gradient: linear-gradient(135deg, #0f0c29 0%, #1a1a3e 40%, #24243e 100%);
13
+ --glass-bg: rgba(255, 255, 255, 0.05);
14
+ --glass-border: rgba(255, 255, 255, 0.1);
15
+ --glass-blur: blur(20px);
16
+ --text-primary: #e0e0e0;
17
+ --text-secondary: rgba(255, 255, 255, 0.5);
18
+ --text-muted: rgba(255, 255, 255, 0.3);
19
+ --accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
20
+ --accent-solid: #667eea;
21
+ --accent-hover: #7b93ff;
22
+ --danger: #e74c3c;
23
+ --success: #2ecc71;
24
+ --radius: 16px;
25
+ --radius-sm: 8px;
26
+ --font: 'Inter', system-ui, -apple-system, sans-serif;
27
+ --nav-height: 64px;
28
+ --transition: all 0.3s ease;
29
+ }
30
+
31
+ /* ── Body ────────────────────────────────────── */
32
+ body {
33
+ font-family: var(--font);
34
+ min-height: 100vh;
35
+ background: var(--bg-gradient);
36
+ color: var(--text-primary);
37
+ line-height: 1.6;
38
+ overflow-x: hidden;
39
+ }
40
+
41
+ /* ── Background Orbs ─────────────────────────── */
42
+ .orb {
43
+ position: fixed;
44
+ border-radius: 50%;
45
+ filter: blur(80px);
46
+ opacity: 0.3;
47
+ animation: float 8s ease-in-out infinite;
48
+ pointer-events: none;
49
+ z-index: 0;
50
+ }
51
+ .orb-1 { width: 400px; height: 400px; background: #667eea; top: -100px; right: -100px; }
52
+ .orb-2 { width: 300px; height: 300px; background: #764ba2; bottom: -80px; left: -80px; animation-delay: -4s; }
53
+ .orb-3 { width: 200px; height: 200px; background: #f093fb; top: 50%; left: 60%; animation-delay: -2s; }
54
+
55
+ @keyframes float {
56
+ 0%, 100% { transform: translate(0, 0); }
57
+ 50% { transform: translate(30px, -30px); }
58
+ }
59
+
60
+ /* ── Navbar ──────────────────────────────────── */
61
+ .navbar {
62
+ position: fixed;
63
+ top: 0;
64
+ left: 0;
65
+ right: 0;
66
+ height: var(--nav-height);
67
+ background: rgba(15, 12, 41, 0.6);
68
+ backdrop-filter: var(--glass-blur);
69
+ -webkit-backdrop-filter: var(--glass-blur);
70
+ border-bottom: 1px solid var(--glass-border);
71
+ z-index: 100;
72
+ }
73
+
74
+ .nav-container {
75
+ max-width: 1200px;
76
+ margin: 0 auto;
77
+ height: 100%;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: space-between;
81
+ padding: 0 2rem;
82
+ }
83
+
84
+ .nav-brand {
85
+ font-size: 1.5rem;
86
+ font-weight: 800;
87
+ background: var(--accent-gradient);
88
+ -webkit-background-clip: text;
89
+ background-clip: text;
90
+ -webkit-text-fill-color: transparent;
91
+ text-decoration: none;
92
+ letter-spacing: -1px;
93
+ }
94
+
95
+ .nav-links {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 0.5rem;
99
+ }
100
+
101
+ .nav-link {
102
+ color: var(--text-secondary);
103
+ text-decoration: none;
104
+ font-size: 0.9rem;
105
+ padding: 8px 16px;
106
+ border-radius: var(--radius-sm);
107
+ transition: var(--transition);
108
+ border: none;
109
+ background: none;
110
+ cursor: pointer;
111
+ font-family: var(--font);
112
+ }
113
+
114
+ .nav-link:hover,
115
+ .nav-link.router-link-active {
116
+ color: #fff;
117
+ background: rgba(102, 126, 234, 0.15);
118
+ }
119
+
120
+ .nav-logout { display: inline; }
121
+
122
+ .btn-link {
123
+ border: none;
124
+ background: none;
125
+ cursor: pointer;
126
+ font-family: var(--font);
127
+ }
128
+
129
+ /* ── Main Content ────────────────────────────── */
130
+ .main-content {
131
+ min-height: 100vh;
132
+ position: relative;
133
+ z-index: 1;
134
+ }
135
+
136
+ .main-content.has-nav {
137
+ padding-top: calc(var(--nav-height) + 2rem);
138
+ }
139
+
140
+ .container {
141
+ max-width: 1140px;
142
+ margin: 0 auto;
143
+ padding: 2rem;
144
+ }
145
+
146
+ /* ── Glass Card ──────────────────────────────── */
147
+ .glass-card {
148
+ background: var(--glass-bg);
149
+ backdrop-filter: var(--glass-blur);
150
+ -webkit-backdrop-filter: var(--glass-blur);
151
+ border: 1px solid var(--glass-border);
152
+ border-radius: var(--radius);
153
+ padding: 2rem;
154
+ animation: fadeInUp 0.5s ease-out;
155
+ }
156
+
157
+ @keyframes fadeInUp {
158
+ from { opacity: 0; transform: translateY(20px); }
159
+ to { opacity: 1; transform: translateY(0); }
160
+ }
161
+
162
+ /* ── Auth Pages ──────────────────────────────── */
163
+ .auth-container {
164
+ min-height: 100vh;
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: center;
168
+ position: relative;
169
+ z-index: 1;
170
+ }
171
+
172
+ .auth-card {
173
+ width: 100%;
174
+ max-width: 420px;
175
+ text-align: center;
176
+ margin: 1rem;
177
+ }
178
+
179
+ .auth-logo {
180
+ font-size: 2.5rem;
181
+ font-weight: 800;
182
+ background: var(--accent-gradient);
183
+ -webkit-background-clip: text;
184
+ background-clip: text;
185
+ -webkit-text-fill-color: transparent;
186
+ letter-spacing: -2px;
187
+ margin-bottom: 0.5rem;
188
+ }
189
+
190
+ .auth-subtitle {
191
+ font-size: 1rem;
192
+ color: var(--text-secondary);
193
+ margin-bottom: 2rem;
194
+ }
195
+
196
+ .auth-form { text-align: left; }
197
+
198
+ .auth-footer {
199
+ margin-top: 1.5rem;
200
+ font-size: 0.85rem;
201
+ color: var(--text-secondary);
202
+ }
203
+
204
+ .auth-footer a {
205
+ color: var(--accent-solid);
206
+ text-decoration: none;
207
+ }
208
+
209
+ .auth-footer a:hover {
210
+ text-decoration: underline;
211
+ }
212
+
213
+ /* ── Forms ────────────────────────────────────── */
214
+ .form-group {
215
+ margin-bottom: 1.25rem;
216
+ }
217
+
218
+ .form-group label {
219
+ display: block;
220
+ font-size: 0.85rem;
221
+ font-weight: 500;
222
+ color: var(--text-secondary);
223
+ margin-bottom: 0.4rem;
224
+ }
225
+
226
+ .form-group input,
227
+ .form-group textarea,
228
+ .form-group select {
229
+ width: 100%;
230
+ padding: 10px 14px;
231
+ background: rgba(255, 255, 255, 0.08);
232
+ border: 1px solid var(--glass-border);
233
+ border-radius: var(--radius-sm);
234
+ color: var(--text-primary);
235
+ font-family: var(--font);
236
+ font-size: 0.95rem;
237
+ transition: var(--transition);
238
+ outline: none;
239
+ }
240
+
241
+ .form-group input:focus,
242
+ .form-group textarea:focus {
243
+ border-color: var(--accent-solid);
244
+ background: rgba(255, 255, 255, 0.12);
245
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);
246
+ }
247
+
248
+ .form-group input::placeholder,
249
+ .form-group textarea::placeholder {
250
+ color: var(--text-muted);
251
+ }
252
+
253
+ .form-actions {
254
+ display: flex;
255
+ gap: 0.75rem;
256
+ margin-top: 1.5rem;
257
+ }
258
+
259
+ /* ── Buttons ─────────────────────────────────── */
260
+ .btn {
261
+ display: inline-block;
262
+ padding: 10px 24px;
263
+ border-radius: var(--radius-sm);
264
+ font-family: var(--font);
265
+ font-size: 0.9rem;
266
+ font-weight: 600;
267
+ border: none;
268
+ cursor: pointer;
269
+ text-decoration: none;
270
+ transition: var(--transition);
271
+ text-align: center;
272
+ }
273
+
274
+ .btn-primary {
275
+ background: linear-gradient(135deg, #667eea, #764ba2);
276
+ color: #fff;
277
+ }
278
+
279
+ .btn-primary:hover {
280
+ transform: translateY(-2px);
281
+ box-shadow: 0 8px 20px rgba(102, 126, 234, 0.25);
282
+ }
283
+
284
+ .btn-primary:disabled {
285
+ opacity: 0.5;
286
+ cursor: not-allowed;
287
+ transform: none;
288
+ }
289
+
290
+ .btn-full { width: 100%; }
291
+
292
+ .btn-outline {
293
+ background: transparent;
294
+ border: 1px solid var(--glass-border);
295
+ color: var(--text-primary);
296
+ }
297
+
298
+ .btn-outline:hover {
299
+ border-color: var(--accent-solid);
300
+ color: #fff;
301
+ background: rgba(102, 126, 234, 0.1);
302
+ }
303
+
304
+ .btn-danger {
305
+ background: var(--danger);
306
+ color: #fff;
307
+ }
308
+
309
+ .btn-danger:hover {
310
+ background: #c0392b;
311
+ transform: translateY(-2px);
312
+ }
313
+
314
+ /* ── Alert ────────────────────────────────────── */
315
+ .alert {
316
+ padding: 10px 16px;
317
+ border-radius: var(--radius-sm);
318
+ margin-bottom: 1.25rem;
319
+ font-size: 0.9rem;
320
+ }
321
+
322
+ .alert-error {
323
+ background: rgba(231, 76, 60, 0.15);
324
+ border: 1px solid rgba(231, 76, 60, 0.3);
325
+ color: #e74c3c;
326
+ }
327
+
328
+ .alert-success {
329
+ background: rgba(46, 204, 113, 0.15);
330
+ border: 1px solid rgba(46, 204, 113, 0.3);
331
+ color: #2ecc71;
332
+ }
333
+
334
+ /* ── Page Header ─────────────────────────────── */
335
+ .page-header {
336
+ display: flex;
337
+ align-items: center;
338
+ justify-content: space-between;
339
+ margin-bottom: 1.5rem;
340
+ }
341
+
342
+ .page-title {
343
+ font-size: 1.5rem;
344
+ font-weight: 700;
345
+ letter-spacing: -0.5px;
346
+ }
347
+
348
+ .page-subtitle {
349
+ color: var(--text-secondary);
350
+ margin-top: 0.5rem;
351
+ }
352
+
353
+ .page-actions {
354
+ display: flex;
355
+ gap: 0.5rem;
356
+ }
357
+
358
+ /* ── Stats Grid (Dashboard) ──────────────────── */
359
+ .stats-grid {
360
+ display: grid;
361
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
362
+ gap: 1rem;
363
+ margin-top: 2rem;
364
+ }
365
+
366
+ .stat-card {
367
+ display: flex;
368
+ align-items: center;
369
+ gap: 1rem;
370
+ padding: 1.25rem;
371
+ background: rgba(255, 255, 255, 0.03);
372
+ border: 1px solid var(--glass-border);
373
+ border-radius: var(--radius);
374
+ transition: var(--transition);
375
+ text-decoration: none;
376
+ color: inherit;
377
+ position: relative;
378
+ }
379
+
380
+ .stat-card:hover {
381
+ background: rgba(102, 126, 234, 0.08);
382
+ border-color: rgba(102, 126, 234, 0.3);
383
+ transform: translateY(-2px);
384
+ }
385
+
386
+ .stat-icon { font-size: 2rem; }
387
+ .stat-label { display: block; font-size: 0.8rem; color: var(--text-secondary); }
388
+ .stat-value { display: block; font-size: 1.1rem; font-weight: 600; margin-top: 0.25rem; }
389
+ .stat-link { position: absolute; inset: 0; }
390
+
391
+ /* ── Table ────────────────────────────────────── */
392
+ .table {
393
+ width: 100%;
394
+ border-collapse: collapse;
395
+ }
396
+
397
+ .table th {
398
+ text-align: left;
399
+ font-size: 0.8rem;
400
+ font-weight: 600;
401
+ text-transform: uppercase;
402
+ letter-spacing: 0.5px;
403
+ color: var(--text-secondary);
404
+ padding: 12px 16px;
405
+ border-bottom: 1px solid var(--glass-border);
406
+ }
407
+
408
+ .table td {
409
+ padding: 12px 16px;
410
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
411
+ font-size: 0.9rem;
412
+ }
413
+
414
+ .table tr:hover td {
415
+ background: rgba(255, 255, 255, 0.02);
416
+ }
417
+
418
+ .table-link {
419
+ color: var(--accent-hover);
420
+ text-decoration: none;
421
+ }
422
+
423
+ .table-link:hover {
424
+ text-decoration: underline;
425
+ }
426
+
427
+ .table-empty {
428
+ text-align: center;
429
+ color: var(--text-muted);
430
+ padding: 2rem !important;
431
+ }
432
+
433
+ /* ── Pagination ──────────────────────────────── */
434
+ .pagination {
435
+ display: flex;
436
+ align-items: center;
437
+ justify-content: center;
438
+ gap: 1rem;
439
+ margin-top: 1.5rem;
440
+ }
441
+
442
+ .page-link {
443
+ padding: 6px 16px;
444
+ border-radius: var(--radius-sm);
445
+ border: 1px solid var(--glass-border);
446
+ background: transparent;
447
+ color: var(--text-primary);
448
+ cursor: pointer;
449
+ font-family: var(--font);
450
+ font-size: 0.85rem;
451
+ transition: var(--transition);
452
+ text-decoration: none;
453
+ }
454
+
455
+ .page-link:hover:not(:disabled) {
456
+ border-color: var(--accent-solid);
457
+ color: #fff;
458
+ }
459
+
460
+ .page-link:disabled {
461
+ opacity: 0.3;
462
+ cursor: not-allowed;
463
+ }
464
+
465
+ .page-info {
466
+ font-size: 0.85rem;
467
+ color: var(--text-secondary);
468
+ }
469
+
470
+ /* ── Post Detail ─────────────────────────────── */
471
+ .post-meta {
472
+ display: flex;
473
+ gap: 1rem;
474
+ font-size: 0.85rem;
475
+ color: var(--text-secondary);
476
+ margin-bottom: 1.5rem;
477
+ padding-bottom: 1rem;
478
+ border-bottom: 1px solid var(--glass-border);
479
+ }
480
+
481
+ .post-content {
482
+ white-space: pre-wrap;
483
+ line-height: 1.8;
484
+ margin-bottom: 2rem;
485
+ }
486
+
487
+ .post-footer {
488
+ border-top: 1px solid var(--glass-border);
489
+ padding-top: 1rem;
490
+ }
491
+
492
+ /* ── Responsive ──────────────────────────────── */
493
+ @media (max-width: 768px) {
494
+ .container { padding: 1rem; }
495
+ .glass-card { padding: 1.5rem; }
496
+ .nav-container { padding: 0 1rem; }
497
+ .page-header { flex-direction: column; align-items: flex-start; gap: 1rem; }
498
+ .stats-grid { grid-template-columns: 1fr; }
499
+ .table { font-size: 0.85rem; }
500
+ .table th, .table td { padding: 8px 10px; }
501
+ }
502
+
503
+ @media (max-width: 480px) {
504
+ .auth-card { margin: 0.5rem; padding: 1.5rem 1rem; }
505
+ .auth-logo { font-size: 2rem; }
506
+ .nav-links { gap: 0.25rem; }
507
+ .nav-link { padding: 6px 10px; font-size: 0.8rem; }
508
+ }
509
+
510
+ /* ── 뱃지 ── */
511
+ .badge {
512
+ display: inline-block;
513
+ padding: 2px 8px;
514
+ border-radius: 12px;
515
+ font-size: 0.7rem;
516
+ font-weight: 600;
517
+ vertical-align: middle;
518
+ }
519
+ .badge-processing {
520
+ background: rgba(241, 196, 15, 0.2);
521
+ color: #f1c40f;
522
+ animation: pulse-badge 2s infinite;
523
+ }
524
+ @keyframes pulse-badge {
525
+ 0%, 100% { opacity: 1; }
526
+ 50% { opacity: 0.5; }
527
+ }
528
+
529
+ /* ── 업로드 진행률 ── */
530
+ .upload-progress {
531
+ margin: 1rem 0;
532
+ }
533
+ .progress-bar-track {
534
+ background: rgba(255,255,255,0.1);
535
+ border-radius: 8px;
536
+ height: 12px;
537
+ overflow: hidden;
538
+ }
539
+ .progress-bar-fill {
540
+ height: 100%;
541
+ width: 0;
542
+ background: linear-gradient(90deg, #667eea, #764ba2);
543
+ border-radius: 8px;
544
+ transition: width 0.3s ease;
545
+ }
546
+ .progress-info {
547
+ display: flex;
548
+ justify-content: space-between;
549
+ margin-top: 4px;
550
+ font-size: 0.8rem;
551
+ color: var(--text-secondary, #aaa);
552
+ }
553
+
554
+ /* ── 인라인 비디오 ── */
555
+ .inline-video {
556
+ margin: 1.5rem 0;
557
+ }
558
+ .inline-video video {
559
+ background: #000;
560
+ }
561
+ .inline-video-name {
562
+ font-size: 0.85rem;
563
+ color: var(--text-secondary, #aaa);
564
+ margin-top: 0.5rem;
565
+ }
566
+
567
+ /* ── 대시보드 ── */
568
+ .dashboard-card { padding: 2rem; }
569
+ .dashboard-section {
570
+ margin-top: 2.5rem;
571
+ }
572
+ .dashboard-section h2 {
573
+ font-size: 1.3rem;
574
+ margin-bottom: 1rem;
575
+ color: var(--text-primary, #e0e0e0);
576
+ }
577
+ .stat-info {
578
+ display: flex;
579
+ flex-direction: column;
580
+ }
581
+ .feature-grid {
582
+ display: grid;
583
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
584
+ gap: 1rem;
585
+ }
586
+ .feature-card {
587
+ background: var(--glass-bg, rgba(255,255,255,0.05));
588
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
589
+ border-radius: 12px;
590
+ padding: 1.25rem;
591
+ transition: transform 0.2s, box-shadow 0.2s;
592
+ }
593
+ .feature-card:hover {
594
+ transform: translateY(-2px);
595
+ box-shadow: 0 8px 24px rgba(0,0,0,0.3);
596
+ }
597
+ .feature-card h3 {
598
+ font-size: 1rem;
599
+ margin-bottom: 0.5rem;
600
+ color: var(--text-primary, #e0e0e0);
601
+ }
602
+ .feature-card p {
603
+ font-size: 0.85rem;
604
+ color: var(--text-secondary, rgba(255,255,255,0.5));
605
+ line-height: 1.5;
606
+ }
607
+ .code-example {
608
+ background: rgba(0,0,0,0.4);
609
+ border: 1px solid rgba(255,255,255,0.08);
610
+ border-radius: 8px;
611
+ padding: 0.75rem 1rem;
612
+ margin-top: 0.75rem;
613
+ font-family: 'Fira Code', 'Consolas', monospace;
614
+ font-size: 0.8rem;
615
+ color: #a0cfff;
616
+ white-space: pre-wrap;
617
+ overflow-x: auto;
618
+ }
619
+ .badge-rust { background: rgba(222,110,75,0.2); color: #de6e4b; }
620
+ .badge-node { background: rgba(104,159,56,0.2); color: #68a038; }
621
+
622
+ /* ── 게시판 목록 ── */
623
+ .post-list {
624
+ display: flex;
625
+ flex-direction: column;
626
+ gap: 0.75rem;
627
+ }
628
+ .post-list-empty {
629
+ text-align: center;
630
+ padding: 3rem 1rem;
631
+ color: var(--text-muted, rgba(255,255,255,0.3));
632
+ }
633
+ .post-card {
634
+ display: flex;
635
+ gap: 1rem;
636
+ padding: 1rem 1.25rem;
637
+ background: var(--glass-bg, rgba(255,255,255,0.05));
638
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
639
+ border-radius: 12px;
640
+ text-decoration: none;
641
+ color: inherit;
642
+ transition: transform 0.15s, background 0.15s;
643
+ }
644
+ .post-card:hover {
645
+ transform: translateX(4px);
646
+ background: rgba(255,255,255,0.08);
647
+ }
648
+ .post-card-thumb {
649
+ width: 80px;
650
+ height: 60px;
651
+ border-radius: 8px;
652
+ overflow: hidden;
653
+ flex-shrink: 0;
654
+ background: rgba(0,0,0,0.3);
655
+ }
656
+ .post-card-thumb img {
657
+ width: 100%;
658
+ height: 100%;
659
+ object-fit: cover;
660
+ }
661
+ .post-card-body {
662
+ flex: 1;
663
+ min-width: 0;
664
+ }
665
+ .post-card-title {
666
+ font-weight: 600;
667
+ font-size: 1rem;
668
+ color: var(--text-primary, #e0e0e0);
669
+ white-space: nowrap;
670
+ overflow: hidden;
671
+ text-overflow: ellipsis;
672
+ }
673
+ .post-card-meta {
674
+ font-size: 0.8rem;
675
+ color: var(--text-muted, rgba(255,255,255,0.3));
676
+ margin-top: 4px;
677
+ }
678
+
679
+ /* ── 첨부파일 그리드 (보기 페이지) ── */
680
+ .post-attachments {
681
+ margin-top: 2rem;
682
+ padding-top: 1.5rem;
683
+ border-top: 1px solid var(--glass-border, rgba(255,255,255,0.1));
684
+ }
685
+ .post-attachments h3 {
686
+ margin-bottom: 1rem;
687
+ font-size: 1rem;
688
+ }
689
+ .attachment-grid {
690
+ display: grid;
691
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
692
+ gap: 0.75rem;
693
+ }
694
+ .attachment-card {
695
+ background: var(--glass-bg, rgba(255,255,255,0.05));
696
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
697
+ border-radius: 10px;
698
+ overflow: hidden;
699
+ transition: transform 0.15s;
700
+ }
701
+ .attachment-card:hover { transform: translateY(-2px); }
702
+ .attachment-card a {
703
+ text-decoration: none;
704
+ color: inherit;
705
+ display: block;
706
+ }
707
+ .attachment-thumb {
708
+ width: 100%;
709
+ height: 100px;
710
+ overflow: hidden;
711
+ background: rgba(0,0,0,0.3);
712
+ display: flex;
713
+ align-items: center;
714
+ justify-content: center;
715
+ position: relative;
716
+ }
717
+ .attachment-thumb img {
718
+ width: 100%;
719
+ height: 100%;
720
+ object-fit: cover;
721
+ }
722
+ .attachment-info {
723
+ padding: 0.5rem 0.6rem;
724
+ }
725
+ .attachment-name {
726
+ font-size: 0.75rem;
727
+ color: var(--text-secondary, rgba(255,255,255,0.5));
728
+ display: block;
729
+ overflow: hidden;
730
+ text-overflow: ellipsis;
731
+ white-space: nowrap;
732
+ }
733
+ .attachment-download {
734
+ text-decoration: none;
735
+ color: inherit;
736
+ display: block;
737
+ }
738
+ .thumb-placeholder {
739
+ font-size: 2rem;
740
+ opacity: 0.5;
741
+ }
742
+ .play-overlay {
743
+ position: absolute;
744
+ top: 50%;
745
+ left: 50%;
746
+ transform: translate(-50%, -50%);
747
+ font-size: 2rem;
748
+ background: rgba(0,0,0,0.5);
749
+ border-radius: 50%;
750
+ width: 40px;
751
+ height: 40px;
752
+ display: flex;
753
+ align-items: center;
754
+ justify-content: center;
755
+ color: #fff;
756
+ pointer-events: none;
757
+ }
758
+
759
+ /* ── 에디터 툴바 ── */
760
+ .editor-toolbar {
761
+ display: flex;
762
+ gap: 4px;
763
+ padding: 6px 8px;
764
+ background: rgba(0,0,0,0.3);
765
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
766
+ border-bottom: none;
767
+ border-radius: 8px 8px 0 0;
768
+ }
769
+ .editor-toolbar button {
770
+ background: transparent;
771
+ border: 1px solid transparent;
772
+ color: var(--text-secondary, rgba(255,255,255,0.5));
773
+ border-radius: 4px;
774
+ padding: 4px 8px;
775
+ cursor: pointer;
776
+ font-size: 0.85rem;
777
+ transition: background 0.15s, color 0.15s;
778
+ }
779
+ .editor-toolbar button:hover {
780
+ background: rgba(255,255,255,0.1);
781
+ color: var(--text-primary, #e0e0e0);
782
+ }
783
+ .editor-toolbar .separator {
784
+ width: 1px;
785
+ background: var(--glass-border, rgba(255,255,255,0.1));
786
+ margin: 2px 4px;
787
+ }
788
+ textarea.has-toolbar {
789
+ border-radius: 0 0 8px 8px;
790
+ }
791
+
792
+ /* ── 파일 업로드 영역 ── */
793
+ .file-upload-area {
794
+ border: 2px dashed var(--glass-border, rgba(255,255,255,0.15));
795
+ border-radius: 12px;
796
+ padding: 2rem;
797
+ text-align: center;
798
+ cursor: pointer;
799
+ transition: border-color 0.2s, background 0.2s;
800
+ }
801
+ .file-upload-area:hover,
802
+ .file-upload-area.dragover {
803
+ border-color: var(--accent-solid, #667eea);
804
+ background: rgba(102,126,234,0.05);
805
+ }
806
+ .upload-icon { font-size: 2rem; margin-bottom: 0.5rem; }
807
+ .upload-text {
808
+ font-size: 0.9rem;
809
+ color: var(--text-primary, #e0e0e0);
810
+ margin-bottom: 0.25rem;
811
+ }
812
+ .upload-hint {
813
+ font-size: 0.75rem;
814
+ color: var(--text-muted, rgba(255,255,255,0.3));
815
+ }
816
+ .file-list {
817
+ margin-top: 0.75rem;
818
+ display: flex;
819
+ flex-direction: column;
820
+ gap: 0.5rem;
821
+ }
822
+ .file-item {
823
+ display: flex;
824
+ align-items: center;
825
+ gap: 0.75rem;
826
+ padding: 0.5rem 0.75rem;
827
+ background: var(--glass-bg, rgba(255,255,255,0.05));
828
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
829
+ border-radius: 8px;
830
+ }
831
+ .file-preview {
832
+ width: 40px;
833
+ height: 40px;
834
+ object-fit: cover;
835
+ border-radius: 6px;
836
+ }
837
+ .file-preview-icon {
838
+ font-size: 1.5rem;
839
+ width: 40px;
840
+ text-align: center;
841
+ }
842
+ .file-name {
843
+ flex: 1;
844
+ font-size: 0.85rem;
845
+ overflow: hidden;
846
+ text-overflow: ellipsis;
847
+ white-space: nowrap;
848
+ }
849
+ .file-size {
850
+ font-size: 0.75rem;
851
+ color: var(--text-muted, rgba(255,255,255,0.3));
852
+ }
853
+ .file-remove {
854
+ background: transparent;
855
+ border: none;
856
+ color: var(--text-muted, rgba(255,255,255,0.3));
857
+ cursor: pointer;
858
+ font-size: 1rem;
859
+ padding: 2px 6px;
860
+ border-radius: 4px;
861
+ transition: color 0.15s;
862
+ }
863
+ .file-remove:hover { color: #e74c3c; }
864
+
865
+ /* ── 기존 첨부파일 그리드 (수정 폼) ── */
866
+ .existing-files-grid {
867
+ display: grid;
868
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
869
+ gap: 0.75rem;
870
+ }
871
+ .existing-file-card {
872
+ background: var(--glass-bg, rgba(255,255,255,0.05));
873
+ border: 1px solid var(--glass-border, rgba(255,255,255,0.1));
874
+ border-radius: 10px;
875
+ overflow: hidden;
876
+ }
877
+ .existing-file-thumb {
878
+ width: 100%;
879
+ height: 80px;
880
+ overflow: hidden;
881
+ background: rgba(0,0,0,0.3);
882
+ display: flex;
883
+ align-items: center;
884
+ justify-content: center;
885
+ }
886
+ .existing-file-thumb img {
887
+ width: 100%;
888
+ height: 100%;
889
+ object-fit: cover;
890
+ }
891
+ .existing-file-info {
892
+ display: flex;
893
+ align-items: center;
894
+ justify-content: space-between;
895
+ padding: 0.4rem 0.5rem;
896
+ }
897
+
898
+ /* ── Lightbox 모달 ── */
899
+ .lightbox-overlay {
900
+ position: fixed;
901
+ top: 0; left: 0; right: 0; bottom: 0;
902
+ background: rgba(0,0,0,0.85);
903
+ z-index: 9999;
904
+ align-items: center;
905
+ justify-content: center;
906
+ }
907
+ .lightbox-content {
908
+ position: relative;
909
+ max-width: 90vw;
910
+ max-height: 90vh;
911
+ }
912
+ .lightbox-close {
913
+ position: absolute;
914
+ top: -40px;
915
+ right: 0;
916
+ background: transparent;
917
+ border: none;
918
+ color: #fff;
919
+ font-size: 1.5rem;
920
+ cursor: pointer;
921
+ z-index: 10000;
922
+ }
923
+ .lightbox-trigger {
924
+ cursor: pointer;
925
+ }
926
+
927
+ /* ── 에러 페이지 ── */
928
+ .error-message {
929
+ font-size: 1.2rem;
930
+ color: #e74c3c;
931
+ margin-bottom: 1rem;
932
+ }
933
+ .error-detail {
934
+ font-size: 0.9rem;
935
+ color: var(--text-secondary, rgba(255,255,255,0.5));
936
+ margin-bottom: 1rem;
937
+ }
938
+ .error-stack {
939
+ background: rgba(0,0,0,0.4);
940
+ border: 1px solid rgba(255,255,255,0.08);
941
+ border-radius: 8px;
942
+ padding: 1rem;
943
+ font-family: monospace;
944
+ font-size: 0.8rem;
945
+ color: #a0cfff;
946
+ white-space: pre-wrap;
947
+ overflow-x: auto;
948
+ max-height: 400px;
949
+ overflow-y: auto;
950
+ }
951
+ /* ═══════════════════════════════════════════════
952
+ * FuzionX — Landing / Features / Chat Styles
953
+ * ═══════════════════════════════════════════════ */
954
+
955
+ /* ── Hero Section ── */
956
+ .hero-section { position:relative; padding:6rem 0 4rem; text-align:center; overflow:hidden; }
957
+ .hero-container { position:relative; z-index:2; }
958
+ .hero-badge { display:inline-block; padding:6px 18px; border-radius:20px; font-size:.8rem; font-weight:600; background:rgba(102,126,234,.12); border:1px solid rgba(102,126,234,.25); color:#7b93ff; margin-bottom:1.5rem; letter-spacing:.5px; }
959
+ .hero-title { font-size:clamp(2.2rem,5vw,4rem); font-weight:900; line-height:1.1; letter-spacing:-2px; margin-bottom:1.5rem; }
960
+ .gradient-text { background:var(--accent-gradient); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
961
+ .hero-subtitle { font-size:1.1rem; color:var(--text-secondary); max-width:600px; margin:0 auto 2.5rem; line-height:1.7; }
962
+ .hero-actions { display:flex; gap:1rem; justify-content:center; flex-wrap:wrap; }
963
+ .btn-hero-primary { display:inline-flex; align-items:center; gap:8px; padding:14px 32px; background:linear-gradient(135deg,#667eea,#764ba2); color:#fff; border-radius:12px; font-weight:700; font-size:.95rem; text-decoration:none; transition:all .3s; border:none; cursor:pointer; }
964
+ .btn-hero-primary:hover { transform:translateY(-3px); box-shadow:0 12px 30px rgba(102,126,234,.35); }
965
+ .btn-hero-outline { display:inline-flex; align-items:center; gap:8px; padding:14px 32px; background:transparent; border:1px solid var(--glass-border); color:var(--text-primary); border-radius:12px; font-weight:600; font-size:.95rem; text-decoration:none; transition:all .3s; cursor:pointer; }
966
+ .btn-hero-outline:hover { border-color:var(--accent-solid); color:#fff; background:rgba(102,126,234,.08); }
967
+
968
+ /* Hero Code Block */
969
+ .hero-code { max-width:560px; margin:3rem auto 0; text-align:left; border-radius:16px; overflow:hidden; border:1px solid var(--glass-border); background:rgba(0,0,0,.45); backdrop-filter:blur(10px); }
970
+ .code-header { display:flex; align-items:center; gap:8px; padding:12px 16px; background:rgba(0,0,0,.3); border-bottom:1px solid rgba(255,255,255,.06); }
971
+ .code-dot { width:12px; height:12px; border-radius:50%; }
972
+ .code-dot.red { background:#ff5f56; }
973
+ .code-dot.yellow { background:#ffbd2e; }
974
+ .code-dot.green { background:#27c93f; }
975
+ .code-title { font-size:.75rem; color:var(--text-muted); margin-left:auto; font-family:'JetBrains Mono',monospace; }
976
+ .code-body { padding:1.25rem; font-family:'JetBrains Mono','Fira Code',monospace; font-size:.85rem; line-height:1.8; color:#c9d1d9; overflow-x:auto; margin:0; }
977
+ .code-kw { color:#ff7b72; }
978
+ .code-str { color:#a5d6ff; }
979
+ .code-fn { color:#d2a8ff; }
980
+ .code-cmt { color:#8b949e; }
981
+ .code-num { color:#79c0ff; }
982
+
983
+ /* Hero Particles */
984
+ .hero-particles { position:absolute; inset:0; overflow:hidden; pointer-events:none; }
985
+ .particle { position:absolute; border-radius:50%; opacity:.15; animation:particleFloat 12s ease-in-out infinite; }
986
+ .p1 { width:6px; height:6px; background:#667eea; top:20%; left:15%; animation-duration:10s; }
987
+ .p2 { width:4px; height:4px; background:#f093fb; top:60%; left:80%; animation-delay:-3s; }
988
+ .p3 { width:8px; height:8px; background:#764ba2; top:30%; left:65%; animation-delay:-5s; animation-duration:14s; }
989
+ .p4 { width:5px; height:5px; background:#667eea; top:70%; left:25%; animation-delay:-7s; }
990
+ .p5 { width:3px; height:3px; background:#f093fb; top:10%; left:90%; animation-delay:-2s; animation-duration:11s; }
991
+ .p6 { width:7px; height:7px; background:#764ba2; top:85%; left:50%; animation-delay:-4s; }
992
+ @keyframes particleFloat { 0%,100%{transform:translate(0,0) scale(1)} 25%{transform:translate(20px,-30px) scale(1.2)} 50%{transform:translate(-15px,-50px) scale(.8)} 75%{transform:translate(25px,-20px) scale(1.1)} }
993
+
994
+ /* ── Stats Bar ── */
995
+ .stats-bar { padding:2rem 0; border-top:1px solid var(--glass-border); border-bottom:1px solid var(--glass-border); background:rgba(0,0,0,.15); }
996
+ .stats-bar-grid { display:flex; align-items:center; justify-content:center; gap:2rem; flex-wrap:wrap; }
997
+ .stat-bar-item { text-align:center; }
998
+ .stat-bar-number { display:block; font-size:2rem; font-weight:800; background:var(--accent-gradient); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
999
+ .stat-bar-label { font-size:.8rem; color:var(--text-secondary); }
1000
+ .stat-bar-divider { width:1px; height:40px; background:var(--glass-border); }
1001
+
1002
+ /* ── Sections ── */
1003
+ .section { padding:5rem 0; }
1004
+ .section-dark { background:rgba(0,0,0,.12); }
1005
+ .section-header { text-align:center; max-width:700px; margin:0 auto 3rem; }
1006
+ .section-title { font-size:clamp(1.6rem,3.5vw,2.5rem); font-weight:800; letter-spacing:-1px; line-height:1.2; margin-bottom:1rem; }
1007
+ .section-subtitle { font-size:1rem; color:var(--text-secondary); line-height:1.6; }
1008
+
1009
+ /* ── Features Showcase (Landing) ── */
1010
+ .features-showcase { display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); gap:1.25rem; }
1011
+ .feature-showcase-card { background:var(--glass-bg); border:1px solid var(--glass-border); border-radius:16px; padding:2rem; transition:all .3s; position:relative; overflow:hidden; }
1012
+ .feature-showcase-card::before { content:''; position:absolute; top:0; left:0; right:0; height:3px; background:var(--accent-gradient); opacity:0; transition:opacity .3s; }
1013
+ .feature-showcase-card:hover { transform:translateY(-4px); box-shadow:0 16px 40px rgba(0,0,0,.3); border-color:rgba(102,126,234,.25); }
1014
+ .feature-showcase-card:hover::before { opacity:1; }
1015
+ .feature-icon-wrap { width:48px; height:48px; border-radius:12px; background:rgba(102,126,234,.1); display:flex; align-items:center; justify-content:center; margin-bottom:1rem; }
1016
+ .feature-icon { font-size:1.5rem; }
1017
+ .feature-showcase-card h3 { font-size:1.1rem; font-weight:700; margin-bottom:.5rem; }
1018
+ .feature-showcase-card p { font-size:.85rem; color:var(--text-secondary); line-height:1.6; }
1019
+ .feature-tag { display:inline-block; padding:3px 10px; border-radius:10px; font-size:.65rem; font-weight:600; margin-top:.75rem; }
1020
+ .tag-rust { background:rgba(222,110,75,.15); color:#de6e4b; }
1021
+ .tag-node { background:rgba(104,159,56,.15); color:#68a038; }
1022
+ .tag-ws { background:rgba(102,126,234,.15); color:#7b93ff; }
1023
+
1024
+ /* ── Architecture Layers ── */
1025
+ .arch-layers { max-width:600px; margin:0 auto; }
1026
+ .arch-layer { background:var(--glass-bg); border:1px solid var(--glass-border); border-radius:16px; padding:1.5rem 2rem; text-align:center; }
1027
+ .arch-layer h4 { font-size:1.1rem; font-weight:700; margin-bottom:.5rem; }
1028
+ .arch-layer p { font-size:.85rem; color:var(--text-secondary); line-height:1.5; }
1029
+ .arch-layer-badge { display:inline-block; padding:3px 12px; border-radius:10px; font-size:.7rem; font-weight:600; margin-bottom:.75rem; }
1030
+ .arch-layer-top { border-color:rgba(102,126,234,.3); }
1031
+ .arch-layer-top .arch-layer-badge { background:rgba(102,126,234,.15); color:#7b93ff; }
1032
+ .arch-layer-mid { border-color:rgba(118,75,162,.3); }
1033
+ .arch-layer-mid .arch-layer-badge { background:rgba(118,75,162,.15); color:#a87bd4; }
1034
+ .arch-layer-bottom { border-color:rgba(222,110,75,.3); }
1035
+ .arch-layer-bottom .arch-layer-badge { background:rgba(222,110,75,.15); color:#de6e4b; }
1036
+ .arch-connector { text-align:center; padding:4px 0; }
1037
+
1038
+ /* ── Comparison Table ── */
1039
+ .comparison-table-wrap { overflow-x:auto; border-radius:16px; border:1px solid var(--glass-border); }
1040
+ .comparison-table { width:100%; border-collapse:collapse; font-size:.9rem; }
1041
+ .comparison-table th { padding:14px 20px; text-align:left; font-size:.8rem; text-transform:uppercase; letter-spacing:.5px; color:var(--text-secondary); border-bottom:1px solid var(--glass-border); background:rgba(0,0,0,.2); }
1042
+ .comparison-table td { padding:12px 20px; border-bottom:1px solid rgba(255,255,255,.04); }
1043
+ .comparison-table tr:hover td { background:rgba(255,255,255,.02); }
1044
+ .highlight-col { background:rgba(102,126,234,.06) !important; }
1045
+ .comparison-table th.highlight-col { color:#7b93ff; }
1046
+ .check { color:#2ecc71; font-weight:700; }
1047
+ .cross { color:var(--text-muted); }
1048
+
1049
+ /* ── CTA Section ── */
1050
+ .cta-section { padding:4rem 0; }
1051
+ .cta-card { text-align:center; padding:3rem 2rem !important; }
1052
+ .cta-title { font-size:clamp(1.5rem,3vw,2.2rem); font-weight:800; letter-spacing:-1px; margin-bottom:.75rem; }
1053
+ .cta-subtitle { color:var(--text-secondary); margin-bottom:1.5rem; }
1054
+ .cta-install { display:inline-block; padding:12px 28px; background:rgba(0,0,0,.4); border:1px solid rgba(255,255,255,.1); border-radius:12px; font-family:'JetBrains Mono',monospace; font-size:.9rem; color:#a5d6ff; }
1055
+
1056
+ /* ── Footer ── */
1057
+ .site-footer { padding:2rem 0; border-top:1px solid var(--glass-border); }
1058
+ .footer-content { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:1rem; }
1059
+ .footer-brand { font-weight:800; background:var(--accent-gradient); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
1060
+ .footer-text { font-size:.85rem; color:var(--text-muted); }
1061
+
1062
+ /* ── Nav CTA + Mobile ── */
1063
+ .nav-link-cta { background:linear-gradient(135deg,#667eea,#764ba2) !important; color:#fff !important; border-radius:8px !important; padding:8px 20px !important; font-weight:600 !important; }
1064
+ .nav-link-cta:hover { box-shadow:0 4px 15px rgba(102,126,234,.3); }
1065
+ .nav-mobile-toggle { display:none; background:none; border:none; cursor:pointer; padding:8px; }
1066
+ .nav-mobile-toggle span { display:block; width:20px; height:2px; background:var(--text-primary); margin:4px 0; border-radius:2px; transition:all .3s; }
1067
+
1068
+ /* ── Locale Switcher ── */
1069
+ .nav-locale { display:flex; align-items:center; margin-left:.25rem; }
1070
+ .nav-locale-btn { display:inline-flex; align-items:center; justify-content:center; width:34px; height:28px; border-radius:6px; font-size:.75rem; font-weight:700; color:var(--text-secondary); border:1px solid var(--glass-border); text-decoration:none; transition:all .3s; letter-spacing:.5px; }
1071
+ .nav-locale-btn:hover { color:#fff; border-color:var(--accent-solid); background:rgba(102,126,234,.12); }
1072
+
1073
+ /* ── Features Detail (Features Page) ── */
1074
+ .feat-detail { max-width:900px; margin:0 auto; }
1075
+ .feat-detail-header { display:flex; align-items:flex-start; gap:1.25rem; margin-bottom:2rem; }
1076
+ .feat-detail-icon { font-size:2.5rem; flex-shrink:0; }
1077
+ .feat-detail-title { font-size:1.7rem; font-weight:800; letter-spacing:-.5px; margin-bottom:.4rem; }
1078
+ .feat-detail-sub { color:var(--text-secondary); font-size:.95rem; }
1079
+ .feat-detail-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:1rem; margin-bottom:2rem; }
1080
+ .feat-detail-grid-3 { grid-template-columns:repeat(3,1fr); }
1081
+ .feat-detail-card { background:rgba(255,255,255,.03); border:1px solid var(--glass-border); border-radius:12px; padding:1.25rem; transition:all .2s; }
1082
+ .feat-detail-card:hover { background:rgba(255,255,255,.06); transform:translateY(-2px); }
1083
+ .feat-detail-card h4 { font-size:.95rem; font-weight:700; margin-bottom:.4rem; }
1084
+ .feat-detail-card p { font-size:.82rem; color:var(--text-secondary); line-height:1.55; }
1085
+ .feat-detail-card code { background:rgba(102,126,234,.12); padding:1px 6px; border-radius:4px; font-size:.78rem; color:#a5d6ff; font-family:'JetBrains Mono',monospace; }
1086
+ .feat-code-block { border-radius:16px; overflow:hidden; border:1px solid var(--glass-border); background:rgba(0,0,0,.4); }
1087
+
1088
+ /* ── Chat Page ── */
1089
+ .chat-join-screen { min-height:60vh; display:flex; align-items:center; justify-content:center; }
1090
+ .chat-join-card { max-width:460px; width:100%; text-align:center; padding:3rem 2rem !important; }
1091
+ .chat-join-icon { font-size:3rem; margin-bottom:1rem; }
1092
+ .chat-join-title { font-size:1.8rem; font-weight:800; letter-spacing:-1px; margin-bottom:.75rem; }
1093
+ .chat-join-sub { font-size:.9rem; color:var(--text-secondary); line-height:1.6; }
1094
+ .chat-join-sub code { background:rgba(102,126,234,.12); padding:1px 6px; border-radius:4px; font-size:.8rem; color:#a5d6ff; }
1095
+ .chat-join-tech { display:flex; gap:.5rem; justify-content:center; margin-top:1.5rem; }
1096
+ .chat-nickname-input { width:100%; padding:14px 18px; background:rgba(255,255,255,.08); border:1px solid var(--glass-border); border-radius:12px; color:var(--text-primary); font-family:var(--font); font-size:1rem; outline:none; transition:all .3s; text-align:center; }
1097
+ .chat-nickname-input:focus { border-color:var(--accent-solid); box-shadow:0 0 0 3px rgba(102,126,234,.15); }
1098
+
1099
+ /* Chat Layout */
1100
+ .chat-room { padding-bottom:2rem; }
1101
+ .chat-layout { display:grid; grid-template-columns:240px 1fr; gap:1rem; min-height:70vh; }
1102
+ .chat-sidebar { display:flex; flex-direction:column; padding:0 !important; overflow:hidden; }
1103
+ .chat-sidebar-header { padding:1.25rem 1.25rem .75rem; border-bottom:1px solid var(--glass-border); }
1104
+ .chat-sidebar-header h3 { font-size:.95rem; font-weight:700; }
1105
+ .chat-user-count { background:rgba(102,126,234,.15); color:#7b93ff; padding:2px 8px; border-radius:10px; font-size:.75rem; margin-left:.5rem; }
1106
+ .chat-user-list { list-style:none; flex:1; overflow-y:auto; padding:.75rem; }
1107
+ .chat-user-item { display:flex; align-items:center; gap:.5rem; padding:8px 10px; border-radius:8px; font-size:.85rem; margin-bottom:2px; transition:background .15s; }
1108
+ .chat-user-item:hover { background:rgba(255,255,255,.05); }
1109
+ .chat-user-item.is-me { background:rgba(102,126,234,.08); }
1110
+ .chat-user-dot { width:8px; height:8px; border-radius:50%; background:#2ecc71; flex-shrink:0; }
1111
+ .chat-user-name { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
1112
+ .chat-user-me { font-size:.65rem; color:var(--accent-solid); padding:1px 6px; border-radius:6px; background:rgba(102,126,234,.1); }
1113
+ .chat-sidebar-footer { padding:.75rem 1rem; border-top:1px solid var(--glass-border); }
1114
+
1115
+ /* Chat Main */
1116
+ .chat-main { display:flex; flex-direction:column; padding:0 !important; overflow:hidden; }
1117
+ .chat-messages-header { display:flex; align-items:center; justify-content:space-between; padding:1.25rem 1.5rem; border-bottom:1px solid var(--glass-border); }
1118
+ .chat-messages-header h3 { font-size:.95rem; font-weight:700; }
1119
+ .chat-status { font-size:.75rem; padding:3px 10px; border-radius:10px; font-weight:500; }
1120
+ .chat-status-connecting { background:rgba(241,196,15,.12); color:#f1c40f; }
1121
+ .chat-status-connected { background:rgba(46,204,113,.12); color:#2ecc71; }
1122
+ .chat-status-disconnected { background:rgba(231,76,60,.12); color:#e74c3c; }
1123
+ .chat-status-error { background:rgba(231,76,60,.12); color:#e74c3c; }
1124
+ .chat-messages { flex:1; overflow-y:auto; padding:1rem 1.5rem; display:flex; flex-direction:column; gap:.5rem; }
1125
+ .chat-msg { display:flex; }
1126
+ .chat-msg-me { justify-content:flex-end; }
1127
+ .chat-msg-other { justify-content:flex-start; }
1128
+ .chat-msg-bubble { max-width:70%; padding:10px 14px; border-radius:14px; font-size:.88rem; line-height:1.5; position:relative; }
1129
+ .chat-msg-me .chat-msg-bubble { background:linear-gradient(135deg,rgba(102,126,234,.25),rgba(118,75,162,.25)); border:1px solid rgba(102,126,234,.2); border-bottom-right-radius:4px; }
1130
+ .chat-msg-other .chat-msg-bubble { background:rgba(255,255,255,.06); border:1px solid var(--glass-border); border-bottom-left-radius:4px; }
1131
+ .chat-msg-sender { display:block; font-size:.75rem; font-weight:600; color:#7b93ff; margin-bottom:3px; }
1132
+ .chat-msg-text { word-break:break-word; }
1133
+ .chat-msg-time { display:block; font-size:.65rem; color:var(--text-muted); margin-top:4px; text-align:right; }
1134
+ .chat-msg-system { text-align:center; font-size:.78rem; color:var(--text-muted); padding:6px 0; font-style:italic; }
1135
+ .chat-typing { padding:4px 1.5rem; font-size:.78rem; color:var(--text-muted); font-style:italic; }
1136
+ .chat-input-form { display:flex; gap:.5rem; padding:1rem 1.5rem; border-top:1px solid var(--glass-border); }
1137
+ .chat-message-input { flex:1; padding:12px 16px; background:rgba(255,255,255,.08); border:1px solid var(--glass-border); border-radius:12px; color:var(--text-primary); font-family:var(--font); font-size:.9rem; outline:none; transition:all .3s; }
1138
+ .chat-message-input:focus { border-color:var(--accent-solid); }
1139
+ .chat-send-btn { padding:12px 24px; border-radius:12px; }
1140
+
1141
+ /* ── Responsive ── */
1142
+ @media(max-width:900px) {
1143
+ .feat-detail-grid { grid-template-columns:1fr; }
1144
+ .feat-detail-grid-3 { grid-template-columns:1fr; }
1145
+ .chat-layout { grid-template-columns:1fr; }
1146
+ .chat-sidebar { max-height:200px; }
1147
+ }
1148
+ @media(max-width:768px) {
1149
+ .hero-title { font-size:2rem; }
1150
+ .stats-bar-grid { gap:1rem; }
1151
+ .stat-bar-divider { display:none; }
1152
+ .features-showcase { grid-template-columns:1fr; }
1153
+ .nav-mobile-toggle { display:block; }
1154
+ .nav-links { display:none; position:absolute; top:var(--nav-height); left:0; right:0; flex-direction:column; background:rgba(15,12,41,.95); backdrop-filter:blur(20px); padding:1rem; border-bottom:1px solid var(--glass-border); }
1155
+ .nav-links.open { display:flex; }
1156
+ }