@moonshot-ai/kimi-code 0.22.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/main.mjs +989 -197
  2. package/dist-web/assets/{CodeBlockNode-CHRi13cp.js → CodeBlockNode-BeQAAdW3.js} +1 -1
  3. package/dist-web/assets/{CodeBlockShell.vue_vue_type_style_index_0_lang-Bw3zdw7l.js → CodeBlockShell.vue_vue_type_style_index_0_lang-D-VEP4Fn.js} +1 -1
  4. package/dist-web/assets/{Tooltip-Co8nMusV.js → Tooltip-ChsJyhEI.js} +1 -1
  5. package/dist-web/assets/{arc-dY0kCO7r.js → arc-DrGcGe6d.js} +1 -1
  6. package/dist-web/assets/{architectureDiagram-3BPJPVTR-CVGQC8aY.js → architectureDiagram-3BPJPVTR-iQ9G25kx.js} +1 -1
  7. package/dist-web/assets/{blockDiagram-GPEHLZMM-B2akGU98.js → blockDiagram-GPEHLZMM-CuzX8waX.js} +1 -1
  8. package/dist-web/assets/{c4Diagram-AAUBKEIU-d0Tnj3h7.js → c4Diagram-AAUBKEIU-lWe0pssH.js} +1 -1
  9. package/dist-web/assets/channel-BbUnBXY4.js +1 -0
  10. package/dist-web/assets/{chunk-2J33WTMH-aLmQ7kE7.js → chunk-2J33WTMH-BcD2luAP.js} +1 -1
  11. package/dist-web/assets/{chunk-4BX2VUAB-jj7AfMtu.js → chunk-4BX2VUAB-ZTdMsiUw.js} +1 -1
  12. package/dist-web/assets/{chunk-55IACEB6-DOuxcNQK.js → chunk-55IACEB6-JOHB87lb.js} +1 -1
  13. package/dist-web/assets/{chunk-727SXJPM-ByX_U4aJ.js → chunk-727SXJPM-BKcvO8HJ.js} +1 -1
  14. package/dist-web/assets/{chunk-AQP2D5EJ-Dwe8AVWQ.js → chunk-AQP2D5EJ-pRCfr-UT.js} +1 -1
  15. package/dist-web/assets/{chunk-FMBD7UC4-D4Su5t72.js → chunk-FMBD7UC4-Dwc_LTGi.js} +1 -1
  16. package/dist-web/assets/{chunk-ND2GUHAM-BNRuB-eG.js → chunk-ND2GUHAM-BXa5VPW8.js} +1 -1
  17. package/dist-web/assets/{chunk-QZHKN3VN-CfTAMtms.js → chunk-QZHKN3VN-DImyhT7B.js} +1 -1
  18. package/dist-web/assets/classDiagram-4FO5ZUOK-C-JqfdmA.js +1 -0
  19. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-C-JqfdmA.js +1 -0
  20. package/dist-web/assets/{cose-bilkent-S5V4N54A-Db4x33Cx.js → cose-bilkent-S5V4N54A-CmvBDyEQ.js} +1 -1
  21. package/dist-web/assets/{dagre-BM42HDAG-CSVzL3o5.js → dagre-BM42HDAG-BLlVemY_.js} +1 -1
  22. package/dist-web/assets/{diagram-2AECGRRQ-ChQghRCe.js → diagram-2AECGRRQ-S_ZOnEGh.js} +1 -1
  23. package/dist-web/assets/{diagram-5GNKFQAL-CzjFtwV4.js → diagram-5GNKFQAL-VWugledA.js} +1 -1
  24. package/dist-web/assets/{diagram-KO2AKTUF-DzzhiPZ_.js → diagram-KO2AKTUF-BqrJi52N.js} +1 -1
  25. package/dist-web/assets/{diagram-LMA3HP47-D_U1BnUF.js → diagram-LMA3HP47-BRwG6VJ2.js} +1 -1
  26. package/dist-web/assets/{diagram-OG6HWLK6-BfFICgG3.js → diagram-OG6HWLK6-B4h3lC_6.js} +1 -1
  27. package/dist-web/assets/{erDiagram-TEJ5UH35-DrJpAckD.js → erDiagram-TEJ5UH35-CoynqafK.js} +1 -1
  28. package/dist-web/assets/{flowDiagram-I6XJVG4X-DXu73Cwn.js → flowDiagram-I6XJVG4X-mSrbhP6V.js} +1 -1
  29. package/dist-web/assets/{ganttDiagram-6RSMTGT7-C6uzlaWx.js → ganttDiagram-6RSMTGT7-DB1PpBk0.js} +1 -1
  30. package/dist-web/assets/{gitGraphDiagram-PVQCEYII-BJs5S8Wt.js → gitGraphDiagram-PVQCEYII-DAFYaHhJ.js} +1 -1
  31. package/dist-web/assets/index-BQvC0kGr.css +1 -0
  32. package/dist-web/assets/{index-CZrAeDIj.js → index-C8mys0NG.js} +2 -2
  33. package/dist-web/assets/index-DZSqyBof.js +279 -0
  34. package/dist-web/assets/{index-0aK13Vx6.js → index-DlpeCxLp.js} +1 -1
  35. package/dist-web/assets/{index10-B0hKHFI0.js → index10-DRCxutuy.js} +1 -1
  36. package/dist-web/assets/{index11-97AxRDhM.js → index11-tnZiF2AO.js} +1 -1
  37. package/dist-web/assets/{index5-Dhi5S4AY.js → index5-D2oq_xzS.js} +1 -1
  38. package/dist-web/assets/{index6-Bt9yqgGH.js → index6-1drcChs1.js} +1 -1
  39. package/dist-web/assets/{index7-CnqGakDF.js → index7-aHTOwsn3.js} +1 -1
  40. package/dist-web/assets/{index8-Dca1sG3X.js → index8-Dirigide.js} +2 -2
  41. package/dist-web/assets/{infoDiagram-5YYISTIA-Cfn6nswp.js → infoDiagram-5YYISTIA-Baaxoh0q.js} +1 -1
  42. package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-BJ-8LuY8.js → ishikawaDiagram-YF4QCWOH-B8gKWcN0.js} +1 -1
  43. package/dist-web/assets/{journeyDiagram-JHISSGLW-D1yaSavm.js → journeyDiagram-JHISSGLW-BFLRc4vu.js} +1 -1
  44. package/dist-web/assets/{kanban-definition-UN3LZRKU-BBFB4HDO.js → kanban-definition-UN3LZRKU-DMx7OMEF.js} +1 -1
  45. package/dist-web/assets/{linear-hHmXIR2Z.js → linear-BEozvq1i.js} +1 -1
  46. package/dist-web/assets/{mermaid.core-VDZ71vKz.js → mermaid.core-WmeW05Ym.js} +66 -66
  47. package/dist-web/assets/{mindmap-definition-RKZ34NQL-RMoWi0xV.js → mindmap-definition-RKZ34NQL-4lvrad5M.js} +1 -1
  48. package/dist-web/assets/{pieDiagram-4H26LBE5-CQ4ZrI1-.js → pieDiagram-4H26LBE5-CMLLNBXh.js} +1 -1
  49. package/dist-web/assets/{quadrantDiagram-W4KKPZXB-Znu_X2s5.js → quadrantDiagram-W4KKPZXB-CqO6IFQw.js} +1 -1
  50. package/dist-web/assets/{requirementDiagram-4Y6WPE33-VSTs_T7S.js → requirementDiagram-4Y6WPE33-BSLBSfd0.js} +1 -1
  51. package/dist-web/assets/{sankeyDiagram-5OEKKPKP-DMQVbj0y.js → sankeyDiagram-5OEKKPKP-Wkno3RO7.js} +1 -1
  52. package/dist-web/assets/{sequenceDiagram-3UESZ5HK-B8CkNeLt.js → sequenceDiagram-3UESZ5HK-BGHwV3az.js} +1 -1
  53. package/dist-web/assets/{stateDiagram-AJRCARHV-Lhe74gFS.js → stateDiagram-AJRCARHV-CCyVLSRK.js} +1 -1
  54. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BiqQXX0_.js +1 -0
  55. package/dist-web/assets/{timeline-definition-PNZ67QCA-BhvuXeeE.js → timeline-definition-PNZ67QCA-CUeXNWjD.js} +1 -1
  56. package/dist-web/assets/{vennDiagram-CIIHVFJN-CSNE2nud.js → vennDiagram-CIIHVFJN-xk-ZH7as.js} +1 -1
  57. package/dist-web/assets/{vue.runtime.esm-bundler-B84GkS0f.js → vue.runtime.esm-bundler-Cka7aKLe.js} +1 -1
  58. package/dist-web/assets/{wardley-L42UT6IY-uLQHoAEc.js → wardley-L42UT6IY-DgiOtIwh.js} +1 -1
  59. package/dist-web/assets/{wardleyDiagram-YWT4CUSO-ChcE1LUX.js → wardleyDiagram-YWT4CUSO-BAVBFC-Y.js} +1 -1
  60. package/dist-web/assets/{xychartDiagram-2RQKCTM6-o26J5Mzy.js → xychartDiagram-2RQKCTM6-C3IYtAxp.js} +1 -1
  61. package/dist-web/design-system.html +813 -704
  62. package/dist-web/index.html +2 -2
  63. package/package.json +6 -6
  64. package/dist-web/assets/channel-Bw3RVCmn.js +0 -1
  65. package/dist-web/assets/classDiagram-4FO5ZUOK-DSr63Xlm.js +0 -1
  66. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-DSr63Xlm.js +0 -1
  67. package/dist-web/assets/index-Bfuo9grI.css +0 -1
  68. package/dist-web/assets/index-_zaDlMUv.js +0 -279
  69. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-C4weiutZ.js +0 -1
@@ -1,15 +1,16 @@
1
1
  <!doctype html>
2
- <html lang="zh-CN">
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Kimi Web · 设计系统</title>
6
+ <title>Kimi Web · Design System</title>
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
10
10
  <style>
11
11
  /* =====================================================================
12
- 文档自身的设计令牌(仅用于这份提案页面的呈现,与产品 token 解耦)
12
+ Document's own design tokens (used only to render this proposal page;
13
+ decoupled from product tokens)
13
14
  ===================================================================== */
14
15
  :root {
15
16
  --d-bg: #ffffff;
@@ -69,7 +70,7 @@
69
70
  white-space: nowrap;
70
71
  }
71
72
 
72
- /* ---------- 布局 ---------- */
73
+ /* ---------- Layout ---------- */
73
74
  .layout { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }
74
75
  .sidebar {
75
76
  position: sticky; top: 0; align-self: start; height: 100vh;
@@ -120,7 +121,7 @@
120
121
  .meta-chip b { color: var(--d-fg); font-weight: 600; }
121
122
  .meta-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--d-green); }
122
123
 
123
- /* ---------- 通用排版 ---------- */
124
+ /* ---------- General typography ---------- */
124
125
  .sec-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 8px; }
125
126
  .sec-num { font-family: "JetBrains Mono", monospace; font-size: 13px; font-weight: 600; color: var(--d-accent-2); }
126
127
  .sec-title { font-size: 26px; letter-spacing: -.02em; }
@@ -129,7 +130,7 @@
129
130
  h3.sub::before { content: ""; width: 4px; height: 16px; border-radius: 2px; background: var(--d-accent); }
130
131
  h4.mini { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--d-fg-muted); margin: 24px 0 12px; }
131
132
 
132
- /* ---------- 统计卡 / 指标 ---------- */
133
+ /* ---------- Stat cards / metrics ---------- */
133
134
  .stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 24px 0; }
134
135
  .stat { background: var(--d-surface); border: 1px solid var(--d-line); border-radius: 14px; padding: 18px 18px 16px; }
135
136
  .stat .v { font-size: 34px; font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--d-fg); }
@@ -142,7 +143,7 @@
142
143
  .stat.good { background: var(--d-green-soft); border-color: #bfe3cc; }
143
144
  .stat.good .v { color: var(--d-green); }
144
145
 
145
- /* ---------- 卡片 / 面板 ---------- */
146
+ /* ---------- Cards / panels ---------- */
146
147
  .panel { background: var(--d-bg); border: 1px solid var(--d-line); border-radius: 16px; box-shadow: var(--d-shadow-sm); }
147
148
  .panel-pad { padding: 22px; }
148
149
  .panel-soft { background: var(--d-surface); border: 1px solid var(--d-line); border-radius: 14px; }
@@ -158,7 +159,7 @@
158
159
  .callout.good { background: var(--d-green-soft); border-color: #bfe3cc; }
159
160
  .callout.good .ico { background: var(--d-green); color: #fff; }
160
161
 
161
- /* ---------- 表格 ---------- */
162
+ /* ---------- Tables ---------- */
162
163
  table.dt { width: 100%; border-collapse: collapse; font-size: 13.5px; margin: 16px 0; }
163
164
  table.dt th { text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--d-fg-faint); font-weight: 700; padding: 10px 12px; border-bottom: 1px solid var(--d-line); }
164
165
  table.dt td { padding: 11px 12px; border-bottom: 1px solid var(--d-line-2); color: var(--d-fg-soft); vertical-align: middle; }
@@ -167,7 +168,7 @@
167
168
  table.dt td.val { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--d-fg-muted); }
168
169
  .swatch { display: inline-block; width: 16px; height: 16px; border-radius: 4px; border: 1px solid rgba(0,0,0,.08); vertical-align: -3px; margin-right: 8px; }
169
170
 
170
- /* ---------- 色板 ---------- */
171
+ /* ---------- Color swatches ---------- */
171
172
  .palette { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 16px 0; }
172
173
  .color-card { border: 1px solid var(--d-line); border-radius: 12px; overflow: hidden; background: var(--d-bg); }
173
174
  .color-chip { height: 56px; border-bottom: 1px solid var(--d-line); }
@@ -175,13 +176,13 @@
175
176
  .color-meta .cn { font-size: 13px; font-weight: 600; color: var(--d-fg); }
176
177
  .color-meta .cv { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--d-fg-muted); margin-top: 2px; }
177
178
 
178
- /* ---------- 字号阶梯 ---------- */
179
+ /* ---------- Type scale ---------- */
179
180
  .type-row { display: flex; align-items: baseline; gap: 18px; padding: 13px 0; border-bottom: 1px solid var(--d-line-2); }
180
181
  .type-row:last-child { border-bottom: none; }
181
182
  .type-sample { flex: 1; color: var(--d-fg); line-height: 1.2; }
182
183
  .type-meta { width: 190px; flex: none; text-align: right; font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--d-fg-muted); }
183
184
 
184
- /* ---------- 间距 / 半径 ---------- */
185
+ /* ---------- Spacing / radius ---------- */
185
186
  .space-row { display: flex; align-items: center; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--d-line-2); }
186
187
  .space-row:last-child { border-bottom: none; }
187
188
  .space-bar { height: 18px; border-radius: 4px; background: linear-gradient(90deg, var(--d-accent), var(--d-accent-2)); flex: none; }
@@ -192,7 +193,7 @@
192
193
  .radius-box { width: 64px; height: 64px; border: 2px solid var(--d-accent); background: var(--d-accent-soft); }
193
194
  .radius-item .rl { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--d-fg-soft); }
194
195
 
195
- /* ---------- 组件舞台 ---------- */
196
+ /* ---------- Component stage ---------- */
196
197
  .stage-wrap { border: 1px solid var(--d-line); border-radius: 16px; overflow: hidden; margin: 18px 0; background: var(--d-bg); box-shadow: var(--d-shadow-sm); }
197
198
  .stage-bar { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--d-line); background: var(--d-surface); }
198
199
  .stage-bar .st { font-size: 13px; font-weight: 600; color: var(--d-fg); display: flex; align-items: center; gap: 8px; }
@@ -232,7 +233,7 @@
232
233
  .ba-body { padding: 24px; background: var(--d-surface); min-height: 120px; }
233
234
  .ba-col.after .ba-body { background: #fff; }
234
235
 
235
- /* ---------- 代码块 ---------- */
236
+ /* ---------- Code block ---------- */
236
237
  .code { background: #0d1117; border-radius: 12px; overflow: hidden; margin: 16px 0; border: 1px solid #1c2128; }
237
238
  .code-bar { display: flex; align-items: center; gap: 8px; padding: 9px 14px; background: #161b22; border-bottom: 1px solid #1c2128; }
238
239
  .code-bar .d { width: 10px; height: 10px; border-radius: 50%; background: #30363d; }
@@ -245,7 +246,7 @@
245
246
  .code .n { color: #d2a8ff; }
246
247
  .code .v { color: #ffa657; }
247
248
 
248
- /* ---------- 标签 / pill(文档用) ---------- */
249
+ /* ---------- Tag / pill (document use) ---------- */
249
250
  .pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--d-line); background: var(--d-surface); color: var(--d-fg-soft); }
250
251
  .pill.blue { background: var(--d-accent-soft); border-color: var(--d-accent-bd); color: var(--d-accent-2); }
251
252
  .pill.green { background: var(--d-green-soft); border-color: #bfe3cc; color: var(--d-green); }
@@ -253,7 +254,7 @@
253
254
  .pill.red { background: var(--d-red-soft); border-color: #f0cccc; color: var(--d-red); }
254
255
  .pill.mono { font-family: "JetBrains Mono", monospace; }
255
256
 
256
- /* ---------- 列表 ---------- */
257
+ /* ---------- Lists ---------- */
257
258
  ul.clean { list-style: none; padding: 0; margin: 14px 0; }
258
259
  ul.clean li { position: relative; padding: 8px 0 8px 26px; color: var(--d-fg-soft); border-bottom: 1px solid var(--d-line-2); }
259
260
  ul.clean li:last-child { border-bottom: none; }
@@ -263,7 +264,7 @@
263
264
  ul.clean li b { color: var(--d-fg); }
264
265
  ul.clean li .path { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--d-fg-muted); }
265
266
 
266
- /* ---------- 时间线 / 迁移计划 ---------- */
267
+ /* ---------- Timeline / migration plan ---------- */
267
268
  .roadmap { position: relative; margin: 24px 0; }
268
269
  .phase { position: relative; display: grid; grid-template-columns: 120px 1fr; gap: 24px; padding: 0 0 32px; }
269
270
  .phase:not(:last-child)::after { content: ""; position: absolute; left: 59px; top: 36px; bottom: 0; width: 2px; background: var(--d-line); }
@@ -275,7 +276,7 @@
275
276
  .phase-body p { font-size: 14px; margin-bottom: 12px; }
276
277
  .phase-body ul { margin: 0; }
277
278
 
278
- /* ---------- 反模式矩阵 ---------- */
279
+ /* ---------- Anti-pattern matrix ---------- */
279
280
  .matrix { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 16px 0; }
280
281
  .anti { border: 1px solid var(--d-line); border-radius: 12px; padding: 16px; background: var(--d-bg); }
281
282
  .anti .ah { display: flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 700; margin-bottom: 8px; }
@@ -285,7 +286,7 @@
285
286
  .verdict.warn { background: var(--d-amber-soft); color: var(--d-amber); }
286
287
  .anti p { font-size: 13px; margin: 0; color: var(--d-fg-muted); }
287
288
 
288
- /* ---------- 脚注 ---------- */
289
+ /* ---------- Footnote ---------- */
289
290
  .footer { margin-top: 80px; padding-top: 28px; border-top: 1px solid var(--d-line); font-size: 13px; color: var(--d-fg-faint); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
290
291
  .kbd { font-family: "JetBrains Mono", monospace; font-size: 11px; background: var(--d-surface-2); border: 1px solid var(--d-line); border-bottom-width: 2px; border-radius: 5px; padding: 1px 6px; }
291
292
 
@@ -305,10 +306,10 @@
305
306
  <body>
306
307
 
307
308
  <!-- =====================================================================
308
- 提案设计系统:组件预览所使用的统一 token 与组件样式
309
+ Proposed design system: unified tokens and component styles used by the component previews
309
310
  ===================================================================== -->
310
311
  <style>
311
- /* ---- 提案 token:默认 = modern / light ---- */
312
+ /* ---- Proposal tokens: default = modern / light ---- */
312
313
  .p, .stage.p-skin, [data-p] {
313
314
  --p-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans SC", Roboto, Ubuntu, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
314
315
  --p-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
@@ -347,13 +348,13 @@
347
348
  --p-ic-sm: 14px; --p-ic-md: 16px; --p-ic-lg: 20px;
348
349
  --p-selection: rgba(23,131,255,.18);
349
350
  --p-sidebar-w: 264px;
350
- --p-content-max: 760px; /* 聊天阅读栏 */
351
- --p-content-wide: 920px; /* 宽内容 */
352
- --p-bp-sm: 640px; /* 手机 / 桌面分界 */
353
- --p-bp-md: 980px; /* 窄屏 / 宽屏分界 */
351
+ --p-content-max: 760px; /* chat reading column */
352
+ --p-content-wide: 920px; /* wide content */
353
+ --p-bp-sm: 640px; /* mobile / desktop boundary */
354
+ --p-bp-md: 980px; /* narrow / wide screen boundary */
354
355
  font-family: var(--p-font-sans); color: var(--p-text); font-size: var(--p-font-size-base);
355
356
  }
356
- /* ---- 暗色皮肤覆盖 ---- */
357
+ /* ---- Dark skin overrides ---- */
357
358
  [data-p="dark"] {
358
359
  --p-bg: #0d1117; --p-surface: #161b22; --p-surface-raised: #1c2128; --p-surface-sunken: #0d1117;
359
360
  --p-text: #c9cdd4; --p-text-muted: #9aa0a8; --p-text-faint: #6b7280;
@@ -366,11 +367,12 @@
366
367
  --p-selection: rgba(88,166,255,.32);
367
368
  }
368
369
 
369
- /* 全局图标基线:所有 .p-ic SVG 默认 16×16,避免无上下文时撑满容器。
370
- 各组件上下文(.p-btn/.p-badge/.p-pill 等)会按需覆盖尺寸。 */
370
+ /* Global icon baseline: all .p-ic SVGs default to 16×16 to avoid filling the
371
+ container when no context sets a size. Each component context
372
+ (.p-btn/.p-badge/.p-pill, etc.) overrides the size as needed. */
371
373
  .p-ic { width: 16px; height: 16px; flex: none; display: inline-block; vertical-align: middle; }
372
374
 
373
- /* ===== 按钮 Button ===== */
375
+ /* ===== Button ===== */
374
376
  .p-btn {
375
377
  --_h: 36px; --_px: 16px; --_fs: var(--p-font-size-base); --_r: var(--p-r-md);
376
378
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
@@ -410,7 +412,7 @@
410
412
  .p-icon-btn .p-ic { width: 16px; height: 16px; }
411
413
  .p-icon-btn.lg .p-ic { width: 20px; height: 20px; }
412
414
 
413
- /* ===== 徽标 / 芯片 Badge / Chip / Pill ===== */
415
+ /* ===== Badge / Chip / Pill ===== */
414
416
  .p-badge {
415
417
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 9px;
416
418
  border-radius: var(--p-r-full); font-family: var(--p-font-sans); font-size: var(--p-font-size-xs); font-weight: 600; line-height: 1;
@@ -426,7 +428,7 @@
426
428
  .p-badge.solid { background: var(--p-text); color: var(--p-bg); border-color: var(--p-text); }
427
429
  .p-badge .p-ic { width: 12px; height: 12px; }
428
430
 
429
- /* model / mode pill(composer 工具条) */
431
+ /* model / mode pill (composer toolbar) */
430
432
  .p-pill {
431
433
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
432
434
  border-radius: var(--p-r-md); border: 1px solid transparent; background: transparent;
@@ -438,9 +440,10 @@
438
440
  .p-pill .pp-sub { color: var(--p-accent); font-weight: 600; }
439
441
  .p-pill .p-ic { width: 14px; height: 14px; color: var(--p-text-faint); }
440
442
 
441
- /* ===== 卡片 / 表面 Card / Surface ===== */
442
- /* 统一卡片外壳:扁平、1px 描边、radius-md,无阴影。所有卡片共用此外壳;
443
- 区别只在头部 —— 操作卡头部紧凑 mono、无底色;注意卡头部带语义色带。 */
443
+ /* ===== Card / Surface ===== */
444
+ /* Unified card shell: flat, 1px border, radius-md, no shadow. All cards share this
445
+ shell; they differ only in the head — action cards have a compact mono head with no
446
+ fill; note cards have a semantic color band in the head. */
444
447
  .p-card {
445
448
  background: var(--p-surface); border: 1px solid var(--p-line); border-radius: var(--p-r-md);
446
449
  overflow: hidden; color: var(--p-text);
@@ -452,7 +455,7 @@
452
455
  .p-card-body { padding: 14px; font-size: var(--p-font-size-base); color: var(--p-text); line-height: var(--p-leading-normal); }
453
456
  .p-card-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--p-line); background: var(--p-surface); }
454
457
 
455
- /* ===== 表单 Input / Select / Textarea ===== */
458
+ /* ===== Form Input / Select / Textarea ===== */
456
459
  .p-field { display: flex; flex-direction: column; gap: 6px; }
457
460
  .p-label { font-size: var(--p-font-size-sm); font-weight: 600; color: var(--p-text); }
458
461
  .p-input, .p-select, .p-textarea {
@@ -468,7 +471,7 @@
468
471
  .p-input.sm { height: 32px; font-size: var(--p-font-size-sm); border-radius: var(--p-r-sm); }
469
472
  .p-hint { font-size: var(--p-font-size-xs); color: var(--p-text-faint); }
470
473
 
471
- /* ===== 弹窗 Dialog ===== */
474
+ /* ===== Dialog ===== */
472
475
  .p-dialog {
473
476
  width: 480px; max-width: calc(100vw - 48px); background: var(--p-surface-raised); border: 1px solid var(--p-line);
474
477
  border-radius: var(--p-r-xl); box-shadow: var(--p-sh-xl); overflow: hidden; color: var(--p-text);
@@ -479,7 +482,7 @@
479
482
  .p-dialog-body { padding: 4px 22px 18px; }
480
483
  .p-dialog-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 22px 20px; }
481
484
 
482
- /* ===== 轻提示 Toast ===== */
485
+ /* ===== Toast ===== */
483
486
  .p-toast {
484
487
  display: flex; align-items: flex-start; gap: 11px; width: 360px; padding: 13px 14px;
485
488
  background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-lg); box-shadow: var(--p-sh-md);
@@ -490,7 +493,7 @@
490
493
  .p-toast .tt { font-size: var(--p-font-size-base); font-weight: 600; color: var(--p-text); }
491
494
  .p-toast .td { font-size: var(--p-font-size-sm); color: var(--p-text-muted); margin-top: 2px; line-height: 1.45; }
492
495
 
493
- /* ===== 加载 Spinner(普通 SVG 环形,默认加载器) ===== */
496
+ /* ===== Spinner (plain SVG ring, the default loader) ===== */
494
497
  .p-spinner { width: 18px; height: 18px; animation: p-spin 0.85s linear infinite; }
495
498
  .p-spinner.sm { width: 14px; height: 14px; }
496
499
  .p-spinner circle { fill: none; stroke-width: 2.2; stroke-linecap: round; }
@@ -499,7 +502,7 @@
499
502
  @keyframes p-spin { to { transform: rotate(360deg); } }
500
503
  .p-thinking { display: inline-flex; align-items: center; gap: 9px; font-size: var(--p-font-size-sm); color: var(--p-text-muted); font-family: var(--p-font-sans); }
501
504
 
502
- /* ===== 聊天:用户气泡 ===== */
505
+ /* ===== Chat: user bubble ===== */
503
506
  .p-bubble-user {
504
507
  align-self: flex-end; max-width: 78%; background: var(--p-accent-soft); border: 1px solid var(--p-accent-bd);
505
508
  color: var(--p-text); border-radius: 18px 18px 5px 18px; padding: 11px 15px;
@@ -509,7 +512,7 @@
509
512
  .p-msg p { margin: 0 0 10px; color: var(--p-text); }
510
513
  .p-msg code { font-family: var(--p-font-mono); background: var(--p-surface-sunken); border: 1px solid var(--p-line); color: var(--p-accent-hover); padding: 1px 6px; border-radius: 5px; font-size: .9em; }
511
514
 
512
- /* ===== 聊天:Agent 卡 ===== */
515
+ /* ===== Chat: Agent card ===== */
513
516
  .p-agent { background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-md); overflow: hidden; }
514
517
  .p-agent-head { display: flex; align-items: center; gap: 10px; padding: 11px 14px; }
515
518
  .p-agent-av { width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; background: var(--p-surface-sunken); border: 1px solid var(--p-line); color: var(--p-text-muted); flex: none; }
@@ -517,7 +520,7 @@
517
520
  .p-agent-phase { font-size: var(--p-font-size-xs); color: var(--p-text-muted); }
518
521
  .p-agent-body { padding: 0 14px 13px; }
519
522
 
520
- /* ===== 聊天:工具调用卡 ===== */
523
+ /* ===== Chat: tool call card ===== */
521
524
  .p-tool { background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-md); overflow: hidden; }
522
525
  .p-tool-head { display: flex; align-items: center; gap: 9px; padding: 9px 13px; background: var(--p-surface); border-bottom: 1px solid var(--p-line); }
523
526
  .p-tool-ic { width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center; background: var(--p-accent-soft); color: var(--p-accent); flex: none; }
@@ -525,7 +528,7 @@
525
528
  .p-tool-body { padding: 12px 13px; }
526
529
  .p-code { font-family: var(--p-font-mono); font-size: var(--p-font-size-sm); line-height: 1.65; background: var(--p-surface-sunken); border: 1px solid var(--p-line); border-radius: var(--p-r-md); padding: 11px 13px; color: var(--p-text); overflow-x: auto; }
527
530
 
528
- /* ===== 聊天:提问 / 审批 卡 ===== */
531
+ /* ===== Chat: question / approval card ===== */
529
532
  .p-action { border-radius: var(--p-r-md); overflow: hidden; border: 1px solid var(--p-accent-bd); background: var(--p-surface); }
530
533
  .p-action.warn { border-color: var(--p-warning-bd); }
531
534
  .p-action-head { display: flex; align-items: center; gap: 9px; padding: 10px 14px; background: var(--p-accent-soft); border-bottom: 1px solid var(--p-accent-bd); }
@@ -535,7 +538,7 @@
535
538
  .p-action-body { padding: 14px; font-size: var(--p-font-size-base); color: var(--p-text); line-height: var(--p-leading-normal); }
536
539
  .p-action-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 11px 14px; border-top: 1px solid var(--p-line); background: var(--p-surface); }
537
540
 
538
- /* ===== 聊天:Todo 卡 ===== */
541
+ /* ===== Chat: Todo card ===== */
539
542
  .p-todo { background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-md); padding: 6px; }
540
543
  .p-todo-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--p-r-md); font-size: var(--p-font-size-base); color: var(--p-text); }
541
544
  .p-todo-row.done { color: var(--p-text-faint); text-decoration: line-through; }
@@ -544,15 +547,16 @@
544
547
  .p-todo-row.done .p-todo-check { color: var(--p-success); }
545
548
  .p-todo-row.active .p-todo-check { color: var(--p-accent); font-weight: 500; }
546
549
 
547
- /* ===== 聊天:紧凑工具调用(read_file / bash / grep 等高频低权重调用) ===== */
548
- /* 状态点 */
550
+ /* ===== Chat: compact tool calls (high-frequency, low-weight calls such as read_file / bash / grep) ===== */
551
+ /* Status dot */
549
552
  .p-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--p-text-faint); }
550
553
  .p-dot.done { background: var(--p-success); }
551
554
  .p-dot.error { background: var(--p-danger); }
552
555
  .p-dot.running { background: var(--p-accent); box-shadow: 0 0 0 0 var(--p-accent-soft); animation: p-pulse 1.4s ease-out infinite; }
553
556
  @keyframes p-pulse { 0% { box-shadow: 0 0 0 0 rgba(23,131,255,.4); } 100% { box-shadow: 0 0 0 6px rgba(23,131,255,0); } }
554
557
 
555
- /* 工具调用组:把连续 / 并行的多次调用收成一叠,整体视觉权重远低于卡片 */
558
+ /* Tool call group: collapses a run of consecutive / parallel calls into a stack;
559
+ overall visual weight is much lower than a card. */
556
560
  .p-tool-group { border: 1px solid var(--p-line); border-radius: var(--p-r-md); background: var(--p-surface); overflow: hidden; }
557
561
  .p-tool-group-head { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 11px; cursor: pointer; font-size: var(--p-font-size-sm); color: var(--p-text-muted); user-select: none; }
558
562
  .p-tool-group-head:hover { background: var(--p-surface-sunken); color: var(--p-text); }
@@ -561,7 +565,7 @@
561
565
  .p-tool-group-head .tg-car { margin-left: auto; width: 14px; height: 14px; color: var(--p-text-faint); transition: transform var(--p-dur) var(--p-ease); }
562
566
  .p-tool-group.open .p-tool-group-head .tg-car { transform: rotate(90deg); }
563
567
 
564
- /* 单行工具调用:默认紧凑态,一行搞定 */
568
+ /* Single-line tool call: compact by default, fits on one line */
565
569
  .p-tool-row { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 11px; border-top: 1px solid var(--p-line-2, var(--p-line)); cursor: pointer; font-family: var(--p-font-mono); font-size: var(--p-font-size-sm); color: var(--p-text); }
566
570
  .p-tool-row:hover { background: var(--p-surface-sunken); }
567
571
  .p-tool-row .tr-ic { width: 14px; height: 14px; color: var(--p-text-faint); flex: none; }
@@ -572,11 +576,11 @@
572
576
  .p-tool-row.expanded { background: var(--p-surface-sunken); }
573
577
  .p-tool-row.expanded .tr-car { transform: rotate(90deg); }
574
578
 
575
- /* 单行展开后的细节(代码 / 输出) */
579
+ /* Detail after a row is expanded (code / output) */
576
580
  .p-tool-detail { padding: 0 11px 11px 36px; background: var(--p-surface-sunken); border-top: 1px solid var(--p-line); }
577
581
  .p-tool-detail .p-code { margin-top: 10px; }
578
582
 
579
- /* ===== 聊天:Composer ===== */
583
+ /* ===== Chat: Composer ===== */
580
584
  .p-composer { background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-xl); box-shadow: var(--p-sh-md); overflow: hidden; }
581
585
  .p-composer:focus-within { border-color: var(--p-accent); box-shadow: var(--p-sh-md), 0 0 0 3px var(--p-accent-soft); }
582
586
  .p-composer-ta { padding: 14px 16px 8px; font-family: var(--p-font-sans); font-size: var(--p-font-size-md); color: var(--p-text); line-height: var(--p-leading-normal); }
@@ -588,10 +592,10 @@
588
592
  .p-send:active { transform: scale(.92); }
589
593
  .p-send .p-ic { width: 16px; height: 16px; }
590
594
 
591
- /* ===== 选中文本 Selection ===== */
595
+ /* ===== Text selection ===== */
592
596
  .p ::selection, [data-p] ::selection { background: var(--p-selection); }
593
597
 
594
- /* ===== 文字链接 Link ===== */
598
+ /* ===== Text link ===== */
595
599
  .p-link {
596
600
  color: var(--p-accent); text-decoration: none; font-family: var(--p-font-sans);
597
601
  transition: color var(--p-dur) var(--p-ease);
@@ -602,7 +606,7 @@
602
606
  .p-link.muted:hover { color: var(--p-text); }
603
607
  .p-link .p-ic { width: var(--p-ic-sm); height: var(--p-ic-sm); vertical-align: -2px; }
604
608
 
605
- /* ===== 菜单 / 下拉 Menu · Dropdown ===== */
609
+ /* ===== Menu / Dropdown ===== */
606
610
  .p-menu {
607
611
  background: var(--p-surface-raised); border: 1px solid var(--p-line);
608
612
  border-radius: var(--p-r-lg); box-shadow: var(--p-sh-sm);
@@ -625,7 +629,7 @@
625
629
  .p-menu-item.lg { min-height: 44px; padding: 12px 14px; font-size: var(--p-font-size-base); }
626
630
  .p-menu-sep { height: 1px; background: var(--p-line); margin: 4px 0; }
627
631
 
628
- /* ===== 分段控件 SegmentedControl ===== */
632
+ /* ===== SegmentedControl ===== */
629
633
  .p-seg {
630
634
  display: inline-flex; gap: 2px; padding: 2px;
631
635
  background: var(--p-surface-sunken); border: 1px solid var(--p-line);
@@ -639,7 +643,7 @@
639
643
  .p-seg-item:hover { color: var(--p-text); }
640
644
  .p-seg-item.on { background: var(--p-surface-raised); color: var(--p-text); box-shadow: var(--p-sh-xs); }
641
645
 
642
- /* ===== 标签页 Tabs ===== */
646
+ /* ===== Tabs ===== */
643
647
  .p-tabs {
644
648
  display: flex; align-items: center; gap: 0;
645
649
  border-bottom: 1px solid var(--p-line); font-family: var(--p-font-sans);
@@ -653,7 +657,7 @@
653
657
  .p-tab:hover { color: var(--p-text); }
654
658
  .p-tab.on { color: var(--p-accent); border-bottom-color: var(--p-accent); }
655
659
 
656
- /* ===== 开关 Switch ===== */
660
+ /* ===== Switch ===== */
657
661
  .p-switch {
658
662
  position: relative; display: inline-block; width: 36px; height: 20px; flex: none;
659
663
  border-radius: var(--p-r-full); background: var(--p-line-strong);
@@ -669,7 +673,7 @@
669
673
  .p-switch.on::after { transform: translateX(16px); }
670
674
  .p-switch:focus-visible { outline: none; box-shadow: var(--p-focus-ring); }
671
675
 
672
- /* ===== 复选框 Checkbox ===== */
676
+ /* ===== Checkbox ===== */
673
677
  .p-check {
674
678
  width: 17px; height: 17px; flex: none; display: inline-grid; place-items: center;
675
679
  border: 1.5px solid var(--p-line-strong); border-radius: var(--p-r-sm);
@@ -680,7 +684,7 @@
680
684
  .p-check:focus-visible { outline: none; box-shadow: var(--p-focus-ring); }
681
685
  .p-check .p-ic { width: 12px; height: 12px; }
682
686
 
683
- /* ===== 头像 Avatar ===== */
687
+ /* ===== Avatar ===== */
684
688
  .p-avatar {
685
689
  width: 32px; height: 32px; flex: none; display: grid; place-items: center;
686
690
  border-radius: var(--p-r-md); background: var(--p-surface-sunken);
@@ -691,7 +695,7 @@
691
695
  .p-avatar .p-ic { width: 16px; height: 16px; }
692
696
  .p-avatar.sm .p-ic { width: 13px; height: 13px; }
693
697
 
694
- /* ===== 空状态 EmptyState ===== */
698
+ /* ===== EmptyState ===== */
695
699
  .p-empty {
696
700
  display: flex; flex-direction: column; align-items: center; gap: 8px;
697
701
  padding: 32px 16px; color: var(--p-text-muted); text-align: center;
@@ -700,11 +704,11 @@
700
704
  .p-empty .em-title { font-size: var(--p-font-size-base); font-weight: 600; color: var(--p-text); }
701
705
  .p-empty .em-hint { font-size: var(--p-font-size-sm); color: var(--p-text-muted); }
702
706
 
703
- /* ===== 分隔线 Divider ===== */
707
+ /* ===== Divider ===== */
704
708
  .p-divider { width: 100%; height: 1px; background: var(--p-line); border: none; }
705
709
  .p-divider-v { width: 1px; align-self: stretch; background: var(--p-line); border: none; }
706
710
 
707
- /* ===== 工具提示 Tooltip ===== */
711
+ /* ===== Tooltip ===== */
708
712
  .p-tip { position: relative; display: inline-flex; }
709
713
  .p-tip .p-tooltip {
710
714
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
@@ -714,7 +718,7 @@
714
718
  }
715
719
  .p-tip:hover .p-tooltip { opacity: 1; }
716
720
 
717
- /* ===== 横幅通知 Banner ===== */
721
+ /* ===== Banner ===== */
718
722
  .p-banner {
719
723
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
720
724
  border-radius: var(--p-r-md); border: 1px solid var(--p-line);
@@ -728,7 +732,7 @@
728
732
  .p-banner.danger { background: var(--p-danger-soft); border-color: var(--p-danger-bd); }
729
733
  .p-banner.danger .bn-ic { color: var(--p-danger); }
730
734
 
731
- /* ===== 底部面板 Sheet / BottomSheet ===== */
735
+ /* ===== Sheet / BottomSheet ===== */
732
736
  .p-sheet {
733
737
  background: var(--p-surface-raised); border: 1px solid var(--p-line);
734
738
  border-radius: var(--p-r-xl) var(--p-r-xl) 0 0; box-shadow: var(--p-sh-xl);
@@ -739,14 +743,14 @@
739
743
  background: var(--p-line-strong); margin: 0 auto 8px;
740
744
  }
741
745
 
742
- /* ===== 骨架屏 Skeleton ===== */
746
+ /* ===== Skeleton ===== */
743
747
  .p-skeleton {
744
748
  background: var(--p-surface-sunken); border-radius: var(--p-r-sm);
745
749
  animation: p-skel 1.2s var(--p-ease-inout) infinite alternate;
746
750
  }
747
751
  @keyframes p-skel { from { opacity: .5; } to { opacity: 1; } }
748
752
 
749
- /* ===== 命令 + 复制条 Command Bar ===== */
753
+ /* ===== Command Bar ===== */
750
754
  .p-cmdbar { display: flex; align-items: center; gap: 8px; width: 100%; }
751
755
  .p-cmd { flex: 1; min-width: 0; height: 38px; display: flex; align-items: center; gap: 10px; padding: 0 10px 0 14px; background: var(--p-surface-sunken); border: 1px solid var(--p-line); border-radius: var(--p-r-md); font-family: var(--p-font-mono); font-size: var(--p-font-size-sm); color: var(--p-text-muted); }
752
756
  .p-cmd .cmd-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -754,25 +758,26 @@
754
758
  .p-cmd .cmd-copy:hover { background: var(--p-surface-raised); color: var(--p-text); }
755
759
  .p-cmd .cmd-copy .p-ic { width: 15px; height: 15px; }
756
760
 
757
- /* ===== 顶部栏 TopBar ===== */
761
+ /* ===== TopBar ===== */
758
762
  .p-topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 48px; padding: 0 16px; background: var(--p-surface-raised); border: 1px solid var(--p-line); border-radius: var(--p-r-lg); }
759
763
  .p-topbar .tb-title { font-size: var(--p-font-size-sm); font-weight: 600; color: var(--p-text); }
760
764
  .p-topbar .tb-actions { display: flex; align-items: center; gap: 4px; }
761
765
  .p-topbar.frost { background: rgba(255,255,255,.72); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-color: rgba(255,255,255,.6); }
762
766
  [data-p="dark"] .p-topbar.frost { background: rgba(22,27,34,.72); border-color: rgba(255,255,255,.08); }
763
767
 
764
- /* 色系切换演示:把 accent 一组 token 覆盖为中性黑,演示「黑色系」。
765
- 真实切换由主题层统一下发,组件无需感知。 */
768
+ /* Color-family demo: override the accent token set to neutral black to demo the
769
+ "black" family. Real switching is handled uniformly by the theme layer; components
770
+ do not need to be aware of it. */
766
771
  .demo-family-black { --p-accent: #14171c; --p-accent-hover: #2f3540; --p-accent-soft: #f1f2f4; --p-accent-bd: #d8dbe0; --p-text-on-accent: #ffffff; }
767
772
 
768
- /* 小工具:demo 行 */
773
+ /* Utility: demo rows */
769
774
  .demo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
770
775
  .demo-stack { display: flex; flex-direction: column; gap: 12px; width: 100%; }
771
776
  .demo-col { display: flex; flex-direction: column; gap: 10px; }
772
777
  .demo-grow { flex: 1; min-width: 0; }
773
778
  .demo-chat { display: flex; flex-direction: column; gap: 14px; width: 100%; max-width: 560px; }
774
779
 
775
- /* 图标目录(§02 Icon library) */
780
+ /* Icon catalog (§02 Icon library) */
776
781
  .icon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 8px; margin: 14px 0; }
777
782
  .icon-group-label { grid-column: 1 / -1; margin-top: 10px; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--d-fg-muted); }
778
783
  .icon-cell { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--d-line); border-radius: 8px; background: var(--d-surface); }
@@ -781,7 +786,7 @@
781
786
  .icon-sizes { display: flex; align-items: end; gap: 22px; flex-wrap: wrap; }
782
787
  .icon-sizes .sz { display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 11px; color: var(--d-fg-muted); font-family: "JetBrains Mono", ui-monospace, monospace; }
783
788
 
784
- /* ===== 代码 / 差异 Code / Diff ===== */
789
+ /* ===== Code / Diff ===== */
785
790
  .p-code-inline { font-family: var(--p-font-mono); background: var(--p-surface-sunken); color: var(--p-text); padding: 0 5px; border-radius: var(--p-r-sm); font-size: .9em; }
786
791
  .p-code-block { border: 1px solid var(--p-line); border-radius: var(--p-r-md); overflow: hidden; background: var(--p-surface-sunken); }
787
792
  .p-code-block-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; background: var(--p-surface); border-bottom: 1px solid var(--p-line); font-family: var(--p-font-mono); font-size: var(--p-font-size-xs); color: var(--p-text-muted); }
@@ -796,16 +801,17 @@
796
801
  .p-diff-row.del .pm { color: var(--p-danger); }
797
802
  .p-diff-row .p-diff-code { color: var(--p-text); }
798
803
 
799
- /* ===== 表单错误提示 Field error ===== */
804
+ /* ===== Field error ===== */
800
805
  .p-field-error { color: var(--p-danger); font-size: var(--p-font-size-xs); }
801
806
 
802
- /* 按钮内嵌 spinner:跟随文字色,保证在 accent 底上可见(无需硬编码颜色) */
807
+ /* Inline spinner inside a button: follows the text color so it stays visible on an
808
+ accent background (no hard-coded color needed). */
803
809
  .p-btn .p-spinner { vertical-align: middle; }
804
810
  .p-btn .p-spinner .track { stroke: currentColor; opacity: .35; }
805
811
  .p-btn .p-spinner .arc { stroke: currentColor; }
806
812
  </style>
807
813
  <div class="layout">
808
- <!-- ===================== 侧边导航 ===================== -->
814
+ <!-- ===================== Side navigation ===================== -->
809
815
  <aside class="sidebar">
810
816
  <div class="brand">
811
817
  <div class="brand-mark">K</div>
@@ -813,27 +819,28 @@
813
819
  </div>
814
820
  <div class="brand-sub">Design System · v1.0</div>
815
821
 
816
- <div class="nav-group">导览</div>
822
+ <div class="nav-group">Navigate</div>
817
823
  <nav class="nav" id="nav">
818
- <a href="#overview"><span class="num">00</span>总览</a>
819
- <a href="#principles"><span class="num">01</span>设计原则</a>
820
- <a href="#tokens"><span class="num">02</span>设计令牌</a>
821
- <a href="#primitives"><span class="num">03</span>组件基元</a>
822
- <a href="#chat"><span class="num">04</span>聊天界面</a>
823
- <a href="#themes"><span class="num">05</span>主题系统</a>
824
- <a href="#rules"><span class="num">06</span>样式规则</a>
825
- <a href="#shell"><span class="num">07</span>应用壳与侧栏</a>
824
+ <a href="#overview"><span class="num">00</span>Overview</a>
825
+ <a href="#principles"><span class="num">01</span>Design Principles</a>
826
+ <a href="#tokens"><span class="num">02</span>Design Tokens</a>
827
+ <a href="#primitives"><span class="num">03</span>Primitives</a>
828
+ <a href="#chat"><span class="num">04</span>Chat Interface</a>
829
+ <a href="#themes"><span class="num">05</span>Theming</a>
830
+ <a href="#rules"><span class="num">06</span>Style Rules</a>
831
+ <a href="#shell"><span class="num">07</span>App Shell &amp; Sidebar</a>
832
+ <a href="#a11y"><span class="num">08</span>Accessibility</a>
826
833
  </nav>
827
834
 
828
- <div class="nav-group">配套产出</div>
835
+ <div class="nav-group">Companion output</div>
829
836
  <nav class="nav">
830
- <a href="#tokens"><span class="num">↗</span>Token 清单</a>
831
- <a href="#primitives"><span class="num">↗</span>组件 API</a>
832
- <a href="#rules"><span class="num">↗</span>样式规则</a>
837
+ <a href="#tokens"><span class="num">↗</span>Token list</a>
838
+ <a href="#primitives"><span class="num">↗</span>Component API</a>
839
+ <a href="#rules"><span class="num">↗</span>Style rules</a>
833
840
  </nav>
834
841
  </aside>
835
842
 
836
- <!-- ===================== 主内容 ===================== -->
843
+ <!-- ===================== Main content ===================== -->
837
844
  <main class="content">
838
845
  <div class="content-inner">
839
846
 
@@ -841,76 +848,80 @@
841
848
  <section id="overview">
842
849
  <div class="hero">
843
850
  <span class="eyebrow">● Design System · v1.0</span>
844
- <h1>Kimi Web <span class="grad">设计系统</span></h1>
851
+ <h1>Kimi Web <span class="grad">Design System</span></h1>
845
852
  <p class="lead">
846
- 本文定义 Kimi Web 的视觉语言与组件规范——设计令牌、组件基元、聊天界面、主题系统与样式规则。
847
- 所有 UI 工作以此为基准:统一、克制、token 驱动、可主题化。
853
+ This document defines the visual language and component specification for Kimi Web — design tokens, component primitives, the chat interface, theming, and style rules.
854
+ All UI work is grounded in it: unified, restrained, token-driven, and themeable.
848
855
  </p>
849
856
  <div class="hero-meta">
850
- <span class="meta-chip"><span class="dot"></span> 范围 <b>apps/kimi-web</b></span>
851
- <span class="meta-chip">组件基元</span>
852
- <span class="meta-chip">主题 <b>1 套 · 4 色可定制</b></span>
853
- <span class="meta-chip">亮 / 暗模式</span>
857
+ <span class="meta-chip"><span class="dot"></span> Scope <b>apps/kimi-web</b></span>
858
+ <span class="meta-chip">Component primitives</span>
859
+ <span class="meta-chip">Theme <b>1 set · 4 customizable colors</b></span>
860
+ <span class="meta-chip">Light / dark mode</span>
854
861
  </div>
855
862
  </div>
856
863
 
857
864
  <div class="callout info">
858
865
  <span class="ico">i</span>
859
866
  <div>
860
- <b>本规范是改 web UI 时的唯一参考。</b>新增或修改组件、样式、布局、主题前,请先读本文;
861
- 颜色、字体、圆角、间距、阴影、层级、动效一律使用 §02 的 token,组件复用 §03 的基元,并遵守 §06 的样式规则。
867
+ <b>This spec is the single reference when changing the web UI.</b> Before adding or modifying a component, style, layout, or theme, read this document first;
868
+ color, font, radius, spacing, shadow, z-index, and motion always use the §02 tokens, components reuse the §03 primitives, and the §06 style rules are followed.
862
869
  </div>
863
870
  </div>
864
871
  </section>
865
872
 
866
- <!-- ===== 01 设计原则 ===== -->
873
+ <!-- ===== 01 Design Principles ===== -->
867
874
  <section id="principles">
868
875
  <div class="sec-head">
869
876
  <span class="sec-num">01</span>
870
- <h2 class="sec-title">设计原则</h2>
877
+ <h2 class="sec-title">Design Principles</h2>
871
878
  </div>
872
879
  <p class="sec-desc">
873
- 所有 UI 决策回指以下原则。Kimi Web 是给开发者用的本地 Agent 工具:快速扫读、长时间注视、经常在暗色下——设计服务于任务,克制、临床、信息密度优先。
880
+ Every UI decision traces back to the following principles. Kimi Web is a local Agent tool for developers: quick scanning, long stretches of staring, often in the dark — the design serves the task, and is restrained, clinical, and density-first.
874
881
  </p>
875
882
 
876
883
  <ul class="clean check">
877
- <li><b>一致性 Consistency</b> —— 同一语义用同一组件。主按钮、弹窗、输入、徽标在全站只应各有「一种」正确写法。</li>
878
- <li><b>视觉层级 Hierarchy</b> —— 通过字号、字重、色彩与留白建立清晰层级;用「克制」而非「加粗加大」来强调。</li>
879
- <li><b>亲密性 Proximity</b> —— 相关元素归组,无关元素留白。卡片的内边距、行间与分组间距来自同一间距刻度。</li>
880
- <li><b>反馈 Feedback</b> —— hover / active / focus / loading / success / error 都有可见状态,且状态语言统一。</li>
881
- <li><b>留白 Breathing room</b> —— 用间距刻度而非随机像素控制密度;宁可克制留白,不让控件互相挤压。</li>
882
- <li><b>可访问性 A11y</b> —— 文本对比度 ≥ 4.5:1,焦点环可见,触摸目标 ≥ 32px,状态不只依赖颜色。</li>
883
- <li><b>少即是多 Reduction</b> —— 颜色数量、圆角数量、阴影层级、字号阶梯都收敛到有限 token,删除游离值。</li>
884
+ <li><b>Consistency</b> —— The same semantics use the same component. The primary button, dialog, input, and badge should each have exactly "one" correct way to be written across the entire site.</li>
885
+ <li><b>Hierarchy</b> —— Build a clear hierarchy through size, weight, color, and whitespace; emphasize through "restraint" rather than "bolder and bigger".</li>
886
+ <li><b>Proximity</b> —— Group related elements, leave whitespace between unrelated ones. A card's padding, line spacing, and group spacing all come from the same spacing scale.</li>
887
+ <li><b>Feedback</b> —— hover / active / focus / loading / success / error all have visible states, and the state language is unified.</li>
888
+ <li><b>Breathing room</b> —— Control density with the spacing scale rather than arbitrary pixels; prefer restrained whitespace over cramming controls together.</li>
889
+ <li><b>Accessibility (A11y)</b> —— Text contrast ≥ 4.5:1, visible focus rings, touch targets ≥ 32px, and states that don't rely on color alone.</li>
890
+ <li><b>Reduction</b> —— The number of colors, radii, shadow levels, and type sizes all converge to a finite set of tokens; delete stray values.</li>
884
891
  </ul>
885
892
 
886
893
  <div class="callout good">
887
894
  <span class="ico">✓</span>
888
895
  <div>
889
- <b>品牌调性(反向清单)</b>:冷静、临床、不夸大。<span class="pill red" style="margin:0 4px">拒绝</span>紫色渐变、玻璃拟态、发光阴影、「Boost your productivity」式营销文案、以及用 emoji 充当图标——<b>月相 🌑…🌘 是唯一例外</b>,仅用于「等待 Agent 响应」的聊天态,属品牌特色。
896
+ <b>Brand tone (the do-not list)</b>: calm, clinical, never exaggerated. <span class="pill red" style="margin:0 4px">Reject</span> purple gradients, glassmorphism, glowing shadows, AI purple / blue glows, endlessly looping fussy micro-animations, "Boost your productivity"-style marketing copy, and using emoji as icons — <b>the moon phases 🌑…🌘 are the sole exception</b>, used only in the "waiting for the Agent to respond" chat state, as a brand signature. These are all common tells of AI-generated interfaces (an "AI tell"), deliberately avoided.
890
897
  </div>
891
898
  </div>
899
+
900
+ <div class="callout info"><span class="ico">i</span><div>
901
+ <b>Declare design intent first (Design Read)</b>: before adding a component / page, write one sentence describing its scenario, audience, and tone (for example, "a lightweight tool card embedded in a conversation, for developers, calm and restrained"), then build. If the intent isn't clear, ask one question first rather than defaulting to the nearest existing style.
902
+ </div></div>
892
903
  </section>
893
904
 
894
905
 
895
- <!-- ===== 02 设计令牌 ===== -->
906
+ <!-- ===== 02 Design Tokens ===== -->
896
907
  <section id="tokens">
897
908
  <div class="sec-head">
898
909
  <span class="sec-num">02</span>
899
- <h2 class="sec-title">设计令牌 Design Tokens</h2>
910
+ <h2 class="sec-title">Design Tokens</h2>
900
911
  </div>
901
912
  <p class="sec-desc">
902
- 把所有视觉决策收敛为 token。<b>颜色 token 沿用现有短名并补全语义</b>(降低迁移成本),
903
- <b>间距、层级、动效、字重</b>则补齐目前缺失的刻度。每个 token 都有:名称、浅色值、深色值、用途。
913
+ Collapse every visual decision into tokens. <b>Color tokens keep the existing short names and fill out the semantics</b> (lowering migration cost),
914
+ while <b>spacing, z-index, motion, and font-weight</b> fill in the scales that are currently missing. Every token has: name, light value, dark value, and usage.
904
915
  </p>
905
916
 
906
917
  <div class="callout info"><span class="ico">i</span><div>
907
- <b>命名约定</b>:<code>--&lt;类别&gt;-&lt;角色&gt;-&lt;状态&gt;</code>。例如 <code>--color-text-muted</code>、<code>--radius-md</code>、<code>--space-4</code>。
908
- 为减少改动,现有短名(<code>--bg</code> / <code>--ink</code> / <code>--line</code> / <code>--blue</code> …)作为<b>兼容别名</b>保留一个版本周期。
918
+ <b>Naming convention</b>: <code>--&lt;category&gt;-&lt;role&gt;-&lt;state&gt;</code>. For example <code>--color-text-muted</code>, <code>--radius-md</code>, <code>--space-4</code>.
919
+ To reduce churn, the existing short names (<code>--bg</code> / <code>--ink</code> / <code>--line</code> / <code>--blue</code> …) are kept as <b>compatibility aliases</b> for one release cycle.
909
920
  </div></div>
910
921
 
911
- <h3 class="sub">颜色 Color</h3>
912
- <p>语义优先、三层递进:<b>背景 / 文字 / 描边</b> + <b>强调色</b> + <b>状态色</b>。所有色值在浅色 / 深色下成对定义,对比度均 ≥ 4.5:1。</p>
913
- <div class="callout info"><span class="ico">i</span><div>下表是<b>派生后的语义 token</b>。其中<b>中性色与强调色</b>由 §05 的 4 个颜色种子派生——例如 <code>--color-accent</code> 取自 <code>--accent-primary</code>,<code>--color-bg</code> 取自当前亮 / 暗面。<b>语义状态色</b>(success / warning / danger / info)是与种子配套的独立调色板,亮 / 暗各一套,不自动从种子派生;日常换肤通常只需调 4 个种子,状态色按需微调。</div></div>
922
+ <h3 class="sub">Color</h3>
923
+ <p>Semantic-first, in three layers: <b>background / text / border</b> + <b>accent</b> + <b>status colors</b>. All colors are defined in light / dark pairs, with contrast ≥ 4.5:1.</p>
924
+ <div class="callout info"><span class="ico">i</span><div>The table below shows the <b>derived semantic tokens</b>. The <b>neutrals and the accent</b> are derived from the 4 color seeds in §05 — for example <code>--color-accent</code> comes from <code>--accent-primary</code>, and <code>--color-bg</code> comes from the current light / dark surface. The <b>semantic status colors</b> (success / warning / danger / info) are independent palettes paired with the seeds, one set each for light / dark; they are not auto-derived from the seeds. Day-to-day reskinning usually only needs the 4 seeds, with the status colors fine-tuned as needed.</div></div>
914
925
  <div class="palette">
915
926
  <div class="color-card"><div class="color-chip" style="background:#ffffff"></div><div class="color-meta"><div class="cn">bg</div><div class="cv">#ffffff / #0d1117</div></div></div>
916
927
  <div class="color-card"><div class="color-chip" style="background:#fafbfc"></div><div class="color-meta"><div class="cn">surface</div><div class="cv">#fafbfc / #161b22</div></div></div>
@@ -922,217 +933,220 @@
922
933
  <div class="color-card"><div class="color-chip" style="background:#e8f3ff"></div><div class="color-meta"><div class="cn">accent-soft</div><div class="cv">#e8f3ff / rgba(88,166,255,.14)</div></div></div>
923
934
  </div>
924
935
  <table class="dt">
925
- <thead><tr><th>Token</th><th>浅色</th><th>深色</th><th>用途</th></tr></thead>
936
+ <thead><tr><th>Token</th><th>Light</th><th>Dark</th><th>Usage</th></tr></thead>
926
937
  <tbody>
927
- <tr><td class="tk">--color-bg</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>页面底色</td></tr>
928
- <tr><td class="tk">--color-surface</td><td class="val"><span class="swatch" style="background:#fafbfc"></span>#fafbfc</td><td class="val"><span class="swatch" style="background:#161b22"></span>#161b22</td><td>面板 / 侧栏 / 卡片头</td></tr>
929
- <tr><td class="tk">--color-surface-raised</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#1c2128"></span>#1c2128</td><td>浮起卡片 / 弹窗 / 输入</td></tr>
930
- <tr><td class="tk">--color-text</td><td class="val"><span class="swatch" style="background:#14171c"></span>#14171c</td><td class="val"><span class="swatch" style="background:#e8eaed"></span>#e8eaed</td><td>正文 / 标题</td></tr>
931
- <tr><td class="tk">--color-text-muted</td><td class="val"><span class="swatch" style="background:#6b7280"></span>#6b7280</td><td class="val"><span class="swatch" style="background:#9aa0a8"></span>#9aa0a8</td><td>次级文字 / 占位符</td></tr>
932
- <tr><td class="tk">--color-line</td><td class="val"><span class="swatch" style="background:#e7eaee"></span>#e7eaee</td><td class="val"><span class="swatch" style="background:#2d333b"></span>#2d333b</td><td>分割线 / 卡片描边</td></tr>
933
- <tr><td class="tk">--color-accent</td><td class="val"><span class="swatch" style="background:#1783ff"></span>#1783ff</td><td class="val"><span class="swatch" style="background:#58a6ff"></span>#58a6ff</td><td>主操作 / 链接 / 焦点</td></tr>
934
- <tr><td class="tk">--color-success</td><td class="val"><span class="swatch" style="background:#0e7a38"></span>#0e7a38</td><td class="val"><span class="swatch" style="background:#3fb950"></span>#3fb950</td><td>成功 / 通过</td></tr>
935
- <tr><td class="tk">--color-warning</td><td class="val"><span class="swatch" style="background:#a9610a"></span>#a9610a</td><td class="val"><span class="swatch" style="background:#d29922"></span>#d29922</td><td>警告 / 待确认</td></tr>
936
- <tr><td class="tk">--color-danger</td><td class="val"><span class="swatch" style="background:#c0392b"></span>#c0392b</td><td class="val"><span class="swatch" style="background:#f85149"></span>#f85149</td><td>危险 / 错误 / 中止</td></tr>
938
+ <tr><td class="tk">--color-bg</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>Page background</td></tr>
939
+ <tr><td class="tk">--color-surface</td><td class="val"><span class="swatch" style="background:#fafbfc"></span>#fafbfc</td><td class="val"><span class="swatch" style="background:#161b22"></span>#161b22</td><td>Panel / sidebar / card head</td></tr>
940
+ <tr><td class="tk">--color-surface-raised</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#1c2128"></span>#1c2128</td><td>Raised card / dialog / input</td></tr>
941
+ <tr><td class="tk">--color-text</td><td class="val"><span class="swatch" style="background:#14171c"></span>#14171c</td><td class="val"><span class="swatch" style="background:#e8eaed"></span>#e8eaed</td><td>Body text / headings</td></tr>
942
+ <tr><td class="tk">--color-text-muted</td><td class="val"><span class="swatch" style="background:#6b7280"></span>#6b7280</td><td class="val"><span class="swatch" style="background:#9aa0a8"></span>#9aa0a8</td><td>Secondary text / placeholder</td></tr>
943
+ <tr><td class="tk">--color-line</td><td class="val"><span class="swatch" style="background:#e7eaee"></span>#e7eaee</td><td class="val"><span class="swatch" style="background:#2d333b"></span>#2d333b</td><td>Divider / card border</td></tr>
944
+ <tr><td class="tk">--color-accent</td><td class="val"><span class="swatch" style="background:#1783ff"></span>#1783ff</td><td class="val"><span class="swatch" style="background:#58a6ff"></span>#58a6ff</td><td>Primary action / link / focus</td></tr>
945
+ <tr><td class="tk">--color-success</td><td class="val"><span class="swatch" style="background:#0e7a38"></span>#0e7a38</td><td class="val"><span class="swatch" style="background:#3fb950"></span>#3fb950</td><td>Success / pass</td></tr>
946
+ <tr><td class="tk">--color-warning</td><td class="val"><span class="swatch" style="background:#a9610a"></span>#a9610a</td><td class="val"><span class="swatch" style="background:#d29922"></span>#d29922</td><td>Warning / pending</td></tr>
947
+ <tr><td class="tk">--color-danger</td><td class="val"><span class="swatch" style="background:#c0392b"></span>#c0392b</td><td class="val"><span class="swatch" style="background:#f85149"></span>#f85149</td><td>Danger / error / abort</td></tr>
937
948
  </tbody>
938
949
  </table>
939
950
 
940
- <h4 class="mini">表面用法 Surface usage</h4>
941
- <p>四层表面各司其职,按「要抬起的层 / 默认平层 / 下沉层 / 页面底色」选用,避免把 <code>--p-surface-raised</code> 当成万能背景。</p>
951
+ <h4 class="mini">Surface usage</h4>
952
+ <p>The four surface layers each have a role — choose by "raised layer / default flat layer / sunken layer / page background", and avoid treating <code>--p-surface-raised</code> as a universal background.</p>
942
953
  <table class="dt">
943
- <thead><tr><th>Token</th><th>浅色</th><th>深色</th><th>用途</th></tr></thead>
954
+ <thead><tr><th>Token</th><th>Light</th><th>Dark</th><th>Usage</th></tr></thead>
944
955
  <tbody>
945
- <tr><td class="tk">--p-surface-raised</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#1c2128"></span>#1c2128</td><td>浮起卡片 / 弹窗 / 输入(要抬起的层)</td></tr>
946
- <tr><td class="tk">--p-surface</td><td class="val"><span class="swatch" style="background:#fafbfc"></span>#fafbfc</td><td class="val"><span class="swatch" style="background:#161b22"></span>#161b22</td><td>面板 / 侧栏 / 卡片头(默认平层)</td></tr>
947
- <tr><td class="tk">--p-surface-sunken</td><td class="val"><span class="swatch" style="background:#f3f5f8"></span>#f3f5f8</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>代码块 / 输入内嵌 / 凹陷区(下沉层)</td></tr>
948
- <tr><td class="tk">--p-bg</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>页面底色</td></tr>
956
+ <tr><td class="tk">--p-surface-raised</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#1c2128"></span>#1c2128</td><td>Raised card / dialog / input (raised layer)</td></tr>
957
+ <tr><td class="tk">--p-surface</td><td class="val"><span class="swatch" style="background:#fafbfc"></span>#fafbfc</td><td class="val"><span class="swatch" style="background:#161b22"></span>#161b22</td><td>Panel / sidebar / card head (default flat layer)</td></tr>
958
+ <tr><td class="tk">--p-surface-sunken</td><td class="val"><span class="swatch" style="background:#f3f5f8"></span>#f3f5f8</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>Code block / inline input / recessed area (sunken layer)</td></tr>
959
+ <tr><td class="tk">--p-bg</td><td class="val"><span class="swatch" style="background:#fff"></span>#ffffff</td><td class="val"><span class="swatch" style="background:#0d1117"></span>#0d1117</td><td>Page background</td></tr>
949
960
  </tbody>
950
961
  </table>
951
962
 
952
- <h4 class="mini">焦点环 Focus ring</h4>
953
- <p>所有可聚焦控件(按钮、输入、链接、菜单项、开关、复选框)统一使用焦点环 token,禁止各自手写 <code>box-shadow</code> 焦点环。</p>
963
+ <h4 class="mini">Focus ring</h4>
964
+ <p>All focusable controls (button, input, link, menu item, switch, checkbox) use the focus-ring token uniformly; do not hand-write a <code>box-shadow</code> focus ring.</p>
954
965
  <table class="dt">
955
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
966
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
956
967
  <tbody>
957
- <tr><td class="tk">--p-focus-ring</td><td class="val">0 0 0 3px var(--p-accent-soft)</td><td>默认焦点环(链接、菜单项、开关、复选框)</td></tr>
958
- <tr><td class="tk">--p-focus-ring-strong</td><td class="val">0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)</td><td>强焦点环(按钮、主操作)</td></tr>
968
+ <tr><td class="tk">--p-focus-ring</td><td class="val">0 0 0 3px var(--p-accent-soft)</td><td>Default focus ring (link, menu item, switch, checkbox)</td></tr>
969
+ <tr><td class="tk">--p-focus-ring-strong</td><td class="val">0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)</td><td>Strong focus ring (button, primary action)</td></tr>
959
970
  </tbody>
960
971
  </table>
961
972
 
962
- <h4 class="mini">选中文本 Selection</h4>
963
- <p>文本选中色统一走 <code>--p-selection</code>(浅色 <code>rgba(23,131,255,.18)</code> / 深色 <code>rgba(88,166,255,.32)</code>),由全局 <code>::selection</code> 规则套用,不另设高亮背景。</p>
973
+ <h4 class="mini">Text selection</h4>
974
+ <p>The text-selection color uses <code>--p-selection</code> uniformly (light <code>rgba(23,131,255,.18)</code> / dark <code>rgba(88,166,255,.32)</code>), applied by the global <code>::selection</code> rule; do not set a separate highlight background.</p>
964
975
 
965
- <h4 class="mini">禁用态 Disabled</h4>
966
- <p>所有禁用控件统一 <code>opacity:.5</code> + <code>cursor:not-allowed</code>,不再单独调灰或改色。</p>
976
+ <h4 class="mini">Disabled state</h4>
977
+ <p>All disabled controls use <code>opacity:.5</code> + <code>cursor:not-allowed</code> uniformly; do not separately grey out or recolor.</p>
967
978
 
968
- <h3 class="sub">字体族 Font families</h3>
969
- <p>Kimi Web 使用两套字体族:<b>--font-ui</b>(UI 与正文,系统字体优先)与 <b>--font-mono</b>(代码与等宽)。组件一律通过变量引用,禁止硬编码字体名。</p>
979
+ <h3 class="sub">Font families</h3>
980
+ <p>Kimi Web uses two font families: <b>--font-ui</b> (UI and body, system fonts first) and <b>--font-mono</b> (code and monospace). Components always reference the variables; do not hard-code font names.</p>
970
981
 
971
- <h4 class="mini">--font-ui · UI 与正文(系统字体优先)</h4>
972
- <p>正文与 UI 采用各平台原生 UI 字体,观感接近系统、长文与中文更舒适。回退链:</p>
982
+ <h4 class="mini">--font-ui · UI &amp; body (system fonts first)</h4>
983
+ <p>Body and UI use each platform's native UI font — close to the system feel, comfortable for long text and CJK. Fallback chain:</p>
973
984
  <div class="code"><div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">--font-ui</span></div><pre>--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI",
974
985
  "PingFang SC", "Microsoft YaHei", "Noto Sans SC",
975
986
  "Helvetica Neue", Arial, sans-serif,
976
987
  "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";</pre></div>
977
988
  <ul class="clean">
978
- <li>系统 UI 字体在前:macOS / iOS 用 SF Pro,Windows 用 Segoe UI。</li>
979
- <li>CJK 紧随:PingFang SC(macOS)/ Microsoft YaHei(Windows)/ Noto Sans SC(Linux)。</li>
980
- <li>Helvetica Neue / Arial / sans-serif 通用兜底;末尾补 emoji 字体。</li>
989
+ <li>System UI fonts first: SF Pro on macOS / iOS, Segoe UI on Windows.</li>
990
+ <li>CJK next: PingFang SC (macOS) / Microsoft YaHei (Windows) / Noto Sans SC (Linux).</li>
991
+ <li>Helvetica Neue / Arial / sans-serif as generic fallbacks; emoji fonts at the end.</li>
981
992
  </ul>
982
993
 
983
- <h4 class="mini">--font-mono · 代码与等宽</h4>
984
- <p>代码、工具名、行号、diff 等使用 JetBrains Mono(自托管可变字体),回退到系统等宽:</p>
994
+ <h4 class="mini">--font-mono · Code &amp; monospace</h4>
995
+ <p>Code, tool names, line numbers, diffs, etc. use JetBrains Mono (a self-hosted variable font), falling back to the system monospace:</p>
985
996
  <div class="code"><div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">--font-mono</span></div><pre>--font-mono: "JetBrains Mono Variable", "JetBrains Mono",
986
997
  ui-monospace, "SF Mono", Menlo, Consolas, monospace;</pre></div>
987
998
 
988
- <h4 class="mini">加载策略</h4>
999
+ <h4 class="mini">Loading strategy</h4>
989
1000
  <table class="dt">
990
- <thead><tr><th>字体</th><th>来源</th><th>打包</th><th>用途</th></tr></thead>
1001
+ <thead><tr><th>Font</th><th>Source</th><th>Bundled</th><th>Usage</th></tr></thead>
991
1002
  <tbody>
992
- <tr><td class="tk">JetBrains Mono</td><td class="val">@fontsource-variable/jetbrains-mono</td><td class="val">✓ 自托管</td><td>等宽 / 代码(--font-mono)</td></tr>
993
- <tr><td class="tk">Inter</td><td class="val">@fontsource-variable/inter</td><td class="val">✓ 自托管</td><td>可选:页面标题 / 品牌字样(--font-display)</td></tr>
994
- <tr><td class="tk">系统 UI / CJK 字体</td><td class="val">操作系统</td><td class="val">—</td><td>正文 / UI(--font-ui),不打包</td></tr>
1003
+ <tr><td class="tk">JetBrains Mono</td><td class="val">@fontsource-variable/jetbrains-mono</td><td class="val">✓ self-hosted</td><td>monospace / code (--font-mono)</td></tr>
1004
+ <tr><td class="tk">Inter</td><td class="val">@fontsource-variable/inter</td><td class="val">✓ self-hosted</td><td>optional: page titles / brand wordmark (--font-display)</td></tr>
1005
+ <tr><td class="tk">System UI / CJK fonts</td><td class="val">operating system</td><td class="val">—</td><td>body / UI (--font-ui), not bundled</td></tr>
995
1006
  </tbody>
996
1007
  </table>
997
1008
  <div class="callout good"><span class="ico">✓</span><div>
998
- 自托管 Inter / JetBrains Mono,无外部网络请求、无 FOUT、可离线;系统字体不打包,符合本地优先。
1009
+ Self-hosted Inter / JetBrains Mono: no external network requests, no FOUT, works offline; system fonts are not bundled, consistent with the local-first approach.
999
1010
  </div></div>
1000
1011
 
1001
- <h4 class="mini">使用规则</h4>
1012
+ <h4 class="mini">Usage rules</h4>
1002
1013
  <ul class="clean check">
1003
- <li>组件一律用 <code>var(--font-ui)</code> / <code>var(--font-mono)</code>,禁止硬编码 <code>'Inter'</code> / <code>'JetBrains Mono'</code> 等字体名。</li>
1004
- <li>正文 / UI 走 <code>--font-ui</code>(系统字体优先);代码 / 等宽走 <code>--font-mono</code>(JetBrains Mono)。</li>
1005
- <li>Inter 仅用于需要统一观感的标题 / 品牌场景(可选 <code>--font-display</code>),不再作为正文默认。</li>
1014
+ <li>Components always use <code>var(--font-ui)</code> / <code>var(--font-mono)</code>; do not hard-code font names like <code>'Inter'</code> / <code>'JetBrains Mono'</code>.</li>
1015
+ <li>Body / UI use <code>--font-ui</code> (system fonts first); code / monospace use <code>--font-mono</code> (JetBrains Mono).</li>
1016
+ <li>Inter is used only for headings / brand scenarios that need a unified look (optional <code>--font-display</code>); it is no longer the body default.</li>
1006
1017
  </ul>
1007
1018
 
1008
- <h3 class="sub">字号与字重 Type scale & weight</h3>
1009
- <p>字号阶梯沿用并规范现有的 <code>--ui-font-size</code>(UI,默认 14px)/ <code>--content-font-size</code>(正文,16px)双轨:<b>UI 控件 / 按钮 / 表单</b>用 <code>--text-base</code>(14px);<b>阅读型正文——包括聊天 Markdown、消息气泡等</b>为提升可读性用 <code>--text-lg</code>(16px,行高 relaxed);<b>侧栏会话列表</b>为信息密度用 <code>calc(var(--ui-font-size) - 1px)</code>(15px,比侧栏 16px 基底小一档)。
1010
- 删除游离的 <code>font-weight: 650 / 750</code>,统一到 400 / 500 两档(常规 / 强调)。</p>
1019
+ <h3 class="sub">Type scale &amp; weight</h3>
1020
+ <p>The type scale keeps and formalizes the existing <code>--ui-font-size</code> (UI, default 14px) / <code>--content-font-size</code> (body, 16px) dual tracks: <b>UI controls / buttons / forms</b> use <code>--text-base</code> (14px); <b>reading body — including chat Markdown, message bubbles, etc.</b> uses <code>--text-lg</code> (16px, relaxed line-height) for readability; the <b>sidebar session list</b> uses <code>calc(var(--ui-font-size) - 1px)</code> (15px, one step below the sidebar's 16px base) for density.
1021
+ Drop stray <code>font-weight: 650 / 750</code>; converge on two weights, 400 / 500 (regular / emphasis).</p>
1011
1022
  <div class="panel panel-pad" style="margin:16px 0">
1012
- <div class="type-row"><div class="type-sample" style="font-size:22px;font-weight:500">页面标题 Page Title</div><div class="type-meta">--text-2xl · 22 / 500</div></div>
1013
- <div class="type-row"><div class="type-sample" style="font-size:18px;font-weight:500">区块标题 Section</div><div class="type-meta">--text-xl · 18 / 500</div></div>
1014
- <div class="type-row"><div class="type-sample" style="font-size:16px;font-weight:400">聊天正文 / 卡片标题 Content</div><div class="type-meta">--text-lg · 16 / 400</div></div>
1015
- <div class="type-row"><div class="type-sample" style="font-size:14px;font-weight:500">UI 控件 / 按钮 / 表单 UI</div><div class="type-meta">--text-base · 14 / 500</div></div>
1016
- <div class="type-row"><div class="type-sample" style="font-size:13px">辅助说明 / 表格</div><div class="type-meta">--text-sm · 13 / 400</div></div>
1017
- <div class="type-row"><div class="type-sample" style="font-size:12px">徽标 / 时间戳 / 行号</div><div class="type-meta">--text-xs · 12 / 500</div></div>
1023
+ <div class="type-row"><div class="type-sample" style="font-size:22px;font-weight:500">Page Title</div><div class="type-meta">--text-2xl · 22 / 500</div></div>
1024
+ <div class="type-row"><div class="type-sample" style="font-size:18px;font-weight:500">Section Title</div><div class="type-meta">--text-xl · 18 / 500</div></div>
1025
+ <div class="type-row"><div class="type-sample" style="font-size:16px;font-weight:400">Chat body / card title</div><div class="type-meta">--text-lg · 16 / 400</div></div>
1026
+ <div class="type-row"><div class="type-sample" style="font-size:14px;font-weight:500">UI control / button / form</div><div class="type-meta">--text-base · 14 / 500</div></div>
1027
+ <div class="type-row"><div class="type-sample" style="font-size:13px">Helper text / table</div><div class="type-meta">--text-sm · 13 / 400</div></div>
1028
+ <div class="type-row"><div class="type-sample" style="font-size:12px">Badge / timestamp / line number</div><div class="type-meta">--text-xs · 12 / 500</div></div>
1018
1029
  </div>
1019
1030
  <table class="dt">
1020
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
1031
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
1021
1032
  <tbody>
1022
- <tr><td class="tk">--font-ui</td><td class="val">-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC"…</td><td>UI 与正文(系统字体优先)</td></tr>
1023
- <tr><td class="tk">--font-mono</td><td class="val">JetBrains Mono…</td><td>代码、工具名、行号、diff</td></tr>
1024
- <tr><td class="tk">--leading-tight/normal/relaxed</td><td class="val">1.25 / 1.5 / 1.7</td><td>标题 / UI / 长文</td></tr>
1025
- <tr><td class="tk">--weight-regular/medium</td><td class="val">400 / 500</td><td>正文 / 强调</td></tr>
1033
+ <tr><td class="tk">--font-ui</td><td class="val">-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC"…</td><td>UI &amp; body (system fonts first)</td></tr>
1034
+ <tr><td class="tk">--font-mono</td><td class="val">JetBrains Mono…</td><td>code, tool names, line numbers, diffs</td></tr>
1035
+ <tr><td class="tk">--leading-tight/normal/relaxed</td><td class="val">1.25 / 1.5 / 1.7</td><td>headings / UI / long text</td></tr>
1036
+ <tr><td class="tk">--weight-regular/medium</td><td class="val">400 / 500</td><td>body / emphasis</td></tr>
1026
1037
  </tbody>
1027
1038
  </table>
1028
1039
 
1029
- <h4 class="mini">图标尺寸 Icon size</h4>
1030
- <p>图标统一使用三档尺寸 token,全局 <code>.p-ic</code> 默认 16px(<code>--p-ic-md</code>);各组件按需选用,禁止手写随机像素。</p>
1040
+ <h4 class="mini">Icon size</h4>
1041
+ <p>Icons use three size tokens uniformly. The global <code>.p-ic</code> default is 16px (<code>--p-ic-md</code>); components pick as needed, and random pixel sizes are forbidden.</p>
1031
1042
  <table class="dt">
1032
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
1043
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
1033
1044
  <tbody>
1034
- <tr><td class="tk">--p-ic-sm</td><td class="val">14px</td><td>小按钮、徽标、菜单项、链接内嵌图标</td></tr>
1035
- <tr><td class="tk">--p-ic-md</td><td class="val">16px</td><td>默认(按钮、图标按钮、工具条)</td></tr>
1036
- <tr><td class="tk">--p-ic-lg</td><td class="val">20px</td><td>Toast 状态图标、空状态插图</td></tr>
1045
+ <tr><td class="tk">--p-ic-sm</td><td class="val">14px</td><td>small button, badge, menu item, inline link icon</td></tr>
1046
+ <tr><td class="tk">--p-ic-md</td><td class="val">16px</td><td>default (button, icon button, toolbar)</td></tr>
1047
+ <tr><td class="tk">--p-ic-lg</td><td class="val">20px</td><td>Toast status icon, empty-state illustration</td></tr>
1037
1048
  </tbody>
1038
1049
  </table>
1039
1050
 
1040
- <h4 class="mini">图标 Icon</h4>
1041
- <p>图标一律从集中注册表 <code>lib/icons.ts</code> 取用:模板中用 <code>&lt;Icon name size /&gt;</code> 组件(<code>components/ui/Icon.vue</code>),<code>v-html</code> 场景(如工具 glyph)用 <code>iconSvg(name, size)</code>。<b>禁止手写 <code>&lt;svg&gt;</code></b>——<code>scripts/check-style.mjs</code> 的 <code>icon-from-registry</code> 规则会对游离 SVG 告警。默认线稿风格:描边 1.5px、<code>stroke="currentColor"</code>、<code>stroke-linecap/linejoin: round</code>、无 fill,颜色跟随文字;尺寸走下方三档 token。少数「实心即语义」的图标(<code>play / stop / star</code>)为 fill 例外。</p>
1051
+ <h4 class="mini">Icon</h4>
1052
+ <p>Icons always come from the centralized registry <code>lib/icons.ts</code>: in templates use the <code>&lt;Icon name size /&gt;</code> component (<code>components/ui/Icon.vue</code>); for <code>v-html</code> contexts (such as a tool glyph) use <code>iconSvg(name, size)</code>. <b>Do not hand-write <code>&lt;svg&gt;</code></b> — the <code>scripts/check-style.mjs</code> <code>icon-from-registry</code> rule flags stray SVGs. Icons come from <a href="https://remixicon.com/">Remix Icon</a> (Apache-2.0), uniformly in a fill style (<code>fill="currentColor"</code>, 24×24 source grid), with color following the text; size uses the three tokens below. The registry is generated on demand by <code>scripts/gen-icon-data.mjs</code> from <code>@iconify-json/ri</code>, offline and tree-shaken. <b>The whole site uses only this one icon family</b>; do not mix in other icon libraries, and <b>never hand-write SVG paths</b>. When an icon is missing, add it to the registry (edit the mapping in <code>gen-icon-data.mjs</code> and regenerate) rather than drawing it in a component.</p>
1042
1053
 
1043
- <h4 class="mini">尺寸阶梯 Size scale</h4>
1054
+ <h4 class="mini">Size scale</h4>
1044
1055
  <div class="icon-sizes">
1045
- <div class="sz"><svg class="p-ic" style="width:14px;height:14px" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v10M3 8h10"/></svg>sm · 14</div>
1046
- <div class="sz"><svg class="p-ic" style="width:16px;height:16px" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v10M3 8h10"/></svg>md · 16</div>
1047
- <div class="sz"><svg class="p-ic" style="width:20px;height:20px" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v10M3 8h10"/></svg>lg · 20</div>
1056
+ <div class="sz"><svg class="p-ic" style="width:14px;height:14px" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg>sm · 14</div>
1057
+ <div class="sz"><svg class="p-ic" style="width:16px;height:16px" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg>md · 16</div>
1058
+ <div class="sz"><svg class="p-ic" style="width:20px;height:20px" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg>lg · 20</div>
1048
1059
  </div>
1049
1060
 
1050
- <h4 class="mini">图标库 Icon library</h4>
1051
- <p>当前注册的图标(按用途分组)。新增图标时,把图形以 <code>name → body</code> 加入 <code>lib/icons.ts</code>,按需补 <code>viewBox</code>(默认 16×16)/<code>fill</code>,再用 <code>node --experimental-strip-types scripts/gen-icon-catalog.mjs</code> 重新生成本目录,保证注册表与文档不漂移。</p>
1061
+ <h4 class="mini">Icon library</h4>
1062
+ <p>Currently registered icons, grouped by purpose. The icon data is determined by the <code>NAME_TO_REMIX</code> mapping in <code>scripts/gen-icon-data.mjs</code>; running <code>pnpm gen:icons</code> generates <code>lib/icon-data.ts</code>. This catalog is regenerated with <code>node --experimental-strip-types scripts/gen-icon-catalog.mjs</code> so the registry and the document never drift.</p>
1052
1063
  <div class="icon-grid">
1053
- <div class="icon-group-label">Actions</div>
1054
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v10M3 8h10"/></svg><span class="ic-name">plus</span></div>
1055
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4l8 8M12 4l-8 8"/></svg><span class="ic-name">close</span></div>
1056
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5l3.5 3.5L13 4.5"/></svg><span class="ic-name">check</span></div>
1057
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="7" cy="7" r="4.5"/><path d="m10.5 10.5 3 3"/></svg><span class="ic-name">search</span></div>
1058
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="9" height="9" rx="1.5"/><path d="M6 1h7a1 1 0 0 1 1 1v7"/></svg><span class="ic-name">copy</span></div>
1059
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 9.5a3 3 0 0 0 4.2.3l2-2a3 3 0 0 0-4.2-4.2l-1 1"/><path d="M9.5 6.5a3 3 0 0 0-4.2-.3l-2 2a3 3 0 0 0 4.2 4.2l1-1"/></svg><span class="ic-name">link</span></div>
1060
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 2.5h4v4"/><path d="M13.5 2.5 7.5 8.5"/><path d="M12 8.7V12a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 12V5.5A1.5 1.5 0 0 1 4 4h3.3"/></svg><span class="ic-name">external-link</span></div>
1061
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2v8"/><path d="M4.5 6.5 8 10l3.5-3.5"/><path d="M2.5 13.5h11"/></svg><span class="ic-name">download</span></div>
1062
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 2.5 3 6l3.5 3.5"/><path d="M3 6h6.5a3.8 3.8 0 1 1 0 7.6H7.5"/></svg><span class="ic-name">undo</span></div>
1063
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3l6 5.5M8 3L2 8.5M8 3v10"/></svg><span class="ic-name">send</span></div>
1064
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><circle cx="5" cy="6" r="1.2"/><path d="M2 10.5l3-2.5L8 11l2.5-2L14 11"/></svg><span class="ic-name">image</span></div>
1065
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l-.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09A1.65 1.65 0 0 0 15 4.6a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09A1.65 1.65 0 0 0 19.4 15z"/></svg><span class="ic-name">settings</span></div>
1066
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="8" x2="20" y2="8"/><circle cx="10" cy="8" r="2.5" fill="var(--color-bg)" stroke="none"/><line x1="4" y1="16" x2="20" y2="16"/><circle cx="15" cy="16" r="2.5" fill="var(--color-bg)" stroke="none"/></svg><span class="ic-name">sliders</span></div>
1067
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h5a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H6"/><path d="M9 8H2"/><path d="M5 5l3 3-3 3"/></svg><span class="ic-name">log-in</span></div>
1068
- <div class="icon-group-label">Navigation &amp; layout</div>
1069
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6l4 4 4-4"/></svg><span class="ic-name">chevron-down</span></div>
1070
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4l4 4-4 4"/></svg><span class="ic-name">chevron-right</span></div>
1071
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 12V4M4 7l4-3 4 3"/></svg><span class="ic-name">arrow-up</span></div>
1072
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4v8m0 0 3.5-3.5M8 12l-3.5-3.5"/></svg><span class="ic-name">arrow-down</span></div>
1073
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 8h10"/><path d="M8 4l4 4-4 4"/></svg><span class="ic-name">arrow-right</span></div>
1074
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8h10"/></svg><span class="ic-name">minus</span></div>
1075
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M11 6h9"/><path d="M11 12h9"/><path d="M11 18h9"/><path d="M7 9l-3 3 3 3"/></svg><span class="ic-name">panel-collapse</span></div>
1076
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h9"/><path d="M4 12h9"/><path d="M4 18h9"/><path d="M17 9l3 3-3 3"/></svg><span class="ic-name">panel-expand</span></div>
1077
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg><span class="ic-name">expand</span></div>
1078
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 14h6v6"/><path d="M20 10h-6V4"/><path d="M14 10l7-7"/><path d="M3 21l7-7"/></svg><span class="ic-name">collapse</span></div>
1079
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4h12M2 8h12M2 12h8"/></svg><span class="ic-name">list</span></div>
1080
- <div class="icon-group-label">Files &amp; tools</div>
1081
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1 3.5V2.5A1 1 0 0 1 2 1.5h3.5l1.3 2h5.2a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1z"/><path d="M1 5.5h12"/></svg><span class="ic-name">folder</span></div>
1082
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="3.5" width="12" height="8.5" rx="1"/><path d="M1 5V3.5A1 1 0 0 1 2 2.5h3.5l1.3 2"/></svg><span class="ic-name">folder-closed</span></div>
1083
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1 3.5V2.5A1 1 0 0 1 2 1.5h3.5l1.3 2h5.2a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1z"/><path d="M1 5.5h12"/><path d="M8 7.25v4.5M5.75 9.5h4.5"/></svg><span class="ic-name">folder-plus</span></div>
1084
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="currentColor"><path d="M1.5 3.5h3l1.5 2h7a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1z"/></svg><span class="ic-name">folder-solid</span></div>
1085
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 1.5h5l3 3v10H4z"/><polyline points="9,1.5 9,4.5 12,4.5"/></svg><span class="ic-name">file</span></div>
1086
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2.5" y="1.5" width="9" height="13" rx="1"/><line x1="5" y1="5" x2="9" y2="5"/><line x1="5" y1="7.5" x2="11" y2="7.5"/><line x1="5" y1="10" x2="10" y2="10"/></svg><span class="ic-name">file-text</span></div>
1087
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12V4.5L8 2l5 2.5V12H3z"/><line x1="6" y1="7" x2="10" y2="7"/><line x1="8" y1="5" x2="8" y2="9"/></svg><span class="ic-name">file-plus</span></div>
1088
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 3h7l4 4v10H5V3z"/><path d="M12 3v4h4"/></svg><span class="ic-name">file-off</span></div>
1089
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="16" height="16" rx="2"/><path d="M7 10h6M10 7v6"/></svg><span class="ic-name">image-off</span></div>
1090
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="5.5,5 2.5,8 5.5,11"/><polyline points="10.5,5 13.5,8 10.5,11"/></svg><span class="ic-name">code</span></div>
1091
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1.5" y="2.5" width="13" height="11" rx="1.5"/><polyline points="4,6 6.5,8 4,10"/><line x1="8" y1="10" x2="12" y2="10"/></svg><span class="ic-name">terminal</span></div>
1092
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.5 2.5l3 3-8 8H2.5v-3l8-8z"/><line x1="8.5" y1="4.5" x2="11.5" y2="7.5"/></svg><span class="ic-name">pencil</span></div>
1093
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 2.5C3.5 2.5 3.5 5 3.5 6.5S2.5 8 2.5 8s1 0 1 1.5S3.5 13.5 5 13.5"/><path d="M11 2.5c1.5 0 1.5 2.5 1.5 4S13.5 8 13.5 8s-1 0-1 1.5.5 4-1.5 4"/><line x1="8" y1="6" x2="8" y2="10"/><line x1="6.3" y1="6.8" x2="9.7" y2="9.2"/><line x1="9.7" y1="6.8" x2="6.3" y2="9.2"/></svg><span class="ic-name">glob</span></div>
1094
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6"/><path d="M8 2c-2 2-3 3.6-3 6s1 4 3 6"/><path d="M8 2c2 2 3 3.6 3 6s-1 4-3 6"/><line x1="2" y1="8" x2="14" y2="8"/></svg><span class="ic-name">globe</span></div>
1095
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,4.5 3.5,6 5.5,3"/><polyline points="2,11 3.5,12.5 5.5,9.5"/><line x1="8" y1="4.5" x2="14" y2="4.5"/><line x1="8" y1="11" x2="14" y2="11"/></svg><span class="ic-name">check-list</span></div>
1096
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 1L3 9h4l-1.5 6 5.5-8h-4l1.5-6z"/></svg><span class="ic-name">bolt</span></div>
1097
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="6" r="3"/><path d="M5 9v12"/><circle cx="19" cy="18" r="3"/><path d="m15 9-3-3 3-3"/><path d="M12 6h5a2 2 0 0 1 2 2v7"/></svg><span class="ic-name">git-pull-request</span></div>
1098
- <div class="icon-group-label">Communication</div>
1099
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 2.5h8a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H8.5l-2.5 2V11.5H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2z"/></svg><span class="ic-name">message</span></div>
1100
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4l6 4 6-4"/><rect x="2" y="4" width="12" height="8" rx="1.5"/></svg><span class="ic-name">mail</span></div>
1101
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="5" r="3"/><path d="M3 14c0-3 2.2-5 5-5s5 2 5 5"/></svg><span class="ic-name">user</span></div>
1102
- <div class="icon-group-label">Status &amp; media</div>
1103
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="5"/><line x1="6" y1="3.5" x2="6" y2="6.5"/><circle cx="6" cy="8.5" r="0.5" fill="currentColor"/></svg><span class="ic-name">info</span></div>
1104
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.5"/><path d="M6.2 6a1.8 1.8 0 0 1 3.5.6c0 1.2-1.7 1.4-1.7 2.6"/><circle cx="8" cy="11.5" r=".7" fill="currentColor"/></svg><span class="ic-name">help-circle</span></div>
1105
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2 14 13H2L8 2Z"/><path d="M8 6v3"/><circle cx="8" cy="11" r=".6" fill="currentColor"/></svg><span class="ic-name">alert-triangle</span></div>
1106
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="5.5"/><path d="M8 4.5V8l2.5 1.5"/></svg><span class="ic-name">clock</span></div>
1107
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2l1.5 4.5L14 8l-4.5 1.5L8 14l-1.5-4.5L2 8l4.5-1.5z"/></svg><span class="ic-name">sparkles</span></div>
1108
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="currentColor"><path d="M5 3.5v9l7-4.5z"/></svg><span class="ic-name">play</span></div>
1109
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="currentColor"><rect x="3" y="3" width="10" height="10" rx="1.5"/></svg><span class="ic-name">stop</span></div>
1110
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><span class="ic-name">star</span></div>
1111
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg><span class="ic-name">star-outline</span></div>
1112
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="currentColor"><circle cx="8" cy="3" r="1.3"/><circle cx="8" cy="8" r="1.3"/><circle cx="8" cy="13" r="1.3"/></svg><span class="ic-name">dots-vertical</span></div>
1113
- <div class="icon-cell"><svg class="p-ic" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.3"/><circle cx="8" cy="8" r="1.3"/><circle cx="13" cy="8" r="1.3"/></svg><span class="ic-name">dots-horizontal</span></div>
1064
+ <div class="icon-group-label">Actions</div>
1065
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg><span class="ic-name">plus</span></div>
1066
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M14 3v2H4v13.385L5.763 17H20v-7h2v8a1 1 0 0 1-1 1H6.455L2 22.5V4a1 1 0 0 1 1-1zm5 0V0h2v3h3v2h-3v3h-2V5h-3V3z"/></svg><span class="ic-name">chat-new</span></div>
1067
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z"/></svg><span class="ic-name">close</span></div>
1068
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg><span class="ic-name">check</span></div>
1069
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z"/></svg><span class="ic-name">search</span></div>
1070
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z"/></svg><span class="ic-name">copy</span></div>
1071
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.06 8.111l1.415 1.414a7 7 0 0 1 0 9.9l-.354.353a7 7 0 1 1-9.9-9.9l1.415 1.415a5 5 0 1 0 7.071 7.071l.354-.354a5 5 0 0 0 0-7.07l-1.415-1.415zm6.718 6.01l-1.414-1.414a5 5 0 0 0-7.071-7.07l-.354.353a5 5 0 0 0 0 7.07l1.415 1.415l-1.415 1.414l-1.414-1.414a7 7 0 0 1 0-9.9l.354-.353a7 7 0 1 1 9.9 9.9"/></svg><span class="ic-name">link</span></div>
1072
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"/></svg><span class="ic-name">external-link</span></div>
1073
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 19h18v2H3zm10-5.828L19.071 7.1l1.414 1.414L12 17L3.515 8.515L4.929 7.1L11 13.173V2h2z"/></svg><span class="ic-name">download</span></div>
1074
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m5.828 7l2.536 2.535L6.95 10.95L2 6l4.95-4.95l1.414 1.415L5.828 5H13a8 8 0 1 1 0 16H4v-2h9a6 6 0 0 0 0-12z"/></svg><span class="ic-name">undo</span></div>
1075
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M13 7.828V20h-2V7.828l-5.364 5.364l-1.414-1.414L12 4l7.778 7.778l-1.414 1.414z"/></svg><span class="ic-name">send</span></div>
1076
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M2.992 21A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993zM20 15V5H4v14L14 9zm0 2.828l-6-6L6.828 19H20zM8 11a2 2 0 1 1 0-4a2 2 0 0 1 0 4"/></svg><span class="ic-name">image</span></div>
1077
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3.34 17a10 10 0 0 1-.979-2.326a3 3 0 0 0 .003-5.347a10 10 0 0 1 2.5-4.337a3 3 0 0 0 4.632-2.674a10 10 0 0 1 5.007.003a3 3 0 0 0 4.632 2.671a10.06 10.06 0 0 1 2.503 4.336a3 3 0 0 0-.002 5.347a10 10 0 0 1-2.501 4.337a3 3 0 0 0-4.632 2.674a10 10 0 0 1-5.007-.002a3 3 0 0 0-4.631-2.672A10 10 0 0 1 3.339 17m5.66.196a5 5 0 0 1 2.25 2.77q.75.07 1.499.002a5 5 0 0 1 2.25-2.772a5 5 0 0 1 3.526-.564q.435-.614.748-1.298A5 5 0 0 1 18 12c0-1.26.47-2.437 1.273-3.334a8 8 0 0 0-.75-1.298A5 5 0 0 1 15 6.804a5 5 0 0 1-2.25-2.77q-.75-.071-1.5-.001A5 5 0 0 1 9 6.804a5 5 0 0 1-3.526.564q-.436.614-.747 1.298A5 5 0 0 1 6 12c0 1.26-.471 2.437-1.273 3.334a8 8 0 0 0 .75 1.298A5 5 0 0 1 9 17.196M12 15a3 3 0 1 1 0-6a3 3 0 0 1 0 6m0-2a1 1 0 1 0 0-2a1 1 0 0 0 0 2"/></svg><span class="ic-name">settings</span></div>
1078
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M6.17 18a3.001 3.001 0 0 1 5.66 0H22v2H11.83a3.001 3.001 0 0 1-5.66 0H2v-2zm6-7a3.001 3.001 0 0 1 5.66 0H22v2h-4.17a3.001 3.001 0 0 1-5.66 0H2v-2zm-6-7a3.001 3.001 0 0 1 5.66 0H22v2H11.83a3.001 3.001 0 0 1-5.66 0H2V4zM9 6a1 1 0 1 0 0-2a1 1 0 0 0 0 2m6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m-6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2"/></svg><span class="ic-name">sliders</span></div>
1079
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 15h2v5h12V4H6v5H4V3a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm6-4V8l5 4l-5 4v-3H2v-2z"/></svg><span class="ic-name">log-in</span></div>
1080
+ <div class="icon-group-label">Navigation &amp; layout</div>
1081
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z"/></svg><span class="ic-name">chevron-down</span></div>
1082
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg><span class="ic-name">chevron-right</span></div>
1083
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M13 7.828V20h-2V7.828l-5.364 5.364l-1.414-1.414L12 4l7.778 7.778l-1.414 1.414z"/></svg><span class="ic-name">arrow-up</span></div>
1084
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13 16.172l5.364-5.364l1.414 1.414L12 20l-7.778-7.778l1.414-1.414L11 16.172V4h2z"/></svg><span class="ic-name">arrow-down</span></div>
1085
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m16.172 11l-5.364-5.364l1.414-1.414L20 12l-7.778 7.778l-1.414-1.414L16.172 13H4v-2z"/></svg><span class="ic-name">arrow-right</span></div>
1086
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M5 11v2h14v-2z"/></svg><span class="ic-name">minus</span></div>
1087
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m15.071 4.929l1.414 1.414L11.83 11H21v2h-9.17l4.656 4.657l-1.414 1.414L8.001 12zm-11.07 14.07V5h2v14z"/></svg><span class="ic-name">panel-collapse</span></div>
1088
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m17.172 11l-4.657-4.657l1.414-1.414L21 12l-7.071 7.071l-1.414-1.414L17.172 13H8v-2zM4 19V5h2v14z"/></svg><span class="ic-name">panel-expand</span></div>
1089
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M17.586 5H14V3h7v7h-2V6.414l-4.293 4.293l-1.414-1.414zM3 14h2v3.586l4.293-4.293l1.414 1.414L6.414 19H10v2H3z"/></svg><span class="ic-name">expand</span></div>
1090
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M15 4h-2v7h7V9h-3.586l4.293-4.293l-1.414-1.414L15 7.586zM4 15h3.586l-4.293 4.293l1.414 1.414L9 16.414V20h2v-7H4z"/></svg><span class="ic-name">collapse</span></div>
1091
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"/></svg><span class="ic-name">list</span></div>
1092
+ <div class="icon-group-label">Files &amp; tools</div>
1093
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 21a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414l2 2H20a1 1 0 0 1 1 1v3h-2V7h-7.414l-2-2H4v11.998L5.5 11h17l-2.31 9.243a1 1 0 0 1-.97.757zm16.938-8H7.062l-1.5 6h12.876z"/></svg><span class="ic-name">folder</span></div>
1094
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg><span class="ic-name">folder-closed</span></div>
1095
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414zM4 5v14h16V7h-8.414l-2-2zm7 7V9h2v3h3v2h-3v3h-2v-3H8v-2z"/></svg><span class="ic-name">folder-plus</span></div>
1096
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg><span class="ic-name">folder-solid</span></div>
1097
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg><span class="ic-name">file</span></div>
1098
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M21 8v12.993A1 1 0 0 1 20.007 22H3.993A.993.993 0 0 1 3 21.008V2.992C3 2.455 3.449 2 4.002 2h10.995zm-2 1h-5V4H5v16h14zM8 7h3v2H8zm0 4h8v2H8zm0 4h8v2H8z"/></svg><span class="ic-name">file-text</span></div>
1099
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M15 4H5v16h14V8h-4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008zM11 11V8h2v3h3v2h-3v3h-2v-3H8v-2z"/></svg><span class="ic-name">file-plus</span></div>
1100
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg><span class="ic-name">file-off</span></div>
1101
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M2.992 21A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993zM20 15V5H4v14L14 9zm0 2.828l-6-6L6.828 19H20zM8 11a2 2 0 1 1 0-4a2 2 0 0 1 0 4"/></svg><span class="ic-name">image-off</span></div>
1102
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414z"/></svg><span class="ic-name">code</span></div>
1103
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1m1 2v14h16V5zm8 10h6v2h-6zm-3.333-3L5.838 9.172l1.415-1.415L11.495 12l-4.242 4.243l-1.415-1.415z"/></svg><span class="ic-name">terminal</span></div>
1104
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m15.728 9.576l-1.414-1.414L5 17.476v1.414h1.414zm1.414-1.414l1.414-1.414l-1.414-1.414l-1.414 1.414zm-9.9 12.728H3v-4.243L16.435 3.212a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414z"/></svg><span class="ic-name">pencil</span></div>
1105
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12A2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3m16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5"/></svg><span class="ic-name">glob</span></div>
1106
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.01 8.01 0 0 0 5.648 6.667M10.03 13c.151 2.439.848 4.73 1.97 6.752A15.9 15.9 0 0 0 13.97 13zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.01 8.01 0 0 0 19.938 13M4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333A8.01 8.01 0 0 0 4.062 11m5.969 0h3.938A15.9 15.9 0 0 0 12 4.248A15.9 15.9 0 0 0 10.03 11m4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.01 8.01 0 0 0-5.648-6.667"/></svg><span class="ic-name">globe</span></div>
1107
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zm-5-.5h3v3H3zm0 7h3v3H3zm0 7h3v3H3zM8 11h13v2H8zm0 7h13v2H8z"/></svg><span class="ic-name">check-list</span></div>
1108
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M13 9h8L11 24v-9H4l9-15zm-2 2V7.22L7.532 13H13v4.394L17.263 11z"/></svg><span class="ic-name">bolt</span></div>
1109
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M15 5h2a2 2 0 0 1 2 2v8.17a3.001 3.001 0 1 1-2 0V7h-2v3l-4.5-4L15 2zM5 8.83a3.001 3.001 0 1 1 2 0v6.34a3.001 3.001 0 1 1-2 0zM6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m0 12a1 1 0 1 0 0-2a1 1 0 0 0 0 2m12 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2"/></svg><span class="ic-name">git-pull-request</span></div>
1110
+ <div class="icon-group-label">Communication</div>
1111
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1zm-.692-2H20V5H4v13.385zM8 10h8v2H8z"/></svg><span class="ic-name">message</span></div>
1112
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1m17 4.238l-7.928 7.1L4 7.216V19h16zM4.511 5l7.55 6.662L19.502 5z"/></svg><span class="ic-name">mail</span></div>
1113
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 0 0-12 0zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6s6 2.685 6 6s-2.685 6-6 6m0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4s-4 1.79-4 4s1.79 4 4 4"/></svg><span class="ic-name">user</span></div>
1114
+ <div class="icon-group-label">Status &amp; media</div>
1115
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M11 7h2v2h-2zm0 4h2v6h-2z"/></svg><span class="ic-name">info</span></div>
1116
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-1-5h2v2h-2zm2-1.645V14h-2v-1.5a1 1 0 0 1 1-1a1.5 1.5 0 1 0-1.471-1.794l-1.962-.393A3.501 3.501 0 1 1 13 13.355"/></svg><span class="ic-name">help-circle</span></div>
1117
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z"/></svg><span class="ic-name">alert-triangle</span></div>
1118
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m1-8h4v2h-6V7h2z"/></svg><span class="ic-name">clock</span></div>
1119
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M14 4.438A2.437 2.437 0 0 0 16.438 2h1.125A2.437 2.437 0 0 0 20 4.438v1.125A2.437 2.437 0 0 0 17.563 8h-1.125A2.437 2.437 0 0 0 14 5.563zM1 11a6 6 0 0 0 6-6h2a6 6 0 0 0 6 6v2a6 6 0 0 0-6 6H7a6 6 0 0 0-6-6zm3.876 1A8.04 8.04 0 0 1 8 15.124A8.04 8.04 0 0 1 11.124 12A8.04 8.04 0 0 1 8 8.876A8.04 8.04 0 0 1 4.876 12m12.374 2A3.25 3.25 0 0 1 14 17.25v1.5A3.25 3.25 0 0 1 17.25 22h1.5A3.25 3.25 0 0 1 22 18.75v-1.5A3.25 3.25 0 0 1 18.75 14z"/></svg><span class="ic-name">sparkles</span></div>
1120
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M19.376 12.416L8.777 19.482A.5.5 0 0 1 8 19.066V4.934a.5.5 0 0 1 .777-.416l10.599 7.066a.5.5 0 0 1 0 .832"/></svg><span class="ic-name">play</span></div>
1121
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M6 5h12a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1"/></svg><span class="ic-name">stop</span></div>
1122
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928z"/></svg><span class="ic-name">star</span></div>
1123
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928zm0-2.292l4.247 2.377l-.948-4.773l3.573-3.305l-4.833-.573l-2.038-4.419l-2.039 4.42l-4.833.572l3.573 3.305l-.948 4.773z"/></svg><span class="ic-name">star-outline</span></div>
1124
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4.5 10.5c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S6 12.825 6 12s-.675-1.5-1.5-1.5m15 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S21 12.825 21 12s-.675-1.5-1.5-1.5m-7.5 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5s1.5-.675 1.5-1.5s-.675-1.5-1.5-1.5"/></svg><span class="ic-name">dots-horizontal</span></div>
1125
+ <div class="icon-group-label">Other</div>
1126
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M20 4v12h3l-4 5l-4-5h3V4zm-8 14v2H3v-2zm2-7v2H3v-2zm0-7v2H3V4z"/></svg><span class="ic-name">sort</span></div>
1127
+ <div class="icon-cell"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8.5 7a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m0 6.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m1.5 5a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0M15.5 7a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m1.5 5a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0m-1.5 8a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3"/></svg><span class="ic-name">grip</span></div>
1114
1128
  </div>
1115
1129
 
1116
- <p>禁止用 emoji 充当功能图标(唯一例外:月相 🌑…🌘,仅用于「等待 Agent 响应」聊天态)。Kimi 品牌标记(32×22 的眼睛 logo)属于品牌资产,不在此线稿图标体系内。</p>
1117
- <p>少数<b>非线稿图形</b>不进注册表,各有专属组件统一维护,禁止复制手写:<code>&lt;ContextRing :pct /&gt;</code>(Composer 上下文进度环,数据驱动)、<code>&lt;AuthStateIcon kind /&gt;</code>(登录流程的成功 / 过期 / 错误彩色插图)、<code>&lt;Spinner /&gt;</code>(加载态)。状态小圆点(如 Provider 列表)一律用 CSS 圆点(<code>border-radius:50%</code>),不再用 SVG。<code>scripts/check-style.mjs</code> 的 <code>icon-from-registry</code> 规则对以上与品牌标记豁免,其余手写 <code>&lt;svg&gt;</code> 一律告警。</p>
1130
+ <p>Do not use emoji as functional icons (the sole exception is the moon phases 🌑…🌘, used only in the "waiting for the Agent to respond" chat state). The Kimi brand mark (the 32×22 eye logo) is a brand asset and is not part of this icon system.</p>
1131
+ <p>A few <b>special graphics</b> are not in the registry; each has a dedicated component maintained in one place, and must not be copied by hand: <code>&lt;ContextRing :pct /&gt;</code> (the Composer context progress ring, data-driven), <code>&lt;AuthStateIcon kind /&gt;</code> (the success / expired / error colored illustrations in the login flow), <code>&lt;Spinner /&gt;</code> (loading state). Status dots (such as in the Provider list) always use CSS dots (<code>border-radius:50%</code>), not SVG. The <code>scripts/check-style.mjs</code> <code>icon-from-registry</code> rule exempts the above and the brand mark; all other hand-written <code>&lt;svg&gt;</code> is flagged.</p>
1118
1132
 
1119
- <h3 class="sub">间距 Spacing </h3>
1120
- <p>4px 基础网格,组件内外所有间距、间隙、内边距都来自此刻度,杜绝随机像素。</p>
1133
+ <h3 class="sub">Spacing</h3>
1134
+ <p>A 4px base grid. All spacing, gaps, and padding inside and outside components come from this scale — no arbitrary pixels.</p>
1121
1135
  <div class="panel panel-pad" style="margin:16px 0">
1122
- <div class="space-row"><div class="space-bar" style="width:4px"></div><div class="space-meta">--space-1 · 4</div><div class="space-use">图标间距、徽标内距</div></div>
1123
- <div class="space-row"><div class="space-bar" style="width:8px"></div><div class="space-meta">--space-2 · 8</div><div class="space-use">控件间隙、小内边距</div></div>
1124
- <div class="space-row"><div class="space-bar" style="width:12px"></div><div class="space-meta">--space-3 · 12</div><div class="space-use">按钮内距、表单项间距</div></div>
1125
- <div class="space-row"><div class="space-bar" style="width:16px"></div><div class="space-meta">--space-4 · 16</div><div class="space-use">卡片内边距、栅格 gap</div></div>
1126
- <div class="space-row"><div class="space-bar" style="width:20px"></div><div class="space-meta">--space-5 · 20</div><div class="space-use">弹窗内边距</div></div>
1127
- <div class="space-row"><div class="space-bar" style="width:24px"></div><div class="space-meta">--space-6 · 24</div><div class="space-use">区块间距</div></div>
1128
- <div class="space-row"><div class="space-bar" style="width:32px"></div><div class="space-meta">--space-8 · 32</div><div class="space-use">大区块间距</div></div>
1136
+ <div class="space-row"><div class="space-bar" style="width:4px"></div><div class="space-meta">--space-1 · 4</div><div class="space-use">icon gap, badge padding</div></div>
1137
+ <div class="space-row"><div class="space-bar" style="width:8px"></div><div class="space-meta">--space-2 · 8</div><div class="space-use">control gap, small padding</div></div>
1138
+ <div class="space-row"><div class="space-bar" style="width:12px"></div><div class="space-meta">--space-3 · 12</div><div class="space-use">button padding, form-item gap</div></div>
1139
+ <div class="space-row"><div class="space-bar" style="width:16px"></div><div class="space-meta">--space-4 · 16</div><div class="space-use">card padding, grid gap</div></div>
1140
+ <div class="space-row"><div class="space-bar" style="width:20px"></div><div class="space-meta">--space-5 · 20</div><div class="space-use">dialog padding</div></div>
1141
+ <div class="space-row"><div class="space-bar" style="width:24px"></div><div class="space-meta">--space-6 · 24</div><div class="space-use">section gap</div></div>
1142
+ <div class="space-row"><div class="space-bar" style="width:32px"></div><div class="space-meta">--space-8 · 32</div><div class="space-use">large section gap</div></div>
1129
1143
  </div>
1130
1144
 
1131
- <h4 class="mini">密集列表 Dense list(侧栏 / 文件树)</h4>
1132
- <p>侧栏这类高密度导航列表共用一套节奏,全部落在 4px 网格:<b>行内纵向内距</b> <code>--space-1</code>(4px),行间 <b>无外边距</b>(hover 圆角 pill 自身提供分隔);<b>区段间距</b>(logo / 搜索 / 操作钮 / 分组标题 / 列表之间)统一 <code>--space-2</code>(8px);<b>分组之间</b> <code>--space-2</code>;品牌页头顶部略松(<code>--space-3</code>)。新建同类列表时复用此刻度,不要手写 1/6/7/10px。</p>
1145
+ <h4 class="mini">Dense list (sidebar / file tree)</h4>
1146
+ <p>High-density navigation lists like the sidebar share one rhythm, all on the 4px grid: <b>in-row vertical padding</b> <code>--space-1</code> (4px), <b>no margin between rows</b> (the hover pill provides the separation); <b>section gap</b> (between logo / search / action buttons / group title / list) uniformly <code>--space-2</code> (8px); <b>between groups</b> <code>--space-2</code>; the brand header is slightly looser at the top (<code>--space-3</code>). When building similar lists, reuse this scale — do not hand-write 1/6/7/10px.</p>
1133
1147
 
1134
- <h3 class="sub">圆角 Radius</h3>
1135
- <p>把现有 14 个值<b>就近归并</b>到 7 档刻度。规则:组件类型决定圆角,而非作者手感。</p>
1148
+ <h3 class="sub">Radius</h3>
1149
+ <p>Merge the existing 14 values <b>into the nearest</b> of 7 scale steps. Rule: the component type determines the radius, not the author's feel.</p>
1136
1150
  <div class="radius-grid">
1137
1151
  <div class="radius-item"><div class="radius-box" style="border-radius:4px"></div><span class="rl">xs · 4</span></div>
1138
1152
  <div class="radius-item"><div class="radius-box" style="border-radius:6px"></div><span class="rl">sm · 6</span></div>
@@ -1143,312 +1157,316 @@
1143
1157
  <div class="radius-item"><div class="radius-box" style="border-radius:999px"></div><span class="rl">full · 999</span></div>
1144
1158
  </div>
1145
1159
  <table class="dt">
1146
- <thead><tr><th>Token</th><th>值</th><th>用途</th><th>归并来源</th></tr></thead>
1160
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th><th>Merged from</th></tr></thead>
1147
1161
  <tbody>
1148
- <tr><td class="tk">--radius-xs</td><td class="val">4px</td><td>小徽标、内嵌标签</td><td class="val">2/3/4px →</td></tr>
1149
- <tr><td class="tk">--radius-sm</td><td class="val">6px</td><td>小按钮、图标按钮、菜单项</td><td class="val">5/6px →</td></tr>
1150
- <tr><td class="tk">--radius-md</td><td class="val">8px</td><td>按钮、输入、徽标、卡片</td><td class="val">7/8/9px →</td></tr>
1151
- <tr><td class="tk">--radius-lg</td><td class="val">12px</td><td>下拉面板</td><td class="val">10/12px →</td></tr>
1152
- <tr><td class="tk">--radius-xl</td><td class="val">16px</td><td>弹窗、底部 Sheet、Composer</td><td class="val">14/16px →</td></tr>
1153
- <tr><td class="tk">--radius-2xl</td><td class="val">20px</td><td>强调容器 / 大面板</td><td class="val">20px</td></tr>
1154
- <tr><td class="tk">--radius-full</td><td class="val">999px</td><td>药丸徽标、头像、发送钮</td><td class="val">999px / 50%</td></tr>
1162
+ <tr><td class="tk">--radius-xs</td><td class="val">4px</td><td>small badge, inline tag</td><td class="val">2/3/4px →</td></tr>
1163
+ <tr><td class="tk">--radius-sm</td><td class="val">6px</td><td>small button, icon button, menu item</td><td class="val">5/6px →</td></tr>
1164
+ <tr><td class="tk">--radius-md</td><td class="val">8px</td><td>button, input, badge, card</td><td class="val">7/8/9px →</td></tr>
1165
+ <tr><td class="tk">--radius-lg</td><td class="val">12px</td><td>dropdown panel</td><td class="val">10/12px →</td></tr>
1166
+ <tr><td class="tk">--radius-xl</td><td class="val">16px</td><td>dialog, bottom Sheet, Composer</td><td class="val">14/16px →</td></tr>
1167
+ <tr><td class="tk">--radius-2xl</td><td class="val">20px</td><td>accent container / large panel</td><td class="val">20px</td></tr>
1168
+ <tr><td class="tk">--radius-full</td><td class="val">999px</td><td>pill badge, avatar, send button</td><td class="val">999px / 50%</td></tr>
1155
1169
  </tbody>
1156
1170
  </table>
1157
1171
 
1158
- <h3 class="sub">层级与阴影 Elevation & Z-index </h3>
1159
- <p>阴影只表达「层级」,不用作装饰(无彩色 glow)。z-index 统一成阶梯,根除 <code>9999</code> 式的互相压盖。</p>
1172
+ <h3 class="sub">Elevation &amp; z-index</h3>
1173
+ <p>Shadows express only "elevation", never decoration (no colored glow). z-index is unified into a scale, eradicating <code>9999</code>-style one-upping.</p>
1160
1174
  <div class="panel panel-pad" style="margin:16px 0">
1161
1175
  <div class="radius-grid" style="align-items:stretch">
1162
- <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 1px 2px rgba(16,24,40,.05),0 1px 3px rgba(16,24,40,.06)"></div><span class="rl">sm · 下拉菜单 / 吸顶</span></div>
1176
+ <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 1px 2px rgba(16,24,40,.05),0 1px 3px rgba(16,24,40,.06)"></div><span class="rl">sm · dropdown menu / sticky</span></div>
1163
1177
  <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 4px 12px rgba(16,24,40,.07),0 2px 4px rgba(16,24,40,.05)"></div><span class="rl">md · Toast</span></div>
1164
- <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 12px 32px rgba(16,24,40,.12),0 4px 10px rgba(16,24,40,.08)"></div><span class="rl">lg · 浮层(预留)</span></div>
1165
- <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 24px 64px rgba(16,24,40,.18),0 8px 20px rgba(16,24,40,.10)"></div><span class="rl">xl · 弹窗</span></div>
1178
+ <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 12px 32px rgba(16,24,40,.12),0 4px 10px rgba(16,24,40,.08)"></div><span class="rl">lg · overlay (reserved)</span></div>
1179
+ <div class="radius-item"><div class="radius-box" style="border:none;background:#fff;box-shadow:0 24px 64px rgba(16,24,40,.18),0 8px 20px rgba(16,24,40,.10)"></div><span class="rl">xl · dialog</span></div>
1166
1180
  </div>
1167
1181
  </div>
1168
1182
  <table class="dt">
1169
- <thead><tr><th>Z-index Token</th><th>值</th><th>用途</th></tr></thead>
1183
+ <thead><tr><th>Z-index Token</th><th>Value</th><th>Usage</th></tr></thead>
1170
1184
  <tbody>
1171
- <tr><td class="tk">--z-base</td><td class="val">0</td><td>常规流</td></tr>
1172
- <tr><td class="tk">--z-sticky</td><td class="val">100</td><td>吸顶表头 / 侧栏</td></tr>
1173
- <tr><td class="tk">--z-dropdown</td><td class="val">200</td><td>下拉菜单 / 工具提示</td></tr>
1174
- <tr><td class="tk">--z-overlay</td><td class="val">300</td><td>遮罩 / 底部 Sheet</td></tr>
1175
- <tr><td class="tk">--z-modal</td><td class="val">400</td><td>弹窗</td></tr>
1176
- <tr><td class="tk">--z-toast</td><td class="val">600</td><td>轻提示</td></tr>
1177
- <tr><td class="tk">--z-max</td><td class="val">9999</td><td>保留:仅此一档用于极端兜底</td></tr>
1185
+ <tr><td class="tk">--z-base</td><td class="val">0</td><td>normal flow</td></tr>
1186
+ <tr><td class="tk">--z-sticky</td><td class="val">100</td><td>sticky header / sidebar</td></tr>
1187
+ <tr><td class="tk">--z-dropdown</td><td class="val">200</td><td>dropdown menu / tooltip</td></tr>
1188
+ <tr><td class="tk">--z-overlay</td><td class="val">300</td><td>overlay / bottom Sheet</td></tr>
1189
+ <tr><td class="tk">--z-modal</td><td class="val">400</td><td>dialog</td></tr>
1190
+ <tr><td class="tk">--z-toast</td><td class="val">600</td><td>toast</td></tr>
1191
+ <tr><td class="tk">--z-max</td><td class="val">9999</td><td>reserved: only this tier for extreme fallback</td></tr>
1178
1192
  </tbody>
1179
1193
  </table>
1180
1194
 
1181
- <h3 class="sub">动效 Motion </h3>
1195
+ <h3 class="sub">Motion</h3>
1182
1196
  <table class="dt">
1183
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
1197
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
1184
1198
  <tbody>
1185
- <tr><td class="tk">--ease-out</td><td class="val">cubic-bezier(0.16, 1, 0.3, 1)</td><td>进入、悬停、展开</td></tr>
1186
- <tr><td class="tk">--ease-in-out</td><td class="val">cubic-bezier(0.4, 0, 0.2, 1)</td><td>面板宽度、布局变化</td></tr>
1187
- <tr><td class="tk">--duration-fast</td><td class="val">120ms</td><td>按下、焦点</td></tr>
1188
- <tr><td class="tk">--duration-base</td><td class="val">160ms</td><td>悬停、显隐</td></tr>
1189
- <tr><td class="tk">--duration-slow</td><td class="val">260ms</td><td>弹窗、Sheet、布局</td></tr>
1199
+ <tr><td class="tk">--ease-out</td><td class="val">cubic-bezier(0.16, 1, 0.3, 1)</td><td>enter, hover, expand</td></tr>
1200
+ <tr><td class="tk">--ease-in-out</td><td class="val">cubic-bezier(0.4, 0, 0.2, 1)</td><td>panel width, layout changes</td></tr>
1201
+ <tr><td class="tk">--duration-fast</td><td class="val">120ms</td><td>press, focus</td></tr>
1202
+ <tr><td class="tk">--duration-base</td><td class="val">160ms</td><td>hover, show/hide</td></tr>
1203
+ <tr><td class="tk">--duration-slow</td><td class="val">260ms</td><td>dialog, Sheet, layout</td></tr>
1190
1204
  </tbody>
1191
1205
  </table>
1192
1206
 
1193
- <h4 class="mini">减少动态效果 Reduced motion</h4>
1207
+ <h4 class="mini">Reduced motion</h4>
1194
1208
  <div class="callout info"><span class="ico">i</span><div>
1195
- 在 <code>@media (prefers-reduced-motion: reduce)</code> 下,所有动画与过渡时长降到约 <code>0.001ms</code>(即关闭),<b>MoonSpinner 月相暂停</b>在当前帧。组件不应各自判断,统一在全局样式中处理。
1209
+ Under <code>@media (prefers-reduced-motion: reduce)</code>, all animation and transition durations drop to about <code>0.001ms</code> (effectively off), and the <b>MoonSpinner moon phase pauses</b> on the current frame. Components should not check this individually; it is handled uniformly in the global styles.
1196
1210
  </div></div>
1197
1211
 
1198
- <h3 class="sub">布局与断点 Layout &amp; breakpoints </h3>
1199
- <p>布局尺寸与响应式断点同样 token 化:侧栏宽度、内容阅读栏宽度、两个全局断点。组件不应各自写死像素。</p>
1212
+ <h3 class="sub">Layout &amp; breakpoints</h3>
1213
+ <p>Layout sizes and responsive breakpoints are tokenized too: sidebar width, content reading-column width, and two global breakpoints. Components should not hard-code pixels.</p>
1200
1214
  <table class="dt">
1201
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
1215
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
1202
1216
  <tbody>
1203
- <tr><td class="tk">--p-sidebar-w</td><td class="val">264px</td><td>左侧会话侧栏宽度</td></tr>
1204
- <tr><td class="tk">--p-content-max</td><td class="val">760px</td><td>聊天阅读栏最大宽度</td></tr>
1205
- <tr><td class="tk">--p-content-wide</td><td class="val">920px</td><td>宽内容(设置 / 面板)</td></tr>
1206
- <tr><td class="tk">--p-bp-sm</td><td class="val">640px</td><td>手机 / 桌面分界</td></tr>
1207
- <tr><td class="tk">--p-bp-md</td><td class="val">980px</td><td>窄屏 / 宽屏分界</td></tr>
1217
+ <tr><td class="tk">--p-sidebar-w</td><td class="val">264px</td><td>left session sidebar width</td></tr>
1218
+ <tr><td class="tk">--p-content-max</td><td class="val">760px</td><td>chat reading-column max width</td></tr>
1219
+ <tr><td class="tk">--p-content-wide</td><td class="val">920px</td><td>wide content (settings / panel)</td></tr>
1220
+ <tr><td class="tk">--p-bp-sm</td><td class="val">640px</td><td>mobile / desktop boundary</td></tr>
1221
+ <tr><td class="tk">--p-bp-md</td><td class="val">980px</td><td>narrow / wide screen boundary</td></tr>
1208
1222
  </tbody>
1209
1223
  </table>
1210
1224
  <div class="callout info"><span class="ico">i</span><div>
1211
- ≤640px 时:弹窗改为底部 Sheet、侧栏折叠为可展开抽屉、Composer 工具条控件允许换行。
1225
+ At ≤640px: dialogs become bottom Sheets, the sidebar collapses into an expandable drawer, and Composer toolbar controls are allowed to wrap.
1212
1226
  </div></div>
1213
1227
  </section>
1214
1228
 
1215
- <!-- ===== 03 组件基元 ===== -->
1229
+ <!-- ===== 03 Primitives ===== -->
1216
1230
  <section id="primitives">
1217
1231
  <div class="sec-head">
1218
1232
  <span class="sec-num">03</span>
1219
- <h2 class="sec-title">组件基元 Primitives</h2>
1233
+ <h2 class="sec-title">Primitives</h2>
1220
1234
  </div>
1221
1235
  <p class="sec-desc">
1222
- 组件基元是全站 UI 的「最小正确单元」。
1223
- 每个基元只暴露 <code>variant</code> / <code>size</code> 两个维度的变体,外观由 token 驱动,
1224
- 从而天然支持亮 / 暗模式与可定制主题色。
1236
+ Component primitives are the "smallest correct units" of the site UI.
1237
+ Each primitive exposes variants along only two dimensions — <code>variant</code> / <code>size</code> — with appearance driven by tokens,
1238
+ so it naturally supports light / dark mode and customizable theme colors.
1225
1239
  </p>
1226
1240
 
1227
- <!-- ===== 组件选型指南 ===== -->
1228
- <h3 class="sub">组件选型指南</h3>
1241
+ <div class="callout info"><span class="ico">i</span><div>
1242
+ For every interactive primitive, the <b>keyboard behavior, focus, and ARIA contract are in §08 Accessibility</b>. New primitives must ship with a keyboard model — mouse-only interaction is not enough.
1243
+ </div></div>
1244
+
1245
+ <!-- ===== Component selection guide ===== -->
1246
+ <h3 class="sub">Component selection guide</h3>
1229
1247
  <table class="dt">
1230
- <thead><tr><th>场景</th><th>用什么</th></tr></thead>
1248
+ <thead><tr><th>Scenario</th><th>Use</th></tr></thead>
1231
1249
  <tbody>
1232
- <tr><td>主操作(提交 / 确认)</td><td><code>Button variant=primary</code></td></tr>
1233
- <tr><td>次操作 / 取消</td><td><code>Button secondary</code> / <code>ghost</code></td></tr>
1234
- <tr><td>危险操作(删除 / 中止)</td><td><code>Button danger</code> / <code>danger-soft</code></td></tr>
1235
- <tr><td>状态标记</td><td><code>Badge</code></td></tr>
1236
- <tr><td>工具条筛选 / 模型切换</td><td><code>Pill</code></td></tr>
1237
- <tr><td>2–4 项互斥切换</td><td><code>SegmentedControl</code></td></tr>
1238
- <tr><td>顶部标签页</td><td><code>Tabs</code></td></tr>
1239
- <tr><td>开关 / 多选</td><td><code>Switch</code> / <code>Checkbox</code></td></tr>
1240
- <tr><td>浮起内容卡 / 列表动作菜单</td><td><code>Card</code> / <code>Menu</code></td></tr>
1241
- <tr><td>内联通知 / 全局轻提示</td><td><code>Banner</code> / <code>Toast</code></td></tr>
1242
- <tr><td>弹窗 / 确认 · 底部面板(移动)</td><td><code>Dialog</code> / <code>Sheet</code></td></tr>
1250
+ <tr><td>Primary action (submit / confirm)</td><td><code>Button variant=primary</code></td></tr>
1251
+ <tr><td>Secondary action / cancel</td><td><code>Button secondary</code> / <code>ghost</code></td></tr>
1252
+ <tr><td>Destructive action (delete / abort)</td><td><code>Button danger</code> / <code>danger-soft</code></td></tr>
1253
+ <tr><td>Status marker</td><td><code>Badge</code></td></tr>
1254
+ <tr><td>Toolbar filter / model switch</td><td><code>Pill</code></td></tr>
1255
+ <tr><td>2–4 mutually exclusive options</td><td><code>SegmentedControl</code></td></tr>
1256
+ <tr><td>Top tabs</td><td><code>Tabs</code></td></tr>
1257
+ <tr><td>Switch / multi-select</td><td><code>Switch</code> / <code>Checkbox</code></td></tr>
1258
+ <tr><td>Floating content card / list action menu</td><td><code>Card</code> / <code>Menu</code></td></tr>
1259
+ <tr><td>Inline notice / global toast</td><td><code>Banner</code> / <code>Toast</code></td></tr>
1260
+ <tr><td>Dialog / confirmation · bottom panel (mobile)</td><td><code>Dialog</code> / <code>Sheet</code></td></tr>
1243
1261
  </tbody>
1244
1262
  </table>
1245
1263
 
1246
1264
  <!-- ===== Button ===== -->
1247
- <h3 class="sub">Button · 按钮</h3>
1248
- <p>4 个语义变体 × 3 个尺寸。主操作 <code>primary</code> 的颜色取自当前主题色(§05 可在蓝色系 / 黑色系间切换)。圆角统一走 <code>--radius-md</code>(小尺寸 <code>--radius-sm</code>),字重 600,带可见 focus 环。</p>
1265
+ <h3 class="sub">Button</h3>
1266
+ <p>4 semantic variants × 3 sizes. The primary action <code>primary</code> takes its color from the current theme color (§05 can switch between the blue and black families). Radius uses <code>--radius-md</code> uniformly (small size <code>--radius-sm</code>), weight 600, with a visible focus ring.</p>
1249
1267
  <div class="stage-wrap">
1250
- <div class="stage-bar"><span class="st">变体矩阵 <span class="tag spec">light</span></span><span class="sactions"><span class="tab on">preview</span></span></div>
1268
+ <div class="stage-bar"><span class="st">Variant matrix <span class="tag spec">light</span></span><span class="sactions"><span class="tab on">preview</span></span></div>
1251
1269
  <div class="stage p col">
1252
- <span class="stage-label">medium · 默认</span>
1270
+ <span class="stage-label">medium · default</span>
1253
1271
  <div class="demo-row">
1254
- <button class="p-btn primary">主要操作</button>
1255
- <button class="p-btn secondary">次要操作</button>
1256
- <button class="p-btn ghost">幽灵按钮</button>
1257
- <button class="p-btn danger-soft">危险(弱)</button>
1258
- <button class="p-btn danger">危险操作</button>
1272
+ <button class="p-btn primary">Primary action</button>
1273
+ <button class="p-btn secondary">Secondary action</button>
1274
+ <button class="p-btn ghost">Ghost button</button>
1275
+ <button class="p-btn danger-soft">Destructive (soft)</button>
1276
+ <button class="p-btn danger">Destructive action</button>
1259
1277
  </div>
1260
1278
  <span class="stage-label">small</span>
1261
1279
  <div class="demo-row">
1262
- <button class="p-btn primary sm">确认</button>
1263
- <button class="p-btn secondary sm">取消</button>
1264
- <button class="p-btn ghost sm">更多</button>
1280
+ <button class="p-btn primary sm">Confirm</button>
1281
+ <button class="p-btn secondary sm">Cancel</button>
1282
+ <button class="p-btn ghost sm">More</button>
1265
1283
  </div>
1266
- <span class="stage-label">带图标 / 状态</span>
1284
+ <span class="stage-label">With icon / state</span>
1267
1285
  <div class="demo-row">
1268
- <button class="p-btn primary"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>新建会话</button>
1269
- <button class="p-btn secondary"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>已复制</button>
1270
- <button class="p-btn primary disabled" >加载中…</button>
1286
+ <button class="p-btn primary"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg>New chat</button>
1287
+ <button class="p-btn secondary"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg>Copied</button>
1288
+ <button class="p-btn primary disabled" >Loading…</button>
1271
1289
  </div>
1272
1290
  </div>
1273
1291
  </div>
1274
1292
  <div class="stage-wrap">
1275
- <div class="stage-bar"><span class="st">暗色皮肤 <span class="tag spec">dark</span></span></div>
1293
+ <div class="stage-bar"><span class="st">Dark skin <span class="tag spec">dark</span></span></div>
1276
1294
  <div class="stage dark p col" data-p="dark">
1277
1295
  <div class="demo-row">
1278
- <button class="p-btn primary">主要操作</button>
1279
- <button class="p-btn secondary">次要操作</button>
1280
- <button class="p-btn ghost">幽灵按钮</button>
1281
- <button class="p-btn danger">危险操作</button>
1296
+ <button class="p-btn primary">Primary action</button>
1297
+ <button class="p-btn secondary">Secondary action</button>
1298
+ <button class="p-btn ghost">Ghost button</button>
1299
+ <button class="p-btn danger">Destructive action</button>
1282
1300
  </div>
1283
1301
  </div>
1284
1302
  </div>
1285
1303
 
1286
1304
  <h4 class="mini">API</h4>
1287
1305
  <div class="code">
1288
- <div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">Button.vue · 用法</span></div>
1289
- <pre><span class="k">&lt;Button</span> <span class="p">variant</span>=<span class="s">"primary"</span> <span class="p">size</span>=<span class="s">"md"</span> <span class="p">:loading</span>=<span class="s">"submitting"</span><span class="k">&gt;</span>保存<span class="k">&lt;/Button&gt;</span>
1306
+ <div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">Button.vue · usage</span></div>
1307
+ <pre><span class="k">&lt;Button</span> <span class="p">variant</span>=<span class="s">"primary"</span> <span class="p">size</span>=<span class="s">"md"</span> <span class="p">:loading</span>=<span class="s">"submitting"</span><span class="k">&gt;</span>Save<span class="k">&lt;/Button&gt;</span>
1290
1308
  <span class="c">// variant: primary | secondary | ghost | danger | danger-soft</span>
1291
1309
  <span class="c">// size: sm | md | lg</span></pre>
1292
1310
  </div>
1293
1311
  <div class="stage-wrap">
1294
- <div class="stage-bar"><span class="st">状态</span></div>
1312
+ <div class="stage-bar"><span class="st">States</span></div>
1295
1313
  <div class="stage p">
1296
1314
  <div class="demo-row">
1297
- <button class="p-btn primary" disabled style="opacity:.5;cursor:not-allowed">禁用 primary</button>
1298
- <button class="p-btn primary"><svg class="p-spinner sm" viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>提交中</button>
1299
- <button class="p-btn danger" disabled style="opacity:.5;cursor:not-allowed">禁用 danger</button>
1315
+ <button class="p-btn primary" disabled style="opacity:.5;cursor:not-allowed">Disabled primary</button>
1316
+ <button class="p-btn primary"><svg class="p-spinner sm" viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>Submitting</button>
1317
+ <button class="p-btn danger" disabled style="opacity:.5;cursor:not-allowed">Disabled danger</button>
1300
1318
  </div>
1301
1319
  </div>
1302
1320
  </div>
1303
1321
 
1304
1322
  <!-- ===== IconButton ===== -->
1305
- <h3 class="sub">IconButton · 图标按钮</h3>
1306
- <p>统一为 26 / 32 / 44px 三档,hover 浅灰底,focus 环可见。替代当前各组件里散落的图标 + 点击区。</p>
1323
+ <h3 class="sub">IconButton</h3>
1324
+ <p>Unified into three sizes — 26 / 32 / 44px — with a light-grey hover background and a visible focus ring. Replaces the ad-hoc icon + click areas scattered across components today.</p>
1307
1325
  <div class="stage-wrap">
1308
1326
  <div class="stage-bar"><span class="st">IconButton</span></div>
1309
1327
  <div class="stage p">
1310
- <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg></button>
1311
- <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2.5 4h11M2.5 8h11M2.5 12h11" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
1312
- <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
1313
- <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="4.5" stroke="currentColor" stroke-width="1.5"/><path d="m10.5 10.5 3 3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
1314
- <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
1328
+ <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg></button>
1329
+ <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z"/></svg></button>
1330
+ <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z"/></svg></button>
1331
+ <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z"/></svg></button>
1332
+ <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg></button>
1315
1333
  </div>
1316
1334
  </div>
1317
1335
  <div class="callout info"><span class="ico">i</span><div>
1318
- 桌面 IconButton 提供 <code>sm</code> 26 / <code>md</code> 32 两档;在触摸设备上点击目标应 ≥ 44px,用 <code>lg</code> 44px,满足 §01 的可访问性原则(移动端三件套即使用 <code>lg</code>)。
1336
+ The desktop IconButton comes in <code>sm</code> 26 / <code>md</code> 32; on touch devices the tap target should be ≥ 44px, so use <code>lg</code> 44px, satisfying the §01 accessibility principle (the mobile three-piece set uses <code>lg</code>).
1319
1337
  </div></div>
1320
1338
 
1321
1339
  <!-- ===== Badge / Pill ===== -->
1322
- <h3 class="sub">Badge · Chip · Pill </h3>
1323
- <p>收敛为两类:<b>Badge</b>(状态徽标,带可选状态点)与 <b>Pill</b>(composer 工具条的可点击药丸)。圆角、字号、内边距全部统一。</p>
1340
+ <h3 class="sub">Badge · Chip · Pill</h3>
1341
+ <p>Collapsed into two kinds: <b>Badge</b> (status badge, with an optional status dot) and <b>Pill</b> (the clickable pill in the composer toolbar). Radius, font size, and padding are all unified.</p>
1324
1342
  <div class="stage-wrap">
1325
- <div class="stage-bar"><span class="st">Badge · 状态徽标</span></div>
1343
+ <div class="stage-bar"><span class="st">Badge · status badge</span></div>
1326
1344
  <div class="stage p col">
1327
- <span class="stage-label">语义变体</span>
1345
+ <span class="stage-label">Semantic variants</span>
1328
1346
  <div class="demo-row">
1329
- <span class="p-badge neutral"><span class="bd"></span>待运行</span>
1330
- <span class="p-badge info"><span class="bd"></span>运行中</span>
1331
- <span class="p-badge success"><span class="bd"></span>已完成</span>
1332
- <span class="p-badge warning"><span class="bd"></span>需确认</span>
1333
- <span class="p-badge danger"><span class="bd"></span>失败</span>
1347
+ <span class="p-badge neutral"><span class="bd"></span>pending</span>
1348
+ <span class="p-badge info"><span class="bd"></span>running</span>
1349
+ <span class="p-badge success"><span class="bd"></span>completed</span>
1350
+ <span class="p-badge warning"><span class="bd"></span>needs confirmation</span>
1351
+ <span class="p-badge danger"><span class="bd"></span>failed</span>
1334
1352
  <span class="p-badge solid">KIMI</span>
1335
1353
  </div>
1336
- <span class="stage-label">带图标 / 小尺寸</span>
1354
+ <span class="stage-label">With icon / small size</span>
1337
1355
  <div class="demo-row">
1338
- <span class="p-badge info"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2 3.5A1.5 1.5 0 0 1 3.5 2h9A1.5 1.5 0 0 1 14 3.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 12.5v-9Z" stroke="currentColor" stroke-width="1.4"/></svg>plan</span>
1356
+ <span class="p-badge info"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1m1 2v14h14V5z"/></svg>plan</span>
1339
1357
  <span class="p-badge success sm"><span class="bd"></span>passed</span>
1340
1358
  <span class="p-badge neutral sm">read-only</span>
1341
1359
  </div>
1342
1360
  </div>
1343
1361
  </div>
1344
1362
  <div class="stage-wrap">
1345
- <div class="stage-bar"><span class="st">Pill · 工具条药丸(composer)</span></div>
1363
+ <div class="stage-bar"><span class="st">Pill · toolbar pill (composer)</span></div>
1346
1364
  <div class="stage p">
1347
- <span class="p-pill"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2 3.5h12M2 8h12M2 12.5h8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg><span class="pp-strong">kimi-k2</span><span class="pp-sub">· thinking</span><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
1365
+ <span class="p-pill"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"/></svg><span class="pp-strong">kimi-k2</span><span class="pp-sub">· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z"/></svg></span>
1348
1366
  <span class="p-pill"><span style="width:7px;height:7px;border-radius:50%;background:var(--p-warning)"></span>yolo</span>
1349
- <span class="p-pill"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.4"/><path d="M8 5v3l2 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>12k / 200k</span>
1367
+ <span class="p-pill"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m1-8h4v2h-6V7h2z"/></svg>12k / 200k</span>
1350
1368
  </div>
1351
1369
  </div>
1352
1370
 
1353
1371
  <!-- ===== Card / Surface ===== -->
1354
- <h3 class="sub">Card / Surface · 卡片与表面</h3>
1355
- <p>全站卡片共用<b>一种外壳</b>:扁平、<code>1px</code> 描边、圆角 <code>--radius-md</code>、<b>无阴影</b>。结构上分为 <code>head / body / foot</code> 三段。卡片之间的区别<b>只在头部</b>——按视觉权重分两档,外壳始终保持一致:</p>
1372
+ <h3 class="sub">Card / Surface</h3>
1373
+ <p>All cards across the site share <b>one shell</b>: flat, <code>1px</code> border, <code>--radius-md</code> radius, <b>no shadow</b>. The structure is split into three parts — <code>head / body / foot</code>. Cards differ <b>only in the head</b> — in two tiers by visual weight, while the shell stays consistent:</p>
1356
1374
  <ul class="clean">
1357
- <li><b>操作卡 Operation</b> —— 工具调用、Agent、Todo 等「过程」内容。头部紧凑 mono、无底色,默认低权重,不抢对话。</li>
1358
- <li><b>注意卡 Attention</b> —— Question / Approval 等需要用户决策的内容。头部带语义色带(accent / warning),从消息流中凸显。</li>
1375
+ <li><b>Operation card</b> —— "process" content such as tool calls, Agent, Todo. The head is compact mono with no fill, low weight by default, not competing with the conversation.</li>
1376
+ <li><b>Attention card</b> —— content that needs a user decision, such as Question / Approval. The head carries a semantic color band (accent / warning) to stand out from the message stream.</li>
1359
1377
  </ul>
1360
1378
  <div class="stage-wrap">
1361
- <div class="stage-bar"><span class="st">操作卡 · 紧凑 mono 头(无底色)</span></div>
1379
+ <div class="stage-bar"><span class="st">Operation card · compact mono head (no fill)</span></div>
1362
1380
  <div class="stage p col">
1363
1381
  <div class="p-card" style="max-width:460px">
1364
1382
  <div class="p-card-head">
1365
1383
  <span class="p-card-title">read_file</span>
1366
1384
  <span class="p-badge info sm" style="margin-left:auto">session.ts</span>
1367
1385
  </div>
1368
- <div class="p-card-body">头部使用 mono + 中性底色,强调其「代码 / 过程」属性;正文 sans 保证可读性。扁平、radius-md,与工具组、Agent 组同形。</div>
1386
+ <div class="p-card-body">The head uses mono + a neutral background to emphasize its "code / process" nature; the body uses sans for readability. Flat, radius-md, same shape as the tool group and Agent group.</div>
1369
1387
  </div>
1370
1388
  </div>
1371
1389
  </div>
1372
1390
  <div class="stage-wrap">
1373
- <div class="stage-bar"><span class="st">注意卡 · 语义色带头(accent / warning)</span></div>
1391
+ <div class="stage-bar"><span class="st">Attention card · semantic color-band head (accent / warning)</span></div>
1374
1392
  <div class="stage p col">
1375
1393
  <div class="p-action" style="max-width:460px">
1376
- <div class="p-action-head"><span class="p-action-title">需要你确认一个决定</span><span class="p-badge info sm" style="margin-left:auto">question</span></div>
1377
- <div class="p-action-body">头部使用语义色浅底(<code>accent-soft</code> / <code>warning-soft</code>),从消息流中凸显,提示用户必须介入。外壳与操作卡完全相同。</div>
1394
+ <div class="p-action-head"><span class="p-action-title">A decision needs your confirmation</span><span class="p-badge info sm" style="margin-left:auto">question</span></div>
1395
+ <div class="p-action-body">The head uses a semantic light background (<code>accent-soft</code> / <code>warning-soft</code>) to stand out from the message stream, signaling that the user must step in. The shell is exactly the same as the operation card.</div>
1378
1396
  </div>
1379
1397
  </div>
1380
1398
  </div>
1381
1399
  <div class="stage-wrap">
1382
- <div class="stage-bar"><span class="st">分组 · 容器拥有边框,行间发丝分隔</span></div>
1400
+ <div class="stage-bar"><span class="st">Group · the container owns the border, rows are separated by hairlines</span></div>
1383
1401
  <div class="stage p col">
1384
1402
  <div class="p-tool-group open" style="max-width:460px">
1385
- <div class="p-tool-group-head"><span class="p-dot done"></span><span class="tg-title">3 个工具调用</span><span class="tg-meta">· 已完成</span></div>
1403
+ <div class="p-tool-group-head"><span class="p-dot done"></span><span class="tg-title">3 tool calls</span><span class="tg-meta">· completed</span></div>
1386
1404
  <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">read_file</span><span class="tr-arg">session.ts</span></div>
1387
- <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">grep</span><span class="tr-arg">"jwt" · 4 处</span></div>
1405
+ <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">grep</span><span class="tr-arg">"jwt" · 4 hits</span></div>
1388
1406
  </div>
1389
1407
  </div>
1390
1408
  </div>
1391
1409
  <ul class="clean check">
1392
- <li><b>统一外壳</b>:所有卡片扁平 + 1px 描边 + radius-md,不投射阴影。</li>
1393
- <li><b>差异有意为之</b>:仅头部区分类型(mono 紧凑 vs 语义色带),外壳始终保持一致。</li>
1394
- <li><b>分组</b>:外层容器拥有边框与圆角,内部行用 <code>border-top</code> 发丝分隔,不再让每行各自成卡。</li>
1395
- <li><b>状态点</b>:运行中(脉冲蓝)/ 完成(绿)/ 失败(红),共用同一套颜色词汇(详见 §04 工具调用)。</li>
1410
+ <li><b>Unified shell</b>: all cards are flat + 1px border + radius-md, casting no shadow.</li>
1411
+ <li><b>Differences are intentional</b>: only the head distinguishes the type (compact mono vs semantic color band); the shell stays consistent.</li>
1412
+ <li><b>Grouping</b>: the outer container owns the border and radius; inner rows are separated by <code>border-top</code> hairlines, rather than each row being its own card.</li>
1413
+ <li><b>Status dots</b>: running (pulsing blue) / done (green) / failed (red), sharing one color vocabulary (see §04 tool calls).</li>
1396
1414
  </ul>
1397
1415
 
1398
1416
  <!-- ===== Input ===== -->
1399
- <h3 class="sub">Input / Select / Textarea · 表单输入 </h3>
1400
- <p>统一高度 38px(小尺寸 32px)、圆角 <code>--radius-md</code>、<code>--color-surface-raised</code> 底、统一蓝色焦点环(<code>0 0 0 3px accent-soft</code>)。</p>
1417
+ <h3 class="sub">Input / Select / Textarea</h3>
1418
+ <p>Unified 38px height (32px small), <code>--radius-md</code> radius, <code>--color-surface-raised</code> background, and a unified blue focus ring (<code>0 0 0 3px accent-soft</code>).</p>
1401
1419
  <div class="stage-wrap">
1402
- <div class="stage-bar"><span class="st">表单基元</span></div>
1420
+ <div class="stage-bar"><span class="st">Form primitives</span></div>
1403
1421
  <div class="stage p col">
1404
1422
  <div class="demo-row" style="align-items:flex-start">
1405
1423
  <div class="p-field demo-grow">
1406
- <label class="p-label">工作区名称</label>
1407
- <input class="p-input" placeholder="例如:frontend" />
1408
- <span class="p-hint">只能包含字母、数字与连字符。</span>
1424
+ <label class="p-label">Workspace name</label>
1425
+ <input class="p-input" placeholder="e.g. frontend" />
1426
+ <span class="p-hint">Only letters, numbers, and hyphens are allowed.</span>
1409
1427
  </div>
1410
1428
  <div class="p-field demo-grow">
1411
- <label class="p-label">模型提供方</label>
1429
+ <label class="p-label">Model provider</label>
1412
1430
  <select class="p-select"><option>Anthropic</option><option>OpenAI</option><option>Moonshot</option></select>
1413
1431
  </div>
1414
1432
  </div>
1415
1433
  <div class="p-field">
1416
- <label class="p-label">系统提示词</label>
1417
- <textarea class="p-textarea" placeholder="描述这个 Agent 的角色与边界……"></textarea>
1434
+ <label class="p-label">System prompt</label>
1435
+ <textarea class="p-textarea" placeholder="Describe this Agent's role and boundaries…"></textarea>
1418
1436
  </div>
1419
1437
  </div>
1420
1438
  </div>
1421
1439
  <div class="stage-wrap">
1422
- <div class="stage-bar"><span class="st">状态</span></div>
1440
+ <div class="stage-bar"><span class="st">States</span></div>
1423
1441
  <div class="stage p col">
1424
1442
  <div class="demo-row" style="align-items:flex-start">
1425
1443
  <div class="p-field demo-grow">
1426
- <label class="p-label">工作区名称</label>
1444
+ <label class="p-label">Workspace name</label>
1427
1445
  <input class="p-input" value="my workspace!" style="border-color:var(--p-danger)" />
1428
- <span class="p-field-error">请输入有效的工作区名称</span>
1446
+ <span class="p-field-error">Please enter a valid workspace name</span>
1429
1447
  </div>
1430
1448
  <div class="p-field demo-grow">
1431
- <label class="p-label">显示名</label>
1449
+ <label class="p-label">Display name</label>
1432
1450
  <input class="p-input" value="frontend" />
1433
- <span class="p-hint">正常态 · 通过校验</span>
1451
+ <span class="p-hint">Normal state · validation passed</span>
1434
1452
  </div>
1435
1453
  </div>
1436
1454
  </div>
1437
1455
  </div>
1438
1456
 
1439
1457
  <!-- ===== Code / Diff ===== -->
1440
- <h3 class="sub">Code / Diff · 代码与差异</h3>
1441
- <p>inline code、代码块、diff 三档均使用等宽字体(<code>--p-font-mono</code>);代码块带文件名标题条与复制按钮;diff 用 <code>+</code> / <code>-</code> 行色表达增删——新增用成功浅底、删除用危险浅底,无渐变。</p>
1458
+ <h3 class="sub">Code / Diff</h3>
1459
+ <p>Inline code, code blocks, and diffs all use the monospace font (<code>--p-font-mono</code>). Code blocks have a filename title bar and a copy button. Diffs use <code>+</code> / <code>-</code> row colors to express additions and deletions — additions use a success light background, deletions use a danger light background, with no gradients.</p>
1442
1460
  <div class="stage-wrap">
1443
1461
  <div class="stage-bar"><span class="st">Code / Diff</span></div>
1444
1462
  <div class="stage p col">
1445
1463
  <span class="stage-label">inline code</span>
1446
- <div>服务端用 <code class="p-code-inline">jwt.verify(token)</code> 校验签名,失败返回 401。</div>
1464
+ <div>The server uses <code class="p-code-inline">jwt.verify(token)</code> to verify the signature, returning 401 on failure.</div>
1447
1465
  <span class="stage-label">code block</span>
1448
1466
  <div class="p-code-block">
1449
1467
  <div class="p-code-block-head">
1450
1468
  <span>session.ts</span>
1451
- <button class="p-icon-btn sm" aria-label="复制"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="5" width="8" height="8" rx="1.5"/><path d="M3 10V3.5A1.5 1.5 0 0 1 4.5 2H10"/></svg></button>
1469
+ <button class="p-icon-btn sm" aria-label="Copy"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z"/></svg></button>
1452
1470
  </div>
1453
1471
  <pre>import { verify } from './jwt';
1454
1472
 
@@ -1468,154 +1486,154 @@ export function auth(token: string) {
1468
1486
  </div>
1469
1487
 
1470
1488
  <!-- ===== Dialog ===== -->
1471
- <h3 class="sub">Dialog · 弹窗 </h3>
1472
- <p>一套弹窗基元替代 6 套手写实现:统一圆角 <code>--radius-xl</code>、阴影 <code>--shadow-xl</code>、头部 20px、底部操作右对齐、关闭按钮用 IconButton。</p>
1489
+ <h3 class="sub">Dialog</h3>
1490
+ <p>One dialog primitive replaces 6 hand-written implementations: unified <code>--radius-xl</code> radius, <code>--shadow-xl</code> shadow, 20px head padding, right-aligned footer actions, and an IconButton close button.</p>
1473
1491
  <div class="stage-wrap">
1474
- <div class="stage-bar"><span class="st">Dialog 基元 </span></div>
1492
+ <div class="stage-bar"><span class="st">Dialog primitive</span></div>
1475
1493
  <div class="stage p col" style="align-items:center">
1476
1494
  <div class="p-dialog">
1477
1495
  <div class="p-dialog-head">
1478
1496
  <div>
1479
- <div class="p-dialog-title">新建会话</div>
1480
- <div class="p-dialog-desc">为当前工作区创建一个独立的 Agent 会话。</div>
1497
+ <div class="p-dialog-title">New chat</div>
1498
+ <div class="p-dialog-desc">Create an independent Agent chat in the current workspace.</div>
1481
1499
  </div>
1482
- <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
1500
+ <button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z"/></svg></button>
1483
1501
  </div>
1484
1502
  <div class="p-dialog-body">
1485
1503
  <div class="p-field">
1486
- <label class="p-label">会话标题(可选)</label>
1487
- <input class="p-input" placeholder="自动生成" />
1504
+ <label class="p-label">Chat title (optional)</label>
1505
+ <input class="p-input" placeholder="Generated automatically" />
1488
1506
  </div>
1489
1507
  </div>
1490
1508
  <div class="p-dialog-foot">
1491
- <button class="p-btn secondary">取消</button>
1492
- <button class="p-btn primary">创建</button>
1509
+ <button class="p-btn secondary">Cancel</button>
1510
+ <button class="p-btn primary">Create</button>
1493
1511
  </div>
1494
1512
  </div>
1495
1513
  </div>
1496
1514
  </div>
1497
1515
 
1498
1516
  <div class="callout info"><span class="ico">i</span><div>
1499
- <b>尺寸与高度</b>:Dialog 提供三档宽度 <code>md</code> 440 / <code>lg</code> 640 / <code>xl</code> 760(<code>--p-content-max</code>),按内容分量选择。高度分两种:<code>auto</code>(默认,随内容至 <code>max-height</code>)与 <code>fixed</code>(恒定高度 <code>min(680px, 100vh - 64px)</code>,内容超出由 body 内部滚动)。<b>内容型 / 多 tab 弹窗</b>(设置、模型选择、提供方管理、文件夹浏览)一律用 <code>fixed</code>,使框体尺寸恒定、不随切换 tab 或内容多少而跳动;内容少的确认类弹窗保持 <code>auto</code>。
1517
+ <b>Size &amp; height</b>: Dialog offers three widths — <code>md</code> 440 / <code>lg</code> 640 / <code>xl</code> 760 (<code>--p-content-max</code>) — chosen by content weight. Height comes in two kinds: <code>auto</code> (default, grows with content up to <code>max-height</code>) and <code>fixed</code> (constant height <code>min(680px, 100vh - 64px)</code>, with overflow scrolled inside the body). <b>Content / multi-tab dialogs</b> (settings, model picker, provider manager, folder browser) always use <code>fixed</code> so the frame size stays constant and doesn't jump when switching tabs or content length; short confirmation dialogs keep <code>auto</code>.
1500
1518
  </div></div>
1501
1519
 
1502
1520
  <!-- ===== Toast ===== -->
1503
- <h3 class="sub">Toast · 轻提示</h3>
1504
- <p>统一信息架构:状态图标 + 标题 + 描述。状态色只出现在图标上,避免大面积彩色造成视觉噪音。</p>
1521
+ <h3 class="sub">Toast</h3>
1522
+ <p>Unified information architecture: status icon + title + description. The status color appears only on the icon, avoiding large colored areas that create visual noise.</p>
1505
1523
  <div class="stage-wrap">
1506
1524
  <div class="stage-bar"><span class="st">Toast</span></div>
1507
1525
  <div class="stage p col">
1508
1526
  <div class="p-toast success">
1509
- <span class="ti"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
1510
- <div><div class="tt">已连接到服务器</div><div class="td">本地守护进程响应正常,可以开始新会话。</div></div>
1527
+ <span class="ti"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg></span>
1528
+ <div><div class="tt">Connected to server</div><div class="td">The local daemon is responding normally; you can start a new chat.</div></div>
1511
1529
  </div>
1512
1530
  <div class="p-toast warning">
1513
- <span class="ti"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M8 2 14 13H2L8 2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="11" r=".6" fill="currentColor"/></svg></span>
1514
- <div><div class="tt">上下文使用 82%</div><div class="td">建议执行 /compact 以释放空间。</div></div>
1531
+ <span class="ti"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z"/></svg></span>
1532
+ <div><div class="tt">Context usage 82%</div><div class="td">Consider running /compact to free up space.</div></div>
1515
1533
  </div>
1516
1534
  </div>
1517
1535
  </div>
1518
1536
 
1519
1537
  <!-- ===== Spinner ===== -->
1520
- <h3 class="sub">Spinner · 加载指示器</h3>
1521
- <p>加载器按场景分两类,<b>不要混用</b>:</p>
1538
+ <h3 class="sub">Spinner</h3>
1539
+ <p>Loaders fall into two categories by scenario — <b>do not mix them</b>:</p>
1522
1540
  <ul class="clean">
1523
- <li><b>Spinner(普通 · SVG 环形)</b>—— 默认加载器。用于按钮 loading、应用启动(GlobalLoading)、通用内联等待等「其他所有情况」。</li>
1524
- <li><b>MoonSpinner(月相 · 品牌特色)</b>—— <b>仅</b>用于「发出消息、等待 Agent 首条响应」这一聊天等待态(ChatPane 的 sending 占位、SideChatPanel、ActivityNotice)。</li>
1541
+ <li><b>Spinner (plain · SVG ring)</b> —— the default loader. Used for button loading, app startup (GlobalLoading), and general inline waits — "everything else".</li>
1542
+ <li><b>MoonSpinner (moon phase · brand signature)</b> —— used <b>only</b> for the chat waiting state of "message sent, waiting for the Agent's first response" (the sending placeholder in ChatPane, SideChatPanel, ActivityNotice).</li>
1525
1543
  </ul>
1526
1544
 
1527
- <h4 class="mini">Spinner · 普通加载器(默认)</h4>
1545
+ <h4 class="mini">Spinner · plain loader (default)</h4>
1528
1546
  <div class="stage-wrap">
1529
- <div class="stage-bar"><span class="st">Spinner · 常规场景</span></div>
1547
+ <div class="stage-bar"><span class="st">Spinner · common scenarios</span></div>
1530
1548
  <div class="stage p col">
1531
1549
  <div class="demo-row">
1532
1550
  <svg class="p-spinner" viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>
1533
- <span class="p-thinking"><svg class="p-spinner sm" viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>加载中…</span>
1534
- <button class="p-btn primary disabled"><svg class="p-spinner sm" viewBox="0 0 24 24" style="--p-accent:#fff;--p-line:rgba(255,255,255,.35)"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>提交中</button>
1551
+ <span class="p-thinking"><svg class="p-spinner sm" viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>Loading…</span>
1552
+ <button class="p-btn primary disabled"><svg class="p-spinner sm" viewBox="0 0 24 24" style="--p-accent:#fff;--p-line:rgba(255,255,255,.35)"><circle class="track" cx="12" cy="12" r="9"/><circle class="arc" cx="12" cy="12" r="9"/></svg>Submitting</button>
1535
1553
  </div>
1536
1554
  </div>
1537
1555
  </div>
1538
1556
 
1539
- <h4 class="mini">MoonSpinner · 月相(仅「等待 Agent 响应」)</h4>
1557
+ <h4 class="mini">MoonSpinner · moon phase (only "waiting for the Agent")</h4>
1540
1558
  <div class="stage-wrap">
1541
- <div class="stage-bar"><span class="st">MoonSpinner · 聊天等待态专属 <span class="tag spec">特色</span></span></div>
1559
+ <div class="stage-bar"><span class="st">MoonSpinner · chat waiting state only <span class="tag spec">signature</span></span></div>
1542
1560
  <div class="stage p col">
1543
- <span class="stage-label">帧循环(8 帧)</span>
1561
+ <span class="stage-label">Frame loop (8 frames)</span>
1544
1562
  <div class="demo-row" style="font-size:22px;letter-spacing:2px;line-height:1">
1545
1563
  <span>🌑</span><span>🌒</span><span>🌓</span><span>🌔</span><span>🌕</span><span>🌖</span><span>🌗</span><span>🌘</span>
1546
1564
  </div>
1547
- <span class="stage-label">用法 · 仅聊天等待响应</span>
1565
+ <span class="stage-label">Usage · only while the chat waits for a response</span>
1548
1566
  <div class="demo-row">
1549
- <span class="p-thinking"><span style="font-size:16px;line-height:1">🌔</span>正在思考…</span>
1550
- <span class="p-thinking"><span style="font-size:16px;line-height:1">🌕</span>正在等待响应…</span>
1567
+ <span class="p-thinking"><span style="font-size:16px;line-height:1">🌔</span>Thinking…</span>
1568
+ <span class="p-thinking"><span style="font-size:16px;line-height:1">🌕</span>Waiting for response…</span>
1551
1569
  </div>
1552
1570
  </div>
1553
1571
  </div>
1554
- <div class="callout info"><span class="ico">i</span><div>月相是 emoji-as-icon 规则的<b>唯一豁免</b>,且<b>仅限</b>「等待 Agent 首条响应」这一场景。当前它在 <code>MoonSpinner.vue</code> 与 <code>ActivityNotice.vue</code> 各实现了一遍,应合并为单个 <code>MoonSpinner</code> 组件,尺寸走 token、支持 <code>prefers-reduced-motion</code>。其余所有加载态一律用普通 Spinner。</div></div>
1572
+ <div class="callout info"><span class="ico">i</span><div>The moon phase is the <b>sole exception</b> to the emoji-as-icon rule, and is <b>limited</b> to the "waiting for the Agent's first response" scenario. It is currently implemented twice — in <code>MoonSpinner.vue</code> and <code>ActivityNotice.vue</code> — and should be merged into a single <code>MoonSpinner</code> component, sized via tokens and supporting <code>prefers-reduced-motion</code>. All other loading states use the plain Spinner.</div></div>
1555
1573
 
1556
1574
  <!-- ===== Link ===== -->
1557
- <h3 class="sub">Link · 文字链接</h3>
1558
- <p>行内文本链接:默认主色、无下划线,hover 显示下划线并加深;<code>.muted</code> 变体用次级文字色。用于文本内跳转、外链、「查看全部」等轻量操作。</p>
1575
+ <h3 class="sub">Link</h3>
1576
+ <p>Inline text link: the default is the accent color with no underline; on hover it shows an underline and darkens. The <code>.muted</code> variant uses the secondary text color. Used for in-text jumps, external links, "view all", and other lightweight actions.</p>
1559
1577
  <div class="stage-wrap">
1560
- <div class="stage-bar"><span class="st">Link · 行内链接</span></div>
1578
+ <div class="stage-bar"><span class="st">Link · inline link</span></div>
1561
1579
  <div class="stage p col">
1562
1580
  <div class="demo-row" style="font-size:var(--p-font-size-base);color:var(--p-text)">
1563
- <span>阅读完整 <a class="p-link" href="#">设计令牌文档</a> 后再动手。</span>
1564
- <a class="p-link" href="#">在 GitHub 查看<svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M6 3H3.5A1.5 1.5 0 0 0 2 4.5v8A1.5 1.5 0 0 0 3.5 14h8a1.5 1.5 0 0 0 1.5-1.5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M9 2h5v5M14 2 7.5 8.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
1565
- <a class="p-link muted" href="#">查看历史记录</a>
1581
+ <span>Read the full <a class="p-link" href="#">design token docs</a> before building.</span>
1582
+ <a class="p-link" href="#">View on GitHub<svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"/></svg></a>
1583
+ <a class="p-link muted" href="#">View history</a>
1566
1584
  </div>
1567
1585
  </div>
1568
1586
  </div>
1569
1587
 
1570
1588
  <!-- ===== Menu / Dropdown ===== -->
1571
- <h3 class="sub">Menu / Dropdown · 菜单</h3>
1572
- <p>下拉菜单面板:浮起表面 + 描边 + 轻阴影(<code>--shadow-sm</code>,扁平化取向)。菜单项支持图标、当前态(active)、危险态(danger)、禁用态,项与项之间用分隔线分组。触摸 / 移动端用 <code>lg</code>(≥44px 行高)作为菜单项。</p>
1589
+ <h3 class="sub">Menu / Dropdown</h3>
1590
+ <p>Dropdown menu panel: raised surface + border + light shadow (<code>--shadow-sm</code>, flat-leaning). Menu items support icons, the current (active) state, the danger state, and the disabled state, with separators grouping items. On touch / mobile, use <code>lg</code> (≥44px row height) for menu items.</p>
1573
1591
  <div class="stage-wrap">
1574
- <div class="stage-bar"><span class="st">Menu · 下拉菜单</span></div>
1592
+ <div class="stage-bar"><span class="st">Menu · dropdown menu</span></div>
1575
1593
  <div class="stage p col" style="align-items:flex-start">
1576
1594
  <div class="p-menu">
1577
- <div class="p-menu-item"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 3h7l3 3v7H3V3Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>打开文件</div>
1578
- <div class="p-menu-item active"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>已选中项</div>
1579
- <div class="p-menu-item disabled"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.4"/></svg>不可用项</div>
1595
+ <div class="p-menu-item"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg>Open file</div>
1596
+ <div class="p-menu-item active"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg>Selected item</div>
1597
+ <div class="p-menu-item disabled"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M8.523 7.109l8.368 8.368a6 6 0 0 1-1.414 1.414L7.109 8.523A6 6 0 0 1 8.523 7.11"/></svg>Disabled item</div>
1580
1598
  <div class="p-menu-sep"></div>
1581
- <div class="p-menu-item danger"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>删除会话</div>
1599
+ <div class="p-menu-item danger"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z"/></svg>Delete chat</div>
1582
1600
  </div>
1583
1601
  </div>
1584
1602
  </div>
1585
1603
 
1586
1604
  <!-- ===== SegmentedControl ===== -->
1587
- <h3 class="sub">SegmentedControl · 分段控件</h3>
1588
- <p>互斥的短选项组,常见于「浅色 / 深色 / 跟随系统」这类 2–4 项切换。当前项以浮起表面 + 微阴影突出。</p>
1605
+ <h3 class="sub">SegmentedControl</h3>
1606
+ <p>Mutually exclusive short option groups, commonly used for 2–4 option switches such as "light / dark / follow system". The current item is highlighted with a raised surface + subtle shadow.</p>
1589
1607
  <div class="stage-wrap">
1590
- <div class="stage-bar"><span class="st">SegmentedControl · 分段控件</span></div>
1608
+ <div class="stage-bar"><span class="st">SegmentedControl</span></div>
1591
1609
  <div class="stage p col">
1592
1610
  <div class="p-seg">
1593
- <span class="p-seg-item on">浅色</span>
1594
- <span class="p-seg-item">深色</span>
1595
- <span class="p-seg-item">跟随系统</span>
1611
+ <span class="p-seg-item on">Light</span>
1612
+ <span class="p-seg-item">Dark</span>
1613
+ <span class="p-seg-item">Follow system</span>
1596
1614
  </div>
1597
1615
  </div>
1598
1616
  </div>
1599
1617
 
1600
1618
  <!-- ===== Tabs ===== -->
1601
- <h3 class="sub">Tabs · 标签页</h3>
1602
- <p>带底部细线的标签页,用于同级内容的分组切换。当前标签以主色文字 + 主色下划线标示。</p>
1619
+ <h3 class="sub">Tabs</h3>
1620
+ <p>Tabs with a bottom hairline, used for grouping and switching sibling content. The current tab is marked with accent text + an accent underline.</p>
1603
1621
  <div class="stage-wrap">
1604
- <div class="stage-bar"><span class="st">Tabs · 标签页</span></div>
1622
+ <div class="stage-bar"><span class="st">Tabs</span></div>
1605
1623
  <div class="stage p col">
1606
1624
  <div class="p-tabs">
1607
- <span class="p-tab on">通用</span>
1625
+ <span class="p-tab on">General</span>
1608
1626
  <span class="p-tab">Agent</span>
1609
- <span class="p-tab">高级</span>
1627
+ <span class="p-tab">Advanced</span>
1610
1628
  </div>
1611
1629
  </div>
1612
1630
  </div>
1613
1631
 
1614
1632
  <!-- ===== Switch ===== -->
1615
- <h3 class="sub">Switch · 开关</h3>
1616
- <p>二态开关,用于即时生效的设置项。轨道 36×20、圆角全圆,滑块 16px;开启时轨道变主色、滑块右移,过渡走 token。</p>
1633
+ <h3 class="sub">Switch</h3>
1634
+ <p>A two-state switch for settings that take effect immediately. 36×20 track with full radius, 16px knob; when on, the track turns accent and the knob slides right, with the transition driven by tokens.</p>
1617
1635
  <div class="stage-wrap">
1618
- <div class="stage-bar"><span class="st">Switch · 开关</span></div>
1636
+ <div class="stage-bar"><span class="st">Switch</span></div>
1619
1637
  <div class="stage p">
1620
1638
  <span class="p-switch on"></span>
1621
1639
  <span class="p-switch"></span>
@@ -1623,52 +1641,52 @@ export function auth(token: string) {
1623
1641
  </div>
1624
1642
 
1625
1643
  <!-- ===== Checkbox ===== -->
1626
- <h3 class="sub">Checkbox · 复选框</h3>
1627
- <p>17×17 复选框,选中时填充主色并显示白色对勾(inline SVG)。常配合文本标签使用。</p>
1644
+ <h3 class="sub">Checkbox</h3>
1645
+ <p>A 17×17 checkbox. When checked it fills with the accent color and shows a white tick (inline SVG). Often paired with a text label.</p>
1628
1646
  <div class="stage-wrap">
1629
- <div class="stage-bar"><span class="st">Checkbox · 复选框</span></div>
1647
+ <div class="stage-bar"><span class="st">Checkbox</span></div>
1630
1648
  <div class="stage p">
1631
- <span class="p-check on"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
1649
+ <span class="p-check on"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg></span>
1632
1650
  <span class="p-check"></span>
1633
- <label style="display:inline-flex;align-items:center;gap:8px;color:var(--p-text);font-size:var(--p-font-size-base);cursor:pointer"><span class="p-check on"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M3 8.5 6.5 12 13 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>启用自动保存</label>
1651
+ <label style="display:inline-flex;align-items:center;gap:8px;color:var(--p-text);font-size:var(--p-font-size-base);cursor:pointer"><span class="p-check on"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z"/></svg></span>Enable auto-save</label>
1634
1652
  </div>
1635
1653
  </div>
1636
1654
 
1637
1655
  <!-- ===== Avatar ===== -->
1638
- <h3 class="sub">Avatar · 头像 </h3>
1639
- <p>32px 默认头像,圆角 md;<code>.sm</code> 24px。可放首字母或图标,无图片时落回此占位。</p>
1656
+ <h3 class="sub">Avatar</h3>
1657
+ <p>A 32px default avatar with md radius; <code>.sm</code> is 24px. Can hold an initial or an icon; falls back to this placeholder when there is no image.</p>
1640
1658
  <div class="stage-wrap">
1641
1659
  <div class="stage-bar"><span class="st">Avatar</span></div>
1642
1660
  <div class="stage p">
1643
1661
  <span class="p-avatar">K</span>
1644
- <span class="p-avatar"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor"><circle cx="8" cy="5.5" r="2.5" stroke-width="1.5"/><path d="M3 13c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5" stroke-width="1.5" stroke-linecap="round"/></svg></span>
1662
+ <span class="p-avatar"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 0 0-12 0zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6s6 2.685 6 6s-2.685 6-6 6m0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4s-4 1.79-4 4s1.79 4 4 4"/></svg></span>
1645
1663
  <span class="p-avatar sm">K</span>
1646
1664
  </div>
1647
1665
  </div>
1648
1666
 
1649
1667
  <!-- ===== EmptyState ===== -->
1650
- <h3 class="sub">EmptyState · 空状态 </h3>
1651
- <p>列表 / 面板无内容时的居中占位:48px 淡色图标 + 标题 + 提示,避免空白页。</p>
1668
+ <h3 class="sub">EmptyState</h3>
1669
+ <p>A centered placeholder for empty lists / panels: a 48px faint icon + title + hint, avoiding blank pages.</p>
1652
1670
  <div class="stage-wrap">
1653
1671
  <div class="stage-bar"><span class="st">EmptyState</span></div>
1654
1672
  <div class="stage p col">
1655
1673
  <div class="p-empty" style="width:100%;border:1px dashed var(--p-line);border-radius:var(--p-r-lg)">
1656
- <svg class="em-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor"><path d="M3 4.5A1.5 1.5 0 0 1 4.5 3h7A1.5 1.5 0 0 1 13 4.5v5A1.5 1.5 0 0 1 11.5 11H7l-3 2.5V11H4.5A1.5 1.5 0 0 1 3 9.5z" stroke-width="1.3" stroke-linejoin="round"/></svg>
1657
- <div class="em-title">暂无会话</div>
1658
- <div class="em-hint">点击「新建会话」开始与 Kimi 对话</div>
1674
+ <svg class="em-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1zm-.692-2H20V5H4v13.385zM8 10h8v2H8z"/></svg>
1675
+ <div class="em-title">No chats yet</div>
1676
+ <div class="em-hint">Click "New chat" to start a conversation with Kimi</div>
1659
1677
  </div>
1660
1678
  </div>
1661
1679
  </div>
1662
1680
 
1663
1681
  <!-- ===== Divider ===== -->
1664
- <h3 class="sub">Divider · 分隔线 </h3>
1665
- <p>1px 水平分隔线(<code>--p-line</code>);<code>.p-divider-v</code> 为垂直分隔,用于行内元素之间。</p>
1682
+ <h3 class="sub">Divider</h3>
1683
+ <p>A 1px horizontal divider (<code>--p-line</code>); <code>.p-divider-v</code> is the vertical divider, used between inline elements.</p>
1666
1684
  <div class="stage-wrap">
1667
1685
  <div class="stage-bar"><span class="st">Divider</span></div>
1668
1686
  <div class="stage p col">
1669
- <div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text)">上方内容</div>
1687
+ <div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text)">Content above</div>
1670
1688
  <hr class="p-divider">
1671
- <div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text)">下方内容</div>
1689
+ <div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text)">Content below</div>
1672
1690
  <div style="display:flex;align-items:center;gap:10px;height:24px;font-size:var(--p-font-size-sm);color:var(--p-text)">
1673
1691
  <span>kimi-k2</span>
1674
1692
  <span class="p-divider-v"></span>
@@ -1678,38 +1696,38 @@ export function auth(token: string) {
1678
1696
  </div>
1679
1697
 
1680
1698
  <!-- ===== Tooltip ===== -->
1681
- <h3 class="sub">Tooltip · 工具提示 </h3>
1682
- <p>CSS-only 悬停提示,包在 <code>.p-tip</code> 内。反色底(<code>--p-text</code> / <code>--p-bg</code>),单行不换行,仅承载简短说明。</p>
1699
+ <h3 class="sub">Tooltip</h3>
1700
+ <p>A CSS-only hover hint, wrapped in <code>.p-tip</code>. Inverted background (<code>--p-text</code> / <code>--p-bg</code>), single line, no wrapping — carries only short notes.</p>
1683
1701
  <div class="stage-wrap">
1684
- <div class="stage-bar"><span class="st">Tooltip(悬停按钮)</span></div>
1702
+ <div class="stage-bar"><span class="st">Tooltip (hover the button)</span></div>
1685
1703
  <div class="stage p">
1686
1704
  <span class="p-tip">
1687
- <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor"><path d="M8 3v10M3 8h10" stroke-width="1.7" stroke-linecap="round"/></svg></button>
1688
- <span class="p-tooltip">新建会话</span>
1705
+ <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg></button>
1706
+ <span class="p-tooltip">New chat</span>
1689
1707
  </span>
1690
1708
  </div>
1691
1709
  </div>
1692
1710
 
1693
1711
  <!-- ===== Banner ===== -->
1694
- <h3 class="sub">Banner · 横幅通知 </h3>
1695
- <p>内联通知条,置于内容区顶部。三态 <code>.info</code> / <code>.warning</code> / <code>.danger</code>,各配同色 18px 图标。</p>
1712
+ <h3 class="sub">Banner</h3>
1713
+ <p>An inline notice bar placed at the top of a content area. Three states — <code>.info</code> / <code>.warning</code> / <code>.danger</code> — each with a matching 18px icon.</p>
1696
1714
  <div class="stage-wrap">
1697
1715
  <div class="stage-bar"><span class="st">Banner</span></div>
1698
1716
  <div class="stage p col">
1699
- <div class="p-banner info"><svg class="bn-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor"><circle cx="8" cy="8" r="6.5" stroke-width="1.5"/><path d="M8 7v4" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="5" r=".7" fill="currentColor" stroke="none"/></svg>已连接到服务器</div>
1700
- <div class="p-banner warning"><svg class="bn-ic" viewBox="0 0 16 16" fill="none" stroke="currentColor"><path d="M8 2 14 13H2z" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="10.5" r=".7" fill="currentColor" stroke="none"/></svg>当前处于 yolo 模式,工具调用将自动执行</div>
1717
+ <div class="p-banner info"><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M11 7h2v2h-2zm0 4h2v6h-2z"/></svg>Connected to server</div>
1718
+ <div class="p-banner warning"><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z"/></svg>Currently in yolo mode; tool calls will run automatically</div>
1701
1719
  </div>
1702
1720
  </div>
1703
1721
 
1704
1722
  <!-- ===== Sheet / BottomSheet ===== -->
1705
- <h3 class="sub">Sheet / BottomSheet · 底部面板 </h3>
1706
- <p>移动端底部上滑面板:顶部圆角 xl + drag handle,阴影 xl。≤640px 时弹窗改为锚定底部成 Sheet。</p>
1723
+ <h3 class="sub">Sheet / BottomSheet</h3>
1724
+ <p>A mobile bottom slide-up panel: xl top radius + drag handle, xl shadow. At ≤640px, dialogs become bottom-anchored Sheets.</p>
1707
1725
  <div class="stage-wrap">
1708
1726
  <div class="stage-bar"><span class="st">BottomSheet</span></div>
1709
1727
  <div class="stage p col" style="align-items:center">
1710
1728
  <div class="p-sheet" style="width:100%;max-width:360px">
1711
1729
  <div class="p-sheet-handle"></div>
1712
- <div style="font-size:var(--p-font-size-base);font-weight:700;color:var(--p-text);margin-bottom:8px">选择模型</div>
1730
+ <div style="font-size:var(--p-font-size-base);font-weight:700;color:var(--p-text);margin-bottom:8px">Choose a model</div>
1713
1731
  <div class="p-menu-item" style="padding:8px 10px">kimi-k2 · thinking</div>
1714
1732
  <div class="p-menu-item" style="padding:8px 10px">kimi-k2 · instant</div>
1715
1733
  </div>
@@ -1717,8 +1735,8 @@ export function auth(token: string) {
1717
1735
  </div>
1718
1736
 
1719
1737
  <!-- ===== Skeleton ===== -->
1720
- <h3 class="sub">Skeleton · 骨架屏 </h3>
1721
- <p>内容加载中的占位,使用呼吸式透明度动画(无渐变),遵守 <code>no-gradient-text</code> 规则。组合成标题 / 文本行 / 头像。</p>
1738
+ <h3 class="sub">Skeleton</h3>
1739
+ <p>A placeholder for loading content, using a breathing opacity animation (no gradients), following the <code>no-gradient-text</code> rule. Composed into titles / text lines / avatars.</p>
1722
1740
  <div class="stage-wrap">
1723
1741
  <div class="stage-bar"><span class="st">Skeleton</span></div>
1724
1742
  <div class="stage p col">
@@ -1732,353 +1750,353 @@ export function auth(token: string) {
1732
1750
  </div>
1733
1751
 
1734
1752
  <!-- ===== Command Bar ===== -->
1735
- <h3 class="sub">Command Bar · 命令条 </h3>
1736
- <p>「主操作 + 命令文本 + 复制」的内联组合,介于按钮与代码块之间,用于安装 / 引导 / 一键执行。主操作复用 <code>Button primary</code>,命令区用 mono 浅灰底。</p>
1753
+ <h3 class="sub">Command Bar</h3>
1754
+ <p>An inline combination of "primary action + command text + copy", sitting between a button and a code block — used for install / onboarding / one-click execution. The primary action reuses <code>Button primary</code>; the command area uses a mono light-grey background.</p>
1737
1755
  <div class="stage-wrap">
1738
- <div class="stage-bar"><span class="st">Command Bar · 命令条</span></div>
1756
+ <div class="stage-bar"><span class="st">Command Bar</span></div>
1739
1757
  <div class="stage p col">
1740
1758
  <div class="p-cmdbar" style="max-width:620px">
1741
- <button class="p-btn primary">安装 Kimi Code ▾</button>
1742
- <span class="p-cmd"><span class="cmd-text">curl -fsSL https://code.kimi.com/install.sh | bash</span><button class="cmd-copy"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><rect x="5.5" y="5.5" width="8" height="8" rx="1.6" stroke="currentColor" stroke-width="1.4"/><path d="M10.5 5.5V3.6A1.1 1.1 0 0 0 9.4 2.5H3.6A1.1 1.1 0 0 0 2.5 3.6v5.8a1.1 1.1 0 0 0 1.1 1.1h1.9" stroke="currentColor" stroke-width="1.4"/></svg></button></span>
1759
+ <button class="p-btn primary">Install Kimi Code ▾</button>
1760
+ <span class="p-cmd"><span class="cmd-text">curl -fsSL https://code.kimi.com/install.sh | bash</span><button class="cmd-copy"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z"/></svg></button></span>
1743
1761
  </div>
1744
1762
  </div>
1745
1763
  </div>
1746
1764
 
1747
1765
  <!-- ===== TopBar ===== -->
1748
- <h3 class="sub">TopBar · 顶部栏 </h3>
1749
- <p>应用顶部条。默认实色;<code>.frost</code> 变体为半透 + 背景模糊,<b>仅用于吸顶导航栏</b>,是 <code>no-glassmorphism</code> 规则的唯一例外(见 §06)。</p>
1766
+ <h3 class="sub">TopBar</h3>
1767
+ <p>The application top bar. Solid by default; the <code>.frost</code> variant is translucent + background blur, used <b>only for sticky navigation bars</b>, and is the sole exception to the <code>no-glassmorphism</code> rule (see §06).</p>
1750
1768
  <div class="stage-wrap">
1751
- <div class="stage-bar"><span class="st">TopBar · 实色 / 毛玻璃</span></div>
1769
+ <div class="stage-bar"><span class="st">TopBar · solid / frosted glass</span></div>
1752
1770
  <div class="stage p col" style="gap:14px;background:radial-gradient(circle at 18% 30%,rgba(23,131,255,.16),transparent 42%),radial-gradient(circle at 82% 75%,rgba(20,23,28,.10),transparent 46%),var(--p-surface-sunken)">
1753
1771
  <div class="p-topbar" style="width:100%;max-width:580px">
1754
- <span class="tb-title">实色 TopBar</span>
1755
- <span class="tb-actions"><button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2.5 4h11M2.5 8h11M2.5 12h11" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button></span>
1772
+ <span class="tb-title">Solid TopBar</span>
1773
+ <span class="tb-actions"><button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z"/></svg></button></span>
1756
1774
  </div>
1757
1775
  <div class="p-topbar frost" style="width:100%;max-width:580px">
1758
- <span class="tb-title">毛玻璃 TopBar · .frost</span>
1759
- <span class="tb-actions"><button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2.5 4h11M2.5 8h11M2.5 12h11" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button></span>
1776
+ <span class="tb-title">Frosted-glass TopBar · .frost</span>
1777
+ <span class="tb-actions"><button class="p-icon-btn sm"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z"/></svg></button></span>
1760
1778
  </div>
1761
1779
  </div>
1762
1780
  </div>
1763
1781
 
1764
- <h3 class="sub">SectionLabel · 分组标题 </h3>
1765
- <p>侧栏列表的分组小标题,用于为下方内容分区(如侧栏的 <code>Workspaces</code>)。规范:13px / 700 / 大写 / 字距 <code>.08em</code>,色取 <code>--color-fg-faint</code>;左对齐到行的起始内边距(<code>--sb-pad-x</code>),与下方分组行保持同一缩进。中文等无大小写文字下 <code>text-transform:uppercase</code> 自动失效,无需特殊处理。</p>
1782
+ <h3 class="sub">SectionLabel</h3>
1783
+ <p>A small group title for sidebar lists, used to section the content below (such as <code>Workspaces</code> in the sidebar). Spec: 13px / 700 / uppercase / letter-spacing <code>.08em</code>, color <code>--color-fg-faint</code>; left-aligned to the row's starting padding (<code>--sb-pad-x</code>), keeping the same indent as the group rows below. For scripts without case (such as Chinese), <code>text-transform:uppercase</code> simply has no effect — no special handling needed.</p>
1766
1784
  <div class="stage-wrap">
1767
- <div class="stage-bar"><span class="st">Sidebar · 分组标题</span></div>
1785
+ <div class="stage-bar"><span class="st">Sidebar · group title</span></div>
1768
1786
  <div class="stage p col" style="gap:0;background:var(--p-surface);padding:0;max-width:300px;align-items:stretch">
1769
1787
  <div class="p-section-label" style="padding:12px 16px 4px">Workspaces</div>
1770
1788
  <div style="display:flex;align-items:center;gap:8px;padding:7px 10px;margin:1px 6px;border-radius:8px;color:var(--p-text);font-size:13px">
1771
- <svg width="14" height="14" viewBox="0 0 16 16" fill="none" style="color:var(--d-fg-faint);flex:none"><path d="M1.5 4V3A1.5 1.5 0 0 1 3 1.5h3l1.2 1.6H13A1.5 1.5 0 0 1 14.5 4.6v6.9A1.5 1.5 0 0 1 13 13H3a1.5 1.5 0 0 1-1.5-1.5Z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg>
1789
+ <svg style="color:var(--d-fg-faint);flex:none" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg>
1772
1790
  kimi-code-web
1773
1791
  </div>
1774
1792
  <div style="display:flex;align-items:center;gap:8px;padding:7px 10px;margin:1px 6px;border-radius:8px;color:var(--p-text);font-size:13px">
1775
- <svg width="14" height="14" viewBox="0 0 16 16" fill="none" style="color:var(--d-fg-faint);flex:none"><path d="M1.5 4V3A1.5 1.5 0 0 1 3 1.5h3l1.2 1.6H13A1.5 1.5 0 0 1 14.5 4.6v6.9A1.5 1.5 0 0 1 13 13H3a1.5 1.5 0 0 1-1.5-1.5Z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg>
1793
+ <svg style="color:var(--d-fg-faint);flex:none" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg>
1776
1794
  playground
1777
1795
  </div>
1778
1796
  </div>
1779
1797
  </div>
1780
1798
  </section>
1781
1799
 
1782
- <!-- ===== 04 聊天界面 ===== -->
1800
+ <!-- ===== 04 Chat Interface ===== -->
1783
1801
  <section id="chat">
1784
1802
  <div class="sec-head">
1785
1803
  <span class="sec-num">04</span>
1786
- <h2 class="sec-title">聊天界面重构</h2>
1804
+ <h2 class="sec-title">Chat Interface Overhaul</h2>
1787
1805
  </div>
1788
1806
  <p class="sec-desc">
1789
- 消息流是 Kimi Web 的核心。改造目标:让 6 类卡片(Agent / Tool / Question / Approval / Swarm / Todo)
1790
- <b>共享同一套卡片骨架</b>,仅靠头部图标与语义色区分类型;Composer 收敛为单一圆润容器。
1807
+ The message stream is the core of Kimi Web. The goal of the overhaul: have the 6 card types (Agent / Tool / Question / Approval / Swarm / Todo)
1808
+ <b>share one card skeleton</b>, distinguished only by the head icon and semantic color; and collapse the Composer into a single rounded container.
1791
1809
  </p>
1792
1810
 
1793
- <h3 class="sub">统一后的消息流</h3>
1811
+ <h3 class="sub">Unified message stream</h3>
1794
1812
  <div class="stage-wrap">
1795
- <div class="stage-bar"><span class="st">Conversation · 760px 阅读栏 </span></div>
1813
+ <div class="stage-bar"><span class="st">Conversation · 760px reading column</span></div>
1796
1814
  <div class="stage p col" style="align-items:center;background:#fff">
1797
1815
  <div class="demo-chat">
1798
1816
 
1799
1817
  <!-- user -->
1800
- <div class="p-bubble-user">帮我把登录接口改成 JWT,并补上对应的单元测试。</div>
1818
+ <div class="p-bubble-user">Please change the login endpoint to JWT and add the corresponding unit tests.</div>
1801
1819
 
1802
1820
  <!-- thinking -->
1803
- <span class="p-thinking"><span style="font-size:15px;line-height:1">🌔</span>正在分析认证模块…</span>
1821
+ <span class="p-thinking"><span style="font-size:15px;line-height:1">🌔</span>Analyzing the auth module…</span>
1804
1822
 
1805
- <!-- compact tool group:多次工具调用收成一叠,默认低权重 -->
1823
+ <!-- compact tool group: multiple tool calls collapsed into a stack, low weight by default -->
1806
1824
  <div class="p-tool-group open">
1807
1825
  <div class="p-tool-group-head">
1808
1826
  <span class="p-dot done"></span>
1809
- <svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2 4h12M2 8h12M2 12h8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
1810
- <span class="tg-title">3 个工具调用</span>
1811
- <span class="tg-meta">· 已完成 · 0.8s</span>
1812
- <svg class="tg-car" viewBox="0 0 16 16" fill="none"><path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
1827
+ <svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"/></svg>
1828
+ <span class="tg-title">3 tool calls</span>
1829
+ <span class="tg-meta">· completed · 0.8s</span>
1830
+ <svg class="tg-car" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg>
1813
1831
  </div>
1814
- <!-- row 1 · 已展开(按需披露细节) -->
1832
+ <!-- row 1 · expanded (details disclosed on demand) -->
1815
1833
  <div class="p-tool-row expanded">
1816
1834
  <span class="p-dot done"></span>
1817
- <svg class="tr-ic" viewBox="0 0 16 16" fill="none"><path d="M3 3h7l3 3v7H3V3Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/><path d="M9 3v3h3" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
1835
+ <svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg>
1818
1836
  <span class="tr-name">read_file</span>
1819
1837
  <span class="tr-arg">src/auth/session.ts</span>
1820
1838
  <span class="tr-time">0.2s</span>
1821
- <svg class="tr-car" viewBox="0 0 16 16" fill="none"><path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
1839
+ <svg class="tr-car" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg>
1822
1840
  </div>
1823
1841
  <div class="p-tool-detail">
1824
1842
  <div class="p-code">12 export function verify(token: string) {<br/>13 return jwt.verify(token, getSecret());<br/>14 }</div>
1825
1843
  </div>
1826
- <!-- row 2 · 折叠 -->
1844
+ <!-- row 2 · collapsed -->
1827
1845
  <div class="p-tool-row">
1828
1846
  <span class="p-dot done"></span>
1829
- <svg class="tr-ic" viewBox="0 0 16 16" fill="none"><path d="M3 3h7l3 3v7H3V3Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/><path d="M9 3v3h3" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
1847
+ <svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg>
1830
1848
  <span class="tr-name">read_file</span>
1831
1849
  <span class="tr-arg">src/auth/middleware.ts</span>
1832
1850
  <span class="tr-time">0.2s</span>
1833
- <svg class="tr-car" viewBox="0 0 16 16" fill="none"><path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
1851
+ <svg class="tr-car" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg>
1834
1852
  </div>
1835
- <!-- row 3 · 折叠 -->
1853
+ <!-- row 3 · collapsed -->
1836
1854
  <div class="p-tool-row">
1837
1855
  <span class="p-dot done"></span>
1838
- <svg class="tr-ic" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="4.5" stroke="currentColor" stroke-width="1.4"/><path d="m10.5 10.5 3 3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>
1856
+ <svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z"/></svg>
1839
1857
  <span class="tr-name">grep</span>
1840
- <span class="tr-arg">"jwt.verify" · 4 处匹配</span>
1858
+ <span class="tr-arg">"jwt.verify" · 4 matches</span>
1841
1859
  <span class="tr-time">0.1s</span>
1842
- <svg class="tr-car" viewBox="0 0 16 16" fill="none"><path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
1860
+ <svg class="tr-car" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg>
1843
1861
  </div>
1844
1862
  </div>
1845
1863
 
1846
- <!-- assistant prose(结论) -->
1864
+ <!-- assistant prose (conclusion) -->
1847
1865
  <div class="p-msg">
1848
- <p>我看了一下 <code>src/auth</code> 的结构,当前是基于 session cookie 的实现。改动范围如下,你确认后我开始动手。</p>
1866
+ <p>I looked at the structure of <code>src/auth</code>; it is currently based on a session cookie. The scope of the change is below — once you confirm, I'll start.</p>
1849
1867
  </div>
1850
1868
 
1851
- <!-- question(需要用户决策 → 保留完整卡片) -->
1869
+ <!-- question (needs a user decision → keep the full card) -->
1852
1870
  <div class="p-action">
1853
1871
  <div class="p-action-head">
1854
- <svg class="p-ic" viewBox="0 0 16 16" fill="none" style="color:var(--p-accent)"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.4"/><path d="M6.2 6a1.8 1.8 0 0 1 3.5.6c0 1.2-1.7 1.4-1.7 2.6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><circle cx="8" cy="11.5" r=".7" fill="currentColor"/></svg>
1855
- <span class="p-action-title">需要你确认一个决定</span>
1872
+ <svg class="p-ic" style="color:var(--p-accent)" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-1-5h2v2h-2zm2-1.645V14h-2v-1.5a1 1 0 0 1 1-1a1.5 1.5 0 1 0-1.471-1.794l-1.962-.393A3.501 3.501 0 1 1 13 13.355"/></svg>
1873
+ <span class="p-action-title">A decision needs your confirmation</span>
1856
1874
  </div>
1857
- <div class="p-action-body">JWT 的过期时间希望设多长?默认 7 天,刷新令牌 30 天。</div>
1875
+ <div class="p-action-body">How long should the JWT expiry be? Default 7 days, refresh token 30 days.</div>
1858
1876
  <div class="p-action-foot">
1859
- <button class="p-btn secondary sm">自定义</button>
1860
- <button class="p-btn primary sm">使用默认</button>
1877
+ <button class="p-btn secondary sm">Customize</button>
1878
+ <button class="p-btn primary sm">Use default</button>
1861
1879
  </div>
1862
1880
  </div>
1863
1881
 
1864
1882
  <!-- approval (warning) -->
1865
1883
  <div class="p-action warn">
1866
1884
  <div class="p-action-head">
1867
- <svg class="p-ic" viewBox="0 0 16 16" fill="none" style="color:var(--p-warning)"><path d="M8 2 14 13H2L8 2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6v3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="11" r=".6" fill="currentColor"/></svg>
1868
- <span class="p-action-title">需要写入权限</span>
1885
+ <svg class="p-ic" style="color:var(--p-warning)" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z"/></svg>
1886
+ <span class="p-action-title">Write permission required</span>
1869
1887
  <span class="p-badge warning sm" style="margin-left:auto">write_file</span>
1870
1888
  </div>
1871
- <div class="p-action-body">即将修改 <code>src/auth/middleware.ts</code>,共 42 行变更。是否允许?</div>
1889
+ <div class="p-action-body">About to modify <code>src/auth/middleware.ts</code>, 42 lines changed. Allow?</div>
1872
1890
  <div class="p-action-foot">
1873
- <button class="p-btn secondary sm">拒绝</button>
1874
- <button class="p-btn primary sm">允许本次</button>
1875
- <button class="p-btn ghost sm">始终允许</button>
1891
+ <button class="p-btn secondary sm">Deny</button>
1892
+ <button class="p-btn primary sm">Allow this time</button>
1893
+ <button class="p-btn ghost sm">Always allow</button>
1876
1894
  </div>
1877
1895
  </div>
1878
1896
 
1879
1897
  <!-- todo -->
1880
1898
  <div class="p-todo">
1881
- <div class="p-todo-row done"><span class="p-todo-check">✓</span>替换 session 为 JWT 签发</div>
1882
- <div class="p-todo-row active"><span class="p-todo-check">●</span>改造认证中间件</div>
1883
- <div class="p-todo-row"><span class="p-todo-check">○</span>补充单元测试</div>
1899
+ <div class="p-todo-row done"><span class="p-todo-check">✓</span>Replace session with JWT signing</div>
1900
+ <div class="p-todo-row active"><span class="p-todo-check">●</span>Refactor the auth middleware</div>
1901
+ <div class="p-todo-row"><span class="p-todo-check">○</span>Add unit tests</div>
1884
1902
  </div>
1885
1903
 
1886
1904
  </div>
1887
1905
  </div>
1888
1906
  </div>
1889
1907
 
1890
- <h3 class="sub">工具调用:默认紧凑、分组、按需展开</h3>
1891
- <p><code>read_file</code> / <code>bash</code> / <code>grep</code> 这类高频调用是「操作噪音」——若每条都占一张大卡,并行触发时会迅速淹没对话。
1892
- 新策略按<b>视觉权重</b>分三档,把工具调用压到最轻:</p>
1908
+ <h3 class="sub">Tool calls: compact by default, grouped, expand on demand</h3>
1909
+ <p>High-frequency calls like <code>read_file</code> / <code>bash</code> / <code>grep</code> are "operational noise" — if each one took a full card, parallel triggers would quickly drown out the conversation.
1910
+ The new strategy splits tool calls into three tiers by <b>visual weight</b>, pushing them as light as possible:</p>
1893
1911
 
1894
1912
  <div class="stage-wrap">
1895
- <div class="stage-bar"><span class="st">视觉权重三档</span></div>
1913
+ <div class="stage-bar"><span class="st">Three visual-weight tiers</span></div>
1896
1914
  <div class="stage p col">
1897
- <span class="stage-label">① 工具行 · 最轻(默认)</span>
1915
+ <span class="stage-label">① Tool row · lightest (default)</span>
1898
1916
  <div class="p-tool-row" style="border:1px solid var(--p-line);border-radius:8px">
1899
1917
  <span class="p-dot done"></span>
1900
- <svg class="tr-ic" viewBox="0 0 16 16" fill="none"><path d="M3 3h7l3 3v7H3V3Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/><path d="M9 3v3h3" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
1918
+ <svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z"/></svg>
1901
1919
  <span class="tr-name">read_file</span>
1902
1920
  <span class="tr-arg">src/auth/session.ts</span>
1903
1921
  <span class="tr-time">0.2s</span>
1904
1922
  </div>
1905
- <span class="stage-label">② 工具组 · 中(连续 / 并行自动归并,折叠只占一行)</span>
1923
+ <span class="stage-label">② Tool group · medium (consecutive / parallel auto-merged; collapsed to one line)</span>
1906
1924
  <div class="p-tool-group">
1907
1925
  <div class="p-tool-group-head">
1908
1926
  <span class="p-dot done"></span>
1909
- <svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2 4h12M2 8h12M2 12h8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
1910
- <span class="tg-title">3 个工具调用</span>
1911
- <span class="tg-meta">· 已完成 · 0.8s</span>
1912
- <svg class="tg-car" viewBox="0 0 16 16" fill="none"><path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
1927
+ <svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"/></svg>
1928
+ <span class="tg-title">3 tool calls</span>
1929
+ <span class="tg-meta">· completed · 0.8s</span>
1930
+ <svg class="tg-car" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z"/></svg>
1913
1931
  </div>
1914
1932
  </div>
1915
- <span class="stage-label">③ 决策卡 · 重(仅 question / approval,需用户介入)</span>
1933
+ <span class="stage-label">③ Decision card · heavy (only question / approval, needs user input)</span>
1916
1934
  <div class="p-action warn">
1917
- <div class="p-action-head"><span class="p-action-title">需要写入权限</span><span class="p-badge warning sm" style="margin-left:auto">write_file</span></div>
1918
- <div class="p-action-body" style="padding:10px 14px;font-size:13px">即将修改 <code>src/auth/middleware.ts</code>,共 42 行变更。</div>
1935
+ <div class="p-action-head"><span class="p-action-title">Write permission required</span><span class="p-badge warning sm" style="margin-left:auto">write_file</span></div>
1936
+ <div class="p-action-body" style="padding:10px 14px;font-size:13px">About to modify <code>src/auth/middleware.ts</code>, 42 lines changed.</div>
1919
1937
  </div>
1920
1938
  </div>
1921
1939
  </div>
1922
1940
 
1923
1941
  <ul class="clean check">
1924
- <li>工具调用<b>默认渲染为紧凑行</b>(30px 单行 mono + 状态点 + 关键参数),不再有头 / 身 / 阴影。</li>
1925
- <li>连续或并行的调用<b>自动归为一个工具组</b>,折叠时整组只占一行(<code>N 个工具调用 · 状态</code>)。</li>
1926
- <li>点击行<b>就地展开</b>细节(代码 / 输出),再点收起——细节默认不抢视觉。</li>
1927
- <li>状态用<b>颜色点</b>表达:运行中(脉冲蓝)/ 完成(绿)/ 失败(红),不占额外空间。</li>
1928
- <li><b>仅两类保留完整卡片</b>:<code>Question</code>(需回答)、<code>Approval</code>(需授权)——它们才真正需要用户注意力。</li>
1942
+ <li>Tool calls <b>render as compact rows by default</b> (30px single-line mono + status dot + key argument); no head / body / shadow.</li>
1943
+ <li>Consecutive or parallel calls <b>auto-merge into one tool group</b>; when collapsed, the whole group takes one line (<code>N tool calls · status</code>).</li>
1944
+ <li>Clicking a row <b>expands it in place</b> to show details (code / output); click again to collapse — details don't grab attention by default.</li>
1945
+ <li>Status is expressed with a <b>colored dot</b>: running (pulsing blue) / done (green) / failed (red), taking no extra space.</li>
1946
+ <li><b>Only two types keep a full card</b>: <code>Question</code> (needs an answer) and <code>Approval</code> (needs authorization) — they genuinely need the user's attention.</li>
1929
1947
  </ul>
1930
1948
 
1931
1949
  <div class="stage-wrap">
1932
- <div class="stage-bar"><span class="st">Tool Call · 紧凑行(按需展开)</span></div>
1950
+ <div class="stage-bar"><span class="st">Tool Call · compact row (expand on demand)</span></div>
1933
1951
  <div class="stage p">
1934
1952
  <div class="p-tool-group open">
1935
- <div class="p-tool-group-head"><span class="p-dot done"></span><span class="tg-title">3 个工具调用</span><span class="tg-meta">· 已完成</span></div>
1953
+ <div class="p-tool-group-head"><span class="p-dot done"></span><span class="tg-title">3 tool calls</span><span class="tg-meta">· completed</span></div>
1936
1954
  <div class="p-tool-row expanded"><span class="p-dot done"></span><span class="tr-name">read_file</span><span class="tr-arg">session.ts</span></div>
1937
1955
  <div class="p-tool-detail"><div class="p-code" style="font-size:11px;padding:7px 9px;margin-top:8px">12 export function verify(…</div></div>
1938
1956
  <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">read_file</span><span class="tr-arg">middleware.ts</span></div>
1939
- <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">grep</span><span class="tr-arg">"jwt" · 4 处</span></div>
1957
+ <div class="p-tool-row"><span class="p-dot done"></span><span class="tr-name">grep</span><span class="tr-arg">"jwt" · 4 hits</span></div>
1940
1958
  </div>
1941
1959
  </div>
1942
1960
  </div>
1943
1961
 
1944
- <h3 class="sub">Composer · 输入框</h3>
1945
- <p>统一为单一圆润容器:<code>--radius-xl</code>,聚焦时整体描边变蓝 + 软焦点环。工具条控件全部用 Pill / IconButton 基元,发送按钮 32px 圆形。</p>
1962
+ <h3 class="sub">Composer</h3>
1963
+ <p>Unified into a single rounded container: <code>--radius-xl</code>, with the whole border turning blue + a soft focus ring on focus. Toolbar controls all use the Pill / IconButton primitives, and the send button is a 32px circle.</p>
1946
1964
  <div class="stage-wrap">
1947
- <div class="stage-bar"><span class="st">Composer </span></div>
1965
+ <div class="stage-bar"><span class="st">Composer</span></div>
1948
1966
  <div class="stage p col" style="align-items:center;background:#fff">
1949
1967
  <div class="p-composer" style="width:100%;max-width:620px">
1950
- <div class="p-composer-ta ph">给 Kimi 发消息,/ 调用命令,@ 引用文件…</div>
1968
+ <div class="p-composer-ta ph">Message Kimi, / to run a command, @ to reference a file…</div>
1951
1969
  <div class="p-composer-bar">
1952
1970
  <div class="p-composer-left">
1953
- <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg></button>
1971
+ <button class="p-icon-btn"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg></button>
1954
1972
  <span class="p-pill"><span style="width:7px;height:7px;border-radius:50%;background:var(--p-warning)"></span>yolo</span>
1955
- <span class="p-pill"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M2 4h12M2 8h8M2 12h5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>plan</span>
1973
+ <span class="p-pill"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"/></svg>plan</span>
1956
1974
  </div>
1957
1975
  <div class="p-composer-right">
1958
- <span class="p-pill"><span class="pp-strong">kimi-k2</span><span class="pp-sub">· thinking</span><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
1959
- <button class="p-send"><svg class="p-ic" viewBox="0 0 16 16" fill="none"><path d="M8 13V3m0 0L4.5 6.5M8 3l3.5 3.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
1976
+ <span class="p-pill"><span class="pp-strong">kimi-k2</span><span class="pp-sub">· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z"/></svg></span>
1977
+ <button class="p-send"><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M13 7.828V20h-2V7.828l-5.364 5.364l-1.414-1.414L12 4l7.778 7.778l-1.414 1.414z"/></svg></button>
1960
1978
  </div>
1961
1979
  </div>
1962
1980
  </div>
1963
1981
  </div>
1964
1982
  </div>
1965
1983
  <div class="callout info"><span class="ico">i</span><div>
1966
- <b>全站统一</b>:composer 只有一种圆角(<code>--radius-xl</code> · 16px)与一种高度,工具条控件全部用 Pill / IconButton 基元,发送按钮 32px 圆形——不再随主题漂移。
1984
+ <b>Site-wide consistency</b>: the composer has only one radius (<code>--radius-xl</code> · 16px) and one height; toolbar controls all use the Pill / IconButton primitives, and the send button is a 32px circle — it no longer drifts with the theme.
1967
1985
  </div></div>
1968
1986
 
1969
- <h3 class="sub">响应式 Responsive </h3>
1970
- <p>断点见 §02 <code>--p-bp-sm</code>。此处仅给出聊天界面的移动端适配指针,完整移动端 mockup 不在本规范范围。</p>
1987
+ <h3 class="sub">Responsive</h3>
1988
+ <p>See §02 <code>--p-bp-sm</code> for the breakpoint. This section only gives mobile-adaptation pointers for the chat interface; a full mobile mockup is out of scope for this spec.</p>
1971
1989
  <div class="callout info"><span class="ico">i</span><div>
1972
- ≤640px 时:弹窗锚定底部成 Sheet(顶部圆角 xl、顶部 drag handle),侧栏折叠为可展开抽屉,Composer 工具条允许换行,聊天阅读栏去除 max-width 占满。
1990
+ At ≤640px: dialogs anchor to the bottom as Sheets (xl top radius, top drag handle), the sidebar collapses into an expandable drawer, the Composer toolbar is allowed to wrap, and the chat reading column drops its max-width to fill the screen.
1973
1991
  </div></div>
1974
1992
  </section>
1975
1993
 
1976
- <!-- ===== 05 主题系统 ===== -->
1994
+ <!-- ===== 05 Theming ===== -->
1977
1995
  <section id="themes">
1978
1996
  <div class="sec-head">
1979
1997
  <span class="sec-num">05</span>
1980
- <h2 class="sec-title">主题系统</h2>
1998
+ <h2 class="sec-title">Theming</h2>
1981
1999
  </div>
1982
2000
  <p class="sec-desc">
1983
- Kimi Web 使用<b>一套统一主题</b>:同一套组件、字体、圆角、阴影与表面,「换肤」只换颜色。
1984
- 颜色收敛为 <b>4 个种子 token</b>——两个主题色 + 一个亮面 + 一个暗面;中性色与强调色由它们派生,
1985
- 语义状态色(success / warning / danger)作为独立调色板与种子配套,亮 / 暗各一套。
2001
+ Kimi Web uses <b>one unified theme</b>: the same components, fonts, radii, shadows, and surfaces — "reskinning" only changes colors.
2002
+ Colors are collapsed into <b>4 seed tokens</b> — two theme colors + one light surface + one dark surface; the neutrals and accent are derived from them,
2003
+ and the semantic status colors (success / warning / danger) ship as independent palettes paired with the seeds, one set each for light / dark.
1986
2004
  </p>
1987
2005
 
1988
- <h3 class="sub">颜色种子 Color seeds</h3>
1989
- <p>日常定制只需调整这 4 个种子,整站的中性色与强调色随之变化:</p>
2006
+ <h3 class="sub">Color seeds</h3>
2007
+ <p>Day-to-day customization only needs these 4 seeds; the whole site's neutrals and accent change with them:</p>
1990
2008
  <div class="panel panel-pad" style="margin:16px 0">
1991
2009
  <div style="display:grid;grid-template-columns:repeat(4,1fr);gap:14px">
1992
- <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#1783ff;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">主题色 · 主</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--accent-primary</div></div>
1993
- <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#6b7280;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">主题色 · 辅</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--accent-secondary</div></div>
1994
- <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#ffffff;border:1px solid var(--d-line);margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">亮面</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--surface-light</div></div>
1995
- <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#0d1117;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">暗面</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--surface-dark</div></div>
2010
+ <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#1783ff;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">Theme color · primary</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--accent-primary</div></div>
2011
+ <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#6b7280;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">Theme color · secondary</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--accent-secondary</div></div>
2012
+ <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#ffffff;border:1px solid var(--d-line);margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">Light surface</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--surface-light</div></div>
2013
+ <div style="text-align:center"><div style="width:48px;height:48px;border-radius:12px;background:#0d1117;margin:0 auto 8px;box-shadow:var(--d-shadow-sm)"></div><div style="font-size:13px;font-weight:700">Dark surface</div><div class="mono" style="font-size:11.5px;color:var(--d-fg-muted)">--surface-dark</div></div>
1996
2014
  </div>
1997
2015
  </div>
1998
2016
 
1999
- <h3 class="sub">色系切换 Accent families</h3>
2000
- <p>一套主题之内,<b>主题色(accent)可在多套色系间切换</b>。当前提供两套并列色系:<b>蓝色系</b>(默认,品牌蓝,承载语义强调)与<b>黑色系</b>(中性黑,承载克制的最强操作)。两套共用同一套组件、字体、圆角与表面——切换色系只换 accent 一组 token,结构零变化;后续可继续扩展(绿 / 紫等)。下面两卡是同一个 <code>primary</code> 按钮在两种色系下的呈现。</p>
2017
+ <h3 class="sub">Accent families</h3>
2018
+ <p>Within one theme, <b>the theme color (accent) can switch among several color families</b>. Two parallel families are provided today: <b>blue</b> (default, brand blue, carrying semantic emphasis) and <b>black</b> (neutral black, carrying the most restrained strong action). Both share the same components, fonts, radii, and surfaces — switching families only swaps the accent token set, with zero structural change; more families (green / purple, etc.) can be added later. The two cards below show the same <code>primary</code> button under the two families.</p>
2001
2019
  <div class="stage-wrap">
2002
- <div class="stage-bar"><span class="st">色系切换 · 同一 primary,不同主题色</span></div>
2020
+ <div class="stage-bar"><span class="st">Family switch · same primary, different theme color</span></div>
2003
2021
  <div class="stage p col">
2004
2022
  <div class="demo-row" style="align-items:stretch">
2005
2023
  <div class="demo-col" style="flex:1;border:1px solid var(--p-line);border-radius:12px;background:var(--p-surface-raised);padding:16px;gap:12px">
2006
- <span class="stage-label">蓝色系 · 默认</span>
2007
- <div class="demo-row"><button class="p-btn primary sm">主要操作</button><span class="p-badge info sm"><span class="bd"></span>accent</span></div>
2024
+ <span class="stage-label">Blue family · default</span>
2025
+ <div class="demo-row"><button class="p-btn primary sm">Primary action</button><span class="p-badge info sm"><span class="bd"></span>accent</span></div>
2008
2026
  <span class="mono" style="font-size:11px;color:var(--p-text-muted)">--accent #1783ff · soft #e8f3ff</span>
2009
2027
  </div>
2010
2028
  <div class="demo-col demo-family-black" style="flex:1;border:1px solid var(--p-line);border-radius:12px;background:var(--p-surface-raised);padding:16px;gap:12px">
2011
- <span class="stage-label">黑色系 · 中性</span>
2012
- <div class="demo-row"><button class="p-btn primary sm">主要操作</button><span class="p-badge info sm"><span class="bd"></span>accent</span></div>
2029
+ <span class="stage-label">Black family · neutral</span>
2030
+ <div class="demo-row"><button class="p-btn primary sm">Primary action</button><span class="p-badge info sm"><span class="bd"></span>accent</span></div>
2013
2031
  <span class="mono" style="font-size:11px;color:var(--p-text-muted)">--accent #14171c · soft #f1f2f4</span>
2014
2032
  </div>
2015
2033
  </div>
2016
2034
  </div>
2017
2035
  </div>
2018
2036
 
2019
- <h3 class="sub">主题控制台 · 改 4 个色,亮/暗一起变</h3>
2037
+ <h3 class="sub">Theme console · change 4 colors, light &amp; dark change together</h3>
2020
2038
  <div class="stage-wrap">
2021
2039
  <div class="stage-bar"><span class="st">Theme Console</span></div>
2022
2040
  <div class="stage p col" style="gap:18px">
2023
2041
  <div class="demo-row" style="justify-content:center;gap:10px;flex-wrap:wrap">
2024
- <span class="p-badge info"><span style="width:10px;height:10px;border-radius:3px;background:#1783ff"></span>主色 #1783ff</span>
2025
- <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#6b7280"></span>辅色 #6b7280</span>
2026
- <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#ffffff;border:1px solid var(--p-line)"></span>亮面 #ffffff</span>
2027
- <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#0d1117"></span>暗面 #0d1117</span>
2042
+ <span class="p-badge info"><span style="width:10px;height:10px;border-radius:3px;background:#1783ff"></span>Primary #1783ff</span>
2043
+ <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#6b7280"></span>Secondary #6b7280</span>
2044
+ <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#ffffff;border:1px solid var(--p-line)"></span>Light surface #ffffff</span>
2045
+ <span class="p-badge neutral"><span style="width:10px;height:10px;border-radius:3px;background:#0d1117"></span>Dark surface #0d1117</span>
2028
2046
  </div>
2029
2047
  <div class="demo-row" style="align-items:stretch">
2030
2048
  <div class="demo-col" style="flex:1;border:1px solid var(--p-line);border-radius:12px;background:var(--p-surface-raised);padding:16px;gap:10px">
2031
- <span class="stage-label">亮面预览</span>
2032
- <button class="p-btn primary sm" style="align-self:flex-start">主要操作</button>
2033
- <span style="font-size:12px;color:var(--p-text-muted)">白底 + 主色按钮 + 中性文字</span>
2049
+ <span class="stage-label">Light surface preview</span>
2050
+ <button class="p-btn primary sm" style="align-self:flex-start">Primary action</button>
2051
+ <span style="font-size:12px;color:var(--p-text-muted)">White background + accent button + neutral text</span>
2034
2052
  </div>
2035
2053
  <div class="demo-col" data-p="dark" style="flex:1;border:1px solid var(--p-line);border-radius:12px;background:var(--p-surface-raised);padding:16px;gap:10px">
2036
- <span class="stage-label" style="color:#9aa0a8">暗面预览</span>
2037
- <button class="p-btn primary sm" style="align-self:flex-start">主要操作</button>
2038
- <span style="font-size:12px;color:var(--p-text-muted)">深底 + 同一主色 + 派生文字</span>
2054
+ <span class="stage-label" style="color:#9aa0a8">Dark surface preview</span>
2055
+ <button class="p-btn primary sm" style="align-self:flex-start">Primary action</button>
2056
+ <span style="font-size:12px;color:var(--p-text-muted)">Dark background + same accent + derived text</span>
2039
2057
  </div>
2040
2058
  </div>
2041
2059
  </div>
2042
2060
  </div>
2043
2061
 
2044
- <h3 class="sub">亮 / 暗模式</h3>
2045
- <p>由 <code>--surface-light</code> / <code>--surface-dark</code> 两个表面驱动:当前用哪个表面,就派生出对应的前景、描边、阴影与状态色。亮 / 暗切换只是在这两组派生 token 之间切换,结构零变化。</p>
2062
+ <h3 class="sub">Light / dark mode</h3>
2063
+ <p>Driven by the two surfaces <code>--surface-light</code> / <code>--surface-dark</code>: whichever surface is current derives the corresponding foreground, border, shadow, and status colors. Switching light / dark simply swaps between these two sets of derived tokens, with zero structural change.</p>
2046
2064
 
2047
2065
  <div class="callout good"><span class="ico">✓</span><div>
2048
- <b>一套主题的收益</b>:组件、字体、圆角、表面全站一致;换肤只改 4 个颜色种子;亮 / 暗模式开箱即用;语义状态色独立可调。
2066
+ <b>Benefits of one theme</b>: components, fonts, radii, and surfaces are consistent site-wide; reskinning only changes 4 color seeds; light / dark mode works out of the box; semantic status colors are independently tunable.
2049
2067
  </div></div>
2050
2068
  </section>
2051
2069
 
2052
2070
 
2053
- <!-- ===== 06 样式规则 ===== -->
2071
+ <!-- ===== 06 Style Rules ===== -->
2054
2072
  <section id="rules">
2055
2073
  <div class="sec-head">
2056
2074
  <span class="sec-num">06</span>
2057
- <h2 class="sec-title">样式规则</h2>
2075
+ <h2 class="sec-title">Style Rules</h2>
2058
2076
  </div>
2059
2077
  <p class="sec-desc">
2060
- 所有 UI 代码必须遵守的反模式规则。这些规则也是 check-style 检测脚本的依据,逐条对应一条告警。
2078
+ Anti-pattern rules that all UI code must follow. These rules are also the basis of the check-style detection script, one-to-one with a warning.
2061
2079
  </p>
2062
2080
 
2063
2081
  <table class="dt">
2064
- <thead><tr><th>规则 ID</th><th>检测内容</th><th>处置</th></tr></thead>
2082
+ <thead><tr><th>Rule ID</th><th>What it detects</th><th>Action</th></tr></thead>
2065
2083
  <tbody>
2066
- <tr><td class="tk">no-gradient-text</td><td>渐变文字 / 渐变背景</td><td><span class="pill red">禁止</span></td></tr>
2067
- <tr><td class="tk">no-glassmorphism</td><td><code>backdrop-filter: blur</code>(<b>TopBar 吸顶导航栏</b> 为唯一例外)</td><td><span class="pill amber">TopBar 除外</span></td></tr>
2068
- <tr><td class="tk">no-color-glow</td><td>彩色 / 大半径 box-shadow 发光</td><td><span class="pill red">禁止</span></td></tr>
2069
- <tr><td class="tk">no-emoji-icon</td><td>用 emoji 充当功能性图标(<b>月相 🌑…🌘 为唯一豁免</b>,且仅限「等待 Agent 响应」的聊天态;其余加载态用普通 Spinner)</td><td><span class="pill amber">月相除外</span></td></tr>
2070
- <tr><td class="tk">no-hardcoded-hex</td><td>组件 <code>&lt;style&gt;</code> 内出现未登记十六进制色</td><td><span class="pill amber">警告</span></td></tr>
2071
- <tr><td class="tk">no-hardcoded-font</td><td>组件内硬编码 <code>font-family</code>(如 <code>'Inter'</code>)而非 <code>var(--font-ui)</code></td><td><span class="pill amber">警告</span></td></tr>
2072
- <tr><td class="tk">radius-from-scale</td><td>圆角值不在 <code>{4,6,8,12,16,20,999}</code> 内</td><td><span class="pill amber">警告</span></td></tr>
2073
- <tr><td class="tk">z-from-scale</td><td>z-index 使用未登记的大数字</td><td><span class="pill amber">警告</span></td></tr>
2074
- <tr><td class="tk">weight-from-scale</td><td>font-weight 不在 <code>{400,500}</code> 内</td><td><span class="pill amber">警告</span></td></tr>
2084
+ <tr><td class="tk">no-gradient-text</td><td>gradient text / gradient background</td><td><span class="pill red">Forbidden</span></td></tr>
2085
+ <tr><td class="tk">no-glassmorphism</td><td><code>backdrop-filter: blur</code> (<b>TopBar sticky nav bar</b> is the sole exception)</td><td><span class="pill amber">TopBar exempt</span></td></tr>
2086
+ <tr><td class="tk">no-color-glow</td><td>colored / large-radius box-shadow glow</td><td><span class="pill red">Forbidden</span></td></tr>
2087
+ <tr><td class="tk">no-emoji-icon</td><td>using emoji as a functional icon (<b>the moon phases 🌑…🌘 are the sole exception</b>, and only in the "waiting for the Agent to respond" chat state; all other loading states use the plain Spinner)</td><td><span class="pill amber">Moon phase exempt</span></td></tr>
2088
+ <tr><td class="tk">no-hardcoded-hex</td><td>unregistered hex color inside a component <code>&lt;style&gt;</code></td><td><span class="pill amber">Warning</span></td></tr>
2089
+ <tr><td class="tk">no-hardcoded-font</td><td>hard-coded <code>font-family</code> in a component (e.g. <code>'Inter'</code>) instead of <code>var(--font-ui)</code></td><td><span class="pill amber">Warning</span></td></tr>
2090
+ <tr><td class="tk">radius-from-scale</td><td>radius value not in <code>{4,6,8,12,16,20,999}</code></td><td><span class="pill amber">Warning</span></td></tr>
2091
+ <tr><td class="tk">z-from-scale</td><td>z-index using an unregistered large number</td><td><span class="pill amber">Warning</span></td></tr>
2092
+ <tr><td class="tk">weight-from-scale</td><td>font-weight not in <code>{400,500}</code></td><td><span class="pill amber">Warning</span></td></tr>
2075
2093
  </tbody>
2076
2094
  </table>
2077
2095
 
2078
- <h3 class="sub">状态矩阵 State matrix </h3>
2079
- <p>每个可交互基元都应在适用处定义以下状态,缺失即按样式规则告警。<code>focus-visible</code> 一律走 <code>--p-focus-ring</code>,<code>disabled</code> 统一 <code>opacity:.5</code>。</p>
2096
+ <h3 class="sub">State matrix</h3>
2097
+ <p>Every interactive primitive should define the following states where applicable; missing ones are flagged by the style rules. <code>focus-visible</code> always uses <code>--p-focus-ring</code> (appears only on keyboard focus, see §08); <code>disabled</code> is uniformly <code>opacity:.5</code>.</p>
2080
2098
  <table class="dt">
2081
- <thead><tr><th>状态 State</th><th>Button</th><th>Input</th><th>Card</th><th>Menu item</th><th>Switch</th></tr></thead>
2099
+ <thead><tr><th>State</th><th>Button</th><th>Input</th><th>Card</th><th>Menu item</th><th>Switch</th></tr></thead>
2082
2100
  <tbody>
2083
2101
  <tr><td class="tk">default</td><td>✓</td><td>✓</td><td>✓</td><td>✓</td><td>✓</td></tr>
2084
2102
  <tr><td class="tk">hover</td><td>✓</td><td>✓</td><td>✓</td><td>✓</td><td>—</td></tr>
@@ -2092,130 +2110,221 @@ export function auth(token: string) {
2092
2110
  </tbody>
2093
2111
  </table>
2094
2112
 
2095
- <h3 class="sub">月相豁免</h3>
2113
+ <h3 class="sub">Moon phase exemption</h3>
2096
2114
  <div class="callout good"><span class="ico">✓</span><div>
2097
- 「🌑…🌘」月相 emoji 是 Kimi Web 的品牌特色,<b>仅用于「发出消息后、等待 Agent 首条响应」的聊天态</b>,统一由 <code>MoonSpinner</code> 组件渲染;<code>ActivityNotice</code> 等等待态复用它,不再各自实现月相。
2098
- 它是 <code>no-emoji-icon</code> 规则的唯一例外;其余所有加载态一律用普通 <code>Spinner</code>。
2115
+ The "🌑…🌘" moon-phase emoji are a brand signature of Kimi Web, <b>used only in the chat state of "message sent, waiting for the Agent's first response"</b>, and are rendered uniformly by the <code>MoonSpinner</code> component; waiting states such as <code>ActivityNotice</code> reuse it rather than implementing their own moon phase.
2116
+ It is the sole exception to the <code>no-emoji-icon</code> rule; all other loading states use the plain <code>Spinner</code>.
2099
2117
  </div></div>
2100
2118
 
2101
- <h3 class="sub">毛玻璃豁免</h3>
2119
+ <h3 class="sub">Glassmorphism exemption</h3>
2102
2120
  <div class="callout good"><span class="ico">✓</span><div>
2103
- <code>backdrop-filter: blur</code> 全站禁用,<b>唯一例外是 <code>TopBar</code> 的 <code>.frost</code> 变体</b>——且仅限「吸顶导航栏」这一处,用于在滚动内容上方保持可读。其余任何组件(卡片、弹窗、Toast、面板)一律不得使用毛玻璃,违者按 <code>no-glassmorphism</code> 告警。
2121
+ <code>backdrop-filter: blur</code> is banned site-wide, with the <b>sole exception of the <code>.frost</code> variant of <code>TopBar</code></b> — and only in the one place of the "sticky navigation bar", used to stay readable over scrolling content. No other component (card, dialog, Toast, panel) may use glassmorphism; violations are flagged under <code>no-glassmorphism</code>.
2104
2122
  </div></div>
2105
2123
 
2106
2124
  <div class="footer">
2107
- <span>Kimi Web 设计系统 · v1.0</span>
2108
- <span>改 web UI 时以此为准</span>
2125
+ <span>Kimi Web Design System · v1.0</span>
2126
+ <span>The reference when changing the web UI</span>
2109
2127
  </div>
2110
2128
  </section>
2111
2129
 
2112
- <!-- ===== 07 应用壳与侧栏 ===== -->
2130
+ <!-- ===== 07 App Shell & Sidebar ===== -->
2113
2131
  <section id="shell">
2114
2132
  <div class="sec-head">
2115
2133
  <span class="sec-num">07</span>
2116
- <h2 class="sec-title">应用壳与侧栏 App Shell &amp; Sidebar</h2>
2134
+ <h2 class="sec-title">App Shell &amp; Sidebar</h2>
2117
2135
  </div>
2118
2136
  <p class="sec-desc">
2119
- 应用壳(三栏网格 + 右侧预览面板)与左侧会话侧栏的结构规范。这些是与具体业务无关的「骨架」,
2120
- 组件、字体、圆角、表面都复用 §02 / §03,但布局与对齐有自己的一套约定。
2137
+ The structural spec for the app shell (three-column grid + right preview panel) and the left session sidebar. These are business-agnostic "skeletons" —
2138
+ components, fonts, radii, and surfaces are reused from §02 / §03, but layout and alignment have their own conventions.
2121
2139
  </p>
2122
2140
 
2123
- <h3 class="sub">布局网格 Layout grid</h3>
2124
- <p>桌面端是一行 5 轨网格,侧栏与右侧面板各占一条永久轨道,中间是会话栏;两条 0 宽轨道给 ResizeHandle 用。</p>
2141
+ <h3 class="sub">Layout grid</h3>
2142
+ <p>On desktop it is a single-row 5-track grid: the sidebar and the right panel each occupy a permanent track, with the conversation column in the middle; two 0-width tracks are for the ResizeHandles.</p>
2125
2143
  <div class="code"><div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">App.vue · .app</span></div><pre>grid-template-columns: var(--side-w) 0 minmax(0, 1fr) 0 auto;
2126
- /* 侧栏 ↑ ↑handle ↑会话栏 ↑handle ↑右面板(auto) */</pre></div>
2144
+ /* sidebar ↑ ↑handle ↑conversation ↑handle ↑right panel (auto) */</pre></div>
2127
2145
  <table class="dt">
2128
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
2146
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
2129
2147
  <tbody>
2130
- <tr><td class="tk">--side-w</td><td class="val">248px(可调)</td><td>左侧会话栏宽度,ResizeHandle 拖动改变;应趋近 §02 的 <code>--p-sidebar-w</code>(264px)</td></tr>
2131
- <tr><td class="tk">--preview-w</td><td class="val">460px</td><td>右侧预览面板打开时的宽度</td></tr>
2132
- <tr><td class="tk">--panel-head-h</td><td class="val">48px</td><td>所有右侧面板头 + 会话栏头部统一高度,使 hairline 连成一线</td></tr>
2133
- <tr><td class="tk">--p-bp-sm</td><td class="val">640px</td><td>≤640 切为移动端单列(顶栏 + 会话栏),无侧栏/手柄/右面板</td></tr>
2148
+ <tr><td class="tk">--side-w</td><td class="val">248px (adjustable)</td><td>left conversation column width, changed by dragging the ResizeHandle; should approach §02's <code>--p-sidebar-w</code> (264px)</td></tr>
2149
+ <tr><td class="tk">--preview-w</td><td class="val">460px</td><td>width of the right preview panel when open</td></tr>
2150
+ <tr><td class="tk">--panel-head-h</td><td class="val">48px</td><td>unified height for all right panel heads + the conversation column head, so the hairline runs as one line</td></tr>
2151
+ <tr><td class="tk">--p-bp-sm</td><td class="val">640px</td><td>≤640 switches to a mobile single column (top bar + conversation), no sidebar / handle / right panel</td></tr>
2134
2152
  </tbody>
2135
2153
  </table>
2136
2154
  <ul class="clean">
2137
- <li>右侧面板轨道永久存在,宽度在 <code>0 ↔ var(--preview-w)</code> 间过渡(打开时挤压会话栏,而非切换模板)。</li>
2138
- <li>侧栏折叠时,轨道 1 变成一条细「rail」,只放一个展开 IconButton,避免压住会话栏头部。</li>
2139
- <li>所有网格子项须 <code>min-height:0; min-width:0</code>,确保只有内部滚动容器滚动,整页不跟着滚。</li>
2155
+ <li>The right panel track exists permanently, with its width transitioning between <code>0 ↔ var(--preview-w)</code> (when open it squeezes the conversation column, rather than switching templates).</li>
2156
+ <li>When the sidebar is collapsed, track 1 becomes a thin "rail" holding only an expand IconButton, avoiding crushing the conversation column head.</li>
2157
+ <li>All grid children must have <code>min-height:0; min-width:0</code>, so only the inner scroll containers scroll and the page itself does not scroll.</li>
2140
2158
  </ul>
2141
2159
 
2142
- <h3 class="sub">侧栏对齐系统 Sidebar alignment(<code>--sb-*</code>)</h3>
2143
- <p>侧栏所有行(分组头、会话行、New chat 按钮)共用 3 个自定义属性,让「会话标题」精确对齐到「工作区名称」下方。</p>
2160
+ <h3 class="sub">Sidebar alignment system (<code>--sb-*</code>)</h3>
2161
+ <p>All sidebar rows (group head, session row, New chat button) share 3 custom properties, so the "session title" aligns precisely under the "workspace name".</p>
2144
2162
  <table class="dt">
2145
- <thead><tr><th>Token</th><th>值</th><th>用途</th></tr></thead>
2163
+ <thead><tr><th>Token</th><th>Value</th><th>Usage</th></tr></thead>
2146
2164
  <tbody>
2147
- <tr><td class="tk">--sb-pad-x</td><td class="val">16px</td><td>行的水平内边距</td></tr>
2148
- <tr><td class="tk">--sb-gutter</td><td class="val">20px</td><td>行首图标槽宽(14px 图标 + 6px 留白)</td></tr>
2149
- <tr><td class="tk">--sb-gap</td><td class="val">6px</td><td>图标槽与文字之间的 gap</td></tr>
2165
+ <tr><td class="tk">--sb-pad-x</td><td class="val">16px</td><td>row horizontal padding</td></tr>
2166
+ <tr><td class="tk">--sb-gutter</td><td class="val">20px</td><td>leading icon slot width (14px icon + 6px whitespace)</td></tr>
2167
+ <tr><td class="tk">--sb-gap</td><td class="val">6px</td><td>gap between the icon slot and the text</td></tr>
2150
2168
  </tbody>
2151
2169
  </table>
2152
2170
  <div class="callout info"><span class="ico">i</span><div>
2153
- 会话标题的起始 x = <code>--sb-pad-x + --sb-gutter + --sb-gap</code>。分组头有文件夹图标,会话行有状态槽,二者图标同宽、同位,所以标题天然对齐。
2171
+ The session title's starting x = <code>--sb-pad-x + --sb-gutter + --sb-gap</code>. The group head has a folder icon and the session row has a status slot; both icons are the same width and position, so the titles align naturally.
2154
2172
  </div></div>
2155
2173
 
2156
- <h3 class="sub">侧栏结构 Sidebar structure</h3>
2157
- <p>侧栏自上而下:品牌头 → 搜索 → New chat → 分组列表(工作区头 + 会话行)。控件尽量复用 §03 基元。</p>
2174
+ <h3 class="sub">Sidebar structure</h3>
2175
+ <p>The sidebar from top to bottom: brand header → search → New chat → grouped list (workspace head + session rows). Controls reuse the §03 primitives as much as possible.</p>
2158
2176
  <table class="dt">
2159
- <thead><tr><th>区块</th><th>用什么</th><th>说明</th></tr></thead>
2177
+ <thead><tr><th>Block</th><th>Use</th><th>Note</th></tr></thead>
2160
2178
  <tbody>
2161
- <tr><td>品牌头 brand header</td><td>logo + 名称 + IconButton</td><td>折叠 / 设置用 IconButton sm;logo 带动画(眼睛眨动)</td></tr>
2162
- <tr><td>搜索 search</td><td>裸搜索行(custom)</td><td>无边框、hover/focus 出 sunken 底;图标 + input + 清除 IconButton。<b>不用</b> Input(38px 带边框太重)</td></tr>
2163
- <tr><td>New chat</td><td>全宽左对齐按钮(custom)</td><td>与同列表会话行同节奏(左对齐、hover sunken)。<b>不用</b> Button(居中,破坏节奏)</td></tr>
2164
- <tr><td>分组标题 section label</td><td><code>.p-section-label</code></td><td>「Workspaces」这类大写 muted 小标题</td></tr>
2165
- <tr><td>工作区头 / 会话行</td><td>见下两节</td><td>共享 <code>--sb-*</code> 对齐</td></tr>
2179
+ <tr><td>Brand header</td><td>logo + name + IconButton</td><td>collapse / settings use IconButton sm; the logo is animated (a blinking eye)</td></tr>
2180
+ <tr><td>Search</td><td>bare search row (custom)</td><td>no border, hover/focus shows a sunken background; icon + input + clear IconButton. <b>Do not</b> use Input (the 38px bordered version is too heavy)</td></tr>
2181
+ <tr><td>New chat</td><td>full-width left-aligned button (custom)</td><td>same rhythm as the session rows in the list (left-aligned, hover sunken). <b>Do not</b> use Button (centered, breaks the rhythm)</td></tr>
2182
+ <tr><td>Section label</td><td><code>.p-section-label</code></td><td>uppercase muted small titles like "Workspaces"</td></tr>
2183
+ <tr><td>Workspace head / session row</td><td>see next two sections</td><td>share <code>--sb-*</code> alignment</td></tr>
2166
2184
  </tbody>
2167
2185
  </table>
2168
2186
  <div class="callout warn"><span class="ico">!</span><div>
2169
- <b>为什么 New chat / 搜索 / 行间改名不用 Button / Input:</b>它们是「列表式」控件(全宽、左对齐、紧凑、无边框),而 Button 居中、Input 是 38px 带边框——强行套用会破坏侧栏的视觉密度与对齐。这是有意保留的定制,不是遗漏。
2187
+ <b>Why New chat / search / inline rename don't use Button / Input:</b> they are "list-style" controls (full-width, left-aligned, compact, borderless), while Button is centered and Input is a 38px bordered control — forcing them in would break the sidebar's visual density and alignment. This is an intentional custom exception, not an oversight.
2170
2188
  </div></div>
2171
2189
 
2172
- <h3 class="sub">会话行 Session row</h3>
2173
- <p>会话行是一个 inset 圆角 pill,结构:<code>状态槽 → 标题 → 时间 → 注意力 Badge → kebab</code>。</p>
2190
+ <h3 class="sub">Session row</h3>
2191
+ <p>A session row is an inset rounded pill, structured as: <code>status slot → title → attention Badge → trailing action slot</code>.</p>
2174
2192
  <table class="dt">
2175
- <thead><tr><th>部位</th><th>规则</th></tr></thead>
2193
+ <thead><tr><th>Part</th><th>Rule</th></tr></thead>
2176
2194
  <tbody>
2177
- <tr><td>容器</td><td><code>margin: 1px 6px; padding: 7px 10px; radius-md</code>;hover = <code>surface-sunken</code>;active = <code>accent-soft</code> + <code>inset 0 0 0 1px accent-bd</code></td></tr>
2178
- <tr><td>状态槽 lead</td><td>固定 <code>--sb-gutter</code> 宽;运行中 = <code>Spinner</code> sm,否则未读 = 7px accent 圆点</td></tr>
2179
- <tr><td>标题 title</td><td>flex:1 截断;双击进入行间改名(紧凑 input,不用 Input)</td></tr>
2180
- <tr><td>时间 time</td><td>mono xs、<code>fg-faint</code>;hover 时让位给 kebab</td></tr>
2181
- <tr><td>注意力 Badge</td><td><code>Badge</code> sm:info(待回答)/ warning(待审批)/ danger(已中止)</td></tr>
2182
- <tr><td>kebab</td><td><code>IconButton</code> sm,hover 才显示;下拉用 <code>Menu/MenuItem</code></td></tr>
2183
- <tr><td>归档确认</td><td>替换标题区,<code>Button</code> sm(danger 确认 / secondary 取消)</td></tr>
2195
+ <tr><td>Container</td><td><code>margin: 1px 6px; padding: 7px 10px; radius-md</code>; hover = <code>surface-sunken</code>; active = <code>accent-soft</code> + <code>inset 0 0 0 1px accent-bd</code></td></tr>
2196
+ <tr><td>Status slot (lead)</td><td>fixed <code>--sb-gutter</code> width; running = <code>Spinner</code> sm, otherwise unread = 7px accent dot</td></tr>
2197
+ <tr><td>Title</td><td>flex:1 with truncation; double-click enters inline rename (compact input, not Input)</td></tr>
2198
+ <tr><td>Attention Badge</td><td><code>Badge</code> sm: info (needs answer) / warning (needs approval) / danger (aborted); <b>always shown</b>, not toggled on hover</td></tr>
2199
+ <tr><td>Trailing action slot (trail)</td><td>fixed slot shared by the time ↔ kebab (see below)</td></tr>
2200
+ <tr><td>Archive confirmation</td><td>replaces the title area, <code>Button</code> sm (danger confirm / secondary cancel)</td></tr>
2184
2201
  </tbody>
2185
2202
  </table>
2186
2203
 
2187
- <h3 class="sub">工作区分组 Workspace group</h3>
2188
- <p>分组头与会话行共用 <code>--sb-*</code>:文件夹图标(开/合)→ 名称 → 路径副标题,hover 露出 kebab 与「+」。</p>
2204
+ <h4 class="mini">Trailing action slot</h4>
2205
+ <p>The session row's rightmost is a <b>fixed-width</b> action slot: at rest it shows the relative time (mono xs, <code>fg-faint</code>); on hover it swaps <b>in place</b> to the kebab (<code>IconButton</code> sm).</p>
2189
2206
  <ul class="clean">
2190
- <li>文件夹图标放在 <code>--sb-gutter</code> 槽里,开合态切换图标。</li>
2191
- <li>名称下方一行 <code>fg-muted</code> 的小字路径。</li>
2192
- <li>kebab(菜单)与「+」(在该工作区新建)都用 <code>IconButton</code> sm,hover 才显示。</li>
2193
- <li>分组可折叠;折叠时隐藏其会话列表。</li>
2207
+ <li>The time and kebab are stacked with <code>display:inline-grid</code> + <code>grid-area:1/1</code> and swapped on hover via <code>visibility</code> — <b>never <code>display:none</code></b>.</li>
2208
+ <li>The slot width is always <code>max(time width, IconButton sm 26px)</code>, so the right region's total width is unchanged across hover — badges don't shift, the title's visible character count doesn't change, <b>no jitter</b>.</li>
2209
+ <li>A session awaiting an answer (info Badge) likewise shows no time on hover: the slot holds only the kebab.</li>
2210
+ </ul>
2211
+ <div class="code"><div class="code-bar"><span class="d"></span><span class="d"></span><span class="d"></span><span class="fn">SessionRow.vue</span></div><pre>.act { display: inline-grid; flex: none; align-items: center; justify-items: center; }
2212
+ .act .ts, .act .kebab { grid-area: 1 / 1; }
2213
+ .act .kebab { visibility: hidden; }
2214
+ .se:hover .act .kebab, .act:has(.kebab.open) .kebab { visibility: visible; }
2215
+ .se:hover .act .ts, .act:has(.kebab.open) .ts { visibility: hidden; }</pre></div>
2216
+ <div class="callout info"><span class="ico">i</span><div>
2217
+ <b>Why the time and kebab share a slot and use <code>visibility</code> rather than <code>display:none</code>:</b> the time is variable-width (<code>2h</code> / <code>5m</code> / <code>just now</code> …), the kebab a fixed 26px. If hover used <code>display:none</code> to drop the time and append the kebab, the right region would reflow — badges shift and the title's truncation changes, causing visible jitter. Sharing one slot and swapping via <code>visibility</code> keeps the slot width constant; this is a hard rule for sidebar list-row stability.
2218
+ </div></div>
2219
+
2220
+ <h3 class="sub">Workspace group</h3>
2221
+ <p>The group head and session rows share <code>--sb-*</code>: folder icon (open/closed) → name → path subtitle, with the kebab and "+" revealed on hover.</p>
2222
+ <ul class="clean">
2223
+ <li>The folder icon sits in the <code>--sb-gutter</code> slot, switching icons between open and closed states.</li>
2224
+ <li>A small <code>fg-muted</code> path line sits below the name.</li>
2225
+ <li>The kebab (menu) and "+" (new chat in this workspace) both use <code>IconButton</code> sm, shown on hover or keyboard focus (when not hovered they stay in the tab order via <code>opacity:0</code>, keeping them keyboard-reachable).</li>
2226
+ <li>The group is collapsible; when collapsed its session list is hidden.</li>
2194
2227
  </ul>
2195
2228
 
2196
- <h3 class="sub">拖拽手柄 ResizeHandle</h3>
2197
- <p>一条 4px 的竖向拖拽条,叠在 1px 列边框上(<code>margin: 0 -2px</code> 让 4px 整条可抓),hover / 拖拽时变 accent。</p>
2229
+ <h3 class="sub">Show more &amp; collapse</h3>
2230
+ <p>The "load more / show less" control at the bottom of each workspace group is a session-row-shaped compact list control (same family as search, New chat, inline rename — not a Button). It doubles as the pagination trigger and the in-group expand / collapse toggle.</p>
2198
2231
  <table class="dt">
2199
- <thead><tr><th>规则</th><th>值</th></tr></thead>
2232
+ <thead><tr><th>Part</th><th>Rule</th></tr></thead>
2200
2233
  <tbody>
2201
- <tr><td>宽度 / 光标</td><td>4px / <code>col-resize</code></td></tr>
2202
- <tr><td>常态 / 激活</td><td>透明 / <code>accent</code> 填充</td></tr>
2203
- <tr><td>层级</td><td><code>--z-sticky</code>,盖在列边框上</td></tr>
2204
- <tr><td>行为</td><td>拖拽时面板宽度 1:1 跟随指针(父级关掉过渡避免 lag);松开后持久化到 localStorage</td></tr>
2234
+ <tr><td class="tk">Container</td><td>session-row pill: <code>display:flex; gap:--sb-gap; min-height:26px</code>, same padding as a session row, <code>radius-md</code>; hover = <code>surface-sunken</code> (no text recolor); <code>:focus-visible</code> uses <code>--p-focus-ring</code></td></tr>
2235
+ <tr><td class="tk">Lead slot</td><td>empty, <code>--sb-gutter</code> wide, so the label's start x aligns with the session titles (<code>--sb-pad-x + --sb-gutter + --sb-gap</code>)</td></tr>
2236
+ <tr><td class="tk">Label</td><td><code>font-ui</code>, <code>text-xs</code>, <code>--color-text</code>; flex:1, truncated</td></tr>
2237
+ <tr><td class="tk">Behavior</td><td>"Load more" fetches the next page and auto-expands; once more than the first page is loaded, "Show less" appears and collapses back to the first page (view-layer trim — data is kept, no refetch); "Show all" re-expands</td></tr>
2205
2238
  </tbody>
2206
2239
  </table>
2207
2240
 
2208
- <h3 class="sub">右侧面板 Right panel</h3>
2209
- <p>右侧面板(文件预览 / Diff / 思考 / 子 Agent / 侧聊)共用同一条轨道与同一个头部基元。</p>
2241
+ <h3 class="sub">ResizeHandle</h3>
2242
+ <p>A 4px vertical drag bar, layered over the 1px column border (<code>margin: 0 -2px</code> makes the whole 4px grabbable), turning accent on hover / drag.</p>
2243
+ <table class="dt">
2244
+ <thead><tr><th>Rule</th><th>Value</th></tr></thead>
2245
+ <tbody>
2246
+ <tr><td>Width / cursor</td><td>4px / <code>col-resize</code></td></tr>
2247
+ <tr><td>Normal / active</td><td>transparent / <code>accent</code> fill</td></tr>
2248
+ <tr><td>Layer</td><td><code>--z-sticky</code>, over the column border</td></tr>
2249
+ <tr><td>Behavior</td><td>panel width follows the pointer 1:1 while dragging (the parent disables transitions to avoid lag); on release it is persisted to localStorage</td></tr>
2250
+ </tbody>
2251
+ </table>
2252
+
2253
+ <h3 class="sub">Right panel</h3>
2254
+ <p>The right panels (file preview / Diff / thinking / sub-agent / side chat) share one track and one head primitive.</p>
2210
2255
  <ul class="clean">
2211
- <li>面板头用 <code>PanelHeader</code> 基元(48px = <code>--panel-head-h</code>),与会话栏头部等高,hairline 连成一线。</li>
2212
- <li>面板头:粗体 mono 标题 + 可选 muted 副标题 + 中间 slot(Badge / 控件 / 路径)+ 右侧关闭 IconButton。</li>
2213
- <li>打开时面板宽度从 <code>0 → var(--preview-w)</code>,会话栏被平滑挤压。</li>
2214
- <li>≤640px 时面板变为全屏覆盖(<code>position:fixed; inset:0</code>)。</li>
2256
+ <li>The panel head uses the <code>PanelHeader</code> primitive (48px = <code>--panel-head-h</code>), the same height as the conversation column head, so the hairline runs as one line.</li>
2257
+ <li>Panel head: bold mono title + optional muted subtitle + middle slot (Badge / control / path) + close IconButton on the right.</li>
2258
+ <li>When opened, the panel width goes from <code>0 → var(--preview-w)</code>, smoothly squeezing the conversation column.</li>
2259
+ <li>At ≤640px the panel becomes a full-screen overlay (<code>position:fixed; inset:0</code>).</li>
2215
2260
  </ul>
2216
2261
 
2217
2262
  <div class="callout info"><span class="ico">i</span><div>
2218
- <b>一句话原则:</b>侧栏 / 壳是「列表 + 网格」骨架,复用 §02 token 与 §03 基元(Button / IconButton / Badge / Menu / Spinner / PanelHeader);凡是不 fit 基元的紧凑列表控件(search、New chat、行间改名、show-more)保留定制,并以本节为规范。
2263
+ <b>One-sentence principle:</b> the sidebar / shell is a "list + grid" skeleton that reuses the §02 tokens and §03 primitives (Button / IconButton / Badge / Menu / Spinner / PanelHeader); compact list controls that don't fit a primitive (search, New chat, inline rename, show-more) keep their custom form, governed by this section.
2264
+ </div></div>
2265
+ </section>
2266
+
2267
+ <!-- ===== 08 Accessibility A11y ===== -->
2268
+ <section id="a11y">
2269
+ <div class="sec-head">
2270
+ <span class="sec-num">08</span>
2271
+ <h2 class="sec-title">Accessibility (pragmatic edition)</h2>
2272
+ </div>
2273
+ <p class="sec-desc">
2274
+ Kimi Web is a local developer tool; it <b>does not target a specific WCAG conformance level</b>, nor maintain a full screen-reader QA matrix.
2275
+ This section collects only the rules that are "low-cost, don't hurt the look, and directly benefit keyboard-heavy users", as the baseline contract for each primitive;
2276
+ the more expensive, lower-ROI parts (such as real-time announcement orchestration for streaming output) are not mandatory for now.
2277
+ </p>
2278
+
2279
+ <div class="callout info"><span class="ico">i</span><div>
2280
+ <b>On the "ugly" focus ring:</b> the focus visibility required below always uses <code>:focus-visible</code> (not <code>:focus</code>).
2281
+ It appears <b>only on keyboard focus</b>; mouse clicks don't trigger it, so it doesn't pollute the mouse-driven visual; the ring's strength is tuned uniformly with <code>--p-focus-ring</code>, not overridden per place.
2282
+ </div></div>
2283
+
2284
+ <h4 class="mini">1. Contrast &amp; color</h4>
2285
+ <ul class="clean">
2286
+ <li>Body text vs. background contrast <b>≥ 4.5:1</b>; control borders, icons, and key graphics <b>≥ 3:1</b>. When changing theme colors / dark mode, verify against §05 together.</li>
2287
+ <li><b>Button text vs. button background</b>, and <b>form controls</b> (input, placeholder, helper / error text) <b>vs. their section background</b> must all have contrast ≥ 4.5:1 (large text ≥ 3:1). White-on-white text, a transparent borderless button floating over the page background, and a light placeholder on a near-white background are all flagged by the style rules.</li>
2288
+ <li><b>State is not conveyed by color alone.</b> Error, selected, and disabled states also carry text, an icon, or a shape change (for example an error state is not just red, but also carries text or an icon).</li>
2289
+ </ul>
2290
+
2291
+ <h4 class="mini">2. Keyboard operable</h4>
2292
+ <p>Anything doable with a mouse must also be doable with a keyboard; Tab order follows the DOM, with no invented skipping. Composite controls define their keyboard model per the table below; a missing model is treated as incomplete:</p>
2293
+ <table class="dt">
2294
+ <thead><tr><th>Control</th><th>Keyboard behavior</th></tr></thead>
2295
+ <tbody>
2296
+ <tr><td class="tk">Dialog</td><td><code>Tab</code> cycles within the dialog (focus trap); <code>Esc</code> closes; focus returns to the trigger element after closing.</td></tr>
2297
+ <tr><td class="tk">Menu</td><td><code>↑</code> / <code>↓</code> move the highlight, <code>Enter</code> selects, <code>Esc</code> closes.</td></tr>
2298
+ <tr><td class="tk">Tabs</td><td><code>←</code> / <code>→</code> switch tabs (roving tabindex); only the current tab is in the Tab sequence.</td></tr>
2299
+ <tr><td class="tk">Switch / Segmented</td><td><code>←</code> / <code>→</code> or <code>Space</code> / <code>Enter</code> to toggle.</td></tr>
2300
+ </tbody>
2301
+ </table>
2302
+
2303
+ <h4 class="mini">3. Focus visibility</h4>
2304
+ <ul class="clean">
2305
+ <li>Every interactive element must have a visible focus indicator on keyboard focus, uniformly via <code>:focus-visible</code> + <code>--p-focus-ring</code> (primary actions may use <code>--p-focus-ring-strong</code>).</li>
2306
+ <li>Bare <code>outline: none</code> is forbidden. To remove the default outline, you must provide an equivalent replacement style.</li>
2307
+ </ul>
2308
+
2309
+ <h4 class="mini">4. Labels &amp; semantics</h4>
2310
+ <ul class="clean">
2311
+ <li><b>Semantic HTML first</b> (button / a / input / dialog…); ARIA is added only when native semantics fall short.</li>
2312
+ <li>Icon-only buttons must have an <code>aria-label</code> — <code>IconButton</code> already enforces this with a required <code>label</code> prop.</li>
2313
+ <li>Dialog: <code>role="dialog"</code> + <code>aria-modal="true"</code>, with the title as the dialog's accessible name.</li>
2314
+ <li>Purely decorative SVG / icons get <code>aria-hidden="true"</code> to avoid being read out by screen readers.</li>
2315
+ </ul>
2316
+
2317
+ <h4 class="mini">5. Target size</h4>
2318
+ <p>Desktop click targets <b>≥ 32px</b>; touch devices <b>≥ 44px</b> (consistent with the §01 principle and the IconButton <code>lg</code> tier).</p>
2319
+
2320
+ <h4 class="mini">6. Reduced motion</h4>
2321
+ <p>Handled uniformly in the global styles per §02's <code>@media (prefers-reduced-motion: reduce)</code>; components do not check this individually. The MoonSpinner moon phase pauses on the current frame.</p>
2322
+
2323
+ <h4 class="mini">7. Live announcements (non-mandatory)</h4>
2324
+ <p>Screen-reader announcements are <b>not a mandatory contract</b> in this product. Short hints like Toast can use <code>role="status"</code> / <code>aria-live</code>; chat streaming output is currently not announced word-by-word, which is an acceptable trade-off, to be added later if a real need arises.</p>
2325
+
2326
+ <div class="callout good"><span class="ico">✓</span><div>
2327
+ <b>Explicitly not mandatory for now:</b> a WCAG conformance-level claim, a complete ARIA pattern table, a per-screen-reader QA matrix, and real-time announcement orchestration for streaming output — these are not written into the primitive contract, to avoid becoming slogans no one maintains.
2219
2328
  </div></div>
2220
2329
  </section>
2221
2330
 
@@ -2224,7 +2333,7 @@ export function auth(token: string) {
2224
2333
  </div>
2225
2334
 
2226
2335
  <script>
2227
- // 滚动时高亮当前章节对应的侧边导航
2336
+ // Highlight the side-nav entry for the section currently in view while scrolling
2228
2337
  (function () {
2229
2338
  var links = Array.prototype.slice.call(document.querySelectorAll('#nav a[href^="#"]'));
2230
2339
  var map = new Map();