@xingjisoft/neutrino 0.1.7 → 0.2.1

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.
package/web/style.css CHANGED
@@ -1,1093 +1,2070 @@
1
- :root {
2
- color-scheme: dark;
3
- --bg: #0b0e14;
4
- --panel: #0d1119;
5
- --panel-2: #121826;
6
- --border: #1e2633;
7
- --border-soft: #171e29;
8
- --text: #d6deeb;
9
- --muted: #7b8aa3;
10
- --muted-2: #55627a;
11
- --accent: #5cc8ff;
12
- --accent-2: #7c9cff;
13
- --green: #8bd450;
14
- --yellow: #ffd479;
15
- --red: #ff6b81;
16
- --user: #8bd450;
17
- --radius: 10px;
18
- --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
19
- }
20
-
21
- * {
22
- box-sizing: border-box;
23
- }
24
-
25
- html,
26
- body {
27
- height: 100%;
28
- margin: 0;
29
- }
30
-
31
- body {
32
- font-family: var(--mono);
33
- font-size: 13px;
34
- line-height: 1.55;
35
- background: var(--bg);
36
- color: var(--text);
37
- overflow: hidden;
38
- }
39
-
40
- button {
41
- font-family: inherit;
42
- font-size: inherit;
43
- color: inherit;
44
- cursor: pointer;
45
- }
46
-
47
- .hidden {
48
- display: none !important;
49
- }
50
-
51
- #app {
52
- display: flex;
53
- height: 100vh;
54
- height: 100dvh;
55
- width: 100%;
56
- }
57
-
58
- /* ---------------------------------------------------------------- sidebar */
59
-
60
- #sidebar {
61
- width: 340px;
62
- min-width: 260px;
63
- max-width: 42vw;
64
- display: flex;
65
- flex-direction: column;
66
- background: var(--panel);
67
- border-right: 1px solid var(--border);
68
- }
69
-
70
- .brand {
71
- display: flex;
72
- flex-shrink: 0;
73
- align-items: center;
74
- gap: 10px;
75
- padding: 14px 14px 12px;
76
- border-bottom: 1px solid var(--border);
77
- }
78
-
79
- .logo {
80
- width: 30px;
81
- height: 30px;
82
- display: grid;
83
- place-items: center;
84
- border-radius: 8px;
85
- background: linear-gradient(135deg, rgba(92, 200, 255, 0.18), rgba(124, 156, 255, 0.18));
86
- border: 1px solid rgba(92, 200, 255, 0.35);
87
- color: var(--accent);
88
- font-size: 16px;
89
- }
90
-
91
- .brand-text {
92
- display: flex;
93
- flex-direction: column;
94
- line-height: 1.2;
95
- flex: 1;
96
- }
97
-
98
- .brand-text strong {
99
- letter-spacing: 0.08em;
100
- font-size: 13px;
101
- }
102
-
103
- .status {
104
- font-size: 10.5px;
105
- color: var(--muted);
106
- letter-spacing: 0.04em;
107
- text-transform: lowercase;
108
- }
109
-
110
- .status.online {
111
- color: var(--green);
112
- }
113
-
114
- .status.live {
115
- color: var(--accent);
116
- }
117
-
118
- .status.offline {
119
- color: var(--red);
120
- }
121
-
122
- .icon-btn {
123
- background: transparent;
124
- border: 1px solid var(--border);
125
- border-radius: 8px;
126
- width: 30px;
127
- height: 30px;
128
- color: var(--muted);
129
- display: grid;
130
- place-items: center;
131
- transition: color 0.15s, border-color 0.15s, transform 0.3s;
132
- }
133
-
134
- .icon-btn:hover {
135
- color: var(--accent);
136
- border-color: rgba(92, 200, 255, 0.4);
137
- transform: rotate(90deg);
138
- }
139
-
140
- .sessions {
141
- flex: 1;
142
- min-height: 0;
143
- overflow-y: auto;
144
- padding: 8px 8px 24px;
145
- }
146
-
147
- .empty-side {
148
- color: var(--muted-2);
149
- padding: 18px 12px;
150
- font-size: 12px;
151
- }
152
-
153
- .group {
154
- margin-bottom: 4px;
155
- }
156
-
157
- .group-header {
158
- width: 100%;
159
- display: flex;
160
- align-items: center;
161
- gap: 6px;
162
- background: transparent;
163
- border: 0;
164
- padding: 7px 8px;
165
- border-radius: 8px;
166
- color: var(--muted);
167
- text-align: left;
168
- }
169
-
170
- .group-header:hover {
171
- background: var(--panel-2);
172
- color: var(--text);
173
- }
174
-
175
- .chevron {
176
- width: 12px;
177
- color: var(--muted-2);
178
- flex: none;
179
- }
180
-
181
- .group-header .path {
182
- flex: 1;
183
- overflow: hidden;
184
- text-overflow: ellipsis;
185
- white-space: nowrap;
186
- text-align: left;
187
- font-size: 11.5px;
188
- }
189
-
190
- .group-header .count {
191
- flex: none;
192
- font-size: 10px;
193
- color: var(--muted-2);
194
- background: var(--panel-2);
195
- border: 1px solid var(--border);
196
- border-radius: 999px;
197
- padding: 0 7px;
198
- }
199
-
200
- .group-items {
201
- display: flex;
202
- flex-direction: column;
203
- gap: 2px;
204
- padding-left: 6px;
205
- border-left: 1px solid var(--border-soft);
206
- margin-left: 13px;
207
- }
208
-
209
- .session {
210
- display: block;
211
- width: 100%;
212
- text-align: left;
213
- background: transparent;
214
- border: 1px solid transparent;
215
- border-radius: 8px;
216
- padding: 7px 9px;
217
- }
218
-
219
- .session:hover {
220
- background: var(--panel-2);
221
- }
222
-
223
- .session.selected {
224
- background: linear-gradient(90deg, rgba(92, 200, 255, 0.14), rgba(92, 200, 255, 0.04));
225
- border-color: rgba(92, 200, 255, 0.35);
226
- }
227
-
228
- .session-top {
229
- display: flex;
230
- align-items: center;
231
- gap: 6px;
232
- }
233
-
234
- .session-title {
235
- flex: 1;
236
- overflow: hidden;
237
- text-overflow: ellipsis;
238
- white-space: nowrap;
239
- font-size: 12px;
240
- color: var(--text);
241
- }
242
-
243
- .session-meta {
244
- display: flex;
245
- flex-wrap: wrap;
246
- gap: 10px;
247
- margin-top: 2px;
248
- font-size: 10px;
249
- color: var(--muted-2);
250
- }
251
-
252
- .session-meta .model {
253
- color: var(--muted);
254
- }
255
-
256
- .dot {
257
- flex: none;
258
- width: 7px;
259
- height: 7px;
260
- border-radius: 50%;
261
- background: var(--green);
262
- box-shadow: 0 0 0 0 rgba(139, 212, 80, 0.6);
263
- animation: pulse 1.8s infinite;
264
- }
265
-
266
- .session.live .session-title {
267
- color: #eaf5ff;
268
- }
269
-
270
- .more {
271
- margin: 2px 0 4px;
272
- background: transparent;
273
- border: 1px dashed var(--border);
274
- border-radius: 8px;
275
- padding: 5px 8px;
276
- color: var(--muted);
277
- font-size: 11px;
278
- }
279
-
280
- .more:hover {
281
- color: var(--accent);
282
- border-color: rgba(92, 200, 255, 0.4);
283
- }
284
-
285
- /* ------------------------------------------------------------------- main */
286
-
287
- #main {
288
- flex: 1;
289
- display: flex;
290
- flex-direction: column;
291
- min-width: 0;
292
- min-height: 0;
293
- background:
294
- radial-gradient(1200px 500px at 80% -10%, rgba(92, 200, 255, 0.05), transparent 60%),
295
- var(--bg);
296
- }
297
-
298
- .main-header {
299
- display: flex;
300
- flex-shrink: 0;
301
- align-items: flex-start;
302
- gap: 16px;
303
- padding: 14px 22px 12px;
304
- border-bottom: 1px solid var(--border);
305
- background: rgba(13, 17, 25, 0.7);
306
- backdrop-filter: blur(6px);
307
- }
308
-
309
- .main-title {
310
- min-width: 0;
311
- flex: 1;
312
- }
313
-
314
- .back-to-menu {
315
- display: none;
316
- }
317
-
318
- .main-title h1 {
319
- margin: 0;
320
- font-size: 14px;
321
- font-weight: 600;
322
- letter-spacing: 0.01em;
323
- white-space: nowrap;
324
- overflow: hidden;
325
- text-overflow: ellipsis;
326
- }
327
-
328
- .sub {
329
- margin-top: 3px;
330
- font-size: 10.5px;
331
- color: var(--muted);
332
- white-space: nowrap;
333
- overflow: hidden;
334
- text-overflow: ellipsis;
335
- }
336
-
337
- .controls {
338
- display: flex;
339
- align-items: center;
340
- gap: 8px;
341
- flex-wrap: wrap;
342
- justify-content: flex-end;
343
- }
344
-
345
- .badge {
346
- font-size: 10px;
347
- letter-spacing: 0.06em;
348
- text-transform: uppercase;
349
- padding: 3px 8px;
350
- border-radius: 999px;
351
- border: 1px solid var(--border);
352
- color: var(--muted);
353
- background: var(--panel-2);
354
- }
355
-
356
- .badge.busy {
357
- color: var(--yellow);
358
- border-color: rgba(255, 212, 121, 0.4);
359
- background: rgba(255, 212, 121, 0.08);
360
- }
361
-
362
- .badge.paused {
363
- color: var(--red);
364
- border-color: rgba(255, 107, 129, 0.4);
365
- background: rgba(255, 107, 129, 0.08);
366
- }
367
-
368
- .badge.idle {
369
- color: var(--green);
370
- border-color: rgba(139, 212, 80, 0.3);
371
- background: rgba(139, 212, 80, 0.06);
372
- }
373
-
374
- /* A transcript loaded from disk: nothing is running, so nothing can be driven. */
375
- .badge.readonly {
376
- color: var(--muted);
377
- border-style: dashed;
378
- }
379
-
380
- .control {
381
- background: var(--panel-2);
382
- border: 1px solid var(--border);
383
- border-radius: 8px;
384
- padding: 4px 10px;
385
- color: var(--text);
386
- font-size: 11px;
387
- }
388
-
389
- .control:hover {
390
- border-color: rgba(92, 200, 255, 0.45);
391
- color: var(--accent);
392
- }
393
-
394
- .control.primary {
395
- border-color: rgba(92, 200, 255, 0.45);
396
- color: var(--accent);
397
- background: rgba(92, 200, 255, 0.1);
398
- }
399
-
400
- .control.primary:disabled {
401
- opacity: 0.6;
402
- cursor: default;
403
- }
404
-
405
- .queued,
406
- .tokens {
407
- font-size: 10px;
408
- color: var(--muted-2);
409
- border: 1px solid var(--border);
410
- border-radius: 999px;
411
- padding: 2px 8px;
412
- }
413
-
414
- .queued {
415
- color: var(--yellow);
416
- border-color: rgba(255, 212, 121, 0.3);
417
- }
418
-
419
- /* --------------------------------------------------------------- messages */
420
-
421
- .messages {
422
- flex: 1;
423
- min-height: 0;
424
- overflow-y: auto;
425
- padding: 22px clamp(16px, 6vw, 120px) 28px;
426
- }
427
-
428
- .empty {
429
- color: var(--muted-2);
430
- text-align: center;
431
- margin-top: 12vh;
432
- font-size: 12.5px;
433
- }
434
-
435
- .message {
436
- margin: 0 0 18px;
437
- max-width: 900px;
438
- }
439
-
440
- .message .who {
441
- font-size: 10px;
442
- letter-spacing: 0.12em;
443
- text-transform: uppercase;
444
- color: var(--muted);
445
- margin-bottom: 5px;
446
- }
447
-
448
- .message.user .who {
449
- color: var(--user);
450
- }
451
-
452
- .message.user .body {
453
- border-left: 2px solid rgba(139, 212, 80, 0.5);
454
- padding-left: 12px;
455
- }
456
-
457
- .message.assistant .body {
458
- border-left: 2px solid rgba(92, 200, 255, 0.35);
459
- padding-left: 12px;
460
- }
461
-
462
- .message .body {
463
- overflow-wrap: anywhere;
464
- }
465
-
466
- .message .body p {
467
- margin: 0 0 8px;
468
- }
469
-
470
- .message .body > *:last-child {
471
- margin-bottom: 0;
472
- }
473
-
474
- .message code {
475
- background: rgba(124, 156, 255, 0.12);
476
- border: 1px solid rgba(124, 156, 255, 0.18);
477
- border-radius: 5px;
478
- padding: 0 4px;
479
- font-size: 0.94em;
480
- color: #bfe3ff;
481
- }
482
-
483
- .message pre.code {
484
- margin: 10px 0;
485
- padding: 12px 14px;
486
- background: #070a10;
487
- border: 1px solid var(--border);
488
- border-radius: var(--radius);
489
- overflow-x: auto;
490
- }
491
-
492
- .message pre.code code {
493
- background: transparent;
494
- border: 0;
495
- padding: 0;
496
- color: #c7d6ec;
497
- }
498
-
499
- .message a {
500
- color: var(--accent);
501
- text-decoration: none;
502
- border-bottom: 1px solid rgba(92, 200, 255, 0.35);
503
- }
504
-
505
- .message.streaming .body::after {
506
- content: "▋";
507
- margin-left: 2px;
508
- color: var(--accent);
509
- animation: blink 1s steps(2, start) infinite;
510
- }
511
-
512
- .details,
513
- .message details.tool {
514
- background: var(--panel);
515
- border: 1px solid var(--border);
516
- border-radius: var(--radius);
517
- padding: 8px 12px;
518
- }
519
-
520
- .message details.tool summary {
521
- cursor: pointer;
522
- list-style: none;
523
- display: flex;
524
- align-items: baseline;
525
- gap: 10px;
526
- overflow: hidden;
527
- }
528
-
529
- .message details.tool summary::-webkit-details-marker {
530
- display: none;
531
- }
532
-
533
- .tool-name {
534
- flex: none;
535
- color: var(--accent-2);
536
- font-size: 11.5px;
537
- }
538
-
539
- .tool-args {
540
- flex: 1;
541
- overflow: hidden;
542
- text-overflow: ellipsis;
543
- white-space: nowrap;
544
- color: var(--muted-2);
545
- font-size: 11px;
546
- }
547
-
548
- .tool-result {
549
- margin: 10px 0 0;
550
- padding: 10px 12px;
551
- max-height: 420px;
552
- overflow: auto;
553
- background: #070a10;
554
- border: 1px solid var(--border-soft);
555
- border-radius: 8px;
556
- font-size: 11.5px;
557
- white-space: pre-wrap;
558
- overflow-wrap: anywhere;
559
- color: #aebcd4;
560
- }
561
-
562
- .message.summary .body {
563
- background: rgba(255, 212, 121, 0.05);
564
- border: 1px dashed rgba(255, 212, 121, 0.3);
565
- border-radius: var(--radius);
566
- padding: 10px 12px;
567
- color: #c9c2a8;
568
- }
569
-
570
- .summary-label {
571
- font-size: 10px;
572
- letter-spacing: 0.08em;
573
- text-transform: uppercase;
574
- color: var(--yellow);
575
- margin-bottom: 6px;
576
- }
577
-
578
- .conversation-history {
579
- border: 1px dashed var(--border);
580
- border-radius: var(--radius);
581
- padding: 10px 12px;
582
- }
583
-
584
- .conversation-history > summary {
585
- cursor: pointer;
586
- color: var(--yellow);
587
- font-size: 12px;
588
- }
589
-
590
- .history-messages {
591
- display: flex;
592
- flex-direction: column;
593
- gap: 18px;
594
- }
595
-
596
- .conversation-history[open] > summary {
597
- margin-bottom: 18px;
598
- }
599
-
600
- /* A finished turn: its work behind one control line, its reply always below. */
601
- .turn-group {
602
- display: flex;
603
- flex-direction: column;
604
- }
605
-
606
- .turn {
607
- border: 1px dashed var(--border-soft);
608
- border-radius: var(--radius);
609
- padding: 8px 12px;
610
- margin-bottom: 14px;
611
- }
612
-
613
- .turn > summary {
614
- cursor: pointer;
615
- list-style: none;
616
- display: flex;
617
- align-items: baseline;
618
- gap: 8px;
619
- overflow: hidden;
620
- }
621
-
622
- .turn > summary::-webkit-details-marker {
623
- display: none;
624
- }
625
-
626
- .turn-chevron {
627
- flex: none;
628
- display: inline-block;
629
- color: var(--yellow);
630
- transition: transform 0.15s;
631
- }
632
-
633
- .turn-you {
634
- flex: 1 1 auto;
635
- min-width: 0;
636
- overflow: hidden;
637
- text-overflow: ellipsis;
638
- white-space: nowrap;
639
- color: var(--user);
640
- }
641
-
642
- .turn-meta {
643
- flex: 0 1 auto;
644
- min-width: 0;
645
- overflow: hidden;
646
- text-overflow: ellipsis;
647
- white-space: nowrap;
648
- color: var(--muted-2);
649
- font-size: 11px;
650
- }
651
-
652
- .turn-hint {
653
- color: var(--muted);
654
- }
655
-
656
- .turn[open] > summary {
657
- margin-bottom: 14px;
658
- }
659
-
660
- .turn[open] .turn-chevron {
661
- transform: rotate(90deg);
662
- }
663
-
664
- .turn-messages {
665
- display: flex;
666
- flex-direction: column;
667
- }
668
-
669
- .turn-messages > .message:last-child {
670
- margin-bottom: 0;
671
- }
672
-
673
- /* --------------------------------------------------------------- composer */
674
-
675
- .composer {
676
- display: flex;
677
- flex-shrink: 0;
678
- gap: 10px;
679
- align-items: flex-end;
680
- padding: 12px clamp(16px, 6vw, 120px) 16px;
681
- border-top: 1px solid var(--border);
682
- background: linear-gradient(180deg, transparent, rgba(11, 14, 20, 0.9));
683
- }
684
-
685
- .composer textarea {
686
- flex: 1;
687
- min-width: 0;
688
- resize: none;
689
- min-height: 42px;
690
- max-height: 220px;
691
- padding: 11px 13px;
692
- background: var(--panel-2);
693
- color: var(--text);
694
- border: 1px solid var(--border);
695
- border-radius: var(--radius);
696
- font-family: inherit;
697
- font-size: 12.5px;
698
- line-height: 1.5;
699
- outline: none;
700
- }
701
-
702
- .composer textarea:focus {
703
- border-color: rgba(92, 200, 255, 0.5);
704
- box-shadow: 0 0 0 3px rgba(92, 200, 255, 0.08);
705
- }
706
-
707
- .primary {
708
- background: linear-gradient(135deg, #2f7fb5, #3c63c9);
709
- border: 1px solid rgba(92, 200, 255, 0.4);
710
- color: #eaf6ff;
711
- border-radius: var(--radius);
712
- padding: 11px 18px;
713
- font-size: 12px;
714
- letter-spacing: 0.03em;
715
- }
716
-
717
- .primary:hover {
718
- filter: brightness(1.12);
719
- }
720
-
721
- .primary:active {
722
- transform: translateY(1px);
723
- }
724
-
725
- /* --------------------------------------------------------------- scrollbar */
726
-
727
- * {
728
- scrollbar-width: thin;
729
- scrollbar-color: #2a3444 transparent;
730
- }
731
-
732
- *::-webkit-scrollbar {
733
- width: 9px;
734
- height: 9px;
735
- }
736
-
737
- *::-webkit-scrollbar-thumb {
738
- background: #263041;
739
- border-radius: 999px;
740
- border: 2px solid transparent;
741
- background-clip: content-box;
742
- }
743
-
744
- *::-webkit-scrollbar-thumb:hover {
745
- background: #33405a;
746
- background-clip: content-box;
747
- }
748
-
749
- @keyframes blink {
750
- 0%,
751
- 49% {
752
- opacity: 1;
753
- }
754
- 50%,
755
- 100% {
756
- opacity: 0;
757
- }
758
- }
759
-
760
- @keyframes pulse {
761
- 0% {
762
- box-shadow: 0 0 0 0 rgba(139, 212, 80, 0.55);
763
- }
764
- 70% {
765
- box-shadow: 0 0 0 6px rgba(139, 212, 80, 0);
766
- }
767
- 100% {
768
- box-shadow: 0 0 0 0 rgba(139, 212, 80, 0);
769
- }
770
- }
771
-
772
- /* ---- approval banner ------------------------------------------------- */
773
- /* Orange, like the TUI: an approval is a stop-the-line event. */
774
- .approval {
775
- flex-shrink: 0;
776
- max-height: min(58vh, 520px);
777
- min-height: 0;
778
- margin: 0 18px 10px;
779
- padding: 10px 14px;
780
- border: 1px solid #ff9e3d;
781
- border-left-width: 4px;
782
- border-radius: 8px;
783
- background: rgba(255, 158, 61, 0.12);
784
- color: #ffd8ac;
785
- font-size: 13px;
786
- display: flex;
787
- flex-direction: column;
788
- gap: 8px;
789
- }
790
-
791
- .approval.hidden {
792
- display: none;
793
- }
794
-
795
- .approval-head {
796
- flex-shrink: 0;
797
- display: flex;
798
- flex-wrap: wrap;
799
- align-items: center;
800
- justify-content: space-between;
801
- gap: 10px;
802
- color: #ff9e3d;
803
- }
804
-
805
- .approval-risk {
806
- font-size: 11px;
807
- letter-spacing: 0.08em;
808
- padding: 2px 8px;
809
- border-radius: 999px;
810
- background: #ff9e3d;
811
- color: #24160a;
812
- font-weight: 700;
813
- }
814
-
815
- .approval-details {
816
- min-height: 0;
817
- overflow: auto;
818
- overscroll-behavior: contain;
819
- }
820
-
821
- .approval-location {
822
- margin: 4px 0;
823
- font-size: 11px;
824
- overflow-wrap: anywhere;
825
- }
826
-
827
- .approval-code {
828
- margin: 6px 0;
829
- padding: 10px;
830
- border-radius: 5px;
831
- background: rgba(0, 0, 0, 0.22);
832
- font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
833
- font-size: 12px;
834
- white-space: pre-wrap;
835
- overflow-wrap: anywhere;
836
- word-break: break-word;
837
- user-select: text;
838
- }
839
-
840
- .approval-why {
841
- margin: 6px 0;
842
- font-size: 12px;
843
- line-height: 1.45;
844
- overflow-wrap: anywhere;
845
- user-select: text;
846
- }
847
-
848
- .approval-why strong { color: #ffd8ac; }
849
-
850
- .approval-arguments summary { cursor: pointer; }
851
- .approval-reasons { margin: 6px 0 0; padding-left: 20px; overflow-wrap: anywhere; }
852
-
853
- .approval-tool {
854
- font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
855
- color: #ffd8ac;
856
- word-break: break-word;
857
- }
858
-
859
- .approval-actions {
860
- flex-shrink: 0;
861
- display: flex;
862
- gap: 8px;
863
- }
864
-
865
- .approval-actions button {
866
- border: 1px solid #ff9e3d;
867
- background: transparent;
868
- color: #ff9e3d;
869
- border-radius: 6px;
870
- padding: 5px 14px;
871
- font: inherit;
872
- cursor: pointer;
873
- }
874
-
875
- .approval-actions .approve-btn {
876
- background: #ff9e3d;
877
- color: #24160a;
878
- font-weight: 700;
879
- }
880
-
881
- .approval-actions button:hover {
882
- filter: brightness(1.1);
883
- }
884
-
885
- /* -------------------------------------------------------------------- gate */
886
- /* Modal password login remains above the app and settings. */
887
-
888
- .gate {
889
- position: fixed;
890
- inset: 0;
891
- z-index: 100;
892
- width: 100vw;
893
- height: 100dvh;
894
- max-width: none;
895
- max-height: none;
896
- margin: 0;
897
- border: 0;
898
- color: var(--text);
899
- display: flex;
900
- align-items: center;
901
- justify-content: center;
902
- padding: 24px;
903
- background: rgba(6, 9, 14, 0.82);
904
- backdrop-filter: blur(3px);
905
- }
906
-
907
- .gate-card {
908
- width: min(420px, 100%);
909
- display: flex;
910
- flex-direction: column;
911
- gap: 12px;
912
- margin: 0;
913
- padding: 22px;
914
- background: var(--panel-2);
915
- border: 1px solid var(--border);
916
- border-radius: var(--radius);
917
- box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
918
- }
919
-
920
- .gate-card h2 {
921
- margin: 0;
922
- font-size: 14px;
923
- letter-spacing: 0.02em;
924
- }
925
-
926
- .gate-card p {
927
- margin: 0;
928
- color: var(--muted);
929
- font-size: 12px;
930
- }
931
-
932
- .gate-card code {
933
- color: var(--accent);
934
- }
935
-
936
- .gate-card input {
937
- font-family: var(--mono);
938
- font-size: 12px;
939
- color: var(--text);
940
- background: var(--bg);
941
- border: 1px solid var(--border);
942
- border-radius: var(--radius);
943
- padding: 10px 12px;
944
- }
945
-
946
- .gate-card input:focus {
947
- outline: none;
948
- border-color: rgba(92, 200, 255, 0.5);
949
- box-shadow: 0 0 0 3px rgba(92, 200, 255, 0.08);
950
- }
951
-
952
- /* ----------------------------------------------------- model and settings */
953
- .model-picker {
954
- display: flex;
955
- flex-shrink: 0;
956
- flex-wrap: wrap;
957
- align-items: end;
958
- gap: 10px;
959
- padding: 12px 22px 8px;
960
- border-bottom: 1px solid var(--border);
961
- }
962
-
963
- .model-picker label,
964
- .settings-fields label {
965
- display: flex;
966
- flex-direction: column;
967
- gap: 5px;
968
- color: var(--muted);
969
- font-size: 11px;
970
- min-width: 0;
971
- }
972
-
973
- .model-picker label { flex: 1 1 140px; }
974
- .model-picker label:nth-child(2) { flex-grow: 2; }
975
-
976
- .settings-fields input[type="password"],
977
- .settings-fields input[type="number"],
978
- select {
979
- width: 100%;
980
- padding: 7px 10px;
981
- border: 1px solid var(--border);
982
- border-radius: 7px;
983
- background: var(--panel-2);
984
- color: var(--text);
985
- font: inherit;
986
- font-size: 12px;
987
- }
988
-
989
- .settings-fields input[type="password"]:focus-visible,
990
- .settings-fields input[type="number"]:focus-visible,
991
- select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
992
- .form-feedback { flex: 1 0 100%; margin: 0; color: var(--muted); font-size: 11px; overflow-wrap: anywhere; }
993
- .form-feedback.error { color: var(--red); }
994
- .settings-dialog {
995
- width: min(620px, calc(100vw - 24px));
996
- max-height: calc(100vh - 24px);
997
- max-height: calc(100dvh - 24px);
998
- padding: 0;
999
- border: 1px solid var(--border);
1000
- border-radius: var(--radius);
1001
- background: var(--panel);
1002
- color: var(--text);
1003
- }
1004
- .settings-dialog::backdrop { background: rgba(0, 0, 0, 0.65); backdrop-filter: blur(3px); }
1005
- .settings-header { display: flex; justify-content: space-between; align-items: center; padding: 18px 22px; border-bottom: 1px solid var(--border); }
1006
- .settings-header h2 { margin: 0; font-size: 16px; }
1007
- .settings-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: 20px 22px; }
1008
- .settings-fields h3 { grid-column: 1 / -1; margin: 4px 0 0; font-size: 12px; font-weight: 500; color: var(--text); }
1009
- .settings-fields .checkbox-label { grid-column: 1 / -1; flex-direction: row; align-items: center; font-size: 12px; color: var(--text); }
1010
- .settings-note, .settings-fields .form-feedback { grid-column: 1 / -1; margin: 0; font-size: 11px; color: var(--muted); }
1011
- .settings-fields .form-feedback.error { color: var(--red); }
1012
- .settings-actions { display: flex; justify-content: end; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--border); }
1013
- /* Phones use one full-width pane: the conversation list opens first. */
1014
- @media (max-width: 760px) {
1015
- #sidebar {
1016
- width: 100%;
1017
- min-width: 0;
1018
- max-width: none;
1019
- border-right: 0;
1020
- padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
1021
- }
1022
-
1023
- #main { display: none; }
1024
- #app.conversation-open #sidebar { display: none; }
1025
- #app.conversation-open #main { display: flex; }
1026
-
1027
- #main {
1028
- padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
1029
- }
1030
-
1031
- .brand { padding: 12px; }
1032
- .icon-btn { width: 44px; height: 44px; flex: none; }
1033
- .session { padding: 12px 9px; min-height: 56px; }
1034
- .session-title { font-size: 13px; }
1035
- .group-header, .more { min-height: 44px; }
1036
-
1037
- .main-header {
1038
- display: grid;
1039
- grid-template-columns: 44px minmax(0, 1fr);
1040
- align-items: center;
1041
- gap: 8px 10px;
1042
- padding: 8px 12px;
1043
- }
1044
- .back-to-menu { display: grid; }
1045
- .back-to-menu:hover { transform: none; }
1046
- .back-to-menu:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1047
- .controls {
1048
- grid-column: 1 / -1;
1049
- justify-content: flex-start;
1050
- max-height: 20vh;
1051
- max-height: 20dvh;
1052
- overflow: auto;
1053
- }
1054
- .controls:empty { display: none; }
1055
- .controls .control { min-height: 36px; }
1056
- .controls label { min-width: 0; max-width: 100%; }
1057
-
1058
- .model-picker {
1059
- gap: 8px;
1060
- padding: 10px 12px;
1061
- max-height: 30vh;
1062
- max-height: 30dvh;
1063
- overflow: auto;
1064
- }
1065
- .model-picker label { flex: 1 1 calc(50% - 8px); }
1066
- .model-picker .control { flex: 1 1 calc(50% - 8px); min-height: 44px; }
1067
-
1068
- .messages { padding: 16px 12px; }
1069
- .composer { padding: 10px 12px; gap: 8px; }
1070
- .composer textarea { max-height: min(220px, 25dvh); }
1071
- .composer .primary { min-height: 44px; padding: 11px 12px; }
1072
- .approval { margin: 0 12px 8px; max-height: 35dvh; padding: 10px; }
1073
- .approval-actions { flex-wrap: wrap; }
1074
- .approval-actions button { min-height: 44px; }
1075
-
1076
- /* Keep inputs at 16px to avoid automatic zoom when focused on iOS. */
1077
- .composer textarea, .gate-card input, .settings-fields input, select { font-size: 16px; }
1078
- .settings-header, .settings-fields, .settings-actions { padding: 14px 16px; }
1079
- .settings-fields { grid-template-columns: 1fr; }
1080
- .settings-fields label, .settings-note { overflow-wrap: anywhere; }
1081
- .settings-actions button { min-height: 44px; }
1082
- .gate { padding: 16px; overflow-y: auto; }
1083
- .gate-card { margin: auto; }
1084
- }
1085
-
1086
- /* Short landscape screens and the onscreen keyboard leave less vertical room. */
1087
- @media (max-width: 760px) and (max-height: 600px) {
1088
- .main-header { flex-shrink: 1; min-height: 60px; overflow-y: auto; }
1089
- .model-picker { flex-shrink: 1; min-height: 44px; padding-top: 6px; padding-bottom: 6px; }
1090
- .messages { min-height: 40px; padding-top: 8px; padding-bottom: 8px; }
1091
- .approval { max-height: 30dvh; overflow-y: auto; }
1092
- .approval-details { min-height: 64px; }
1093
- }
1
+ /* ==========================================================================
2
+ Neutrino web console
3
+ A quiet, modern agent console: near-black canvas, hairline borders, white
4
+ primary actions and a single blue accent. Typography is the system UI stack;
5
+ monospace is reserved for code and tool output.
6
+ ========================================================================== */
7
+
8
+ :root {
9
+ color-scheme: dark;
10
+
11
+ /* Surfaces (DeepSeek Harness dark palette) */
12
+ --bg: #151517;
13
+ --bg-sidebar: #1b1b1c;
14
+ --surface-1: #232324;
15
+ --surface-2: #2c2c2e;
16
+ --surface-3: #353638;
17
+ --surface-code: #1b1b1c;
18
+ --surface-inline-code: #292929;
19
+
20
+ /* Lines */
21
+ --border: rgba(255, 255, 255, 0.12);
22
+ --border-soft: rgba(255, 255, 255, 0.06);
23
+ --border-strong: rgba(255, 255, 255, 0.18);
24
+
25
+ /* Text */
26
+ --text: #f9fafb;
27
+ --text-secondary: #cfd3d6;
28
+ --text-tertiary: #adb2b8;
29
+ --text-caption: #81858c;
30
+
31
+ /* Accents */
32
+ --accent: #7aaaff;
33
+ --accent-strong: #5686fe;
34
+ --accent-fill: rgba(122, 170, 255, 0.14);
35
+ --accent-line: rgba(122, 170, 255, 0.34);
36
+ --green: #4ed17e;
37
+ --amber: #f7ad31;
38
+ --red: #f25a5a;
39
+
40
+ /* Primary action is white on dark, like the reference consoles. */
41
+ --primary: #f9fafb;
42
+ --primary-hover: #ffffff;
43
+ --primary-fg: #0f1115;
44
+
45
+ /* Shape */
46
+ --radius-xs: 6px;
47
+ --radius-sm: 8px;
48
+ --radius-md: 12px;
49
+ --radius-lg: 16px;
50
+ --radius-xl: 20px;
51
+ --radius-panel: 24px;
52
+ --chat-width: 800px;
53
+
54
+ --shadow-soft:
55
+ 0 4px 16px rgba(0, 0, 0, 0.24),
56
+ 0 0 24px rgba(0, 0, 0, 0.12);
57
+ --shadow-strong:
58
+ 0 18px 48px rgba(0, 0, 0, 0.55),
59
+ 0 2px 8px rgba(0, 0, 0, 0.35);
60
+
61
+ --font:
62
+ -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
63
+ "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial,
64
+ sans-serif;
65
+ --mono:
66
+ "SF Mono", "JetBrains Mono", "Fira Code", Consolas, "Liberation Mono",
67
+ Menlo, Courier, monospace;
68
+
69
+ --ease: cubic-bezier(0.4, 0, 0.2, 1);
70
+ --fast: 0.14s var(--ease);
71
+ }
72
+
73
+ * {
74
+ box-sizing: border-box;
75
+ }
76
+
77
+ html,
78
+ body {
79
+ height: 100%;
80
+ margin: 0;
81
+ }
82
+
83
+ body {
84
+ font-family: var(--font);
85
+ font-size: 14px;
86
+ line-height: 1.5;
87
+ background: var(--bg);
88
+ color: var(--text);
89
+ overflow: hidden;
90
+ -webkit-font-smoothing: antialiased;
91
+ -moz-osx-font-smoothing: grayscale;
92
+ text-rendering: optimizeLegibility;
93
+ }
94
+
95
+ button,
96
+ input,
97
+ textarea,
98
+ select {
99
+ font: inherit;
100
+ color: inherit;
101
+ }
102
+
103
+ button {
104
+ cursor: pointer;
105
+ -webkit-tap-highlight-color: transparent;
106
+ }
107
+
108
+ button:disabled {
109
+ cursor: default;
110
+ }
111
+
112
+ a {
113
+ color: var(--accent);
114
+ text-decoration: none;
115
+ }
116
+
117
+ a:hover {
118
+ text-decoration: underline;
119
+ text-underline-offset: 2px;
120
+ }
121
+
122
+ svg {
123
+ display: block;
124
+ }
125
+
126
+ ::selection {
127
+ background: rgba(122, 170, 255, 0.32);
128
+ color: #ffffff;
129
+ }
130
+
131
+ :focus-visible {
132
+ outline: 2px solid var(--accent);
133
+ outline-offset: 2px;
134
+ }
135
+
136
+ .hidden {
137
+ display: none !important;
138
+ }
139
+
140
+ #app {
141
+ display: flex;
142
+ width: 100%;
143
+ height: 100vh;
144
+ height: 100dvh;
145
+ }
146
+
147
+ /* ---------------------------------------------------------------- sidebar */
148
+
149
+ #sidebar {
150
+ display: flex;
151
+ flex-direction: column;
152
+ flex-shrink: 0;
153
+ width: 288px;
154
+ min-width: 260px;
155
+ max-width: 40vw;
156
+ background: var(--bg-sidebar);
157
+ border-right: 1px solid var(--border-soft);
158
+ }
159
+
160
+ .brand {
161
+ display: flex;
162
+ flex-shrink: 0;
163
+ align-items: center;
164
+ gap: 10px;
165
+ height: 64px;
166
+ padding: 0 10px 0 16px;
167
+ border-bottom: 1px solid var(--border-soft);
168
+ }
169
+
170
+ .logo {
171
+ display: grid;
172
+ place-items: center;
173
+ flex: none;
174
+ width: 30px;
175
+ height: 30px;
176
+ border-radius: 9px;
177
+ background: var(--surface-1);
178
+ border: 1px solid var(--border-soft);
179
+ color: var(--text);
180
+ }
181
+
182
+ .logo svg {
183
+ width: 18px;
184
+ height: 18px;
185
+ }
186
+
187
+ .brand-text {
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: 1px;
191
+ flex: 1;
192
+ min-width: 0;
193
+ line-height: 1.2;
194
+ }
195
+
196
+ .brand-text strong {
197
+ font-size: 14px;
198
+ font-weight: 600;
199
+ letter-spacing: 0.01em;
200
+ color: var(--text);
201
+ }
202
+
203
+ .status {
204
+ display: inline-flex;
205
+ align-items: center;
206
+ gap: 5px;
207
+ font-size: 11.5px;
208
+ color: var(--text-caption);
209
+ text-transform: capitalize;
210
+ white-space: nowrap;
211
+ overflow: hidden;
212
+ text-overflow: ellipsis;
213
+ }
214
+
215
+ .status::before {
216
+ content: "";
217
+ flex: none;
218
+ width: 6px;
219
+ height: 6px;
220
+ border-radius: 50%;
221
+ background: currentColor;
222
+ }
223
+
224
+ .status.online {
225
+ color: var(--green);
226
+ }
227
+
228
+ .status.live {
229
+ color: var(--accent);
230
+ }
231
+
232
+ .status.offline {
233
+ color: var(--red);
234
+ }
235
+
236
+ .brand-actions {
237
+ display: flex;
238
+ align-items: center;
239
+ gap: 2px;
240
+ flex: none;
241
+ }
242
+
243
+ .icon-btn {
244
+ display: grid;
245
+ place-items: center;
246
+ flex: none;
247
+ width: 30px;
248
+ height: 30px;
249
+ padding: 0;
250
+ background: transparent;
251
+ border: 0;
252
+ border-radius: var(--radius-sm);
253
+ color: var(--text-tertiary);
254
+ transition: background var(--fast), color var(--fast);
255
+ }
256
+
257
+ .icon-btn svg {
258
+ width: 16px;
259
+ height: 16px;
260
+ }
261
+
262
+ .icon-btn:hover {
263
+ background: var(--surface-1);
264
+ color: var(--text);
265
+ }
266
+
267
+ .icon-btn:active {
268
+ transform: scale(0.96);
269
+ }
270
+
271
+ .sessions {
272
+ flex: 1;
273
+ min-height: 0;
274
+ overflow-y: auto;
275
+ padding: 10px 8px 20px;
276
+ overscroll-behavior: contain;
277
+ }
278
+
279
+ .sidebar-foot {
280
+ flex: none;
281
+ padding: 10px 16px;
282
+ border-top: 1px solid var(--border-soft);
283
+ color: var(--text-caption);
284
+ font-size: 11px;
285
+ letter-spacing: 0.01em;
286
+ }
287
+
288
+ .empty-side {
289
+ padding: 24px 12px;
290
+ color: var(--text-caption);
291
+ font-size: 12.5px;
292
+ }
293
+
294
+ .group {
295
+ margin-bottom: 4px;
296
+ }
297
+
298
+ .group-header {
299
+ display: flex;
300
+ align-items: center;
301
+ gap: 7px;
302
+ width: 100%;
303
+ height: 30px;
304
+ padding: 0 8px;
305
+ background: transparent;
306
+ border: 0;
307
+ border-radius: var(--radius-sm);
308
+ color: var(--text-caption);
309
+ text-align: left;
310
+ transition: background var(--fast), color var(--fast);
311
+ }
312
+
313
+ .group-header:hover {
314
+ background: var(--surface-1);
315
+ color: var(--text-secondary);
316
+ }
317
+
318
+ .chevron {
319
+ display: grid;
320
+ place-items: center;
321
+ flex: none;
322
+ width: 14px;
323
+ height: 14px;
324
+ color: var(--text-caption);
325
+ }
326
+
327
+ .chevron svg {
328
+ width: 14px;
329
+ height: 14px;
330
+ transition: transform var(--fast);
331
+ }
332
+
333
+ .chevron:not(.collapsed) svg {
334
+ transform: rotate(90deg);
335
+ }
336
+
337
+ .group-header .path {
338
+ flex: 1;
339
+ min-width: 0;
340
+ overflow: hidden;
341
+ white-space: nowrap;
342
+ text-overflow: ellipsis;
343
+ font-size: 12px;
344
+ }
345
+
346
+ .group-header .count {
347
+ flex: none;
348
+ min-width: 20px;
349
+ padding: 0 6px;
350
+ border-radius: 999px;
351
+ background: var(--surface-1);
352
+ color: var(--text-caption);
353
+ font-size: 10.5px;
354
+ line-height: 18px;
355
+ text-align: center;
356
+ }
357
+
358
+ .group-items {
359
+ display: flex;
360
+ flex-direction: column;
361
+ gap: 1px;
362
+ margin: 2px 0 6px;
363
+ padding: 2px 0 2px 6px;
364
+ }
365
+
366
+ .session {
367
+ display: block;
368
+ width: 100%;
369
+ padding: 8px 10px;
370
+ background: transparent;
371
+ border: 0;
372
+ border-radius: 10px;
373
+ color: inherit;
374
+ text-align: left;
375
+ transition: background var(--fast);
376
+ }
377
+
378
+ .session:hover {
379
+ background: var(--surface-1);
380
+ }
381
+
382
+ .session.selected {
383
+ background: var(--surface-2);
384
+ }
385
+
386
+ .session-top {
387
+ display: flex;
388
+ align-items: center;
389
+ gap: 8px;
390
+ min-width: 0;
391
+ }
392
+
393
+ .session-title {
394
+ flex: 1;
395
+ min-width: 0;
396
+ overflow: hidden;
397
+ white-space: nowrap;
398
+ text-overflow: ellipsis;
399
+ font-size: 13px;
400
+ color: var(--text-secondary);
401
+ }
402
+
403
+ .session.selected .session-title,
404
+ .session.live .session-title {
405
+ color: var(--text);
406
+ }
407
+
408
+ .session-meta {
409
+ display: flex;
410
+ align-items: center;
411
+ min-width: 0;
412
+ margin-top: 3px;
413
+ overflow: hidden;
414
+ white-space: nowrap;
415
+ font-size: 11px;
416
+ color: var(--text-caption);
417
+ }
418
+
419
+ .session-meta > span {
420
+ overflow: hidden;
421
+ text-overflow: ellipsis;
422
+ }
423
+
424
+ .session-meta > span + span::before {
425
+ content: "·";
426
+ margin: 0 6px;
427
+ color: var(--text-caption);
428
+ }
429
+
430
+ .session-meta .model {
431
+ color: var(--text-tertiary);
432
+ }
433
+
434
+ .dot {
435
+ flex: none;
436
+ width: 6px;
437
+ height: 6px;
438
+ border-radius: 50%;
439
+ background: var(--accent);
440
+ animation: pulse 2s var(--ease) infinite;
441
+ }
442
+
443
+ .more {
444
+ width: 100%;
445
+ margin: 1px 0 2px;
446
+ padding: 6px 10px;
447
+ background: transparent;
448
+ border: 0;
449
+ border-radius: var(--radius-sm);
450
+ color: var(--text-caption);
451
+ font-size: 11.5px;
452
+ text-align: left;
453
+ transition: background var(--fast), color var(--fast);
454
+ }
455
+
456
+ .more:hover {
457
+ background: var(--surface-1);
458
+ color: var(--text-secondary);
459
+ }
460
+
461
+ /* ------------------------------------------------------------------- main */
462
+
463
+ #main {
464
+ display: flex;
465
+ flex-direction: column;
466
+ flex: 1;
467
+ min-width: 0;
468
+ min-height: 0;
469
+ background: var(--bg);
470
+ }
471
+
472
+ .main-header {
473
+ display: flex;
474
+ flex-shrink: 0;
475
+ align-items: center;
476
+ gap: 14px;
477
+ min-height: 64px;
478
+ padding: 10px clamp(16px, 4vw, 32px);
479
+ border-bottom: 1px solid var(--border-soft);
480
+ }
481
+
482
+ .main-title {
483
+ flex: 1;
484
+ min-width: 0;
485
+ }
486
+
487
+ .back-to-menu {
488
+ display: none;
489
+ }
490
+
491
+ .main-title h1 {
492
+ margin: 0;
493
+ overflow: hidden;
494
+ white-space: nowrap;
495
+ text-overflow: ellipsis;
496
+ font-size: 14px;
497
+ font-weight: 600;
498
+ letter-spacing: 0.005em;
499
+ color: var(--text);
500
+ }
501
+
502
+ .sub {
503
+ margin-top: 2px;
504
+ overflow: hidden;
505
+ white-space: nowrap;
506
+ text-overflow: ellipsis;
507
+ font-size: 12px;
508
+ color: var(--text-caption);
509
+ }
510
+
511
+ .controls {
512
+ display: flex;
513
+ flex-wrap: wrap;
514
+ align-items: center;
515
+ justify-content: flex-end;
516
+ gap: 6px;
517
+ }
518
+
519
+ .badge {
520
+ display: inline-flex;
521
+ align-items: center;
522
+ gap: 6px;
523
+ height: 26px;
524
+ padding: 0 10px;
525
+ border-radius: 999px;
526
+ background: var(--surface-1);
527
+ color: var(--text-tertiary);
528
+ font-size: 11.5px;
529
+ font-weight: 500;
530
+ text-transform: capitalize;
531
+ white-space: nowrap;
532
+ }
533
+
534
+ .badge::before {
535
+ content: "";
536
+ flex: none;
537
+ width: 6px;
538
+ height: 6px;
539
+ border-radius: 50%;
540
+ background: currentColor;
541
+ }
542
+
543
+ .badge.busy {
544
+ color: var(--amber);
545
+ background: rgba(247, 173, 49, 0.12);
546
+ }
547
+
548
+ .badge.busy::before {
549
+ animation: pulse-amber 1.6s ease-out infinite;
550
+ }
551
+
552
+ .badge.paused {
553
+ color: var(--red);
554
+ background: rgba(242, 90, 90, 0.12);
555
+ }
556
+
557
+ .badge.idle {
558
+ color: var(--green);
559
+ background: rgba(78, 209, 126, 0.1);
560
+ }
561
+
562
+ .badge.readonly {
563
+ border: 1px solid var(--border);
564
+ background: transparent;
565
+ text-transform: none;
566
+ }
567
+
568
+ .badge.readonly::before {
569
+ display: none;
570
+ }
571
+
572
+ .control {
573
+ display: inline-flex;
574
+ align-items: center;
575
+ justify-content: center;
576
+ gap: 6px;
577
+ height: 30px;
578
+ padding: 0 12px;
579
+ background: transparent;
580
+ border: 1px solid var(--border);
581
+ border-radius: var(--radius-sm);
582
+ color: var(--text-secondary);
583
+ font-size: 12.5px;
584
+ font-weight: 500;
585
+ white-space: nowrap;
586
+ transition: background var(--fast), border-color var(--fast), color var(--fast);
587
+ }
588
+
589
+ .control:hover {
590
+ background: var(--surface-1);
591
+ border-color: var(--border-strong);
592
+ color: var(--text);
593
+ }
594
+
595
+ .control:disabled {
596
+ opacity: 0.5;
597
+ }
598
+
599
+ .control.primary {
600
+ height: 30px;
601
+ padding: 0 12px;
602
+ border-radius: var(--radius-sm);
603
+ background: var(--primary);
604
+ border-color: transparent;
605
+ color: var(--primary-fg);
606
+ font-size: 12.5px;
607
+ }
608
+
609
+ .control.primary:hover {
610
+ background: var(--primary-hover);
611
+ border-color: transparent;
612
+ color: var(--primary-fg);
613
+ }
614
+
615
+ .primary {
616
+ display: inline-flex;
617
+ align-items: center;
618
+ justify-content: center;
619
+ gap: 8px;
620
+ height: 38px;
621
+ padding: 0 16px;
622
+ background: var(--primary);
623
+ border: 0;
624
+ border-radius: 10px;
625
+ color: var(--primary-fg);
626
+ font-family: var(--font);
627
+ font-size: 13px;
628
+ font-weight: 500;
629
+ transition: background var(--fast), transform var(--fast);
630
+ }
631
+
632
+ .primary:hover {
633
+ background: var(--primary-hover);
634
+ }
635
+
636
+ .primary:active {
637
+ transform: translateY(1px);
638
+ }
639
+
640
+ .primary:disabled {
641
+ opacity: 0.55;
642
+ }
643
+
644
+ .queued,
645
+ .tokens {
646
+ display: inline-flex;
647
+ align-items: center;
648
+ height: 24px;
649
+ padding: 0 9px;
650
+ border-radius: 999px;
651
+ background: var(--surface-1);
652
+ color: var(--text-caption);
653
+ font-size: 11px;
654
+ white-space: nowrap;
655
+ }
656
+
657
+ .queued {
658
+ color: var(--amber);
659
+ background: rgba(247, 173, 49, 0.1);
660
+ }
661
+
662
+ /* --------------------------------------------------------------- messages */
663
+
664
+ .messages {
665
+ flex: 1;
666
+ min-height: 0;
667
+ overflow-y: auto;
668
+ overflow-x: hidden;
669
+ padding: 26px clamp(16px, 4vw, 40px) 28px;
670
+ }
671
+
672
+ .message,
673
+ .turn-group,
674
+ .conversation-history {
675
+ width: 100%;
676
+ max-width: var(--chat-width);
677
+ margin-left: auto;
678
+ margin-right: auto;
679
+ }
680
+
681
+ .empty {
682
+ display: flex;
683
+ flex-direction: column;
684
+ align-items: center;
685
+ gap: 7px;
686
+ max-width: 420px;
687
+ margin: 16vh auto 0;
688
+ padding: 0 12px;
689
+ color: var(--text-caption);
690
+ font-size: 13px;
691
+ line-height: 1.6;
692
+ text-align: center;
693
+ }
694
+
695
+ .empty strong {
696
+ color: var(--text-secondary);
697
+ font-size: 14px;
698
+ font-weight: 500;
699
+ }
700
+
701
+ .empty-mark {
702
+ display: grid;
703
+ place-items: center;
704
+ width: 44px;
705
+ height: 44px;
706
+ margin-bottom: 3px;
707
+ border-radius: 14px;
708
+ background: var(--surface-1);
709
+ border: 1px solid var(--border-soft);
710
+ color: var(--text-tertiary);
711
+ }
712
+
713
+ .empty-mark svg {
714
+ width: 22px;
715
+ height: 22px;
716
+ }
717
+
718
+ .message {
719
+ margin-bottom: 22px;
720
+ font-size: 14.5px;
721
+ }
722
+
723
+ .message .who {
724
+ display: none;
725
+ }
726
+
727
+ .message .body {
728
+ overflow-wrap: anywhere;
729
+ }
730
+
731
+ .message.assistant .body {
732
+ color: var(--text);
733
+ line-height: 1.72;
734
+ }
735
+
736
+ .message.user {
737
+ display: flex;
738
+ flex-direction: column;
739
+ align-items: flex-end;
740
+ }
741
+
742
+ .message.user .body {
743
+ max-width: min(82%, 640px);
744
+ padding: 10px 16px;
745
+ border-radius: var(--radius-xl);
746
+ background: var(--surface-2);
747
+ color: var(--text);
748
+ line-height: 1.65;
749
+ white-space: pre-wrap;
750
+ }
751
+
752
+ .message .body p {
753
+ margin: 0 0 10px;
754
+ }
755
+
756
+ .message .body p:last-child,
757
+ .message .body > *:last-child {
758
+ margin-bottom: 0;
759
+ }
760
+
761
+ .message .body ul,
762
+ .message .body ol {
763
+ margin: 0 0 10px;
764
+ padding-left: 22px;
765
+ }
766
+
767
+ .message .body blockquote {
768
+ margin: 10px 0;
769
+ padding: 2px 0 2px 12px;
770
+ border-left: 2px solid var(--border-strong);
771
+ color: var(--text-tertiary);
772
+ }
773
+
774
+ .message strong {
775
+ color: var(--text);
776
+ font-weight: 600;
777
+ }
778
+
779
+ .message em {
780
+ color: var(--text-secondary);
781
+ }
782
+
783
+ .message code {
784
+ padding: 1px 5px;
785
+ border-radius: var(--radius-xs);
786
+ background: var(--surface-inline-code);
787
+ color: #e9ebee;
788
+ font-family: var(--mono);
789
+ font-size: 0.88em;
790
+ white-space: break-spaces;
791
+ }
792
+
793
+ .message pre.code {
794
+ margin: 12px 0;
795
+ padding: 13px 16px;
796
+ overflow-x: auto;
797
+ background: var(--surface-code);
798
+ border: 1px solid var(--border-soft);
799
+ border-radius: var(--radius-md);
800
+ line-height: 1.65;
801
+ }
802
+
803
+ .message pre.code code {
804
+ padding: 0;
805
+ background: transparent;
806
+ color: var(--text-secondary);
807
+ font-size: 12.5px;
808
+ white-space: pre;
809
+ }
810
+
811
+ .message a {
812
+ color: var(--accent);
813
+ }
814
+
815
+ .message.streaming .body::after {
816
+ content: "";
817
+ display: inline-block;
818
+ width: 2px;
819
+ height: 1em;
820
+ margin-left: 3px;
821
+ vertical-align: -0.14em;
822
+ border-radius: 1px;
823
+ background: var(--accent);
824
+ animation: blink 1s steps(2, start) infinite;
825
+ }
826
+
827
+ /* Tool calls ----------------------------------------------------------------- */
828
+
829
+ .message.tool {
830
+ margin-bottom: 8px;
831
+ font-size: 13px;
832
+ }
833
+
834
+ .message details.tool {
835
+ padding: 0 12px;
836
+ background: var(--surface-code);
837
+ border: 1px solid var(--border-soft);
838
+ border-radius: var(--radius-md);
839
+ transition: border-color var(--fast);
840
+ }
841
+
842
+ .message details.tool:hover {
843
+ border-color: var(--border);
844
+ }
845
+
846
+ .message details.tool[open] {
847
+ border-color: var(--border);
848
+ }
849
+
850
+ .message details.tool summary {
851
+ display: flex;
852
+ align-items: center;
853
+ gap: 8px;
854
+ min-height: 38px;
855
+ padding: 8px 0;
856
+ overflow: hidden;
857
+ list-style: none;
858
+ cursor: pointer;
859
+ }
860
+
861
+ .message details.tool summary::-webkit-details-marker {
862
+ display: none;
863
+ }
864
+
865
+ .tool-name {
866
+ display: inline-flex;
867
+ align-items: center;
868
+ gap: 7px;
869
+ flex: none;
870
+ color: var(--text-secondary);
871
+ font-size: 12.5px;
872
+ font-weight: 500;
873
+ }
874
+
875
+ .tool-name svg {
876
+ width: 14px;
877
+ height: 14px;
878
+ color: var(--text-tertiary);
879
+ }
880
+
881
+ .tool-args {
882
+ flex: 1;
883
+ min-width: 0;
884
+ overflow: hidden;
885
+ white-space: nowrap;
886
+ text-overflow: ellipsis;
887
+ color: var(--text-caption);
888
+ font-family: var(--mono);
889
+ font-size: 11.5px;
890
+ }
891
+
892
+ .tool-result {
893
+ margin: 0 0 12px;
894
+ padding: 12px 14px;
895
+ max-height: 420px;
896
+ overflow: auto;
897
+ background: var(--bg);
898
+ border: 1px solid var(--border-soft);
899
+ border-radius: 10px;
900
+ color: var(--text-tertiary);
901
+ font-family: var(--mono);
902
+ font-size: 12px;
903
+ line-height: 1.65;
904
+ white-space: pre-wrap;
905
+ overflow-wrap: anywhere;
906
+ }
907
+
908
+ /* Context summaries and compressed history ----------------------------------- */
909
+
910
+ .message.summary .body {
911
+ padding: 12px 14px;
912
+ border: 1px solid rgba(247, 173, 49, 0.18);
913
+ border-radius: var(--radius-md);
914
+ background: rgba(247, 173, 49, 0.05);
915
+ color: var(--text-secondary);
916
+ line-height: 1.7;
917
+ }
918
+
919
+ .summary-label {
920
+ margin-bottom: 6px;
921
+ color: var(--amber);
922
+ font-size: 11.5px;
923
+ font-weight: 500;
924
+ }
925
+
926
+ .conversation-history {
927
+ padding: 0 14px;
928
+ border: 1px solid var(--border-soft);
929
+ border-radius: var(--radius-md);
930
+ background: rgba(255, 255, 255, 0.015);
931
+ }
932
+
933
+ .conversation-history > summary {
934
+ display: flex;
935
+ align-items: center;
936
+ gap: 8px;
937
+ padding: 12px 0;
938
+ list-style: none;
939
+ cursor: pointer;
940
+ color: var(--text-tertiary);
941
+ font-size: 12.5px;
942
+ font-weight: 500;
943
+ }
944
+
945
+ .conversation-history > summary::-webkit-details-marker {
946
+ display: none;
947
+ }
948
+
949
+ .conversation-history > summary:hover {
950
+ color: var(--text-secondary);
951
+ }
952
+
953
+ .conversation-history > summary::before {
954
+ content: "";
955
+ flex: none;
956
+ width: 0;
957
+ height: 0;
958
+ border-top: 4px solid transparent;
959
+ border-bottom: 4px solid transparent;
960
+ border-left: 5px solid currentColor;
961
+ transition: transform var(--fast);
962
+ }
963
+
964
+ .conversation-history[open] > summary::before {
965
+ transform: rotate(90deg);
966
+ }
967
+
968
+ .conversation-history[open] > summary {
969
+ margin-bottom: 14px;
970
+ border-bottom: 1px solid var(--border-soft);
971
+ color: var(--text-secondary);
972
+ }
973
+
974
+ .history-messages {
975
+ display: flex;
976
+ flex-direction: column;
977
+ padding-bottom: 6px;
978
+ }
979
+
980
+ .history-messages .message,
981
+ .turn-messages .message {
982
+ max-width: none;
983
+ }
984
+
985
+ /* Folded turns --------------------------------------------------------------- */
986
+
987
+ .turn-group {
988
+ display: flex;
989
+ flex-direction: column;
990
+ }
991
+
992
+ .turn {
993
+ margin-bottom: 4px;
994
+ border: 0;
995
+ border-radius: 10px;
996
+ }
997
+
998
+ .turn > summary {
999
+ display: flex;
1000
+ align-items: center;
1001
+ gap: 8px;
1002
+ padding: 7px 10px;
1003
+ border-radius: 10px;
1004
+ overflow: hidden;
1005
+ list-style: none;
1006
+ cursor: pointer;
1007
+ transition: background var(--fast);
1008
+ }
1009
+
1010
+ .turn > summary:hover {
1011
+ background: var(--surface-1);
1012
+ }
1013
+
1014
+ .turn > summary::-webkit-details-marker {
1015
+ display: none;
1016
+ }
1017
+
1018
+ .turn-chevron {
1019
+ display: grid;
1020
+ place-items: center;
1021
+ flex: none;
1022
+ width: 14px;
1023
+ height: 14px;
1024
+ color: var(--text-caption);
1025
+ transition: transform var(--fast);
1026
+ }
1027
+
1028
+ .turn-chevron svg {
1029
+ width: 14px;
1030
+ height: 14px;
1031
+ }
1032
+
1033
+ .turn[open] .turn-chevron {
1034
+ transform: rotate(90deg);
1035
+ }
1036
+
1037
+ .turn-you {
1038
+ flex: 1 1 auto;
1039
+ min-width: 0;
1040
+ overflow: hidden;
1041
+ white-space: nowrap;
1042
+ text-overflow: ellipsis;
1043
+ color: var(--text-secondary);
1044
+ font-size: 12.5px;
1045
+ }
1046
+
1047
+ .turn-meta {
1048
+ flex: 0 1 auto;
1049
+ min-width: 0;
1050
+ overflow: hidden;
1051
+ white-space: nowrap;
1052
+ text-overflow: ellipsis;
1053
+ color: var(--text-caption);
1054
+ font-size: 11.5px;
1055
+ }
1056
+
1057
+ .turn-hint {
1058
+ color: var(--text-caption);
1059
+ }
1060
+
1061
+ .turn[open] > summary {
1062
+ margin-bottom: 12px;
1063
+ }
1064
+
1065
+ .turn-messages {
1066
+ display: flex;
1067
+ flex-direction: column;
1068
+ margin-left: 7px;
1069
+ padding-left: 20px;
1070
+ border-left: 1px solid var(--border-soft);
1071
+ }
1072
+
1073
+ .turn-messages > .message:last-child {
1074
+ margin-bottom: 16px;
1075
+ }
1076
+
1077
+ /* --------------------------------------------------------------- composer */
1078
+
1079
+ .composer {
1080
+ flex-shrink: 0;
1081
+ padding: 0 clamp(16px, 4vw, 40px) 18px;
1082
+ background: linear-gradient(180deg, rgba(21, 21, 23, 0), var(--bg) 38%);
1083
+ }
1084
+
1085
+ .composer-inner {
1086
+ width: 100%;
1087
+ max-width: var(--chat-width);
1088
+ margin: 0 auto;
1089
+ }
1090
+
1091
+ .composer-card {
1092
+ display: flex;
1093
+ align-items: flex-end;
1094
+ gap: 8px;
1095
+ padding: 8px 8px 8px 16px;
1096
+ background: var(--surface-2);
1097
+ border: 1px solid var(--border-soft);
1098
+ border-radius: var(--radius-panel);
1099
+ box-shadow: var(--shadow-soft);
1100
+ transition: border-color var(--fast), box-shadow var(--fast);
1101
+ }
1102
+
1103
+ .composer-card:focus-within {
1104
+ border-color: var(--accent-line);
1105
+ box-shadow:
1106
+ 0 0 0 3px rgba(122, 170, 255, 0.09),
1107
+ var(--shadow-soft);
1108
+ }
1109
+
1110
+ .composer textarea {
1111
+ flex: 1;
1112
+ min-width: 0;
1113
+ min-height: 36px;
1114
+ max-height: 240px;
1115
+ margin: 0;
1116
+ padding: 7px 0;
1117
+ resize: none;
1118
+ background: transparent;
1119
+ border: 0;
1120
+ outline: none;
1121
+ color: var(--text);
1122
+ font-family: var(--font);
1123
+ font-size: 14px;
1124
+ line-height: 22px;
1125
+ }
1126
+
1127
+ .composer textarea::placeholder {
1128
+ color: var(--text-caption);
1129
+ }
1130
+
1131
+ .composer textarea:focus-visible {
1132
+ outline: none;
1133
+ }
1134
+
1135
+ #send {
1136
+ display: grid;
1137
+ place-items: center;
1138
+ flex: none;
1139
+ width: 36px;
1140
+ height: 36px;
1141
+ padding: 0;
1142
+ border: 0;
1143
+ border-radius: 50%;
1144
+ background: var(--primary);
1145
+ color: var(--primary-fg);
1146
+ transition: background var(--fast), transform var(--fast);
1147
+ }
1148
+
1149
+ #send svg {
1150
+ width: 18px;
1151
+ height: 18px;
1152
+ }
1153
+
1154
+ #send:hover {
1155
+ background: var(--primary-hover);
1156
+ }
1157
+
1158
+ #send:active {
1159
+ transform: scale(0.95);
1160
+ }
1161
+
1162
+ .composer-hint {
1163
+ margin-top: 8px;
1164
+ color: var(--text-caption);
1165
+ font-size: 11.5px;
1166
+ text-align: center;
1167
+ }
1168
+
1169
+ .composer-hint kbd {
1170
+ padding: 1px 5px;
1171
+ border: 1px solid var(--border-soft);
1172
+ border-bottom-color: var(--border);
1173
+ border-radius: 5px;
1174
+ background: var(--surface-1);
1175
+ color: var(--text-tertiary);
1176
+ font-family: var(--font);
1177
+ font-size: 10.5px;
1178
+ }
1179
+
1180
+ /* --------------------------------------------------------------- approval */
1181
+
1182
+ .approval {
1183
+ display: flex;
1184
+ flex-direction: column;
1185
+ gap: 10px;
1186
+ width: calc(100% - 2 * clamp(16px, 4vw, 40px));
1187
+ max-width: var(--chat-width);
1188
+ max-height: min(58vh, 520px);
1189
+ min-height: 0;
1190
+ margin: 0 auto 12px;
1191
+ padding: 14px 16px;
1192
+ border: 1px solid rgba(247, 173, 49, 0.22);
1193
+ border-radius: var(--radius-lg);
1194
+ background: #201b15;
1195
+ background: color-mix(in srgb, #f7ad31 5%, var(--bg-sidebar));
1196
+ box-shadow: var(--shadow-soft);
1197
+ }
1198
+
1199
+ .approval.hidden {
1200
+ display: none;
1201
+ }
1202
+
1203
+ .approval.extreme {
1204
+ border-color: rgba(242, 90, 90, 0.3);
1205
+ background: #221616;
1206
+ background: color-mix(in srgb, #f25a5a 5%, var(--bg-sidebar));
1207
+ }
1208
+
1209
+ .approval-head {
1210
+ display: flex;
1211
+ flex-wrap: wrap;
1212
+ align-items: center;
1213
+ justify-content: space-between;
1214
+ gap: 10px;
1215
+ flex-shrink: 0;
1216
+ }
1217
+
1218
+ .approval-head strong {
1219
+ color: var(--text);
1220
+ font-size: 13.5px;
1221
+ font-weight: 600;
1222
+ }
1223
+
1224
+ .approval-risk {
1225
+ padding: 2px 8px;
1226
+ border-radius: var(--radius-xs);
1227
+ background: rgba(247, 173, 49, 0.15);
1228
+ color: var(--amber);
1229
+ font-size: 10.5px;
1230
+ font-weight: 600;
1231
+ letter-spacing: 0.045em;
1232
+ text-transform: uppercase;
1233
+ }
1234
+
1235
+ .approval.extreme .approval-risk {
1236
+ background: rgba(242, 90, 90, 0.16);
1237
+ color: #ff8d8d;
1238
+ }
1239
+
1240
+ .approval-details {
1241
+ min-height: 0;
1242
+ overflow: auto;
1243
+ overscroll-behavior: contain;
1244
+ color: var(--text-secondary);
1245
+ font-size: 12.5px;
1246
+ }
1247
+
1248
+ .approval-tool {
1249
+ margin-bottom: 2px;
1250
+ color: var(--text);
1251
+ font-family: var(--mono);
1252
+ font-size: 12.5px;
1253
+ font-weight: 500;
1254
+ overflow-wrap: anywhere;
1255
+ }
1256
+
1257
+ .approval-location {
1258
+ margin: 2px 0 6px;
1259
+ color: var(--text-caption);
1260
+ font-size: 11.5px;
1261
+ overflow-wrap: anywhere;
1262
+ }
1263
+
1264
+ .approval-code {
1265
+ margin: 8px 0;
1266
+ padding: 11px 13px;
1267
+ border: 1px solid var(--border-soft);
1268
+ border-radius: 10px;
1269
+ background: rgba(0, 0, 0, 0.28);
1270
+ color: var(--text-secondary);
1271
+ font-family: var(--mono);
1272
+ font-size: 12px;
1273
+ line-height: 1.6;
1274
+ white-space: pre-wrap;
1275
+ overflow-wrap: anywhere;
1276
+ word-break: break-word;
1277
+ user-select: text;
1278
+ }
1279
+
1280
+ .approval-why {
1281
+ margin: 8px 0 4px;
1282
+ color: var(--text-secondary);
1283
+ font-size: 12.5px;
1284
+ line-height: 1.55;
1285
+ overflow-wrap: anywhere;
1286
+ user-select: text;
1287
+ }
1288
+
1289
+ .approval-why strong {
1290
+ color: var(--text);
1291
+ font-weight: 600;
1292
+ }
1293
+
1294
+ .approval-arguments {
1295
+ margin-top: 6px;
1296
+ }
1297
+
1298
+ .approval-arguments summary {
1299
+ display: flex;
1300
+ align-items: center;
1301
+ gap: 7px;
1302
+ padding: 2px 0;
1303
+ list-style: none;
1304
+ cursor: pointer;
1305
+ color: var(--text-tertiary);
1306
+ font-size: 12px;
1307
+ }
1308
+
1309
+ .approval-arguments summary::-webkit-details-marker {
1310
+ display: none;
1311
+ }
1312
+
1313
+ .approval-arguments summary::before {
1314
+ content: "";
1315
+ flex: none;
1316
+ width: 0;
1317
+ height: 0;
1318
+ border-top: 4px solid transparent;
1319
+ border-bottom: 4px solid transparent;
1320
+ border-left: 5px solid currentColor;
1321
+ transition: transform var(--fast);
1322
+ }
1323
+
1324
+ .approval-arguments[open] summary::before {
1325
+ transform: rotate(90deg);
1326
+ }
1327
+
1328
+ .approval-reasons {
1329
+ margin: 8px 0 0;
1330
+ padding-left: 18px;
1331
+ color: var(--text-tertiary);
1332
+ font-size: 12px;
1333
+ overflow-wrap: anywhere;
1334
+ }
1335
+
1336
+ .approval-reasons li + li {
1337
+ margin-top: 3px;
1338
+ }
1339
+
1340
+ .approval-actions {
1341
+ display: flex;
1342
+ flex-shrink: 0;
1343
+ gap: 8px;
1344
+ padding-top: 2px;
1345
+ }
1346
+
1347
+ .approval-actions button {
1348
+ display: inline-flex;
1349
+ align-items: center;
1350
+ justify-content: center;
1351
+ height: 32px;
1352
+ min-width: 84px;
1353
+ padding: 0 16px;
1354
+ border-radius: var(--radius-sm);
1355
+ font-size: 12.5px;
1356
+ font-weight: 500;
1357
+ transition: background var(--fast), border-color var(--fast), color var(--fast);
1358
+ }
1359
+
1360
+ .approval-actions .approve-btn {
1361
+ border: 0;
1362
+ background: var(--primary);
1363
+ color: var(--primary-fg);
1364
+ }
1365
+
1366
+ .approval-actions .approve-btn:hover {
1367
+ background: var(--primary-hover);
1368
+ }
1369
+
1370
+ .approval-actions .deny-btn {
1371
+ border: 1px solid var(--border);
1372
+ background: transparent;
1373
+ color: var(--text-secondary);
1374
+ }
1375
+
1376
+ .approval-actions .deny-btn:hover {
1377
+ border-color: rgba(242, 90, 90, 0.4);
1378
+ background: rgba(242, 90, 90, 0.08);
1379
+ color: #ff9b9b;
1380
+ }
1381
+
1382
+ /* -------------------------------------------------------------------- gate */
1383
+
1384
+ .gate {
1385
+ position: fixed;
1386
+ inset: 0;
1387
+ z-index: 100;
1388
+ display: flex;
1389
+ align-items: center;
1390
+ justify-content: center;
1391
+ width: 100vw;
1392
+ height: 100dvh;
1393
+ max-width: none;
1394
+ max-height: none;
1395
+ margin: 0;
1396
+ padding: 24px;
1397
+ border: 0;
1398
+ color: var(--text);
1399
+ background: rgba(9, 9, 10, 0.78);
1400
+ backdrop-filter: blur(10px);
1401
+ }
1402
+
1403
+ .gate-card {
1404
+ display: flex;
1405
+ flex-direction: column;
1406
+ gap: 13px;
1407
+ width: min(400px, 100%);
1408
+ margin: 0;
1409
+ padding: 28px;
1410
+ background: var(--bg-sidebar);
1411
+ border: 1px solid var(--border);
1412
+ border-radius: var(--radius-xl);
1413
+ box-shadow: var(--shadow-strong);
1414
+ }
1415
+
1416
+ .gate-brand {
1417
+ display: flex;
1418
+ align-items: center;
1419
+ gap: 10px;
1420
+ margin-bottom: 4px;
1421
+ }
1422
+
1423
+ .gate-brand .logo {
1424
+ width: 34px;
1425
+ height: 34px;
1426
+ border-radius: 10px;
1427
+ }
1428
+
1429
+ .gate-brand .logo svg {
1430
+ width: 21px;
1431
+ height: 21px;
1432
+ }
1433
+
1434
+ .gate-brand strong {
1435
+ font-size: 15px;
1436
+ font-weight: 600;
1437
+ letter-spacing: 0.01em;
1438
+ }
1439
+
1440
+ .gate-card h2 {
1441
+ margin: 0;
1442
+ font-size: 18px;
1443
+ font-weight: 600;
1444
+ letter-spacing: -0.01em;
1445
+ }
1446
+
1447
+ .gate-card p {
1448
+ margin: 0;
1449
+ color: var(--text-tertiary);
1450
+ font-size: 12.5px;
1451
+ line-height: 1.6;
1452
+ }
1453
+
1454
+ .gate-card label {
1455
+ margin-bottom: -7px;
1456
+ color: var(--text-secondary);
1457
+ font-size: 12px;
1458
+ }
1459
+
1460
+ .gate-card code {
1461
+ color: var(--accent);
1462
+ font-family: var(--mono);
1463
+ }
1464
+
1465
+ .gate-card input {
1466
+ width: 100%;
1467
+ height: 40px;
1468
+ padding: 0 12px;
1469
+ background: var(--bg);
1470
+ border: 1px solid var(--border);
1471
+ border-radius: 10px;
1472
+ color: var(--text);
1473
+ font-family: var(--font);
1474
+ font-size: 14px;
1475
+ transition: border-color var(--fast), box-shadow var(--fast);
1476
+ }
1477
+
1478
+ .gate-card input:focus {
1479
+ outline: none;
1480
+ border-color: var(--accent-line);
1481
+ box-shadow: 0 0 0 3px rgba(122, 170, 255, 0.1);
1482
+ }
1483
+
1484
+ .gate-card .primary {
1485
+ width: 100%;
1486
+ height: 40px;
1487
+ margin-top: 2px;
1488
+ }
1489
+
1490
+ /* ----------------------------------------------------- model and settings */
1491
+
1492
+ .model-picker {
1493
+ display: flex;
1494
+ flex-shrink: 0;
1495
+ flex-wrap: wrap;
1496
+ align-items: flex-end;
1497
+ gap: 10px;
1498
+ padding: 10px clamp(16px, 4vw, 32px) 12px;
1499
+ border-bottom: 1px solid var(--border-soft);
1500
+ }
1501
+
1502
+ .model-picker label {
1503
+ display: flex;
1504
+ flex-direction: column;
1505
+ gap: 5px;
1506
+ flex: 0 1 170px;
1507
+ min-width: 0;
1508
+ color: var(--text-caption);
1509
+ font-size: 11px;
1510
+ }
1511
+
1512
+ .model-picker label:nth-child(2) {
1513
+ flex-grow: 1;
1514
+ max-width: 300px;
1515
+ }
1516
+
1517
+ .model-picker .control {
1518
+ height: 34px;
1519
+ }
1520
+
1521
+ .model-picker .form-feedback {
1522
+ flex: 1 1 200px;
1523
+ align-self: center;
1524
+ margin: 0;
1525
+ }
1526
+
1527
+ select,
1528
+ .settings-fields input[type="password"],
1529
+ .settings-fields input[type="number"] {
1530
+ width: 100%;
1531
+ height: 36px;
1532
+ padding: 0 11px;
1533
+ background-color: var(--surface-1);
1534
+ border: 1px solid var(--border-soft);
1535
+ border-radius: 9px;
1536
+ color: var(--text-secondary);
1537
+ font-family: var(--font);
1538
+ font-size: 13px;
1539
+ transition: border-color var(--fast), background-color var(--fast);
1540
+ }
1541
+
1542
+ .model-picker select {
1543
+ height: 34px;
1544
+ }
1545
+
1546
+ select {
1547
+ appearance: none;
1548
+ padding-right: 32px;
1549
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23adb2b8' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
1550
+ background-repeat: no-repeat;
1551
+ background-position: right 9px center;
1552
+ cursor: pointer;
1553
+ }
1554
+
1555
+ select:hover,
1556
+ .settings-fields input[type="password"]:hover,
1557
+ .settings-fields input[type="number"]:hover {
1558
+ border-color: var(--border);
1559
+ }
1560
+
1561
+ select:focus-visible,
1562
+ .settings-fields input[type="password"]:focus-visible,
1563
+ .settings-fields input[type="number"]:focus-visible {
1564
+ outline: none;
1565
+ border-color: var(--accent-line);
1566
+ box-shadow: 0 0 0 3px rgba(122, 170, 255, 0.1);
1567
+ }
1568
+
1569
+ select option {
1570
+ background: var(--surface-2);
1571
+ color: var(--text);
1572
+ }
1573
+
1574
+ .form-feedback {
1575
+ flex: 1 0 100%;
1576
+ margin: 0;
1577
+ color: var(--text-caption);
1578
+ font-size: 11.5px;
1579
+ line-height: 1.5;
1580
+ overflow-wrap: anywhere;
1581
+ }
1582
+
1583
+ .form-feedback.error {
1584
+ color: var(--red);
1585
+ }
1586
+
1587
+ .settings-dialog {
1588
+ width: min(700px, calc(100vw - 24px));
1589
+ max-height: calc(100vh - 32px);
1590
+ max-height: calc(100dvh - 32px);
1591
+ padding: 0;
1592
+ border: 1px solid var(--border);
1593
+ border-radius: var(--radius-xl);
1594
+ background: var(--bg-sidebar);
1595
+ color: var(--text);
1596
+ box-shadow: var(--shadow-strong);
1597
+ overflow: hidden;
1598
+ }
1599
+
1600
+ .settings-dialog::backdrop {
1601
+ background: rgba(9, 9, 10, 0.66);
1602
+ backdrop-filter: blur(6px);
1603
+ }
1604
+
1605
+ .settings-dialog[open] {
1606
+ display: flex;
1607
+ flex-direction: column;
1608
+ }
1609
+
1610
+ .settings-dialog form {
1611
+ display: flex;
1612
+ flex-direction: column;
1613
+ min-height: 0;
1614
+ flex: 1;
1615
+ }
1616
+
1617
+ .settings-header {
1618
+ display: flex;
1619
+ align-items: flex-start;
1620
+ justify-content: space-between;
1621
+ gap: 16px;
1622
+ flex: none;
1623
+ padding: 20px 24px 16px;
1624
+ border-bottom: 1px solid var(--border-soft);
1625
+ }
1626
+
1627
+ .settings-header h2 {
1628
+ margin: 0;
1629
+ font-size: 17px;
1630
+ font-weight: 600;
1631
+ letter-spacing: -0.01em;
1632
+ }
1633
+
1634
+ .settings-sub {
1635
+ margin: 3px 0 0;
1636
+ color: var(--text-caption);
1637
+ font-size: 12px;
1638
+ }
1639
+
1640
+ .settings-fields {
1641
+ display: grid;
1642
+ grid-template-columns: 1fr 1fr;
1643
+ gap: 16px 18px;
1644
+ flex: 1 1 auto;
1645
+ min-height: 0;
1646
+ padding: 20px 24px 8px;
1647
+ overflow-y: auto;
1648
+ overscroll-behavior: contain;
1649
+ }
1650
+
1651
+ .settings-fields h3 {
1652
+ grid-column: 1 / -1;
1653
+ margin: 8px 0 0;
1654
+ color: var(--text-secondary);
1655
+ font-size: 12.5px;
1656
+ font-weight: 600;
1657
+ letter-spacing: 0.01em;
1658
+ }
1659
+
1660
+ .settings-fields h3:first-child {
1661
+ margin-top: 0;
1662
+ }
1663
+
1664
+ .settings-fields label {
1665
+ display: flex;
1666
+ flex-direction: column;
1667
+ gap: 6px;
1668
+ min-width: 0;
1669
+ color: var(--text-caption);
1670
+ font-size: 11.5px;
1671
+ }
1672
+
1673
+ .settings-fields input[type="number"] {
1674
+ appearance: textfield;
1675
+ }
1676
+
1677
+ .settings-fields .checkbox-label {
1678
+ grid-column: 1 / -1;
1679
+ flex-direction: row;
1680
+ align-items: center;
1681
+ gap: 10px;
1682
+ color: var(--text-secondary);
1683
+ font-size: 12.5px;
1684
+ line-height: 1.5;
1685
+ cursor: pointer;
1686
+ }
1687
+
1688
+ .settings-fields input[type="checkbox"] {
1689
+ flex: none;
1690
+ width: 34px;
1691
+ height: 20px;
1692
+ margin: 0;
1693
+ appearance: none;
1694
+ border-radius: 999px;
1695
+ background-color: var(--surface-3);
1696
+ background-image: radial-gradient(circle, #ffffff 0 7px, transparent 7.5px);
1697
+ background-repeat: no-repeat;
1698
+ background-position: 3px center;
1699
+ background-size: 16px 16px;
1700
+ cursor: pointer;
1701
+ transition: background-color var(--fast), background-position var(--fast);
1702
+ }
1703
+
1704
+ .settings-fields input[type="checkbox"]:checked {
1705
+ background-color: var(--accent-strong);
1706
+ background-position: calc(100% - 3px) center;
1707
+ }
1708
+
1709
+ .settings-fields input[type="checkbox"]:focus-visible {
1710
+ outline: 2px solid var(--accent);
1711
+ outline-offset: 2px;
1712
+ }
1713
+
1714
+ .settings-note,
1715
+ .settings-fields .form-feedback {
1716
+ grid-column: 1 / -1;
1717
+ margin: -4px 0 0;
1718
+ color: var(--text-caption);
1719
+ font-size: 11.5px;
1720
+ line-height: 1.55;
1721
+ }
1722
+
1723
+ .settings-fields .form-feedback.error {
1724
+ color: var(--red);
1725
+ }
1726
+
1727
+ .settings-actions {
1728
+ display: flex;
1729
+ justify-content: flex-end;
1730
+ gap: 8px;
1731
+ flex: none;
1732
+ padding: 14px 24px;
1733
+ border-top: 1px solid var(--border-soft);
1734
+ background: var(--bg-sidebar);
1735
+ }
1736
+
1737
+ .settings-actions .control {
1738
+ height: 34px;
1739
+ padding: 0 16px;
1740
+ }
1741
+
1742
+ .settings-actions .primary {
1743
+ height: 34px;
1744
+ padding: 0 18px;
1745
+ }
1746
+
1747
+ /* --------------------------------------------------------------- scrollbar */
1748
+
1749
+ * {
1750
+ scrollbar-width: thin;
1751
+ scrollbar-color: #3c3c3d transparent;
1752
+ }
1753
+
1754
+ *::-webkit-scrollbar {
1755
+ width: 8px;
1756
+ height: 8px;
1757
+ }
1758
+
1759
+ *::-webkit-scrollbar-track {
1760
+ background: transparent;
1761
+ }
1762
+
1763
+ *::-webkit-scrollbar-thumb {
1764
+ border: 2px solid transparent;
1765
+ border-radius: 999px;
1766
+ background: #3c3c3d;
1767
+ background-clip: content-box;
1768
+ }
1769
+
1770
+ *::-webkit-scrollbar-thumb:hover {
1771
+ background: #545557;
1772
+ background-clip: content-box;
1773
+ }
1774
+
1775
+ *::-webkit-scrollbar-corner {
1776
+ background: transparent;
1777
+ }
1778
+
1779
+ /* -------------------------------------------------------------- animations */
1780
+
1781
+ @keyframes blink {
1782
+ 0%,
1783
+ 49% {
1784
+ opacity: 1;
1785
+ }
1786
+ 50%,
1787
+ 100% {
1788
+ opacity: 0;
1789
+ }
1790
+ }
1791
+
1792
+ @keyframes pulse {
1793
+ 0% {
1794
+ box-shadow: 0 0 0 0 rgba(122, 170, 255, 0.45);
1795
+ }
1796
+ 70% {
1797
+ box-shadow: 0 0 0 6px rgba(122, 170, 255, 0);
1798
+ }
1799
+ 100% {
1800
+ box-shadow: 0 0 0 0 rgba(122, 170, 255, 0);
1801
+ }
1802
+ }
1803
+
1804
+ @keyframes pulse-amber {
1805
+ 0% {
1806
+ box-shadow: 0 0 0 0 rgba(247, 173, 49, 0.5);
1807
+ }
1808
+ 70% {
1809
+ box-shadow: 0 0 0 5px rgba(247, 173, 49, 0);
1810
+ }
1811
+ 100% {
1812
+ box-shadow: 0 0 0 0 rgba(247, 173, 49, 0);
1813
+ }
1814
+ }
1815
+
1816
+ @media (prefers-reduced-motion: reduce) {
1817
+ *,
1818
+ *::before,
1819
+ *::after {
1820
+ animation-duration: 0.001ms !important;
1821
+ animation-iteration-count: 1 !important;
1822
+ transition-duration: 0.001ms !important;
1823
+ scroll-behavior: auto !important;
1824
+ }
1825
+ }
1826
+
1827
+ /* ---------------------------------------------------------------- compact */
1828
+
1829
+ @media (max-width: 1080px) {
1830
+ #sidebar {
1831
+ width: 264px;
1832
+ }
1833
+
1834
+ .messages {
1835
+ padding-left: 22px;
1836
+ padding-right: 22px;
1837
+ }
1838
+ }
1839
+
1840
+ /* Phones use one full-width pane: the conversation list opens first. */
1841
+ @media (max-width: 760px) {
1842
+ #sidebar {
1843
+ width: 100%;
1844
+ min-width: 0;
1845
+ max-width: none;
1846
+ border-right: 0;
1847
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
1848
+ }
1849
+
1850
+ #main {
1851
+ display: none;
1852
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
1853
+ }
1854
+
1855
+ #app.conversation-open #sidebar {
1856
+ display: none;
1857
+ }
1858
+
1859
+ #app.conversation-open #main {
1860
+ display: flex;
1861
+ }
1862
+
1863
+ .brand {
1864
+ height: 60px;
1865
+ padding: 0 10px 0 14px;
1866
+ }
1867
+
1868
+ .sidebar-foot {
1869
+ display: none;
1870
+ }
1871
+
1872
+ .icon-btn {
1873
+ width: 40px;
1874
+ height: 40px;
1875
+ border-radius: 10px;
1876
+ }
1877
+
1878
+ .session {
1879
+ min-height: 56px;
1880
+ padding: 11px 10px;
1881
+ }
1882
+
1883
+ .session-title {
1884
+ font-size: 13.5px;
1885
+ }
1886
+
1887
+ .group-header,
1888
+ .more {
1889
+ min-height: 40px;
1890
+ }
1891
+
1892
+ .main-header {
1893
+ display: grid;
1894
+ grid-template-columns: 40px minmax(0, 1fr);
1895
+ align-items: center;
1896
+ gap: 6px 8px;
1897
+ min-height: 0;
1898
+ padding: 8px 12px;
1899
+ }
1900
+
1901
+ .back-to-menu {
1902
+ display: grid;
1903
+ }
1904
+
1905
+ .main-title h1 {
1906
+ font-size: 14px;
1907
+ }
1908
+
1909
+ .controls {
1910
+ grid-column: 1 / -1;
1911
+ justify-content: flex-start;
1912
+ max-height: 20vh;
1913
+ max-height: 20dvh;
1914
+ overflow: auto;
1915
+ }
1916
+
1917
+ .controls:empty {
1918
+ display: none;
1919
+ }
1920
+
1921
+ .controls .control {
1922
+ height: 34px;
1923
+ }
1924
+
1925
+ .model-picker {
1926
+ gap: 8px;
1927
+ padding: 10px 12px;
1928
+ max-height: 30vh;
1929
+ max-height: 30dvh;
1930
+ overflow: auto;
1931
+ }
1932
+
1933
+ .model-picker label {
1934
+ flex: 1 1 calc(50% - 8px);
1935
+ }
1936
+
1937
+ .model-picker label:nth-child(2) {
1938
+ max-width: none;
1939
+ }
1940
+
1941
+ .model-picker .control {
1942
+ flex: 1 1 calc(50% - 8px);
1943
+ height: 38px;
1944
+ }
1945
+
1946
+ .messages {
1947
+ padding: 16px 14px 20px;
1948
+ }
1949
+
1950
+ .message {
1951
+ font-size: 15px;
1952
+ }
1953
+
1954
+ .message.user .body {
1955
+ max-width: 90%;
1956
+ }
1957
+
1958
+ .composer {
1959
+ padding: 0 12px calc(12px + env(safe-area-inset-bottom));
1960
+ }
1961
+
1962
+ .composer-card {
1963
+ padding: 6px 6px 6px 14px;
1964
+ border-radius: 20px;
1965
+ }
1966
+
1967
+ .composer textarea {
1968
+ max-height: min(220px, 25dvh);
1969
+ }
1970
+
1971
+ #send {
1972
+ width: 40px;
1973
+ height: 40px;
1974
+ }
1975
+
1976
+ .composer-hint {
1977
+ display: none;
1978
+ }
1979
+
1980
+ .approval {
1981
+ width: calc(100% - 24px);
1982
+ max-height: 35dvh;
1983
+ margin-bottom: 8px;
1984
+ padding: 12px;
1985
+ }
1986
+
1987
+ .approval-actions {
1988
+ flex-wrap: wrap;
1989
+ }
1990
+
1991
+ .approval-actions button {
1992
+ height: 40px;
1993
+ flex: 1;
1994
+ }
1995
+
1996
+ /* Keep inputs at 16px to avoid automatic zoom when focused on iOS. */
1997
+ .composer textarea,
1998
+ .gate-card input,
1999
+ .settings-fields input,
2000
+ select {
2001
+ font-size: 16px;
2002
+ }
2003
+
2004
+ .settings-dialog {
2005
+ width: calc(100vw - 16px);
2006
+ max-height: calc(100dvh - 16px);
2007
+ }
2008
+
2009
+ .settings-header,
2010
+ .settings-fields,
2011
+ .settings-actions {
2012
+ padding-left: 16px;
2013
+ padding-right: 16px;
2014
+ }
2015
+
2016
+ .settings-fields {
2017
+ grid-template-columns: 1fr;
2018
+ }
2019
+
2020
+ .settings-fields label,
2021
+ .settings-note {
2022
+ overflow-wrap: anywhere;
2023
+ }
2024
+
2025
+ .settings-actions button {
2026
+ height: 40px;
2027
+ flex: 1;
2028
+ }
2029
+
2030
+ .gate {
2031
+ padding: 16px;
2032
+ overflow-y: auto;
2033
+ }
2034
+
2035
+ .gate-card {
2036
+ margin: auto;
2037
+ padding: 24px;
2038
+ }
2039
+ }
2040
+
2041
+ /* Short landscape screens and the onscreen keyboard leave less vertical room. */
2042
+ @media (max-width: 760px) and (max-height: 600px) {
2043
+ .main-header {
2044
+ flex-shrink: 1;
2045
+ min-height: 56px;
2046
+ overflow-y: auto;
2047
+ }
2048
+
2049
+ .model-picker {
2050
+ flex-shrink: 1;
2051
+ min-height: 44px;
2052
+ padding-top: 6px;
2053
+ padding-bottom: 6px;
2054
+ }
2055
+
2056
+ .messages {
2057
+ min-height: 40px;
2058
+ padding-top: 8px;
2059
+ padding-bottom: 8px;
2060
+ }
2061
+
2062
+ .approval {
2063
+ max-height: 30dvh;
2064
+ overflow-y: auto;
2065
+ }
2066
+
2067
+ .approval-details {
2068
+ min-height: 64px;
2069
+ }
2070
+ }