codebee 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +392 -0
  3. package/app/__init__.py +0 -0
  4. package/app/core/__init__.py +0 -0
  5. package/app/core/attachments.py +322 -0
  6. package/app/core/automation.py +585 -0
  7. package/app/core/bookmeta.py +296 -0
  8. package/app/core/capability.py +130 -0
  9. package/app/core/catalog.py +319 -0
  10. package/app/core/compaction.py +186 -0
  11. package/app/core/diagnostics.py +115 -0
  12. package/app/core/env_scrub.py +84 -0
  13. package/app/core/error_codes.py +65 -0
  14. package/app/core/flows.py +328 -0
  15. package/app/core/gitmod.py +949 -0
  16. package/app/core/goal_service.py +159 -0
  17. package/app/core/health.py +294 -0
  18. package/app/core/history.py +32 -0
  19. package/app/core/jobs.py +424 -0
  20. package/app/core/manager.py +1415 -0
  21. package/app/core/market.py +299 -0
  22. package/app/core/market_remote.py +896 -0
  23. package/app/core/mocks.py +64 -0
  24. package/app/core/modelhub.py +2750 -0
  25. package/app/core/paths.py +60 -0
  26. package/app/core/pipeline.py +2161 -0
  27. package/app/core/planner.py +493 -0
  28. package/app/core/registry.py +105 -0
  29. package/app/core/remote.py +303 -0
  30. package/app/core/repeat_guard.py +124 -0
  31. package/app/core/router.py +120 -0
  32. package/app/core/runner.py +856 -0
  33. package/app/core/selfupdate.py +170 -0
  34. package/app/core/session_log.py +162 -0
  35. package/app/core/sessions.py +312 -0
  36. package/app/core/settings.py +85 -0
  37. package/app/core/settings_schema.py +250 -0
  38. package/app/core/skillpacks/fanqie-novel.md +80 -0
  39. package/app/core/skillpacks/market/character-bible.md +66 -0
  40. package/app/core/skillpacks/market/code-risk-checklist.md +58 -0
  41. package/app/core/skillpacks/market/git-workflow.md +57 -0
  42. package/app/core/skillpacks/market/release-notes.md +72 -0
  43. package/app/core/skillpacks/market/weekly-report.md +71 -0
  44. package/app/core/skillpacks/market/worldview-consistency.md +70 -0
  45. package/app/core/skillpacks/qimao-signing.md +105 -0
  46. package/app/core/skills.py +649 -0
  47. package/app/core/step_runner.py +61 -0
  48. package/app/core/store.py +1321 -0
  49. package/app/core/token_meter.py +130 -0
  50. package/app/core/usage.py +450 -0
  51. package/app/main.py +1448 -0
  52. package/app/ui/app.js +8021 -0
  53. package/app/ui/i18n.js +1709 -0
  54. package/app/ui/icons/brand-horizontal.png +0 -0
  55. package/app/ui/icons/brand-square.png +0 -0
  56. package/app/ui/icons/icon-192.png +0 -0
  57. package/app/ui/icons/icon-512.png +0 -0
  58. package/app/ui/icons/logo-horizontal.png +0 -0
  59. package/app/ui/icons/logo-mark.png +0 -0
  60. package/app/ui/index.html +864 -0
  61. package/app/ui/manifest.json +16 -0
  62. package/app/ui/qrcode.js +2297 -0
  63. package/app/ui/style.css +2733 -0
  64. package/bin/tutti.js +121 -0
  65. package/package.json +39 -0
@@ -0,0 +1,2733 @@
1
+ /* CodeBee UI —— ChatGPT 风格:左侧栏 + 居中主栏 + 卡片化内容,零依赖 */
2
+ :root {
3
+ --bg: #212121;
4
+ --sidebar: #171717;
5
+ --panel: #2f2f2f;
6
+ --panel2: #3a3a3a;
7
+ --border: rgba(255, 255, 255, .09);
8
+ --border-strong: rgba(255, 255, 255, .18);
9
+ --text: #ececec;
10
+ --muted: #a6a6a6;
11
+ --accent: #5b8cff;
12
+ --accent2: #8b5cf6;
13
+ --ok: #34c98e;
14
+ --warn: #f5b942;
15
+ --bad: #f0566a;
16
+ --chip-queued-bg: #3a3a3a;
17
+ --log-bg: #161616;
18
+ --log-text: #c3c9d6;
19
+ --shadow: 0 10px 30px rgba(0, 0, 0, .35);
20
+ --mono: "Cascadia Code", Consolas, monospace;
21
+ --r-lg: 16px;
22
+ --r-md: 12px;
23
+ --r-sm: 8px;
24
+ /* 用量图表三色:输入 / 缓存·其他 / 输出 —— 蓝→青→淡紫同类色,饱和度明度对齐 */
25
+ --uc-in: #6e9bff;
26
+ --uc-ca: #3fd0bb;
27
+ --uc-out: #b79bff;
28
+ }
29
+ html[data-theme="light"] {
30
+ --bg: #ffffff;
31
+ --sidebar: #f9f9f9;
32
+ --panel: #ffffff;
33
+ --panel2: #f4f4f5;
34
+ --border: #e5e5e5;
35
+ --border-strong: #cfcfcf;
36
+ --text: #0d0d0d;
37
+ --muted: #8f8f8f;
38
+ --accent: #3a6ee8;
39
+ --accent2: #8250e8;
40
+ --ok: #0f9d6c;
41
+ --warn: #b07d18;
42
+ --bad: #d63c55;
43
+ --chip-queued-bg: #ececee;
44
+ --log-bg: #f6f6f7;
45
+ --log-text: #3a4050;
46
+ --shadow: 0 10px 30px rgba(0, 0, 0, .06);
47
+ --uc-in: #3567e0;
48
+ --uc-ca: #0fa592;
49
+ --uc-out: #8a55ee;
50
+ }
51
+
52
+ /* ================= 皮肤(换肤) =================
53
+ * 一套皮肤 = 一份完整调色板,各含「夜间 / 日间」两版,都由上面同一组变量描述,
54
+ * 所以换肤只是换变量值,布局与组件样式一律不动。
55
+ * 上面的 :root 就是默认皮肤「经典」的夜间版,html[data-theme="light"] 是它的日间版——
56
+ * 因此 data-skin="classic"(或皮肤值缺失/非法)时无需任何规则,自然回落到经典。
57
+ * 约定:每个皮肤块必须写全同一组变量(含各自的日间版),漏写会让日间版落到夜间值上。
58
+ * 生效优先级:html[data-skin=X][data-theme=light](0,2,1)> html[data-skin=X] 与
59
+ * html[data-theme=light](均 0,1,1,后者在文件里靠前,同权重下被皮肤块覆盖)。 */
60
+ html[data-skin="ocean"] {
61
+ --bg: #0e1626;
62
+ --sidebar: #0a111e;
63
+ --panel: #17243a;
64
+ --panel2: #21304a;
65
+ --border: rgba(255, 255, 255, .10);
66
+ --border-strong: rgba(255, 255, 255, .20);
67
+ --text: #e7eefb;
68
+ --muted: #93a6c4;
69
+ --accent: #3ba9f5;
70
+ --accent2: #6d6cf6;
71
+ --ok: #35c99b;
72
+ --warn: #f0b429;
73
+ --bad: #f2637a;
74
+ --chip-queued-bg: #21304a;
75
+ --log-bg: #08101c;
76
+ --log-text: #bccbe4;
77
+ --shadow: 0 10px 30px rgba(0, 0, 0, .45);
78
+ --uc-in: #3ba9f5;
79
+ --uc-ca: #6d6cf6;
80
+ --uc-out: #35c99b;
81
+ }
82
+ html[data-skin="ocean"][data-theme="light"] {
83
+ --bg: #ffffff;
84
+ --sidebar: #eff5fd;
85
+ --panel: #ffffff;
86
+ --panel2: #f0f6fd;
87
+ --border: #d7e3f4;
88
+ --border-strong: #b9cde8;
89
+ --text: #0c1a2c;
90
+ --muted: #5d7290;
91
+ --accent: #1f6fd0;
92
+ --accent2: #5b4fe0;
93
+ --ok: #0d9a72;
94
+ --warn: #a9761a;
95
+ --bad: #d23c58;
96
+ --chip-queued-bg: #f0f6fd;
97
+ --log-bg: #f4f8fe;
98
+ --log-text: #33475f;
99
+ --shadow: 0 10px 30px rgba(0, 0, 0, .07);
100
+ --uc-in: #1f6fd0;
101
+ --uc-ca: #5b4fe0;
102
+ --uc-out: #0d9a72;
103
+ }
104
+ html[data-skin="forest"] {
105
+ --bg: #141d18;
106
+ --sidebar: #0f1613;
107
+ --panel: #1d2a23;
108
+ --panel2: #26362d;
109
+ --border: rgba(255, 255, 255, .09);
110
+ --border-strong: rgba(255, 255, 255, .18);
111
+ --text: #e6f1ea;
112
+ --muted: #94ac9e;
113
+ --accent: #35c98c;
114
+ --accent2: #2bbfa8;
115
+ --ok: #35c98c;
116
+ --warn: #e5b154;
117
+ --bad: #ef6a6a;
118
+ --chip-queued-bg: #26362d;
119
+ --log-bg: #0b1310;
120
+ --log-text: #b9cfc2;
121
+ --shadow: 0 10px 30px rgba(0, 0, 0, .42);
122
+ --uc-in: #35c98c;
123
+ --uc-ca: #2bbfa8;
124
+ --uc-out: #35c98c;
125
+ }
126
+ html[data-skin="forest"][data-theme="light"] {
127
+ --bg: #ffffff;
128
+ --sidebar: #eef6f1;
129
+ --panel: #ffffff;
130
+ --panel2: #eff7f2;
131
+ --border: #d6e7dd;
132
+ --border-strong: #b9d4c5;
133
+ --text: #10201a;
134
+ --muted: #5b7266;
135
+ --accent: #0e8f61;
136
+ --accent2: #0d8577;
137
+ --ok: #0e8f61;
138
+ --warn: #9c6d12;
139
+ --bad: #cc3f4d;
140
+ --chip-queued-bg: #eff7f2;
141
+ --log-bg: #f2f8f4;
142
+ --log-text: #33463c;
143
+ --shadow: 0 10px 30px rgba(0, 0, 0, .07);
144
+ --uc-in: #0e8f61;
145
+ --uc-ca: #0d8577;
146
+ --uc-out: #0e8f61;
147
+ }
148
+ html[data-skin="amber"] {
149
+ --bg: #1e1915;
150
+ --sidebar: #171310;
151
+ --panel: #2a231d;
152
+ --panel2: #362c23;
153
+ --border: rgba(255, 255, 255, .09);
154
+ --border-strong: rgba(255, 255, 255, .18);
155
+ --text: #f2e9dd;
156
+ --muted: #b5a390;
157
+ --accent: #e79a2b;
158
+ --accent2: #e2703f;
159
+ --ok: #3fbf8a;
160
+ --warn: #e8b44a;
161
+ --bad: #ea6262;
162
+ --chip-queued-bg: #362c23;
163
+ --log-bg: #15110d;
164
+ --log-text: #dccfbe;
165
+ --shadow: 0 10px 30px rgba(0, 0, 0, .42);
166
+ --uc-in: #e79a2b;
167
+ --uc-ca: #e2703f;
168
+ --uc-out: #3fbf8a;
169
+ }
170
+ html[data-skin="amber"][data-theme="light"] {
171
+ --bg: #ffffff;
172
+ --sidebar: #faf3e9;
173
+ --panel: #ffffff;
174
+ --panel2: #fbf3e8;
175
+ --border: #ebdfcd;
176
+ --border-strong: #d6c3a6;
177
+ --text: #241b12;
178
+ --muted: #7c6952;
179
+ --accent: #b96a12;
180
+ --accent2: #b8542c;
181
+ --ok: #0e8f61;
182
+ --warn: #96650c;
183
+ --bad: #c93b45;
184
+ --chip-queued-bg: #fbf3e8;
185
+ --log-bg: #fdf7ef;
186
+ --log-text: #4a3c2e;
187
+ --shadow: 0 10px 30px rgba(0, 0, 0, .07);
188
+ --uc-in: #b96a12;
189
+ --uc-ca: #b8542c;
190
+ --uc-out: #0e8f61;
191
+ }
192
+ html[data-skin="violet"] {
193
+ --bg: #16121e;
194
+ --sidebar: #110d18;
195
+ --panel: #221b30;
196
+ --panel2: #2e2440;
197
+ --border: rgba(255, 255, 255, .10);
198
+ --border-strong: rgba(255, 255, 255, .20);
199
+ --text: #efe8fa;
200
+ --muted: #a99cc2;
201
+ --accent: #a86cf5;
202
+ --accent2: #ec4f95;
203
+ --ok: #35c99b;
204
+ --warn: #f0b429;
205
+ --bad: #f2637a;
206
+ --chip-queued-bg: #2e2440;
207
+ --log-bg: #0d0913;
208
+ --log-text: #ccc0e2;
209
+ --shadow: 0 10px 30px rgba(0, 0, 0, .46);
210
+ --uc-in: #a86cf5;
211
+ --uc-ca: #ec4f95;
212
+ --uc-out: #35c99b;
213
+ }
214
+ html[data-skin="violet"][data-theme="light"] {
215
+ --bg: #ffffff;
216
+ --sidebar: #f5eefd;
217
+ --panel: #ffffff;
218
+ --panel2: #f6effd;
219
+ --border: #e5d9f6;
220
+ --border-strong: #cdb9ea;
221
+ --text: #1c1230;
222
+ --muted: #6d6090;
223
+ --accent: #7b3ce0;
224
+ --accent2: #c92c74;
225
+ --ok: #0d9a72;
226
+ --warn: #9c6d12;
227
+ --bad: #cc3f4d;
228
+ --chip-queued-bg: #f6effd;
229
+ --log-bg: #f9f4fe;
230
+ --log-text: #3d3352;
231
+ --shadow: 0 10px 30px rgba(0, 0, 0, .07);
232
+ --uc-in: #7b3ce0;
233
+ --uc-ca: #c92c74;
234
+ --uc-out: #0d9a72;
235
+ }
236
+ /* 高对比:纯黑/纯白 + 硬边框 + 去阴影,弱视与强光环境下更清晰 */
237
+ html[data-skin="contrast"] {
238
+ --bg: #000000;
239
+ --sidebar: #000000;
240
+ --panel: #0b0b0b;
241
+ --panel2: #1c1c1c;
242
+ --border: #6f6f6f;
243
+ --border-strong: #c9c9c9;
244
+ --text: #ffffff;
245
+ --muted: #dcdcdc;
246
+ --accent: #4da3ff;
247
+ --accent2: #ff9d4d;
248
+ --ok: #23d18b;
249
+ --warn: #ffc21a;
250
+ --bad: #ff5d5d;
251
+ --chip-queued-bg: #1c1c1c;
252
+ --log-bg: #000000;
253
+ --log-text: #f2f2f2;
254
+ --shadow: none;
255
+ --uc-in: #4da3ff;
256
+ --uc-ca: #ff9d4d;
257
+ --uc-out: #23d18b;
258
+ }
259
+ html[data-skin="contrast"][data-theme="light"] {
260
+ --bg: #ffffff;
261
+ --sidebar: #ffffff;
262
+ --panel: #ffffff;
263
+ --panel2: #f0f0f0;
264
+ --border: #767676;
265
+ --border-strong: #000000;
266
+ --text: #000000;
267
+ --muted: #4a4a4a;
268
+ --accent: #0b52c9;
269
+ --accent2: #b03000;
270
+ --ok: #05703f;
271
+ --warn: #7a5200;
272
+ --bad: #b3001b;
273
+ --chip-queued-bg: #f0f0f0;
274
+ --log-bg: #ffffff;
275
+ --log-text: #000000;
276
+ --shadow: none;
277
+ --uc-in: #0b52c9;
278
+ --uc-ca: #b03000;
279
+ --uc-out: #05703f;
280
+ }
281
+ * { box-sizing: border-box; }
282
+ html, body { height: 100%; }
283
+ body {
284
+ margin: 0; background: var(--bg); color: var(--text);
285
+ font: 14px/1.65 "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
286
+ transition: background-color .2s, color .2s;
287
+ }
288
+ *::-webkit-scrollbar { width: 9px; height: 9px; }
289
+ *::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 5px; }
290
+ *::-webkit-scrollbar-track { background: transparent; }
291
+
292
+ /* ---------------- 布局骨架 ---------------- */
293
+ #app { display: grid; grid-template-columns: 264px 1fr; height: 100vh; }
294
+ body.side-collapsed #app { grid-template-columns: 0 1fr; }
295
+ #mainwrap { display: flex; flex-direction: column; min-width: 0; height: 100vh; }
296
+
297
+ /* ---------------- 侧栏 ---------------- */
298
+ #sidebar {
299
+ display: flex; flex-direction: column;
300
+ background: var(--sidebar); border-right: 1px solid var(--border);
301
+ padding: 14px 12px 12px; min-width: 0; overflow: hidden;
302
+ transition: opacity .15s;
303
+ }
304
+ body.side-collapsed #sidebar { border-right: none; padding-left: 0; padding-right: 0; opacity: 0; pointer-events: none; }
305
+ /* 品牌:方形字母标磁贴 + 字标,单行位于侧栏最顶上 */
306
+ .brand { display: flex; align-items: center; gap: 10px; font-size: 15.5px; font-weight: 700; padding: 6px 8px 12px; white-space: nowrap; overflow: hidden; }
307
+ /* 品牌:Codex 式低调字标——纯正文色小字,无磁贴无渐变(2026-09-15 参考 Codex 桌面端定版) */
308
+ .brand-name { font-size: 15px; font-weight: 700; letter-spacing: .01em; color: var(--text); }
309
+ .new-task {
310
+ display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
311
+ background: none; border: none; color: var(--text);
312
+ border-radius: 8px; padding: 8px 10px; font-size: 13.5px; cursor: pointer; margin-bottom: 2px;
313
+ }
314
+ .new-task:hover { background: var(--panel2); }
315
+ .new-task .nt-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
316
+ /* 图标精灵:统一线性图标(stroke=currentColor,跟随主题与 hover 变色) */
317
+ #icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
318
+ .ico {
319
+ width: 16px; height: 16px; flex: none;
320
+ fill: none; stroke: currentColor; stroke-width: 1.7;
321
+ stroke-linecap: round; stroke-linejoin: round;
322
+ vertical-align: -3px;
323
+ }
324
+ .ico-lg { width: 19px; height: 19px; stroke-width: 1.6; }
325
+
326
+ .side-foot {
327
+ display: flex; align-items: center; gap: 4px;
328
+ border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px;
329
+ }
330
+ /* 左下角常驻图标入口:设置 / 手机连接(ZCode 桌面端式样,不展开菜单) */
331
+ .foot-btn {
332
+ display: flex; align-items: center; justify-content: center;
333
+ width: 34px; height: 34px; flex: none;
334
+ background: none; border: none; color: var(--muted);
335
+ border-radius: 8px; cursor: pointer; padding: 0; font-family: inherit;
336
+ transition: background-color .15s, color .15s;
337
+ }
338
+ .foot-btn:hover { color: var(--text); background: var(--panel2); }
339
+ .foot-btn:active { transform: scale(.94); }
340
+ /* 左下角中间:编排者供应商指示(夹在设置与手机连接两个图标按钮之间,占满剩余宽度) */
341
+ .foot-prov {
342
+ flex: 1; min-width: 0;
343
+ display: flex; align-items: center; gap: 6px;
344
+ height: 34px; padding: 0 8px;
345
+ background: none; border: none; color: var(--muted);
346
+ border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 12.5px;
347
+ transition: background-color .15s, color .15s;
348
+ }
349
+ .foot-prov:hover { color: var(--text); background: var(--panel2); }
350
+ .foot-prov:active { transform: scale(.97); }
351
+ .foot-prov .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
352
+ /* 状态点:灰=未选、绿=生效中、黄=已选但不生效(缺密钥/停用/无模型) */
353
+ .pdot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--muted); }
354
+ .pdot.ok { background: var(--ok); }
355
+ .pdot.warn { background: var(--warn); }
356
+ .side-section { display: flex; flex-direction: column; min-height: 0; flex: 1; margin-top: 14px; }
357
+ .side-section.tasks { flex: 1; }
358
+ .side-label { color: var(--muted); font-size: 11px; padding: 0 10px 6px; letter-spacing: .05em; }
359
+
360
+ /* 任务列表:文件夹 → 任务单行(ZCode 桌面端式样)——
361
+ * 任务行 = 状态字形 + 单行省略标题 + 徽章 + 右对齐紧凑时间,整行即按钮:
362
+ * 点击右缘滑出「任务详情」(无内嵌步骤层,步骤明细看任务详情页) */
363
+ .side-tasks { display: flex; flex-direction: column; gap: 1px; overflow-y: auto; min-height: 0; flex: 1; padding: 0 2px; }
364
+ .stask {
365
+ display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px;
366
+ cursor: pointer; color: var(--text); font-size: 13px; user-select: none;
367
+ }
368
+ .stask:hover { background: var(--panel2); }
369
+ .stask.active { background: var(--panel2); }
370
+ .stask:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
371
+ .stask .t { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
372
+ .stask .tm { flex: none; color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
373
+ /* 状态字形:进行中旋转✻ / 完成绿点 / 失败红点 / 取消橙点 / 排队空圈 / 未运行暗点 */
374
+ /* 闸门等待徽章(任务分支待裁决)+ 侧栏铃铛开关 */
375
+ .sbadge {
376
+ flex: none; font-size: 10.5px; line-height: 1; padding: 2.5px 6px;
377
+ border-radius: 999px; color: var(--warn);
378
+ background: color-mix(in srgb, var(--warn) 14%, transparent);
379
+ animation: sbadge-pulse 2s ease-in-out infinite;
380
+ }
381
+ @keyframes sbadge-pulse { 50% { opacity: .55; } }
382
+ /* 「任务」区头:标签靠左,右侧三颗小工具钮(展开/归档/提示音)收拢成一组 */
383
+ .side-label-row { display: flex; align-items: center; gap: 2px; margin-bottom: 6px; }
384
+ .side-label-row .side-label { margin-right: auto; padding: 0 0 0 10px; line-height: 24px; }
385
+ .side-label-row .foot-btn { width: 24px; height: 24px; border-radius: 6px; }
386
+ .notify-toggle { padding: 0; }
387
+ .notify-toggle .ico { width: 14px; height: 14px; }
388
+ .notify-toggle.off .ico { opacity: .35; }
389
+ .notify-toggle.off:hover .ico { opacity: .6; }
390
+ /* 展开全部:文件夹全开时箭头翻转成收起朝向,点下去语义一致 */
391
+ #btn-side-expand .ico { transition: transform .15s ease; }
392
+ #btn-side-expand.up .ico { transform: rotate(180deg); }
393
+ .sglyph { width: 9px; height: 9px; flex: none; border-radius: 50%; }
394
+ .sglyph.ok { background: var(--ok); }
395
+ .sglyph.bad { background: var(--bad); }
396
+ .sglyph.warn { background: var(--warn); }
397
+ .sglyph.ring { box-sizing: border-box; background: none; border: 1.5px solid var(--muted); }
398
+ .sglyph.none { background: var(--border); }
399
+ .sglyph.ast {
400
+ width: 12px; height: 12px; border-radius: 0; background: none;
401
+ color: var(--text); font-size: 11px; line-height: 12px; text-align: center;
402
+ animation: ico-spin 1.2s linear infinite;
403
+ }
404
+ /* 步骤状态点:检查器「步骤」页签复用(侧栏已无内嵌步骤层) */
405
+ .sdot { width: 5px; height: 5px; border-radius: 50%; flex: none; background: var(--muted); align-self: center; }
406
+ .sdot.done { background: var(--ok); }
407
+ .sdot.failed { background: var(--bad); }
408
+ .sdot.cancelled { background: var(--warn); }
409
+ .sdot.running { background: var(--accent); animation: pulse 1.2s ease-in-out infinite; }
410
+ .side-empty { color: var(--muted); font-size: 12px; padding: 4px 10px; }
411
+
412
+ /* 一级文件夹行(工作目录):折叠箭头 + 目录图标 + 末段名 + 任务计数徽标;
413
+ * 二级任务行整体缩进进 dirbody,沿用 .stask 原有式样 */
414
+ .sdir summary {
415
+ display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-radius: 8px;
416
+ cursor: pointer; color: var(--muted); font-size: 12px; font-weight: 600;
417
+ list-style: none; user-select: none;
418
+ }
419
+ .sdir summary::-webkit-details-marker { display: none; }
420
+ .sdir summary:hover { background: var(--panel2); color: var(--text); }
421
+ .sdir .chev {
422
+ width: 11px; height: 11px; flex: none; color: var(--muted);
423
+ fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
424
+ transition: transform .15s ease;
425
+ }
426
+ .sdir[open] > summary .chev { transform: rotate(90deg); }
427
+ .sdir .fico {
428
+ width: 13px; height: 13px; flex: none; color: var(--muted);
429
+ fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
430
+ }
431
+ .sdir summary .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
432
+ .sdir summary .cnt {
433
+ flex: none; color: var(--muted); font-size: 10.5px; line-height: 16px; padding: 0 6px;
434
+ background: var(--panel2); border-radius: 999px; font-variant-numeric: tabular-nums;
435
+ }
436
+ .sdir > .dirbody { margin: 1px 0 6px 12px; padding-left: 6px; border-left: 1px solid var(--border); }
437
+
438
+ /* ---------------- 右键菜单 ---------------- */
439
+ .ctx-menu {
440
+ position: fixed; z-index: 100; min-width: 150px; padding: 5px;
441
+ background: var(--panel); border: 1px solid var(--border-strong);
442
+ border-radius: 10px; box-shadow: var(--shadow);
443
+ }
444
+ .ctx-item {
445
+ display: flex; align-items: center; gap: 8px; padding: 7px 12px;
446
+ border-radius: 7px; font-size: 13px; color: var(--text); cursor: pointer;
447
+ }
448
+ .ctx-item:hover { background: var(--panel2); }
449
+ .ctx-item.danger { color: var(--bad); }
450
+ .ctx-sep { height: 1px; background: var(--border); margin: 4px 6px; }
451
+ .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); }
452
+ .dot.running { background: var(--accent); animation: pulse 1.2s ease-in-out infinite; }
453
+ .dot.done { background: var(--ok); }
454
+ .dot.failed { background: var(--bad); }
455
+ .dot.cancelled { background: var(--warn); }
456
+ @keyframes pulse { 50% { opacity: .35; } }
457
+
458
+ /* ---------------- 顶栏 ---------------- */
459
+ .topbar {
460
+ display: flex; align-items: center; gap: 12px;
461
+ padding: 12px 24px; border-bottom: 1px solid var(--border);
462
+ background: var(--bg); position: sticky; top: 0; z-index: 10;
463
+ }
464
+ .page-title { font-size: 15.5px; font-weight: 700; letter-spacing: .01em; }
465
+ .icon-btn {
466
+ background: none; border: none; color: var(--muted); font-size: 16px;
467
+ width: 32px; height: 32px; border-radius: 8px; cursor: pointer; line-height: 1;
468
+ display: inline-flex; align-items: center; justify-content: center;
469
+ padding: 0; font-family: inherit; transition: background-color .15s, color .15s;
470
+ }
471
+ .icon-btn:hover { background: var(--panel2); color: var(--text); }
472
+ .icon-btn:active { transform: scale(.94); }
473
+ /* 图标按钮的加载态:图标自旋(不要用 textContent 改文案,会抹掉 SVG 图标) */
474
+ .icon-btn.loading { color: var(--accent); }
475
+ .icon-btn.loading .ico { animation: ico-spin .9s linear infinite; }
476
+ @keyframes ico-spin { to { transform: rotate(360deg); } }
477
+ @media (prefers-reduced-motion: reduce) {
478
+ .icon-btn.loading .ico { animation: none; }
479
+ }
480
+ /* 面板标题里的纯图标按钮(如用量页刷新)比顶栏略小 */
481
+ .panel-head .icon-btn { width: 28px; height: 28px; }
482
+
483
+ /* 顶栏右上角:当前模型胶囊 + 主题 + 连接状态 */
484
+ .top-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; min-width: 0; }
485
+ .pill {
486
+ display: inline-flex; align-items: center; gap: 6px; max-width: 280px;
487
+ background: var(--panel2); color: var(--text); border: 1px solid var(--border);
488
+ border-radius: 999px; padding: 5px 14px; font-size: 12.5px; cursor: pointer;
489
+ white-space: nowrap; font-family: inherit;
490
+ transition: border-color .15s, background-color .15s;
491
+ }
492
+ .pill:hover { border-color: var(--border-strong); }
493
+ .pill > span { overflow: hidden; text-overflow: ellipsis; }
494
+ /* 纯图标胶囊(顶栏皮肤 / 明暗切换):去掉文字后收紧内边距,保持圆形观感 */
495
+ .pill.icon-only { padding: 5px 9px; gap: 0; }
496
+ .top-actions .conn { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
497
+ .top-actions .conn::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
498
+ .top-actions .conn.ok::before { background: var(--ok); }
499
+ .top-actions .conn.bad::before { background: var(--bad); }
500
+
501
+ /* 设置页:内容铺满(导航在左栏,见 .side-settings) */
502
+ #page-settings { max-width: none; }
503
+ .subpage { display: flex; flex-direction: column; gap: 20px; }
504
+
505
+ /* 左栏的「设置」导航(设置模式下替换任务树) */
506
+ .side-main { display: flex; flex-direction: column; flex: 1; min-height: 0; }
507
+ .side-settings { display: none; flex-direction: column; flex: 1; min-height: 0; gap: 2px; overflow-y: auto; }
508
+ body.settings-mode .side-main { display: none; }
509
+ body.settings-mode .side-settings { display: flex; }
510
+ .set-back {
511
+ display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
512
+ background: none; border: none; color: var(--muted); padding: 8px 10px;
513
+ border-radius: 8px; cursor: pointer; font-size: 13.5px; font-family: inherit; margin-bottom: 10px;
514
+ transition: background-color .15s, color .15s;
515
+ }
516
+ .set-back:hover { color: var(--text); background: var(--panel2); }
517
+ .side-settings .set-group { color: var(--muted); font-size: 11px; padding: 12px 10px 4px; letter-spacing: .05em; }
518
+ .side-settings .set-group:first-of-type { padding-top: 2px; }
519
+ .side-settings .set-item {
520
+ display: flex; align-items: center; gap: 9px; text-align: left;
521
+ background: none; border: none; color: var(--muted); padding: 8px 10px;
522
+ border-radius: 8px; cursor: pointer; font-size: 13.5px; width: 100%; font-family: inherit;
523
+ transition: background-color .15s, color .15s;
524
+ }
525
+ .side-settings .set-item:hover { color: var(--text); background: var(--panel2); }
526
+ .side-settings .set-item.active { color: var(--text); background: var(--panel2); font-weight: 600; }
527
+ /* 选中项图标转强调色(图标列与文字列严格对齐,不靠 emoji 宽度撑开) */
528
+ .side-settings .set-item.active .ico { color: var(--accent); }
529
+ .side-settings .set-item .ico, .set-back .ico { opacity: .9; }
530
+
531
+ /* ---------------- 主栏 ---------------- */
532
+ main { flex: 1; overflow-y: auto; padding: 28px 32px 96px; }
533
+ .page { display: flex; flex-direction: column; gap: 20px; max-width: min(1440px, 100%); margin: 0 auto; align-items: stretch; }
534
+ .page.hidden, .hidden { display: none !important; }
535
+ .panel {
536
+ background: var(--panel); border: 1px solid var(--border);
537
+ border-radius: var(--r-lg); padding: 20px 24px;
538
+ }
539
+ .panel.wide { width: 100%; }
540
+ /* 主栏页面级容器(.panel.wide:任务/记录/详情/设置子页/自动化/用量…全部 16 处)
541
+ * 统一无框化:内容直接落在背景上,靠 panel-head 分隔线分节;
542
+ * 内部小卡片(.mgmt-panel/.opanel/.cards 卡片等)不受影响,仍保留边框 */
543
+ main .panel.wide { background: transparent; border: none; box-shadow: none; }
544
+ .panel-head {
545
+ display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
546
+ margin: 0 0 16px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
547
+ }
548
+ .panel-head h2 { margin: 0; }
549
+ .panel-head .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
550
+ h2 { font-size: 15.5px; margin: 0 0 12px; font-weight: 700; }
551
+ h3 { font-size: 13px; margin: 18px 0 8px; color: var(--muted); }
552
+ /* 面板内分节标题:小号大写字距 + 贯穿分隔线 */
553
+ h3.sec-title, .sec-title {
554
+ display: flex; align-items: center; gap: 10px;
555
+ font-size: 12px; font-weight: 700; letter-spacing: .08em;
556
+ color: var(--muted); margin: 24px 0 12px; text-transform: uppercase;
557
+ }
558
+ h3.sec-title::after, .sec-title::after { content: ""; flex: 1; height: 1px; background: var(--border); }
559
+ h3.sec-title:first-child, .sec-title:first-child { margin-top: 0; }
560
+ #rd-plan .sec-title { margin-top: 0; }
561
+ .hint { color: var(--muted); font-size: 12.5px; }
562
+ code { font-family: var(--mono); background: var(--panel2); padding: 1px 6px; border-radius: 5px; font-size: 12px; }
563
+
564
+ /* ---------------- 新任务(composer) ---------------- */
565
+ /* 无框化由上方 main .panel.wide 统一负责,这里只管内边距 */
566
+ .composer { padding: 26px 28px 22px; }
567
+ .hero { font-size: 23px; font-weight: 700; margin: 0 0 4px; letter-spacing: -.01em; }
568
+ .hero-sub { margin: 0 0 20px; }
569
+
570
+ /* ---------------- 表单 ---------------- */
571
+ .form { display: flex; flex-direction: column; gap: 14px; }
572
+ .field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
573
+ /* label 等高(min-height 对齐内嵌 small 按钮的高度):否则「类型」行嵌了管理
574
+ * 按钮、「继续会话」行是纯文本,grid-2 两列的控件会错位几像素 */
575
+ .field > label {
576
+ font-size: 12.5px; font-weight: 600; color: var(--muted);
577
+ display: flex; align-items: center; gap: 6px; min-height: 26px;
578
+ }
579
+ .field > label button { padding: 3px 10px; font-size: 11.5px; border-radius: 8px; flex: none; }
580
+ .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
581
+
582
+ /* 文件夹选择弹框(服务端目录浏览,仅本机) */
583
+ .pk-tools { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
584
+ .pk-path {
585
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
586
+ font-size: 12px; color: var(--muted); padding: 0 2px;
587
+ }
588
+ .pk-list { display: flex; flex-direction: column; gap: 1px; max-height: 46vh; overflow-y: auto; }
589
+ .pk-row {
590
+ display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px;
591
+ cursor: pointer; transition: background-color .1s;
592
+ }
593
+ .pk-row:hover { background: var(--panel2); }
594
+ .pk-row .ico { width: 15px; height: 15px; color: var(--muted); flex: none; }
595
+ .pk-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
596
+ .pk-empty { padding: 18px 4px; text-align: center; }
597
+
598
+ .grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
599
+ .form-actions { display: flex; align-items: center; gap: 12px; margin-top: 4px; flex-wrap: wrap; }
600
+ .input-row { display: flex; gap: 8px; }
601
+ .input-row select { flex: 1; min-width: 0; width: auto; }
602
+ .input-row > button { flex: none; }.input-row input { flex: 1; min-width: 0; }
603
+ input, select, textarea {
604
+ width: 100%; background: var(--panel2); color: var(--text);
605
+ border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px;
606
+ font: inherit; outline: none;
607
+ transition: border-color .15s, background-color .15s;
608
+ }
609
+ input[type="checkbox"], input[type="radio"] { width: auto; }
610
+ select { cursor: pointer; }
611
+ textarea { resize: vertical; line-height: 1.55; }
612
+ input:hover, select:hover, textarea:hover { border-color: var(--border-strong); }
613
+ input:focus, select:focus, textarea:focus { border-color: var(--accent); }
614
+ .msg { font-size: 12.5px; color: var(--muted); }
615
+ .msg.err { color: var(--bad); }
616
+ .msg.ok { color: var(--ok, #4ade80); }
617
+ details#f-advanced { margin-top: 2px; border-top: 1px solid var(--border); padding-top: 14px; }
618
+ details#f-advanced summary {
619
+ cursor: pointer; color: var(--muted); font-size: 13px; user-select: none;
620
+ list-style: none; display: flex; align-items: center; gap: 6px;
621
+ }
622
+ details#f-advanced summary::-webkit-details-marker { display: none; }
623
+ details#f-advanced summary::before { content: "▸"; font-size: 11px; transition: transform .15s; }
624
+ details#f-advanced[open] summary::before { transform: rotate(90deg); }
625
+ details#f-advanced[open] summary { margin-bottom: 14px; }
626
+ .adv-body { display: flex; flex-direction: column; gap: 14px; }
627
+
628
+ /* ---------------- 按钮 ---------------- */
629
+ button { white-space: nowrap; } /* 中文短标签(如「保存」)不得被挤成竖排 */
630
+ button.primary {
631
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
632
+ color: #fff; border: none; border-radius: 10px; padding: 9px 22px;
633
+ font-size: 14px; font-weight: 600; cursor: pointer;
634
+ }
635
+ button.primary:hover { filter: brightness(1.08); }
636
+ /* 带 SVG 图标的文字按钮:图标与文字同一基线、间距统一(图标仍随 currentColor 变色) */
637
+ button.primary:has(> .ico), button.ghost:has(> .ico) {
638
+ display: inline-flex; align-items: center; gap: 6px;
639
+ }
640
+ button.primary > .ico, button.ghost > .ico { vertical-align: 0; }
641
+ button.ghost {
642
+ background: none; color: var(--text); border: 1px solid var(--border-strong);
643
+ border-radius: 9px; padding: 6px 13px; cursor: pointer; font-size: 12.5px;
644
+ }
645
+ button.ghost:hover { background: var(--panel2); }
646
+ button.danger {
647
+ background: none; color: var(--bad); border: 1px solid var(--bad);
648
+ border-radius: 9px; padding: 6px 13px; cursor: pointer; font-size: 12.5px;
649
+ }
650
+ button.danger:hover { background: color-mix(in srgb, var(--bad) 12%, transparent); }
651
+ button:disabled { opacity: .45; cursor: not-allowed; }
652
+ button.small { padding: 4px 10px; font-size: 12px; }
653
+
654
+ /* ---------------- 列表 & 徽标 ---------------- */
655
+ .list { display: flex; flex-direction: column; gap: 10px; }
656
+ .item {
657
+ border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 16px;
658
+ cursor: pointer; transition: border-color .15s, background-color .15s;
659
+ }
660
+ .item:hover { border-color: var(--border-strong); background: var(--panel2); }
661
+ .item .t { display: flex; align-items: center; gap: 10px; }
662
+ .item .name { font-weight: 600; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
663
+ .item .time { color: var(--muted); font-size: 12px; font-family: var(--mono); flex: none; }
664
+ .item .desc { color: var(--muted); font-size: 12.5px; margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
665
+ .item button { flex: none; }
666
+ .item .rcheck { flex: none; accent-color: var(--accent); cursor: pointer; }
667
+ .item .rcheck:disabled { opacity: .35; cursor: not-allowed; }
668
+ .run-tools {
669
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
670
+ font-size: 12px; color: var(--muted);
671
+ }
672
+
673
+ .empty {
674
+ padding: 26px 16px; text-align: center; color: var(--muted); font-size: 13px;
675
+ border: 1px dashed var(--border-strong); border-radius: var(--r-md);
676
+ }
677
+
678
+ .chip { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; flex: none; }
679
+ .chip.queued { background: var(--chip-queued-bg); color: var(--muted); }
680
+ .chip.running { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
681
+ .chip.done { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
682
+ .chip.failed { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
683
+ .chip.cancelled { background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); }
684
+
685
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; }
686
+ .chips label {
687
+ display: flex; align-items: center; gap: 5px; background: var(--panel2);
688
+ border: 1px solid transparent; border-radius: 999px; padding: 4px 12px;
689
+ color: var(--text); cursor: pointer; font-size: 12px;
690
+ }
691
+ .chips label:hover { border-color: var(--border-strong); }
692
+ .chips input { accent-color: var(--accent); }
693
+
694
+ /* ---------------- 任务附件(截图/文件)---------------- */
695
+ .att-strip { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
696
+ .att-hint { font-size: 12px; color: var(--muted); }
697
+ .att-chips { display: flex; flex-wrap: wrap; gap: 6px; }
698
+ .att-chip {
699
+ display: inline-flex; align-items: center; gap: 6px; max-width: 260px;
700
+ background: var(--panel2); border: 1px solid var(--border);
701
+ border-radius: 999px; padding: 3px 10px; font-size: 12px; color: var(--text);
702
+ }
703
+ .att-chip .ico { width: 12px; height: 12px; flex: none; }
704
+ .att-chip i { font-style: normal; color: var(--muted); flex: none; }
705
+ .att-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
706
+ .att-chip .ax {
707
+ border: none; background: none; color: var(--muted); cursor: pointer;
708
+ padding: 0 1px; display: inline-flex;
709
+ }
710
+ .att-chip .ax:hover { color: var(--bad); }
711
+
712
+ /* ---------------- 运行详情 ---------------- */
713
+ .detail-head {
714
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
715
+ padding-bottom: 12px; border-bottom: 1px solid var(--border); margin-bottom: 14px;
716
+ }
717
+ .detail-head h2 { flex: 1; margin: 0; min-width: 200px; font-size: 16px; }
718
+ .stats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
719
+ .stat {
720
+ background: var(--panel2); border: 1px solid var(--border); border-radius: 8px;
721
+ padding: 4px 12px; font-size: 12px; color: var(--muted);
722
+ }
723
+ .stat b { color: var(--text); font-weight: 600; font-family: var(--mono); font-size: 12px; }
724
+ .stat.err { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); background: color-mix(in srgb, var(--bad) 8%, transparent); }
725
+ .route { margin-top: 10px; font-size: 12px; color: var(--muted); }
726
+ .route b { color: var(--text); }
727
+
728
+ .steps { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
729
+ .step {
730
+ display: grid; grid-template-columns: 30px 92px 118px 1fr auto auto;
731
+ align-items: center; gap: 12px;
732
+ background: var(--panel2); border: 1px solid transparent; border-radius: var(--r-md);
733
+ padding: 10px 14px; cursor: pointer; font-size: 13px;
734
+ transition: border-color .15s;
735
+ }
736
+ .step:hover { border-color: var(--border-strong); }
737
+ .step .n {
738
+ width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center;
739
+ background: var(--panel); border: 1px solid var(--border);
740
+ font-family: var(--mono); font-size: 11px; color: var(--muted);
741
+ }
742
+ .step .role { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
743
+ .step .who { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
744
+ .step .sum { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
745
+ .step .dur { color: var(--muted); font-size: 12px; font-family: var(--mono); }
746
+ /* 编排计划(只读,无日志可点) */
747
+ .step.plan { grid-template-columns: 30px 180px 1fr; cursor: default; }
748
+ .step.plan .role { color: var(--text); }
749
+ #rd-plan {
750
+ background: var(--panel); border: 1px dashed var(--border-strong);
751
+ border-radius: var(--r-md); padding: 14px 18px 6px; margin-bottom: 16px;
752
+ }
753
+
754
+ .logbox {
755
+ background: var(--log-bg); border: 1px solid var(--border); border-radius: var(--r-md);
756
+ padding: 14px; margin-bottom: 16px; max-height: 380px; overflow: auto;
757
+ }
758
+ .logbox pre { margin: 0; font-family: var(--mono); font-size: 12px; line-height: 1.6; white-space: pre-wrap; word-break: break-all; color: var(--log-text); }
759
+ /* 日志状态条:● 实时(呼吸点)/ 已结束,右边最后刷新时间——内容没变也能证明通道活着 */
760
+ .log-live-bar {
761
+ position: sticky; top: -14px; z-index: 2; display: flex; align-items: center; gap: 10px;
762
+ margin: -14px -14px 8px; padding: 6px 14px;
763
+ background: color-mix(in srgb, var(--log-bg) 92%, transparent);
764
+ border-bottom: 1px solid var(--border); backdrop-filter: blur(4px);
765
+ font-size: 11.5px;
766
+ }
767
+ .log-live { color: var(--muted); font-weight: 600; }
768
+ .log-live.on { color: var(--ok); }
769
+ @keyframes log-dot-blink { 50% { opacity: .35; } }
770
+ .log-live.on { animation: log-dot-blink 1.6s ease-in-out infinite; }
771
+ .log-at { color: var(--muted); font-family: var(--mono); font-size: 11px; }
772
+ .log-live-bar .spacer { flex: 1; }
773
+ .log-live-bar .hint { color: var(--muted); font-size: 11px; }
774
+
775
+ /* ---------------- 报告(Markdown 正文排版) ---------------- */
776
+ .report { border: 1px solid var(--border); border-radius: var(--r-md); padding: 6px 24px 14px; }
777
+ .report h1 { font-size: 19px; margin: 16px 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
778
+ .report h2 { font-size: 16px; margin: 20px 0 8px; }
779
+ .report h3, .report h4, .report h5 { font-size: 14px; margin: 14px 0 6px; }
780
+ .report p { margin: 8px 0; }
781
+ .report ul { margin: 8px 0; padding-left: 22px; }
782
+ .report li { margin: 3px 0; }
783
+ .report table { border-collapse: collapse; margin: 10px 0; width: 100%; }
784
+ .report th, .report td { border: 1px solid var(--border); padding: 6px 12px; font-size: 13px; text-align: left; vertical-align: top; }
785
+ .report th { background: var(--panel2); font-weight: 600; }
786
+ .report code { background: var(--log-bg); }
787
+ .report pre { background: var(--log-bg); padding: 12px 14px; border-radius: var(--r-sm); overflow: auto; font-size: 12.5px; line-height: 1.6; }
788
+ .report pre code { background: none; padding: 0; }
789
+
790
+ /* ---------------- 卡片(智能体/模型) ---------------- */
791
+ .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 14px; margin-bottom: 10px; }
792
+ .card { border: 1px solid var(--border); border-radius: 14px; padding: 16px; transition: border-color .15s; }
793
+ .card:hover { border-color: var(--border-strong); }
794
+ .card .head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
795
+ .card .head .danger { flex: none; }
796
+ .card .name { font-weight: 700; font-size: 15px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
797
+ .card .note { color: var(--muted); font-size: 12.5px; margin-bottom: 10px; }
798
+ .card .facts { font-size: 12px; color: var(--muted); margin-bottom: 10px; word-break: break-all; line-height: 1.7; }
799
+ .card .facts b { color: var(--text); font-weight: 600; }
800
+ .card .ops { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 4px; }
801
+ /* 编排设置(#orch-config 挂在 panel 下、不在 .card 里):操作行没有 .card .ops 可用,
802
+ * 裸 .ops 会塌成默认行内布局——开关/按钮/结果消息不居中、无间距、基线错位 */
803
+ #orch-config .ops { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin-top: 14px; }
804
+ #orch-config { margin-top: 14px; }
805
+ /* 运行设置:两个 .field 直接挂在 panel 下,块级兄弟之间没有间距会贴在一起 */
806
+ #sub-orch > .panel > .field { margin-top: 16px; }
807
+ #settings-msg { margin-top: 10px; }
808
+ .card .fields { display: flex; flex-direction: column; gap: 10px; }
809
+ .card .fields.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
810
+ .card .fields .full { grid-column: 1 / -1; }
811
+ .card .field > label { font-size: 11.5px; }
812
+ .tag { font-size: 11px; padding: 1px 8px; border-radius: 6px; background: var(--panel2); border: 1px solid var(--border); color: var(--muted); flex: none; }
813
+ .toggle { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); cursor: pointer; }
814
+ .toggle input { accent-color: var(--ok); }
815
+ .conn { font-size: 12px; color: var(--muted); }
816
+ .conn.ok { color: var(--ok); }
817
+ .conn.bad { color: var(--bad); }
818
+
819
+ /* 多端控制权胶囊:空闲 / 我在控制 / 他人控制 */
820
+ .pill.ctrl { max-width: none; }
821
+ .pill.ctrl.mine { border-color: var(--ok); color: var(--ok); }
822
+ .pill.ctrl.held { border-color: var(--warn); color: var(--warn); }
823
+
824
+ /* 访问令牌门(远程设备首次连接) */
825
+ .token-gate {
826
+ position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
827
+ background: var(--bg);
828
+ }
829
+ .token-gate .gate-card {
830
+ width: min(360px, calc(100vw - 48px)); padding: 28px 26px;
831
+ background: var(--panel); border: 1px solid var(--border-strong); border-radius: 14px;
832
+ box-shadow: var(--shadow); text-align: center;
833
+ }
834
+ .token-gate .gate-brand { font-size: 20px; font-weight: 700; margin-bottom: 10px; display: flex; align-items: center; justify-content: center; gap: 10px; }
835
+ .token-gate .gate-brand .brand-name { font-size: 21px; }
836
+ .token-gate .gate-hint { color: var(--muted); font-size: 13px; line-height: 1.7; margin: 0 0 14px; }
837
+ .token-gate .gate-hint span { font-size: 11.5px; opacity: .8; }
838
+ .token-gate input {
839
+ width: 100%; box-sizing: border-box; text-align: center; letter-spacing: .12em;
840
+ padding: 10px 12px; margin-bottom: 12px; font-size: 16px;
841
+ }
842
+ .token-gate .primary { width: 100%; padding: 10px; font-size: 14.5px; }
843
+
844
+ /* 轻提示 */
845
+ .toast {
846
+ position: fixed; left: 50%; bottom: 34px; transform: translateX(-50%) translateY(12px);
847
+ z-index: 300; max-width: min(460px, calc(100vw - 40px));
848
+ background: var(--panel); color: var(--text); border: 1px solid var(--border-strong);
849
+ border-radius: 10px; box-shadow: var(--shadow); padding: 10px 16px; font-size: 13px;
850
+ opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
851
+ }
852
+ .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
853
+ .toast.bad { border-color: var(--bad); color: var(--bad); }
854
+
855
+ /* 减少动效(无障碍;headless 截图验证也靠它定格最终态) */
856
+ @media (prefers-reduced-motion: reduce) {
857
+ * { transition: none !important; animation: none !important; }
858
+ }
859
+
860
+ /* ---------------- 手机连接弹框(扫码) ---------------- */
861
+ .phone-connect { display: flex; flex-direction: column; align-items: center; gap: 14px; }
862
+ .qr-box {
863
+ background: #fff; border-radius: 12px; padding: 14px; line-height: 0;
864
+ box-shadow: var(--shadow);
865
+ }
866
+ .qr-box svg { width: 210px; height: 210px; display: block; }
867
+ .conn-chips { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
868
+ .chip2 {
869
+ background: var(--panel2); border: 1px solid var(--border); color: var(--muted);
870
+ border-radius: 999px; padding: 5px 14px; font-size: 12.5px; cursor: pointer; font-family: inherit;
871
+ transition: border-color .15s, color .15s;
872
+ }
873
+ .chip2.on { border-color: var(--accent); color: var(--text); }
874
+ .conn-url-row { display: flex; align-items: center; gap: 10px; max-width: 100%; }
875
+ .conn-url-row code {
876
+ font-family: var(--mono); font-size: 12.5px; color: var(--text);
877
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
878
+ }
879
+ .phone-connect .hint { text-align: center; }
880
+
881
+ /* ---------------- 任务检查器(右缘停靠列) ---------------- */
882
+ /* 三列 grid:侧栏 | 主栏 | 检查器。列本体隐藏时 grid 自然退回两列 */
883
+ body.inspector-open #app { grid-template-columns: 264px 1fr minmax(280px, 340px); }
884
+ /* 组合态:左栏已收起时检查器仍停靠,但左栏列保持 0——否则恢复出一条 264px 隐形空白 */
885
+ body.side-collapsed.inspector-open #app { grid-template-columns: 0 1fr minmax(280px, 340px); }
886
+ #inspector {
887
+ display: none; flex-direction: column; min-width: 0; height: 100vh;
888
+ background: var(--bg); border-left: 1px solid var(--border);
889
+ }
890
+ body.inspector-open #inspector { display: flex; }
891
+ .insp-head {
892
+ display: flex; align-items: center; gap: 8px; flex: none;
893
+ padding: 12px 12px 10px; border-bottom: 1px solid var(--border);
894
+ }
895
+ .insp-head .t {
896
+ flex: 1; min-width: 0; font-weight: 600; font-size: 13.5px;
897
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
898
+ }
899
+ .insp-body { display: flex; flex-direction: column; gap: 10px; padding: 10px; overflow-y: auto; min-height: 0; flex: 1; }
900
+ /* 常驻统计条(原统计卡压成一行) */
901
+ .insp-strip {
902
+ flex: none; display: flex; flex-wrap: wrap; gap: 4px 14px;
903
+ padding: 9px 14px 0; font-size: 12px; color: var(--muted);
904
+ }
905
+ .insp-strip b { color: var(--text); font-family: var(--mono); }
906
+ /* 分区 TAB:一次只展示一个分区 */
907
+ .insp-tabs {
908
+ flex: none; display: flex; gap: 4px; padding: 8px 10px;
909
+ border-bottom: 1px solid var(--border);
910
+ }
911
+ .insp-tab {
912
+ flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
913
+ background: none; border: none; color: var(--muted);
914
+ font-size: 12px; font-family: inherit; padding: 5px 8px; border-radius: 7px; cursor: pointer;
915
+ }
916
+ .insp-tab .ico { width: 14px; height: 14px; }
917
+ .insp-tab:hover { color: var(--text); background: var(--panel2); }
918
+ .insp-tab.active { color: var(--text); background: var(--panel2); font-weight: 600; }
919
+ .insp-badge {
920
+ font-size: 10.5px; line-height: 1; padding: 2px 5px; border-radius: 999px;
921
+ font-family: var(--mono); color: var(--muted);
922
+ background: color-mix(in srgb, var(--muted) 14%, transparent);
923
+ }
924
+ .insp-badge.verdict { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
925
+ .insp-pane { display: block; min-height: 0; }
926
+ .insp-pane-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; min-height: 20px; }
927
+ /* 进度环:养成感——stroke-dashoffset 走 CSS transition,数据推进时环平滑生长 */
928
+ .insp-ring-wrap { position: relative; width: 84px; height: 84px; margin: 4px auto 10px; }
929
+ .insp-ring { width: 84px; height: 84px; transform: rotate(-90deg); }
930
+ .insp-ring .tr { fill: none; stroke: var(--border); stroke-width: 7; }
931
+ .insp-ring .pr {
932
+ fill: none; stroke: var(--accent); stroke-width: 7; stroke-linecap: round;
933
+ stroke-dasharray: 226.2; stroke-dashoffset: 226.2;
934
+ transition: stroke-dashoffset .7s cubic-bezier(.25, .8, .35, 1);
935
+ }
936
+ .insp-ring-num {
937
+ position: absolute; inset: 0; display: flex; flex-direction: column;
938
+ align-items: center; justify-content: center; gap: 1px;
939
+ }
940
+ .insp-ring-num b { font-size: 17px; font-family: var(--mono); color: var(--text); }
941
+ .insp-ring-num span { font-size: 10px; color: var(--muted); }
942
+ /* 步骤动效:刷新时逐条滑入(stagger 封顶 8 条防长列表拖沓);运行中行呼吸光晕 */
943
+ @keyframes insp-in { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }
944
+ @media (prefers-reduced-motion: no-preference) {
945
+ .insp-step { animation: insp-in .24s ease both; }
946
+ .insp-step:nth-child(1) { animation-delay: .02s; }
947
+ .insp-step:nth-child(2) { animation-delay: .06s; }
948
+ .insp-step:nth-child(3) { animation-delay: .10s; }
949
+ .insp-step:nth-child(4) { animation-delay: .14s; }
950
+ .insp-step:nth-child(5) { animation-delay: .18s; }
951
+ .insp-step:nth-child(6) { animation-delay: .22s; }
952
+ .insp-step:nth-child(7) { animation-delay: .26s; }
953
+ .insp-step:nth-child(n+8) { animation-delay: .28s; }
954
+ }
955
+ @keyframes insp-glow {
956
+ 0%, 100% { background: color-mix(in srgb, var(--accent) 6%, transparent); }
957
+ 50% { background: color-mix(in srgb, var(--accent) 18%, transparent); }
958
+ }
959
+ .insp-step.running { animation: insp-glow 1.6s ease-in-out infinite; border-radius: 6px; }
960
+ /* 底部指挥坞:任何分区下常驻可达 */
961
+ .insp-direct {
962
+ flex: none; border-top: 1px solid var(--border); background: var(--panel);
963
+ padding: 9px 12px 10px;
964
+ }
965
+ .insp-direct-head {
966
+ display: flex; align-items: center; gap: 6px; margin-bottom: 6px;
967
+ color: var(--muted); font-size: 11px; letter-spacing: .05em;
968
+ }
969
+ .insp-card {
970
+ background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
971
+ padding: 10px 12px; flex: none;
972
+ }
973
+ .insp-card-head {
974
+ display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
975
+ color: var(--muted); font-size: 11px; letter-spacing: .05em; margin-bottom: 8px;
976
+ }
977
+ .insp-card-head .ico { color: var(--muted); }
978
+ /* Git 卡:分支行 + +/- 统计 + 变更清单(复用 rd-git 的 gf 芯片口径) */
979
+ .insp-branch {
980
+ display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
981
+ font-family: var(--mono); font-size: 12px;
982
+ }
983
+ .insp-branch code {
984
+ color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
985
+ border-radius: 6px; padding: 2px 7px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
986
+ }
987
+ .insp-plus { color: var(--ok); font-weight: 700; font-family: var(--mono); }
988
+ .insp-minus { color: var(--bad); font-weight: 700; font-family: var(--mono); }
989
+ .insp-changes { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; }
990
+ .insp-cf {
991
+ display: flex; align-items: center; gap: 6px; min-width: 0; width: 100%;
992
+ font-family: var(--mono); font-size: 11.5px; color: var(--text);
993
+ background: none; border: none; border-radius: 6px; padding: 3px 6px;
994
+ cursor: pointer; text-align: left; font-family: inherit;
995
+ }
996
+ .insp-cf:hover { background: var(--panel2); }
997
+ .insp-cf .p {
998
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
999
+ font-family: var(--mono); font-size: 11.5px;
1000
+ }
1001
+ .insp-cf .add, .insp-cf .del { flex: none; font-family: var(--mono); font-size: 11px; }
1002
+ .insp-cf .add { color: var(--ok); }
1003
+ .insp-cf .del { color: var(--bad); }
1004
+ .insp-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
1005
+ .insp-hint { color: var(--muted); font-size: 11.5px; }
1006
+ /* 检查器 Git 卡复用 rd-git 的 meta/状态字口径(那两组选择器钉在 .rd-git 下) */
1007
+ .insp-git-main .git-meta { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 6px; font-size: 12px; color: var(--muted); }
1008
+ .insp-git-main .git-meta b { font-family: var(--mono); }
1009
+ .insp-cf i.gs { font-style: normal; flex: none; font-weight: 700; }
1010
+ .insp-cf i.gs.n { color: var(--ok); }
1011
+ .insp-cf i.gs.m { color: var(--warn); }
1012
+ .insp-cf i.gs.d { color: var(--bad); }
1013
+ /* diff 查看器:检查器内展开,等宽小字,可横向滚动 */
1014
+ .insp-diff {
1015
+ margin: 8px 0 0; padding: 8px 10px; max-height: 260px; overflow: auto;
1016
+ background: var(--panel2); border: 1px solid var(--border); border-radius: 8px;
1017
+ font-family: var(--mono); font-size: 11px; line-height: 1.5; white-space: pre;
1018
+ }
1019
+ /* 进度卡(检查器「步骤」页签):状态点与全局步骤口径一致 */
1020
+ .insp-steps { display: flex; flex-direction: column; gap: 2px; }
1021
+ .insp-step {
1022
+ display: flex; align-items: center; gap: 7px; min-width: 0; width: 100%;
1023
+ background: none; border: none; border-radius: 6px; padding: 4px 6px;
1024
+ cursor: pointer; text-align: left; color: var(--text); font-size: 12px; font-family: inherit;
1025
+ }
1026
+ .insp-step:hover { background: var(--panel2); }
1027
+ .insp-step .sdot { width: 7px; height: 7px; }
1028
+ .insp-step .role { flex: none; color: var(--muted); font-size: 11px; }
1029
+ .insp-step .sum { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1030
+ .insp-step .dur { flex: none; color: var(--muted); font-size: 11px; font-family: var(--mono); }
1031
+ /* 统计卡 */
1032
+ .insp-stats { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; color: var(--muted); }
1033
+ .insp-stats b { color: var(--text); font-family: var(--mono); }
1034
+ /* 成品文件:复用 .file-chip(.rd-files 里的口径),容器只负责换行 */
1035
+ .insp-artifacts { display: flex; flex-wrap: wrap; gap: 6px; }
1036
+ .insp-artifacts .hint { flex-basis: 100%; }
1037
+ /* 迷你指挥区 */
1038
+ #insp-msg-input {
1039
+ width: 100%; resize: vertical; margin-bottom: 6px;
1040
+ background: var(--panel2); border: 1px solid var(--border-strong); border-radius: 8px;
1041
+ padding: 7px 9px; color: var(--text); font: inherit; font-size: 12.5px;
1042
+ }
1043
+ .insp-direct-bar { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
1044
+ .insp-direct-bar .insp-hint { flex: 1; }
1045
+ /* 窄屏:停靠列退化为覆盖抽屉 */
1046
+ #insp-mask { display: none; }
1047
+ @media (max-width: 900px) {
1048
+ body.inspector-open #app { grid-template-columns: 1fr; }
1049
+ body.side-collapsed.inspector-open #app { grid-template-columns: 1fr; }
1050
+ body.inspector-open #inspector {
1051
+ position: fixed; z-index: 60; top: 0; right: 0; bottom: 0;
1052
+ width: min(340px, 92vw); box-shadow: var(--shadow);
1053
+ }
1054
+ body.inspector-open #insp-mask {
1055
+ display: block; position: fixed; inset: 0; z-index: 55;
1056
+ background: rgba(0, 0, 0, .45);
1057
+ }
1058
+ }
1059
+
1060
+ /* ---------------- 响应式 ---------------- */
1061
+ /* 手机抽屉遮罩:抽屉展开时盖住内容区,点击关闭抽屉 */
1062
+ #drawer-mask { display: none; }
1063
+ @media (max-width: 900px) {
1064
+ #app { grid-template-columns: 1fr; }
1065
+ body.side-collapsed #app { grid-template-columns: 1fr; }
1066
+ #sidebar {
1067
+ position: fixed; z-index: 60; top: 0; left: 0; bottom: 0;
1068
+ width: min(300px, 84vw);
1069
+ transform: translateX(-105%); transition: transform .2s ease;
1070
+ box-shadow: var(--shadow);
1071
+ opacity: 1 !important; pointer-events: auto !important;
1072
+ padding: 14px 12px 12px !important; border-right: 1px solid var(--border) !important;
1073
+ }
1074
+ body:not(.side-collapsed) #sidebar { transform: none; }
1075
+ body:not(.side-collapsed) #drawer-mask {
1076
+ display: block; position: fixed; inset: 0; z-index: 55;
1077
+ background: rgba(0, 0, 0, .45);
1078
+ }
1079
+ main { padding: 18px 14px 70px; }
1080
+ .panel { padding: 16px; }
1081
+ .composer { padding: 20px 18px 16px; }
1082
+ .grid-2, .grid-3, .card .fields.grid { grid-template-columns: 1fr; }
1083
+ .card .fields .full { grid-column: auto; }
1084
+ .step { display: flex; flex-wrap: wrap; gap: 6px 10px; }
1085
+ .step .n { width: 24px; height: 24px; }
1086
+ #page-settings { max-width: none; }
1087
+ }
1088
+
1089
+ /* ---- 手机细化(≤640px)---- */
1090
+ @media (max-width: 640px) {
1091
+ .topbar { padding: 10px 12px; gap: 8px; }
1092
+ .top-actions { gap: 6px; }
1093
+ .pill { max-width: 140px; padding: 4px 10px; font-size: 11.5px; }
1094
+ .pill.ctrl { max-width: none; }
1095
+ /* 手机顶栏精简:皮肤入口撤下(皮肤在 设置 → 皮肤),只留明暗图标 */
1096
+ #btn-skin { display: none; }
1097
+ .page-title { font-size: 14px; }
1098
+ main { padding: 14px 10px 70px; }
1099
+ .panel { padding: 13px; }
1100
+ .composer { padding: 16px 14px 13px; }
1101
+ .hero { font-size: 20px; }
1102
+ /* iOS Safari 聚焦输入框时 ≥16px 才不会自动放大页面 */
1103
+ input, select, textarea { font-size: 16px; }
1104
+ .detail-head { flex-wrap: wrap; gap: 8px; }
1105
+ .detail-head h2 { flex-basis: 100%; order: -1; }
1106
+ .toast { bottom: 20px; }
1107
+ }
1108
+
1109
+ /* ---- 模型画廊 ---- */
1110
+ .gal-top {
1111
+ display: flex; flex-direction: column; align-items: stretch; gap: 12px;
1112
+ margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--border);
1113
+ }
1114
+ .gal-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
1115
+ .gal-actions input, .gal-actions select { width: auto; }
1116
+ .gal-body { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 14px; align-items: start; }
1117
+ .gal-side { background: var(--panel2); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; position: sticky; top: 12px; }
1118
+ .gal-side h4 { margin: 8px 0 6px; font-size: 12px; color: var(--muted); }
1119
+ .gal-side h4:first-child { margin-top: 0; }
1120
+ .gal-side label { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 3px 4px; cursor: pointer; color: var(--text); }
1121
+ .gal-side label .cnt { margin-left: auto; color: var(--muted); }
1122
+ .gal-side input { width: auto; accent-color: var(--accent); }
1123
+ .gal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
1124
+ .gal-grid .empty { grid-column: 1 / -1; }
1125
+ .mcard { background: var(--panel2); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
1126
+ .mcard.off { opacity: .5; }
1127
+ .mcard .mhead { display: flex; align-items: center; gap: 8px; }
1128
+ .mcard .mname { font-family: var(--mono); font-size: 13px; font-weight: 600; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1129
+ .mcard .mprio { font-family: var(--mono); font-size: 11px; background: var(--panel); border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px; color: var(--accent); }
1130
+ .mcard .mtags { display: flex; flex-wrap: wrap; gap: 4px; }
1131
+ .mcard .mprice { font-size: 11px; color: var(--muted); }
1132
+ .mcard .mops { display: flex; gap: 4px; align-items: center; }
1133
+ .mcard .mops button { padding: 1px 8px; font-size: 12px; }
1134
+ .mcard .mops .toggle { margin-left: auto; }
1135
+ @media (max-width: 900px) { .gal-body { grid-template-columns: 1fr; } .gal-side { position: static; } }
1136
+
1137
+ /* ---- 供应商主从视图 ---- */
1138
+ .prov-layout { display: grid; grid-template-columns: 330px minmax(0, 1fr); gap: 16px; align-items: start; }
1139
+ .prov-side { background: var(--panel2); border: 1px solid var(--border); border-radius: 10px; padding: 10px; position: sticky; top: 12px; max-height: calc(100vh - 116px); overflow: auto; }
1140
+ .prov-side-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 4px 8px; font-weight: 600; font-size: 13px; }
1141
+ .prov-side-ops { display: flex; gap: 4px; }
1142
+ .side-search { width: 100%; margin-bottom: 8px; }
1143
+ #prov-list { display: flex; flex-direction: column; gap: 4px; }
1144
+ .prov-item { padding: 9px 12px; border-radius: 8px; cursor: pointer; border: 1px solid transparent; }
1145
+ .prov-item:hover { background: var(--panel); }
1146
+ .prov-item.active { background: var(--panel); border-color: var(--accent); }
1147
+ .pi-name {
1148
+ font-size: 13px; font-weight: 600; line-height: 1.45; word-break: break-word;
1149
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
1150
+ }
1151
+ .pi-meta { display: flex; gap: 8px; align-items: center; margin-top: 5px; }
1152
+ /* 名称行:计数与名称首行顶端对齐(不同卡片高度一致),标签独占第二行 */
1153
+ .pi-top { display: flex; align-items: flex-start; gap: 8px; }
1154
+ .pi-n { margin-left: auto; font-size: 11px; color: var(--muted); line-height: 19px; flex: none; }
1155
+ .prov-detail { min-width: 0; min-height: 300px; }
1156
+ /* 详情头部:标题行 / 地址行 / 操作行,危险操作靠右隔离 */
1157
+ .pd-head { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 12px; }
1158
+ .pd-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1159
+ .pd-name { font-size: 16px; font-weight: 700; }
1160
+ .pd-url { font-family: var(--mono); font-size: 11.5px; color: var(--muted); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1161
+ .pd-ops { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
1162
+ .pd-ops-gap { flex: 1; }
1163
+ .pd-config { margin-bottom: 12px; background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
1164
+ .pd-config summary { cursor: pointer; color: var(--muted); font-size: 12px; }
1165
+ /* 模型过滤工具行 */
1166
+ .pm-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
1167
+ .pm-tools input[type="search"] { width: 280px; }
1168
+ .pm-count { font-size: 12px; color: var(--muted); flex: none; }
1169
+ .pgroup { margin-bottom: 14px; }
1170
+ .pgroup-title { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
1171
+ .prow { display: flex; align-items: center; gap: 8px; background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; margin-bottom: 5px; }
1172
+ .prow:hover { border-color: var(--border-strong); }
1173
+ .prow .drag { cursor: grab; color: var(--muted); opacity: .35; transition: opacity .12s; }
1174
+ .prow:hover .drag { opacity: 1; }
1175
+ .prow .pprio { font-family: var(--mono); font-size: 11px; color: var(--accent); min-width: 26px; }
1176
+ .prow .pname { font-family: var(--mono); font-size: 12px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1177
+ .prow.off { opacity: .5; }
1178
+ .prow.drag-over { border-color: var(--accent); border-style: dashed; }
1179
+ .prow.dragging { opacity: .4; }
1180
+ /* 行内操作:hover 才显示,减少整屏按钮噪音 */
1181
+ .prow .row-ops { display: flex; align-items: center; gap: 6px; flex: none; }
1182
+ .prow .row-op { opacity: 0; transition: opacity .12s; }
1183
+ .prow:hover .row-op, .prow:focus-within .row-op { opacity: 1; }
1184
+ .prow:focus-within { border-color: var(--border-strong); }
1185
+ /* 紧凑开关(模型启用/停用) */
1186
+ .tog-mini { position: relative; display: inline-flex; align-items: center; cursor: pointer; flex: none; }
1187
+ .tog-mini input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
1188
+ .tog-mini i { width: 30px; height: 16px; border-radius: 999px; background: var(--border-strong); transition: background .15s; position: relative; }
1189
+ .tog-mini i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
1190
+ .tog-mini input:checked + i { background: var(--ok); }
1191
+ .tog-mini input:checked + i::after { left: 16px; }
1192
+ .tog-mini input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 1px; }
1193
+ .prow-hidden { display: flex; align-items: center; gap: 8px; padding: 2px 2px 8px; font-size: 12px; color: var(--muted); }
1194
+ .prow-hidden button { margin-left: auto; }
1195
+ /* 批量操作 */
1196
+ .prov-batch, .mrow-batch {
1197
+ display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
1198
+ padding: 6px 8px; border: 1px solid var(--accent); border-radius: 8px;
1199
+ background: var(--panel); font-size: 12px;
1200
+ }
1201
+ .prov-batch { margin-bottom: 6px; }
1202
+ .mrow-batch { margin-bottom: 10px; }
1203
+ .prov-batch .n, .mrow-batch .n { color: var(--accent); font-weight: 600; margin-right: auto; }
1204
+ .prov-all, .pcheck-all {
1205
+ display: flex; align-items: center; gap: 5px; font-size: 12px;
1206
+ color: var(--muted); cursor: pointer; padding: 0 2px 6px;
1207
+ }
1208
+ .pcheck-all { display: inline-flex; padding: 0; margin-right: 6px; }
1209
+ .prov-all input, .pcheck-all input, .pi-check, .prow .pcheck { width: auto; accent-color: var(--accent); }
1210
+ /* 勾选框默认隐藏、hover 或已有勾选时显示,降噪 */
1211
+ .pi-check, .prow .pcheck { opacity: 0; transition: opacity .12s; flex: none; margin: 0; cursor: pointer; }
1212
+ .pi-check { margin: 0 2px 0 0; }
1213
+ .prov-item:hover .pi-check, #prov-list.has-sel .pi-check, .pi-check:checked,
1214
+ .prow:hover .pcheck, .prow:focus-within .pcheck, .pm-groups.has-sel .pcheck, .prow .pcheck:checked { opacity: 1; }
1215
+ .prov-item { display: flex; align-items: flex-start; gap: 6px; }
1216
+ .pi-body { min-width: 0; flex: 1; }
1217
+ .prov-item.off .pi-name { color: var(--muted); }
1218
+ details.prow-hidden { display: block; padding: 4px 2px 8px; }
1219
+ details.prow-hidden > summary { cursor: pointer; font-size: 12px; color: var(--muted); }
1220
+ details.prow-hidden[open] > summary { margin-bottom: 6px; }
1221
+ .prow-hidden-list { display: flex; flex-wrap: wrap; gap: 4px 14px; padding: 4px 2px 8px; }
1222
+ .prow-hidden-list label { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text); cursor: pointer; }
1223
+ .prow-hidden-list input { width: auto; accent-color: var(--accent); }
1224
+ .prow-hidden-ops { display: flex; gap: 6px; }
1225
+ .hint.warn { color: var(--warn, #e0a800); }
1226
+ .badge { font-size: 11px; padding: 1px 8px; border-radius: 999px; }
1227
+ .badge.ok { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok); }
1228
+ .badge.bad { background: color-mix(in srgb, var(--bad) 15%, transparent); color: var(--bad); }
1229
+ @media (max-width: 900px) { .prov-layout { grid-template-columns: 1fr; } .prov-side { position: static; } }
1230
+
1231
+ /* ---- 管理操作就地反馈 ---- */
1232
+ .mgmt-panel { border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: 8px; padding: 8px 10px; margin: 8px 0; background: var(--panel); }
1233
+ .mgmt-panel.done { border-left-color: var(--ok); }
1234
+ .mgmt-panel.failed { border-left-color: var(--bad); }
1235
+ .mgmt-panel.queued, .mgmt-panel.running { border-left-color: var(--accent); }
1236
+ .mgmt-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1237
+ .mgmt-title { font-size: 12px; font-weight: 600; }
1238
+ .mgmt-ops { margin-left: auto; display: flex; gap: 4px; }
1239
+ .mgmt-log { max-height: 260px; overflow: auto; background: var(--log-bg); border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px; margin: 8px 0 0; font-family: var(--mono); font-size: 11px; line-height: 1.55; white-space: pre-wrap; word-break: break-all; color: var(--log-text); }
1240
+ .mgmt-log.muted { color: var(--muted); font-style: italic; }
1241
+ /* 运行中:呼吸圆点,日志还没吐字时也能看出"在跑" */
1242
+ .live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; animation: live-pulse 1.1s ease-in-out infinite; }
1243
+ @keyframes live-pulse {
1244
+ 0%, 100% { opacity: 1; transform: scale(1); }
1245
+ 50% { opacity: .35; transform: scale(.75); }
1246
+ }
1247
+ .step.focus {
1248
+ border-color: var(--accent);
1249
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
1250
+ }
1251
+ .step.flash {
1252
+ border-color: var(--accent);
1253
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
1254
+ animation: step-flash 1.8s ease-out;
1255
+ }
1256
+ @keyframes step-flash {
1257
+ 0%, 60% { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); }
1258
+ 100% { border-color: var(--border-strong); background: var(--panel2); }
1259
+ }
1260
+ @media (prefers-reduced-motion: reduce) { .step.flash { animation: none; } }
1261
+ .run-sep {
1262
+ display: flex; align-items: center; gap: 10px;
1263
+ margin: 14px 0 6px; padding: 5px 12px;
1264
+ font-size: 12px; color: var(--muted);
1265
+ background: var(--panel); border: 1px dashed var(--border-strong); border-radius: 8px;
1266
+ }
1267
+ .run-sep:first-child { margin-top: 0; }
1268
+ .run-sep .rs-i { font-weight: 600; color: var(--text); }
1269
+ .run-sep .rs-t { font-family: var(--mono); }
1270
+ .run-sep .rs-err { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--bad); }
1271
+ /* 故事圣经面板:story-bible.md 查看/编辑 */
1272
+ .rd-bible {
1273
+ margin-top: 10px; padding: 10px 12px;
1274
+ background: var(--panel); border: 1px solid var(--border-strong); border-radius: 10px;
1275
+ }
1276
+ .rd-bible .bible-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1277
+ .rd-bible .bible-head .sec-title { margin: 0; }
1278
+ .rd-bible .bible-head .hint { flex: 1; min-width: 120px; }
1279
+ .rd-bible .flex1 { flex: 1; }
1280
+ .rd-bible .bible-view {
1281
+ margin: 8px 0 0; font-family: var(--mono); font-size: 12px; line-height: 1.6;
1282
+ white-space: pre-wrap; word-break: break-word; color: var(--log-text);
1283
+ max-height: 220px; overflow: auto;
1284
+ }
1285
+ .rd-bible .bible-editor {
1286
+ width: 100%; margin-top: 8px; padding: 8px 10px;
1287
+ font-family: var(--mono); font-size: 12px; line-height: 1.6;
1288
+ background: var(--panel2, var(--panel)); color: var(--text);
1289
+ border: 1px solid var(--border-strong); border-radius: 8px; resize: vertical;
1290
+ }
1291
+ /* 代码版本隔离面板:任务分支 tutti/<id> 的变更快照 + 合并/丢弃裁决 */
1292
+ .rd-git {
1293
+ margin-top: 10px; padding: 10px 12px;
1294
+ background: var(--panel); border: 1px solid var(--border-strong); border-radius: 10px;
1295
+ }
1296
+ .rd-git .git-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1297
+ .rd-git .git-head .sec-title { margin: 0; }
1298
+ .rd-git .git-branch {
1299
+ font-family: var(--mono); font-size: 11.5px; color: var(--accent);
1300
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
1301
+ border-radius: 6px; padding: 2px 7px;
1302
+ }
1303
+ .chip.isolated { background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); }
1304
+ .chip.merged { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
1305
+ .chip.discarded { background: var(--panel2, var(--panel)); color: var(--muted); }
1306
+ .rd-git .git-meta { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 6px; font-size: 12px; color: var(--muted); }
1307
+ .rd-git .git-meta b { font-family: var(--mono); }
1308
+ .rd-git .git-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
1309
+ .rd-git .gf {
1310
+ display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
1311
+ font-family: var(--mono); font-size: 11.5px;
1312
+ background: var(--panel2, var(--panel)); border: 1px solid var(--border); border-radius: 6px;
1313
+ padding: 2px 7px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1314
+ }
1315
+ .rd-git .gf i.gs { font-style: normal; flex: none; font-weight: 700; }
1316
+ .rd-git .gf i.gs.n { color: var(--ok); }
1317
+ .rd-git .gf i.gs.m { color: var(--warn); }
1318
+ .rd-git .gf i.gs.d { color: var(--bad); }
1319
+ .rd-git .gm { color: var(--muted); font-size: 11.5px; align-self: center; }
1320
+ .rd-git .git-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
1321
+ .rd-git .git-actions .hint { flex-basis: 100%; }
1322
+
1323
+ /* 成品文件链接区 */
1324
+ .rd-files { margin-top: 10px; }
1325
+ .rd-files .files-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
1326
+ .rd-files .sec-title { margin: 0; }
1327
+ .rd-files .wd {
1328
+ font-family: var(--mono); font-size: 11.5px; color: var(--muted);
1329
+ cursor: copy; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60%;
1330
+ }
1331
+ .file-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
1332
+ .file-chip {
1333
+ display: inline-flex; align-items: center; gap: 6px;
1334
+ padding: 3px 10px; border: 1px solid var(--border-strong); border-radius: 8px;
1335
+ font-size: 12px; color: var(--text); text-decoration: none; max-width: 100%;
1336
+ }
1337
+ .file-chip:hover { background: var(--panel2); border-color: var(--accent); }
1338
+ .file-chip i { font-style: normal; color: var(--muted); font-size: 11px; flex: none; }
1339
+ .file-chip.prev { cursor: pointer; color: var(--accent); }
1340
+ @media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }
1341
+
1342
+
1343
+ /* ---- 通用弹框 ---- */
1344
+ .modal-wrap { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 24px; }
1345
+ .modal-mask { position: absolute; inset: 0; background: rgba(0, 0, 0, .5); }
1346
+ .modal {
1347
+ position: relative; width: 100%; max-width: 620px; max-height: calc(100vh - 48px);
1348
+ display: flex; flex-direction: column; background: var(--bg);
1349
+ border: 1px solid var(--border-strong); border-radius: var(--r-lg); box-shadow: var(--shadow);
1350
+ }
1351
+ .modal-head {
1352
+ display: flex; align-items: center; justify-content: space-between; gap: 12px;
1353
+ padding: 14px 18px; border-bottom: 1px solid var(--border); font-size: 14.5px; font-weight: 700;
1354
+ }
1355
+ .modal-body { padding: 16px 18px; overflow: auto; }
1356
+ .modal-foot {
1357
+ display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
1358
+ padding: 12px 18px; border-top: 1px solid var(--border);
1359
+ }
1360
+ .modal-foot .spacer { flex: 1; }
1361
+ body.modal-open { overflow: hidden; }
1362
+ @media (max-width: 640px) { .modal { max-width: none; } }
1363
+
1364
+ /* ---- 应用内确认 / 输入弹框(替代原生 confirm/prompt;可叠在 #modal 之上) ---- */
1365
+ .ask-wrap { z-index: 250; } /* 高于 #modal(200),低于 toast(300) */
1366
+ .ask-modal { max-width: 440px; }
1367
+ #ask-body .ask-msg { white-space: pre-wrap; line-height: 1.65; font-size: 13.5px; }
1368
+ #ask-body .ask-input { width: 100%; margin-top: 4px; }
1369
+ body.ask-open { overflow: hidden; }
1370
+
1371
+ /* ---- 导入弹框:来源清单 ---- */
1372
+ .src-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
1373
+ .src-row {
1374
+ display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px;
1375
+ background: var(--panel2); border: 1px solid var(--border); border-radius: var(--r-sm);
1376
+ cursor: pointer;
1377
+ }
1378
+ .src-row:hover { border-color: var(--border-strong); }
1379
+ .src-row.disabled { opacity: .55; cursor: default; }
1380
+ .src-row input { width: auto; margin-top: 2px; accent-color: var(--accent); flex: none; }
1381
+ .src-main { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 3px; }
1382
+ .src-name { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1383
+ .src-desc { font-size: 12px; color: var(--muted); }
1384
+ .src-path { font-family: var(--mono); font-size: 10.5px; color: var(--muted); word-break: break-all; opacity: .8; }
1385
+ .src-note { font-size: 11.5px; color: var(--warn); }
1386
+ .src-note.bad { color: var(--bad); }
1387
+ .import-result { margin-top: 12px; }
1388
+ .import-result:empty { display: none; }
1389
+ .import-done { border: 1px solid var(--ok); border-radius: var(--r-sm); padding: 10px 12px; font-size: 12.5px; }
1390
+ .import-done ul { margin: 6px 0 0; padding-left: 18px; color: var(--muted); }
1391
+ .import-done li { margin: 2px 0; }
1392
+ .import-done .bad { color: var(--bad); }
1393
+
1394
+ /* ---- 智能体目录:供应商分组的模型选择 ---- */
1395
+ .tag.upd { color: var(--accent); border-color: var(--accent); }
1396
+ .tag.ok { color: var(--ok); }
1397
+ /* 教训分类 tag:文字色由 JS 按分类内联,边框跟随文字色;点击即按该类过滤 */
1398
+ .tag.cat { border-color: currentColor; opacity: .92; cursor: pointer; }
1399
+ /* 分类 chip 过滤条:药丸按钮,圆点标色,选中态描边+底色 */
1400
+ .cat-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
1401
+ .cat-chip {
1402
+ display: inline-flex; align-items: center; gap: 6px; font-family: inherit;
1403
+ font-size: 12.5px; color: var(--muted); background: var(--panel2);
1404
+ border: 1px solid var(--border); border-radius: 999px; padding: 4px 11px;
1405
+ cursor: pointer; transition: color .15s, border-color .15s, background-color .15s;
1406
+ }
1407
+ .cat-chip:hover { color: var(--text); border-color: var(--accent); }
1408
+ .cat-chip .cdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
1409
+ .cat-chip b { font-size: 11px; font-weight: 700; color: var(--muted); }
1410
+ .cat-chip.active { color: var(--text); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, var(--panel2)); }
1411
+ .cat-chip.active b { color: var(--accent); }
1412
+ .orch-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
1413
+ .ochip {
1414
+ display: inline-flex; align-items: center; gap: 4px; font-size: 12px;
1415
+ padding: 2px 4px 2px 8px; border-radius: 999px;
1416
+ background: var(--panel2); border: 1px solid var(--border); color: var(--text);
1417
+ }
1418
+ .ochip.primary { border-color: var(--accent); }
1419
+ .ochip b { font-size: 10px; font-weight: 700; color: var(--muted); }
1420
+ .ochip.primary b { color: var(--accent); }
1421
+ .ochip .mini {
1422
+ border: none; background: transparent; color: var(--muted);
1423
+ cursor: pointer; font-size: 12px; line-height: 1; padding: 0 3px;
1424
+ display: inline-flex; align-items: center;
1425
+ }
1426
+ .ochip .mini:hover { color: var(--text); }
1427
+ /* 链内小按钮里的图标(设为主模型)比正文图标略小 */
1428
+ .ochip .mini .ico { width: 12px; height: 12px; stroke-width: 2; }
1429
+ .opanel {
1430
+ margin-top: 8px; border: 1px solid var(--border); border-radius: 10px;
1431
+ padding: 10px 12px; background: var(--panel2); max-height: 260px; overflow: auto;
1432
+ }
1433
+ .ogroup + .ogroup { margin-top: 10px; }
1434
+ .ogname { font-size: 11.5px; font-weight: 700; color: var(--muted); margin-bottom: 4px; }
1435
+ .oitem {
1436
+ display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
1437
+ margin: 0 12px 6px 0; cursor: pointer;
1438
+ }
1439
+ .oitem input { width: auto; accent-color: var(--accent); }
1440
+ .ohint { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
1441
+
1442
+ /* ================= 用量统计 ================= */
1443
+ /* 时间范围分段控件:互斥选项用连体分段,选中态一眼可辨
1444
+ *(此前是 4 个 ghost 按钮且 .active 无样式,用户看不出选的是哪个) */
1445
+ .seg {
1446
+ display: inline-flex; align-items: center; gap: 2px;
1447
+ background: var(--panel2); border: 1px solid var(--border);
1448
+ border-radius: 9px; padding: 2px;
1449
+ }
1450
+ .seg-btn {
1451
+ background: none; border: none; color: var(--muted); font-family: inherit;
1452
+ font-size: 12.5px; padding: 4px 11px; border-radius: 7px; cursor: pointer;
1453
+ white-space: nowrap; transition: background-color .15s, color .15s;
1454
+ }
1455
+ .seg-btn:hover { color: var(--text); background: var(--border); }
1456
+ .seg-btn.active {
1457
+ background: var(--accent); color: #fff; font-weight: 600;
1458
+ box-shadow: 0 1px 4px rgba(0, 0, 0, .22);
1459
+ }
1460
+ html[data-theme="light"] .seg-btn.active { box-shadow: 0 1px 3px rgba(0, 0, 0, .16); }
1461
+
1462
+ .usage-kpis {
1463
+ display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px;
1464
+ margin: 14px 0 4px;
1465
+ }
1466
+ .kpi {
1467
+ background: var(--panel2); border: 1px solid var(--border);
1468
+ border-radius: var(--r-md); padding: 12px 14px; min-width: 0;
1469
+ }
1470
+ .kpi.wide { grid-column: span 2; }
1471
+ /* 卡片标签行:图标 + 名称,图标用弱化色,跟随主题 */
1472
+ .kpi-l {
1473
+ display: flex; align-items: center; gap: 5px;
1474
+ color: var(--muted); font-size: 12px; margin-top: 2px;
1475
+ }
1476
+ .kpi-l .ico { opacity: .75; width: 13px; height: 13px; stroke-width: 1.9; }
1477
+ .kpi-v {
1478
+ font-size: 22px; font-weight: 700; letter-spacing: -.02em;
1479
+ font-family: var(--mono); white-space: nowrap;
1480
+ }
1481
+ .kpi-s {
1482
+ color: var(--muted); font-size: 11px; margin-top: 6px;
1483
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1484
+ }
1485
+ .usage-svg {
1486
+ width: 100%; height: auto; display: block;
1487
+ background: var(--panel2); border: 1px solid var(--border);
1488
+ border-radius: var(--r-md); margin-bottom: 6px;
1489
+ }
1490
+ .usage-svg .uc-x { fill: var(--muted); font-size: 11px; }
1491
+ .usage-svg .uc-legend text { fill: var(--muted); font-size: 11px; }
1492
+ .usage-svg .uc-grid { stroke: var(--border); stroke-width: 1; stroke-dasharray: 3 4; }
1493
+ .usage-svg .uc-base { stroke: var(--border-strong); stroke-width: 1; }
1494
+ .usage-svg .uc-peak { fill: var(--muted); font-size: 11px; font-weight: 600; }
1495
+ /* 柱顶总量标签:峰值日加重,矮柱的信息全靠它 */
1496
+ .usage-svg .uc-val { fill: var(--muted); font-size: 10px; font-family: var(--mono); }
1497
+ .usage-svg .uc-val-max { fill: var(--text); font-weight: 600; }
1498
+ /* 悬浮一根柱:整组提亮 + 描边,其余柱压暗,聚焦当下这一天 */
1499
+ .usage-svg g.bar { opacity: 1; transition: opacity .12s; }
1500
+ .usage-svg g.bar:hover { opacity: 1; }
1501
+ .usage-svg:hover g.bar:not(:hover) { opacity: .32; }
1502
+ .usage-svg g.bar-zero rect { opacity: .9; }
1503
+ .usage-svg g.bar:hover rect { stroke: var(--text); stroke-width: .8; }
1504
+ /* 单日构成视图 */
1505
+ .usage-single {
1506
+ background: var(--panel2); border: 1px solid var(--border);
1507
+ border-radius: var(--r-md); margin-bottom: 6px; padding: 14px 18px 12px;
1508
+ }
1509
+ .us-head { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; margin-bottom: 10px; }
1510
+ .us-day { font-weight: 600; font-size: 13px; }
1511
+ .us-sum { color: var(--muted); font-size: 12px; }
1512
+ .us-bar { display: flex; height: 34px; border-radius: 8px; overflow: hidden; background: var(--panel); }
1513
+ .us-seg { min-width: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; }
1514
+ .us-seg span { color: #fff; font-size: 12px; white-space: nowrap; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; }
1515
+ .us-in { background: var(--uc-in); }
1516
+ .us-ca { background: var(--uc-ca); }
1517
+ .us-out { background: var(--uc-out); }
1518
+ .us-empty { align-items: center; justify-content: center; color: var(--muted); font-size: 12px; }
1519
+ .us-foot { margin-top: 8px; color: var(--muted); font-size: 12px; }
1520
+ /* 多日横向构成条(2~14 天):每天一行,全宽堆叠条 + 右侧总量 */
1521
+ .usage-rows {
1522
+ background: var(--panel2); border: 1px solid var(--border);
1523
+ border-radius: var(--r-md); margin-bottom: 6px; padding: 12px 16px 10px;
1524
+ }
1525
+ .ur-legend {
1526
+ display: flex; gap: 14px; align-items: center;
1527
+ color: var(--muted); font-size: 11px; margin-bottom: 8px;
1528
+ }
1529
+ .ur-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; margin-right: 4px; vertical-align: -1px; }
1530
+ .ur-row { display: flex; align-items: center; gap: 10px; padding: 3px 0; }
1531
+ .ur-day {
1532
+ width: 42px; flex: none; font-family: var(--mono); font-size: 11.5px;
1533
+ color: var(--muted); text-align: right;
1534
+ }
1535
+ .ur-row.today .ur-day { color: var(--text); font-weight: 600; }
1536
+ .ur-track {
1537
+ flex: 1; display: flex; height: 16px; border-radius: 5px;
1538
+ background: var(--panel); overflow: hidden; min-width: 0;
1539
+ }
1540
+ .ur-seg { height: 100%; min-width: 0; }
1541
+ .ur-row.zero .ur-track { height: 8px; }
1542
+ .ur-zero {
1543
+ flex: 1; display: flex; align-items: center; justify-content: center;
1544
+ color: var(--muted); font-size: 10px; letter-spacing: .1em;
1545
+ }
1546
+ .ur-sum {
1547
+ width: 64px; flex: none; text-align: right;
1548
+ font-family: var(--mono); font-size: 11.5px; color: var(--muted);
1549
+ }
1550
+ .ur-row.today .ur-sum { color: var(--text); font-weight: 600; }
1551
+ .usage-table { width: 100%; border-collapse: collapse; margin: 6px 0 4px; }
1552
+ .usage-table th {
1553
+ text-align: left; color: var(--muted); font-size: 12px; font-weight: 600;
1554
+ padding: 6px 10px; border-bottom: 1px solid var(--border-strong);
1555
+ white-space: nowrap;
1556
+ }
1557
+ .usage-table th.num, .usage-table td.num { text-align: right; font-family: var(--mono); }
1558
+ .usage-table td {
1559
+ padding: 7px 10px; border-bottom: 1px solid var(--border);
1560
+ font-size: 13px; vertical-align: middle;
1561
+ }
1562
+ .usage-table td.sub, .usage-table .sub { color: var(--muted); }
1563
+ .usage-table td.mono { font-family: var(--mono); font-size: 12px; }
1564
+ .usage-table .bad-row td { background: color-mix(in srgb, var(--bad) 7%, transparent); }
1565
+ .usage-table .bar-cell { width: 26%; min-width: 170px; }
1566
+ .usage-table .bar-outer {
1567
+ position: relative; display: flex; align-items: center;
1568
+ justify-content: space-between; gap: 8px; white-space: nowrap;
1569
+ }
1570
+ .usage-table .bar-fill {
1571
+ position: absolute; top: -3px; bottom: -3px; left: -10px;
1572
+ background: var(--accent); opacity: .16; border-radius: 6px;
1573
+ }
1574
+ .usage-table .bar-outer span {
1575
+ position: relative; font-weight: 600;
1576
+ overflow: hidden; text-overflow: ellipsis;
1577
+ }
1578
+ .usage-table .bar-outer i {
1579
+ position: relative; font-style: normal; font-size: 11px; color: var(--muted);
1580
+ }
1581
+ .usage-recent-wrap { max-height: 420px; overflow: auto; }
1582
+
1583
+ @media (max-width: 900px) {
1584
+ .usage-kpis { grid-template-columns: repeat(2, 1fr); }
1585
+ .kpi.wide { grid-column: span 2; }
1586
+ .usage-table .bar-cell { min-width: 120px; width: 42%; }
1587
+ }
1588
+
1589
+ /* ================= 外观(皮肤 / 换肤) =================
1590
+ * 卡片是 <button>:可 Tab 到、可回车选中。预览色块由 JS 从各皮肤的 CSS 变量
1591
+ * 实时取色后内联(见 app.js skinPalette),所以这里不重复写任何色值,
1592
+ * 皮肤改色只改上面那一组变量即可。 */
1593
+ .skin-grid {
1594
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
1595
+ gap: 12px; margin: 4px 0 2px;
1596
+ }
1597
+ .skin-card {
1598
+ display: flex; flex-direction: column; gap: 9px; text-align: left; font-family: inherit;
1599
+ background: var(--panel2); color: var(--text);
1600
+ border: 1px solid var(--border); border-radius: var(--r-md);
1601
+ padding: 11px; cursor: pointer; min-width: 0;
1602
+ white-space: normal; /* 全局 button 是 nowrap(防中文短标签竖排),这里必须放开,描述才会换行 */
1603
+ transition: border-color .15s, transform .12s;
1604
+ }
1605
+ .skin-card:hover { border-color: var(--border-strong); }
1606
+ .skin-card:active { transform: scale(.985); }
1607
+ .skin-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1608
+ /* 选中态:描边 + 常显勾选,不靠颜色深浅传达(保证各皮肤下都看得出来) */
1609
+ .skin-card.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
1610
+ .skin-card .skin-check { color: var(--accent); opacity: 0; transition: opacity .15s; }
1611
+ .skin-card.active .skin-check { opacity: 1; }
1612
+ /* 预览:左侧栏色 + 主区底色 + 三根「内容条」(强调色 / 正文色 / 次强调色) */
1613
+ .skin-prev {
1614
+ display: flex; height: 52px; border-radius: 8px; overflow: hidden;
1615
+ border: 1px solid var(--border);
1616
+ }
1617
+ .skin-prev .pv-side { width: 30%; }
1618
+ .skin-prev .pv-main { flex: 1; display: flex; flex-direction: column; gap: 5px; padding: 8px; }
1619
+ .skin-prev .pv-bar { height: 6px; border-radius: 4px; }
1620
+ .skin-prev .pv-bar.w85 { width: 85%; }
1621
+ .skin-prev .pv-bar.w60 { width: 60%; }
1622
+ .skin-prev .pv-bar.w40 { width: 40%; }
1623
+ .skin-meta { display: flex; align-items: center; gap: 6px; }
1624
+ .skin-name { flex: 1; font-weight: 600; font-size: 13.5px; }
1625
+ .skin-desc { color: var(--muted); font-size: 11.5px; line-height: 1.5; min-width: 0;
1626
+ overflow-wrap: anywhere; } /* 长描述在卡片内换行,别再越界到隔壁卡片 */
1627
+
1628
+ @media (max-width: 900px) {
1629
+ .skin-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
1630
+ .skin-prev { height: 44px; }
1631
+ .skin-prev .pv-main { gap: 4px; padding: 6px; }
1632
+ .skin-desc { display: none; } /* 窄屏只留名字与配色预览 */
1633
+ }
1634
+ /* 极窄屏(320~340px)才落单列,否则 6 套皮肤要滚很久 */
1635
+ @media (max-width: 340px) {
1636
+ .skin-grid { grid-template-columns: 1fr; }
1637
+ }
1638
+
1639
+ /* ---------------- 运行中指挥(详情页消息信箱)---------------- */
1640
+ .rd-direct { margin-top: 12px; border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; background: var(--panel2); }
1641
+ .rd-direct .sec-title { margin: 0 0 8px; display: flex; align-items: center; gap: 6px; }
1642
+ .rd-msgs { display: flex; flex-direction: column; gap: 5px; margin-bottom: 8px; max-height: 220px; overflow-y: auto; }
1643
+ .rd-msgs:empty { display: none; margin: 0; }
1644
+ .rd-msg { font-size: 12.5px; line-height: 1.5; color: var(--text); background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 5px 9px; }
1645
+ .rd-msg .m-when { color: var(--muted); font-size: 11px; margin-right: 6px; font-family: var(--mono); }
1646
+ .rd-msg .m-who { color: var(--accent); font-weight: 600; margin-right: 6px; }
1647
+ .rd-msg .m-atts { display: block; color: var(--muted); font-size: 11.5px; margin-top: 2px; }
1648
+ .rd-msg.m-consumed { opacity: .65; }
1649
+ .rd-composer textarea { width: 100%; box-sizing: border-box; font-size: 13px; }
1650
+ .rd-composer-bar { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
1651
+ .rd-composer-bar .rd-hint { flex: 1; min-width: 40px; color: var(--muted); font-size: 11.5px; }
1652
+ .rd-att-list { display: inline-flex; gap: 5px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); }
1653
+ .rd-att-list .att-chip2 { border: 1px solid var(--border-strong); border-radius: 6px; padding: 1px 7px; display: inline-flex; align-items: center; gap: 4px; }
1654
+ .rd-att-list .att-chip2 b { font-weight: 400; cursor: pointer; color: var(--muted); }
1655
+ .rd-att-list .att-chip2 b:hover { color: var(--bad, #e5484d); }
1656
+
1657
+ /* ---------------- 蜂巢工作台(每个智能体一格,实时尾巴)---------------- */
1658
+ .rd-hive { margin-top: 12px; }
1659
+ .rd-hive .sec-title { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; }
1660
+ .rd-hive .sec-title .tag { font-weight: 400; }
1661
+ .hive-cells { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; }
1662
+ .hive-cell {
1663
+ position: relative; border: 1px solid var(--border); border-radius: 10px;
1664
+ background: var(--panel); padding: 8px 10px; cursor: pointer; min-width: 0;
1665
+ transition: border-color .15s, box-shadow .15s;
1666
+ }
1667
+ .hive-cell:hover { border-color: var(--accent); }
1668
+ .hive-cell .hc-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
1669
+ .hive-cell .hc-head .ico { flex: none; width: 16px; height: 16px; color: var(--muted); }
1670
+ .hive-cell .hc-role { font-size: 12px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1671
+ .hive-cell .hc-who { margin-left: auto; font-size: 11px; color: var(--muted); flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1672
+ .hive-cell .hc-tail {
1673
+ margin-top: 5px; font-family: var(--mono); font-size: 11px; color: var(--muted);
1674
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 14px;
1675
+ }
1676
+ .hive-cell .hc-meta { margin-top: 4px; display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); }
1677
+
1678
+ /* 运行中:蜜蜂忙碌摆动 + 蜜色描边呼吸 */
1679
+ .hive-cell.st-running { border-color: var(--accent); }
1680
+ .hive-cell.st-running .ico { color: var(--accent); }
1681
+ .hive-cell.st-running .hc-bee { animation: bee-bob 1.1s ease-in-out infinite; }
1682
+ @keyframes bee-bob {
1683
+ 0%, 100% { transform: translateY(0) rotate(0deg); }
1684
+ 30% { transform: translateY(-2px) rotate(-8deg); }
1685
+ 70% { transform: translateY(1px) rotate(8deg); }
1686
+ }
1687
+ .hive-cell.st-running { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); }
1688
+ .hive-cell.st-done { opacity: .72; }
1689
+ .hive-cell.st-done .hc-bee { display: none; }
1690
+ .hive-cell.st-failed { border-color: var(--bad, #e5484d); }
1691
+ .hive-cell.st-failed .hc-bee { display: none; }
1692
+ .hive-cell.st-failed .hc-role::after { content: " ✗"; color: var(--bad, #e5484d); }
1693
+ @media (prefers-reduced-motion: reduce) {
1694
+ .hive-cell.st-running .hc-bee { animation: none; }
1695
+ }
1696
+
1697
+ /* ---------------- 详情页双栏:主栏工作面 + 侧栏控制台 ---------------- */
1698
+ .rd-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 14px; align-items: start; }
1699
+ .rd-main { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
1700
+ .rd-side { position: sticky; top: 12px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
1701
+ .rd-side-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; background: var(--panel2); }
1702
+ .rd-side-card .stats { margin: 0; }
1703
+ .rd-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 8px; }
1704
+ .rd-actions button { width: 100%; margin: 0; }
1705
+ /* 窄屏降单列:控制台跟在工作面后面(触屏滚动可达,吸顶关闭) */
1706
+ @media (max-width: 1100px) {
1707
+ .rd-grid { grid-template-columns: 1fr; }
1708
+ .rd-side { position: static; }
1709
+ }
1710
+
1711
+ /* ---------------- 蜂巢泳道流水线(先后关系 + 流动光点)---------------- */
1712
+ .hive-lanes-noop {}
1713
+ #rd-hive-cells { display: flex; flex-direction: column; gap: 2px; }
1714
+ .hive-lane { border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; background: var(--panel); }
1715
+ .hive-lane.lane-active { border-color: var(--accent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }
1716
+ .hive-lane.lane-idle { opacity: .55; }
1717
+ .hive-lane.lane-done { opacity: .82; }
1718
+ .lane-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
1719
+ .lane-name { font-size: 12.5px; font-weight: 700; color: var(--text); }
1720
+ .lane-n { font-size: 11px; color: var(--muted); }
1721
+ .lane-live { margin-left: auto; font-size: 11px; color: var(--accent); }
1722
+ .lane-track { display: flex; gap: 5px; align-items: center; margin: 2px 0 7px; }
1723
+ .ld { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); flex: none; }
1724
+ .ld-done { background: var(--accent); opacity: .75; }
1725
+ .ld-fail { background: var(--bad, #e5484d); }
1726
+ .ld-run { background: var(--accent); animation: ld-pulse 1s ease-in-out infinite; }
1727
+ @keyframes ld-pulse { 50% { transform: scale(1.7); box-shadow: 0 0 6px var(--accent); } }
1728
+ /* 泳道间轨道 + 流动光点:只有活跃泳道下方的光点在跑 */
1729
+ .lane-flow { position: relative; height: 12px; margin: 1px 0 1px 20px; width: calc(100% - 40px); }
1730
+ .lane-flow::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px;
1731
+ background: repeating-linear-gradient(90deg, var(--border-strong) 0 6px, transparent 6px 12px); }
1732
+ .lane-flow::after { content: ""; position: absolute; top: 50%; left: 0; margin-top: -3px; width: 6px; height: 6px;
1733
+ border-radius: 50%; background: var(--accent); opacity: 0; }
1734
+ .hive-lane.lane-active + .lane-flow::after { animation: flow-dot 1.4s linear infinite; }
1735
+ @keyframes flow-dot {
1736
+ 0% { left: 0; opacity: 0; } 12% { opacity: 1; } 85% { opacity: 1; } 100% { left: calc(100% - 6px); opacity: 0; }
1737
+ }
1738
+ .lane-cells { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 6px; }
1739
+ @media (prefers-reduced-motion: reduce) {
1740
+ .lane-flow::after, .ld.ld-run { animation: none; }
1741
+ }
1742
+
1743
+ /* 检查器「成品文件」TAB:窄栏竖排 chips + 目录行 */
1744
+ .insp-files .files-head { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; }
1745
+ .insp-files .files-head .wd { max-width: 100%; }
1746
+ .insp-files .file-chips { flex-direction: column; flex-wrap: nowrap; }
1747
+ .insp-files .file-chip { max-width: 100%; }
1748
+ .insp-files .file-chip.prev { justify-content: center; }
1749
+
1750
+ /* —— 文件内容弹窗:Git 变更双击看 diff / 成品文件点开看内容 ——
1751
+ * 层级 240:高于主 modal(200)、低于 #ask(250),Esc 逐层关 */
1752
+ #file-pop {
1753
+ position: fixed; inset: 0; z-index: 240; display: flex; align-items: center; justify-content: center;
1754
+ padding: 4vh 4vw; background: rgba(0, 0, 0, 0.45);
1755
+ }
1756
+ #file-pop.hidden { display: none; }
1757
+ #file-pop .fp-panel {
1758
+ display: flex; flex-direction: column; width: min(960px, 100%); height: min(86vh, 900px);
1759
+ background: var(--bg); border: 1px solid var(--border-strong); border-radius: 14px;
1760
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.35); overflow: hidden;
1761
+ }
1762
+ #file-pop .fp-head {
1763
+ display: flex; align-items: center; gap: 8px; padding: 9px 14px;
1764
+ background: var(--panel2, var(--panel)); border-bottom: 1px solid var(--border); flex: none;
1765
+ }
1766
+ #file-pop .fp-title {
1767
+ font-family: var(--mono); font-size: 12.5px; color: var(--accent); overflow: hidden;
1768
+ text-overflow: ellipsis; white-space: nowrap; max-width: 55%;
1769
+ }
1770
+ #file-pop .fp-sub { display: flex; gap: 8px; font-family: var(--mono); font-size: 11.5px; color: var(--muted); flex: none; }
1771
+ #file-pop .fp-flex { flex: 1; }
1772
+ #file-pop .fp-acts { display: flex; gap: 6px; flex: none; }
1773
+ #file-pop .fp-acts .ghost, #file-pop .fp-x { padding: 2px 10px; font-size: 12px; text-decoration: none; }
1774
+ #file-pop .fp-body { flex: 1; min-height: 0; overflow: auto; }
1775
+ #file-pop .fp-hint { padding: 24px 18px; color: var(--muted); font-size: 12.5px; }
1776
+ /* diff:行着色,等宽小字,横向可滚 */
1777
+ #file-pop .fp-diff { font-family: var(--mono); font-size: 12px; line-height: 1.55; min-width: max-content; padding: 6px 0 12px; }
1778
+ #file-pop .fp-ln { padding: 0 14px; white-space: pre; }
1779
+ #file-pop .fp-add { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
1780
+ #file-pop .fp-del { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
1781
+ #file-pop .fp-hunk { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
1782
+ #file-pop .fp-meta { color: var(--muted); }
1783
+ /* 文本/代码:统一 codeBlockHTML 行号表格(.code-block 自带排版),无独立 md 排版路径 */
1784
+ #file-pop .fp-code pre {
1785
+ margin: 0; padding: 12px 16px; font-family: var(--mono); font-size: 12.5px; line-height: 1.6;
1786
+ white-space: pre-wrap; word-break: break-word;
1787
+ }
1788
+ /* 图片:居中直显,太大等比缩 */
1789
+ #file-pop .fp-img { display: flex; align-items: center; justify-content: center; min-height: 100%; padding: 14px; }
1790
+ #file-pop .fp-img img { max-width: 100%; max-height: calc(86vh - 120px); border-radius: 8px; }
1791
+
1792
+ /* —— 成品文件列表换成 Git 变更清单同款行样式(只作用于检查器成品 TAB)—— */
1793
+ #insp-pane-files .file-chips { flex-direction: column; flex-wrap: nowrap; gap: 2px; }
1794
+ #insp-pane-files .file-chip {
1795
+ display: flex; align-items: center; gap: 6px; width: 100%; box-sizing: border-box;
1796
+ background: none; border: none; border-radius: 6px; padding: 3px 6px;
1797
+ font-family: var(--mono); font-size: 11.5px; cursor: pointer;
1798
+ }
1799
+ #insp-pane-files .file-chip:hover { background: var(--panel2); border-color: transparent; }
1800
+ #insp-pane-files .file-chip .p {
1801
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1802
+ font-family: var(--mono); font-size: 11.5px;
1803
+ }
1804
+ #insp-pane-files .file-chip i.fx {
1805
+ flex: none; font-style: normal; font-weight: 700; font-size: 10px; letter-spacing: 0.5px;
1806
+ color: var(--ok); text-transform: uppercase; min-width: 26px;
1807
+ }
1808
+ #insp-pane-files .file-chip i:not(.fx) { color: var(--muted); }
1809
+ #insp-pane-files .file-chip.prev { flex: none; width: auto; justify-content: center; color: var(--accent); }
1810
+
1811
+ /* 主栏 Git 面板 .gf 升级成可双击的按钮:外观不变,补指针与左对齐 */
1812
+ .rd-git .gf { cursor: pointer; }
1813
+ .rd-git .gf:hover { border-color: var(--accent); }
1814
+ /* 弹窗高度随内容走(封顶 86vh),短内容不留大片空白;图片弹窗保底高度 */
1815
+ #file-pop .fp-panel { height: auto; min-height: 280px; max-height: min(86vh, 900px); }
1816
+ #file-pop .fp-img { min-height: 320px; }
1817
+ /* 成品行 + 内联预览按钮同行;预览按钮保留 pill 形态 */
1818
+ #insp-pane-files .fc-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
1819
+ #insp-pane-files .fc-row .file-chip { flex: 1; min-width: 0; }
1820
+ #insp-pane-files .fc-row .file-chip.prev {
1821
+ flex: none; width: auto; justify-content: center; padding: 2px 9px;
1822
+ border: 1px solid var(--border-strong); border-radius: 8px; background: none;
1823
+ }
1824
+ /* 弹窗动作按钮:a.ghost 没有继承 button.ghost 的样式,裸链接挤在一起像叠字——
1825
+ * 给齐 pill 观感(边框+底色 hover+不换行),与 复制/× 按钮视觉一致 */
1826
+ #file-pop .fp-acts a.ghost, #file-pop .fp-acts button {
1827
+ display: inline-block; background: none; color: var(--text);
1828
+ border: 1px solid var(--border-strong); border-radius: 9px;
1829
+ padding: 3px 11px; cursor: pointer; font-size: 12px; line-height: 1.6;
1830
+ white-space: nowrap; text-decoration: none;
1831
+ }
1832
+ #file-pop .fp-acts a.ghost:hover, #file-pop .fp-acts button:hover { background: var(--panel2); }
1833
+ /* 高度完全随内容走(图片弹窗有 fp-img 兜底),去掉对短内容偏大的 min-height */
1834
+ #file-pop .fp-panel { min-height: 0; }
1835
+ /* 选择文件夹弹框:固定高度——目录间跳转内容多少不一,弹框忽高忽低会晃眼;
1836
+ * 列表区自己滚,空目录居中提示 */
1837
+ #pk-body { height: 56vh; min-height: 340px; display: flex; flex-direction: column; }
1838
+ #pk-body .pk-list { flex: 1; min-height: 0; max-height: none; }
1839
+ #pk-body .pk-empty { margin: auto; }
1840
+
1841
+ /* 侧栏「显示已归档」开关(原「最近任务」面板移除后,归档找回的唯一入口):
1842
+ * 默认暗显,打开后高亮;已归档任务行整体降透明 + 灰色静态徽章(区别于待裁决的橙色脉冲) */
1843
+ .arch-toggle .ico { opacity: .4; }
1844
+ .arch-toggle.on .ico { opacity: 1; color: var(--accent); }
1845
+ .arch-toggle.on { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
1846
+ .stask.archived .t { opacity: .5; }
1847
+ .stask.archived .sglyph { opacity: .4; }
1848
+ .sbadge.archb {
1849
+ color: var(--muted);
1850
+ background: color-mix(in srgb, var(--muted) 16%, transparent);
1851
+ animation: none;
1852
+ }
1853
+
1854
+ /* ============ 侧栏改版(2026-09-15,参考 Codex/暗色参考稿):搜索行 + 快捷键 + 工具行 + 底部徽章 ============ */
1855
+ /* 键位提示小徽(N / Ctrl K) */
1856
+ .kbd {
1857
+ flex: none; font-size: 10.5px; line-height: 1; color: var(--muted);
1858
+ border: 1px solid var(--border); border-radius: 5px; padding: 3px 5px;
1859
+ font-family: inherit; background: color-mix(in srgb, var(--panel2) 55%, transparent);
1860
+ }
1861
+ /* 搜索行:放大镜 + 输入 + Ctrl K 提示,聚焦时边框亮 accent */
1862
+ .side-search {
1863
+ display: flex; align-items: center; gap: 7px;
1864
+ border: 1px solid var(--border); border-radius: 8px;
1865
+ padding: 7px 9px; margin: 2px 0 10px; color: var(--muted);
1866
+ background: color-mix(in srgb, var(--panel2) 40%, transparent);
1867
+ transition: border-color .15s, color .15s;
1868
+ }
1869
+ .side-search:focus-within { border-color: var(--accent); color: var(--text); }
1870
+ .side-search input {
1871
+ flex: 1; min-width: 0; background: none; border: none; outline: none;
1872
+ color: var(--text); font-size: 13px; font-family: inherit; padding: 0;
1873
+ }
1874
+ .side-search input::placeholder { color: var(--muted); }
1875
+ /* 底部编排者 pill:胶囊描边(之前是隐形行),待裁决徽章点缀 */
1876
+ .foot-prov { border: 1px solid var(--border); border-radius: 999px; height: 30px; padding: 0 6px 0 10px; }
1877
+ .pbadge {
1878
+ flex: none; min-width: 16px; height: 16px; padding: 0 5px;
1879
+ border-radius: 999px; background: var(--accent); color: #fff;
1880
+ font-size: 10.5px; font-weight: 700; line-height: 16px; text-align: center;
1881
+ }
1882
+ .pbadge.hidden { display: none; }
1883
+
1884
+ /* 详情页自适应:左栏收起/检查器开合时,运行详情主区铺满可用宽度。
1885
+ * 列表类页面保持 920 阅读宽度不变;只对 sub-runs 可见时放宽,大屏封顶 1440。 */
1886
+ /* :has 依赖浏览器支持(不生效时整条静默失效)——JS 同步 .page-wide 兜底为准 */
1887
+ #page-settings.page-wide { max-width: min(1440px, 100%); }
1888
+ @supports selector(:has(*)) {
1889
+ #page-settings:has(#sub-runs:not(.hidden)) { max-width: min(1440px, 100%); }
1890
+ }
1891
+
1892
+ /* 运行详情右侧按钮区压缩:「删除记录」降为细身小按钮、右对齐、独占一行但不再
1893
+ * 满宽——破坏性动作退居视觉次要位,按钮区整体少占一截竖向空间。 */
1894
+ #btn-delete { grid-column: 1 / -1; justify-self: end; width: auto;
1895
+ padding: 4px 10px; font-size: 12px; }
1896
+
1897
+ /* ---------------- 任务类型选择器:黑白线性图标 + 自定义下拉 ----------------
1898
+ * 值真源是隐藏的 #f-type(select),这里只负责可见层外观。 */
1899
+ .type-wrap { position: relative; }
1900
+ .type-pick {
1901
+ display: flex; align-items: center; gap: 8px; width: 100%;
1902
+ padding: 8px 12px; background: var(--panel); color: var(--text);
1903
+ border: 1px solid var(--border); border-radius: 8px;
1904
+ font: inherit; font-size: 13.5px; cursor: pointer; text-align: left;
1905
+ transition: border-color .15s;
1906
+ }
1907
+ .type-pick:hover { border-color: var(--border-strong); }
1908
+ .type-pick:focus-visible { border-color: var(--accent); outline: none; }
1909
+ .type-pick .chev { margin-left: auto; width: 14px; height: 14px; color: var(--muted); transform: rotate(90deg); }
1910
+ .tp-ico { display: inline-flex; flex: none; align-items: center; color: var(--text); }
1911
+ .tp-ico .ico { width: 17px; height: 17px; }
1912
+ .tp-ico .tp-emoji { font-size: 14px; line-height: 1; }
1913
+ .tp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1914
+ .type-menu {
1915
+ position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 60;
1916
+ max-height: 316px; overflow-y: auto; padding: 5px;
1917
+ background: var(--panel); border: 1px solid var(--border-strong);
1918
+ border-radius: 10px; box-shadow: var(--shadow);
1919
+ }
1920
+ .type-item {
1921
+ display: flex; align-items: center; gap: 10px; width: 100%;
1922
+ padding: 7px 10px; border: none; border-radius: 8px;
1923
+ background: none; color: var(--text); font: inherit; font-size: 13px;
1924
+ cursor: pointer; text-align: left;
1925
+ }
1926
+ .type-item:hover { background: var(--panel2); }
1927
+ .ti-ico { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 20px; color: var(--text); }
1928
+ .ti-ico .ico { width: 17px; height: 17px; }
1929
+ .ti-ico .tp-emoji { font-size: 14px; line-height: 1; }
1930
+ .ti-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
1931
+ .ti-name { font-weight: 600; display: flex; align-items: center; gap: 6px; }
1932
+ .ti-tag {
1933
+ font-style: normal; font-weight: 500; font-size: 10.5px; color: var(--muted);
1934
+ border: 1px solid var(--border); border-radius: 999px; padding: 0 6px; line-height: 15px;
1935
+ }
1936
+ .ti-desc { color: var(--muted); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1937
+ .ti-check { flex: none; width: 15px; height: 15px; color: var(--accent); visibility: hidden; }
1938
+ .type-item.on { background: var(--panel2); }
1939
+ .type-item.on .ti-check { visibility: visible; }
1940
+ @media (max-width: 720px) {
1941
+ /* iOS Safari 聚焦输入控件 ≥16px 才不自动放大页面 */
1942
+ .type-pick { font-size: 16px; }
1943
+ }
1944
+
1945
+ /* ============================== 设置 - 自动化(定时任务 + 模板) ============================== */
1946
+ /* 低调克制:复用 .card/.tag/.toggle 语汇,只补状态色与两行截断 */
1947
+ #auto-filter { margin-bottom: 14px; }
1948
+ .card.off { opacity: .6; }
1949
+ .auto-kind {
1950
+ display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
1951
+ font-size: 12.5px; color: var(--text); margin-bottom: 8px;
1952
+ }
1953
+ .auto-prompt {
1954
+ color: var(--muted); font-size: 12.5px; line-height: 1.6; margin-bottom: 10px;
1955
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
1956
+ }
1957
+ .auto-meta {
1958
+ display: flex; flex-wrap: wrap; gap: 4px 14px;
1959
+ font-size: 12px; color: var(--muted); margin-bottom: 10px;
1960
+ }
1961
+ .auto-tag-err { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
1962
+ .auto-tag-miss { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
1963
+ .auto-tpl-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
1964
+ .auto-tpl-card .note {
1965
+ display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
1966
+ }
1967
+ .auto-tpl-card .ops { justify-content: space-between; }
1968
+ .auto-pace {
1969
+ font-size: 11px; color: var(--muted); flex: none;
1970
+ border: 1px dashed var(--border); border-radius: 6px; padding: 1px 8px;
1971
+ }
1972
+ @media (max-width: 720px) {
1973
+ .auto-tpl-grid { grid-template-columns: 1fr; }
1974
+ }
1975
+
1976
+ /* ============================== 设置 - 插件市场 ============================== */
1977
+ .mk-tools { margin-bottom: 14px; flex-wrap: wrap; }
1978
+ .mk-tools select { width: auto; flex: none; }
1979
+ .mk-meta {
1980
+ display: flex; flex-wrap: wrap; gap: 4px 14px;
1981
+ font-size: 12px; color: var(--muted); margin-bottom: 10px;
1982
+ }
1983
+ .mk-card .ops { min-height: 26px; }
1984
+
1985
+ /* ============================== 步骤「超时」状态 ==============================
1986
+ * 只是显示层细分:步骤被超时杀停记 timeout(紫色),run 级仍是 failed。
1987
+ * 芯片/圆点/glyph 与失败(红)、取消(琥珀)三色区分。 */
1988
+ .chip.timeout { background: color-mix(in srgb, var(--accent2) 16%, transparent); color: var(--accent2); }
1989
+ .sdot.timeout { background: var(--accent2); }
1990
+ .sglyph.tout { color: var(--accent2); font-size: 12px; line-height: 1; }
1991
+ /* 运行错误框的来源徽标:TIMEOUT(超时)/后续可扩展其他来源标签 */
1992
+ .err-tag {
1993
+ display: inline-block; margin-right: 6px; padding: 0 6px;
1994
+ border-radius: 4px; font-size: 11px; line-height: 18px; vertical-align: 1px;
1995
+ background: color-mix(in srgb, var(--accent2) 16%, transparent); color: var(--accent2);
1996
+ }
1997
+
1998
+ /* ---------------- 顶栏「任务详情」开合按钮 ----------------
1999
+ * 箭头方向靠 CSS 变量穿透 <use> 影子树切换(symbol 内 path 的 display 绑定变量):
2000
+ * 关着显示 ›(展开)、开着显示 ‹(收起),与面板状态严格同步。 */
2001
+ #btn-insp { --insp-chev-open: none; --insp-chev-closed: inline; }
2002
+ body.inspector-open #btn-insp { --insp-chev-open: inline; --insp-chev-closed: none; }
2003
+ body.inspector-open #btn-insp .ico { color: var(--accent); }
2004
+
2005
+ /* ============================================================ 代码设置(皮肤页)
2006
+ * 只管代码内容:文件弹窗、diff 弹窗、设置页预览卡。主题=一组 --ct-* 变量,
2007
+ * 挂在 [data-codetheme] 上(html 落当前生效值,预览卡各自拨一套即可同屏双色)。
2008
+ * 字号走 --code-size(applyCodeTheme 写根),与界面字号解耦。 */
2009
+ .cs-set-rows { margin-top: 4px; }
2010
+ .cs-row {
2011
+ display: flex; align-items: center; gap: 16px; justify-content: space-between;
2012
+ padding: 14px 2px; border-bottom: 1px solid var(--border);
2013
+ }
2014
+ .cs-row:last-child { border-bottom: none; }
2015
+ .cs-lab { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
2016
+ .cs-lab b { font-size: 13.5px; font-weight: 600; color: var(--text); }
2017
+ .cs-lab .hint { font-size: 12px; }
2018
+ .cs-row select { width: 200px; flex: none; }
2019
+ .cs-size { display: flex; align-items: center; gap: 6px; flex: none; }
2020
+ .cs-size input { width: 72px; text-align: right; }
2021
+ /* iOS 式开关:checkbox 隐形铺在轨道上,键盘可达(focus-visible 描边给轨道) */
2022
+ .cs-switch { position: relative; flex: none; width: 42px; height: 24px; cursor: pointer; }
2023
+ .cs-switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
2024
+ .cs-track {
2025
+ position: absolute; inset: 0; border-radius: 999px; background: var(--border-strong);
2026
+ transition: background .18s; pointer-events: none;
2027
+ }
2028
+ .cs-track::after {
2029
+ content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
2030
+ border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.35); transition: left .18s;
2031
+ }
2032
+ .cs-switch input:checked + .cs-track { background: var(--accent); }
2033
+ .cs-switch input:checked + .cs-track::after { left: 21px; }
2034
+ .cs-switch input:focus-visible + .cs-track { outline: 2px solid var(--accent); outline-offset: 2px; }
2035
+
2036
+ /* 双主题预览卡:浅色永远浅、深色永远深,与界面明暗无关;当前那套挂徽章 */
2037
+ .cs-previews { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
2038
+ @media (max-width: 900px) { .cs-previews { grid-template-columns: 1fr; } }
2039
+ .cs-preview { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; background: var(--card); }
2040
+ .cs-pv-head {
2041
+ display: flex; align-items: center; justify-content: space-between; gap: 10px;
2042
+ padding: 10px 14px; border-bottom: 1px solid var(--border);
2043
+ }
2044
+ .cs-pv-tt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
2045
+ .cs-pv-tt b { font-size: 13px; }
2046
+ .cs-pv-theme { font-size: 12px; color: var(--muted); }
2047
+ .cs-pv-badge { flex: none; }
2048
+ .cs-badge-on { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
2049
+ .cs-pv-code { overflow: auto; }
2050
+
2051
+ /* ---------- 代码块(行号+高亮二合一表格)与主题调色板 ---------- */
2052
+ .code-block {
2053
+ border-collapse: collapse; width: 100%; table-layout: auto;
2054
+ font-family: var(--mono); font-size: var(--code-size, 12.5px); line-height: 1.6;
2055
+ background: var(--ct-bg, var(--log-bg)); color: var(--ct-fg, var(--log-text));
2056
+ }
2057
+ .code-block td { padding: 0; vertical-align: top; }
2058
+ .cb-ln {
2059
+ display: none; width: 1%; text-align: right; user-select: none; white-space: pre;
2060
+ padding: 0 12px 0 14px; color: var(--ct-lncol, var(--muted)); opacity: .75;
2061
+ border-right: 1px solid color-mix(in srgb, var(--ct-fg, var(--text)) 10%, transparent);
2062
+ }
2063
+ html.code-linenum .cb-ln { display: table-cell; }
2064
+ .cb-code { padding: 0 14px; white-space: pre; }
2065
+ html.code-wrap .cb-code { white-space: pre-wrap; word-break: break-word; }
2066
+ .ct-kw { color: var(--ct-kw, var(--accent)); }
2067
+ .ct-str { color: var(--ct-str, var(--ok)); }
2068
+ .ct-num { color: var(--ct-num, var(--warn)); }
2069
+ .ct-com { color: var(--ct-com, var(--muted)); font-style: italic; }
2070
+ .ct-fn { color: var(--ct-fn, var(--accent2)); }
2071
+
2072
+ /* GitHub Light / Dark */
2073
+ [data-codetheme="github"] { --ct-bg:#ffffff; --ct-fg:#24292e; --ct-kw:#d73a49; --ct-str:#032f62; --ct-num:#005cc5; --ct-com:#6a737d; --ct-fn:#6f42c1; --ct-lncol:#b3b8be; }
2074
+ [data-codetheme="github-dark"] { --ct-bg:#0d1117; --ct-fg:#c9d1d9; --ct-kw:#ff7b72; --ct-str:#a5d6ff; --ct-num:#79c0ff; --ct-com:#8b949e; --ct-fn:#d2a8ff; --ct-lncol:#49515c; }
2075
+ /* Visual Studio Light / Dark */
2076
+ [data-codetheme="vs"] { --ct-bg:#f8f8f8; --ct-fg:#1f1f1f; --ct-kw:#0000ff; --ct-str:#a31515; --ct-num:#098658; --ct-com:#008000; --ct-fn:#795e26; --ct-lncol:#c2c2c2; }
2077
+ [data-codetheme="vs2015"] { --ct-bg:#1e1e1e; --ct-fg:#d4d4d4; --ct-kw:#569cd6; --ct-str:#ce9178; --ct-num:#b5cea8; --ct-com:#6a9955; --ct-fn:#dcdcaa; --ct-lncol:#5e5e5e; }
2078
+ /* Xcode Light */
2079
+ [data-codetheme="xcode"] { --ct-bg:#ffffff; --ct-fg:#333333; --ct-kw:#ad3ca9; --ct-str:#c41a16; --ct-num:#1c00cf; --ct-com:#717c69; --ct-fn:#3903a0; --ct-lncol:#c0c0c0; }
2080
+ /* Solarized Light */
2081
+ [data-codetheme="solarized"] { --ct-bg:#fdf6e3; --ct-fg:#586e75; --ct-kw:#859900; --ct-str:#2aa198; --ct-num:#d33682; --ct-com:#93a1a1; --ct-fn:#268bd2; --ct-lncol:#c8c0a8; }
2082
+ /* Monokai */
2083
+ [data-codetheme="monokai"] { --ct-bg:#272822; --ct-fg:#f8f8f2; --ct-kw:#f92672; --ct-str:#e6db74; --ct-num:#ae81ff; --ct-com:#75715e; --ct-fn:#66d9ef; --ct-lncol:#5e5d55; }
2084
+ /* One Dark */
2085
+ [data-codetheme="one-dark"] { --ct-bg:#282c34; --ct-fg:#abb2bf; --ct-kw:#c678dd; --ct-str:#98c379; --ct-num:#d19a66; --ct-com:#5c6370; --ct-fn:#61afef; --ct-lncol:#4b5263; }
2086
+
2087
+ /* diff 弹窗:行号槽(fp-no)与字号跟随代码设置 */
2088
+ #file-pop .fp-diff { font-size: var(--code-size, 12.5px); }
2089
+ #file-pop .fp-no {
2090
+ display: none; width: 2.5em; margin-right: 12px; text-align: right; user-select: none;
2091
+ color: var(--ct-lncol, var(--muted)); opacity: .8;
2092
+ }
2093
+ html.code-linenum #file-pop .fp-no { display: inline-block; }
2094
+ html.code-wrap #file-pop .fp-diff { min-width: 0; }
2095
+ html.code-wrap #file-pop .fp-ln { white-space: pre-wrap; word-break: break-word; }
2096
+ /* 卡内展开的单文件 diff(insp-diff)同步字号 */
2097
+ #insp-diff { font-size: var(--code-size, 12.5px); }
2098
+
2099
+ /* 蜂巢格/泳道圆点的超时与取消三色(取消=琥珀、超时=紫,完成不再吞掉它们) */
2100
+ .hive-cell.st-timeout { border-color: var(--accent2); }
2101
+ .hive-cell.st-timeout .hc-bee { display: none; }
2102
+ .hive-cell.st-timeout .hc-role::after { content: " ⏱"; color: var(--accent2); }
2103
+ .hive-cell.st-cancelled { border-color: var(--warn); opacity: .72; }
2104
+ .hive-cell.st-cancelled .hc-bee { display: none; }
2105
+ .hive-cell.st-cancelled .hc-role::after { content: " ⏸"; color: var(--warn); }
2106
+ .hc-dead { font-size: 12px; color: var(--muted); }
2107
+ .hive-cell.st-timeout .hc-dead { color: var(--accent2); }
2108
+ .hive-cell.st-cancelled .hc-dead { color: var(--warn); }
2109
+ .ld-cancel { background: var(--warn); opacity: .85; }
2110
+ .ld-time { background: var(--accent2); }
2111
+
2112
+ /* 主侧栏快捷入口:自动化 / 插件市场一级直达(样式对齐设置导航行,2026-09-15 参考稿布局) */
2113
+ .side-quick { display: flex; flex-direction: column; gap: 1px; margin: 4px 0 2px; }
2114
+ .qitem {
2115
+ display: flex; align-items: center; gap: 9px; text-align: left;
2116
+ background: none; border: none; color: var(--muted); padding: 7px 10px;
2117
+ border-radius: 8px; cursor: pointer; font-size: 13px; width: 100%; font-family: inherit;
2118
+ transition: background-color .15s, color .15s;
2119
+ }
2120
+ .qitem:hover { color: var(--text); background: var(--panel2); }
2121
+ .qitem:active { transform: scale(.99); }
2122
+ .qitem .ico { opacity: .9; }
2123
+
2124
+ /* ================= 运行详情页 · 标签化重构(2026-09-15,追加块) =================
2125
+ * 主栏详情从「一根长条 + 右侧窄栏」改为:头部(标题/状态/操作/统计)+ 标签分区 +
2126
+ * 贴底日志抽屉。旧 .rd-grid/.rd-side 样式保留不再被引用;本块覆盖头部与新增部件。 */
2127
+ #run-detail .detail-head { gap: 8px 10px; }
2128
+ #run-detail .detail-head h2 { flex: 1 1 auto; min-width: 160px; }
2129
+ #run-detail .rd-actions {
2130
+ display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px;
2131
+ grid-template-columns: none; margin: 0;
2132
+ }
2133
+ #run-detail .rd-actions button { width: auto; margin: 0; }
2134
+ /* 统计条:从侧栏卡片改为头部下方一行小胶囊;错误胶囊限宽省略 */
2135
+ .rd-meta-strip { margin: 0 0 12px; gap: 6px; }
2136
+ .rd-meta-strip .stat { padding: 3px 10px; border-radius: 999px; }
2137
+ .rd-meta-strip .stat.err {
2138
+ max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2139
+ }
2140
+ /* 标签条:底部一条分隔线,激活项染强调色;横向可滚(窄屏不换行) */
2141
+ .rd-tabs {
2142
+ display: flex; align-items: center; gap: 2px; flex-wrap: nowrap;
2143
+ border-bottom: 1px solid var(--border); margin-bottom: 14px;
2144
+ overflow-x: auto; scrollbar-width: none;
2145
+ }
2146
+ .rd-tabs::-webkit-scrollbar { display: none; }
2147
+ .rd-tab {
2148
+ position: relative; display: inline-flex; align-items: center; gap: 6px;
2149
+ background: none; border: none; cursor: pointer; font: inherit; font-size: 13px;
2150
+ color: var(--muted); padding: 8px 14px 10px; white-space: nowrap;
2151
+ border-radius: 8px 8px 0 0; transition: color .15s, background-color .15s;
2152
+ }
2153
+ .rd-tab:hover { color: var(--text); background: var(--panel2); }
2154
+ .rd-tab.active { color: var(--accent); font-weight: 600; }
2155
+ .rd-tab.active::after {
2156
+ content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px;
2157
+ height: 2px; border-radius: 2px; background: var(--accent);
2158
+ }
2159
+ .rd-badge {
2160
+ display: inline-flex; align-items: center; padding: 1px 7px; border-radius: 999px;
2161
+ font-size: 11px; font-weight: 600; font-family: var(--mono);
2162
+ background: var(--panel2); border: 1px solid var(--border); color: var(--muted);
2163
+ }
2164
+ .rd-tab.active .rd-badge { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
2165
+ .rd-badge.verdict {
2166
+ color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent);
2167
+ background: color-mix(in srgb, var(--warn) 10%, transparent);
2168
+ }
2169
+ /* 分区容器:隐性时由 .hidden 接管;主容器不再做两栏网格 */
2170
+ #run-detail .rd-main { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
2171
+ /* 日志抽屉:贴详情卡底部悬浮(sticky bottom),任何分区下点开都看得见 */
2172
+ #rd-log.rd-logdrawer {
2173
+ position: sticky; bottom: 10px; z-index: 5; max-height: 42vh;
2174
+ margin: 4px 2px 2px; box-shadow: 0 8px 28px rgba(0, 0, 0, .38);
2175
+ border-color: var(--border-strong);
2176
+ }
2177
+ /* 成品文件在「成果」分区里的呈现(与检查器同标记,间距对齐分区节奏) */
2178
+ .rd-arts .files-head { display: flex; align-items: center; gap: 10px; margin: 4px 0 8px; flex-wrap: wrap; }
2179
+ .rd-arts .files-head .wd {
2180
+ font-family: var(--mono); font-size: 11.5px; color: var(--muted); cursor: pointer;
2181
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
2182
+ }
2183
+ .rd-arts .file-chips { display: flex; flex-direction: column; gap: 6px; }
2184
+ .rd-pane .rd-hive { margin-top: 0; }
2185
+ .rd-pane .steps { margin-bottom: 0; }
2186
+ .rd-pane .report { margin-bottom: 0; }
2187
+ /* 窄屏:操作按钮折到标题下方整行,标签条保持横滚 */
2188
+ @media (max-width: 1100px) {
2189
+ #run-detail .detail-head .rd-actions { flex-basis: 100%; justify-content: flex-start; }
2190
+ #run-detail .detail-head h2 { order: -1; flex-basis: 100%; }
2191
+ }
2192
+
2193
+ /* 皮肤页锚点胶囊:吸顶跟随(滚动容器是 main,sticky 相对 subpage 生效) */
2194
+ .cs-anchor {
2195
+ position: sticky; top: -14px; z-index: 5;
2196
+ align-self: flex-start; margin: 0 0 12px;
2197
+ background: color-mix(in srgb, var(--bg) 88%, transparent);
2198
+ backdrop-filter: blur(6px);
2199
+ padding: 3px; border-radius: 999px;
2200
+ }
2201
+ /* 锚点滚动的落点余量:面板顶不被 sticky 胶囊压住 */
2202
+ #apn-skin, #apn-code { scroll-margin-top: 8px; }
2203
+
2204
+ /* ============================== 采访式向导(新建任务) ============================== */
2205
+ .hero-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
2206
+ .wz-goal, .wz-input { width: 100%; }
2207
+ .wz-flows { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
2208
+ .wz-flow {
2209
+ display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
2210
+ padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
2211
+ background: var(--panel2); cursor: pointer; text-align: left; width: 100%;
2212
+ }
2213
+ .wz-flow:hover { border-color: var(--border-strong); }
2214
+ .wz-flow.on {
2215
+ border-color: var(--accent);
2216
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
2217
+ }
2218
+ .wz-flow .ico { width: 18px; height: 18px; }
2219
+ .wz-fname { font-weight: 600; }
2220
+ .wz-fdesc { font-size: 12px; color: var(--muted); }
2221
+ .wz-sum { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; }
2222
+ .wz-sum > div { display: flex; gap: 10px; align-items: baseline; }
2223
+ .wz-k { flex: none; width: 64px; font-size: 12px; color: var(--muted); }
2224
+
2225
+ /* ============ 命令面板(Ctrl+K / 侧栏搜索行唤起)============ */
2226
+ .cmdk-mask {
2227
+ position: fixed; inset: 0; z-index: 300;
2228
+ background: rgba(0, 0, 0, .45); backdrop-filter: blur(2px);
2229
+ display: flex; align-items: flex-start; justify-content: center; padding-top: 11vh;
2230
+ }
2231
+ .cmdk-mask.hidden { display: none; }
2232
+ .cmdk {
2233
+ width: min(560px, 92vw); max-height: 68vh;
2234
+ display: flex; flex-direction: column;
2235
+ background: var(--panel); border: 1px solid var(--border-strong); border-radius: 14px;
2236
+ box-shadow: var(--shadow), 0 18px 48px rgba(0, 0, 0, .35);
2237
+ overflow: hidden;
2238
+ }
2239
+ .cmdk-input { display: flex; align-items: center; gap: 9px; padding: 13px 14px; border-bottom: 1px solid var(--border); color: var(--muted); }
2240
+ .cmdk-input input { flex: 1; min-width: 0; background: none; border: none; outline: none; color: var(--text); font-size: 14.5px; font-family: inherit; padding: 0; }
2241
+ .cmdk-input input::placeholder { color: var(--muted); }
2242
+ .cmdk-tabs { display: flex; gap: 6px; padding: 10px 14px 4px; }
2243
+ .cmdk-tabs button {
2244
+ background: none; border: none; color: var(--muted); font-size: 12.5px;
2245
+ padding: 4px 10px; border-radius: 999px; cursor: pointer; font-family: inherit;
2246
+ }
2247
+ .cmdk-tabs button.on { color: var(--text); background: var(--panel2); font-weight: 600; }
2248
+ .cmdk-list { overflow-y: auto; padding: 6px 8px 10px; min-height: 120px; }
2249
+ .cmdk-sec { color: var(--muted); font-size: 11px; letter-spacing: .05em; padding: 10px 8px 4px; }
2250
+ .cmdk-item {
2251
+ display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px;
2252
+ cursor: pointer; color: var(--text); font-size: 13.5px;
2253
+ }
2254
+ .cmdk-item .ico { color: var(--muted); }
2255
+ .cmdk-item:hover { background: var(--panel2); }
2256
+ .cmdk-item.on { background: var(--panel2); }
2257
+ .cmdk-item.on .ico { color: var(--accent); }
2258
+ .cmdk-item .l { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2259
+ .cmdk-item .tm { flex: none; color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
2260
+ .cmdk-empty { color: var(--muted); text-align: center; padding: 28px 0 20px; font-size: 13px; }
2261
+ /* 侧栏搜索行 = 命令面板触发按钮(去边框,安静行式样,2026-09-15 用户反馈) */
2262
+ button.side-search {
2263
+ width: 100%; text-align: left; font-family: inherit; cursor: pointer;
2264
+ border: none; background: none; margin: 4px 0 2px;
2265
+ }
2266
+ button.side-search:hover { color: var(--text); background: var(--panel2); border: none; }
2267
+ button.side-search .ss-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2268
+
2269
+ /* ---- 日志抽屉 v2:贴底停靠的控制台样式 + 步骤标题(2026-09-15 追加) ----
2270
+ * 旧样式是「浮在内容上的黑框」,边缘无依、没有标题,像临时贴上去的;
2271
+ * 改为停靠底部的控制台:头部条(步骤名+实时徽章+关闭)与正文分栏、圆角只留上方。 */
2272
+ #run-detail #rd-log.rd-logdrawer {
2273
+ position: sticky; bottom: 0; z-index: 5;
2274
+ display: flex; flex-direction: column;
2275
+ max-height: 46vh; margin: 4px 0 0; padding: 0;
2276
+ border: 1px solid var(--border-strong); border-bottom: none;
2277
+ border-radius: 10px 10px 0 0;
2278
+ box-shadow: 0 -6px 24px rgba(0, 0, 0, .28);
2279
+ overflow: hidden;
2280
+ }
2281
+ #run-detail #rd-log.rd-logdrawer .log-live-bar {
2282
+ position: static; margin: 0; padding: 7px 12px;
2283
+ background: var(--panel2); border-bottom: 1px solid var(--border);
2284
+ backdrop-filter: none;
2285
+ }
2286
+ #run-detail #rd-log.rd-logdrawer pre {
2287
+ flex: 1; min-height: 120px; max-height: calc(46vh - 36px);
2288
+ margin: 0; padding: 10px 14px; overflow: auto;
2289
+ }
2290
+ .rd-log-step {
2291
+ font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--text);
2292
+ max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2293
+ }
2294
+ .rd-log-x { padding: 2px 7px; flex: none; }
2295
+ .rd-log-x .ico { width: 13px; height: 13px; }
2296
+ /* 指挥信箱回归蜂巢分区:蜂巢+指挥=运行驾驶舱;输入区贴卡片底 */
2297
+ .rd-pane .rd-direct { margin-top: 2px; }
2298
+ .rd-pane .rd-direct .rd-composer { margin-top: 8px; }
2299
+
2300
+ /* ===== 侧栏文件浏览页(右键文件夹「查看文件」:左栏整页切到该目录文件树) ===== */
2301
+ .side-files { display: none; flex-direction: column; flex: 1; min-height: 0; padding: 0 6px 8px; }
2302
+ body.files-mode .side-main,
2303
+ body.files-mode .side-settings { display: none; }
2304
+ body.files-mode .side-files { display: flex; }
2305
+ .side-files .set-back { margin: 8px 4px 4px; }
2306
+ .sf-head {
2307
+ display: flex; align-items: center; gap: 7px; padding: 7px 10px;
2308
+ border-bottom: 1px solid var(--border); margin-bottom: 6px;
2309
+ }
2310
+ .sf-head .ico { color: var(--accent); flex: none; }
2311
+ .sf-title { font-size: 13px; font-weight: 700; flex: 1; min-width: 0;
2312
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2313
+ .sf-count { font-size: 10.5px; color: var(--muted); flex: none; }
2314
+ .sf-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 1px; }
2315
+ .sf-msg { font-size: 12px; color: var(--muted); padding: 10px; }
2316
+ .sf-msg.sf-error { color: var(--bad); }
2317
+ .sf-note { font-size: 11px; color: var(--muted); padding: 8px 10px 2px; }
2318
+ details.sf-dir > summary,
2319
+ a.sf-file {
2320
+ display: flex; align-items: center; gap: 7px; border-radius: 7px; cursor: pointer;
2321
+ padding: 4px 8px 4px calc(8px + var(--sf-d, 0) * 14px);
2322
+ font-size: 12.5px; color: var(--text); text-decoration: none; user-select: none;
2323
+ list-style: none; min-width: 0;
2324
+ }
2325
+ details.sf-dir > summary::-webkit-details-marker { display: none; }
2326
+ details.sf-dir > summary::before {
2327
+ content: "▸"; font-size: 9px; color: var(--muted); flex: none;
2328
+ transition: transform .12s ease;
2329
+ }
2330
+ details.sf-dir[open] > summary::before { transform: rotate(90deg); }
2331
+ details.sf-dir > summary:hover, a.sf-file:hover { background: var(--panel2); }
2332
+ details.sf-dir > summary .ico, a.sf-file .ico { width: 13px; height: 13px; flex: none; color: var(--muted); }
2333
+ details.sf-dir > summary span, a.sf-file span {
2334
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2335
+ }
2336
+ details.sf-dir > summary i, a.sf-file i { font-style: normal; color: var(--muted); font-size: 10px; flex: none; }
2337
+
2338
+ /* ================= 使用统计:多模型折线 / 热力图 / 甜甜圈 =================
2339
+ * 六色板全部从主题已有变量派生(皮肤与明暗自动适配),不逐皮肤配值。 */
2340
+ :root {
2341
+ --uch-1: var(--accent);
2342
+ --uch-2: var(--ok);
2343
+ --uch-3: var(--accent2);
2344
+ --uch-4: var(--warn);
2345
+ --uch-5: var(--bad);
2346
+ --uch-6: color-mix(in srgb, var(--accent) 52%, var(--ok));
2347
+ }
2348
+ .um-legend {
2349
+ display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
2350
+ margin: 2px 0 6px; font-size: 12px; color: var(--muted);
2351
+ }
2352
+ .um-legend span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
2353
+ .um-legend i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
2354
+ .um-legend .um-peak { margin-left: auto; font-weight: 600; color: var(--muted); }
2355
+
2356
+ /* Token 活动热力图 */
2357
+ .usage-heat-head {
2358
+ display: flex; align-items: center; justify-content: space-between;
2359
+ gap: 12px; margin: 2px 0 6px;
2360
+ }
2361
+ .usage-heat-scale { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--muted); }
2362
+ .usage-heat-scale i { width: 10px; height: 10px; border-radius: 2.5px; }
2363
+ .usage-heat-scale .hs0 { background: color-mix(in srgb, var(--text) 7%, transparent); }
2364
+ .usage-heat-scale .hs1 { background: color-mix(in srgb, var(--accent) 30%, var(--panel)); }
2365
+ .usage-heat-scale .hs2 { background: color-mix(in srgb, var(--accent) 55%, var(--panel)); }
2366
+ .usage-heat-scale .hs3 { background: color-mix(in srgb, var(--accent) 78%, var(--panel)); }
2367
+ .usage-heat-scale .hs4 { background: var(--accent); }
2368
+ .usage-heat-svg { width: 100%; max-height: 130px; }
2369
+ .uh-h0 { fill: color-mix(in srgb, var(--text) 7%, transparent); }
2370
+ .uh-h1 { fill: color-mix(in srgb, var(--accent) 30%, var(--panel)); }
2371
+ .uh-h2 { fill: color-mix(in srgb, var(--accent) 55%, var(--panel)); }
2372
+ .uh-h3 { fill: color-mix(in srgb, var(--accent) 78%, var(--panel)); }
2373
+ .uh-h4 { fill: var(--accent); }
2374
+ .uh-mon { fill: var(--muted); font-size: 10px; }
2375
+
2376
+ /* 模型用量甜甜圈 */
2377
+ .usage-donut { display: flex; align-items: center; gap: 30px; padding: 6px 0 2px; }
2378
+ .ud-ring { width: 190px; height: 190px; flex: none; }
2379
+ .ud-ring .ud-seg { transition: opacity .12s; }
2380
+ .ud-ring:hover .ud-seg:not(:hover) { opacity: .35; }
2381
+ .ud-total { fill: var(--text); font-size: 21px; font-weight: 700; }
2382
+ .ud-unit { fill: var(--muted); font-size: 11px; }
2383
+ .ud-list { flex: 1; min-width: 0; display: flex; flex-direction: column; }
2384
+ .ud-row {
2385
+ display: flex; align-items: center; gap: 10px; padding: 8px 2px;
2386
+ border-bottom: 1px solid var(--border);
2387
+ }
2388
+ .ud-row:last-child { border-bottom: 0; }
2389
+ .ud-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
2390
+ .ud-name {
2391
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2392
+ font-size: 13px; color: var(--text);
2393
+ }
2394
+ .ud-name small { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }
2395
+ .ud-pct { font-family: var(--mono); font-size: 13px; color: var(--muted); flex: none; }
2396
+
2397
+ /* 页内标题旁的小徽章(「使用统计 · 应用用量」) */
2398
+ .badge2 {
2399
+ display: inline-block; vertical-align: 3px; margin-left: 8px;
2400
+ padding: 2px 9px; border-radius: 999px;
2401
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
2402
+ color: var(--accent); font-size: 12px; font-weight: 600; line-height: 1.5;
2403
+ }
2404
+ @media (max-width: 720px) {
2405
+ .usage-donut { flex-direction: column; gap: 10px; }
2406
+ .ud-ring { width: 160px; height: 160px; }
2407
+ }
2408
+
2409
+ /* —— 详情页 meta 条:任务累计 pill(run 级统计旁的全貌,side 数据驱动) —— */
2410
+ .rd-meta-strip .stat.tasksum {
2411
+ border-left: 2px solid var(--accent);
2412
+ border-radius: 4px 999px 999px 4px;
2413
+ color: var(--text-2, var(--text));
2414
+ }
2415
+
2416
+ /* ---------------------------------------------------------- 供应商健康告警横幅 */
2417
+ .health-banner {
2418
+ margin-left: 10px;
2419
+ padding: 3px 10px;
2420
+ border-radius: 999px;
2421
+ font-size: 12px;
2422
+ font-weight: 600;
2423
+ cursor: pointer;
2424
+ white-space: nowrap;
2425
+ overflow: hidden;
2426
+ text-overflow: ellipsis;
2427
+ max-width: 40vw;
2428
+ user-select: none;
2429
+ }
2430
+ .health-banner.alerting {
2431
+ background: rgba(220, 38, 38, 0.14);
2432
+ color: #dc2626;
2433
+ border: 1px solid rgba(220, 38, 38, 0.45);
2434
+ animation: health-pulse 2s ease-in-out infinite;
2435
+ }
2436
+ .health-banner.recovered {
2437
+ background: rgba(34, 197, 94, 0.12);
2438
+ color: #16a34a;
2439
+ border: 1px solid rgba(34, 197, 94, 0.4);
2440
+ }
2441
+ @keyframes health-pulse {
2442
+ 0%, 100% { opacity: 1; }
2443
+ 50% { opacity: 0.55; }
2444
+ }
2445
+
2446
+ /* 插件市场:本地/外部目录视图切换与外部条目(追加于文件尾,防并行重排) */
2447
+ .mk-view { margin: 2px 0 12px; }
2448
+ .mk-card.blocked { opacity: 0.55; }
2449
+ .mk-src { background: var(--accent-soft, rgba(64, 150, 238, 0.14)); color: var(--accent, #4096ee); }
2450
+ .mkr-meta { margin: -2px 0 8px; }
2451
+
2452
+ /* ---- 供应商健康告警弹框:禁用厂商的危险按钮 ---- */
2453
+ .modal-foot button.danger {
2454
+ background: rgba(220, 38, 38, 0.12);
2455
+ color: #dc2626;
2456
+ border: 1px solid rgba(220, 38, 38, 0.45);
2457
+ }
2458
+ .modal-foot button.danger:hover { background: rgba(220, 38, 38, 0.22); }
2459
+
2460
+ /* 运行中指挥:未消费指令的撤回按钮(贴右侧,hover 提亮) */
2461
+ .rd-msg .m-retract { float: right; margin-left: 8px; padding: 0 7px; font-size: 11.5px; opacity: .8; }
2462
+ .rd-msg .m-retract:hover { opacity: 1; color: #dc2626; border-color: rgba(220, 38, 38, .45); }
2463
+
2464
+ /* 外部目录滚动分页:续页提示行 + 哨兵(追加于文件尾,防并行重排) */
2465
+ .mkr-more { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 10px 0 2px; }
2466
+ .mkr-more.hidden { display: none; }
2467
+ .mkr-sentinel { height: 1px; }
2468
+
2469
+
2470
+ /* 顶栏左上角更新胶囊(追加于文件尾,防并行重排):有新版才出现,点击进「关于与更新」 */
2471
+ .upd-pill { background: color-mix(in srgb, var(--accent) 18%, transparent);
2472
+ border-color: var(--accent); color: var(--text); gap: 5px; padding: 5px 10px; }
2473
+ .upd-pill:hover { background: color-mix(in srgb, var(--accent) 30%, transparent); }
2474
+ .upd-pill .upd-x { display: inline-flex; align-items: center; opacity: .65;
2475
+ border-radius: 50%; padding: 1px; }
2476
+ .upd-pill .upd-x:hover { opacity: 1; background: color-mix(in srgb, var(--text) 15%, transparent); }
2477
+ .upd-pill .upd-x .ico { width: 11px; height: 11px; }
2478
+ .upd-pill.hidden { display: none; }
2479
+
2480
+ /* ============ Composer 化新建任务(2026-09-16):胶囊行 + 大输入框 + 快捷 chips ============ */
2481
+ /* 胶囊行:类型(复用 .type-pick 外观,宽度收成 auto)+ 目录(图标 + 无边框输入 + 选择…)。
2482
+ 值真源仍是 #f-type / #f-workdir,这里只是排版层。 */
2483
+ .cmp-pills { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
2484
+ .cmp-pills .type-pick { width: auto; min-width: 120px; border-radius: 999px; padding: 6px 12px; font-size: 13px; background: var(--bg); }
2485
+ .cmp-pills .type-pick .chev { width: 12px; height: 12px; }
2486
+ .cmp-wd { display: inline-flex; align-items: center; gap: 6px; min-width: 0; flex: 1 1 240px;
2487
+ border: 1px solid var(--border); border-radius: 999px; padding: 2px 6px 2px 12px; background: var(--bg);
2488
+ transition: border-color .15s; }
2489
+ .cmp-wd:hover { border-color: var(--border-strong); }
2490
+ .cmp-wd > .ico { width: 14px; height: 14px; color: var(--muted); flex: none; }
2491
+ .cmp-wd .input-row { flex: 1; min-width: 0; gap: 4px; }
2492
+ .cmp-wd input { border: none; background: transparent; padding: 6px 4px; font-size: 13px; }
2493
+ .cmp-wd input:hover, .cmp-wd input:focus { border: none; }
2494
+ .cmp-wd .ghost.small { padding: 3px 9px; font-size: 11.5px; border-radius: 999px; flex: none; }
2495
+ .cmp-hint { margin: 0 2px 10px; font-size: 11.5px; }
2496
+ .cmp-hint:empty { display: none; }
2497
+ /* 大输入框:无边框 textarea + 底部工具条,整体一个圆角卡片,聚焦时描边点亮 */
2498
+ .cmp-box { border: 1px solid var(--border); border-radius: 14px; background: var(--panel);
2499
+ padding: 4px 6px 6px 6px; transition: border-color .15s, box-shadow .15s; }
2500
+ .cmp-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent); }
2501
+ .cmp-box textarea { border: none; background: transparent; resize: none; padding: 10px 8px 4px;
2502
+ font-size: 15px; line-height: 1.6; min-height: 64px; }
2503
+ .cmp-box textarea:hover, .cmp-box textarea:focus { border: none; box-shadow: none; }
2504
+ .cmp-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding: 0 4px; }
2505
+ .cmp-bar .att-strip { margin-top: 0; }
2506
+ .cmp-send { display: flex; align-items: center; gap: 10px; margin-left: auto; }
2507
+ #btn-create.round { width: 34px; height: 34px; border-radius: 50%; padding: 0; display: inline-flex;
2508
+ align-items: center; justify-content: center; flex: none; }
2509
+ #btn-create.round .ico { width: 17px; height: 17px; }
2510
+ /* 快捷类型 chips:内置流程一键选定(选中态 .on) */
2511
+ .cmp-quick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 2px 2px; }
2512
+ .cmp-quick:empty { display: none; }
2513
+ .cmp-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px;
2514
+ border: 1px solid var(--border); border-radius: 999px; background: var(--bg); color: var(--text);
2515
+ font: inherit; font-size: 12.5px; cursor: pointer; transition: border-color .15s, background .15s; }
2516
+ .cmp-chip:hover { border-color: var(--border-strong); }
2517
+ .cmp-chip .ico { width: 14px; height: 14px; color: var(--muted); }
2518
+ .cmp-chip.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg)); }
2519
+ .cmp-chip.on .ico { color: var(--accent); }
2520
+ @media (max-width: 720px) {
2521
+ .cmp-pills { gap: 6px; }
2522
+ .cmp-wd { flex-basis: 100%; }
2523
+ }
2524
+
2525
+ /* ---------------- 作品信息(独立 TAB:番茄/七猫平台卡片,字段内联逐条复制) ---------------- */
2526
+ .rd-bookmeta { padding: 2px 0 20px; max-width: 1180px; }
2527
+ .bm-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
2528
+ .bm-head .ico { color: var(--accent); }
2529
+ .bm-head .hint { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2530
+ .bm-warn { color: var(--warn); font-size: 12px; flex: none; }
2531
+ .bm-guide { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; margin-bottom: 16px;
2532
+ border: 1px solid var(--line); border-radius: var(--r-md); background: var(--panel); }
2533
+ .bm-guide .ico { flex: none; margin-top: 1px; width: 18px; height: 18px; color: var(--accent); }
2534
+ .bm-guide b { color: var(--text); font-size: 13.5px; font-weight: 600; }
2535
+ .bm-guide p { margin: 5px 0 0; font-size: 12.5px; line-height: 1.75; color: var(--muted); }
2536
+
2537
+ /* 平台卡片:两列自适应;窄屏自动堆叠 */
2538
+ .bm-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 16px; }
2539
+ .bm-card { display: flex; flex-direction: column; border: 1px solid var(--line);
2540
+ border-radius: var(--r-md); background: var(--panel); overflow: hidden; min-width: 0; }
2541
+ .bm-card.st-running { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
2542
+ .bm-card-head { display: flex; align-items: center; gap: 10px; padding: 11px 16px;
2543
+ background: var(--panel2); border-bottom: 1px solid var(--line); }
2544
+ .bm-plat-name { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; font-size: 13.5px; }
2545
+ .bm-plat-name .ico { width: 15px; height: 15px; color: var(--accent); }
2546
+ .bm-st { flex: none; font-size: 11.5px; line-height: 1; padding: 4px 9px; border-radius: 999px;
2547
+ border: 1px solid var(--line); color: var(--muted); }
2548
+ .bm-st.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent);
2549
+ background: color-mix(in srgb, var(--ok) 12%, transparent); }
2550
+ .bm-st.run { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent);
2551
+ background: color-mix(in srgb, var(--accent) 12%, transparent); animation: bm-pulse 1.6s ease-in-out infinite; }
2552
+ .bm-st.bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent);
2553
+ background: color-mix(in srgb, var(--bad) 12%, transparent); }
2554
+ @keyframes bm-pulse { 50% { opacity: .5; } }
2555
+ .bm-card-head button { font-size: 12.5px; padding: 4px 11px; }
2556
+
2557
+ /* 字段区:标签固定宽右对齐、值占满;行 hover 才点亮复制按钮(默认低调不抢视线) */
2558
+ .bm-fields { padding: 4px 16px 12px; }
2559
+ .bm-f { display: flex; align-items: baseline; gap: 12px; padding: 9px 0;
2560
+ border-bottom: 1px solid var(--line); min-width: 0; }
2561
+ .bm-f:last-child { border-bottom: 0; padding-bottom: 4px; }
2562
+ .bm-f-k { flex: none; width: 5.2em; color: var(--muted); font-size: 12px; text-align: right; }
2563
+ .bm-f-v { flex: 1 1 auto; min-width: 0; font-size: 13.5px; line-height: 1.65; color: var(--text);
2564
+ word-break: break-all; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2565
+ .bm-f-v.bm-f--scroll { max-height: 7.5em; overflow-y: auto; white-space: pre-wrap;
2566
+ text-overflow: clip; font-size: 13px; line-height: 1.75; }
2567
+ .bm-chips { flex: 1 1 auto; display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
2568
+ .bm-chip { font-size: 12px; line-height: 1; padding: 5px 10px; border-radius: 999px;
2569
+ background: var(--panel2); border: 1px solid var(--line); color: var(--text); }
2570
+
2571
+ /* 复制按钮:图标 + 文字,默认淡出,行 hover / 键盘聚焦时点亮 */
2572
+ .bm-copy { flex: none; display: inline-flex; align-items: center; gap: 4px;
2573
+ font-size: 11.5px; line-height: 1; padding: 4px 8px; border-radius: var(--r-sm);
2574
+ border: 1px solid transparent; background: none; color: var(--muted); cursor: pointer;
2575
+ opacity: .55; transition: opacity .15s, color .15s, background .15s, border-color .15s; }
2576
+ .bm-copy .ico { width: 12px; height: 12px; }
2577
+ .bm-f:hover .bm-copy { opacity: 1; }
2578
+ .bm-copy:hover, .bm-copy:focus-visible { color: var(--accent); border-color: var(--line);
2579
+ background: var(--panel2); opacity: 1; }
2580
+ .bm-copy:active { transform: translateY(1px); }
2581
+
2582
+ /* 生成中骨架屏 */
2583
+ .bm-skwrap { padding: 6px 16px 14px; }
2584
+ .bm-sk { display: flex; gap: 12px; align-items: center; padding: 9px 0;
2585
+ border-bottom: 1px solid var(--line); }
2586
+ .bm-sk:last-child { border-bottom: 0; }
2587
+ .bm-sk-l { flex: none; width: 5.2em; height: 9px; border-radius: 5px; background: var(--line); }
2588
+ .bm-sk-v { flex: 1 1 auto; height: 9px; border-radius: 5px; background: var(--line);
2589
+ opacity: .55; animation: bm-pulse 1.6s ease-in-out infinite; }
2590
+ .bm-empty { color: var(--muted); font-size: 13px; padding: 16px; text-align: center; }
2591
+ .bm-errhint { color: var(--bad); font-size: 12.5px; line-height: 1.7; padding: 14px 16px;
2592
+ word-break: break-all; }
2593
+ .bm-src { color: var(--muted); font-size: 11.5px; padding: 9px 16px; border-top: 1px solid var(--line);
2594
+ background: var(--panel2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2595
+ .rd-bookmeta .ico.spin { animation: ico-spin 1.2s linear infinite; }
2596
+
2597
+ /* 文件内容弹窗·文本预览/编辑(目录文件弹窗专属):
2598
+ * 同一个 .fp-code 稳定高度盒子——预览层与编辑层共用,切换不跳变;
2599
+ * 观感对齐设置页代码主题预览卡(圆角卡片、跟随主题/字号/行号/换行设置) */
2600
+ #file-pop .fp-code {
2601
+ display: flex; flex-direction: column;
2602
+ height: min(62vh, 620px); margin: 10px 12px;
2603
+ border: 1px solid var(--border); border-radius: var(--r-md, 10px);
2604
+ overflow: hidden; flex: none;
2605
+ }
2606
+ #file-pop .fp-vp { flex: 1; min-height: 0; overflow: auto; }
2607
+ #file-pop .fp-edit {
2608
+ display: block; flex: 1; width: 100%; min-height: 0; border: none; border-radius: 0;
2609
+ background: var(--ct-bg, var(--log-bg)); color: var(--ct-fg, var(--log-text));
2610
+ font-family: var(--mono); font-size: var(--code-size, 12.5px); line-height: 1.6;
2611
+ padding: 10px 14px; resize: none; outline: none; white-space: pre;
2612
+ overflow: auto;
2613
+ }
2614
+ /* 设置里开了「代码换行」→ 编辑框同样换行,两边观感一致 */
2615
+ html.code-wrap #file-pop .fp-edit { white-space: pre-wrap; word-break: break-word; }
2616
+
2617
+ /* ============================== 顶栏语言快捷切换 ============================== */
2618
+ /* 地球按钮 + 原生语名下拉;语言名(中文/English)永远用母语,不做 i18n */
2619
+ .lang-wrap { position: relative; display: inline-flex; }
2620
+ .lang-menu {
2621
+ position: absolute; top: calc(100% + 8px); right: 0; z-index: 80;
2622
+ min-width: 150px; padding: 5px;
2623
+ background: var(--panel); border: 1px solid var(--border-strong);
2624
+ border-radius: 10px; box-shadow: var(--shadow);
2625
+ }
2626
+ .lang-item {
2627
+ display: flex; align-items: center; gap: 8px; width: 100%;
2628
+ padding: 7px 10px; border: none; border-radius: 8px;
2629
+ background: none; color: var(--text); font: inherit; font-size: 13px;
2630
+ cursor: pointer; text-align: left;
2631
+ }
2632
+ .lang-item:hover { background: var(--panel2); }
2633
+ .lang-item .li-check { margin-left: auto; width: 15px; height: 15px; color: var(--accent); visibility: hidden; }
2634
+ .lang-item.on { background: var(--panel2); }
2635
+ .lang-item.on .li-check { visibility: visible; }
2636
+
2637
+ /* ---------------- GIT 工作台(详情页 Git 页签) ----------------
2638
+ * 追加在文件尾:分支下拉 / 工具条 / 三组变更行(悬停操作钮)/ 提交区 / 时间线 */
2639
+ .rd-git .gwb-branch { flex: none; max-width: 220px; height: 24px; font-size: 12px;
2640
+ font-family: var(--mono); background: var(--panel2); color: var(--text);
2641
+ border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; cursor: pointer; }
2642
+ .rd-git .gwb-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
2643
+ .rd-git .gwb-toolbar button { font-size: 12px; padding: 3px 10px; }
2644
+ .rd-git .gwb-toolbar .hint { font-size: 12px; }
2645
+ .rd-git .gwb-group { margin-top: 10px; }
2646
+ .rd-git .gwb-ghead { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
2647
+ .rd-git .gwb-ghead b { color: var(--text); font-weight: 600; }
2648
+ .rd-git .gwb-row { display: flex; align-items: center; gap: 4px; }
2649
+ .rd-git .gwb-row .gf { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px;
2650
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2651
+ .rd-git .gwb-row .gf .p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2652
+ .rd-git .gwb-act { flex: none; width: 22px; height: 22px; padding: 0; font-size: 13px; line-height: 1;
2653
+ visibility: hidden; border-radius: 5px; }
2654
+ .rd-git .gwb-row:hover .gwb-act { visibility: visible; }
2655
+ .rd-git .gwb-act.gwb-danger:hover { color: var(--bad); border-color: var(--bad); }
2656
+ .rd-git .gwb-commit { display: flex; gap: 8px; margin-top: 12px; }
2657
+ .rd-git .gwb-commit input { flex: 1 1 auto; min-width: 0; background: var(--panel2); color: var(--text);
2658
+ border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; font: inherit; font-size: 13px; }
2659
+ .rd-git .gwb-commit input:focus { outline: none; border-color: var(--accent); }
2660
+ .rd-git .gwb-log { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 8px; }
2661
+ .rd-git .gwb-lc { display: flex; align-items: baseline; gap: 8px; font-size: 12px; padding: 2px 0; min-width: 0; }
2662
+ .rd-git .gwb-lc code { font-family: var(--mono); color: var(--accent); flex: none; }
2663
+ .rd-git .gwb-lc .p { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2664
+ .rd-git .gwb-lc .gm { flex: none; color: var(--muted); }
2665
+ .rd-git .gwb-stash { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-top: 6px; }
2666
+ .rd-git .gwb-stash .p { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
2667
+ .rd-git .gwb-stash button { font-size: 12px; padding: 2px 8px; }
2668
+ .rd-bookmeta .ico.spin { animation: ico-spin 1.2s linear infinite; }
2669
+
2670
+ /* 市场外部目录工具行:四个控件严格同高(34px)垂直居中(追加于文件尾) */
2671
+ .mk-tools { align-items: center; }
2672
+ .mk-tools input[type="search"] {
2673
+ width: 320px; flex: none; height: 34px; box-sizing: border-box; padding: 0 12px;
2674
+ }
2675
+ .mk-tools .ghost.small,
2676
+ .mk-tools select {
2677
+ height: 34px; box-sizing: border-box; padding-top: 0; padding-bottom: 0; line-height: 1;
2678
+ }
2679
+ .mk-tools .ghost.small { display: inline-flex; align-items: center; gap: 5px; padding-left: 12px; padding-right: 12px; }
2680
+ .mk-tools .ghost.small .ico { width: 14px; height: 14px; }
2681
+ .mk-tools input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
2682
+
2683
+ /* 类型菜单宽度不再锁死胶囊:胶囊窄化后菜单被挤成两字宽,描述全截断。
2684
+ 固定舒适宽度 + 左对齐弹出(胶囊在面板左侧,向右展开空间充足)。 */
2685
+ .type-menu { left: 0; right: auto; width: 320px; max-width: min(380px, calc(100vw - 32px)); }
2686
+ .type-item { padding: 8px 11px; border-radius: 9px; }
2687
+ .ti-name { font-size: 13.5px; }
2688
+ .ti-desc { font-size: 11.5px; opacity: .85; }
2689
+ .type-item.on { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); }
2690
+
2691
+ /* 多 KEY(同厂商多密钥):顺序即调用顺序;样式复用 .prow 的行语言 */
2692
+ .keys-box { margin: 10px 0 4px; border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; background: var(--panel); }
2693
+ .keys-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
2694
+ .keys-head b { font-size: 12.5px; }
2695
+ .keys-box .krow { display: flex; align-items: center; gap: 8px; background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; margin-bottom: 5px; }
2696
+ .keys-box .krow:hover { border-color: var(--border-strong); }
2697
+ .keys-box .krow.off { opacity: .5; }
2698
+ .keys-box .krow.dragging { opacity: .4; }
2699
+ .keys-box .krow.drag-over { border-color: var(--accent); border-style: dashed; }
2700
+ .keys-box .krow .drag { cursor: grab; color: var(--muted); opacity: .35; transition: opacity .12s; }
2701
+ .keys-box .krow:hover .drag { opacity: 1; }
2702
+ .keys-box .krow .pprio { font-family: var(--mono); font-size: 11px; color: var(--accent); min-width: 26px; }
2703
+ .keys-box .klabel { font-size: 12.5px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2704
+ .keys-box .kval { font-family: var(--mono); font-size: 11.5px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2705
+ .keys-box .krow .row-ops { display: flex; align-items: center; gap: 6px; flex: none; }
2706
+ .tag.warn { color: var(--warn, #b45309); border-color: var(--warn, #b45309); }
2707
+
2708
+ /* ============ 对话分区(直连任务默认视图) ============ */
2709
+ .rd-chat { display: flex; flex-direction: column; gap: 12px; min-height: 0; }
2710
+ .rd-chat-flow { display: flex; flex-direction: column; gap: 10px; overflow-y: auto;
2711
+ max-height: calc(100vh - 320px); padding: 4px 2px; scroll-behavior: smooth; }
2712
+ .chat-row { display: flex; justify-content: flex-start; }
2713
+ .chat-row.me { justify-content: flex-end; }
2714
+ .chat-bubble { max-width: 78%; border: 1px solid var(--border); border-radius: 12px;
2715
+ padding: 8px 12px; background: var(--panel2); font-size: 13.5px; line-height: 1.6;
2716
+ overflow-wrap: anywhere; }
2717
+ .chat-bubble.me { background: color-mix(in srgb, var(--accent) 12%, var(--panel));
2718
+ border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); }
2719
+ .chat-bubble.agent { background: var(--bg); }
2720
+ .chat-meta { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
2721
+ .chat-bubble.me .chat-meta { text-align: right; }
2722
+ .chat-body { margin: 0; font: inherit; white-space: pre-wrap; max-height: 420px;
2723
+ overflow-y: auto; }
2724
+ .chat-atts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
2725
+ .rd-chat-bar { border: 1px solid var(--border); border-radius: 12px; background: var(--panel);
2726
+ padding: 4px 6px 6px; transition: border-color .15s; }
2727
+ .rd-chat-bar:focus-within { border-color: var(--accent); }
2728
+ .rd-chat-bar textarea { border: none; background: transparent; resize: none;
2729
+ padding: 8px 6px 4px; font-size: 14px; width: 100%; }
2730
+ .rd-chat-bar textarea:hover, .rd-chat-bar textarea:focus { border: none; box-shadow: none; }
2731
+ .rd-chat-tools { display: flex; align-items: center; gap: 8px; padding: 0 4px; flex-wrap: wrap; }
2732
+ .rd-chat-tools .primary.round { width: 32px; height: 32px; border-radius: 50%; padding: 0;
2733
+ display: inline-flex; align-items: center; justify-content: center; margin-left: auto; }