neoagent 1.6.0 → 2.0.0

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 (62) hide show
  1. package/README.md +18 -4
  2. package/docs/configuration.md +2 -2
  3. package/docs/skills.md +1 -1
  4. package/lib/manager.js +64 -2
  5. package/package.json +9 -2
  6. package/server/config/origins.js +34 -0
  7. package/server/db/database.js +0 -13
  8. package/server/http/errors.js +17 -0
  9. package/server/http/middleware.js +81 -0
  10. package/server/http/routes.js +45 -0
  11. package/server/http/socket.js +23 -0
  12. package/server/http/static.js +50 -0
  13. package/server/index.js +50 -188
  14. package/server/public/.last_build_id +1 -0
  15. package/server/public/assets/AssetManifest.bin +1 -0
  16. package/server/public/assets/AssetManifest.bin.json +1 -0
  17. package/server/public/assets/AssetManifest.json +1 -0
  18. package/server/public/assets/FontManifest.json +1 -0
  19. package/server/public/assets/NOTICES +33454 -0
  20. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  21. package/server/public/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf +0 -0
  22. package/server/public/assets/shaders/ink_sparkle.frag +126 -0
  23. package/server/public/assets/web/icons/Icon-192.png +0 -0
  24. package/server/public/canvaskit/canvaskit.js +192 -0
  25. package/server/public/canvaskit/canvaskit.js.symbols +12142 -0
  26. package/server/public/canvaskit/canvaskit.wasm +0 -0
  27. package/server/public/canvaskit/chromium/canvaskit.js +192 -0
  28. package/server/public/canvaskit/chromium/canvaskit.js.symbols +11106 -0
  29. package/server/public/canvaskit/chromium/canvaskit.wasm +0 -0
  30. package/server/public/canvaskit/skwasm.js +140 -0
  31. package/server/public/canvaskit/skwasm.js.symbols +12164 -0
  32. package/server/public/canvaskit/skwasm.wasm +0 -0
  33. package/server/public/canvaskit/skwasm_heavy.js +140 -0
  34. package/server/public/canvaskit/skwasm_heavy.js.symbols +13766 -0
  35. package/server/public/canvaskit/skwasm_heavy.wasm +0 -0
  36. package/server/public/favicon.png +0 -0
  37. package/server/public/flutter.js +32 -0
  38. package/server/public/flutter_bootstrap.js +43 -0
  39. package/server/public/flutter_service_worker.js +208 -0
  40. package/server/public/icons/Icon-192.png +0 -0
  41. package/server/public/icons/Icon-512.png +0 -0
  42. package/server/public/icons/Icon-maskable-192.png +0 -0
  43. package/server/public/icons/Icon-maskable-512.png +0 -0
  44. package/server/public/index.html +38 -0
  45. package/server/public/main.dart.js +103124 -0
  46. package/server/public/manifest.json +35 -0
  47. package/server/public/version.json +1 -0
  48. package/server/services/ai/models.js +2 -8
  49. package/server/services/ai/tools.js +0 -47
  50. package/server/services/browser/controller.js +34 -0
  51. package/server/services/manager.js +49 -118
  52. package/server/services/messaging/automation.js +210 -0
  53. package/server/utils/version.js +37 -0
  54. package/server/public/app.html +0 -682
  55. package/server/public/assets/world-office-dark.png +0 -0
  56. package/server/public/assets/world-office-light.png +0 -0
  57. package/server/public/css/app.css +0 -941
  58. package/server/public/css/styles.css +0 -963
  59. package/server/public/favicon.svg +0 -17
  60. package/server/public/js/app.js +0 -4105
  61. package/server/public/login.html +0 -313
  62. package/server/routes/protocols.js +0 -87
@@ -1,963 +0,0 @@
1
- /* ══════════════════════════════════════════
2
- NeoAgent · Design System · v2
3
- ══════════════════════════════════════════ */
4
-
5
- @import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&display=swap');
6
-
7
- /* ── design tokens ── */
8
- :root {
9
- /* backgrounds */
10
- --bg-0: #07070f;
11
- --bg-1: #0c0c18;
12
- --bg-2: #111120;
13
- --bg-3: #181828;
14
- --bg-4: #1e1e32;
15
- --bg-5: #262640;
16
-
17
- /* contextual aliases */
18
- --bg-primary: var(--bg-0);
19
- --bg-secondary: var(--bg-1);
20
- --bg-tertiary: var(--bg-2);
21
- --bg-card: var(--bg-3);
22
- --bg-hover: var(--bg-5);
23
- --bg-input: var(--bg-1);
24
- --bg-modal: rgba(14, 14, 26, .96);
25
- --bg-toast: rgba(18, 18, 32, .92);
26
- --bg-logs: rgba(5, 10, 18, .8);
27
-
28
- /* borders */
29
- --border: rgba(255, 255, 255, .07);
30
- --border-light: rgba(255, 255, 255, .13);
31
-
32
- /* text */
33
- --text-primary: #eaeaf4;
34
- --text-secondary: #8080a8;
35
- --text-muted: #4d4d6a;
36
-
37
- /* accent */
38
- --accent: #6366f1;
39
- --accent-hover: #818cf8;
40
- --accent-dim: rgba(99, 102, 241, .12);
41
- --accent-glow: rgba(99, 102, 241, .28);
42
- --accent-muted: rgba(99, 102, 241, .15);
43
-
44
- /* semantic */
45
- --success: #22c55e;
46
- --warning: #f59e0b;
47
- --error: #ef4444;
48
- --info: #3b82f6;
49
-
50
- /* layout */
51
- --sidebar-width: 220px;
52
- --header-height: 56px;
53
-
54
- /* shape */
55
- --radius: 8px;
56
- --radius-lg: 14px;
57
- --radius-xl: 20px;
58
-
59
- /* shadow */
60
- --shadow-sm: 0 2px 8px rgba(0, 0, 0, .35);
61
- --shadow: 0 8px 32px rgba(0, 0, 0, .5);
62
- --shadow-lg: 0 20px 60px rgba(0, 0, 0, .6);
63
-
64
- /* motion */
65
- --ease-out: cubic-bezier(.16, 1, .3, 1);
66
- --ease-in: cubic-bezier(.7, 0, .84, 0);
67
- --t-fast: 100ms;
68
- --t-mid: 200ms;
69
- --t-slow: 360ms;
70
- --transition: var(--t-mid) var(--ease-out);
71
-
72
- color-scheme: dark;
73
- }
74
-
75
- [data-theme="light"] {
76
- /* backgrounds */
77
- --bg-0: #f5f5fa;
78
- --bg-1: #eeeef6;
79
- --bg-2: #e5e5f0;
80
- --bg-3: #dcdcec;
81
- --bg-4: #d0d0e0;
82
- --bg-5: #c8c8da;
83
-
84
- --bg-primary: var(--bg-0);
85
- --bg-secondary: var(--bg-1);
86
- --bg-tertiary: var(--bg-2);
87
- --bg-card: var(--bg-3);
88
- --bg-hover: var(--bg-5);
89
- --bg-input: var(--bg-1);
90
- --bg-modal: rgba(240, 240, 250, .97);
91
- --bg-toast: rgba(235, 235, 248, .95);
92
- --bg-logs: rgba(228, 228, 240, .9);
93
-
94
- /* borders */
95
- --border: rgba(0, 0, 0, .08);
96
- --border-light: rgba(0, 0, 0, .15);
97
-
98
- /* text */
99
- --text-primary: #1a1a2e;
100
- --text-secondary: #4a4a6a;
101
- --text-muted: #8080a0;
102
-
103
- /* accent — same hue, keep brand consistent */
104
- --accent: #5254cc;
105
- --accent-hover: #6366f1;
106
- --accent-dim: rgba(82, 84, 204, .12);
107
- --accent-glow: rgba(82, 84, 204, .22);
108
- --accent-muted: rgba(82, 84, 204, .12);
109
-
110
- /* shadow — lighter for light mode */
111
- --shadow-sm: 0 2px 8px rgba(0, 0, 0, .08);
112
- --shadow: 0 8px 32px rgba(0, 0, 0, .12);
113
- --shadow-lg: 0 20px 60px rgba(0, 0, 0, .18);
114
-
115
- color-scheme: light;
116
- }
117
-
118
- *,
119
- *::before,
120
- *::after {
121
- margin: 0;
122
- padding: 0;
123
- box-sizing: border-box;
124
- }
125
-
126
- html,
127
- body {
128
- height: 100%;
129
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
130
- background: var(--bg-0);
131
- color: var(--text-primary);
132
- font-size: 14px;
133
- line-height: 1.5;
134
- -webkit-font-smoothing: antialiased;
135
- -moz-osx-font-smoothing: grayscale;
136
- }
137
-
138
- a {
139
- color: var(--accent);
140
- text-decoration: none;
141
- }
142
-
143
- a:hover {
144
- color: var(--accent-hover);
145
- }
146
-
147
- button,
148
- input,
149
- textarea,
150
- select {
151
- font-family: inherit;
152
- font-size: inherit;
153
- color: inherit;
154
- }
155
-
156
- ::selection {
157
- background: var(--accent);
158
- color: white;
159
- }
160
-
161
- ::-webkit-scrollbar {
162
- width: 4px;
163
- height: 4px;
164
- }
165
-
166
- ::-webkit-scrollbar-track {
167
- background: transparent;
168
- }
169
-
170
- ::-webkit-scrollbar-thumb {
171
- background: rgba(255, 255, 255, .1);
172
- border-radius: 99px;
173
- }
174
-
175
- ::-webkit-scrollbar-thumb:hover {
176
- background: rgba(255, 255, 255, .2);
177
- }
178
-
179
- /* ── Buttons ── */
180
-
181
- .btn {
182
- display: inline-flex;
183
- align-items: center;
184
- gap: 7px;
185
- padding: 8px 16px;
186
- border-radius: var(--radius);
187
- border: 1px solid transparent;
188
- cursor: pointer;
189
- font-weight: 500;
190
- transition: background var(--t-fast, 100ms), border-color var(--t-fast, 100ms), transform var(--t-fast, 100ms), box-shadow var(--t-fast, 100ms);
191
- white-space: nowrap;
192
- font-size: 13px;
193
- user-select: none;
194
- position: relative;
195
- }
196
-
197
- .btn:active {
198
- transform: scale(.96);
199
- }
200
-
201
- .btn-primary {
202
- background: var(--accent);
203
- color: white;
204
- border-color: var(--accent);
205
- box-shadow: 0 2px 10px rgba(99, 102, 241, .3);
206
- }
207
-
208
- .btn-primary:hover {
209
- background: var(--accent-hover);
210
- border-color: var(--accent-hover);
211
- box-shadow: 0 4px 18px rgba(99, 102, 241, .45);
212
- }
213
-
214
- .btn-secondary {
215
- background: rgba(255, 255, 255, .04);
216
- color: var(--text-primary);
217
- border-color: var(--border);
218
- }
219
-
220
- .btn-secondary:hover {
221
- background: rgba(255, 255, 255, .08);
222
- border-color: var(--border-light);
223
- }
224
-
225
- .btn-danger {
226
- background: transparent;
227
- color: var(--error);
228
- border-color: var(--error);
229
- }
230
-
231
- .btn-danger:hover {
232
- background: rgba(239, 68, 68, 0.1);
233
- }
234
-
235
- .btn-ghost {
236
- background: transparent;
237
- color: var(--text-secondary);
238
- border: none;
239
- padding: 6px 10px;
240
- }
241
-
242
- .btn-ghost:hover {
243
- color: var(--text-primary);
244
- background: rgba(255, 255, 255, .06);
245
- }
246
-
247
- .btn-sm {
248
- padding: 4px 10px;
249
- font-size: 12px;
250
- }
251
-
252
- .btn-lg {
253
- padding: 12px 24px;
254
- font-size: 15px;
255
- }
256
-
257
- .btn:disabled {
258
- opacity: 0.5;
259
- cursor: not-allowed;
260
- }
261
-
262
- /* ── Inputs ── */
263
-
264
- .input,
265
- .textarea,
266
- .select {
267
- width: 100%;
268
- padding: 9px 13px;
269
- background: var(--bg-input);
270
- border: 1px solid var(--border);
271
- border-radius: var(--radius);
272
- color: var(--text-primary);
273
- transition: border-color var(--t-fast, 100ms), box-shadow var(--t-fast, 100ms);
274
- outline: none;
275
- }
276
-
277
- .input:focus,
278
- .textarea:focus,
279
- .select:focus {
280
- border-color: var(--accent);
281
- box-shadow: 0 0 0 3px var(--accent-dim, rgba(99, 102, 241, .12));
282
- }
283
-
284
- .input::placeholder,
285
- .textarea::placeholder {
286
- color: var(--text-muted);
287
- }
288
-
289
- .textarea {
290
- resize: vertical;
291
- min-height: 80px;
292
- }
293
-
294
- .form-group {
295
- margin-bottom: 16px;
296
- }
297
-
298
- .form-label {
299
- display: block;
300
- margin-bottom: 5px;
301
- font-size: 11px;
302
- font-weight: 600;
303
- letter-spacing: .4px;
304
- color: var(--text-secondary);
305
- text-transform: uppercase;
306
- }
307
-
308
- .settings-inline-label {
309
- display: flex;
310
- align-items: center;
311
- gap: 8px;
312
- }
313
-
314
- .settings-info-wrap {
315
- position: relative;
316
- display: inline-flex;
317
- align-items: center;
318
- justify-content: center;
319
- width: 15px;
320
- height: 15px;
321
- border-radius: 999px;
322
- border: 1px solid var(--border-light);
323
- color: var(--text-secondary);
324
- font-size: 10px;
325
- line-height: 1;
326
- cursor: help;
327
- text-transform: none;
328
- }
329
-
330
- .settings-info-icon {
331
- display: inline-flex;
332
- align-items: center;
333
- justify-content: center;
334
- width: 100%;
335
- height: 100%;
336
- }
337
-
338
- .settings-info-pop {
339
- position: absolute;
340
- top: 20px;
341
- left: 50%;
342
- transform: translateX(-50%);
343
- min-width: 240px;
344
- max-width: 280px;
345
- padding: 8px 10px;
346
- border-radius: 8px;
347
- border: 1px solid var(--border-light);
348
- background: var(--bg-modal);
349
- color: var(--text-primary);
350
- font-size: 11px;
351
- font-weight: 400;
352
- letter-spacing: 0;
353
- text-transform: none;
354
- line-height: 1.4;
355
- white-space: normal;
356
- opacity: 0;
357
- pointer-events: none;
358
- transition: opacity 120ms ease;
359
- z-index: 2;
360
- }
361
-
362
- .settings-info-wrap:hover .settings-info-pop,
363
- .settings-info-wrap:focus .settings-info-pop,
364
- .settings-info-wrap:focus-within .settings-info-pop {
365
- opacity: 1;
366
- }
367
-
368
- .settings-token-box {
369
- border: 1px solid var(--border);
370
- border-radius: 10px;
371
- padding: 10px 12px;
372
- background: rgba(255, 255, 255, .02);
373
- color: var(--text-secondary);
374
- font-size: 12px;
375
- line-height: 1.45;
376
- }
377
-
378
- /* ── Cards ── */
379
-
380
- .card {
381
- background: var(--bg-card);
382
- border: 1px solid var(--border);
383
- border-radius: var(--radius-lg);
384
- padding: 20px;
385
- transition: border-color var(--t-mid, 200ms), box-shadow var(--t-mid, 200ms);
386
- }
387
-
388
- .card:hover {
389
- border-color: var(--border-light);
390
- box-shadow: 0 2px 12px rgba(0, 0, 0, .3);
391
- }
392
-
393
- .card-header {
394
- display: flex;
395
- align-items: center;
396
- justify-content: space-between;
397
- margin-bottom: 16px;
398
- }
399
-
400
- .card-title {
401
- font-size: 16px;
402
- font-weight: 600;
403
- }
404
-
405
- /* ── Badge / Tag ── */
406
-
407
- .badge {
408
- display: inline-flex;
409
- align-items: center;
410
- gap: 4px;
411
- padding: 2px 8px;
412
- border-radius: 100px;
413
- font-size: 11px;
414
- font-weight: 600;
415
- text-transform: uppercase;
416
- letter-spacing: 0.5px;
417
- }
418
-
419
- .badge-success {
420
- background: rgba(34, 197, 94, 0.15);
421
- color: var(--success);
422
- }
423
-
424
- .badge-warning {
425
- background: rgba(245, 158, 11, 0.15);
426
- color: var(--warning);
427
- }
428
-
429
- .badge-error {
430
- background: rgba(239, 68, 68, 0.15);
431
- color: var(--error);
432
- }
433
-
434
- .badge-info {
435
- background: rgba(59, 130, 246, 0.15);
436
- color: var(--info);
437
- }
438
-
439
- .badge-neutral {
440
- background: var(--bg-hover);
441
- color: var(--text-secondary);
442
- }
443
-
444
- /* ── Toast / Notification ── */
445
-
446
- .toast-container {
447
- position: fixed;
448
- top: 20px;
449
- right: 20px;
450
- z-index: 10000;
451
- display: flex;
452
- flex-direction: column;
453
- gap: 8px;
454
- pointer-events: none;
455
- }
456
-
457
- .toast {
458
- padding: 12px 18px;
459
- border-radius: var(--radius-lg);
460
- background: var(--bg-toast);
461
- backdrop-filter: blur(20px) saturate(1.4);
462
- -webkit-backdrop-filter: blur(20px) saturate(1.4);
463
- border: 1px solid var(--border-light);
464
- box-shadow: var(--shadow);
465
- font-size: 13px;
466
- pointer-events: all;
467
- animation: toastIn 200ms var(--ease-out, cubic-bezier(.16, 1, .3, 1)) both;
468
- max-width: 380px;
469
- }
470
-
471
- .toast.removing {
472
- animation: toastOut 120ms ease-in both;
473
- }
474
-
475
- .toast-success {
476
- border-left: 3px solid var(--success);
477
- }
478
-
479
- .toast-error {
480
- border-left: 3px solid var(--error);
481
- }
482
-
483
- .toast-info {
484
- border-left: 3px solid var(--info);
485
- }
486
-
487
- @keyframes toastIn {
488
- from {
489
- transform: translateX(110%) scale(.9);
490
- opacity: 0;
491
- }
492
-
493
- to {
494
- transform: translateX(0) scale(1);
495
- opacity: 1;
496
- }
497
- }
498
-
499
- @keyframes toastOut {
500
- from {
501
- transform: translateX(0) scale(1);
502
- opacity: 1;
503
- }
504
-
505
- to {
506
- transform: translateX(60%) scale(.9);
507
- opacity: 0;
508
- }
509
- }
510
-
511
- /* ── Modal ── */
512
-
513
- .modal-overlay {
514
- position: fixed;
515
- inset: 0;
516
- background: rgba(0, 0, 0, .68);
517
- backdrop-filter: blur(10px);
518
- -webkit-backdrop-filter: blur(10px);
519
- display: flex;
520
- align-items: center;
521
- justify-content: center;
522
- z-index: 5000;
523
- animation: fadeIn 120ms ease both;
524
- }
525
-
526
- .modal {
527
- background: var(--bg-modal);
528
- backdrop-filter: blur(24px) saturate(1.3);
529
- -webkit-backdrop-filter: blur(24px) saturate(1.3);
530
- border: 1px solid var(--border-light);
531
- border-radius: var(--radius-xl);
532
- width: 90%;
533
- max-width: 600px;
534
- max-height: 80vh;
535
- overflow-y: auto;
536
- box-shadow: var(--shadow-lg);
537
- animation: modalIn 200ms var(--ease-out, cubic-bezier(.16, 1, .3, 1)) both;
538
- }
539
-
540
- .modal-header {
541
- display: flex;
542
- align-items: center;
543
- justify-content: space-between;
544
- padding: 20px 24px;
545
- border-bottom: 1px solid var(--border);
546
- }
547
-
548
- .modal-header h2 {
549
- font-size: 18px;
550
- font-weight: 600;
551
- }
552
-
553
- .modal-body {
554
- padding: 24px;
555
- }
556
-
557
- .modal-footer {
558
- display: flex;
559
- justify-content: flex-end;
560
- gap: 8px;
561
- padding: 16px 24px;
562
- border-top: 1px solid var(--border);
563
- }
564
-
565
- .settings-update-panel {
566
- margin-top: 18px;
567
- border: 1px solid var(--border);
568
- border-radius: 12px;
569
- padding: 14px;
570
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0.01));
571
- }
572
-
573
- .settings-update-head {
574
- display: flex;
575
- align-items: center;
576
- justify-content: space-between;
577
- gap: 12px;
578
- margin-bottom: 10px;
579
- }
580
-
581
- .settings-update-title {
582
- font-size: 12px;
583
- font-weight: 700;
584
- letter-spacing: .6px;
585
- text-transform: uppercase;
586
- color: var(--text-secondary);
587
- }
588
-
589
- .settings-update-progress-wrap {
590
- width: 100%;
591
- height: 8px;
592
- border-radius: 999px;
593
- background: rgba(255, 255, 255, .08);
594
- overflow: hidden;
595
- }
596
-
597
- .settings-update-progress-bar {
598
- height: 100%;
599
- width: 0%;
600
- background: linear-gradient(90deg, #22c55e, #06b6d4);
601
- border-radius: inherit;
602
- transition: width 240ms ease;
603
- }
604
-
605
- .settings-update-row {
606
- display: flex;
607
- justify-content: space-between;
608
- align-items: center;
609
- gap: 10px;
610
- margin-top: 8px;
611
- font-size: 12px;
612
- color: var(--text-secondary);
613
- }
614
-
615
- .settings-update-meta {
616
- margin-top: 6px;
617
- font-family: 'JetBrains Mono', monospace;
618
- font-size: 11px;
619
- color: var(--text-muted);
620
- }
621
-
622
- .settings-update-section {
623
- margin-top: 12px;
624
- }
625
-
626
- .settings-update-label {
627
- font-size: 11px;
628
- font-weight: 600;
629
- letter-spacing: .4px;
630
- text-transform: uppercase;
631
- color: var(--text-secondary);
632
- margin-bottom: 6px;
633
- }
634
-
635
- .settings-update-changelog {
636
- margin: 0;
637
- padding-left: 18px;
638
- max-height: 110px;
639
- overflow-y: auto;
640
- font-size: 12px;
641
- color: var(--text-primary);
642
- display: flex;
643
- flex-direction: column;
644
- gap: 4px;
645
- }
646
-
647
- .settings-update-empty {
648
- list-style: none;
649
- margin-left: -18px;
650
- color: var(--text-muted);
651
- }
652
-
653
- .settings-update-logs {
654
- margin: 0;
655
- padding: 10px;
656
- background: var(--bg-logs);
657
- border: 1px solid var(--border);
658
- border-radius: 8px;
659
- font-family: 'JetBrains Mono', monospace;
660
- font-size: 11px;
661
- line-height: 1.45;
662
- color: var(--text-secondary);
663
- max-height: 140px;
664
- overflow-y: auto;
665
- white-space: pre-wrap;
666
- word-break: break-word;
667
- }
668
-
669
- @keyframes modalIn {
670
- from {
671
- transform: translateY(14px) scale(.96);
672
- opacity: 0;
673
- }
674
-
675
- to {
676
- transform: translateY(0) scale(1);
677
- opacity: 1;
678
- }
679
- }
680
-
681
- @keyframes fadeIn {
682
- from {
683
- opacity: 0;
684
- }
685
-
686
- to {
687
- opacity: 1;
688
- }
689
- }
690
-
691
- /* ── Tabs ── */
692
-
693
- .tabs {
694
- display: flex;
695
- gap: 0;
696
- border-bottom: 1px solid var(--border);
697
- margin-bottom: 20px;
698
- }
699
-
700
- .tab {
701
- padding: 10px 20px;
702
- cursor: pointer;
703
- color: var(--text-secondary);
704
- border-bottom: 2px solid transparent;
705
- font-weight: 500;
706
- transition: all var(--transition);
707
- font-size: 13px;
708
- }
709
-
710
- .tab:hover {
711
- color: var(--text-primary);
712
- }
713
-
714
- .tab.active {
715
- color: var(--accent);
716
- border-bottom-color: var(--accent);
717
- }
718
-
719
- /* ── Code Block ── */
720
-
721
- .code-block {
722
- background: var(--bg-primary);
723
- border: 1px solid var(--border);
724
- border-radius: var(--radius);
725
- padding: 14px;
726
- font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', monospace;
727
- font-size: 12.5px;
728
- line-height: 1.6;
729
- overflow-x: auto;
730
- white-space: pre-wrap;
731
- word-break: break-word;
732
- }
733
-
734
- /* ── Empty State ── */
735
-
736
- .empty-state {
737
- display: flex;
738
- flex-direction: column;
739
- align-items: center;
740
- justify-content: center;
741
- padding: 64px 24px;
742
- color: var(--text-muted);
743
- text-align: center;
744
- gap: 8px;
745
- }
746
-
747
- .empty-state svg {
748
- opacity: .25;
749
- margin-bottom: 8px;
750
- }
751
-
752
- .empty-state p {
753
- font-size: 15px;
754
- font-weight: 500;
755
- color: var(--text-secondary);
756
- }
757
-
758
- /* ── Spinner ── */
759
-
760
- .spinner {
761
- width: 20px;
762
- height: 20px;
763
- border: 2px solid var(--border);
764
- border-top-color: var(--accent);
765
- border-radius: 50%;
766
- animation: spin 600ms linear infinite;
767
- }
768
-
769
- @keyframes spin {
770
- to {
771
- transform: rotate(360deg);
772
- }
773
- }
774
-
775
- /* ── Markdown Content ── */
776
-
777
- .md-content h1,
778
- .md-content h2,
779
- .md-content h3 {
780
- margin: 16px 0 8px;
781
- }
782
-
783
- .md-content h1 {
784
- font-size: 20px;
785
- }
786
-
787
- .md-content h2 {
788
- font-size: 17px;
789
- }
790
-
791
- .md-content h3 {
792
- font-size: 15px;
793
- }
794
-
795
- .md-content p {
796
- margin-bottom: 8px;
797
- }
798
-
799
- .md-content ul,
800
- .md-content ol {
801
- padding-left: 24px;
802
- margin-bottom: 8px;
803
- }
804
-
805
- .md-content code {
806
- background: var(--bg-2, #111120);
807
- padding: 2px 6px;
808
- border-radius: 5px;
809
- font-family: 'JetBrains Mono', 'SF Mono', monospace;
810
- font-size: 12.5px;
811
- color: var(--accent-hover);
812
- }
813
-
814
- .md-content pre {
815
- background: var(--bg-primary);
816
- border: 1px solid var(--border);
817
- border-radius: var(--radius);
818
- padding: 14px;
819
- overflow-x: auto;
820
- margin-bottom: 12px;
821
- }
822
-
823
- .md-content pre code {
824
- background: none;
825
- padding: 0;
826
- }
827
-
828
- .md-content blockquote {
829
- border-left: 3px solid var(--accent);
830
- padding-left: 14px;
831
- color: var(--text-secondary);
832
- margin-bottom: 8px;
833
- }
834
-
835
- /* ── Utility ── */
836
-
837
- .flex {
838
- display: flex;
839
- }
840
-
841
- .flex-col {
842
- flex-direction: column;
843
- }
844
-
845
- .items-center {
846
- align-items: center;
847
- }
848
-
849
- .justify-between {
850
- justify-content: space-between;
851
- }
852
-
853
- .gap-2 {
854
- gap: 8px;
855
- }
856
-
857
- .gap-3 {
858
- gap: 12px;
859
- }
860
-
861
- .gap-4 {
862
- gap: 16px;
863
- }
864
-
865
- .w-full {
866
- width: 100%;
867
- }
868
-
869
- .text-center {
870
- text-align: center;
871
- }
872
-
873
- .text-sm {
874
- font-size: 13px;
875
- }
876
-
877
- .text-xs {
878
- font-size: 11px;
879
- }
880
-
881
- .text-muted {
882
- color: var(--text-secondary);
883
- }
884
-
885
- .font-mono {
886
- font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
887
- }
888
-
889
- .truncate {
890
- overflow: hidden;
891
- text-overflow: ellipsis;
892
- white-space: nowrap;
893
- }
894
-
895
- .hidden {
896
- display: none !important;
897
- }
898
-
899
- .mt-1 {
900
- margin-top: 4px;
901
- }
902
-
903
- .mt-2 {
904
- margin-top: 8px;
905
- }
906
-
907
- .mt-4 {
908
- margin-top: 16px;
909
- }
910
-
911
- .mb-2 {
912
- margin-bottom: 8px;
913
- }
914
-
915
- .mb-4 {
916
- margin-bottom: 16px;
917
- }
918
-
919
- .p-4 {
920
- padding: 16px;
921
- }
922
-
923
- .gap-1 {
924
- gap: 4px;
925
- }
926
-
927
- .justify-center {
928
- justify-content: center;
929
- }
930
-
931
- .rounded {
932
- border-radius: var(--radius);
933
- }
934
-
935
- /* ── ANIMATIONS (global) ── */
936
-
937
- @keyframes pulse {
938
-
939
- 0%,
940
- 100% {
941
- opacity: 1;
942
- }
943
-
944
- 50% {
945
- opacity: .35;
946
- }
947
- }
948
-
949
- @keyframes fadeSlideUp {
950
- from {
951
- opacity: 0;
952
- transform: translateY(8px);
953
- }
954
-
955
- to {
956
- opacity: 1;
957
- transform: translateY(0);
958
- }
959
- }
960
-
961
- .animate-in {
962
- animation: fadeSlideUp 200ms cubic-bezier(.16, 1, .3, 1) both;
963
- }