jinzd-ai-cli 0.4.202 → 0.4.204

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +435 -435
  3. package/README.zh-CN.md +450 -450
  4. package/dist/agent-client-6GX6QQDU.js +0 -0
  5. package/dist/auth-FSTAKSYF.js +0 -0
  6. package/dist/{batch-UF4EWYFD.js → batch-ZP52GVVD.js} +2 -2
  7. package/dist/chat-index-FDSGKWQV.js +0 -0
  8. package/dist/{chunk-Y6U6FMVV.js → chunk-26YWVRLT.js} +1 -1
  9. package/dist/chunk-4BKXL7SM.js +0 -0
  10. package/dist/chunk-A4GUGWEY.js +0 -0
  11. package/dist/{chunk-2YLYDFEX.js → chunk-B75A6AG4.js} +19 -5
  12. package/dist/{chunk-JCY7RQIA.js → chunk-BENRC3OO.js} +1 -1
  13. package/dist/chunk-BXP6YZ2P.js +0 -0
  14. package/dist/chunk-CITDVXXM.js +0 -0
  15. package/dist/chunk-CKH4KQ4E.js +0 -0
  16. package/dist/chunk-E44DTERW.js +0 -0
  17. package/dist/{chunk-75SUTNYY.js → chunk-GYN2PTY2.js} +1 -1
  18. package/dist/chunk-HLWUDRBO.js +0 -0
  19. package/dist/chunk-HOSJZMQS.js +0 -0
  20. package/dist/chunk-IW3Q7AE5.js +0 -0
  21. package/dist/{chunk-GOKVKOG3.js → chunk-JLZ5QA2I.js} +1 -1
  22. package/dist/chunk-JVKAL5Q3.js +0 -0
  23. package/dist/chunk-KHYD3WXE.js +0 -0
  24. package/dist/chunk-MC34ISJU.js +0 -0
  25. package/dist/chunk-NZ4X6GUC.js +0 -0
  26. package/dist/chunk-O6UFCEUZ.js +0 -0
  27. package/dist/chunk-OJL3PY36.js +0 -0
  28. package/dist/{chunk-Q2MBPMTW.js → chunk-PIZWD5JN.js} +2 -2
  29. package/dist/chunk-Q3ZUDA6S.js +0 -0
  30. package/dist/{chunk-HZKC424D.js → chunk-SCQOEDVL.js} +1 -1
  31. package/dist/chunk-SLSWPBK3.js +0 -0
  32. package/dist/{chunk-5UR6ZOF4.js → chunk-SMFRJCXB.js} +7 -0
  33. package/dist/chunk-T2NL5ZIA.js +0 -0
  34. package/dist/{chunk-SB77W6XS.js → chunk-T5RTPF2Q.js} +1 -1
  35. package/dist/chunk-TB4W4Y4T.js +0 -0
  36. package/dist/chunk-TZQHYZKT.js +0 -0
  37. package/dist/{chunk-2NINHXEZ.js → chunk-UZISJ3KZ.js} +1 -1
  38. package/dist/{ci-YOJTTP4J.js → ci-LWE2I5QW.js} +4 -4
  39. package/dist/{constants-VP7TYJL7.js → constants-JRY7PDEY.js} +1 -1
  40. package/dist/{doctor-cli-PCIKXTNV.js → doctor-cli-KPUULUPS.js} +6 -6
  41. package/dist/electron-server.js +27 -6
  42. package/dist/file-checkpoint-NKBHGC7L.js +0 -0
  43. package/dist/git-context-EXOEHQSF.js +0 -0
  44. package/dist/{hub-N2ZRAXRO.js → hub-4CDJPNIM.js} +1 -1
  45. package/dist/hub-server-LJ2JSKZ2.js +0 -0
  46. package/dist/index.js +23 -21
  47. package/dist/indexer-AKWMYNJI.js +0 -0
  48. package/dist/persist-L54DPLI7.js +0 -0
  49. package/dist/project-trust-NKYHL3VZ.js +0 -0
  50. package/dist/{run-tests-AXPZOPX7.js → run-tests-6G2F7OSC.js} +1 -1
  51. package/dist/{run-tests-RNU733RF.js → run-tests-RQWSG25U.js} +2 -2
  52. package/dist/semantic-PK7AUOJT.js +0 -0
  53. package/dist/{server-SLFGYGBO.js → server-MF6UDMBZ.js} +14 -12
  54. package/dist/{server-YIBPZJ34.js → server-XNB76DRR.js} +5 -5
  55. package/dist/store-MWNHVGJT.js +0 -0
  56. package/dist/{task-orchestrator-FM4EXIBZ.js → task-orchestrator-PKZ2UTOK.js} +5 -5
  57. package/dist/{usage-QFW2XPF3.js → usage-Z64KJASD.js} +2 -2
  58. package/dist/vector-store-BBDXB5IQ.js +0 -0
  59. package/dist/wasm/web-tree-sitter.wasm +0 -0
  60. package/dist/web/client/app.js +3351 -3351
  61. package/dist/web/client/icon.svg +22 -22
  62. package/dist/web/client/index.html +360 -360
  63. package/dist/web/client/manifest.json +15 -15
  64. package/dist/web/client/style.css +991 -991
  65. package/dist/web/client/sw.js +86 -86
  66. package/package.json +176 -176
@@ -1,991 +1,991 @@
1
- /* ai-cli Web UI — Custom styles (DaisyUI handles base theme) */
2
-
3
- /* ── Auth Screen ───────────────────────────────────── */
4
- .auth-screen {
5
- position: fixed;
6
- inset: 0;
7
- z-index: 9999;
8
- display: flex;
9
- align-items: center;
10
- justify-content: center;
11
- background: oklch(var(--b3));
12
- backdrop-filter: blur(8px);
13
- }
14
- .auth-card {
15
- background: oklch(var(--b1));
16
- border: 1px solid oklch(var(--bc) / 0.1);
17
- border-radius: var(--rounded-box, 1rem);
18
- padding: 2rem;
19
- width: 100%;
20
- max-width: 380px;
21
- box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
22
- }
23
-
24
- /* ── Scrollbar ──────────────────────────────────────── */
25
- #chat-area::-webkit-scrollbar { width: 6px; }
26
- #chat-area::-webkit-scrollbar-track { background: transparent; }
27
- #chat-area::-webkit-scrollbar-thumb {
28
- background: oklch(var(--bc) / 0.2);
29
- border-radius: 3px;
30
- }
31
-
32
- /* ── Chat bubbles ───────────────────────────────────── */
33
- .chat-bubble-user {
34
- white-space: pre-wrap;
35
- }
36
-
37
- /* ── Assistant message (markdown rendered) ──────────── */
38
- .msg-assistant {
39
- background: oklch(var(--b2));
40
- border-radius: var(--rounded-box, 1rem);
41
- padding: 1rem 1.25rem;
42
- line-height: 1.7;
43
- word-wrap: break-word;
44
- overflow-wrap: break-word;
45
- border-left: 3px solid oklch(var(--su));
46
- }
47
-
48
- .msg-assistant h1,
49
- .msg-assistant h2,
50
- .msg-assistant h3 {
51
- color: oklch(var(--p));
52
- margin: 1rem 0 0.5rem;
53
- font-weight: 700;
54
- }
55
- .msg-assistant h1 { font-size: 1.3em; }
56
- .msg-assistant h2 { font-size: 1.15em; }
57
- .msg-assistant h3 { font-size: 1.05em; }
58
-
59
- .msg-assistant code {
60
- background: oklch(var(--b3));
61
- padding: 2px 6px;
62
- border-radius: 4px;
63
- font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
64
- font-size: 0.88em;
65
- }
66
-
67
- .msg-assistant pre {
68
- background: oklch(var(--b3));
69
- border-radius: 0.5rem;
70
- overflow-x: auto;
71
- margin: 0.75rem 0;
72
- position: relative;
73
- }
74
-
75
- .msg-assistant pre code {
76
- display: block;
77
- padding: 1rem;
78
- background: transparent;
79
- font-size: 0.85em;
80
- line-height: 1.5;
81
- }
82
-
83
- .msg-assistant ul, .msg-assistant ol {
84
- padding-left: 1.25rem;
85
- margin: 0.5rem 0;
86
- }
87
-
88
- .msg-assistant li { margin: 0.25rem 0; }
89
-
90
- .msg-assistant blockquote {
91
- border-left: 3px solid oklch(var(--p) / 0.5);
92
- padding-left: 0.75rem;
93
- opacity: 0.85;
94
- margin: 0.5rem 0;
95
- }
96
-
97
- .msg-assistant table {
98
- border-collapse: collapse;
99
- margin: 0.5rem 0;
100
- width: 100%;
101
- font-size: 0.9em;
102
- }
103
- .msg-assistant th,
104
- .msg-assistant td {
105
- border: 1px solid oklch(var(--bc) / 0.15);
106
- padding: 0.4rem 0.75rem;
107
- text-align: left;
108
- }
109
- .msg-assistant th {
110
- background: oklch(var(--b3));
111
- font-weight: 600;
112
- }
113
-
114
- .msg-assistant a {
115
- color: oklch(var(--p));
116
- text-decoration: underline;
117
- }
118
-
119
- .msg-assistant p {
120
- margin: 0.4rem 0;
121
- }
122
-
123
- /* ── Streaming cursor ───────────────────────────────── */
124
- .streaming-cursor::after {
125
- content: '▌';
126
- animation: blink 0.8s infinite;
127
- color: oklch(var(--p));
128
- }
129
- @keyframes blink {
130
- 0%, 100% { opacity: 1; }
131
- 50% { opacity: 0; }
132
- }
133
-
134
- /* ── Tool call cards (collapsible <details>) ────────── */
135
- .tool-card {
136
- background: oklch(var(--b2));
137
- border-radius: 0.5rem;
138
- padding: 0.5rem 1rem;
139
- font-size: 0.85rem;
140
- border-left: 3px solid transparent;
141
- }
142
- .tool-card summary {
143
- list-style: none;
144
- }
145
- .tool-card summary::-webkit-details-marker { display: none; }
146
- .tool-card summary::before {
147
- content: '▶';
148
- font-size: 0.65rem;
149
- margin-right: 0.4rem;
150
- transition: transform 0.15s;
151
- display: inline-block;
152
- opacity: 0.5;
153
- }
154
- .tool-card[open] summary::before {
155
- transform: rotate(90deg);
156
- }
157
- .tool-card .tool-details-body {
158
- padding-top: 0.25rem;
159
- }
160
- .tool-border-safe { border-left-color: oklch(var(--in)); }
161
- .tool-border-write { border-left-color: oklch(var(--wa)); }
162
- .tool-border-destructive { border-left-color: oklch(var(--er)); }
163
-
164
- .tool-card .tool-args {
165
- white-space: pre-wrap;
166
- max-height: 100px;
167
- overflow-y: auto;
168
- font-size: 0.8rem;
169
- opacity: 0.65;
170
- line-height: 1.5;
171
- }
172
- .tool-card .tool-result-content {
173
- white-space: pre-wrap;
174
- max-height: 200px;
175
- overflow-y: auto;
176
- font-size: 0.8rem;
177
- }
178
-
179
- /* ── Confirm / ask-user card ────────────────────────── */
180
- .confirm-card {
181
- background: oklch(var(--b2));
182
- border-radius: 0.5rem;
183
- padding: 0.75rem 1rem;
184
- border-left: 3px solid transparent;
185
- }
186
-
187
- .confirm-diff {
188
- background: oklch(var(--b3));
189
- color: oklch(var(--bc));
190
- padding: 0.5rem;
191
- border-radius: 0.375rem;
192
- font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
193
- font-size: 0.78rem;
194
- white-space: pre-wrap;
195
- max-height: 200px;
196
- overflow-y: auto;
197
- margin-bottom: 0.5rem;
198
- }
199
-
200
- /* ── Error message ──────────────────────────────────── */
201
- .error-message {
202
- background: oklch(var(--er) / 0.1);
203
- border-left: 3px solid oklch(var(--er));
204
- border-radius: 0.5rem;
205
- padding: 0.5rem 1rem;
206
- }
207
-
208
- /* ── Thinking block ─────────────────────────────────── */
209
- .thinking-block summary {
210
- cursor: pointer;
211
- font-style: italic;
212
- opacity: 0.6;
213
- font-size: 0.85rem;
214
- }
215
- .thinking-block .thinking-content {
216
- padding: 0.5rem 0.75rem;
217
- border-left: 2px solid oklch(var(--bc) / 0.15);
218
- margin-top: 0.25rem;
219
- white-space: pre-wrap;
220
- font-size: 0.85rem;
221
- opacity: 0.6;
222
- }
223
-
224
- /* ── Todo list ──────────────────────────────────────── */
225
- .todo-item.completed { color: oklch(var(--su)); }
226
- .todo-item.in_progress { color: oklch(var(--wa)); }
227
- .todo-item.pending { opacity: 0.5; }
228
-
229
- /* ── Copy button on code blocks ─────────────────────── */
230
- .copy-code-btn {
231
- position: absolute;
232
- top: 0.4rem;
233
- right: 0.4rem;
234
- padding: 0.2rem 0.5rem;
235
- font-size: 0.7rem;
236
- opacity: 0;
237
- transition: opacity 0.2s;
238
- }
239
- .msg-assistant pre:hover .copy-code-btn {
240
- opacity: 1;
241
- }
242
-
243
- /* ── Active toggle buttons ──────────────────────────── */
244
- .btn-active-toggle {
245
- border: 1px solid oklch(var(--p)) !important;
246
- background: oklch(var(--p) / 0.15) !important;
247
- color: oklch(var(--p)) !important;
248
- }
249
-
250
- /* ── Batch confirm file list ────────────────────────── */
251
- .file-item {
252
- display: flex;
253
- align-items: center;
254
- gap: 0.5rem;
255
- padding: 0.25rem 0;
256
- font-size: 0.85rem;
257
- }
258
-
259
- /* ── Connection status ──────────────────────────────── */
260
- .status-connected { color: oklch(var(--su)); }
261
- .status-disconnected { color: oklch(var(--er)); }
262
-
263
- /* ── Sidebar tabs ──────────────────────────────────── */
264
- .sidebar-tab {
265
- cursor: pointer;
266
- opacity: 0.5;
267
- transition: all 0.15s;
268
- border-bottom: 2px solid transparent;
269
- }
270
- .sidebar-tab:hover { opacity: 0.8; }
271
- .sidebar-tab.active {
272
- opacity: 1;
273
- border-bottom-color: oklch(var(--p));
274
- color: oklch(var(--p));
275
- }
276
-
277
- /* ── Sidebar resize handle ─────────────────────────── */
278
- .sidebar-resize-handle {
279
- width: 4px;
280
- cursor: col-resize;
281
- flex-shrink: 0;
282
- background: transparent;
283
- transition: background 0.15s;
284
- position: relative;
285
- z-index: 5;
286
- }
287
- .sidebar-resize-handle::after {
288
- content: '';
289
- position: absolute;
290
- top: 0;
291
- left: -3px;
292
- right: -3px;
293
- bottom: 0;
294
- }
295
- .sidebar-resize-handle:hover,
296
- .sidebar-resize-handle.resizing {
297
- background: oklch(var(--p) / 0.4);
298
- }
299
-
300
- /* ── Sidebar ───────────────────────────────────────── */
301
- .sidebar {
302
- width: 18rem;
303
- transition: width 0.2s ease;
304
- }
305
- .sidebar.no-transition {
306
- transition: none;
307
- }
308
- .sidebar .session-item {
309
- padding: 0.5rem 0.6rem;
310
- border-radius: 0.375rem;
311
- cursor: pointer;
312
- transition: background 0.15s;
313
- border-left: 2px solid transparent;
314
- }
315
- .sidebar .session-item:hover {
316
- background: oklch(var(--b3));
317
- }
318
- .sidebar .session-item.active {
319
- background: oklch(var(--p) / 0.15);
320
- border-left-color: oklch(var(--p));
321
- }
322
- .sidebar .session-item .session-title {
323
- white-space: nowrap;
324
- overflow: hidden;
325
- text-overflow: ellipsis;
326
- font-size: 0.85rem;
327
- cursor: text;
328
- }
329
- .sidebar .session-item .session-rename-input {
330
- height: 1.5rem;
331
- min-height: 1.5rem;
332
- padding: 0 0.4rem;
333
- }
334
- .sidebar .session-item .session-meta {
335
- font-size: 0.7rem;
336
- opacity: 0.5;
337
- }
338
- .sidebar .session-item:hover .session-delete-btn {
339
- opacity: 0.5;
340
- }
341
- .sidebar .session-item:hover .session-delete-btn:hover {
342
- opacity: 1;
343
- }
344
-
345
- /* ── Image upload preview ──────────────────────────── */
346
- #image-preview {
347
- border-top: 1px dashed oklch(var(--bc) / 0.15);
348
- padding-top: 0.5rem;
349
- }
350
- .image-thumb {
351
- display: inline-block;
352
- }
353
-
354
- /* ── Diff syntax highlighting ─────────────────────── */
355
- .confirm-diff .diff-add {
356
- color: oklch(var(--su));
357
- background: oklch(var(--su) / 0.1);
358
- }
359
- .confirm-diff .diff-del {
360
- color: oklch(var(--er));
361
- background: oklch(var(--er) / 0.1);
362
- }
363
- .confirm-diff .diff-hunk {
364
- color: oklch(var(--p));
365
- opacity: 0.8;
366
- font-weight: 600;
367
- }
368
- .confirm-diff .diff-ctx {
369
- opacity: 0.6;
370
- }
371
-
372
- /* ── Tools sidebar list ──────────────────────────── */
373
- .tools-section-title {
374
- font-size: 0.7rem;
375
- font-weight: 700;
376
- text-transform: uppercase;
377
- letter-spacing: 0.05em;
378
- opacity: 0.4;
379
- padding: 0.5rem 0.25rem 0.25rem;
380
- }
381
- .tool-item {
382
- padding: 0.3rem 0.5rem;
383
- border-radius: 0.25rem;
384
- font-size: 0.8rem;
385
- display: flex;
386
- align-items: center;
387
- gap: 0.35rem;
388
- }
389
- .tool-item:hover {
390
- background: oklch(var(--b3));
391
- }
392
- .tool-item .tool-dot {
393
- width: 6px;
394
- height: 6px;
395
- border-radius: 50%;
396
- flex-shrink: 0;
397
- }
398
- .tool-dot-safe { background: oklch(var(--in)); }
399
- .tool-dot-write { background: oklch(var(--wa)); }
400
- .tool-dot-destructive { background: oklch(var(--er)); }
401
- .tool-dot-connected { background: oklch(var(--su)); }
402
- .tool-dot-disconnected { background: oklch(var(--er)); }
403
- .tool-dot-active { background: oklch(var(--su)); }
404
- .tool-dot-inactive { background: oklch(var(--bc) / 0.3); }
405
-
406
- .mcp-server-item {
407
- padding: 0.3rem 0.5rem;
408
- border-radius: 0.25rem;
409
- cursor: pointer;
410
- font-size: 0.8rem;
411
- }
412
- .mcp-server-item:hover {
413
- background: oklch(var(--b3));
414
- }
415
- .mcp-server-tools {
416
- padding-left: 1.25rem;
417
- font-size: 0.75rem;
418
- opacity: 0.6;
419
- }
420
-
421
- /* ── File tree ──────────────────────────────────────── */
422
- .file-tree-item {
423
- user-select: none;
424
- }
425
- .file-tree-row {
426
- display: flex;
427
- align-items: center;
428
- gap: 0.3rem;
429
- padding: 0.2rem 0.5rem;
430
- border-radius: 0.25rem;
431
- cursor: pointer;
432
- font-size: 0.8rem;
433
- transition: background 0.1s;
434
- min-width: 0;
435
- }
436
- .file-tree-row:hover {
437
- background: oklch(var(--b3));
438
- }
439
- .file-tree-row.file-tree-dir {
440
- font-weight: 500;
441
- }
442
- .file-tree-chevron {
443
- font-size: 0.55rem;
444
- opacity: 0.4;
445
- flex-shrink: 0;
446
- transition: transform 0.15s;
447
- display: inline-block;
448
- width: 0.75rem;
449
- text-align: center;
450
- }
451
- .file-tree-chevron.expanded {
452
- transform: rotate(90deg);
453
- }
454
- .file-tree-icon {
455
- font-size: 0.8rem;
456
- flex-shrink: 0;
457
- line-height: 1;
458
- }
459
- .file-tree-name {
460
- flex: 1;
461
- overflow: hidden;
462
- text-overflow: ellipsis;
463
- white-space: nowrap;
464
- min-width: 0;
465
- }
466
- .file-tree-insert-btn {
467
- flex-shrink: 0;
468
- font-size: 0.65rem;
469
- font-weight: 700;
470
- color: oklch(var(--p));
471
- opacity: 0;
472
- background: oklch(var(--p) / 0.12);
473
- border: none;
474
- border-radius: 0.2rem;
475
- padding: 0 0.3rem;
476
- cursor: pointer;
477
- line-height: 1.4;
478
- transition: opacity 0.15s, background 0.15s;
479
- }
480
- .file-tree-row:hover .file-tree-insert-btn {
481
- opacity: 1;
482
- }
483
- .file-tree-insert-btn:hover {
484
- background: oklch(var(--p) / 0.25) !important;
485
- }
486
- .file-tree-children {
487
- padding-left: 1rem;
488
- border-left: 1px solid oklch(var(--bc) / 0.08);
489
- margin-left: 0.85rem;
490
- }
491
-
492
- /* file preview card in chat */
493
- .file-preview-card {
494
- background: oklch(var(--b2));
495
- border-radius: var(--rounded-box, 1rem);
496
- padding: 0.75rem 1rem;
497
- border-left: 3px solid oklch(var(--in));
498
- }
499
- .file-preview-card pre {
500
- background: oklch(var(--b3));
501
- border-radius: 0.375rem;
502
- overflow-x: auto;
503
- margin: 0.5rem 0 0;
504
- }
505
- .file-preview-card pre code {
506
- display: block;
507
- padding: 0.75rem;
508
- font-size: 0.78rem;
509
- line-height: 1.5;
510
- font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
511
- }
512
-
513
- /* ── Session Tab Bar (P2-1: multi-tab in page) ──────── */
514
- .session-tab-bar {
515
- display: flex;
516
- align-items: stretch;
517
- min-height: 2.25rem;
518
- padding: 0;
519
- gap: 0;
520
- overflow: hidden;
521
- }
522
- .session-tabs-scroll {
523
- display: flex;
524
- align-items: stretch;
525
- overflow-x: auto;
526
- overflow-y: hidden;
527
- flex: 1;
528
- min-width: 0;
529
- scrollbar-width: thin;
530
- scrollbar-color: oklch(var(--bc) / 0.15) transparent;
531
- }
532
- .session-tabs-scroll::-webkit-scrollbar { height: 3px; }
533
- .session-tabs-scroll::-webkit-scrollbar-thumb { background: oklch(var(--bc) / 0.15); border-radius: 2px; }
534
-
535
- .session-tab-item {
536
- display: flex;
537
- align-items: center;
538
- gap: 0.35rem;
539
- padding: 0 0.75rem;
540
- font-size: 0.78rem;
541
- white-space: nowrap;
542
- cursor: pointer;
543
- border-right: 1px solid oklch(var(--bc) / 0.08);
544
- transition: background 0.12s;
545
- min-width: 0;
546
- max-width: 12rem;
547
- flex-shrink: 0;
548
- position: relative;
549
- user-select: none;
550
- }
551
- .session-tab-item:hover {
552
- background: oklch(var(--b3));
553
- }
554
- .session-tab-item.active {
555
- background: oklch(var(--b1));
556
- border-bottom: 2px solid oklch(var(--p));
557
- color: oklch(var(--p));
558
- font-weight: 600;
559
- }
560
- .session-tab-item:not(.active) {
561
- border-bottom: 2px solid transparent;
562
- }
563
- .session-tab-item .tab-title {
564
- overflow: hidden;
565
- text-overflow: ellipsis;
566
- white-space: nowrap;
567
- min-width: 0;
568
- flex: 1;
569
- }
570
- .session-tab-item .tab-processing {
571
- width: 6px;
572
- height: 6px;
573
- border-radius: 50%;
574
- background: oklch(var(--wa));
575
- flex-shrink: 0;
576
- animation: tab-pulse 1.2s infinite;
577
- }
578
- @keyframes tab-pulse {
579
- 0%, 100% { opacity: 0.4; }
580
- 50% { opacity: 1; }
581
- }
582
- .session-tab-item .tab-close {
583
- opacity: 0;
584
- font-size: 0.85rem;
585
- line-height: 1;
586
- padding: 0 0.15rem;
587
- border-radius: 0.2rem;
588
- cursor: pointer;
589
- flex-shrink: 0;
590
- transition: opacity 0.12s, background 0.12s;
591
- }
592
- .session-tab-item:hover .tab-close,
593
- .session-tab-item.active .tab-close {
594
- opacity: 0.5;
595
- }
596
- .session-tab-item .tab-close:hover {
597
- opacity: 1;
598
- background: oklch(var(--er) / 0.2);
599
- color: oklch(var(--er));
600
- }
601
- .session-tab-add {
602
- display: flex;
603
- align-items: center;
604
- justify-content: center;
605
- width: 2rem;
606
- flex-shrink: 0;
607
- font-size: 1.1rem;
608
- font-weight: 300;
609
- cursor: pointer;
610
- opacity: 0.4;
611
- transition: opacity 0.12s, background 0.12s;
612
- border: none;
613
- background: transparent;
614
- color: inherit;
615
- }
616
- .session-tab-add:hover {
617
- opacity: 1;
618
- background: oklch(var(--b3));
619
- }
620
-
621
- /* ── Round progress bar (sticky top of chat area) ──── */
622
- .round-progress-bar {
623
- position: sticky;
624
- top: 0;
625
- z-index: 10;
626
- padding: 0.4rem 1rem;
627
- background: oklch(var(--b2) / 0.92);
628
- backdrop-filter: blur(8px);
629
- border-bottom: 1px solid oklch(var(--bc) / 0.1);
630
- max-width: 64rem;
631
- margin: -1rem auto 0.5rem;
632
- }
633
- .round-progress-inner {
634
- display: flex;
635
- align-items: center;
636
- gap: 0.75rem;
637
- }
638
- .round-progress-label {
639
- font-size: 0.75rem;
640
- font-weight: 600;
641
- opacity: 0.7;
642
- white-space: nowrap;
643
- }
644
-
645
- /* ── Tool duration & timer ─────────────────────────── */
646
- .tool-timer {
647
- font-size: 0.7rem;
648
- font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
649
- opacity: 0.5;
650
- white-space: nowrap;
651
- }
652
- .tool-timer.timing {
653
- color: oklch(var(--wa));
654
- opacity: 0.7;
655
- }
656
- .tool-duration {
657
- font-size: 0.7rem;
658
- font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
659
- opacity: 0.6;
660
- white-space: nowrap;
661
- }
662
- .tool-duration.fast { color: oklch(var(--su)); }
663
- .tool-duration.medium { color: oklch(var(--wa)); }
664
- .tool-duration.slow { color: oklch(var(--er)); }
665
-
666
- /* ── Prompt templates ──────────────────────────────── */
667
- .template-item {
668
- display: flex;
669
- align-items: flex-start;
670
- gap: 0.5rem;
671
- padding: 0.5rem 0.75rem;
672
- border-radius: 0.375rem;
673
- cursor: pointer;
674
- transition: background 0.15s;
675
- border: 1px solid oklch(var(--bc) / 0.08);
676
- }
677
- .template-item:hover {
678
- background: oklch(var(--b3));
679
- border-color: oklch(var(--p) / 0.3);
680
- }
681
- .template-item-body {
682
- flex: 1;
683
- min-width: 0;
684
- }
685
- .template-item-name {
686
- font-weight: 600;
687
- font-size: 0.9rem;
688
- }
689
- .template-item-preview {
690
- font-size: 0.78rem;
691
- opacity: 0.55;
692
- white-space: nowrap;
693
- overflow: hidden;
694
- text-overflow: ellipsis;
695
- max-width: 100%;
696
- }
697
- .template-item-tags {
698
- display: flex;
699
- gap: 0.25rem;
700
- flex-wrap: wrap;
701
- margin-top: 0.2rem;
702
- }
703
- .template-item-tag {
704
- font-size: 0.65rem;
705
- padding: 0.05rem 0.35rem;
706
- border-radius: 0.25rem;
707
- background: oklch(var(--p) / 0.12);
708
- color: oklch(var(--p));
709
- }
710
- .template-item-actions {
711
- display: flex;
712
- gap: 0.25rem;
713
- flex-shrink: 0;
714
- opacity: 0;
715
- transition: opacity 0.15s;
716
- }
717
- .template-item:hover .template-item-actions {
718
- opacity: 1;
719
- }
720
- .template-empty {
721
- text-align: center;
722
- padding: 2rem;
723
- opacity: 0.4;
724
- font-size: 0.85rem;
725
- }
726
-
727
- /* ── Sidebar toggle button ──────────────────────────── */
728
- /* Visible on every width: on desktop it collapses the panel to give all
729
- space to the chat; on mobile (≤768px) it opens/closes the slide-over. */
730
- .sidebar-toggle-btn { display: flex; }
731
-
732
- /* Desktop collapse: scoped to ≥769px so it never fights the mobile
733
- slide-over rules (which use .sidebar-open). width:0 !important is needed
734
- to override the inline width set by the drag-resize handle. */
735
- @media (min-width: 769px) {
736
- .sidebar.sidebar-collapsed {
737
- width: 0 !important;
738
- min-width: 0;
739
- border-right-width: 0;
740
- overflow: hidden;
741
- }
742
- .sidebar.sidebar-collapsed + .sidebar-resize-handle { display: none; }
743
- }
744
-
745
- /* ── Sidebar backdrop (mobile overlay) ───────────────── */
746
- .sidebar-backdrop {
747
- position: fixed;
748
- inset: 0;
749
- top: 3.5rem;
750
- background: rgba(0, 0, 0, 0.5);
751
- z-index: 19;
752
- -webkit-backdrop-filter: blur(2px);
753
- backdrop-filter: blur(2px);
754
- }
755
-
756
- /* ── Touch optimization ──────────────────────────────── */
757
- button, a, .session-item, .file-tree-row, .template-item, .tool-item, .mcp-server-item {
758
- -webkit-tap-highlight-color: transparent;
759
- touch-action: manipulation;
760
- }
761
-
762
- /* ── Input footer safe area (iPhone notch) ───────────── */
763
- .input-footer {
764
- padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
765
- }
766
-
767
- /* ── Responsive: Tablet ────────────────────────────── */
768
- @media (max-width: 768px) {
769
- .sidebar-toggle-btn { display: flex; }
770
- .sidebar-resize-handle { display: none; }
771
- .sidebar {
772
- width: 0;
773
- padding: 0;
774
- border: none;
775
- position: fixed;
776
- z-index: 20;
777
- top: 3.5rem;
778
- left: 0;
779
- height: calc(100vh - 3.5rem);
780
- height: calc(100dvh - 3.5rem);
781
- transition: width 0.2s ease, padding 0.2s ease;
782
- }
783
- .sidebar.sidebar-open {
784
- width: 18rem;
785
- border-right: 1px solid oklch(var(--bc) / 0.1);
786
- overflow: hidden;
787
- }
788
- /* Provider/model selects: narrower on tablet */
789
- .navbar-select { width: 7rem; font-size: 0.8rem; }
790
- /* Navbar end buttons: hide text labels */
791
- #btn-think, #btn-plan { font-size: 0.8rem; padding: 0 0.4rem; }
792
- }
793
-
794
- /* ── Responsive: Phone ──────────────────────────────── */
795
- @media (max-width: 640px) {
796
- /* Navbar: compact layout */
797
- .navbar { padding: 0 0.5rem; min-height: 3rem; }
798
- .navbar-start { gap: 0.25rem; }
799
- .navbar-end { gap: 0; }
800
- .brand-text { display: none; }
801
- .navbar-select { width: 5.5rem; font-size: 0.72rem; height: 2rem; min-height: 2rem; }
802
- /* Navbar end: icon-only for action buttons */
803
- #btn-think, #btn-plan { font-size: 0.75rem; padding: 0 0.3rem; min-height: 2rem; height: 2rem; }
804
- .divider-horizontal { display: none; }
805
- #btn-clear, #btn-compact { min-height: 2rem; height: 2rem; padding: 0 0.3rem; }
806
-
807
- /* Sidebar: full width on small phones */
808
- .sidebar.sidebar-open { width: min(85vw, 20rem); }
809
-
810
- /* Tab bar: smaller on phone */
811
- .session-tab-item { padding: 0 0.5rem; font-size: 0.72rem; max-width: 9rem; }
812
- .session-tab-bar { min-height: 2rem; }
813
- .session-tab-item .tab-close { opacity: 0.4; } /* always visible on mobile (no hover) */
814
-
815
- /* Chat area */
816
- #chat-area { padding: 0.75rem 0.5rem; }
817
- .msg-assistant { padding: 0.75rem; font-size: 0.92rem; }
818
- .msg-assistant pre code { font-size: 0.78rem; padding: 0.75rem; }
819
- .msg-assistant table { font-size: 0.8rem; }
820
- .msg-assistant th, .msg-assistant td { padding: 0.3rem 0.5rem; }
821
-
822
- /* Input area */
823
- .input-footer { padding: 0.5rem; padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px)); }
824
- .input-footer .max-w-4xl { gap: 0.35rem; }
825
- #user-input { font-size: 16px; /* Prevents iOS zoom on focus */ min-height: 2.5rem; }
826
- #btn-send, #btn-stop { width: 2.5rem; height: 2.5rem; min-height: 2.5rem; }
827
- #btn-templates { width: 2rem; height: 2rem; min-height: 2rem; }
828
- #btn-templates .text-lg { font-size: 1rem; }
829
-
830
- /* Status bar: hide or compact */
831
- .input-footer .text-xs { font-size: 0.65rem; gap: 0.25rem; }
832
-
833
- /* Tool cards */
834
- .tool-card { padding: 0.4rem 0.65rem; font-size: 0.8rem; }
835
- .confirm-diff { font-size: 0.72rem; max-height: 150px; }
836
-
837
- /* Copy button always visible on mobile (no hover) */
838
- .copy-code-btn { opacity: 0.6; }
839
-
840
- /* Modals: near full-width on phone */
841
- .modal-box { max-width: 95vw; margin: 0.5rem; }
842
- #templates-modal .modal-box { max-height: 85vh; }
843
- }
844
-
845
- /* ── Responsive: Very small phones (320px) ───────────── */
846
- @media (max-width: 380px) {
847
- .navbar-select { width: 4.5rem; font-size: 0.68rem; }
848
- .sidebar.sidebar-open { width: 90vw; }
849
- .msg-assistant { padding: 0.5rem 0.6rem; font-size: 0.88rem; }
850
- }
851
-
852
- /* ── Landscape phone: reduce vertical space ──────────── */
853
- @media (max-height: 500px) and (max-width: 900px) {
854
- .navbar { min-height: 2.5rem; }
855
- .input-footer { padding-top: 0.35rem; padding-bottom: calc(0.35rem + env(safe-area-inset-bottom, 0px)); }
856
- #chat-area { padding-top: 0.5rem; padding-bottom: 0.5rem; }
857
- }
858
-
859
- /* ── PWA standalone mode: extra top padding for status bar ── */
860
- @media (display-mode: standalone) {
861
- .navbar { padding-top: env(safe-area-inset-top, 0px); }
862
- }
863
-
864
- /* ── Session Replay (B1) ───────────────────────────── */
865
- .replay-step {
866
- border-left: 3px solid hsl(var(--b3));
867
- padding: 0.5rem 0.6rem;
868
- background: hsl(var(--b1));
869
- border-radius: 0 0.35rem 0.35rem 0;
870
- font-size: 0.85rem;
871
- }
872
- .replay-step.role-user { border-left-color: #3b82f6; }
873
- .replay-step.role-assistant { border-left-color: #10b981; }
874
- .replay-step.role-tool { border-left-color: #f59e0b; }
875
- .replay-step.role-tool.error { border-left-color: #ef4444; }
876
- .replay-step-header {
877
- display: flex;
878
- gap: 0.5rem;
879
- align-items: center;
880
- font-size: 0.72rem;
881
- opacity: 0.75;
882
- margin-bottom: 0.25rem;
883
- }
884
- .replay-step-header .role-tag {
885
- font-weight: 600;
886
- padding: 0 0.35rem;
887
- border-radius: 0.25rem;
888
- background: hsl(var(--b3));
889
- }
890
- .replay-step-body {
891
- white-space: pre-wrap;
892
- word-break: break-word;
893
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
894
- font-size: 0.78rem;
895
- max-height: 18rem;
896
- overflow-y: auto;
897
- }
898
- .replay-step-body.text-body {
899
- font-family: inherit;
900
- font-size: 0.85rem;
901
- }
902
- .replay-tool-block {
903
- margin-top: 0.3rem;
904
- padding: 0.4rem;
905
- background: hsl(var(--b2));
906
- border-radius: 0.3rem;
907
- font-size: 0.78rem;
908
- }
909
- .replay-tool-block .tool-name {
910
- font-weight: 600;
911
- color: #f59e0b;
912
- }
913
- .replay-tool-block pre {
914
- margin: 0.2rem 0 0;
915
- white-space: pre-wrap;
916
- word-break: break-word;
917
- font-size: 0.72rem;
918
- max-height: 12rem;
919
- overflow-y: auto;
920
- }
921
-
922
- /* ── B2 Branch picker (sidebar) ─────────────────────────── */
923
- .branch-item {
924
- display: flex;
925
- align-items: center;
926
- gap: 0.35rem;
927
- padding: 0.35rem 0.5rem;
928
- border-radius: 0.35rem;
929
- cursor: pointer;
930
- border: 1px solid transparent;
931
- transition: background 0.1s, border-color 0.1s;
932
- font-size: 0.78rem;
933
- line-height: 1.25;
934
- position: relative;
935
- }
936
- .branch-item:hover {
937
- background: rgba(128, 128, 128, 0.12);
938
- }
939
- .branch-item.active {
940
- background: rgba(34, 197, 94, 0.12);
941
- border-color: rgba(34, 197, 94, 0.45);
942
- }
943
- .branch-item .branch-marker {
944
- flex-shrink: 0;
945
- width: 0.8rem;
946
- color: rgb(34, 197, 94);
947
- }
948
- .branch-item .branch-title {
949
- flex: 1;
950
- min-width: 0;
951
- overflow: hidden;
952
- text-overflow: ellipsis;
953
- white-space: nowrap;
954
- }
955
- .branch-item .branch-id {
956
- flex-shrink: 0;
957
- opacity: 0.5;
958
- font-family: ui-monospace, SFMono-Regular, monospace;
959
- font-size: 0.7rem;
960
- }
961
- .branch-item .branch-count {
962
- flex-shrink: 0;
963
- opacity: 0.55;
964
- font-size: 0.7rem;
965
- }
966
- .branch-item .branch-actions {
967
- display: none;
968
- gap: 0.15rem;
969
- flex-shrink: 0;
970
- }
971
- .branch-item:hover .branch-actions {
972
- display: flex;
973
- }
974
- .branch-item .branch-actions button {
975
- background: transparent;
976
- border: none;
977
- padding: 0 0.2rem;
978
- font-size: 0.72rem;
979
- cursor: pointer;
980
- opacity: 0.7;
981
- }
982
- .branch-item .branch-actions button:hover {
983
- opacity: 1;
984
- }
985
- .branch-item .branch-indent {
986
- flex-shrink: 0;
987
- color: rgba(128, 128, 128, 0.5);
988
- font-family: ui-monospace, SFMono-Regular, monospace;
989
- font-size: 0.72rem;
990
- white-space: pre;
991
- }
1
+ /* ai-cli Web UI — Custom styles (DaisyUI handles base theme) */
2
+
3
+ /* ── Auth Screen ───────────────────────────────────── */
4
+ .auth-screen {
5
+ position: fixed;
6
+ inset: 0;
7
+ z-index: 9999;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ background: oklch(var(--b3));
12
+ backdrop-filter: blur(8px);
13
+ }
14
+ .auth-card {
15
+ background: oklch(var(--b1));
16
+ border: 1px solid oklch(var(--bc) / 0.1);
17
+ border-radius: var(--rounded-box, 1rem);
18
+ padding: 2rem;
19
+ width: 100%;
20
+ max-width: 380px;
21
+ box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
22
+ }
23
+
24
+ /* ── Scrollbar ──────────────────────────────────────── */
25
+ #chat-area::-webkit-scrollbar { width: 6px; }
26
+ #chat-area::-webkit-scrollbar-track { background: transparent; }
27
+ #chat-area::-webkit-scrollbar-thumb {
28
+ background: oklch(var(--bc) / 0.2);
29
+ border-radius: 3px;
30
+ }
31
+
32
+ /* ── Chat bubbles ───────────────────────────────────── */
33
+ .chat-bubble-user {
34
+ white-space: pre-wrap;
35
+ }
36
+
37
+ /* ── Assistant message (markdown rendered) ──────────── */
38
+ .msg-assistant {
39
+ background: oklch(var(--b2));
40
+ border-radius: var(--rounded-box, 1rem);
41
+ padding: 1rem 1.25rem;
42
+ line-height: 1.7;
43
+ word-wrap: break-word;
44
+ overflow-wrap: break-word;
45
+ border-left: 3px solid oklch(var(--su));
46
+ }
47
+
48
+ .msg-assistant h1,
49
+ .msg-assistant h2,
50
+ .msg-assistant h3 {
51
+ color: oklch(var(--p));
52
+ margin: 1rem 0 0.5rem;
53
+ font-weight: 700;
54
+ }
55
+ .msg-assistant h1 { font-size: 1.3em; }
56
+ .msg-assistant h2 { font-size: 1.15em; }
57
+ .msg-assistant h3 { font-size: 1.05em; }
58
+
59
+ .msg-assistant code {
60
+ background: oklch(var(--b3));
61
+ padding: 2px 6px;
62
+ border-radius: 4px;
63
+ font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
64
+ font-size: 0.88em;
65
+ }
66
+
67
+ .msg-assistant pre {
68
+ background: oklch(var(--b3));
69
+ border-radius: 0.5rem;
70
+ overflow-x: auto;
71
+ margin: 0.75rem 0;
72
+ position: relative;
73
+ }
74
+
75
+ .msg-assistant pre code {
76
+ display: block;
77
+ padding: 1rem;
78
+ background: transparent;
79
+ font-size: 0.85em;
80
+ line-height: 1.5;
81
+ }
82
+
83
+ .msg-assistant ul, .msg-assistant ol {
84
+ padding-left: 1.25rem;
85
+ margin: 0.5rem 0;
86
+ }
87
+
88
+ .msg-assistant li { margin: 0.25rem 0; }
89
+
90
+ .msg-assistant blockquote {
91
+ border-left: 3px solid oklch(var(--p) / 0.5);
92
+ padding-left: 0.75rem;
93
+ opacity: 0.85;
94
+ margin: 0.5rem 0;
95
+ }
96
+
97
+ .msg-assistant table {
98
+ border-collapse: collapse;
99
+ margin: 0.5rem 0;
100
+ width: 100%;
101
+ font-size: 0.9em;
102
+ }
103
+ .msg-assistant th,
104
+ .msg-assistant td {
105
+ border: 1px solid oklch(var(--bc) / 0.15);
106
+ padding: 0.4rem 0.75rem;
107
+ text-align: left;
108
+ }
109
+ .msg-assistant th {
110
+ background: oklch(var(--b3));
111
+ font-weight: 600;
112
+ }
113
+
114
+ .msg-assistant a {
115
+ color: oklch(var(--p));
116
+ text-decoration: underline;
117
+ }
118
+
119
+ .msg-assistant p {
120
+ margin: 0.4rem 0;
121
+ }
122
+
123
+ /* ── Streaming cursor ───────────────────────────────── */
124
+ .streaming-cursor::after {
125
+ content: '▌';
126
+ animation: blink 0.8s infinite;
127
+ color: oklch(var(--p));
128
+ }
129
+ @keyframes blink {
130
+ 0%, 100% { opacity: 1; }
131
+ 50% { opacity: 0; }
132
+ }
133
+
134
+ /* ── Tool call cards (collapsible <details>) ────────── */
135
+ .tool-card {
136
+ background: oklch(var(--b2));
137
+ border-radius: 0.5rem;
138
+ padding: 0.5rem 1rem;
139
+ font-size: 0.85rem;
140
+ border-left: 3px solid transparent;
141
+ }
142
+ .tool-card summary {
143
+ list-style: none;
144
+ }
145
+ .tool-card summary::-webkit-details-marker { display: none; }
146
+ .tool-card summary::before {
147
+ content: '▶';
148
+ font-size: 0.65rem;
149
+ margin-right: 0.4rem;
150
+ transition: transform 0.15s;
151
+ display: inline-block;
152
+ opacity: 0.5;
153
+ }
154
+ .tool-card[open] summary::before {
155
+ transform: rotate(90deg);
156
+ }
157
+ .tool-card .tool-details-body {
158
+ padding-top: 0.25rem;
159
+ }
160
+ .tool-border-safe { border-left-color: oklch(var(--in)); }
161
+ .tool-border-write { border-left-color: oklch(var(--wa)); }
162
+ .tool-border-destructive { border-left-color: oklch(var(--er)); }
163
+
164
+ .tool-card .tool-args {
165
+ white-space: pre-wrap;
166
+ max-height: 100px;
167
+ overflow-y: auto;
168
+ font-size: 0.8rem;
169
+ opacity: 0.65;
170
+ line-height: 1.5;
171
+ }
172
+ .tool-card .tool-result-content {
173
+ white-space: pre-wrap;
174
+ max-height: 200px;
175
+ overflow-y: auto;
176
+ font-size: 0.8rem;
177
+ }
178
+
179
+ /* ── Confirm / ask-user card ────────────────────────── */
180
+ .confirm-card {
181
+ background: oklch(var(--b2));
182
+ border-radius: 0.5rem;
183
+ padding: 0.75rem 1rem;
184
+ border-left: 3px solid transparent;
185
+ }
186
+
187
+ .confirm-diff {
188
+ background: oklch(var(--b3));
189
+ color: oklch(var(--bc));
190
+ padding: 0.5rem;
191
+ border-radius: 0.375rem;
192
+ font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
193
+ font-size: 0.78rem;
194
+ white-space: pre-wrap;
195
+ max-height: 200px;
196
+ overflow-y: auto;
197
+ margin-bottom: 0.5rem;
198
+ }
199
+
200
+ /* ── Error message ──────────────────────────────────── */
201
+ .error-message {
202
+ background: oklch(var(--er) / 0.1);
203
+ border-left: 3px solid oklch(var(--er));
204
+ border-radius: 0.5rem;
205
+ padding: 0.5rem 1rem;
206
+ }
207
+
208
+ /* ── Thinking block ─────────────────────────────────── */
209
+ .thinking-block summary {
210
+ cursor: pointer;
211
+ font-style: italic;
212
+ opacity: 0.6;
213
+ font-size: 0.85rem;
214
+ }
215
+ .thinking-block .thinking-content {
216
+ padding: 0.5rem 0.75rem;
217
+ border-left: 2px solid oklch(var(--bc) / 0.15);
218
+ margin-top: 0.25rem;
219
+ white-space: pre-wrap;
220
+ font-size: 0.85rem;
221
+ opacity: 0.6;
222
+ }
223
+
224
+ /* ── Todo list ──────────────────────────────────────── */
225
+ .todo-item.completed { color: oklch(var(--su)); }
226
+ .todo-item.in_progress { color: oklch(var(--wa)); }
227
+ .todo-item.pending { opacity: 0.5; }
228
+
229
+ /* ── Copy button on code blocks ─────────────────────── */
230
+ .copy-code-btn {
231
+ position: absolute;
232
+ top: 0.4rem;
233
+ right: 0.4rem;
234
+ padding: 0.2rem 0.5rem;
235
+ font-size: 0.7rem;
236
+ opacity: 0;
237
+ transition: opacity 0.2s;
238
+ }
239
+ .msg-assistant pre:hover .copy-code-btn {
240
+ opacity: 1;
241
+ }
242
+
243
+ /* ── Active toggle buttons ──────────────────────────── */
244
+ .btn-active-toggle {
245
+ border: 1px solid oklch(var(--p)) !important;
246
+ background: oklch(var(--p) / 0.15) !important;
247
+ color: oklch(var(--p)) !important;
248
+ }
249
+
250
+ /* ── Batch confirm file list ────────────────────────── */
251
+ .file-item {
252
+ display: flex;
253
+ align-items: center;
254
+ gap: 0.5rem;
255
+ padding: 0.25rem 0;
256
+ font-size: 0.85rem;
257
+ }
258
+
259
+ /* ── Connection status ──────────────────────────────── */
260
+ .status-connected { color: oklch(var(--su)); }
261
+ .status-disconnected { color: oklch(var(--er)); }
262
+
263
+ /* ── Sidebar tabs ──────────────────────────────────── */
264
+ .sidebar-tab {
265
+ cursor: pointer;
266
+ opacity: 0.5;
267
+ transition: all 0.15s;
268
+ border-bottom: 2px solid transparent;
269
+ }
270
+ .sidebar-tab:hover { opacity: 0.8; }
271
+ .sidebar-tab.active {
272
+ opacity: 1;
273
+ border-bottom-color: oklch(var(--p));
274
+ color: oklch(var(--p));
275
+ }
276
+
277
+ /* ── Sidebar resize handle ─────────────────────────── */
278
+ .sidebar-resize-handle {
279
+ width: 4px;
280
+ cursor: col-resize;
281
+ flex-shrink: 0;
282
+ background: transparent;
283
+ transition: background 0.15s;
284
+ position: relative;
285
+ z-index: 5;
286
+ }
287
+ .sidebar-resize-handle::after {
288
+ content: '';
289
+ position: absolute;
290
+ top: 0;
291
+ left: -3px;
292
+ right: -3px;
293
+ bottom: 0;
294
+ }
295
+ .sidebar-resize-handle:hover,
296
+ .sidebar-resize-handle.resizing {
297
+ background: oklch(var(--p) / 0.4);
298
+ }
299
+
300
+ /* ── Sidebar ───────────────────────────────────────── */
301
+ .sidebar {
302
+ width: 18rem;
303
+ transition: width 0.2s ease;
304
+ }
305
+ .sidebar.no-transition {
306
+ transition: none;
307
+ }
308
+ .sidebar .session-item {
309
+ padding: 0.5rem 0.6rem;
310
+ border-radius: 0.375rem;
311
+ cursor: pointer;
312
+ transition: background 0.15s;
313
+ border-left: 2px solid transparent;
314
+ }
315
+ .sidebar .session-item:hover {
316
+ background: oklch(var(--b3));
317
+ }
318
+ .sidebar .session-item.active {
319
+ background: oklch(var(--p) / 0.15);
320
+ border-left-color: oklch(var(--p));
321
+ }
322
+ .sidebar .session-item .session-title {
323
+ white-space: nowrap;
324
+ overflow: hidden;
325
+ text-overflow: ellipsis;
326
+ font-size: 0.85rem;
327
+ cursor: text;
328
+ }
329
+ .sidebar .session-item .session-rename-input {
330
+ height: 1.5rem;
331
+ min-height: 1.5rem;
332
+ padding: 0 0.4rem;
333
+ }
334
+ .sidebar .session-item .session-meta {
335
+ font-size: 0.7rem;
336
+ opacity: 0.5;
337
+ }
338
+ .sidebar .session-item:hover .session-delete-btn {
339
+ opacity: 0.5;
340
+ }
341
+ .sidebar .session-item:hover .session-delete-btn:hover {
342
+ opacity: 1;
343
+ }
344
+
345
+ /* ── Image upload preview ──────────────────────────── */
346
+ #image-preview {
347
+ border-top: 1px dashed oklch(var(--bc) / 0.15);
348
+ padding-top: 0.5rem;
349
+ }
350
+ .image-thumb {
351
+ display: inline-block;
352
+ }
353
+
354
+ /* ── Diff syntax highlighting ─────────────────────── */
355
+ .confirm-diff .diff-add {
356
+ color: oklch(var(--su));
357
+ background: oklch(var(--su) / 0.1);
358
+ }
359
+ .confirm-diff .diff-del {
360
+ color: oklch(var(--er));
361
+ background: oklch(var(--er) / 0.1);
362
+ }
363
+ .confirm-diff .diff-hunk {
364
+ color: oklch(var(--p));
365
+ opacity: 0.8;
366
+ font-weight: 600;
367
+ }
368
+ .confirm-diff .diff-ctx {
369
+ opacity: 0.6;
370
+ }
371
+
372
+ /* ── Tools sidebar list ──────────────────────────── */
373
+ .tools-section-title {
374
+ font-size: 0.7rem;
375
+ font-weight: 700;
376
+ text-transform: uppercase;
377
+ letter-spacing: 0.05em;
378
+ opacity: 0.4;
379
+ padding: 0.5rem 0.25rem 0.25rem;
380
+ }
381
+ .tool-item {
382
+ padding: 0.3rem 0.5rem;
383
+ border-radius: 0.25rem;
384
+ font-size: 0.8rem;
385
+ display: flex;
386
+ align-items: center;
387
+ gap: 0.35rem;
388
+ }
389
+ .tool-item:hover {
390
+ background: oklch(var(--b3));
391
+ }
392
+ .tool-item .tool-dot {
393
+ width: 6px;
394
+ height: 6px;
395
+ border-radius: 50%;
396
+ flex-shrink: 0;
397
+ }
398
+ .tool-dot-safe { background: oklch(var(--in)); }
399
+ .tool-dot-write { background: oklch(var(--wa)); }
400
+ .tool-dot-destructive { background: oklch(var(--er)); }
401
+ .tool-dot-connected { background: oklch(var(--su)); }
402
+ .tool-dot-disconnected { background: oklch(var(--er)); }
403
+ .tool-dot-active { background: oklch(var(--su)); }
404
+ .tool-dot-inactive { background: oklch(var(--bc) / 0.3); }
405
+
406
+ .mcp-server-item {
407
+ padding: 0.3rem 0.5rem;
408
+ border-radius: 0.25rem;
409
+ cursor: pointer;
410
+ font-size: 0.8rem;
411
+ }
412
+ .mcp-server-item:hover {
413
+ background: oklch(var(--b3));
414
+ }
415
+ .mcp-server-tools {
416
+ padding-left: 1.25rem;
417
+ font-size: 0.75rem;
418
+ opacity: 0.6;
419
+ }
420
+
421
+ /* ── File tree ──────────────────────────────────────── */
422
+ .file-tree-item {
423
+ user-select: none;
424
+ }
425
+ .file-tree-row {
426
+ display: flex;
427
+ align-items: center;
428
+ gap: 0.3rem;
429
+ padding: 0.2rem 0.5rem;
430
+ border-radius: 0.25rem;
431
+ cursor: pointer;
432
+ font-size: 0.8rem;
433
+ transition: background 0.1s;
434
+ min-width: 0;
435
+ }
436
+ .file-tree-row:hover {
437
+ background: oklch(var(--b3));
438
+ }
439
+ .file-tree-row.file-tree-dir {
440
+ font-weight: 500;
441
+ }
442
+ .file-tree-chevron {
443
+ font-size: 0.55rem;
444
+ opacity: 0.4;
445
+ flex-shrink: 0;
446
+ transition: transform 0.15s;
447
+ display: inline-block;
448
+ width: 0.75rem;
449
+ text-align: center;
450
+ }
451
+ .file-tree-chevron.expanded {
452
+ transform: rotate(90deg);
453
+ }
454
+ .file-tree-icon {
455
+ font-size: 0.8rem;
456
+ flex-shrink: 0;
457
+ line-height: 1;
458
+ }
459
+ .file-tree-name {
460
+ flex: 1;
461
+ overflow: hidden;
462
+ text-overflow: ellipsis;
463
+ white-space: nowrap;
464
+ min-width: 0;
465
+ }
466
+ .file-tree-insert-btn {
467
+ flex-shrink: 0;
468
+ font-size: 0.65rem;
469
+ font-weight: 700;
470
+ color: oklch(var(--p));
471
+ opacity: 0;
472
+ background: oklch(var(--p) / 0.12);
473
+ border: none;
474
+ border-radius: 0.2rem;
475
+ padding: 0 0.3rem;
476
+ cursor: pointer;
477
+ line-height: 1.4;
478
+ transition: opacity 0.15s, background 0.15s;
479
+ }
480
+ .file-tree-row:hover .file-tree-insert-btn {
481
+ opacity: 1;
482
+ }
483
+ .file-tree-insert-btn:hover {
484
+ background: oklch(var(--p) / 0.25) !important;
485
+ }
486
+ .file-tree-children {
487
+ padding-left: 1rem;
488
+ border-left: 1px solid oklch(var(--bc) / 0.08);
489
+ margin-left: 0.85rem;
490
+ }
491
+
492
+ /* file preview card in chat */
493
+ .file-preview-card {
494
+ background: oklch(var(--b2));
495
+ border-radius: var(--rounded-box, 1rem);
496
+ padding: 0.75rem 1rem;
497
+ border-left: 3px solid oklch(var(--in));
498
+ }
499
+ .file-preview-card pre {
500
+ background: oklch(var(--b3));
501
+ border-radius: 0.375rem;
502
+ overflow-x: auto;
503
+ margin: 0.5rem 0 0;
504
+ }
505
+ .file-preview-card pre code {
506
+ display: block;
507
+ padding: 0.75rem;
508
+ font-size: 0.78rem;
509
+ line-height: 1.5;
510
+ font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
511
+ }
512
+
513
+ /* ── Session Tab Bar (P2-1: multi-tab in page) ──────── */
514
+ .session-tab-bar {
515
+ display: flex;
516
+ align-items: stretch;
517
+ min-height: 2.25rem;
518
+ padding: 0;
519
+ gap: 0;
520
+ overflow: hidden;
521
+ }
522
+ .session-tabs-scroll {
523
+ display: flex;
524
+ align-items: stretch;
525
+ overflow-x: auto;
526
+ overflow-y: hidden;
527
+ flex: 1;
528
+ min-width: 0;
529
+ scrollbar-width: thin;
530
+ scrollbar-color: oklch(var(--bc) / 0.15) transparent;
531
+ }
532
+ .session-tabs-scroll::-webkit-scrollbar { height: 3px; }
533
+ .session-tabs-scroll::-webkit-scrollbar-thumb { background: oklch(var(--bc) / 0.15); border-radius: 2px; }
534
+
535
+ .session-tab-item {
536
+ display: flex;
537
+ align-items: center;
538
+ gap: 0.35rem;
539
+ padding: 0 0.75rem;
540
+ font-size: 0.78rem;
541
+ white-space: nowrap;
542
+ cursor: pointer;
543
+ border-right: 1px solid oklch(var(--bc) / 0.08);
544
+ transition: background 0.12s;
545
+ min-width: 0;
546
+ max-width: 12rem;
547
+ flex-shrink: 0;
548
+ position: relative;
549
+ user-select: none;
550
+ }
551
+ .session-tab-item:hover {
552
+ background: oklch(var(--b3));
553
+ }
554
+ .session-tab-item.active {
555
+ background: oklch(var(--b1));
556
+ border-bottom: 2px solid oklch(var(--p));
557
+ color: oklch(var(--p));
558
+ font-weight: 600;
559
+ }
560
+ .session-tab-item:not(.active) {
561
+ border-bottom: 2px solid transparent;
562
+ }
563
+ .session-tab-item .tab-title {
564
+ overflow: hidden;
565
+ text-overflow: ellipsis;
566
+ white-space: nowrap;
567
+ min-width: 0;
568
+ flex: 1;
569
+ }
570
+ .session-tab-item .tab-processing {
571
+ width: 6px;
572
+ height: 6px;
573
+ border-radius: 50%;
574
+ background: oklch(var(--wa));
575
+ flex-shrink: 0;
576
+ animation: tab-pulse 1.2s infinite;
577
+ }
578
+ @keyframes tab-pulse {
579
+ 0%, 100% { opacity: 0.4; }
580
+ 50% { opacity: 1; }
581
+ }
582
+ .session-tab-item .tab-close {
583
+ opacity: 0;
584
+ font-size: 0.85rem;
585
+ line-height: 1;
586
+ padding: 0 0.15rem;
587
+ border-radius: 0.2rem;
588
+ cursor: pointer;
589
+ flex-shrink: 0;
590
+ transition: opacity 0.12s, background 0.12s;
591
+ }
592
+ .session-tab-item:hover .tab-close,
593
+ .session-tab-item.active .tab-close {
594
+ opacity: 0.5;
595
+ }
596
+ .session-tab-item .tab-close:hover {
597
+ opacity: 1;
598
+ background: oklch(var(--er) / 0.2);
599
+ color: oklch(var(--er));
600
+ }
601
+ .session-tab-add {
602
+ display: flex;
603
+ align-items: center;
604
+ justify-content: center;
605
+ width: 2rem;
606
+ flex-shrink: 0;
607
+ font-size: 1.1rem;
608
+ font-weight: 300;
609
+ cursor: pointer;
610
+ opacity: 0.4;
611
+ transition: opacity 0.12s, background 0.12s;
612
+ border: none;
613
+ background: transparent;
614
+ color: inherit;
615
+ }
616
+ .session-tab-add:hover {
617
+ opacity: 1;
618
+ background: oklch(var(--b3));
619
+ }
620
+
621
+ /* ── Round progress bar (sticky top of chat area) ──── */
622
+ .round-progress-bar {
623
+ position: sticky;
624
+ top: 0;
625
+ z-index: 10;
626
+ padding: 0.4rem 1rem;
627
+ background: oklch(var(--b2) / 0.92);
628
+ backdrop-filter: blur(8px);
629
+ border-bottom: 1px solid oklch(var(--bc) / 0.1);
630
+ max-width: 64rem;
631
+ margin: -1rem auto 0.5rem;
632
+ }
633
+ .round-progress-inner {
634
+ display: flex;
635
+ align-items: center;
636
+ gap: 0.75rem;
637
+ }
638
+ .round-progress-label {
639
+ font-size: 0.75rem;
640
+ font-weight: 600;
641
+ opacity: 0.7;
642
+ white-space: nowrap;
643
+ }
644
+
645
+ /* ── Tool duration & timer ─────────────────────────── */
646
+ .tool-timer {
647
+ font-size: 0.7rem;
648
+ font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
649
+ opacity: 0.5;
650
+ white-space: nowrap;
651
+ }
652
+ .tool-timer.timing {
653
+ color: oklch(var(--wa));
654
+ opacity: 0.7;
655
+ }
656
+ .tool-duration {
657
+ font-size: 0.7rem;
658
+ font-family: 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
659
+ opacity: 0.6;
660
+ white-space: nowrap;
661
+ }
662
+ .tool-duration.fast { color: oklch(var(--su)); }
663
+ .tool-duration.medium { color: oklch(var(--wa)); }
664
+ .tool-duration.slow { color: oklch(var(--er)); }
665
+
666
+ /* ── Prompt templates ──────────────────────────────── */
667
+ .template-item {
668
+ display: flex;
669
+ align-items: flex-start;
670
+ gap: 0.5rem;
671
+ padding: 0.5rem 0.75rem;
672
+ border-radius: 0.375rem;
673
+ cursor: pointer;
674
+ transition: background 0.15s;
675
+ border: 1px solid oklch(var(--bc) / 0.08);
676
+ }
677
+ .template-item:hover {
678
+ background: oklch(var(--b3));
679
+ border-color: oklch(var(--p) / 0.3);
680
+ }
681
+ .template-item-body {
682
+ flex: 1;
683
+ min-width: 0;
684
+ }
685
+ .template-item-name {
686
+ font-weight: 600;
687
+ font-size: 0.9rem;
688
+ }
689
+ .template-item-preview {
690
+ font-size: 0.78rem;
691
+ opacity: 0.55;
692
+ white-space: nowrap;
693
+ overflow: hidden;
694
+ text-overflow: ellipsis;
695
+ max-width: 100%;
696
+ }
697
+ .template-item-tags {
698
+ display: flex;
699
+ gap: 0.25rem;
700
+ flex-wrap: wrap;
701
+ margin-top: 0.2rem;
702
+ }
703
+ .template-item-tag {
704
+ font-size: 0.65rem;
705
+ padding: 0.05rem 0.35rem;
706
+ border-radius: 0.25rem;
707
+ background: oklch(var(--p) / 0.12);
708
+ color: oklch(var(--p));
709
+ }
710
+ .template-item-actions {
711
+ display: flex;
712
+ gap: 0.25rem;
713
+ flex-shrink: 0;
714
+ opacity: 0;
715
+ transition: opacity 0.15s;
716
+ }
717
+ .template-item:hover .template-item-actions {
718
+ opacity: 1;
719
+ }
720
+ .template-empty {
721
+ text-align: center;
722
+ padding: 2rem;
723
+ opacity: 0.4;
724
+ font-size: 0.85rem;
725
+ }
726
+
727
+ /* ── Sidebar toggle button ──────────────────────────── */
728
+ /* Visible on every width: on desktop it collapses the panel to give all
729
+ space to the chat; on mobile (≤768px) it opens/closes the slide-over. */
730
+ .sidebar-toggle-btn { display: flex; }
731
+
732
+ /* Desktop collapse: scoped to ≥769px so it never fights the mobile
733
+ slide-over rules (which use .sidebar-open). width:0 !important is needed
734
+ to override the inline width set by the drag-resize handle. */
735
+ @media (min-width: 769px) {
736
+ .sidebar.sidebar-collapsed {
737
+ width: 0 !important;
738
+ min-width: 0;
739
+ border-right-width: 0;
740
+ overflow: hidden;
741
+ }
742
+ .sidebar.sidebar-collapsed + .sidebar-resize-handle { display: none; }
743
+ }
744
+
745
+ /* ── Sidebar backdrop (mobile overlay) ───────────────── */
746
+ .sidebar-backdrop {
747
+ position: fixed;
748
+ inset: 0;
749
+ top: 3.5rem;
750
+ background: rgba(0, 0, 0, 0.5);
751
+ z-index: 19;
752
+ -webkit-backdrop-filter: blur(2px);
753
+ backdrop-filter: blur(2px);
754
+ }
755
+
756
+ /* ── Touch optimization ──────────────────────────────── */
757
+ button, a, .session-item, .file-tree-row, .template-item, .tool-item, .mcp-server-item {
758
+ -webkit-tap-highlight-color: transparent;
759
+ touch-action: manipulation;
760
+ }
761
+
762
+ /* ── Input footer safe area (iPhone notch) ───────────── */
763
+ .input-footer {
764
+ padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
765
+ }
766
+
767
+ /* ── Responsive: Tablet ────────────────────────────── */
768
+ @media (max-width: 768px) {
769
+ .sidebar-toggle-btn { display: flex; }
770
+ .sidebar-resize-handle { display: none; }
771
+ .sidebar {
772
+ width: 0;
773
+ padding: 0;
774
+ border: none;
775
+ position: fixed;
776
+ z-index: 20;
777
+ top: 3.5rem;
778
+ left: 0;
779
+ height: calc(100vh - 3.5rem);
780
+ height: calc(100dvh - 3.5rem);
781
+ transition: width 0.2s ease, padding 0.2s ease;
782
+ }
783
+ .sidebar.sidebar-open {
784
+ width: 18rem;
785
+ border-right: 1px solid oklch(var(--bc) / 0.1);
786
+ overflow: hidden;
787
+ }
788
+ /* Provider/model selects: narrower on tablet */
789
+ .navbar-select { width: 7rem; font-size: 0.8rem; }
790
+ /* Navbar end buttons: hide text labels */
791
+ #btn-think, #btn-plan { font-size: 0.8rem; padding: 0 0.4rem; }
792
+ }
793
+
794
+ /* ── Responsive: Phone ──────────────────────────────── */
795
+ @media (max-width: 640px) {
796
+ /* Navbar: compact layout */
797
+ .navbar { padding: 0 0.5rem; min-height: 3rem; }
798
+ .navbar-start { gap: 0.25rem; }
799
+ .navbar-end { gap: 0; }
800
+ .brand-text { display: none; }
801
+ .navbar-select { width: 5.5rem; font-size: 0.72rem; height: 2rem; min-height: 2rem; }
802
+ /* Navbar end: icon-only for action buttons */
803
+ #btn-think, #btn-plan { font-size: 0.75rem; padding: 0 0.3rem; min-height: 2rem; height: 2rem; }
804
+ .divider-horizontal { display: none; }
805
+ #btn-clear, #btn-compact { min-height: 2rem; height: 2rem; padding: 0 0.3rem; }
806
+
807
+ /* Sidebar: full width on small phones */
808
+ .sidebar.sidebar-open { width: min(85vw, 20rem); }
809
+
810
+ /* Tab bar: smaller on phone */
811
+ .session-tab-item { padding: 0 0.5rem; font-size: 0.72rem; max-width: 9rem; }
812
+ .session-tab-bar { min-height: 2rem; }
813
+ .session-tab-item .tab-close { opacity: 0.4; } /* always visible on mobile (no hover) */
814
+
815
+ /* Chat area */
816
+ #chat-area { padding: 0.75rem 0.5rem; }
817
+ .msg-assistant { padding: 0.75rem; font-size: 0.92rem; }
818
+ .msg-assistant pre code { font-size: 0.78rem; padding: 0.75rem; }
819
+ .msg-assistant table { font-size: 0.8rem; }
820
+ .msg-assistant th, .msg-assistant td { padding: 0.3rem 0.5rem; }
821
+
822
+ /* Input area */
823
+ .input-footer { padding: 0.5rem; padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px)); }
824
+ .input-footer .max-w-4xl { gap: 0.35rem; }
825
+ #user-input { font-size: 16px; /* Prevents iOS zoom on focus */ min-height: 2.5rem; }
826
+ #btn-send, #btn-stop { width: 2.5rem; height: 2.5rem; min-height: 2.5rem; }
827
+ #btn-templates { width: 2rem; height: 2rem; min-height: 2rem; }
828
+ #btn-templates .text-lg { font-size: 1rem; }
829
+
830
+ /* Status bar: hide or compact */
831
+ .input-footer .text-xs { font-size: 0.65rem; gap: 0.25rem; }
832
+
833
+ /* Tool cards */
834
+ .tool-card { padding: 0.4rem 0.65rem; font-size: 0.8rem; }
835
+ .confirm-diff { font-size: 0.72rem; max-height: 150px; }
836
+
837
+ /* Copy button always visible on mobile (no hover) */
838
+ .copy-code-btn { opacity: 0.6; }
839
+
840
+ /* Modals: near full-width on phone */
841
+ .modal-box { max-width: 95vw; margin: 0.5rem; }
842
+ #templates-modal .modal-box { max-height: 85vh; }
843
+ }
844
+
845
+ /* ── Responsive: Very small phones (320px) ───────────── */
846
+ @media (max-width: 380px) {
847
+ .navbar-select { width: 4.5rem; font-size: 0.68rem; }
848
+ .sidebar.sidebar-open { width: 90vw; }
849
+ .msg-assistant { padding: 0.5rem 0.6rem; font-size: 0.88rem; }
850
+ }
851
+
852
+ /* ── Landscape phone: reduce vertical space ──────────── */
853
+ @media (max-height: 500px) and (max-width: 900px) {
854
+ .navbar { min-height: 2.5rem; }
855
+ .input-footer { padding-top: 0.35rem; padding-bottom: calc(0.35rem + env(safe-area-inset-bottom, 0px)); }
856
+ #chat-area { padding-top: 0.5rem; padding-bottom: 0.5rem; }
857
+ }
858
+
859
+ /* ── PWA standalone mode: extra top padding for status bar ── */
860
+ @media (display-mode: standalone) {
861
+ .navbar { padding-top: env(safe-area-inset-top, 0px); }
862
+ }
863
+
864
+ /* ── Session Replay (B1) ───────────────────────────── */
865
+ .replay-step {
866
+ border-left: 3px solid hsl(var(--b3));
867
+ padding: 0.5rem 0.6rem;
868
+ background: hsl(var(--b1));
869
+ border-radius: 0 0.35rem 0.35rem 0;
870
+ font-size: 0.85rem;
871
+ }
872
+ .replay-step.role-user { border-left-color: #3b82f6; }
873
+ .replay-step.role-assistant { border-left-color: #10b981; }
874
+ .replay-step.role-tool { border-left-color: #f59e0b; }
875
+ .replay-step.role-tool.error { border-left-color: #ef4444; }
876
+ .replay-step-header {
877
+ display: flex;
878
+ gap: 0.5rem;
879
+ align-items: center;
880
+ font-size: 0.72rem;
881
+ opacity: 0.75;
882
+ margin-bottom: 0.25rem;
883
+ }
884
+ .replay-step-header .role-tag {
885
+ font-weight: 600;
886
+ padding: 0 0.35rem;
887
+ border-radius: 0.25rem;
888
+ background: hsl(var(--b3));
889
+ }
890
+ .replay-step-body {
891
+ white-space: pre-wrap;
892
+ word-break: break-word;
893
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
894
+ font-size: 0.78rem;
895
+ max-height: 18rem;
896
+ overflow-y: auto;
897
+ }
898
+ .replay-step-body.text-body {
899
+ font-family: inherit;
900
+ font-size: 0.85rem;
901
+ }
902
+ .replay-tool-block {
903
+ margin-top: 0.3rem;
904
+ padding: 0.4rem;
905
+ background: hsl(var(--b2));
906
+ border-radius: 0.3rem;
907
+ font-size: 0.78rem;
908
+ }
909
+ .replay-tool-block .tool-name {
910
+ font-weight: 600;
911
+ color: #f59e0b;
912
+ }
913
+ .replay-tool-block pre {
914
+ margin: 0.2rem 0 0;
915
+ white-space: pre-wrap;
916
+ word-break: break-word;
917
+ font-size: 0.72rem;
918
+ max-height: 12rem;
919
+ overflow-y: auto;
920
+ }
921
+
922
+ /* ── B2 Branch picker (sidebar) ─────────────────────────── */
923
+ .branch-item {
924
+ display: flex;
925
+ align-items: center;
926
+ gap: 0.35rem;
927
+ padding: 0.35rem 0.5rem;
928
+ border-radius: 0.35rem;
929
+ cursor: pointer;
930
+ border: 1px solid transparent;
931
+ transition: background 0.1s, border-color 0.1s;
932
+ font-size: 0.78rem;
933
+ line-height: 1.25;
934
+ position: relative;
935
+ }
936
+ .branch-item:hover {
937
+ background: rgba(128, 128, 128, 0.12);
938
+ }
939
+ .branch-item.active {
940
+ background: rgba(34, 197, 94, 0.12);
941
+ border-color: rgba(34, 197, 94, 0.45);
942
+ }
943
+ .branch-item .branch-marker {
944
+ flex-shrink: 0;
945
+ width: 0.8rem;
946
+ color: rgb(34, 197, 94);
947
+ }
948
+ .branch-item .branch-title {
949
+ flex: 1;
950
+ min-width: 0;
951
+ overflow: hidden;
952
+ text-overflow: ellipsis;
953
+ white-space: nowrap;
954
+ }
955
+ .branch-item .branch-id {
956
+ flex-shrink: 0;
957
+ opacity: 0.5;
958
+ font-family: ui-monospace, SFMono-Regular, monospace;
959
+ font-size: 0.7rem;
960
+ }
961
+ .branch-item .branch-count {
962
+ flex-shrink: 0;
963
+ opacity: 0.55;
964
+ font-size: 0.7rem;
965
+ }
966
+ .branch-item .branch-actions {
967
+ display: none;
968
+ gap: 0.15rem;
969
+ flex-shrink: 0;
970
+ }
971
+ .branch-item:hover .branch-actions {
972
+ display: flex;
973
+ }
974
+ .branch-item .branch-actions button {
975
+ background: transparent;
976
+ border: none;
977
+ padding: 0 0.2rem;
978
+ font-size: 0.72rem;
979
+ cursor: pointer;
980
+ opacity: 0.7;
981
+ }
982
+ .branch-item .branch-actions button:hover {
983
+ opacity: 1;
984
+ }
985
+ .branch-item .branch-indent {
986
+ flex-shrink: 0;
987
+ color: rgba(128, 128, 128, 0.5);
988
+ font-family: ui-monospace, SFMono-Regular, monospace;
989
+ font-size: 0.72rem;
990
+ white-space: pre;
991
+ }