返回 CodeWhale
styles.css
根目录 / crates / tui / src / runtime_web / styles.css
1 :root {
2 color-scheme: dark;
3 /* CWC Ocean is the dark Blue Stage view. Keep semantic roles here so this
4 dependency-free client shares the product grammar without importing the
5 managed app or its component runtime. */
6 --bg: #020711;
7 --sidebar: #050b16;
8 --surface: #0e1a30;
9 --surface-raised: #172945;
10 --hover: rgba(106, 174, 242, 0.09);
11 --selected: rgba(106, 174, 242, 0.15);
12 --scrim: rgba(0, 2, 8, 0.7);
13 --line: rgba(72, 215, 255, 0.14);
14 --line-strong: rgba(106, 174, 242, 0.28);
15 --edge: rgba(209, 235, 244, 0.08);
16 --shadow-color: rgba(0, 2, 8, 0.56);
17 --text: #f6f2e8;
18 --text-soft: #b6c0d4;
19 --text-muted: #93a0b8;
20 --text-faint: #8491aa;
21 --action: #6aaef2;
22 --action-strong: #4f8fe8;
23 --action-contrast: #03070d;
24 --action-soft: rgba(106, 174, 242, 0.13);
25 --status-live: #4fd1c5;
26 --status-human: #f6c453;
27 --status-warning: #ff7a59;
28 --status-danger: #ff86b2;
29 --status-offline: #93a0b8;
30 --status-live-soft: rgba(79, 209, 197, 0.11);
31 --status-human-soft: rgba(246, 196, 83, 0.11);
32 --status-warning-soft: rgba(255, 122, 89, 0.11);
33 --status-danger-soft: rgba(255, 134, 178, 0.11);
34 --stage-surface: #142747;
35 --stage-shallows: #0d1b33;
36 --stage-depth: #061226;
37 --stage-abyss: #020711;
38 --plate: rgba(18, 34, 60, 0.9);
39 --well: #06111f;
40 --well-deep: #020711;
41 --rim: rgba(209, 235, 244, 0.13);
42 --caustic: rgba(72, 215, 255, 0.12);
43 --vignette: rgba(0, 2, 8, 0.58);
44
45 /* Compatibility aliases keep the existing embedded markup intentionally
46 small while all new styling speaks in the semantic roles above. */
47 --ink-0: var(--bg);
48 --ink-1: var(--stage-depth);
49 --ink-2: var(--surface);
50 --ink-3: var(--surface-raised);
51 --text-dim: var(--text-muted);
52 --action-wash: var(--action-soft);
53 --human: var(--status-human);
54 --human-wash: var(--status-human-soft);
55 --live: var(--status-live);
56 --live-wash: var(--status-live-soft);
57 --warning: var(--status-warning);
58 --danger: var(--status-danger);
59 --ok: #9bd66f;
60 --radius-control: 6px;
61 --radius-card: 12px;
62 --radius-composer: 16px;
63 --space-1: 4px;
64 --space-2: 8px;
65 --space-3: 12px;
66 --space-4: 16px;
67 --space-5: 24px;
68 --space-6: 32px;
69 --dur-fast: 120ms;
70 --dur-med: 200ms;
71 --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
72 --rail: 256px;
73 --content: 760px;
74 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
75 font-synthesis: none;
76 text-rendering: optimizeLegibility;
77 }
78
79 * {
80 box-sizing: border-box;
81 }
82
83 html,
84 body {
85 width: 100%;
86 min-width: 280px;
87 height: 100%;
88 margin: 0;
89 overflow: hidden;
90 background: var(--bg);
91 color: var(--text);
92 -webkit-font-smoothing: antialiased;
93 }
94
95 button,
96 input,
97 textarea {
98 color: inherit;
99 font: inherit;
100 }
101
102 button {
103 cursor: pointer;
104 touch-action: manipulation;
105 }
106
107 button:disabled,
108 textarea:disabled {
109 cursor: not-allowed;
110 opacity: 0.45;
111 }
112
113 button:focus-visible,
114 input:focus-visible,
115 textarea:focus-visible,
116 summary:focus-visible {
117 outline: 3px solid var(--action);
118 outline-offset: 3px;
119 }
120
121 .shell {
122 --visual-viewport-height: 100dvh;
123 --visual-viewport-offset-top: 0px;
124 display: grid;
125 grid-template-columns: var(--rail) minmax(0, 1fr);
126 width: 100%;
127 height: var(--visual-viewport-height);
128 min-height: 0;
129 background: var(--bg);
130 }
131
132 .rail {
133 position: relative;
134 z-index: 20;
135 display: grid;
136 grid-template-rows: 52px auto auto minmax(144px, 1fr) minmax(0, 34%) auto;
137 gap: var(--space-2);
138 min-width: 0;
139 min-height: 0;
140 overflow: hidden;
141 padding: 10px 10px 12px;
142 border-right: 1px solid var(--line);
143 background: var(--sidebar);
144 }
145
146 .rail-brand,
147 .session-heading,
148 .header-actions,
149 .composer-bar,
150 .composer-actions,
151 .rail-footer,
152 .fact-chip,
153 .thread-title-row,
154 .attention-actions,
155 .dialog-actions {
156 display: flex;
157 align-items: center;
158 }
159
160 .rail-brand {
161 min-width: 0;
162 gap: 10px;
163 padding: 0 8px;
164 }
165
166 .brand-mark {
167 display: block;
168 flex: 0 0 34px;
169 width: 34px;
170 height: 34px;
171 border-radius: 9px;
172 }
173
174 .eyebrow {
175 margin: 0;
176 color: var(--text-dim);
177 font-size: 11px;
178 font-weight: 700;
179 letter-spacing: 0.11em;
180 line-height: 1.3;
181 text-transform: uppercase;
182 }
183
184 .brand-name {
185 margin: 0;
186 font-size: 16px;
187 font-weight: 650;
188 letter-spacing: -0.01em;
189 }
190
191 .brand-context {
192 margin: 2px 0 0;
193 color: var(--text-dim);
194 font-size: 12px;
195 }
196
197 .primary-button,
198 .quiet-button,
199 .send-button,
200 .icon-button {
201 min-height: 36px;
202 border: 1px solid var(--line);
203 border-radius: var(--radius-control);
204 background: var(--surface);
205 color: var(--text-soft);
206 font-size: 13px;
207 font-weight: 650;
208 transition:
209 border-color var(--dur-fast) ease,
210 background var(--dur-fast) ease,
211 color var(--dur-fast) ease,
212 transform var(--dur-fast) var(--ease-out);
213 }
214
215 .primary-button,
216 .send-button {
217 border-color: rgba(106, 174, 242, 0.46);
218 background: var(--action);
219 color: var(--action-contrast);
220 }
221
222 .primary-button:hover,
223 .send-button:hover {
224 background: var(--action-strong);
225 }
226
227 .quiet-button {
228 padding: 0 11px;
229 }
230
231 .quiet-button:hover,
232 .icon-button:hover {
233 border-color: var(--line-strong);
234 background: var(--surface-raised);
235 color: var(--text);
236 }
237
238 .quiet-button.danger:hover {
239 border-color: rgba(255, 134, 178, 0.42);
240 color: var(--danger);
241 }
242
243 .icon-button {
244 display: inline-grid;
245 width: 36px;
246 min-width: 36px;
247 padding: 0;
248 place-items: center;
249 }
250
251 .new-thread {
252 display: flex;
253 width: 100%;
254 max-width: 100%;
255 min-width: 0;
256 align-items: center;
257 justify-content: flex-start;
258 min-height: 40px;
259 padding: 0 12px;
260 border-color: transparent;
261 background: var(--action-wash);
262 color: var(--text);
263 font-size: 13px;
264 }
265
266 .new-thread:hover {
267 border-color: transparent;
268 background: var(--selected);
269 color: var(--text);
270 }
271
272 .search-field {
273 display: flex;
274 min-width: 0;
275 height: 38px;
276 align-items: center;
277 gap: 8px;
278 padding: 0 11px;
279 border: 1px solid transparent;
280 border-radius: var(--radius-control);
281 background: var(--well);
282 color: var(--text-dim);
283 }
284
285 .search-field:focus-within {
286 border-color: rgba(106, 174, 242, 0.46);
287 box-shadow: 0 0 0 2px rgba(106, 174, 242, 0.1);
288 }
289
290 .search-field input {
291 width: 100%;
292 min-width: 0;
293 border: 0;
294 outline: 0;
295 background: transparent;
296 color: var(--text);
297 font-size: 14px;
298 }
299
300 .search-field input::placeholder,
301 textarea::placeholder {
302 color: var(--text-dim);
303 }
304
305 .thread-list {
306 min-height: 0;
307 margin: 0;
308 overflow-x: hidden;
309 overflow-y: auto;
310 overscroll-behavior: contain;
311 scrollbar-color: var(--ink-3) transparent;
312 }
313
314 .thread-group + .thread-group {
315 margin-top: 12px;
316 padding-top: 10px;
317 border-top: 1px solid var(--line);
318 }
319
320 .thread-group-title {
321 position: sticky;
322 z-index: 1;
323 top: 0;
324 margin: 0;
325 padding: 8px 11px 5px;
326 background: var(--sidebar);
327 }
328
329 .thread-group-needs-you .thread-group-title {
330 color: var(--status-human);
331 }
332
333 .thread-row {
334 display: block;
335 width: 100%;
336 min-height: 62px;
337 margin: 2px 0;
338 padding: 10px 11px;
339 overflow: hidden;
340 border: 1px solid transparent;
341 border-radius: var(--radius-control);
342 background: transparent;
343 color: var(--text-soft);
344 text-align: left;
345 }
346
347 .thread-row:hover {
348 background: var(--hover);
349 color: var(--text);
350 }
351
352 .thread-row[aria-current="true"] {
353 border-color: transparent;
354 background: var(--selected);
355 color: var(--text);
356 box-shadow: inset 2px 0 0 var(--action);
357 }
358
359 .thread-title-row {
360 min-width: 0;
361 justify-content: space-between;
362 gap: 8px;
363 }
364
365 .thread-row-indicators {
366 display: inline-flex;
367 flex: 0 0 auto;
368 align-items: center;
369 gap: 7px;
370 }
371
372 .thread-attention-count {
373 min-width: 20px;
374 padding: 2px 6px;
375 border: 1px solid rgba(246, 196, 83, 0.42);
376 border-radius: 999px;
377 background: rgba(246, 196, 83, 0.12);
378 color: var(--status-human);
379 font-size: 10px;
380 font-weight: 750;
381 line-height: 1.3;
382 text-align: center;
383 }
384
385 .thread-title {
386 overflow: hidden;
387 font-size: 14px;
388 font-weight: 600;
389 text-overflow: ellipsis;
390 white-space: nowrap;
391 }
392
393 .thread-preview {
394 display: -webkit-box;
395 margin-top: 4px;
396 overflow: hidden;
397 color: var(--text-dim);
398 font-size: 12px;
399 line-height: 1.45;
400 -webkit-box-orient: vertical;
401 -webkit-line-clamp: 2;
402 }
403
404 .thread-meta {
405 margin-top: 5px;
406 overflow: hidden;
407 color: var(--text-dim);
408 font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
409 font-size: 10px;
410 text-overflow: ellipsis;
411 white-space: nowrap;
412 }
413
414 .status-pip {
415 flex: 0 0 7px;
416 width: 7px;
417 height: 7px;
418 border-radius: 50%;
419 background: var(--text-dim);
420 }
421
422 .status-pip.running {
423 background: var(--live);
424 box-shadow: 0 0 0 3px var(--live-wash);
425 }
426
427 .status-pip.failed {
428 background: var(--danger);
429 }
430
431 /* Read-only peek for a saved session. Visually distinct from the live
432 transcript so a recording is never mistaken for a running thread. */
433 .session-peek {
434 min-height: 0;
435 overflow-y: auto;
436 padding: 18px max(20px, calc((100% - var(--content)) / 2));
437 border-bottom: 1px solid var(--line);
438 background: rgba(2, 7, 17, 0.22);
439 }
440
441 .session-peek[hidden] {
442 display: none;
443 }
444
445 .peek-entry {
446 display: flex;
447 flex-wrap: wrap;
448 gap: 10px;
449 align-items: baseline;
450 padding: 10px 0;
451 border-top: 1px solid var(--line);
452 }
453
454 .peek-kind {
455 min-width: 84px;
456 color: var(--text-dim);
457 font-size: 11px;
458 text-transform: uppercase;
459 letter-spacing: 0.06em;
460 }
461
462 .peek-text {
463 flex: 1 1 240px;
464 min-width: 0;
465 margin: 0;
466 color: var(--text-soft);
467 font-size: 14px;
468 line-height: 1.6;
469 overflow-wrap: anywhere;
470 }
471
472 .peek-flag,
473 .peek-omitted {
474 color: var(--text-dim);
475 font-size: 11px;
476 }
477
478 /* Narrow viewports: the peek must not force horizontal scrolling, and the
479 kind label stacks above its text rather than squeezing it. */
480 @media (max-width: 480px) {
481 .session-peek {
482 padding: 10px 12px;
483 max-height: 45vh;
484 }
485
486 .peek-entry {
487 flex-direction: column;
488 gap: 2px;
489 }
490
491 .peek-text {
492 flex-basis: auto;
493 }
494
495 .saved-sessions {
496 max-height: 30%;
497 }
498 }
499
500 /* Saved sessions sit under the live thread list and are capped so a large
501 session store cannot push the connection footer off-screen. */
502 .saved-sessions {
503 min-height: 0;
504 max-height: 100%;
505 display: flex;
506 flex-direction: column;
507 padding-top: 12px;
508 border-top: 1px solid var(--line);
509 }
510
511 .saved-sessions[hidden] {
512 display: none;
513 }
514
515 .rail-section-title {
516 margin: 0 8px 8px;
517 color: var(--text-dim);
518 font-size: 11px;
519 font-weight: 700;
520 letter-spacing: 0.08em;
521 text-transform: uppercase;
522 }
523
524 .rail-footer {
525 min-width: 0;
526 align-items: flex-start;
527 gap: 10px;
528 padding: 11px 8px 0;
529 border-top: 1px solid var(--line);
530 color: var(--text-dim);
531 font-size: 12px;
532 }
533
534 .connection-dot {
535 flex: 0 0 8px;
536 width: 8px;
537 height: 8px;
538 margin-top: 4px;
539 border-radius: 50%;
540 background: var(--action);
541 }
542
543 .connection-copy {
544 display: grid;
545 min-width: 0;
546 gap: 3px;
547 }
548
549 .runtime-provenance {
550 overflow: hidden;
551 color: var(--text-faint);
552 font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
553 font-size: 10px;
554 text-overflow: ellipsis;
555 white-space: nowrap;
556 }
557
558 .connection-dot.ready {
559 background: var(--ok);
560 }
561
562 .connection-dot.error {
563 background: var(--danger);
564 }
565
566 .session {
567 display: grid;
568 grid-template-areas:
569 "header"
570 "status"
571 "transcript"
572 "attention"
573 "composer";
574 grid-template-rows: 64px auto minmax(0, 1fr) auto auto;
575 min-width: 0;
576 min-height: 0;
577 background: var(--stage-surface);
578 }
579
580 .session-header {
581 display: grid;
582 grid-area: header;
583 grid-template-areas: "heading facts actions";
584 grid-template-columns: minmax(180px, 1fr) minmax(0, auto) auto;
585 align-items: center;
586 gap: 16px;
587 min-width: 0;
588 overflow: hidden;
589 padding: 0 20px;
590 border-bottom: 1px solid var(--line);
591 background: rgba(14, 26, 48, 0.95);
592 box-shadow: inset 0 -1px 0 var(--edge);
593 backdrop-filter: blur(14px) saturate(1.08);
594 }
595
596 .session-heading {
597 grid-area: heading;
598 min-width: 0;
599 gap: 12px;
600 }
601
602 .title-stack {
603 min-width: 0;
604 }
605
606 .session-header h1 {
607 margin: 2px 0 0;
608 overflow: hidden;
609 font-size: 18px;
610 font-weight: 700;
611 letter-spacing: -0.015em;
612 line-height: 1.25;
613 text-overflow: ellipsis;
614 white-space: nowrap;
615 }
616
617 .header-actions {
618 grid-area: actions;
619 align-self: center;
620 gap: 6px;
621 }
622
623 .session-facts {
624 display: flex;
625 flex-wrap: nowrap;
626 grid-area: facts;
627 min-width: 0;
628 gap: 6px;
629 overflow-x: auto;
630 overflow-y: hidden;
631 scrollbar-width: none;
632 }
633
634 .session-facts::-webkit-scrollbar {
635 display: none;
636 }
637
638 .fact-chip {
639 flex: 0 0 auto;
640 min-height: 28px;
641 gap: 5px;
642 padding: 0 9px;
643 border: 1px solid var(--line);
644 border-radius: var(--radius-control);
645 background: rgba(2, 7, 17, 0.18);
646 color: var(--text-dim);
647 font-size: 11px;
648 white-space: nowrap;
649 }
650
651 .fact-chip strong {
652 color: var(--text-soft);
653 font-weight: 650;
654 }
655
656 .rail-open,
657 .rail-close,
658 .rail-scrim {
659 display: none;
660 }
661
662 .status-banner {
663 grid-area: status;
664 margin: 16px auto 0;
665 width: min(var(--content), calc(100% - 40px));
666 padding: 11px 14px;
667 border: 1px solid rgba(255, 122, 89, 0.34);
668 border-radius: var(--radius-control);
669 background: var(--status-warning-soft);
670 color: var(--warning);
671 font-size: 13px;
672 line-height: 1.5;
673 }
674
675 .transcript {
676 grid-area: transcript;
677 min-height: 0;
678 padding: 34px max(20px, calc((100% - var(--content)) / 2)) 56px;
679 overflow-x: hidden;
680 overflow-y: auto;
681 overscroll-behavior: contain;
682 scroll-behavior: smooth;
683 scrollbar-color: var(--ink-3) transparent;
684 background: var(--stage-surface);
685 }
686
687 .empty-state {
688 display: grid;
689 min-height: 100%;
690 place-content: center;
691 justify-items: center;
692 padding: 32px;
693 color: var(--text-dim);
694 text-align: center;
695 }
696
697 .empty-state h2 {
698 margin: 18px 0 8px;
699 color: var(--text);
700 font-size: 22px;
701 letter-spacing: -0.02em;
702 }
703
704 .empty-state p {
705 max-width: 480px;
706 margin: 0;
707 font-size: 15px;
708 line-height: 1.65;
709 }
710
711 .empty-mark {
712 display: block;
713 width: 52px;
714 height: 52px;
715 border-radius: var(--radius-card);
716 opacity: 0.9;
717 }
718
719 .message,
720 .receipt,
721 .reasoning {
722 width: 100%;
723 margin: 0 0 24px;
724 }
725
726 .message-label,
727 .receipt-label {
728 margin-bottom: 8px;
729 color: var(--text-dim);
730 font-size: 12px;
731 font-weight: 600;
732 letter-spacing: 0;
733 }
734
735 .message-body {
736 max-width: 100%;
737 padding: 0;
738 border: 0;
739 border-radius: 0;
740 background: transparent;
741 color: var(--text);
742 font-size: 15.5px;
743 line-height: 1.7;
744 overflow-wrap: anywhere;
745 white-space: pre-wrap;
746 }
747
748 .message.user .message-body {
749 width: fit-content;
750 max-width: 82%;
751 margin-left: auto;
752 padding: 11px 15px;
753 border: 1px solid var(--line);
754 border-radius: 18px 18px 6px 18px;
755 background: var(--plate);
756 box-shadow: inset 0 1px 0 var(--rim);
757 font-size: 14.5px;
758 }
759
760 .message.user .message-label { display: none; }
761
762 .message.in-progress .message-body::after {
763 content: "";
764 display: inline-block;
765 width: 5px;
766 height: 12px;
767 margin-left: 4px;
768 background: var(--live);
769 vertical-align: -1px;
770 animation: cursor-pulse 1s steps(2, end) infinite;
771 }
772
773 @keyframes cursor-pulse {
774 50% { opacity: 0; }
775 }
776
777 .receipt {
778 display: flex;
779 width: fit-content;
780 max-width: 100%;
781 align-items: flex-start;
782 gap: 10px;
783 margin-top: -6px;
784 color: var(--text-dim);
785 }
786
787 .receipt-dot {
788 flex: 0 0 7px;
789 width: 7px;
790 height: 7px;
791 margin-top: 7px;
792 border-radius: 50%;
793 background: var(--live);
794 }
795
796 .receipt.failed .receipt-dot {
797 background: var(--danger);
798 }
799
800 .receipt.failed .receipt-copy strong {
801 color: var(--danger);
802 }
803
804 .receipt-copy {
805 display: flex;
806 min-width: 0;
807 flex-direction: column;
808 gap: 2px;
809 }
810
811 .receipt-copy strong {
812 color: var(--text-soft);
813 font-size: 12.5px;
814 font-weight: 600;
815 line-height: 1.5;
816 }
817
818 .receipt-summary {
819 color: var(--text-dim);
820 font-size: 12px;
821 line-height: 1.55;
822 overflow-wrap: anywhere;
823 }
824
825 .receipt details,
826 .reasoning details {
827 margin-top: 8px;
828 }
829
830 .receipt summary,
831 .reasoning summary {
832 display: inline-flex;
833 min-height: 34px;
834 align-items: center;
835 color: var(--text-dim);
836 cursor: pointer;
837 font-size: 12px;
838 }
839
840 .receipt pre,
841 .reasoning pre {
842 max-width: 100%;
843 max-height: 320px;
844 margin: 8px 0 0;
845 padding: 12px 14px;
846 overflow: auto;
847 border: 1px solid var(--line);
848 border-radius: var(--radius-control);
849 background: var(--well-deep);
850 color: var(--text-soft);
851 font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
852 font-size: 12px;
853 line-height: 1.6;
854 overflow-wrap: anywhere;
855 white-space: pre-wrap;
856 }
857
858 .reasoning {
859 padding-left: 16px;
860 border-left: 2px solid var(--line);
861 }
862
863 .attention {
864 grid-area: attention;
865 width: min(var(--content), calc(100% - 40px));
866 max-height: 44vh;
867 margin: 0 auto 14px;
868 overflow-y: auto;
869 }
870
871 .attention-card {
872 margin-top: 10px;
873 padding: 16px;
874 border: 1px solid rgba(246, 196, 83, 0.34);
875 border-radius: var(--radius-card);
876 background: var(--status-human-soft);
877 box-shadow: inset 0 1px 0 rgba(246, 196, 83, 0.08);
878 }
879
880 .attention-card h2 {
881 margin: 5px 0 7px;
882 font-size: 15px;
883 }
884
885 .attention-card p {
886 margin: 0;
887 color: var(--text-soft);
888 font-size: 13.5px;
889 line-height: 1.6;
890 }
891
892 .attention-actions {
893 flex-wrap: wrap;
894 gap: 10px;
895 margin-top: 14px;
896 }
897
898 .remember-field,
899 .answer-option {
900 display: flex;
901 min-height: 34px;
902 align-items: center;
903 gap: 10px;
904 color: var(--text-soft);
905 font-size: 13px;
906 }
907
908 .question-fieldset {
909 margin: 14px 0 0;
910 padding: 12px;
911 border: 1px solid var(--line);
912 border-radius: var(--radius-control);
913 }
914
915 .question-fieldset legend {
916 padding: 0 5px;
917 color: var(--text);
918 font-size: 13px;
919 font-weight: 650;
920 }
921
922 .answer-option {
923 margin: 9px 0;
924 }
925
926 .answer-option small {
927 display: block;
928 margin-top: 2px;
929 color: var(--text-dim);
930 font-size: 12px;
931 line-height: 1.45;
932 }
933
934 .other-answer,
935 .rename-dialog input {
936 width: 100%;
937 min-height: 40px;
938 margin-top: 8px;
939 padding: 0 12px;
940 border: 1px solid var(--line);
941 border-radius: var(--radius-control);
942 outline: 0;
943 background: var(--well-deep);
944 color: var(--text);
945 font-size: 14px;
946 }
947
948 .composer-wrap {
949 grid-area: composer;
950 padding: 0 max(20px, calc((100% - var(--content)) / 2)) 20px;
951 background: linear-gradient(transparent, var(--stage-surface) 28%);
952 }
953
954 .composer {
955 overflow: hidden;
956 border: 1px solid var(--line);
957 border-radius: var(--radius-composer);
958 background: var(--plate);
959 box-shadow: inset 0 1px 0 var(--rim), 0 18px 48px rgba(0, 2, 8, 0.2);
960 }
961
962 .composer:focus-within {
963 border-color: rgba(106, 174, 242, 0.46);
964 box-shadow: inset 0 1px 0 var(--rim), 0 0 0 3px rgba(106, 174, 242, 0.1);
965 }
966
967 .composer textarea {
968 display: block;
969 width: 100%;
970 min-height: 72px;
971 max-height: 220px;
972 padding: 16px 17px 8px;
973 resize: none;
974 overflow-y: auto;
975 border: 0;
976 outline: 0;
977 background: transparent;
978 color: var(--text);
979 font-size: 15.5px;
980 line-height: 1.55;
981 }
982
983 .composer-bar {
984 justify-content: space-between;
985 gap: 14px;
986 padding: 6px 8px 8px 17px;
987 }
988
989 .composer-hint {
990 color: var(--text-dim);
991 font-size: 11px;
992 }
993
994 .composer-actions {
995 gap: 8px;
996 }
997
998 .send-button {
999 min-width: 72px;
1000 padding: 0 15px;
1001 }
1002
1003 .rename-dialog {
1004 width: min(420px, calc(100% - 28px));
1005 padding: 0;
1006 border: 1px solid var(--line-strong);
1007 border-radius: var(--radius-card);
1008 background: var(--surface-raised);
1009 color: var(--text);
1010 box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55);
1011 }
1012
1013 .rename-dialog::backdrop {
1014 background: var(--scrim);
1015 }
1016
1017 .rename-dialog form {
1018 padding: 24px;
1019 }
1020
1021 .rename-dialog h2 {
1022 margin: 6px 0 18px;
1023 font-size: 20px;
1024 }
1025
1026 .new-thread-dialog {
1027 width: min(500px, calc(100% - 28px));
1028 }
1029
1030 .dialog-copy {
1031 margin: -8px 0 20px;
1032 color: var(--text-dim);
1033 font-size: 13px;
1034 line-height: 1.55;
1035 }
1036
1037 .dialog-field {
1038 display: grid;
1039 gap: 7px;
1040 margin-top: 16px;
1041 }
1042
1043 .dialog-label {
1044 color: var(--text-soft);
1045 font-size: 13px;
1046 font-weight: 650;
1047 }
1048
1049 .new-thread-dialog select {
1050 width: 100%;
1051 min-height: 42px;
1052 padding: 0 12px;
1053 border: 1px solid var(--line);
1054 border-radius: var(--radius-control);
1055 outline: 0;
1056 background: var(--well-deep);
1057 color: var(--text);
1058 font-size: 14px;
1059 }
1060
1061 .new-thread-dialog select:focus,
1062 .new-thread-dialog input:focus {
1063 border-color: rgba(106, 174, 242, 0.58);
1064 box-shadow: 0 0 0 3px rgba(106, 174, 242, 0.1);
1065 }
1066
1067 .model-capability {
1068 min-height: 42px;
1069 margin: 16px 0 0;
1070 padding: 10px 12px;
1071 border: 1px solid var(--line);
1072 border-radius: var(--radius-control);
1073 background: rgba(2, 7, 17, 0.2);
1074 color: var(--text-dim);
1075 font-size: 12px;
1076 line-height: 1.5;
1077 }
1078
1079 .model-capability:empty {
1080 display: none;
1081 }
1082
1083 .model-capability[data-state="supported"] {
1084 border-color: rgba(79, 209, 197, 0.34);
1085 background: var(--status-live-soft);
1086 color: var(--status-live);
1087 }
1088
1089 .model-capability[data-state="unsupported"] {
1090 color: var(--text-soft);
1091 }
1092
1093 .dialog-status {
1094 min-height: 20px;
1095 margin: 10px 0 0;
1096 color: var(--text-dim);
1097 font-size: 12px;
1098 line-height: 1.5;
1099 }
1100
1101 .dialog-status[data-state="error"] {
1102 color: var(--warning);
1103 }
1104
1105 .dialog-actions {
1106 justify-content: flex-end;
1107 gap: 10px;
1108 margin-top: 20px;
1109 }
1110
1111 .dialog-actions .primary-button {
1112 padding: 0 13px;
1113 }
1114
1115 .sr-only {
1116 position: absolute;
1117 width: 1px;
1118 height: 1px;
1119 padding: 0;
1120 overflow: hidden;
1121 clip: rect(0, 0, 0, 0);
1122 white-space: nowrap;
1123 border: 0;
1124 }
1125
1126 [hidden] {
1127 display: none !important;
1128 }
1129
1130 noscript {
1131 position: fixed;
1132 inset: 0;
1133 z-index: 100;
1134 display: grid;
1135 place-items: center;
1136 padding: 24px;
1137 background: var(--bg);
1138 color: var(--text);
1139 }
1140
1141 /* The runtime exposes more truth in its header than the managed shell. Give
1142 those facts a second row before they can squeeze the thread title or action
1143 controls, including on compact desktop windows. */
1144 @media (max-width: 1120px) {
1145 .session {
1146 grid-template-rows: auto auto minmax(0, 1fr) auto auto;
1147 }
1148
1149 .session-header {
1150 grid-template-areas:
1151 "heading actions"
1152 "facts facts";
1153 grid-template-columns: minmax(0, 1fr) auto;
1154 gap: 8px 12px;
1155 min-height: 86px;
1156 padding-top: 8px;
1157 padding-bottom: 8px;
1158 }
1159
1160 .session-facts {
1161 width: 100%;
1162 }
1163 }
1164
1165 @media (max-width: 800px) {
1166 .shell {
1167 grid-template-columns: minmax(0, 1fr);
1168 }
1169
1170 .rail {
1171 position: fixed;
1172 top: var(--visual-viewport-offset-top);
1173 bottom: auto;
1174 left: 0;
1175 width: min(88vw, 288px);
1176 height: var(--visual-viewport-height);
1177 transform: translateX(-102%);
1178 box-shadow: 24px 0 70px var(--shadow-color);
1179 transition: transform var(--dur-med) var(--ease-out);
1180 }
1181
1182 .rail-open,
1183 .rail-close {
1184 display: inline-grid;
1185 }
1186
1187 .rail-close {
1188 margin-left: auto;
1189 }
1190
1191 .rail-scrim {
1192 position: fixed;
1193 top: var(--visual-viewport-offset-top);
1194 right: 0;
1195 bottom: auto;
1196 left: 0;
1197 z-index: 15;
1198 display: block;
1199 visibility: hidden;
1200 width: 100%;
1201 height: var(--visual-viewport-height);
1202 padding: 0;
1203 border: 0;
1204 opacity: 0;
1205 background: var(--scrim);
1206 transition: opacity var(--dur-med) ease-out, visibility var(--dur-med) step-end;
1207 }
1208
1209 .rail-visible .rail {
1210 transform: translateX(0);
1211 }
1212
1213 .rail-visible .rail-scrim {
1214 visibility: visible;
1215 opacity: 1;
1216 transition: opacity var(--dur-med) ease-out;
1217 }
1218
1219 .session-header {
1220 min-height: 90px;
1221 padding: 9px 14px;
1222 }
1223
1224 .session-header h1 {
1225 font-size: 17px;
1226 }
1227
1228 .header-actions {
1229 gap: 4px;
1230 }
1231
1232 .header-actions .quiet-button {
1233 padding: 0 10px;
1234 }
1235
1236 .transcript {
1237 padding: 26px 16px 44px;
1238 }
1239
1240 .status-banner,
1241 .attention {
1242 width: calc(100% - 32px);
1243 }
1244
1245 .composer-wrap {
1246 padding-right: 16px;
1247 padding-bottom: max(12px, env(safe-area-inset-bottom));
1248 padding-left: 16px;
1249 }
1250
1251 .search-field input,
1252 .composer textarea,
1253 .other-answer,
1254 .new-thread-dialog select,
1255 .rename-dialog input {
1256 font-size: 16px;
1257 }
1258
1259 .message.user .message-body {
1260 margin-left: 20px;
1261 }
1262 }
1263
1264 @media (max-width: 430px) {
1265 .session {
1266 grid-template-rows: auto auto minmax(0, 1fr) auto auto;
1267 }
1268
1269 .session-header {
1270 grid-template-columns: minmax(0, 1fr) auto;
1271 gap: 8px;
1272 min-height: 92px;
1273 padding-top: 8px;
1274 padding-bottom: 8px;
1275 }
1276
1277 .header-actions {
1278 position: static;
1279 }
1280
1281 .header-actions .quiet-button {
1282 min-width: 0;
1283 min-height: 34px;
1284 padding: 0 8px;
1285 font-size: 12px;
1286 }
1287
1288 .session-heading {
1289 padding-right: 0;
1290 }
1291
1292 .session-facts {
1293 display: flex;
1294 flex-wrap: nowrap;
1295 overflow-x: auto;
1296 scrollbar-width: none;
1297 }
1298
1299 .session-facts .fact-chip[data-fact="workspace"],
1300 .session-facts .fact-chip[data-fact="branch"] {
1301 display: none;
1302 }
1303
1304 .fact-chip {
1305 min-height: 26px;
1306 padding: 0 8px;
1307 font-size: 10.5px;
1308 }
1309
1310 .composer-hint {
1311 display: none;
1312 }
1313
1314 .composer-bar {
1315 justify-content: flex-end;
1316 }
1317
1318 .message.user .message-body {
1319 max-width: 92%;
1320 margin-left: 12px;
1321 }
1322 }
1323
1324 @media (pointer: coarse) {
1325 .primary-button,
1326 .quiet-button,
1327 .send-button,
1328 .icon-button,
1329 .new-thread,
1330 .search-field,
1331 .other-answer,
1332 .new-thread-dialog select,
1333 .rename-dialog input,
1334 .answer-option,
1335 .remember-field,
1336 .receipt summary,
1337 .reasoning summary {
1338 min-height: 44px;
1339 }
1340
1341 .answer-option,
1342 .remember-field,
1343 .receipt summary,
1344 .reasoning summary {
1345 display: flex;
1346 align-items: center;
1347 }
1348
1349 .icon-button {
1350 width: 44px;
1351 min-width: 44px;
1352 }
1353
1354 input[type="radio"],
1355 input[type="checkbox"] {
1356 width: 18px;
1357 height: 18px;
1358 flex: 0 0 18px;
1359 }
1360 }
1361
1362 @media (prefers-contrast: more) {
1363 :root {
1364 --line: rgba(209, 235, 244, 0.28);
1365 --line-strong: rgba(209, 235, 244, 0.46);
1366 --text-muted: #b6c0d4;
1367 --text-faint: #a8b3c5;
1368 }
1369 }
1370
1371 @media (forced-colors: active) {
1372 .status-pip,
1373 .connection-dot,
1374 .receipt-dot {
1375 border: 1px solid CanvasText;
1376 }
1377 }
1378
1379 @media (prefers-reduced-motion: reduce) {
1380 *,
1381 *::before,
1382 *::after {
1383 scroll-behavior: auto !important;
1384 transition-duration: 0.01ms !important;
1385 animation-duration: 0.01ms !important;
1386 animation-iteration-count: 1 !important;
1387 }
1388 }
1389
1389 lines CSS