@vincentbanana/bananacli 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,885 @@
1
+ :root {
2
+ --bg: #ffffff;
3
+ --panel: #fbfbfa;
4
+ --panel-2: #f4f4f2;
5
+ --line: #e6e6e2;
6
+ --line-strong: #d6d6d1;
7
+ --text: #16161a;
8
+ --text-2: #5f5f66;
9
+ --text-3: #8c8c93;
10
+ --inverse: #16161a;
11
+ --shadow-sm: 0 1px 2px rgba(16, 16, 20, 0.05);
12
+ --shadow-lg: 0 18px 44px rgba(16, 16, 20, 0.16);
13
+ --radius: 12px;
14
+ --ease: cubic-bezier(0.22, 1, 0.36, 1);
15
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
16
+ --dur: 220ms;
17
+ --sidebar: 274px;
18
+ --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
19
+ --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
20
+ }
21
+
22
+ /* 深色主题:默认跟随系统,也可以手动锁 light / dark */
23
+ @media (prefers-color-scheme: dark) {
24
+ :root:not([data-theme='light']) {
25
+ --bg: #0e0e10;
26
+ --panel: #131316;
27
+ --panel-2: #1a1a1e;
28
+ --line: #26262b;
29
+ --line-strong: #33333a;
30
+ --text: #f2f2f0;
31
+ --text-2: #a1a1a8;
32
+ --text-3: #74747c;
33
+ --inverse: #f2f2f0;
34
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
35
+ --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.55);
36
+ }
37
+ }
38
+
39
+ :root[data-theme='dark'] {
40
+ --bg: #0e0e10;
41
+ --panel: #131316;
42
+ --panel-2: #1a1a1e;
43
+ --line: #26262b;
44
+ --line-strong: #33333a;
45
+ --text: #f2f2f0;
46
+ --text-2: #a1a1a8;
47
+ --text-3: #74747c;
48
+ --inverse: #f2f2f0;
49
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
50
+ --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.55);
51
+ }
52
+
53
+ * { box-sizing: border-box; }
54
+
55
+ html, body {
56
+ margin: 0;
57
+ height: 100%;
58
+ background: var(--bg);
59
+ color: var(--text);
60
+ font-family: var(--sans);
61
+ font-size: 15px;
62
+ line-height: 1.62;
63
+ -webkit-font-smoothing: antialiased;
64
+ }
65
+
66
+ button, input, textarea, select { font: inherit; color: inherit; }
67
+
68
+ .app {
69
+ display: grid;
70
+ grid-template-columns: var(--sidebar) minmax(0, 1fr);
71
+ height: 100%;
72
+ overflow: hidden;
73
+ }
74
+
75
+ /* ---------- sidebar ---------- */
76
+
77
+ .sidebar {
78
+ display: flex;
79
+ flex-direction: column;
80
+ min-height: 0;
81
+ background: var(--panel);
82
+ border-right: 1px solid var(--line);
83
+ }
84
+
85
+ .sidebar-head {
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: space-between;
89
+ gap: 8px;
90
+ height: 54px;
91
+ padding: 0 12px 0 16px;
92
+ }
93
+
94
+ .brand { display: flex; align-items: center; gap: 9px; }
95
+ .brand-mark {
96
+ width: 20px;
97
+ height: 20px;
98
+ fill: none;
99
+ stroke: var(--text);
100
+ stroke-width: 1.5;
101
+ stroke-linecap: round;
102
+ stroke-linejoin: round;
103
+ }
104
+ .brand-name { font-size: 14px; font-weight: 600; letter-spacing: 0.01em; }
105
+
106
+ .icon-btn {
107
+ display: inline-grid;
108
+ place-items: center;
109
+ width: 30px;
110
+ height: 30px;
111
+ padding: 0;
112
+ border: 1px solid transparent;
113
+ border-radius: 8px;
114
+ background: transparent;
115
+ color: var(--text-2);
116
+ cursor: pointer;
117
+ transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease), transform 140ms var(--ease);
118
+ }
119
+ .icon-btn:hover { background: var(--panel-2); color: var(--text); }
120
+ .icon-btn:active { transform: scale(0.94); }
121
+ .icon-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
122
+
123
+ .session-list {
124
+ flex: 1;
125
+ min-height: 0;
126
+ overflow-y: auto;
127
+ padding: 4px 8px 12px;
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: 1px;
131
+ }
132
+
133
+ .session-item {
134
+ display: block;
135
+ width: 100%;
136
+ text-align: left;
137
+ padding: 8px 10px;
138
+ border: 0;
139
+ border-radius: 8px;
140
+ background: transparent;
141
+ color: var(--text-2);
142
+ cursor: pointer;
143
+ transition: background 130ms var(--ease), color 130ms var(--ease);
144
+ }
145
+ .session-item:hover { background: var(--panel-2); color: var(--text); }
146
+ .session-item.is-active { background: var(--panel-2); color: var(--text); font-weight: 550; }
147
+ .session-item .s-title {
148
+ display: block;
149
+ font-size: 13.5px;
150
+ white-space: nowrap;
151
+ overflow: hidden;
152
+ text-overflow: ellipsis;
153
+ }
154
+ .session-item .s-meta {
155
+ display: block;
156
+ font-size: 11.5px;
157
+ color: var(--text-3);
158
+ margin-top: 1px;
159
+ font-variant-numeric: tabular-nums;
160
+ }
161
+ .session-item .s-del {
162
+ float: right;
163
+ opacity: 0;
164
+ color: var(--text-3);
165
+ transition: opacity 130ms var(--ease);
166
+ }
167
+ .session-item:hover .s-del { opacity: 1; }
168
+
169
+ .sidebar-foot {
170
+ display: flex;
171
+ gap: 6px;
172
+ padding: 10px;
173
+ border-top: 1px solid var(--line);
174
+ }
175
+
176
+ .ghost-btn {
177
+ flex: 1;
178
+ display: inline-flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ gap: 7px;
182
+ padding: 7px 8px;
183
+ border: 1px solid var(--line);
184
+ border-radius: 8px;
185
+ background: transparent;
186
+ color: var(--text-2);
187
+ font-size: 13px;
188
+ cursor: pointer;
189
+ transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease);
190
+ }
191
+ .ghost-btn:hover { background: var(--panel-2); color: var(--text); border-color: var(--line-strong); }
192
+ .ghost-btn.danger:hover { color: var(--text); }
193
+ .ghost-ico { display: inline-grid; place-items: center; }
194
+ .ghost-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
195
+
196
+ /* ---------- main ---------- */
197
+
198
+ .main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
199
+
200
+ .topbar {
201
+ display: flex;
202
+ align-items: center;
203
+ gap: 10px;
204
+ height: 54px;
205
+ padding: 0 16px;
206
+ border-bottom: 1px solid var(--line);
207
+ background: color-mix(in srgb, var(--bg) 82%, transparent);
208
+ backdrop-filter: saturate(140%) blur(8px);
209
+ }
210
+
211
+ .topbar-title {
212
+ font-size: 14px;
213
+ font-weight: 600;
214
+ letter-spacing: 0.01em;
215
+ white-space: nowrap;
216
+ overflow: hidden;
217
+ text-overflow: ellipsis;
218
+ }
219
+
220
+ .topbar-meta {
221
+ font-size: 12px;
222
+ color: var(--text-3);
223
+ font-variant-numeric: tabular-nums;
224
+ white-space: nowrap;
225
+ overflow: hidden;
226
+ text-overflow: ellipsis;
227
+ }
228
+
229
+ .topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; }
230
+
231
+ .chip-btn {
232
+ display: inline-flex;
233
+ align-items: center;
234
+ gap: 6px;
235
+ height: 28px;
236
+ padding: 0 10px;
237
+ border: 1px solid var(--line);
238
+ border-radius: 999px;
239
+ background: transparent;
240
+ color: var(--text-2);
241
+ font-size: 12.5px;
242
+ cursor: pointer;
243
+ transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease);
244
+ }
245
+ .chip-btn:hover { background: var(--panel-2); color: var(--text); border-color: var(--line-strong); }
246
+ .chip-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
247
+
248
+ .thread {
249
+ flex: 1;
250
+ min-height: 0;
251
+ overflow-y: auto;
252
+ scroll-behavior: smooth;
253
+ padding: 26px 0 12px;
254
+ }
255
+
256
+ .msg {
257
+ max-width: 780px;
258
+ margin: 0 auto;
259
+ padding: 0 24px;
260
+ animation: rise 320ms var(--ease) both;
261
+ }
262
+
263
+ @keyframes rise {
264
+ from { opacity: 0; transform: translateY(8px); }
265
+ to { opacity: 1; transform: none; }
266
+ }
267
+
268
+ .msg + .msg { margin-top: 22px; }
269
+
270
+ .msg-role {
271
+ display: flex;
272
+ align-items: center;
273
+ gap: 7px;
274
+ font-size: 11.5px;
275
+ font-weight: 600;
276
+ letter-spacing: 0.06em;
277
+ text-transform: uppercase;
278
+ color: var(--text-3);
279
+ margin-bottom: 7px;
280
+ }
281
+ .msg-role::before {
282
+ content: "";
283
+ width: 14px;
284
+ height: 1px;
285
+ background: var(--line-strong);
286
+ }
287
+
288
+ .msg.user .msg-body {
289
+ background: var(--panel-2);
290
+ border: 1px solid var(--line);
291
+ border-radius: var(--radius);
292
+ padding: 12px 14px;
293
+ }
294
+
295
+ .msg-body { font-size: 15px; overflow-wrap: anywhere; }
296
+ .msg-body p { margin: 0 0 10px; }
297
+ .msg-body p:last-child { margin-bottom: 0; }
298
+ .msg-body ul, .msg-body ol { margin: 0 0 10px; padding-left: 20px; }
299
+ .msg-body li { margin: 2px 0; }
300
+ .msg-body h1, .msg-body h2, .msg-body h3 { font-size: 15px; margin: 16px 0 6px; }
301
+ .msg-body a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
302
+
303
+ .msg-body code {
304
+ font-family: var(--mono);
305
+ font-size: 12.8px;
306
+ padding: 1px 5px;
307
+ border: 1px solid var(--line);
308
+ border-radius: 5px;
309
+ background: var(--panel-2);
310
+ }
311
+
312
+ pre.code {
313
+ position: relative;
314
+ margin: 10px 0;
315
+ padding: 12px 14px;
316
+ border: 1px solid var(--line);
317
+ border-radius: 10px;
318
+ background: var(--panel);
319
+ overflow-x: auto;
320
+ }
321
+ pre.code code { border: 0; background: none; padding: 0; font-size: 12.6px; line-height: 1.6; }
322
+
323
+ .tool-group {
324
+ margin: 10px 0 4px;
325
+ border-left: 1px solid var(--line-strong);
326
+ padding-left: 12px;
327
+ }
328
+
329
+ .tool-row {
330
+ display: flex;
331
+ align-items: center;
332
+ gap: 8px;
333
+ padding: 3px 0;
334
+ font-size: 13px;
335
+ color: var(--text-2);
336
+ animation: fade 160ms var(--ease) both;
337
+ }
338
+ @keyframes fade { from { opacity: 0; } to { opacity: 1; } }
339
+ .tool-row .t-ico { display: inline-grid; place-items: center; color: var(--text-3); }
340
+ .tool-row .t-ico svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
341
+ .tool-row .t-name { color: var(--text); font-weight: 550; }
342
+ .tool-row .t-detail { color: var(--text-3); font-family: var(--mono); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
343
+ .tool-row .t-state { margin-left: auto; font-size: 11.5px; color: var(--text-3); }
344
+ .tool-row.is-error .t-state { color: var(--text); }
345
+ .tool-row .spin {
346
+ width: 11px; height: 11px;
347
+ border: 1px solid var(--line-strong);
348
+ border-top-color: var(--text-2);
349
+ border-radius: 50%;
350
+ animation: spin 720ms linear infinite;
351
+ }
352
+ @keyframes spin { to { transform: rotate(360deg); } }
353
+
354
+ .reasoning {
355
+ margin: 8px 0;
356
+ padding-left: 12px;
357
+ border-left: 1px solid var(--line);
358
+ color: var(--text-3);
359
+ font-size: 13.5px;
360
+ white-space: pre-wrap;
361
+ }
362
+
363
+ .caret::after {
364
+ content: "";
365
+ display: inline-block;
366
+ width: 7px;
367
+ height: 15px;
368
+ margin-left: 2px;
369
+ vertical-align: -2px;
370
+ background: var(--text);
371
+ animation: blink 1s steps(2, start) infinite;
372
+ }
373
+ @keyframes blink { to { opacity: 0; } }
374
+
375
+ .turn-meta {
376
+ margin-top: 10px;
377
+ font-size: 11.5px;
378
+ color: var(--text-3);
379
+ font-variant-numeric: tabular-nums;
380
+ display: flex;
381
+ gap: 10px;
382
+ flex-wrap: wrap;
383
+ }
384
+
385
+ .empty {
386
+ max-width: 520px;
387
+ margin: 12vh auto 0;
388
+ text-align: center;
389
+ color: var(--text-3);
390
+ animation: rise 320ms var(--ease) both;
391
+ }
392
+ .empty h1 { font-size: 17px; font-weight: 600; color: var(--text); margin: 0 0 6px; }
393
+ .empty p { margin: 0; font-size: 13.5px; }
394
+ .empty .suggest { margin-top: 18px; display: flex; flex-direction: column; gap: 6px; }
395
+ .empty .suggest button {
396
+ text-align: left;
397
+ padding: 9px 12px;
398
+ border: 1px solid var(--line);
399
+ border-radius: 9px;
400
+ background: transparent;
401
+ color: var(--text-2);
402
+ font-size: 13.5px;
403
+ cursor: pointer;
404
+ transition: background 140ms var(--ease), color 140ms var(--ease), transform 140ms var(--ease);
405
+ }
406
+ .empty .suggest button:hover { background: var(--panel-2); color: var(--text); transform: translateX(2px); }
407
+
408
+ /* ---------- composer ---------- */
409
+
410
+ .composer-wrap {
411
+ padding: 10px 24px 16px;
412
+ border-top: 1px solid var(--line);
413
+ background: var(--bg);
414
+ }
415
+
416
+ .composer {
417
+ max-width: 780px;
418
+ margin: 0 auto;
419
+ display: flex;
420
+ align-items: flex-end;
421
+ gap: 8px;
422
+ padding: 8px 8px 8px 14px;
423
+ border: 1px solid var(--line-strong);
424
+ border-radius: 14px;
425
+ background: var(--bg);
426
+ box-shadow: var(--shadow-sm);
427
+ transition: border-color 160ms var(--ease), box-shadow 160ms var(--ease);
428
+ }
429
+ .composer:focus-within { border-color: var(--text-3); box-shadow: 0 2px 14px rgba(16, 16, 20, 0.07); }
430
+
431
+ .composer textarea {
432
+ flex: 1;
433
+ min-height: 26px;
434
+ max-height: 220px;
435
+ padding: 4px 0;
436
+ border: 0;
437
+ outline: none;
438
+ resize: none;
439
+ background: transparent;
440
+ line-height: 1.55;
441
+ }
442
+ .composer textarea::placeholder { color: var(--text-3); }
443
+
444
+ .send-btn {
445
+ display: inline-grid;
446
+ place-items: center;
447
+ width: 32px;
448
+ height: 32px;
449
+ border: 0;
450
+ border-radius: 9px;
451
+ background: var(--inverse);
452
+ color: var(--bg);
453
+ cursor: pointer;
454
+ transition: opacity 140ms var(--ease), transform 140ms var(--ease);
455
+ }
456
+ .send-btn:disabled { opacity: 0.25; cursor: default; }
457
+ .send-btn:not(:disabled):hover { opacity: 0.86; }
458
+ .send-btn:not(:disabled):active { transform: scale(0.93); }
459
+ .send-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
460
+
461
+ .composer-hint {
462
+ max-width: 780px;
463
+ margin: 8px auto 0;
464
+ font-size: 11.5px;
465
+ color: var(--text-3);
466
+ text-align: center;
467
+ }
468
+
469
+ .attachments {
470
+ max-width: 780px;
471
+ margin: 0 auto 8px;
472
+ display: flex;
473
+ gap: 8px;
474
+ flex-wrap: wrap;
475
+ }
476
+ .att {
477
+ display: inline-flex;
478
+ align-items: center;
479
+ gap: 7px;
480
+ padding: 4px 8px;
481
+ border: 1px solid var(--line);
482
+ border-radius: 8px;
483
+ background: var(--panel);
484
+ font-size: 12px;
485
+ color: var(--text-2);
486
+ font-family: var(--mono);
487
+ }
488
+ .att button { border: 0; background: none; color: var(--text-3); cursor: pointer; padding: 0; line-height: 1; }
489
+ .att button svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
490
+
491
+ /* ---------- sheet / modal ---------- */
492
+
493
+ .sheet {
494
+ position: fixed;
495
+ inset: 0;
496
+ background: rgba(10, 10, 12, 0.28);
497
+ display: flex;
498
+ justify-content: flex-end;
499
+ animation: fade var(--dur) var(--ease) both;
500
+ }
501
+ .sheet[hidden] { display: none; }
502
+ .sheet.is-closing { animation: fadeOut 160ms var(--ease-in) both; }
503
+ @keyframes fadeOut { to { opacity: 0; } }
504
+ @keyframes pop {
505
+ from { opacity: 0; transform: translateY(4px) scale(0.99); }
506
+ to { opacity: 1; transform: none; }
507
+ }
508
+ .sheet-panel {
509
+ width: min(420px, 92vw);
510
+ height: 100%;
511
+ background: var(--bg);
512
+ border-left: 1px solid var(--line);
513
+ box-shadow: var(--shadow-lg);
514
+ display: flex;
515
+ flex-direction: column;
516
+ animation: slide var(--dur) var(--ease) both;
517
+ will-change: transform;
518
+ }
519
+ @keyframes slide {
520
+ from { transform: translateX(18px); opacity: 0; }
521
+ to { transform: none; opacity: 1; }
522
+ }
523
+ .sheet-head { display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 16px; border-bottom: 1px solid var(--line); }
524
+ .sheet-head h2 { font-size: 14px; margin: 0; font-weight: 600; }
525
+ .sheet-body { padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 22px; }
526
+
527
+ .field { display: flex; flex-direction: column; gap: 8px; }
528
+ .field > label { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
529
+ .field select, .field input {
530
+ height: 34px;
531
+ padding: 0 10px;
532
+ border: 1px solid var(--line);
533
+ border-radius: 9px;
534
+ background: var(--bg);
535
+ outline: none;
536
+ font-size: 13.5px;
537
+ }
538
+ .field select:focus, .field input:focus { border-color: var(--text-3); }
539
+ .field .row { display: flex; gap: 8px; }
540
+ .seg { display: flex; border: 1px solid var(--line); border-radius: 9px; overflow: hidden; flex: 1; }
541
+ .seg button {
542
+ flex: 1;
543
+ height: 32px;
544
+ border: 0;
545
+ background: transparent;
546
+ color: var(--text-2);
547
+ font-size: 12.5px;
548
+ cursor: pointer;
549
+ transition: background 180ms var(--ease), color 180ms var(--ease);
550
+ }
551
+ .seg button + button { border-left: 1px solid var(--line); }
552
+ .seg button:hover { background: var(--panel-2); color: var(--text); }
553
+ .seg button:active { transform: scale(0.98); }
554
+ .seg button.is-on { background: var(--inverse); color: var(--bg); }
555
+
556
+ .perm-row { display: block; }
557
+ .perm-block { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
558
+ .perm-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
559
+ .perm-name { font-size: 13px; color: var(--text); font-weight: 500; }
560
+ .perm-head .seg { flex: none; width: 190px; }
561
+ .perm-detail {
562
+ margin-top: 6px;
563
+ padding-top: 6px;
564
+ border-top: 1px dashed var(--line);
565
+ font-size: 12px;
566
+ color: var(--text-2);
567
+ line-height: 1.5;
568
+ }
569
+ .perm-note { margin-top: 4px; }
570
+
571
+ /* ---------- 空状态引导 ---------- */
572
+ .empty-warn {
573
+ display: flex;
574
+ flex-direction: column;
575
+ align-items: flex-start;
576
+ gap: 8px;
577
+ max-width: 520px;
578
+ margin: 4px auto 22px;
579
+ padding: 16px 18px;
580
+ border: 1px solid var(--line-strong);
581
+ border-radius: var(--radius);
582
+ background: var(--panel);
583
+ text-align: left;
584
+ }
585
+ .empty-warn strong { font-size: 14.5px; font-weight: 600; }
586
+ .empty-warn span { font-size: 13px; color: var(--text-2); line-height: 1.6; }
587
+ .empty-warn .btn { margin-top: 4px; }
588
+ .empty-tips {
589
+ display: flex;
590
+ flex-wrap: wrap;
591
+ justify-content: center;
592
+ gap: 6px 18px;
593
+ margin-top: 22px;
594
+ font-size: 12px;
595
+ color: var(--text-3);
596
+ }
597
+ .empty-tips b { font-family: var(--mono); font-weight: 600; color: var(--text-2); }
598
+ .thread-divider {
599
+ max-width: 780px;
600
+ margin: 6px auto 18px;
601
+ padding: 0 24px;
602
+ display: flex;
603
+ align-items: center;
604
+ gap: 12px;
605
+ color: var(--text-3);
606
+ font-size: 11.5px;
607
+ }
608
+ .thread-divider::before,
609
+ .thread-divider::after {
610
+ content: '';
611
+ flex: 1;
612
+ height: 1px;
613
+ background: var(--line);
614
+ }
615
+ .thread-divider:empty::before,
616
+ .thread-divider:empty::after { display: none; }
617
+
618
+ /* ---------- 命令面板 ---------- */
619
+ .command-palette {
620
+ position: absolute;
621
+ left: 12px;
622
+ right: 12px;
623
+ bottom: calc(100% + 8px);
624
+ z-index: 40;
625
+ padding: 5px;
626
+ border: 1px solid var(--line);
627
+ border-radius: 11px;
628
+ background: var(--bg);
629
+ box-shadow: var(--shadow-lg);
630
+ animation: pop 170ms var(--ease) both;
631
+ max-height: 320px;
632
+ overflow: auto;
633
+ }
634
+ .command-palette[hidden] { display: none; }
635
+ .cmd-item {
636
+ display: grid;
637
+ grid-template-columns: minmax(70px, 108px) 1fr auto;
638
+ align-items: baseline;
639
+ gap: 10px;
640
+ width: 100%;
641
+ padding: 7px 9px;
642
+ border: 0;
643
+ border-radius: 7px;
644
+ background: transparent;
645
+ text-align: left;
646
+ cursor: pointer;
647
+ transition: background 120ms var(--ease);
648
+ }
649
+ .cmd-item:hover, .cmd-item.is-on { background: var(--panel-2); }
650
+ .cmd-name { font-family: var(--mono); font-size: 12.5px; color: var(--text); }
651
+ .cmd-summary { font-size: 12.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
652
+ .cmd-usage { font-family: var(--mono); font-size: 11.5px; color: var(--text-3); }
653
+ .cmd-empty { padding: 10px; font-size: 12.5px; color: var(--text-3); }
654
+
655
+ /* 命令输出用等宽字体,和对话正文区分开 */
656
+ .msg.cmd .msg-body { font-family: var(--mono); font-size: 12.6px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-2); }
657
+ .cmd-out.is-error { color: var(--text); }
658
+ .msg.cmd .msg-role { color: var(--text-3); }
659
+
660
+ .hint { font-size: 12px; color: var(--text-3); line-height: 1.5; }
661
+
662
+ /* ---------- 工具详情 ---------- */
663
+ .tool-row { cursor: default; }
664
+ .tool-row.is-open .t-detail { color: var(--text-2); }
665
+ .tool-caret { transition: transform 200ms var(--ease); }
666
+ .tool-row.is-open .tool-caret { transform: rotate(90deg); }
667
+ .tool-output {
668
+ margin: 2px 0 8px;
669
+ padding: 10px 12px;
670
+ max-height: 320px;
671
+ overflow: auto;
672
+ border: 1px solid var(--line);
673
+ border-radius: 9px;
674
+ background: var(--panel);
675
+ font-family: var(--mono);
676
+ font-size: 12.2px;
677
+ line-height: 1.55;
678
+ white-space: pre-wrap;
679
+ overflow-wrap: anywhere;
680
+ animation: fade 200ms var(--ease) both;
681
+ }
682
+ .tool-output.is-error { color: var(--text); border-color: var(--line-strong); }
683
+
684
+ /* ---------- 文件面板 ---------- */
685
+ .files-panel {
686
+ position: fixed;
687
+ top: 0;
688
+ right: 0;
689
+ bottom: 0;
690
+ width: min(420px, 92vw);
691
+ background: var(--bg);
692
+ border-left: 1px solid var(--line);
693
+ box-shadow: var(--shadow-lg);
694
+ display: flex;
695
+ flex-direction: column;
696
+ z-index: 30;
697
+ animation: slide 260ms var(--ease) both;
698
+ }
699
+ .files-panel[hidden] { display: none; }
700
+ .files-head {
701
+ display: flex;
702
+ align-items: center;
703
+ justify-content: space-between;
704
+ height: 54px;
705
+ padding: 0 10px 0 16px;
706
+ border-bottom: 1px solid var(--line);
707
+ font-size: 13px;
708
+ color: var(--text-2);
709
+ }
710
+ .files-tree { flex: 1; min-height: 0; overflow: auto; padding: 8px; }
711
+ .file-row {
712
+ display: flex;
713
+ align-items: center;
714
+ gap: 6px;
715
+ width: 100%;
716
+ padding: 5px 8px;
717
+ border: 0;
718
+ border-radius: 7px;
719
+ background: transparent;
720
+ color: var(--text-2);
721
+ font-size: 13px;
722
+ text-align: left;
723
+ cursor: pointer;
724
+ transition: background 140ms var(--ease), color 140ms var(--ease);
725
+ }
726
+ .file-row:hover { background: var(--panel-2); color: var(--text); }
727
+ .file-row.is-active { background: var(--panel-2); color: var(--text); }
728
+ .tool-caret { flex: none; display: inline-grid; place-items: center; width: 13px; height: 13px; color: var(--text-3); }
729
+ .file-row.is-open .tool-caret { transform: rotate(90deg); }
730
+ .file-children { margin-left: 13px; padding-left: 7px; border-left: 1px solid var(--line); }
731
+ .tool-row.is-clickable { cursor: pointer; }
732
+ .tool-row.is-clickable:hover .t-detail { color: var(--text); }
733
+ .tool-row.is-clickable .t-state { opacity: 1; }
734
+ .file-row svg { width: 13px; height: 13px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
735
+ .file-row .f-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
736
+ .files-preview { border-top: 1px solid var(--line); max-height: 46%; display: flex; flex-direction: column; }
737
+ .files-preview-head {
738
+ display: flex;
739
+ align-items: center;
740
+ justify-content: space-between;
741
+ gap: 8px;
742
+ padding: 8px 10px 8px 14px;
743
+ font-size: 12px;
744
+ color: var(--text-3);
745
+ font-family: var(--mono);
746
+ }
747
+ .files-preview pre {
748
+ margin: 0;
749
+ padding: 0 14px 14px;
750
+ overflow: auto;
751
+ font-family: var(--mono);
752
+ font-size: 12.2px;
753
+ line-height: 1.55;
754
+ color: var(--text-2);
755
+ white-space: pre-wrap;
756
+ overflow-wrap: anywhere;
757
+ }
758
+ .btn.tiny { height: 24px; padding: 0 9px; font-size: 12px; border-radius: 7px; }
759
+
760
+ /* ---------- popover ---------- */
761
+ .popover {
762
+ position: fixed;
763
+ z-index: 60;
764
+ min-width: 172px;
765
+ padding: 5px;
766
+ border: 1px solid var(--line);
767
+ border-radius: 10px;
768
+ background: var(--bg);
769
+ box-shadow: var(--shadow-lg);
770
+ animation: pop 160ms var(--ease) both;
771
+ }
772
+ .popover button {
773
+ display: block;
774
+ width: 100%;
775
+ text-align: left;
776
+ padding: 7px 10px;
777
+ border: 0;
778
+ border-radius: 7px;
779
+ background: transparent;
780
+ color: var(--text-2);
781
+ font-size: 13px;
782
+ cursor: pointer;
783
+ transition: background 130ms var(--ease), color 130ms var(--ease);
784
+ }
785
+ .popover button:hover { background: var(--panel-2); color: var(--text); }
786
+
787
+ /* ---------- 侧边栏操作 ---------- */
788
+ .session-item { position: relative; padding-right: 52px; }
789
+ .s-actions { position: absolute; right: 6px; top: 6px; display: flex; gap: 2px; opacity: 0; transition: opacity 140ms var(--ease); }
790
+ .session-item:hover .s-actions, .session-item.is-active .s-actions { opacity: 1; }
791
+ .s-act { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 5px; color: var(--text-3); transition: background 130ms var(--ease), color 130ms var(--ease); }
792
+ .s-act:hover { background: var(--panel-2); color: var(--text); }
793
+ .s-act svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
794
+ .session-item.is-active .s-title { padding-right: 0; }
795
+
796
+ @media (prefers-reduced-motion: reduce) {
797
+ *, *::before, *::after {
798
+ animation-duration: 1ms !important;
799
+ animation-iteration-count: 1 !important;
800
+ transition-duration: 1ms !important;
801
+ scroll-behavior: auto !important;
802
+ }
803
+ }
804
+
805
+ .modal {
806
+ position: fixed;
807
+ inset: 0;
808
+ background: rgba(10, 10, 12, 0.32);
809
+ display: grid;
810
+ place-items: center;
811
+ padding: 20px;
812
+ animation: fade 140ms var(--ease);
813
+ }
814
+ .modal[hidden] { display: none; }
815
+ .modal-card {
816
+ width: min(560px, 100%);
817
+ background: var(--bg);
818
+ border: 1px solid var(--line);
819
+ border-radius: 14px;
820
+ box-shadow: var(--shadow-lg);
821
+ padding: 18px;
822
+ animation: pop 200ms var(--ease);
823
+ }
824
+ @keyframes pop { from { transform: translateY(8px) scale(0.985); opacity: 0; } to { transform: none; opacity: 1; } }
825
+ .modal-head { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; }
826
+ .modal-ico { display: inline-grid; place-items: center; }
827
+ .modal-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
828
+ .modal-summary { margin: 10px 0 0; font-family: var(--mono); font-size: 12.6px; color: var(--text-2); overflow-wrap: anywhere; }
829
+ .modal-preview {
830
+ margin: 12px 0 0;
831
+ padding: 10px 12px;
832
+ max-height: 240px;
833
+ overflow: auto;
834
+ border: 1px solid var(--line);
835
+ border-radius: 9px;
836
+ background: var(--panel);
837
+ font-family: var(--mono);
838
+ font-size: 12.2px;
839
+ line-height: 1.55;
840
+ white-space: pre-wrap;
841
+ }
842
+ .modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
843
+
844
+ .btn {
845
+ height: 32px;
846
+ padding: 0 14px;
847
+ border: 1px solid var(--line);
848
+ border-radius: 9px;
849
+ background: transparent;
850
+ color: var(--text-2);
851
+ font-size: 13.5px;
852
+ cursor: pointer;
853
+ transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease);
854
+ }
855
+ .btn:hover { background: var(--panel-2); color: var(--text); }
856
+ .btn.primary { background: var(--inverse); border-color: var(--inverse); color: var(--bg); }
857
+ .btn.primary:hover { opacity: 0.88; background: var(--inverse); color: var(--bg); }
858
+
859
+ .toast {
860
+ position: fixed;
861
+ left: 50%;
862
+ bottom: 26px;
863
+ transform: translate(-50%, 8px);
864
+ padding: 8px 14px;
865
+ border: 1px solid var(--line);
866
+ border-radius: 10px;
867
+ background: var(--bg);
868
+ box-shadow: var(--shadow-lg);
869
+ font-size: 13px;
870
+ opacity: 0;
871
+ transition: opacity 180ms var(--ease), transform 180ms var(--ease);
872
+ }
873
+ .toast[hidden] { display: none; }
874
+ .toast.show { opacity: 1; transform: translate(-50%, 0); }
875
+
876
+ .only-narrow { display: none; }
877
+
878
+ @media (max-width: 900px) {
879
+ .app { grid-template-columns: 1fr; }
880
+ .sidebar { position: absolute; inset: 0 auto 0 0; width: var(--sidebar); z-index: 20; transform: translateX(-100%); transition: transform 220ms var(--ease); box-shadow: var(--shadow-lg); }
881
+ .sidebar.open { transform: none; }
882
+ .only-narrow { display: inline-grid; }
883
+ .msg { padding: 0 16px; }
884
+ .composer-wrap { padding: 8px 14px 12px; }
885
+ }