aegis-desktop 0.3.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.
@@ -0,0 +1,1454 @@
1
+ :root {
2
+ --bg: #0a0e14;
3
+ --surface: #12161e;
4
+ --surface2: #181e28;
5
+ --border: #2a3342;
6
+ --border2: #3d4a5e;
7
+ --text: #d0dfee;
8
+ --text2: #7e9ab8;
9
+ --text3: #3a4a60;
10
+ --teal: #00e5c0;
11
+ --purple: #6b8fd4;
12
+ --green: #00ff88;
13
+ --red: #ff1744;
14
+ --amber: #ff9100;
15
+
16
+ --panel: var(--surface);
17
+ --muted: var(--text2);
18
+ --accent: var(--teal);
19
+ --good: var(--green);
20
+ --user: var(--purple);
21
+ --assistant: var(--surface2);
22
+
23
+ --font-display: 'Syne', 'Segoe UI', system-ui, sans-serif;
24
+ --font-mono: 'DM Mono', monospace;
25
+ --font-chat: 'Ubuntu', 'Segoe UI', system-ui, sans-serif;
26
+ }
27
+
28
+ * {
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ html,
33
+ body {
34
+ height: 100%;
35
+ }
36
+
37
+ body {
38
+ margin: 0;
39
+ display: flex;
40
+ flex-direction: column;
41
+ background: var(--bg);
42
+ color: var(--text);
43
+ font: 14px/1.5 var(--font-display);
44
+ }
45
+
46
+ /* --------------------------------------------------------------- top bar */
47
+ .topbar {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 12px;
51
+ padding: 8px 16px;
52
+ background: var(--surface);
53
+ border-bottom: 1px solid var(--border);
54
+ }
55
+
56
+ .topbar h1 {
57
+ font-size: 16px;
58
+ margin: 0;
59
+ font-weight: 700;
60
+ font-family: var(--font-display);
61
+ }
62
+
63
+ .accent {
64
+ color: var(--teal);
65
+ }
66
+
67
+ .conn {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 6px;
71
+ font-size: 12px;
72
+ color: var(--text2);
73
+ font-family: var(--font-mono);
74
+ }
75
+
76
+ .dot {
77
+ width: 8px;
78
+ height: 8px;
79
+ border-radius: 50%;
80
+ background: var(--text3);
81
+ }
82
+
83
+ .dot.ok {
84
+ background: var(--teal);
85
+ box-shadow: 0 0 6px var(--teal);
86
+ }
87
+
88
+ .spacer {
89
+ flex: 1;
90
+ }
91
+
92
+ .toggle-wrap {
93
+ display: flex;
94
+ align-items: center;
95
+ gap: 8px;
96
+ font-size: 12px;
97
+ color: var(--text2);
98
+ }
99
+
100
+ #mode-label.local {
101
+ color: var(--teal);
102
+ }
103
+
104
+ .switch {
105
+ position: relative;
106
+ width: 34px;
107
+ height: 18px;
108
+ }
109
+
110
+ .switch input {
111
+ opacity: 0;
112
+ width: 0;
113
+ height: 0;
114
+ }
115
+
116
+ .slider {
117
+ position: absolute;
118
+ inset: 0;
119
+ border-radius: 18px;
120
+ background: var(--border);
121
+ transition: 0.15s;
122
+ cursor: pointer;
123
+ }
124
+
125
+ .slider::before {
126
+ content: '';
127
+ position: absolute;
128
+ width: 12px;
129
+ height: 12px;
130
+ left: 3px;
131
+ top: 3px;
132
+ border-radius: 50%;
133
+ background: var(--text);
134
+ transition: 0.15s;
135
+ }
136
+
137
+ .switch input:checked + .slider {
138
+ background: var(--purple);
139
+ }
140
+
141
+ .switch input:checked + .slider::before {
142
+ transform: translateX(16px);
143
+ }
144
+
145
+ /* --------------------------------------------------------------- layout */
146
+ main {
147
+ flex: 1;
148
+ display: flex;
149
+ min-height: 0;
150
+ }
151
+
152
+ .side {
153
+ width: 300px;
154
+ flex: none;
155
+ border-right: 1px solid var(--border);
156
+ padding: 12px;
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 12px;
160
+ overflow-y: auto;
161
+ background: var(--surface);
162
+ }
163
+
164
+ .chat {
165
+ flex: 1;
166
+ display: flex;
167
+ flex-direction: column;
168
+ min-width: 0;
169
+ background: var(--bg);
170
+ }
171
+
172
+ .card {
173
+ background: var(--surface2);
174
+ border: 1px solid var(--border);
175
+ border-radius: 8px;
176
+ padding: 12px;
177
+ }
178
+
179
+ .card h2 {
180
+ font-size: 12px;
181
+ text-transform: uppercase;
182
+ letter-spacing: 0.06em;
183
+ color: var(--text2);
184
+ margin: 0 0 8px;
185
+ font-family: var(--font-display);
186
+ }
187
+
188
+ .card dl {
189
+ display: grid;
190
+ grid-template-columns: auto 1fr;
191
+ gap: 4px 10px;
192
+ margin: 0;
193
+ font-size: 13px;
194
+ font-family: var(--font-mono);
195
+ }
196
+
197
+ .card dt {
198
+ color: var(--text2);
199
+ }
200
+
201
+ .card dd {
202
+ margin: 0;
203
+ word-break: break-all;
204
+ }
205
+
206
+ select {
207
+ width: 100%;
208
+ margin-top: 6px;
209
+ background: var(--surface);
210
+ color: var(--text);
211
+ border: 1px solid var(--border);
212
+ border-radius: 6px;
213
+ padding: 6px;
214
+ font-family: var(--font-display);
215
+ }
216
+
217
+ select:focus {
218
+ outline: none;
219
+ border-color: var(--teal);
220
+ }
221
+
222
+ select:disabled {
223
+ opacity: 0.55;
224
+ }
225
+
226
+ .hint {
227
+ font-size: 12px;
228
+ color: var(--text2);
229
+ margin: 8px 0 0;
230
+ }
231
+
232
+ /* --------------------------------------------------------- in-app key entry */
233
+ .api-key-row {
234
+ display: flex;
235
+ gap: 6px;
236
+ margin-top: 10px;
237
+ }
238
+
239
+ .api-key-row input {
240
+ flex: 1;
241
+ min-width: 0;
242
+ background: var(--surface);
243
+ color: var(--text);
244
+ border: 1px solid var(--border);
245
+ border-radius: 6px;
246
+ padding: 5px 8px;
247
+ font: inherit;
248
+ font-size: 12px;
249
+ }
250
+
251
+ .api-key-row input:focus {
252
+ outline: none;
253
+ border-color: var(--teal);
254
+ }
255
+
256
+ /* --------------------------------------------------------------- memory */
257
+ .memory-search {
258
+ display: flex;
259
+ gap: 6px;
260
+ }
261
+
262
+ .memory-search input {
263
+ flex: 1;
264
+ min-width: 0;
265
+ background: var(--surface);
266
+ color: var(--text);
267
+ border: 1px solid var(--border);
268
+ border-radius: 6px;
269
+ padding: 6px 8px;
270
+ font: inherit;
271
+ }
272
+
273
+ .memory-search input:focus {
274
+ outline: none;
275
+ border-color: var(--teal);
276
+ }
277
+
278
+ .memory-search button {
279
+ border: none;
280
+ border-radius: 6px;
281
+ background: var(--surface2);
282
+ color: var(--text);
283
+ border: 1px solid var(--border);
284
+ padding: 0 10px;
285
+ font: inherit;
286
+ cursor: pointer;
287
+ }
288
+
289
+ .memory-search button:hover {
290
+ border-color: var(--teal);
291
+ color: var(--teal);
292
+ }
293
+
294
+ .memory-results {
295
+ list-style: none;
296
+ margin: 8px 0 0;
297
+ padding: 0;
298
+ max-height: 160px;
299
+ overflow-y: auto;
300
+ display: flex;
301
+ flex-direction: column;
302
+ gap: 6px;
303
+ }
304
+
305
+ .memory-results li {
306
+ font-size: 12px;
307
+ border: 1px solid var(--border);
308
+ border-radius: 6px;
309
+ padding: 6px 8px;
310
+ word-break: break-word;
311
+ }
312
+
313
+ .memory-results .empty {
314
+ color: var(--text2);
315
+ border-style: dashed;
316
+ }
317
+
318
+ /* Sidebar rows now carry provenance: the source is a quiet prefix, the body
319
+ stays the readable part. Both are <span>s inside the existing <li>. */
320
+ .memory-results .mem-side-src {
321
+ display: block;
322
+ font-size: 10px;
323
+ letter-spacing: 0.04em;
324
+ text-transform: uppercase;
325
+ color: var(--teal);
326
+ opacity: 0.75;
327
+ margin-bottom: 2px;
328
+ }
329
+
330
+ .memory-results .mem-side-body {
331
+ color: var(--text);
332
+ overflow: hidden;
333
+ display: -webkit-box;
334
+ -webkit-line-clamp: 3;
335
+ -webkit-box-orient: vertical;
336
+ }
337
+
338
+ /* The Memory heading doubles as the inspector's trigger. Reset the button so
339
+ it inherits the .card h2 typography (style.css:179) and reads as a heading,
340
+ then add only an affordance on hover/focus. */
341
+ .card-title-btn {
342
+ display: inline-flex;
343
+ align-items: center;
344
+ gap: 6px;
345
+ width: 100%;
346
+ padding: 0;
347
+ border: none;
348
+ background: none;
349
+ font: inherit;
350
+ color: inherit;
351
+ letter-spacing: inherit;
352
+ text-transform: inherit;
353
+ cursor: pointer;
354
+ text-align: left;
355
+ }
356
+
357
+ .card-title-btn .ctb-expand {
358
+ margin-left: auto;
359
+ font-size: 11px;
360
+ opacity: 0.4;
361
+ transition: opacity 0.15s, color 0.15s;
362
+ }
363
+
364
+ .card-title-btn:hover,
365
+ .card-title-btn:focus-visible {
366
+ color: var(--teal);
367
+ }
368
+
369
+ .card-title-btn:hover .ctb-expand,
370
+ .card-title-btn:focus-visible .ctb-expand {
371
+ opacity: 1;
372
+ color: var(--teal);
373
+ }
374
+
375
+ .card-title-btn:focus-visible {
376
+ outline: 1px solid var(--teal);
377
+ outline-offset: 2px;
378
+ border-radius: 3px;
379
+ }
380
+
381
+ /* ------------------------------------------------------ memory inspector */
382
+ /* Full-viewport translucent layer: the app stays visible but recedes behind a
383
+ blur, so every entry and its source reads as a foreground sheet. */
384
+ .memory-overlay[hidden] {
385
+ display: none;
386
+ }
387
+
388
+ .memory-overlay {
389
+ position: fixed;
390
+ inset: 0;
391
+ z-index: 60;
392
+ display: flex;
393
+ align-items: center;
394
+ justify-content: center;
395
+ padding: 40px 24px;
396
+ }
397
+
398
+ .memory-backdrop {
399
+ position: absolute;
400
+ inset: 0;
401
+ background: rgba(4, 8, 14, 0.55);
402
+ backdrop-filter: blur(8px);
403
+ -webkit-backdrop-filter: blur(8px);
404
+ }
405
+
406
+ .memory-panel {
407
+ position: relative;
408
+ display: flex;
409
+ flex-direction: column;
410
+ width: min(860px, 100%);
411
+ max-height: 100%;
412
+ min-height: 0;
413
+ background: color-mix(in srgb, var(--surface2) 88%, transparent);
414
+ border: 1px solid var(--border2);
415
+ border-radius: 12px;
416
+ box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
417
+ overflow: hidden;
418
+ }
419
+
420
+ .memory-panel-head {
421
+ display: flex;
422
+ align-items: baseline;
423
+ gap: 10px;
424
+ padding: 14px 16px;
425
+ border-bottom: 1px solid var(--border);
426
+ }
427
+
428
+ .memory-panel-head h2 {
429
+ font-size: 12px;
430
+ text-transform: uppercase;
431
+ letter-spacing: 0.06em;
432
+ color: var(--text2);
433
+ margin: 0;
434
+ font-family: var(--font-display);
435
+ }
436
+
437
+ .memory-count {
438
+ font-size: 11px;
439
+ color: var(--text2);
440
+ font-family: var(--font-mono);
441
+ }
442
+
443
+ .memory-panel-head .spacer {
444
+ flex: 1;
445
+ }
446
+
447
+ .memory-filters {
448
+ display: flex;
449
+ gap: 6px;
450
+ padding: 12px 16px 0;
451
+ }
452
+
453
+ .memory-filters input {
454
+ flex: 1;
455
+ min-width: 0;
456
+ background: var(--surface);
457
+ color: var(--text);
458
+ border: 1px solid var(--border);
459
+ border-radius: 6px;
460
+ padding: 7px 9px;
461
+ font: inherit;
462
+ }
463
+
464
+ .memory-filters input:focus {
465
+ outline: none;
466
+ border-color: var(--teal);
467
+ }
468
+
469
+ .memory-filters button {
470
+ border: 1px solid var(--border);
471
+ border-radius: 6px;
472
+ background: var(--surface);
473
+ color: var(--text);
474
+ padding: 0 12px;
475
+ font: inherit;
476
+ cursor: pointer;
477
+ }
478
+
479
+ .memory-filters button:hover {
480
+ border-color: var(--teal);
481
+ color: var(--teal);
482
+ }
483
+
484
+ .memory-chips {
485
+ display: flex;
486
+ flex-direction: column;
487
+ gap: 5px;
488
+ padding: 10px 16px 0;
489
+ }
490
+
491
+ .memory-chips:empty {
492
+ display: none;
493
+ }
494
+
495
+ .mem-chip-group {
496
+ display: flex;
497
+ flex-wrap: wrap;
498
+ align-items: center;
499
+ gap: 5px;
500
+ }
501
+
502
+ .mem-chip-label {
503
+ font-size: 10px;
504
+ text-transform: uppercase;
505
+ letter-spacing: 0.06em;
506
+ color: var(--text3);
507
+ margin-right: 2px;
508
+ }
509
+
510
+ .mem-chip {
511
+ display: inline-flex;
512
+ align-items: center;
513
+ font-size: 10px;
514
+ line-height: 1.6;
515
+ padding: 1px 7px;
516
+ border-radius: 999px;
517
+ border: 1px solid var(--border);
518
+ color: var(--text2);
519
+ background: var(--surface);
520
+ white-space: nowrap;
521
+ max-width: 22ch;
522
+ overflow: hidden;
523
+ text-overflow: ellipsis;
524
+ }
525
+
526
+ button.mem-chip {
527
+ cursor: pointer;
528
+ font: inherit;
529
+ font-size: 10px;
530
+ }
531
+
532
+ button.mem-chip:hover {
533
+ border-color: var(--teal);
534
+ color: var(--teal);
535
+ }
536
+
537
+ button.mem-chip.on {
538
+ border-color: var(--teal);
539
+ background: rgba(0, 229, 192, 0.14);
540
+ color: var(--teal);
541
+ }
542
+
543
+ .mem-chip.src {
544
+ border-color: rgba(0, 229, 192, 0.45);
545
+ color: var(--teal);
546
+ }
547
+
548
+ .mem-chip.role {
549
+ border-color: rgba(107, 143, 212, 0.5);
550
+ color: var(--purple);
551
+ }
552
+
553
+ .mem-chip.imp {
554
+ border-color: rgba(255, 145, 0, 0.45);
555
+ color: var(--amber);
556
+ }
557
+
558
+ .mem-chip.sent,
559
+ .mem-chip.flag {
560
+ color: var(--text3);
561
+ }
562
+
563
+ .mem-chip.pill {
564
+ border-style: dashed;
565
+ color: var(--text2);
566
+ }
567
+
568
+ .memory-scroll {
569
+ flex: 1;
570
+ min-height: 0;
571
+ overflow-y: auto;
572
+ padding: 12px 16px;
573
+ }
574
+
575
+ .memory-list {
576
+ list-style: none;
577
+ margin: 0;
578
+ padding: 0;
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 8px;
582
+ }
583
+
584
+ .mem-card {
585
+ border: 1px solid var(--border);
586
+ border-radius: 8px;
587
+ background: var(--surface);
588
+ padding: 9px 11px;
589
+ }
590
+
591
+ .mem-card-head {
592
+ display: flex;
593
+ flex-wrap: wrap;
594
+ align-items: center;
595
+ gap: 5px;
596
+ margin-bottom: 6px;
597
+ }
598
+
599
+ .mem-card-meta {
600
+ margin-left: auto;
601
+ font-size: 10px;
602
+ color: var(--text3);
603
+ font-family: var(--font-mono);
604
+ }
605
+
606
+ .mem-card-body {
607
+ margin: 0;
608
+ font-size: 12px;
609
+ line-height: 1.55;
610
+ color: var(--text);
611
+ white-space: pre-wrap;
612
+ word-break: break-word;
613
+ overflow: hidden;
614
+ display: -webkit-box;
615
+ -webkit-line-clamp: 3;
616
+ -webkit-box-orient: vertical;
617
+ cursor: pointer;
618
+ }
619
+
620
+ .mem-card.expanded .mem-card-body {
621
+ -webkit-line-clamp: unset;
622
+ }
623
+
624
+ .mem-card-pills {
625
+ display: flex;
626
+ flex-wrap: wrap;
627
+ gap: 5px;
628
+ margin-top: 7px;
629
+ padding-top: 7px;
630
+ border-top: 1px dashed var(--border);
631
+ }
632
+
633
+ .mem-empty {
634
+ font-size: 12px;
635
+ color: var(--text2);
636
+ border: 1px dashed var(--border);
637
+ border-radius: 8px;
638
+ padding: 18px;
639
+ text-align: center;
640
+ }
641
+
642
+ .mem-upgrade {
643
+ display: flex;
644
+ flex-direction: column;
645
+ gap: 10px;
646
+ align-items: center;
647
+ border-color: rgba(255, 145, 0, 0.45);
648
+ }
649
+
650
+ .mem-upgrade strong {
651
+ color: var(--amber);
652
+ }
653
+
654
+ .mem-upgrade span {
655
+ max-width: 52ch;
656
+ line-height: 1.6;
657
+ }
658
+
659
+ .mem-upgrade a {
660
+ color: var(--teal);
661
+ }
662
+
663
+ /* Sidebar counterpart of the inspector's .mem-upgrade card: the same cap
664
+ notice, sized for the narrow memory list instead of the full-width panel. */
665
+ .mem-side-upgrade {
666
+ border-color: rgba(255, 145, 0, 0.45);
667
+ }
668
+
669
+ .mem-side-upgrade a {
670
+ color: var(--teal);
671
+ line-height: 1.5;
672
+ display: inline-block;
673
+ }
674
+
675
+ .memory-actions {
676
+ border-top: 1px solid var(--border);
677
+ padding: 12px 16px 14px;
678
+ }
679
+
680
+ .memory-actions textarea {
681
+ width: 100%;
682
+ resize: none;
683
+ background: var(--surface);
684
+ color: var(--text);
685
+ border: 1px solid var(--border);
686
+ border-radius: 6px;
687
+ padding: 6px 8px;
688
+ font: inherit;
689
+ }
690
+
691
+ .memory-actions textarea:focus {
692
+ outline: none;
693
+ border-color: var(--teal);
694
+ }
695
+
696
+ /* Stop the page behind the overlay from scrolling under it. */
697
+ body.memory-open {
698
+ overflow: hidden;
699
+ }
700
+
701
+ #memory-entry {
702
+ width: 100%;
703
+ margin-top: 10px;
704
+ resize: none;
705
+ background: var(--surface);
706
+ color: var(--text);
707
+ border: 1px solid var(--border);
708
+ border-radius: 6px;
709
+ padding: 6px 8px;
710
+ font: inherit;
711
+ }
712
+
713
+ #memory-entry:focus {
714
+ outline: none;
715
+ border-color: var(--teal);
716
+ }
717
+
718
+ .btn-block {
719
+ width: 100%;
720
+ margin-top: 6px;
721
+ border: none;
722
+ border-radius: 6px;
723
+ background: var(--teal);
724
+ color: #04140f;
725
+ padding: 6px 0;
726
+ font: inherit;
727
+ font-weight: 700;
728
+ cursor: pointer;
729
+ }
730
+
731
+ .btn-block:hover:not(:disabled) {
732
+ box-shadow: 0 0 12px rgba(0, 229, 192, 0.35);
733
+ }
734
+
735
+ .btn-block:disabled {
736
+ opacity: 0.5;
737
+ cursor: default;
738
+ }
739
+
740
+ /* ------------------------------------------------------------- messages */
741
+ .messages {
742
+ flex: 1;
743
+ overflow-y: auto;
744
+ padding: 16px;
745
+ display: flex;
746
+ flex-direction: column;
747
+ gap: 10px;
748
+ min-height: 0;
749
+ font-family: var(--font-chat);
750
+ }
751
+
752
+ .msg {
753
+ max-width: 76%;
754
+ padding: 10px 12px;
755
+ border-radius: 10px;
756
+ }
757
+
758
+ .msg.user {
759
+ align-self: flex-end;
760
+ background: var(--purple);
761
+ color: #fff;
762
+ }
763
+
764
+ .msg.assistant {
765
+ align-self: flex-start;
766
+ background: var(--surface2);
767
+ border: 1px solid var(--border);
768
+ }
769
+
770
+ .msg.system {
771
+ align-self: center;
772
+ background: transparent;
773
+ color: var(--text2);
774
+ font-size: 12px;
775
+ border: 1px dashed var(--border);
776
+ max-width: 92%;
777
+ text-align: center;
778
+ }
779
+
780
+ .msg.pending {
781
+ opacity: 0.6;
782
+ }
783
+
784
+ .typing-dots {
785
+ display: inline-flex;
786
+ align-items: center;
787
+ gap: 5px;
788
+ }
789
+
790
+ .typing-dots span {
791
+ width: 6px;
792
+ height: 6px;
793
+ border-radius: 50%;
794
+ background: var(--text3);
795
+ animation: typing-glow 1.2s ease-in-out infinite;
796
+ }
797
+
798
+ .typing-dots span:nth-child(1) {
799
+ animation-delay: 0s;
800
+ }
801
+
802
+ .typing-dots span:nth-child(2) {
803
+ animation-delay: 0.2s;
804
+ }
805
+
806
+ .typing-dots span:nth-child(3) {
807
+ animation-delay: 0.4s;
808
+ }
809
+
810
+ @keyframes typing-glow {
811
+ 0%,
812
+ 60%,
813
+ 100% {
814
+ background: var(--text3);
815
+ box-shadow: none;
816
+ }
817
+ 30% {
818
+ background: var(--accent);
819
+ box-shadow: 0 0 6px 1px var(--accent);
820
+ }
821
+ }
822
+
823
+ .who {
824
+ font-size: 11px;
825
+ font-weight: 600;
826
+ text-transform: uppercase;
827
+ letter-spacing: 0.05em;
828
+ opacity: 0.7;
829
+ margin-bottom: 2px;
830
+ font-family: var(--font-display);
831
+ }
832
+
833
+ .msg.user .who {
834
+ text-align: right;
835
+ }
836
+
837
+ .body {
838
+ white-space: pre-wrap;
839
+ word-break: break-word;
840
+ }
841
+
842
+ /* Tool-call log for a turn (desktop/lib/local/engine.js onDelta's `tool`
843
+ events) — a retrospective list of what the model did, shown above the
844
+ answer text it produced. */
845
+ .tool-activity {
846
+ font-family: var(--font-mono);
847
+ font-size: 11px;
848
+ color: var(--text2);
849
+ margin-bottom: 6px;
850
+ display: flex;
851
+ flex-direction: column;
852
+ gap: 2px;
853
+ }
854
+
855
+ .meta {
856
+ font-size: 11px;
857
+ color: var(--text2);
858
+ margin-top: 6px;
859
+ font-family: var(--font-mono);
860
+ }
861
+
862
+ .msg.user .meta {
863
+ color: rgba(255, 255, 255, 0.75);
864
+ text-align: right;
865
+ }
866
+
867
+ /* --------------------------------------------------- discovery lane (D2.2)
868
+ The vertical thread stays one column of .msg rows; the lane drops a
869
+ horizontal track underneath it so the AI's *other* paths read left→right
870
+ beside the answer instead of being buried under it. */
871
+ .chatflow {
872
+ align-self: stretch;
873
+ max-width: 100%;
874
+ margin: 2px 0 6px;
875
+ padding: 8px 10px 10px;
876
+ border: 1px solid var(--border);
877
+ border-left: 2px solid var(--teal);
878
+ border-radius: 10px;
879
+ background: linear-gradient(
880
+ 90deg,
881
+ rgba(0, 229, 192, 0.05),
882
+ rgba(107, 143, 212, 0.05)
883
+ );
884
+ }
885
+
886
+ .flow-rail {
887
+ display: flex;
888
+ align-items: baseline;
889
+ gap: 8px;
890
+ margin-bottom: 6px;
891
+ }
892
+
893
+ .flow-rail-label {
894
+ font-family: var(--font-display);
895
+ font-size: 11px;
896
+ font-weight: 700;
897
+ letter-spacing: 0.08em;
898
+ text-transform: uppercase;
899
+ color: var(--teal);
900
+ }
901
+
902
+ .flow-rail-hint {
903
+ font-size: 11px;
904
+ color: var(--text2);
905
+ }
906
+
907
+ /* Horizontal scroller: the lane's whole point. Snap stops keep a card
908
+ legible instead of leaving the track parked mid-card. */
909
+ .flow-track {
910
+ position: relative; /* containing block for the between-card connectors */
911
+ display: flex;
912
+ flex-direction: row;
913
+ align-items: stretch;
914
+ gap: 10px;
915
+ overflow-x: auto;
916
+ overflow-y: hidden;
917
+ padding-bottom: 6px;
918
+ scroll-snap-type: x proximity;
919
+ scrollbar-width: thin;
920
+ }
921
+
922
+ .flow-card {
923
+ flex: 0 0 clamp(230px, 42%, 340px);
924
+ scroll-snap-align: start;
925
+ display: flex;
926
+ flex-direction: column;
927
+ gap: 6px;
928
+ padding: 9px 11px;
929
+ border: 1px solid var(--border2);
930
+ border-radius: 10px;
931
+ background: var(--surface2);
932
+ min-height: 92px;
933
+ }
934
+
935
+ /* Connector between adjacent cards — the visual "2nd path" arrow. */
936
+ .flow-card + .flow-card::before {
937
+ content: '→';
938
+ position: absolute;
939
+ margin-left: -13px;
940
+ margin-top: 34px;
941
+ color: var(--border2);
942
+ font-size: 12px;
943
+ }
944
+
945
+ .flow-card.pending {
946
+ opacity: 0.72;
947
+ border-style: dashed;
948
+ }
949
+
950
+ .flow-card.done {
951
+ border-color: rgba(0, 229, 192, 0.45);
952
+ }
953
+
954
+ .flow-card.stopped {
955
+ opacity: 0.7;
956
+ }
957
+
958
+ .flow-head {
959
+ display: flex;
960
+ align-items: center;
961
+ gap: 6px;
962
+ font-family: var(--font-display);
963
+ }
964
+
965
+ .flow-badge {
966
+ flex: 0 0 auto;
967
+ width: 18px;
968
+ height: 18px;
969
+ border-radius: 50%;
970
+ display: grid;
971
+ place-items: center;
972
+ font-size: 11px;
973
+ font-weight: 700;
974
+ color: #04140f;
975
+ background: var(--teal);
976
+ }
977
+
978
+ .flow-card[data-path='discovery'] .flow-badge {
979
+ background: var(--purple);
980
+ color: #fff;
981
+ }
982
+
983
+ .flow-card[data-path='genre'] .flow-badge {
984
+ background: var(--amber);
985
+ }
986
+
987
+ .flow-title {
988
+ flex: 1;
989
+ font-size: 12px;
990
+ font-weight: 700;
991
+ letter-spacing: 0.02em;
992
+ color: var(--text);
993
+ }
994
+
995
+ .flow-state {
996
+ flex: 0 0 auto;
997
+ font-size: 10px;
998
+ text-transform: uppercase;
999
+ letter-spacing: 0.06em;
1000
+ color: var(--text2);
1001
+ }
1002
+
1003
+ .flow-card.done .flow-state {
1004
+ color: var(--teal);
1005
+ }
1006
+
1007
+ .flow-tools {
1008
+ font-family: var(--font-mono);
1009
+ font-size: 10.5px;
1010
+ color: var(--text2);
1011
+ display: flex;
1012
+ flex-direction: column;
1013
+ gap: 2px;
1014
+ }
1015
+
1016
+ .flow-body {
1017
+ flex: 1;
1018
+ font-family: var(--font-chat);
1019
+ font-size: 12.5px;
1020
+ line-height: 1.45;
1021
+ color: var(--text);
1022
+ white-space: pre-wrap;
1023
+ word-break: break-word;
1024
+ max-height: 260px;
1025
+ overflow-y: auto;
1026
+ }
1027
+
1028
+ .flow-meta {
1029
+ font-family: var(--font-mono);
1030
+ font-size: 10.5px;
1031
+ color: var(--text2);
1032
+ }
1033
+
1034
+ .flow-abort {
1035
+ align-self: flex-start;
1036
+ padding: 2px 8px;
1037
+ font-size: 11px;
1038
+ }
1039
+
1040
+ .flow-add {
1041
+ flex: 0 0 auto;
1042
+ align-self: center;
1043
+ border-style: dashed;
1044
+ scroll-snap-align: end;
1045
+ }
1046
+
1047
+ /* Composer side rail: the lane toggle sits above Send so it is visible
1048
+ without stealing composer width. */
1049
+ .composer-side {
1050
+ display: flex;
1051
+ flex-direction: column;
1052
+ align-items: stretch;
1053
+ gap: 6px;
1054
+ }
1055
+
1056
+ .composer-side button[type='submit'] {
1057
+ flex: 1;
1058
+ min-height: 34px;
1059
+ }
1060
+
1061
+ .flow-toggle {
1062
+ display: flex;
1063
+ align-items: center;
1064
+ gap: 5px;
1065
+ margin-top: 0;
1066
+ font-size: 11px;
1067
+ color: var(--text2);
1068
+ cursor: pointer;
1069
+ user-select: none;
1070
+ white-space: nowrap;
1071
+ }
1072
+
1073
+ .max-tokens-row {
1074
+ display: flex;
1075
+ align-items: center;
1076
+ gap: 8px;
1077
+ }
1078
+
1079
+ .max-tokens-row select {
1080
+ flex: 1;
1081
+ min-width: 0;
1082
+ }
1083
+
1084
+ #autonomous-toggle-wrap {
1085
+ margin-top: 6px;
1086
+ }
1087
+
1088
+ /* .flow-toggle sets display: flex, which — being an author-stylesheet rule —
1089
+ outranks the UA stylesheet's `[hidden] { display: none }` regardless of
1090
+ selector specificity. Without this override, hiding the toggle via the
1091
+ `hidden` attribute (see loadModels() in app.js) has no visual effect. */
1092
+ #autonomous-toggle-wrap[hidden] {
1093
+ display: none;
1094
+ }
1095
+
1096
+ .autonomous-controls {
1097
+ display: flex;
1098
+ align-items: center;
1099
+ gap: 6px;
1100
+ margin-top: 6px;
1101
+ font-size: 11px;
1102
+ color: var(--text2);
1103
+ }
1104
+
1105
+ .autonomous-controls select,
1106
+ .autonomous-controls input {
1107
+ font-size: 11px;
1108
+ }
1109
+
1110
+ .autonomous-controls input[type='number'] {
1111
+ width: 48px;
1112
+ }
1113
+
1114
+ /* Same author-stylesheet-beats-UA-stylesheet gotcha as #autonomous-toggle-wrap
1115
+ above: `display: flex` here needs an explicit [hidden] override too. */
1116
+ .autonomous-controls[hidden] {
1117
+ display: none;
1118
+ }
1119
+
1120
+ .flow-toggle input {
1121
+ accent-color: var(--teal);
1122
+ margin: 0;
1123
+ cursor: pointer;
1124
+ }
1125
+
1126
+ .flow-toggle:hover {
1127
+ color: var(--teal);
1128
+ }
1129
+
1130
+ /* ------------------------------------------------------------- composer */
1131
+ .composer {
1132
+ display: flex;
1133
+ gap: 8px;
1134
+ align-items: flex-end;
1135
+ padding: 12px;
1136
+ margin: 0 auto;
1137
+ max-width: 100%;
1138
+ width: calc(100% - 24px);
1139
+ border: 1px solid var(--border2);
1140
+ border-radius: 16px;
1141
+ background: var(--surface2);
1142
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
1143
+ transition: border-color 0.15s, box-shadow 0.15s;
1144
+ margin-bottom: 12px;
1145
+ }
1146
+
1147
+ .composer:focus-within {
1148
+ border-color: var(--teal);
1149
+ box-shadow: 0 0 0 1px rgba(0, 229, 192, 0.35), 0 6px 22px rgba(0, 229, 192, 0.08);
1150
+ }
1151
+
1152
+ .composer textarea {
1153
+ flex: 1;
1154
+ resize: none;
1155
+ background: transparent;
1156
+ color: var(--text);
1157
+ border: none;
1158
+ border-radius: 8px;
1159
+ padding: 8px 10px;
1160
+ font: inherit;
1161
+ font-family: var(--font-chat);
1162
+ }
1163
+
1164
+ .composer textarea:focus {
1165
+ outline: none;
1166
+ }
1167
+
1168
+ .composer button {
1169
+ border: none;
1170
+ border-radius: 8px;
1171
+ background: var(--teal);
1172
+ color: #04140f;
1173
+ padding: 0 18px;
1174
+ font: inherit;
1175
+ font-weight: 700;
1176
+ cursor: pointer;
1177
+ }
1178
+
1179
+ .composer button:hover:not(:disabled) {
1180
+ box-shadow: 0 0 12px rgba(0, 229, 192, 0.35);
1181
+ }
1182
+
1183
+ .composer button:disabled {
1184
+ opacity: 0.5;
1185
+ cursor: default;
1186
+ }
1187
+
1188
+ /* ------------------------------------------------------------- new UI bits */
1189
+ label {
1190
+ display: block;
1191
+ font-size: 12px;
1192
+ color: var(--text2);
1193
+ margin-top: 8px;
1194
+ }
1195
+
1196
+ .ghost-btn {
1197
+ border: 1px solid var(--border);
1198
+ border-radius: 6px;
1199
+ background: var(--surface2);
1200
+ color: var(--text);
1201
+ padding: 4px 10px;
1202
+ font: inherit;
1203
+ font-size: 12px;
1204
+ cursor: pointer;
1205
+ }
1206
+
1207
+ .ghost-btn:hover {
1208
+ border-color: var(--teal);
1209
+ color: var(--teal);
1210
+ }
1211
+
1212
+ .ghost-btn:disabled {
1213
+ opacity: 0.5;
1214
+ cursor: default;
1215
+ }
1216
+
1217
+ .ghost-btn.danger:hover {
1218
+ border-color: var(--red);
1219
+ color: var(--red);
1220
+ }
1221
+
1222
+ #model-input {
1223
+ width: 100%;
1224
+ margin-top: 6px;
1225
+ background: var(--surface);
1226
+ color: var(--text);
1227
+ border: 1px solid var(--border);
1228
+ border-radius: 6px;
1229
+ padding: 6px;
1230
+ font: inherit;
1231
+ }
1232
+
1233
+ #model-input:focus {
1234
+ outline: none;
1235
+ border-color: var(--teal);
1236
+ }
1237
+
1238
+ .cancel-btn {
1239
+ margin-top: 8px;
1240
+ border: 1px solid var(--red);
1241
+ border-radius: 6px;
1242
+ background: transparent;
1243
+ color: var(--red);
1244
+ padding: 2px 10px;
1245
+ font: inherit;
1246
+ font-size: 11px;
1247
+ cursor: pointer;
1248
+ }
1249
+
1250
+ .copy-btn {
1251
+ margin-top: 8px;
1252
+ border: 1px solid var(--teal);
1253
+ border-radius: 6px;
1254
+ background: transparent;
1255
+ color: var(--teal);
1256
+ padding: 2px 10px;
1257
+ font: inherit;
1258
+ font-size: 11px;
1259
+ cursor: pointer;
1260
+ }
1261
+
1262
+ .copy-btn:disabled {
1263
+ opacity: 0.6;
1264
+ cursor: default;
1265
+ }
1266
+
1267
+ /* ------------------------------------------------------- settings pane */
1268
+ .setting-row {
1269
+ border: 1px solid var(--border);
1270
+ border-radius: 6px;
1271
+ padding: 8px;
1272
+ margin-bottom: 8px;
1273
+ display: flex;
1274
+ flex-direction: column;
1275
+ gap: 6px;
1276
+ }
1277
+
1278
+ .setting-name {
1279
+ font-size: 12px;
1280
+ font-weight: 600;
1281
+ }
1282
+
1283
+ .setting-input {
1284
+ width: 100%;
1285
+ background: var(--surface);
1286
+ color: var(--text);
1287
+ border: 1px solid var(--border);
1288
+ border-radius: 6px;
1289
+ padding: 5px 7px;
1290
+ font: inherit;
1291
+ font-size: 12px;
1292
+ }
1293
+
1294
+ .setting-input:focus {
1295
+ outline: none;
1296
+ border-color: var(--teal);
1297
+ }
1298
+
1299
+ .setting-status {
1300
+ font-size: 11px;
1301
+ color: var(--text2);
1302
+ }
1303
+
1304
+ .setting-actions {
1305
+ display: flex;
1306
+ gap: 6px;
1307
+ }
1308
+
1309
+ /* ------------------------------------------------------- sessions pane */
1310
+ .sessions-list {
1311
+ list-style: none;
1312
+ margin: 8px 0 0;
1313
+ padding: 0;
1314
+ max-height: 180px;
1315
+ overflow-y: auto;
1316
+ display: flex;
1317
+ flex-direction: column;
1318
+ gap: 6px;
1319
+ }
1320
+
1321
+ .sessions-list .empty {
1322
+ font-size: 12px;
1323
+ color: var(--text2);
1324
+ border: 1px dashed var(--border);
1325
+ border-radius: 6px;
1326
+ padding: 6px 8px;
1327
+ }
1328
+
1329
+ .session-row {
1330
+ display: flex;
1331
+ flex-direction: column;
1332
+ gap: 2px;
1333
+ border: 1px solid var(--border);
1334
+ border-radius: 6px;
1335
+ padding: 6px 8px;
1336
+ cursor: pointer;
1337
+ }
1338
+
1339
+ .session-row:hover {
1340
+ border-color: var(--teal);
1341
+ }
1342
+
1343
+ .session-title {
1344
+ font-size: 12px;
1345
+ word-break: break-word;
1346
+ }
1347
+
1348
+ .session-meta {
1349
+ font-size: 11px;
1350
+ color: var(--text2);
1351
+ }
1352
+
1353
+ /* ---------------------------------------------------------- chat welcome */
1354
+ /* Shown when the transcript is empty; cloned from #welcome-template. */
1355
+ @keyframes shimmer {
1356
+ to {
1357
+ background-position: 200% center;
1358
+ }
1359
+ }
1360
+
1361
+ .chat-welcome {
1362
+ display: flex;
1363
+ flex-direction: column;
1364
+ align-items: center;
1365
+ justify-content: center;
1366
+ flex: 1;
1367
+ gap: 18px;
1368
+ text-align: center;
1369
+ padding: 40px 24px;
1370
+ color: var(--text3);
1371
+ }
1372
+
1373
+ .chat-greeting-row {
1374
+ display: flex;
1375
+ align-items: center;
1376
+ gap: 14px;
1377
+ justify-content: center;
1378
+ }
1379
+
1380
+ .chat-welcome .glyph {
1381
+ font-size: 38px;
1382
+ line-height: 1;
1383
+ margin: 0;
1384
+ background: linear-gradient(135deg, #b0d4ee, #5a7fd4, var(--teal));
1385
+ background-size: 200%;
1386
+ -webkit-background-clip: text;
1387
+ background-clip: text;
1388
+ -webkit-text-fill-color: transparent;
1389
+ filter: drop-shadow(0 0 14px rgba(0, 229, 192, 0.3));
1390
+ animation: shimmer 5s linear infinite;
1391
+ }
1392
+
1393
+ .chat-welcome .title {
1394
+ font-size: 30px;
1395
+ font-weight: 700;
1396
+ color: var(--text);
1397
+ letter-spacing: -0.02em;
1398
+ margin: 0;
1399
+ font-family: var(--font-display);
1400
+ }
1401
+
1402
+ .chat-welcome .sub {
1403
+ font-size: 12px;
1404
+ color: var(--text3);
1405
+ max-width: 420px;
1406
+ line-height: 1.6;
1407
+ margin: 0;
1408
+ }
1409
+
1410
+ .chat-quick-actions {
1411
+ display: flex;
1412
+ flex-wrap: wrap;
1413
+ gap: 8px;
1414
+ justify-content: center;
1415
+ max-width: 560px;
1416
+ margin-top: 2px;
1417
+ }
1418
+
1419
+ .chat-quick-pill {
1420
+ display: inline-flex;
1421
+ align-items: center;
1422
+ gap: 7px;
1423
+ padding: 7px 14px;
1424
+ border-radius: 999px;
1425
+ border: 1px solid var(--border2);
1426
+ background: var(--surface);
1427
+ color: var(--text2);
1428
+ font-size: 12px;
1429
+ font-weight: 500;
1430
+ cursor: pointer;
1431
+ transition: all 0.15s;
1432
+ font-family: var(--font-chat);
1433
+ white-space: nowrap;
1434
+ }
1435
+
1436
+ .chat-quick-pill:hover {
1437
+ border-color: var(--teal);
1438
+ color: var(--teal);
1439
+ background: rgba(0, 229, 192, 0.06);
1440
+ }
1441
+
1442
+ .chat-quick-pill .qp-ic {
1443
+ font-size: 13px;
1444
+ line-height: 1;
1445
+ }
1446
+
1447
+ .chat-welcome .hints {
1448
+ font-size: 10px;
1449
+ color: var(--text3);
1450
+ margin-top: 6px;
1451
+ opacity: 0.55;
1452
+ max-width: 460px;
1453
+ line-height: 1.6;
1454
+ }