@sanqianx/claude-ai-workbench 0.13.2 → 0.13.4

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 (122) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +156 -156
  3. package/apps/agent-terminal/app.css +652 -613
  4. package/apps/agent-terminal/app.js +143 -67
  5. package/apps/agent-terminal/conversation-composer.js +44 -0
  6. package/apps/agent-terminal/index.html +172 -170
  7. package/apps/agent-terminal/panel-host-proof.html +152 -152
  8. package/apps/agent-terminal/panel-proof-content.html +41 -41
  9. package/apps/agent-terminal/right-workspace-dock.css +189 -159
  10. package/apps/agent-terminal/right-workspace-dock.js +652 -521
  11. package/apps/agent-terminal/user-question-card.js +68 -0
  12. package/apps/ai-profile-settings-host/index.html +25 -25
  13. package/apps/ai-profile-settings-host/page.css +1 -1
  14. package/apps/ai-profile-settings-host/page.js +113 -113
  15. package/apps/minimal-test-host/README.md +15 -15
  16. package/apps/minimal-test-host/host.css +2 -2
  17. package/apps/minimal-test-host/host.js +35 -35
  18. package/apps/minimal-test-host/index.html +58 -58
  19. package/apps/minimal-test-host/optional-mock/fault-injection.js +15 -15
  20. package/docs/sdk/FILE_LAYOUT.md +31 -31
  21. package/docs/sdk/INTEGRATION.md +126 -126
  22. package/docs/sdk/README.md +21 -21
  23. package/docs/sdk/SESSION_EVENTS.md +15 -13
  24. package/docs/sdk/openapi.yaml +16 -1
  25. package/package.json +1 -1
  26. package/packages/client/README.md +29 -29
  27. package/packages/client/index.d.ts +122 -122
  28. package/packages/client/index.js +260 -260
  29. package/packages/client/package.json +2 -2
  30. package/packages/contracts/README.md +9 -9
  31. package/packages/contracts/index.d.ts +519 -517
  32. package/packages/contracts/index.js +312 -312
  33. package/packages/contracts/package.json +1 -1
  34. package/packages/core/README.md +8 -8
  35. package/packages/core/index.d.ts +76 -76
  36. package/packages/core/index.js +222 -222
  37. package/packages/core/package.json +2 -2
  38. package/packages/server/README.md +17 -17
  39. package/packages/server/bin/agent-terminal-server.js +42 -42
  40. package/packages/server/bin/claude-workbench.js +225 -225
  41. package/packages/server/index.d.ts +171 -171
  42. package/packages/server/index.js +230 -230
  43. package/packages/server/lib/agent-discovery.js +133 -133
  44. package/packages/server/lib/agent-registry.js +143 -143
  45. package/packages/server/lib/agent-spawn-env.js +17 -17
  46. package/packages/server/lib/attachment-store.js +78 -78
  47. package/packages/server/lib/bridges/app-server-bridge.js +373 -373
  48. package/packages/server/lib/bridges/opencode-server-bridge.js +506 -506
  49. package/packages/server/lib/capture-settings-store.js +35 -35
  50. package/packages/server/lib/claude-history-recovery.js +87 -87
  51. package/packages/server/lib/cli-session-recovery.js +28 -28
  52. package/packages/server/lib/context-resolver.js +55 -55
  53. package/packages/server/lib/conversation-capture.js +51 -51
  54. package/packages/server/lib/delegation-phase-store.js +357 -357
  55. package/packages/server/lib/delegation-store.js +474 -468
  56. package/packages/server/lib/diagnostics.js +32 -32
  57. package/packages/server/lib/drivers/cli-json-runner.js +974 -974
  58. package/packages/server/lib/drivers/codex-driver.js +1461 -1442
  59. package/packages/server/lib/drivers/opencode-driver.js +1554 -1554
  60. package/packages/server/lib/drivers/zcode-driver.js +1250 -1250
  61. package/packages/server/lib/drivers/zcode-profile-runtime.js +71 -71
  62. package/packages/server/lib/event-stream.js +138 -138
  63. package/packages/server/lib/folder-picker.js +623 -623
  64. package/packages/server/lib/http-handler.js +339 -339
  65. package/packages/server/lib/json-file.js +26 -26
  66. package/packages/server/lib/knowledge-context.js +33 -33
  67. package/packages/server/lib/model-detection.js +295 -295
  68. package/packages/server/lib/parent-context.js +44 -0
  69. package/packages/server/lib/profile-store.js +283 -283
  70. package/packages/server/lib/project-store.js +102 -102
  71. package/packages/server/lib/runtime-loader.js +120 -120
  72. package/packages/server/lib/session-archive-store.js +53 -53
  73. package/packages/server/lib/session-history.js +612 -612
  74. package/packages/server/lib/system-doctor.js +125 -125
  75. package/packages/server/lib/ui-preferences-store.js +48 -48
  76. package/packages/server/lib/user-questions.js +67 -0
  77. package/packages/server/lib/workbench-service.js +1696 -1675
  78. package/packages/server/package.json +2 -2
  79. package/packages/ui/README.md +30 -30
  80. package/packages/ui/ai-profile-settings.d.ts +45 -45
  81. package/packages/ui/ai-profile-settings.js +283 -283
  82. package/packages/ui/claude-terminal.d.ts +31 -31
  83. package/packages/ui/claude-terminal.js +343 -343
  84. package/packages/ui/index.d.ts +18 -18
  85. package/packages/ui/index.js +51 -51
  86. package/packages/ui/package.json +2 -2
  87. package/packages/ui/theme.css +13 -13
  88. package/src/assets/claude-prompts.json +21 -21
  89. package/src/backend/http/ai-profile-routes.js +61 -61
  90. package/src/backend/http/claude-routes.js +170 -170
  91. package/src/backend/http/node-helpers.js +45 -45
  92. package/src/backend/index.js +21 -21
  93. package/src/backend/lib/ai-adapter.js +144 -144
  94. package/src/backend/lib/ai-profile-store.js +259 -259
  95. package/src/backend/lib/ai-vendor-presets.js +83 -83
  96. package/src/backend/lib/ai-workspace.js +140 -140
  97. package/src/backend/lib/automation-config.js +253 -253
  98. package/src/backend/lib/claude-cli-runner.js +2408 -2392
  99. package/src/backend/lib/data-dir.js +169 -169
  100. package/src/backend/lib/llm-client.js +176 -176
  101. package/src/backend/lib/model-context-windows.js +82 -82
  102. package/src/backend/lib/native-task-control.js +217 -217
  103. package/src/backend/lib/native-task-history-index.js +475 -475
  104. package/src/backend/lib/native-task-history-reader.js +526 -526
  105. package/src/backend/lib/native-task-messages.js +457 -457
  106. package/src/backend/lib/native-task-registry.js +325 -325
  107. package/src/backend/lib/native-task-runtime.js +242 -242
  108. package/src/backend/lib/native-task-trace.js +440 -440
  109. package/src/backend/lib/native-task-transcript.js +393 -393
  110. package/src/backend/lib/prompt-registry.js +166 -166
  111. package/src/backend/lib/runtime-config.js +121 -121
  112. package/src/backend/lib/sdk-session-stream.js +143 -143
  113. package/src/backend/lib/sdk-turn-stream.js +16 -16
  114. package/src/backend/lib/store-scope.js +131 -131
  115. package/src/backend/lib/task-identity.js +104 -104
  116. package/src/backend/lib/task-state-projection.js +58 -58
  117. package/src/index.js +7 -7
  118. package/src/sdk-wave-a.ts +1 -1
  119. package/src/sdk-wave-b.ts +1 -1
  120. package/src/sdk-wave-c.ts +1 -1
  121. package/src/sdk-wave-d.ts +1 -1
  122. package/src/sdk-wave-e.ts +1 -1
@@ -1,613 +1,652 @@
1
- /* Agent Terminal — desktop-flat theme.
2
- Design scale: spacing 4/8/12/16/24 · type 11/12.5/13/15/18 · radius 6/9/13 (+pills)
3
- control heights 26/30/36 (22px micro icon buttons) · two shadow levels:
4
- --shadow-1 hover/floating, --shadow-2 popovers & modals. */
5
-
6
- /* ===== tokens ===== */
7
- :root {
8
- --page:#0d0d0d; --side:#0d0d0d; --surface:#1a1a1a; --surface2:#242424;
9
- --line:#242424; --line2:#303030; --pop:#1f1f1f;
10
- --text:#ececec; --muted:#909090; --faint:#5f5f5f;
11
- --good:#4cc38a; --warn:#e2b466; --bad:#f08080; --accent:#e8863c; --blue:#4f8ef7;
12
- --good-soft:rgba(76,195,138,.12); --bad-soft:rgba(240,128,128,.1);
13
- --blue-soft:rgba(79,142,247,.14); --accent-soft:rgba(232,134,60,.14);
14
- --focus:rgba(79,142,247,.55); --focus-line:rgba(79,142,247,.45);
15
- --code-bg:#141417; --code-line:#26262b;
16
- --shadow-1:0 2px 10px rgba(0,0,0,.3);
17
- --shadow-2:0 12px 32px rgba(0,0,0,.55);
18
- }
19
- body.light {
20
- --page:#f7f7f7; --side:#f7f7f7; --surface:#ececec; --surface2:#e2e2e2;
21
- --line:#dcdcdc; --line2:#c9c9c9; --pop:#ffffff;
22
- --text:#1c1c1c; --muted:#666666; --faint:#9a9a9a;
23
- --good:#258263; --warn:#9d6e21; --bad:#bd4e4e; --accent:#c26a1e; --blue:#2f6fd0;
24
- --good-soft:rgba(37,130,99,.12); --bad-soft:rgba(189,78,78,.1);
25
- --blue-soft:rgba(47,111,208,.12); --accent-soft:rgba(194,106,30,.12);
26
- --focus:rgba(47,111,208,.5); --focus-line:rgba(47,111,208,.45);
27
- --code-bg:#f2f3f5; --code-line:#dfe1e6;
28
- --shadow-1:0 2px 10px rgba(30,30,30,.1);
29
- --shadow-2:0 12px 32px rgba(30,30,30,.18);
30
- }
31
-
32
- /* ===== base ===== */
33
- * { box-sizing:border-box; }
34
- [hidden] { display:none !important; }
35
- body { margin:0; overflow:hidden; background:var(--page); color:var(--text);
36
- font:13px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif; }
37
- button, input, textarea, select { font:inherit; }
38
- button { cursor:pointer; color:inherit; }
39
- :focus-visible { outline:2px solid var(--focus); outline-offset:1px; }
40
- .fin:focus-visible, .pop-search:focus-visible, .composer textarea:focus-visible { outline:none; }
41
- .view { display:none; height:100vh; }
42
- .view.active { display:flex; }
43
- .view[inert] { cursor:wait; }
44
- .view[inert] button, .view[inert] textarea { opacity:.55; }
45
- .linklike { border:0; color:var(--blue); background:transparent; padding:0; font-size:inherit; }
46
- .linklike:hover { text-decoration:underline; }
47
-
48
- /* Shared micro-interaction: every flat interactive surface eases its state change. */
49
- .session, .proj-item, .add-proj, .stab, .mgmt-item, .pop-item, .bar-btn, .ghost, .new-session,
50
- .act-btn, .foot-btn, .io-copy, .bubble-copy, .cb-copy, .attachment-remove, .del,
51
- .path-row .browse, .cta, .btn-allow, .btn-deny, .jump-latest, .send, .toggle-caret {
52
- transition:background-color .12s ease, color .12s ease, border-color .12s ease, filter .12s ease, transform .06s ease;
53
- }
54
-
55
- /* ===== generic buttons ===== */
56
- .ghost { display:inline-flex; align-items:center; gap:8px; height:26px; padding:0 12px;
57
- border:0; color:var(--muted); background:transparent; font-size:12.5px; border-radius:6px; }
58
- .ghost:hover { color:var(--text); background:var(--surface); }
59
-
60
- /* ===== 侧栏 ===== */
61
- .sidebar { display:flex; flex-direction:column; width:264px; flex:0 0 auto;
62
- background:var(--side); border-right:1px solid var(--line); }
63
- .brand { display:flex; align-items:center; justify-content:space-between; padding:16px 16px 12px; }
64
- .brand h1 { display:flex; align-items:center; gap:8px; margin:0; font-size:15px; font-weight:700; }
65
- .brand h1 svg.ics { width:15px; height:15px; color:var(--accent); }
66
- .brand .ver { color:var(--faint); font-size:11px; }
67
- .new-session { display:flex; align-items:center; gap:8px; height:30px; margin:4px 12px 8px;
68
- padding:0 12px; border:1px solid var(--line2); border-radius:9px; color:var(--muted);
69
- background:var(--surface); text-align:left; font-size:12.5px; }
70
- .new-session:hover { color:var(--text); background:var(--surface2); border-color:var(--line2); }
71
- .session-scroll { flex:1; overflow-y:auto; padding:4px 12px 12px; }
72
- .group-label { margin:16px 4px 4px; color:var(--faint); font-size:11px; letter-spacing:.12em; text-transform:uppercase; }
73
-
74
- /* 项目行:折叠箭头 + 名称 + 悬浮操作。激活项目以左侧主色条标记。 */
75
- .proj-item { display:flex; align-items:center; gap:8px; width:100%; height:26px; padding:0 8px;
76
- border:0; border-radius:6px; color:var(--text); background:transparent;
77
- font-size:12.5px; font-weight:600; text-align:left; }
78
- .proj-item:hover { background:var(--surface); }
79
- .proj.active > .proj-item { background:var(--surface); box-shadow:inset 2px 0 0 var(--accent); }
80
- .p-caret { display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px;
81
- flex:0 0 auto; color:var(--faint); transition:transform .15s ease; }
82
- .p-caret.closed { transform:rotate(-90deg); }
83
- .proj-item .p-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
84
- .toggle-caret { display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px;
85
- flex:0 0 auto; color:inherit; transition:transform .15s ease; }
86
- .toggle-caret.closed { transform:rotate(-90deg); }
87
- .sess-list { padding:0 0 4px; }
88
- .sess-list .session { padding-left:24px; }
89
- .session { display:flex; align-items:center; gap:8px; width:100%; height:26px; padding:0 8px;
90
- border:0; border-radius:6px; background:transparent; color:var(--muted); text-align:left; font-size:12.5px; }
91
- .session:hover { background:var(--surface); color:var(--text); }
92
- .session.active { background:var(--surface2); color:var(--text); box-shadow:inset 2px 0 0 var(--accent); }
93
- .session .s-title { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
94
- .session .when { margin-left:auto; color:var(--faint); font-size:11px; flex:0 0 auto; }
95
- .session:hover > .when { display:none; }
96
- .agent-badge { display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
97
- width:18px; height:18px; border-radius:6px; color:#fff; font-size:11px; font-weight:700; }
98
- .agent-badge.claude-code { background:#c9642d; }
99
- .agent-badge.codex { background:#2e7d5b; }
100
- .agent-badge.zcode { background:#6d5bd0; }
101
- .agent-badge.opencode { background:#33739e; }
102
- .add-proj { display:flex; align-items:center; gap:8px; width:100%; height:26px; margin:4px 0 0;
103
- padding:0 8px; border:0; border-radius:6px; color:var(--muted); background:transparent;
104
- font-size:12.5px; text-align:left; }
105
- .add-proj:hover { color:var(--text); background:var(--surface); }
106
- .proj-empty { padding:4px 8px 8px 24px; color:var(--faint); font-size:11px; }
107
-
108
- /* 侧栏空态:SVG 图标组合的插画式提示,不依赖外部资源。 */
109
- .side-empty { display:grid; justify-items:center; gap:4px; margin:8px 4px 12px; padding:16px 12px;
110
- border:1px dashed var(--line2); border-radius:9px; color:var(--faint); font-size:12.5px; text-align:center; }
111
- .side-empty-art { display:flex; align-items:center; justify-content:center; width:40px; height:40px;
112
- border-radius:9px; background:var(--surface); color:var(--faint); }
113
- .side-empty-sub { font-size:11px; }
114
-
115
- .row-acts { display:none; align-items:center; gap:2px; margin-left:auto; flex:0 0 auto; }
116
- .session:hover > .row-acts, .proj-item:hover > .row-acts { display:inline-flex; }
117
- .act-btn { display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
118
- padding:0; border:0; color:var(--muted); background:transparent; border-radius:6px; user-select:none; }
119
- .act-btn:hover { color:var(--text); background:var(--surface2); }
120
- .act-btn.danger:hover { color:var(--bad); background:var(--bad-soft); }
121
-
122
- /* 归档区:分隔线 + 可折叠标题 + 计数徽标。 */
123
- .arch-toggle { display:flex; align-items:center; gap:4px; width:calc(100% - 8px); margin:16px 0 4px;
124
- padding:8px 4px 4px; border:0; border-top:1px solid var(--line); background:transparent;
125
- color:var(--faint); font-size:11px; letter-spacing:.12em; text-transform:uppercase; text-align:left; }
126
- .arch-toggle:hover { color:var(--muted); }
127
- .arch-count { margin-left:4px; padding:0 4px; border-radius:99px; background:var(--surface);
128
- color:var(--faint); font-size:11px; letter-spacing:0; }
129
- .arch-list .session .s-title { color:var(--muted); }
130
- .arch-list .agent-badge { opacity:.75; }
131
- .sidebar-foot { display:flex; align-items:center; gap:8px; padding:12px 16px;
132
- border-top:1px solid var(--line); color:var(--faint); font-size:11px; }
133
- .sidebar-foot .ghost { padding:0 4px; }
134
- .dot { display:inline-block; width:7px; height:7px; flex:0 0 auto; border-radius:99px; background:var(--good); }
135
- .dot.run { animation:pulse 1.4s infinite; }
136
- @keyframes pulse { 50% { opacity:.4; } }
137
-
138
- /* ===== 主区 ===== */
139
- .main { display:flex; flex-direction:column; flex:1; min-width:0; position:relative; }
140
- .top-strip { display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:12px 24px 8px; }
141
- .top-strip .t { font-weight:600; font-size:13px; }
142
- .session-provider { color:var(--faint); font-size:11px; overflow:hidden; text-overflow:ellipsis;
143
- white-space:nowrap; min-width:0; }
144
- .top-strip .st { display:inline-flex; align-items:center; gap:8px; margin-left:auto; padding:4px 12px;
145
- border-radius:99px; color:#9db8ff; background:var(--blue-soft); font-size:12.5px; }
146
- body.light .top-strip .st { color:#2f5fd0; }
147
-
148
- /* ===== 消息流(ZCode 风格:过程折叠,正文直出)===== */
149
- .stream { flex:1; overflow-y:auto; padding:8px 24px 24px; }
150
- .stream:focus { outline:none; }
151
- .history-bar { max-width:860px; margin:0 auto 16px; display:flex; align-items:center; justify-content:center; gap:8px; color:var(--muted); font-size:12px; }
152
- .history-bar[hidden], .history-bar [hidden] { display:none; }
153
- .history-bar button:disabled { opacity:.6; cursor:wait; }
154
- .col { max-width:860px; margin:0 auto; }
155
- .empty-hint { text-align:center; color:var(--muted); margin-top:18vh; font-size:13px; line-height:1.7; }
156
- .empty-hint .big { display:flex; align-items:center; justify-content:center; margin-bottom:12px; }
157
- .hint-wrap { position:relative; display:inline-flex; }
158
- .hint-art { display:flex; align-items:center; justify-content:center; width:56px; height:56px;
159
- border-radius:13px; border:1px solid var(--line); background:var(--surface); color:var(--muted); }
160
- .hint-art svg { width:24px; height:24px; }
161
- .hint-art svg, .hint-spark svg { fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
162
- .hint-spark { position:absolute; top:-6px; right:-8px; display:flex; align-items:center; justify-content:center;
163
- width:20px; height:20px; border-radius:99px; background:var(--surface2); color:var(--accent); box-shadow:var(--shadow-1); }
164
- .hint-spark svg { width:11px; height:11px; }
165
- .empty-hint p { margin:4px 0 0; }
166
-
167
- /* 用户消息:轻量右置色块(尾部小圆角);AI 消息:全宽白板。 */
168
- .msg.user { display:grid; justify-items:end; margin:24px 0 12px; }
169
- .bubble { max-width:82%; padding:8px 12px; border:1px solid var(--line); border-radius:13px 13px 4px 13px;
170
- background:var(--surface2); color:var(--text); font-size:13px; line-height:1.65;
171
- white-space:pre-wrap; overflow-wrap:anywhere; }
172
- body.light .bubble { background:var(--surface); }
173
- .msg.ai { margin:12px 0 16px; }
174
- .msg.ai p { margin:0 0 12px; white-space:pre-wrap; overflow-wrap:anywhere; line-height:1.7; }
175
- .msg.ai .dim { color:var(--muted); }
176
-
177
- /* 回合折叠区:头部即计时行(工作中 X 秒 → 已工作 X 秒) */
178
- .proc { margin:4px 0 12px; user-select:none; }
179
- .proc > summary { display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
180
- color:var(--muted); font-size:12.5px; padding:4px 8px; margin-left:-8px; border-radius:6px; }
181
- .proc > summary:hover { color:var(--text); background:var(--surface); }
182
- .proc > summary::-webkit-details-marker { display:none; }
183
- .proc .caret { display:inline-flex; color:var(--faint); transition:transform .15s ease; }
184
- .proc[open] > summary .caret { transform:rotate(90deg); }
185
- .proc .p-meta { color:var(--faint); }
186
- .proc-steps { display:grid; gap:2px; margin:2px 0 8px 16px; padding-left:12px; border-left:1px solid var(--line); }
187
- .turn-note { display:flex; align-items:center; gap:8px; margin:4px 0 16px; color:var(--faint); font-size:12.5px; }
188
-
189
- /* 过程行:思考分段 / 工具步骤 / 备注行 */
190
- .think-seg { margin:4px 0 8px; }
191
- .think-label { display:flex; align-items:center; gap:8px; color:var(--muted); font-size:12.5px; padding:2px 0; }
192
- .t-glyph { color:var(--faint); }
193
- .t-meta { color:var(--faint); font-size:12.5px; }
194
- .think-body { color:var(--faint); font-size:12.5px; line-height:1.65; white-space:pre-wrap;
195
- overflow-wrap:anywhere; margin:2px 0 4px 16px; max-height:280px; overflow-y:auto; }
196
- .step { color:var(--muted); font-size:12.5px; }
197
- .step > summary { display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
198
- flex-wrap:wrap; padding:4px 0; min-width:0; }
199
- .step > summary::-webkit-details-marker { display:none; }
200
- .s-caret { display:inline-flex; color:var(--faint); flex:0 0 auto; transition:transform .15s ease; }
201
- .step[open] > summary .s-caret { transform:rotate(90deg); }
202
- .s-dot { width:8px; height:8px; flex:0 0 auto; border-radius:99px; background:var(--blue); }
203
- .step.failed .s-dot { background:var(--bad); }
204
- .step.note .s-dot { background:var(--faint); }
205
- .s-name { font-weight:600; color:var(--text); font-size:12.5px; }
206
- .s-desc { color:var(--faint); font-size:12.5px; overflow:hidden; text-overflow:ellipsis;
207
- white-space:nowrap; min-width:0; max-width:60%; }
208
- .s-meta { color:var(--faint); font-size:12.5px; margin-left:auto; flex:0 0 auto; }
209
- .s-meta.failed { color:var(--bad); }
210
- .step-body { display:grid; gap:8px; margin:2px 0 12px 16px; }
211
- .step-line { display:flex; align-items:center; gap:8px; color:var(--faint); font-size:12.5px; padding:2px 0; }
212
- .step-line .s-dot { width:6px; height:6px; background:var(--warn); }
213
-
214
- /* 输入/输出卡片:语言标签 + 复制按钮 + 语法高亮 */
215
- .io-card { border:1px solid var(--line); border-radius:9px; background:var(--surface); overflow:hidden; }
216
- .io-head { display:flex; align-items:center; justify-content:space-between; padding:4px 4px 0 12px; }
217
- .io-tag { display:inline-flex; align-items:center; gap:4px; color:var(--faint); font-size:11px;
218
- letter-spacing:.05em; text-transform:uppercase; }
219
- .io-brace { font:11px Consolas,monospace; color:var(--muted); }
220
- .io-copy { display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
221
- border:0; color:var(--faint); background:transparent; border-radius:6px; }
222
- .io-copy:hover { color:var(--text); background:var(--surface2); }
223
- .io-card pre { margin:0; padding:4px 12px 8px; color:var(--muted);
224
- font:12.5px/1.6 Consolas,"Microsoft YaHei",monospace; white-space:pre-wrap;
225
- overflow-wrap:anywhere; max-height:320px; overflow-y:auto; }
226
- .j-key { color:#7aa2f7; }
227
- .j-str { color:#9ece6a; }
228
- .j-num { color:#e0af68; }
229
- .j-bool { color:#bb9af7; }
230
- body.light .j-key { color:#2f5fd0; }
231
- body.light .j-str { color:#3a7d3a; }
232
- body.light .j-num { color:#9d6e21; }
233
- body.light .j-bool { color:#7a4fb3; }
234
- .file-changes { display:grid; gap:4px; font-size:12.5px; }
235
- .file-change { display:flex; gap:8px; align-items:baseline; min-width:0; }
236
- .file-path { min-width:0; overflow-wrap:anywhere; }
237
- .diff-add { color:var(--good); }
238
- .diff-remove { color:var(--bad); }
239
-
240
- /* 用户气泡复制按钮 */
241
- .bubble-copy { display:inline-flex; align-items:center; justify-content:center; height:22px;
242
- min-width:26px; margin:4px 2px 0 auto; border:0; color:var(--faint); background:transparent;
243
- border-radius:6px; }
244
- .bubble-copy:hover { color:var(--text); background:var(--surface2); }
245
- .copied .ic { color:var(--good); }
246
-
247
- /* 最终消息操作条:复制 / 重试 / 模型 · 时间 */
248
- .msg-foot { display:flex; align-items:center; gap:2px; margin:4px 0 16px; }
249
- .foot-btn { display:inline-flex; align-items:center; justify-content:center; width:26px; height:24px;
250
- border:0; color:var(--faint); background:transparent; border-radius:6px; }
251
- .foot-btn:hover { color:var(--text); background:var(--surface2); }
252
- .foot-time { color:var(--faint); font-size:11px; margin-left:8px; }
253
-
254
- /* 回合文件变更汇总 */
255
- .turn-diffs { margin:4px 0 16px; }
256
- .turn-diffs-head { display:flex; align-items:center; gap:8px; padding:2px 0 4px; }
257
- .td-label { color:var(--muted); font-size:12.5px; font-weight:600; }
258
- .td-count { display:inline-flex; align-items:center; gap:8px; font:11px Consolas,monospace; }
259
- .td-approx { font-style:normal; color:var(--faint); font-size:11px; }
260
- .turn-diffs-list { padding:0 0 0 12px; display:grid; gap:2px; }
261
- .td-row { display:flex; gap:8px; align-items:baseline; justify-content:space-between;
262
- font-size:12.5px; color:var(--faint); }
263
- .td-rowcount { font:11px Consolas,monospace; color:var(--faint); flex:0 0 auto; }
264
- .td-more { color:var(--faint); }
265
-
266
- /* 工具行参数徽章与运行态 shimmer */
267
- .s-args { display:inline-flex; gap:4px; }
268
- .s-args i { font-style:normal; font:11px Consolas,"Microsoft YaHei",monospace; color:var(--faint);
269
- background:var(--surface2); padding:1px 4px; border-radius:99px; }
270
- .s-meta.running { background:linear-gradient(90deg, var(--faint) 25%, var(--text) 50%, var(--faint) 75%);
271
- background-size:200% 100%; -webkit-background-clip:text; background-clip:text; color:transparent;
272
- animation:shimmer 1.6s linear infinite; }
273
- @keyframes shimmer { to { background-position:-200% 0; } }
274
-
275
- /* 回到底部悬浮按钮 */
276
- .jump-latest { position:absolute; right:24px; bottom:136px; z-index:5; display:inline-flex;
277
- align-items:center; gap:4px; height:26px; padding:0 12px; border:1px solid var(--line2);
278
- border-radius:99px; background:var(--pop); color:var(--muted); font-size:12.5px;
279
- box-shadow:var(--shadow-2); }
280
- .jump-latest:hover { color:var(--text); background:var(--surface); }
281
-
282
- /* 助手正文 markdown */
283
- .md-body { font-size:15px; line-height:1.7; color:#d8d8d8; overflow-wrap:anywhere; }
284
- body.light .md-body { color:var(--text); }
285
- .md-body.streaming::after { content:"▍"; animation:pulse 1s infinite; color:var(--text); }
286
- .md-body p { margin:0 0 12px; white-space:pre-wrap; }
287
- .md-body p:last-child { margin-bottom:0; }
288
- .md-body h3, .md-body h4, .md-body h5, .md-body h6 { margin:16px 0 8px; font-size:15px; font-weight:650; }
289
- .md-body h3 { font-size:18px; }
290
- .md-body h5, .md-body h6 { font-weight:600; color:var(--muted); }
291
- .md-body ul, .md-body ol { margin:0 0 12px; padding-left:24px; }
292
- .md-body li { margin:4px 0; }
293
- .md-body blockquote { margin:0 0 12px; padding:4px 12px; border-left:2px solid var(--line2); color:var(--muted); }
294
- .md-body hr { border:0; border-top:1px solid var(--line); margin:16px 0; }
295
- .md-body strong { color:var(--text); font-weight:650; }
296
- .md-body code { padding:1px 4px; border-radius:6px; background:rgba(255,255,255,.07);
297
- font:12.5px/1.5 Consolas,"Microsoft YaHei",monospace; }
298
- body.light .md-body code { background:rgba(0,0,0,.06); }
299
- .md-body a { color:var(--blue); }
300
- .codeblock { margin:0 0 12px; border:1px solid var(--code-line); border-radius:9px;
301
- background:var(--code-bg); overflow:hidden; }
302
- .cb-head { display:flex; align-items:center; justify-content:space-between; padding:4px 4px 4px 12px;
303
- border-bottom:1px solid var(--code-line); }
304
- .cb-lang { color:var(--faint); font-size:11px; letter-spacing:.05em; text-transform:uppercase; }
305
- .cb-copy { display:inline-flex; align-items:center; height:22px; padding:0 4px; border:0;
306
- color:var(--muted); background:transparent; font-size:11px; border-radius:6px; }
307
- .cb-copy:hover { color:var(--text); background:var(--surface2); }
308
- .codeblock pre { margin:0; padding:8px 12px; overflow-x:auto; }
309
- .codeblock code { font:12.5px/1.65 Consolas,"Microsoft YaHei",monospace; background:transparent;
310
- padding:0; color:#cfd8ea; }
311
- body.light .codeblock code { color:#24304a; }
312
-
313
- /* 权限确认卡 */
314
- .perm { display:flex; align-items:center; gap:12px; margin:16px 0; padding:12px 16px;
315
- border:1px solid var(--line); border-radius:13px; background:var(--surface); }
316
- .perm.settled { display:inline-flex; margin:4px 0; padding:0; background:transparent; border:0; }
317
- .perm.settled .p-title { font-weight:400; color:var(--faint); font-size:12.5px; }
318
- .perm.settled .p-sub, .perm.settled .p-icon { display:none; }
319
- .perm.settled .p-state { font-size:12.5px; }
320
- .perm .p-icon { flex:0 0 auto; color:var(--warn); display:inline-flex; }
321
- .perm .p-body { flex:1; min-width:0; }
322
- .perm .p-title { font-size:13px; font-weight:600; }
323
- .perm .p-sub { margin-top:2px; color:var(--muted); font-size:11px; font-family:Consolas,monospace; overflow-wrap:anywhere; }
324
- .perm .p-actions { display:flex; gap:8px; }
325
- .perm .btn-allow { height:30px; padding:0 16px; border:0; border-radius:9px; color:#161616;
326
- background:var(--accent); font-weight:650; font-size:12.5px; }
327
- .perm .btn-allow:hover { filter:brightness(1.08); }
328
- body.light .perm .btn-allow { color:#fff; }
329
- .perm .btn-deny { height:30px; padding:0 12px; border:0; border-radius:9px; color:var(--muted);
330
- background:transparent; font-size:12.5px; }
331
- .perm .btn-deny:hover { color:var(--bad); }
332
- .perm .p-state { color:var(--muted); font-size:12.5px; }
333
- .perm .p-state.no { color:var(--bad); }
334
-
335
- /* 附件托盘:缩略图统一 48px,移除按钮悬浮于角标 */
336
- .attach-tray { display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; margin:-8px 0 12px; }
337
- .attach-tray img { width:48px; height:48px; object-fit:cover; display:block;
338
- border-radius:9px; border:1px solid var(--line); }
339
- .attachment-item { position:relative; display:flex; align-items:center; gap:4px; max-width:100%; }
340
- .attachment-file { display:inline-flex; align-items:center; gap:4px; max-width:100%; padding:4px 8px;
341
- border:1px solid var(--line); border-radius:9px; background:var(--surface);
342
- color:var(--muted); font-size:12.5px; overflow-wrap:anywhere; }
343
- .attachment-remove { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px;
344
- border:0; border-radius:99px; background:transparent; color:var(--muted); }
345
- .attachment-item.img .attachment-remove { position:absolute; top:-6px; right:-6px;
346
- background:var(--surface2); box-shadow:var(--shadow-1); z-index:1; }
347
- .attachment-remove:hover { color:var(--bad); background:var(--surface2); }
348
- .composer .attach-tray { justify-content:flex-start; margin:0 0 8px; }
349
-
350
- /* ===== 底部输入容器 ===== */
351
- .composer-wrap { padding:8px 24px 16px; }
352
- .composer { max-width:860px; margin:0 auto; border-radius:13px; background:var(--surface);
353
- border:1px solid var(--line); padding:12px 12px 8px;
354
- transition:border-color .15s ease, box-shadow .15s ease; }
355
- .composer:focus-within { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
356
- .composer textarea { width:100%; min-height:22px; max-height:150px; padding:2px 2px 8px; border:0;
357
- color:var(--text); background:transparent; resize:none; outline:none; font:13px/1.6 inherit; }
358
- .composer textarea::placeholder { color:var(--faint); }
359
- .cmdrow { display:flex; align-items:center; gap:4px; }
360
- .bar-btn { display:inline-flex; align-items:center; gap:4px; height:26px; padding:0 8px;
361
- border:0; border-radius:6px; color:var(--muted); background:transparent;
362
- font-size:12.5px; white-space:nowrap; }
363
- .bar-btn:hover { background:var(--surface2); color:var(--text); }
364
- .bar-btn .chev { display:inline-flex; color:var(--faint); }
365
- #model-label { max-width:min(34vw,330px); overflow:hidden; text-overflow:ellipsis; }
366
- .bar-btn.plus .ic { width:15px; height:15px; }
367
- .bar-btn.mode { color:var(--text); }
368
- .bar-btn.mode .shield { display:inline-flex; filter:grayscale(1); opacity:.85; }
369
- .bar-btn.mode.accent { color:var(--accent); }
370
- .bar-btn.mode.accent .shield { filter:none; opacity:1; }
371
- .cmd-spacer { flex:1; }
372
- .ring { display:inline-block; width:13px; height:13px; flex:0 0 auto; margin:0 8px 0 0;
373
- border:2px solid var(--faint); border-top-color:var(--text); border-right-color:var(--text);
374
- border-radius:50%; transform:rotate(-35deg); animation:spin 1s linear infinite; }
375
- .ctx-mini { position:relative; width:54px; height:4px; margin:0 2px; border-radius:99px;
376
- background:var(--surface2); overflow:hidden; }
377
- .ctx-mini i { position:absolute; top:0; bottom:0; left:0; border-radius:99px;
378
- background:linear-gradient(90deg, var(--good), var(--warn)); }
379
- @keyframes spin { to { transform:rotate(325deg); } }
380
- .send { display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px;
381
- border:0; border-radius:99px; background:var(--accent); }
382
- .send:hover { filter:brightness(1.1); }
383
- .send:active { transform:scale(.94); }
384
- .send .up, .send .sq { color:#161616; }
385
- .send .up { display:inline-flex; align-items:center; justify-content:center; }
386
- .send .sq { width:10px; height:10px; border-radius:2px; background:#161616; }
387
- body.light .send .up { color:#fff; }
388
- body.light .send .sq { background:#fff; }
389
-
390
- /* ===== 弹出层 ===== */
391
- .anchor { position:relative; display:inline-flex; }
392
- .pop { position:absolute; bottom:calc(100% + 8px); z-index:40; min-width:240px; padding:4px;
393
- border-radius:13px; background:var(--pop); border:1px solid var(--line2);
394
- box-shadow:var(--shadow-2); animation:pop-in .12s ease; }
395
- .pop[hidden] { display:none; }
396
- .pop.from-left { left:0; } .pop.from-right { right:0; }
397
- .pop-group { display:flex; align-items:center; gap:8px; padding:8px 8px 4px; color:var(--muted); font-size:12.5px; }
398
- .tag { display:inline-flex; align-items:center; padding:1px 8px; border-radius:6px;
399
- background:var(--surface2); color:var(--muted); font-size:11px; }
400
- .pop-item { display:flex; align-items:center; gap:8px; width:100%; padding:4px 8px; border:0;
401
- border-radius:6px; color:var(--text); background:transparent; font-size:13px; text-align:left; }
402
- .pop-item:hover:not(:disabled) { background:var(--surface2); }
403
- .pop-item:disabled { opacity:.4; cursor:not-allowed; }
404
- /* Whole menu scrolls as one — no nested inner scrollbar. */
405
- #pop-model { max-height:min(560px,76vh); max-width:min(480px,90vw); overflow:auto; }
406
- .pop-item .grow { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
407
- .pop-item .check { display:inline-flex; color:var(--blue); visibility:hidden; }
408
- .pop-item.selected .check { visibility:visible; }
409
- .pop-item.selected .grow { font-weight:600; }
410
- .pop-item.muted { color:var(--muted); }
411
- .pop-sep { height:1px; margin:4px; background:var(--line); }
412
- .ctx-pop { width:360px; padding:16px; }
413
- .ctx-head { display:flex; justify-content:space-between; align-items:center; font-size:12.5px; }
414
- .ctx-head .num { color:var(--muted); }
415
- .bar { height:5px; margin:8px 0 12px; border-radius:99px; background:var(--surface2); overflow:hidden; }
416
- .bar > i { display:block; height:100%; border-radius:99px; background:var(--blue); }
417
- .ctx-row { display:flex; justify-content:space-between; padding:4px 0; color:var(--muted); font-size:12.5px; }
418
- .ctx-sep { height:1px; margin:8px 0; background:var(--line); }
419
-
420
- /* ===== 设置页 ===== */
421
- .settings-wrap { display:flex; flex:1; min-width:0; }
422
- .settings-nav { width:190px; flex:0 0 auto; padding:16px 8px; border-right:1px solid var(--line); }
423
- .settings-nav strong { display:block; padding:0 12px 12px; font-size:13px; }
424
- .settings-back { margin:0 0 12px; padding-left:0; }
425
- .stab { width:100%; height:30px; margin:1px 0; padding:0 12px; border:0; border-radius:6px;
426
- color:var(--muted); background:transparent; text-align:left; font-size:12.5px; }
427
- .stab:hover { color:var(--text); background:var(--surface); }
428
- .stab.active { color:var(--text); background:var(--surface2); box-shadow:inset 2px 0 0 var(--accent); }
429
- .settings-body { flex:1; overflow-y:auto; padding:24px; }
430
- .settings-body h2 { margin:0 0 4px; font-size:18px; }
431
- .settings-body .sub { margin:0 0 24px; color:var(--muted); font-size:12.5px; }
432
- .spanel { display:none; } .spanel.active { display:block; }
433
- .prov-cols { display:grid; grid-template-columns:210px minmax(0,1fr); gap:12px; align-items:start; }
434
- .mgmt-side { padding:8px; border-radius:13px; background:var(--surface); border:1px solid var(--line); }
435
- .mgmt-group { padding:8px 8px 4px; color:var(--faint); font-size:11px; }
436
- .mgmt-item { display:flex; align-items:center; gap:8px; width:100%; height:30px; padding:0 8px;
437
- border:0; border-radius:6px; color:var(--text); background:transparent; font-size:13px; text-align:left; }
438
- .mgmt-item:hover { background:var(--surface2); }
439
- .mgmt-item.active { background:var(--surface2); }
440
- .mgmt-item .grow { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
441
- .mgmt-item .dot { width:6px; height:6px; }
442
- .mgmt-item .dot.off { background:var(--faint); }
443
- .mgmt-detail { min-height:380px; padding:24px; border-radius:13px; background:var(--surface);
444
- border:1px solid var(--line); }
445
- .empty-models { padding:24px 0; color:var(--faint); font-size:12.5px; text-align:center; }
446
- .pd { display:none; } .pd.active { display:block; }
447
- .pd-head { display:flex; align-items:center; gap:8px; }
448
- .pd-head h3 { margin:0; font-size:15px; }
449
- .status-chip { display:inline-flex; align-items:center; height:22px; padding:0 12px; border-radius:99px;
450
- font-size:11px; color:var(--good); background:var(--good-soft); }
451
- .status-chip.off { color:var(--muted); background:var(--surface2); }
452
- .pd-head .sp { flex:1; }
453
- .pd-head .del { display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px;
454
- border:0; border-radius:6px; color:var(--muted); background:transparent; }
455
- .pd-head .del:hover { color:var(--bad); background:var(--bad-soft); }
456
- .f { display:grid; gap:8px; margin-top:16px; }
457
- .f > label { color:var(--text); font-size:12.5px; }
458
- .field-note { color:var(--muted); font-size:11px; }
459
- .fin { width:100%; height:36px; padding:0 12px; border:1px solid var(--line2); border-radius:9px;
460
- color:var(--text); background:var(--page); font-size:13px; outline:none;
461
- transition:border-color .12s ease, box-shadow .12s ease; }
462
- .fin:focus { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
463
- .fin::placeholder { color:var(--faint); }
464
- .key-row { position:relative; }
465
- .key-row .fin { padding-right:42px; }
466
- .eye { position:absolute; right:4px; top:50%; transform:translateY(-50%); display:inline-flex;
467
- align-items:center; justify-content:center; width:26px; height:26px; border:0; border-radius:6px;
468
- color:var(--muted); background:transparent; }
469
- .eye:hover { color:var(--text); background:var(--surface2); }
470
- .pd-foot { display:flex; align-items:center; gap:8px; margin-top:24px; }
471
- .pd-foot .note { flex:1; display:flex; align-items:center; gap:8px; color:var(--muted); font-size:12.5px; }
472
- .cta { height:30px; padding:0 16px; border:0; border-radius:9px; color:#161616;
473
- background:var(--accent); font-weight:650; font-size:12.5px; }
474
- .cta:hover { filter:brightness(1.08); }
475
- body.light .cta { color:#fff; }
476
- .cta[disabled] { opacity:.45; cursor:not-allowed; filter:none; }
477
- .agent-card { display:flex; align-items:flex-start; gap:12px; margin-bottom:12px; padding:16px;
478
- border-radius:13px; background:var(--surface); border:1px solid var(--line); }
479
- .agent-card.missing { opacity:.55; }
480
- .agent-card .agent-badge { width:22px; height:22px; font-size:11px; }
481
- .agent-card .a-body { flex:1; min-width:0; }
482
- .agent-card .a-name { display:flex; align-items:center; gap:8px; font-weight:650; font-size:13px; }
483
- .agent-card .a-meta { margin-top:4px; color:var(--muted); font-size:11px; }
484
- .cap-chips { display:flex; flex-wrap:wrap; gap:4px; margin-top:8px; }
485
- .chip { display:inline-flex; align-items:center; padding:1px 8px; border-radius:99px;
486
- background:var(--surface2); color:var(--muted); font-size:11px; }
487
- .chip.good { color:var(--good); background:var(--good-soft); }
488
- .cap-chips .chip.off { color:var(--faint); opacity:.6; }
489
- .auth-note { margin:16px 0 0; padding:2px 0 2px 16px; border-left:2px solid var(--line2);
490
- color:var(--muted); font-size:12.5px; }
491
-
492
- /* ===== 弹窗 / 提示 ===== */
493
- .modal { position:fixed; inset:0; z-index:70; display:none; align-items:center; justify-content:center;
494
- background:rgba(0,0,0,.55); }
495
- .modal.open { display:flex; animation:fade-in .12s ease; }
496
- body.light .modal { background:rgba(20,20,20,.35); }
497
- .modal-box { width:min(470px,92vw); border-radius:13px; background:var(--pop);
498
- border:1px solid var(--line2); padding:24px; box-shadow:var(--shadow-2); }
499
- .modal.open .modal-box { animation:modal-in .14s cubic-bezier(.2,.9,.3,1); }
500
- .modal-box h3 { margin:0 0 4px; font-size:15px; }
501
- .modal-box .sub { margin:0 0 16px; color:var(--muted); font-size:12.5px; }
502
- .modal-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:24px; }
503
- .form-error { margin-top:12px; padding:8px 12px; border-radius:9px; color:var(--bad);
504
- background:var(--bad-soft); font-size:12.5px; border:1px solid rgba(240,128,128,.2); }
505
- body.light .form-error { border-color:rgba(189,78,78,.2); }
506
- /* 添加项目弹窗:路径输入 + 系统浏览按钮同行 */
507
- .path-row { display:flex; gap:8px; align-items:stretch; }
508
- .path-row .fin { flex:1; min-width:0; width:auto; }
509
- .path-row .browse { flex:0 0 auto; display:inline-flex; align-items:center; height:36px; padding:0 12px;
510
- border:1px solid var(--line2); border-radius:9px; }
511
- .path-row .browse:hover { background:var(--surface); border-color:var(--faint); }
512
- .path-row .browse:disabled { opacity:.45; cursor:not-allowed; }
513
-
514
- /* Toast:类型化配色 + 图标,底部居中堆叠,进入/退出动画。 */
515
- .toast-host { position:fixed; bottom:24px; left:0; right:0; z-index:90; display:flex;
516
- flex-direction:column; align-items:center; gap:8px; pointer-events:none; }
517
- .toast { pointer-events:auto; display:flex; align-items:center; gap:8px; max-width:min(480px,90vw);
518
- padding:8px 16px; border-radius:9px; border:1px solid var(--line2); background:var(--pop);
519
- color:var(--text); font-size:12.5px; box-shadow:var(--shadow-2); animation:toast-in .16s ease; }
520
- .toast .ic { color:var(--muted); }
521
- .toast.good .ic { color:var(--good); }
522
- .toast.bad .ic { color:var(--bad); }
523
- .toast.leaving { animation:toast-out .15s ease forwards; }
524
-
525
- .pop-search { width:100%; height:30px; padding:0 8px; margin-bottom:4px; border:1px solid var(--line2);
526
- border-radius:6px; color:var(--text); background:var(--page); font-size:12.5px; outline:none;
527
- transition:border-color .12s ease, box-shadow .12s ease; }
528
- .pop-search:focus { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
529
-
530
- /* Themed scrollbars: slim rounded thumb, no track chrome or arrow buttons. */
531
- * { scrollbar-width: thin; scrollbar-color: #3f3f3f transparent; }
532
- ::-webkit-scrollbar { width: 10px; height: 10px; }
533
- ::-webkit-scrollbar-track { background: transparent; }
534
- ::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
535
- ::-webkit-scrollbar-thumb { background: #3f3f3f; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
536
- ::-webkit-scrollbar-thumb:hover { background: #525252; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
537
- ::-webkit-scrollbar-corner { background: transparent; }
538
- body.light * { scrollbar-color: #c4c4c4 transparent; }
539
- body.light ::-webkit-scrollbar-thumb { background: #c4c4c4; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
540
- body.light ::-webkit-scrollbar-thumb:hover { background: #adadad; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
541
- .f[hidden] { display:none; }
542
-
543
- /* ===================== icon system & runtime polish ===================== */
544
- .ic { display:inline-flex; flex:0 0 auto; vertical-align:-2px; color:inherit; }
545
- .ic svg, svg.ics { width:100%; height:100%; fill:none; stroke:currentColor; stroke-width:1.8;
546
- stroke-linecap:round; stroke-linejoin:round; }
547
- svg.ics { width:13px; height:13px; flex:0 0 auto; }
548
- #open-settings, #btn-rescan { display:inline-flex; align-items:center; }
549
-
550
- /* Thinking hint: shown while the driver streams nothing yet (reasoning phase). */
551
- .think-hint { display:flex; align-items:center; gap:8px; margin:12px 2px; color:var(--muted); font-size:12.5px; }
552
-
553
- /* Unified error row replaces the bare ⚠ paragraph. */
554
- .msg.ai.error { display:flex; gap:8px; align-items:flex-start; margin:16px 0; padding:8px 12px;
555
- border:1px solid rgba(255,96,96,.3); background:var(--bad-soft); border-radius:9px;
556
- color:#ff9c9c; font-size:13px; line-height:1.5; }
557
- .msg.ai.error .ic { margin-top:2px; }
558
- body.light .msg.ai.error { color:#b42318; border-color:rgba(180,35,24,.25); background:rgba(180,35,24,.05); }
559
-
560
- /* Gentle reveal when a fold opens; hover feedback on rows. */
561
- .proc[open] > .proc-steps, .step[open] > .step-body { animation:fade-in .18s ease; }
562
- @keyframes fade-in { from { opacity:0; transform:translateY(-3px); } }
563
- @keyframes pop-in { from { opacity:0; transform:translateY(4px); } }
564
- @keyframes modal-in { from { opacity:0; transform:translateY(6px) scale(.985); } }
565
- @keyframes toast-in { from { opacity:0; transform:translateY(8px); } }
566
- @keyframes toast-out { to { opacity:0; transform:translateY(6px); } }
567
-
568
- @media (prefers-reduced-motion: reduce) {
569
- *, *::before, *::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
570
- }
571
-
572
- /* ===== embed 模式(被知识库壳嵌入):折叠左侧项目栏,由壳 postMessage 控制 ===== */
573
- body.embed-collapse .sidebar { display: none; }
574
-
575
- /* Embedded product tokens are owned by the shell; standalone styling stays. */
576
- body.kb-embedded.light {
577
- --page:#ffffff; --side:#f8f9fb; --surface:#f3f5f7; --surface2:#edf1f4;
578
- --line:#dce2e8; --line2:#dce2e8; --pop:#ffffff;
579
- --text:#202733; --muted:#687587; --faint:#8e99a7;
580
- --good:#397761; --bad:#a05252; --blue:#516f89; --blue-soft:#e6edf3;
581
- --code-bg:#f3f5f7; --code-line:#dce2e8;
582
- }
583
- body.kb-embedded:not(.light) {
584
- --page:#20252d; --side:#1b2028; --surface:#252b34; --surface2:#2c333e;
585
- --line:#39424f; --line2:#39424f; --pop:#252b34;
586
- --text:#e6ebf0; --muted:#a0aaba; --faint:#788393; --blue:#8aa8cf; --blue-soft:#293748;
587
- --good:#81b29a; --bad:#d88b8b; --code-bg:#252b34; --code-line:#39424f;
588
- }
589
- body.kb-embedded { --accent:var(--blue); --accent-soft:var(--blue-soft); }
590
- body.kb-embedded .agent-badge { background:var(--blue); }
591
- body.kb-embedded .sidebar { display:flex; width:208px; min-width:208px; border-right:1px solid var(--line); }
592
- body.kb-embedded .brand, body.kb-embedded .group-label, body.kb-embedded .add-proj,
593
- body.kb-embedded .proj-item .row-acts, body.kb-embedded .sidebar-foot, body.kb-embedded #btn-top-settings { display:none; }
594
- body.kb-embedded .new-session { margin:16px 16px 8px; }
595
- body.kb-embedded .hint-spark, body.kb-embedded .hint-art { display:none; }
596
- body.kb-embedded .empty-hint .big { display:none; }
597
- .embedded-hint { display:none; }
598
- body.kb-embedded .standalone-hint { display:none; }
599
- body.kb-embedded .embedded-hint { display:block; }
600
- body.kb-embedded .cmdrow { min-width:0; }
601
- body.kb-embedded .cmdrow > .bar-btn, body.kb-embedded .send { flex-shrink:0; }
602
- body.kb-embedded .cmdrow > .anchor { flex:0 0 auto; }
603
- body.kb-embedded .cmdrow > .model-anchor { flex:0 1 auto; min-width:0; }
604
- body.kb-embedded #btn-model { min-width:0; max-width:100%; }
605
- body.kb-embedded #model-label { display:block; min-width:0; max-width:100%; }
606
- body.kb-embedded #btn-ctx .ctx-mini { display:none; }
607
- body.kb-embedded .ctx-mini i { background:var(--blue); }
608
- /* Task state comes from SDK notifications and persists independently of turns. */
609
- .background-tasks { padding: 12px 0; }
610
- .background-tasks[hidden] { display: none; }
611
- .background-tasks .task-card { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: 8px 0; }
612
- .background-tasks .task-detail { white-space: pre-wrap; overflow-wrap: anywhere; opacity: .8; font-size: 12px; margin-top: 6px; }
613
- .task-count { font-size: 11px; color: var(--accent); }
1
+ /* Agent Terminal — desktop-flat theme.
2
+ Design scale: spacing 4/8/12/16/24 · type 11/12.5/13/15/18 · radius 6/9/13 (+pills)
3
+ control heights 26/30/36 (22px micro icon buttons) · two shadow levels:
4
+ --shadow-1 hover/floating, --shadow-2 popovers & modals. */
5
+
6
+ /* ===== tokens ===== */
7
+ :root {
8
+ --page:#0d0d0d; --side:#0d0d0d; --surface:#1a1a1a; --surface2:#242424;
9
+ --line:#242424; --line2:#303030; --pop:#1f1f1f;
10
+ --text:#ececec; --muted:#909090; --faint:#5f5f5f;
11
+ --good:#4cc38a; --warn:#e2b466; --bad:#f08080; --accent:#e8863c; --blue:#4f8ef7;
12
+ --good-soft:rgba(76,195,138,.12); --bad-soft:rgba(240,128,128,.1);
13
+ --blue-soft:rgba(79,142,247,.14); --accent-soft:rgba(232,134,60,.14);
14
+ --focus:rgba(79,142,247,.55); --focus-line:rgba(79,142,247,.45);
15
+ --code-bg:#141417; --code-line:#26262b;
16
+ --shadow-1:0 2px 10px rgba(0,0,0,.3);
17
+ --shadow-2:0 12px 32px rgba(0,0,0,.55);
18
+ }
19
+ body.light {
20
+ --page:#f7f7f7; --side:#f7f7f7; --surface:#ececec; --surface2:#e2e2e2;
21
+ --line:#dcdcdc; --line2:#c9c9c9; --pop:#ffffff;
22
+ --text:#1c1c1c; --muted:#666666; --faint:#9a9a9a;
23
+ --good:#258263; --warn:#9d6e21; --bad:#bd4e4e; --accent:#c26a1e; --blue:#2f6fd0;
24
+ --good-soft:rgba(37,130,99,.12); --bad-soft:rgba(189,78,78,.1);
25
+ --blue-soft:rgba(47,111,208,.12); --accent-soft:rgba(194,106,30,.12);
26
+ --focus:rgba(47,111,208,.5); --focus-line:rgba(47,111,208,.45);
27
+ --code-bg:#f2f3f5; --code-line:#dfe1e6;
28
+ --shadow-1:0 2px 10px rgba(30,30,30,.1);
29
+ --shadow-2:0 12px 32px rgba(30,30,30,.18);
30
+ }
31
+
32
+ /* ===== base ===== */
33
+ * { box-sizing:border-box; }
34
+ [hidden] { display:none !important; }
35
+ body { margin:0; overflow:hidden; background:var(--page); color:var(--text);
36
+ font:13px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif; }
37
+ button, input, textarea, select { font:inherit; }
38
+ button { cursor:pointer; color:inherit; }
39
+ :focus-visible { outline:2px solid var(--focus); outline-offset:1px; }
40
+ .fin:focus-visible, .pop-search:focus-visible, .composer textarea:focus-visible { outline:none; }
41
+ .view { display:none; height:100vh; }
42
+ .view.active { display:flex; }
43
+ .view[inert] { cursor:wait; }
44
+ .view[inert] button, .view[inert] textarea { opacity:.55; }
45
+ .linklike { border:0; color:var(--blue); background:transparent; padding:0; font-size:inherit; }
46
+ .linklike:hover { text-decoration:underline; }
47
+
48
+ /* Shared micro-interaction: every flat interactive surface eases its state change. */
49
+ .session, .proj-item, .add-proj, .stab, .mgmt-item, .pop-item, .bar-btn, .ghost, .new-session,
50
+ .act-btn, .foot-btn, .io-copy, .bubble-copy, .cb-copy, .attachment-remove, .del,
51
+ .path-row .browse, .cta, .btn-allow, .btn-deny, .jump-latest, .send, .toggle-caret {
52
+ transition:background-color .12s ease, color .12s ease, border-color .12s ease, filter .12s ease, transform .06s ease;
53
+ }
54
+
55
+ /* ===== generic buttons ===== */
56
+ .ghost { display:inline-flex; align-items:center; gap:8px; height:26px; padding:0 12px;
57
+ border:0; color:var(--muted); background:transparent; font-size:12.5px; border-radius:6px; }
58
+ .ghost:hover { color:var(--text); background:var(--surface); }
59
+
60
+ /* ===== 侧栏 ===== */
61
+ .sidebar { display:flex; flex-direction:column; width:264px; flex:0 0 auto;
62
+ background:var(--side); border-right:1px solid var(--line); }
63
+ .brand { display:flex; align-items:center; justify-content:space-between; padding:16px 16px 12px; }
64
+ .brand h1 { display:flex; align-items:center; gap:8px; margin:0; font-size:15px; font-weight:700; }
65
+ .brand h1 svg.ics { width:15px; height:15px; color:var(--accent); }
66
+ .brand .ver { color:var(--faint); font-size:11px; }
67
+ .new-session { display:flex; align-items:center; gap:8px; height:30px; margin:4px 12px 8px;
68
+ padding:0 12px; border:1px solid var(--line2); border-radius:9px; color:var(--muted);
69
+ background:var(--surface); text-align:left; font-size:12.5px; }
70
+ .new-session:hover { color:var(--text); background:var(--surface2); border-color:var(--line2); }
71
+ .session-scroll { flex:1; overflow-y:auto; padding:4px 12px 12px; }
72
+ .group-label { margin:16px 4px 4px; color:var(--faint); font-size:11px; letter-spacing:.12em; text-transform:uppercase; }
73
+
74
+ /* 项目行:折叠箭头 + 名称 + 悬浮操作。激活项目以左侧主色条标记。 */
75
+ .proj-item { display:flex; align-items:center; gap:8px; width:100%; height:26px; padding:0 8px;
76
+ border:0; border-radius:6px; color:var(--text); background:transparent;
77
+ font-size:12.5px; font-weight:600; text-align:left; }
78
+ .proj-item:hover { background:var(--surface); }
79
+ .proj.active > .proj-item { background:var(--surface); box-shadow:inset 2px 0 0 var(--accent); }
80
+ .p-caret { display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px;
81
+ flex:0 0 auto; color:var(--faint); transition:transform .15s ease; }
82
+ .p-caret.closed { transform:rotate(-90deg); }
83
+ .proj-item .p-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
84
+ .toggle-caret { display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px;
85
+ flex:0 0 auto; color:inherit; transition:transform .15s ease; }
86
+ .toggle-caret.closed { transform:rotate(-90deg); }
87
+ .sess-list { padding:0 0 4px; }
88
+ .sess-list .session { padding-left:24px; }
89
+ .session { display:flex; align-items:center; gap:8px; width:100%; height:26px; padding:0 8px;
90
+ border:0; border-radius:6px; background:transparent; color:var(--muted); text-align:left; font-size:12.5px; }
91
+ .session:hover { background:var(--surface); color:var(--text); }
92
+ .session.active { background:var(--surface2); color:var(--text); box-shadow:inset 2px 0 0 var(--accent); }
93
+ .session .s-title { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
94
+ .session .when { margin-left:auto; color:var(--faint); font-size:11px; flex:0 0 auto; }
95
+ .session:hover > .when { display:none; }
96
+ .agent-badge { display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
97
+ width:18px; height:18px; border-radius:6px; color:#fff; font-size:11px; font-weight:700; }
98
+ .agent-badge.claude-code { background:#c9642d; }
99
+ .agent-badge.codex { background:#2e7d5b; }
100
+ .agent-badge.zcode { background:#6d5bd0; }
101
+ .agent-badge.opencode { background:#33739e; }
102
+ .add-proj { display:flex; align-items:center; gap:8px; width:100%; height:26px; margin:4px 0 0;
103
+ padding:0 8px; border:0; border-radius:6px; color:var(--muted); background:transparent;
104
+ font-size:12.5px; text-align:left; }
105
+ .add-proj:hover { color:var(--text); background:var(--surface); }
106
+ .proj-empty { padding:4px 8px 8px 24px; color:var(--faint); font-size:11px; }
107
+
108
+ /* 侧栏空态:SVG 图标组合的插画式提示,不依赖外部资源。 */
109
+ .side-empty { display:grid; justify-items:center; gap:4px; margin:8px 4px 12px; padding:16px 12px;
110
+ border:1px dashed var(--line2); border-radius:9px; color:var(--faint); font-size:12.5px; text-align:center; }
111
+ .side-empty-art { display:flex; align-items:center; justify-content:center; width:40px; height:40px;
112
+ border-radius:9px; background:var(--surface); color:var(--faint); }
113
+ .side-empty-sub { font-size:11px; }
114
+
115
+ .row-acts { display:none; align-items:center; gap:2px; margin-left:auto; flex:0 0 auto; }
116
+ .session:hover > .row-acts, .proj-item:hover > .row-acts { display:inline-flex; }
117
+ .act-btn { display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
118
+ padding:0; border:0; color:var(--muted); background:transparent; border-radius:6px; user-select:none; }
119
+ .act-btn:hover { color:var(--text); background:var(--surface2); }
120
+ .act-btn.danger:hover { color:var(--bad); background:var(--bad-soft); }
121
+
122
+ /* 归档区:分隔线 + 可折叠标题 + 计数徽标。 */
123
+ .arch-toggle { display:flex; align-items:center; gap:4px; width:calc(100% - 8px); margin:16px 0 4px;
124
+ padding:8px 4px 4px; border:0; border-top:1px solid var(--line); background:transparent;
125
+ color:var(--faint); font-size:11px; letter-spacing:.12em; text-transform:uppercase; text-align:left; }
126
+ .arch-toggle:hover { color:var(--muted); }
127
+ .arch-count { margin-left:4px; padding:0 4px; border-radius:99px; background:var(--surface);
128
+ color:var(--faint); font-size:11px; letter-spacing:0; }
129
+ .arch-list .session .s-title { color:var(--muted); }
130
+ .arch-list .agent-badge { opacity:.75; }
131
+ .sidebar-foot { display:flex; align-items:center; gap:8px; padding:12px 16px;
132
+ border-top:1px solid var(--line); color:var(--faint); font-size:11px; }
133
+ .sidebar-foot .ghost { padding:0 4px; }
134
+ .dot { display:inline-block; width:7px; height:7px; flex:0 0 auto; border-radius:99px; background:var(--good); }
135
+ .dot.run { animation:pulse 1.4s infinite; }
136
+ @keyframes pulse { 50% { opacity:.4; } }
137
+
138
+ /* ===== 主区 ===== */
139
+ .main { display:flex; flex-direction:column; flex:1; min-width:0; position:relative; }
140
+ .top-strip { display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:12px 24px 8px; }
141
+ .top-strip .t { font-weight:600; font-size:13px; }
142
+ .session-provider { color:var(--faint); font-size:11px; overflow:hidden; text-overflow:ellipsis;
143
+ white-space:nowrap; min-width:0; }
144
+ .top-strip .st { display:inline-flex; align-items:center; gap:8px; margin-left:auto; padding:4px 12px;
145
+ border-radius:99px; color:#9db8ff; background:var(--blue-soft); font-size:12.5px; }
146
+ body.light .top-strip .st { color:#2f5fd0; }
147
+
148
+ /* ===== 消息流(ZCode 风格:过程折叠,正文直出)===== */
149
+ .stream { flex:1; overflow-y:auto; padding:8px 24px 24px; }
150
+ .stream:focus { outline:none; }
151
+ .history-bar { max-width:860px; margin:0 auto 16px; display:flex; align-items:center; justify-content:center; gap:8px; color:var(--muted); font-size:12px; }
152
+ .history-bar[hidden], .history-bar [hidden] { display:none; }
153
+ .history-bar button:disabled { opacity:.6; cursor:wait; }
154
+ .col { max-width:860px; margin:0 auto; }
155
+ .empty-hint { text-align:center; color:var(--muted); margin-top:18vh; font-size:13px; line-height:1.7; }
156
+ .empty-hint .big { display:flex; align-items:center; justify-content:center; margin-bottom:12px; }
157
+ .hint-wrap { position:relative; display:inline-flex; }
158
+ .hint-art { display:flex; align-items:center; justify-content:center; width:56px; height:56px;
159
+ border-radius:13px; border:1px solid var(--line); background:var(--surface); color:var(--muted); }
160
+ .hint-art svg { width:24px; height:24px; }
161
+ .hint-art svg, .hint-spark svg { fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
162
+ .hint-spark { position:absolute; top:-6px; right:-8px; display:flex; align-items:center; justify-content:center;
163
+ width:20px; height:20px; border-radius:99px; background:var(--surface2); color:var(--accent); box-shadow:var(--shadow-1); }
164
+ .hint-spark svg { width:11px; height:11px; }
165
+ .empty-hint p { margin:4px 0 0; }
166
+
167
+ /* 用户消息:轻量右置色块(尾部小圆角);AI 消息:全宽白板。 */
168
+ .msg.user { display:grid; justify-items:end; margin:24px 0 12px; }
169
+ .bubble { max-width:82%; padding:8px 12px; border:1px solid var(--line); border-radius:13px 13px 4px 13px;
170
+ background:var(--surface2); color:var(--text); font-size:13px; line-height:1.65;
171
+ white-space:pre-wrap; overflow-wrap:anywhere; }
172
+ body.light .bubble { background:var(--surface); }
173
+ .msg.ai { margin:12px 0 16px; }
174
+ .msg.ai p { margin:0 0 12px; white-space:pre-wrap; overflow-wrap:anywhere; line-height:1.7; }
175
+ .msg.ai .dim { color:var(--muted); }
176
+
177
+ /* 回合折叠区:头部即计时行(工作中 X 秒 → 已工作 X 秒) */
178
+ .proc { margin:4px 0 12px; user-select:none; }
179
+ .proc > summary { display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
180
+ color:var(--muted); font-size:12.5px; padding:4px 8px; margin-left:-8px; border-radius:6px; }
181
+ .proc > summary:hover { color:var(--text); background:var(--surface); }
182
+ .proc > summary::-webkit-details-marker { display:none; }
183
+ .proc .caret { display:inline-flex; color:var(--faint); transition:transform .15s ease; }
184
+ .proc[open] > summary .caret { transform:rotate(90deg); }
185
+ .proc .p-meta { color:var(--faint); }
186
+ .proc-steps { display:grid; gap:2px; margin:2px 0 8px 16px; padding-left:12px; border-left:1px solid var(--line); }
187
+ .turn-note { display:flex; align-items:center; gap:8px; margin:4px 0 16px; color:var(--faint); font-size:12.5px; }
188
+
189
+ /* 过程行:思考分段 / 工具步骤 / 备注行 */
190
+ .think-seg { margin:4px 0 8px; }
191
+ .think-label { display:flex; align-items:center; gap:8px; color:var(--muted); font-size:12.5px; padding:2px 0; }
192
+ .t-glyph { color:var(--faint); }
193
+ .t-meta { color:var(--faint); font-size:12.5px; }
194
+ .think-body { color:var(--faint); font-size:12.5px; line-height:1.65; white-space:pre-wrap;
195
+ overflow-wrap:anywhere; margin:2px 0 4px 16px; max-height:280px; overflow-y:auto; }
196
+ .step { color:var(--muted); font-size:12.5px; }
197
+ .step > summary { display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
198
+ flex-wrap:wrap; padding:4px 0; min-width:0; }
199
+ .step > summary::-webkit-details-marker { display:none; }
200
+ .s-caret { display:inline-flex; color:var(--faint); flex:0 0 auto; transition:transform .15s ease; }
201
+ .step[open] > summary .s-caret { transform:rotate(90deg); }
202
+ .s-dot { width:8px; height:8px; flex:0 0 auto; border-radius:99px; background:var(--blue); }
203
+ .step.failed .s-dot { background:var(--bad); }
204
+ .step.note .s-dot { background:var(--faint); }
205
+ .s-name { font-weight:600; color:var(--text); font-size:12.5px; }
206
+ .s-desc { color:var(--faint); font-size:12.5px; overflow:hidden; text-overflow:ellipsis;
207
+ white-space:nowrap; min-width:0; max-width:60%; }
208
+ .s-meta { color:var(--faint); font-size:12.5px; margin-left:auto; flex:0 0 auto; }
209
+ .s-meta.failed { color:var(--bad); }
210
+ .step-body { display:grid; gap:8px; margin:2px 0 12px 16px; }
211
+ .step-line { display:flex; align-items:center; gap:8px; color:var(--faint); font-size:12.5px; padding:2px 0; }
212
+ .step-line .s-dot { width:6px; height:6px; background:var(--warn); }
213
+
214
+ /* 输入/输出卡片:语言标签 + 复制按钮 + 语法高亮 */
215
+ .io-card { border:1px solid var(--line); border-radius:9px; background:var(--surface); overflow:hidden; }
216
+ .io-head { display:flex; align-items:center; justify-content:space-between; padding:4px 4px 0 12px; }
217
+ .io-tag { display:inline-flex; align-items:center; gap:4px; color:var(--faint); font-size:11px;
218
+ letter-spacing:.05em; text-transform:uppercase; }
219
+ .io-brace { font:11px Consolas,monospace; color:var(--muted); }
220
+ .io-copy { display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
221
+ border:0; color:var(--faint); background:transparent; border-radius:6px; }
222
+ .io-copy:hover { color:var(--text); background:var(--surface2); }
223
+ .io-card pre { margin:0; padding:4px 12px 8px; color:var(--muted);
224
+ font:12.5px/1.6 Consolas,"Microsoft YaHei",monospace; white-space:pre-wrap;
225
+ overflow-wrap:anywhere; max-height:320px; overflow-y:auto; }
226
+ .j-key { color:#7aa2f7; }
227
+ .j-str { color:#9ece6a; }
228
+ .j-num { color:#e0af68; }
229
+ .j-bool { color:#bb9af7; }
230
+ body.light .j-key { color:#2f5fd0; }
231
+ body.light .j-str { color:#3a7d3a; }
232
+ body.light .j-num { color:#9d6e21; }
233
+ body.light .j-bool { color:#7a4fb3; }
234
+ .file-changes { display:grid; gap:4px; font-size:12.5px; }
235
+ .file-change { display:flex; gap:8px; align-items:baseline; min-width:0; }
236
+ .file-path { min-width:0; overflow-wrap:anywhere; }
237
+ .diff-add { color:var(--good); }
238
+ .diff-remove { color:var(--bad); }
239
+
240
+ /* 用户气泡复制按钮 */
241
+ .bubble-copy { display:inline-flex; align-items:center; justify-content:center; height:22px;
242
+ min-width:26px; margin:4px 2px 0 auto; border:0; color:var(--faint); background:transparent;
243
+ border-radius:6px; }
244
+ .bubble-copy:hover { color:var(--text); background:var(--surface2); }
245
+ .copied .ic { color:var(--good); }
246
+
247
+ /* 最终消息操作条:复制 / 重试 / 模型 · 时间 */
248
+ .msg-foot { display:flex; align-items:center; gap:2px; margin:4px 0 16px; }
249
+ .foot-btn { display:inline-flex; align-items:center; justify-content:center; width:26px; height:24px;
250
+ border:0; color:var(--faint); background:transparent; border-radius:6px; }
251
+ .foot-btn:hover { color:var(--text); background:var(--surface2); }
252
+ .foot-time { color:var(--faint); font-size:11px; margin-left:8px; }
253
+
254
+ /* 回合文件变更汇总 */
255
+ .turn-diffs { margin:4px 0 16px; }
256
+ .turn-diffs-head { display:flex; align-items:center; gap:8px; padding:2px 0 4px; }
257
+ .td-label { color:var(--muted); font-size:12.5px; font-weight:600; }
258
+ .td-count { display:inline-flex; align-items:center; gap:8px; font:11px Consolas,monospace; }
259
+ .td-approx { font-style:normal; color:var(--faint); font-size:11px; }
260
+ .turn-diffs-list { padding:0 0 0 12px; display:grid; gap:2px; }
261
+ .td-row { display:flex; gap:8px; align-items:baseline; justify-content:space-between;
262
+ font-size:12.5px; color:var(--faint); }
263
+ .td-rowcount { font:11px Consolas,monospace; color:var(--faint); flex:0 0 auto; }
264
+ .td-more { color:var(--faint); }
265
+
266
+ /* 工具行参数徽章与运行态 shimmer */
267
+ .s-args { display:inline-flex; gap:4px; }
268
+ .s-args i { font-style:normal; font:11px Consolas,"Microsoft YaHei",monospace; color:var(--faint);
269
+ background:var(--surface2); padding:1px 4px; border-radius:99px; }
270
+ .s-meta.running { background:linear-gradient(90deg, var(--faint) 25%, var(--text) 50%, var(--faint) 75%);
271
+ background-size:200% 100%; -webkit-background-clip:text; background-clip:text; color:transparent;
272
+ animation:shimmer 1.6s linear infinite; }
273
+ @keyframes shimmer { to { background-position:-200% 0; } }
274
+
275
+ /* 回到底部悬浮按钮 */
276
+ .jump-latest { position:absolute; right:24px; bottom:136px; z-index:5; display:inline-flex;
277
+ align-items:center; gap:4px; height:26px; padding:0 12px; border:1px solid var(--line2);
278
+ border-radius:99px; background:var(--pop); color:var(--muted); font-size:12.5px;
279
+ box-shadow:var(--shadow-2); }
280
+ .jump-latest:hover { color:var(--text); background:var(--surface); }
281
+
282
+ /* 助手正文 markdown */
283
+ .md-body { font-size:15px; line-height:1.7; color:#d8d8d8; overflow-wrap:anywhere; }
284
+ body.light .md-body { color:var(--text); }
285
+ .md-body.streaming::after { content:"▍"; animation:pulse 1s infinite; color:var(--text); }
286
+ .md-body p { margin:0 0 12px; white-space:pre-wrap; }
287
+ .md-body p:last-child { margin-bottom:0; }
288
+ .md-body h3, .md-body h4, .md-body h5, .md-body h6 { margin:16px 0 8px; font-size:15px; font-weight:650; }
289
+ .md-body h3 { font-size:18px; }
290
+ .md-body h5, .md-body h6 { font-weight:600; color:var(--muted); }
291
+ .md-body ul, .md-body ol { margin:0 0 12px; padding-left:24px; }
292
+ .md-body li { margin:4px 0; }
293
+ .md-body blockquote { margin:0 0 12px; padding:4px 12px; border-left:2px solid var(--line2); color:var(--muted); }
294
+ .md-body hr { border:0; border-top:1px solid var(--line); margin:16px 0; }
295
+ .md-body strong { color:var(--text); font-weight:650; }
296
+ .md-body code { padding:1px 4px; border-radius:6px; background:rgba(255,255,255,.07);
297
+ font:12.5px/1.5 Consolas,"Microsoft YaHei",monospace; }
298
+ body.light .md-body code { background:rgba(0,0,0,.06); }
299
+ .md-body a { color:var(--blue); }
300
+ .codeblock { margin:0 0 12px; border:1px solid var(--code-line); border-radius:9px;
301
+ background:var(--code-bg); overflow:hidden; }
302
+ .cb-head { display:flex; align-items:center; justify-content:space-between; padding:4px 4px 4px 12px;
303
+ border-bottom:1px solid var(--code-line); }
304
+ .cb-lang { color:var(--faint); font-size:11px; letter-spacing:.05em; text-transform:uppercase; }
305
+ .cb-copy { display:inline-flex; align-items:center; height:22px; padding:0 4px; border:0;
306
+ color:var(--muted); background:transparent; font-size:11px; border-radius:6px; }
307
+ .cb-copy:hover { color:var(--text); background:var(--surface2); }
308
+ .codeblock pre { margin:0; padding:8px 12px; overflow-x:auto; }
309
+ .codeblock code { font:12.5px/1.65 Consolas,"Microsoft YaHei",monospace; background:transparent;
310
+ padding:0; color:#cfd8ea; }
311
+ body.light .codeblock code { color:#24304a; }
312
+
313
+ /* 权限确认卡 */
314
+ .perm { display:flex; align-items:center; gap:12px; margin:16px 0; padding:12px 16px;
315
+ border:1px solid var(--line); border-radius:13px; background:var(--surface); }
316
+ .perm.settled { display:inline-flex; margin:4px 0; padding:0; background:transparent; border:0; }
317
+ .perm.settled .p-title { font-weight:400; color:var(--faint); font-size:12.5px; }
318
+ .perm.settled .p-sub, .perm.settled .p-icon { display:none; }
319
+ .perm.settled .p-state { font-size:12.5px; }
320
+ .perm .p-icon { flex:0 0 auto; color:var(--warn); display:inline-flex; }
321
+ .perm .p-body { flex:1; min-width:0; }
322
+ .perm .p-title { font-size:13px; font-weight:600; }
323
+ .perm .p-sub { margin-top:2px; color:var(--muted); font-size:11px; font-family:Consolas,monospace; overflow-wrap:anywhere; }
324
+ .perm .p-actions { display:flex; gap:8px; }
325
+ .perm .btn-allow { height:30px; padding:0 16px; border:0; border-radius:9px; color:#161616;
326
+ background:var(--accent); font-weight:650; font-size:12.5px; }
327
+ .perm .btn-allow:hover { filter:brightness(1.08); }
328
+ body.light .perm .btn-allow { color:#fff; }
329
+ .perm .btn-deny { height:30px; padding:0 12px; border:0; border-radius:9px; color:var(--muted);
330
+ background:transparent; font-size:12.5px; }
331
+ .perm .btn-deny:hover { color:var(--bad); }
332
+ .perm .p-state { color:var(--muted); font-size:12.5px; }
333
+ .perm .p-state.no { color:var(--bad); }
334
+ .perm.question-card { display:block; padding:16px; color:var(--text); }
335
+ .question-title { font-size:14px; font-weight:600; margin-bottom:12px; }
336
+ .question-fields { max-height: min(52vh, 460px); overflow:auto; overscroll-behavior:contain; }
337
+ .question-field { min-width:0; margin:0 0 16px; padding:0; border:0; }
338
+ .question-field legend { font-size:14px; line-height:1.6; margin:0 0 10px; padding:0; overflow-wrap:anywhere; }
339
+ .question-option { display:flex; gap:10px; align-items:flex-start; padding:10px; margin:6px 0; border:1px solid var(--line); border-radius:10px; cursor:pointer; }
340
+ .question-option:has(input:checked) { border-color:var(--accent); background:var(--surface2); }
341
+ .question-option input { flex:0 0 auto; width:16px; height:16px; margin:3px 0; accent-color:var(--accent); }
342
+ .question-option-copy { min-width:0; display:grid; gap:3px; overflow-wrap:anywhere; }
343
+ .question-option-label { font-size:14px; line-height:1.5; }
344
+ .question-option-description { font-size:12px; color:var(--muted); line-height:1.5; }
345
+ .question-custom { box-sizing:border-box; width:100%; margin-top:6px; padding:10px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:inherit; font:inherit; font-size:14px; }
346
+ .question-footer { display:flex; justify-content:space-between; align-items:center; gap:10px; font-size:12px; color:var(--muted); }
347
+ .question-error { font-size:12px; color:var(--bad); margin-bottom:8px; }
348
+ .question-submit:disabled { opacity:.45; cursor:default; }
349
+ .question-settled .question-title { margin:0; font-size:12px; font-weight:400; color:var(--muted); }
350
+
351
+ /* 附件托盘:缩略图统一 48px,移除按钮悬浮于角标 */
352
+ .attach-tray { display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; margin:-8px 0 12px; }
353
+ .attach-tray img { width:48px; height:48px; object-fit:cover; display:block;
354
+ border-radius:9px; border:1px solid var(--line); }
355
+ .attachment-item { position:relative; display:flex; align-items:center; gap:4px; max-width:100%; }
356
+ .attachment-file { display:inline-flex; align-items:center; gap:4px; max-width:100%; padding:4px 8px;
357
+ border:1px solid var(--line); border-radius:9px; background:var(--surface);
358
+ color:var(--muted); font-size:12.5px; overflow-wrap:anywhere; }
359
+ .attachment-remove { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px;
360
+ border:0; border-radius:99px; background:transparent; color:var(--muted); }
361
+ .attachment-item.img .attachment-remove { position:absolute; top:-6px; right:-6px;
362
+ background:var(--surface2); box-shadow:var(--shadow-1); z-index:1; }
363
+ .attachment-remove:hover { color:var(--bad); background:var(--surface2); }
364
+ .composer .attach-tray { justify-content:flex-start; margin:0 0 8px; }
365
+
366
+ /* ===== 底部输入容器 ===== */
367
+ .composer-wrap { padding:8px 24px 16px; }
368
+ .composer { max-width:860px; margin:0 auto; border-radius:13px; background:var(--surface);
369
+ border:1px solid var(--line); padding:12px 12px 8px;
370
+ transition:border-color .15s ease, box-shadow .15s ease; }
371
+ .composer:focus-within { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
372
+ .composer textarea { width:100%; min-height:22px; max-height:150px; padding:2px 2px 8px; border:0;
373
+ color:var(--text); background:transparent; resize:none; outline:none; font:13px/1.6 inherit; }
374
+ .composer textarea::placeholder { color:var(--faint); }
375
+ .cmdrow { display:flex; align-items:center; gap:4px; }
376
+ .bar-btn { display:inline-flex; align-items:center; gap:4px; height:26px; padding:0 8px;
377
+ border:0; border-radius:6px; color:var(--muted); background:transparent;
378
+ font-size:12.5px; white-space:nowrap; }
379
+ .bar-btn:hover { background:var(--surface2); color:var(--text); }
380
+ .bar-btn .chev { display:inline-flex; color:var(--faint); }
381
+ #model-label { max-width:min(34vw,330px); overflow:hidden; text-overflow:ellipsis; }
382
+ .bar-btn.plus .ic { width:15px; height:15px; }
383
+ .bar-btn.mode { color:var(--text); }
384
+ .bar-btn.mode .shield { display:inline-flex; filter:grayscale(1); opacity:.85; }
385
+ .bar-btn.mode.accent { color:var(--accent); }
386
+ .bar-btn.mode.accent .shield { filter:none; opacity:1; }
387
+ .cmd-spacer { flex:1; }
388
+ .ring { display:inline-block; width:13px; height:13px; flex:0 0 auto; margin:0 8px 0 0;
389
+ border:2px solid var(--faint); border-top-color:var(--text); border-right-color:var(--text);
390
+ border-radius:50%; transform:rotate(-35deg); animation:spin 1s linear infinite; }
391
+ .ctx-mini { position:relative; width:54px; height:4px; margin:0 2px; border-radius:99px;
392
+ background:var(--surface2); overflow:hidden; }
393
+ .ctx-mini i { position:absolute; top:0; bottom:0; left:0; border-radius:99px;
394
+ background:linear-gradient(90deg, var(--good), var(--warn)); }
395
+ @keyframes spin { to { transform:rotate(325deg); } }
396
+ .send { display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px;
397
+ border:0; border-radius:99px; background:var(--accent); }
398
+ .send:hover { filter:brightness(1.1); }
399
+ .send:active { transform:scale(.94); }
400
+ .send .up, .send .sq { color:#161616; }
401
+ .send .up { display:inline-flex; align-items:center; justify-content:center; }
402
+ .send .sq { width:10px; height:10px; border-radius:2px; background:#161616; }
403
+ body.light .send .up { color:#fff; }
404
+ body.light .send .sq { background:#fff; }
405
+
406
+ /* ===== 弹出层 ===== */
407
+ .anchor { position:relative; display:inline-flex; }
408
+ .pop { position:absolute; bottom:calc(100% + 8px); z-index:40; min-width:240px; padding:4px;
409
+ border-radius:13px; background:var(--pop); border:1px solid var(--line2);
410
+ box-shadow:var(--shadow-2); animation:pop-in .12s ease; }
411
+ .pop[hidden] { display:none; }
412
+ .pop.from-left { left:0; } .pop.from-right { right:0; }
413
+ .pop-group { display:flex; align-items:center; gap:8px; padding:8px 8px 4px; color:var(--muted); font-size:12.5px; }
414
+ .tag { display:inline-flex; align-items:center; padding:1px 8px; border-radius:6px;
415
+ background:var(--surface2); color:var(--muted); font-size:11px; }
416
+ .pop-item { display:flex; align-items:center; gap:8px; width:100%; padding:4px 8px; border:0;
417
+ border-radius:6px; color:var(--text); background:transparent; font-size:13px; text-align:left; }
418
+ .pop-item:hover:not(:disabled) { background:var(--surface2); }
419
+ .pop-item:disabled { opacity:.4; cursor:not-allowed; }
420
+ /* Whole menu scrolls as one — no nested inner scrollbar. */
421
+ #pop-model { max-height:min(560px,76vh); max-width:min(480px,90vw); overflow:auto; }
422
+ .pop-item .grow { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
423
+ .pop-item .check { display:inline-flex; color:var(--blue); visibility:hidden; }
424
+ .pop-item.selected .check { visibility:visible; }
425
+ .pop-item.selected .grow { font-weight:600; }
426
+ .pop-item.muted { color:var(--muted); }
427
+ .pop-sep { height:1px; margin:4px; background:var(--line); }
428
+ .ctx-pop { width:360px; padding:16px; }
429
+ .ctx-head { display:flex; justify-content:space-between; align-items:center; font-size:12.5px; }
430
+ .ctx-head .num { color:var(--muted); }
431
+ .bar { height:5px; margin:8px 0 12px; border-radius:99px; background:var(--surface2); overflow:hidden; }
432
+ .bar > i { display:block; height:100%; border-radius:99px; background:var(--blue); }
433
+ .ctx-row { display:flex; justify-content:space-between; padding:4px 0; color:var(--muted); font-size:12.5px; }
434
+ .ctx-sep { height:1px; margin:8px 0; background:var(--line); }
435
+
436
+ /* ===== 设置页 ===== */
437
+ .settings-wrap { display:flex; flex:1; min-width:0; }
438
+ .settings-nav { width:190px; flex:0 0 auto; padding:16px 8px; border-right:1px solid var(--line); }
439
+ .settings-nav strong { display:block; padding:0 12px 12px; font-size:13px; }
440
+ .settings-back { margin:0 0 12px; padding-left:0; }
441
+ .stab { width:100%; height:30px; margin:1px 0; padding:0 12px; border:0; border-radius:6px;
442
+ color:var(--muted); background:transparent; text-align:left; font-size:12.5px; }
443
+ .stab:hover { color:var(--text); background:var(--surface); }
444
+ .stab.active { color:var(--text); background:var(--surface2); box-shadow:inset 2px 0 0 var(--accent); }
445
+ .settings-body { flex:1; overflow-y:auto; padding:24px; }
446
+ .settings-body h2 { margin:0 0 4px; font-size:18px; }
447
+ .settings-body .sub { margin:0 0 24px; color:var(--muted); font-size:12.5px; }
448
+ .spanel { display:none; } .spanel.active { display:block; }
449
+ .prov-cols { display:grid; grid-template-columns:210px minmax(0,1fr); gap:12px; align-items:start; }
450
+ .mgmt-side { padding:8px; border-radius:13px; background:var(--surface); border:1px solid var(--line); }
451
+ .mgmt-group { padding:8px 8px 4px; color:var(--faint); font-size:11px; }
452
+ .mgmt-item { display:flex; align-items:center; gap:8px; width:100%; height:30px; padding:0 8px;
453
+ border:0; border-radius:6px; color:var(--text); background:transparent; font-size:13px; text-align:left; }
454
+ .mgmt-item:hover { background:var(--surface2); }
455
+ .mgmt-item.active { background:var(--surface2); }
456
+ .mgmt-item .grow { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
457
+ .mgmt-item .dot { width:6px; height:6px; }
458
+ .mgmt-item .dot.off { background:var(--faint); }
459
+ .mgmt-detail { min-height:380px; padding:24px; border-radius:13px; background:var(--surface);
460
+ border:1px solid var(--line); }
461
+ .empty-models { padding:24px 0; color:var(--faint); font-size:12.5px; text-align:center; }
462
+ .pd { display:none; } .pd.active { display:block; }
463
+ .pd-head { display:flex; align-items:center; gap:8px; }
464
+ .pd-head h3 { margin:0; font-size:15px; }
465
+ .status-chip { display:inline-flex; align-items:center; height:22px; padding:0 12px; border-radius:99px;
466
+ font-size:11px; color:var(--good); background:var(--good-soft); }
467
+ .status-chip.off { color:var(--muted); background:var(--surface2); }
468
+ .pd-head .sp { flex:1; }
469
+ .pd-head .del { display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px;
470
+ border:0; border-radius:6px; color:var(--muted); background:transparent; }
471
+ .pd-head .del:hover { color:var(--bad); background:var(--bad-soft); }
472
+ .f { display:grid; gap:8px; margin-top:16px; }
473
+ .f > label { color:var(--text); font-size:12.5px; }
474
+ .field-note { color:var(--muted); font-size:11px; }
475
+ .fin { width:100%; height:36px; padding:0 12px; border:1px solid var(--line2); border-radius:9px;
476
+ color:var(--text); background:var(--page); font-size:13px; outline:none;
477
+ transition:border-color .12s ease, box-shadow .12s ease; }
478
+ .fin:focus { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
479
+ .fin::placeholder { color:var(--faint); }
480
+ .key-row { position:relative; }
481
+ .key-row .fin { padding-right:42px; }
482
+ .eye { position:absolute; right:4px; top:50%; transform:translateY(-50%); display:inline-flex;
483
+ align-items:center; justify-content:center; width:26px; height:26px; border:0; border-radius:6px;
484
+ color:var(--muted); background:transparent; }
485
+ .eye:hover { color:var(--text); background:var(--surface2); }
486
+ .pd-foot { display:flex; align-items:center; gap:8px; margin-top:24px; }
487
+ .pd-foot .note { flex:1; display:flex; align-items:center; gap:8px; color:var(--muted); font-size:12.5px; }
488
+ .cta { height:30px; padding:0 16px; border:0; border-radius:9px; color:#161616;
489
+ background:var(--accent); font-weight:650; font-size:12.5px; }
490
+ .cta:hover { filter:brightness(1.08); }
491
+ body.light .cta { color:#fff; }
492
+ .cta[disabled] { opacity:.45; cursor:not-allowed; filter:none; }
493
+ .agent-card { display:flex; align-items:flex-start; gap:12px; margin-bottom:12px; padding:16px;
494
+ border-radius:13px; background:var(--surface); border:1px solid var(--line); }
495
+ .agent-card.missing { opacity:.55; }
496
+ .agent-card .agent-badge { width:22px; height:22px; font-size:11px; }
497
+ .agent-card .a-body { flex:1; min-width:0; }
498
+ .agent-card .a-name { display:flex; align-items:center; gap:8px; font-weight:650; font-size:13px; }
499
+ .agent-card .a-meta { margin-top:4px; color:var(--muted); font-size:11px; }
500
+ .cap-chips { display:flex; flex-wrap:wrap; gap:4px; margin-top:8px; }
501
+ .chip { display:inline-flex; align-items:center; padding:1px 8px; border-radius:99px;
502
+ background:var(--surface2); color:var(--muted); font-size:11px; }
503
+ .chip.good { color:var(--good); background:var(--good-soft); }
504
+ .cap-chips .chip.off { color:var(--faint); opacity:.6; }
505
+ .auth-note { margin:16px 0 0; padding:2px 0 2px 16px; border-left:2px solid var(--line2);
506
+ color:var(--muted); font-size:12.5px; }
507
+
508
+ /* ===== 弹窗 / 提示 ===== */
509
+ .modal { position:fixed; inset:0; z-index:70; display:none; align-items:center; justify-content:center;
510
+ background:rgba(0,0,0,.55); }
511
+ .modal.open { display:flex; animation:fade-in .12s ease; }
512
+ body.light .modal { background:rgba(20,20,20,.35); }
513
+ .modal-box { width:min(470px,92vw); border-radius:13px; background:var(--pop);
514
+ border:1px solid var(--line2); padding:24px; box-shadow:var(--shadow-2); }
515
+ .modal.open .modal-box { animation:modal-in .14s cubic-bezier(.2,.9,.3,1); }
516
+ .modal-box h3 { margin:0 0 4px; font-size:15px; }
517
+ .modal-box .sub { margin:0 0 16px; color:var(--muted); font-size:12.5px; }
518
+ .modal-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:24px; }
519
+ .form-error { margin-top:12px; padding:8px 12px; border-radius:9px; color:var(--bad);
520
+ background:var(--bad-soft); font-size:12.5px; border:1px solid rgba(240,128,128,.2); }
521
+ body.light .form-error { border-color:rgba(189,78,78,.2); }
522
+ /* 添加项目弹窗:路径输入 + 系统浏览按钮同行 */
523
+ .path-row { display:flex; gap:8px; align-items:stretch; }
524
+ .path-row .fin { flex:1; min-width:0; width:auto; }
525
+ .path-row .browse { flex:0 0 auto; display:inline-flex; align-items:center; height:36px; padding:0 12px;
526
+ border:1px solid var(--line2); border-radius:9px; }
527
+ .path-row .browse:hover { background:var(--surface); border-color:var(--faint); }
528
+ .path-row .browse:disabled { opacity:.45; cursor:not-allowed; }
529
+
530
+ /* Toast:类型化配色 + 图标,底部居中堆叠,进入/退出动画。 */
531
+ .toast-host { position:fixed; bottom:24px; left:0; right:0; z-index:90; display:flex;
532
+ flex-direction:column; align-items:center; gap:8px; pointer-events:none; }
533
+ .toast { pointer-events:auto; display:flex; align-items:center; gap:8px; max-width:min(480px,90vw);
534
+ padding:8px 16px; border-radius:9px; border:1px solid var(--line2); background:var(--pop);
535
+ color:var(--text); font-size:12.5px; box-shadow:var(--shadow-2); animation:toast-in .16s ease; }
536
+ .toast .ic { color:var(--muted); }
537
+ .toast.good .ic { color:var(--good); }
538
+ .toast.bad .ic { color:var(--bad); }
539
+ .toast.leaving { animation:toast-out .15s ease forwards; }
540
+
541
+ .pop-search { width:100%; height:30px; padding:0 8px; margin-bottom:4px; border:1px solid var(--line2);
542
+ border-radius:6px; color:var(--text); background:var(--page); font-size:12.5px; outline:none;
543
+ transition:border-color .12s ease, box-shadow .12s ease; }
544
+ .pop-search:focus { border-color:var(--focus-line); box-shadow:0 0 0 3px var(--blue-soft); }
545
+
546
+ /* Themed scrollbars: slim rounded thumb, no track chrome or arrow buttons. */
547
+ * { scrollbar-width: thin; scrollbar-color: #3f3f3f transparent; }
548
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
549
+ ::-webkit-scrollbar-track { background: transparent; }
550
+ ::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
551
+ ::-webkit-scrollbar-thumb { background: #3f3f3f; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
552
+ ::-webkit-scrollbar-thumb:hover { background: #525252; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
553
+ ::-webkit-scrollbar-corner { background: transparent; }
554
+ body.light * { scrollbar-color: #c4c4c4 transparent; }
555
+ body.light ::-webkit-scrollbar-thumb { background: #c4c4c4; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
556
+ body.light ::-webkit-scrollbar-thumb:hover { background: #adadad; border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
557
+ .f[hidden] { display:none; }
558
+
559
+ /* ===================== icon system & runtime polish ===================== */
560
+ .ic { display:inline-flex; flex:0 0 auto; vertical-align:-2px; color:inherit; }
561
+ .ic svg, svg.ics { width:100%; height:100%; fill:none; stroke:currentColor; stroke-width:1.8;
562
+ stroke-linecap:round; stroke-linejoin:round; }
563
+ svg.ics { width:13px; height:13px; flex:0 0 auto; }
564
+ #open-settings, #btn-rescan { display:inline-flex; align-items:center; }
565
+
566
+ /* Thinking hint: shown while the driver streams nothing yet (reasoning phase). */
567
+ .think-hint { display:flex; align-items:center; gap:8px; margin:12px 2px; color:var(--muted); font-size:12.5px; }
568
+
569
+ /* Unified error row replaces the bare ⚠ paragraph. */
570
+ .msg.ai.error { display:flex; gap:8px; align-items:flex-start; margin:16px 0; padding:8px 12px;
571
+ border:1px solid rgba(255,96,96,.3); background:var(--bad-soft); border-radius:9px;
572
+ color:#ff9c9c; font-size:13px; line-height:1.5; }
573
+ .msg.ai.error .ic { margin-top:2px; }
574
+ body.light .msg.ai.error { color:#b42318; border-color:rgba(180,35,24,.25); background:rgba(180,35,24,.05); }
575
+
576
+ /* Gentle reveal when a fold opens; hover feedback on rows. */
577
+ .proc[open] > .proc-steps, .step[open] > .step-body { animation:fade-in .18s ease; }
578
+ @keyframes fade-in { from { opacity:0; transform:translateY(-3px); } }
579
+ @keyframes pop-in { from { opacity:0; transform:translateY(4px); } }
580
+ @keyframes modal-in { from { opacity:0; transform:translateY(6px) scale(.985); } }
581
+ @keyframes toast-in { from { opacity:0; transform:translateY(8px); } }
582
+ @keyframes toast-out { to { opacity:0; transform:translateY(6px); } }
583
+
584
+ @media (prefers-reduced-motion: reduce) {
585
+ *, *::before, *::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
586
+ }
587
+
588
+ /* ===== embed 模式(被知识库壳嵌入):折叠左侧项目栏,由壳 postMessage 控制 ===== */
589
+ body.embed-collapse .sidebar { display: none; }
590
+
591
+ /* Embedded product tokens are owned by the shell; standalone styling stays. */
592
+ body.kb-embedded.light {
593
+ --page:#ffffff; --side:#f8f9fb; --surface:#f3f5f7; --surface2:#edf1f4;
594
+ --line:#dce2e8; --line2:#dce2e8; --pop:#ffffff;
595
+ --text:#202733; --muted:#687587; --faint:#8e99a7;
596
+ --good:#397761; --bad:#a05252; --blue:#516f89; --blue-soft:#e6edf3;
597
+ --code-bg:#f3f5f7; --code-line:#dce2e8;
598
+ }
599
+ body.kb-embedded:not(.light) {
600
+ --page:#20252d; --side:#1b2028; --surface:#252b34; --surface2:#2c333e;
601
+ --line:#39424f; --line2:#39424f; --pop:#252b34;
602
+ --text:#e6ebf0; --muted:#a0aaba; --faint:#788393; --blue:#8aa8cf; --blue-soft:#293748;
603
+ --good:#81b29a; --bad:#d88b8b; --code-bg:#252b34; --code-line:#39424f;
604
+ }
605
+ body.kb-embedded { --accent:var(--blue); --accent-soft:var(--blue-soft); }
606
+ body.kb-embedded .agent-badge { background:var(--blue); }
607
+ body.kb-embedded .sidebar { display:flex; width:208px; min-width:208px; border-right:1px solid var(--line); }
608
+ body.kb-embedded .brand, body.kb-embedded .group-label, body.kb-embedded .add-proj,
609
+ body.kb-embedded .proj-item .row-acts, body.kb-embedded .sidebar-foot, body.kb-embedded #btn-top-settings { display:none; }
610
+ body.kb-embedded .new-session { margin:16px 16px 8px; }
611
+ body.kb-embedded .hint-spark, body.kb-embedded .hint-art { display:none; }
612
+ body.kb-embedded .empty-hint .big { display:none; }
613
+ .embedded-hint { display:none; }
614
+ body.kb-embedded .standalone-hint { display:none; }
615
+ body.kb-embedded .embedded-hint { display:block; }
616
+ body.kb-embedded .cmdrow { min-width:0; }
617
+ body.kb-embedded .cmdrow > .bar-btn, body.kb-embedded .send { flex-shrink:0; }
618
+ body.kb-embedded .cmdrow > .anchor { flex:0 0 auto; }
619
+ body.kb-embedded .cmdrow > .model-anchor { flex:0 1 auto; min-width:0; }
620
+ body.kb-embedded #btn-model { min-width:0; max-width:100%; }
621
+ body.kb-embedded #model-label { display:block; min-width:0; max-width:100%; }
622
+ body.kb-embedded #btn-ctx .ctx-mini { display:none; }
623
+ body.kb-embedded .ctx-mini i { background:var(--blue); }
624
+ /* Task state comes from SDK notifications and persists independently of turns. */
625
+ .background-tasks { padding: 12px 0; }
626
+ .background-tasks[hidden] { display: none; }
627
+ .background-tasks .task-card { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: 8px 0; }
628
+ .background-tasks .task-detail { white-space: pre-wrap; overflow-wrap: anywhere; opacity: .8; font-size: 12px; margin-top: 6px; }
629
+ .background-tasks { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 8px; max-height: 180px; overflow: auto; }
630
+ .background-tasks > strong { grid-column: 1 / -1; color: var(--muted); font-size: 11px; }
631
+ .background-tasks .task-card { margin: 0; padding: 8px 10px; font-size: 12px; }
632
+ .background-tasks .task-detail { max-height: 3.2em; overflow: auto; }
633
+ .task-count { font-size: 11px; color: var(--accent); }
634
+
635
+ /* Shared chat density in the main conversation and side workspace. */
636
+ .main, .right-dock { font-size:14px; line-height:1.65; }
637
+ .main .msg, .right-dock .msg, .main .bubble, .right-dock .bubble { font-size:14px; }
638
+ .main .col { max-width:760px; }
639
+ .main .composer, .right-dock .composer { border-radius:16px; }
640
+ .main .composer textarea, .right-dock .composer textarea { font-size:14px; min-height:48px; }
641
+ .main .composer:focus-within, .right-dock .composer:focus-within { box-shadow:none; border-color:var(--line); }
642
+ .main .bubble, .right-dock .bubble { border-color:transparent; background:var(--surface); }
643
+ .main .composer-wrap { padding:12px 24px 20px; }
644
+ .background-tasks { display:block; max-height:none; overflow:visible; padding:8px 0; }
645
+ .background-tasks .task-row { display:flex; align-items:center; gap:10px; width:100%; border:0; border-radius:0; background:transparent; color:var(--text); text-align:left; padding:10px 0; margin:0; font-size:14px; }
646
+ .task-row-title { flex:1; font-weight:400; overflow-wrap:anywhere; }
647
+ .task-row-title { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
648
+ .main .send:not(.stop), .right-dock .send:not(.stop) { background:var(--text); color:var(--page); }
649
+ .task-row-status { flex:0 0 auto; font-size:12px; color:var(--muted); }
650
+ .task-row:hover .task-row-title { text-decoration:underline; text-underline-offset:3px; }
651
+ .task-row > .ic:last-child { transform:rotate(180deg); color:var(--muted); }
652
+ .main .step, .right-dock .step, .main .msg-foot, .right-dock .msg-foot { font-size:12px; }