hongcoding commited on
Commit
f402bb3
·
verified ·
1 Parent(s): 7b57540

feat: Warm Paper 设计系统开源(48 CSS + 令牌 + 实时预览)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
README.md CHANGED
@@ -1,10 +1,165 @@
1
  ---
2
- title: Perch Design
3
- emoji: 🏃
4
- colorFrom: red
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: 栖木 Perch · Warm Paper 设计系统
3
+ emoji: 🎨
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ license: mit
9
+ short_description: 像纸一样温暖、像工具一样安静的界面语言
10
  ---
11
 
12
+ # 🎨 perch-design
13
+
14
+ ### 一套像纸一样温暖、像工具一样安静的界面语言。
15
+
16
+ > 大多数 AI 应用长这样:纯白背景 + 蓝紫渐变 + 冷冰冰的圆角。
17
+ > 那是"工具"的语言,不是"伙伴"的语言。
18
+ >
19
+ > 栖木选了**暖纸**——纸张泛黄的白、墨水的深棕、陶土橙的强调色。
20
+ > 用户要长时间盯着它,**暖色比冷色更不容易疲劳**。
21
+
22
+ [栖木 Perch](https://huggingface.co/datasets/hongcoding/perch) 的完整设计系统 · 48 个 CSS 文件 · MIT 开源
23
+
24
+ ---
25
+
26
+ ## ✨ 三个设计原则
27
+
28
+ | 原则 | 含义 | 体现 |
29
+ |---|---|---|
30
+ | **安静优先** | 界面不抢注意力 | 低饱和、少动画、无渐变噪点 |
31
+ | **内容为王** | 结构和排版服务于阅读 | 衬线标题 + 无衬线正文 |
32
+ | **物理感** | 元素像真的纸/玻璃 | 柔和阴影、毛玻璃、微圆角 |
33
+
34
+ ---
35
+
36
+ ## 🎨 调色板(一眼看懂)
37
+
38
+ ```
39
+ ┌─────────────────────────────────────────────────────────┐
40
+ │ 暖纸底 #faf9f5 卡片 #f0eee6 凹陷 #e8e5db │
41
+ │ 墨水 #1f1e1b 次要 #6b6862 提示 #9c988d │
42
+ │ 陶土橙 #d97757 ← 唯一的强调色(不滥用) │
43
+ └─────────────────────────────────────────────────────────┘
44
+ ```
45
+
46
+ **只有一个强调色**。大多数界面之所以"脏",就是因为用了太多颜色。
47
+ 栖木只用一个陶土橙,其余全靠中性色的层次关系。
48
+
49
+ **深色模式**不是简单反色——是重新调的一套:
50
+ 暖纸 `#faf9f5` → 炭黑 `#262521`,橙 `#d97757` → `#e08a6e`(深色下略提亮)。
51
+
52
+ ---
53
+
54
+ ## 📦 三种用法
55
+
56
+ ### 1. 直接引入(最快)
57
+
58
+ ```html
59
+ <link rel="stylesheet" href="tokens/theme.css" />
60
+ <link rel="stylesheet" href="css/chat.css" />
61
+ <!-- 按需引入其他模块 -->
62
+ ```
63
+
64
+ ### 2. 只取令牌(最灵活)
65
+
66
+ ```css
67
+ :root {
68
+ --bg: #faf9f5;
69
+ --text: #1f1e1b;
70
+ --accent: #d97757;
71
+ /* ... */
72
+ }
73
+ ```
74
+
75
+ ### 3. 看效果(最直观)
76
+
77
+ 打开 `preview/index.html` —— 一个零依赖的组件预览页。
78
+
79
+ ---
80
+
81
+ ## 🔧 主题切换
82
+
83
+ ```html
84
+ <!-- 跟随系统(默认) -->
85
+ <html>
86
+
87
+ <!-- 强制浅色 -->
88
+ <html data-theme="light">
89
+
90
+ <!-- 强制深色 -->
91
+ <html data-theme="dark">
92
+ ```
93
+
94
+ ```css
95
+ /* 令牌文件里三套定义并存:
96
+ 1) @media (prefers-color-scheme: dark) → 跟随系统
97
+ 2) [data-theme="light"] → 显式浅色
98
+ 3) [data-theme="dark"] → 显式深色
99
+ 顺序保证显式覆盖能盖过系统偏好。 */
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 📐 设计令牌速查
105
+
106
+ | 类别 | 令牌 | 值 |
107
+ |---|---|---|
108
+ | **圆角** | `--radius-control` | 10px |
109
+ | | `--radius-card` | 14px |
110
+ | | `--radius-float` | 16px |
111
+ | **阴影** | `--shadow-float` | `0 4px 24px rgba(31,30,27,0.08)` |
112
+ | **毛玻璃** | `--glass` / `--glass-blur` | 85% 暖纸 + 20px 模糊 |
113
+ | **动效** | `--ease` / `--dur` | 快进慢出 / 150ms |
114
+ | **字体** | `--font-serif` | Source Serif 4 |
115
+ | | `--font-sans` | Inter |
116
+ | | `--font-mono` | JetBrains Mono |
117
+
118
+ ---
119
+
120
+ ## 🗂️ 文件地图
121
+
122
+ ```
123
+ perch-design/
124
+ ├── tokens/
125
+ │ └── theme.css 全局令牌 + 三套主题 + 排版基线
126
+ ├── css/ 48 个模块样式
127
+ │ ├── chat.css 对话区
128
+ │ ├── composer.css 输入区(思考滑块)
129
+ │ ├── markdown.css Markdown 渲染
130
+ │ ├── materials.css 材质
131
+ │ ├── screensaver.css 待机屏保
132
+ │ └── ... 各功能面板
133
+ ├── docs/
134
+ │ └── design-system.md ★ 完整设计文档(先读这个)
135
+ └── preview/
136
+ └── index.html 零依赖预览页
137
+ ```
138
+
139
+ ---
140
+
141
+ ## ♿ 可访问性
142
+
143
+ - 正文对背景对比度 **≥ 7:1**(WCAG AAA)
144
+ - 键盘导航有可见焦点环
145
+ - 尊重 `prefers-reduced-motion`
146
+ - 正文字号 14.5px 起(不玩 12px 小字)
147
+
148
+ ---
149
+
150
+ ## 🔗 相关项目
151
+
152
+ | 项目 | 说明 | 链接 |
153
+ |---|---|---|
154
+ | **栖木 Perch**(应用) | macOS 本地优先 AI 工作台 | https://huggingface.co/datasets/hongcoding/perch |
155
+ | **perch-ultrafast**(框架) | 混合流 + Ultrafast:首字 1s → 80ms | https://huggingface.co/hongcoding/perch-ultrafast |
156
+ | **perch-gpu**(工具) | 本机 GPU 加速:冷启动 5s → 0.08s | https://huggingface.co/hongcoding/perch-gpu |
157
+ | **perch-design**(本库) | 就是这套设计系统 | https://huggingface.co/hongcoding/perch-design |
158
+
159
+ ## 📜 许可
160
+
161
+ MIT —— 随便用,注明出处即可。
162
+
163
+ ---
164
+
165
+ **🎨 好的界面不抢戏。它只是安静地把内容递到你面前。**
css/App.css ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Warm Paper 外壳布局 + 通用按钮(颜色一律走 theme.css 令牌) */
2
+
3
+ .shell {
4
+ display: flex;
5
+ height: 100vh;
6
+ overflow: hidden; /* 整窗禁止滚动:只有消息流内部滚动 */
7
+ background: var(--bg);
8
+ }
9
+
10
+ /* ---------- 侧栏 ---------- */
11
+ /* 顶部 40px 安全边距:主窗 titleBarStyle=overlay 后 traffic light 悬浮在内容上,
12
+ 侧栏品牌位必须让开左上角(实测遮挡区约高 20px,留 40px 余量)。
13
+ .brand 带 data-tauri-drag-region,作为窗口拖拽区。 */
14
+ .sidebar {
15
+ width: 232px;
16
+ flex-shrink: 0;
17
+ display: flex;
18
+ flex-direction: column;
19
+ padding: 40px 16px 20px;
20
+ border-right: 1px solid var(--border);
21
+ }
22
+
23
+ .brand {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 10px;
27
+ padding: 0 8px 28px;
28
+ cursor: default;
29
+ }
30
+
31
+ /* 品牌标:内联 SVG 鸟巢(Brand.tsx),陶土橙单线,不再用色块文字标 */
32
+ .brand-mark {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ color: var(--accent);
36
+ }
37
+
38
+ .brand-name {
39
+ font-family: var(--font-serif);
40
+ font-size: 16px;
41
+ font-weight: 600;
42
+ }
43
+
44
+ .sidebar nav {
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: 2px;
48
+ flex: 1;
49
+ }
50
+
51
+ .nav-item {
52
+ position: relative;
53
+ display: flex;
54
+ flex-direction: column;
55
+ align-items: flex-start;
56
+ gap: 1px;
57
+ padding: 9px 12px;
58
+ border: none;
59
+ border-radius: var(--radius-control);
60
+ background: transparent;
61
+ color: var(--text);
62
+ font-family: inherit;
63
+ font-size: 14px;
64
+ text-align: left;
65
+ cursor: pointer;
66
+ transition: background-color var(--dur) var(--ease);
67
+ }
68
+
69
+ .nav-item:hover {
70
+ background: var(--bg-elevated);
71
+ }
72
+
73
+ .nav-item.is-active {
74
+ background: var(--accent-soft);
75
+ }
76
+
77
+ /* 激活态左侧 2px accent 竖条(Claude 式);非激活时淡出 */
78
+ .nav-item::before {
79
+ content: "";
80
+ position: absolute;
81
+ left: 0;
82
+ top: 8px;
83
+ bottom: 8px;
84
+ width: 2px;
85
+ border-radius: 1px;
86
+ background: var(--accent);
87
+ opacity: 0;
88
+ transition: opacity var(--dur) var(--ease);
89
+ }
90
+
91
+ .nav-item.is-active::before {
92
+ opacity: 1;
93
+ }
94
+
95
+ .nav-label {
96
+ font-weight: 500;
97
+ }
98
+
99
+ /* 设置项:行内齿轮图标 + 文字 */
100
+ .nav-row {
101
+ display: inline-flex;
102
+ align-items: center;
103
+ gap: 8px;
104
+ color: var(--text);
105
+ }
106
+
107
+ .nav-row svg {
108
+ color: var(--text-secondary);
109
+ }
110
+
111
+ .nav-hint {
112
+ font-size: 12px;
113
+ color: var(--text-tertiary);
114
+ }
115
+
116
+ .sidebar-foot {
117
+ padding: 8px 12px;
118
+ font-size: 12px;
119
+ color: var(--text-tertiary);
120
+ }
121
+
122
+ /* ---------- 主区 ---------- */
123
+ .content {
124
+ flex: 1;
125
+ min-width: 0;
126
+ min-height: 0; /* 关键:允许子项收缩,消息流才能在视口内滚动 */
127
+ display: flex;
128
+ flex-direction: column;
129
+ }
130
+
131
+ /* ---------- 占位板块空态 ---------- */
132
+ .placeholder {
133
+ flex: 1;
134
+ display: flex;
135
+ flex-direction: column;
136
+ justify-content: center;
137
+ align-items: flex-start;
138
+ gap: 12px;
139
+ max-width: 620px;
140
+ padding: 48px 80px;
141
+ }
142
+
143
+ .placeholder h1 {
144
+ font-size: 32px;
145
+ }
146
+
147
+ .placeholder-sub {
148
+ margin: 0;
149
+ font-size: 16px;
150
+ color: var(--text-secondary);
151
+ }
152
+
153
+ .placeholder-note {
154
+ margin: 0;
155
+ font-size: 13px;
156
+ color: var(--text-tertiary);
157
+ }
158
+
159
+ /* ---------- 按钮 ---------- */
160
+ .btn-primary {
161
+ height: 40px;
162
+ padding: 0 22px;
163
+ border: none;
164
+ border-radius: var(--radius-control);
165
+ background: var(--accent);
166
+ color: var(--bg);
167
+ font-family: inherit;
168
+ font-size: 14px;
169
+ font-weight: 500;
170
+ cursor: pointer;
171
+ transition: background-color var(--dur) var(--ease);
172
+ }
173
+
174
+ .btn-primary:hover {
175
+ filter: brightness(0.94);
176
+ }
177
+
178
+ .btn-primary:disabled,
179
+ .btn-secondary:disabled {
180
+ opacity: 0.6;
181
+ cursor: default;
182
+ filter: none;
183
+ }
184
+
185
+ .btn-secondary {
186
+ height: 36px;
187
+ padding: 0 16px;
188
+ border: 1px solid var(--border);
189
+ border-radius: var(--radius-control);
190
+ background: transparent;
191
+ color: var(--text);
192
+ font-family: inherit;
193
+ font-size: 13.5px;
194
+ cursor: pointer;
195
+ transition: background-color var(--dur) var(--ease);
196
+ }
197
+
198
+ .btn-secondary:hover {
199
+ background: var(--bg-elevated);
200
+ }
201
+
202
+ .icon-btn {
203
+ display: inline-grid;
204
+ place-items: center;
205
+ width: 28px;
206
+ height: 28px;
207
+ border: none;
208
+ border-radius: var(--radius-control);
209
+ background: transparent;
210
+ color: var(--text-tertiary);
211
+ cursor: pointer;
212
+ transition: background-color var(--dur) var(--ease);
213
+ }
214
+
215
+ .icon-btn:hover {
216
+ background: var(--bg-elevated);
217
+ color: var(--text);
218
+ }
219
+
220
+ .icon-btn-danger:hover {
221
+ background: var(--accent-soft);
222
+ color: var(--danger);
223
+ }
224
+
225
+ /* ---------- 卡片 hover 统一(design-system §6:克制的 150ms) ----------
226
+ 描边加深 + 极轻上浮 1px;只作用于内容卡片,覆盖看板/诊断/技能/专家/表单。 */
227
+ .metric-card,
228
+ .panel,
229
+ .diag-card,
230
+ .diag-trash,
231
+ .skill-card,
232
+ .mcp-card,
233
+ .cloud-card,
234
+ .expert-card {
235
+ transition:
236
+ border-color var(--dur) var(--ease),
237
+ transform var(--dur) var(--ease);
238
+ }
239
+
240
+ .metric-card:hover,
241
+ .panel:hover,
242
+ .diag-card:hover,
243
+ .diag-trash:hover,
244
+ .skill-card:hover,
245
+ .mcp-card:hover,
246
+ .cloud-card:hover,
247
+ .expert-card:hover {
248
+ border-color: color-mix(in srgb, var(--border) 55%, var(--text-tertiary));
249
+ transform: translateY(-1px);
250
+ }
251
+
252
+ /* 选中态的专家卡保持 accent 描边,不被 hover 色盖掉 */
253
+ .expert-card.is-active,
254
+ .expert-card.is-active:hover {
255
+ border-color: var(--accent);
256
+ }
257
+
258
+ /* 个人账户(契约 40A) */
259
+ .account-redeem { display: flex; gap: 6px; align-items: center; }
260
+ .account-redeem input {
261
+ padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
262
+ background: var(--surface); color: var(--ink-1); font-size: 12px; width: 140px;
263
+ font-family: ui-monospace, monospace;
264
+ }
265
+ .account-redeem button {
266
+ padding: 6px 12px; border: 1px solid var(--accent); border-radius: 8px;
267
+ background: var(--accent-soft); color: var(--accent); font-size: 12px; cursor: pointer;
268
+ }
269
+ .account-redeem button:disabled { opacity: 0.5; cursor: default; }
270
+ .account-msg { font-size: 12px; color: var(--ink-2); margin: 6px 0; }
271
+
272
+ /* Pro 门控(免费缩水) */
273
+ .pro-gate {
274
+ display: flex; flex-direction: column; align-items: center; gap: 8px;
275
+ padding: 32px 20px; text-align: center;
276
+ border: 1px dashed var(--line); border-radius: 12px;
277
+ background: var(--surface-2);
278
+ }
279
+ .pro-gate-badge {
280
+ display: inline-flex; padding: 3px 12px; border-radius: 999px;
281
+ background: var(--accent-soft); color: var(--accent); font-weight: 600; font-size: 12px;
282
+ }
283
+ .pro-gate-text { font-size: 14px; color: var(--ink-1); margin: 0; }
284
+ .pro-gate-hint { font-size: 12px; color: var(--ink-3); margin: 0; }
285
+
286
+ /* 底部状态条(契约 6E):常驻显示输出速度 + 缓存命中 */
287
+ .stats-bar {
288
+ display: flex; align-items: center; gap: 12px;
289
+ padding: 4px 14px; border-top: 1px solid var(--line);
290
+ font-size: 11px; color: var(--ink-3);
291
+ background: var(--surface-2);
292
+ flex: 0 0 auto;
293
+ }
294
+ .stats-dot {
295
+ width: 6px; height: 6px; border-radius: 50%;
296
+ background: var(--ink-4); flex: 0 0 auto;
297
+ }
298
+ .stats-dot.is-live {
299
+ background: var(--accent);
300
+ animation: stats-pulse 1.2s ease-in-out infinite;
301
+ }
302
+ @keyframes stats-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
303
+ .stats-item { white-space: nowrap; font-variant-numeric: tabular-nums; }
304
+ .stats-spacer { flex: 1; }
305
+ .stats-hint { color: var(--ink-4); font-size: 10px; }
css/acceptance.css ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 小栖验收卡(契约 19A A2)——Warm Paper 全令牌,语义色只出现在状态语境。
2
+ 规则来自 docs/design-system.md:1px 描边、无阴影、克制 150ms 过渡。 */
3
+
4
+ .acc-card {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 10px;
8
+ padding: 12px 14px;
9
+ border: 1px solid var(--border);
10
+ border-left-width: 3px;
11
+ border-radius: var(--radius-card);
12
+ font-size: 13px;
13
+ line-height: 1.65;
14
+ /* 液态玻璃(2026-10-23 用户点名):半透明底 + 背景模糊 + 内侧高光,
15
+ 语义色以"雾"的浓度存在而非实心块;主窗口 WebView 支持 backdrop-filter
16
+ (坑位记录里的禁令只针对透明原生窗)。 */
17
+ background: color-mix(in srgb, var(--bg-elevated) 72%, transparent);
18
+ backdrop-filter: blur(18px) saturate(140%);
19
+ -webkit-backdrop-filter: blur(18px) saturate(140%);
20
+ box-shadow:
21
+ inset 0 1px 0 color-mix(in srgb, var(--text) 5%, transparent),
22
+ inset 0 0 0 1px color-mix(in srgb, var(--text) 4%, transparent);
23
+ transition: background var(--dur) var(--ease);
24
+ }
25
+
26
+ /* 语义色只染左侧状态条、徽章与玻璃雾浓度(克制) */
27
+ .acc-card.is-success {
28
+ border-left-color: var(--success);
29
+ background: color-mix(
30
+ in srgb,
31
+ var(--success) 9%,
32
+ color-mix(in srgb, var(--bg-elevated) 74%, transparent)
33
+ );
34
+ }
35
+ .acc-card.is-warning {
36
+ border-left-color: var(--warning);
37
+ background: color-mix(
38
+ in srgb,
39
+ var(--warning) 8%,
40
+ color-mix(in srgb, var(--bg-elevated) 74%, transparent)
41
+ );
42
+ }
43
+ .acc-card.is-danger {
44
+ border-left-color: var(--danger);
45
+ background: color-mix(
46
+ in srgb,
47
+ var(--danger) 8%,
48
+ color-mix(in srgb, var(--bg-elevated) 74%, transparent)
49
+ );
50
+ }
51
+ .acc-card.is-tertiary {
52
+ border-left-color: var(--text-tertiary);
53
+ }
54
+
55
+ .acc-head {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 8px;
59
+ flex-wrap: wrap;
60
+ }
61
+
62
+ .acc-badge {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ height: 20px;
66
+ padding: 0 8px;
67
+ border-radius: var(--radius-chip);
68
+ font-size: 12px;
69
+ white-space: nowrap;
70
+ background: var(--bg-sunken);
71
+ color: var(--text-secondary);
72
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
73
+ }
74
+
75
+ .acc-badge.is-success {
76
+ background: color-mix(in srgb, var(--success) 16%, transparent);
77
+ color: var(--success);
78
+ }
79
+
80
+ .acc-badge.is-warning {
81
+ background: color-mix(in srgb, var(--warning) 18%, transparent);
82
+ color: var(--warning);
83
+ }
84
+
85
+ .acc-badge.is-danger {
86
+ background: color-mix(in srgb, var(--danger) 14%, transparent);
87
+ color: var(--danger);
88
+ }
89
+
90
+ .acc-badge.is-tertiary {
91
+ background: var(--bg-sunken);
92
+ color: var(--text-tertiary);
93
+ }
94
+
95
+ .acc-title {
96
+ font-family: var(--font-serif);
97
+ font-size: 14px;
98
+ font-weight: 600;
99
+ color: var(--text);
100
+ }
101
+
102
+ .acc-meta {
103
+ margin-left: auto;
104
+ color: var(--text-tertiary);
105
+ font-size: 11.5px;
106
+ }
107
+
108
+ .acc-degraded {
109
+ margin: 0;
110
+ padding: 8px 10px;
111
+ border-left: 3px solid var(--warning);
112
+ border-radius: 0 var(--radius-chip) var(--radius-chip) 0;
113
+ background: color-mix(in srgb, var(--warning) 10%, transparent);
114
+ color: var(--text-secondary);
115
+ font-size: 12.5px;
116
+ }
117
+
118
+ .acc-task {
119
+ margin: 0;
120
+ color: var(--text-secondary);
121
+ font-size: 12.5px;
122
+ overflow: hidden;
123
+ text-overflow: ellipsis;
124
+ white-space: nowrap;
125
+ }
126
+
127
+ .acc-block {
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: 6px;
131
+ }
132
+
133
+ .acc-block-title {
134
+ margin: 0;
135
+ color: var(--text-tertiary);
136
+ font-family: inherit;
137
+ font-size: 11.5px;
138
+ font-weight: 600;
139
+ letter-spacing: 0.04em;
140
+ text-transform: none;
141
+ }
142
+
143
+ /* 缺口清单 */
144
+ .acc-gaps,
145
+ .acc-evidence,
146
+ .acc-plan {
147
+ margin: 0;
148
+ padding: 0;
149
+ list-style: none;
150
+ display: flex;
151
+ flex-direction: column;
152
+ gap: 4px;
153
+ }
154
+
155
+ .acc-gaps li {
156
+ position: relative;
157
+ padding-left: 14px;
158
+ color: var(--text);
159
+ }
160
+
161
+ .acc-gaps li::before {
162
+ content: "";
163
+ position: absolute;
164
+ left: 2px;
165
+ top: 9px;
166
+ width: 5px;
167
+ height: 5px;
168
+ border-radius: 50%;
169
+ background: var(--warning);
170
+ }
171
+
172
+ /* 证据行:小号等宽,单条最多三行(长片段在后端已截到 3KB) */
173
+ .acc-evidence li {
174
+ padding: 6px 8px;
175
+ border-radius: var(--radius-chip);
176
+ background: var(--bg-sunken);
177
+ color: var(--text-secondary);
178
+ font-family: var(--font-mono);
179
+ font-size: 11.5px;
180
+ line-height: 1.6;
181
+ white-space: pre-wrap;
182
+ word-break: break-word;
183
+ max-height: 4.8em;
184
+ overflow: hidden;
185
+ }
186
+
187
+ /* 分步方案:序号 + 工具 chip + 说明 */
188
+ .acc-plan li {
189
+ display: flex;
190
+ align-items: baseline;
191
+ gap: 8px;
192
+ padding: 6px 8px;
193
+ border-radius: var(--radius-chip);
194
+ background: var(--bg-sunken);
195
+ }
196
+
197
+ .acc-tool {
198
+ flex-shrink: 0;
199
+ padding: 1px 6px;
200
+ border-radius: var(--radius-chip);
201
+ background: var(--accent-soft);
202
+ color: var(--accent);
203
+ font-family: var(--font-mono);
204
+ font-size: 11px;
205
+ white-space: nowrap;
206
+ }
207
+
208
+ .acc-step {
209
+ color: var(--text);
210
+ }
211
+
212
+ /* 一键派发(16A 同款次按钮基调) */
213
+ .acc-dispatch {
214
+ align-self: flex-start;
215
+ display: inline-flex;
216
+ align-items: center;
217
+ gap: 6px;
218
+ height: 30px;
219
+ padding: 0 12px;
220
+ border: 1px solid var(--border);
221
+ border-radius: var(--radius-control);
222
+ background: transparent;
223
+ color: var(--text);
224
+ font-family: inherit;
225
+ font-size: 12.5px;
226
+ cursor: pointer;
227
+ transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
228
+ }
229
+
230
+ .acc-dispatch:hover {
231
+ background: var(--accent-soft);
232
+ border-color: var(--accent);
233
+ }
234
+
235
+ .acc-dispatch:focus-visible {
236
+ outline: 2px solid var(--accent);
237
+ outline-offset: 2px;
238
+ }
css/account.css ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 个人账户 / 变现(契约 40A)——Warm Paper 令牌,无硬编码色,克制动效。
2
+ 账户卡 · token 用量看板 · Alipay 解锁区 · 免费缩水「Pro 解锁」占位卡。
3
+ 色彩全部走 theme.css 的 var(--*),深浅色两套自动跟随;不引任何硬编码色。 */
4
+
5
+ /* ── 通用按钮(账户区自成一体,不依赖 mcp.css 的 field/btn 类)───── */
6
+ .account-btn {
7
+ display: inline-flex;
8
+ align-items: center;
9
+ gap: 6px;
10
+ padding: 8px 15px;
11
+ border: 1px solid transparent;
12
+ border-radius: var(--radius-control);
13
+ background: var(--accent);
14
+ color: var(--bg);
15
+ font-family: inherit;
16
+ font-size: 13px;
17
+ font-weight: 600;
18
+ line-height: 1.2;
19
+ cursor: pointer;
20
+ transition: filter var(--dur) var(--ease), transform var(--dur) var(--ease);
21
+ }
22
+ .account-btn:hover:not(:disabled) {
23
+ filter: brightness(1.05);
24
+ }
25
+ .account-btn:active:not(:disabled) {
26
+ transform: translateY(1px);
27
+ }
28
+ .account-btn:disabled {
29
+ opacity: 0.55;
30
+ cursor: default;
31
+ }
32
+
33
+ .account-btn-ghost {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ gap: 6px;
37
+ padding: 8px 15px;
38
+ border: 1px solid var(--border);
39
+ border-radius: var(--radius-control);
40
+ background: transparent;
41
+ color: var(--text-secondary);
42
+ font-family: inherit;
43
+ font-size: 13px;
44
+ font-weight: 500;
45
+ line-height: 1.2;
46
+ cursor: pointer;
47
+ transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
48
+ }
49
+ .account-btn-ghost:hover:not(:disabled) {
50
+ border-color: var(--text-tertiary);
51
+ color: var(--text);
52
+ }
53
+ .account-btn-ghost:disabled {
54
+ opacity: 0.55;
55
+ cursor: default;
56
+ }
57
+
58
+ /* 载入小转圈(Loader2 用):克制、可被系统「减少动态效果」关掉。 */
59
+ .spin {
60
+ animation: perch-spin 900ms linear infinite;
61
+ }
62
+ @keyframes perch-spin {
63
+ to {
64
+ transform: rotate(360deg);
65
+ }
66
+ }
67
+ @media (prefers-reduced-motion: reduce) {
68
+ .spin {
69
+ animation: none;
70
+ }
71
+ .account-btn,
72
+ .account-btn-ghost,
73
+ .token-bar-fill {
74
+ transition: none;
75
+ }
76
+ }
77
+
78
+ /* ── 账户卡 ─────────────────────────────────────────────────── */
79
+ .account-card {
80
+ border: 1px solid var(--border);
81
+ border-radius: var(--radius-card);
82
+ background: var(--bg-elevated);
83
+ padding: 16px 18px;
84
+ }
85
+ .account-card-top {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 10px;
89
+ margin-bottom: 8px;
90
+ }
91
+ .account-tier {
92
+ display: inline-flex;
93
+ align-items: center;
94
+ padding: 3px 12px;
95
+ border-radius: var(--radius-chip);
96
+ font-family: var(--font-serif);
97
+ font-size: 15px;
98
+ font-weight: 600;
99
+ letter-spacing: 0.01em;
100
+ }
101
+ .account-tier.is-free {
102
+ background: var(--bg-sunken);
103
+ color: var(--text-secondary);
104
+ }
105
+ .account-tier.is-pro {
106
+ background: var(--accent-soft);
107
+ color: var(--accent);
108
+ }
109
+ .account-admin {
110
+ padding: 2px 9px;
111
+ border: 1px solid var(--border);
112
+ border-radius: var(--radius-chip);
113
+ font-size: 11px;
114
+ color: var(--text-secondary);
115
+ }
116
+ .account-card-desc {
117
+ margin: 0;
118
+ color: var(--text);
119
+ font-size: 13.5px;
120
+ line-height: 1.6;
121
+ }
122
+ .account-card-meta {
123
+ margin: 6px 0 0;
124
+ color: var(--text-tertiary);
125
+ font-size: 12px;
126
+ }
127
+
128
+ /* ── token 用量看板 ─────────────────────────────────────────── */
129
+ .token-board {
130
+ margin-top: 12px;
131
+ border: 1px solid var(--border);
132
+ border-radius: var(--radius-card);
133
+ background: var(--bg);
134
+ padding: 16px 18px;
135
+ }
136
+ .token-board-head {
137
+ display: flex;
138
+ align-items: baseline;
139
+ justify-content: space-between;
140
+ gap: 12px;
141
+ }
142
+ .token-board-title {
143
+ font-family: var(--font-serif);
144
+ font-size: 15px;
145
+ font-weight: 600;
146
+ color: var(--text);
147
+ }
148
+ .token-board-total {
149
+ font-family: var(--font-mono);
150
+ font-size: 13px;
151
+ color: var(--text-secondary);
152
+ }
153
+ .token-bar {
154
+ margin: 12px 0 8px;
155
+ height: 8px;
156
+ border-radius: 999px;
157
+ background: var(--bg-sunken);
158
+ overflow: hidden;
159
+ }
160
+ .token-bar-fill {
161
+ height: 100%;
162
+ border-radius: 999px;
163
+ background: var(--accent);
164
+ transition: width var(--dur) var(--ease);
165
+ }
166
+ .token-board-caption {
167
+ margin: 0;
168
+ color: var(--text-tertiary);
169
+ font-size: 11.5px;
170
+ line-height: 1.55;
171
+ }
172
+ .token-board-caption strong {
173
+ color: var(--text-secondary);
174
+ font-weight: 600;
175
+ }
176
+ .token-grid {
177
+ display: grid;
178
+ grid-template-columns: repeat(4, 1fr);
179
+ gap: 10px;
180
+ margin: 14px 0 0;
181
+ }
182
+ .token-cell {
183
+ border: 1px solid var(--border);
184
+ border-radius: var(--radius-chip);
185
+ background: var(--bg-elevated);
186
+ padding: 9px 11px;
187
+ }
188
+ .token-cell dt {
189
+ margin: 0;
190
+ color: var(--text-tertiary);
191
+ font-size: 11px;
192
+ }
193
+ .token-cell dd {
194
+ margin: 3px 0 0;
195
+ font-family: var(--font-mono);
196
+ font-size: 15px;
197
+ color: var(--text);
198
+ }
199
+
200
+ /* ── Alipay 解锁区 ──────────────────────────────────────────── */
201
+ .unlock-block {
202
+ margin-top: 12px;
203
+ border: 1px solid var(--border);
204
+ border-radius: var(--radius-card);
205
+ background: var(--bg-elevated);
206
+ padding: 16px 18px;
207
+ }
208
+ .unlock-title {
209
+ margin: 0 0 12px;
210
+ font-family: var(--font-serif);
211
+ font-size: 15px;
212
+ font-weight: 600;
213
+ }
214
+ .unlock-row {
215
+ display: flex;
216
+ gap: 18px;
217
+ align-items: flex-start;
218
+ flex-wrap: wrap;
219
+ }
220
+ .unlock-qr {
221
+ margin: 0;
222
+ display: flex;
223
+ flex-direction: column;
224
+ align-items: center;
225
+ gap: 8px;
226
+ }
227
+ .unlock-qr-img {
228
+ width: 148px;
229
+ height: 148px;
230
+ border: 1px solid var(--border);
231
+ border-radius: var(--radius-control);
232
+ background: var(--bg);
233
+ padding: 6px;
234
+ }
235
+ .unlock-qr-cap {
236
+ color: var(--text-tertiary);
237
+ font-size: 11px;
238
+ }
239
+ .unlock-form {
240
+ flex: 1;
241
+ min-width: 220px;
242
+ display: flex;
243
+ flex-direction: column;
244
+ gap: 10px;
245
+ }
246
+ .unlock-price {
247
+ margin: 0;
248
+ font-family: var(--font-serif);
249
+ font-size: 14px;
250
+ font-weight: 600;
251
+ color: var(--accent);
252
+ }
253
+ .unlock-field {
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: 5px;
257
+ }
258
+ .unlock-label {
259
+ color: var(--text-secondary);
260
+ font-size: 12px;
261
+ }
262
+ .unlock-input {
263
+ padding: 9px 12px;
264
+ border: 1px solid var(--border);
265
+ border-radius: var(--radius-control);
266
+ background: var(--bg);
267
+ color: var(--text);
268
+ font-family: var(--font-mono);
269
+ font-size: 13px;
270
+ letter-spacing: 0.04em;
271
+ }
272
+ .unlock-input:focus-visible {
273
+ outline: 2px solid var(--accent);
274
+ outline-offset: 1px;
275
+ }
276
+ .unlock-input:disabled {
277
+ opacity: 0.6;
278
+ cursor: default;
279
+ }
280
+ .unlock-actions {
281
+ display: flex;
282
+ gap: 10px;
283
+ flex-wrap: wrap;
284
+ }
285
+ .unlock-honest {
286
+ margin: 14px 0 0;
287
+ padding: 11px 13px;
288
+ border-left: 3px solid var(--warning);
289
+ border-radius: var(--radius-chip);
290
+ background: var(--bg-sunken);
291
+ color: var(--text-secondary);
292
+ font-size: 11.5px;
293
+ line-height: 1.65;
294
+ }
295
+ .unlock-honest strong {
296
+ color: var(--text);
297
+ font-weight: 600;
298
+ }
299
+
300
+ /* ── 免费缩水「Pro 解锁」占位卡(AssistantPanel / 看板等复用)── */
301
+ .pro-lock {
302
+ display: flex;
303
+ flex-direction: column;
304
+ align-items: center;
305
+ gap: 10px;
306
+ margin: 8px;
307
+ padding: 30px 24px;
308
+ border: 1px dashed var(--border);
309
+ border-radius: var(--radius-card);
310
+ background: var(--bg-elevated);
311
+ text-align: center;
312
+ }
313
+ .pro-lock-badge {
314
+ display: inline-flex;
315
+ align-items: center;
316
+ gap: 6px;
317
+ padding: 3px 11px;
318
+ border-radius: var(--radius-chip);
319
+ background: var(--accent-soft);
320
+ color: var(--accent);
321
+ font-size: 11.5px;
322
+ font-weight: 600;
323
+ }
324
+ .pro-lock-title {
325
+ margin: 0;
326
+ font-family: var(--font-serif);
327
+ font-size: 16px;
328
+ font-weight: 600;
329
+ color: var(--text);
330
+ }
331
+ .pro-lock-desc {
332
+ margin: 0;
333
+ max-width: 380px;
334
+ color: var(--text-secondary);
335
+ font-size: 13px;
336
+ line-height: 1.65;
337
+ }
338
+ .pro-lock-hint {
339
+ margin: 2px 0 0;
340
+ max-width: 380px;
341
+ color: var(--text-tertiary);
342
+ font-size: 11px;
343
+ line-height: 1.6;
344
+ }
345
+
346
+ /* ── 置灰的 Pro-only 子项(自定义专家 / 看板全量项)───────────── */
347
+ .is-pro-locked {
348
+ opacity: 0.5;
349
+ filter: grayscale(0.85);
350
+ pointer-events: none;
351
+ user-select: none;
352
+ }
353
+ .pro-gate-note {
354
+ display: inline-flex;
355
+ align-items: center;
356
+ gap: 6px;
357
+ margin: 8px 0 0;
358
+ padding: 8px 12px;
359
+ border: 1px dashed var(--border);
360
+ border-radius: var(--radius-chip);
361
+ background: var(--bg-elevated);
362
+ color: var(--text-secondary);
363
+ font-size: 12px;
364
+ }
365
+ .pro-gate-note .account-btn {
366
+ padding: 5px 11px;
367
+ font-size: 12px;
368
+ }
css/agent.css ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Agent 面板(Phase 5B:能操控电脑的手):Warm Paper 令牌配色,与全站一致。
2
+ 只服务 AgentPanel.tsx;样式独立不外溢。 */
3
+
4
+ .agent-panel {
5
+ flex: 1;
6
+ min-width: 0;
7
+ display: flex;
8
+ flex-direction: column;
9
+ padding: 26px 32px 20px;
10
+ gap: 14px;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .agent-head h1 {
15
+ font-family: var(--font-serif);
16
+ font-size: 26px;
17
+ font-weight: 600;
18
+ }
19
+
20
+ .agent-sub {
21
+ margin-top: 4px;
22
+ color: var(--text-secondary);
23
+ font-size: 14px;
24
+ }
25
+
26
+ .agent-sub-dim {
27
+ color: var(--text-tertiary);
28
+ }
29
+
30
+ /* 常驻安全说明(琥珀色细条,温和不吓人) */
31
+ .agent-safety {
32
+ padding: 10px 14px;
33
+ border: 1px solid var(--border);
34
+ border-left: 3px solid var(--warning);
35
+ border-radius: var(--radius-card);
36
+ background: var(--bg-elevated);
37
+ color: var(--text-secondary);
38
+ font-size: 12.5px;
39
+ line-height: 1.6;
40
+ }
41
+
42
+ /* 输入区 */
43
+ .agent-inputs {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: 10px;
47
+ }
48
+
49
+ .agent-model {
50
+ align-self: flex-start;
51
+ min-width: 240px;
52
+ padding: 7px 12px;
53
+ border: 1px solid var(--border);
54
+ border-radius: var(--radius-control);
55
+ background: var(--bg);
56
+ color: var(--text);
57
+ font-family: var(--font-mono);
58
+ font-size: 12.5px;
59
+ }
60
+
61
+ .agent-task {
62
+ width: 100%;
63
+ resize: vertical;
64
+ min-height: 64px;
65
+ padding: 12px 14px;
66
+ border: 1px solid var(--border);
67
+ border-radius: var(--radius-card);
68
+ background: var(--bg);
69
+ color: var(--text);
70
+ font-family: var(--font-sans);
71
+ font-size: 14px;
72
+ line-height: 1.6;
73
+ }
74
+
75
+ .agent-task:focus,
76
+ .agent-model:focus {
77
+ outline: none;
78
+ border-color: var(--accent);
79
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
80
+ }
81
+
82
+ .agent-actions {
83
+ display: flex;
84
+ gap: 10px;
85
+ align-items: center;
86
+ }
87
+
88
+ .agent-run,
89
+ .agent-cancel,
90
+ .agent-audit,
91
+ .agent-allow,
92
+ .agent-deny,
93
+ .agent-audit-close,
94
+ .agent-tool-copy {
95
+ padding: 8px 18px;
96
+ border: 1px solid var(--border);
97
+ border-radius: var(--radius-control);
98
+ background: var(--bg);
99
+ color: var(--text);
100
+ font-size: 13.5px;
101
+ cursor: pointer;
102
+ transition: background-color var(--dur) var(--ease);
103
+ }
104
+
105
+ .agent-run,
106
+ .agent-allow {
107
+ background: var(--accent);
108
+ border-color: var(--accent);
109
+ color: var(--bg);
110
+ }
111
+
112
+ .agent-run:disabled {
113
+ opacity: 0.55;
114
+ cursor: default;
115
+ }
116
+
117
+ .agent-run:not(:disabled):hover,
118
+ .agent-allow:hover {
119
+ filter: brightness(1.05);
120
+ }
121
+
122
+ .agent-cancel:hover,
123
+ .agent-audit:hover,
124
+ .agent-audit-close:hover,
125
+ .agent-tool-copy:hover {
126
+ background: var(--bg-elevated);
127
+ }
128
+
129
+ .agent-empty {
130
+ color: var(--text-secondary);
131
+ font-size: 13px;
132
+ }
133
+
134
+ /* ── 工具调用卡片(时间线主角)───────────────────────────────────── */
135
+
136
+ .agent-tool-card {
137
+ border: 1px solid var(--border);
138
+ border-left: 3px solid var(--border);
139
+ border-radius: var(--radius-card);
140
+ background: var(--bg-elevated);
141
+ padding: 10px 14px;
142
+ display: flex;
143
+ flex-direction: column;
144
+ gap: 8px;
145
+ }
146
+
147
+ /* 🟢 自动执行:绿色细条;🟡 需确认:琥珀细条 */
148
+ .agent-tool-card.level-green {
149
+ border-left-color: var(--success);
150
+ }
151
+
152
+ .agent-tool-card.level-yellow {
153
+ border-left-color: var(--warning);
154
+ }
155
+
156
+ .agent-tool-card.is-pending {
157
+ background: var(--accent-soft);
158
+ border-color: var(--accent);
159
+ border-left-color: var(--accent);
160
+ }
161
+
162
+ .agent-tool-card.is-failed {
163
+ border-left-color: var(--danger);
164
+ }
165
+
166
+ .agent-tool-head {
167
+ display: flex;
168
+ align-items: baseline;
169
+ gap: 8px;
170
+ flex-wrap: wrap;
171
+ }
172
+
173
+ /* 衬线小标题:「读文件」「执行命令」 */
174
+ .agent-tool-title {
175
+ font-family: var(--font-serif);
176
+ font-size: 15px;
177
+ font-weight: 600;
178
+ color: var(--text);
179
+ }
180
+
181
+ /* 状态徽章:与全站徽章同尺寸同字重(2px 8px / 12px / 500 / pill) */
182
+ .agent-tool-badge {
183
+ font-size: 12px;
184
+ font-weight: 500;
185
+ padding: 2px 8px;
186
+ border-radius: 999px;
187
+ border: 1px solid var(--border);
188
+ color: var(--text-secondary);
189
+ white-space: nowrap;
190
+ }
191
+
192
+ .agent-tool-badge.is-green {
193
+ color: var(--success);
194
+ border-color: var(--success);
195
+ }
196
+
197
+ .agent-tool-badge.is-yellow {
198
+ color: var(--warning);
199
+ border-color: var(--warning);
200
+ }
201
+
202
+ .agent-tool-summary {
203
+ font-size: 13px;
204
+ color: var(--text-secondary);
205
+ min-width: 0;
206
+ }
207
+
208
+ .agent-tool-status {
209
+ margin-left: auto;
210
+ font-size: 12px;
211
+ color: var(--text-tertiary);
212
+ white-space: nowrap;
213
+ }
214
+
215
+ /* 参数原文(mono;命令原文/文件路径都在这里看清楚) */
216
+ .agent-tool-args {
217
+ font-family: var(--font-mono);
218
+ font-size: 12px;
219
+ line-height: 1.6;
220
+ color: var(--text-secondary);
221
+ background: var(--bg-sunken);
222
+ border: 1px solid var(--border);
223
+ border-radius: var(--radius-chip);
224
+ padding: 8px 10px;
225
+ white-space: pre-wrap;
226
+ word-break: break-all;
227
+ max-height: 180px;
228
+ overflow-y: auto;
229
+ }
230
+
231
+ .agent-tool-actions {
232
+ display: flex;
233
+ gap: 10px;
234
+ }
235
+
236
+ .agent-tool-running {
237
+ font-size: 12.5px;
238
+ color: var(--text-tertiary);
239
+ }
240
+
241
+ /* 危险命令被拦:人话提示(danger 红,仅指引不代执行) */
242
+ .agent-tool-blocked {
243
+ font-size: 13px;
244
+ color: var(--danger);
245
+ border: 1px dashed var(--danger);
246
+ border-radius: var(--radius-chip);
247
+ padding: 6px 10px;
248
+ }
249
+
250
+ /* 结果折叠区(mono、可复制) */
251
+ .agent-tool-result {
252
+ border-top: 1px dashed var(--border);
253
+ padding-top: 6px;
254
+ }
255
+
256
+ .agent-tool-result summary {
257
+ cursor: pointer;
258
+ font-size: 12.5px;
259
+ color: var(--text-secondary);
260
+ user-select: none;
261
+ }
262
+
263
+ .agent-tool-result pre {
264
+ margin-top: 6px;
265
+ font-family: var(--font-mono);
266
+ font-size: 12px;
267
+ line-height: 1.6;
268
+ color: var(--text);
269
+ background: var(--bg-sunken);
270
+ border: 1px solid var(--border);
271
+ border-radius: var(--radius-chip);
272
+ padding: 8px 10px;
273
+ white-space: pre-wrap;
274
+ word-break: break-all;
275
+ max-height: 240px;
276
+ overflow-y: auto;
277
+ }
278
+
279
+ .agent-tool-copy {
280
+ margin-top: 6px;
281
+ padding: 4px 12px;
282
+ font-size: 12px;
283
+ }
284
+
285
+ /* ── 时间线 ─────────────────────────────────────────────────────── */
286
+
287
+ .agent-timeline {
288
+ flex: 1;
289
+ min-height: 120px;
290
+ overflow-y: auto;
291
+ display: flex;
292
+ flex-direction: column;
293
+ gap: 8px;
294
+ padding: 4px 2px;
295
+ }
296
+
297
+ .agent-timeline-empty {
298
+ color: var(--text-tertiary);
299
+ font-size: 13.5px;
300
+ }
301
+
302
+ .agent-item {
303
+ padding: 9px 13px;
304
+ border-radius: var(--radius-card);
305
+ border: 1px solid var(--border);
306
+ font-size: 13.5px;
307
+ line-height: 1.6;
308
+ }
309
+
310
+ .agent-item-task {
311
+ align-self: flex-end;
312
+ background: var(--accent-soft);
313
+ border-color: transparent;
314
+ max-width: 78%;
315
+ }
316
+
317
+ .agent-item-assistant {
318
+ background: var(--bg-elevated);
319
+ }
320
+
321
+ .agent-item-notice {
322
+ color: var(--text-secondary);
323
+ border-style: dashed;
324
+ }
325
+
326
+ .agent-item-notice.is-danger {
327
+ color: var(--danger);
328
+ border-color: var(--danger);
329
+ }
330
+
331
+ /* ── 审计日志查看 ───────────────────────────────────────────────── */
332
+
333
+ .agent-audit-view {
334
+ max-height: 220px;
335
+ overflow-y: auto;
336
+ border: 1px solid var(--border);
337
+ border-radius: var(--radius-card);
338
+ background: var(--bg-sunken);
339
+ padding: 10px 14px;
340
+ }
341
+
342
+ .agent-audit-title {
343
+ display: flex;
344
+ justify-content: space-between;
345
+ align-items: center;
346
+ font-size: 12px;
347
+ color: var(--text-secondary);
348
+ margin-bottom: 6px;
349
+ gap: 10px;
350
+ }
351
+
352
+ .agent-audit-view pre {
353
+ font-family: var(--font-mono);
354
+ font-size: 11px;
355
+ line-height: 1.7;
356
+ color: var(--text-secondary);
357
+ white-space: pre-wrap;
358
+ word-break: break-all;
359
+ }
css/assistant.css ADDED
@@ -0,0 +1,704 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 常驻助理(契约 11A):面板 + 页签 + 设置区(Warm Paper,全令牌配色) */
2
+
3
+ /* ---------- 工作台根(页签条 + 内容区的纵向骨架) ---------- */
4
+ .wb-root {
5
+ flex: 1;
6
+ min-width: 0;
7
+ min-height: 0;
8
+ display: flex;
9
+ flex-direction: column;
10
+ }
11
+
12
+ .wb-body {
13
+ flex: 1;
14
+ min-width: 0;
15
+ min-height: 0;
16
+ display: flex;
17
+ }
18
+
19
+ /* ---------- 页签(对话工作台最左第一位) ---------- */
20
+ .wb-tabs {
21
+ display: flex;
22
+ align-items: center;
23
+ gap: 4px;
24
+ padding: 10px 16px 0;
25
+ border-bottom: 1px solid var(--border);
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .wb-tab {
30
+ position: relative;
31
+ display: inline-flex;
32
+ align-items: center;
33
+ gap: 6px;
34
+ height: 32px;
35
+ padding: 0 12px;
36
+ border: none;
37
+ border-radius: var(--radius-control) var(--radius-control) 0 0;
38
+ background: transparent;
39
+ color: var(--text-secondary);
40
+ font-family: inherit;
41
+ font-size: 13px;
42
+ cursor: pointer;
43
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
44
+ }
45
+
46
+ .wb-tab:hover {
47
+ background: var(--bg-elevated);
48
+ color: var(--text);
49
+ }
50
+
51
+ .wb-tab.is-active {
52
+ background: var(--accent-soft);
53
+ color: var(--text);
54
+ font-weight: 600;
55
+ }
56
+
57
+ .wb-tab:focus-visible {
58
+ outline: 2px solid var(--accent);
59
+ outline-offset: 2px;
60
+ }
61
+
62
+ /* 主动观察红点(v1 占位:有未读观察结论时亮点) */
63
+ .wb-tab-dot {
64
+ width: 7px;
65
+ height: 7px;
66
+ border-radius: 50%;
67
+ background: var(--danger);
68
+ flex-shrink: 0;
69
+ }
70
+
71
+ /* ---------- 面板骨架 ---------- */
72
+ .assistant-panel {
73
+ flex: 1;
74
+ min-width: 0;
75
+ min-height: 0;
76
+ display: flex;
77
+ flex-direction: column;
78
+ }
79
+
80
+ /* ---------- 头部:状态灯 + 人设名 + 设置 ---------- */
81
+ .assistant-head {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: space-between;
85
+ gap: 16px;
86
+ padding: 20px 48px 14px;
87
+ border-bottom: 1px solid var(--border);
88
+ flex-shrink: 0;
89
+ }
90
+
91
+ .assistant-id {
92
+ display: flex;
93
+ align-items: baseline;
94
+ gap: 10px;
95
+ min-width: 0;
96
+ }
97
+
98
+ .assistant-name {
99
+ font-size: 18px;
100
+ margin: 0;
101
+ }
102
+
103
+ .assistant-style {
104
+ font-size: 12px;
105
+ color: var(--text-tertiary);
106
+ white-space: nowrap;
107
+ overflow: hidden;
108
+ text-overflow: ellipsis;
109
+ }
110
+
111
+ .assistant-head-right {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 8px;
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ /* 驻场状态灯 */
119
+ .assistant-light {
120
+ display: inline-flex;
121
+ align-items: center;
122
+ gap: 6px;
123
+ height: 28px;
124
+ padding: 0 10px;
125
+ border: 1px solid var(--border);
126
+ border-radius: var(--radius-chip);
127
+ background: transparent;
128
+ color: var(--text-secondary);
129
+ font-family: inherit;
130
+ font-size: 12px;
131
+ cursor: pointer;
132
+ transition: background-color var(--dur) var(--ease);
133
+ }
134
+
135
+ .assistant-light:hover {
136
+ background: var(--bg-elevated);
137
+ }
138
+
139
+ .assistant-light-dot {
140
+ width: 8px;
141
+ height: 8px;
142
+ border-radius: 50%;
143
+ background: var(--text-tertiary);
144
+ flex-shrink: 0;
145
+ }
146
+
147
+ .assistant-light.is-resident .assistant-light-dot {
148
+ background: var(--success);
149
+ }
150
+
151
+ .assistant-light.is-sleeping .assistant-light-dot {
152
+ background: var(--text-tertiary);
153
+ }
154
+
155
+ .assistant-light.is-offline .assistant-light-dot {
156
+ background: var(--warning);
157
+ }
158
+
159
+ /* 云端在线(契约 17A:API 模型,不占本机内存)——accent 点色区分本机驻留 */
160
+ .assistant-light.is-cloud .assistant-light-dot {
161
+ background: var(--accent);
162
+ }
163
+
164
+ .assistant-light.is-cloud {
165
+ color: var(--text-secondary);
166
+ }
167
+
168
+ /* 专属助理徽标(契约 17A:对话页签里的专属模式) */
169
+ .assistant-style.is-thread {
170
+ color: var(--accent);
171
+ font-weight: 500;
172
+ }
173
+
174
+ /* 线程下拉(契约 17A:侧栏全局模式顶部的「全局 / 某会话」切换) */
175
+ .assistant-thread {
176
+ display: inline-flex;
177
+ align-items: center;
178
+ gap: 6px;
179
+ font-size: 12px;
180
+ color: var(--text-tertiary);
181
+ flex-shrink: 0;
182
+ }
183
+
184
+ .assistant-thread-label {
185
+ white-space: nowrap;
186
+ }
187
+
188
+ .assistant-thread-select {
189
+ max-width: 200px;
190
+ height: 28px;
191
+ padding: 0 8px;
192
+ border: 1px solid var(--border);
193
+ border-radius: var(--radius-chip);
194
+ background: var(--bg-elevated);
195
+ color: var(--text-secondary);
196
+ font-family: inherit;
197
+ font-size: 12px;
198
+ cursor: pointer;
199
+ }
200
+
201
+ .assistant-thread-select:disabled {
202
+ opacity: 0.5;
203
+ cursor: default;
204
+ }
205
+
206
+ .assistant-settings-btn {
207
+ display: inline-flex;
208
+ align-items: center;
209
+ gap: 5px;
210
+ height: 28px;
211
+ padding: 0 10px;
212
+ border: 1px solid var(--border);
213
+ border-radius: var(--radius-chip);
214
+ background: transparent;
215
+ color: var(--text-secondary);
216
+ font-family: inherit;
217
+ font-size: 12px;
218
+ cursor: pointer;
219
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
220
+ }
221
+
222
+ .assistant-settings-btn:hover {
223
+ background: var(--bg-elevated);
224
+ color: var(--text);
225
+ }
226
+
227
+ /* ---------- 消息流 ---------- */
228
+ .assistant-stream {
229
+ flex: 1;
230
+ min-height: 0;
231
+ overflow-y: auto;
232
+ }
233
+
234
+ .assistant-stream-inner {
235
+ max-width: 760px;
236
+ width: 100%;
237
+ margin: 0 auto;
238
+ padding: 32px 48px 24px;
239
+ display: flex;
240
+ flex-direction: column;
241
+ gap: 28px;
242
+ }
243
+
244
+ .ap-msg {
245
+ display: flex;
246
+ flex-direction: column;
247
+ gap: 8px;
248
+ }
249
+
250
+ .ap-msg.is-user {
251
+ align-items: flex-end;
252
+ }
253
+
254
+ .ap-msg-card {
255
+ max-width: 86%;
256
+ padding: 10px 16px;
257
+ border: 1px solid color-mix(in srgb, var(--accent) 16%, transparent);
258
+ border-radius: var(--radius-card);
259
+ background: var(--accent-soft);
260
+ font-size: 15px;
261
+ line-height: 1.7;
262
+ white-space: pre-wrap;
263
+ word-break: break-word;
264
+ }
265
+
266
+ .ap-md {
267
+ font-size: 15px;
268
+ line-height: 1.75;
269
+ color: var(--text);
270
+ }
271
+
272
+ /* 流式呼吸光标(design-system.md:1s 呼吸闪烁) */
273
+ .ap-caret {
274
+ display: inline-block;
275
+ width: 7px;
276
+ height: 15px;
277
+ margin-left: 2px;
278
+ vertical-align: text-bottom;
279
+ background: var(--accent);
280
+ border-radius: 1px;
281
+ animation: ap-breathe 1s ease-in-out infinite;
282
+ }
283
+
284
+ @keyframes ap-breathe {
285
+ 0%,
286
+ 100% {
287
+ opacity: 0.15;
288
+ }
289
+ 50% {
290
+ opacity: 0.9;
291
+ }
292
+ }
293
+
294
+ @media (prefers-reduced-motion: reduce) {
295
+ .ap-caret {
296
+ animation: none;
297
+ opacity: 0.6;
298
+ }
299
+ }
300
+
301
+ /* 只读工具迹(模型查了什么) */
302
+ .ap-tools {
303
+ display: flex;
304
+ flex-wrap: wrap;
305
+ gap: 6px;
306
+ }
307
+
308
+ .ap-tool-chip {
309
+ display: inline-flex;
310
+ align-items: center;
311
+ height: 22px;
312
+ padding: 0 8px;
313
+ border: 1px solid var(--border);
314
+ border-radius: var(--radius-chip);
315
+ background: var(--bg-elevated);
316
+ color: var(--text-secondary);
317
+ font-family: var(--font-mono);
318
+ font-size: 11px;
319
+ }
320
+
321
+ .ap-error {
322
+ margin: 0;
323
+ color: var(--danger);
324
+ font-size: 13px;
325
+ line-height: 1.6;
326
+ }
327
+
328
+ /* ---------- 空状态 ---------- */
329
+ .assistant-empty {
330
+ display: flex;
331
+ flex-direction: column;
332
+ gap: 12px;
333
+ padding: 40px 0;
334
+ }
335
+
336
+ .assistant-empty-title {
337
+ margin: 0;
338
+ font-family: var(--font-serif);
339
+ font-size: 22px;
340
+ font-weight: 600;
341
+ letter-spacing: -0.01em;
342
+ }
343
+
344
+ .assistant-empty-hint {
345
+ margin: 0;
346
+ color: var(--text-secondary);
347
+ font-size: 14px;
348
+ line-height: 1.7;
349
+ }
350
+
351
+ .assistant-suggestions {
352
+ display: flex;
353
+ flex-wrap: wrap;
354
+ gap: 8px;
355
+ margin-top: 8px;
356
+ }
357
+
358
+ .assistant-suggestion {
359
+ height: 32px;
360
+ padding: 0 14px;
361
+ border: 1px solid var(--border);
362
+ border-radius: var(--radius-chip);
363
+ background: transparent;
364
+ color: var(--text);
365
+ font-family: inherit;
366
+ font-size: 13px;
367
+ cursor: pointer;
368
+ transition: background-color var(--dur) var(--ease);
369
+ }
370
+
371
+ .assistant-suggestion:hover {
372
+ background: var(--bg-elevated);
373
+ }
374
+
375
+ /* ---------- 输入区 ---------- */
376
+ .assistant-composer-wrap {
377
+ flex-shrink: 0;
378
+ padding: 0 48px 24px;
379
+ }
380
+
381
+ .assistant-composer {
382
+ max-width: 760px;
383
+ margin: 0 auto;
384
+ border: 1px solid var(--border);
385
+ border-radius: var(--radius-card);
386
+ background: var(--bg-sunken);
387
+ transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
388
+ }
389
+
390
+ .assistant-composer:focus-within {
391
+ border-color: var(--accent);
392
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
393
+ }
394
+
395
+ .assistant-input {
396
+ display: block;
397
+ width: 100%;
398
+ padding: 12px 16px 4px;
399
+ border: none;
400
+ background: transparent;
401
+ color: var(--text);
402
+ font-family: inherit;
403
+ font-size: 15px;
404
+ line-height: 1.6;
405
+ resize: none;
406
+ outline: none;
407
+ }
408
+
409
+ .assistant-input::placeholder {
410
+ color: var(--text-tertiary);
411
+ }
412
+
413
+ .assistant-input:disabled {
414
+ color: var(--text-tertiary);
415
+ }
416
+
417
+ .assistant-composer-bar {
418
+ display: flex;
419
+ align-items: center;
420
+ justify-content: space-between;
421
+ gap: 12px;
422
+ padding: 6px 10px 10px 16px;
423
+ }
424
+
425
+ .assistant-hint {
426
+ font-size: 12px;
427
+ color: var(--text-tertiary);
428
+ }
429
+
430
+ .assistant-send {
431
+ display: inline-flex;
432
+ align-items: center;
433
+ justify-content: center;
434
+ width: 32px;
435
+ height: 32px;
436
+ border: none;
437
+ border-radius: var(--radius-chip);
438
+ background: var(--accent);
439
+ color: #fff;
440
+ cursor: pointer;
441
+ transition: opacity var(--dur) var(--ease);
442
+ flex-shrink: 0;
443
+ }
444
+
445
+ .assistant-send:hover:not(:disabled) {
446
+ opacity: 0.9;
447
+ }
448
+
449
+ .assistant-send:disabled {
450
+ opacity: 0.4;
451
+ cursor: default;
452
+ }
453
+
454
+ .assistant-send:focus-visible {
455
+ outline: 2px solid var(--accent);
456
+ outline-offset: 2px;
457
+ }
458
+
459
+ .assistant-send-spin {
460
+ width: 13px;
461
+ height: 13px;
462
+ border: 2px solid color-mix(in srgb, #fff 45%, transparent);
463
+ border-top-color: #fff;
464
+ border-radius: 50%;
465
+ animation: ap-spin 0.8s linear infinite;
466
+ }
467
+
468
+ @keyframes ap-spin {
469
+ to {
470
+ transform: rotate(360deg);
471
+ }
472
+ }
473
+
474
+ /* ---------- 设置区(AssistantSettings,Settings.tsx 挂载) ---------- */
475
+ .asst-set-row {
476
+ display: flex;
477
+ flex-direction: column;
478
+ gap: 8px;
479
+ margin-bottom: 20px;
480
+ }
481
+
482
+ .asst-set-row:last-child {
483
+ margin-bottom: 0;
484
+ }
485
+
486
+ .asst-set-label {
487
+ font-size: 13px;
488
+ font-weight: 600;
489
+ color: var(--text);
490
+ }
491
+
492
+ .asst-set-hint {
493
+ margin: 0;
494
+ font-size: 12px;
495
+ color: var(--text-secondary);
496
+ line-height: 1.6;
497
+ }
498
+
499
+ /* 驻场档四选:每档一个卡片,卡下方明示内存成本 */
500
+ .asst-residency-grid {
501
+ display: grid;
502
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
503
+ gap: 10px;
504
+ }
505
+
506
+ .asst-residency-card {
507
+ display: flex;
508
+ flex-direction: column;
509
+ gap: 6px;
510
+ padding: 12px 14px;
511
+ border: 1px solid var(--border);
512
+ border-radius: var(--radius-card);
513
+ background: transparent;
514
+ text-align: left;
515
+ font-family: inherit;
516
+ cursor: pointer;
517
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
518
+ }
519
+
520
+ .asst-residency-card:hover {
521
+ background: var(--bg-elevated);
522
+ }
523
+
524
+ .asst-residency-card.is-active {
525
+ border-color: var(--accent);
526
+ background: var(--accent-soft);
527
+ }
528
+
529
+ .asst-residency-card:focus-visible {
530
+ outline: 2px solid var(--accent);
531
+ outline-offset: 2px;
532
+ }
533
+
534
+ .asst-residency-name {
535
+ font-size: 13px;
536
+ font-weight: 600;
537
+ color: var(--text);
538
+ }
539
+
540
+ .asst-residency-cost {
541
+ font-size: 12px;
542
+ color: var(--text-secondary);
543
+ line-height: 1.55;
544
+ }
545
+
546
+ /* 人设编辑 */
547
+ .asst-persona-fields {
548
+ display: flex;
549
+ flex-direction: column;
550
+ gap: 10px;
551
+ }
552
+
553
+ .asst-field {
554
+ display: flex;
555
+ flex-direction: column;
556
+ gap: 4px;
557
+ }
558
+
559
+ .asst-field-label {
560
+ font-size: 12px;
561
+ color: var(--text-secondary);
562
+ }
563
+
564
+ .asst-input,
565
+ .asst-textarea {
566
+ width: 100%;
567
+ padding: 8px 12px;
568
+ border: 1px solid var(--border);
569
+ border-radius: var(--radius-control);
570
+ background: var(--bg-sunken);
571
+ color: var(--text);
572
+ font-family: inherit;
573
+ font-size: 14px;
574
+ line-height: 1.6;
575
+ outline: none;
576
+ transition: border-color var(--dur) var(--ease);
577
+ }
578
+
579
+ .asst-textarea {
580
+ min-height: 120px;
581
+ resize: vertical;
582
+ }
583
+
584
+ .asst-input:focus,
585
+ .asst-textarea:focus {
586
+ border-color: var(--accent);
587
+ }
588
+
589
+ .asst-actions {
590
+ display: flex;
591
+ align-items: center;
592
+ gap: 10px;
593
+ }
594
+
595
+ .asst-note {
596
+ font-size: 12px;
597
+ color: var(--text-secondary);
598
+ }
599
+
600
+ .asst-note.is-error {
601
+ color: var(--danger);
602
+ }
603
+
604
+ .asst-note.is-ok {
605
+ color: var(--success);
606
+ }
607
+
608
+ /* ── 「求助大脑」(契约 11B 补充二)──────────────────── */
609
+ .assistant-brain {
610
+ height: 30px;
611
+ padding: 0 12px;
612
+ border: 1px solid var(--border);
613
+ border-radius: var(--radius-control);
614
+ background: transparent;
615
+ color: var(--text-secondary);
616
+ font-family: inherit;
617
+ font-size: 12.5px;
618
+ cursor: default;
619
+ transition: background-color var(--dur) var(--ease),
620
+ border-color var(--dur) var(--ease);
621
+ }
622
+ .assistant-brain:hover:not(:disabled) {
623
+ background: var(--accent-soft);
624
+ border-color: var(--accent);
625
+ color: var(--text);
626
+ }
627
+ .assistant-brain:disabled {
628
+ opacity: 0.45;
629
+ }
630
+ .ap-msg-brain-tag {
631
+ display: inline-block;
632
+ margin-bottom: 4px;
633
+ padding: 1px 8px;
634
+ border-radius: 99px;
635
+ background: var(--accent-soft);
636
+ color: var(--accent);
637
+ font-size: 11px;
638
+ font-weight: 500;
639
+ }
640
+
641
+ /* ── 「发给主对话」(契约 16A)────────────────────── */
642
+ .ap-dispatch {
643
+ align-self: flex-start;
644
+ margin-top: 6px;
645
+ height: 26px;
646
+ padding: 0 10px;
647
+ border: 1px solid var(--border);
648
+ border-radius: var(--radius-control);
649
+ background: transparent;
650
+ color: var(--text-tertiary);
651
+ font-family: inherit;
652
+ font-size: 12px;
653
+ cursor: default;
654
+ transition: background-color var(--dur) var(--ease),
655
+ border-color var(--dur) var(--ease), color var(--dur) var(--ease);
656
+ }
657
+ .ap-dispatch:hover {
658
+ background: var(--accent-soft);
659
+ border-color: var(--accent);
660
+ color: var(--accent);
661
+ }
662
+
663
+ /* ──契约 22A 意图徽章 + 建议 chip ──
664
+ * 徽章:12px 衬线 tertiary 小字(不吵);chip:单个、贴在消息下方、
665
+ * hover 说「小栖猜你想…」——一律需点击,意图只影响建议不自动执行。 */
666
+ .ap-msg-meta {
667
+ display: flex;
668
+ align-items: center;
669
+ gap: 8px;
670
+ }
671
+
672
+ .ap-intent-badge {
673
+ font-family: var(--font-serif);
674
+ font-size: 12px;
675
+ line-height: 1.4;
676
+ color: var(--text-tertiary);
677
+ }
678
+
679
+ .ap-intent-chip {
680
+ display: inline-flex;
681
+ align-items: center;
682
+ height: 26px;
683
+ padding: 0 10px;
684
+ border: 1px solid var(--border);
685
+ border-radius: var(--radius-control);
686
+ background: var(--bg-elevated);
687
+ color: var(--text-secondary);
688
+ font-family: inherit;
689
+ font-size: 12px;
690
+ cursor: pointer;
691
+ transition: background-color var(--dur) var(--ease),
692
+ border-color var(--dur) var(--ease), color var(--dur) var(--ease);
693
+ }
694
+
695
+ .ap-intent-chip:hover {
696
+ background: var(--accent-soft);
697
+ border-color: var(--accent);
698
+ color: var(--accent);
699
+ }
700
+
701
+ .ap-intent-chip:focus-visible {
702
+ outline: 2px solid var(--accent);
703
+ outline-offset: 2px;
704
+ }
css/bench.css ADDED
@@ -0,0 +1,934 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 批量推理台(契约 20A · 工作台第三 tab「对比」)——Warm Paper 令牌,
2
+ 零硬编码色:所有颜色走 theme.css 变量(深浅色自动跟随)。
3
+ 布局沿用 .kb / .skills 的整页滚动容器(flex:1 + 独立滚动 + 48px 留白)。 */
4
+
5
+ .bench {
6
+ flex: 1;
7
+ min-width: 0;
8
+ overflow-y: auto;
9
+ padding: 36px 48px 48px;
10
+ }
11
+
12
+ /* ── 页头 ───────────────────────────────────────────────────────── */
13
+
14
+ .bench-head {
15
+ display: flex;
16
+ align-items: flex-end;
17
+ justify-content: space-between;
18
+ gap: 16px;
19
+ margin-bottom: 20px;
20
+ }
21
+
22
+ .bench-title {
23
+ font-family: var(--font-serif);
24
+ font-size: 26px;
25
+ font-weight: 600;
26
+ letter-spacing: -0.01em;
27
+ color: var(--text);
28
+ }
29
+
30
+ .bench-head-sub {
31
+ margin: 6px 0 0;
32
+ font-size: 13.5px;
33
+ line-height: 1.6;
34
+ color: var(--text-secondary);
35
+ }
36
+
37
+ .bench-head-actions {
38
+ display: flex;
39
+ gap: 8px;
40
+ flex-shrink: 0;
41
+ }
42
+
43
+ .bench-muted {
44
+ font-size: 13px;
45
+ line-height: 1.6;
46
+ color: var(--text-secondary);
47
+ }
48
+
49
+ .bench-notice {
50
+ margin: 0 0 16px;
51
+ padding: 10px 14px;
52
+ border: 1px solid var(--border);
53
+ border-radius: var(--radius-control);
54
+ background: var(--bg-elevated);
55
+ font-size: 13.5px;
56
+ line-height: 1.6;
57
+ color: var(--text);
58
+ }
59
+
60
+ /* ── 卡片与表单 ─────────────────────────────────────────────────── */
61
+
62
+ .bench-card {
63
+ background: var(--bg-elevated);
64
+ border: 1px solid var(--border);
65
+ border-radius: var(--radius-card);
66
+ padding: 22px 24px;
67
+ margin-bottom: 24px;
68
+ }
69
+
70
+ .bench-card-title {
71
+ font-family: var(--font-serif);
72
+ font-size: 18px;
73
+ font-weight: 600;
74
+ color: var(--text);
75
+ margin: 0 0 18px;
76
+ }
77
+
78
+ .bench-field {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: 8px;
82
+ margin-bottom: 18px;
83
+ }
84
+
85
+ .bench-field-label {
86
+ font-size: 13px;
87
+ color: var(--text-secondary);
88
+ }
89
+
90
+ .bench-field-row {
91
+ display: flex;
92
+ flex-wrap: wrap;
93
+ gap: 24px;
94
+ align-items: flex-start;
95
+ }
96
+
97
+ .bench-field-row .bench-field {
98
+ min-width: 240px;
99
+ flex: 1;
100
+ }
101
+
102
+ .bench-field textarea,
103
+ .bench-field select {
104
+ width: 100%;
105
+ font-family: var(--font-sans);
106
+ font-size: 14px;
107
+ line-height: 1.65;
108
+ color: var(--text);
109
+ background: var(--bg-sunken);
110
+ border: 1px solid transparent;
111
+ border-radius: var(--radius-control);
112
+ padding: 10px 12px;
113
+ transition: border-color var(--dur) var(--ease);
114
+ }
115
+
116
+ .bench-field textarea {
117
+ resize: vertical;
118
+ min-height: 120px;
119
+ }
120
+
121
+ .bench-field textarea::placeholder {
122
+ color: var(--text-tertiary);
123
+ }
124
+
125
+ .bench-field textarea:focus-visible,
126
+ .bench-field select:focus-visible {
127
+ outline: none;
128
+ border-color: var(--accent);
129
+ }
130
+
131
+ /* ── 模型分组多选(本机 / 云 · 接口名) ───────────────────────────── */
132
+
133
+ .bench-groups {
134
+ display: flex;
135
+ flex-direction: column;
136
+ gap: 14px;
137
+ }
138
+
139
+ .bench-group {
140
+ display: flex;
141
+ flex-direction: column;
142
+ gap: 8px;
143
+ }
144
+
145
+ .bench-group-label {
146
+ font-family: var(--font-serif);
147
+ font-size: 14px;
148
+ font-weight: 600;
149
+ color: var(--text);
150
+ }
151
+
152
+ .bench-chips {
153
+ display: flex;
154
+ flex-wrap: wrap;
155
+ gap: 8px;
156
+ }
157
+
158
+ .bench-chip {
159
+ display: inline-flex;
160
+ align-items: center;
161
+ gap: 7px;
162
+ height: 30px;
163
+ padding: 0 11px;
164
+ border: 1px solid var(--border);
165
+ border-radius: var(--radius-chip);
166
+ background: var(--bg);
167
+ color: var(--text-secondary);
168
+ font-family: inherit;
169
+ font-size: 13px;
170
+ cursor: pointer;
171
+ transition:
172
+ background-color var(--dur) var(--ease),
173
+ border-color var(--dur) var(--ease),
174
+ color var(--dur) var(--ease);
175
+ }
176
+
177
+ .bench-chip:hover {
178
+ background: var(--accent-soft);
179
+ color: var(--text);
180
+ }
181
+
182
+ .bench-chip.is-on {
183
+ background: var(--accent-soft);
184
+ border-color: var(--accent);
185
+ color: var(--text);
186
+ font-weight: 600;
187
+ }
188
+
189
+ .bench-chip:focus-visible {
190
+ outline: 2px solid var(--accent);
191
+ outline-offset: 2px;
192
+ }
193
+
194
+ .bench-chip-name {
195
+ max-width: 200px;
196
+ overflow: hidden;
197
+ text-overflow: ellipsis;
198
+ white-space: nowrap;
199
+ }
200
+
201
+ .bench-chip-badge {
202
+ font-size: 11px;
203
+ line-height: 1;
204
+ padding: 3px 6px;
205
+ border-radius: var(--radius-chip);
206
+ background: var(--bg-sunken);
207
+ color: var(--text-secondary);
208
+ }
209
+
210
+ .bench-chip-badge.is-cloud {
211
+ background: var(--accent-soft);
212
+ color: var(--text);
213
+ }
214
+
215
+ /* ── 评委开关 ───────────────────────────────────────────────────── */
216
+
217
+ .bench-field-switch {
218
+ min-width: 280px;
219
+ }
220
+
221
+ .bench-switch-line {
222
+ display: flex;
223
+ align-items: center;
224
+ gap: 10px;
225
+ }
226
+
227
+ .bench-switch {
228
+ position: relative;
229
+ width: 42px;
230
+ height: 24px;
231
+ flex-shrink: 0;
232
+ border: 1px solid var(--border);
233
+ border-radius: var(--radius-chip);
234
+ background: var(--bg-sunken);
235
+ cursor: pointer;
236
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
237
+ }
238
+
239
+ .bench-switch.is-on {
240
+ background: var(--accent);
241
+ border-color: var(--accent);
242
+ }
243
+
244
+ .bench-switch-knob {
245
+ position: absolute;
246
+ top: 2px;
247
+ left: 2px;
248
+ width: 18px;
249
+ height: 18px;
250
+ border-radius: 50%;
251
+ background: var(--bg);
252
+ transition: transform var(--dur) var(--ease);
253
+ }
254
+
255
+ .bench-switch.is-on .bench-switch-knob {
256
+ transform: translateX(18px);
257
+ }
258
+
259
+ .bench-switch:focus-visible {
260
+ outline: 2px solid var(--accent);
261
+ outline-offset: 2px;
262
+ }
263
+
264
+ /* ── think 五档(整场统一一档) ──────────────────────────────────── */
265
+
266
+ .bench-think {
267
+ display: inline-flex;
268
+ gap: 4px;
269
+ padding: 4px;
270
+ background: var(--bg-sunken);
271
+ border-radius: var(--radius-control);
272
+ }
273
+
274
+ .bench-think-btn {
275
+ min-width: 44px;
276
+ height: 28px;
277
+ padding: 0 10px;
278
+ border: none;
279
+ border-radius: var(--radius-control);
280
+ background: transparent;
281
+ color: var(--text-secondary);
282
+ font-family: inherit;
283
+ font-size: 12.5px;
284
+ cursor: pointer;
285
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
286
+ }
287
+
288
+ .bench-think-btn:hover {
289
+ color: var(--text);
290
+ }
291
+
292
+ .bench-think-btn.is-on {
293
+ background: var(--bg-elevated);
294
+ color: var(--text);
295
+ font-weight: 600;
296
+ box-shadow: inset 0 0 0 1px var(--border);
297
+ }
298
+
299
+ .bench-think-btn.is-ultra.is-on {
300
+ background: var(--accent-soft);
301
+ box-shadow: inset 0 0 0 1px var(--accent);
302
+ }
303
+
304
+ .bench-think-btn:focus-visible {
305
+ outline: 2px solid var(--accent);
306
+ outline-offset: 2px;
307
+ }
308
+
309
+ /* ── 成本提示(契约:开跑前必须可见) ────────────────────────────── */
310
+
311
+ .bench-cost {
312
+ padding: 12px 14px;
313
+ margin-bottom: 18px;
314
+ background: var(--bg-sunken);
315
+ border-radius: var(--radius-control);
316
+ }
317
+
318
+ .bench-cost-summary {
319
+ margin: 0;
320
+ font-size: 13.5px;
321
+ line-height: 1.6;
322
+ color: var(--text);
323
+ }
324
+
325
+ .bench-cost-discipline {
326
+ display: inline-block;
327
+ margin-left: 10px;
328
+ padding: 2px 8px;
329
+ border: 1px solid var(--border);
330
+ border-radius: var(--radius-chip);
331
+ font-size: 12px;
332
+ color: var(--text-secondary);
333
+ }
334
+
335
+ .bench-cost-lines {
336
+ display: flex;
337
+ flex-wrap: wrap;
338
+ gap: 6px 16px;
339
+ margin: 8px 0 0;
340
+ padding: 0;
341
+ list-style: none;
342
+ }
343
+
344
+ .bench-cost-lines li {
345
+ display: inline-flex;
346
+ align-items: baseline;
347
+ gap: 6px;
348
+ font-size: 12.5px;
349
+ color: var(--text-secondary);
350
+ }
351
+
352
+ .bench-cost-model {
353
+ font-family: var(--font-mono);
354
+ font-size: 12px;
355
+ color: var(--text);
356
+ }
357
+
358
+ .bench-cost-lines li.is-free .bench-cost-label {
359
+ color: var(--success);
360
+ }
361
+
362
+ .bench-cost-lines li.is-paid .bench-cost-label {
363
+ color: var(--warning);
364
+ }
365
+
366
+ .bench-cost-lines li.is-local .bench-cost-label {
367
+ color: var(--text-secondary);
368
+ }
369
+
370
+ /* ── 按钮 ───────────────────────────────────────────────────────── */
371
+
372
+ .bench-actions {
373
+ display: flex;
374
+ align-items: center;
375
+ gap: 14px;
376
+ flex-wrap: wrap;
377
+ }
378
+
379
+ .bench-primary {
380
+ display: inline-flex;
381
+ align-items: center;
382
+ gap: 7px;
383
+ height: 38px;
384
+ padding: 0 18px;
385
+ border: none;
386
+ border-radius: var(--radius-control);
387
+ background: var(--accent);
388
+ color: var(--bg);
389
+ font-family: inherit;
390
+ font-size: 14px;
391
+ font-weight: 600;
392
+ cursor: pointer;
393
+ transition: opacity var(--dur) var(--ease);
394
+ }
395
+
396
+ .bench-primary:hover:not(:disabled) {
397
+ opacity: 0.9;
398
+ }
399
+
400
+ .bench-primary:disabled {
401
+ opacity: 0.45;
402
+ cursor: not-allowed;
403
+ }
404
+
405
+ .bench-primary:focus-visible {
406
+ outline: 2px solid var(--accent);
407
+ outline-offset: 2px;
408
+ }
409
+
410
+ .bench-secondary,
411
+ .bench-danger,
412
+ .bench-icon-btn {
413
+ display: inline-flex;
414
+ align-items: center;
415
+ gap: 6px;
416
+ height: 30px;
417
+ padding: 0 11px;
418
+ border: 1px solid var(--border);
419
+ border-radius: var(--radius-control);
420
+ background: transparent;
421
+ color: var(--text-secondary);
422
+ font-family: inherit;
423
+ font-size: 13px;
424
+ cursor: pointer;
425
+ transition:
426
+ background-color var(--dur) var(--ease),
427
+ color var(--dur) var(--ease),
428
+ border-color var(--dur) var(--ease);
429
+ }
430
+
431
+ .bench-secondary:hover {
432
+ background: var(--accent-soft);
433
+ color: var(--text);
434
+ }
435
+
436
+ .bench-danger {
437
+ color: var(--danger);
438
+ border-color: var(--danger);
439
+ }
440
+
441
+ .bench-danger:hover {
442
+ background: var(--danger);
443
+ color: var(--bg);
444
+ }
445
+
446
+ .bench-icon-btn {
447
+ padding: 0 9px;
448
+ font-size: 16px;
449
+ line-height: 1;
450
+ }
451
+
452
+ .bench-secondary:focus-visible,
453
+ .bench-danger:focus-visible,
454
+ .bench-icon-btn:focus-visible {
455
+ outline: 2px solid var(--accent);
456
+ outline-offset: 2px;
457
+ }
458
+
459
+ /* ── 运行头 + 进度 ──────────────────────────────────────────────── */
460
+
461
+ .bench-run-head {
462
+ display: flex;
463
+ align-items: center;
464
+ justify-content: space-between;
465
+ gap: 16px;
466
+ flex-wrap: wrap;
467
+ margin-bottom: 14px;
468
+ }
469
+
470
+ .bench-run-title {
471
+ display: flex;
472
+ align-items: baseline;
473
+ gap: 10px;
474
+ flex-wrap: wrap;
475
+ min-width: 0;
476
+ }
477
+
478
+ .bench-run-title .bench-card-title {
479
+ margin: 0;
480
+ }
481
+
482
+ .bench-toolbar {
483
+ display: flex;
484
+ gap: 8px;
485
+ flex-shrink: 0;
486
+ }
487
+
488
+ .bench-progress {
489
+ height: 6px;
490
+ border-radius: var(--radius-chip);
491
+ background: var(--bg-sunken);
492
+ overflow: hidden;
493
+ margin-bottom: 18px;
494
+ }
495
+
496
+ .bench-progress-fill {
497
+ height: 100%;
498
+ background: var(--accent);
499
+ border-radius: var(--radius-chip);
500
+ transition: width var(--dur) var(--ease);
501
+ }
502
+
503
+ /* ── 状态点 / 徽章 ──────────────────────────────────────────────── */
504
+
505
+ .bench-dot {
506
+ width: 9px;
507
+ height: 9px;
508
+ flex-shrink: 0;
509
+ border-radius: 50%;
510
+ background: var(--text-tertiary);
511
+ }
512
+
513
+ .bench-dot.is-running {
514
+ background: var(--accent);
515
+ }
516
+
517
+ .bench-dot.is-done {
518
+ background: var(--success);
519
+ }
520
+
521
+ .bench-dot.is-failed {
522
+ background: var(--danger);
523
+ }
524
+
525
+ .bench-dot.is-stopped {
526
+ background: var(--warning);
527
+ }
528
+
529
+ .bench-dot.is-pending {
530
+ background: var(--text-tertiary);
531
+ }
532
+
533
+ .bench-badge {
534
+ display: inline-flex;
535
+ align-items: center;
536
+ height: 20px;
537
+ padding: 0 8px;
538
+ border-radius: var(--radius-chip);
539
+ background: var(--bg-sunken);
540
+ font-size: 11.5px;
541
+ color: var(--text-secondary);
542
+ white-space: nowrap;
543
+ }
544
+
545
+ .bench-badge.is-running {
546
+ background: var(--accent-soft);
547
+ color: var(--text);
548
+ }
549
+
550
+ .bench-badge.is-done {
551
+ color: var(--success);
552
+ }
553
+
554
+ .bench-badge.is-error,
555
+ .bench-badge.is-failed {
556
+ color: var(--danger);
557
+ }
558
+
559
+ .bench-badge.is-cancelled,
560
+ .bench-badge.is-stopped {
561
+ color: var(--warning);
562
+ }
563
+
564
+ /* ── 评委卡(完成后置顶) ───────────────────────────────────────── */
565
+
566
+ .bench-judge {
567
+ border: 1px solid var(--border);
568
+ border-radius: var(--radius-card);
569
+ background: var(--bg);
570
+ padding: 18px 20px;
571
+ margin-bottom: 20px;
572
+ }
573
+
574
+ .bench-judge-head {
575
+ display: flex;
576
+ align-items: center;
577
+ gap: 10px;
578
+ flex-wrap: wrap;
579
+ margin-bottom: 10px;
580
+ }
581
+
582
+ .bench-judge-badge {
583
+ display: inline-flex;
584
+ align-items: center;
585
+ height: 22px;
586
+ padding: 0 9px;
587
+ border-radius: var(--radius-chip);
588
+ background: var(--accent);
589
+ color: var(--bg);
590
+ font-size: 11.5px;
591
+ font-weight: 600;
592
+ }
593
+
594
+ .bench-judge-model {
595
+ margin: 0;
596
+ font-family: var(--font-serif);
597
+ font-size: 15px;
598
+ font-weight: 600;
599
+ color: var(--text);
600
+ }
601
+
602
+ .bench-judge-rec {
603
+ display: inline-flex;
604
+ align-items: center;
605
+ height: 22px;
606
+ padding: 0 9px;
607
+ border: 1px solid var(--accent);
608
+ border-radius: var(--radius-chip);
609
+ background: var(--accent-soft);
610
+ font-size: 12px;
611
+ color: var(--text);
612
+ max-width: 320px;
613
+ overflow: hidden;
614
+ text-overflow: ellipsis;
615
+ white-space: nowrap;
616
+ }
617
+
618
+ /* ── 矩阵表(行 = prompt、列 = 模型) ────────────────────────────── */
619
+
620
+ .bench-table-wrap {
621
+ overflow-x: auto;
622
+ border: 1px solid var(--border);
623
+ border-radius: var(--radius-card);
624
+ }
625
+
626
+ .bench-table {
627
+ width: 100%;
628
+ border-collapse: collapse;
629
+ font-size: 13px;
630
+ }
631
+
632
+ .bench-table th,
633
+ .bench-table td {
634
+ border-bottom: 1px solid var(--border);
635
+ vertical-align: top;
636
+ text-align: left;
637
+ }
638
+
639
+ .bench-table thead th {
640
+ background: var(--bg-sunken);
641
+ padding: 10px 12px;
642
+ font-weight: 600;
643
+ color: var(--text);
644
+ white-space: nowrap;
645
+ }
646
+
647
+ .bench-col-name {
648
+ display: block;
649
+ font-family: var(--font-serif);
650
+ font-size: 13.5px;
651
+ }
652
+
653
+ .bench-col-cost {
654
+ display: block;
655
+ margin-top: 2px;
656
+ font-size: 11.5px;
657
+ font-weight: 400;
658
+ color: var(--text-secondary);
659
+ }
660
+
661
+ .bench-table tbody tr:last-child th,
662
+ .bench-table tbody tr:last-child td {
663
+ border-bottom: none;
664
+ }
665
+
666
+ .bench-row-prompt {
667
+ width: 240px;
668
+ padding: 12px;
669
+ font-weight: 500;
670
+ color: var(--text);
671
+ }
672
+
673
+ .bench-idx {
674
+ display: inline-block;
675
+ min-width: 20px;
676
+ margin-right: 6px;
677
+ font-family: var(--font-mono);
678
+ font-size: 12px;
679
+ color: var(--text-tertiary);
680
+ }
681
+
682
+ .bench-row-text {
683
+ font-size: 13px;
684
+ line-height: 1.6;
685
+ }
686
+
687
+ .bench-td {
688
+ position: relative;
689
+ min-width: 190px;
690
+ padding: 0;
691
+ }
692
+
693
+ .bench-cell {
694
+ display: block;
695
+ width: 100%;
696
+ padding: 12px;
697
+ border: none;
698
+ background: transparent;
699
+ font-family: inherit;
700
+ text-align: left;
701
+ cursor: pointer;
702
+ transition: background-color var(--dur) var(--ease);
703
+ }
704
+
705
+ .bench-cell:hover {
706
+ background: var(--accent-soft);
707
+ }
708
+
709
+ .bench-cell:focus-visible {
710
+ outline: 2px solid var(--accent);
711
+ outline-offset: -2px;
712
+ }
713
+
714
+ .bench-cell-top {
715
+ display: flex;
716
+ align-items: center;
717
+ gap: 7px;
718
+ margin-bottom: 5px;
719
+ }
720
+
721
+ .bench-cell-metric {
722
+ font-family: var(--font-mono);
723
+ font-size: 11.5px;
724
+ color: var(--text-secondary);
725
+ }
726
+
727
+ .bench-excerpt {
728
+ font-size: 12.5px;
729
+ line-height: 1.55;
730
+ color: var(--text-secondary);
731
+ overflow: hidden;
732
+ display: -webkit-box;
733
+ -webkit-line-clamp: 2;
734
+ -webkit-box-orient: vertical;
735
+ }
736
+
737
+ .bench-cell-retry,
738
+ .bench-cell-stop {
739
+ position: absolute;
740
+ top: 8px;
741
+ right: 8px;
742
+ width: 22px;
743
+ height: 22px;
744
+ display: inline-flex;
745
+ align-items: center;
746
+ justify-content: center;
747
+ border: 1px solid var(--border);
748
+ border-radius: var(--radius-chip);
749
+ background: var(--bg-elevated);
750
+ color: var(--text-secondary);
751
+ cursor: pointer;
752
+ transition:
753
+ background-color var(--dur) var(--ease),
754
+ color var(--dur) var(--ease);
755
+ }
756
+
757
+ .bench-cell-retry:hover {
758
+ background: var(--accent-soft);
759
+ color: var(--text);
760
+ }
761
+
762
+ .bench-cell-stop:hover {
763
+ background: var(--danger);
764
+ color: var(--bg);
765
+ }
766
+
767
+ .bench-cell-retry:focus-visible,
768
+ .bench-cell-stop:focus-visible {
769
+ outline: 2px solid var(--accent);
770
+ outline-offset: 1px;
771
+ }
772
+
773
+ .bench-legend {
774
+ margin: 12px 0 0;
775
+ font-size: 12.5px;
776
+ line-height: 1.6;
777
+ color: var(--text-secondary);
778
+ }
779
+
780
+ /* ── 全文抽屉 ───────────────────────────────────────────────────── */
781
+
782
+ .bench-drawer-mask {
783
+ position: fixed;
784
+ inset: 0;
785
+ display: flex;
786
+ justify-content: flex-end;
787
+ background: var(--scrim);
788
+ z-index: 40;
789
+ }
790
+
791
+ .bench-drawer {
792
+ display: flex;
793
+ flex-direction: column;
794
+ width: min(560px, 92vw);
795
+ height: 100%;
796
+ background: var(--bg-elevated);
797
+ border-left: 1px solid var(--border);
798
+ box-shadow: var(--shadow-float);
799
+ animation: bench-drawer-in 180ms var(--ease);
800
+ }
801
+
802
+ @keyframes bench-drawer-in {
803
+ from {
804
+ opacity: 0;
805
+ transform: translateX(12px);
806
+ }
807
+ to {
808
+ opacity: 1;
809
+ transform: translateX(0);
810
+ }
811
+ }
812
+
813
+ .bench-drawer-head {
814
+ display: flex;
815
+ align-items: center;
816
+ justify-content: space-between;
817
+ gap: 12px;
818
+ padding: 18px 22px;
819
+ border-bottom: 1px solid var(--border);
820
+ }
821
+
822
+ .bench-drawer-title {
823
+ display: flex;
824
+ align-items: center;
825
+ gap: 9px;
826
+ min-width: 0;
827
+ font-family: var(--font-serif);
828
+ font-size: 15px;
829
+ font-weight: 600;
830
+ color: var(--text);
831
+ }
832
+
833
+ .bench-drawer-actions {
834
+ display: flex;
835
+ align-items: center;
836
+ gap: 8px;
837
+ flex-shrink: 0;
838
+ }
839
+
840
+ .bench-drawer-meta {
841
+ margin: 0;
842
+ padding: 10px 22px;
843
+ border-bottom: 1px solid var(--border);
844
+ font-family: var(--font-mono);
845
+ font-size: 12px;
846
+ color: var(--text-secondary);
847
+ }
848
+
849
+ .bench-drawer-body {
850
+ flex: 1;
851
+ overflow-y: auto;
852
+ padding: 20px 22px;
853
+ font-size: 14.5px;
854
+ line-height: 1.7;
855
+ }
856
+
857
+ .bench-drawer-body .md > * {
858
+ margin: 0 0 12px;
859
+ }
860
+
861
+ /* ── 历史 ───────────────────────────────────────────────────────── */
862
+
863
+ .bench-history {
864
+ margin-top: 8px;
865
+ }
866
+
867
+ .bench-history-title {
868
+ font-family: var(--font-serif);
869
+ font-size: 15px;
870
+ font-weight: 600;
871
+ color: var(--text);
872
+ margin: 0 0 10px;
873
+ }
874
+
875
+ .bench-history-list {
876
+ list-style: none;
877
+ margin: 0;
878
+ padding: 0;
879
+ border-top: 1px solid var(--border);
880
+ }
881
+
882
+ .bench-history-item {
883
+ display: flex;
884
+ align-items: center;
885
+ gap: 12px;
886
+ width: 100%;
887
+ padding: 11px 6px;
888
+ border: none;
889
+ border-bottom: 1px solid var(--border);
890
+ background: transparent;
891
+ font-family: inherit;
892
+ text-align: left;
893
+ cursor: pointer;
894
+ transition: background-color var(--dur) var(--ease);
895
+ }
896
+
897
+ .bench-history-item:hover {
898
+ background: var(--accent-soft);
899
+ }
900
+
901
+ .bench-history-item.is-active {
902
+ background: var(--accent-soft);
903
+ }
904
+
905
+ .bench-history-item:focus-visible {
906
+ outline: 2px solid var(--accent);
907
+ outline-offset: -2px;
908
+ }
909
+
910
+ .bench-history-name {
911
+ font-family: var(--font-serif);
912
+ font-size: 14px;
913
+ color: var(--text);
914
+ max-width: 46%;
915
+ overflow: hidden;
916
+ text-overflow: ellipsis;
917
+ white-space: nowrap;
918
+ }
919
+
920
+ .bench-history-meta {
921
+ font-size: 12.5px;
922
+ color: var(--text-secondary);
923
+ }
924
+
925
+ /* ── 动效克制(尊重 reduced-motion) ────────────────────────────── */
926
+
927
+ @media (prefers-reduced-motion: reduce) {
928
+ .bench *,
929
+ .bench *::before,
930
+ .bench *::after {
931
+ transition-duration: 0.01ms !important;
932
+ animation-duration: 0.01ms !important;
933
+ }
934
+ }
css/board.css ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 系统看板:指标卡 + 进程表 + 网络简报(Warm Paper,全令牌配色)。
2
+ 数字一律 tabular-nums 等宽对齐(design-system §4)。 */
3
+
4
+ .board {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ }
10
+
11
+ .board-head {
12
+ margin-bottom: 28px;
13
+ }
14
+
15
+ .board-head h1 {
16
+ font-size: 30px;
17
+ }
18
+
19
+ .board-sub {
20
+ margin: 6px 0 0;
21
+ font-size: 13.5px;
22
+ color: var(--text-secondary);
23
+ font-variant-numeric: tabular-nums;
24
+ }
25
+
26
+ /* ── 指标卡 ─────────────────────────────────────────────────────── */
27
+
28
+ .board-cards {
29
+ display: grid;
30
+ grid-template-columns: repeat(4, minmax(0, 1fr));
31
+ gap: 16px;
32
+ }
33
+
34
+ .metric-card {
35
+ display: flex;
36
+ flex-direction: column;
37
+ padding: 20px 22px 18px;
38
+ border: 1px solid var(--border);
39
+ border-radius: var(--radius-card);
40
+ background: var(--bg-elevated);
41
+ }
42
+
43
+ .metric-label {
44
+ font-size: 13px;
45
+ color: var(--text-secondary);
46
+ }
47
+
48
+ .metric-value {
49
+ margin-top: 6px;
50
+ font-family: var(--font-serif);
51
+ font-size: 40px;
52
+ font-weight: 600;
53
+ line-height: 1.15;
54
+ letter-spacing: -0.01em;
55
+ color: var(--text);
56
+ font-variant-numeric: tabular-nums;
57
+ }
58
+
59
+ .metric-unit {
60
+ margin-left: 2px;
61
+ font-size: 20px;
62
+ color: var(--text-secondary);
63
+ }
64
+
65
+ .metric-bar {
66
+ margin-top: 12px;
67
+ height: 6px;
68
+ border-radius: 3px;
69
+ background: var(--bg-sunken);
70
+ overflow: hidden;
71
+ }
72
+
73
+ .metric-bar-fill {
74
+ height: 100%;
75
+ border-radius: 3px;
76
+ transition: background-color var(--dur) var(--ease);
77
+ }
78
+
79
+ .metric-note {
80
+ margin-top: 10px;
81
+ font-size: 12.5px;
82
+ line-height: 1.5;
83
+ color: var(--text-secondary);
84
+ font-variant-numeric: tabular-nums;
85
+ }
86
+
87
+ /* 语义色:<70% success / 70–85% warning / >85% danger
88
+ 2026-10-23 修复:必须带填充物类作用域——裸 .is-success 会匹配全 App 所有
89
+ is-success 元素(曾把验收卡整卡刷成实心绿)。 */
90
+ .metric-bar-fill.is-success,
91
+ .core-bar-fill.is-success {
92
+ background: var(--success);
93
+ }
94
+ .metric-bar-fill.is-warning,
95
+ .core-bar-fill.is-warning {
96
+ background: var(--warning);
97
+ }
98
+ .metric-bar-fill.is-danger,
99
+ .core-bar-fill.is-danger {
100
+ background: var(--danger);
101
+ }
102
+
103
+ /* CPU 每核迷你竖条 */
104
+ .core-bars {
105
+ display: flex;
106
+ align-items: flex-end;
107
+ gap: 3px;
108
+ height: 22px;
109
+ margin-top: 12px;
110
+ }
111
+
112
+ .core-bar {
113
+ flex: 1;
114
+ min-width: 0;
115
+ height: 100%;
116
+ display: flex;
117
+ align-items: flex-end;
118
+ border-radius: 2px;
119
+ background: var(--bg-sunken);
120
+ overflow: hidden;
121
+ }
122
+
123
+ .core-bar-fill {
124
+ width: 100%;
125
+ min-height: 2px;
126
+ border-radius: 2px;
127
+ transition: background-color var(--dur) var(--ease);
128
+ }
129
+
130
+ /* 数值变化只做 150ms 淡入,不做数字滚动(design-system §6) */
131
+ .board-num {
132
+ display: inline-block;
133
+ animation: board-fade var(--dur) var(--ease);
134
+ }
135
+
136
+ @keyframes board-fade {
137
+ from {
138
+ opacity: 0.35;
139
+ }
140
+ to {
141
+ opacity: 1;
142
+ }
143
+ }
144
+
145
+ /* ── 下方两个面板 ───────────────────────────────────────────────── */
146
+
147
+ .board-panels {
148
+ display: grid;
149
+ grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
150
+ gap: 16px;
151
+ margin-top: 16px;
152
+ align-items: start;
153
+ }
154
+
155
+ .panel {
156
+ padding: 20px 22px;
157
+ border: 1px solid var(--border);
158
+ border-radius: var(--radius-card);
159
+ background: var(--bg-elevated);
160
+ }
161
+
162
+ .panel h2 {
163
+ font-size: 16px;
164
+ margin-bottom: 12px;
165
+ }
166
+
167
+ .panel-note {
168
+ margin: 4px 0;
169
+ font-size: 13px;
170
+ color: var(--text-tertiary);
171
+ }
172
+
173
+ .panel-foot {
174
+ margin: 12px 0 0;
175
+ font-size: 12px;
176
+ color: var(--text-tertiary);
177
+ }
178
+
179
+ /* ── 进程表 ─────────────────────────────────────────────────────── */
180
+
181
+ .proc-table {
182
+ width: 100%;
183
+ border-collapse: collapse;
184
+ font-size: 13px;
185
+ font-variant-numeric: tabular-nums;
186
+ }
187
+
188
+ .proc-table th {
189
+ padding: 6px 8px;
190
+ text-align: left;
191
+ font-weight: 500;
192
+ font-size: 12px;
193
+ color: var(--text-secondary);
194
+ border-bottom: 1px solid var(--border);
195
+ }
196
+
197
+ .proc-table th.num,
198
+ .proc-table td.num {
199
+ text-align: right;
200
+ }
201
+
202
+ .proc-table td {
203
+ padding: 7px 8px;
204
+ border-bottom: 1px solid var(--border);
205
+ }
206
+
207
+ .proc-table tbody tr {
208
+ transition: background-color var(--dur) var(--ease);
209
+ }
210
+
211
+ /* hover 行底色 = accent-soft 的 40%(design-system §7) */
212
+ .proc-table tbody tr:hover {
213
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
214
+ }
215
+
216
+ .proc-table tbody tr:last-child td {
217
+ border-bottom: none;
218
+ }
219
+
220
+ .proc-name {
221
+ max-width: 0;
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ white-space: nowrap;
225
+ }
226
+
227
+ .sort-btn {
228
+ padding: 0;
229
+ border: none;
230
+ background: transparent;
231
+ color: inherit;
232
+ font: inherit;
233
+ font-variant-numeric: tabular-nums;
234
+ cursor: pointer;
235
+ }
236
+
237
+ .sort-btn:hover {
238
+ color: var(--text);
239
+ }
240
+
241
+ .sort-btn.is-active {
242
+ color: var(--accent);
243
+ }
244
+
245
+ .sort-arrow {
246
+ font-size: 10px;
247
+ }
248
+
249
+ /* ── 网络简报 ───────────────────────────────────────────────────── */
250
+
251
+ .net-public {
252
+ display: flex;
253
+ align-items: baseline;
254
+ gap: 10px;
255
+ padding-bottom: 12px;
256
+ border-bottom: 1px solid var(--border);
257
+ }
258
+
259
+ .net-public-label {
260
+ flex-shrink: 0;
261
+ font-size: 12.5px;
262
+ color: var(--text-secondary);
263
+ }
264
+
265
+ .net-public-value {
266
+ font-family: var(--font-mono);
267
+ font-size: 15px;
268
+ color: var(--text);
269
+ font-variant-numeric: tabular-nums;
270
+ overflow-wrap: anywhere;
271
+ }
272
+
273
+ .iface-list {
274
+ list-style: none;
275
+ margin: 10px 0 0;
276
+ padding: 0;
277
+ }
278
+
279
+ .iface {
280
+ display: flex;
281
+ align-items: baseline;
282
+ gap: 10px;
283
+ padding: 7px 0;
284
+ font-size: 13px;
285
+ }
286
+
287
+ .iface + .iface {
288
+ border-top: 1px solid var(--border);
289
+ }
290
+
291
+ .iface-name {
292
+ flex-shrink: 0;
293
+ min-width: 56px;
294
+ font-family: var(--font-mono);
295
+ font-size: 12.5px;
296
+ color: var(--text);
297
+ }
298
+
299
+ .iface-ips {
300
+ flex: 1;
301
+ min-width: 0;
302
+ color: var(--text-secondary);
303
+ font-variant-numeric: tabular-nums;
304
+ overflow-wrap: anywhere;
305
+ }
306
+
307
+ .iface-mac {
308
+ flex-shrink: 0;
309
+ font-family: var(--font-mono);
310
+ font-size: 11.5px;
311
+ color: var(--text-tertiary);
312
+ }
313
+
314
+ /* ── 空态(衬线大字一句话,design-system §7)─────────────────────── */
315
+
316
+ .board-empty {
317
+ padding: 56px 0 24px;
318
+ }
319
+
320
+ .board-empty-title {
321
+ margin: 0;
322
+ font-family: var(--font-serif);
323
+ font-size: 24px;
324
+ font-weight: 600;
325
+ color: var(--text);
326
+ }
327
+
328
+ .board-empty-sub {
329
+ margin: 10px 0 0;
330
+ font-size: 13.5px;
331
+ color: var(--text-secondary);
332
+ }
333
+
334
+ /* ── CPU 异构分组(Apple Silicon 性能核/能效核)────────────── */
335
+ .core-groups {
336
+ display: flex;
337
+ flex-direction: column;
338
+ gap: 6px;
339
+ }
340
+ .core-group-row {
341
+ display: flex;
342
+ align-items: center;
343
+ gap: 10px;
344
+ }
345
+ .core-group-label {
346
+ flex-shrink: 0;
347
+ width: 60px;
348
+ font-size: 12px;
349
+ color: var(--text-secondary);
350
+ }
351
+ .core-group-count {
352
+ font-family: var(--font-mono);
353
+ font-variant-numeric: tabular-nums;
354
+ color: var(--text-tertiary);
355
+ }
356
+ .core-group-row .core-bars {
357
+ flex: 1;
358
+ }
359
+ .core-group-avg {
360
+ flex-shrink: 0;
361
+ width: 38px;
362
+ text-align: right;
363
+ font-family: var(--font-mono);
364
+ font-size: 12px;
365
+ font-variant-numeric: tabular-nums;
366
+ color: var(--text-secondary);
367
+ }
css/chat.css ADDED
@@ -0,0 +1,489 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 对话工作台:会话列表 + 消息流 + 输入区(Warm Paper,全令牌配色) */
2
+
3
+ .workbench {
4
+ flex: 1;
5
+ min-width: 0;
6
+ min-height: 0; /* flex 子项默认 min-height:auto 会拒绝收缩——必须显式置 0,否则消息一长整页跟着滚 */
7
+ display: flex;
8
+ }
9
+
10
+ /* ---------- 会话列表 ---------- */
11
+ .conversations {
12
+ width: 264px;
13
+ flex-shrink: 0;
14
+ min-height: 0;
15
+ display: flex;
16
+ flex-direction: column;
17
+ border-right: 1px solid var(--border);
18
+ background: var(--bg);
19
+ }
20
+
21
+ .conv-head {
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: space-between;
25
+ padding: 26px 16px 14px;
26
+ }
27
+
28
+ .conv-head h2 {
29
+ font-size: 17px;
30
+ }
31
+
32
+ .conv-new {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ gap: 6px;
36
+ height: 30px;
37
+ padding: 0 12px;
38
+ border: 1px solid var(--border);
39
+ border-radius: var(--radius-control);
40
+ background: transparent;
41
+ color: var(--text);
42
+ font-family: inherit;
43
+ font-size: 13px;
44
+ cursor: pointer;
45
+ transition: background-color var(--dur) var(--ease);
46
+ }
47
+
48
+ .conv-new:hover {
49
+ background: var(--bg-elevated);
50
+ }
51
+
52
+ .conv-scroll {
53
+ flex: 1;
54
+ overflow-y: auto;
55
+ display: flex;
56
+ flex-direction: column;
57
+ gap: 2px;
58
+ padding: 4px 12px 16px;
59
+ }
60
+
61
+ .conv-empty {
62
+ padding: 20px 12px;
63
+ color: var(--text-tertiary);
64
+ font-size: 13px;
65
+ line-height: 1.7;
66
+ }
67
+
68
+ .conv-empty p {
69
+ margin: 0 0 4px;
70
+ }
71
+
72
+ .conv-empty-title {
73
+ color: var(--text-secondary);
74
+ font-size: 13.5px;
75
+ font-weight: 500;
76
+ }
77
+
78
+ .conv-item {
79
+ display: flex;
80
+ align-items: center;
81
+ flex-wrap: wrap;
82
+ gap: 2px;
83
+ border-radius: var(--radius-control);
84
+ transition: background-color var(--dur) var(--ease);
85
+ }
86
+
87
+ .conv-item:hover {
88
+ background: var(--bg-elevated);
89
+ }
90
+
91
+ .conv-item.is-active {
92
+ background: var(--accent-soft);
93
+ }
94
+
95
+ .conv-open {
96
+ flex: 1;
97
+ min-width: 0;
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 1px;
101
+ padding: 10px 12px;
102
+ border: none;
103
+ background: transparent;
104
+ color: var(--text);
105
+ font-family: inherit;
106
+ text-align: left;
107
+ cursor: pointer;
108
+ border-radius: var(--radius-control);
109
+ }
110
+
111
+ .conv-title {
112
+ display: block;
113
+ overflow: hidden;
114
+ white-space: nowrap;
115
+ text-overflow: ellipsis;
116
+ font-size: 13.5px;
117
+ font-weight: 500;
118
+ }
119
+
120
+ .conv-meta {
121
+ display: block;
122
+ overflow: hidden;
123
+ white-space: nowrap;
124
+ text-overflow: ellipsis;
125
+ font-size: 11.5px;
126
+ color: var(--text-tertiary);
127
+ font-variant-numeric: tabular-nums;
128
+ }
129
+
130
+ .conv-actions {
131
+ display: none;
132
+ gap: 2px;
133
+ padding-right: 6px;
134
+ }
135
+
136
+ .conv-item:hover .conv-actions,
137
+ .conv-item:focus-within .conv-actions {
138
+ display: inline-flex;
139
+ }
140
+
141
+ .conv-rename {
142
+ flex: 1;
143
+ min-width: 0;
144
+ margin: 6px 8px;
145
+ padding: 7px 10px;
146
+ border: 1px solid transparent;
147
+ border-radius: var(--radius-control);
148
+ background: var(--bg-sunken);
149
+ color: var(--text);
150
+ font-family: inherit;
151
+ font-size: 13px;
152
+ }
153
+
154
+ .conv-rename:focus {
155
+ outline: none;
156
+ border-color: var(--accent);
157
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
158
+ }
159
+
160
+ .conv-confirm {
161
+ flex-basis: 100%;
162
+ display: flex;
163
+ align-items: center;
164
+ gap: 8px;
165
+ padding: 8px 12px 10px;
166
+ font-size: 12px;
167
+ color: var(--text-secondary);
168
+ }
169
+
170
+ .conv-confirm span {
171
+ flex: 1;
172
+ }
173
+
174
+ .conv-confirm-yes,
175
+ .conv-confirm-no {
176
+ display: inline-flex;
177
+ align-items: center;
178
+ gap: 4px;
179
+ height: 26px;
180
+ padding: 0 10px;
181
+ border: 1px solid var(--border);
182
+ border-radius: var(--radius-control);
183
+ background: transparent;
184
+ font-family: inherit;
185
+ font-size: 12px;
186
+ cursor: pointer;
187
+ transition: background-color var(--dur) var(--ease);
188
+ }
189
+
190
+ .conv-confirm-yes {
191
+ color: var(--danger);
192
+ }
193
+
194
+ .conv-confirm-yes:hover {
195
+ background: var(--accent-soft);
196
+ }
197
+
198
+ .conv-confirm-no {
199
+ color: var(--text-secondary);
200
+ }
201
+
202
+ .conv-confirm-no:hover {
203
+ background: var(--bg-elevated);
204
+ }
205
+
206
+ .conv-error {
207
+ margin: 0;
208
+ padding: 10px 16px 14px;
209
+ color: var(--danger);
210
+ font-size: 12px;
211
+ line-height: 1.6;
212
+ }
213
+
214
+ /* ---------- 消息区 ---------- */
215
+ .chat-main {
216
+ flex: 1;
217
+ min-width: 0;
218
+ min-height: 0;
219
+ display: flex;
220
+ flex-direction: column;
221
+ }
222
+
223
+ .stream {
224
+ flex: 1;
225
+ min-height: 0;
226
+ overflow-y: auto;
227
+ display: flex;
228
+ flex-direction: column;
229
+ }
230
+
231
+ .stream-inner {
232
+ flex-shrink: 0;
233
+ max-width: 760px;
234
+ width: 100%;
235
+ margin: 0 auto;
236
+ padding: 48px 48px 24px;
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 32px;
240
+ }
241
+
242
+ .msg {
243
+ display: flex;
244
+ flex-direction: column;
245
+ gap: 8px;
246
+ }
247
+
248
+ .msg-role {
249
+ font-size: 12px;
250
+ color: var(--text-tertiary);
251
+ font-variant-numeric: tabular-nums;
252
+ }
253
+
254
+ .msg-card {
255
+ padding: 12px 16px;
256
+ border: 1px solid color-mix(in srgb, var(--accent) 16%, transparent);
257
+ border-radius: var(--radius-card);
258
+ background: var(--accent-soft);
259
+ font-size: 15px;
260
+ line-height: 1.75;
261
+ white-space: pre-wrap;
262
+ overflow-wrap: break-word;
263
+ user-select: text;
264
+ }
265
+
266
+ .msg-body {
267
+ font-size: 15px;
268
+ user-select: text;
269
+ }
270
+
271
+ .msg-error {
272
+ display: flex;
273
+ align-items: center;
274
+ gap: 6px;
275
+ margin: 0;
276
+ color: var(--danger);
277
+ font-size: 13px;
278
+ }
279
+
280
+ .msg-note {
281
+ margin: 0;
282
+ color: var(--text-tertiary);
283
+ font-size: 12.5px;
284
+ }
285
+
286
+ .msg-reasoning summary {
287
+ cursor: pointer;
288
+ color: var(--text-tertiary);
289
+ font-size: 12.5px;
290
+ }
291
+
292
+ .msg-reasoning-body {
293
+ margin-top: 8px;
294
+ padding: 12px 14px;
295
+ border-radius: var(--radius-control);
296
+ background: var(--bg-elevated);
297
+ color: var(--text-secondary);
298
+ font-size: 13px;
299
+ line-height: 1.7;
300
+ white-space: pre-wrap;
301
+ user-select: text;
302
+ }
303
+
304
+ /* 流式呼吸光标(1s 透明度呼吸;reduced-motion 时 theme.css 全局降级为静止) */
305
+ @keyframes cursor-breathe {
306
+ 0%,
307
+ 100% {
308
+ opacity: 1;
309
+ }
310
+ 50% {
311
+ opacity: 0.15;
312
+ }
313
+ }
314
+
315
+ .stream-cursor {
316
+ display: inline-block;
317
+ width: 2px;
318
+ height: 1.05em;
319
+ margin-left: 4px;
320
+ border-radius: 1px;
321
+ background: var(--accent);
322
+ vertical-align: text-bottom;
323
+ animation: cursor-breathe 1s ease-in-out infinite;
324
+ }
325
+
326
+ /* 有内容时,光标贴在最后一个 Markdown 块的文本尾部 */
327
+ .msg-body.is-streaming .md > :last-child::after {
328
+ content: "";
329
+ display: inline-block;
330
+ width: 2px;
331
+ height: 1em;
332
+ margin-left: 3px;
333
+ border-radius: 1px;
334
+ background: var(--accent);
335
+ vertical-align: -0.12em;
336
+ animation: cursor-breathe 1s ease-in-out infinite;
337
+ }
338
+
339
+ /* 代码块收尾时,光标落到代码行尾 */
340
+ .msg-body.is-streaming .md > .code-block:last-child::after {
341
+ content: none;
342
+ }
343
+
344
+ .msg-body.is-streaming .md > .code-block:last-child pre::after {
345
+ content: "";
346
+ display: inline-block;
347
+ width: 2px;
348
+ height: 1em;
349
+ margin-left: 3px;
350
+ border-radius: 1px;
351
+ background: var(--accent);
352
+ vertical-align: -0.12em;
353
+ animation: cursor-breathe 1s ease-in-out infinite;
354
+ }
355
+
356
+ /* ---------- 欢迎空态 ---------- */
357
+ .chat-welcome {
358
+ position: relative;
359
+ flex: 1;
360
+ display: flex;
361
+ flex-direction: column;
362
+ justify-content: center;
363
+ padding: 48px 80px;
364
+ overflow: hidden;
365
+ }
366
+
367
+ /* 极淡的径向暖光(accent-soft 的 5%,无新颜色) */
368
+ .chat-welcome::before {
369
+ content: "";
370
+ position: absolute;
371
+ inset: 0;
372
+ pointer-events: none;
373
+ background: radial-gradient(
374
+ 56% 48% at 28% 40%,
375
+ color-mix(in srgb, var(--accent-soft) 5%, transparent) 0%,
376
+ transparent 72%
377
+ );
378
+ }
379
+
380
+ /* 品牌鸟巢水印(Brand.tsx 复用,极低透明度) */
381
+ .chat-welcome-mark {
382
+ position: absolute;
383
+ right: 72px;
384
+ top: 50%;
385
+ transform: translateY(-50%);
386
+ color: var(--accent);
387
+ opacity: 0.07;
388
+ pointer-events: none;
389
+ }
390
+
391
+ .chat-welcome h1 {
392
+ position: relative;
393
+ margin: 0 0 12px;
394
+ font-size: 32px;
395
+ }
396
+
397
+ .chat-welcome p {
398
+ position: relative;
399
+ margin: 0;
400
+ max-width: 520px;
401
+ font-size: 16px;
402
+ line-height: 1.8;
403
+ color: var(--text-secondary);
404
+ }
405
+
406
+ /* ---------- 对话头部右侧动作区(ultrafast 开关 + 专家选择器) ---------- */
407
+ .chat-header-actions {
408
+ display: flex;
409
+ align-items: center;
410
+ gap: 8px;
411
+ }
412
+
413
+ /* ultrafast 闪电开关(dev-ultrafast):与狂暴火焰同款视觉语言(幽灵按钮 →
414
+ 金渐变徽章,warning 金 → accent 陶土走令牌,反向渐变以区分二者),
415
+ 只是图标换 Zap、语义求快(关思考 + 用最快的模型) */
416
+ .ultrafast-toggle {
417
+ position: relative;
418
+ display: inline-flex;
419
+ align-items: center;
420
+ gap: 4px;
421
+ padding: 3px 10px;
422
+ border: 1px solid var(--border);
423
+ border-radius: var(--radius-control);
424
+ background: transparent;
425
+ color: var(--text-secondary);
426
+ font-size: 12px;
427
+ font-weight: 600;
428
+ cursor: pointer;
429
+ transition:
430
+ background var(--dur) var(--ease),
431
+ color var(--dur) var(--ease),
432
+ border-color var(--dur) var(--ease);
433
+ }
434
+
435
+ .ultrafast-toggle:hover {
436
+ color: var(--text);
437
+ border-color: var(--accent);
438
+ }
439
+
440
+ .ultrafast-toggle.is-on {
441
+ border-color: transparent;
442
+ color: var(--bg);
443
+ background: linear-gradient(135deg, var(--accent), var(--warning));
444
+ /* 开启瞬间的小特效①:徽章轻微弹跳("啪"地一下上档) */
445
+ animation: ultrafast-pop 300ms var(--ease);
446
+ }
447
+
448
+ /* 开启瞬间的小特效②:一圈金色能量环从徽章外扩淡出(像被点亮/充能)——
449
+ 纯 ::after,只在 is-on 类加上时跑一次,不常驻不刺眼(Warm Paper 克制) */
450
+ .ultrafast-toggle.is-on::after {
451
+ content: "";
452
+ position: absolute;
453
+ inset: -2px;
454
+ border-radius: inherit;
455
+ border: 1px solid var(--warning);
456
+ opacity: 0;
457
+ pointer-events: none;
458
+ animation: ultrafast-ring 520ms var(--ease);
459
+ }
460
+
461
+ @keyframes ultrafast-pop {
462
+ 0% { transform: scale(1); }
463
+ 38% { transform: scale(1.09); }
464
+ 100% { transform: scale(1); }
465
+ }
466
+
467
+ @keyframes ultrafast-ring {
468
+ 0% { opacity: 0.85; transform: scale(0.92); }
469
+ 100% { opacity: 0; transform: scale(1.6); }
470
+ }
471
+
472
+ /* 尊重系统减弱动效:关掉开启特效(弹跳与能量环都不跑) */
473
+ @media (prefers-reduced-motion: reduce) {
474
+ .ultrafast-toggle.is-on,
475
+ .ultrafast-toggle.is-on::after {
476
+ animation: none;
477
+ }
478
+ }
479
+
480
+ .ultrafast-toggle.is-on:hover {
481
+ color: var(--bg);
482
+ filter: brightness(1.04);
483
+ }
484
+
485
+ .ultrafast-toggle:focus-visible {
486
+ outline: 2px solid var(--accent);
487
+ outline-offset: 2px;
488
+ }
489
+
css/cloud.css ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 设置页(Phase 5A):云端 API 接入 + 关于。
2
+ Warm Paper 全令牌配色(design-system.md),无硬编码颜色。 */
3
+
4
+ .settings {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ }
10
+
11
+ .settings-head h1 {
12
+ font-size: 30px;
13
+ }
14
+
15
+ .settings-head-sub {
16
+ margin: 6px 0 0;
17
+ font-size: 13.5px;
18
+ color: var(--text-secondary);
19
+ }
20
+
21
+ .settings-section {
22
+ max-width: 760px;
23
+ margin-top: 40px;
24
+ }
25
+
26
+ .settings-section h2 {
27
+ font-size: 21px;
28
+ }
29
+
30
+ .settings-sub {
31
+ margin: 6px 0 0;
32
+ font-size: 13px;
33
+ color: var(--text-secondary);
34
+ }
35
+
36
+ /* ── 云端 API 区 ────────────────────────────────────────────────── */
37
+
38
+ .cloud-section-head {
39
+ display: flex;
40
+ align-items: flex-end;
41
+ justify-content: space-between;
42
+ gap: 16px;
43
+ margin-bottom: 14px;
44
+ flex-wrap: wrap;
45
+ }
46
+
47
+ .cloud-privacy {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 7px;
51
+ margin: 0 0 16px;
52
+ padding: 8px 14px;
53
+ border: 1px dashed var(--border);
54
+ border-radius: var(--radius-control);
55
+ background: var(--bg-sunken);
56
+ font-size: 13px;
57
+ color: var(--text-secondary);
58
+ }
59
+
60
+ .cloud-muted {
61
+ margin: 0;
62
+ font-size: 13px;
63
+ color: var(--text-secondary);
64
+ }
65
+
66
+ .cloud-error {
67
+ margin: 8px 0 0;
68
+ font-size: 13px;
69
+ color: var(--danger);
70
+ }
71
+
72
+ .cloud-test-line {
73
+ margin: 10px 0 0;
74
+ font-size: 13px;
75
+ }
76
+
77
+ .cloud-test-line.is-ok {
78
+ color: var(--success);
79
+ }
80
+
81
+ /* ── 接口卡片 ───────────────────────────────────────────────────── */
82
+
83
+ .cloud-card {
84
+ margin-bottom: 12px;
85
+ padding: 16px 18px;
86
+ border: 1px solid var(--border);
87
+ border-radius: var(--radius-card);
88
+ background: var(--bg-elevated);
89
+ }
90
+
91
+ .cloud-card-head {
92
+ display: flex;
93
+ align-items: center;
94
+ gap: 10px;
95
+ flex-wrap: wrap;
96
+ }
97
+
98
+ .cloud-card-icon {
99
+ display: inline-flex;
100
+ color: var(--text-secondary);
101
+ }
102
+
103
+ .cloud-card-title h3 {
104
+ font-size: 16px;
105
+ margin: 0;
106
+ }
107
+
108
+ .cloud-card-url {
109
+ margin: 2px 0 0;
110
+ font-family: var(--font-mono);
111
+ font-size: 12px;
112
+ color: var(--text-secondary);
113
+ word-break: break-all;
114
+ }
115
+
116
+ .cloud-card-count {
117
+ margin-left: auto;
118
+ font-size: 12.5px;
119
+ color: var(--text-secondary);
120
+ font-variant-numeric: tabular-nums;
121
+ }
122
+
123
+ /* 状态徽章:与全站徽章同尺寸同字重 */
124
+ .cloud-badge {
125
+ display: inline-flex;
126
+ align-items: center;
127
+ gap: 4px;
128
+ padding: 2px 8px;
129
+ border: 1px solid var(--border);
130
+ border-radius: 999px;
131
+ font-size: 12px;
132
+ font-weight: 500;
133
+ color: var(--text-secondary);
134
+ }
135
+
136
+ .cloud-badge.is-ok {
137
+ color: var(--success);
138
+ }
139
+
140
+ .cloud-badge.is-warn {
141
+ color: var(--warning);
142
+ }
143
+
144
+ .cloud-card-actions {
145
+ display: flex;
146
+ align-items: center;
147
+ gap: 8px;
148
+ flex-wrap: wrap;
149
+ margin-top: 12px;
150
+ }
151
+
152
+ .cloud-confirm {
153
+ display: inline-flex;
154
+ align-items: center;
155
+ gap: 8px;
156
+ font-size: 12.5px;
157
+ color: var(--text-secondary);
158
+ }
159
+
160
+ /* ── 模型 chips ────────────────────────────────────────────────── */
161
+
162
+ .cloud-chips {
163
+ display: flex;
164
+ flex-wrap: wrap;
165
+ gap: 6px;
166
+ margin-top: 10px;
167
+ }
168
+
169
+ .cloud-chip {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ gap: 5px;
173
+ padding: 2px 8px;
174
+ border: 1px solid var(--border);
175
+ border-radius: 8px;
176
+ background: var(--bg-sunken);
177
+ font-family: var(--font-mono);
178
+ font-size: 12px;
179
+ color: var(--text);
180
+ }
181
+
182
+ .cloud-chip button {
183
+ display: inline-flex;
184
+ padding: 0;
185
+ border: none;
186
+ background: transparent;
187
+ color: var(--text-tertiary);
188
+ cursor: pointer;
189
+ }
190
+
191
+ .cloud-chip button:hover {
192
+ color: var(--danger);
193
+ }
194
+
195
+ .cloud-model-add {
196
+ display: flex;
197
+ gap: 8px;
198
+ }
199
+
200
+ .cloud-model-add input {
201
+ flex: 1;
202
+ min-width: 0;
203
+ }
204
+
205
+ /* ── 按钮 / 输入 ────────────────────────────────────────────────── */
206
+
207
+ .cloud-btn {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ gap: 5px;
211
+ height: 30px;
212
+ padding: 0 10px;
213
+ border: 1px solid var(--border);
214
+ border-radius: var(--radius-control);
215
+ background: transparent;
216
+ color: var(--text);
217
+ font-family: inherit;
218
+ font-size: 12.5px;
219
+ cursor: pointer;
220
+ transition: background-color var(--dur) var(--ease);
221
+ }
222
+
223
+ .cloud-btn:hover {
224
+ background: var(--bg-sunken);
225
+ }
226
+
227
+ .cloud-btn:disabled {
228
+ opacity: 0.6;
229
+ cursor: default;
230
+ }
231
+
232
+ .cloud-btn.is-danger {
233
+ color: var(--danger);
234
+ border-color: var(--danger);
235
+ }
236
+
237
+ .cloud-btn.is-danger-quiet {
238
+ color: var(--text-secondary);
239
+ }
240
+
241
+ .cloud-btn.is-danger-quiet:hover {
242
+ color: var(--danger);
243
+ }
244
+
245
+ /* ── 表单 ───────────────────────────────────────────────────────── */
246
+
247
+ .cloud-form {
248
+ display: flex;
249
+ flex-direction: column;
250
+ gap: 14px;
251
+ margin-top: 16px;
252
+ padding: 18px 20px;
253
+ border: 1px solid var(--border);
254
+ border-radius: var(--radius-card);
255
+ background: var(--bg-elevated);
256
+ }
257
+
258
+ .cloud-form h3 {
259
+ margin: 0;
260
+ font-size: 16px;
261
+ }
262
+
263
+ .cloud-field {
264
+ display: flex;
265
+ flex-direction: column;
266
+ gap: 6px;
267
+ }
268
+
269
+ .cloud-field > span {
270
+ font-size: 13px;
271
+ font-weight: 500;
272
+ }
273
+
274
+ .cloud-field input {
275
+ height: 36px;
276
+ padding: 0 12px;
277
+ border: 1px solid var(--border);
278
+ border-radius: var(--radius-control);
279
+ background: var(--bg-sunken);
280
+ color: var(--text);
281
+ font-family: inherit;
282
+ font-size: 13.5px;
283
+ }
284
+
285
+ .cloud-field input:focus {
286
+ outline: none;
287
+ border-color: var(--accent);
288
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
289
+ }
290
+
291
+ .cloud-field input::placeholder {
292
+ color: var(--text-tertiary);
293
+ }
294
+
295
+ .cloud-field small {
296
+ font-size: 12px;
297
+ color: var(--text-tertiary);
298
+ }
299
+
300
+ .cloud-test {
301
+ display: flex;
302
+ flex-direction: column;
303
+ align-items: flex-start;
304
+ gap: 8px;
305
+ padding: 8px 12px;
306
+ border: 1px solid var(--border);
307
+ border-radius: var(--radius-control);
308
+ font-size: 13px;
309
+ }
310
+
311
+ .cloud-test p {
312
+ margin: 0;
313
+ }
314
+
315
+ .cloud-test.is-ok {
316
+ color: var(--success);
317
+ }
318
+
319
+ .cloud-test.is-fail {
320
+ color: var(--danger);
321
+ }
322
+
323
+ .cloud-form-actions {
324
+ display: flex;
325
+ gap: 10px;
326
+ margin-top: 4px;
327
+ }
328
+
329
+ /* ── 关于 ───────────────────────────────────────────────────────── */
330
+
331
+ .about-list {
332
+ display: flex;
333
+ flex-direction: column;
334
+ gap: 14px;
335
+ margin: 16px 0 0;
336
+ max-width: 640px;
337
+ }
338
+
339
+ .about-list > div {
340
+ display: flex;
341
+ flex-direction: column;
342
+ gap: 2px;
343
+ }
344
+
345
+ .about-list dt {
346
+ font-size: 12.5px;
347
+ color: var(--text-tertiary);
348
+ }
349
+
350
+ .about-list dd {
351
+ margin: 0;
352
+ font-size: 13.5px;
353
+ }
354
+
355
+ .about-mono {
356
+ font-family: var(--font-mono);
357
+ font-size: 12.5px;
358
+ word-break: break-all;
359
+ }
360
+
361
+ /* ── 小转圈(测试/保存中);prefers-reduced-motion 下会被全局关掉 ── */
362
+
363
+ .cloud-spin {
364
+ animation: cloud-spin 1s linear infinite;
365
+ }
366
+
367
+ @keyframes cloud-spin {
368
+ to {
369
+ transform: rotate(360deg);
370
+ }
371
+ }
372
+
373
+ /* ── 浏览器伴侣桥接(契约 8A)────────────────────────── */
374
+ .bridge-desc {
375
+ margin: 0 0 14px;
376
+ color: var(--text-secondary);
377
+ font-size: 13.5px;
378
+ line-height: 1.7;
379
+ }
380
+ .bridge-status-row {
381
+ display: flex;
382
+ align-items: center;
383
+ gap: 8px;
384
+ margin-bottom: 12px;
385
+ }
386
+ .bridge-dot {
387
+ width: 9px;
388
+ height: 9px;
389
+ border-radius: 50%;
390
+ flex-shrink: 0;
391
+ }
392
+ .bridge-dot.is-on {
393
+ background: var(--success);
394
+ }
395
+ .bridge-dot.is-off {
396
+ background: var(--text-tertiary);
397
+ }
398
+ /* ── 异地访问状态灯(契约 24B):连接中 = warning、失败 = danger。
399
+ 只用主题变量,深浅色各自成套,无硬编码色 ── */
400
+ .bridge-dot.is-busy {
401
+ background: var(--warning);
402
+ }
403
+ .bridge-dot.is-fail {
404
+ background: var(--danger);
405
+ }
406
+ /* ── 异地访问子块(契约 24B):与上面的局域网块用虚线隔开,
407
+ 一眼看出这是两个互相独立的开关 ── */
408
+ .remote-block {
409
+ margin-top: 18px;
410
+ padding-top: 16px;
411
+ border-top: 1px dashed var(--border);
412
+ }
413
+ .remote-privacy {
414
+ margin-top: 12px;
415
+ margin-bottom: 0;
416
+ }
417
+ /* 临时网址比局域网地址长,给它留足一行(不然省略号吃掉 .trycloudflare.com) */
418
+ .remote-block .bridge-token {
419
+ max-width: min(560px, 100%);
420
+ }
421
+ .bridge-status-text {
422
+ font-size: 13.5px;
423
+ color: var(--text);
424
+ }
425
+ .bridge-error {
426
+ margin: 0 0 12px;
427
+ color: var(--danger);
428
+ font-size: 13px;
429
+ }
430
+ .bridge-token-row {
431
+ display: flex;
432
+ align-items: center;
433
+ gap: 8px;
434
+ flex-wrap: wrap;
435
+ }
436
+ .bridge-token {
437
+ font-family: var(--font-mono);
438
+ font-size: 12px;
439
+ background: var(--bg-sunken);
440
+ border-radius: var(--radius-chip);
441
+ padding: 4px 10px;
442
+ max-width: 380px;
443
+ overflow: hidden;
444
+ text-overflow: ellipsis;
445
+ white-space: nowrap;
446
+ }
447
+ .bridge-path {
448
+ direction: rtl;
449
+ text-align: left;
450
+ }
451
+ .bridge-steps {
452
+ margin: 14px 0 0;
453
+ padding-left: 20px;
454
+ color: var(--text-secondary);
455
+ font-size: 13px;
456
+ line-height: 2;
457
+ }
458
+
459
+ .about-build {
460
+ margin-left: 6px;
461
+ font-size: 11.5px;
462
+ color: var(--text-tertiary);
463
+ }
css/composer.css ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 输入区(Composer)视觉层 —— 两层结构(design-system.md Warm Paper 铁律):
2
+ 上层 = textarea(呼吸空间足),下层 = 控件条:
3
+ 左组【对话|任务 分段 pill + 批准档 + 权限小字】,右组【思考滑轨 → 模型 → 发送】。
4
+ 组内聚拢(8px)、组间留白(16px)、控件统一 32px 高、圆角按令牌;
5
+ 模型选择是窄触发器 + 向上 popover(--shadow-float 描边浮层,不用毛玻璃)。
6
+ 窄窗时按「整组」换行,绝不把控件压扁——发送按钮永远待在右下角。
7
+ 本文件只服务 Composer.tsx;模式切换/批准档的原始规则在 task.css,
8
+ 这里用 .composer-bar 前缀做作用域内的密度统一(不改 task.css)。 */
9
+
10
+ /* ---------- 外层:贴底输入区 ---------- */
11
+ .composer-wrap {
12
+ padding: 16px 48px 24px;
13
+ border-top: 1px solid var(--border);
14
+ }
15
+
16
+ /* ---------- 输入盒:sunken 底,聚焦 accent 描边 + 极浅外晕 ---------- */
17
+ .composer {
18
+ max-width: 760px;
19
+ margin: 0 auto;
20
+ padding: 12px 14px;
21
+ border: 1px solid transparent;
22
+ border-radius: var(--radius-float);
23
+ background: var(--bg-sunken);
24
+ transition: border-color var(--dur) var(--ease);
25
+ }
26
+
27
+ .composer:focus-within {
28
+ border-color: var(--accent);
29
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
30
+ }
31
+
32
+ /* ---------- 上层:输入 textarea(不与控件抢空间) ---------- */
33
+ .composer-input {
34
+ display: block;
35
+ width: 100%;
36
+ min-height: 44px;
37
+ max-height: 200px;
38
+ padding: 4px 2px 8px;
39
+ border: none;
40
+ background: transparent;
41
+ color: var(--text);
42
+ font-family: var(--font-sans);
43
+ font-size: 15px;
44
+ line-height: 1.65;
45
+ resize: none;
46
+ overflow-y: auto;
47
+ }
48
+
49
+ .composer-input:focus {
50
+ outline: none;
51
+ }
52
+
53
+ .composer-input::placeholder {
54
+ color: var(--text-tertiary);
55
+ }
56
+
57
+ /* ---------- 下层:控件条(左右两组) ---------- */
58
+ .composer-bar {
59
+ display: flex;
60
+ flex-wrap: wrap;
61
+ align-items: center;
62
+ justify-content: space-between;
63
+ gap: 8px 16px; /* 行间 8、组间 16:8px 网格 */
64
+ margin-top: 8px;
65
+ }
66
+
67
+ .composer-group {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ align-items: center;
71
+ gap: 8px;
72
+ flex: 0 0 auto; /* 不缩小:放不下就整组换行,永不挤压控件 */
73
+ }
74
+
75
+ .composer-group-end {
76
+ margin-left: auto;
77
+ }
78
+
79
+ /* ---------- 模式切换(契约 6D):Codex 式无边框文字切换 ----------
80
+ 去掉容器边框与凹底(覆盖 task.css 基础款),激活档用暖陶土淡染,
81
+ 不再是实心 pill——与整条控制条的「文字优先」一致。 */
82
+ .composer-bar .mode-switch {
83
+ gap: 2px;
84
+ padding: 0;
85
+ border: none;
86
+ background: transparent;
87
+ }
88
+
89
+ .composer-bar .mode-pill {
90
+ height: 28px;
91
+ padding: 0 10px;
92
+ border-radius: var(--radius-chip);
93
+ font-size: 13px;
94
+ color: var(--text-tertiary);
95
+ background: transparent;
96
+ }
97
+
98
+ .composer-bar .mode-pill:hover {
99
+ color: var(--text-secondary);
100
+ background: color-mix(in srgb, var(--accent-soft) 45%, transparent);
101
+ }
102
+
103
+ .composer-bar .mode-pill.is-active {
104
+ background: color-mix(in srgb, var(--accent-soft) 85%, transparent);
105
+ color: var(--accent);
106
+ }
107
+
108
+ .quick-tool-wrap{position:relative;z-index:20}
109
+ .composer-bar .quick-tool-trigger{display:inline-flex;align-items:center;gap:6px;height:27px;padding:0 8px;border:1px solid var(--border);border-radius:6px;background:transparent;color:var(--text-secondary);font:10px var(--font-sans);cursor:pointer}
110
+ .composer-bar .quick-tool-trigger:hover,.composer-bar .quick-tool-trigger[aria-expanded="true"]{color:var(--accent);background:var(--accent-soft)}
111
+ .quick-tool-menu{position:absolute;left:0;bottom:calc(100% + 9px);width:268px;padding:8px;border:1px solid var(--border);border-radius:8px;background:var(--bg-elevated);box-shadow:var(--shadow-float)}
112
+ .quick-tool-menu>strong{display:block;padding:5px 7px 8px;color:var(--text-tertiary);font-size:9px;font-weight:500}
113
+ .quick-tool-item{display:flex;align-items:center;gap:2px}
114
+ .quick-tool-item>button:first-child{display:flex;align-items:center;gap:9px;flex:1;min-width:0;height:34px;padding:0 8px;border:0;border-radius:5px;background:transparent;color:var(--text);font-size:10px;text-align:left;cursor:pointer}
115
+ .quick-tool-item>button:first-child:hover{background:var(--accent-soft)}
116
+ .quick-tool-item>button:first-child>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
117
+ .quick-tool-pin{display:grid;place-items:center;width:27px;height:27px;border:0;border-radius:5px;background:transparent;color:var(--text-tertiary);cursor:pointer}
118
+ .quick-tool-pin:hover,.quick-tool-pin.is-pinned{color:var(--warning);background:var(--bg-sunken)}
119
+ .quick-tool-menu>small{display:block;padding:8px 7px 3px;border-top:1px solid var(--border);color:var(--text-tertiary);font-size:9px}
120
+ .research-consent{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:12px 14px;margin:0 8px 8px;border:1px solid color-mix(in srgb,var(--warning) 45%,var(--border));border-radius:7px;background:var(--bg-sunken)}
121
+ .research-consent>div{flex:1;min-width:220px}
122
+ .research-consent strong{font-size:11px;color:var(--text)}
123
+ .research-consent p{margin:4px 0 0;color:var(--text-secondary);font-size:10px;line-height:1.6}
124
+ .research-consent .ws-primary{padding:7px 10px}
125
+ .research-consent .ws-link{font-size:10px}
126
+
127
+ /* ---------- 批准档(仅任务模式):彩色文字 + 安全图标,去边框下拉 ----------
128
+ Codex 的「⚠ 完全访问」范式:select 视觉隐藏为纯文字载体,图标与文字
129
+ 承担全部观感;全访问=陶土警示色,智能=暖中性偏正向,询问=中性。 */
130
+ .composer-bar .perm-picker {
131
+ gap: 5px;
132
+ height: 28px;
133
+ padding: 0 6px;
134
+ border-radius: var(--radius-chip);
135
+ cursor: pointer;
136
+ transition: background-color var(--dur) var(--ease);
137
+ }
138
+
139
+ .composer-bar .perm-picker:hover {
140
+ background: color-mix(in srgb, var(--accent-soft) 45%, transparent);
141
+ }
142
+
143
+ .composer-bar .perm-picker select {
144
+ appearance: none;
145
+ -webkit-appearance: none;
146
+ height: 28px;
147
+ padding: 0;
148
+ border: none;
149
+ background: transparent;
150
+ color: inherit;
151
+ font-family: inherit;
152
+ font-size: 12.5px;
153
+ cursor: pointer;
154
+ }
155
+
156
+ .composer-bar .perm-picker select:focus {
157
+ outline: none;
158
+ }
159
+
160
+ .composer-bar .perm-picker select:focus-visible {
161
+ outline: 2px solid var(--accent);
162
+ outline-offset: 2px;
163
+ }
164
+
165
+ /* 图标与文字同色:按档位着色(图标靠 color: inherit 跟随) */
166
+ .composer-bar .perm-picker.is-full-access {
167
+ color: var(--danger);
168
+ }
169
+ .composer-bar .perm-picker.is-smart-approve {
170
+ color: var(--accent);
171
+ }
172
+ .composer-bar .perm-picker.is-always-ask {
173
+ color: var(--text-secondary);
174
+ }
175
+
176
+ /* ---------- 权限总闸状态小字(只读,契约 13A) ---------- */
177
+ .composer-bar .perm-gate-hint {
178
+ align-self: center;
179
+ font-size: 11.5px;
180
+ line-height: 1.2;
181
+ color: var(--text-tertiary);
182
+ white-space: nowrap;
183
+ }
184
+
185
+ /* ---------- 模型选择:窄触发器 + 向上 popover ---------- */
186
+ .model-menu-wrap {
187
+ position: relative;
188
+ display: inline-flex;
189
+ }
190
+
191
+ .model-trigger {
192
+ display: inline-flex;
193
+ align-items: center;
194
+ gap: 6px;
195
+ height: 28px;
196
+ max-width: 176px;
197
+ padding: 0 6px;
198
+ border: none;
199
+ border-radius: var(--radius-chip);
200
+ background: transparent;
201
+ color: var(--text-secondary);
202
+ font-family: inherit;
203
+ font-size: 12.5px;
204
+ cursor: pointer;
205
+ transition:
206
+ color var(--dur) var(--ease),
207
+ background-color var(--dur) var(--ease);
208
+ }
209
+
210
+ .model-trigger:hover {
211
+ color: var(--text);
212
+ background: color-mix(in srgb, var(--accent-soft) 45%, transparent);
213
+ }
214
+
215
+ .model-trigger[aria-expanded="true"] {
216
+ color: var(--text);
217
+ background: color-mix(in srgb, var(--accent-soft) 60%, transparent);
218
+ }
219
+
220
+ .model-trigger:focus-visible,
221
+ .model-option:focus-visible {
222
+ outline: 2px solid var(--accent);
223
+ outline-offset: 2px;
224
+ }
225
+
226
+ .model-trigger-name {
227
+ min-width: 0;
228
+ overflow: hidden;
229
+ text-overflow: ellipsis;
230
+ white-space: nowrap;
231
+ }
232
+
233
+ .model-trigger-caret {
234
+ flex: 0 0 auto;
235
+ color: var(--text-tertiary);
236
+ }
237
+
238
+ /* 「云」徽章:与全站徽章同尺寸同字重(同 bench 云徽章口径) */
239
+ .model-cloud {
240
+ flex: 0 0 auto;
241
+ font-size: 11px;
242
+ line-height: 1;
243
+ padding: 3px 6px;
244
+ border-radius: var(--radius-chip);
245
+ background: var(--accent-soft);
246
+ color: var(--text);
247
+ }
248
+
249
+ /* popover:Warm Paper 浮层(elevated 底 + 1px 描边 + --shadow-float;
250
+ 毛玻璃禁用——透明窗口上 WebKit 的 backdrop-filter 有已知坑)。
251
+ 入场 = opacity + translateY 6px,180ms。 */
252
+ .model-menu {
253
+ position: absolute;
254
+ right: 0;
255
+ bottom: calc(100% + 8px);
256
+ z-index: 30;
257
+ min-width: 236px;
258
+ max-width: 320px;
259
+ max-height: 264px;
260
+ overflow-y: auto;
261
+ padding: 6px;
262
+ border: 1px solid var(--border);
263
+ border-radius: var(--radius-float);
264
+ background: var(--bg-elevated);
265
+ box-shadow: var(--shadow-float);
266
+ animation: model-menu-in 180ms var(--ease);
267
+ }
268
+
269
+ @keyframes model-menu-in {
270
+ from {
271
+ opacity: 0;
272
+ transform: translateY(6px);
273
+ }
274
+ to {
275
+ opacity: 1;
276
+ transform: translateY(0);
277
+ }
278
+ }
279
+
280
+ @media (prefers-reduced-motion: reduce) {
281
+ .model-menu {
282
+ animation: none;
283
+ }
284
+ }
285
+
286
+ .model-option {
287
+ display: flex;
288
+ align-items: center;
289
+ gap: 8px;
290
+ width: 100%;
291
+ height: 32px;
292
+ padding: 0 10px;
293
+ border: none;
294
+ border-radius: var(--radius-control);
295
+ background: transparent;
296
+ color: var(--text);
297
+ font-family: inherit;
298
+ font-size: 12.5px;
299
+ text-align: left;
300
+ cursor: pointer;
301
+ transition: background-color var(--dur) var(--ease);
302
+ }
303
+
304
+ .model-option:hover {
305
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
306
+ }
307
+
308
+ .model-option.is-active {
309
+ background: var(--accent-soft);
310
+ }
311
+
312
+ .model-option-name {
313
+ min-width: 0;
314
+ overflow: hidden;
315
+ text-overflow: ellipsis;
316
+ white-space: nowrap;
317
+ }
318
+
319
+ /* 空态(没模型):触发器只显示短句,完整人话在浮层里 */
320
+ .model-menu-empty {
321
+ margin: 0;
322
+ padding: 6px 8px;
323
+ max-width: 264px;
324
+ color: var(--text-tertiary);
325
+ font-size: 12px;
326
+ line-height: 1.6;
327
+ }
328
+
329
+ /* ---------- 右组动作:快捷键提示 + 发送/停止 ---------- */
330
+ .composer-actions {
331
+ display: inline-flex;
332
+ align-items: center;
333
+ gap: 8px;
334
+ flex: 0 0 auto;
335
+ }
336
+
337
+ .composer-hint {
338
+ font-size: 12px;
339
+ line-height: 1;
340
+ color: var(--text-tertiary);
341
+ white-space: nowrap;
342
+ }
343
+
344
+ /* 发送:Codex 式圆形图标按钮(暖陶土实底 + ↑),去文字。 */
345
+ .btn-send {
346
+ display: inline-flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ flex: 0 0 auto;
350
+ width: 30px;
351
+ height: 30px;
352
+ padding: 0;
353
+ border: none;
354
+ border-radius: 50%;
355
+ background: var(--accent);
356
+ color: var(--bg);
357
+ cursor: pointer;
358
+ transition:
359
+ background-color var(--dur) var(--ease),
360
+ opacity var(--dur) var(--ease),
361
+ transform var(--dur) var(--ease);
362
+ }
363
+
364
+ .btn-send:hover:not(:disabled) {
365
+ filter: brightness(0.94);
366
+ }
367
+
368
+ .btn-send:active:not(:disabled) {
369
+ transform: scale(0.94);
370
+ }
371
+
372
+ .btn-send:disabled {
373
+ opacity: 0.4;
374
+ cursor: default;
375
+ }
376
+
377
+ .btn-send:focus-visible {
378
+ outline: 2px solid var(--accent);
379
+ outline-offset: 2px;
380
+ }
381
+
382
+ /* 停止:圆形描边图标按钮(□),与发送同尺寸。 */
383
+ .btn-stop {
384
+ display: inline-flex;
385
+ align-items: center;
386
+ justify-content: center;
387
+ flex: 0 0 auto;
388
+ width: 30px;
389
+ height: 30px;
390
+ padding: 0;
391
+ border: 1px solid var(--border);
392
+ border-radius: 50%;
393
+ background: transparent;
394
+ color: var(--text);
395
+ cursor: pointer;
396
+ transition: background-color var(--dur) var(--ease);
397
+ }
398
+
399
+ .btn-stop:hover {
400
+ background: var(--accent-soft);
401
+ }
402
+
403
+ .btn-stop:focus-visible {
404
+ outline: 2px solid var(--accent);
405
+ outline-offset: 2px;
406
+ }
407
+
408
+ .composer-error {
409
+ max-width: 760px;
410
+ margin: 0 auto 8px;
411
+ color: var(--danger);
412
+ font-size: 12.5px;
413
+ }
414
+
415
+ /* ---------- 思考强度胶囊滑轨(契约 6F)----------
416
+ Warm Paper 基调:sunken 细轨 + 五个刻度点 + 圆点手柄;
417
+ 手柄 150ms transform 过渡滑动;Ultra 档手柄与轨道末端用 accent
418
+ 渐变提示「最烧脑」。不引外部滑块库。
419
+ 收紧版:档名衬线小字(约 50px)+ 72px 轨道(五档间距 18px),
420
+ 整条约 128px;任务模式/狂暴锁 Ultra 的语义一字未改。 */
421
+ /* ── 思考强度滑块(契约 6F)—— 对齐参考设计 ──────────────────────
422
+ 顶行「思考强度」标题 + 右侧当前档值;下方暗色渐变轨道 + 白色圆旋钮。
423
+ 五档(关/低/中/高/炽焰)连续拖拽,松手吸附。 */
424
+ .think-slider {
425
+ display: flex; flex-direction: column; gap: 5px;
426
+ flex: 0 0 auto; width: 220px; min-width: 0;
427
+ }
428
+ .think-slider.is-disabled { opacity: 0.45; pointer-events: none; }
429
+ .think-head {
430
+ display: flex; justify-content: space-between; align-items: baseline; gap: 6px;
431
+ }
432
+ .think-label {
433
+ font-size: 11px; color: var(--ink-3); white-space: nowrap;
434
+ }
435
+ .think-value {
436
+ font-size: 11px; color: var(--ink-1); font-weight: 600;
437
+ font-variant-numeric: tabular-nums;
438
+ transition: color var(--dur-2) var(--ease);
439
+ }
440
+ .think-slider[data-lv="4"] .think-value { color: var(--warning); }
441
+
442
+ /* 暗色圆角轨道 + 渐变填充 + 白色圆旋钮 */
443
+ .think-track {
444
+ position: relative; height: 16px; border-radius: 999px;
445
+ background: linear-gradient(180deg, rgba(0,0,0,0.35), rgba(0,0,0,0.15));
446
+ box-shadow: inset 0 1px 2px rgba(0,0,0,0.35);
447
+ cursor: pointer; touch-action: none;
448
+ }
449
+ .think-fill {
450
+ position: absolute; left: 2px; top: 2px; bottom: 2px;
451
+ width: calc((var(--think-pos, 0) / 4) * (100% - 4px));
452
+ border-radius: 999px;
453
+ background: linear-gradient(90deg, rgba(217,119,87,0.55), rgba(201,162,39,0.75));
454
+ transition: width var(--dur-2) var(--ease);
455
+ overflow: hidden;
456
+ }
457
+ .think-knob {
458
+ position: absolute; top: 50%;
459
+ left: calc(2px + (var(--think-pos, 0) / 4) * (100% - 4px));
460
+ width: 16px; height: 16px; transform: translate(-50%, -50%);
461
+ border-radius: 50%; background: #fff;
462
+ box-shadow: 0 1px 4px rgba(0,0,0,0.45), 0 0 0 1px rgba(0,0,0,0.08);
463
+ transition: left var(--dur-2) var(--ease);
464
+ pointer-events: none;
465
+ }
466
+ .think-slider[data-lv="4"] .think-knob {
467
+ box-shadow: 0 1px 4px rgba(0,0,0,0.45), 0 0 8px rgba(201,162,39,0.6);
468
+ }
469
+ .think-slider.is-dragging .think-knob,
470
+ .think-slider.is-dragging .think-fill { transition: none; }
471
+
472
+ /* 星点(飞驰小点,随档位加速) */
473
+ .think-spark {
474
+ position: absolute; top: 50%; width: 3px; height: 3px;
475
+ transform: translateY(-50%); border-radius: 50%;
476
+ background: rgba(255,255,255,0.85); opacity: 0; pointer-events: none;
477
+ animation: think-fly var(--d, 1400ms) var(--ease) infinite;
478
+ animation-delay: var(--delay, 0ms);
479
+ }
480
+ @keyframes think-fly {
481
+ 0% { left: 0; opacity: 0; }
482
+ 15% { opacity: var(--o, 0.8); }
483
+ 85% { opacity: var(--o, 0.8); }
484
+ 100% { left: 100%; opacity: 0; }
485
+ }
486
+ @media (prefers-reduced-motion: reduce) {
487
+ .think-spark { animation: none; opacity: 0; }
488
+ }
css/computer-use.css ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .computer-use-workspace{gap:14px}
2
+ .computer-use-tabs{display:flex;gap:3px;padding:4px;width:max-content;max-width:100%;border:1px solid var(--border);border-radius:7px;background:var(--bg-sunken)}
3
+ .computer-use-tabs>button{display:flex;align-items:center;gap:7px;min-height:32px;padding:0 11px;border:0;border-radius:5px;background:transparent;color:var(--text-secondary);font-size:11px;cursor:pointer}
4
+ .computer-use-tabs>button[aria-selected="true"]{background:var(--bg-elevated);color:var(--accent);box-shadow:0 1px 3px rgba(0,0,0,.08)}
5
+ .computer-use-toolbar{display:flex;align-items:flex-end;gap:14px;padding:12px 14px}
6
+ .computer-use-toolbar>label{display:grid;gap:5px;min-width:240px;color:var(--text-tertiary);font-size:10px}
7
+ .computer-use-toolbar>label select{width:100%}
8
+ .computer-local-badge{display:flex;align-items:center;gap:6px;margin-right:auto;color:var(--success);font-size:10px}
9
+ .computer-sandbox-card{display:grid;gap:10px;padding:13px}
10
+ .computer-sandbox-card>header,.computer-action-log>header{display:flex;align-items:center;gap:10px}
11
+ .computer-sandbox-card>header>div{display:grid;gap:3px;margin-right:auto}
12
+ .computer-sandbox-card>header strong,.computer-action-log>header strong{font-size:11px;font-weight:600}
13
+ .computer-sandbox-card>header span,.computer-action-log>header span{color:var(--text-tertiary);font-size:9px}
14
+ .computer-sandbox-canvas{display:block;width:100%;height:auto;max-height:62vh;aspect-ratio:12/7;border:1px solid var(--border);border-radius:4px;background:#eef2f6;object-fit:contain;cursor:default;image-rendering:auto}
15
+ .computer-sandbox-canvas.is-agent-running{cursor:progress}
16
+ .computer-action-log{display:grid;gap:9px;padding:13px}
17
+ .computer-action-log>header{margin-bottom:2px}
18
+ .computer-action-log>header>span{margin-left:auto}
19
+ .computer-action-log>div{display:grid;grid-template-columns:28px minmax(120px,1fr) minmax(140px,2fr) 70px;align-items:center;gap:9px;padding:7px 0;border-top:1px solid var(--border)}
20
+ .computer-action-log>div>small,.computer-action-log>div>code{color:var(--text-tertiary);font:9px var(--font-mono)}
21
+ .computer-action-log>div>strong{font-size:10px;font-weight:550}
22
+ .computer-action-log>div>span{overflow:hidden;color:var(--text-secondary);font-size:9px;text-overflow:ellipsis;white-space:nowrap}
23
+ .computer-action-log .ws-empty{margin:0}
24
+ .computer-benchmark{display:grid;gap:13px}
25
+ .computer-benchmark>.feature-heading{margin:0;padding:0}
26
+ .computer-model-choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}
27
+ .computer-model-choices>label{display:flex;align-items:center;gap:8px;min-width:0;padding:9px 10px;border:1px solid var(--border);border-radius:5px;background:var(--bg-elevated);font-size:10px}
28
+ .computer-model-choices input{accent-color:var(--accent)}
29
+ .computer-model-choices>label>span{overflow:hidden;flex:1;text-overflow:ellipsis;white-space:nowrap}
30
+ .computer-model-choices small{color:var(--text-tertiary);font:9px var(--font-mono)}
31
+ .computer-benchmark-summary{display:flex;flex-wrap:wrap;gap:16px;align-items:center;padding:10px 12px;border:1px solid var(--border);border-radius:5px;background:var(--bg-sunken);font-size:10px}
32
+ .computer-benchmark-summary strong{color:var(--accent)}
33
+ .computer-benchmark-summary span{color:var(--text-secondary)}
34
+ .computer-benchmark-rows{display:grid;gap:6px}
35
+ .computer-benchmark-row{padding:10px 12px;border:1px solid var(--border);border-radius:5px;background:var(--bg-elevated)}
36
+ .computer-benchmark-row>header{display:grid;grid-template-columns:minmax(100px,1fr) auto minmax(120px,auto);align-items:center;gap:10px}
37
+ .computer-benchmark-row>header strong{font-size:10px;font-weight:600}
38
+ .computer-benchmark-row>header>span{font-size:9px}.computer-benchmark-row .is-pass{color:var(--success)}.computer-benchmark-row .is-fail{color:var(--warning)}
39
+ .computer-benchmark-row>header small{color:var(--text-tertiary);font:9px var(--font-mono);text-align:right}
40
+ .computer-benchmark-row>p{margin:8px 0 0;color:var(--text-secondary);font-size:10px;line-height:1.65;white-space:pre-wrap;overflow-wrap:anywhere}
41
+ .computer-benchmark-row .computer-failure{display:block;margin-top:6px;color:var(--warning);font-size:9px}
42
+ @media(max-width:760px){.computer-use-toolbar{align-items:stretch;flex-direction:column}.computer-use-toolbar>label{min-width:0}.computer-local-badge{margin:0}.computer-action-log>div{grid-template-columns:25px 1fr 60px}.computer-action-log>div>span{grid-column:2/-1}.computer-model-choices{grid-template-columns:1fr}.computer-benchmark-row>header{grid-template-columns:1fr auto}.computer-benchmark-row>header small{grid-column:1/-1;text-align:left}}
css/darkside.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ /* V5: graphite, champagne, and restrained depth. Opt-in; old themes stay intact. */
2
+ [data-style="darkside"]{color-scheme:dark;--bg:#101317;--bg-elevated:#171b21;--bg-sunken:#0d1014;--border:#2a3038;--text:#e8eaed;--text-secondary:#9ca5b2;--text-tertiary:#7f8a99;--accent:#e7bf78;--accent-soft:#2f291e;--success:#8bbfb0;--warning:#dec077;--danger:#e79797;--glass:rgba(17,21,27,.94);--scrim:rgba(0,0,0,.6);--shadow-float:0 20px 70px rgba(0,0,0,.42);--font-serif:var(--font-sans)}
3
+ [data-style="darkside"] .shell{background:var(--bg)}[data-style="darkside"] .sidebar{background:#12161c;width:210px;border-color:#252b34;padding-left:14px;padding-right:14px}[data-style="darkside"] .brand{gap:8px;padding-bottom:24px}[data-style="darkside"] .brand-name{font-family:var(--font-sans);font-weight:550;font-size:15px;letter-spacing:-.5px}[data-style="darkside"] .brand-mark{color:var(--accent)}[data-style="darkside"] .nav-item{padding:11px 13px;gap:4px;margin-bottom:3px;border:1px solid transparent;border-radius:9px}[data-style="darkside"] .nav-item:hover{background:#1a2029}[data-style="darkside"] .nav-item.is-active{background:linear-gradient(110deg,#27261f,#211f1b);border-color:#3a3325}[data-style="darkside"] .nav-item.is-active:before{display:none}[data-style="darkside"] .nav-item.is-active .nav-row,[data-style="darkside"] .nav-item.is-active .nav-row svg{color:var(--accent)}[data-style="darkside"] .nav-row{font-size:12px;gap:9px}[data-style="darkside"] .nav-row svg{width:15px;height:15px}[data-style="darkside"] .nav-hint{font-size:10px;padding-left:24px}[data-style="darkside"] .sidebar-foot{padding:12px 9px 0;border-top:1px solid var(--border);font-size:9px;letter-spacing:.3px;line-height:2}
4
+ .release-plate{display:flex;flex-direction:column;gap:5px;padding:0 8px 22px;color:var(--text-tertiary);font:8px var(--font-mono);letter-spacing:1.5px}.release-plate strong{color:var(--text-secondary);font-size:9px;font-weight:400}.release-plate span{letter-spacing:2px}
5
+ [data-style="darkside"] .conversations{background:#12161c;border-right:1px solid var(--border)}[data-style="darkside"] .conv-item.is-active{background:#252a32}[data-style="darkside"] .conv-title{font-size:12px}[data-style="darkside"] .conv-meta{font-size:10px}[data-style="darkside"] .wb-tabs,[data-style="darkside"] .workbench-head{background:var(--bg);border-color:var(--border)}[data-style="darkside"] .composer-box{background:var(--bg-elevated);border-color:#343c47;box-shadow:0 5px 24px rgba(0,0,0,.14)}[data-style="darkside"] .msg-user .msg-card{background:#232933;border:1px solid #313946}[data-style="darkside"] .msg-assistant .msg-body{font-size:14px;line-height:1.9}[data-style="darkside"] .stats-bar{font-size:10px;border-color:var(--border)}[data-style="darkside"] button,[data-style="darkside"] input,[data-style="darkside"] select,[data-style="darkside"] textarea{transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}[data-style="darkside"] :focus-visible{outline:2px solid var(--accent);outline-offset:3px}[data-style="darkside"] .pref-section,[data-style="darkside"] .settings-section{border-color:var(--border)}[data-style="darkside"] .style-picker{flex-wrap:wrap;justify-content:flex-end}
6
+ [data-style="darkside"][data-theme="light"]{color-scheme:light;--bg:#f5f4f0;--bg-elevated:#fff;--bg-sunken:#eeece6;--border:#d9d5cc;--text:#20252b;--text-secondary:#5b6571;--text-tertiary:#717b86;--accent:#805c29;--accent-soft:#eee4d1;--success:#356c5b;--warning:#8a6725;--danger:#a13b3b;--glass:rgba(245,244,240,.94)}
7
+ [data-style="darkside"][data-theme="light"] .sidebar,[data-style="darkside"][data-theme="light"] .conversations{background:#ebe9e2;border-color:var(--border)}[data-style="darkside"][data-theme="light"] .nav-item.is-active{background:var(--accent-soft);border-color:#d7c7a6}[data-style="darkside"][data-theme="light"] .nav-item:hover,[data-style="darkside"][data-theme="light"] .conv-item.is-active{background:#e1ddd1}[data-style="darkside"][data-theme="light"] .msg-user .msg-card{background:#ece8df;border-color:var(--border)}
8
+ @media(prefers-reduced-motion:reduce){.workspace-page *,[data-style="darkside"] *{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
css/diag.css ADDED
@@ -0,0 +1,569 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 错误诊断 · 体检报告(Warm Paper,全令牌配色,无硬编码颜色)。
2
+ 只读呈现:没有任何「立即修复」按钮,徽章仅表达状态与修复难度。 */
3
+
4
+ .diag {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ }
10
+
11
+ .diag-head {
12
+ margin-bottom: 24px;
13
+ }
14
+
15
+ .diag-head-row {
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: space-between;
19
+ gap: 16px;
20
+ }
21
+
22
+ .diag-head h1 {
23
+ font-size: 30px;
24
+ }
25
+
26
+ .diag-refresh {
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ .diag-refresh:disabled {
31
+ opacity: 0.6;
32
+ cursor: default;
33
+ }
34
+
35
+ .diag-sub {
36
+ margin: 6px 0 0;
37
+ font-size: 13.5px;
38
+ color: var(--text-secondary);
39
+ font-variant-numeric: tabular-nums;
40
+ }
41
+
42
+ .diag-sub-dim {
43
+ color: var(--text-tertiary);
44
+ }
45
+
46
+ /* ── 检查卡列表 ───────────────────────────────────────────────────── */
47
+
48
+ .diag-list {
49
+ display: flex;
50
+ flex-direction: column;
51
+ gap: 16px;
52
+ }
53
+
54
+ .diag-card {
55
+ padding: 20px 22px 18px;
56
+ border: 1px solid var(--border);
57
+ border-radius: var(--radius-card);
58
+ background: var(--bg-elevated);
59
+ }
60
+
61
+ /* 状态只用左侧一条细色带表达,克制不喧哗(design-system §2 语义色规则) */
62
+ .diag-card.is-warn {
63
+ border-left: 3px solid var(--warning);
64
+ }
65
+
66
+ .diag-card.is-critical {
67
+ border-left: 3px solid var(--danger);
68
+ }
69
+
70
+ .diag-card.is-ok {
71
+ border-left: 3px solid var(--success);
72
+ }
73
+
74
+ .diag-card-head {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: space-between;
78
+ gap: 12px;
79
+ margin-bottom: 12px;
80
+ }
81
+
82
+ .diag-card-title {
83
+ font-size: 16px;
84
+ }
85
+
86
+ /* ── 徽章 ─────────────────────────────────────────────────────────── */
87
+
88
+ /* 徽章:与全站徽章同尺寸同字重(2px 8px / 12px / 500 / pill) */
89
+ .diag-badge {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ flex-shrink: 0;
93
+ padding: 2px 8px;
94
+ border-radius: 999px;
95
+ font-size: 12px;
96
+ font-weight: 500;
97
+ line-height: 1.6;
98
+ }
99
+
100
+ .diag-badge-status.is-ok {
101
+ background: color-mix(in srgb, var(--success) 14%, transparent);
102
+ color: var(--success);
103
+ }
104
+
105
+ .diag-badge-status.is-warn {
106
+ background: color-mix(in srgb, var(--warning) 16%, transparent);
107
+ color: var(--warning);
108
+ }
109
+
110
+ .diag-badge-status.is-critical {
111
+ background: color-mix(in srgb, var(--danger) 14%, transparent);
112
+ color: var(--danger);
113
+ }
114
+
115
+ .diag-badge-risk.is-green {
116
+ background: color-mix(in srgb, var(--success) 14%, transparent);
117
+ color: var(--success);
118
+ }
119
+
120
+ .diag-badge-risk.is-yellow {
121
+ background: color-mix(in srgb, var(--warning) 16%, transparent);
122
+ color: var(--warning);
123
+ }
124
+
125
+ .diag-badge-risk.is-red {
126
+ background: color-mix(in srgb, var(--danger) 14%, transparent);
127
+ color: var(--danger);
128
+ }
129
+
130
+ /* ── 三段式文案 ───────────────────────────────────────────────────── */
131
+
132
+ .diag-card-body {
133
+ display: flex;
134
+ flex-direction: column;
135
+ gap: 8px;
136
+ }
137
+
138
+ .diag-line {
139
+ display: flex;
140
+ align-items: baseline;
141
+ gap: 12px;
142
+ }
143
+
144
+ .diag-line-label {
145
+ flex-shrink: 0;
146
+ width: 64px;
147
+ font-size: 12px;
148
+ color: var(--text-tertiary);
149
+ }
150
+
151
+ .diag-line-text {
152
+ margin: 0;
153
+ font-size: 13.5px;
154
+ line-height: 1.65;
155
+ color: var(--text);
156
+ }
157
+
158
+ .diag-fix-hint {
159
+ margin: 4px 0 0;
160
+ font-size: 12.5px;
161
+ color: var(--text-secondary);
162
+ font-family: var(--font-mono);
163
+ }
164
+
165
+ /* ── 明细列表(崩溃报告 / Top 进程 / 端口)─────────────────────────── */
166
+
167
+ .diag-crash-list,
168
+ .diag-mini-list {
169
+ list-style: none;
170
+ margin: 12px 0 0;
171
+ padding: 12px 0 0;
172
+ border-top: 1px solid var(--border);
173
+ }
174
+
175
+ .diag-crash,
176
+ .diag-mini {
177
+ display: flex;
178
+ align-items: baseline;
179
+ gap: 12px;
180
+ padding: 5px 0;
181
+ font-size: 13px;
182
+ font-variant-numeric: tabular-nums;
183
+ }
184
+
185
+ .diag-crash-name,
186
+ .diag-mini-name {
187
+ flex-shrink: 0;
188
+ min-width: 96px;
189
+ color: var(--text);
190
+ overflow-wrap: anywhere;
191
+ }
192
+
193
+ .diag-crash-time {
194
+ flex: 1;
195
+ min-width: 0;
196
+ color: var(--text-secondary);
197
+ overflow-wrap: anywhere;
198
+ }
199
+
200
+ .diag-crash-kind {
201
+ flex-shrink: 0;
202
+ max-width: 220px;
203
+ overflow: hidden;
204
+ text-overflow: ellipsis;
205
+ white-space: nowrap;
206
+ font-family: var(--font-mono);
207
+ font-size: 12px;
208
+ color: var(--text-tertiary);
209
+ }
210
+
211
+ .diag-mini-value {
212
+ flex: 1;
213
+ min-width: 0;
214
+ text-align: right;
215
+ color: var(--text-secondary);
216
+ font-variant-numeric: tabular-nums;
217
+ overflow-wrap: anywhere;
218
+ }
219
+
220
+ /* 文字按钮(查看原文):无底色,hover 才出现下划线 */
221
+ .diag-link-btn {
222
+ flex-shrink: 0;
223
+ padding: 0;
224
+ border: none;
225
+ background: transparent;
226
+ color: var(--accent);
227
+ font-family: inherit;
228
+ font-size: 13px;
229
+ cursor: pointer;
230
+ transition: opacity var(--dur) var(--ease);
231
+ }
232
+
233
+ .diag-link-btn:hover {
234
+ text-decoration: underline;
235
+ }
236
+
237
+ /* ── 卡片脚注(修复难度徽章 + 温和话术)────────────────────────────── */
238
+
239
+ .diag-card-foot {
240
+ display: flex;
241
+ align-items: baseline;
242
+ gap: 10px;
243
+ margin-top: 12px;
244
+ }
245
+
246
+ .diag-risk-note {
247
+ font-size: 12.5px;
248
+ color: var(--text-tertiary);
249
+ }
250
+
251
+ .diag-foot {
252
+ margin: 8px 0 0;
253
+ font-size: 12px;
254
+ color: var(--text-tertiary);
255
+ }
256
+
257
+ /* ── 空态 / 加载态(衬线大字一句话,design-system §7)──────────────── */
258
+
259
+ .diag-empty {
260
+ padding: 56px 0 24px;
261
+ }
262
+
263
+ .diag-empty-title {
264
+ margin: 0;
265
+ font-family: var(--font-serif);
266
+ font-size: 24px;
267
+ font-weight: 600;
268
+ color: var(--text);
269
+ }
270
+
271
+ .diag-empty-sub {
272
+ margin: 10px 0 0;
273
+ max-width: 560px;
274
+ font-size: 13.5px;
275
+ color: var(--text-secondary);
276
+ }
277
+
278
+ /* 呼吸点加载指示:三点错峰呼吸(reduced-motion 时 theme.css 全局静止) */
279
+ @keyframes diag-breathe {
280
+ 0%,
281
+ 100% {
282
+ opacity: 0.25;
283
+ }
284
+ 50% {
285
+ opacity: 1;
286
+ }
287
+ }
288
+
289
+ .diag-loading-dots {
290
+ display: inline-flex;
291
+ gap: 5px;
292
+ margin-left: 10px;
293
+ vertical-align: middle;
294
+ }
295
+
296
+ .diag-loading-dots span {
297
+ width: 6px;
298
+ height: 6px;
299
+ border-radius: 50%;
300
+ background: var(--accent);
301
+ animation: diag-breathe 1.2s var(--ease) infinite;
302
+ }
303
+
304
+ .diag-loading-dots span:nth-child(2) {
305
+ animation-delay: 150ms;
306
+ }
307
+
308
+ .diag-loading-dots span:nth-child(3) {
309
+ animation-delay: 300ms;
310
+ }
311
+
312
+ /* ── 修复区(Phase 6A):🟢 直接可点 / 🟡 先确认 ────────────────────── */
313
+
314
+ .diag-fixes {
315
+ display: flex;
316
+ flex-direction: column;
317
+ gap: 10px;
318
+ margin-top: 14px;
319
+ padding-top: 12px;
320
+ border-top: 1px solid var(--border);
321
+ }
322
+
323
+ .diag-fix {
324
+ display: flex;
325
+ flex-direction: column;
326
+ gap: 10px;
327
+ align-items: flex-start;
328
+ }
329
+
330
+ /* 修复按钮:语义色只做描边与文字,底色保持纸感(design-system §2) */
331
+ .diag-fix-btn {
332
+ height: 34px;
333
+ padding: 0 14px;
334
+ border: 1px solid transparent;
335
+ border-radius: var(--radius-control);
336
+ font-family: inherit;
337
+ font-size: 13px;
338
+ cursor: pointer;
339
+ transition: background-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
340
+ }
341
+
342
+ .diag-fix-btn.is-green {
343
+ background: color-mix(in srgb, var(--success) 14%, transparent);
344
+ border-color: color-mix(in srgb, var(--success) 32%, transparent);
345
+ color: var(--success);
346
+ }
347
+
348
+ .diag-fix-btn.is-green:hover:not(:disabled) {
349
+ background: color-mix(in srgb, var(--success) 22%, transparent);
350
+ }
351
+
352
+ .diag-fix-btn.is-yellow {
353
+ background: color-mix(in srgb, var(--warning) 14%, transparent);
354
+ border-color: color-mix(in srgb, var(--warning) 34%, transparent);
355
+ color: var(--warning);
356
+ }
357
+
358
+ .diag-fix-btn.is-yellow:hover:not(:disabled) {
359
+ background: color-mix(in srgb, var(--warning) 22%, transparent);
360
+ }
361
+
362
+ .diag-fix-btn:disabled {
363
+ opacity: 0.55;
364
+ cursor: default;
365
+ }
366
+
367
+ /* 展开的「会发生什么」面板 */
368
+ .diag-fix-panel {
369
+ width: 100%;
370
+ padding: 12px 14px;
371
+ border: 1px solid var(--border);
372
+ border-radius: var(--radius-control);
373
+ background: var(--bg-sunken);
374
+ display: flex;
375
+ flex-direction: column;
376
+ gap: 10px;
377
+ }
378
+
379
+ .diag-fix-detail {
380
+ margin: 0;
381
+ font-size: 13px;
382
+ line-height: 1.65;
383
+ color: var(--text);
384
+ }
385
+
386
+ /* 候选清单:默认全不勾,一行一项 */
387
+ .diag-candidates {
388
+ list-style: none;
389
+ margin: 0;
390
+ padding: 0;
391
+ display: flex;
392
+ flex-direction: column;
393
+ gap: 2px;
394
+ }
395
+
396
+ .diag-candidate {
397
+ display: flex;
398
+ align-items: baseline;
399
+ gap: 10px;
400
+ padding: 5px 6px;
401
+ border-radius: var(--radius-chip);
402
+ cursor: pointer;
403
+ font-size: 13px;
404
+ }
405
+
406
+ .diag-candidate:hover {
407
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
408
+ }
409
+
410
+ .diag-candidate input {
411
+ flex-shrink: 0;
412
+ align-self: center;
413
+ accent-color: var(--accent);
414
+ }
415
+
416
+ .diag-candidate-title {
417
+ flex-shrink: 0;
418
+ max-width: 40%;
419
+ overflow: hidden;
420
+ text-overflow: ellipsis;
421
+ white-space: nowrap;
422
+ color: var(--text);
423
+ }
424
+
425
+ .diag-candidate-size {
426
+ flex-shrink: 0;
427
+ min-width: 72px;
428
+ text-align: right;
429
+ color: var(--text-secondary);
430
+ font-variant-numeric: tabular-nums;
431
+ }
432
+
433
+ .diag-candidate-detail {
434
+ flex: 1;
435
+ min-width: 0;
436
+ color: var(--text-tertiary);
437
+ overflow: hidden;
438
+ text-overflow: ellipsis;
439
+ white-space: nowrap;
440
+ }
441
+
442
+ .diag-fix-summary {
443
+ margin: 0;
444
+ font-size: 12.5px;
445
+ color: var(--text-secondary);
446
+ font-variant-numeric: tabular-nums;
447
+ }
448
+
449
+ .diag-fix-actions {
450
+ display: flex;
451
+ align-items: center;
452
+ gap: 10px;
453
+ }
454
+
455
+ /* 修复结果行:人话 + 释放体积 + 可撤销说明 */
456
+ .diag-fix-result {
457
+ display: flex;
458
+ align-items: baseline;
459
+ gap: 8px;
460
+ margin: 0;
461
+ max-width: 100%;
462
+ font-size: 13px;
463
+ line-height: 1.65;
464
+ }
465
+
466
+ .diag-fix-result.is-ok {
467
+ color: var(--text);
468
+ }
469
+
470
+ .diag-fix-result.is-note {
471
+ color: var(--text-secondary);
472
+ }
473
+
474
+ .diag-fix-result-mark {
475
+ flex-shrink: 0;
476
+ font-family: var(--font-mono);
477
+ }
478
+
479
+ .diag-fix-result.is-ok .diag-fix-result-mark {
480
+ color: var(--success);
481
+ }
482
+
483
+ .diag-fix-undone {
484
+ color: var(--text-secondary);
485
+ }
486
+
487
+ .diag-open-settings {
488
+ margin-top: 12px;
489
+ }
490
+
491
+ /* ── 后悔药(隔离区清单)───────────────────────────────────────────── */
492
+
493
+ .diag-trash {
494
+ margin-top: 10px;
495
+ padding: 18px 22px;
496
+ border: 1px solid var(--border);
497
+ border-radius: var(--radius-card);
498
+ background: var(--bg-elevated);
499
+ }
500
+
501
+ .diag-trash-head {
502
+ display: flex;
503
+ align-items: baseline;
504
+ gap: 14px;
505
+ flex-wrap: wrap;
506
+ }
507
+
508
+ .diag-trash-title {
509
+ margin: 0;
510
+ font-size: 16px;
511
+ }
512
+
513
+ .diag-trash-sub {
514
+ margin: 0;
515
+ font-size: 12.5px;
516
+ color: var(--text-secondary);
517
+ }
518
+
519
+ .diag-trash-empty {
520
+ margin: 12px 0 0;
521
+ font-family: var(--font-serif);
522
+ font-size: 15px;
523
+ color: var(--text-tertiary);
524
+ }
525
+
526
+ .diag-trash-list {
527
+ list-style: none;
528
+ margin: 12px 0 0;
529
+ padding: 0;
530
+ display: flex;
531
+ flex-direction: column;
532
+ }
533
+
534
+ .diag-trash-item {
535
+ display: flex;
536
+ align-items: baseline;
537
+ gap: 12px;
538
+ padding: 7px 0;
539
+ border-top: 1px solid var(--border);
540
+ font-size: 13px;
541
+ font-variant-numeric: tabular-nums;
542
+ flex-wrap: wrap;
543
+ }
544
+
545
+ .diag-trash-time {
546
+ flex-shrink: 0;
547
+ min-width: 168px;
548
+ color: var(--text-secondary);
549
+ }
550
+
551
+ .diag-trash-info {
552
+ flex: 1;
553
+ min-width: 160px;
554
+ color: var(--text);
555
+ }
556
+
557
+ .diag-trash-confirm {
558
+ display: inline-flex;
559
+ align-items: baseline;
560
+ gap: 8px;
561
+ font-size: 12.5px;
562
+ color: var(--text-secondary);
563
+ }
564
+
565
+ .diag-trash-confirm-yes {
566
+ height: 28px;
567
+ padding: 0 10px;
568
+ font-size: 12.5px;
569
+ }
css/discuss.css ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 模型讨论区(契约 25A · 工作台「讨论」tab)——Warm Paper 令牌,零硬编码色:
2
+ 所有颜色走 theme.css 变量(深浅色自动跟随)。布局沿用 .bench 的整页滚动容器。 */
3
+
4
+ .discuss {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ }
10
+
11
+ /* ── 页头 ───────────────────────────────────────────────────────── */
12
+
13
+ .discuss-head {
14
+ display: flex;
15
+ align-items: flex-end;
16
+ justify-content: space-between;
17
+ gap: 16px;
18
+ margin-bottom: 20px;
19
+ }
20
+
21
+ .discuss-title {
22
+ font-family: var(--font-serif);
23
+ font-size: 26px;
24
+ font-weight: 600;
25
+ letter-spacing: -0.01em;
26
+ color: var(--text);
27
+ }
28
+
29
+ .discuss-head-sub {
30
+ margin: 6px 0 0;
31
+ font-size: 13.5px;
32
+ line-height: 1.6;
33
+ color: var(--text-secondary);
34
+ }
35
+
36
+ .discuss-head-actions {
37
+ display: flex;
38
+ gap: 8px;
39
+ flex-shrink: 0;
40
+ }
41
+
42
+ .discuss-muted {
43
+ font-size: 13px;
44
+ line-height: 1.6;
45
+ color: var(--text-secondary);
46
+ }
47
+
48
+ .discuss-notice {
49
+ margin: 0 0 16px;
50
+ padding: 10px 14px;
51
+ border: 1px solid var(--border);
52
+ border-radius: var(--radius-control);
53
+ background: var(--bg-elevated);
54
+ font-size: 13.5px;
55
+ line-height: 1.6;
56
+ color: var(--text);
57
+ }
58
+
59
+ /* ── 卡片与表单 ─────────────────────────────────────────────────── */
60
+
61
+ .discuss-card {
62
+ background: var(--bg-elevated);
63
+ border: 1px solid var(--border);
64
+ border-radius: var(--radius-card);
65
+ padding: 22px 24px;
66
+ margin-bottom: 24px;
67
+ }
68
+
69
+ .discuss-card-title {
70
+ font-family: var(--font-serif);
71
+ font-size: 18px;
72
+ font-weight: 600;
73
+ color: var(--text);
74
+ margin: 0 0 18px;
75
+ }
76
+
77
+ .discuss-field {
78
+ display: flex;
79
+ flex-direction: column;
80
+ gap: 8px;
81
+ margin-bottom: 18px;
82
+ }
83
+
84
+ .discuss-field-label {
85
+ font-size: 13px;
86
+ color: var(--text-secondary);
87
+ }
88
+
89
+ .discuss-field textarea {
90
+ width: 100%;
91
+ font-family: var(--font-sans);
92
+ font-size: 14px;
93
+ line-height: 1.65;
94
+ color: var(--text);
95
+ background: var(--bg-sunken);
96
+ border: 1px solid transparent;
97
+ border-radius: var(--radius-control);
98
+ padding: 10px 12px;
99
+ resize: vertical;
100
+ min-height: 72px;
101
+ transition: border-color var(--dur) var(--ease);
102
+ }
103
+
104
+ .discuss-field textarea::placeholder {
105
+ color: var(--text-tertiary);
106
+ }
107
+
108
+ .discuss-field textarea:focus-visible {
109
+ outline: none;
110
+ border-color: var(--accent);
111
+ }
112
+
113
+ /* ── 模型分组多选(本机 / 云 · 接口名) ───────────────────────────── */
114
+
115
+ .discuss-groups {
116
+ display: flex;
117
+ flex-direction: column;
118
+ gap: 14px;
119
+ }
120
+
121
+ .discuss-group {
122
+ display: flex;
123
+ flex-direction: column;
124
+ gap: 8px;
125
+ }
126
+
127
+ .discuss-group-label {
128
+ font-family: var(--font-serif);
129
+ font-size: 14px;
130
+ font-weight: 600;
131
+ color: var(--text);
132
+ }
133
+
134
+ .discuss-chips {
135
+ display: flex;
136
+ flex-wrap: wrap;
137
+ gap: 8px;
138
+ }
139
+
140
+ .discuss-chip {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ gap: 7px;
144
+ height: 30px;
145
+ padding: 0 11px;
146
+ border: 1px solid var(--border);
147
+ border-radius: var(--radius-chip);
148
+ background: var(--bg);
149
+ color: var(--text-secondary);
150
+ font-family: inherit;
151
+ font-size: 13px;
152
+ cursor: pointer;
153
+ transition:
154
+ background-color var(--dur) var(--ease),
155
+ border-color var(--dur) var(--ease),
156
+ color var(--dur) var(--ease);
157
+ }
158
+
159
+ .discuss-chip:hover {
160
+ background: var(--accent-soft);
161
+ color: var(--text);
162
+ }
163
+
164
+ .discuss-chip.is-on {
165
+ background: var(--accent-soft);
166
+ border-color: var(--accent);
167
+ color: var(--text);
168
+ font-weight: 600;
169
+ }
170
+
171
+ .discuss-chip:focus-visible {
172
+ outline: 2px solid var(--accent);
173
+ outline-offset: 2px;
174
+ }
175
+
176
+ .discuss-chip-name {
177
+ max-width: 200px;
178
+ overflow: hidden;
179
+ text-overflow: ellipsis;
180
+ white-space: nowrap;
181
+ }
182
+
183
+ .discuss-chip-badge {
184
+ font-size: 11px;
185
+ line-height: 1;
186
+ padding: 3px 6px;
187
+ border-radius: var(--radius-chip);
188
+ background: var(--bg-sunken);
189
+ color: var(--text-secondary);
190
+ }
191
+
192
+ .discuss-chip-badge.is-cloud {
193
+ background: var(--accent-soft);
194
+ color: var(--text);
195
+ }
196
+
197
+ /* ── 轮数选择 + 预算说明 ───────────────────────────────────────── */
198
+
199
+ .discuss-rounds {
200
+ display: inline-flex;
201
+ gap: 4px;
202
+ padding: 4px;
203
+ background: var(--bg-sunken);
204
+ border-radius: var(--radius-control);
205
+ }
206
+
207
+ .discuss-round-btn {
208
+ min-width: 34px;
209
+ height: 28px;
210
+ padding: 0 8px;
211
+ border: none;
212
+ border-radius: var(--radius-control);
213
+ background: transparent;
214
+ color: var(--text-secondary);
215
+ font-family: inherit;
216
+ font-size: 13px;
217
+ cursor: pointer;
218
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
219
+ }
220
+
221
+ .discuss-round-btn:hover {
222
+ color: var(--text);
223
+ }
224
+
225
+ .discuss-round-btn.is-on {
226
+ background: var(--bg-elevated);
227
+ color: var(--text);
228
+ font-weight: 600;
229
+ box-shadow: inset 0 0 0 1px var(--border);
230
+ }
231
+
232
+ .discuss-round-btn:focus-visible {
233
+ outline: 2px solid var(--accent);
234
+ outline-offset: 2px;
235
+ }
236
+
237
+ .discuss-budget {
238
+ margin: 4px 0 0;
239
+ font-size: 12.5px;
240
+ line-height: 1.6;
241
+ color: var(--text-secondary);
242
+ }
243
+
244
+ /* ── 按钮 ───────────────────────────────────────────────────────── */
245
+
246
+ .discuss-actions {
247
+ display: flex;
248
+ align-items: center;
249
+ gap: 14px;
250
+ flex-wrap: wrap;
251
+ }
252
+
253
+ .discuss-primary {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ gap: 7px;
257
+ height: 38px;
258
+ padding: 0 18px;
259
+ border: none;
260
+ border-radius: var(--radius-control);
261
+ background: var(--accent);
262
+ color: var(--bg);
263
+ font-family: inherit;
264
+ font-size: 14px;
265
+ font-weight: 600;
266
+ cursor: pointer;
267
+ transition: opacity var(--dur) var(--ease);
268
+ }
269
+
270
+ .discuss-primary:hover:not(:disabled) {
271
+ opacity: 0.9;
272
+ }
273
+
274
+ .discuss-primary:disabled {
275
+ opacity: 0.45;
276
+ cursor: not-allowed;
277
+ }
278
+
279
+ .discuss-primary:focus-visible {
280
+ outline: 2px solid var(--accent);
281
+ outline-offset: 2px;
282
+ }
283
+
284
+ .discuss-secondary,
285
+ .discuss-danger {
286
+ display: inline-flex;
287
+ align-items: center;
288
+ gap: 6px;
289
+ height: 30px;
290
+ padding: 0 11px;
291
+ border: 1px solid var(--border);
292
+ border-radius: var(--radius-control);
293
+ background: transparent;
294
+ color: var(--text-secondary);
295
+ font-family: inherit;
296
+ font-size: 13px;
297
+ cursor: pointer;
298
+ transition:
299
+ background-color var(--dur) var(--ease),
300
+ color var(--dur) var(--ease),
301
+ border-color var(--dur) var(--ease);
302
+ }
303
+
304
+ .discuss-secondary:hover:not(:disabled) {
305
+ background: var(--accent-soft);
306
+ color: var(--text);
307
+ }
308
+
309
+ .discuss-secondary:disabled {
310
+ opacity: 0.45;
311
+ cursor: not-allowed;
312
+ }
313
+
314
+ .discuss-danger {
315
+ color: var(--danger);
316
+ border-color: var(--danger);
317
+ }
318
+
319
+ .discuss-danger:hover {
320
+ background: var(--danger);
321
+ color: var(--bg);
322
+ }
323
+
324
+ .discuss-secondary:focus-visible,
325
+ .discuss-danger:focus-visible {
326
+ outline: 2px solid var(--accent);
327
+ outline-offset: 2px;
328
+ }
329
+
330
+ /* ── 运行头 + 进度 ──────────────────────────────────────────────── */
331
+
332
+ .discuss-run-head {
333
+ display: flex;
334
+ align-items: center;
335
+ justify-content: space-between;
336
+ gap: 16px;
337
+ flex-wrap: wrap;
338
+ margin-bottom: 14px;
339
+ }
340
+
341
+ .discuss-run-title {
342
+ display: flex;
343
+ align-items: center;
344
+ gap: 10px;
345
+ flex-wrap: wrap;
346
+ min-width: 0;
347
+ }
348
+
349
+ .discuss-run-title .discuss-card-title {
350
+ margin: 0;
351
+ }
352
+
353
+ .discuss-toolbar {
354
+ display: flex;
355
+ gap: 8px;
356
+ flex-shrink: 0;
357
+ }
358
+
359
+ .discuss-progress-label {
360
+ margin: 0 0 6px;
361
+ font-size: 12.5px;
362
+ color: var(--text-secondary);
363
+ }
364
+
365
+ .discuss-progress {
366
+ height: 6px;
367
+ border-radius: var(--radius-chip);
368
+ background: var(--bg-sunken);
369
+ overflow: hidden;
370
+ margin-bottom: 16px;
371
+ }
372
+
373
+ .discuss-progress-fill {
374
+ height: 100%;
375
+ background: var(--accent);
376
+ border-radius: var(--radius-chip);
377
+ transition: width var(--dur) var(--ease);
378
+ }
379
+
380
+ .discuss-stop-reason {
381
+ margin: 0 0 14px;
382
+ padding: 9px 13px;
383
+ border: 1px solid var(--border);
384
+ border-radius: var(--radius-control);
385
+ background: var(--bg-sunken);
386
+ font-size: 13px;
387
+ line-height: 1.6;
388
+ color: var(--text-secondary);
389
+ }
390
+
391
+ /* ── 状态点 / 徽章 ──────────────────────────────────────────────── */
392
+
393
+ .discuss-dot {
394
+ width: 9px;
395
+ height: 9px;
396
+ flex-shrink: 0;
397
+ border-radius: 50%;
398
+ background: var(--text-tertiary);
399
+ }
400
+
401
+ .discuss-dot.is-running {
402
+ background: var(--accent);
403
+ }
404
+
405
+ .discuss-dot.is-done {
406
+ background: var(--success);
407
+ }
408
+
409
+ .discuss-dot.is-error {
410
+ background: var(--danger);
411
+ }
412
+
413
+ .discuss-dot.is-cancelled {
414
+ background: var(--warning);
415
+ }
416
+
417
+ .discuss-badge {
418
+ display: inline-flex;
419
+ align-items: center;
420
+ height: 20px;
421
+ padding: 0 8px;
422
+ border-radius: var(--radius-chip);
423
+ background: var(--bg-sunken);
424
+ font-size: 11.5px;
425
+ color: var(--text-secondary);
426
+ white-space: nowrap;
427
+ }
428
+
429
+ .discuss-badge.is-running {
430
+ background: var(--accent-soft);
431
+ color: var(--text);
432
+ }
433
+
434
+ .discuss-badge.is-done {
435
+ color: var(--success);
436
+ }
437
+
438
+ .discuss-badge.is-error {
439
+ color: var(--danger);
440
+ }
441
+
442
+ .discuss-badge.is-cancelled {
443
+ color: var(--warning);
444
+ }
445
+
446
+ /* ── 逐条发言流 ─────────────────────────────────────────────────── */
447
+
448
+ .discuss-thread {
449
+ display: flex;
450
+ flex-direction: column;
451
+ gap: 14px;
452
+ }
453
+
454
+ .discuss-msg {
455
+ border: 1px solid var(--border);
456
+ border-radius: var(--radius-card);
457
+ background: var(--bg);
458
+ padding: 14px 16px;
459
+ }
460
+
461
+ .discuss-msg.is-streaming {
462
+ border-color: var(--accent);
463
+ }
464
+
465
+ .discuss-msg.is-failed {
466
+ background: var(--bg-sunken);
467
+ }
468
+
469
+ .discuss-msg-head {
470
+ display: flex;
471
+ align-items: center;
472
+ gap: 10px;
473
+ flex-wrap: wrap;
474
+ margin-bottom: 8px;
475
+ }
476
+
477
+ .discuss-msg-author {
478
+ font-family: var(--font-serif);
479
+ font-size: 14px;
480
+ font-weight: 600;
481
+ color: var(--text);
482
+ }
483
+
484
+ .discuss-msg-round {
485
+ font-family: var(--font-mono);
486
+ font-size: 11.5px;
487
+ color: var(--text-tertiary);
488
+ }
489
+
490
+ .discuss-msg-live {
491
+ display: inline-flex;
492
+ align-items: center;
493
+ height: 18px;
494
+ padding: 0 7px;
495
+ border-radius: var(--radius-chip);
496
+ background: var(--accent-soft);
497
+ font-size: 11px;
498
+ color: var(--text);
499
+ }
500
+
501
+ .discuss-msg-failed {
502
+ display: inline-flex;
503
+ align-items: center;
504
+ height: 18px;
505
+ padding: 0 7px;
506
+ border-radius: var(--radius-chip);
507
+ background: var(--bg-sunken);
508
+ font-size: 11px;
509
+ color: var(--warning);
510
+ }
511
+
512
+ .discuss-msg-body {
513
+ font-size: 14px;
514
+ line-height: 1.7;
515
+ color: var(--text);
516
+ }
517
+
518
+ .discuss-msg-error {
519
+ margin: 0;
520
+ font-size: 13px;
521
+ line-height: 1.6;
522
+ color: var(--danger);
523
+ }
524
+
525
+ .discuss-msg-body.md > * {
526
+ margin: 0 0 10px;
527
+ }
528
+
529
+ .discuss-msg-body.md > *:last-child {
530
+ margin-bottom: 0;
531
+ }
532
+
533
+ /* 流式光标(克制的闪烁点) */
534
+ .discuss-caret {
535
+ display: inline-block;
536
+ width: 7px;
537
+ height: 15px;
538
+ margin-left: 2px;
539
+ vertical-align: text-bottom;
540
+ background: var(--accent);
541
+ border-radius: 1px;
542
+ animation: discuss-caret-blink 1s steps(2, start) infinite;
543
+ }
544
+
545
+ @keyframes discuss-caret-blink {
546
+ to {
547
+ opacity: 0;
548
+ }
549
+ }
550
+
551
+ .discuss-distilled {
552
+ margin: 16px 0 0;
553
+ font-size: 12.5px;
554
+ color: var(--success);
555
+ }
556
+
557
+ /* ── 动效克制(尊重 reduced-motion) ────────────────────────────── */
558
+
559
+ @media (prefers-reduced-motion: reduce) {
560
+ .discuss *,
561
+ .discuss *::before,
562
+ .discuss *::after {
563
+ transition-duration: 0.01ms !important;
564
+ animation-duration: 0.01ms !important;
565
+ }
566
+ }
css/dropzone.css ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 拖文件即问:Warm Paper 拖放蒙层 + 温和说明条(颜色走 theme.css 令牌) */
2
+
3
+ /* 全屏蒙层:半透明暖纸底,覆盖主窗口内容区之上 */
4
+ .dropzone {
5
+ position: fixed;
6
+ inset: 0;
7
+ z-index: 60;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ background: color-mix(in srgb, var(--bg) 82%, transparent);
12
+ backdrop-filter: none; /* WebKit 透明窗口坑:不要用 backdrop-filter(坑位实测记录 #1) */
13
+ animation: dropzone-in 150ms var(--ease);
14
+ }
15
+
16
+ @keyframes dropzone-in {
17
+ from {
18
+ opacity: 0;
19
+ }
20
+ to {
21
+ opacity: 1;
22
+ }
23
+ }
24
+
25
+ .dropzone-card {
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ gap: 16px;
30
+ padding: 48px 64px;
31
+ border: 1px dashed var(--border);
32
+ border-radius: var(--radius-float);
33
+ background: var(--glass);
34
+ box-shadow: var(--shadow-float);
35
+ text-align: center;
36
+ }
37
+
38
+ .dropzone-icon {
39
+ color: var(--accent);
40
+ }
41
+
42
+ .dropzone-title {
43
+ margin: 0;
44
+ font-family: var(--font-serif);
45
+ font-size: 30px;
46
+ font-weight: 600;
47
+ letter-spacing: -0.01em;
48
+ line-height: 1.3;
49
+ color: var(--text);
50
+ }
51
+
52
+ .dropzone-sub {
53
+ margin: 0;
54
+ max-width: 360px;
55
+ font-size: 13.5px;
56
+ line-height: 1.65;
57
+ color: var(--text-secondary);
58
+ }
59
+
60
+ /* 不支持文件时的温和说明条(底部浮出) */
61
+ .dropzone-notice {
62
+ position: fixed;
63
+ left: 50%;
64
+ bottom: 28px;
65
+ z-index: 70;
66
+ transform: translateX(-50%);
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 16px;
70
+ max-width: 560px;
71
+ padding: 12px 16px;
72
+ border: 1px solid var(--border);
73
+ border-radius: var(--radius-card);
74
+ background: var(--bg-elevated);
75
+ box-shadow: var(--shadow-float);
76
+ animation: dropzone-in 150ms var(--ease);
77
+ }
78
+
79
+ .dropzone-notice-text {
80
+ font-size: 13px;
81
+ line-height: 1.6;
82
+ color: var(--text-secondary);
83
+ }
84
+
85
+ .dropzone-notice-close {
86
+ flex-shrink: 0;
87
+ height: 28px;
88
+ padding: 0 12px;
89
+ border: 1px solid var(--border);
90
+ border-radius: var(--radius-control);
91
+ background: transparent;
92
+ color: var(--text-secondary);
93
+ font-family: inherit;
94
+ font-size: 12.5px;
95
+ cursor: pointer;
96
+ transition: background-color var(--dur) var(--ease);
97
+ }
98
+
99
+ .dropzone-notice-close:hover {
100
+ background: var(--bg-sunken);
101
+ color: var(--text);
102
+ }
css/evolution.css ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* RSI 自我进化区(契约 11B-B3)——只用 theme.css 的色彩令牌,不硬编码颜色;
2
+ 风格对齐 Warm Paper(design-system.md):留白优先、克制动效、卡片 1px 描边。 */
3
+
4
+ /* 挂在「常驻助理」区里:视觉上是同一页的第二个子区(分隔线 + 略小的标题) */
5
+ .rsi-section {
6
+ margin-top: 32px;
7
+ padding-top: 24px;
8
+ border-top: 1px solid var(--border);
9
+ }
10
+
11
+ .rsi-section h2 {
12
+ font-size: 18px;
13
+ }
14
+
15
+ .rsi-intro {
16
+ margin: 0 0 20px;
17
+ font-size: 13.5px;
18
+ line-height: 1.7;
19
+ color: var(--text-secondary);
20
+ }
21
+
22
+ .rsi-intro strong {
23
+ color: var(--text);
24
+ font-weight: 600;
25
+ }
26
+
27
+ /* 指令开关的红字说明(契约:这个开关要配红字提醒) */
28
+ .rsi-danger-note {
29
+ color: var(--danger) !important;
30
+ line-height: 1.6;
31
+ }
32
+
33
+ .rsi-select {
34
+ flex-shrink: 0;
35
+ padding: 7px 10px;
36
+ border: 1px solid var(--border);
37
+ border-radius: 10px;
38
+ background: var(--bg-sunken);
39
+ color: var(--text);
40
+ font: inherit;
41
+ font-size: 13px;
42
+ }
43
+
44
+ /* ---------- 一眼状态 ---------- */
45
+ .rsi-status {
46
+ margin-top: 20px;
47
+ padding: 14px 16px;
48
+ border: 1px solid var(--border);
49
+ border-radius: 14px;
50
+ background: var(--bg-elevated);
51
+ }
52
+
53
+ .rsi-status-line {
54
+ display: flex;
55
+ flex-wrap: wrap;
56
+ gap: 6px 18px;
57
+ font-size: 13px;
58
+ color: var(--text-secondary);
59
+ font-variant-numeric: tabular-nums;
60
+ }
61
+
62
+ .rsi-status-line strong {
63
+ color: var(--text);
64
+ }
65
+
66
+ .rsi-gates {
67
+ display: flex;
68
+ flex-wrap: wrap;
69
+ gap: 8px;
70
+ margin: 12px 0 10px;
71
+ }
72
+
73
+ .rsi-gate {
74
+ padding: 3px 10px;
75
+ border: 1px solid var(--border);
76
+ border-radius: 999px;
77
+ font-size: 12px;
78
+ color: var(--text-tertiary);
79
+ background: var(--bg-sunken);
80
+ }
81
+
82
+ .rsi-gate.is-on {
83
+ border-color: var(--success);
84
+ color: var(--success);
85
+ background: transparent;
86
+ }
87
+
88
+ /* ---------- 操作 ---------- */
89
+ .rsi-actions {
90
+ display: flex;
91
+ flex-wrap: wrap;
92
+ gap: 10px;
93
+ margin-top: 18px;
94
+ }
95
+
96
+ .rsi-actions button {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ gap: 6px;
100
+ }
101
+
102
+ /* ---------- 一轮结论 ---------- */
103
+ .rsi-outcome {
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: 4px;
107
+ margin-top: 16px;
108
+ padding: 12px 14px;
109
+ border: 1px solid var(--border);
110
+ border-left-width: 3px;
111
+ border-radius: 10px;
112
+ background: var(--bg-elevated);
113
+ font-size: 13px;
114
+ line-height: 1.6;
115
+ color: var(--text);
116
+ }
117
+
118
+ .rsi-outcome.is-promoted {
119
+ border-left-color: var(--success);
120
+ }
121
+
122
+ .rsi-outcome.is-rejected,
123
+ .rsi-outcome.is-aborted,
124
+ .rsi-outcome.is-disabled {
125
+ border-left-color: var(--danger);
126
+ }
127
+
128
+ .rsi-outcome-kind {
129
+ font-size: 11.5px;
130
+ letter-spacing: 0.06em;
131
+ color: var(--text-tertiary);
132
+ text-transform: uppercase;
133
+ }
134
+
135
+ .rsi-outcome-scores {
136
+ color: var(--text-secondary);
137
+ font-variant-numeric: tabular-nums;
138
+ }
139
+
140
+ /* ---------- 探针得分明细 ---------- */
141
+ .rsi-details {
142
+ margin-top: 20px;
143
+ border-top: 1px solid var(--border);
144
+ padding-top: 14px;
145
+ }
146
+
147
+ .rsi-details h3 {
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 10px;
151
+ margin: 0 0 10px;
152
+ font-family: "Source Serif 4", "Songti SC", Georgia, serif;
153
+ font-size: 15px;
154
+ font-weight: 600;
155
+ color: var(--text);
156
+ }
157
+
158
+ .rsi-probe {
159
+ padding: 10px 12px;
160
+ border: 1px solid var(--border);
161
+ border-radius: 10px;
162
+ background: var(--bg);
163
+ margin-bottom: 8px;
164
+ }
165
+
166
+ .rsi-probe.is-failed {
167
+ border-color: var(--danger);
168
+ }
169
+
170
+ .rsi-probe-head {
171
+ display: flex;
172
+ align-items: center;
173
+ gap: 10px;
174
+ }
175
+
176
+ .rsi-probe-kind {
177
+ font-size: 11.5px;
178
+ color: var(--text-tertiary);
179
+ }
180
+
181
+ .rsi-probe-id {
182
+ font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
183
+ font-size: 12px;
184
+ color: var(--text-secondary);
185
+ }
186
+
187
+ .rsi-probe-verdict {
188
+ margin-left: auto;
189
+ font-size: 12px;
190
+ color: var(--success);
191
+ }
192
+
193
+ .rsi-probe-verdict.is-no {
194
+ color: var(--danger);
195
+ }
196
+
197
+ .rsi-probe-question,
198
+ .rsi-probe-answer {
199
+ margin: 6px 0 0;
200
+ font-size: 12.5px;
201
+ line-height: 1.6;
202
+ }
203
+
204
+ .rsi-probe-question {
205
+ color: var(--text);
206
+ }
207
+
208
+ .rsi-probe-answer {
209
+ color: var(--text-tertiary);
210
+ }
211
+
212
+ /* ---------- 时间线 ---------- */
213
+ .rsi-timeline-title {
214
+ margin: 26px 0 8px;
215
+ font-family: "Source Serif 4", "Songti SC", Georgia, serif;
216
+ font-size: 16px;
217
+ font-weight: 600;
218
+ color: var(--text);
219
+ }
220
+
221
+ .rsi-timeline {
222
+ list-style: none;
223
+ margin: 0;
224
+ padding: 0;
225
+ }
226
+
227
+ .rsi-item {
228
+ position: relative;
229
+ padding: 12px 0 12px 16px;
230
+ border-left: 2px solid var(--border);
231
+ }
232
+
233
+ .rsi-item::before {
234
+ content: "";
235
+ position: absolute;
236
+ left: -5px;
237
+ top: 18px;
238
+ width: 8px;
239
+ height: 8px;
240
+ border-radius: 50%;
241
+ background: var(--text-tertiary);
242
+ }
243
+
244
+ .rsi-item.is-rejected {
245
+ border-left-color: var(--danger);
246
+ }
247
+
248
+ .rsi-item.is-rejected::before {
249
+ background: var(--danger);
250
+ }
251
+
252
+ .rsi-item-head {
253
+ display: flex;
254
+ align-items: center;
255
+ flex-wrap: wrap;
256
+ gap: 8px;
257
+ }
258
+
259
+ .rsi-version {
260
+ font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
261
+ font-size: 13px;
262
+ font-weight: 600;
263
+ color: var(--text);
264
+ }
265
+
266
+ .rsi-version.is-current {
267
+ color: var(--accent);
268
+ }
269
+
270
+ .rsi-version.is-rejected {
271
+ display: inline-flex;
272
+ align-items: center;
273
+ gap: 4px;
274
+ color: var(--danger);
275
+ }
276
+
277
+ .rsi-time {
278
+ font-size: 12px;
279
+ color: var(--text-tertiary);
280
+ font-variant-numeric: tabular-nums;
281
+ }
282
+
283
+ .rsi-badge {
284
+ padding: 1px 8px;
285
+ border: 1px solid var(--accent);
286
+ border-radius: 999px;
287
+ font-size: 11px;
288
+ color: var(--accent);
289
+ }
290
+
291
+ .rsi-badge.is-warn {
292
+ border-color: var(--warning);
293
+ color: var(--warning);
294
+ }
295
+
296
+ .rsi-item-meta {
297
+ display: flex;
298
+ flex-wrap: wrap;
299
+ gap: 6px 14px;
300
+ margin-top: 4px;
301
+ font-size: 12.5px;
302
+ color: var(--text-secondary);
303
+ font-variant-numeric: tabular-nums;
304
+ }
305
+
306
+ .rsi-score.is-up {
307
+ color: var(--success);
308
+ }
309
+
310
+ .rsi-score.is-down {
311
+ color: var(--danger);
312
+ }
313
+
314
+ .rsi-score.is-pending {
315
+ color: var(--text-tertiary);
316
+ }
317
+
318
+ .rsi-source {
319
+ margin: 6px 0 0;
320
+ font-size: 12px;
321
+ line-height: 1.6;
322
+ color: var(--text-tertiary);
323
+ }
324
+
325
+ .rsi-reject-reason {
326
+ margin: 6px 0 0;
327
+ font-size: 13px;
328
+ line-height: 1.6;
329
+ color: var(--danger);
330
+ }
331
+
332
+ /* 经验卡折叠列表 */
333
+ .rsi-cards {
334
+ margin-top: 8px;
335
+ font-size: 12.5px;
336
+ }
337
+
338
+ .rsi-cards summary {
339
+ cursor: pointer;
340
+ color: var(--text-secondary);
341
+ }
342
+
343
+ .rsi-cards ul {
344
+ list-style: none;
345
+ margin: 8px 0 0;
346
+ padding: 0;
347
+ }
348
+
349
+ .rsi-cards li {
350
+ padding: 8px 10px;
351
+ margin-bottom: 6px;
352
+ border: 1px solid var(--border);
353
+ border-radius: 10px;
354
+ background: var(--bg-sunken);
355
+ line-height: 1.6;
356
+ color: var(--text-secondary);
357
+ }
358
+
359
+ .rsi-cards strong {
360
+ color: var(--text);
361
+ font-weight: 600;
362
+ }
363
+
364
+ @media (prefers-reduced-motion: reduce) {
365
+ .rsi-outcome,
366
+ .rsi-item,
367
+ .rsi-probe {
368
+ transition: none !important;
369
+ }
370
+ }
css/expedition.css ADDED
@@ -0,0 +1,613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 知识远征(契约 23A P3 · 工作台第四 tab「远征」)——Warm Paper 令牌,
2
+ 零硬编码色:所有颜色走 theme.css 变量(深浅色自动跟随)。
3
+ 布局沿用 .bench / .kb 的整页滚动容器(flex:1 + 独立滚动 + 48px 留白)。 */
4
+
5
+ .xp {
6
+ flex: 1;
7
+ min-width: 0;
8
+ overflow-y: auto;
9
+ padding: 36px 48px 48px;
10
+ }
11
+
12
+ /* ── 页头 ───────────────────────────────────────────────────────── */
13
+
14
+ .xp-head {
15
+ display: flex;
16
+ align-items: flex-end;
17
+ justify-content: space-between;
18
+ gap: 16px;
19
+ margin-bottom: 24px;
20
+ }
21
+
22
+ .xp-title {
23
+ font-family: var(--font-serif);
24
+ font-size: 26px;
25
+ font-weight: 600;
26
+ letter-spacing: -0.01em;
27
+ color: var(--text);
28
+ margin: 0;
29
+ }
30
+
31
+ .xp-head-sub {
32
+ margin: 6px 0 0;
33
+ font-size: 13.5px;
34
+ line-height: 1.6;
35
+ color: var(--text-secondary);
36
+ max-width: 60ch;
37
+ }
38
+
39
+ .xp-notice {
40
+ margin: 0 0 16px;
41
+ padding: 10px 14px;
42
+ border: 1px solid var(--border);
43
+ border-radius: var(--radius-control);
44
+ background: var(--bg-elevated);
45
+ font-size: 13.5px;
46
+ line-height: 1.6;
47
+ color: var(--text);
48
+ }
49
+
50
+ .xp-notice.is-danger {
51
+ border-color: var(--danger);
52
+ }
53
+
54
+ /* ── 卡片(上块 Deep Research / 下块 订阅监控)─────────────────── */
55
+
56
+ .xp-card {
57
+ background: var(--bg-elevated);
58
+ border: 1px solid var(--border);
59
+ border-radius: var(--radius-card);
60
+ padding: 22px 24px;
61
+ margin-bottom: 28px;
62
+ }
63
+
64
+ .xp-card-head {
65
+ display: flex;
66
+ align-items: baseline;
67
+ justify-content: space-between;
68
+ gap: 16px;
69
+ margin-bottom: 16px;
70
+ }
71
+
72
+ .xp-card-title {
73
+ font-family: var(--font-serif);
74
+ font-size: 18px;
75
+ font-weight: 600;
76
+ color: var(--text);
77
+ margin: 0;
78
+ }
79
+
80
+ .xp-card-hint {
81
+ font-size: 12.5px;
82
+ line-height: 1.6;
83
+ color: var(--text-secondary);
84
+ }
85
+
86
+ /* ── 表单 ───────────────────────────────────────────────────────── */
87
+
88
+ .xp-form {
89
+ display: flex;
90
+ flex-wrap: wrap;
91
+ gap: 10px;
92
+ align-items: center;
93
+ }
94
+
95
+ .xp-input,
96
+ .xp-select {
97
+ font-family: var(--font-sans);
98
+ font-size: 14px;
99
+ line-height: 1.65;
100
+ color: var(--text);
101
+ background: var(--bg-sunken);
102
+ border: 1px solid transparent;
103
+ border-radius: var(--radius-control);
104
+ padding: 9px 12px;
105
+ transition: border-color var(--dur) var(--ease);
106
+ }
107
+
108
+ .xp-input {
109
+ flex: 1;
110
+ min-width: 260px;
111
+ }
112
+
113
+ .xp-input::placeholder {
114
+ color: var(--text-tertiary);
115
+ }
116
+
117
+ .xp-input:focus-visible,
118
+ .xp-select:focus-visible {
119
+ outline: none;
120
+ border-color: var(--accent);
121
+ }
122
+
123
+ .xp-select {
124
+ max-width: 260px;
125
+ }
126
+
127
+ /* ── 按钮 ───────────────────────────────────────────────────────── */
128
+
129
+ .xp-btn {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ gap: 6px;
133
+ height: 36px;
134
+ padding: 0 14px;
135
+ border: 1px solid var(--border);
136
+ border-radius: var(--radius-control);
137
+ background: transparent;
138
+ color: var(--text);
139
+ font-family: inherit;
140
+ font-size: 13.5px;
141
+ cursor: pointer;
142
+ transition:
143
+ background-color var(--dur) var(--ease),
144
+ border-color var(--dur) var(--ease),
145
+ color var(--dur) var(--ease);
146
+ }
147
+
148
+ .xp-btn:hover:not(:disabled) {
149
+ background: var(--bg);
150
+ }
151
+
152
+ .xp-btn:disabled {
153
+ opacity: 0.55;
154
+ cursor: default;
155
+ }
156
+
157
+ .xp-btn:focus-visible {
158
+ outline: 2px solid var(--accent);
159
+ outline-offset: 2px;
160
+ }
161
+
162
+ .xp-btn-primary {
163
+ border-color: transparent;
164
+ background: var(--accent);
165
+ color: var(--bg);
166
+ font-weight: 600;
167
+ }
168
+
169
+ .xp-btn-primary:hover:not(:disabled) {
170
+ filter: brightness(0.94);
171
+ background: var(--accent);
172
+ }
173
+
174
+ .xp-btn-quiet {
175
+ border-color: transparent;
176
+ color: var(--text-secondary);
177
+ }
178
+
179
+ .xp-btn-quiet:hover:not(:disabled) {
180
+ background: var(--accent-soft);
181
+ color: var(--text);
182
+ }
183
+
184
+ .xp-icon-btn {
185
+ display: inline-flex;
186
+ align-items: center;
187
+ justify-content: center;
188
+ width: 28px;
189
+ height: 28px;
190
+ border: none;
191
+ border-radius: var(--radius-control);
192
+ background: transparent;
193
+ color: var(--text-secondary);
194
+ cursor: pointer;
195
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
196
+ }
197
+
198
+ .xp-icon-btn:hover {
199
+ background: var(--accent-soft);
200
+ color: var(--text);
201
+ }
202
+
203
+ .xp-icon-btn:focus-visible {
204
+ outline: 2px solid var(--accent);
205
+ outline-offset: 2px;
206
+ }
207
+
208
+ /* ── 进度 ───────────────────────────────────────────────────────── */
209
+
210
+ .xp-progress {
211
+ margin-top: 16px;
212
+ padding: 14px 16px;
213
+ border: 1px solid var(--border);
214
+ border-radius: var(--radius-control);
215
+ background: var(--bg);
216
+ }
217
+
218
+ .xp-progress-step {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 8px;
222
+ font-size: 13.5px;
223
+ line-height: 1.6;
224
+ color: var(--text);
225
+ word-break: break-all;
226
+ }
227
+
228
+ .xp-progress-meta {
229
+ display: flex;
230
+ flex-wrap: wrap;
231
+ gap: 14px;
232
+ margin-top: 8px;
233
+ font-size: 12px;
234
+ color: var(--text-secondary);
235
+ font-variant-numeric: tabular-nums;
236
+ }
237
+
238
+ .xp-bar {
239
+ height: 6px;
240
+ border-radius: var(--radius-chip);
241
+ background: var(--bg-sunken);
242
+ overflow: hidden;
243
+ margin-top: 12px;
244
+ }
245
+
246
+ .xp-bar-fill {
247
+ height: 100%;
248
+ background: var(--accent);
249
+ border-radius: var(--radius-chip);
250
+ transition: width var(--dur) var(--ease);
251
+ }
252
+
253
+ .xp-phase-dot {
254
+ width: 8px;
255
+ height: 8px;
256
+ border-radius: 50%;
257
+ background: var(--accent);
258
+ flex-shrink: 0;
259
+ }
260
+
261
+ /* ── 报告 ───────────────────────────────────────────────────────── */
262
+
263
+ .xp-report {
264
+ margin-top: 18px;
265
+ padding-top: 18px;
266
+ border-top: 1px solid var(--border);
267
+ }
268
+
269
+ .xp-report-head {
270
+ display: flex;
271
+ flex-wrap: wrap;
272
+ align-items: center;
273
+ justify-content: space-between;
274
+ gap: 10px;
275
+ margin-bottom: 14px;
276
+ }
277
+
278
+ .xp-report-stats {
279
+ font-size: 12.5px;
280
+ color: var(--text-secondary);
281
+ font-variant-numeric: tabular-nums;
282
+ }
283
+
284
+ .xp-report-actions {
285
+ display: flex;
286
+ flex-wrap: wrap;
287
+ gap: 8px;
288
+ }
289
+
290
+ .xp-sources {
291
+ margin: 18px 0 0;
292
+ padding: 14px 16px;
293
+ border: 1px solid var(--border);
294
+ border-radius: var(--radius-control);
295
+ background: var(--bg);
296
+ }
297
+
298
+ .xp-sources-title {
299
+ font-family: var(--font-serif);
300
+ font-size: 14px;
301
+ font-weight: 600;
302
+ color: var(--text);
303
+ margin: 0 0 10px;
304
+ }
305
+
306
+ .xp-source-list {
307
+ margin: 0;
308
+ padding-left: 18px;
309
+ display: flex;
310
+ flex-direction: column;
311
+ gap: 6px;
312
+ }
313
+
314
+ .xp-source-list li {
315
+ font-size: 13px;
316
+ line-height: 1.6;
317
+ color: var(--text-secondary);
318
+ }
319
+
320
+ .xp-source-list a {
321
+ color: var(--text);
322
+ text-decoration: underline;
323
+ text-underline-offset: 2px;
324
+ word-break: break-all;
325
+ }
326
+
327
+ .xp-source-time {
328
+ color: var(--text-tertiary);
329
+ font-variant-numeric: tabular-nums;
330
+ }
331
+
332
+ /* ── 历史报告 ───────────────────────────────────────────────────── */
333
+
334
+ .xp-history {
335
+ margin-top: 20px;
336
+ padding-top: 16px;
337
+ border-top: 1px solid var(--border);
338
+ }
339
+
340
+ .xp-history-title {
341
+ font-family: var(--font-serif);
342
+ font-size: 14px;
343
+ font-weight: 600;
344
+ color: var(--text);
345
+ margin: 0 0 8px;
346
+ }
347
+
348
+ .xp-history-list {
349
+ list-style: none;
350
+ margin: 0;
351
+ padding: 0;
352
+ }
353
+
354
+ .xp-history-item {
355
+ display: flex;
356
+ align-items: center;
357
+ gap: 12px;
358
+ width: 100%;
359
+ padding: 10px 8px;
360
+ border: none;
361
+ border-bottom: 1px solid var(--border);
362
+ background: transparent;
363
+ color: inherit;
364
+ font-family: inherit;
365
+ font-size: 13.5px;
366
+ text-align: left;
367
+ cursor: pointer;
368
+ transition: background-color var(--dur) var(--ease);
369
+ }
370
+
371
+ .xp-history-item:last-child {
372
+ border-bottom: none;
373
+ }
374
+
375
+ .xp-history-item:hover {
376
+ background: var(--accent-soft);
377
+ }
378
+
379
+ .xp-history-item:focus-visible {
380
+ outline: 2px solid var(--accent);
381
+ outline-offset: -2px;
382
+ }
383
+
384
+ .xp-history-topic {
385
+ flex: 1;
386
+ min-width: 0;
387
+ overflow: hidden;
388
+ text-overflow: ellipsis;
389
+ white-space: nowrap;
390
+ color: var(--text);
391
+ }
392
+
393
+ .xp-history-meta {
394
+ flex-shrink: 0;
395
+ font-size: 12px;
396
+ color: var(--text-secondary);
397
+ font-variant-numeric: tabular-nums;
398
+ }
399
+
400
+ /* ── 空状态 ─────────────────────────────────────────────────────── */
401
+
402
+ .xp-empty {
403
+ padding: 22px 4px;
404
+ font-family: var(--font-serif);
405
+ font-size: 15px;
406
+ line-height: 1.7;
407
+ color: var(--text-secondary);
408
+ }
409
+
410
+ /* ── 订阅列表 ───────────────────────────────────────────────────── */
411
+
412
+ .xp-subs {
413
+ list-style: none;
414
+ margin: 16px 0 0;
415
+ padding: 0;
416
+ border-top: 1px solid var(--border);
417
+ }
418
+
419
+ .xp-sub {
420
+ border-bottom: 1px solid var(--border);
421
+ }
422
+
423
+ .xp-sub-row {
424
+ display: flex;
425
+ align-items: center;
426
+ gap: 12px;
427
+ padding: 12px 4px;
428
+ }
429
+
430
+ .xp-sub.is-changed .xp-sub-name {
431
+ color: var(--accent);
432
+ font-weight: 600;
433
+ }
434
+
435
+ .xp-sub-main {
436
+ flex: 1;
437
+ min-width: 0;
438
+ }
439
+
440
+ .xp-sub-name {
441
+ display: flex;
442
+ align-items: center;
443
+ gap: 8px;
444
+ font-family: var(--font-serif);
445
+ font-size: 14.5px;
446
+ font-weight: 600;
447
+ color: var(--text);
448
+ }
449
+
450
+ .xp-sub-url {
451
+ display: block;
452
+ margin-top: 2px;
453
+ font-size: 12px;
454
+ color: var(--text-tertiary);
455
+ overflow: hidden;
456
+ text-overflow: ellipsis;
457
+ white-space: nowrap;
458
+ }
459
+
460
+ .xp-sub-meta {
461
+ display: flex;
462
+ flex-wrap: wrap;
463
+ gap: 12px;
464
+ margin-top: 5px;
465
+ font-size: 12px;
466
+ color: var(--text-secondary);
467
+ font-variant-numeric: tabular-nums;
468
+ }
469
+
470
+ .xp-badge {
471
+ display: inline-flex;
472
+ align-items: center;
473
+ height: 20px;
474
+ padding: 0 7px;
475
+ border-radius: var(--radius-chip);
476
+ background: var(--bg-sunken);
477
+ color: var(--text-secondary);
478
+ font-size: 11px;
479
+ font-weight: 500;
480
+ font-family: var(--font-sans);
481
+ white-space: nowrap;
482
+ }
483
+
484
+ .xp-badge.is-changed {
485
+ background: var(--accent-soft);
486
+ color: var(--text);
487
+ }
488
+
489
+ .xp-badge.is-error {
490
+ background: var(--bg-sunken);
491
+ color: var(--danger);
492
+ }
493
+
494
+ .xp-sub-actions {
495
+ display: flex;
496
+ align-items: center;
497
+ gap: 6px;
498
+ flex-shrink: 0;
499
+ }
500
+
501
+ /* 启停开关(沿用 bench-switch 的形制,颜色全走令牌) */
502
+ .xp-switch {
503
+ position: relative;
504
+ width: 42px;
505
+ height: 24px;
506
+ flex-shrink: 0;
507
+ border: 1px solid var(--border);
508
+ border-radius: var(--radius-chip);
509
+ background: var(--bg-sunken);
510
+ cursor: pointer;
511
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
512
+ }
513
+
514
+ .xp-switch.is-on {
515
+ background: var(--accent);
516
+ border-color: var(--accent);
517
+ }
518
+
519
+ .xp-switch::after {
520
+ content: "";
521
+ position: absolute;
522
+ top: 2px;
523
+ left: 2px;
524
+ width: 18px;
525
+ height: 18px;
526
+ border-radius: 50%;
527
+ background: var(--bg);
528
+ transition: transform var(--dur) var(--ease);
529
+ }
530
+
531
+ .xp-switch.is-on::after {
532
+ transform: translateX(18px);
533
+ }
534
+
535
+ .xp-switch:focus-visible {
536
+ outline: 2px solid var(--accent);
537
+ outline-offset: 2px;
538
+ }
539
+
540
+ /* ── 变化历史(点开展开)───────────────────────────────────────── */
541
+
542
+ .xp-history-panel {
543
+ padding: 4px 4px 14px;
544
+ display: flex;
545
+ flex-direction: column;
546
+ gap: 10px;
547
+ }
548
+
549
+ .xp-change {
550
+ padding: 10px 12px;
551
+ border: 1px solid var(--border);
552
+ border-radius: var(--radius-control);
553
+ background: var(--bg);
554
+ }
555
+
556
+ .xp-change-head {
557
+ display: flex;
558
+ flex-wrap: wrap;
559
+ align-items: center;
560
+ gap: 10px;
561
+ font-size: 12px;
562
+ color: var(--text-secondary);
563
+ font-variant-numeric: tabular-nums;
564
+ }
565
+
566
+ .xp-change-body {
567
+ margin: 8px 0 0;
568
+ font-family: var(--font-mono);
569
+ font-size: 12.5px;
570
+ line-height: 1.6;
571
+ color: var(--text);
572
+ white-space: pre-wrap;
573
+ word-break: break-word;
574
+ }
575
+
576
+ .xp-change-none {
577
+ font-size: 13px;
578
+ color: var(--text-secondary);
579
+ padding: 8px 4px;
580
+ }
581
+
582
+ /* ── 小工具 ─────────────────────────────────────────────────────── */
583
+
584
+ .xp-inline-form {
585
+ display: flex;
586
+ flex-wrap: wrap;
587
+ gap: 10px;
588
+ align-items: flex-end;
589
+ padding-bottom: 4px;
590
+ }
591
+
592
+ .xp-field {
593
+ display: flex;
594
+ flex-direction: column;
595
+ gap: 6px;
596
+ min-width: 0;
597
+ }
598
+
599
+ .xp-field.grow {
600
+ flex: 1;
601
+ min-width: 240px;
602
+ }
603
+
604
+ .xp-field-label {
605
+ font-size: 12.5px;
606
+ color: var(--text-secondary);
607
+ }
608
+
609
+ .xp-muted {
610
+ font-size: 12.5px;
611
+ line-height: 1.6;
612
+ color: var(--text-secondary);
613
+ }
css/flow.css ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 栖木流(契约 25B · 工作台第五 tab「流」)——Warm Paper 令牌,零硬编码色:
2
+ 所有颜色走 theme.css 变量(深浅色自动跟随)。
3
+ 布局沿用 .xp / .bench 整页滚动容器(flex:1 + 独立滚动 + 48px 留白)。 */
4
+
5
+ .flow {
6
+ flex: 1;
7
+ min-width: 0;
8
+ overflow-y: auto;
9
+ padding: 36px 48px 48px;
10
+ }
11
+
12
+ /* ── 页头 ───────────────────────────────────────────────────────── */
13
+
14
+ .flow-head {
15
+ display: flex;
16
+ align-items: flex-end;
17
+ justify-content: space-between;
18
+ gap: 16px;
19
+ margin-bottom: 24px;
20
+ }
21
+
22
+ .flow-title {
23
+ font-family: var(--font-serif);
24
+ font-size: 26px;
25
+ font-weight: 600;
26
+ letter-spacing: -0.01em;
27
+ color: var(--text);
28
+ margin: 0;
29
+ }
30
+
31
+ .flow-head-sub {
32
+ margin: 6px 0 0;
33
+ font-size: 13.5px;
34
+ line-height: 1.6;
35
+ color: var(--text-secondary);
36
+ max-width: 62ch;
37
+ }
38
+
39
+ /* ── 流卡片列表 ─────────────────────────────────────────────────── */
40
+
41
+ .flow-list {
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: 12px;
45
+ }
46
+
47
+ .flow-item {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 14px;
51
+ padding: 14px 18px;
52
+ background: var(--bg-elevated);
53
+ border: 1px solid var(--border);
54
+ border-radius: var(--radius-card);
55
+ transition: border-color 150ms ease;
56
+ }
57
+
58
+ .flow-item:hover {
59
+ border-color: var(--border-strong);
60
+ }
61
+
62
+ .flow-item-main {
63
+ flex: 1;
64
+ min-width: 0;
65
+ cursor: pointer;
66
+ }
67
+
68
+ .flow-item-name {
69
+ font-size: 15px;
70
+ font-weight: 600;
71
+ color: var(--text);
72
+ margin: 0;
73
+ }
74
+
75
+ .flow-item-meta {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 10px;
79
+ flex-wrap: wrap;
80
+ margin-top: 4px;
81
+ font-size: 12.5px;
82
+ color: var(--text-secondary);
83
+ }
84
+
85
+ .flow-badge {
86
+ display: inline-flex;
87
+ align-items: center;
88
+ gap: 5px;
89
+ padding: 2px 8px;
90
+ border-radius: 999px;
91
+ border: 1px solid var(--border);
92
+ font-size: 11.5px;
93
+ color: var(--text-secondary);
94
+ background: var(--bg);
95
+ white-space: nowrap;
96
+ }
97
+
98
+ .flow-badge.is-on {
99
+ color: var(--accent);
100
+ border-color: var(--accent-soft, var(--accent));
101
+ }
102
+
103
+ .flow-status-dot {
104
+ width: 7px;
105
+ height: 7px;
106
+ border-radius: 50%;
107
+ background: var(--text-tertiary);
108
+ flex: none;
109
+ }
110
+
111
+ .flow-status-dot.is-done {
112
+ background: var(--success);
113
+ }
114
+
115
+ .flow-status-dot.is-error {
116
+ background: var(--danger);
117
+ }
118
+
119
+ .flow-status-dot.is-running {
120
+ background: var(--warning);
121
+ animation: flow-pulse 1.2s ease-in-out infinite;
122
+ }
123
+
124
+ @keyframes flow-pulse {
125
+ 0%,
126
+ 100% {
127
+ opacity: 1;
128
+ }
129
+ 50% {
130
+ opacity: 0.35;
131
+ }
132
+ }
133
+
134
+ /* ── 按钮 ───────────────────────────────────────────────────────── */
135
+
136
+ .flow-actions {
137
+ display: flex;
138
+ align-items: center;
139
+ gap: 8px;
140
+ flex: none;
141
+ }
142
+
143
+ .flow-btn {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ gap: 6px;
147
+ padding: 7px 14px;
148
+ border-radius: var(--radius-control);
149
+ border: 1px solid var(--border);
150
+ background: var(--bg);
151
+ color: var(--text);
152
+ font-size: 13px;
153
+ cursor: pointer;
154
+ transition:
155
+ border-color 150ms ease,
156
+ background 150ms ease;
157
+ }
158
+
159
+ .flow-btn:hover {
160
+ border-color: var(--border-strong);
161
+ }
162
+
163
+ .flow-btn.is-primary {
164
+ border-color: var(--accent);
165
+ color: var(--accent);
166
+ }
167
+
168
+ .flow-btn.is-primary:hover {
169
+ background: var(--accent-soft, transparent);
170
+ }
171
+
172
+ .flow-btn.is-ghost {
173
+ border-color: transparent;
174
+ color: var(--text-secondary);
175
+ }
176
+
177
+ .flow-btn:disabled {
178
+ opacity: 0.45;
179
+ cursor: not-allowed;
180
+ }
181
+
182
+ .flow-icon-btn {
183
+ display: inline-flex;
184
+ align-items: center;
185
+ justify-content: center;
186
+ width: 30px;
187
+ height: 30px;
188
+ border-radius: var(--radius-control);
189
+ border: 1px solid transparent;
190
+ background: transparent;
191
+ color: var(--text-secondary);
192
+ cursor: pointer;
193
+ transition:
194
+ color 150ms ease,
195
+ border-color 150ms ease;
196
+ }
197
+
198
+ .flow-icon-btn:hover {
199
+ color: var(--text);
200
+ border-color: var(--border);
201
+ }
202
+
203
+ .flow-icon-btn.is-danger:hover {
204
+ color: var(--danger);
205
+ border-color: var(--danger);
206
+ }
207
+
208
+ /* ── 开关(沿用设置中心的形状语言)──────────────────────────────── */
209
+
210
+ .flow-switch {
211
+ position: relative;
212
+ width: 38px;
213
+ height: 22px;
214
+ border-radius: 999px;
215
+ border: 1px solid var(--border);
216
+ background: var(--bg);
217
+ cursor: pointer;
218
+ flex: none;
219
+ transition: background 150ms ease;
220
+ padding: 0;
221
+ }
222
+
223
+ .flow-switch::after {
224
+ content: "";
225
+ position: absolute;
226
+ top: 2px;
227
+ left: 2px;
228
+ width: 16px;
229
+ height: 16px;
230
+ border-radius: 50%;
231
+ background: var(--text-secondary);
232
+ transition:
233
+ transform 150ms ease,
234
+ background 150ms ease;
235
+ }
236
+
237
+ .flow-switch.is-on {
238
+ background: var(--accent);
239
+ border-color: var(--accent);
240
+ }
241
+
242
+ .flow-switch.is-on::after {
243
+ transform: translateX(16px);
244
+ background: var(--bg-elevated);
245
+ }
246
+
247
+ /* ── 编辑器 ─────────────────────────────────────────────────────── */
248
+
249
+ .flow-editor {
250
+ max-width: 760px;
251
+ }
252
+
253
+ .flow-field {
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: 6px;
257
+ margin-bottom: 18px;
258
+ }
259
+
260
+ .flow-label {
261
+ font-size: 12.5px;
262
+ font-weight: 600;
263
+ color: var(--text-secondary);
264
+ }
265
+
266
+ .flow-input,
267
+ .flow-select,
268
+ .flow-textarea {
269
+ padding: 9px 12px;
270
+ border-radius: var(--radius-control);
271
+ border: 1px solid var(--border);
272
+ background: var(--bg-elevated);
273
+ color: var(--text);
274
+ font-size: 13.5px;
275
+ font-family: inherit;
276
+ outline: none;
277
+ transition: border-color 150ms ease;
278
+ }
279
+
280
+ .flow-input:focus,
281
+ .flow-select:focus,
282
+ .flow-textarea:focus {
283
+ border-color: var(--accent);
284
+ }
285
+
286
+ .flow-textarea {
287
+ min-height: 72px;
288
+ resize: vertical;
289
+ line-height: 1.6;
290
+ }
291
+
292
+ .flow-inline-row {
293
+ display: flex;
294
+ gap: 8px;
295
+ align-items: center;
296
+ }
297
+
298
+ .flow-inline-row > .flow-input {
299
+ flex: 1;
300
+ }
301
+
302
+ .flow-hint {
303
+ font-size: 12px;
304
+ line-height: 1.6;
305
+ color: var(--text-tertiary);
306
+ }
307
+
308
+ /* ── 步骤列表(列表式编辑:不炫技的排序 + 参数行)────────────── */
309
+
310
+ .flow-steps {
311
+ display: flex;
312
+ flex-direction: column;
313
+ gap: 10px;
314
+ margin-bottom: 18px;
315
+ }
316
+
317
+ .flow-step {
318
+ display: flex;
319
+ gap: 12px;
320
+ padding: 14px 16px;
321
+ background: var(--bg-elevated);
322
+ border: 1px solid var(--border);
323
+ border-radius: var(--radius-card);
324
+ }
325
+
326
+ .flow-step-no {
327
+ width: 26px;
328
+ height: 26px;
329
+ border-radius: 50%;
330
+ border: 1px solid var(--border);
331
+ display: flex;
332
+ align-items: center;
333
+ justify-content: center;
334
+ font-size: 12px;
335
+ color: var(--text-secondary);
336
+ flex: none;
337
+ margin-top: 2px;
338
+ }
339
+
340
+ .flow-step-body {
341
+ flex: 1;
342
+ min-width: 0;
343
+ display: flex;
344
+ flex-direction: column;
345
+ gap: 8px;
346
+ }
347
+
348
+ .flow-step-kind {
349
+ display: flex;
350
+ align-items: center;
351
+ gap: 8px;
352
+ font-size: 13px;
353
+ font-weight: 600;
354
+ color: var(--text);
355
+ }
356
+
357
+ .flow-step-ops {
358
+ display: flex;
359
+ flex-direction: column;
360
+ gap: 4px;
361
+ flex: none;
362
+ }
363
+
364
+ /* ── 模板选择 ───────────────────────────────────────────────────── */
365
+
366
+ .flow-templates {
367
+ display: grid;
368
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
369
+ gap: 12px;
370
+ margin-bottom: 20px;
371
+ }
372
+
373
+ .flow-template {
374
+ display: flex;
375
+ flex-direction: column;
376
+ gap: 6px;
377
+ padding: 16px;
378
+ text-align: left;
379
+ background: var(--bg-elevated);
380
+ border: 1px solid var(--border);
381
+ border-radius: var(--radius-card);
382
+ cursor: pointer;
383
+ transition: border-color 150ms ease;
384
+ }
385
+
386
+ .flow-template:hover {
387
+ border-color: var(--accent);
388
+ }
389
+
390
+ .flow-template-name {
391
+ font-size: 14px;
392
+ font-weight: 600;
393
+ color: var(--text);
394
+ }
395
+
396
+ .flow-template-desc {
397
+ font-size: 12.5px;
398
+ line-height: 1.6;
399
+ color: var(--text-secondary);
400
+ }
401
+
402
+ /* ── 运行记录 ───────────────────────────────────────────────────── */
403
+
404
+ .flow-runs {
405
+ display: flex;
406
+ flex-direction: column;
407
+ gap: 8px;
408
+ }
409
+
410
+ .flow-run {
411
+ padding: 12px 16px;
412
+ background: var(--bg-elevated);
413
+ border: 1px solid var(--border);
414
+ border-radius: var(--radius-card);
415
+ cursor: pointer;
416
+ }
417
+
418
+ .flow-run:hover {
419
+ border-color: var(--border-strong);
420
+ }
421
+
422
+ .flow-run-head {
423
+ display: flex;
424
+ align-items: center;
425
+ gap: 10px;
426
+ font-size: 13px;
427
+ color: var(--text);
428
+ }
429
+
430
+ .flow-run-steps {
431
+ display: flex;
432
+ flex-direction: column;
433
+ gap: 6px;
434
+ margin-top: 10px;
435
+ }
436
+
437
+ .flow-run-step {
438
+ display: flex;
439
+ align-items: flex-start;
440
+ gap: 10px;
441
+ padding: 10px 12px;
442
+ border: 1px solid var(--border);
443
+ border-radius: var(--radius-control);
444
+ background: var(--bg);
445
+ font-size: 12.5px;
446
+ color: var(--text);
447
+ }
448
+
449
+ .flow-run-step-kind {
450
+ font-weight: 600;
451
+ white-space: nowrap;
452
+ color: var(--text-secondary);
453
+ flex: none;
454
+ }
455
+
456
+ .flow-run-step-output {
457
+ flex: 1;
458
+ min-width: 0;
459
+ white-space: pre-wrap;
460
+ word-break: break-word;
461
+ line-height: 1.55;
462
+ color: var(--text);
463
+ /* 耗时毫秒等数字等宽:跳动不抖行(细节质感) */
464
+ font-variant-numeric: tabular-nums;
465
+ }
466
+
467
+ .flow-run-step-output.is-error {
468
+ color: var(--danger);
469
+ }
470
+
471
+ .flow-run-step-output.is-skipped {
472
+ color: var(--text-tertiary);
473
+ }
474
+
475
+ .flow-empty {
476
+ padding: 36px 0;
477
+ text-align: center;
478
+ color: var(--text-tertiary);
479
+ font-size: 13.5px;
480
+ line-height: 1.8;
481
+ }
css/gemini.css ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ═══════════════════════════════════════════════════════════════════
2
+ Gemini 皮肤 · 组件层(dev-duotheme 双外观,Warm Paper 零改动)
3
+
4
+ 纪律(完工自检 grep):
5
+ - 本文件不出现 width / height / left / top / position ——
6
+ 只改颜色、字体、圆角、阴影、hover 这类「皮」;布局、间距、
7
+ 宽高、位置、tab 结构一律不动(避免与 dev-composer-ui 打架)。
8
+ - 每条覆盖规则都以 [data-style="gemini"] 打头 → Warm Paper 完全不受影响。
9
+ - 签名渐变(--grad-start/mid/end 蓝→紫→粉)只允许三处:
10
+ ① 品牌标方标 ② 欢迎页大标题高光 ③ Ultra 档强调。
11
+ 其余全靠黑白灰 + Google Blue 单主色(彩色 = 点缀,不铺满)。
12
+ - 设置页「风格」预览卡是新控件:其排版样式走 Settings.tsx 内联
13
+ 样式(本文件保持「纯覆盖」),不新增任何组件 css 文件改动。
14
+
15
+ 大量视觉其实由 theme.css 的 [data-style="gemini"] 令牌自动换血
16
+ (导航激活浅蓝 #e8f0fe + Google Blue 竖条、焦点环、滚动条、选区、
17
+ 分段控件蓝底白字、卡片灰边……),本文件只补「换骨」的几处。
18
+ ═══════════════════════════════════════════════════════════════ */
19
+
20
+ /* ── ① 品牌标:签名渐变方标 + 白色线稿(渐变位 1/3) ───────────── */
21
+ [data-style="gemini"] .brand-mark {
22
+ background: linear-gradient(
23
+ 135deg,
24
+ var(--grad-start) 0%,
25
+ var(--grad-mid) 55%,
26
+ var(--grad-end) 100%
27
+ );
28
+ border-radius: 9px; /* 紧贴 26px 图形的圆角方标(不动其尺寸) */
29
+ color: #ffffff; /* BrandMark 走 currentColor 描边 → 白线 */
30
+ }
31
+
32
+ [data-style="gemini"] .brand-name {
33
+ font-weight: 500; /* Material 标题档 500,撤掉书卷气 600 */
34
+ }
35
+
36
+ /* ── 标题字重:Material/Gemini 标题 400~500,不用衬线粗体气质 ──── */
37
+ [data-style="gemini"] h1,
38
+ [data-style="gemini"] h2,
39
+ [data-style="gemini"] h3 {
40
+ font-weight: 500;
41
+ }
42
+
43
+ [data-style="gemini"] .hub-tab.is-active,
44
+ [data-style="gemini"] .pref-subhead {
45
+ font-weight: 500;
46
+ }
47
+
48
+ /* ── 按钮:pill 化(Google 主行动全圆角) + 蓝色态 ─────────────── */
49
+ [data-style="gemini"] .btn-primary,
50
+ [data-style="gemini"] .btn-secondary,
51
+ [data-style="gemini"] .btn-send,
52
+ [data-style="gemini"] .btn-stop,
53
+ [data-style="gemini"] .conv-new,
54
+ [data-style="gemini"] .icon-btn {
55
+ border-radius: 999px;
56
+ }
57
+
58
+ /* 主按钮 hover:Google 蓝变体(浅色 = Blue 700 加深,深色 = 加亮);
59
+ 令牌切换后两套深浅色自动各取各的 --accent-hover。 */
60
+ [data-style="gemini"] .btn-primary:hover,
61
+ [data-style="gemini"] .btn-send:hover:not(:disabled) {
62
+ background: var(--accent-hover);
63
+ }
64
+
65
+ /* 次按钮:浅灰底(elevated),hover 落到 sunken——中性灰,不用暖调 */
66
+ [data-style="gemini"] .btn-secondary {
67
+ background: var(--bg-elevated);
68
+ }
69
+
70
+ [data-style="gemini"] .btn-secondary:hover,
71
+ [data-style="gemini"] .btn-stop:hover,
72
+ [data-style="gemini"] .conv-new:hover {
73
+ background: var(--bg-sunken);
74
+ }
75
+
76
+ /* 危险小按钮 hover:红色浅底(accent-soft 在本皮肤是浅蓝,语义不对) */
77
+ [data-style="gemini"] .icon-btn-danger:hover {
78
+ background: color-mix(in srgb, var(--danger) 12%, transparent);
79
+ }
80
+
81
+ /* ── 分段控件 / 模式切换:Google 分段 pill 形(只动圆角) ───────── */
82
+ [data-style="gemini"] .pref-seg,
83
+ [data-style="gemini"] .pref-seg-btn,
84
+ [data-style="gemini"] .mode-switch,
85
+ [data-style="gemini"] .mode-pill {
86
+ border-radius: 999px;
87
+ }
88
+
89
+ /* ── 卡片 hover:浅灰蓝描边(令牌已把圆角变 16、底变 #f8f9fa 灰) ── */
90
+ [data-style="gemini"] .metric-card:hover,
91
+ [data-style="gemini"] .panel:hover,
92
+ [data-style="gemini"] .diag-card:hover,
93
+ [data-style="gemini"] .diag-trash:hover,
94
+ [data-style="gemini"] .skill-card:hover,
95
+ [data-style="gemini"] .mcp-card:hover,
96
+ [data-style="gemini"] .cloud-card:hover,
97
+ [data-style="gemini"] .expert-card:hover {
98
+ border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
99
+ }
100
+
101
+ /* ── 消息:用户气泡中性化(Google 风更克制:浅灰底 + 发丝描边,
102
+ 圆角走 --radius-card=16;渐变不进对话流) ─────────────────── */
103
+ [data-style="gemini"] .msg-card {
104
+ background: var(--bg-elevated);
105
+ border-color: var(--border);
106
+ }
107
+
108
+ /* ── ② 欢迎页大标题:签名渐变高光(渐变位 2/3;整句文字渐变,
109
+ 正文与水印保持中性/单色) ─────────────────────────────────── */
110
+ [data-style="gemini"] .chat-welcome h1 {
111
+ background: linear-gradient(
112
+ 100deg,
113
+ var(--grad-start) 0%,
114
+ var(--grad-mid) 52%,
115
+ var(--grad-end) 100%
116
+ );
117
+ -webkit-background-clip: text;
118
+ background-clip: text;
119
+ color: transparent;
120
+ -webkit-text-fill-color: transparent;
121
+ }
122
+
123
+ /* ── ③ Ultra 档强调:档名渐变高光(渐变位 3/3;轨道/手柄的蓝色系
124
+ 渐变由 --accent 令牌自动中性化,不在本文件另写) ───────────── */
125
+ [data-style="gemini"] .think-slider.is-ultra .think-name {
126
+ background: linear-gradient(
127
+ 90deg,
128
+ var(--grad-start),
129
+ var(--grad-mid),
130
+ var(--grad-end)
131
+ );
132
+ -webkit-background-clip: text;
133
+ background-clip: text;
134
+ color: transparent;
135
+ -webkit-text-fill-color: transparent;
136
+ }
137
+
138
+ /* ── 滚动条:全圆角细条(颜色本身已走中性令牌:#dadce0 → #80868b) ── */
139
+ [data-style="gemini"] ::-webkit-scrollbar-thumb {
140
+ border-radius: 999px;
141
+ }
142
+
143
+ /* ── 按图精修层(Lead,2026-10-23,依据 docs/refs 五张 Gemini 实拍)────
144
+ ① 环境光晕:Gemini 的"彩色元素"本体——内容区背后两团大范围柔光
145
+ (浅色=薰衣草紫、深色=蓝紫,取自 --grad-* 低透明度),只用 background-image
146
+ 不引入任何布局属性;欢迎页最明显,对话中退为氛围。
147
+ ② 用户气泡:更圆的 18px 近胶囊,贴近 Gemini 对话态实拍。 */
148
+ [data-style="gemini"] .content {
149
+ background-image:
150
+ radial-gradient(55% 40% at 80% 100%, color-mix(in srgb, var(--grad-mid) 14%, transparent), transparent 72%),
151
+ radial-gradient(45% 35% at 12% 100%, color-mix(in srgb, var(--grad-start) 10%, transparent), transparent 70%);
152
+ background-repeat: no-repeat;
153
+ }
154
+ [data-style="gemini"][data-theme="dark"] .content {
155
+ background-image:
156
+ radial-gradient(55% 42% at 78% 100%, color-mix(in srgb, var(--grad-mid) 20%, transparent), transparent 72%),
157
+ radial-gradient(45% 36% at 14% 100%, color-mix(in srgb, var(--grad-start) 14%, transparent), transparent 70%);
158
+ }
159
+ [data-style="gemini"] .msg-card {
160
+ border-radius: 18px;
161
+ }
css/glance.css ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 每日一瞥(契约 18A A2):Warm Paper 全令牌配色,晨报式克制排版。
2
+ 一句体检(衬线略大)→ 两行任务 → 一行数字 → 预警列表 + 巡检开关。 */
3
+
4
+ .glance {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 24px;
12
+ }
13
+
14
+ .glance-head h1 {
15
+ font-size: 30px;
16
+ }
17
+
18
+ .glance-date {
19
+ margin: 6px 0 0;
20
+ font-size: 13.5px;
21
+ color: var(--text-secondary);
22
+ }
23
+
24
+ /* ── 晨报主体:一句话体检 ─────────────────────────────────────── */
25
+ .glance-card {
26
+ max-width: 760px;
27
+ padding: 24px 26px;
28
+ border: 1px solid var(--border);
29
+ border-radius: var(--radius-card);
30
+ background: var(--bg-elevated);
31
+ }
32
+
33
+ .glance-headline {
34
+ margin: 0;
35
+ font-family: var(--font-serif);
36
+ font-size: 20px;
37
+ font-weight: 600;
38
+ line-height: 1.5;
39
+ letter-spacing: -0.01em;
40
+ color: var(--text);
41
+ }
42
+
43
+ /* 严重度只染 headline 的小徽点(语义色仅用于状态语境) */
44
+ .glance-headline.is-warn::before,
45
+ .glance-headline.is-critical::before {
46
+ content: "";
47
+ display: inline-block;
48
+ width: 8px;
49
+ height: 8px;
50
+ margin-right: 10px;
51
+ border-radius: 50%;
52
+ vertical-align: 0.2em;
53
+ }
54
+
55
+ .glance-headline.is-warn::before {
56
+ background: var(--warning);
57
+ }
58
+
59
+ .glance-headline.is-critical::before {
60
+ background: var(--danger);
61
+ }
62
+
63
+ .glance-lines {
64
+ margin: 16px 0 0;
65
+ padding-top: 14px;
66
+ border-top: 1px solid var(--border);
67
+ display: flex;
68
+ flex-direction: column;
69
+ gap: 6px;
70
+ }
71
+
72
+ .glance-line {
73
+ margin: 0;
74
+ font-size: 14px;
75
+ line-height: 1.65;
76
+ color: var(--text-secondary);
77
+ }
78
+
79
+ .glance-digits {
80
+ margin: 14px 0 0;
81
+ font-family: var(--font-mono);
82
+ font-size: 13px;
83
+ font-variant-numeric: tabular-nums;
84
+ color: var(--text-secondary);
85
+ }
86
+
87
+ .glance-meta {
88
+ margin: 12px 0 0;
89
+ font-size: 12px;
90
+ color: var(--text-tertiary);
91
+ }
92
+
93
+ /* ── 预警区 ───────────────────────────────────────────────────── */
94
+ .glance-section {
95
+ max-width: 760px;
96
+ }
97
+
98
+ .glance-section h2 {
99
+ font-size: 18px;
100
+ margin-bottom: 4px;
101
+ }
102
+
103
+ .glance-section-sub {
104
+ margin: 0 0 10px;
105
+ font-size: 12.5px;
106
+ color: var(--text-tertiary);
107
+ line-height: 1.5;
108
+ }
109
+
110
+ .glance-alert {
111
+ padding: 12px 14px;
112
+ border: 1px solid var(--border);
113
+ border-left: 3px solid var(--warning);
114
+ border-radius: var(--radius-chip);
115
+ background: var(--bg-elevated);
116
+ margin-bottom: 8px;
117
+ }
118
+
119
+ .glance-alert-title {
120
+ margin: 0;
121
+ font-weight: 600;
122
+ font-size: 13.5px;
123
+ color: var(--text);
124
+ }
125
+
126
+ .glance-alert-detail {
127
+ margin: 3px 0 0;
128
+ font-size: 13px;
129
+ line-height: 1.6;
130
+ color: var(--text-secondary);
131
+ }
132
+
133
+ .glance-quiet {
134
+ margin: 0;
135
+ padding: 12px 14px;
136
+ border: 1px dashed var(--border);
137
+ border-radius: var(--radius-chip);
138
+ font-size: 13px;
139
+ color: var(--text-tertiary);
140
+ }
141
+
142
+ /* 巡检开关行(复用 pref-row / pref-switch 的骨架,宽度自适应) */
143
+ .glance-switches {
144
+ max-width: 760px;
145
+ border-top: 1px solid var(--border);
146
+ padding-top: 4px;
147
+ }
148
+
149
+ .glance-switch-row {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ gap: 16px;
154
+ padding: 11px 0;
155
+ border-bottom: 1px solid var(--border);
156
+ }
157
+
158
+ .glance-switch-row:last-child {
159
+ border-bottom: none;
160
+ }
161
+
162
+ .glance-switch-label {
163
+ font-size: 13.5px;
164
+ color: var(--text);
165
+ }
166
+
167
+ .glance-switch-hint {
168
+ margin: 2px 0 0;
169
+ font-size: 12px;
170
+ color: var(--text-tertiary);
171
+ }
172
+
173
+ .glance-refresh {
174
+ align-self: flex-start;
175
+ }
176
+
177
+ /* 空载 / 出错态(衬线一句话,不画问号机器人) */
178
+ .glance-state {
179
+ font-family: var(--font-serif);
180
+ font-size: 17px;
181
+ color: var(--text-secondary);
182
+ line-height: 1.6;
183
+ }
184
+
185
+ .glance-state-error {
186
+ color: var(--danger);
187
+ }
css/hub.css ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Hub 二级页签外壳(契约 18A A1:工作台 / 系统 / 设置并入后的子导航)。
2
+ 视觉沿用对话工作台的 wb-tabs(同一套 Warm Paper 令牌,150ms 过渡)。 */
3
+
4
+ /* 纵向外壳:页签条 + 内容区(内容区仍是各组件自己的滚动容器) */
5
+ .hub-root {
6
+ flex: 1;
7
+ min-width: 0;
8
+ min-height: 0;
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+
13
+ .hub-body {
14
+ flex: 1;
15
+ min-width: 0;
16
+ min-height: 0;
17
+ display: flex;
18
+ }
19
+
20
+ /* 页签条:贴内容区左内边距(48px),底边一条 1px 分隔线 */
21
+ .hub-tabs {
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 4px;
25
+ padding: 10px 48px 0;
26
+ border-bottom: 1px solid var(--border);
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ .hub-tab {
31
+ position: relative;
32
+ display: inline-flex;
33
+ align-items: center;
34
+ gap: 6px;
35
+ height: 32px;
36
+ padding: 0 12px;
37
+ border: none;
38
+ border-radius: var(--radius-control) var(--radius-control) 0 0;
39
+ background: transparent;
40
+ color: var(--text-secondary);
41
+ font-family: inherit;
42
+ font-size: 13px;
43
+ cursor: pointer;
44
+ transition:
45
+ background-color var(--dur) var(--ease),
46
+ color var(--dur) var(--ease);
47
+ }
48
+
49
+ .hub-tab:hover {
50
+ background: var(--bg-elevated);
51
+ color: var(--text);
52
+ }
53
+
54
+ .hub-tab.is-active {
55
+ background: var(--accent-soft);
56
+ color: var(--text);
57
+ font-weight: 600;
58
+ }
59
+
60
+ .hub-tab:focus-visible {
61
+ outline: 2px solid var(--accent);
62
+ outline-offset: 2px;
63
+ }
css/human-ui.css ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* V5 daily workspace: one navigation rail, one content canvas, contextual tools. */
2
+ .studio-shell.is-daily{grid-template-columns:178px minmax(0,1fr);font-size:13px}
3
+ .is-daily .studio-topbar{padding-left:76px;background:var(--bg);border-bottom-color:var(--border);gap:12px}
4
+ .is-daily .studio-main{padding-top:0}
5
+ .is-daily .studio-breadcrumb,.is-daily .studio-document-tabs{display:none}
6
+ .is-daily .studio-activity{padding:16px 10px 12px;background:var(--bg-sunken);border-right-color:var(--border)}
7
+ .is-daily .studio-activity>button{min-height:48px;margin:2px 0;padding:9px 10px;border-radius:9px}
8
+ .is-daily .studio-activity>button>span{font-size:13px}
9
+ .is-daily .studio-activity button small{margin-top:3px;font-size:10px;line-height:1.4}
10
+ .is-daily .studio-nav-bottom{padding-top:10px}
11
+ .is-daily .studio-nav-bottom>p{margin-top:8px;padding-top:9px}
12
+ .studio-shell .wb-root{min-height:0;background:var(--bg)}
13
+ .studio-shell .wb-tabs{height:38px;min-height:38px;justify-content:flex-start;gap:18px;padding:0 22px;background:var(--bg);border-bottom:1px solid var(--border)}
14
+ .studio-shell .wb-tab{position:relative;height:38px;padding:0 2px;border:0;border-radius:0;background:transparent;color:var(--text-tertiary);font-size:11px}
15
+ .studio-shell .wb-tab.is-active{background:transparent;color:var(--text)}
16
+ .studio-shell .wb-tab.is-active:after{position:absolute;right:0;bottom:-1px;left:0;height:2px;background:var(--accent);content:""}
17
+ .studio-shell .wb-body{min-height:0;background:var(--bg)}
18
+ .studio-shell .workbench{min-height:0;gap:0;background:var(--bg)}
19
+ .studio-shell .conversations{border-right:1px solid var(--border);background:var(--bg-sunken)}
20
+ .studio-shell .conv-head{height:52px;padding:0 12px;border-bottom:1px solid var(--border)}
21
+ .studio-shell .conv-head-actions{display:flex;align-items:center;gap:5px}
22
+ .studio-shell .conv-head h2{font:550 12px var(--font-sans);color:var(--text)}
23
+ .studio-shell .conv-new{height:29px;padding:0 9px;border-radius:6px;background:var(--bg-elevated);border:1px solid var(--border);color:var(--text-secondary);font-size:10px}
24
+ .studio-shell .conv-item{margin:3px 7px;border-radius:6px}
25
+ .studio-shell .conv-item.is-active{background:var(--accent-soft)}
26
+ .studio-shell .conv-title{font-size:11px}
27
+ .studio-shell .conv-meta{font-size:9px}
28
+ .studio-shell .chat-main{min-width:0;background:var(--bg)}
29
+ .studio-shell .chat-header{min-height:54px;padding:8px 24px;border-bottom:1px solid var(--border);background:var(--bg)}
30
+ .studio-shell .chat-heading{min-width:0;display:flex;flex-direction:column;gap:3px}
31
+ .studio-shell .chat-section-label{font-size:9px;color:var(--text-tertiary)}
32
+ .studio-shell .chat-header-title{font:550 14px var(--font-sans);color:var(--text);letter-spacing:0}
33
+ .studio-shell .chat-welcome{gap:8px;justify-content:center;max-width:760px;margin:0 auto;padding:24px 32px}
34
+ .studio-shell .chat-welcome:before{display:none}
35
+ .studio-shell .chat-welcome-mark{position:relative;inset:auto;transform:none;width:26px;height:26px;opacity:.9;margin-bottom:7px}
36
+ .studio-shell .chat-welcome h1{font-size:21px;font-weight:550;margin:0 0 4px}
37
+ .studio-shell .chat-welcome p{font-size:12px;line-height:1.6}
38
+ .studio-shell.is-daily .chat-welcome h1{font-size:24px;font-weight:600}
39
+ .studio-shell.is-daily .chat-welcome p{font-size:13px;line-height:1.75}
40
+ .studio-shell .message-list{padding:24px max(24px,calc((100% - 820px)/2)) 18px}
41
+ .studio-shell .composer-wrap{z-index:3;padding:8px 22px 14px;background:linear-gradient(180deg,transparent,var(--bg) 18%)}
42
+ .studio-shell .composer{max-width:920px;margin:0 auto;border:1px solid var(--border);border-radius:9px;background:var(--bg-elevated);box-shadow:0 5px 22px rgba(15,24,26,.08)}
43
+ .studio-shell .composer:focus-within{border-color:color-mix(in srgb,var(--accent) 60%,var(--border));box-shadow:0 7px 24px rgba(15,24,26,.11)}
44
+ .studio-shell .composer-input{min-height:54px;padding:15px 16px 8px;font-size:13px;line-height:1.65}
45
+ .studio-shell .composer-bar{padding:4px 10px 9px;margin-top:2px;gap:6px 12px}
46
+ .studio-shell .composer-bar .mode-pill{height:27px;padding:0 9px;font-size:10px}
47
+ .studio-shell .model-trigger{max-width:190px}
48
+ .studio-shell .btn-send,.studio-shell .btn-stop{width:31px;height:31px;border-radius:7px}
49
+ .studio-shell .task-notice{margin:8px auto 0;max-width:920px;border-radius:7px}
50
+ .studio-shell .composer-skills{max-width:920px;margin:0 auto 5px}
51
+ .studio-shell .stats-bar{justify-content:center}
52
+ .conversation-research-status,.research-history{max-width:920px;width:calc(100% - 44px);margin:10px auto 0;border:1px solid var(--border);border-radius:7px;background:var(--bg-elevated)}
53
+ .conversation-research-status{padding:10px 13px}
54
+ .research-status-main{display:flex;align-items:center;gap:10px;min-width:0}
55
+ .research-status-mark{width:8px;height:8px;flex:none;border-radius:50%;background:var(--success)}
56
+ .conversation-research-status.is-running .research-status-mark{background:var(--info);box-shadow:0 0 0 3px color-mix(in srgb,var(--info) 18%,transparent)}
57
+ .research-status-main>div{min-width:0;flex:1}
58
+ .research-status-main strong{font-size:10px;font-weight:600}
59
+ .research-status-main p{overflow:hidden;margin:3px 0 0;color:var(--text-secondary);font-size:10px;text-overflow:ellipsis;white-space:nowrap}
60
+ .research-status-counts{color:var(--text-tertiary);font:9px var(--font-mono);white-space:nowrap}
61
+ .research-status-actions{display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-top:7px;color:var(--success);font-size:9px}
62
+ .research-status-actions .ws-secondary{padding:5px 8px;font-size:9px}
63
+ .research-status-error{margin:6px 0 0;color:var(--danger);font-size:10px;line-height:1.5}
64
+ .research-history{flex:none;margin-top:7px;overflow:hidden}
65
+ .research-history>summary{display:flex;align-items:center;gap:8px;min-height:34px;padding:0 12px;color:var(--text-secondary);cursor:pointer;list-style:none}
66
+ .research-history>summary::-webkit-details-marker{display:none}
67
+ .research-history>summary:before{content:"▸";color:var(--text-tertiary)}
68
+ .research-history[open]>summary:before{content:"▾"}
69
+ .research-history>summary strong{font-size:10px;color:var(--text)}
70
+ .research-history>summary span{font-size:9px;color:var(--text-tertiary)}
71
+ .research-history>ul{max-height:190px;overflow:auto;margin:0;padding:0 12px 5px;list-style:none}
72
+ .research-history li{display:flex;align-items:center;gap:12px;padding:8px 0;border-top:1px solid var(--border)}
73
+ .research-history li>div{min-width:0;flex:1}
74
+ .research-history li strong,.research-history li small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
75
+ .research-history li strong{font-size:10px;font-weight:500}
76
+ .research-history li small{margin-top:3px;color:var(--text-tertiary);font-size:9px}
77
+ .research-history-empty{margin:0;padding:8px 12px 12px;color:var(--text-tertiary);font-size:10px}
78
+ .research-history-notice{margin:5px 12px;color:var(--success);font-size:10px}
79
+ .research-preview{margin:0 12px 12px;padding:12px;border-top:1px solid var(--border);background:var(--bg-sunken)}
80
+ .research-preview>header{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:10px}
81
+ .research-preview>header strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
82
+ .research-preview>div{max-height:260px;overflow:auto;margin:8px 0;font-size:10px;line-height:1.7}
83
+ .studio-shell .tc-subtabs{display:flex;gap:4px;max-width:100%;overflow-x:auto;padding:8px 18px 0;background:var(--bg);}
84
+ .studio-shell .tc-subtab{flex:none;height:30px;padding:0 11px;border-radius:5px 5px 0 0;font-size:10px;white-space:nowrap}
85
+ .studio-shell .tc-body{min-width:0}
86
+ .studio-shell .ws-card,.studio-shell .studio-card{border-radius:7px}
87
+ .studio-shell :focus-visible{outline-color:var(--accent);outline-offset:2px}
88
+
89
+ [data-style="darkside"]{--bg:#111619;--bg-sunken:#0c1114;--bg-elevated:#1a2226;--border:#2b3639;--text:#e8eeee;--text-secondary:#a1afb0;--text-tertiary:#7f9092;--accent:#e1bd79;--accent-soft:#2b2a22;--success:#85c2a7;--warning:#dfb95e;--danger:#e38e88;--info:#82b7d0;--glass:rgba(17,22,25,.96)}
90
+ [data-style="darkside"][data-theme="light"]{--bg:#f2f5f3;--bg-sunken:#e9efec;--bg-elevated:#fff;--border:#d7e0db;--text:#202a28;--text-secondary:#596a66;--text-tertiary:#788782;--accent:#28776b;--accent-soft:#deeee8;--success:#2f765b;--warning:#9a6c20;--danger:#a84442;--info:#346c8a;--glass:rgba(242,245,243,.96)}
91
+ [data-style="darkside"] .studio-activity,[data-style="darkside"] .studio-topbar,[data-style="darkside"] .conversations{background:var(--bg-sunken);border-color:var(--border)}
92
+ [data-style="darkside"] .studio-main,[data-style="darkside"] .chat-main,[data-style="darkside"] .wb-root,[data-style="darkside"] .wb-body{background:var(--bg)}
93
+ [data-style="darkside"] .conv-item.is-active{background:var(--accent-soft)}
94
+ [data-style="darkside"] .composer{background:var(--bg-elevated);border-color:var(--border);box-shadow:0 8px 28px rgba(0,0,0,.16)}
95
+ [data-style="darkside"] .task-notice{background:var(--bg-elevated);border-color:var(--border)}
96
+ [data-style="darkside"][data-theme="light"] .studio-activity,[data-style="darkside"][data-theme="light"] .studio-topbar,[data-style="darkside"][data-theme="light"] .conversations{background:#e9efec}
97
+
98
+ @media(max-width:960px){.studio-shell.is-daily{grid-template-columns:164px minmax(0,1fr)}.is-daily .studio-activity{padding-left:7px;padding-right:7px}.studio-shell .studio-stage .conversations{width:168px;min-width:150px}.studio-shell .chat-header{padding-right:14px;padding-left:14px}.studio-shell .composer-wrap{padding-right:12px;padding-left:12px}.studio-shell .message-list{padding-right:20px;padding-left:20px}}
99
+ @media(max-width:720px){.studio-shell.is-daily{grid-template-columns:52px minmax(0,1fr)}.is-daily .studio-activity{align-items:center;padding:10px 4px}.is-daily .studio-activity>button,.is-daily .studio-nav-bottom>button{justify-content:center;width:42px;height:42px;padding:0}.is-daily .studio-activity>button>span,.is-daily .studio-nav-bottom>button>span,.is-daily .studio-nav-bottom>button>svg:last-child,.is-daily .studio-activity>button>small,.is-daily .studio-nav-bottom>p{display:none}.studio-shell .studio-stage .conversations{width:145px;min-width:130px}.studio-shell .command-search{width:32px;max-width:32px;padding:7px;justify-content:center}.studio-shell .command-search span,.studio-shell .command-search kbd{display:none}.studio-shell .studio-brand>span{display:none}.studio-shell .layout-toggle button{padding:5px 6px}}
100
+ @media(prefers-reduced-motion:reduce){.studio-shell.is-daily *{scroll-behavior:auto!important;animation:none!important;transition:none!important}}
101
+
102
+ /* The two workspaces keep the same data and tools, but use different visual grammars. */
103
+ .studio-shell.is-daily{--radius-control:10px;--radius-card:10px;--radius-chip:8px}
104
+ .studio-shell.is-daily .studio-resources{display:none}
105
+ .studio-shell.is-daily .studio-main{grid-column:2;padding-top:0}
106
+ .studio-shell.is-daily .studio-document-tabs{display:none}
107
+ .studio-shell.is-daily .studio-breadcrumb{display:none}
108
+ .studio-shell.is-daily .studio-nav-bottom>button[aria-label="开发者工具"],
109
+ .studio-shell.is-daily .studio-nav-bottom>button[aria-label="开发者工具"]+.nav-disclosure{display:none}
110
+ .studio-shell.is-daily .studio-nav-bottom{padding-top:12px}
111
+ .studio-shell.is-daily .studio-nav-bottom>p{max-width:140px;line-height:1.65}
112
+ .studio-shell.is-daily .studio-topbar{background:var(--bg-elevated);box-shadow:0 1px 8px color-mix(in srgb,var(--text) 4%,transparent)}
113
+ .studio-shell.is-daily .studio-brand>span{font:9px var(--font-sans);letter-spacing:.2px;color:var(--text-tertiary)}
114
+ .studio-shell.is-daily .layout-toggle{padding:3px;border-radius:9px;background:var(--bg-sunken)}
115
+ .studio-shell.is-daily .layout-toggle button{height:29px;padding:0 10px;border-radius:7px;font-size:10px}
116
+ .studio-shell.is-daily .layout-toggle button[aria-pressed="true"]{background:var(--bg-elevated);box-shadow:0 1px 5px color-mix(in srgb,var(--text) 9%,transparent)}
117
+ .studio-shell.is-daily .studio-activity>button.is-active{position:relative}
118
+ .studio-shell.is-daily .studio-activity>button.is-active:before{position:absolute;left:-1px;top:10px;bottom:10px;width:3px;border-radius:0 3px 3px 0;background:var(--accent);content:""}
119
+ .studio-shell.is-daily .overview-start{padding:25px 24px;border:1px solid var(--border);border-radius:10px;background:var(--bg-elevated)}
120
+ .studio-shell.is-daily .overview-start h2{font-size:20px}
121
+ .studio-shell.is-daily .overview-actions .ws-primary,.studio-shell.is-daily .overview-actions .ws-secondary{min-height:36px;border-radius:8px}
122
+ .studio-shell.is-daily .workspace-metrics{padding:22px 0}
123
+ .studio-shell.is-daily .ws-metric strong{font-size:24px;font-variant-numeric:tabular-nums}
124
+ .studio-shell.is-daily .ws-card,.studio-shell.is-daily .workspace-recent-list>button{border-radius:9px}
125
+ .studio-shell.is-daily .studio-inspector,.studio-shell.is-daily .run-console{display:none}
126
+ .studio-shell.is-daily .studio-statusbar.is-friendly{height:27px;font:10px var(--font-sans);background:var(--bg-elevated)}
127
+ .studio-shell.is-daily .studio-statusbar.is-friendly>.status-local-dot{width:7px;height:7px}
128
+ .studio-shell.is-daily .studio-statusbar.is-friendly>.status-spacer{flex:1}
129
+
130
+ .studio-shell.is-developer{--radius-control:4px;--radius-card:4px;--radius-chip:3px}
131
+ .studio-shell.is-developer .studio-topbar{background:var(--bg-sunken);border-bottom-color:var(--border)}
132
+ .studio-shell.is-developer .studio-brand>span{font:8px var(--font-mono);letter-spacing:1px;color:var(--accent)}
133
+ .studio-shell.is-developer .layout-toggle{border-radius:4px}
134
+ .studio-shell.is-developer .layout-toggle button{height:25px;border-radius:2px;font:9px var(--font-mono)}
135
+ .studio-shell.is-developer .developer-rail-label{width:36px;margin:0 0 10px;text-align:center;color:var(--accent);font:8px var(--font-mono);letter-spacing:.8px}
136
+ .studio-shell.is-developer .studio-resources>header{border-bottom:1px solid var(--border)}
137
+ .studio-shell.is-developer .resource-project{font:10px var(--font-mono)}
138
+ .studio-shell.is-developer .studio-resources>button{border-radius:3px;font:10px var(--font-mono)}
139
+ .studio-shell.is-developer .studio-document-tabs{background:var(--bg-sunken);border-bottom-color:var(--border)}
140
+ .studio-shell.is-developer .studio-document-tabs>div{border-radius:0;border-right-color:var(--border)}
141
+ .studio-shell.is-developer .studio-breadcrumb{font:9px var(--font-mono);text-transform:uppercase}
142
+ .studio-shell.is-developer .studio-inspector{box-shadow:none;border-left-color:var(--border)}
143
+ .studio-shell.is-developer .studio-inspector>header strong,.studio-shell.is-developer .studio-statusbar{font-family:var(--font-mono)}
144
+ .studio-shell.is-developer .studio-statusbar{height:24px;font-size:9px}
145
+ .studio-shell.is-developer .run-console{border-radius:0}
146
+ .studio-shell.is-developer .run-console pre{font-size:10px}
147
+ .studio-shell.is-developer .studio-card,.studio-shell.is-developer .ws-card{border-radius:4px}
148
+ .studio-shell.is-developer .chat-welcome{align-items:flex-start;margin:0;max-width:100%;padding:24px 32px}
149
+ .studio-shell.is-developer .chat-welcome h1{font:550 17px var(--font-mono)}
150
+ .studio-shell.is-developer .chat-welcome-kicker{color:var(--accent);font:9px var(--font-mono);letter-spacing:.6px}
151
+ .studio-shell.is-developer .chat-starters{max-width:680px;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:20px}
152
+ .studio-shell.is-developer .chat-starter{min-height:62px;border-radius:4px;background:var(--bg-sunken);font-family:var(--font-mono)}
153
+
154
+ [data-style="darkside"] .studio-shell.is-daily{--bg:#18211f;--bg-sunken:#121a18;--bg-elevated:#202c29;--border:#354741;--text:#e8f1ed;--text-secondary:#a9bdb5;--text-tertiary:#81988e;--accent:#90d6b6;--accent-soft:#253b32;--success:#78d2a3;--warning:#e7bd74;--danger:#ed9688;--info:#85bfe2;color-scheme:dark}
155
+ [data-style="darkside"][data-theme="light"] .studio-shell.is-daily{--bg:#f3f7f4;--bg-sunken:#eaf1ec;--bg-elevated:#fff;--border:#d8e4dc;--text:#25342d;--text-secondary:#5f7167;--text-tertiary:#819087;--accent:#28775d;--accent-soft:#e0f0e6;--success:#2d805c;--warning:#a36b26;--danger:#b34843;--info:#346f9c;color-scheme:light}
156
+ [data-style="darkside"] .studio-shell.is-daily .conversations{background:var(--bg-sunken);border-right-color:var(--border)}
157
+ [data-style="darkside"] .studio-shell.is-daily .chat-welcome{color:var(--text)}
158
+ [data-style="darkside"] .studio-shell.is-daily .chat-starter{background:var(--bg-elevated);border-color:var(--border)}
159
+ [data-style="darkside"] .studio-shell.is-daily .composer{box-shadow:0 8px 28px color-mix(in srgb,var(--text) 8%,transparent)}
160
+
161
+ [data-style="darkside"] .studio-shell.is-developer{--bg:#0c1118;--bg-sunken:#080d13;--bg-elevated:#121a24;--border:#283747;--text:#e3edf4;--text-secondary:#9bafbd;--text-tertiary:#708798;--accent:#65cde0;--accent-soft:#142c38;--success:#65d2a4;--warning:#f0bd67;--danger:#ef887f;--info:#85baf2;color-scheme:dark}
162
+ [data-style="darkside"][data-theme="light"] .studio-shell.is-developer{--bg:#eff3f8;--bg-sunken:#e5ebf2;--bg-elevated:#fff;--border:#cbd6e2;--text:#1c2a35;--text-secondary:#526879;--text-tertiary:#73899a;--accent:#087c98;--accent-soft:#d9eef2;--success:#217950;--warning:#9a681a;--danger:#b4413a;--info:#366dba;color-scheme:light}
163
+ [data-style="darkside"] .studio-shell.is-developer .studio-activity,[data-style="darkside"] .studio-shell.is-developer .studio-resources,[data-style="darkside"] .studio-shell.is-developer .run-console{background:var(--bg-sunken)}
164
+ [data-style="darkside"] .studio-shell.is-developer .studio-main,[data-style="darkside"] .studio-shell.is-developer .studio-inspector{background:var(--bg)}
165
+ [data-style="darkside"] .studio-shell.is-developer .studio-resources>button.is-selected{box-shadow:inset 2px 0 0 var(--accent)}
166
+ [data-style="darkside"] .studio-shell.is-developer .studio-document-tabs>div.is-active{background:var(--bg);border-top-color:var(--accent)}
167
+
168
+ .studio-shell .chat-welcome-kicker{display:block;color:var(--text-tertiary);font-size:9px;letter-spacing:.7px}
169
+ .chat-starters{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;width:min(680px,100%);margin-top:16px}
170
+ .chat-starter{display:flex;align-items:center;gap:9px;min-width:0;min-height:48px;padding:9px 11px;border:1px solid var(--border);border-radius:8px;background:var(--bg-elevated);color:var(--text-secondary);font:11px var(--font-sans);text-align:left;cursor:pointer;transition:border-color .15s ease,background .15s ease,color .15s ease}
171
+ .chat-starter:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--text)}
172
+ .chat-starter>svg{flex:none;color:var(--accent)}
173
+ .chat-starter>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
174
+ @media(max-width:760px){.chat-starters{grid-template-columns:1fr}.studio-shell.is-daily .overview-start{align-items:flex-start;flex-direction:column}.studio-shell.is-daily .overview-actions{justify-content:flex-start}}
css/kb.css ADDED
@@ -0,0 +1,644 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 本地知识库(Phase 3 RAG):文档列表 + 检索测试 + 带引用问答。
2
+ Warm Paper 全令牌配色,遵循 design-system.md。 */
3
+
4
+ .kb {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ }
10
+
11
+ .kb-head {
12
+ display: flex;
13
+ align-items: flex-end;
14
+ justify-content: space-between;
15
+ gap: 16px;
16
+ margin-bottom: 16px;
17
+ flex-wrap: wrap;
18
+ }
19
+
20
+ .kb-head h1 {
21
+ font-size: 30px;
22
+ }
23
+
24
+ .kb-head-sub {
25
+ margin: 6px 0 0;
26
+ font-size: 13.5px;
27
+ color: var(--text-secondary);
28
+ }
29
+
30
+ .kb-head-actions {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 14px;
34
+ }
35
+
36
+ .kb-stat {
37
+ font-size: 13px;
38
+ color: var(--text-secondary);
39
+ font-variant-numeric: tabular-nums;
40
+ }
41
+
42
+ .kb-backend-note {
43
+ margin: 0 0 16px;
44
+ padding: 8px 14px;
45
+ border: 1px dashed var(--border);
46
+ border-radius: var(--radius-control);
47
+ background: var(--bg-sunken);
48
+ font-size: 13px;
49
+ color: var(--text-secondary);
50
+ }
51
+
52
+ .kb-notice {
53
+ margin: 0 0 16px;
54
+ padding: 8px 14px;
55
+ border: 1px solid var(--border);
56
+ border-radius: var(--radius-control);
57
+ background: var(--accent-soft);
58
+ font-size: 13px;
59
+ color: var(--text);
60
+ }
61
+
62
+ .kb-error {
63
+ margin: 8px 0 0;
64
+ font-size: 13px;
65
+ color: var(--danger);
66
+ }
67
+
68
+ .kb-muted {
69
+ font-size: 13px;
70
+ color: var(--text-secondary);
71
+ }
72
+
73
+ /* ── 按钮 / 输入 ────────────────────────────────────────────────── */
74
+
75
+ .kb-btn {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: 6px;
79
+ height: 36px;
80
+ padding: 0 14px;
81
+ border: 1px solid var(--border);
82
+ border-radius: var(--radius-control);
83
+ background: transparent;
84
+ color: var(--text);
85
+ font-family: inherit;
86
+ font-size: 13.5px;
87
+ cursor: pointer;
88
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
89
+ }
90
+
91
+ .kb-btn:hover:not(:disabled) {
92
+ background: var(--bg-elevated);
93
+ }
94
+
95
+ .kb-btn:disabled {
96
+ opacity: 0.55;
97
+ cursor: default;
98
+ }
99
+
100
+ .kb-btn-primary {
101
+ border-color: transparent;
102
+ background: var(--accent);
103
+ color: var(--bg);
104
+ }
105
+
106
+ .kb-btn-primary:hover:not(:disabled) {
107
+ filter: brightness(0.94);
108
+ }
109
+
110
+ .kb-icon-btn {
111
+ display: inline-flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ width: 28px;
115
+ height: 28px;
116
+ border: none;
117
+ border-radius: var(--radius-control);
118
+ background: transparent;
119
+ color: var(--text-secondary);
120
+ cursor: pointer;
121
+ transition: background-color var(--dur) var(--ease);
122
+ }
123
+
124
+ .kb-icon-btn:hover {
125
+ background: var(--accent-soft);
126
+ color: var(--text);
127
+ }
128
+
129
+ .kb-input {
130
+ flex: 1;
131
+ min-width: 0;
132
+ height: 36px;
133
+ padding: 0 12px;
134
+ border: 1px solid transparent;
135
+ border-radius: var(--radius-control);
136
+ background: var(--bg-sunken);
137
+ color: var(--text);
138
+ font-family: inherit;
139
+ font-size: 14px;
140
+ }
141
+
142
+ .kb-input::placeholder {
143
+ color: var(--text-tertiary);
144
+ }
145
+
146
+ .kb-input:focus {
147
+ outline: none;
148
+ border-color: var(--accent);
149
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
150
+ }
151
+
152
+ .kb-select {
153
+ height: 36px;
154
+ padding: 0 8px;
155
+ border: 1px solid var(--border);
156
+ border-radius: var(--radius-control);
157
+ background: var(--bg-elevated);
158
+ color: var(--text);
159
+ font-family: inherit;
160
+ font-size: 13px;
161
+ }
162
+
163
+ .kb-input-row {
164
+ display: flex;
165
+ align-items: center;
166
+ gap: 8px;
167
+ margin-bottom: 12px;
168
+ }
169
+
170
+ /* ── 双栏布局 ───────────────────────────────────────────────────── */
171
+
172
+ .kb-columns {
173
+ display: grid;
174
+ grid-template-columns: 320px minmax(0, 1fr);
175
+ gap: 20px;
176
+ align-items: start;
177
+ }
178
+
179
+ .kb-right {
180
+ display: flex;
181
+ flex-direction: column;
182
+ gap: 20px;
183
+ min-width: 0;
184
+ }
185
+
186
+ .kb-panel {
187
+ padding: 20px 22px;
188
+ border: 1px solid var(--border);
189
+ border-radius: var(--radius-card);
190
+ background: var(--bg-elevated);
191
+ }
192
+
193
+ .kb-panel-title {
194
+ margin: 0 0 14px;
195
+ font-family: var(--font-serif);
196
+ font-size: 17px;
197
+ font-weight: 600;
198
+ }
199
+
200
+ /* ── 文档列表 ───────────────────────────────────────────────────── */
201
+
202
+ .kb-empty {
203
+ display: flex;
204
+ flex-direction: column;
205
+ align-items: center;
206
+ gap: 8px;
207
+ padding: 28px 12px;
208
+ text-align: center;
209
+ color: var(--text-secondary);
210
+ }
211
+
212
+ .kb-empty p {
213
+ margin: 0;
214
+ font-family: var(--font-serif);
215
+ font-size: 15px;
216
+ color: var(--text);
217
+ }
218
+
219
+ .kb-empty .kb-muted {
220
+ font-family: var(--font-sans);
221
+ font-size: 13px;
222
+ color: var(--text-secondary);
223
+ }
224
+
225
+ .kb-doc-list {
226
+ list-style: none;
227
+ margin: 0;
228
+ padding: 0;
229
+ }
230
+
231
+ .kb-doc {
232
+ display: flex;
233
+ align-items: center;
234
+ justify-content: space-between;
235
+ gap: 8px;
236
+ padding: 10px 4px;
237
+ border-bottom: 1px solid var(--border);
238
+ }
239
+
240
+ .kb-doc:last-child {
241
+ border-bottom: none;
242
+ }
243
+
244
+ .kb-doc-main {
245
+ display: flex;
246
+ flex-direction: column;
247
+ min-width: 0;
248
+ }
249
+
250
+ .kb-doc-name {
251
+ font-size: 14px;
252
+ color: var(--text);
253
+ overflow: hidden;
254
+ text-overflow: ellipsis;
255
+ white-space: nowrap;
256
+ }
257
+
258
+ .kb-doc-meta {
259
+ margin-top: 2px;
260
+ font-size: 12px;
261
+ color: var(--text-secondary);
262
+ font-variant-numeric: tabular-nums;
263
+ }
264
+
265
+ /* ── 检索命中卡片 ───────────────────────────────────────────────── */
266
+
267
+ .kb-hit-list {
268
+ list-style: none;
269
+ margin: 0;
270
+ padding: 0;
271
+ display: flex;
272
+ flex-direction: column;
273
+ gap: 10px;
274
+ }
275
+
276
+ .kb-hit {
277
+ padding: 12px 14px;
278
+ border: 1px solid var(--border);
279
+ border-radius: var(--radius-control);
280
+ background: var(--bg);
281
+ transition: border-color var(--dur) var(--ease);
282
+ }
283
+
284
+ .kb-hit:hover {
285
+ border-color: var(--accent);
286
+ }
287
+
288
+ .kb-hit-head {
289
+ display: flex;
290
+ align-items: baseline;
291
+ justify-content: space-between;
292
+ gap: 10px;
293
+ margin-bottom: 6px;
294
+ }
295
+
296
+ .kb-hit-source {
297
+ font-size: 12.5px;
298
+ color: var(--text-secondary);
299
+ overflow: hidden;
300
+ text-overflow: ellipsis;
301
+ white-space: nowrap;
302
+ }
303
+
304
+ .kb-hit-score {
305
+ flex-shrink: 0;
306
+ font-family: var(--font-mono);
307
+ font-size: 12px;
308
+ color: var(--accent);
309
+ font-variant-numeric: tabular-nums;
310
+ }
311
+
312
+ .kb-hit-excerpt {
313
+ margin: 0;
314
+ font-size: 13.5px;
315
+ line-height: 1.6;
316
+ color: var(--text);
317
+ }
318
+
319
+ /* ── 问答结果 ───────────────────────────────────────────────────── */
320
+
321
+ .kb-ask-result {
322
+ margin-top: 4px;
323
+ }
324
+
325
+ .kb-question-line {
326
+ margin: 10px 0 6px;
327
+ font-size: 13px;
328
+ color: var(--text-secondary);
329
+ }
330
+
331
+ .kb-answer-body {
332
+ font-size: 14.5px;
333
+ line-height: 1.7;
334
+ }
335
+
336
+ .kb-answer-body > * {
337
+ margin: 0 0 10px;
338
+ }
339
+
340
+ .kb-cite-ref {
341
+ display: inline;
342
+ padding: 0 3px;
343
+ margin: 0 1px;
344
+ border: none;
345
+ border-radius: 4px;
346
+ background: var(--accent-soft);
347
+ color: var(--accent);
348
+ font-family: var(--font-mono);
349
+ font-size: 12px;
350
+ cursor: pointer;
351
+ vertical-align: super;
352
+ line-height: 1;
353
+ transition: background-color var(--dur) var(--ease);
354
+ }
355
+
356
+ .kb-cite-ref:hover {
357
+ background: var(--accent);
358
+ color: var(--bg);
359
+ }
360
+
361
+ /* ── 引用条目(可折叠) ─────────────────────────────────────────── */
362
+
363
+ .kb-citations {
364
+ margin: 0 0 12px;
365
+ padding: 10px 14px;
366
+ border: 1px solid var(--border);
367
+ border-radius: var(--radius-control);
368
+ background: var(--bg-sunken);
369
+ }
370
+
371
+ .kb-citations > summary {
372
+ cursor: pointer;
373
+ font-size: 13px;
374
+ color: var(--text-secondary);
375
+ list-style: none;
376
+ }
377
+
378
+ .kb-citations > summary::-webkit-details-marker {
379
+ display: none;
380
+ }
381
+
382
+ .kb-citation-list {
383
+ list-style: none;
384
+ margin: 10px 0 0;
385
+ padding: 0;
386
+ display: flex;
387
+ flex-direction: column;
388
+ gap: 8px;
389
+ }
390
+
391
+ .kb-citation {
392
+ padding-top: 8px;
393
+ border-top: 1px solid var(--border);
394
+ }
395
+
396
+ .kb-citation:first-child {
397
+ border-top: none;
398
+ padding-top: 0;
399
+ }
400
+
401
+ .kb-citation-btn {
402
+ display: flex;
403
+ align-items: baseline;
404
+ gap: 6px;
405
+ width: 100%;
406
+ padding: 0;
407
+ border: none;
408
+ background: transparent;
409
+ text-align: left;
410
+ cursor: pointer;
411
+ }
412
+
413
+ .kb-citation-rank {
414
+ flex-shrink: 0;
415
+ font-family: var(--font-mono);
416
+ font-size: 12px;
417
+ color: var(--accent);
418
+ }
419
+
420
+ .kb-citation-source {
421
+ font-size: 12.5px;
422
+ color: var(--text-secondary);
423
+ overflow: hidden;
424
+ text-overflow: ellipsis;
425
+ white-space: nowrap;
426
+ }
427
+
428
+ .kb-citation-quote {
429
+ margin: 4px 0 0;
430
+ font-size: 13px;
431
+ line-height: 1.55;
432
+ color: var(--text);
433
+ display: -webkit-box;
434
+ -webkit-line-clamp: 2;
435
+ -webkit-box-orient: vertical;
436
+ overflow: hidden;
437
+ }
438
+
439
+ /* ── 引用原文抽屉 ───────────────────────────────────────────────── */
440
+
441
+ .kb-drawer-mask {
442
+ position: fixed;
443
+ inset: 0;
444
+ display: flex;
445
+ justify-content: flex-end;
446
+ background: var(--scrim);
447
+ z-index: 40;
448
+ }
449
+
450
+ .kb-drawer {
451
+ display: flex;
452
+ flex-direction: column;
453
+ width: min(520px, 90vw);
454
+ height: 100%;
455
+ background: var(--bg-elevated);
456
+ border-left: 1px solid var(--border);
457
+ box-shadow: var(--shadow-float);
458
+ animation: kb-drawer-in 180ms var(--ease);
459
+ }
460
+
461
+ @keyframes kb-drawer-in {
462
+ from {
463
+ opacity: 0;
464
+ transform: translateX(12px);
465
+ }
466
+ to {
467
+ opacity: 1;
468
+ transform: translateX(0);
469
+ }
470
+ }
471
+
472
+ .kb-drawer-head {
473
+ display: flex;
474
+ align-items: center;
475
+ justify-content: space-between;
476
+ gap: 10px;
477
+ padding: 18px 22px;
478
+ border-bottom: 1px solid var(--border);
479
+ }
480
+
481
+ .kb-drawer-head > div {
482
+ display: flex;
483
+ align-items: baseline;
484
+ gap: 8px;
485
+ min-width: 0;
486
+ }
487
+
488
+ .kb-drawer-source {
489
+ font-family: var(--font-serif);
490
+ font-size: 15px;
491
+ font-weight: 600;
492
+ color: var(--text);
493
+ overflow: hidden;
494
+ text-overflow: ellipsis;
495
+ white-space: nowrap;
496
+ }
497
+
498
+ .kb-drawer-body {
499
+ flex: 1;
500
+ overflow-y: auto;
501
+ padding: 20px 22px;
502
+ font-size: 14.5px;
503
+ line-height: 1.7;
504
+ }
505
+
506
+ .kb-drawer-body .md > * {
507
+ margin: 0 0 12px;
508
+ }
509
+
510
+ /* ── 拖放蒙层 ───────────────────────────────────────────────────── */
511
+
512
+ .kb-drag-overlay {
513
+ position: fixed;
514
+ inset: 0;
515
+ z-index: 50;
516
+ background: var(--glass);
517
+ display: flex;
518
+ align-items: center;
519
+ justify-content: center;
520
+ }
521
+
522
+ .kb-drag-card {
523
+ display: flex;
524
+ flex-direction: column;
525
+ align-items: center;
526
+ gap: 10px;
527
+ padding: 40px 56px;
528
+ border: 1px dashed var(--accent);
529
+ border-radius: var(--radius-float);
530
+ color: var(--text);
531
+ }
532
+
533
+ .kb-drag-title {
534
+ margin: 0;
535
+ font-family: var(--font-serif);
536
+ font-size: 24px;
537
+ font-weight: 600;
538
+ }
539
+
540
+ .kb-drag-sub {
541
+ margin: 0;
542
+ font-size: 13.5px;
543
+ color: var(--text-secondary);
544
+ }
545
+
546
+ /* 转圈(theme.css 的 reduced-motion 会全局关停动画) */
547
+ .kb-spin {
548
+ animation: kb-rot 1s linear infinite;
549
+ }
550
+
551
+ @keyframes kb-rot {
552
+ to {
553
+ transform: rotate(360deg);
554
+ }
555
+ }
556
+
557
+ /* 窄屏:双栏折叠成单栏 */
558
+ @media (max-width: 900px) {
559
+ .kb-columns {
560
+ grid-template-columns: minmax(0, 1fr);
561
+ }
562
+ }
563
+
564
+ /* ── 语义检索徽章(契约 7B)────────────────────────────────────── */
565
+
566
+ .kb-backend {
567
+ margin-bottom: 12px;
568
+ }
569
+
570
+ /* 徽章本体是个按钮:点开才看细节,默认视图只给结论 */
571
+ .kb-backend-badge {
572
+ display: inline-flex;
573
+ align-items: center;
574
+ gap: 6px;
575
+ padding: 4px 12px;
576
+ border: 1px solid var(--border);
577
+ border-radius: var(--radius-chip);
578
+ background: var(--bg-elevated);
579
+ color: var(--text-secondary);
580
+ font-size: 12px;
581
+ line-height: 1.6;
582
+ cursor: pointer;
583
+ transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
584
+ }
585
+
586
+ .kb-backend-badge:hover {
587
+ border-color: var(--accent);
588
+ color: var(--text);
589
+ }
590
+
591
+ .kb-backend-badge:focus-visible {
592
+ outline: 2px solid var(--accent);
593
+ outline-offset: 2px;
594
+ }
595
+
596
+ /* 状态点:启用=success,降级=warning。不用红——降级是设计内的正常状态 */
597
+ .kb-dot {
598
+ width: 7px;
599
+ height: 7px;
600
+ border-radius: 50%;
601
+ background: var(--warning);
602
+ flex: none;
603
+ }
604
+
605
+ .kb-backend-on .kb-dot {
606
+ background: var(--success);
607
+ }
608
+
609
+ .kb-backend-label {
610
+ font-weight: 500;
611
+ }
612
+
613
+ .kb-backend-on .kb-backend-label {
614
+ color: var(--text);
615
+ }
616
+
617
+ /* 模型名片片:次要信息,弱化显示 */
618
+ .kb-backend-model {
619
+ padding-left: 6px;
620
+ margin-left: 2px;
621
+ border-left: 1px solid var(--border);
622
+ color: var(--text-tertiary);
623
+ font-family: var(--font-mono);
624
+ font-size: 11px;
625
+ }
626
+
627
+ .kb-backend-detail {
628
+ margin-top: 8px;
629
+ }
630
+
631
+ .kb-backend-detail .kb-backend-note {
632
+ margin: 0;
633
+ }
634
+
635
+ .kb-backend-meta {
636
+ margin: 4px 0 0;
637
+ color: var(--text-tertiary);
638
+ font-size: 12px;
639
+ }
640
+
641
+ /* 导入进度:等宽数字更好读 */
642
+ .kb-import-progress {
643
+ font-variant-numeric: tabular-nums;
644
+ }
css/launcher.css ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 启动器:大输入框 + 模糊搜索结果列表(Warm Paper,颜色一律走 theme.css 令牌) */
2
+
3
+ /* ---------- 通用容器 ---------- */
4
+ .launcher {
5
+ display: flex;
6
+ flex-direction: column;
7
+ min-width: 0;
8
+ overflow: hidden;
9
+ }
10
+
11
+ /* ---------- 主窗口内嵌版:普通面板,靠左上对齐留白 ---------- */
12
+ .launcher--page {
13
+ flex: 1;
14
+ height: 100%;
15
+ background: transparent;
16
+ }
17
+
18
+ .launcher--page .launcher-search,
19
+ .launcher--page .launcher-body,
20
+ .launcher--page .launcher-foot {
21
+ width: min(720px, 100%);
22
+ }
23
+
24
+ /* ---------- 浮窗版:毛玻璃 + 圆角 + 极轻阴影 ---------- */
25
+ /* 注意:透明窗口上 WebKit 的 backdrop-filter 会把元素整个画没(macOS 已知坑),
26
+ 所以模糊交给系统的窗口特效(tauri.conf.json 的 windowEffects),
27
+ CSS 只负责 85% 暖纸底色,透出桌面就靠它本身是半透明的。 */
28
+ .launcher--overlay {
29
+ flex: 1;
30
+ min-height: 0;
31
+ border: 1px solid var(--border);
32
+ border-radius: var(--radius-float);
33
+ background: var(--glass);
34
+ box-shadow: var(--shadow-float);
35
+ animation: launcher-in 180ms var(--ease);
36
+ }
37
+
38
+ /* 透明窗口本体:桌面要从圆角外透出来 */
39
+ body.launcher-surface {
40
+ background: transparent;
41
+ }
42
+
43
+ .launcher-overlay {
44
+ height: 100%;
45
+ display: flex;
46
+ padding: 12px;
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ @keyframes launcher-in {
51
+ from {
52
+ opacity: 0;
53
+ transform: translateY(6px);
54
+ }
55
+ to {
56
+ opacity: 1;
57
+ transform: translateY(0);
58
+ }
59
+ }
60
+
61
+ /* ---------- 输入区 ---------- */
62
+ .launcher-search {
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 12px;
66
+ margin: 16px 16px 8px;
67
+ padding: 10px 16px;
68
+ border: 1px solid transparent;
69
+ border-radius: var(--radius-card);
70
+ background: var(--bg-sunken);
71
+ transition:
72
+ border-color var(--dur) var(--ease),
73
+ background-color var(--dur) var(--ease);
74
+ }
75
+
76
+ .launcher-search:focus-within {
77
+ border-color: var(--accent);
78
+ }
79
+
80
+ .launcher-search-icon {
81
+ flex-shrink: 0;
82
+ color: var(--text-tertiary);
83
+ }
84
+
85
+ .launcher-input {
86
+ flex: 1;
87
+ min-width: 0;
88
+ border: none;
89
+ background: transparent;
90
+ color: var(--text);
91
+ font-family: var(--font-serif);
92
+ font-size: 26px;
93
+ line-height: 1.4;
94
+ letter-spacing: -0.01em;
95
+ outline: none;
96
+ cursor: text;
97
+ }
98
+
99
+ .launcher-input::placeholder {
100
+ color: var(--text-tertiary);
101
+ }
102
+
103
+ .launcher-kbd {
104
+ flex-shrink: 0;
105
+ font-size: 12px;
106
+ color: var(--text-tertiary);
107
+ white-space: nowrap;
108
+ }
109
+
110
+ /* ---------- 结果列表 ---------- */
111
+ .launcher-body {
112
+ flex: 1;
113
+ min-height: 0;
114
+ overflow-y: auto;
115
+ padding: 4px 8px 8px;
116
+ }
117
+
118
+ .launcher-list {
119
+ margin: 0;
120
+ padding: 0;
121
+ list-style: none;
122
+ }
123
+
124
+ .launcher-item {
125
+ display: flex;
126
+ align-items: baseline;
127
+ gap: 16px;
128
+ width: 100%;
129
+ padding: 9px 14px;
130
+ border: none;
131
+ border-radius: var(--radius-control);
132
+ background: transparent;
133
+ color: var(--text);
134
+ font-family: inherit;
135
+ font-size: 14.5px;
136
+ text-align: left;
137
+ cursor: pointer;
138
+ transition: background-color var(--dur) var(--ease);
139
+ }
140
+
141
+ .launcher-item:hover {
142
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
143
+ }
144
+
145
+ .launcher-item.is-selected {
146
+ background: var(--accent-soft);
147
+ }
148
+
149
+ .launcher-item-name {
150
+ flex: 1;
151
+ min-width: 0;
152
+ overflow: hidden;
153
+ text-overflow: ellipsis;
154
+ white-space: nowrap;
155
+ }
156
+
157
+ .launcher-item-name mark {
158
+ background: transparent;
159
+ color: var(--accent);
160
+ font-weight: 600;
161
+ }
162
+
163
+ .launcher-item-meta {
164
+ flex-shrink: 0;
165
+ display: flex;
166
+ gap: 12px;
167
+ font-size: 12.5px;
168
+ color: var(--text-tertiary);
169
+ font-variant-numeric: tabular-nums;
170
+ }
171
+
172
+ /* ---------- 空态 / 状态行 ---------- */
173
+ .launcher-empty {
174
+ padding: 20px 16px;
175
+ }
176
+
177
+ .launcher-empty-title {
178
+ margin: 0 0 6px;
179
+ font-family: var(--font-serif);
180
+ font-size: 20px;
181
+ color: var(--text);
182
+ }
183
+
184
+ .launcher-empty-note {
185
+ margin: 0;
186
+ font-size: 13.5px;
187
+ color: var(--text-secondary);
188
+ }
189
+
190
+ .launcher-note {
191
+ margin: 0;
192
+ padding: 16px;
193
+ font-size: 13.5px;
194
+ color: var(--text-secondary);
195
+ }
196
+
197
+ .launcher-note.is-error {
198
+ color: var(--danger);
199
+ }
200
+
201
+ /* ---------- 底栏 ---------- */
202
+ .launcher-foot {
203
+ display: flex;
204
+ align-items: center;
205
+ justify-content: space-between;
206
+ gap: 16px;
207
+ padding: 10px 20px 14px;
208
+ border-top: 1px solid var(--border);
209
+ font-size: 12.5px;
210
+ color: var(--text-tertiary);
211
+ }
212
+
213
+ .launcher-hint {
214
+ color: var(--text-tertiary);
215
+ }
216
+
217
+ .launcher-settings {
218
+ display: flex;
219
+ flex-direction: column;
220
+ align-items: flex-start;
221
+ gap: 4px;
222
+ min-width: 0;
223
+ }
224
+
225
+ .launcher-settings-row {
226
+ display: flex;
227
+ align-items: center;
228
+ gap: 10px;
229
+ min-width: 0;
230
+ }
231
+
232
+ .launcher-settings-note {
233
+ max-width: 480px;
234
+ font-size: 12px;
235
+ line-height: 1.6;
236
+ color: var(--text-tertiary);
237
+ }
238
+
239
+ .launcher-settings-label {
240
+ color: var(--text-secondary);
241
+ white-space: nowrap;
242
+ }
243
+
244
+ .launcher-settings-error {
245
+ color: var(--danger);
246
+ }
247
+
248
+ .launcher-chips {
249
+ display: flex;
250
+ gap: 6px;
251
+ }
252
+
253
+ .launcher-chip {
254
+ height: 26px;
255
+ padding: 0 10px;
256
+ border: 1px solid var(--border);
257
+ border-radius: var(--radius-control);
258
+ background: transparent;
259
+ color: var(--text-secondary);
260
+ font-family: inherit;
261
+ font-size: 12.5px;
262
+ cursor: pointer;
263
+ transition: background-color var(--dur) var(--ease);
264
+ }
265
+
266
+ .launcher-chip:hover {
267
+ background: var(--bg-elevated);
268
+ color: var(--text);
269
+ }
270
+
271
+ .launcher-chip.is-active {
272
+ border-color: var(--accent-soft);
273
+ background: var(--accent-soft);
274
+ color: var(--text);
275
+ }
276
+
277
+ .launcher-foot-right {
278
+ display: flex;
279
+ align-items: center;
280
+ gap: 14px;
281
+ }
282
+
283
+ .launcher-refresh {
284
+ display: inline-flex;
285
+ align-items: center;
286
+ gap: 6px;
287
+ height: 28px;
288
+ padding: 0 10px;
289
+ border: none;
290
+ border-radius: var(--radius-control);
291
+ background: transparent;
292
+ color: var(--text-secondary);
293
+ font-family: inherit;
294
+ font-size: 12.5px;
295
+ cursor: pointer;
296
+ transition: background-color var(--dur) var(--ease);
297
+ }
298
+
299
+ .launcher-refresh:hover {
300
+ background: var(--bg-elevated);
301
+ color: var(--text);
302
+ }
css/live-eye.css ADDED
@@ -0,0 +1,474 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 实时之眼窗口:Warm Paper 卡片(颜色一律走 theme.css 令牌)。
2
+ 与看图问答的差别:本窗带系统标题栏(兑现契约「标题栏红点」——标题由后端
3
+ 改成「🔴 实时之眼中」),所以页面本体是不透明暖纸底,不做透明圆角悬浮。 */
4
+
5
+ body.live-surface {
6
+ background: var(--bg);
7
+ }
8
+
9
+ .live-root {
10
+ height: 100%;
11
+ display: flex;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ .live-card {
16
+ flex: 1;
17
+ min-height: 0;
18
+ display: flex;
19
+ flex-direction: column;
20
+ overflow: hidden;
21
+ }
22
+
23
+ /* ---------- 顶栏:标题 + 录制徽章 ---------- */
24
+ .live-head {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ gap: 12px;
29
+ padding: 18px 20px 6px;
30
+ }
31
+
32
+ .live-head-main {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 10px;
36
+ min-width: 0;
37
+ }
38
+
39
+ .live-title {
40
+ margin: 0;
41
+ font-family: var(--font-serif);
42
+ font-size: 20px;
43
+ font-weight: 600;
44
+ letter-spacing: -0.01em;
45
+ color: var(--text);
46
+ }
47
+
48
+ /* 录制级指示(第二层):红点呼吸 +「实时之眼中」徽章 */
49
+ .live-badge {
50
+ display: inline-flex;
51
+ align-items: center;
52
+ gap: 6px;
53
+ height: 22px;
54
+ padding: 0 9px;
55
+ border: 1px solid var(--border);
56
+ border-radius: var(--radius-chip);
57
+ background: var(--bg-elevated);
58
+ color: var(--text-tertiary);
59
+ font-size: 11.5px;
60
+ white-space: nowrap;
61
+ }
62
+
63
+ .live-badge.is-rec {
64
+ border-color: var(--danger);
65
+ color: var(--danger);
66
+ }
67
+
68
+ .live-badge-dot {
69
+ width: 7px;
70
+ height: 7px;
71
+ border-radius: 50%;
72
+ background: var(--text-tertiary);
73
+ flex-shrink: 0;
74
+ }
75
+
76
+ .live-badge.is-rec .live-badge-dot {
77
+ background: var(--danger);
78
+ animation: live-breathe 1.6s ease-in-out infinite;
79
+ }
80
+
81
+ @keyframes live-breathe {
82
+ 0%,
83
+ 100% {
84
+ opacity: 1;
85
+ }
86
+ 50% {
87
+ opacity: 0.25;
88
+ }
89
+ }
90
+
91
+ .live-esc {
92
+ font-size: 12px;
93
+ color: var(--text-tertiary);
94
+ white-space: nowrap;
95
+ }
96
+
97
+ /* ---------- 权限状态灯 ---------- */
98
+ .live-perms {
99
+ display: flex;
100
+ flex-wrap: wrap;
101
+ align-items: center;
102
+ gap: 10px;
103
+ padding: 6px 20px 2px;
104
+ }
105
+
106
+ .live-perm {
107
+ display: inline-flex;
108
+ align-items: center;
109
+ gap: 6px;
110
+ color: var(--text-tertiary);
111
+ font-size: 12px;
112
+ }
113
+
114
+ .live-dot {
115
+ width: 7px;
116
+ height: 7px;
117
+ border-radius: 50%;
118
+ background: var(--text-tertiary);
119
+ flex-shrink: 0;
120
+ }
121
+
122
+ .live-perm.is-ok {
123
+ color: var(--success);
124
+ }
125
+
126
+ .live-perm.is-ok .live-dot {
127
+ background: var(--success);
128
+ }
129
+
130
+ .live-perm.is-bad {
131
+ color: var(--danger);
132
+ }
133
+
134
+ .live-perm.is-bad .live-dot {
135
+ background: var(--danger);
136
+ }
137
+
138
+ .live-perm.is-wait {
139
+ color: var(--warning);
140
+ }
141
+
142
+ .live-perm.is-wait .live-dot {
143
+ background: var(--warning);
144
+ }
145
+
146
+ .live-perm-link {
147
+ padding: 0;
148
+ border: none;
149
+ background: transparent;
150
+ color: var(--accent);
151
+ font-family: inherit;
152
+ font-size: 12px;
153
+ cursor: pointer;
154
+ text-decoration: underline;
155
+ text-underline-offset: 3px;
156
+ }
157
+
158
+ /* ---------- 引导态(没授权绝不硬开摄像头) ---------- */
159
+ .live-guide {
160
+ flex: 1;
161
+ display: flex;
162
+ flex-direction: column;
163
+ padding: 24px 24px 20px;
164
+ }
165
+
166
+ .live-guide-head {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 10px;
170
+ color: var(--accent);
171
+ }
172
+
173
+ .live-guide-title {
174
+ margin: 0;
175
+ font-family: var(--font-serif);
176
+ font-size: 22px;
177
+ font-weight: 600;
178
+ letter-spacing: -0.01em;
179
+ }
180
+
181
+ .live-lead {
182
+ margin: 12px 0 18px;
183
+ color: var(--text-secondary);
184
+ font-size: 14px;
185
+ line-height: 1.65;
186
+ }
187
+
188
+ .live-guide-actions {
189
+ display: flex;
190
+ flex-wrap: wrap;
191
+ gap: 10px;
192
+ }
193
+
194
+ .live-primary {
195
+ height: 40px;
196
+ padding: 0 20px;
197
+ border: none;
198
+ border-radius: var(--radius-control);
199
+ background: var(--accent);
200
+ color: var(--bg);
201
+ font-family: inherit;
202
+ font-size: 14px;
203
+ cursor: pointer;
204
+ }
205
+
206
+ .live-primary:hover {
207
+ filter: brightness(0.94);
208
+ }
209
+
210
+ .live-secondary {
211
+ height: 40px;
212
+ padding: 0 16px;
213
+ border: 1px solid var(--border);
214
+ border-radius: var(--radius-control);
215
+ background: transparent;
216
+ color: var(--text-secondary);
217
+ font-family: inherit;
218
+ font-size: 13.5px;
219
+ cursor: pointer;
220
+ }
221
+
222
+ .live-secondary:hover {
223
+ background: var(--bg-elevated);
224
+ color: var(--text);
225
+ }
226
+
227
+ .live-guide-why {
228
+ margin: 16px 0 0;
229
+ color: var(--text-tertiary);
230
+ font-size: 12.5px;
231
+ line-height: 1.7;
232
+ }
233
+
234
+ .live-guide-hint {
235
+ margin-top: auto;
236
+ padding-top: 18px;
237
+ color: var(--danger);
238
+ font-size: 12.5px;
239
+ line-height: 1.6;
240
+ }
241
+
242
+ /* ---------- 采集控制 ---------- */
243
+ .live-controls {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: 12px;
247
+ padding: 12px 20px 0;
248
+ }
249
+
250
+ .live-start,
251
+ .live-stop {
252
+ height: 36px;
253
+ padding: 0 16px;
254
+ border-radius: var(--radius-control);
255
+ font-family: inherit;
256
+ font-size: 13.5px;
257
+ cursor: pointer;
258
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
259
+ }
260
+
261
+ .live-start {
262
+ border: none;
263
+ background: var(--accent);
264
+ color: var(--bg);
265
+ }
266
+
267
+ .live-start:hover:not(:disabled) {
268
+ filter: brightness(0.94);
269
+ }
270
+
271
+ .live-stop {
272
+ border: 1px solid var(--danger);
273
+ background: transparent;
274
+ color: var(--danger);
275
+ }
276
+
277
+ .live-stop:hover:not(:disabled) {
278
+ background: var(--danger);
279
+ color: var(--bg);
280
+ }
281
+
282
+ .live-start:disabled,
283
+ .live-stop:disabled {
284
+ opacity: 0.45;
285
+ cursor: default;
286
+ }
287
+
288
+ .live-interval {
289
+ display: inline-flex;
290
+ align-items: center;
291
+ gap: 6px;
292
+ font-size: 12.5px;
293
+ color: var(--text-secondary);
294
+ }
295
+
296
+ .live-interval-select {
297
+ height: 30px;
298
+ padding: 0 6px;
299
+ border: 1px solid var(--border);
300
+ border-radius: var(--radius-chip);
301
+ background: var(--bg-sunken);
302
+ color: var(--text);
303
+ font-family: inherit;
304
+ font-size: 12.5px;
305
+ outline: none;
306
+ cursor: pointer;
307
+ }
308
+
309
+ .live-meta {
310
+ margin: 8px 0 0;
311
+ padding: 0 20px;
312
+ color: var(--text-tertiary);
313
+ font-size: 12px;
314
+ line-height: 1.6;
315
+ font-variant-numeric: tabular-nums;
316
+ }
317
+
318
+ .live-error {
319
+ margin: 8px 20px 0;
320
+ color: var(--danger);
321
+ font-size: 12.5px;
322
+ line-height: 1.5;
323
+ }
324
+
325
+ /* ---------- 提问输入 ---------- */
326
+ .live-custom {
327
+ display: flex;
328
+ align-items: center;
329
+ gap: 8px;
330
+ margin: 12px 20px 0;
331
+ padding: 6px 6px 6px 12px;
332
+ border: 1px solid transparent;
333
+ border-radius: var(--radius-control);
334
+ background: var(--bg-sunken);
335
+ transition: border-color var(--dur) var(--ease);
336
+ }
337
+
338
+ .live-custom:focus-within {
339
+ border-color: var(--accent);
340
+ }
341
+
342
+ .live-input {
343
+ flex: 1;
344
+ min-width: 0;
345
+ border: none;
346
+ background: transparent;
347
+ color: var(--text);
348
+ font-family: inherit;
349
+ font-size: 13.5px;
350
+ outline: none;
351
+ cursor: text;
352
+ }
353
+
354
+ .live-input::placeholder {
355
+ color: var(--text-tertiary);
356
+ }
357
+
358
+ .live-input:disabled {
359
+ cursor: default;
360
+ }
361
+
362
+ .live-send {
363
+ flex-shrink: 0;
364
+ height: 28px;
365
+ padding: 0 12px;
366
+ border: none;
367
+ border-radius: var(--radius-chip);
368
+ background: var(--accent);
369
+ color: var(--bg);
370
+ font-family: inherit;
371
+ font-size: 13px;
372
+ cursor: pointer;
373
+ }
374
+
375
+ .live-send:disabled {
376
+ opacity: 0.4;
377
+ cursor: default;
378
+ }
379
+
380
+ /* ---------- 模型下拉(vision-only 过滤后的清单) ---------- */
381
+ .live-model-row {
382
+ display: flex;
383
+ align-items: center;
384
+ gap: 8px;
385
+ margin: 8px 20px 0;
386
+ }
387
+
388
+ .live-model-label {
389
+ font-size: 12px;
390
+ color: var(--text-tertiary);
391
+ white-space: nowrap;
392
+ }
393
+
394
+ .live-model {
395
+ flex: 1;
396
+ min-width: 0;
397
+ height: 30px;
398
+ padding: 0 8px;
399
+ border: 1px solid var(--border);
400
+ border-radius: var(--radius-chip);
401
+ background: var(--bg-sunken);
402
+ color: var(--text);
403
+ font-family: inherit;
404
+ font-size: 12.5px;
405
+ outline: none;
406
+ cursor: pointer;
407
+ }
408
+
409
+ .live-model:disabled {
410
+ opacity: 0.6;
411
+ cursor: default;
412
+ }
413
+
414
+ /* ---------- 回答区 ---------- */
415
+ .live-answer {
416
+ flex: 1;
417
+ min-height: 0;
418
+ display: flex;
419
+ flex-direction: column;
420
+ margin-top: 12px;
421
+ padding: 10px 20px 14px;
422
+ border-top: 1px solid var(--border);
423
+ }
424
+
425
+ .live-answer-body {
426
+ flex: 1;
427
+ min-height: 0;
428
+ overflow-y: auto;
429
+ }
430
+
431
+ .live-answer-text {
432
+ margin: 0;
433
+ color: var(--text);
434
+ font-size: 13.5px;
435
+ line-height: 1.65;
436
+ white-space: pre-wrap;
437
+ word-break: break-word;
438
+ user-select: text;
439
+ }
440
+
441
+ /* 流式呼吸光标(与看图问答同款;reduced-motion 由 theme.css 全局降级) */
442
+ .live-cursor {
443
+ display: inline-block;
444
+ width: 2px;
445
+ height: 1.05em;
446
+ margin-left: 3px;
447
+ border-radius: 1px;
448
+ background: var(--accent);
449
+ vertical-align: text-bottom;
450
+ animation: live-cursor-breathe 1s ease-in-out infinite;
451
+ }
452
+
453
+ @keyframes live-cursor-breathe {
454
+ 0%,
455
+ 100% {
456
+ opacity: 1;
457
+ }
458
+ 50% {
459
+ opacity: 0.15;
460
+ }
461
+ }
462
+
463
+ .live-answer-foot {
464
+ display: flex;
465
+ align-items: center;
466
+ justify-content: space-between;
467
+ gap: 12px;
468
+ margin-top: 10px;
469
+ }
470
+
471
+ .live-foot-hint {
472
+ font-size: 12px;
473
+ color: var(--text-tertiary);
474
+ }
css/markdown.css ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 消息内 Markdown 排版 + 代码块(配色全部映射到 theme.css 令牌) */
2
+
3
+ .md {
4
+ font-family: var(--font-sans);
5
+ font-size: 15px;
6
+ line-height: 1.75;
7
+ color: var(--text);
8
+ overflow-wrap: break-word;
9
+ }
10
+
11
+ .md > *:first-child {
12
+ margin-top: 0;
13
+ }
14
+
15
+ .md > *:last-child {
16
+ margin-bottom: 0;
17
+ }
18
+
19
+ .md p {
20
+ margin: 0 0 16px;
21
+ }
22
+
23
+ .md h1,
24
+ .md h2,
25
+ .md h3,
26
+ .md h4 {
27
+ font-family: var(--font-serif);
28
+ margin: 32px 0 12px;
29
+ }
30
+
31
+ .md h1 {
32
+ font-size: 24px;
33
+ }
34
+
35
+ .md h2 {
36
+ font-size: 20px;
37
+ }
38
+
39
+ .md h3 {
40
+ font-size: 17px;
41
+ }
42
+
43
+ .md h4 {
44
+ font-size: 15px;
45
+ }
46
+
47
+ .md ul,
48
+ .md ol {
49
+ margin: 0 0 16px;
50
+ padding-left: 24px;
51
+ }
52
+
53
+ .md li {
54
+ margin: 4px 0;
55
+ }
56
+
57
+ .md li > p {
58
+ margin: 0;
59
+ }
60
+
61
+ .md a {
62
+ color: var(--accent);
63
+ text-decoration: underline;
64
+ text-decoration-thickness: 1px;
65
+ text-underline-offset: 3px;
66
+ cursor: pointer;
67
+ }
68
+
69
+ .md blockquote {
70
+ margin: 0 0 16px;
71
+ padding: 4px 0 4px 16px;
72
+ border-left: 2px solid var(--border);
73
+ color: var(--text-secondary);
74
+ }
75
+
76
+ .md hr {
77
+ margin: 24px 0;
78
+ border: none;
79
+ border-top: 1px solid var(--border);
80
+ }
81
+
82
+ .md table {
83
+ width: 100%;
84
+ margin: 0 0 16px;
85
+ border-collapse: collapse;
86
+ font-size: 14px;
87
+ font-variant-numeric: tabular-nums;
88
+ }
89
+
90
+ .md th,
91
+ .md td {
92
+ padding: 8px 12px;
93
+ border-bottom: 1px solid var(--border);
94
+ text-align: left;
95
+ }
96
+
97
+ .md th {
98
+ font-weight: 600;
99
+ color: var(--text-secondary);
100
+ }
101
+
102
+ .md img {
103
+ max-width: 100%;
104
+ border-radius: var(--radius-control);
105
+ }
106
+
107
+ /* 行内代码 */
108
+ .md code {
109
+ padding: 2px 6px;
110
+ border-radius: var(--radius-control);
111
+ background: var(--bg-sunken);
112
+ font-family: var(--font-mono);
113
+ font-size: 0.92em;
114
+ }
115
+
116
+ /* ---------- 代码块 ---------- */
117
+ .code-block {
118
+ margin: 0 0 16px;
119
+ border: 1px solid var(--border);
120
+ border-radius: var(--radius-card);
121
+ background: var(--bg-sunken);
122
+ overflow: hidden;
123
+ }
124
+
125
+ .code-head {
126
+ display: flex;
127
+ align-items: center;
128
+ justify-content: space-between;
129
+ padding: 6px 10px 6px 14px;
130
+ border-bottom: 1px solid var(--border);
131
+ }
132
+
133
+ .code-lang {
134
+ font-family: var(--font-mono);
135
+ font-size: 12px;
136
+ color: var(--text-tertiary);
137
+ }
138
+
139
+ .code-copy {
140
+ display: inline-flex;
141
+ align-items: center;
142
+ gap: 6px;
143
+ height: 26px;
144
+ padding: 0 10px;
145
+ border: none;
146
+ border-radius: var(--radius-control);
147
+ background: transparent;
148
+ color: var(--text-secondary);
149
+ font-family: inherit;
150
+ font-size: 12px;
151
+ cursor: pointer;
152
+ transition: background-color var(--dur) var(--ease);
153
+ }
154
+
155
+ .code-copy:hover {
156
+ background: var(--bg-elevated);
157
+ color: var(--text);
158
+ }
159
+
160
+ .code-block pre {
161
+ margin: 0;
162
+ padding: 14px 16px;
163
+ overflow-x: auto;
164
+ font-family: var(--font-mono);
165
+ font-size: 13px;
166
+ line-height: 1.65;
167
+ }
168
+
169
+ .code-block pre code {
170
+ padding: 0;
171
+ border-radius: 0;
172
+ background: none;
173
+ font-size: 13px;
174
+ }
175
+
176
+ /* ---------- 语法高亮:highlight.js 语义 → 主题令牌 ---------- */
177
+ .hljs-comment,
178
+ .hljs-quote {
179
+ color: var(--text-tertiary);
180
+ font-style: italic;
181
+ }
182
+
183
+ .hljs-keyword,
184
+ .hljs-selector-tag,
185
+ .hljs-literal,
186
+ .hljs-type,
187
+ .hljs-name,
188
+ .hljs-tag {
189
+ color: var(--accent);
190
+ }
191
+
192
+ .hljs-string,
193
+ .hljs-regexp,
194
+ .hljs-addition {
195
+ color: var(--success);
196
+ }
197
+
198
+ .hljs-number,
199
+ .hljs-symbol,
200
+ .hljs-bullet,
201
+ .hljs-attr,
202
+ .hljs-attribute,
203
+ .hljs-selector-attr,
204
+ .hljs-selector-class,
205
+ .hljs-selector-id,
206
+ .hljs-variable,
207
+ .hljs-template-variable,
208
+ .hljs-link {
209
+ color: var(--warning);
210
+ }
211
+
212
+ .hljs-title,
213
+ .hljs-section,
214
+ .hljs-title.function_ {
215
+ color: var(--text);
216
+ font-weight: 600;
217
+ }
218
+
219
+ .hljs-built_in,
220
+ .hljs-class .hljs-title,
221
+ .hljs-namespace {
222
+ color: var(--text-secondary);
223
+ }
224
+
225
+ .hljs-meta {
226
+ color: var(--text-tertiary);
227
+ }
228
+
229
+ .hljs-emphasis {
230
+ font-style: italic;
231
+ }
232
+
233
+ .hljs-strong {
234
+ font-weight: 600;
235
+ }
236
+
237
+ .hljs-deletion {
238
+ color: var(--danger);
239
+ }
css/materials.css ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .materials-hub{height:100%;min-height:0;display:flex;flex-direction:column;color:var(--text)}
2
+ .materials-header{padding:20px 30px 14px;border-bottom:1px solid var(--border)}
3
+ .materials-header h1{margin:4px 0;font-size:21px;font-weight:600}
4
+ .materials-header p{margin:0;color:var(--text-secondary);font-size:12px;line-height:1.5}
5
+ .materials-tabs{display:flex;gap:4px;padding:8px 24px;border-bottom:1px solid var(--border);overflow-x:auto;flex:none}
6
+ .materials-tabs button{display:inline-flex;align-items:center;gap:7px;min-height:32px;padding:0 11px;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--text-secondary);font:500 11px var(--font-sans);white-space:nowrap;cursor:pointer}
7
+ .materials-tabs button:hover{background:var(--bg-elevated);color:var(--text)}
8
+ .materials-tabs button.is-active{border-color:var(--border);background:var(--bg-elevated);color:var(--accent)}
9
+ .materials-content{flex:1;min-height:0;overflow:auto}
10
+ .materials-content>.studio-feature{min-height:100%;padding:18px 28px 30px}
11
+ .materials-content>.xp{padding:18px 28px 30px}
12
+ @media(max-width:760px){.materials-header{padding:16px 18px 12px}.materials-tabs{padding:7px 12px}.materials-content>.studio-feature,.materials-content>.xp{padding:14px 14px 22px}}
css/mcp.css ADDED
@@ -0,0 +1,721 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* MCP 服务器 + 专家中心(Phase 5D):Warm Paper 全令牌配色。
2
+ 覆盖组件:McpPanel / ExpertsCenter / ExpertPicker,以及对话头部的专家入口。
3
+ 规则来自 docs/design-system.md:留白优先、衬线标题、语义色只出现在状态语境。 */
4
+
5
+ /* ---------- 通用面板骨架 ---------- */
6
+ .experts-center {
7
+ flex: 1;
8
+ min-width: 0;
9
+ overflow-y: auto;
10
+ padding: 36px 48px 48px;
11
+ }
12
+
13
+ .mcp-panel {
14
+ min-width: 0;
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 20px;
18
+ }
19
+
20
+ .panel-head {
21
+ display: flex;
22
+ align-items: flex-end;
23
+ justify-content: space-between;
24
+ gap: 16px;
25
+ flex-wrap: wrap;
26
+ margin-bottom: 4px;
27
+ }
28
+
29
+ .panel-title {
30
+ margin: 0;
31
+ font-family: var(--font-serif);
32
+ font-size: 30px;
33
+ font-weight: 600;
34
+ letter-spacing: -0.01em;
35
+ color: var(--text);
36
+ }
37
+
38
+ .panel-desc {
39
+ margin: 8px 0 0;
40
+ max-width: 60ch;
41
+ font-size: 13.5px;
42
+ line-height: 1.7;
43
+ color: var(--text-secondary);
44
+ }
45
+
46
+ .panel-error {
47
+ margin: 0;
48
+ padding: 10px 14px;
49
+ border: 1px solid var(--danger);
50
+ border-radius: var(--radius-control);
51
+ background: var(--bg-sunken);
52
+ color: var(--danger);
53
+ font-size: 13px;
54
+ line-height: 1.6;
55
+ }
56
+
57
+ .panel-empty {
58
+ margin: 0;
59
+ padding: 28px 0;
60
+ font-size: 13.5px;
61
+ line-height: 1.9;
62
+ color: var(--text-tertiary);
63
+ }
64
+
65
+ .inline-code {
66
+ padding: 1px 6px;
67
+ border-radius: 6px;
68
+ background: var(--bg-sunken);
69
+ color: var(--text-secondary);
70
+ font-family: var(--font-mono);
71
+ font-size: 12.5px;
72
+ }
73
+
74
+ /* ---------- 按钮(补充 App.css 的 .btn-primary/.btn-secondary)---------- */
75
+ .btn-ghost {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: 6px;
79
+ height: 32px;
80
+ padding: 0 12px;
81
+ border: 1px solid transparent;
82
+ border-radius: var(--radius-control);
83
+ background: transparent;
84
+ color: var(--text-secondary);
85
+ font-family: inherit;
86
+ font-size: 13px;
87
+ cursor: pointer;
88
+ transition: background-color var(--dur) var(--ease);
89
+ }
90
+
91
+ .btn-ghost:hover:not(:disabled) {
92
+ background: var(--bg-elevated);
93
+ color: var(--text);
94
+ }
95
+
96
+ .btn-ghost:disabled {
97
+ opacity: 0.55;
98
+ cursor: default;
99
+ }
100
+
101
+ .btn-danger {
102
+ display: inline-flex;
103
+ align-items: center;
104
+ gap: 6px;
105
+ height: 32px;
106
+ padding: 0 12px;
107
+ border: 1px solid var(--danger);
108
+ border-radius: var(--radius-control);
109
+ background: transparent;
110
+ color: var(--danger);
111
+ font-family: inherit;
112
+ font-size: 13px;
113
+ cursor: pointer;
114
+ transition: background-color var(--dur) var(--ease);
115
+ }
116
+
117
+ .btn-danger:hover {
118
+ background: var(--bg-elevated);
119
+ }
120
+
121
+ .btn-icon {
122
+ display: inline-grid;
123
+ place-items: center;
124
+ width: 28px;
125
+ height: 28px;
126
+ border: 1px solid transparent;
127
+ border-radius: var(--radius-control);
128
+ background: transparent;
129
+ color: var(--text-secondary);
130
+ cursor: pointer;
131
+ transition: background-color var(--dur) var(--ease);
132
+ }
133
+
134
+ .btn-icon:hover {
135
+ background: var(--bg-elevated);
136
+ color: var(--text);
137
+ }
138
+
139
+ .mcp-panel .btn-primary,
140
+ .experts-center .btn-primary {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ gap: 6px;
144
+ height: 36px;
145
+ padding: 0 18px;
146
+ }
147
+
148
+ /* ---------- 表单 ---------- */
149
+ .mcp-form,
150
+ .expert-form {
151
+ display: flex;
152
+ flex-direction: column;
153
+ gap: 16px;
154
+ padding: 20px 22px;
155
+ border: 1px solid var(--border);
156
+ border-radius: var(--radius-card);
157
+ background: var(--bg-elevated);
158
+ }
159
+
160
+ .mcp-form-title {
161
+ margin: 0;
162
+ font-family: var(--font-serif);
163
+ font-size: 19px;
164
+ font-weight: 600;
165
+ color: var(--text);
166
+ }
167
+
168
+ .field {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: 6px;
172
+ }
173
+
174
+ .field-label {
175
+ font-size: 13px;
176
+ font-weight: 500;
177
+ color: var(--text-secondary);
178
+ }
179
+
180
+ .field-note {
181
+ margin: 0;
182
+ font-size: 12.5px;
183
+ line-height: 1.7;
184
+ color: var(--text-tertiary);
185
+ }
186
+
187
+ .field-input {
188
+ width: 100%;
189
+ padding: 9px 12px;
190
+ border: 1px solid transparent;
191
+ border-radius: var(--radius-control);
192
+ background: var(--bg-sunken);
193
+ color: var(--text);
194
+ font-family: inherit;
195
+ font-size: 13.5px;
196
+ line-height: 1.6;
197
+ resize: vertical;
198
+ transition: border-color var(--dur) var(--ease);
199
+ }
200
+
201
+ .field-input:focus {
202
+ outline: none;
203
+ border-color: var(--accent);
204
+ }
205
+
206
+ .field-mono {
207
+ font-family: var(--font-mono);
208
+ font-size: 12.5px;
209
+ }
210
+
211
+ .mcp-env-row {
212
+ display: grid;
213
+ grid-template-columns: 1fr 1fr auto;
214
+ gap: 8px;
215
+ align-items: center;
216
+ }
217
+
218
+ .mcp-form-actions {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 10px;
222
+ }
223
+
224
+ .expert-form-row {
225
+ display: grid;
226
+ grid-template-columns: 1fr 1.2fr;
227
+ gap: 16px;
228
+ align-items: start;
229
+ }
230
+
231
+ .expert-emoji-grid {
232
+ display: flex;
233
+ flex-wrap: wrap;
234
+ gap: 6px;
235
+ }
236
+
237
+ .expert-emoji {
238
+ display: inline-grid;
239
+ place-items: center;
240
+ width: 34px;
241
+ height: 34px;
242
+ border: 1px solid var(--border);
243
+ border-radius: var(--radius-control);
244
+ background: var(--bg-sunken);
245
+ font-size: 17px;
246
+ cursor: pointer;
247
+ transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
248
+ }
249
+
250
+ .expert-emoji:hover {
251
+ background: var(--bg-elevated);
252
+ }
253
+
254
+ .expert-emoji.is-active {
255
+ border-color: var(--accent);
256
+ background: var(--accent-soft);
257
+ }
258
+
259
+ .expert-prompt {
260
+ font-family: var(--font-sans);
261
+ line-height: 1.75;
262
+ }
263
+
264
+ /* ---------- MCP 服务器卡片 ---------- */
265
+ .mcp-list {
266
+ display: flex;
267
+ flex-direction: column;
268
+ gap: 14px;
269
+ margin: 0;
270
+ padding: 0;
271
+ list-style: none;
272
+ }
273
+
274
+ .mcp-card {
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 10px;
278
+ padding: 18px 20px;
279
+ border: 1px solid var(--border);
280
+ border-radius: var(--radius-card);
281
+ background: var(--bg-elevated);
282
+ }
283
+
284
+ .mcp-card-head {
285
+ display: flex;
286
+ align-items: center;
287
+ justify-content: space-between;
288
+ gap: 12px;
289
+ flex-wrap: wrap;
290
+ }
291
+
292
+ .mcp-card-title {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: 10px;
296
+ flex-wrap: wrap;
297
+ }
298
+
299
+ .mcp-name {
300
+ font-family: var(--font-serif);
301
+ font-size: 18px;
302
+ font-weight: 600;
303
+ color: var(--text);
304
+ }
305
+
306
+ .mcp-status {
307
+ display: inline-flex;
308
+ align-items: center;
309
+ gap: 6px;
310
+ font-size: 12.5px;
311
+ color: var(--text-secondary);
312
+ }
313
+
314
+ .mcp-status-dot {
315
+ width: 8px;
316
+ height: 8px;
317
+ border-radius: 50%;
318
+ background: var(--text-tertiary);
319
+ }
320
+
321
+ .mcp-status.is-connected .mcp-status-dot {
322
+ background: var(--success);
323
+ }
324
+
325
+ .mcp-status.is-connecting .mcp-status-dot {
326
+ background: var(--warning);
327
+ }
328
+
329
+ .mcp-status.is-error .mcp-status-dot {
330
+ background: var(--danger);
331
+ }
332
+
333
+ .mcp-tools-count {
334
+ font-size: 12.5px;
335
+ color: var(--text-tertiary);
336
+ font-variant-numeric: tabular-nums;
337
+ }
338
+
339
+ .mcp-card-actions {
340
+ display: flex;
341
+ align-items: center;
342
+ gap: 4px;
343
+ flex-wrap: wrap;
344
+ }
345
+
346
+ .mcp-command {
347
+ margin: 0;
348
+ overflow-wrap: anywhere;
349
+ }
350
+
351
+ .mcp-enabled {
352
+ display: inline-flex;
353
+ align-items: center;
354
+ gap: 8px;
355
+ font-size: 13px;
356
+ color: var(--text-secondary);
357
+ cursor: pointer;
358
+ }
359
+
360
+ .mcp-error {
361
+ margin: 0;
362
+ font-size: 12.5px;
363
+ line-height: 1.7;
364
+ color: var(--danger);
365
+ }
366
+
367
+ .mcp-confirm {
368
+ display: inline-flex;
369
+ align-items: center;
370
+ gap: 6px;
371
+ font-size: 12.5px;
372
+ color: var(--text-secondary);
373
+ }
374
+
375
+ /* ---------- MCP 工具清单 ---------- */
376
+ .mcp-tools {
377
+ border-top: 1px solid var(--border);
378
+ padding-top: 10px;
379
+ }
380
+
381
+ .mcp-tools-toggle {
382
+ display: inline-flex;
383
+ align-items: center;
384
+ gap: 4px;
385
+ padding: 4px 6px 4px 0;
386
+ border: none;
387
+ background: transparent;
388
+ color: var(--text-secondary);
389
+ font-family: inherit;
390
+ font-size: 13px;
391
+ cursor: pointer;
392
+ }
393
+
394
+ .mcp-tools-toggle:hover {
395
+ color: var(--text);
396
+ }
397
+
398
+ .mcp-tool-list {
399
+ display: flex;
400
+ flex-direction: column;
401
+ margin: 8px 0 0;
402
+ padding: 0;
403
+ list-style: none;
404
+ }
405
+
406
+ .mcp-tool {
407
+ display: flex;
408
+ align-items: center;
409
+ justify-content: space-between;
410
+ gap: 16px;
411
+ padding: 9px 0;
412
+ border-bottom: 1px solid var(--border);
413
+ }
414
+
415
+ .mcp-tool:last-child {
416
+ border-bottom: none;
417
+ }
418
+
419
+ .mcp-tool-info {
420
+ display: flex;
421
+ flex-direction: column;
422
+ gap: 2px;
423
+ min-width: 0;
424
+ }
425
+
426
+ .mcp-tool-name {
427
+ font-family: var(--font-mono);
428
+ font-size: 12.5px;
429
+ color: var(--text);
430
+ overflow-wrap: anywhere;
431
+ }
432
+
433
+ .mcp-tool-desc {
434
+ font-size: 12.5px;
435
+ line-height: 1.6;
436
+ color: var(--text-secondary);
437
+ overflow-wrap: anywhere;
438
+ }
439
+
440
+ .mcp-tool-toggle {
441
+ display: inline-flex;
442
+ align-items: center;
443
+ gap: 6px;
444
+ flex-shrink: 0;
445
+ padding: 5px 10px;
446
+ border: 1px solid var(--border);
447
+ border-radius: var(--radius-control);
448
+ background: var(--bg-sunken);
449
+ color: var(--text-secondary);
450
+ font-size: 12.5px;
451
+ cursor: pointer;
452
+ transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
453
+ }
454
+
455
+ .mcp-tool-toggle input {
456
+ accent-color: var(--accent);
457
+ }
458
+
459
+ .mcp-tool-toggle.is-on {
460
+ border-color: var(--success);
461
+ background: var(--bg-elevated);
462
+ color: var(--text);
463
+ }
464
+
465
+ /* ---------- 专家中心 ---------- */
466
+ .experts-tabs {
467
+ display: inline-flex;
468
+ gap: 4px;
469
+ padding: 3px;
470
+ border: 1px solid var(--border);
471
+ border-radius: var(--radius-control);
472
+ background: var(--bg-sunken);
473
+ }
474
+
475
+ .experts-tab {
476
+ height: 30px;
477
+ padding: 0 14px;
478
+ border: none;
479
+ border-radius: calc(var(--radius-control) - 2px);
480
+ background: transparent;
481
+ color: var(--text-secondary);
482
+ font-family: inherit;
483
+ font-size: 13px;
484
+ cursor: pointer;
485
+ transition: background-color var(--dur) var(--ease);
486
+ }
487
+
488
+ .experts-tab.is-active {
489
+ background: var(--bg-elevated);
490
+ color: var(--text);
491
+ }
492
+
493
+ .experts-actions {
494
+ margin-bottom: 16px;
495
+ }
496
+
497
+ .expert-grid {
498
+ display: grid;
499
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
500
+ gap: 16px;
501
+ margin: 0;
502
+ padding: 0;
503
+ list-style: none;
504
+ }
505
+
506
+ /* hover 统一(描边加深 + 轻上浮)在 App.css;transition 也集中在那里定义 */
507
+ .expert-card {
508
+ display: flex;
509
+ gap: 14px;
510
+ padding: 18px 20px;
511
+ border: 1px solid var(--border);
512
+ border-radius: var(--radius-card);
513
+ background: var(--bg-elevated);
514
+ }
515
+
516
+ .expert-card.is-active {
517
+ border-color: var(--accent);
518
+ }
519
+
520
+ .expert-card-emoji {
521
+ font-size: 30px;
522
+ line-height: 1.2;
523
+ }
524
+
525
+ .expert-card-body {
526
+ display: flex;
527
+ flex-direction: column;
528
+ gap: 6px;
529
+ min-width: 0;
530
+ }
531
+
532
+ .expert-card-name {
533
+ display: flex;
534
+ align-items: center;
535
+ gap: 8px;
536
+ margin: 0;
537
+ font-family: var(--font-serif);
538
+ font-size: 18px;
539
+ font-weight: 600;
540
+ color: var(--text);
541
+ }
542
+
543
+ .expert-card-desc {
544
+ margin: 0;
545
+ font-size: 13px;
546
+ line-height: 1.7;
547
+ color: var(--text-secondary);
548
+ }
549
+
550
+ .expert-card-model {
551
+ margin: 0;
552
+ font-size: 12.5px;
553
+ color: var(--text-tertiary);
554
+ }
555
+
556
+ .expert-card-actions {
557
+ display: flex;
558
+ align-items: center;
559
+ gap: 4px;
560
+ flex-wrap: wrap;
561
+ margin-top: 4px;
562
+ }
563
+
564
+ /* 状态徽章:与全站徽章同尺寸同字重 */
565
+ .expert-badge {
566
+ padding: 2px 8px;
567
+ border-radius: 999px;
568
+ background: var(--bg-sunken);
569
+ color: var(--text-tertiary);
570
+ font-family: var(--font-sans);
571
+ font-size: 12px;
572
+ font-weight: 500;
573
+ }
574
+
575
+ .expert-badge.is-custom {
576
+ color: var(--text-secondary);
577
+ }
578
+
579
+ .experts-foot {
580
+ margin: 18px 0 0;
581
+ font-size: 12.5px;
582
+ line-height: 1.7;
583
+ color: var(--text-tertiary);
584
+ }
585
+
586
+ /* ---------- 对话头部的专家选择器 ---------- */
587
+ .chat-header {
588
+ display: flex;
589
+ align-items: center;
590
+ justify-content: space-between;
591
+ gap: 12px;
592
+ padding: 10px 24px;
593
+ border-bottom: 1px solid var(--border);
594
+ }
595
+
596
+ .chat-header-title {
597
+ margin: 0;
598
+ font-family: var(--font-serif);
599
+ font-size: 15px;
600
+ font-weight: 600;
601
+ color: var(--text-secondary);
602
+ }
603
+
604
+ .expert-picker {
605
+ position: relative;
606
+ }
607
+
608
+ .expert-picker-trigger {
609
+ display: inline-flex;
610
+ align-items: center;
611
+ gap: 7px;
612
+ height: 32px;
613
+ padding: 0 12px;
614
+ border: 1px solid var(--border);
615
+ border-radius: var(--radius-control);
616
+ background: transparent;
617
+ color: var(--text);
618
+ font-family: inherit;
619
+ font-size: 13px;
620
+ cursor: pointer;
621
+ transition: background-color var(--dur) var(--ease);
622
+ }
623
+
624
+ .expert-picker-trigger:hover {
625
+ background: var(--bg-elevated);
626
+ }
627
+
628
+ .expert-picker-emoji {
629
+ font-size: 15px;
630
+ }
631
+
632
+ .expert-menu {
633
+ position: absolute;
634
+ top: calc(100% + 6px);
635
+ right: 0;
636
+ z-index: 20;
637
+ width: 300px;
638
+ max-height: 360px;
639
+ overflow-y: auto;
640
+ padding: 10px;
641
+ border: 1px solid var(--border);
642
+ border-radius: var(--radius-float);
643
+ background: var(--bg-elevated);
644
+ box-shadow: var(--shadow-float);
645
+ }
646
+
647
+ .expert-menu-title {
648
+ margin: 2px 6px 8px;
649
+ font-size: 12px;
650
+ color: var(--text-tertiary);
651
+ }
652
+
653
+ .expert-option {
654
+ display: flex;
655
+ align-items: flex-start;
656
+ gap: 10px;
657
+ width: 100%;
658
+ padding: 8px 10px;
659
+ border: none;
660
+ border-radius: var(--radius-control);
661
+ background: transparent;
662
+ color: var(--text);
663
+ font-family: inherit;
664
+ text-align: left;
665
+ cursor: pointer;
666
+ transition: background-color var(--dur) var(--ease);
667
+ }
668
+
669
+ .expert-option:hover {
670
+ background: var(--accent-soft);
671
+ }
672
+
673
+ .expert-option.is-active {
674
+ background: var(--accent-soft);
675
+ }
676
+
677
+ .expert-option-emoji {
678
+ font-size: 18px;
679
+ line-height: 1.3;
680
+ }
681
+
682
+ .expert-option-body {
683
+ display: flex;
684
+ flex-direction: column;
685
+ gap: 2px;
686
+ min-width: 0;
687
+ }
688
+
689
+ .expert-option-name {
690
+ display: flex;
691
+ align-items: center;
692
+ gap: 6px;
693
+ font-size: 13.5px;
694
+ font-weight: 500;
695
+ }
696
+
697
+ .expert-option-desc {
698
+ font-size: 12px;
699
+ line-height: 1.6;
700
+ color: var(--text-secondary);
701
+ }
702
+
703
+ .expert-menu-foot {
704
+ display: flex;
705
+ align-items: center;
706
+ gap: 6px;
707
+ margin: 8px 6px 2px;
708
+ font-size: 12px;
709
+ color: var(--text-tertiary);
710
+ }
711
+
712
+ @media (prefers-reduced-motion: reduce) {
713
+ .mcp-card,
714
+ .expert-card,
715
+ .expert-menu,
716
+ .expert-option,
717
+ .btn-ghost,
718
+ .mcp-tool-toggle {
719
+ transition: none;
720
+ }
721
+ }
css/memory.css ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 记忆板块(契约 7A):Warm Paper 全令牌配色,规则来自 docs/design-system.md。
2
+ 覆盖组件:MemoryCenter——卡片墙 + 行内表单;语义色只用于 kind 徽章语境。 */
3
+
4
+ .memory-center {
5
+ flex: 1;
6
+ min-width: 0;
7
+ overflow-y: auto;
8
+ padding: 36px 48px 48px;
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 18px;
12
+ }
13
+
14
+ .memory-actions {
15
+ margin-bottom: 4px;
16
+ }
17
+
18
+ /* ---------- 行内表单(新增/编辑)---------- */
19
+ .memory-form {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 14px;
23
+ padding: 18px 20px;
24
+ border: 1px solid var(--border);
25
+ border-radius: var(--radius-card);
26
+ background: var(--bg-elevated);
27
+ }
28
+
29
+ .memory-form-title {
30
+ margin: 0;
31
+ font-family: var(--font-serif);
32
+ font-size: 17px;
33
+ font-weight: 600;
34
+ color: var(--text);
35
+ }
36
+
37
+ .memory-form-row {
38
+ display: grid;
39
+ grid-template-columns: 140px 1fr;
40
+ gap: 12px;
41
+ }
42
+
43
+ .memory-content-input {
44
+ resize: vertical;
45
+ min-height: 84px;
46
+ }
47
+
48
+ .memory-form-actions {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 8px;
52
+ }
53
+
54
+ /* ---------- 卡片墙 ---------- */
55
+ .memory-grid {
56
+ display: grid;
57
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
58
+ gap: 16px;
59
+ margin: 0;
60
+ padding: 0;
61
+ list-style: none;
62
+ }
63
+
64
+ .memory-card {
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 6px;
68
+ padding: 16px 18px;
69
+ border: 1px solid var(--border);
70
+ border-radius: var(--radius-card);
71
+ background: var(--bg-elevated);
72
+ }
73
+
74
+ .memory-card-top {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: space-between;
78
+ gap: 8px;
79
+ }
80
+
81
+ /* kind 徽章:语义色只出现在类型语境;底色统一 sunken,深浅色主题都稳 */
82
+ .memory-badge {
83
+ padding: 2px 10px;
84
+ border-radius: 999px;
85
+ background: var(--bg-sunken);
86
+ font-size: 12px;
87
+ font-weight: 500;
88
+ }
89
+
90
+ .memory-badge.is-preference {
91
+ color: var(--accent);
92
+ }
93
+
94
+ .memory-badge.is-project {
95
+ color: var(--success);
96
+ }
97
+
98
+ .memory-badge.is-device {
99
+ color: var(--warning);
100
+ }
101
+
102
+ .memory-badge.is-custom {
103
+ color: var(--text-secondary);
104
+ }
105
+
106
+ .memory-pin {
107
+ display: inline-flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ width: 28px;
111
+ height: 28px;
112
+ padding: 0;
113
+ border: 1px solid transparent;
114
+ border-radius: var(--radius-chip);
115
+ background: transparent;
116
+ color: var(--text-tertiary);
117
+ cursor: pointer;
118
+ transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
119
+ }
120
+
121
+ .memory-pin:hover {
122
+ color: var(--text-secondary);
123
+ border-color: var(--border);
124
+ }
125
+
126
+ .memory-pin.is-active {
127
+ color: var(--accent);
128
+ }
129
+
130
+ .memory-card-title {
131
+ margin: 0;
132
+ font-family: var(--font-serif);
133
+ font-size: 16.5px;
134
+ font-weight: 600;
135
+ color: var(--text);
136
+ overflow-wrap: anywhere;
137
+ }
138
+
139
+ .memory-card-content {
140
+ margin: 0;
141
+ font-size: 13px;
142
+ line-height: 1.7;
143
+ color: var(--text-secondary);
144
+ overflow: hidden;
145
+ display: -webkit-box;
146
+ -webkit-box-orient: vertical;
147
+ -webkit-line-clamp: 2;
148
+ line-clamp: 2;
149
+ overflow-wrap: anywhere;
150
+ }
151
+
152
+ .memory-card-actions {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 4px;
156
+ flex-wrap: wrap;
157
+ margin-top: 4px;
158
+ }
159
+
160
+ /* 删除两段确认(与专家板块同款交互) */
161
+ .memory-confirm {
162
+ display: inline-flex;
163
+ align-items: center;
164
+ gap: 8px;
165
+ font-size: 12.5px;
166
+ color: var(--text-secondary);
167
+ }
168
+
169
+ /* ---------- 空态引导 ---------- */
170
+ .memory-empty {
171
+ display: flex;
172
+ flex-direction: column;
173
+ align-items: flex-start;
174
+ gap: 8px;
175
+ padding: 32px 24px;
176
+ border: 1px dashed var(--border);
177
+ border-radius: var(--radius-card);
178
+ background: var(--bg-elevated);
179
+ }
180
+
181
+ .memory-empty-title {
182
+ margin: 0;
183
+ font-family: var(--font-serif);
184
+ font-size: 19px;
185
+ font-weight: 600;
186
+ color: var(--text);
187
+ }
188
+
189
+ .memory-empty-hint {
190
+ margin: 0 0 6px;
191
+ max-width: 56ch;
192
+ font-size: 13px;
193
+ line-height: 1.7;
194
+ color: var(--text-secondary);
195
+ }
196
+
197
+ .memory-foot {
198
+ margin: 0;
199
+ font-size: 12.5px;
200
+ line-height: 1.7;
201
+ color: var(--text-tertiary);
202
+ }
203
+
204
+ @media (max-width: 720px) {
205
+ .memory-center {
206
+ padding: 24px 20px 32px;
207
+ }
208
+
209
+ .memory-form-row {
210
+ grid-template-columns: 1fr;
211
+ }
212
+ }
css/msgboard.css ADDED
@@ -0,0 +1,464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 模型留言区(契约 26B · 工作台「留言板」tab)——Warm Paper 令牌,零硬编码色:
2
+ 所有颜色走 theme.css 变量(深浅色 / 双皮肤自动跟随)。kind 分色只用
3
+ accent(发现·陶土)/ warning(问题·土金)/ success(回答·苔绿)三个语义令牌;
4
+ 动效克制:只用 --dur/--ease 的边框与背景过渡,无位移无闪烁。 */
5
+
6
+ .msgboard {
7
+ flex: 1;
8
+ min-width: 0;
9
+ overflow-y: auto;
10
+ padding: 36px 48px 48px;
11
+ }
12
+
13
+ /* ── 页头 ───────────────────────────────────────────────────────── */
14
+
15
+ .msgboard-head {
16
+ display: flex;
17
+ align-items: flex-end;
18
+ justify-content: space-between;
19
+ gap: 16px;
20
+ margin-bottom: 20px;
21
+ }
22
+
23
+ .msgboard-title {
24
+ font-family: var(--font-serif);
25
+ font-size: 26px;
26
+ font-weight: 600;
27
+ letter-spacing: -0.01em;
28
+ color: var(--text);
29
+ margin: 0;
30
+ }
31
+
32
+ .msgboard-sub {
33
+ margin: 6px 0 0;
34
+ font-size: 13.5px;
35
+ line-height: 1.65;
36
+ color: var(--text-secondary);
37
+ max-width: 68ch;
38
+ }
39
+
40
+ .msgboard-sub strong {
41
+ color: var(--text);
42
+ font-weight: 600;
43
+ }
44
+
45
+ .msgboard-muted {
46
+ font-size: 13px;
47
+ line-height: 1.6;
48
+ color: var(--text-secondary);
49
+ }
50
+
51
+ .msgboard-notice {
52
+ margin: 0 0 16px;
53
+ padding: 10px 14px;
54
+ border: 1px solid var(--border);
55
+ border-radius: var(--radius-control);
56
+ background: var(--bg-elevated);
57
+ font-size: 13.5px;
58
+ line-height: 1.6;
59
+ color: var(--text);
60
+ }
61
+
62
+ /* ── 按钮 ───────────────────────────────────────────────────────── */
63
+
64
+ .msgboard-primary,
65
+ .msgboard-secondary,
66
+ .msgboard-ghost {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ gap: 7px;
70
+ font-family: var(--font-sans);
71
+ font-size: 13.5px;
72
+ font-weight: 550;
73
+ border-radius: var(--radius-control);
74
+ padding: 9px 16px;
75
+ cursor: pointer;
76
+ transition:
77
+ background var(--dur) var(--ease),
78
+ border-color var(--dur) var(--ease),
79
+ color var(--dur) var(--ease);
80
+ }
81
+
82
+ .msgboard-primary {
83
+ color: var(--bg);
84
+ background: var(--accent);
85
+ border: 1px solid var(--accent);
86
+ }
87
+
88
+ .msgboard-primary:hover:not(:disabled) {
89
+ background: var(--accent-hover, var(--accent));
90
+ border-color: var(--accent-hover, var(--accent));
91
+ }
92
+
93
+ .msgboard-secondary {
94
+ color: var(--text);
95
+ background: var(--bg-elevated);
96
+ border: 1px solid var(--border);
97
+ }
98
+
99
+ .msgboard-secondary:hover:not(:disabled) {
100
+ border-color: var(--accent);
101
+ color: var(--accent);
102
+ }
103
+
104
+ .msgboard-ghost {
105
+ color: var(--text-secondary);
106
+ background: transparent;
107
+ border: 1px solid transparent;
108
+ padding: 7px 10px;
109
+ flex-shrink: 0;
110
+ }
111
+
112
+ .msgboard-ghost:hover:not(:disabled) {
113
+ color: var(--text);
114
+ border-color: var(--border);
115
+ background: var(--bg-elevated);
116
+ }
117
+
118
+ .msgboard-primary:disabled,
119
+ .msgboard-secondary:disabled,
120
+ .msgboard-ghost:disabled {
121
+ opacity: 0.45;
122
+ cursor: default;
123
+ }
124
+
125
+ /* ── 工具条 ─────────────────────────────────────────────────────── */
126
+
127
+ .msgboard-toolbar {
128
+ background: var(--bg-elevated);
129
+ border: 1px solid var(--border);
130
+ border-radius: var(--radius-card);
131
+ padding: 18px 22px;
132
+ margin-bottom: 20px;
133
+ }
134
+
135
+ .msgboard-toolbar-main {
136
+ display: flex;
137
+ gap: 10px;
138
+ flex-wrap: wrap;
139
+ }
140
+
141
+ .msgboard-toolbar-hint {
142
+ margin: 12px 0 0;
143
+ font-size: 12.5px;
144
+ color: var(--text-secondary);
145
+ font-variant-numeric: tabular-nums;
146
+ }
147
+
148
+ .msgboard-outcome {
149
+ margin: 8px 0 0;
150
+ padding: 8px 12px;
151
+ border-left: 2px solid var(--accent);
152
+ font-size: 12.5px;
153
+ line-height: 1.6;
154
+ color: var(--text-secondary);
155
+ font-variant-numeric: tabular-nums;
156
+ }
157
+
158
+ /* ── 贴条区 ─────────────────────────────────────────────────────── */
159
+
160
+ .msgboard-composer {
161
+ background: var(--bg-elevated);
162
+ border: 1px solid var(--border);
163
+ border-radius: var(--radius-card);
164
+ padding: 18px 22px 20px;
165
+ margin-bottom: 24px;
166
+ }
167
+
168
+ .msgboard-kind-row {
169
+ display: flex;
170
+ gap: 8px;
171
+ margin-bottom: 14px;
172
+ }
173
+
174
+ .msgboard-kind {
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: 6px;
178
+ font-family: var(--font-sans);
179
+ font-size: 12.5px;
180
+ font-weight: 550;
181
+ padding: 6px 12px;
182
+ border-radius: var(--radius-chip);
183
+ border: 1px solid var(--border);
184
+ background: var(--bg-sunken);
185
+ color: var(--text-secondary);
186
+ cursor: pointer;
187
+ transition:
188
+ border-color var(--dur) var(--ease),
189
+ color var(--dur) var(--ease),
190
+ background var(--dur) var(--ease);
191
+ }
192
+
193
+ /* kind 三态分色:未选中只留图标色,选中加 accent 描边 + 字色 */
194
+ .msgboard-kind.is-finding svg {
195
+ color: var(--accent);
196
+ }
197
+ .msgboard-kind.is-question svg {
198
+ color: var(--warning);
199
+ }
200
+ .msgboard-kind.is-answer svg {
201
+ color: var(--success);
202
+ }
203
+
204
+ .msgboard-kind.is-on {
205
+ background: var(--bg-elevated);
206
+ color: var(--text);
207
+ }
208
+ .msgboard-kind.is-finding.is-on {
209
+ border-color: var(--accent);
210
+ }
211
+ .msgboard-kind.is-question.is-on {
212
+ border-color: var(--warning);
213
+ }
214
+ .msgboard-kind.is-answer.is-on {
215
+ border-color: var(--success);
216
+ }
217
+
218
+ .msgboard-composer-row {
219
+ display: flex;
220
+ gap: 10px;
221
+ align-items: flex-start;
222
+ }
223
+
224
+ .msgboard-author {
225
+ flex: 0 0 140px;
226
+ font-family: var(--font-sans);
227
+ font-size: 13px;
228
+ color: var(--text);
229
+ background: var(--bg-sunken);
230
+ border: 1px solid transparent;
231
+ border-radius: var(--radius-control);
232
+ padding: 10px 12px;
233
+ transition: border-color var(--dur) var(--ease);
234
+ }
235
+
236
+ .msgboard-author:focus-visible {
237
+ outline: none;
238
+ border-color: var(--accent);
239
+ }
240
+
241
+ .msgboard-input {
242
+ flex: 1;
243
+ min-width: 0;
244
+ font-family: var(--font-sans);
245
+ font-size: 14px;
246
+ line-height: 1.65;
247
+ color: var(--text);
248
+ background: var(--bg-sunken);
249
+ border: 1px solid transparent;
250
+ border-radius: var(--radius-control);
251
+ padding: 10px 12px;
252
+ resize: vertical;
253
+ min-height: 72px;
254
+ transition: border-color var(--dur) var(--ease);
255
+ }
256
+
257
+ .msgboard-input::placeholder {
258
+ color: var(--text-tertiary);
259
+ }
260
+
261
+ .msgboard-input:focus-visible {
262
+ outline: none;
263
+ border-color: var(--accent);
264
+ }
265
+
266
+ .msgboard-answer-target {
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 8px;
270
+ margin-top: 12px;
271
+ font-size: 13px;
272
+ color: var(--text-secondary);
273
+ }
274
+
275
+ .msgboard-answer-target select {
276
+ flex: 1;
277
+ min-width: 0;
278
+ font-family: var(--font-sans);
279
+ font-size: 13px;
280
+ color: var(--text);
281
+ background: var(--bg-sunken);
282
+ border: 1px solid var(--border);
283
+ border-radius: var(--radius-control);
284
+ padding: 8px 10px;
285
+ }
286
+
287
+ .msgboard-answer-target select:focus-visible {
288
+ outline: none;
289
+ border-color: var(--accent);
290
+ }
291
+
292
+ .msgboard-composer-actions {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: 12px;
296
+ margin-top: 14px;
297
+ }
298
+
299
+ /* ── 留言流 ─────────────────────────────────────────────────────── */
300
+
301
+ .msgboard-stream {
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 14px;
305
+ }
306
+
307
+ .msgboard-empty {
308
+ padding: 28px 22px;
309
+ border: 1px dashed var(--border);
310
+ border-radius: var(--radius-card);
311
+ font-size: 13.5px;
312
+ line-height: 1.7;
313
+ color: var(--text-secondary);
314
+ text-align: center;
315
+ }
316
+
317
+ .msgboard-card {
318
+ background: var(--bg-elevated);
319
+ border: 1px solid var(--border);
320
+ border-left: 3px solid var(--border);
321
+ border-radius: var(--radius-card);
322
+ padding: 14px 18px 16px;
323
+ transition: border-color var(--dur) var(--ease);
324
+ }
325
+
326
+ /* kind 分色:只染左侧竖条(克制,不整卡染色) */
327
+ .msgboard-card.is-finding {
328
+ border-left-color: var(--accent);
329
+ }
330
+ .msgboard-card.is-question {
331
+ border-left-color: var(--warning);
332
+ }
333
+ .msgboard-card.is-answer {
334
+ border-left-color: var(--success);
335
+ }
336
+
337
+ .msgboard-card-head {
338
+ display: flex;
339
+ align-items: center;
340
+ gap: 8px;
341
+ margin-bottom: 8px;
342
+ }
343
+
344
+ .msgboard-badge {
345
+ display: inline-flex;
346
+ align-items: center;
347
+ gap: 4px;
348
+ font-size: 11.5px;
349
+ font-weight: 600;
350
+ padding: 2px 8px;
351
+ border-radius: var(--radius-chip);
352
+ border: 1px solid var(--border);
353
+ color: var(--text-secondary);
354
+ }
355
+
356
+ .msgboard-badge.is-finding {
357
+ color: var(--accent);
358
+ border-color: var(--accent-soft);
359
+ background: var(--accent-soft);
360
+ }
361
+ .msgboard-badge.is-question {
362
+ color: var(--warning);
363
+ }
364
+ .msgboard-badge.is-answer {
365
+ color: var(--success);
366
+ }
367
+
368
+ .msgboard-author-name {
369
+ font-size: 13px;
370
+ font-weight: 600;
371
+ color: var(--text);
372
+ }
373
+
374
+ .msgboard-time {
375
+ font-size: 12px;
376
+ color: var(--text-tertiary);
377
+ font-variant-numeric: tabular-nums;
378
+ }
379
+
380
+ .msgboard-synced {
381
+ font-size: 11px;
382
+ padding: 1px 7px;
383
+ border-radius: var(--radius-chip);
384
+ background: var(--bg-sunken);
385
+ color: var(--text-tertiary);
386
+ }
387
+
388
+ .msgboard-remove {
389
+ margin-left: auto;
390
+ display: inline-flex;
391
+ align-items: center;
392
+ gap: 5px;
393
+ font-family: var(--font-sans);
394
+ font-size: 12px;
395
+ color: var(--text-tertiary);
396
+ background: transparent;
397
+ border: 1px solid transparent;
398
+ border-radius: var(--radius-chip);
399
+ padding: 4px 8px;
400
+ cursor: pointer;
401
+ transition:
402
+ color var(--dur) var(--ease),
403
+ border-color var(--dur) var(--ease);
404
+ }
405
+
406
+ .msgboard-remove:hover {
407
+ color: var(--danger);
408
+ border-color: var(--danger);
409
+ }
410
+
411
+ .msgboard-remove.is-armed {
412
+ color: var(--danger);
413
+ border-color: var(--danger);
414
+ }
415
+
416
+ .msgboard-card-body {
417
+ font-size: 14px;
418
+ line-height: 1.7;
419
+ color: var(--text);
420
+ white-space: pre-wrap;
421
+ word-break: break-word;
422
+ }
423
+
424
+ /* ── 回答(缩进挂在被答问题下) ──────────────────────────────────── */
425
+
426
+ .msgboard-answers {
427
+ margin-top: 12px;
428
+ padding-left: 18px;
429
+ border-left: 2px solid var(--border);
430
+ display: flex;
431
+ flex-direction: column;
432
+ gap: 10px;
433
+ }
434
+
435
+ .msgboard-answer {
436
+ background: var(--bg-sunken);
437
+ border: 1px solid transparent;
438
+ border-left: 3px solid var(--success);
439
+ border-radius: var(--radius-control);
440
+ padding: 10px 14px 12px;
441
+ }
442
+
443
+ .msgboard-waiting {
444
+ font-size: 12.5px;
445
+ color: var(--text-tertiary);
446
+ font-style: italic;
447
+ }
448
+
449
+ /* ── 窄屏(沿用 hub 既有滚动容器,这里只收紧内边距) ─────────────── */
450
+
451
+ @media (max-width: 900px) {
452
+ .msgboard {
453
+ padding: 24px 20px 32px;
454
+ }
455
+
456
+ .msgboard-composer-row {
457
+ flex-direction: column;
458
+ }
459
+
460
+ .msgboard-author {
461
+ flex: none;
462
+ width: 100%;
463
+ }
464
+ }
css/onboarding.css ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 首次引导(契约 7C)——Warm Paper 全屏向导:衬线大标题 + 圆点进度 + 大量留白 */
2
+
3
+ .ob-overlay {
4
+ position: fixed;
5
+ inset: 0;
6
+ z-index: 80;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ padding: 48px 24px;
11
+ background: var(--bg);
12
+ animation: ob-fade 200ms var(--ease);
13
+ }
14
+
15
+ @keyframes ob-fade {
16
+ from {
17
+ opacity: 0;
18
+ }
19
+ to {
20
+ opacity: 1;
21
+ }
22
+ }
23
+
24
+ @keyframes ob-rise {
25
+ from {
26
+ opacity: 0;
27
+ transform: translateY(6px);
28
+ }
29
+ to {
30
+ opacity: 1;
31
+ transform: none;
32
+ }
33
+ }
34
+
35
+ @keyframes ob-rotate {
36
+ to {
37
+ transform: rotate(360deg);
38
+ }
39
+ }
40
+
41
+ /* 右上角「跳过引导」:文字按钮,安静但一直在 */
42
+ .ob-skip {
43
+ position: absolute;
44
+ top: 18px;
45
+ right: 22px;
46
+ height: 30px;
47
+ padding: 0 12px;
48
+ border: none;
49
+ border-radius: var(--radius-chip);
50
+ background: transparent;
51
+ color: var(--text-tertiary);
52
+ font-family: inherit;
53
+ font-size: 12.5px;
54
+ cursor: pointer;
55
+ transition:
56
+ background-color var(--dur) var(--ease),
57
+ color var(--dur) var(--ease);
58
+ }
59
+
60
+ .ob-skip:hover {
61
+ background: var(--bg-elevated);
62
+ color: var(--text);
63
+ }
64
+
65
+ .ob-card {
66
+ width: min(620px, 100%);
67
+ max-height: 100%;
68
+ overflow-y: auto;
69
+ padding: 44px 48px 40px;
70
+ border: 1px solid var(--border);
71
+ border-radius: var(--radius-float);
72
+ background: var(--bg);
73
+ box-shadow: var(--shadow-float);
74
+ animation: ob-rise 220ms var(--ease);
75
+ }
76
+
77
+ .ob-brand {
78
+ display: flex;
79
+ align-items: center;
80
+ gap: 8px;
81
+ margin-bottom: 26px;
82
+ color: var(--text-secondary);
83
+ font-size: 13px;
84
+ letter-spacing: 0.01em;
85
+ }
86
+
87
+ /* ── 圆点进度:做完的实心浅陶土,当前的深陶土,未到的描边 ───────── */
88
+
89
+ .ob-dots {
90
+ display: flex;
91
+ gap: 8px;
92
+ margin-bottom: 24px;
93
+ }
94
+
95
+ .ob-dot {
96
+ width: 7px;
97
+ height: 7px;
98
+ border-radius: 50%;
99
+ background: transparent;
100
+ border: 1px solid var(--border);
101
+ transition:
102
+ background-color var(--dur) var(--ease),
103
+ border-color var(--dur) var(--ease);
104
+ }
105
+
106
+ .ob-dot.is-done {
107
+ background: var(--accent-soft);
108
+ border-color: var(--accent-soft);
109
+ }
110
+
111
+ .ob-dot.is-active {
112
+ background: var(--accent);
113
+ border-color: var(--accent);
114
+ }
115
+
116
+ /* ── 标题与正文三级字阶 ───────────────────────────────────────── */
117
+
118
+ .ob-title {
119
+ margin: 0 0 10px;
120
+ font-family: var(--font-serif);
121
+ font-size: 27px;
122
+ font-weight: 600;
123
+ letter-spacing: -0.01em;
124
+ line-height: 1.35;
125
+ }
126
+
127
+ .ob-sub {
128
+ margin: 0 0 28px;
129
+ color: var(--text-secondary);
130
+ font-size: 14.5px;
131
+ line-height: 1.7;
132
+ }
133
+
134
+ .ob-lede {
135
+ margin: 0 0 4px;
136
+ color: var(--text);
137
+ font-size: 14.5px;
138
+ line-height: 1.75;
139
+ }
140
+
141
+ .ob-lede a {
142
+ color: var(--accent);
143
+ cursor: pointer;
144
+ text-decoration: underline;
145
+ text-underline-offset: 3px;
146
+ }
147
+
148
+ .ob-hint {
149
+ margin: 10px 0 0;
150
+ color: var(--text-tertiary);
151
+ font-size: 12.5px;
152
+ line-height: 1.65;
153
+ }
154
+
155
+ .ob-loading {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 10px;
159
+ margin: 0;
160
+ color: var(--text-secondary);
161
+ font-size: 14px;
162
+ }
163
+
164
+ .ob-spin {
165
+ color: var(--accent);
166
+ animation: ob-rotate 900ms linear infinite;
167
+ }
168
+
169
+ /* ── 第一步:已就绪 + 模型清单 ────────────────────────────────── */
170
+
171
+ .ob-ready {
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 8px;
175
+ margin: 0 0 16px;
176
+ color: var(--success);
177
+ font-size: 14px;
178
+ font-weight: 500;
179
+ }
180
+
181
+ .ob-models {
182
+ list-style: none;
183
+ margin: 0 0 8px;
184
+ padding: 0;
185
+ border: 1px solid var(--border);
186
+ border-radius: var(--radius-card);
187
+ background: var(--bg-elevated);
188
+ overflow: hidden;
189
+ }
190
+
191
+ .ob-models li {
192
+ display: flex;
193
+ align-items: baseline;
194
+ justify-content: space-between;
195
+ gap: 16px;
196
+ padding: 11px 18px;
197
+ }
198
+
199
+ .ob-models li + li {
200
+ border-top: 1px solid var(--border);
201
+ }
202
+
203
+ .ob-model-name {
204
+ font-family: var(--font-mono);
205
+ font-size: 13px;
206
+ color: var(--text);
207
+ }
208
+
209
+ .ob-model-meta {
210
+ color: var(--text-tertiary);
211
+ font-size: 12.5px;
212
+ font-variant-numeric: tabular-nums;
213
+ white-space: nowrap;
214
+ }
215
+
216
+ /* ── 第二步:两个大选择 ───────────────────────────────────────── */
217
+
218
+ .ob-choices {
219
+ display: flex;
220
+ flex-direction: column;
221
+ gap: 12px;
222
+ }
223
+
224
+ .ob-choice {
225
+ display: flex;
226
+ align-items: center;
227
+ justify-content: space-between;
228
+ gap: 16px;
229
+ width: 100%;
230
+ padding: 18px 20px;
231
+ border: 1px solid var(--border);
232
+ border-radius: var(--radius-card);
233
+ background: var(--bg-elevated);
234
+ color: var(--text);
235
+ font-family: inherit;
236
+ text-align: left;
237
+ cursor: pointer;
238
+ transition:
239
+ border-color var(--dur) var(--ease),
240
+ background-color var(--dur) var(--ease),
241
+ transform var(--dur) var(--ease);
242
+ }
243
+
244
+ .ob-choice:hover {
245
+ border-color: var(--accent);
246
+ background: var(--accent-soft);
247
+ transform: translateY(-1px);
248
+ }
249
+
250
+ .ob-choice-text {
251
+ display: flex;
252
+ flex-direction: column;
253
+ gap: 4px;
254
+ }
255
+
256
+ .ob-choice-title {
257
+ font-family: var(--font-serif);
258
+ font-size: 16px;
259
+ font-weight: 600;
260
+ }
261
+
262
+ .ob-choice-desc {
263
+ color: var(--text-secondary);
264
+ font-size: 13px;
265
+ line-height: 1.6;
266
+ }
267
+
268
+ .ob-choice svg {
269
+ flex: none;
270
+ color: var(--text-tertiary);
271
+ }
272
+
273
+ /* ── 第三步:模型下拉 + 输入 + 回显 ───────────────────────────── */
274
+
275
+ .ob-field {
276
+ display: flex;
277
+ flex-direction: column;
278
+ gap: 6px;
279
+ margin-bottom: 14px;
280
+ }
281
+
282
+ .ob-field > span {
283
+ color: var(--text-tertiary);
284
+ font-size: 12.5px;
285
+ }
286
+
287
+ .ob-select {
288
+ height: 38px;
289
+ padding: 0 12px;
290
+ border: none;
291
+ border-radius: var(--radius-control);
292
+ background: var(--bg-sunken);
293
+ color: var(--text);
294
+ font-family: inherit;
295
+ font-size: 13.5px;
296
+ cursor: pointer;
297
+ transition: box-shadow var(--dur) var(--ease);
298
+ }
299
+
300
+ .ob-select:focus {
301
+ outline: none;
302
+ box-shadow: 0 0 0 1px var(--accent);
303
+ }
304
+
305
+ .ob-textarea {
306
+ width: 100%;
307
+ padding: 12px 14px;
308
+ border: none;
309
+ border-radius: var(--radius-control);
310
+ background: var(--bg-sunken);
311
+ color: var(--text);
312
+ font-family: inherit;
313
+ font-size: 14.5px;
314
+ line-height: 1.7;
315
+ resize: none;
316
+ user-select: text;
317
+ cursor: text;
318
+ transition: box-shadow var(--dur) var(--ease);
319
+ }
320
+
321
+ .ob-textarea:focus {
322
+ outline: none;
323
+ box-shadow: 0 0 0 1px var(--accent);
324
+ }
325
+
326
+ .ob-transcript {
327
+ display: flex;
328
+ flex-direction: column;
329
+ gap: 10px;
330
+ margin-top: 20px;
331
+ }
332
+
333
+ .ob-bubble {
334
+ margin: 0;
335
+ padding: 12px 16px;
336
+ border-radius: var(--radius-card);
337
+ font-size: 14px;
338
+ line-height: 1.7;
339
+ white-space: pre-wrap;
340
+ word-break: break-word;
341
+ user-select: text;
342
+ animation: ob-rise 200ms var(--ease);
343
+ }
344
+
345
+ .ob-bubble.is-user {
346
+ align-self: flex-end;
347
+ max-width: 85%;
348
+ background: var(--accent-soft);
349
+ }
350
+
351
+ .ob-bubble.is-assistant {
352
+ align-self: flex-start;
353
+ max-width: 92%;
354
+ background: var(--bg-elevated);
355
+ border: 1px solid var(--border);
356
+ }
357
+
358
+ /* ── 完成页与公共动作行 ───────────────────────────────────────── */
359
+
360
+ .ob-done {
361
+ display: flex;
362
+ flex-direction: column;
363
+ align-items: flex-start;
364
+ gap: 4px;
365
+ color: var(--accent);
366
+ }
367
+
368
+ .ob-done .ob-title {
369
+ margin-top: 14px;
370
+ color: var(--text);
371
+ }
372
+
373
+ .ob-actions {
374
+ display: flex;
375
+ align-items: center;
376
+ gap: 12px;
377
+ margin-top: 28px;
378
+ flex-wrap: wrap;
379
+ }
380
+
381
+ .ob-actions .btn-primary {
382
+ display: inline-flex;
383
+ align-items: center;
384
+ gap: 8px;
385
+ }
386
+
387
+ .ob-actions .btn-secondary {
388
+ display: inline-flex;
389
+ align-items: center;
390
+ gap: 7px;
391
+ }
css/overlay.css ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 划词浮层:Warm Paper 毛玻璃卡片(颜色一律走 theme.css 令牌)。
2
+ 注意:透明原生窗口上 WebKit 的 backdrop-filter 会把元素整个画没(坑位实测记录 #1),
3
+ 所以模糊交给 macOS 窗口特效,CSS 只保留 85% 暖纸半透明底色。 */
4
+
5
+ /* 透明窗口本体:桌面要从圆角外透出来 */
6
+ body.overlay-surface {
7
+ background: transparent;
8
+ }
9
+
10
+ .overlay-root {
11
+ height: 100%;
12
+ display: flex;
13
+ padding: 12px;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ /* ---------- 卡片容器 ---------- */
18
+ .overlay-card {
19
+ flex: 1;
20
+ min-height: 0;
21
+ display: flex;
22
+ flex-direction: column;
23
+ overflow: hidden;
24
+ border: 1px solid var(--border);
25
+ border-radius: var(--radius-float);
26
+ background: var(--glass);
27
+ box-shadow: var(--shadow-float);
28
+ animation: overlay-in 180ms var(--ease);
29
+ }
30
+
31
+ @keyframes overlay-in {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(6px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ /* ---------- 顶栏 ---------- */
43
+ .overlay-head {
44
+ display: flex;
45
+ align-items: baseline;
46
+ justify-content: space-between;
47
+ gap: 12px;
48
+ padding: 16px 20px 8px;
49
+ }
50
+
51
+ .overlay-title {
52
+ margin: 0;
53
+ font-family: var(--font-serif);
54
+ font-size: 20px;
55
+ font-weight: 600;
56
+ letter-spacing: -0.01em;
57
+ color: var(--text);
58
+ }
59
+
60
+ .overlay-esc {
61
+ font-size: 12px;
62
+ color: var(--text-tertiary);
63
+ white-space: nowrap;
64
+ }
65
+
66
+ /* ---------- 空态 / 提示 ---------- */
67
+ .overlay-note {
68
+ margin: 0;
69
+ padding: 12px 20px 20px;
70
+ font-size: 13.5px;
71
+ line-height: 1.6;
72
+ color: var(--text-secondary);
73
+ }
74
+
75
+ .overlay-note.is-warn {
76
+ color: var(--warning);
77
+ }
78
+
79
+ /* ---------- 选中文字预览 ---------- */
80
+ .overlay-quote {
81
+ margin: 4px 20px 0;
82
+ padding: 10px 14px;
83
+ max-height: 120px;
84
+ overflow-y: auto;
85
+ border-left: 2px solid var(--accent-soft);
86
+ border-radius: 0 var(--radius-control) var(--radius-control) 0;
87
+ background: var(--bg-sunken);
88
+ color: var(--text);
89
+ font-size: 13.5px;
90
+ line-height: 1.6;
91
+ user-select: text;
92
+ white-space: pre-wrap;
93
+ word-break: break-word;
94
+ }
95
+
96
+ /* ---------- 动作 chips ---------- */
97
+ .overlay-chips {
98
+ display: flex;
99
+ flex-wrap: wrap;
100
+ gap: 8px;
101
+ padding: 12px 20px 4px;
102
+ }
103
+
104
+ .overlay-chip {
105
+ height: 30px;
106
+ padding: 0 14px;
107
+ border: 1px solid var(--border);
108
+ border-radius: var(--radius-control);
109
+ background: transparent;
110
+ color: var(--text-secondary);
111
+ font-family: inherit;
112
+ font-size: 13px;
113
+ cursor: pointer;
114
+ transition:
115
+ background-color var(--dur) var(--ease),
116
+ border-color var(--dur) var(--ease);
117
+ }
118
+
119
+ .overlay-chip:hover:not(:disabled) {
120
+ background: var(--accent-soft);
121
+ border-color: var(--accent-soft);
122
+ color: var(--text);
123
+ }
124
+
125
+ .overlay-chip:disabled {
126
+ opacity: 0.5;
127
+ cursor: default;
128
+ }
129
+
130
+ /* ---------- 自定义输入 ---------- */
131
+ .overlay-custom {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 8px;
135
+ margin: 8px 20px 0;
136
+ padding: 6px 6px 6px 12px;
137
+ border: 1px solid transparent;
138
+ border-radius: var(--radius-control);
139
+ background: var(--bg-sunken);
140
+ transition: border-color var(--dur) var(--ease);
141
+ }
142
+
143
+ .overlay-custom:focus-within {
144
+ border-color: var(--accent);
145
+ }
146
+
147
+ .overlay-input {
148
+ flex: 1;
149
+ min-width: 0;
150
+ border: none;
151
+ background: transparent;
152
+ color: var(--text);
153
+ font-family: inherit;
154
+ font-size: 13.5px;
155
+ outline: none;
156
+ cursor: text;
157
+ }
158
+
159
+ .overlay-input::placeholder {
160
+ color: var(--text-tertiary);
161
+ }
162
+
163
+ .overlay-send {
164
+ flex-shrink: 0;
165
+ height: 28px;
166
+ padding: 0 12px;
167
+ border: none;
168
+ border-radius: var(--radius-chip);
169
+ background: var(--accent);
170
+ color: var(--bg);
171
+ font-family: inherit;
172
+ font-size: 13px;
173
+ cursor: pointer;
174
+ transition: opacity var(--dur) var(--ease);
175
+ }
176
+
177
+ .overlay-send:disabled {
178
+ opacity: 0.4;
179
+ cursor: default;
180
+ }
181
+
182
+ /* ---------- 回答区 ---------- */
183
+ .overlay-answer {
184
+ flex: 1;
185
+ min-height: 0;
186
+ display: flex;
187
+ flex-direction: column;
188
+ margin-top: 12px;
189
+ padding: 12px 20px 16px;
190
+ border-top: 1px solid var(--border);
191
+ }
192
+
193
+ .overlay-answer-body {
194
+ flex: 1;
195
+ min-height: 0;
196
+ overflow-y: auto;
197
+ }
198
+
199
+ .overlay-answer-text {
200
+ margin: 0;
201
+ color: var(--text);
202
+ font-size: 13.5px;
203
+ line-height: 1.65;
204
+ white-space: pre-wrap;
205
+ word-break: break-word;
206
+ user-select: text;
207
+ }
208
+
209
+ /* 流式呼吸光标(1s 透明度呼吸;reduced-motion 时 theme.css 全局降级为静止) */
210
+ .overlay-cursor {
211
+ display: inline-block;
212
+ width: 2px;
213
+ height: 1.05em;
214
+ margin-left: 3px;
215
+ border-radius: 1px;
216
+ background: var(--accent);
217
+ vertical-align: text-bottom;
218
+ animation: overlay-cursor-breathe 1s ease-in-out infinite;
219
+ }
220
+
221
+ @keyframes overlay-cursor-breathe {
222
+ 0%,
223
+ 100% {
224
+ opacity: 1;
225
+ }
226
+ 50% {
227
+ opacity: 0.15;
228
+ }
229
+ }
230
+
231
+ .overlay-error {
232
+ margin: 8px 0 0;
233
+ color: var(--danger);
234
+ font-size: 12.5px;
235
+ }
236
+
237
+ .overlay-answer-foot {
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: space-between;
241
+ gap: 12px;
242
+ margin-top: 12px;
243
+ }
244
+
245
+ .overlay-copy {
246
+ display: inline-flex;
247
+ align-items: center;
248
+ gap: 6px;
249
+ height: 30px;
250
+ padding: 0 12px;
251
+ border: 1px solid var(--border);
252
+ border-radius: var(--radius-control);
253
+ background: transparent;
254
+ color: var(--text-secondary);
255
+ font-family: inherit;
256
+ font-size: 12.5px;
257
+ cursor: pointer;
258
+ transition: background-color var(--dur) var(--ease);
259
+ }
260
+
261
+ .overlay-copy:hover:not(:disabled) {
262
+ background: var(--bg-elevated);
263
+ color: var(--text);
264
+ }
265
+
266
+ .overlay-copy:disabled {
267
+ opacity: 0.5;
268
+ cursor: default;
269
+ }
270
+
271
+ .overlay-foot-hint {
272
+ font-size: 12px;
273
+ color: var(--text-tertiary);
274
+ }
275
+
276
+ /* ---------- 授权引导态 ---------- */
277
+ .overlay-guide {
278
+ flex: 1;
279
+ display: flex;
280
+ flex-direction: column;
281
+ padding: 24px 24px 20px;
282
+ }
283
+
284
+ .overlay-guide-head {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 10px;
288
+ color: var(--accent);
289
+ }
290
+
291
+ .overlay-guide .overlay-title {
292
+ font-size: 22px;
293
+ }
294
+
295
+ .overlay-lead {
296
+ margin: 12px 0 20px;
297
+ color: var(--text-secondary);
298
+ font-size: 14px;
299
+ line-height: 1.65;
300
+ }
301
+
302
+ .overlay-primary {
303
+ align-self: flex-start;
304
+ height: 40px;
305
+ padding: 0 20px;
306
+ border: none;
307
+ border-radius: var(--radius-control);
308
+ background: var(--accent);
309
+ color: var(--bg);
310
+ font-family: inherit;
311
+ font-size: 14px;
312
+ cursor: pointer;
313
+ }
314
+
315
+ .overlay-primary:hover {
316
+ filter: brightness(0.94);
317
+ }
318
+
319
+ .overlay-why-toggle {
320
+ align-self: flex-start;
321
+ margin-top: 18px;
322
+ padding: 0;
323
+ border: none;
324
+ background: transparent;
325
+ color: var(--text-secondary);
326
+ font-family: inherit;
327
+ font-size: 13px;
328
+ text-decoration: underline;
329
+ text-underline-offset: 3px;
330
+ cursor: pointer;
331
+ }
332
+
333
+ .overlay-why-body {
334
+ margin: 10px 0 0;
335
+ color: var(--text-tertiary);
336
+ font-size: 12.5px;
337
+ line-height: 1.7;
338
+ }
339
+
340
+ .overlay-guide-hint {
341
+ margin-top: auto;
342
+ padding-top: 20px;
343
+ color: var(--text-tertiary);
344
+ font-size: 12.5px;
345
+ line-height: 1.6;
346
+ }
css/palette.css ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ⌘K 统一浮窗(契约 19A-A1):大输入框 + 模式 chips + 结果区。
2
+ Warm Paper 浮窗样式,颜色一律走 theme.css 令牌。
3
+ 注意(design-system §7 + 坑位记录):透明窗口上 WebKit 的 backdrop-filter
4
+ 会把元素整个画没,所以**不写 backdrop-filter**,直接用 85% 暖纸半透明底(--glass)。 */
5
+
6
+ /* ---------- 容器 ---------- */
7
+ body.palette-surface {
8
+ background: transparent;
9
+ }
10
+
11
+ .palette-overlay {
12
+ height: 100%;
13
+ display: flex;
14
+ padding: 12px;
15
+ box-sizing: border-box;
16
+ }
17
+
18
+ .palette-card {
19
+ display: flex;
20
+ flex-direction: column;
21
+ flex: 1;
22
+ min-height: 0;
23
+ border: 1px solid var(--border);
24
+ border-radius: var(--radius-float);
25
+ background: var(--glass);
26
+ box-shadow: var(--shadow-float);
27
+ overflow: hidden;
28
+ animation: palette-in 180ms var(--ease);
29
+ }
30
+
31
+ @keyframes palette-in {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(6px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ /* ---------- 输入区 ---------- */
43
+ .palette-search {
44
+ display: flex;
45
+ align-items: center;
46
+ gap: 12px;
47
+ margin: 14px 14px 8px;
48
+ padding: 10px 16px;
49
+ border: 1px solid transparent;
50
+ border-radius: var(--radius-card);
51
+ background: var(--bg-sunken);
52
+ transition: border-color var(--dur) var(--ease);
53
+ }
54
+
55
+ .palette-search:focus-within {
56
+ border-color: var(--accent);
57
+ }
58
+
59
+ .palette-search-icon {
60
+ flex-shrink: 0;
61
+ color: var(--text-tertiary);
62
+ }
63
+
64
+ .palette-input {
65
+ flex: 1;
66
+ min-width: 0;
67
+ border: none;
68
+ background: transparent;
69
+ color: var(--text);
70
+ font-family: var(--font-serif);
71
+ font-size: 24px;
72
+ line-height: 1.4;
73
+ letter-spacing: -0.01em;
74
+ outline: none;
75
+ cursor: text;
76
+ }
77
+
78
+ .palette-input::placeholder {
79
+ color: var(--text-tertiary);
80
+ }
81
+
82
+ .palette-kbd {
83
+ flex-shrink: 0;
84
+ font-size: 12px;
85
+ color: var(--text-tertiary);
86
+ white-space: nowrap;
87
+ }
88
+
89
+ /* ---------- 模式 chips ---------- */
90
+ .palette-chips {
91
+ display: flex;
92
+ gap: 6px;
93
+ padding: 0 14px 8px;
94
+ }
95
+
96
+ .palette-chip {
97
+ display: inline-flex;
98
+ align-items: baseline;
99
+ gap: 6px;
100
+ height: 28px;
101
+ padding: 0 10px;
102
+ border: 1px solid var(--border);
103
+ border-radius: var(--radius-control);
104
+ background: transparent;
105
+ color: var(--text-secondary);
106
+ font-family: inherit;
107
+ font-size: 12.5px;
108
+ cursor: pointer;
109
+ transition:
110
+ background-color var(--dur) var(--ease),
111
+ border-color var(--dur) var(--ease);
112
+ }
113
+
114
+ .palette-chip:hover {
115
+ background: var(--bg-elevated);
116
+ color: var(--text);
117
+ }
118
+
119
+ .palette-chip.is-active {
120
+ border-color: var(--accent-soft);
121
+ background: var(--accent-soft);
122
+ color: var(--text);
123
+ }
124
+
125
+ .palette-chip-slash {
126
+ font-family: var(--font-mono);
127
+ font-size: 11px;
128
+ color: var(--text-tertiary);
129
+ }
130
+
131
+ /* ---------- 结果区 ---------- */
132
+ .palette-body {
133
+ flex: 1;
134
+ min-height: 0;
135
+ overflow-y: auto;
136
+ padding: 2px 8px 8px;
137
+ }
138
+
139
+ .palette-list {
140
+ margin: 0;
141
+ padding: 0;
142
+ list-style: none;
143
+ }
144
+
145
+ .palette-item {
146
+ display: flex;
147
+ align-items: baseline;
148
+ gap: 16px;
149
+ width: 100%;
150
+ padding: 9px 14px;
151
+ border: none;
152
+ border-radius: var(--radius-control);
153
+ background: transparent;
154
+ color: var(--text);
155
+ font-family: inherit;
156
+ font-size: 14.5px;
157
+ text-align: left;
158
+ cursor: pointer;
159
+ transition: background-color var(--dur) var(--ease);
160
+ }
161
+
162
+ .palette-item:hover {
163
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
164
+ }
165
+
166
+ .palette-item.is-selected {
167
+ background: var(--accent-soft);
168
+ }
169
+
170
+ .palette-item-name {
171
+ flex: 1;
172
+ min-width: 0;
173
+ overflow: hidden;
174
+ text-overflow: ellipsis;
175
+ white-space: nowrap;
176
+ }
177
+
178
+ .palette-item-name mark {
179
+ background: transparent;
180
+ color: var(--accent);
181
+ font-weight: 600;
182
+ }
183
+
184
+ .palette-item-meta {
185
+ flex-shrink: 0;
186
+ display: flex;
187
+ gap: 12px;
188
+ font-size: 12.5px;
189
+ color: var(--text-tertiary);
190
+ font-variant-numeric: tabular-nums;
191
+ }
192
+
193
+ /* ---------- 空态 / 状态行 ---------- */
194
+ .palette-empty {
195
+ padding: 18px 14px;
196
+ }
197
+
198
+ .palette-empty-title {
199
+ margin: 0 0 6px;
200
+ font-family: var(--font-serif);
201
+ font-size: 19px;
202
+ color: var(--text);
203
+ }
204
+
205
+ .palette-empty-note {
206
+ margin: 0;
207
+ font-size: 13.5px;
208
+ color: var(--text-secondary);
209
+ }
210
+
211
+ .palette-note {
212
+ margin: 0;
213
+ padding: 14px;
214
+ font-size: 13.5px;
215
+ color: var(--text-secondary);
216
+ }
217
+
218
+ .palette-note.is-error {
219
+ color: var(--danger);
220
+ }
221
+
222
+ .palette-task {
223
+ margin: 6px 6px 0;
224
+ padding: 12px 14px;
225
+ font-family: var(--font-serif);
226
+ font-size: 17px;
227
+ line-height: 1.6;
228
+ color: var(--text);
229
+ }
230
+
231
+ .palette-error {
232
+ margin: 8px 8px 0;
233
+ color: var(--danger);
234
+ font-size: 12.5px;
235
+ }
236
+
237
+ /* ---------- 闲时提示 ---------- */
238
+ .palette-hints {
239
+ padding: 12px 14px;
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: 6px;
243
+ }
244
+
245
+ .palette-hint-line {
246
+ margin: 0;
247
+ font-size: 13px;
248
+ color: var(--text-secondary);
249
+ }
250
+
251
+ .palette-hint-line.is-quiet {
252
+ color: var(--text-tertiary);
253
+ }
254
+
255
+ .palette-hint-line kbd,
256
+ .palette-foot kbd {
257
+ padding: 1px 5px;
258
+ border: 1px solid var(--border);
259
+ border-radius: var(--radius-chip);
260
+ background: var(--bg-sunken);
261
+ font-family: var(--font-mono);
262
+ font-size: 11.5px;
263
+ color: var(--text);
264
+ }
265
+
266
+ /* ---------- 回答(复用 Markdown;呼吸光标同划词浮层) ---------- */
267
+ .palette-answer {
268
+ margin: 4px 6px 0;
269
+ }
270
+
271
+ .palette-answer-body {
272
+ max-height: 320px;
273
+ overflow-y: auto;
274
+ font-size: 14.5px;
275
+ line-height: 1.7;
276
+ color: var(--text);
277
+ }
278
+
279
+ .palette-answer-body > :first-child {
280
+ margin-top: 0;
281
+ }
282
+
283
+ .palette-cursor {
284
+ display: inline-block;
285
+ width: 2px;
286
+ height: 1.05em;
287
+ margin-left: 3px;
288
+ border-radius: 1px;
289
+ background: var(--accent);
290
+ vertical-align: text-bottom;
291
+ animation: palette-cursor-breathe 1s ease-in-out infinite;
292
+ }
293
+
294
+ @keyframes palette-cursor-breathe {
295
+ 0%,
296
+ 100% {
297
+ opacity: 1;
298
+ }
299
+ 50% {
300
+ opacity: 0.15;
301
+ }
302
+ }
303
+
304
+ /* ---------- 底栏 ---------- */
305
+ .palette-foot {
306
+ display: flex;
307
+ align-items: center;
308
+ justify-content: space-between;
309
+ gap: 16px;
310
+ padding: 9px 18px 12px;
311
+ border-top: 1px solid var(--border);
312
+ font-size: 12.5px;
313
+ color: var(--text-tertiary);
314
+ }
315
+
316
+ .palette-hint {
317
+ color: var(--text-tertiary);
318
+ }
319
+
320
+ .palette-hint.is-quiet {
321
+ color: var(--text-tertiary);
322
+ opacity: 0.85;
323
+ }
css/perch-home.css ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Gravity Core shares the product's theme tokens; no new appearance preference. */
2
+ .perch-home { --home-metal: var(--accent); padding: 0 0 24px; color: var(--text); }
3
+ [data-style="darkside"] .perch-home { --home-metal: #d5b580; }
4
+ [data-style="darkside"][data-theme="light"] .perch-home { --home-metal: #866330; }
5
+ .home-pagebar { display:flex; align-items:center; justify-content:space-between; gap:16px; color:var(--text-secondary); font-size:11px; }
6
+ .home-layout-label { display:flex; align-items:center; gap:7px; flex:none; color:var(--home-metal); font-size:10px; }
7
+ .home-layout-label::before { content:""; width:5px; height:5px; border-radius:50%; background:var(--home-metal); }
8
+ .home-cover { display:grid; grid-template-columns:1fr 1fr; align-items:center; min-height:284px; position:relative; isolation:isolate; }
9
+ .home-cover-copy { position:relative; z-index:1; pointer-events:none; }
10
+ .home-eyebrow { margin:0 0 15px; color:var(--home-metal); font:10px/1.7 var(--font-mono); letter-spacing:2px; }
11
+ .home-cover h2 { margin:0; font:500 clamp(28px,3.4vw,45px)/1.28 var(--font-sans); letter-spacing:-1px; }
12
+ .home-cover h2 em { color:var(--home-metal); font-style:normal; }
13
+ .home-description { margin:15px 0 0; color:var(--text-secondary); font-size:12px; line-height:1.9; }
14
+ .home-core-art { position:relative; min-width:0; height:290px; margin:0 0 0 -26px; overflow:clip; touch-action:pan-y; color:var(--home-metal); }
15
+ .home-core-art canvas { display:block; width:100%; height:100%; pointer-events:none; }
16
+ .home-core-caption { position:absolute; bottom:17px; right:14px; color:var(--text-secondary); font:9px var(--font-mono); letter-spacing:1px; pointer-events:none; }
17
+ .home-core-caption::before { content:""; display:inline-block; width:20px; height:1px; vertical-align:middle; margin-right:7px; background:var(--home-metal); }
18
+ .home-core-coordinates { position:absolute; bottom:14px; left:0; color:var(--text-secondary); font:9px/1.9 var(--font-mono); pointer-events:none; }
19
+ .home-goal-editor { background:var(--bg-elevated); border:1px solid color-mix(in srgb,var(--home-metal) 24%,var(--border)); border-radius:12px; overflow:hidden; box-shadow:0 12px 30px color-mix(in srgb,var(--bg-sunken) 38%,transparent); }
20
+ .home-goal-editor:focus-within { border-color:var(--home-metal); }
21
+ .home-goal-editor textarea { display:block; resize:vertical; width:100%; min-height:72px; max-height:340px; padding:18px 18px 8px; background:transparent; border:0; color:var(--text); font:13px/1.8 var(--font-sans); user-select:text; }
22
+ .home-goal-editor textarea::placeholder { color:var(--text-secondary); opacity:1; }
23
+ .home-goal-editor textarea:focus-visible { outline:none; }
24
+ .home-composer-foot { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:9px 11px 11px; }
25
+ .home-work-modes { display:flex; flex-wrap:wrap; gap:2px; min-width:0; }
26
+ .home-work-modes button { display:flex; align-items:center; justify-content:center; gap:6px; min-height:31px; padding:7px 9px; border:1px solid transparent; border-radius:6px; background:transparent; color:var(--text-secondary); font:11px var(--font-sans); cursor:pointer; }
27
+ .home-work-modes button[aria-pressed="true"] { background:color-mix(in srgb,var(--text) 5%,var(--bg-elevated)); border-color:var(--border); color:var(--text); }
28
+ .home-work-modes button:hover { background:color-mix(in srgb,var(--text) 6%,var(--bg-elevated)); color:var(--text); }
29
+ .home-start { display:flex; align-items:center; justify-content:center; gap:9px; min-height:34px; padding:7px 12px; border:1px solid color-mix(in srgb,var(--home-metal) 86%,var(--text)); border-radius:7px; background:var(--home-metal); color:#1c1a15; font:500 11px var(--font-sans); white-space:nowrap; cursor:pointer; }
30
+ [data-style="darkside"] .home-start { color:#1c1a15; }
31
+ [data-style="darkside"][data-theme="light"] .home-start { color:#fffdf8; }
32
+ .home-start kbd { color:inherit; background:none; border:0; padding:0; font:10px var(--font-mono); opacity:.7; }
33
+ .home-start:hover { filter:brightness(1.07); }
34
+ .home-goal-help { display:flex; align-items:flex-start; gap:6px; margin-top:10px; color:var(--text-secondary); font-size:10px; line-height:1.7; overflow-wrap:anywhere; }
35
+ .home-goal-help svg { flex:none; margin-top:2px; }
36
+ .home-goal-error { color:var(--danger); border-left:2px solid var(--danger); margin:13px 0 0; padding:4px 10px; font-size:12px; line-height:1.8; }
37
+ .home-sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
38
+ .home-command-grid { display:grid; grid-template-columns:minmax(0,.94fr) minmax(0,1fr); gap:26px; align-items:center; margin-top:23px; }
39
+ .home-command-core { min-width:0; }
40
+ .home-core-top { display:flex; align-items:center; justify-content:space-between; color:var(--text-secondary); font:9px var(--font-mono); letter-spacing:1px; }
41
+ .is-professional .home-core-art { margin:0; height:286px; }
42
+ .is-professional .home-pagebar,.is-professional .home-layout-label { font-family:var(--font-mono); font-size:10px; letter-spacing:.6px; }
43
+ .home-mission { min-width:0; }
44
+ .home-mission .home-eyebrow { color:var(--text-secondary); margin-bottom:10px; }
45
+ .home-mission h2 { margin:0; font:500 26px/1.4 var(--font-sans); letter-spacing:-.7px; }
46
+ .home-mission .home-description { margin-top:8px; font-size:11px; }
47
+ .home-mission .home-goal-editor { margin-top:17px; border-color:var(--border); border-radius:6px; box-shadow:none; }
48
+ .home-editor-head { display:flex; align-items:center; gap:7px; padding:8px 12px; border-bottom:1px solid var(--border); color:var(--text-secondary); font:10px var(--font-mono); }
49
+ .home-editor-head>span:last-child { margin-left:auto; color:var(--home-metal); }
50
+ .home-mission textarea { min-height:148px; padding:12px; font:11px/1.9 var(--font-mono); }
51
+ .home-mission .home-composer-foot { padding:7px 9px; border-top:1px solid var(--border); }
52
+ .home-mission .home-work-modes button { min-height:28px; padding:5px 7px; font:9px var(--font-mono); }
53
+ .home-mission .home-work-modes svg { display:none; }
54
+ .home-mission .home-start { min-height:30px; padding:5px 9px; border-radius:4px; font:10px var(--font-mono); }
55
+ .home-mission .home-start kbd { display:none; }
56
+ .home-mission .home-goal-help { font-size:9px; }
57
+ .workspace-page.has-gravity-home .workspace-header { padding:18px 40px 7px; }
58
+ .workspace-page.has-gravity-home .workspace-header .ws-eyebrow { display:none; }
59
+ .workspace-page.has-gravity-home .workspace-header h1 { margin:0; font:500 11px var(--font-sans); letter-spacing:0; color:var(--text-secondary); }
60
+ .workspace-page.has-gravity-home .workspace-header-actions .local-pill { font-size:9px; }
61
+ .workspace-page.has-gravity-home .workspace-header .ws-icon { width:25px; height:25px; border:0; }
62
+ .workspace-page.has-gravity-home .workspace-scroll { padding-top:12px; }
63
+ .workspace-page.has-gravity-home .workspace-metrics { padding:20px 0 25px; }
64
+ .workspace-page.has-gravity-home .ws-metric strong { font-size:25px; }
65
+ .workspace-page.has-gravity-home .workspace-recent { display:block; padding:0 0 22px; border:0; }
66
+ .workspace-page.has-gravity-home .workspace-recent>div:first-child { display:flex; align-items:center; justify-content:space-between; gap:15px; margin-bottom:10px; }
67
+ .workspace-page.has-gravity-home .workspace-recent h2 { font-size:11px; font-weight:500; margin:0; }
68
+ .workspace-page.has-gravity-home .workspace-recent-list { display:block; }
69
+ .workspace-page.has-gravity-home .workspace-recent-list>button { width:100%; display:flex; align-items:center; gap:10px; padding:12px 1px; background:none; border:0; border-bottom:1px solid var(--border); border-radius:0; }
70
+ .workspace-page.has-gravity-home .workspace-recent-list>button:first-child { border-top:1px solid var(--border); }
71
+ .workspace-page.has-gravity-home .workspace-recent-list>button>span { flex:1; text-align:left; font-size:11px; }
72
+ .workspace-page.has-gravity-home .workspace-recent-list>button>small { font-size:10px; }
73
+ .workspace-home-details { margin:3px 0 0; border-top:1px solid var(--border); }
74
+ .workspace-home-details>summary { display:flex; justify-content:space-between; align-items:center; gap:15px; list-style:none; cursor:pointer; padding:16px 0; font-size:11px; color:var(--text-secondary); }
75
+ .workspace-home-details>summary::-webkit-details-marker { display:none; }
76
+ .workspace-home-details>summary::after { content:"+"; color:var(--text-secondary); margin-left:auto; }
77
+ .workspace-home-details[open]>summary::after { content:"−"; }
78
+ .workspace-home-details>summary>small { font-size:10px; color:var(--text-secondary); }
79
+ @media(max-width:1080px) {
80
+ .workspace-page.has-gravity-home .workspace-header { padding-left:25px; padding-right:25px; }
81
+ .home-command-grid { gap:17px; grid-template-columns:minmax(0,.85fr) minmax(0,1fr); }
82
+ .home-mission h2 { font-size:23px; }
83
+ }
84
+ @container perch-cover (max-width:650px) {
85
+ .home-cover h2 { font-size:32px; }
86
+ .home-command-grid { grid-template-columns:1fr; gap:18px; }
87
+ .is-professional .home-core-art { height:230px; }
88
+ .home-mission h2 br { display:none; }
89
+ .home-mission h2 { font-size:24px; }
90
+ }
91
+ .perch-home { container-type:inline-size; container-name:perch-cover; }
92
+ @container perch-cover (max-width:500px) {
93
+ .home-cover { grid-template-columns:1fr; min-height:0; }
94
+ .home-cover-copy { padding-top:25px; }
95
+ .home-cover h2 { font-size:30px; }
96
+ .home-core-art { height:230px; margin:-8px 0 0; }
97
+ .home-eyebrow { font-size:9px; letter-spacing:1.4px; }
98
+ .home-composer-foot { align-items:stretch; flex-direction:column; gap:8px; }
99
+ .home-work-modes button { flex:1; }
100
+ .home-work-modes { flex-wrap:nowrap; }
101
+ .home-start { width:100%; }
102
+ .home-goal-help { font-size:10px; }
103
+ .home-mission .home-goal-help { font-size:10px; }
104
+ }
105
+ @media(prefers-reduced-motion:reduce) { .home-core-art canvas { transform:none!important; } }
css/permissions.css ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 设置 → 权限(契约 13A 自主授权模式)——只用 theme.css 的色彩令牌,
2
+ 不硬编码任何颜色;危险授权卡「红但不恐吓」(design-system.md:danger
3
+ 只做指引,不用高饱和大面积红)。 */
4
+
5
+ /* 危险操作授权状态卡:未授权=灰(安全态),已授权=danger 描边 + 极淡底 */
6
+ .perm-card {
7
+ margin: 14px 0 0;
8
+ padding: 14px 16px;
9
+ border: 1px solid var(--border);
10
+ border-radius: var(--radius-card, 12px);
11
+ background: var(--bg-sunken);
12
+ transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
13
+ }
14
+ .perm-card.is-authorized {
15
+ border-color: var(--danger);
16
+ background: color-mix(in srgb, var(--danger) 6%, var(--bg));
17
+ }
18
+ .perm-card-head {
19
+ display: flex;
20
+ gap: 12px;
21
+ align-items: flex-start;
22
+ }
23
+ .perm-card-icon {
24
+ display: inline-flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ width: 30px;
28
+ height: 30px;
29
+ border-radius: 50%;
30
+ border: 1px solid var(--border);
31
+ background: var(--bg);
32
+ color: var(--text-secondary);
33
+ flex-shrink: 0;
34
+ }
35
+ .perm-card.is-authorized .perm-card-icon {
36
+ color: var(--danger);
37
+ border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
38
+ }
39
+ .perm-card-text {
40
+ min-width: 0;
41
+ }
42
+ .perm-card-title {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 10px;
46
+ flex-wrap: wrap;
47
+ font-weight: 500;
48
+ color: var(--text);
49
+ }
50
+ .perm-card-desc {
51
+ margin: 4px 0 0;
52
+ font-size: 12.5px;
53
+ line-height: 1.6;
54
+ color: var(--text-secondary);
55
+ }
56
+
57
+ /* 状态徽章:未授权=灰点,已授权=danger 点 */
58
+ .perm-status-badge {
59
+ display: inline-flex;
60
+ align-items: center;
61
+ gap: 6px;
62
+ font-size: 11.5px;
63
+ font-weight: 500;
64
+ padding: 3px 9px;
65
+ border-radius: 999px;
66
+ border: 1px solid var(--border);
67
+ color: var(--text-secondary);
68
+ background: var(--bg);
69
+ }
70
+ .perm-status-badge.is-on {
71
+ color: var(--danger);
72
+ border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
73
+ }
74
+ .perm-status-dot {
75
+ width: 7px;
76
+ height: 7px;
77
+ border-radius: 50%;
78
+ background: var(--text-tertiary);
79
+ }
80
+ .perm-status-badge.is-on .perm-status-dot {
81
+ background: var(--danger);
82
+ }
83
+
84
+ /* 卡内操作行 */
85
+ .perm-card-actions {
86
+ margin-top: 12px;
87
+ display: flex;
88
+ gap: 8px;
89
+ }
90
+
91
+ /* 一次性授权面板(输入确认词) */
92
+ .perm-grant-panel {
93
+ margin-top: 12px;
94
+ padding: 12px 14px;
95
+ border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--border));
96
+ border-radius: var(--radius-control, 9px);
97
+ background: var(--bg);
98
+ }
99
+ .perm-grant-risk {
100
+ margin: 0;
101
+ font-size: 13px;
102
+ font-weight: 500;
103
+ color: var(--danger);
104
+ line-height: 1.6;
105
+ }
106
+ .perm-grant-note {
107
+ margin: 4px 0 0;
108
+ font-size: 12.5px;
109
+ color: var(--text-secondary);
110
+ line-height: 1.6;
111
+ }
112
+ .perm-grant-row {
113
+ margin-top: 10px;
114
+ display: flex;
115
+ gap: 8px;
116
+ align-items: center;
117
+ flex-wrap: wrap;
118
+ }
119
+ .perm-grant-input {
120
+ font: inherit;
121
+ font-size: 13px;
122
+ color: var(--text);
123
+ background: var(--bg-sunken);
124
+ border: 1px solid var(--border);
125
+ border-radius: var(--radius-control);
126
+ padding: 8px 10px;
127
+ min-width: 180px;
128
+ }
129
+ .perm-grant-input:focus-visible {
130
+ outline: 2px solid var(--accent);
131
+ outline-offset: 1px;
132
+ }
133
+
134
+ /* 按钮三态:危险红底(有分量不刺眼)/ 危险描边(安静入口)/ 中性 */
135
+ .perm-btn-danger,
136
+ .perm-btn-danger-quiet,
137
+ .perm-btn-quiet {
138
+ appearance: none;
139
+ font: inherit;
140
+ font-size: 13px;
141
+ line-height: 1;
142
+ padding: 9px 14px;
143
+ border-radius: var(--radius-control);
144
+ cursor: pointer;
145
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
146
+ border-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
147
+ }
148
+ .perm-btn-danger {
149
+ border: 1px solid var(--danger);
150
+ background: var(--danger);
151
+ color: var(--bg);
152
+ }
153
+ .perm-btn-danger:hover:not(:disabled) {
154
+ background: color-mix(in srgb, var(--danger) 88%, var(--text));
155
+ }
156
+ .perm-btn-danger:disabled {
157
+ opacity: 0.45;
158
+ cursor: not-allowed;
159
+ }
160
+ .perm-btn-danger-quiet {
161
+ border: 1px solid color-mix(in srgb, var(--danger) 45%, var(--border));
162
+ background: transparent;
163
+ color: var(--danger);
164
+ }
165
+ .perm-btn-danger-quiet:hover:not(:disabled) {
166
+ background: color-mix(in srgb, var(--danger) 10%, transparent);
167
+ }
168
+ .perm-btn-quiet {
169
+ border: 1px solid var(--border);
170
+ background: transparent;
171
+ color: var(--text-secondary);
172
+ }
173
+ .perm-btn-quiet:hover:not(:disabled) {
174
+ color: var(--text);
175
+ background: var(--bg-elevated);
176
+ }
177
+ .perm-btn-danger:focus-visible,
178
+ .perm-btn-danger-quiet:focus-visible,
179
+ .perm-btn-quiet:focus-visible {
180
+ outline: 2px solid var(--accent);
181
+ outline-offset: 1px;
182
+ }
183
+
184
+ /* sudo 固定说明行(不可更改):中性底 + 锁形小图标 */
185
+ .perm-fixed-row {
186
+ margin-top: 14px;
187
+ display: flex;
188
+ gap: 10px;
189
+ align-items: flex-start;
190
+ padding: 11px 14px;
191
+ border: 1px solid var(--border);
192
+ border-radius: var(--radius-control, 9px);
193
+ background: var(--bg-sunken);
194
+ font-size: 12.5px;
195
+ line-height: 1.6;
196
+ color: var(--text-secondary);
197
+ }
198
+ .perm-fixed-row strong {
199
+ color: var(--text);
200
+ font-weight: 500;
201
+ margin-right: 4px;
202
+ }
203
+ .perm-fixed-icon {
204
+ display: inline-flex;
205
+ align-items: center;
206
+ color: var(--text-tertiary);
207
+ margin-top: 2px;
208
+ flex-shrink: 0;
209
+ }
210
+
211
+ /* 底部常驻审计承诺行 */
212
+ .perm-audit-pledge {
213
+ margin: 14px 0 0;
214
+ padding-top: 12px;
215
+ border-top: 1px solid var(--border);
216
+ font-size: 12px;
217
+ line-height: 1.6;
218
+ color: var(--text-tertiary);
219
+ }
220
+
221
+ /* Composer 任务模式的总闸状态小字(只读展示,改动去设置) */
222
+ .perm-gate-hint {
223
+ font-size: 11px;
224
+ line-height: 1;
225
+ color: var(--text-tertiary);
226
+ white-space: nowrap;
227
+ align-self: center;
228
+ cursor: default;
229
+ }
230
+
231
+ /* 实时之眼摄像头状态徽章(契约 12B):授权=绿(与危险授权的红语义区分) */
232
+ .perm-status-badge.is-good {
233
+ color: var(--success);
234
+ border-color: color-mix(in srgb, var(--success) 45%, var(--border));
235
+ }
236
+ .perm-status-badge.is-good .perm-status-dot {
237
+ background: var(--success);
238
+ }
css/plugins.css ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 插件面板(契约 30A/30B · 工作台第六 tab「插件」)——复用 flow/xp 的
2
+ 令牌与容器口径(整页滚动 + 48px 留白 + Warm Paper 变量),零硬编码色。 */
3
+
4
+ /* 运行面板容器 */
5
+ .plugin-runner {
6
+ margin-top: 28px;
7
+ padding: 20px 22px;
8
+ background: var(--bg-elevated);
9
+ border: 1px solid var(--border);
10
+ border-radius: var(--radius-card);
11
+ max-width: 560px;
12
+ }
13
+
14
+ .plugin-runner-title {
15
+ font-family: var(--font-serif);
16
+ font-size: 17px;
17
+ font-weight: 600;
18
+ color: var(--text);
19
+ margin: 0 0 16px;
20
+ }
21
+
22
+ /* 结果:等宽 + 可横向滚(JSON 美化输出) */
23
+ .plugin-result {
24
+ margin: 12px 0 0;
25
+ padding: 12px 14px;
26
+ background: var(--bg-sunken);
27
+ border: 1px solid var(--border);
28
+ border-radius: var(--radius-control);
29
+ font-family: var(--font-mono);
30
+ font-size: 12.5px;
31
+ line-height: 1.6;
32
+ color: var(--text);
33
+ white-space: pre-wrap;
34
+ word-break: break-word;
35
+ overflow-x: auto;
36
+ font-variant-numeric: tabular-nums;
37
+ }
38
+
39
+ /* 选中态(卡片主区点击选中,运行面板跟着切) */
40
+ .flow-item.is-selected {
41
+ border-color: var(--accent);
42
+ }
43
+
44
+ .flow-item.is-selected .flow-item-name {
45
+ color: var(--accent);
46
+ }
47
+
48
+ /* 卡片里的一句描述(100 件库没有描述会难挑) */
49
+ .flow-item-desc {
50
+ overflow: hidden;
51
+ text-overflow: ellipsis;
52
+ white-space: nowrap;
53
+ max-width: 40ch;
54
+ }
55
+
56
+ /* 分类筛选行(全部/文本/编码/…) */
57
+ .plugin-categories {
58
+ display: flex;
59
+ flex-wrap: wrap;
60
+ gap: 6px;
61
+ margin-bottom: 14px;
62
+ }
63
+
64
+ .plugin-cat {
65
+ padding: 4px 12px;
66
+ border: 1px solid var(--border);
67
+ border-radius: 999px;
68
+ background: var(--bg);
69
+ color: var(--text-secondary);
70
+ font-size: 12px;
71
+ cursor: pointer;
72
+ transition:
73
+ border-color 150ms ease,
74
+ color 150ms ease,
75
+ background 150ms ease;
76
+ }
77
+
78
+ .plugin-cat:hover {
79
+ border-color: var(--border-strong);
80
+ color: var(--text);
81
+ }
82
+
83
+ .plugin-cat.is-active {
84
+ border-color: var(--accent);
85
+ color: var(--accent);
86
+ background: var(--accent-soft);
87
+ }
88
+
89
+ /* 分类徽章(卡片上,主色化) */
90
+ .flow-badge.is-on {
91
+ color: var(--accent);
92
+ border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
93
+ }
css/prefs-ui.css ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 模型偏好分组(契约 14A)的控件样式——只用 theme.css 的色彩令牌,
2
+ 不硬编码任何颜色;风格对齐设置页其余分组(Warm Paper)。 */
3
+
4
+ /* 顶部「MiMo 预置建议」一键应用条 */
5
+ .mp-preset {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ gap: 16px;
10
+ padding: 12px 0;
11
+ border-top: 1px solid var(--border);
12
+ }
13
+ .mp-preset-text {
14
+ min-width: 0;
15
+ }
16
+ .mp-preset-label {
17
+ font-weight: 500;
18
+ color: var(--text);
19
+ }
20
+ .mp-preset-hint {
21
+ margin: 2px 0 0;
22
+ font-size: 12.5px;
23
+ color: var(--text-tertiary);
24
+ line-height: 1.5;
25
+ }
26
+ .mp-preset-btn {
27
+ appearance: none;
28
+ border: 1px solid var(--accent);
29
+ background: var(--accent);
30
+ color: var(--bg);
31
+ font: inherit;
32
+ font-size: 13px;
33
+ line-height: 1;
34
+ padding: 8px 14px;
35
+ border-radius: var(--radius-control);
36
+ cursor: pointer;
37
+ flex-shrink: 0;
38
+ transition: opacity var(--dur) var(--ease);
39
+ }
40
+ .mp-preset-btn:hover {
41
+ opacity: 0.9;
42
+ }
43
+ .mp-preset-btn:disabled {
44
+ opacity: 0.5;
45
+ cursor: not-allowed;
46
+ }
47
+ .mp-preset-btn:focus-visible {
48
+ outline: 2px solid var(--accent);
49
+ outline-offset: 1px;
50
+ }
51
+
52
+ /* 模型行列表 */
53
+ .mp-list {
54
+ margin-top: 4px;
55
+ }
56
+ .mp-row {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: 16px;
60
+ padding: 12px 0;
61
+ border-top: 1px solid var(--border);
62
+ flex-wrap: wrap;
63
+ }
64
+ .mp-row:first-child {
65
+ border-top: none;
66
+ }
67
+ .mp-row-text {
68
+ min-width: 0;
69
+ flex: 1 1 180px;
70
+ }
71
+ .mp-row-name {
72
+ display: flex;
73
+ align-items: center;
74
+ gap: 8px;
75
+ font-weight: 500;
76
+ color: var(--text);
77
+ }
78
+ .mp-row-id {
79
+ margin: 2px 0 0;
80
+ font-size: 12px;
81
+ color: var(--text-tertiary);
82
+ font-family: var(--font-mono);
83
+ overflow: hidden;
84
+ text-overflow: ellipsis;
85
+ white-space: nowrap;
86
+ }
87
+
88
+ /* 云 / 本机 徽章 */
89
+ .mp-badge {
90
+ font-size: 11px;
91
+ line-height: 1;
92
+ padding: 3px 7px;
93
+ border-radius: var(--radius-chip);
94
+ flex-shrink: 0;
95
+ }
96
+ .mp-badge.is-cloud {
97
+ background: var(--accent-soft);
98
+ color: var(--accent);
99
+ }
100
+ .mp-badge.is-local {
101
+ background: var(--bg-sunken);
102
+ color: var(--text-secondary);
103
+ border: 1px solid var(--border);
104
+ }
105
+
106
+ /* 单个控件(思考档下拉 / 最大回复长度输入) */
107
+ .mp-field {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: 4px;
111
+ flex-shrink: 0;
112
+ }
113
+ .mp-field-label {
114
+ font-size: 12px;
115
+ color: var(--text-secondary);
116
+ }
117
+ .mp-select {
118
+ appearance: none;
119
+ border: 1px solid var(--border);
120
+ background: var(--bg);
121
+ color: var(--text);
122
+ font: inherit;
123
+ font-size: 13px;
124
+ padding: 7px 10px;
125
+ border-radius: var(--radius-control);
126
+ min-width: 92px;
127
+ cursor: pointer;
128
+ }
129
+ .mp-select:focus-visible {
130
+ outline: 2px solid var(--accent);
131
+ outline-offset: 1px;
132
+ }
133
+ .mp-number {
134
+ border: 1px solid var(--border);
135
+ background: var(--bg);
136
+ color: var(--text);
137
+ font: inherit;
138
+ font-size: 13px;
139
+ padding: 7px 10px;
140
+ border-radius: var(--radius-control);
141
+ width: 130px;
142
+ }
143
+ .mp-number.is-invalid {
144
+ border-color: var(--danger);
145
+ }
146
+ .mp-number:focus-visible {
147
+ outline: 2px solid var(--accent);
148
+ outline-offset: 1px;
149
+ }
150
+ .mp-number.is-invalid:focus-visible {
151
+ outline-color: var(--danger);
152
+ }
153
+ .mp-field-error {
154
+ margin: 0;
155
+ font-size: 12px;
156
+ color: var(--danger);
157
+ line-height: 1.4;
158
+ max-width: 220px;
159
+ }
160
+
161
+ /* 操作反馈(一键应用结果) */
162
+ .mp-notice {
163
+ margin: 8px 0 0;
164
+ font-size: 12.5px;
165
+ color: var(--text-secondary);
166
+ }
css/prefs.css ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 设置页「可调控项」新分组的控件(契约 10A)——只用 theme.css 的色彩令牌,
2
+ 不硬编码任何颜色;风格对齐 Warm Paper(design-system.md)。 */
3
+
4
+ /* 分组内的一行:左侧说明,右侧控件 */
5
+ .pref-row {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ gap: 16px;
10
+ padding: 12px 0;
11
+ border-top: 1px solid var(--border);
12
+ }
13
+ .pref-row:first-of-type {
14
+ border-top: none;
15
+ }
16
+ .pref-row-text {
17
+ min-width: 0;
18
+ }
19
+ .pref-row-label {
20
+ font-weight: 500;
21
+ color: var(--text);
22
+ }
23
+ .pref-row-hint {
24
+ margin: 2px 0 0;
25
+ font-size: 12.5px;
26
+ color: var(--text-tertiary);
27
+ line-height: 1.5;
28
+ }
29
+
30
+ /* 分组内的子标题(把一行行控件分段) */
31
+ .pref-subhead {
32
+ margin: 20px 0 4px;
33
+ font-size: 12px;
34
+ font-weight: 600;
35
+ letter-spacing: 0.02em;
36
+ color: var(--text-secondary);
37
+ }
38
+ .pref-subhead:first-of-type {
39
+ margin-top: 8px;
40
+ }
41
+
42
+ /* 分段控件(三选/五选 pill):一排等宽小按钮,选中用 accent 底 */
43
+ .pref-seg {
44
+ display: inline-flex;
45
+ gap: 4px;
46
+ padding: 3px;
47
+ background: var(--bg-sunken);
48
+ border: 1px solid var(--border);
49
+ border-radius: var(--radius-control);
50
+ flex-shrink: 0;
51
+ }
52
+ .pref-seg-btn {
53
+ appearance: none;
54
+ border: none;
55
+ background: transparent;
56
+ color: var(--text-secondary);
57
+ font: inherit;
58
+ font-size: 13px;
59
+ line-height: 1;
60
+ padding: 7px 12px;
61
+ border-radius: var(--radius-chip);
62
+ cursor: pointer;
63
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
64
+ white-space: nowrap;
65
+ }
66
+ .pref-seg-btn:hover {
67
+ color: var(--text);
68
+ background: var(--bg-elevated);
69
+ }
70
+ .pref-seg-btn.is-active {
71
+ background: var(--accent);
72
+ color: var(--bg);
73
+ }
74
+ .pref-seg-btn:focus-visible {
75
+ outline: 2px solid var(--accent);
76
+ outline-offset: 1px;
77
+ }
78
+
79
+ /* 下拉(模型/轮询等):与设置页其它输入框同款 */
80
+ .pref-select {
81
+ font: inherit;
82
+ font-size: 13px;
83
+ color: var(--text);
84
+ background: var(--bg-sunken);
85
+ border: 1px solid var(--border);
86
+ border-radius: var(--radius-control);
87
+ padding: 8px 10px;
88
+ min-width: 200px;
89
+ cursor: pointer;
90
+ }
91
+ .pref-select:focus-visible {
92
+ outline: 2px solid var(--accent);
93
+ outline-offset: 1px;
94
+ }
95
+
96
+ /* 开关(记忆/语义检索):胶囊滑块,选中=accent */
97
+ .pref-switch {
98
+ appearance: none;
99
+ border: 1px solid var(--border);
100
+ background: var(--bg-sunken);
101
+ position: relative;
102
+ width: 42px;
103
+ height: 24px;
104
+ border-radius: 12px;
105
+ cursor: pointer;
106
+ flex-shrink: 0;
107
+ transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
108
+ }
109
+ .pref-switch::after {
110
+ content: "";
111
+ position: absolute;
112
+ top: 2px;
113
+ left: 2px;
114
+ width: 18px;
115
+ height: 18px;
116
+ border-radius: 50%;
117
+ background: var(--bg-elevated);
118
+ border: 1px solid var(--border);
119
+ transition: transform var(--dur) var(--ease);
120
+ }
121
+ .pref-switch[aria-checked="true"] {
122
+ background: var(--accent);
123
+ border-color: var(--accent);
124
+ }
125
+ .pref-switch[aria-checked="true"]::after {
126
+ transform: translateX(18px);
127
+ background: var(--bg);
128
+ border-color: transparent;
129
+ }
130
+ .pref-switch:focus-visible {
131
+ outline: 2px solid var(--accent);
132
+ outline-offset: 2px;
133
+ }
134
+
135
+ /* 保存/失败的一句人话提示(成功淡出、失败用 danger) */
136
+ .pref-notice {
137
+ margin: 10px 0 0;
138
+ font-size: 12.5px;
139
+ line-height: 1.5;
140
+ }
141
+ .pref-notice.is-ok {
142
+ color: var(--success);
143
+ }
144
+ .pref-notice.is-error {
145
+ color: var(--danger);
146
+ }
147
+
148
+ /* 「关于」里的审计日志按钮行 */
149
+ .pref-audit-row {
150
+ display: flex;
151
+ gap: 8px;
152
+ align-items: center;
153
+ flex-wrap: wrap;
154
+ }
155
+ .pref-confirm {
156
+ display: inline-flex;
157
+ gap: 8px;
158
+ align-items: center;
159
+ font-size: 12.5px;
160
+ color: var(--text-secondary);
161
+ }
162
+
163
+ .gpu-accel-actions {
164
+ display: flex;
165
+ flex-wrap: wrap;
166
+ gap: 8px;
167
+ padding: 12px 0;
168
+ border-top: 1px solid var(--border);
169
+ }
170
+ .gpu-accel-actions button {
171
+ display: inline-flex;
172
+ align-items: center;
173
+ gap: 7px;
174
+ }
175
+ .gpu-accel-message {
176
+ margin: 4px 0 10px;
177
+ color: var(--success);
178
+ font-size: 12.5px;
179
+ line-height: 1.5;
180
+ }
181
+ .gpu-accel-message.is-error {
182
+ color: var(--danger);
183
+ }
184
+ .gpu-accel-status {
185
+ padding-top: 12px;
186
+ border-top: 1px solid var(--border);
187
+ color: var(--text-secondary);
188
+ font-size: 12.5px;
189
+ }
190
+ .gpu-accel-status > strong {
191
+ display: block;
192
+ margin-bottom: 8px;
193
+ color: var(--text);
194
+ font-weight: 550;
195
+ }
196
+ .gpu-accel-status > p {
197
+ margin: 0;
198
+ color: var(--text-tertiary);
199
+ }
200
+ .gpu-accel-model {
201
+ display: grid;
202
+ grid-template-columns: minmax(120px, 1fr) auto auto;
203
+ gap: 12px;
204
+ padding: 7px 0;
205
+ border-top: 1px solid var(--border-subtle, var(--border));
206
+ font-variant-numeric: tabular-nums;
207
+ }
208
+ .gpu-accel-model span:first-child {
209
+ min-width: 0;
210
+ overflow-wrap: anywhere;
211
+ color: var(--text);
212
+ }
213
+ @media (max-width: 620px) {
214
+ .gpu-accel-model {
215
+ grid-template-columns: 1fr auto;
216
+ }
217
+ .gpu-accel-model span:first-child {
218
+ grid-column: 1 / -1;
219
+ }
220
+ }
css/screensaver.css ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 待机显示 · 涅槃屏保 b2(对齐参考:Google 新标签页风格)——
2
+ 明亮浅蓝渐变底 + 斜向柔光带流动 + 中央磨砂玻璃卡四色星 + 极简时钟。
3
+ 纯 CSS(三层大渐变缓动,GPU 合成、零 WebGL),颜色锚 Google 四色系。 */
4
+
5
+ .saver-root {
6
+ position: fixed;
7
+ inset: 0;
8
+ overflow: hidden;
9
+ /* 明亮浅蓝基底(参考图主调):上浅白 → 下饱和蓝 */
10
+ background: linear-gradient(180deg, #eaf3fc 0%, #cfe6fb 38%, #9fcbf5 78%, #7fb5ee 100%);
11
+ cursor: none;
12
+ }
13
+
14
+ /* ── 三层柔光带:斜向大渐变,缓慢漂移(生命力的来源)──────────── */
15
+ .saver-glow {
16
+ position: absolute;
17
+ inset: -30%;
18
+ pointer-events: none;
19
+ }
20
+
21
+ /* 光带 A:左上斜白光(参考图里的斜向光束) */
22
+ .saver-glow-a {
23
+ background: linear-gradient(
24
+ 118deg,
25
+ transparent 12%,
26
+ rgba(255, 255, 255, 0.75) 26%,
27
+ rgba(255, 255, 255, 0.15) 34%,
28
+ transparent 46%
29
+ );
30
+ animation: saver-drift-a 26s ease-in-out infinite alternate;
31
+ }
32
+
33
+ /* 光带 B:右侧青蓝柔光团 */
34
+ .saver-glow-b {
35
+ background: radial-gradient(
36
+ 55% 70% at 78% 30%,
37
+ rgba(120, 200, 255, 0.55),
38
+ transparent 70%
39
+ );
40
+ animation: saver-drift-b 34s ease-in-out infinite alternate;
41
+ }
42
+
43
+ /* 光带 C:底部深蓝晕(压出层次与纵深) */
44
+ .saver-glow-c {
45
+ background: radial-gradient(
46
+ 80% 60% at 30% 110%,
47
+ rgba(35, 90, 200, 0.4),
48
+ transparent 65%
49
+ );
50
+ animation: saver-drift-c 42s ease-in-out infinite alternate;
51
+ }
52
+
53
+ @keyframes saver-drift-a {
54
+ from { transform: translateX(-8%) rotate(-2deg); }
55
+ to { transform: translateX(10%) rotate(3deg); }
56
+ }
57
+ @keyframes saver-drift-b {
58
+ from { transform: translate(0, 0) scale(1); }
59
+ to { transform: translate(-6%, 8%) scale(1.15); }
60
+ }
61
+ @keyframes saver-drift-c {
62
+ from { transform: translate(0, 0); }
63
+ to { transform: translate(8%, -4%) scale(1.1); }
64
+ }
65
+
66
+ /* ── 中央磨砂玻璃卡 + 四色星(参考图主体)──────────────────────── */
67
+ .saver-card {
68
+ position: absolute;
69
+ left: 50%;
70
+ top: 50%;
71
+ transform: translate(-50%, -52%);
72
+ width: min(34vmin, 300px);
73
+ aspect-ratio: 1;
74
+ border-radius: 15%; /* 参考图的大圆角方卡 */
75
+ background: linear-gradient(155deg, rgba(255, 255, 255, 0.92), rgba(240, 248, 255, 0.78));
76
+ backdrop-filter: blur(18px) saturate(1.15);
77
+ -webkit-backdrop-filter: blur(18px) saturate(1.15);
78
+ box-shadow:
79
+ 0 24px 70px rgba(30, 80, 160, 0.28),
80
+ 0 4px 18px rgba(30, 80, 160, 0.14),
81
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ /* 卡整体极缓呼吸(5% 缩放,22 秒一拍——「活着」但不抢戏) */
86
+ animation: saver-card-breathe 22s ease-in-out infinite;
87
+ }
88
+
89
+ @keyframes saver-card-breathe {
90
+ 0%, 100% { transform: translate(-50%, -52%) scale(1); }
91
+ 50% { transform: translate(-50%, -52%) scale(1.045); }
92
+ }
93
+
94
+ /* 四色四角星:conic 渐变 + clip-path(与品牌标同形状语言),
95
+ 极慢自转(60 秒一圈——看得见在转,不引人焦躁) */
96
+ .saver-star {
97
+ width: 52%;
98
+ aspect-ratio: 1;
99
+ background: conic-gradient(
100
+ from 200deg,
101
+ #4285f4,
102
+ #9b72cb,
103
+ #ea4335,
104
+ #fbbc04,
105
+ #34a853,
106
+ #4285f4
107
+ );
108
+ clip-path: polygon(
109
+ 50% 0%, 61% 39%, 100% 50%, 61% 61%,
110
+ 50% 100%, 39% 61%, 0% 50%, 39% 39%
111
+ );
112
+ filter: blur(0.3px) saturate(1.08);
113
+ animation: saver-star-spin 60s linear infinite;
114
+ }
115
+
116
+ @keyframes saver-star-spin {
117
+ from { transform: rotate(0deg); }
118
+ to { transform: rotate(360deg); }
119
+ }
120
+
121
+ /* ── 时钟:卡下极简一行,浅色系深灰细字 ────────────────────────── */
122
+ .saver-clock {
123
+ position: absolute;
124
+ left: 50%;
125
+ bottom: 12%;
126
+ transform: translateX(-50%);
127
+ display: flex;
128
+ align-items: baseline;
129
+ gap: 14px;
130
+ color: rgba(20, 50, 95, 0.72);
131
+ font-family: "Source Serif 4", "Songti SC", Georgia, serif;
132
+ text-shadow: 0 1px 12px rgba(255, 255, 255, 0.6);
133
+ user-select: none;
134
+ pointer-events: none;
135
+ }
136
+
137
+ .saver-time {
138
+ font-size: clamp(34px, 5.6vw, 64px);
139
+ font-weight: 600;
140
+ letter-spacing: 0.03em;
141
+ line-height: 1;
142
+ font-variant-numeric: tabular-nums;
143
+ }
144
+
145
+ .saver-date {
146
+ font-size: clamp(15px, 2vw, 22px);
147
+ font-weight: 400;
148
+ letter-spacing: 0.18em;
149
+ opacity: 0.85;
150
+ }
151
+
152
+ /* ── 形态一:苹果航拍视频层(全屏 object-fit cover)────────────── */
153
+ .saver-video {
154
+ position: absolute;
155
+ inset: 0;
156
+ width: 100%;
157
+ height: 100%;
158
+ object-fit: cover;
159
+ display: block;
160
+ }
161
+
162
+ /* 航拍态时钟:浅白字(视频上) */
163
+ .saver-clock.on-video {
164
+ color: rgba(255, 255, 255, 0.9);
165
+ text-shadow: 0 1px 18px rgba(0, 0, 0, 0.45);
166
+ }
167
+
168
+ /* ── 回来提示(首次进入 5 秒淡出)──────────────────────────────── */
169
+ .saver-hint {
170
+ position: absolute;
171
+ bottom: 34px;
172
+ right: 40px;
173
+ margin: 0;
174
+ color: rgba(20, 50, 95, 0.45);
175
+ font-size: 12.5px;
176
+ letter-spacing: 0.2em;
177
+ pointer-events: none;
178
+ user-select: none;
179
+ animation: saver-hint-fade 5s ease forwards;
180
+ }
181
+
182
+ @keyframes saver-hint-fade {
183
+ 0%, 60% { opacity: 1; }
184
+ 100% { opacity: 0; }
185
+ }
186
+
187
+ /* 减弱动效:全部光层静止(星也停转),只留静帧构图 */
188
+ @media (prefers-reduced-motion: reduce) {
189
+ .saver-glow-a,
190
+ .saver-glow-b,
191
+ .saver-glow-c,
192
+ .saver-star,
193
+ .saver-card {
194
+ animation: none;
195
+ }
196
+ }
css/sight.css ADDED
@@ -0,0 +1,447 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 看图问答浮窗:与划词浮层同款 Warm Paper 毛玻璃卡片(颜色一律走 theme.css 令牌)。
2
+ 透明原生窗口上不用 backdrop-filter(坑位实测记录 #1),模糊交给 macOS 窗口特效,
3
+ CSS 只保留 85% 暖纸半透明底色。 */
4
+
5
+ /* 透明窗口本体:桌面要从圆角外透出来 */
6
+ body.sight-surface {
7
+ background: transparent;
8
+ }
9
+
10
+ .sight-root {
11
+ height: 100%;
12
+ display: flex;
13
+ padding: 12px;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ /* ---------- 卡片容器 ---------- */
18
+ .sight-card {
19
+ flex: 1;
20
+ min-height: 0;
21
+ display: flex;
22
+ flex-direction: column;
23
+ overflow: hidden;
24
+ border: 1px solid var(--border);
25
+ border-radius: var(--radius-float);
26
+ background: var(--glass);
27
+ box-shadow: var(--shadow-float);
28
+ animation: sight-in 180ms var(--ease);
29
+ }
30
+
31
+ @keyframes sight-in {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(6px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ /* ---------- 顶栏 ---------- */
43
+ .sight-head {
44
+ display: flex;
45
+ align-items: baseline;
46
+ justify-content: space-between;
47
+ gap: 12px;
48
+ padding: 16px 20px 4px;
49
+ }
50
+
51
+ .sight-title {
52
+ margin: 0;
53
+ font-family: var(--font-serif);
54
+ font-size: 20px;
55
+ font-weight: 600;
56
+ letter-spacing: -0.01em;
57
+ color: var(--text);
58
+ }
59
+
60
+ .sight-esc {
61
+ font-size: 12px;
62
+ color: var(--text-tertiary);
63
+ white-space: nowrap;
64
+ }
65
+
66
+ /* ---------- 权限状态灯 ---------- */
67
+ .sight-perms {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ gap: 10px;
71
+ padding: 6px 20px 2px;
72
+ }
73
+
74
+ .sight-perm {
75
+ display: inline-flex;
76
+ align-items: center;
77
+ gap: 6px;
78
+ padding: 0;
79
+ border: none;
80
+ background: transparent;
81
+ color: var(--text-secondary);
82
+ font-family: inherit;
83
+ font-size: 12px;
84
+ cursor: default;
85
+ text-align: left;
86
+ }
87
+
88
+ button.sight-perm.is-bad {
89
+ cursor: pointer;
90
+ text-decoration: underline;
91
+ text-underline-offset: 3px;
92
+ }
93
+
94
+ .sight-dot {
95
+ width: 7px;
96
+ height: 7px;
97
+ border-radius: 50%;
98
+ background: var(--text-tertiary);
99
+ flex-shrink: 0;
100
+ }
101
+
102
+ .sight-perm.is-ok {
103
+ color: var(--success);
104
+ }
105
+
106
+ .sight-perm.is-ok .sight-dot {
107
+ background: var(--success);
108
+ }
109
+
110
+ .sight-perm.is-bad {
111
+ color: var(--warning);
112
+ }
113
+
114
+ .sight-perm.is-bad .sight-dot {
115
+ background: var(--warning);
116
+ }
117
+
118
+ .sight-perm.is-mute {
119
+ color: var(--text-tertiary);
120
+ }
121
+
122
+ /* ---------- 空态 / 提示 ---------- */
123
+ .sight-note {
124
+ margin: 0;
125
+ padding: 16px 20px 20px;
126
+ font-size: 13.5px;
127
+ line-height: 1.6;
128
+ color: var(--text-secondary);
129
+ }
130
+
131
+ .sight-note.is-warn {
132
+ color: var(--warning);
133
+ }
134
+
135
+ /* ---------- 图片预览 ---------- */
136
+ .sight-preview {
137
+ margin: 10px 20px 0;
138
+ padding: 0;
139
+ display: flex;
140
+ flex-direction: column;
141
+ gap: 6px;
142
+ }
143
+
144
+ .sight-preview img {
145
+ display: block;
146
+ max-width: 100%;
147
+ max-height: 170px;
148
+ object-fit: contain;
149
+ object-position: left top;
150
+ border: 1px solid var(--border);
151
+ border-radius: var(--radius-control);
152
+ background: var(--bg-sunken);
153
+ }
154
+
155
+ .sight-preview-meta {
156
+ font-size: 11.5px;
157
+ color: var(--text-tertiary);
158
+ font-variant-numeric: tabular-nums;
159
+ }
160
+
161
+ /* ---------- 提问输入 ---------- */
162
+ .sight-custom {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: 8px;
166
+ margin: 10px 20px 0;
167
+ padding: 6px 6px 6px 12px;
168
+ border: 1px solid transparent;
169
+ border-radius: var(--radius-control);
170
+ background: var(--bg-sunken);
171
+ transition: border-color var(--dur) var(--ease);
172
+ }
173
+
174
+ .sight-custom:focus-within {
175
+ border-color: var(--accent);
176
+ }
177
+
178
+ .sight-input {
179
+ flex: 1;
180
+ min-width: 0;
181
+ border: none;
182
+ background: transparent;
183
+ color: var(--text);
184
+ font-family: inherit;
185
+ font-size: 13.5px;
186
+ outline: none;
187
+ cursor: text;
188
+ }
189
+
190
+ .sight-input::placeholder {
191
+ color: var(--text-tertiary);
192
+ }
193
+
194
+ .sight-send {
195
+ flex-shrink: 0;
196
+ height: 28px;
197
+ padding: 0 12px;
198
+ border: none;
199
+ border-radius: var(--radius-chip);
200
+ background: var(--accent);
201
+ color: var(--bg);
202
+ font-family: inherit;
203
+ font-size: 13px;
204
+ cursor: pointer;
205
+ transition: opacity var(--dur) var(--ease);
206
+ }
207
+
208
+ .sight-send:disabled {
209
+ opacity: 0.4;
210
+ cursor: default;
211
+ }
212
+
213
+ /* ---------- 模型下拉(vision-only 过滤后的清单) ---------- */
214
+ .sight-model-row {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 8px;
218
+ margin: 8px 20px 0;
219
+ }
220
+
221
+ .sight-model-label {
222
+ font-size: 12px;
223
+ color: var(--text-tertiary);
224
+ white-space: nowrap;
225
+ }
226
+
227
+ .sight-model {
228
+ flex: 1;
229
+ min-width: 0;
230
+ height: 30px;
231
+ padding: 0 8px;
232
+ border: 1px solid var(--border);
233
+ border-radius: var(--radius-chip);
234
+ background: var(--bg-sunken);
235
+ color: var(--text);
236
+ font-family: inherit;
237
+ font-size: 12.5px;
238
+ outline: none;
239
+ cursor: pointer;
240
+ }
241
+
242
+ .sight-model:disabled {
243
+ opacity: 0.6;
244
+ cursor: default;
245
+ }
246
+
247
+ /* ---------- 回答区 ---------- */
248
+ .sight-answer {
249
+ flex: 1;
250
+ min-height: 0;
251
+ display: flex;
252
+ flex-direction: column;
253
+ margin-top: 10px;
254
+ padding: 10px 20px 14px;
255
+ border-top: 1px solid var(--border);
256
+ }
257
+
258
+ .sight-answer-body {
259
+ flex: 1;
260
+ min-height: 0;
261
+ overflow-y: auto;
262
+ }
263
+
264
+ .sight-answer-text {
265
+ margin: 0;
266
+ color: var(--text);
267
+ font-size: 13.5px;
268
+ line-height: 1.65;
269
+ white-space: pre-wrap;
270
+ word-break: break-word;
271
+ user-select: text;
272
+ }
273
+
274
+ /* 流式呼吸光标(与划词浮层同款;reduced-motion 时 theme.css 全局降级) */
275
+ .sight-cursor {
276
+ display: inline-block;
277
+ width: 2px;
278
+ height: 1.05em;
279
+ margin-left: 3px;
280
+ border-radius: 1px;
281
+ background: var(--accent);
282
+ vertical-align: text-bottom;
283
+ animation: sight-cursor-breathe 1s ease-in-out infinite;
284
+ }
285
+
286
+ @keyframes sight-cursor-breathe {
287
+ 0%,
288
+ 100% {
289
+ opacity: 1;
290
+ }
291
+ 50% {
292
+ opacity: 0.15;
293
+ }
294
+ }
295
+
296
+ .sight-error {
297
+ margin: 8px 0 0;
298
+ color: var(--danger);
299
+ font-size: 12.5px;
300
+ line-height: 1.5;
301
+ }
302
+
303
+ .sight-answer-foot {
304
+ display: flex;
305
+ align-items: center;
306
+ justify-content: space-between;
307
+ gap: 12px;
308
+ margin-top: 12px;
309
+ }
310
+
311
+ .sight-save {
312
+ display: inline-flex;
313
+ align-items: center;
314
+ gap: 6px;
315
+ height: 30px;
316
+ padding: 0 12px;
317
+ border: 1px solid var(--border);
318
+ border-radius: var(--radius-control);
319
+ background: transparent;
320
+ color: var(--text-secondary);
321
+ font-family: inherit;
322
+ font-size: 12.5px;
323
+ cursor: pointer;
324
+ transition: background-color var(--dur) var(--ease);
325
+ }
326
+
327
+ .sight-save:hover:not(:disabled) {
328
+ background: var(--accent-soft);
329
+ color: var(--text);
330
+ }
331
+
332
+ .sight-save:disabled {
333
+ opacity: 0.5;
334
+ cursor: default;
335
+ }
336
+
337
+ .sight-foot-hint {
338
+ font-size: 12px;
339
+ color: var(--text-tertiary);
340
+ }
341
+
342
+ /* ---------- 授权引导态(与划词浮层同款骨架) ---------- */
343
+ .sight-guide {
344
+ flex: 1;
345
+ display: flex;
346
+ flex-direction: column;
347
+ padding: 24px 24px 20px;
348
+ }
349
+
350
+ .sight-guide-head {
351
+ display: flex;
352
+ align-items: center;
353
+ gap: 10px;
354
+ color: var(--accent);
355
+ }
356
+
357
+ .sight-guide .sight-title {
358
+ font-size: 22px;
359
+ }
360
+
361
+ .sight-lead {
362
+ margin: 12px 0 18px;
363
+ color: var(--text-secondary);
364
+ font-size: 14px;
365
+ line-height: 1.65;
366
+ }
367
+
368
+ .sight-guide-actions {
369
+ display: flex;
370
+ flex-wrap: wrap;
371
+ gap: 10px;
372
+ }
373
+
374
+ .sight-primary {
375
+ height: 40px;
376
+ padding: 0 20px;
377
+ border: none;
378
+ border-radius: var(--radius-control);
379
+ background: var(--accent);
380
+ color: var(--bg);
381
+ font-family: inherit;
382
+ font-size: 14px;
383
+ cursor: pointer;
384
+ }
385
+
386
+ .sight-primary:hover {
387
+ filter: brightness(0.94);
388
+ }
389
+
390
+ .sight-secondary {
391
+ height: 40px;
392
+ padding: 0 16px;
393
+ border: 1px solid var(--border);
394
+ border-radius: var(--radius-control);
395
+ background: transparent;
396
+ color: var(--text-secondary);
397
+ font-family: inherit;
398
+ font-size: 13.5px;
399
+ cursor: pointer;
400
+ }
401
+
402
+ .sight-secondary:hover {
403
+ background: var(--bg-elevated);
404
+ color: var(--text);
405
+ }
406
+
407
+ .sight-guide-why {
408
+ margin: 16px 0 0;
409
+ color: var(--text-tertiary);
410
+ font-size: 12.5px;
411
+ line-height: 1.7;
412
+ }
413
+
414
+ .sight-guide-hint {
415
+ margin-top: auto;
416
+ padding-top: 18px;
417
+ color: var(--text-tertiary);
418
+ font-size: 12.5px;
419
+ line-height: 1.6;
420
+ }
421
+
422
+ /* ---------- 实时之眼入口(契约 12B):摄像头状态点 + 打开 ---------- */
423
+ .sight-perm.is-wait {
424
+ color: var(--warning);
425
+ }
426
+
427
+ .sight-perm.is-wait .sight-dot {
428
+ background: var(--warning);
429
+ }
430
+
431
+ button.sight-perm.is-live {
432
+ cursor: pointer;
433
+ color: var(--accent);
434
+ }
435
+
436
+ button.sight-perm.is-live:hover {
437
+ text-decoration: underline;
438
+ text-underline-offset: 3px;
439
+ }
440
+
441
+ button.sight-perm.is-live.is-ok {
442
+ color: var(--success);
443
+ }
444
+
445
+ button.sight-perm.is-live.is-bad {
446
+ color: var(--danger);
447
+ }
css/skills.css ADDED
@@ -0,0 +1,424 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Skill 技能系统(Phase 5C):技能中心页 + Composer 技能选择条。
2
+ Warm Paper 全令牌配色,遵循 design-system.md;无硬编码颜色。 */
3
+
4
+ /* ── Composer 技能选择条(输入框上方,可横向滚动) ─────────────────── */
5
+
6
+ .composer-skills {
7
+ display: flex;
8
+ gap: 8px;
9
+ max-width: 760px;
10
+ margin: 0 auto 10px;
11
+ padding-bottom: 2px;
12
+ overflow-x: auto;
13
+ scrollbar-width: none;
14
+ }
15
+
16
+ .composer-skills::-webkit-scrollbar {
17
+ display: none;
18
+ }
19
+
20
+ .skill-chip {
21
+ display: inline-flex;
22
+ align-items: center;
23
+ gap: 6px;
24
+ flex: 0 0 auto;
25
+ height: 28px;
26
+ padding: 0 12px;
27
+ border: 1px solid var(--border);
28
+ border-radius: var(--radius-control);
29
+ background: var(--bg);
30
+ color: var(--text-secondary);
31
+ font-family: var(--font-sans);
32
+ font-size: 12.5px;
33
+ line-height: 1;
34
+ cursor: pointer;
35
+ transition:
36
+ background-color var(--dur) var(--ease),
37
+ border-color var(--dur) var(--ease);
38
+ }
39
+
40
+ .skill-chip:hover {
41
+ border-color: var(--accent);
42
+ color: var(--text);
43
+ }
44
+
45
+ .skill-chip:focus-visible {
46
+ outline: 2px solid var(--accent);
47
+ outline-offset: 2px;
48
+ }
49
+
50
+ .skill-chip.is-selected {
51
+ background: var(--accent-soft);
52
+ border-color: var(--accent);
53
+ color: var(--text);
54
+ }
55
+
56
+ /* 脚本技能置灰不可选:执行属于 Agent 面板的确认流程 */
57
+ .skill-chip.is-script {
58
+ opacity: 0.55;
59
+ cursor: not-allowed;
60
+ }
61
+
62
+ .skill-chip.is-script:hover {
63
+ border-color: var(--border);
64
+ color: var(--text-secondary);
65
+ }
66
+
67
+ /* ── 技能中心页 ───────────────────────────────────────────────────── */
68
+
69
+ .skills {
70
+ flex: 1;
71
+ min-width: 0;
72
+ overflow-y: auto;
73
+ padding: 36px 48px 48px;
74
+ }
75
+
76
+ .skills-head {
77
+ display: flex;
78
+ align-items: flex-end;
79
+ justify-content: space-between;
80
+ gap: 16px;
81
+ margin-bottom: 20px;
82
+ flex-wrap: wrap;
83
+ }
84
+
85
+ .skills-head h1 {
86
+ font-size: 30px;
87
+ }
88
+
89
+ .skills-head-sub {
90
+ max-width: 560px;
91
+ margin: 6px 0 0;
92
+ font-size: 13.5px;
93
+ line-height: 1.7;
94
+ color: var(--text-secondary);
95
+ }
96
+
97
+ .skills-import-btn {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: 8px;
101
+ height: 40px;
102
+ padding: 0 18px;
103
+ border: none;
104
+ border-radius: var(--radius-control);
105
+ background: var(--accent);
106
+ color: var(--bg);
107
+ font-family: var(--font-sans);
108
+ font-size: 14px;
109
+ cursor: pointer;
110
+ transition: opacity var(--dur) var(--ease);
111
+ }
112
+
113
+ .skills-import-btn:hover {
114
+ opacity: 0.9;
115
+ }
116
+
117
+ .skills-import-btn:focus-visible {
118
+ outline: 2px solid var(--accent);
119
+ outline-offset: 2px;
120
+ }
121
+
122
+ .skills-import-btn:disabled {
123
+ opacity: 0.6;
124
+ cursor: default;
125
+ }
126
+
127
+ .skills-spin {
128
+ animation: skills-rotate 1s linear infinite;
129
+ }
130
+
131
+ @keyframes skills-rotate {
132
+ to {
133
+ transform: rotate(360deg);
134
+ }
135
+ }
136
+
137
+ @media (prefers-reduced-motion: reduce) {
138
+ .skills-spin {
139
+ animation: none;
140
+ }
141
+ }
142
+
143
+ .skills-notice {
144
+ margin: 0 0 20px;
145
+ padding: 10px 14px;
146
+ border: 1px solid var(--border);
147
+ border-radius: var(--radius-control);
148
+ background: var(--accent-soft);
149
+ font-size: 13px;
150
+ line-height: 1.7;
151
+ color: var(--text);
152
+ }
153
+
154
+ .skills-error {
155
+ margin: 0 0 20px;
156
+ font-size: 13px;
157
+ color: var(--danger);
158
+ }
159
+
160
+ .skills-muted {
161
+ margin: 24px 0 0;
162
+ font-size: 13px;
163
+ color: var(--text-secondary);
164
+ }
165
+
166
+ .skills-empty {
167
+ margin: 56px 0;
168
+ text-align: center;
169
+ }
170
+
171
+ .skills-empty-title {
172
+ margin: 0;
173
+ font-family: var(--font-serif);
174
+ font-size: 24px;
175
+ font-weight: 600;
176
+ color: var(--text);
177
+ }
178
+
179
+ .skills-empty-sub {
180
+ max-width: 420px;
181
+ margin: 12px auto 0;
182
+ font-size: 13.5px;
183
+ line-height: 1.8;
184
+ color: var(--text-secondary);
185
+ }
186
+
187
+ .skills-group {
188
+ margin-bottom: 40px;
189
+ }
190
+
191
+ .skills-group-title {
192
+ margin: 0;
193
+ font-size: 19px;
194
+ }
195
+
196
+ .skills-group-hint {
197
+ margin: 4px 0 16px;
198
+ font-size: 13px;
199
+ color: var(--text-secondary);
200
+ }
201
+
202
+ .skills-grid {
203
+ display: grid;
204
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
205
+ gap: 16px;
206
+ }
207
+
208
+ /* ── 技能卡片 ───────────────────────────────────────────────────── */
209
+
210
+ .skill-card {
211
+ display: flex;
212
+ flex-direction: column;
213
+ gap: 8px;
214
+ padding: 16px;
215
+ border: 1px solid var(--border);
216
+ border-radius: var(--radius-card);
217
+ background: var(--bg-elevated);
218
+ }
219
+
220
+ .skill-card-head {
221
+ display: flex;
222
+ align-items: baseline;
223
+ justify-content: space-between;
224
+ gap: 10px;
225
+ }
226
+
227
+ .skill-name {
228
+ margin: 0;
229
+ font-family: var(--font-serif);
230
+ font-size: 17px;
231
+ font-weight: 600;
232
+ letter-spacing: -0.01em;
233
+ color: var(--text);
234
+ }
235
+
236
+ /* 状态徽章:与全站徽章同尺寸同字重(2px 8px / 12px / 500 / pill) */
237
+ .skill-badge {
238
+ display: inline-flex;
239
+ align-items: center;
240
+ gap: 4px;
241
+ flex: 0 0 auto;
242
+ padding: 2px 8px;
243
+ border-radius: 999px;
244
+ font-size: 12px;
245
+ font-weight: 500;
246
+ line-height: 1.5;
247
+ white-space: nowrap;
248
+ }
249
+
250
+ /* 提示词 = 绿色(安全);脚本 = 黄色(确认级) */
251
+ .skill-badge.is-prompt {
252
+ background: color-mix(in srgb, var(--success) 16%, transparent);
253
+ color: var(--success);
254
+ }
255
+
256
+ .skill-badge.is-script {
257
+ background: color-mix(in srgb, var(--warning) 18%, transparent);
258
+ color: var(--warning);
259
+ }
260
+
261
+ .skill-desc {
262
+ margin: 0;
263
+ font-size: 13px;
264
+ line-height: 1.7;
265
+ color: var(--text-secondary);
266
+ }
267
+
268
+ .skill-script-note {
269
+ margin: 0;
270
+ font-size: 12px;
271
+ line-height: 1.7;
272
+ color: var(--text-tertiary);
273
+ }
274
+
275
+ .skill-card-foot {
276
+ display: flex;
277
+ gap: 8px;
278
+ margin-top: auto;
279
+ padding-top: 4px;
280
+ }
281
+
282
+ .skill-btn {
283
+ display: inline-flex;
284
+ align-items: center;
285
+ gap: 5px;
286
+ height: 28px;
287
+ padding: 0 10px;
288
+ border: 1px solid var(--border);
289
+ border-radius: var(--radius-chip);
290
+ background: transparent;
291
+ color: var(--text-secondary);
292
+ font-family: var(--font-sans);
293
+ font-size: 12.5px;
294
+ cursor: pointer;
295
+ transition:
296
+ border-color var(--dur) var(--ease),
297
+ background-color var(--dur) var(--ease);
298
+ }
299
+
300
+ .skill-btn:hover {
301
+ color: var(--text);
302
+ border-color: var(--accent);
303
+ }
304
+
305
+ .skill-btn:focus-visible {
306
+ outline: 2px solid var(--accent);
307
+ outline-offset: 2px;
308
+ }
309
+
310
+ .skill-btn:disabled {
311
+ opacity: 0.5;
312
+ cursor: default;
313
+ }
314
+
315
+ .skill-btn:disabled:hover {
316
+ color: var(--text-secondary);
317
+ border-color: var(--border);
318
+ }
319
+
320
+ .skill-btn.is-primary {
321
+ background: var(--accent);
322
+ border-color: var(--accent);
323
+ color: var(--bg);
324
+ }
325
+
326
+ .skill-btn.is-primary:hover {
327
+ color: var(--bg);
328
+ opacity: 0.9;
329
+ }
330
+
331
+ .skill-btn.is-danger:hover {
332
+ color: var(--danger);
333
+ border-color: var(--danger);
334
+ }
335
+
336
+ /* 删除的两段确认:armed 状态用危险色提醒「再点一次」 */
337
+ .skill-btn.is-danger.is-armed {
338
+ color: var(--danger);
339
+ border-color: var(--danger);
340
+ background: color-mix(in srgb, var(--danger) 10%, transparent);
341
+ }
342
+
343
+ .skill-edit {
344
+ display: flex;
345
+ flex-direction: column;
346
+ gap: 8px;
347
+ }
348
+
349
+ .skill-edit-input {
350
+ width: 100%;
351
+ padding: 8px 10px;
352
+ border: 1px solid transparent;
353
+ border-radius: var(--radius-control);
354
+ background: var(--bg-sunken);
355
+ color: var(--text);
356
+ font-family: var(--font-sans);
357
+ font-size: 13px;
358
+ line-height: 1.7;
359
+ resize: vertical;
360
+ }
361
+
362
+ .skill-edit-input:focus {
363
+ outline: none;
364
+ border-color: var(--accent);
365
+ box-shadow: 0 0 0 3px var(--accent-soft);
366
+ }
367
+
368
+ .skill-edit-actions {
369
+ display: flex;
370
+ justify-content: flex-end;
371
+ gap: 8px;
372
+ }
373
+
374
+ /* ── 拖拽导入蒙层 ───────────────────────────────────────────────── */
375
+
376
+ .skills-drag-overlay {
377
+ position: fixed;
378
+ inset: 0;
379
+ z-index: 40;
380
+ display: flex;
381
+ align-items: center;
382
+ justify-content: center;
383
+ background: var(--glass);
384
+ }
385
+
386
+ .skills-drag-card {
387
+ display: flex;
388
+ flex-direction: column;
389
+ align-items: center;
390
+ gap: 8px;
391
+ padding: 40px 56px;
392
+ border: 1px dashed var(--border);
393
+ border-radius: var(--radius-float);
394
+ background: var(--bg-elevated);
395
+ color: var(--text-secondary);
396
+ }
397
+
398
+ .skills-drag-title {
399
+ margin: 8px 0 0;
400
+ font-family: var(--font-serif);
401
+ font-size: 22px;
402
+ font-weight: 600;
403
+ color: var(--text);
404
+ }
405
+
406
+ .skills-drag-sub {
407
+ margin: 0;
408
+ font-size: 13px;
409
+ color: var(--text-secondary);
410
+ }
411
+
412
+ @media (prefers-color-scheme: dark) {
413
+ .skill-badge.is-prompt {
414
+ background: color-mix(in srgb, var(--success) 22%, transparent);
415
+ }
416
+
417
+ .skill-badge.is-script {
418
+ background: color-mix(in srgb, var(--warning) 22%, transparent);
419
+ }
420
+
421
+ .skills-import-btn {
422
+ color: var(--bg);
423
+ }
424
+ }
css/studio.css ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* A shared shell, two densities. No duplicated business UI. */
2
+ .studio-shell{--resource-width:224px;display:grid;grid-template-rows:52px minmax(0,1fr) 26px;grid-template-columns:194px minmax(0,1fr);height:100dvh;background:var(--bg);color:var(--text);overflow:hidden;font-size:13px}
3
+ .studio-shell button,.studio-shell input,.studio-shell select,.studio-shell textarea{font-family:var(--font-sans)}.studio-topbar{grid-column:1/-1;display:flex;align-items:center;gap:14px;padding:0 15px 0 80px;border-bottom:1px solid var(--border);background:var(--bg-sunken);min-width:0}.studio-brand{display:flex;align-items:center;gap:7px;white-space:nowrap}.studio-brand>svg{color:var(--accent)}.studio-brand strong{font-size:14px;letter-spacing:-.4px}.studio-brand>span{font:7px var(--font-mono);letter-spacing:1px;color:var(--text-tertiary);margin-left:7px}.project-switch{display:flex;align-items:center;gap:6px;min-width:120px;max-width:240px}.project-switch select{border:0;background:transparent;color:var(--text);max-width:190px;min-width:70px;font-size:11px;outline-offset:2px}.project-switch .ws-icon{width:25px;height:25px}.command-search{margin-left:auto;display:flex;align-items:center;gap:9px;width:240px;max-width:28%;padding:6px 10px;background:var(--bg-elevated);border:1px solid var(--border);color:var(--text-secondary);border-radius:6px;font-size:10px;cursor:pointer}.command-search kbd{font-size:8px;color:var(--text-tertiary);margin-left:auto}.layout-toggle{display:flex;gap:2px;background:var(--bg-elevated);padding:3px;border:1px solid var(--border);border-radius:6px}.layout-toggle button{display:flex;align-items:center;gap:5px;padding:4px 9px;border:0;border-radius:4px;background:transparent;color:var(--text-secondary);font-size:10px;cursor:pointer}.layout-toggle button[aria-pressed="true"]{background:var(--bg-sunken);color:var(--accent);box-shadow:0 1px 3px rgba(0,0,0,.15)}
4
+ .studio-activity{grid-column:1;grid-row:2;display:flex;flex-direction:column;min-height:0;overflow-y:auto;overflow-x:hidden;padding:22px 10px 12px;border-right:1px solid var(--border);background:var(--bg-sunken)}.studio-activity>button,.studio-nav-bottom>button{display:flex;align-items:center;gap:10px;width:100%;border:1px solid transparent;background:transparent;color:var(--text-secondary);border-radius:8px;text-align:left;padding:11px 12px;margin-bottom:5px;cursor:pointer;flex-shrink:0}.studio-activity>button>svg,.studio-nav-bottom>button>svg{flex-shrink:0}.studio-activity button>span{min-width:0;font-size:12px;font-weight:500}.studio-activity button small{display:block;font-size:9px;font-weight:400;color:var(--text-tertiary);line-height:1.8;margin-top:4px}.studio-activity>button:hover,.studio-nav-bottom>button:hover{background:var(--bg-elevated);color:var(--text)}.studio-activity>button.is-active,.studio-nav-bottom>button.is-active{background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 23%,transparent);color:var(--accent)}.studio-nav-bottom{margin-top:auto;padding-top:18px;flex-shrink:0}.studio-nav-bottom>button{font-size:11px}.studio-nav-bottom>button>span{flex:1}.studio-nav-bottom>p{font-size:9px;color:var(--text-tertiary);line-height:1.8;margin:15px 12px 0;padding-top:12px;border-top:1px solid var(--border)}.nav-disclosure{padding:0 0 7px 30px}.nav-disclosure button{display:block;width:100%;padding:6px 4px;border:0;background:none;color:var(--text-secondary);font-size:10px;text-align:left;cursor:pointer}.nav-disclosure button:hover{color:var(--accent)}
5
+ .studio-main{grid-column:2;grid-row:2;display:flex;flex-direction:column;min-width:0;min-height:0;position:relative;padding-top:42px}.studio-document-tabs{display:none}.studio-breadcrumb{display:flex;align-items:center;gap:8px;padding:0 24px;height:34px;min-height:34px;border-bottom:1px solid var(--border);font-size:10px;color:var(--text-tertiary);overflow:hidden}.studio-breadcrumb>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-breadcrumb>strong{font-weight:400;color:var(--text-secondary);white-space:nowrap}.studio-breadcrumb>.ws-link{margin-left:auto;flex-shrink:0;font-size:10px}.studio-stage{display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;overflow:hidden;position:relative}.studio-stage>.studio-feature,.studio-stage>.workspace-page,.studio-stage>.wb-root,.studio-stage>.hub-root{flex:1;min-height:0;min-width:0}.studio-stage>.settings,.studio-stage>.settings-root{overflow:auto;min-height:0}.studio-resources{position:absolute;left:194px;right:0;top:52px;height:42px;z-index:3;display:flex;align-items:center;gap:20px;overflow:auto;padding:0 24px;border-bottom:1px solid var(--border);background:var(--bg);white-space:nowrap}.studio-resources>header,.resource-project,.resource-caption,.resource-empty,.resource-resizer{display:none}.studio-resources>button{position:relative;display:inline-flex;align-items:center;gap:6px;padding:11px 0;border:0;border-radius:0;background:transparent;color:var(--text-secondary);font-size:11px;cursor:pointer;flex-shrink:0}.studio-resources>button.is-selected{color:var(--text)}.studio-resources>button.is-selected:after{position:absolute;content:"";left:0;right:0;bottom:0;height:2px;background:var(--accent)}.studio-resources>button small{margin-left:auto;font:8px var(--font-mono);color:var(--text-tertiary)}
6
+ .studio-shell.is-developer{grid-template-columns:48px var(--resource-width) minmax(0,1fr)}.is-developer .studio-activity{padding:10px 5px 8px;align-items:center}.is-developer .studio-activity>button,.is-developer .studio-nav-bottom>button{justify-content:center;gap:0;padding:10px 0;width:36px;height:37px;border-radius:6px;margin-bottom:5px}.is-developer .studio-activity button>span,.is-developer .studio-nav-bottom>button>svg:last-child,.is-developer .studio-nav-bottom>p,.is-developer .nav-disclosure{display:none}.is-developer .studio-nav-bottom{width:36px;padding-top:12px}.is-developer .studio-resources{grid-column:2;grid-row:2;position:relative;left:auto;right:auto;top:auto;height:auto;display:block;padding:0 8px 16px;overflow:auto;border-right:1px solid var(--border);border-bottom:0;background:var(--bg-sunken);white-space:normal;z-index:2;min-width:0;min-height:0}.is-developer .studio-resources>header{display:flex;align-items:center;justify-content:space-between;height:40px;padding:0 4px;color:var(--text-tertiary);font:8px var(--font-mono);letter-spacing:1.2px}.is-developer .studio-resources>header .ws-icon{width:24px;height:24px;border:0}.is-developer .resource-project{display:flex;align-items:center;gap:7px;padding:9px 3px 12px;font-size:11px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.is-developer .studio-resources>button{display:flex;align-items:center;gap:8px;width:100%;padding:8px;border:1px solid transparent;border-radius:5px;color:var(--text-secondary);font-size:11px;white-space:nowrap;min-width:0}.is-developer .studio-resources>button>span{overflow:hidden;text-overflow:ellipsis;min-width:0}.is-developer .studio-resources>button>svg{flex-shrink:0}.is-developer .studio-resources>button:hover{background:var(--bg-elevated);color:var(--text)}.is-developer .studio-resources>button.is-selected{background:var(--bg-elevated);border-color:var(--border);color:var(--accent)}.is-developer .studio-resources>button.is-selected:after{display:none}.is-developer .resource-caption{display:block;font:8px var(--font-mono);letter-spacing:1.2px;color:var(--text-tertiary);margin:25px 8px 10px}.is-developer .resource-empty{display:block;font-size:10px;color:var(--text-tertiary);line-height:1.9;padding:0 8px}.is-developer .resource-resizer{display:block;position:absolute;right:0;top:40px;bottom:0;width:5px;cursor:col-resize;touch-action:none}.is-developer .resource-resizer:hover,.is-developer .resource-resizer:focus-visible{background:var(--accent);opacity:.55}.is-developer .studio-main{grid-column:3;padding-top:0}.is-developer .studio-document-tabs{display:flex;align-items:center;gap:0;min-height:36px;height:36px;border-bottom:1px solid var(--border);background:var(--bg-sunken);overflow-x:auto;overflow-y:hidden;flex-shrink:0}.studio-document-tabs>div{display:flex;align-items:center;gap:7px;height:100%;border-right:1px solid var(--border);border-top:2px solid transparent;padding:0 9px 0 13px;flex-shrink:0}.studio-document-tabs>div.is-active{border-top-color:var(--accent);background:var(--bg)}.studio-document-tabs>div>button{border:0;background:transparent;color:var(--text-secondary);font-size:10px;cursor:pointer;padding:6px 0;white-space:nowrap}.studio-document-tabs>div.is-active>button:first-child{color:var(--text)}.studio-document-tabs .close-doc{opacity:.55;display:flex;align-items:center}.studio-document-tabs .close-doc:hover{opacity:1;color:var(--danger)}.studio-document-tabs>span{flex:1;min-width:8px}.studio-document-tabs>.ws-icon{height:25px;width:25px;margin:0 4px;border:0;flex-shrink:0}.is-developer .studio-breadcrumb{height:28px;min-height:28px;padding:0 18px;font-size:9px}.is-developer.resources-hidden{grid-template-columns:48px minmax(0,1fr)}.is-developer.resources-hidden .studio-resources{display:none}.is-developer.resources-hidden .studio-main{grid-column:2}
7
+ .studio-inspector{position:absolute;top:52px;bottom:26px;right:0;width:300px;z-index:12;background:var(--bg-elevated);border-left:1px solid var(--border);padding:18px;box-shadow:-15px 0 35px rgba(0,0,0,.18);overflow:auto}.studio-inspector>header{display:flex;align-items:center;justify-content:space-between;margin-bottom:25px}.studio-inspector>header strong{font-size:12px;font-weight:500}.studio-inspector>.ws-link{display:flex;margin:14px 0}.inspector-values{display:flex;flex-direction:column;gap:15px;margin:16px 0 25px;font-size:11px}.inspector-values>div{display:flex;justify-content:space-between;gap:15px}.inspector-values dt{color:var(--text-secondary);flex-shrink:0}.inspector-values dd{margin:0;text-align:right;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.studio-statusbar{grid-column:1/-1;grid-row:3;display:flex;align-items:center;gap:10px;padding:0 13px;height:26px;min-width:0;overflow:hidden;white-space:nowrap;border-top:1px solid var(--border);background:var(--bg-sunken);font:9px var(--font-mono);color:var(--text-secondary);z-index:14}.status-local-dot{width:4px;height:4px;border-radius:50%;background:var(--success);flex-shrink:0}.status-divider{width:1px;height:10px;background:var(--border);flex-shrink:0}.status-spacer{flex:1}.speed-select{display:flex;align-items:center;gap:5px;color:var(--accent);font-size:9px}.speed-select select{font:9px var(--font-sans);color:var(--text);background:transparent;border:0;outline-offset:1px;max-width:70px}.run-console{height:190px;min-height:95px;max-height:38%;border-top:1px solid var(--border);flex-shrink:0;display:flex;flex-direction:column;background:var(--bg-sunken);overflow:hidden}.run-console>header{display:flex;align-items:center;height:33px;min-height:33px;gap:20px;padding:0 15px;border-bottom:1px solid var(--border)}.run-console>header>span{flex:1}.run-console>header>button:not(.ws-icon){height:100%;padding:0;border:0;border-bottom:1px solid transparent;background:none;color:var(--text-secondary);font-size:10px;cursor:pointer}.run-console>header>button.is-active{border-bottom-color:var(--accent);color:var(--text)}.run-console>header>.ws-icon{height:23px;width:23px;border:0}.run-console>div{flex:1;min-height:0;overflow:auto;padding:8px 15px}.run-console pre{margin:0 0 5px;white-space:pre-wrap;overflow-wrap:anywhere;color:var(--text-secondary);font:10px/1.7 var(--font-mono);user-select:text}.run-console p{font-size:10px;color:var(--text-tertiary)}
8
+ /* The main feature is shared in both shells; only framing and density change. */
9
+ .studio-feature{height:100%;min-height:0;min-width:0;overflow:auto;padding:26px 30px 38px;display:flex;flex-direction:column;gap:18px}.is-developer .studio-feature{padding:22px 24px 30px}.feature-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;flex-shrink:0}.feature-heading h1{font:550 24px/1.4 var(--font-sans);letter-spacing:-.6px;margin:8px 0 0}.feature-heading p{font-size:11px;line-height:1.8;color:var(--text-secondary);margin:8px 0 0;max-width:680px}.feature-actions{display:flex;gap:8px;align-items:center;flex-shrink:0;padding-top:20px}.document-dirty{display:inline-block;margin-left:12px;font:9px var(--font-mono);letter-spacing:0;color:var(--text-tertiary);vertical-align:middle}.studio-card{min-width:0;background:var(--bg-elevated);border:1px solid var(--border);border-radius:10px;padding:19px}.studio-card h2{display:flex;align-items:center;gap:7px;font:550 13px var(--font-sans);margin:0 0 15px}.studio-card h3{font:500 12px var(--font-sans)}.studio-shell input:not([type="checkbox"]):not([type="range"]),.studio-shell select,.studio-shell textarea{color:var(--text);background:var(--bg-sunken);border:1px solid var(--border);border-radius:6px;font-size:11px;padding:9px;min-width:0}.studio-shell input[type="checkbox"]{accent-color:var(--accent)}.studio-shell textarea{font:11px/1.8 var(--font-mono);resize:vertical;user-select:text}.studio-shell input:focus-visible,.studio-shell textarea:focus-visible,.studio-shell select:focus-visible{outline:1px solid var(--accent);outline-offset:1px}.studio-shell button:disabled{opacity:.4;cursor:not-allowed}.developer-toolbar{display:grid;grid-template-columns:1fr 1fr 1.1fr auto;gap:12px;align-items:end;flex-shrink:0}.developer-toolbar>label,.intelligence-controls>label,.artifact-library>label{display:flex;flex-direction:column;gap:6px;font-size:9px;color:var(--text-secondary)}.developer-toolbar>label input,.developer-toolbar>label select{width:100%;height:34px}.developer-toolbar>.ws-icon{height:34px;width:34px}.developer-edit-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;flex-shrink:0}.developer-edit-grid.has-diff{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.editor-card{padding:0;overflow:hidden}.editor-caption{display:flex;align-items:center;justify-content:space-between;gap:10px;height:37px;padding:0 13px;border-bottom:1px solid var(--border);font:8px var(--font-mono);letter-spacing:1px;color:var(--text-tertiary)}.editor-caption>label{font:9px var(--font-sans);letter-spacing:0;display:flex;align-items:center;gap:5px}.code-editor{height:300px;max-height:48vh;min-height:180px;overflow:hidden}.code-editor .cm-editor{height:100%}.code-editor .cm-scroller{overscroll-behavior:contain}.code-editor .cm-lineNumbers .cm-gutterElement{min-width:28px}.code-editor .cm-selectionBackground{background:var(--accent-soft)!important}.code-editor .cm-panel input{font-size:10px}.line-diff{max-height:310px;overflow:auto;user-select:text}.line-diff pre{margin:0;padding:2px 6px;font:10px/1.7 var(--font-mono);white-space:pre-wrap;overflow-wrap:anywhere;color:var(--text-secondary)}.line-diff pre.is-added{background:color-mix(in srgb,var(--success) 12%,transparent);color:var(--success)}.line-diff pre.is-removed{background:color-mix(in srgb,var(--danger) 10%,transparent);color:var(--danger)}.prompt-tools{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;flex-shrink:0}.prompt-tools textarea{width:100%}.version-row{display:flex;align-items:center;gap:8px;padding:10px 0;border:0;border-bottom:1px solid var(--border);background:transparent;color:var(--accent);width:100%;font:11px var(--font-mono);text-align:left;cursor:pointer}.version-row small{font:9px var(--font-sans);color:var(--text-secondary);margin-left:auto}.run-confirm{background:color-mix(in srgb,var(--warning) 7%,var(--bg));border:1px solid color-mix(in srgb,var(--warning) 65%,transparent);border-radius:8px;padding:15px;flex-shrink:0}.run-confirm strong{font-size:12px;font-weight:550}.run-confirm p{font-size:11px;line-height:1.8;color:var(--text-secondary);margin:8px 0 13px}.run-confirm>.ws-primary{margin-right:14px}.studio-notice{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--success);margin:0;flex-shrink:0}.request-output{flex-shrink:0}.request-output pre{max-height:450px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.9 var(--font-sans);user-select:text}.evaluation-row{padding:14px 0;border-top:1px solid var(--border)}.evaluation-row>strong{font-size:12px}.evaluation-row>span{margin-left:12px;font:9px var(--font-mono);color:var(--text-tertiary)}.evaluation-row>p{font-size:10px;color:var(--danger)}.evaluation-row pre{font:11px/1.8 var(--font-mono);white-space:pre-wrap;overflow-wrap:anywhere;max-height:260px;overflow:auto;user-select:text}.trace-grid{display:grid;grid-template-columns:230px minmax(0,1fr);gap:16px;align-items:start}.trace-index{padding:8px;max-height:650px;overflow:auto}.trace-index>button{display:flex;flex-direction:column;gap:5px;text-align:left;width:100%;padding:12px 9px;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--text);cursor:pointer}.trace-index>button strong{font-size:11px;font-weight:500}.trace-index>button small{font:9px var(--font-mono);color:var(--text-tertiary);overflow-wrap:anywhere}.trace-index>button.is-selected{background:var(--bg-sunken);border-color:var(--border)}.trace-json{max-height:450px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font:10px/1.8 var(--font-mono);user-select:text}.studio-label{display:flex;flex-direction:column;gap:7px;font-size:11px;color:var(--text-secondary)}.studio-label textarea{width:100%}.intelligence-controls{display:flex;align-items:end;gap:12px;margin-top:15px;flex-wrap:wrap}.intelligence-controls>label{flex:1;min-width:130px}.intelligence-controls select{width:100%;height:34px}.intelligence-controls>.ws-primary,.intelligence-controls>.ws-secondary{min-height:34px}.intelligence-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start;flex-shrink:0}.source-option{display:flex;align-items:flex-start;gap:8px;font-size:11px;padding:12px 0;border-bottom:1px solid var(--border);cursor:pointer}.source-option>span{overflow-wrap:anywhere}.source-option small{display:block;font:9px var(--font-mono);color:var(--text-tertiary);margin-top:5px}.context-preview,.source-fulltext{white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.9 var(--font-mono);max-height:420px;overflow:auto;user-select:text}.artifact-library{max-width:420px}.artifact-editor{flex-shrink:0}.artifact-editor>.ws-card-top>input{flex:1;font-weight:500}.artifact-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px}.artifact-split textarea{width:100%;min-height:240px}.artifact-preview{max-height:500px;overflow:auto;font-size:12px;line-height:1.9;user-select:text;overflow-wrap:anywhere}.artifact-preview pre{overflow:auto;max-width:100%}.evidence-hit{padding:12px 0;border-top:1px solid var(--border)}.evidence-hit strong{font-size:11px;font-weight:500}.evidence-hit p{font-size:11px;color:var(--text-secondary);line-height:1.8;overflow-wrap:anywhere}.intelligence-grid details{border-top:1px solid var(--border);padding:12px 0}.intelligence-grid summary{font-size:11px;cursor:pointer;overflow-wrap:anywhere}.intelligence-grid summary>button{margin-left:12px}.collaboration-results{display:flex;flex-direction:column;gap:12px}.collaboration-results summary{display:flex;align-items:center;justify-content:space-between;font-size:13px;font-weight:500;cursor:pointer}.collaboration-results .studio-card[open]>summary{margin-bottom:15px}.collaboration-results details>div{font-size:12px;overflow-wrap:anywhere}.checkpoint-file{display:flex;align-items:center;justify-content:space-between;gap:12px;border-bottom:1px solid var(--border);padding:15px 0}.checkpoint-file>div{min-width:0}.checkpoint-file strong{display:block;font:10px var(--font-mono);overflow-wrap:anywhere;font-weight:400}.checkpoint-file small{display:block;font:8px var(--font-mono);color:var(--text-tertiary);margin-top:6px}.checkpoint-file>div>span{font-size:10px;color:var(--warning);display:block;margin-bottom:8px}.shell-notice{display:flex;align-items:center;justify-content:space-between;gap:15px;background:var(--accent-soft);padding:8px 20px;font-size:10px;flex-shrink:0;color:var(--text-secondary)}.studio-stage .ultrafast-toggle{display:none}.studio-stage .tc-subtabs{display:none}.studio-stage .workspace-header{padding-top:25px}.studio-stage .workspace-header h1{font-size:23px}.studio-stage .workspace-scroll{padding-top:18px}.studio-stage .workspace-foot{font-size:7px}.studio-stage .chat-header-title{font-size:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.studio-stage .conversations{min-width:170px;width:210px}.studio-stage .conv-meta{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;max-width:170px}.studio-stage .wb-tabs{height:40px;min-height:40px;padding-left:20px}.studio-stage .wb-tab{font-size:11px}.studio-stage .stats-bar{font-size:9px}.studio-stage .workbench,.studio-stage .chat-main{min-width:0}
10
+ /* Shared primitives must exist even when Overview has never been loaded. */
11
+ .studio-shell .ws-icon{width:29px;height:29px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:6px;background:transparent;color:var(--text-secondary);cursor:pointer;flex-shrink:0}.studio-shell .ws-icon:hover{background:var(--bg-elevated);color:var(--text)}.studio-shell .ws-primary,.studio-shell .ws-secondary{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:9px 13px;border:1px solid var(--border);border-radius:7px;font-size:11px;font-weight:500;cursor:pointer;white-space:nowrap}.studio-shell .ws-primary{background:var(--text);color:var(--bg)}.studio-shell .ws-secondary{background:transparent;color:var(--text-secondary)}.studio-shell .ws-primary:hover{filter:brightness(1.06)}.studio-shell .ws-secondary:hover{background:var(--bg-sunken);color:var(--text)}.studio-shell .ws-link{display:inline-flex;align-items:center;gap:5px;background:none;border:0;padding:4px 0;color:var(--accent);font-size:10px;cursor:pointer}.studio-shell .ws-muted{font-size:11px;color:var(--text-secondary);line-height:1.8}.studio-shell .ws-label{font:8px/1.6 var(--font-mono);letter-spacing:.6px;color:var(--text-tertiary)}.studio-shell .ws-eyebrow{display:inline-flex;align-items:center;gap:8px;font:8px/1.8 var(--font-mono);letter-spacing:1.6px;color:var(--text-secondary)}.studio-shell .ws-empty{padding:22px 0;font-size:11px;line-height:1.9;color:var(--text-secondary)}.studio-shell .ws-error{padding:12px 14px;border:1px solid var(--danger);border-radius:7px;color:var(--danger);font-size:11px;line-height:1.8;overflow-wrap:anywhere;white-space:pre-wrap;flex-shrink:0;margin:0}.studio-shell .ws-card-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:15px}
12
+ .studio-modal-scrim{position:fixed;inset:0;z-index:150;background:var(--scrim);display:flex;align-items:center;justify-content:center;padding:30px}.studio-modal{width:440px;max-width:100%;max-height:85vh;overflow:auto;background:var(--bg-elevated);border:1px solid var(--border);border-radius:12px;padding:25px;box-shadow:var(--shadow-float)}.studio-modal h2{font:550 19px var(--font-sans);letter-spacing:-.4px}.studio-modal>p{font-size:11px;line-height:1.8;color:var(--text-secondary);margin:12px 0 18px}.studio-modal>input{width:100%;margin:0 0 20px}.studio-modal>div:last-child:not(:first-child){display:flex;gap:10px;justify-content:flex-end}.studio-modal.command-menu{width:530px;padding:0;overflow:hidden}.command-menu>label{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--border);color:var(--text-secondary)}.studio-shell .command-menu>label>input{flex:1;background:transparent;border:0;border-radius:0;padding:3px 0;font-size:13px;outline:none}.command-menu>label>.ws-icon{border:0;width:22px;height:22px}.studio-modal.command-menu>div{display:block;max-height:420px;overflow:auto;padding:7px}.command-menu>div>button{display:flex;align-items:center;gap:10px;padding:11px;width:100%;border:0;border-radius:6px;background:transparent;color:var(--text);text-align:left;cursor:pointer}.command-menu>div>button:hover,.command-menu>div>button:focus-visible{background:var(--accent-soft);outline:none}.command-menu>div>button>span{font-size:12px;flex:1}.command-menu>div>button>small{font:8px var(--font-mono);color:var(--text-tertiary)}.command-menu>div>button>svg{color:var(--text-secondary)}
13
+ @media(min-width:1280px){.studio-shell.is-developer:has(.studio-inspector){grid-template-columns:48px var(--resource-width) minmax(0,1fr) 300px}.is-developer:has(.studio-inspector) .studio-inspector{grid-column:4;grid-row:2;position:relative;top:auto;bottom:auto;right:auto;width:auto;box-shadow:none;min-height:0;z-index:4}.studio-shell.is-developer.resources-hidden:has(.studio-inspector){grid-template-columns:48px minmax(0,1fr) 300px}.is-developer.resources-hidden:has(.studio-inspector) .studio-inspector{grid-column:3}}
14
+ @media(max-width:1100px){.studio-brand>span{display:none}.studio-topbar{gap:10px}.command-search{width:200px}.studio-feature,.is-developer .studio-feature{padding:22px 20px 28px}.feature-heading h1{font-size:21px}.feature-heading{gap:12px}.feature-heading p{font-size:10px}.feature-actions{padding-top:15px}.developer-toolbar{grid-template-columns:1fr 1fr auto}.developer-toolbar>label:first-child{grid-column:1/-1}.trace-grid{grid-template-columns:180px minmax(0,1fr)}.intelligence-grid{gap:12px}.studio-stage .conversations{width:185px}.studio-statusbar>.status-spacer+span{display:none}.studio-document-tabs>div{padding-left:9px;gap:5px}.developer-edit-grid.has-diff{grid-template-columns:minmax(0,1fr)}.studio-stage .workspace-header{padding-left:24px;padding-right:24px}.studio-stage .workspace-scroll{padding-left:24px;padding-right:24px}}
15
+ @media(max-width:960px){.studio-shell.is-developer{--resource-width:200px!important}.studio-shell.is-daily{grid-template-columns:170px minmax(0,1fr)}.is-daily .studio-resources{left:170px;gap:17px;padding:0 20px}.studio-activity{padding-left:8px;padding-right:8px}.studio-activity>button,.studio-nav-bottom>button{padding-left:10px;padding-right:8px}.studio-activity button small{font-size:8px}.studio-topbar{padding-right:9px;gap:9px}.project-switch{min-width:100px;max-width:180px}.project-switch select{max-width:135px}.command-search{width:150px;max-width:23%;padding:6px 8px}.command-search kbd{display:none}.command-search span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-brand strong{font-size:13px}.layout-toggle button{font-size:9px;padding:4px 7px}.developer-edit-grid.has-diff,.prompt-tools,.artifact-split,.intelligence-grid{grid-template-columns:minmax(0,1fr)}.feature-heading{flex-wrap:wrap}.feature-actions{padding-top:0;margin-left:auto}.trace-grid{grid-template-columns:minmax(0,1fr)}.trace-index{max-height:170px}.artifact-preview{max-height:300px}.studio-statusbar{gap:7px;padding-left:9px;font-size:8px}.speed-select{font-size:8px}.studio-statusbar>span:last-child{max-width:150px;overflow:hidden;text-overflow:ellipsis}.studio-stage .conversations{width:172px;min-width:150px}.studio-stage .conv-meta{max-width:140px}.studio-stage .composer{padding-left:15px;padding-right:15px}.studio-stage .chat-header{padding-left:18px;padding-right:18px}.studio-stage .workspace-header h1{font-size:20px}}
16
+ @media(max-height:680px){.run-console{height:160px;max-height:180px}.studio-activity{padding-top:12px}.studio-activity>button{padding-top:8px;padding-bottom:8px}.studio-nav-bottom{padding-top:10px}.studio-nav-bottom>p{margin-top:8px;padding-top:8px}.feature-heading h1{font-size:20px}.code-editor{height:240px}.studio-feature,.is-developer .studio-feature{padding-top:18px;gap:14px}.studio-stage .workspace-header{padding-top:18px;padding-bottom:15px}.studio-stage .darkside-hero{min-height:220px}.studio-stage .hero-copy{padding-top:24px;padding-bottom:24px}}
17
+ @media(prefers-reduced-motion:reduce){.studio-shell *{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
css/task-center.css ADDED
@@ -0,0 +1,958 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 任务中心(契约 15A):任务页签三子区(任务 / 定时 / 批处理)。
2
+ Warm Paper 全令牌配色,规则来自 docs/design-system.md:
3
+ 衬线标题 / 语义色只出现在状态语境 / 1px 分隔 / 克制动效。 */
4
+
5
+ .tc-root {
6
+ flex: 1;
7
+ min-width: 0;
8
+ min-height: 0;
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+
13
+ /* ---------- 子区页签(任务页签内部) ---------- */
14
+ .tc-subtabs {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 4px;
18
+ padding: 12px 24px 0;
19
+ border-bottom: 1px solid var(--border);
20
+ flex-shrink: 0;
21
+ }
22
+
23
+ .tc-subtab {
24
+ position: relative;
25
+ height: 30px;
26
+ padding: 0 12px;
27
+ border: none;
28
+ border-radius: var(--radius-control) var(--radius-control) 0 0;
29
+ background: transparent;
30
+ color: var(--text-secondary);
31
+ font-family: inherit;
32
+ font-size: 13.5px;
33
+ cursor: pointer;
34
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
35
+ }
36
+
37
+ .tc-subtab:hover {
38
+ background: var(--accent-soft);
39
+ color: var(--text);
40
+ }
41
+
42
+ .tc-subtab.is-active {
43
+ color: var(--text);
44
+ font-weight: 600;
45
+ }
46
+
47
+ .tc-subtab.is-active::after {
48
+ content: "";
49
+ position: absolute;
50
+ left: 10px;
51
+ right: 10px;
52
+ bottom: -1px;
53
+ height: 2px;
54
+ border-radius: 1px;
55
+ background: var(--accent);
56
+ }
57
+
58
+ .tc-subtab:focus-visible {
59
+ outline: 2px solid var(--accent);
60
+ outline-offset: 2px;
61
+ }
62
+
63
+ /* ---------- 子区内容滚动区 ---------- */
64
+ .tc-body {
65
+ flex: 1;
66
+ min-height: 0;
67
+ overflow-y: auto;
68
+ }
69
+
70
+ .tc-sub {
71
+ max-width: 880px;
72
+ margin: 0 auto;
73
+ padding: 28px 32px 48px;
74
+ display: flex;
75
+ flex-direction: column;
76
+ gap: 16px;
77
+ }
78
+
79
+ .tc-sub-head {
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: space-between;
83
+ gap: 12px;
84
+ }
85
+
86
+ .tc-sub-head-right {
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 12px;
90
+ }
91
+
92
+ .tc-sub-title {
93
+ margin: 0;
94
+ font-family: var(--font-serif);
95
+ font-size: 19px;
96
+ font-weight: 600;
97
+ color: var(--text);
98
+ }
99
+
100
+ .tc-history-title {
101
+ margin-top: 12px;
102
+ }
103
+
104
+ /* ---------- 通用小料 ---------- */
105
+ .tc-empty {
106
+ margin: 8px 0;
107
+ color: var(--text-tertiary);
108
+ font-size: 14px;
109
+ line-height: 1.7;
110
+ }
111
+
112
+ .tc-error {
113
+ margin: 0;
114
+ color: var(--danger);
115
+ font-size: 13.5px;
116
+ }
117
+
118
+ .tc-notice {
119
+ margin: 0;
120
+ padding: 10px 14px;
121
+ border: 1px solid var(--border);
122
+ border-radius: var(--radius-control);
123
+ background: var(--bg-elevated);
124
+ color: var(--text-secondary);
125
+ font-size: 13.5px;
126
+ line-height: 1.6;
127
+ }
128
+
129
+ .tc-hint {
130
+ color: var(--text-tertiary);
131
+ font-size: 12.5px;
132
+ }
133
+
134
+ .tc-redline {
135
+ margin: 0;
136
+ padding: 10px 14px;
137
+ border-left: 3px solid var(--warning);
138
+ border-radius: 0 var(--radius-chip) var(--radius-chip) 0;
139
+ background: var(--bg-elevated);
140
+ color: var(--text-secondary);
141
+ font-size: 13px;
142
+ line-height: 1.65;
143
+ }
144
+
145
+ .tc-redline strong {
146
+ color: var(--text);
147
+ }
148
+
149
+ /* 状态徽章(语义色只在状态语境) */
150
+ .tc-badge {
151
+ display: inline-flex;
152
+ align-items: center;
153
+ height: 20px;
154
+ padding: 0 8px;
155
+ border-radius: var(--radius-chip);
156
+ font-size: 12px;
157
+ white-space: nowrap;
158
+ background: var(--bg-sunken);
159
+ color: var(--text-secondary);
160
+ }
161
+
162
+ .tc-badge.is-running {
163
+ background: var(--accent-soft);
164
+ color: var(--accent);
165
+ }
166
+
167
+ .tc-badge.is-done {
168
+ background: color-mix(in srgb, var(--success) 16%, transparent);
169
+ color: var(--success);
170
+ }
171
+
172
+ .tc-badge.is-error {
173
+ background: color-mix(in srgb, var(--danger) 14%, transparent);
174
+ color: var(--danger);
175
+ }
176
+
177
+ .tc-badge.is-cancelled,
178
+ .tc-badge.is-stopped {
179
+ background: var(--bg-sunken);
180
+ color: var(--text-tertiary);
181
+ }
182
+
183
+ /* 验收结论徽章(契约 19A A2:done=success / partial=warning / failed=danger /
184
+ undecided=tertiary;语义色只出现在状态语境) */
185
+ .tc-badge.is-success {
186
+ background: color-mix(in srgb, var(--success) 16%, transparent);
187
+ color: var(--success);
188
+ }
189
+
190
+ .tc-badge.is-warning {
191
+ background: color-mix(in srgb, var(--warning) 18%, transparent);
192
+ color: var(--warning);
193
+ }
194
+
195
+ .tc-badge.is-danger {
196
+ background: color-mix(in srgb, var(--danger) 14%, transparent);
197
+ color: var(--danger);
198
+ }
199
+
200
+ .tc-badge.is-tertiary {
201
+ background: var(--bg-sunken);
202
+ color: var(--text-tertiary);
203
+ }
204
+
205
+ /* 徽章本身是按钮(点开看验收报告):把按钮默认样式抹平 */
206
+ .tc-verify-badge {
207
+ border: none;
208
+ font-family: inherit;
209
+ cursor: pointer;
210
+ gap: 5px;
211
+ transition: filter var(--dur) var(--ease);
212
+ }
213
+
214
+ .tc-verify-badge:hover:not(:disabled) {
215
+ filter: brightness(0.97);
216
+ }
217
+
218
+ .tc-verify-badge:disabled {
219
+ opacity: 0.7;
220
+ }
221
+
222
+ .tc-verify-badge:focus-visible {
223
+ outline: 2px solid var(--accent);
224
+ outline-offset: 2px;
225
+ }
226
+
227
+ /* 验收中转圈(按钮内 12px 细环) */
228
+ .tc-verify-spin {
229
+ width: 11px;
230
+ height: 11px;
231
+ border: 1.5px solid var(--border);
232
+ border-top-color: var(--accent);
233
+ border-radius: 50%;
234
+ animation: tc-spin 0.8s linear infinite;
235
+ }
236
+
237
+ @keyframes tc-spin {
238
+ to {
239
+ transform: rotate(360deg);
240
+ }
241
+ }
242
+
243
+ @media (prefers-reduced-motion: reduce) {
244
+ .tc-verify-spin {
245
+ animation: none;
246
+ }
247
+ }
248
+
249
+ /* ---------- 按钮 ---------- */
250
+ .tc-primary {
251
+ display: inline-flex;
252
+ align-items: center;
253
+ gap: 6px;
254
+ height: 34px;
255
+ padding: 0 16px;
256
+ border: none;
257
+ border-radius: var(--radius-control);
258
+ background: var(--accent);
259
+ color: #fff;
260
+ font-family: inherit;
261
+ font-size: 13.5px;
262
+ cursor: pointer;
263
+ transition: filter var(--dur) var(--ease);
264
+ }
265
+
266
+ .tc-primary:hover:not(:disabled) {
267
+ filter: brightness(1.06);
268
+ }
269
+
270
+ .tc-primary:disabled {
271
+ opacity: 0.5;
272
+ cursor: default;
273
+ }
274
+
275
+ .tc-primary:focus-visible {
276
+ outline: 2px solid var(--accent);
277
+ outline-offset: 2px;
278
+ }
279
+
280
+ .tc-ghost {
281
+ height: 34px;
282
+ padding: 0 14px;
283
+ border: 1px solid var(--border);
284
+ border-radius: var(--radius-control);
285
+ background: transparent;
286
+ color: var(--text-secondary);
287
+ font-family: inherit;
288
+ font-size: 13.5px;
289
+ cursor: pointer;
290
+ transition: background var(--dur) var(--ease);
291
+ }
292
+
293
+ .tc-ghost:hover {
294
+ background: var(--bg-elevated);
295
+ }
296
+
297
+ .tc-icon-btn {
298
+ display: inline-flex;
299
+ align-items: center;
300
+ gap: 4px;
301
+ height: 28px;
302
+ padding: 0 8px;
303
+ border: 1px solid var(--border);
304
+ border-radius: var(--radius-chip);
305
+ background: transparent;
306
+ color: var(--text-secondary);
307
+ font-family: inherit;
308
+ font-size: 12.5px;
309
+ cursor: pointer;
310
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
311
+ }
312
+
313
+ .tc-icon-btn:hover:not(:disabled) {
314
+ background: var(--bg-elevated);
315
+ color: var(--text);
316
+ }
317
+
318
+ .tc-icon-btn.is-danger:hover:not(:disabled) {
319
+ color: var(--danger);
320
+ border-color: var(--danger);
321
+ }
322
+
323
+ .tc-icon-btn.is-confirm {
324
+ color: var(--danger);
325
+ border-color: var(--danger);
326
+ }
327
+
328
+ .tc-refresh {
329
+ display: inline-flex;
330
+ align-items: center;
331
+ justify-content: center;
332
+ width: 28px;
333
+ height: 28px;
334
+ border: 1px solid var(--border);
335
+ border-radius: var(--radius-chip);
336
+ background: transparent;
337
+ color: var(--text-secondary);
338
+ cursor: pointer;
339
+ transition: background var(--dur) var(--ease);
340
+ }
341
+
342
+ .tc-refresh:hover {
343
+ background: var(--bg-elevated);
344
+ }
345
+
346
+ /* ---------- 通知开关 ---------- */
347
+ .tc-notify-switch {
348
+ display: inline-flex;
349
+ align-items: center;
350
+ gap: 6px;
351
+ color: var(--text-secondary);
352
+ font-size: 13px;
353
+ cursor: pointer;
354
+ user-select: none;
355
+ }
356
+
357
+ .tc-notify-switch input {
358
+ accent-color: var(--accent);
359
+ }
360
+
361
+ /* ---------- 进行中卡片 ---------- */
362
+ .tc-running-card {
363
+ display: flex;
364
+ flex-direction: column;
365
+ gap: 8px;
366
+ padding: 16px 18px;
367
+ border: 1px solid var(--border);
368
+ border-radius: var(--radius-card);
369
+ background: var(--bg-elevated);
370
+ }
371
+
372
+ .tc-running-head {
373
+ display: flex;
374
+ align-items: center;
375
+ gap: 10px;
376
+ }
377
+
378
+ .tc-running-pulse {
379
+ width: 8px;
380
+ height: 8px;
381
+ border-radius: 50%;
382
+ background: var(--accent);
383
+ animation: tc-pulse 1.6s var(--ease) infinite;
384
+ }
385
+
386
+ @keyframes tc-pulse {
387
+ 0%,
388
+ 100% {
389
+ opacity: 1;
390
+ }
391
+ 50% {
392
+ opacity: 0.3;
393
+ }
394
+ }
395
+
396
+ @media (prefers-reduced-motion: reduce) {
397
+ .tc-running-pulse {
398
+ animation: none;
399
+ }
400
+ }
401
+
402
+ .tc-running-task {
403
+ margin: 0;
404
+ font-family: var(--font-serif);
405
+ font-size: 16px;
406
+ font-weight: 600;
407
+ color: var(--text);
408
+ line-height: 1.5;
409
+ }
410
+
411
+ .tc-running-meta {
412
+ display: flex;
413
+ flex-wrap: wrap;
414
+ gap: 12px;
415
+ color: var(--text-tertiary);
416
+ font-size: 12.5px;
417
+ }
418
+
419
+ .tc-running-event {
420
+ margin: 0;
421
+ color: var(--text-secondary);
422
+ font-size: 13px;
423
+ }
424
+
425
+ /* ---------- 历史列表 ---------- */
426
+ .tc-history {
427
+ list-style: none;
428
+ margin: 0;
429
+ padding: 0;
430
+ border: 1px solid var(--border);
431
+ border-radius: var(--radius-card);
432
+ background: var(--bg-elevated);
433
+ overflow: hidden;
434
+ }
435
+
436
+ .tc-history-item + .tc-history-item {
437
+ border-top: 1px solid var(--border);
438
+ }
439
+
440
+ /* 行容器:左边主按钮(标题 + 状态 + 时间)+ 右边动作区(验收 / 徽章) */
441
+ .tc-history-row {
442
+ display: flex;
443
+ align-items: center;
444
+ gap: 8px;
445
+ }
446
+
447
+ .tc-history-main {
448
+ display: flex;
449
+ align-items: center;
450
+ gap: 10px;
451
+ flex: 1;
452
+ min-width: 0;
453
+ padding: 12px 16px;
454
+ border: none;
455
+ background: transparent;
456
+ color: var(--text);
457
+ font-family: inherit;
458
+ font-size: 13.5px;
459
+ text-align: left;
460
+ cursor: pointer;
461
+ transition: background var(--dur) var(--ease);
462
+ }
463
+
464
+ .tc-history-actions {
465
+ display: flex;
466
+ align-items: center;
467
+ gap: 6px;
468
+ flex-shrink: 0;
469
+ padding-right: 14px;
470
+ }
471
+
472
+ .tc-history-main:hover {
473
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
474
+ }
475
+
476
+ .tc-history-task {
477
+ flex: 1;
478
+ min-width: 0;
479
+ overflow: hidden;
480
+ text-overflow: ellipsis;
481
+ white-space: nowrap;
482
+ }
483
+
484
+ .tc-history-meta {
485
+ color: var(--text-tertiary);
486
+ font-size: 12.5px;
487
+ white-space: nowrap;
488
+ }
489
+
490
+ .tc-history-detail {
491
+ padding: 4px 16px 16px;
492
+ border-top: 1px dashed var(--border);
493
+ }
494
+
495
+ .tc-history-summary {
496
+ margin: 10px 0 0;
497
+ color: var(--text-secondary);
498
+ font-size: 13px;
499
+ line-height: 1.65;
500
+ white-space: pre-wrap;
501
+ }
502
+
503
+ /* ---------- 事件时间线 ---------- */
504
+ .tc-timeline {
505
+ list-style: none;
506
+ margin: 12px 0 0;
507
+ padding: 0;
508
+ display: flex;
509
+ flex-direction: column;
510
+ gap: 6px;
511
+ }
512
+
513
+ .tc-timeline-item {
514
+ display: flex;
515
+ align-items: baseline;
516
+ gap: 10px;
517
+ padding: 6px 10px;
518
+ border-radius: var(--radius-chip);
519
+ background: var(--bg-sunken);
520
+ font-size: 12.5px;
521
+ }
522
+
523
+ .tc-timeline-item.is-green {
524
+ border-left: 3px solid var(--success);
525
+ }
526
+
527
+ .tc-timeline-item.is-yellow {
528
+ border-left: 3px solid var(--warning);
529
+ }
530
+
531
+ .tc-timeline-item.is-red {
532
+ border-left: 3px solid var(--danger);
533
+ }
534
+
535
+ .tc-timeline-ts {
536
+ color: var(--text-tertiary);
537
+ font-family: var(--font-mono);
538
+ font-size: 11.5px;
539
+ white-space: nowrap;
540
+ }
541
+
542
+ .tc-timeline-text {
543
+ color: var(--text);
544
+ white-space: nowrap;
545
+ }
546
+
547
+ .tc-timeline-summary {
548
+ flex: 1;
549
+ min-width: 0;
550
+ color: var(--text-secondary);
551
+ overflow: hidden;
552
+ text-overflow: ellipsis;
553
+ white-space: nowrap;
554
+ }
555
+
556
+ .tc-timeline-hint,
557
+ .tc-timeline-error {
558
+ margin: 10px 0 0;
559
+ color: var(--text-tertiary);
560
+ font-size: 13px;
561
+ }
562
+
563
+ .tc-timeline-error {
564
+ color: var(--danger);
565
+ }
566
+
567
+ /* ---------- 表单(新建定时任务 / 批处理模板) ---------- */
568
+ .tc-form {
569
+ display: flex;
570
+ flex-direction: column;
571
+ gap: 14px;
572
+ padding: 18px 20px;
573
+ border: 1px solid var(--border);
574
+ border-radius: var(--radius-card);
575
+ background: var(--bg-elevated);
576
+ }
577
+
578
+ .tc-field {
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 6px;
582
+ flex: 1;
583
+ min-width: 0;
584
+ }
585
+
586
+ .tc-field > span {
587
+ color: var(--text-secondary);
588
+ font-size: 12.5px;
589
+ }
590
+
591
+ .tc-field > input,
592
+ .tc-field > select,
593
+ .tc-field > textarea {
594
+ height: 34px;
595
+ padding: 0 12px;
596
+ border: 1px solid var(--border);
597
+ border-radius: var(--radius-control);
598
+ background: var(--bg-sunken);
599
+ color: var(--text);
600
+ font-family: inherit;
601
+ font-size: 13.5px;
602
+ }
603
+
604
+ .tc-field > textarea {
605
+ height: auto;
606
+ padding: 10px 12px;
607
+ line-height: 1.6;
608
+ resize: vertical;
609
+ font-family: inherit;
610
+ }
611
+
612
+ .tc-field > input:focus,
613
+ .tc-field > select:focus,
614
+ .tc-field > textarea:focus {
615
+ outline: none;
616
+ border-color: var(--accent);
617
+ }
618
+
619
+ .tc-field-row {
620
+ display: flex;
621
+ gap: 14px;
622
+ }
623
+
624
+ .tc-form-actions {
625
+ display: flex;
626
+ align-items: center;
627
+ gap: 10px;
628
+ }
629
+
630
+ /* 分段控件(三选) */
631
+ .tc-seg {
632
+ display: inline-flex;
633
+ gap: 4px;
634
+ padding: 3px;
635
+ border: 1px solid var(--border);
636
+ border-radius: var(--radius-control);
637
+ background: var(--bg-sunken);
638
+ width: fit-content;
639
+ }
640
+
641
+ .tc-seg-btn {
642
+ height: 28px;
643
+ padding: 0 14px;
644
+ border: none;
645
+ border-radius: var(--radius-chip);
646
+ background: transparent;
647
+ color: var(--text-secondary);
648
+ font-family: inherit;
649
+ font-size: 13px;
650
+ cursor: pointer;
651
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
652
+ }
653
+
654
+ .tc-seg-btn.is-active {
655
+ background: var(--bg-elevated);
656
+ color: var(--text);
657
+ font-weight: 600;
658
+ box-shadow: 0 1px 3px rgba(31, 30, 27, 0.08);
659
+ }
660
+
661
+ /* 周几多选 */
662
+ .tc-weekdays {
663
+ display: flex;
664
+ align-items: center;
665
+ gap: 6px;
666
+ flex-wrap: wrap;
667
+ }
668
+
669
+ .tc-weekday {
670
+ width: 30px;
671
+ height: 30px;
672
+ border: 1px solid var(--border);
673
+ border-radius: var(--radius-chip);
674
+ background: transparent;
675
+ color: var(--text-secondary);
676
+ font-family: inherit;
677
+ font-size: 13px;
678
+ cursor: pointer;
679
+ transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
680
+ }
681
+
682
+ .tc-weekday.is-on {
683
+ background: var(--accent);
684
+ border-color: var(--accent);
685
+ color: #fff;
686
+ }
687
+
688
+ .tc-weekdays input[type="time"] {
689
+ height: 30px;
690
+ padding: 0 8px;
691
+ border: 1px solid var(--border);
692
+ border-radius: var(--radius-chip);
693
+ background: var(--bg-sunken);
694
+ color: var(--text);
695
+ font-family: inherit;
696
+ font-size: 13px;
697
+ }
698
+
699
+ /* ---------- 定时任务列表 ---------- */
700
+ .tc-schedule-list {
701
+ list-style: none;
702
+ margin: 0;
703
+ padding: 0;
704
+ display: flex;
705
+ flex-direction: column;
706
+ gap: 10px;
707
+ }
708
+
709
+ .tc-schedule-item {
710
+ display: flex;
711
+ align-items: center;
712
+ justify-content: space-between;
713
+ gap: 14px;
714
+ padding: 14px 16px;
715
+ border: 1px solid var(--border);
716
+ border-radius: var(--radius-card);
717
+ background: var(--bg-elevated);
718
+ }
719
+
720
+ .tc-schedule-item.is-off {
721
+ opacity: 0.62;
722
+ }
723
+
724
+ .tc-schedule-info {
725
+ min-width: 0;
726
+ }
727
+
728
+ .tc-schedule-name {
729
+ display: flex;
730
+ align-items: center;
731
+ gap: 8px;
732
+ color: var(--text);
733
+ font-size: 14px;
734
+ font-weight: 600;
735
+ }
736
+
737
+ .tc-schedule-cadence {
738
+ padding: 1px 8px;
739
+ border-radius: var(--radius-chip);
740
+ background: var(--accent-soft);
741
+ color: var(--accent);
742
+ font-size: 12px;
743
+ font-weight: 400;
744
+ }
745
+
746
+ .tc-schedule-meta {
747
+ margin: 4px 0 0;
748
+ color: var(--text-tertiary);
749
+ font-size: 12.5px;
750
+ }
751
+
752
+ .tc-schedule-actions {
753
+ display: flex;
754
+ align-items: center;
755
+ gap: 8px;
756
+ flex-shrink: 0;
757
+ }
758
+
759
+ .tc-toggle input {
760
+ accent-color: var(--accent);
761
+ }
762
+
763
+ /* ---------- 批处理:拖放区 / 文件 chips ---------- */
764
+ .tc-dropzone {
765
+ display: flex;
766
+ flex-direction: column;
767
+ align-items: center;
768
+ justify-content: center;
769
+ gap: 8px;
770
+ min-height: 92px;
771
+ padding: 18px;
772
+ border: 1.5px dashed var(--border);
773
+ border-radius: var(--radius-card);
774
+ background: var(--bg-elevated);
775
+ color: var(--text-tertiary);
776
+ font-size: 13.5px;
777
+ text-align: center;
778
+ cursor: pointer;
779
+ transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
780
+ }
781
+
782
+ .tc-dropzone:hover {
783
+ border-color: var(--accent);
784
+ }
785
+
786
+ .tc-dropzone.is-over {
787
+ border-color: var(--accent);
788
+ background: var(--accent-soft);
789
+ color: var(--accent);
790
+ }
791
+
792
+ .tc-dropzone p {
793
+ margin: 0;
794
+ }
795
+
796
+ .tc-file-chips {
797
+ list-style: none;
798
+ margin: 0;
799
+ padding: 0;
800
+ display: flex;
801
+ flex-wrap: wrap;
802
+ gap: 8px;
803
+ }
804
+
805
+ .tc-file-chip {
806
+ display: inline-flex;
807
+ align-items: center;
808
+ gap: 6px;
809
+ height: 28px;
810
+ padding: 0 6px 0 10px;
811
+ border: 1px solid var(--border);
812
+ border-radius: var(--radius-chip);
813
+ background: var(--bg-elevated);
814
+ color: var(--text);
815
+ font-size: 12.5px;
816
+ }
817
+
818
+ .tc-chip-x {
819
+ display: inline-flex;
820
+ align-items: center;
821
+ justify-content: center;
822
+ width: 18px;
823
+ height: 18px;
824
+ border: none;
825
+ border-radius: 4px;
826
+ background: transparent;
827
+ color: var(--text-tertiary);
828
+ cursor: pointer;
829
+ }
830
+
831
+ .tc-chip-x:hover {
832
+ background: var(--bg-sunken);
833
+ color: var(--danger);
834
+ }
835
+
836
+ /* ---------- 批处理:进度 / 结果 ---------- */
837
+ .tc-batch-running,
838
+ .tc-batch-card {
839
+ display: flex;
840
+ flex-direction: column;
841
+ gap: 10px;
842
+ padding: 16px 18px;
843
+ border: 1px solid var(--border);
844
+ border-radius: var(--radius-card);
845
+ background: var(--bg-elevated);
846
+ }
847
+
848
+ .tc-batch-running-head,
849
+ .tc-batch-card-head {
850
+ display: flex;
851
+ align-items: center;
852
+ gap: 10px;
853
+ }
854
+
855
+ .tc-batch-running-head h3,
856
+ .tc-batch-card-head h3 {
857
+ margin: 0;
858
+ font-family: var(--font-serif);
859
+ font-size: 15.5px;
860
+ font-weight: 600;
861
+ color: var(--text);
862
+ }
863
+
864
+ .tc-batch-card-actions {
865
+ margin-left: auto;
866
+ display: flex;
867
+ gap: 6px;
868
+ }
869
+
870
+ .tc-progress {
871
+ height: 6px;
872
+ border-radius: 3px;
873
+ background: var(--bg-sunken);
874
+ overflow: hidden;
875
+ }
876
+
877
+ .tc-progress-fill {
878
+ height: 100%;
879
+ border-radius: 3px;
880
+ background: var(--accent);
881
+ transition: width 240ms var(--ease);
882
+ }
883
+
884
+ @media (prefers-reduced-motion: reduce) {
885
+ .tc-progress-fill {
886
+ transition: none;
887
+ }
888
+ }
889
+
890
+ .tc-result-grid {
891
+ list-style: none;
892
+ margin: 0;
893
+ padding: 0;
894
+ border-top: 1px solid var(--border);
895
+ }
896
+
897
+ .tc-result-item {
898
+ display: flex;
899
+ align-items: center;
900
+ gap: 8px;
901
+ border-bottom: 1px solid var(--border);
902
+ }
903
+
904
+ .tc-result-main {
905
+ flex: 1;
906
+ min-width: 0;
907
+ display: flex;
908
+ align-items: center;
909
+ gap: 10px;
910
+ padding: 10px 4px;
911
+ border: none;
912
+ background: transparent;
913
+ color: var(--text);
914
+ font-family: inherit;
915
+ font-size: 13px;
916
+ text-align: left;
917
+ cursor: pointer;
918
+ transition: background var(--dur) var(--ease);
919
+ }
920
+
921
+ .tc-result-main:hover {
922
+ background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
923
+ }
924
+
925
+ .tc-result-name {
926
+ width: 180px;
927
+ overflow: hidden;
928
+ text-overflow: ellipsis;
929
+ white-space: nowrap;
930
+ font-weight: 500;
931
+ }
932
+
933
+ .tc-result-excerpt {
934
+ flex: 1;
935
+ min-width: 0;
936
+ color: var(--text-secondary);
937
+ overflow: hidden;
938
+ text-overflow: ellipsis;
939
+ white-space: nowrap;
940
+ }
941
+
942
+ .tc-result-full {
943
+ flex-basis: 100%;
944
+ padding: 4px 0 12px;
945
+ }
946
+
947
+ .tc-result-full pre {
948
+ margin: 6px 0 0;
949
+ padding: 12px 14px;
950
+ border-radius: var(--radius-chip);
951
+ background: var(--bg-sunken);
952
+ color: var(--text);
953
+ font-family: var(--font-mono);
954
+ font-size: 12.5px;
955
+ line-height: 1.65;
956
+ white-space: pre-wrap;
957
+ word-break: break-word;
958
+ }
css/task.css ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 任务模式(契约 6D:对话/任务切换 + 三档批准)。
2
+ 只服务 Composer 的模式切换、ChatWorkbench 的任务提示条;Warm Paper 令牌配色。 */
3
+
4
+ /* 模式切换 pill(对话 | 任务):任务选中时用 accent 底 */
5
+ .mode-switch {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ gap: 2px;
9
+ padding: 2px;
10
+ border: 1px solid var(--border);
11
+ border-radius: var(--radius-control);
12
+ background: var(--bg-sunken);
13
+ }
14
+
15
+ .mode-pill {
16
+ padding: 4px 12px;
17
+ border: none;
18
+ border-radius: calc(var(--radius-control) - 2px);
19
+ background: transparent;
20
+ color: var(--text-secondary);
21
+ font-size: 12.5px;
22
+ cursor: pointer;
23
+ transition: background-color var(--dur) var(--ease);
24
+ }
25
+
26
+ .mode-pill:hover {
27
+ color: var(--text);
28
+ }
29
+
30
+ .mode-pill.is-active {
31
+ background: var(--accent);
32
+ color: var(--bg);
33
+ }
34
+
35
+ /* 权限档三选(下拉) */
36
+ .perm-picker {
37
+ display: inline-flex;
38
+ align-items: center;
39
+ gap: 6px;
40
+ }
41
+
42
+ .perm-label {
43
+ font-size: 11.5px;
44
+ color: var(--text-tertiary);
45
+ white-space: nowrap;
46
+ }
47
+
48
+ .perm-picker select {
49
+ padding: 4px 8px;
50
+ border: 1px solid var(--border);
51
+ border-radius: var(--radius-control);
52
+ background: var(--bg);
53
+ color: var(--text);
54
+ font-size: 12.5px;
55
+ cursor: pointer;
56
+ }
57
+
58
+ .perm-picker select:focus {
59
+ border-color: var(--accent);
60
+ }
61
+
62
+ /* 任务模式头部提示条(琥珀细条,温和不吓人) */
63
+ .task-notice {
64
+ margin: 0 32px;
65
+ padding: 8px 14px;
66
+ border: 1px solid var(--border);
67
+ border-left: 3px solid var(--warning);
68
+ border-radius: var(--radius-card);
69
+ background: var(--bg-elevated);
70
+ color: var(--text-secondary);
71
+ font-size: 12.5px;
72
+ line-height: 1.6;
73
+ }
74
+
75
+ .task-notice strong {
76
+ color: var(--text);
77
+ font-weight: 600;
78
+ }
79
+
80
+ .task-notice-mode {
81
+ color: var(--accent);
82
+ font-weight: 600;
83
+ }
84
+
85
+ /* ── 狂暴模式(契约 9A):提示条左上的火焰开关 + 进行中状态 ──────────── */
86
+
87
+ .task-notice-head {
88
+ display: flex;
89
+ align-items: center;
90
+ gap: 8px;
91
+ margin-bottom: 2px;
92
+ }
93
+
94
+ /* 火焰开关:关闭=幽灵按钮;开启=金渐变徽章(warning 金 → accent 陶土,走令牌) */
95
+ .frenzy-toggle {
96
+ display: inline-flex;
97
+ align-items: center;
98
+ gap: 4px;
99
+ padding: 3px 10px;
100
+ border: 1px solid var(--border);
101
+ border-radius: var(--radius-control);
102
+ background: transparent;
103
+ color: var(--text-secondary);
104
+ font-size: 12px;
105
+ font-weight: 600;
106
+ cursor: pointer;
107
+ transition:
108
+ background var(--dur) var(--ease),
109
+ color var(--dur) var(--ease),
110
+ border-color var(--dur) var(--ease);
111
+ }
112
+
113
+ .frenzy-toggle:hover {
114
+ color: var(--text);
115
+ border-color: var(--warning);
116
+ }
117
+
118
+ .frenzy-toggle.is-on {
119
+ border-color: transparent;
120
+ color: var(--bg);
121
+ background: linear-gradient(135deg, var(--warning), var(--accent));
122
+ }
123
+
124
+ .frenzy-toggle.is-on:hover {
125
+ color: var(--bg);
126
+ filter: brightness(1.04);
127
+ }
128
+
129
+ .frenzy-toggle:focus-visible {
130
+ outline: 2px solid var(--accent);
131
+ outline-offset: 2px;
132
+ }
133
+
134
+ /* 自查 / 站岗进行中状态小签(契约 9A:「自查第 N 轮」「站岗质询」) */
135
+ .task-notice-status {
136
+ display: inline-flex;
137
+ align-items: center;
138
+ padding: 2px 8px;
139
+ border-radius: var(--radius-chip);
140
+ font-size: 11.5px;
141
+ font-weight: 600;
142
+ background: var(--bg-sunken);
143
+ color: var(--text-secondary);
144
+ animation: task-status-pulse 1.6s var(--ease) infinite;
145
+ }
146
+
147
+ .task-notice-status.is-sentry {
148
+ color: var(--warning);
149
+ background: color-mix(in srgb, var(--warning) 12%, var(--bg));
150
+ }
151
+
152
+ .task-notice-status.is-check {
153
+ color: var(--accent);
154
+ background: var(--accent-soft);
155
+ }
156
+
157
+ @keyframes task-status-pulse {
158
+ 0%,
159
+ 100% {
160
+ opacity: 1;
161
+ }
162
+ 50% {
163
+ opacity: 0.55;
164
+ }
165
+ }
166
+
167
+ /* 狂暴开启时的一句话说明 */
168
+ .task-notice-frenzy-note {
169
+ font-size: 11.5px;
170
+ color: var(--text-tertiary);
171
+ }
172
+
173
+ /* 提示条正文段落(配合上面的 head 行,去掉默认段距) */
174
+ .task-notice-body {
175
+ margin: 0;
176
+ }
177
+
178
+ /* 消息流里的工具卡容器(卡片视觉复用 agent.css 的 .agent-tool-card) */
179
+ .msg-task-cards {
180
+ display: flex;
181
+ flex-direction: column;
182
+ gap: 8px;
183
+ margin: 4px 0 8px;
184
+ }
185
+
186
+ /* 「本会话自动允许」勾选框 */
187
+ .task-always {
188
+ display: inline-flex;
189
+ align-items: center;
190
+ gap: 6px;
191
+ font-size: 12px;
192
+ color: var(--text-secondary);
193
+ cursor: pointer;
194
+ user-select: none;
195
+ }
196
+
197
+ .task-always input {
198
+ accent-color: var(--accent);
199
+ cursor: pointer;
200
+ }
201
+
202
+ /* ── edit_file 改动预览(契约 6H):旧文 / 新文两栏 mono 对照 ────────── */
203
+
204
+ .edit-diff {
205
+ border: 1px solid var(--border);
206
+ border-radius: var(--radius-chip);
207
+ overflow: hidden;
208
+ margin-top: 6px;
209
+ }
210
+
211
+ .edit-diff-label {
212
+ font-size: 11px;
213
+ color: var(--text-tertiary);
214
+ padding: 4px 10px;
215
+ background: var(--bg-sunken);
216
+ border-bottom: 1px solid var(--border);
217
+ }
218
+
219
+ .edit-diff-cols {
220
+ display: grid;
221
+ grid-template-columns: 1fr 1fr;
222
+ }
223
+
224
+ .edit-diff-col {
225
+ min-width: 0;
226
+ }
227
+
228
+ .edit-diff-col + .edit-diff-col {
229
+ border-left: 1px solid var(--border);
230
+ }
231
+
232
+ .edit-diff-col-head {
233
+ font-size: 11px;
234
+ padding: 3px 10px;
235
+ font-family: var(--font-mono);
236
+ border-bottom: 1px solid var(--border);
237
+ }
238
+
239
+ /* 旧文淡红底 / 新文淡绿底(语义色 danger/success 的淡底,深浅色都成立) */
240
+ .edit-diff-col.is-removed .edit-diff-col-head {
241
+ color: var(--danger);
242
+ background: color-mix(in srgb, var(--danger) 12%, var(--bg));
243
+ }
244
+
245
+ .edit-diff-col.is-added .edit-diff-col-head {
246
+ color: var(--success);
247
+ background: color-mix(in srgb, var(--success) 12%, var(--bg));
248
+ }
249
+
250
+ .edit-diff-col pre {
251
+ margin: 0;
252
+ padding: 6px 0;
253
+ font-family: var(--font-mono);
254
+ font-size: 12px;
255
+ line-height: 1.55;
256
+ overflow-x: auto;
257
+ }
258
+
259
+ .edit-diff-col.is-removed pre {
260
+ background: color-mix(in srgb, var(--danger) 6%, var(--bg));
261
+ }
262
+
263
+ .edit-diff-col.is-added pre {
264
+ background: color-mix(in srgb, var(--success) 6%, var(--bg));
265
+ }
266
+
267
+ .edit-diff-line {
268
+ padding: 0 10px;
269
+ white-space: pre-wrap;
270
+ word-break: break-all;
271
+ }
272
+
273
+ /* 窄屏两栏改上下叠放,避免挤成一条 */
274
+ @media (max-width: 640px) {
275
+ .edit-diff-cols {
276
+ grid-template-columns: 1fr;
277
+ }
278
+
279
+ .edit-diff-col + .edit-diff-col {
280
+ border-left: none;
281
+ border-top: 1px solid var(--border);
282
+ }
283
+ }
284
+
285
+ /* 超过 40 行的折叠开关 */
286
+ .edit-diff-toggle {
287
+ display: block;
288
+ width: 100%;
289
+ padding: 5px 10px;
290
+ font-size: 11px;
291
+ color: var(--text-secondary);
292
+ background: var(--bg-sunken);
293
+ border: none;
294
+ border-top: 1px solid var(--border);
295
+ cursor: pointer;
296
+ text-align: center;
297
+ }
298
+
299
+ .edit-diff-toggle:hover {
300
+ color: var(--text);
301
+ }
css/terminal.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .terminal-workspace{height:100%;min-height:0;overflow:auto}
2
+ .terminal-heading{align-items:flex-start}
3
+ .terminal-heading .feature-actions{padding-top:0}
4
+ .terminal-session-tabs{display:flex;align-items:center;gap:5px;min-height:34px;overflow-x:auto}
5
+ .terminal-session-tabs>button{display:flex;align-items:center;gap:7px;max-width:220px;min-height:30px;padding:0 9px;border:1px solid var(--border);border-radius:4px;background:var(--bg-elevated);color:var(--text-secondary);font:9px var(--font-mono);cursor:pointer}
6
+ .terminal-session-tabs>button[aria-selected="true"]{border-color:var(--accent);color:var(--text)}
7
+ .terminal-session-tabs>button>small{color:var(--text-tertiary);font:8px var(--font-sans)}
8
+ .terminal-cwd{display:flex;align-items:center;gap:9px;color:var(--text-tertiary);font-size:9px}
9
+ .terminal-cwd>input{width:min(420px,100%);height:28px;padding:4px 8px;border:1px solid var(--border);border-radius:4px;background:var(--bg-elevated);color:var(--text);font:10px var(--font-mono)}
10
+ .terminal-status-dot{width:6px;height:6px;flex:none;border-radius:50%;background:var(--text-tertiary)}
11
+ .terminal-status-dot.is-running{background:var(--success)}.terminal-status-dot.is-stopping{background:var(--warning)}
12
+ .terminal-frame{display:grid;grid-template-rows:32px minmax(220px,1fr);min-height:320px;height:min(58vh,560px);overflow:hidden;border:1px solid #293746;border-radius:4px;background:#080d13}
13
+ .terminal-frame>header{display:flex;align-items:center;gap:8px;padding:0 10px;border-bottom:1px solid #263340;background:#0d141c;color:#aebdc7;font:9px var(--font-mono)}
14
+ .terminal-frame>header>span:first-of-type{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
15
+ .terminal-frame>header>code{color:#6f8899;font:9px var(--font-mono)}
16
+ .terminal-header-spacer{flex:1}
17
+ .terminal-screen{min-height:0;padding:7px 9px}
18
+ .terminal-screen .xterm{height:100%;}
19
+ .terminal-screen .xterm-viewport{overflow-y:auto!important}
20
+ .terminal-approval{display:grid;grid-template-columns:24px minmax(0,1fr) auto;align-items:start;gap:11px;padding:12px;border:1px solid var(--warning);border-radius:5px;background:color-mix(in srgb,var(--warning) 6%,var(--bg-elevated))}
21
+ .terminal-approval-icon{color:var(--warning)}
22
+ .terminal-approval-copy{min-width:0}
23
+ .terminal-approval-copy>strong{font-size:11px}
24
+ .terminal-approval-copy>pre{max-height:110px;overflow:auto;margin:6px 0;padding:8px;border:1px solid var(--border);border-radius:3px;background:var(--bg-sunken);color:var(--text);font:10px/1.55 var(--font-mono);white-space:pre-wrap;overflow-wrap:anywhere}
25
+ .terminal-approval-copy>p{margin:0;color:var(--text-secondary);font-size:9px;line-height:1.55}
26
+ .terminal-approval-actions{display:flex;gap:6px}
27
+ .terminal-approval-actions button{white-space:nowrap}
28
+ .terminal-buffer-note{margin:0;color:var(--warning);font-size:9px}
29
+ @media(max-width:760px){.terminal-approval{grid-template-columns:20px minmax(0,1fr)}.terminal-approval-actions{grid-column:2;justify-content:flex-end}.terminal-heading{gap:8px}}
css/theme.css ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Perch · Warm Paper 主题(Claude 式设计语言,详见 docs/design-system.md) */
2
+
3
+ :root {
4
+ --bg: #faf9f5;
5
+ --bg-elevated: #f0eee6;
6
+ --bg-sunken: #e8e5db;
7
+ --border: #e3dfd3;
8
+ --text: #1f1e1b;
9
+ --text-secondary: #6b6862;
10
+ --text-tertiary: #9c988d;
11
+ --accent: #d97757;
12
+ --accent-soft: #f4e3dc;
13
+ --success: #7a9b76;
14
+ --warning: #c9a227;
15
+ --danger: #c05b4d;
16
+
17
+ --font-serif: "Source Serif 4", "Songti SC", Georgia, serif;
18
+ --font-sans: "Inter", "PingFang SC", system-ui, -apple-system, sans-serif;
19
+ --font-mono: "JetBrains Mono", "SF Mono", Menlo, monospace;
20
+
21
+ --radius-control: 10px;
22
+ --radius-card: 14px;
23
+ --radius-float: 16px;
24
+ --radius-chip: 8px; /* 小按钮/内嵌标签的次级圆角(控件 10px 之下的一档) */
25
+ --ease: cubic-bezier(0.2, 0, 0, 1);
26
+ --dur: 150ms;
27
+ --shadow-float: 0 4px 24px rgba(31, 30, 27, 0.08);
28
+
29
+ /* 模态遮罩(抽屉/浮层后面的那层暗纱),深浅色各自取值 */
30
+ --scrim: rgba(31, 30, 27, 0.28);
31
+
32
+ /* 浮窗毛玻璃(design-system §7:85% 暖纸底 + 20px 背景模糊) */
33
+ --glass: rgba(250, 249, 245, 0.85);
34
+ --glass-blur: blur(20px);
35
+ }
36
+
37
+ @media (prefers-color-scheme: dark) {
38
+ :root {
39
+ --bg: #262521;
40
+ --bg-elevated: #2f2e29;
41
+ --bg-sunken: #1e1d1a;
42
+ --border: #3b3a34;
43
+ --text: #edeae0;
44
+ --text-secondary: #a8a49a;
45
+ --text-tertiary: #79766d;
46
+ --accent: #e08a6e;
47
+ --accent-soft: #45342d;
48
+ --shadow-float: 0 4px 24px rgba(0, 0, 0, 0.35);
49
+ --glass: rgba(38, 37, 33, 0.85);
50
+ --scrim: rgba(0, 0, 0, 0.4);
51
+ }
52
+ }
53
+
54
+ /* 契约 10A 外观:`data-theme` 显式覆盖段(设置里选「浅色/深色」时由 App 挂到
55
+ <html> 上)。`system` 不设属性 → 上面的 matchMedia 继续生效;这里的显式段
56
+ 写在 matchMedia 之后,同特异性下后写者赢,因此能盖过系统偏好。 */
57
+ [data-theme="light"] {
58
+ --bg: #faf9f5;
59
+ --bg-elevated: #f0eee6;
60
+ --bg-sunken: #e8e5db;
61
+ --border: #e3dfd3;
62
+ --text: #1f1e1b;
63
+ --text-secondary: #6b6862;
64
+ --text-tertiary: #9c988d;
65
+ --accent: #d97757;
66
+ --accent-soft: #f4e3dc;
67
+ --shadow-float: 0 4px 24px rgba(31, 30, 27, 0.08);
68
+ --glass: rgba(250, 249, 245, 0.85);
69
+ --scrim: rgba(31, 30, 27, 0.28);
70
+ }
71
+
72
+ [data-theme="dark"] {
73
+ --bg: #262521;
74
+ --bg-elevated: #2f2e29;
75
+ --bg-sunken: #1e1d1a;
76
+ --border: #3b3a34;
77
+ --text: #edeae0;
78
+ --text-secondary: #a8a49a;
79
+ --text-tertiary: #79766d;
80
+ --accent: #e08a6e;
81
+ --accent-soft: #45342d;
82
+ --shadow-float: 0 4px 24px rgba(0, 0, 0, 0.35);
83
+ --glass: rgba(38, 37, 33, 0.85);
84
+ --scrim: rgba(0, 0, 0, 0.4);
85
+ }
86
+
87
+ * {
88
+ box-sizing: border-box;
89
+ }
90
+
91
+ html,
92
+ body,
93
+ #root {
94
+ height: 100%;
95
+ margin: 0;
96
+ }
97
+
98
+ body {
99
+ background: var(--bg);
100
+ color: var(--text);
101
+ font-family: var(--font-sans);
102
+ font-size: 14.5px;
103
+ line-height: 1.65;
104
+ -webkit-font-smoothing: antialiased;
105
+ user-select: none;
106
+ cursor: default;
107
+ }
108
+
109
+ h1,
110
+ h2,
111
+ h3 {
112
+ font-family: var(--font-serif);
113
+ font-weight: 600;
114
+ letter-spacing: -0.01em;
115
+ line-height: 1.3;
116
+ margin: 0;
117
+ }
118
+
119
+ ::selection {
120
+ background: var(--accent-soft);
121
+ }
122
+
123
+ :focus-visible {
124
+ outline: 2px solid var(--accent);
125
+ outline-offset: 2px;
126
+ }
127
+
128
+ /* 滚动条:细、暖、低调 */
129
+ ::-webkit-scrollbar {
130
+ width: 8px;
131
+ height: 8px;
132
+ }
133
+ ::-webkit-scrollbar-thumb {
134
+ background: var(--border);
135
+ border-radius: 4px;
136
+ }
137
+ ::-webkit-scrollbar-thumb:hover {
138
+ background: var(--text-tertiary);
139
+ }
140
+
141
+ @media (prefers-reduced-motion: reduce) {
142
+ * {
143
+ transition: none !important;
144
+ animation: none !important;
145
+ }
146
+ }
147
+
148
+ /* ═══════════════════════════════════════════════════════════════════
149
+ Gemini 外观(dev-duotheme · 双皮肤)——`[data-style="gemini"]` 覆盖段。
150
+ 与 `data-theme` 两轴正交(照 dev-tidy 的显式覆盖模式,追加在末尾):
151
+ 本段每条选择器都要求 data-style="gemini",Warm Paper(无该属性 /
152
+ ="warm")零影响。段内顺序即层叠顺序:
153
+ 1) Gemini 浅色默认(data-theme 缺省且系统浅色,或 data-theme="light")
154
+ 2) 系统深色(media 内 :not([data-theme="light"]),特异性 0,2,0 盖过 1)
155
+ 3) 显式 data-theme="dark"(与 2 同特异性、写在其后 → 后写者赢;
156
+ 系统浅色时 2 不命中,由它兜底)
157
+ 配色取自 Google/Material(见回复《Gemini 风格规范》):白底 +
158
+ #dadce0 发丝线 + Google Blue 单主色 + 蓝→紫→粉签名渐变三令牌。
159
+ ═══════════════════════════════════════════════════════════════ */
160
+
161
+ /* 1) Gemini 浅色(纯白底 · Material 中性灰阶 · Google Blue) */
162
+ [data-style="gemini"] {
163
+ --bg: #ffffff;
164
+ --bg-elevated: #f8f9fa;
165
+ --bg-sunken: #f1f3f4;
166
+ --border: #dadce0;
167
+ --text: #1f1f1f;
168
+ --text-secondary: #5f6368;
169
+ --text-tertiary: #80868b;
170
+ --accent: #1a73e8;
171
+ --accent-hover: #1967d2; /* 按钮 hover:Google Blue 700 */
172
+ --accent-soft: #e8f0fe; /* 蓝 50:激活态浅蓝底/选区 */
173
+ --success: #188038;
174
+ --warning: #e37400;
175
+ --danger: #d93025;
176
+
177
+ /* Gemini 全 sans(「极简」的关键一刀):所有衬线位换 Google Sans 展示栈,
178
+ 正文同栈换 Text 字身;macOS 无 Google Sans → SF Pro Display/Text 接住。 */
179
+ --font-serif: "Google Sans Display", "Google Sans", "SF Pro Display",
180
+ -apple-system, BlinkMacSystemFont, "PingFang SC", system-ui, sans-serif;
181
+ --font-sans: "Google Sans Text", "Google Sans", "SF Pro Text", -apple-system,
182
+ BlinkMacSystemFont, "PingFang SC", system-ui, sans-serif;
183
+ /* --font-mono 不动:代码永远等宽 */
184
+
185
+ /* 签名渐变三令牌(蓝 → 紫 → 珊瑚粉)。使用纪律:只允许
186
+ 品牌标 / 欢迎页大标题高光 / Ultra 档强调 三处,其余黑白灰 + 单主色。 */
187
+ --grad-start: #4285f4;
188
+ --grad-mid: #9b72cb;
189
+ --grad-end: #d96570;
190
+
191
+ --radius-card: 16px; /* Material 大圆角档(8/12/16/28);控件/浮层令牌不动 */
192
+
193
+ --shadow-float: 0 1px 2px rgba(60, 64, 67, 0.1), 0 1px 3px rgba(60, 64, 67, 0.14);
194
+ --glass: rgba(255, 255, 255, 0.85);
195
+ --scrim: rgba(32, 33, 36, 0.32);
196
+ }
197
+
198
+ /* 2) Gemini 深色(跟随系统:Google dark gray #1e1f20 系) */
199
+ @media (prefers-color-scheme: dark) {
200
+ [data-style="gemini"]:not([data-theme="light"]) {
201
+ --bg: #1e1f20;
202
+ --bg-elevated: #282a2c;
203
+ --bg-sunken: #131314;
204
+ --border: #3c4043;
205
+ --text: #e3e3e3;
206
+ --text-secondary: #9aa0a6;
207
+ --text-tertiary: #80868b;
208
+ --accent: #8ab4f8;
209
+ --accent-hover: #a8c7fa; /* 深色 hover 走「浅变体」(Google 深色态加亮) */
210
+ --accent-soft: #1e3a5f;
211
+ --success: #81c995;
212
+ --warning: #fdd663;
213
+ --danger: #f28b82;
214
+ --shadow-float: 0 1px 3px rgba(0, 0, 0, 0.55);
215
+ --glass: rgba(30, 31, 32, 0.85);
216
+ --scrim: rgba(0, 0, 0, 0.5);
217
+ }
218
+ }
219
+
220
+ /* 3) Gemini 显式深色(设置里选「深色」→ data-theme="dark";与 2 同款取值) */
221
+ [data-style="gemini"][data-theme="dark"] {
222
+ --bg: #1e1f20;
223
+ --bg-elevated: #282a2c;
224
+ --bg-sunken: #131314;
225
+ --border: #3c4043;
226
+ --text: #e3e3e3;
227
+ --text-secondary: #9aa0a6;
228
+ --text-tertiary: #80868b;
229
+ --accent: #8ab4f8;
230
+ --accent-hover: #a8c7fa;
231
+ --accent-soft: #1e3a5f;
232
+ --success: #81c995;
233
+ --warning: #fdd663;
234
+ --danger: #f28b82;
235
+ --shadow-float: 0 1px 3px rgba(0, 0, 0, 0.55);
236
+ --glass: rgba(30, 31, 32, 0.85);
237
+ --scrim: rgba(0, 0, 0, 0.5);
238
+ }
css/vendor-picker.css ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* 选择服务商(Phase 6B):搜索 + 厂商 chips + 预置表单。
2
+ Warm Paper 全令牌配色(design-system.md),无硬编码颜色。 */
3
+
4
+ .vp-wrap {
5
+ margin-bottom: 18px;
6
+ padding: 16px 18px;
7
+ border: 1px solid var(--border);
8
+ border-radius: var(--radius-card);
9
+ background: var(--bg-elevated);
10
+ }
11
+
12
+ .vp-head {
13
+ margin-bottom: 12px;
14
+ }
15
+
16
+ .vp-head h3 {
17
+ margin: 0;
18
+ font-size: 16px;
19
+ }
20
+
21
+ .vp-head p {
22
+ margin: 4px 0 0;
23
+ font-size: 12.5px;
24
+ color: var(--text-secondary);
25
+ }
26
+
27
+ /* ── 搜索框 ────────────────────────────────────────────────────── */
28
+
29
+ .vp-search {
30
+ width: 100%;
31
+ height: 36px;
32
+ margin-bottom: 12px;
33
+ padding: 0 14px;
34
+ border: 1px solid var(--border);
35
+ border-radius: var(--radius-control);
36
+ background: var(--bg-sunken);
37
+ color: var(--text);
38
+ font-family: inherit;
39
+ font-size: 13.5px;
40
+ }
41
+
42
+ .vp-search::placeholder {
43
+ color: var(--text-tertiary);
44
+ }
45
+
46
+ .vp-search:focus-visible {
47
+ outline: none;
48
+ border-color: var(--accent);
49
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-soft) 65%, transparent);
50
+ }
51
+
52
+ /* ── 厂商 chips 网格 ───────────────────────────────────────────── */
53
+
54
+ .vp-grid {
55
+ display: flex;
56
+ flex-wrap: wrap;
57
+ gap: 8px;
58
+ }
59
+
60
+ .vp-chip {
61
+ display: inline-flex;
62
+ align-items: center;
63
+ gap: 9px;
64
+ padding: 7px 12px 7px 9px;
65
+ border: 1px solid var(--border);
66
+ border-radius: var(--radius-control);
67
+ background: var(--bg);
68
+ color: var(--text);
69
+ font-family: inherit;
70
+ text-align: left;
71
+ cursor: pointer;
72
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
73
+ }
74
+
75
+ .vp-chip:hover {
76
+ background: var(--accent-soft);
77
+ }
78
+
79
+ .vp-chip.is-active {
80
+ border-color: var(--accent);
81
+ background: var(--accent-soft);
82
+ }
83
+
84
+ .vp-chip.is-custom {
85
+ border-style: dashed;
86
+ }
87
+
88
+ /* 衬线首字母圆标(logo 位) */
89
+ .vp-avatar {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ width: 26px;
94
+ height: 26px;
95
+ flex: none;
96
+ border: 1px solid var(--border);
97
+ border-radius: 50%;
98
+ background: var(--bg-sunken);
99
+ font-family: var(--font-serif);
100
+ font-size: 13px;
101
+ font-weight: 600;
102
+ color: var(--text-secondary);
103
+ }
104
+
105
+ .vp-chip.is-active .vp-avatar {
106
+ color: var(--accent);
107
+ }
108
+
109
+ .vp-chip-text {
110
+ display: flex;
111
+ flex-direction: column;
112
+ gap: 1px;
113
+ min-width: 0;
114
+ }
115
+
116
+ .vp-chip-name {
117
+ font-size: 13px;
118
+ font-weight: 500;
119
+ line-height: 1.3;
120
+ }
121
+
122
+ .vp-chip-alias {
123
+ font-size: 11.5px;
124
+ color: var(--text-tertiary);
125
+ line-height: 1.3;
126
+ white-space: nowrap;
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ max-width: 150px;
130
+ }
131
+
132
+ /* ── 没搜到 ────────────────────────────────────────────────────── */
133
+
134
+ .vp-empty {
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: space-between;
138
+ gap: 12px;
139
+ flex-wrap: wrap;
140
+ padding: 10px 12px;
141
+ border: 1px dashed var(--border);
142
+ border-radius: var(--radius-control);
143
+ background: var(--bg-sunken);
144
+ }
145
+
146
+ .vp-empty p {
147
+ margin: 0;
148
+ font-size: 13px;
149
+ color: var(--text-secondary);
150
+ }
151
+
152
+ /* ── 选中后的预置表单 ──────────────────────────────────────────── */
153
+
154
+ .vp-form {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 14px;
158
+ margin-top: 14px;
159
+ padding-top: 14px;
160
+ border-top: 1px solid var(--border);
161
+ }
162
+
163
+ .vp-form-head {
164
+ display: flex;
165
+ align-items: center;
166
+ gap: 12px;
167
+ }
168
+
169
+ .vp-avatar.is-big {
170
+ width: 36px;
171
+ height: 36px;
172
+ font-size: 16px;
173
+ }
174
+
175
+ .vp-form-head h4 {
176
+ margin: 0;
177
+ font-size: 15.5px;
178
+ }
179
+
180
+ .vp-form-head p {
181
+ margin: 3px 0 0;
182
+ font-size: 12.5px;
183
+ color: var(--text-secondary);
184
+ }
185
+
186
+ .vp-form-head a {
187
+ color: var(--accent);
188
+ text-decoration: underline;
189
+ text-underline-offset: 2px;
190
+ cursor: pointer;
191
+ }
192
+
193
+ /* Base URL 预置展示:只读一行 + 「改」按钮解锁 */
194
+ .vp-baseurl {
195
+ display: flex;
196
+ align-items: center;
197
+ gap: 8px;
198
+ }
199
+
200
+ .vp-baseurl code {
201
+ flex: 1;
202
+ min-width: 0;
203
+ padding: 8px 12px;
204
+ border: 1px solid var(--border);
205
+ border-radius: var(--radius-control);
206
+ background: var(--bg-sunken);
207
+ font-family: var(--font-mono);
208
+ font-size: 12.5px;
209
+ color: var(--text-secondary);
210
+ word-break: break-all;
211
+ }
css/workspace.css ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .workspace-page{display:flex;flex-direction:column;height:100%;min-height:0;background:var(--bg);color:var(--text)}
2
+ .workspace-header{display:flex;align-items:center;justify-content:space-between;padding:37px 40px 22px;gap:16px;flex-shrink:0}
3
+ .ws-eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:var(--font-mono);font-size:10px;letter-spacing:2px;color:var(--text-secondary);line-height:1.6}
4
+ .ws-eyebrow>span{width:5px;height:5px;border-radius:50%;background:var(--accent)}
5
+ .workspace-header h1{display:flex;align-items:center;gap:12px;margin-top:9px;font-family:var(--font-sans);font-size:24px;font-weight:550;letter-spacing:-.7px}
6
+ .ws-version{font:9px var(--font-mono);letter-spacing:1px;padding:4px 6px;border:1px solid var(--border);border-radius:4px;color:var(--text-secondary)}
7
+ .workspace-header-actions{display:flex;align-items:center;gap:12px}.local-pill{display:inline-flex;align-items:center;gap:6px;font:9px var(--font-mono);letter-spacing:1px;color:var(--text-secondary)}
8
+ .workspace-tabs{display:flex;gap:28px;padding:0 40px;border-bottom:1px solid var(--border);flex-shrink:0}.workspace-tabs button{display:flex;align-items:center;gap:7px;position:relative;padding:12px 0 14px;border:0;background:none;font:12px var(--font-sans);color:var(--text-secondary);cursor:pointer}.workspace-tabs button.is-active{color:var(--text)}.workspace-tabs button.is-active:after{content:"";position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent)}
9
+ .workspace-scroll{overflow:auto;min-height:0;flex:1;padding:28px 40px 20px}.ws-muted{font-size:12px;line-height:1.7;color:var(--text-secondary)}.ws-label{font:9px var(--font-mono);letter-spacing:.8px;color:var(--text-tertiary);line-height:1.6}.ws-card{border:1px solid var(--border);border-radius:14px;background:var(--bg-elevated);padding:22px;min-width:0}.ws-card h2{font:550 14px var(--font-sans);letter-spacing:-.2px;display:flex;align-items:center;gap:8px}.ws-card-top{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:15px}.ws-card-top svg{color:var(--text-secondary)}
10
+ .ws-icon{width:30px;height:30px;display:inline-flex;justify-content:center;align-items:center;background:none;color:var(--text-secondary);border:1px solid var(--border);border-radius:7px;cursor:pointer;flex-shrink:0}.ws-icon:hover{color:var(--text);background:var(--bg-sunken)}.workspace-page button:disabled{opacity:.4;cursor:not-allowed}.ws-primary,.ws-secondary{display:inline-flex;justify-content:center;align-items:center;gap:8px;cursor:pointer;font:500 12px var(--font-sans);padding:10px 15px;border-radius:8px;border:1px solid var(--border)}.ws-primary{background:var(--text);color:var(--bg)}.ws-secondary{background:transparent;color:var(--text)}.ws-primary:hover{filter:brightness(1.08)}.ws-link{display:inline-flex;align-items:center;gap:6px;border:none;padding:4px 0;color:var(--accent);font:11px var(--font-sans);background:none;cursor:pointer}.ws-error{border:1px solid var(--danger);border-radius:8px;padding:12px;color:var(--danger);font-size:12px;white-space:pre-wrap;overflow-wrap:anywhere}.ws-empty{padding:24px 0;font-size:12px;color:var(--text-secondary);line-height:1.8}
11
+ .darkside-hero{position:relative;display:flex;overflow:hidden;min-height:265px;border:1px solid var(--border);border-radius:16px;background:linear-gradient(118deg,var(--bg-elevated),var(--bg-sunken));isolation:isolate}.hero-copy{z-index:1;position:relative;padding:30px 32px;flex:1}.hero-copy .ws-eyebrow{font-size:8px;letter-spacing:2.1px}.hero-copy h2{font-family:var(--font-sans);font-weight:450;font-size:35px;letter-spacing:-1.4px;line-height:1.35;margin-top:14px}.hero-copy p{font-size:12px;color:var(--text-secondary);line-height:1.8;margin:12px 0 20px}.hero-orbit{position:relative;width:45%;min-width:220px;flex-shrink:0}.orbit-sphere{position:absolute;top:34px;right:55px;width:178px;height:178px;border-radius:50%;background:radial-gradient(circle at 32% 27%,#47505a 0%,#232a34 22%,#10151c 50%,#090b10 69%,#080a0d 73%);box-shadow:-8px -3px 22px rgba(217,190,143,.1),inset -15px -12px 25px #050608,1px 1px 0 rgba(229,193,131,.3)}.orbit-sphere:after{content:"";position:absolute;inset:-1px;border-radius:50%;border:1px solid rgba(219,190,137,.14);border-right-color:transparent;border-bottom-color:transparent;transform:rotate(-25deg)}.orbit-line{position:absolute;top:28px;right:20px;width:256px;height:212px;transform:rotate(-32deg);border:1px solid rgba(149,157,168,.17);border-radius:50%}.orbit-two{width:320px;height:154px;top:60px;right:-10px;transform:rotate(-32deg);border-color:rgba(149,157,168,.1)}.orbit-caption{position:absolute;bottom:24px;right:31px;font:9px var(--font-mono);color:var(--text-secondary);letter-spacing:3px;line-height:2}.orbit-caption b{font-size:6px;font-weight:400;letter-spacing:2px;color:var(--text-tertiary)}
12
+ .workspace-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));padding:25px 0;gap:12px}.ws-metric{padding:0 20px;border-right:1px solid var(--border);display:flex;flex-direction:column;gap:5px}.ws-metric:first-child{padding-left:0}.ws-metric:last-child{border:0;padding-right:0}.ws-metric strong{font:400 30px var(--font-sans);letter-spacing:-1px;font-variant-numeric:tabular-nums}.ws-metric>.ws-muted{font-size:11px}.ws-metric .ws-label{font-family:var(--font-sans);letter-spacing:0;font-size:10px}.workspace-bottom{display:grid;grid-template-columns:1.15fr 1fr;gap:16px}.runs-empty{display:flex;align-items:center;gap:14px;min-height:155px}.empty-signal{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:48px;height:48px;border:1px solid var(--border);border-radius:50%;color:var(--text-tertiary)}.runs-empty strong{font-size:12px;font-weight:500}.runs-empty p{font-size:11px;color:var(--text-tertiary);line-height:1.9;margin:8px 0}.health-card dl{margin:0;display:flex;flex-direction:column;gap:13px}.health-card dl>div{display:flex;justify-content:space-between;font-size:10px;gap:12px}.health-card dt{color:var(--text-secondary)}.health-card dd{margin:0;text-align:right}.health-card>.ws-muted{font-size:10px;margin:17px 0 9px}.health-pill{font-size:9px;padding:3px 7px;border:1px solid var(--border);border-radius:4px;color:var(--text-secondary)}.health-pill.is-ok{color:var(--success);border-color:color-mix(in srgb,var(--success) 30%,transparent)}.workspace-foot{display:flex;justify-content:space-between;gap:12px;margin-top:24px;padding-top:16px;border-top:1px solid var(--border);color:var(--text-tertiary);font:8px var(--font-mono);letter-spacing:1px}.workspace-foot span:last-child{font-family:var(--font-sans);letter-spacing:.3px}.live-run{display:flex;align-items:center;gap:10px;padding:14px 0;border-top:1px solid var(--border)}.live-run>div{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.live-run strong{font-size:11px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.live-run .ws-muted{font-size:10px}.live-indicator,.run-state.is-live:before{width:5px;height:5px;border-radius:50%;background:var(--success)}
13
+ .history-grid{display:grid;grid-template-columns:minmax(230px,.8fr) minmax(280px,1.2fr);gap:18px;align-items:start}.ws-search{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--bg-sunken);border:1px solid var(--border);border-radius:8px}.ws-search svg{color:var(--text-secondary);flex-shrink:0}.ws-search input{min-width:0;width:100%;border:0;background:none;color:var(--text);font:12px var(--font-sans);outline:none}.ws-search:focus-within{border-color:var(--accent)}.history-search>.ws-muted{font-size:10px}.ws-results{max-height:550px;overflow:auto;margin-top:16px}.ws-result{width:100%;display:flex;flex-direction:column;gap:9px;padding:15px 10px;border:0;border-bottom:1px solid var(--border);border-radius:6px;background:none;color:var(--text);text-align:left;cursor:pointer}.ws-result.is-active,.ws-result:hover{background:var(--bg-sunken)}.ws-result-title{display:flex;justify-content:space-between;width:100%;align-items:center;font-size:12px;gap:8px;overflow-wrap:anywhere}.ws-result-snippet{font-size:10px;color:var(--text-secondary);line-height:1.8;overflow-wrap:anywhere}.checkpoint-list{list-style:none;margin:22px 0 0;padding:0 0 0 15px;max-height:530px;overflow:auto}.checkpoint-list>li{position:relative;border-left:1px solid var(--border);padding:0 0 22px 20px}.checkpoint-list>li:last-child{border-left-color:transparent}.checkpoint-node{position:absolute;left:-4px;top:3px;width:7px;height:7px;border:1px solid var(--accent);background:var(--bg-elevated);border-radius:50%}.checkpoint-head{display:flex;justify-content:space-between;gap:8px}.checkpoint-list p{font-size:12px;line-height:1.8;color:var(--text-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:9px 0 6px}.history-timeline>.ws-muted{font-size:11px;margin-top:0}
14
+ .lab-form{max-width:100%}.lab-models{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:20px 0 15px}.lab-models label{display:flex;flex-direction:column;gap:7px}.lab-models select,.lab-run-picker select{color:var(--text);background:var(--bg-sunken);border:1px solid var(--border);border-radius:7px;padding:10px;font:12px var(--font-sans);min-width:0;width:100%}.lab-form textarea{resize:vertical;min-height:110px;width:100%;background:var(--bg-sunken);border:1px solid var(--border);border-radius:8px;color:var(--text);font:12px/1.8 var(--font-sans);padding:14px;user-select:text}.lab-submit{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:12px}.lab-consent{border:1px solid var(--warning);border-radius:9px;padding:15px;margin-top:18px;font-size:12px}.lab-consent p{font-size:11px;color:var(--text-secondary);line-height:1.8}.lab-consent>div{display:flex;gap:10px}.lab-comparison{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:18px}.lab-placeholder{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:50px 20px;color:var(--text-tertiary)}.lab-placeholder h3{font:400 18px var(--font-sans);color:var(--text-secondary)}.lab-placeholder p{font-size:11px;margin:0}.lab-letter{font:20px var(--font-mono);color:var(--accent)}.lab-answer h3{font:500 11px var(--font-sans);overflow-wrap:anywhere;flex:1}.run-state{font-size:9px;white-space:nowrap;color:var(--text-secondary);display:flex;align-items:center;gap:5px}.run-state.is-live:before{content:""}.lab-answer pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:450px;overflow:auto;font:12px/1.9 var(--font-sans);user-select:text}.lab-answer footer{display:flex;justify-content:space-between;gap:10px;border-top:1px solid var(--border);padding-top:12px}.lab-run-picker{display:flex;justify-content:flex-end;align-items:center;gap:12px;margin:15px 0}.lab-run-picker select{width:auto;max-width:220px}.is-spinning{animation:ws-spin 1s linear infinite}.ui-recovery{max-width:560px;margin:10vh auto;padding:32px;display:flex;flex-direction:column;align-items:flex-start;gap:18px}.ui-recovery p{color:var(--text-secondary);line-height:1.9}.section-loading{display:flex;align-items:center;justify-content:center;flex:1;min-height:120px;color:var(--text-secondary);font-size:12px}@keyframes ws-spin{to{transform:rotate(360deg)}}
15
+ @media(max-width:1080px){.workspace-header{padding:34px 25px 20px}.workspace-tabs{padding:0 25px}.workspace-scroll{padding:24px 25px 18px}.hero-copy{padding:26px}.hero-copy h2{font-size:30px}.hero-orbit{min-width:190px}.orbit-sphere{right:30px;width:160px;height:160px}.orbit-line{right:0;width:225px}.orbit-two{right:-30px;width:270px}.ws-card{padding:18px}.workspace-metrics{gap:6px}.ws-metric{padding:0 12px}.history-grid{grid-template-columns:1fr}.workspace-bottom{grid-template-columns:1fr 1fr}}
16
+ @media(max-width:800px){.workspace-bottom{grid-template-columns:1fr}.workspace-metrics{grid-template-columns:1fr 1fr;gap:20px}.ws-metric:nth-child(2){border:0}.ws-metric:nth-child(3){padding-left:0}.hero-orbit{display:none}.local-pill{display:none}.lab-comparison{grid-template-columns:1fr}.workspace-foot{flex-direction:column}.workspace-header h1{font-size:21px}.lab-models{grid-template-columns:1fr}}
17
+
18
+ .ws-safety-note{display:flex;align-items:flex-start;gap:10px;border:1px solid var(--warning);border-radius:9px;padding:12px 14px;margin-bottom:18px;color:var(--warning);font-size:11px;line-height:1.8}.ws-safety-note svg{flex-shrink:0;margin-top:2px}
19
+
20
+ .legacy-linker{margin-top:14px;border-top:1px solid var(--border);padding:12px 4px}.legacy-linker summary{font-size:10px;color:var(--text-secondary);cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:8px}.legacy-linker summary span{font-size:9px;color:var(--text-tertiary)}.legacy-linker>div{display:flex;justify-content:space-between;gap:8px;padding:10px 2px;border-top:1px solid var(--border);font-size:10px}.legacy-linker>div>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
21
+
22
+ .workspace-recent{display:grid;grid-template-columns:170px 1fr;gap:18px;align-items:start;padding:0 0 21px;border-bottom:1px solid var(--border)}.workspace-recent h2{font:550 12px var(--font-sans);margin:2px 0 5px}.workspace-recent .ws-muted{font-size:10px}.workspace-recent-list{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.workspace-recent-list>button{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:5px 8px;align-items:center;text-align:left;padding:10px 11px;border:1px solid var(--border);border-radius:7px;background:var(--bg-elevated);color:var(--text);cursor:pointer;min-width:0}.workspace-recent-list>button:hover{border-color:var(--accent)}.workspace-recent-list>button>span{font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workspace-recent-list>button>small{font:8px var(--font-mono);color:var(--text-tertiary)}.workspace-recent-list>button>svg{grid-column:2;grid-row:1 / span 2;color:var(--text-tertiary)}
23
+ .overview-start{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:22px 0 20px;border-bottom:1px solid var(--border)}.overview-start h2{margin:5px 0;font-size:19px;font-weight:550}.overview-start p{margin:0;color:var(--text-secondary);font-size:11px;line-height:1.6}.overview-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:7px}.overview-actions .ws-primary,.overview-actions .ws-secondary{padding:7px 10px;font-size:10px}
24
+ @media(max-width:960px){.workspace-recent{grid-template-columns:1fr;gap:10px}.workspace-recent-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
25
+ @media(max-width:760px){.overview-start{align-items:flex-start;flex-direction:column}.overview-actions{justify-content:flex-start}}
docs/design-system.md ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 栖木 Perch · 设计系统(Warm Paper)
2
+
3
+ > 一套"像纸一样温暖、像工具一样安静"的界面语言。
4
+ > 目标是让 AI 应用**不像一个聊天机器人**,而像你桌上一本笔记本。
5
+
6
+ ---
7
+
8
+ ## 1. 设计哲学
9
+
10
+ ### 1.1 为什么是"暖纸"
11
+
12
+ 大多数 AI 应用用的是**冷色科技感**:纯白/纯黑背景 + 蓝紫渐变。
13
+ 那是"工具"的语言,不是"伙伴"的语言。
14
+
15
+ 栖木选了**暖纸**:
16
+
17
+ - 背景 `#faf9f5`——不是纯白,是纸张微微泛黄的白
18
+ - 文字 `#1f1e1b`——不是纯黑,是墨水的深棕
19
+ - 强调色 `#d97757`——陶土橙,温暖但不刺眼
20
+
21
+ **用户长时间盯着它**,暖色比冷色更不容易疲劳。
22
+
23
+ ### 1.2 三条原则
24
+
25
+ | 原则 | 含义 | 体现 |
26
+ |---|---|---|
27
+ | **安静优先** | 界面不抢注意力 | 低饱和、少动画、无渐变噪点 |
28
+ | **内容为王** | 结构和排版服务于阅读 | 衬线标题 + 无衬线正文 |
29
+ | **物理感** | 元素像真的纸/玻璃 | 柔和阴影、毛玻璃、微圆角 |
30
+
31
+ ---
32
+
33
+ ## 2. 色彩令牌
34
+
35
+ 所有颜色都是 CSS 变量(`tokens/theme.css`),三套主题自动切换:
36
+
37
+ | 令牌 | 浅色(Warm Paper) | 深色(Dark Side) | 用途 |
38
+ |---|---|---|---|
39
+ | `--bg` | `#faf9f5` | `#262521` | 页面底色 |
40
+ | `--bg-elevated` | `#f0eee6` | `#2f2e29` | 卡片/浮层 |
41
+ | `--bg-sunken` | `#e8e5db` | `#1e1d1a` | 凹陷区/代码块 |
42
+ | `--border` | `#e3dfd3` | `#3b3a34` | 分隔线/描边 |
43
+ | `--text` | `#1f1e1b` | `#edeae0` | 主文字 |
44
+ | `--text-secondary` | `#6b6862` | `#a8a49a` | 次要文字 |
45
+ | `--text-tertiary` | `#9c988d` | `#79766d` | 提示/占位 |
46
+ | `--accent` | `#d97757` | `#e08a6e` | 强调/主按钮 |
47
+ | `--accent-soft` | `#f4e3dc` | `#45342d` | 强调背景 |
48
+ | `--success` | `#7a9b76` | — | 成功 |
49
+ | `--warning` | `#c9a227` | — | 警告 |
50
+ | `--danger` | `#c05b4d` | — | 危险 |
51
+
52
+ ### 主题切换机制
53
+
54
+ ```css
55
+ /* 1) 默认跟随系统 */
56
+ @media (prefers-color-scheme: dark) { :root { ... } }
57
+
58
+ /* 2) 显式覆盖(设置里选浅色/深色时挂到 <html data-theme="...">) */
59
+ [data-theme="light"] { ... }
60
+ [data-theme="dark"] { ... }
61
+ ```
62
+
63
+ **顺序很重要**:显式段写在 `matchMedia` 之后,同特异性下后写者赢 → 能覆盖系统偏好。
64
+
65
+ ---
66
+
67
+ ## 3. 字体
68
+
69
+ | 用途 | 令牌 | 字体栈 |
70
+ |---|---|---|
71
+ | 标题 | `--font-serif` | Source Serif 4 / Songti SC / Georgia |
72
+ | 正文 | `--font-sans` | Inter / PingFang SC / system-ui |
73
+ | 代码 | `--font-mono` | JetBrains Mono / SF Mono / Menlo |
74
+
75
+ **为什么标题用衬线**:衬线有"书"的质感,让长文阅读更舒服,也拉开与"聊天机器人"的距离。
76
+
77
+ 正文 `14.5px` / 行高 `1.65`——比常规 UI 略大,因为 AI 应用的主要行为是**读**。
78
+
79
+ ---
80
+
81
+ ## 4. 圆角与阴影
82
+
83
+ ```css
84
+ --radius-control: 10px; /* 按钮/输入框 */
85
+ --radius-card: 14px; /* 卡片 */
86
+ --radius-float: 16px; /* 浮层/弹窗 */
87
+ --radius-chip: 8px; /* 小标签 */
88
+ --shadow-float: 0 4px 24px rgba(31,30,27,0.08); /* 浮起 */
89
+ ```
90
+
91
+ **原则**:圆角随"层级"递增——控件 < 卡片 < 浮层。
92
+ 阴影很淡(8% 透明度),只用来暗示层级,不制造视觉噪音。
93
+
94
+ ---
95
+
96
+ ## 5. 毛玻璃(Glass)
97
+
98
+ ```css
99
+ --glass: rgba(250, 249, 245, 0.85);
100
+ --glass-blur: blur(20px);
101
+ ```
102
+
103
+ 用于浮窗、命令面板、侧边抽屉——**85% 暖纸底 + 20px 模糊**。
104
+ 既保持内容可读,又透出底层氛围。
105
+
106
+ ---
107
+
108
+ ## 6. 动效
109
+
110
+ ```css
111
+ --ease: cubic-bezier(0.2, 0, 0, 1); /* 快进慢出 */
112
+ --dur: 150ms;
113
+ ```
114
+
115
+ **原则**:
116
+ - 只用 `opacity` / `transform`(GPU 友好)
117
+ - 时长 150ms——快到不打断,慢到可感知
118
+ - 缓动是"快进慢出",模拟物理惯性
119
+
120
+ ---
121
+
122
+ ## 7. 组件样式地图
123
+
124
+ 48 个 CSS 文件按模块拆分(见 `css/`),核心几个:
125
+
126
+ | 文件 | 模块 |
127
+ |---|---|
128
+ | `theme.css` | 全局令牌、清空、排版基线 |
129
+ | `chat.css` | 对话区(消息气泡、流式光标) |
130
+ | `composer.css` | 输入区(思考强度滑块、ultrafast 徽章) |
131
+ | `markdown.css` | Markdown 渲染(代码块/表格/引用) |
132
+ | `materials.css` | 材质(毛玻璃/纸张/凹陷) |
133
+ | `screensaver.css` | 待机屏保(四色流体 + 视频) |
134
+
135
+ 其余是各功能面板(知识库、任务、启动器、讨论区…)。
136
+
137
+ ---
138
+
139
+ ## 8. 可访问性
140
+
141
+ - **对比度**:正文对背景 ≥ 7:1(AAA)
142
+ - **焦点环**:键盘导航有可见焦点(不靠颜色单独传达状态)
143
+ - **动效偏好**:尊重 `prefers-reduced-motion`
144
+ - **字号**:正文 14.5px 起(不玩 12px 小字)
145
+
146
+ ---
147
+
148
+ ## 9. 怎么用这套设计
149
+
150
+ 1. 引入 `tokens/theme.css`(令牌层)
151
+ 2. 按需引入 `css/*.css`(组件层)
152
+ 3. 主题切换:给 `<html>` 加 `data-theme="light" | "dark"`,或不加(跟随系统)
153
+ 4. 所有自定义样式都用 `var(--token)`,不要写死颜色
154
+
155
+ 详见 `preview/index.html`(一个可直接打开的效果预览)。
156
+
157
+ ---
158
+
159
+ MIT License · 来自 [栖木 Perch](https://huggingface.co/datasets/hongcoding/perch)