From d1275557f91da746c251e18b3cf3a86d51fc49e8 Mon Sep 17 00:00:00 2001 From: qer Date: Thu, 2 Jul 2026 19:16:04 +0800 Subject: [PATCH] docs(web): translate design system to English and add anti-slop guidance (#1302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(web): add anti-slop design guidance inspired by taste-skill Codify one icon family (Remix) with no hand-rolled SVG in §02. Expand the banned AI-tell list in §01 (AI-purple/blue glow, infinite-loop micro-animations). Add button and form contrast requirements to §08. Add a 'declare design intent (Design Read) first' callout. * docs(web): resolve merge conflict with main Reset design-system.html to latest main (which includes the merged #1300 and #1301) and re-apply the taste-skill design guidance on top, so the branch merges cleanly. * docs(web): translate design system to English Translate the entire design-system.html from Chinese to English, preserving all HTML structure, CSS, code blocks, SVGs, the scroll-spy script, and token values. The design system is now a single English document. --- apps/kimi-web/design/design-system.html | 1285 ++++++++++++----------- apps/kimi-web/public/design-system.html | 1285 ++++++++++++----------- 2 files changed, 1296 insertions(+), 1274 deletions(-) diff --git a/apps/kimi-web/design/design-system.html b/apps/kimi-web/design/design-system.html index 41fa3e2d2..3694066d9 100644 --- a/apps/kimi-web/design/design-system.html +++ b/apps/kimi-web/design/design-system.html @@ -1,15 +1,16 @@ - + -Kimi Web · 设计系统 +Kimi Web · Design System
- + - +
@@ -842,76 +848,80 @@
● Design System · v1.0 -

Kimi Web 设计系统

+

Kimi Web Design System

- 本文定义 Kimi Web 的视觉语言与组件规范——设计令牌、组件基元、聊天界面、主题系统与样式规则。 - 所有 UI 工作以此为基准:统一、克制、token 驱动、可主题化。 + This document defines the visual language and component specification for Kimi Web — design tokens, component primitives, the chat interface, theming, and style rules. + All UI work is grounded in it: unified, restrained, token-driven, and themeable.

- 范围 apps/kimi-web - 组件基元 - 主题 1 套 · 4 色可定制 - 亮 / 暗模式 + Scope apps/kimi-web + Component primitives + Theme 1 set · 4 customizable colors + Light / dark mode
i
- 本规范是改 web UI 时的唯一参考。新增或修改组件、样式、布局、主题前,请先读本文; - 颜色、字体、圆角、间距、阴影、层级、动效一律使用 §02 的 token,组件复用 §03 的基元,并遵守 §06 的样式规则。 + This spec is the single reference when changing the web UI. Before adding or modifying a component, style, layout, or theme, read this document first; + 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.
- +
01 -

设计原则

+

Design Principles

- 所有 UI 决策回指以下原则。Kimi Web 是给开发者用的本地 Agent 工具:快速扫读、长时间注视、经常在暗色下——设计服务于任务,克制、临床、信息密度优先。 + 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.

    -
  • 一致性 Consistency —— 同一语义用同一组件。主按钮、弹窗、输入、徽标在全站只应各有「一种」正确写法。
  • -
  • 视觉层级 Hierarchy —— 通过字号、字重、色彩与留白建立清晰层级;用「克制」而非「加粗加大」来强调。
  • -
  • 亲密性 Proximity —— 相关元素归组,无关元素留白。卡片的内边距、行间与分组间距来自同一间距刻度。
  • -
  • 反馈 Feedback —— hover / active / focus / loading / success / error 都有可见状态,且状态语言统一。
  • -
  • 留白 Breathing room —— 用间距刻度而非随机像素控制密度;宁可克制留白,不让控件互相挤压。
  • -
  • 可访问性 A11y —— 文本对比度 ≥ 4.5:1,焦点环可见,触摸目标 ≥ 32px,状态不只依赖颜色。
  • -
  • 少即是多 Reduction —— 颜色数量、圆角数量、阴影层级、字号阶梯都收敛到有限 token,删除游离值。
  • +
  • Consistency —— 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.
  • +
  • Hierarchy —— Build a clear hierarchy through size, weight, color, and whitespace; emphasize through "restraint" rather than "bolder and bigger".
  • +
  • Proximity —— Group related elements, leave whitespace between unrelated ones. A card's padding, line spacing, and group spacing all come from the same spacing scale.
  • +
  • Feedback —— hover / active / focus / loading / success / error all have visible states, and the state language is unified.
  • +
  • Breathing room —— Control density with the spacing scale rather than arbitrary pixels; prefer restrained whitespace over cramming controls together.
  • +
  • Accessibility (A11y) —— Text contrast ≥ 4.5:1, visible focus rings, touch targets ≥ 32px, and states that don't rely on color alone.
  • +
  • Reduction —— The number of colors, radii, shadow levels, and type sizes all converge to a finite set of tokens; delete stray values.
- 品牌调性(反向清单):冷静、临床、不夸大。拒绝紫色渐变、玻璃拟态、发光阴影、「Boost your productivity」式营销文案、以及用 emoji 充当图标——月相 🌑…🌘 是唯一例外,仅用于「等待 Agent 响应」的聊天态,属品牌特色。 + Brand tone (the do-not list): calm, clinical, never exaggerated. Reject 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 — the moon phases 🌑…🌘 are the sole exception, 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.
+ +
i
+ Declare design intent first (Design Read): 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. +
- +
02 -

设计令牌 Design Tokens

+

Design Tokens

- 把所有视觉决策收敛为 token。颜色 token 沿用现有短名并补全语义(降低迁移成本), - 间距、层级、动效、字重则补齐目前缺失的刻度。每个 token 都有:名称、浅色值、深色值、用途。 + Collapse every visual decision into tokens. Color tokens keep the existing short names and fill out the semantics (lowering migration cost), + while spacing, z-index, motion, and font-weight fill in the scales that are currently missing. Every token has: name, light value, dark value, and usage.

i
- 命名约定--<类别>-<角色>-<状态>。例如 --color-text-muted--radius-md--space-4。 - 为减少改动,现有短名(--bg / --ink / --line / --blue …)作为兼容别名保留一个版本周期。 + Naming convention: --<category>-<role>-<state>. For example --color-text-muted, --radius-md, --space-4. + To reduce churn, the existing short names (--bg / --ink / --line / --blue …) are kept as compatibility aliases for one release cycle.
-

颜色 Color

-

语义优先、三层递进:背景 / 文字 / 描边 + 强调色 + 状态色。所有色值在浅色 / 深色下成对定义,对比度均 ≥ 4.5:1。

-
i
下表是派生后的语义 token。其中中性色与强调色由 §05 的 4 个颜色种子派生——例如 --color-accent 取自 --accent-primary--color-bg 取自当前亮 / 暗面。语义状态色(success / warning / danger / info)是与种子配套的独立调色板,亮 / 暗各一套,不自动从种子派生;日常换肤通常只需调 4 个种子,状态色按需微调。
+

Color

+

Semantic-first, in three layers: background / text / border + accent + status colors. All colors are defined in light / dark pairs, with contrast ≥ 4.5:1.

+
i
The table below shows the derived semantic tokens. The neutrals and the accent are derived from the 4 color seeds in §05 — for example --color-accent comes from --accent-primary, and --color-bg comes from the current light / dark surface. The semantic status colors (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.
bg
#ffffff / #0d1117
surface
#fafbfc / #161b22
@@ -923,133 +933,133 @@
accent-soft
#e8f3ff / rgba(88,166,255,.14)
- + - - - - - - - - - - + + + + + + + + + +
Token浅色深色用途
TokenLightDarkUsage
--color-bg#ffffff#0d1117页面底色
--color-surface#fafbfc#161b22面板 / 侧栏 / 卡片头
--color-surface-raised#ffffff#1c2128浮起卡片 / 弹窗 / 输入
--color-text#14171c#e8eaed正文 / 标题
--color-text-muted#6b7280#9aa0a8次级文字 / 占位符
--color-line#e7eaee#2d333b分割线 / 卡片描边
--color-accent#1783ff#58a6ff主操作 / 链接 / 焦点
--color-success#0e7a38#3fb950成功 / 通过
--color-warning#a9610a#d29922警告 / 待确认
--color-danger#c0392b#f85149危险 / 错误 / 中止
--color-bg#ffffff#0d1117Page background
--color-surface#fafbfc#161b22Panel / sidebar / card head
--color-surface-raised#ffffff#1c2128Raised card / dialog / input
--color-text#14171c#e8eaedBody text / headings
--color-text-muted#6b7280#9aa0a8Secondary text / placeholder
--color-line#e7eaee#2d333bDivider / card border
--color-accent#1783ff#58a6ffPrimary action / link / focus
--color-success#0e7a38#3fb950Success / pass
--color-warning#a9610a#d29922Warning / pending
--color-danger#c0392b#f85149Danger / error / abort
-

表面用法 Surface usage

-

四层表面各司其职,按「要抬起的层 / 默认平层 / 下沉层 / 页面底色」选用,避免把 --p-surface-raised 当成万能背景。

+

Surface usage

+

The four surface layers each have a role — choose by "raised layer / default flat layer / sunken layer / page background", and avoid treating --p-surface-raised as a universal background.

- + - - - - + + + +
Token浅色深色用途
TokenLightDarkUsage
--p-surface-raised#ffffff#1c2128浮起卡片 / 弹窗 / 输入(要抬起的层)
--p-surface#fafbfc#161b22面板 / 侧栏 / 卡片头(默认平层)
--p-surface-sunken#f3f5f8#0d1117代码块 / 输入内嵌 / 凹陷区(下沉层)
--p-bg#ffffff#0d1117页面底色
--p-surface-raised#ffffff#1c2128Raised card / dialog / input (raised layer)
--p-surface#fafbfc#161b22Panel / sidebar / card head (default flat layer)
--p-surface-sunken#f3f5f8#0d1117Code block / inline input / recessed area (sunken layer)
--p-bg#ffffff#0d1117Page background
-

焦点环 Focus ring

-

所有可聚焦控件(按钮、输入、链接、菜单项、开关、复选框)统一使用焦点环 token,禁止各自手写 box-shadow 焦点环。

+

Focus ring

+

All focusable controls (button, input, link, menu item, switch, checkbox) use the focus-ring token uniformly; do not hand-write a box-shadow focus ring.

- + - - + +
Token用途
TokenValueUsage
--p-focus-ring0 0 0 3px var(--p-accent-soft)默认焦点环(链接、菜单项、开关、复选框)
--p-focus-ring-strong0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)强焦点环(按钮、主操作)
--p-focus-ring0 0 0 3px var(--p-accent-soft)Default focus ring (link, menu item, switch, checkbox)
--p-focus-ring-strong0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)Strong focus ring (button, primary action)
-

选中文本 Selection

-

文本选中色统一走 --p-selection(浅色 rgba(23,131,255,.18) / 深色 rgba(88,166,255,.32)),由全局 ::selection 规则套用,不另设高亮背景。

+

Text selection

+

The text-selection color uses --p-selection uniformly (light rgba(23,131,255,.18) / dark rgba(88,166,255,.32)), applied by the global ::selection rule; do not set a separate highlight background.

-

禁用态 Disabled

-

所有禁用控件统一 opacity:.5 + cursor:not-allowed,不再单独调灰或改色。

+

Disabled state

+

All disabled controls use opacity:.5 + cursor:not-allowed uniformly; do not separately grey out or recolor.

-

字体族 Font families

-

Kimi Web 使用两套字体族:--font-ui(UI 与正文,系统字体优先)与 --font-mono(代码与等宽)。组件一律通过变量引用,禁止硬编码字体名。

+

Font families

+

Kimi Web uses two font families: --font-ui (UI and body, system fonts first) and --font-mono (code and monospace). Components always reference the variables; do not hard-code font names.

-

--font-ui · UI 与正文(系统字体优先)

-

正文与 UI 采用各平台原生 UI 字体,观感接近系统、长文与中文更舒适。回退链:

+

--font-ui · UI & body (system fonts first)

+

Body and UI use each platform's native UI font — close to the system feel, comfortable for long text and CJK. Fallback chain:

--font-ui
--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI",
   "PingFang SC", "Microsoft YaHei", "Noto Sans SC",
   "Helvetica Neue", Arial, sans-serif,
   "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
    -
  • 系统 UI 字体在前:macOS / iOS 用 SF Pro,Windows 用 Segoe UI。
  • -
  • CJK 紧随:PingFang SC(macOS)/ Microsoft YaHei(Windows)/ Noto Sans SC(Linux)。
  • -
  • Helvetica Neue / Arial / sans-serif 通用兜底;末尾补 emoji 字体。
  • +
  • System UI fonts first: SF Pro on macOS / iOS, Segoe UI on Windows.
  • +
  • CJK next: PingFang SC (macOS) / Microsoft YaHei (Windows) / Noto Sans SC (Linux).
  • +
  • Helvetica Neue / Arial / sans-serif as generic fallbacks; emoji fonts at the end.
-

--font-mono · 代码与等宽

-

代码、工具名、行号、diff 等使用 JetBrains Mono(自托管可变字体),回退到系统等宽:

+

--font-mono · Code & monospace

+

Code, tool names, line numbers, diffs, etc. use JetBrains Mono (a self-hosted variable font), falling back to the system monospace:

--font-mono
--font-mono: "JetBrains Mono Variable", "JetBrains Mono",
   ui-monospace, "SF Mono", Menlo, Consolas, monospace;
-

加载策略

+

Loading strategy

- + - - - + + +
字体来源打包用途
FontSourceBundledUsage
JetBrains Mono@fontsource-variable/jetbrains-mono✓ 自托管等宽 / 代码(--font-mono)
Inter@fontsource-variable/inter✓ 自托管可选:页面标题 / 品牌字样(--font-display)
系统 UI / CJK 字体操作系统正文 / UI(--font-ui),不打包
JetBrains Mono@fontsource-variable/jetbrains-mono✓ self-hostedmonospace / code (--font-mono)
Inter@fontsource-variable/inter✓ self-hostedoptional: page titles / brand wordmark (--font-display)
System UI / CJK fontsoperating systembody / UI (--font-ui), not bundled
- 自托管 Inter / JetBrains Mono,无外部网络请求、无 FOUT、可离线;系统字体不打包,符合本地优先。 + Self-hosted Inter / JetBrains Mono: no external network requests, no FOUT, works offline; system fonts are not bundled, consistent with the local-first approach.
-

使用规则

+

Usage rules

    -
  • 组件一律用 var(--font-ui) / var(--font-mono),禁止硬编码 'Inter' / 'JetBrains Mono' 等字体名。
  • -
  • 正文 / UI 走 --font-ui(系统字体优先);代码 / 等宽走 --font-mono(JetBrains Mono)。
  • -
  • Inter 仅用于需要统一观感的标题 / 品牌场景(可选 --font-display),不再作为正文默认。
  • +
  • Components always use var(--font-ui) / var(--font-mono); do not hard-code font names like 'Inter' / 'JetBrains Mono'.
  • +
  • Body / UI use --font-ui (system fonts first); code / monospace use --font-mono (JetBrains Mono).
  • +
  • Inter is used only for headings / brand scenarios that need a unified look (optional --font-display); it is no longer the body default.
-

字号与字重 Type scale & weight

-

字号阶梯沿用并规范现有的 --ui-font-size(UI,默认 14px)/ --content-font-size(正文,16px)双轨:UI 控件 / 按钮 / 表单--text-base(14px);阅读型正文——包括聊天 Markdown、消息气泡等为提升可读性用 --text-lg(16px,行高 relaxed);侧栏会话列表为信息密度用 calc(var(--ui-font-size) - 1px)(15px,比侧栏 16px 基底小一档)。 - 删除游离的 font-weight: 650 / 750,统一到 400 / 500 两档(常规 / 强调)。

+

Type scale & weight

+

The type scale keeps and formalizes the existing --ui-font-size (UI, default 14px) / --content-font-size (body, 16px) dual tracks: UI controls / buttons / forms use --text-base (14px); reading body — including chat Markdown, message bubbles, etc. uses --text-lg (16px, relaxed line-height) for readability; the sidebar session list uses calc(var(--ui-font-size) - 1px) (15px, one step below the sidebar's 16px base) for density. + Drop stray font-weight: 650 / 750; converge on two weights, 400 / 500 (regular / emphasis).

-
页面标题 Page Title
--text-2xl · 22 / 500
-
区块标题 Section
--text-xl · 18 / 500
-
聊天正文 / 卡片标题 Content
--text-lg · 16 / 400
-
UI 控件 / 按钮 / 表单 UI
--text-base · 14 / 500
-
辅助说明 / 表格
--text-sm · 13 / 400
-
徽标 / 时间戳 / 行号
--text-xs · 12 / 500
+
Page Title
--text-2xl · 22 / 500
+
Section Title
--text-xl · 18 / 500
+
Chat body / card title
--text-lg · 16 / 400
+
UI control / button / form
--text-base · 14 / 500
+
Helper text / table
--text-sm · 13 / 400
+
Badge / timestamp / line number
--text-xs · 12 / 500
- + - - - - + + + +
Token用途
TokenValueUsage
--font-ui-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC"…UI 与正文(系统字体优先)
--font-monoJetBrains Mono…代码、工具名、行号、diff
--leading-tight/normal/relaxed1.25 / 1.5 / 1.7标题 / UI / 长文
--weight-regular/medium400 / 500正文 / 强调
--font-ui-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC"…UI & body (system fonts first)
--font-monoJetBrains Mono…code, tool names, line numbers, diffs
--leading-tight/normal/relaxed1.25 / 1.5 / 1.7headings / UI / long text
--weight-regular/medium400 / 500body / emphasis
-

图标尺寸 Icon size

-

图标统一使用三档尺寸 token,全局 .p-ic 默认 16px(--p-ic-md);各组件按需选用,禁止手写随机像素。

+

Icon size

+

Icons use three size tokens uniformly. The global .p-ic default is 16px (--p-ic-md); components pick as needed, and random pixel sizes are forbidden.

- + - - - + + +
Token用途
TokenValueUsage
--p-ic-sm14px小按钮、徽标、菜单项、链接内嵌图标
--p-ic-md16px默认(按钮、图标按钮、工具条)
--p-ic-lg20pxToast 状态图标、空状态插图
--p-ic-sm14pxsmall button, badge, menu item, inline link icon
--p-ic-md16pxdefault (button, icon button, toolbar)
--p-ic-lg20pxToast status icon, empty-state illustration
-

图标 Icon

-

图标一律从集中注册表 lib/icons.ts 取用:模板中用 <Icon name size /> 组件(components/ui/Icon.vue),v-html 场景(如工具 glyph)用 iconSvg(name, size)禁止手写 <svg>——scripts/check-style.mjsicon-from-registry 规则会对游离 SVG 告警。图标来自 Remix Icon(Apache-2.0),统一为 fill 风格(fill="currentColor"、24×24 源网格),颜色跟随文字;尺寸走下方三档 token。注册表由 scripts/gen-icon-data.mjs@iconify-json/ri 按需生成,离线且 tree-shaken。

+

Icon

+

Icons always come from the centralized registry lib/icons.ts: in templates use the <Icon name size /> component (components/ui/Icon.vue); for v-html contexts (such as a tool glyph) use iconSvg(name, size). Do not hand-write <svg> — the scripts/check-style.mjs icon-from-registry rule flags stray SVGs. Icons come from Remix Icon (Apache-2.0), uniformly in a fill style (fill="currentColor", 24×24 source grid), with color following the text; size uses the three tokens below. The registry is generated on demand by scripts/gen-icon-data.mjs from @iconify-json/ri, offline and tree-shaken. The whole site uses only this one icon family; do not mix in other icon libraries, and never hand-write SVG paths. When an icon is missing, add it to the registry (edit the mapping in gen-icon-data.mjs and regenerate) rather than drawing it in a component.

-

尺寸阶梯 Size scale

+

Size scale

sm · 14
md · 16
lg · 20
-

图标库 Icon library

-

当前注册的图标(按用途分组)。图标数据由 scripts/gen-icon-data.mjs 中的 NAME_TO_REMIX 映射决定,运行 pnpm gen:icons 生成 lib/icon-data.ts;本目录由 node --experimental-strip-types scripts/gen-icon-catalog.mjs 重新生成,保证注册表与文档不漂移。

+

Icon library

+

Currently registered icons, grouped by purpose. The icon data is determined by the NAME_TO_REMIX mapping in scripts/gen-icon-data.mjs; running pnpm gen:icons generates lib/icon-data.ts. This catalog is regenerated with node --experimental-strip-types scripts/gen-icon-catalog.mjs so the registry and the document never drift.

Actions
plus
@@ -1117,26 +1127,26 @@
grip
-

禁止用 emoji 充当功能图标(唯一例外:月相 🌑…🌘,仅用于「等待 Agent 响应」聊天态)。Kimi 品牌标记(32×22 的眼睛 logo)属于品牌资产,不在此图标体系内。

-

少数特殊图形不进注册表,各有专属组件统一维护,禁止复制手写:<ContextRing :pct />(Composer 上下文进度环,数据驱动)、<AuthStateIcon kind />(登录流程的成功 / 过期 / 错误彩色插图)、<Spinner />(加载态)。状态小圆点(如 Provider 列表)一律用 CSS 圆点(border-radius:50%),不再用 SVG。scripts/check-style.mjsicon-from-registry 规则对以上与品牌标记豁免,其余手写 <svg> 一律告警。

+

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.

+

A few special graphics are not in the registry; each has a dedicated component maintained in one place, and must not be copied by hand: <ContextRing :pct /> (the Composer context progress ring, data-driven), <AuthStateIcon kind /> (the success / expired / error colored illustrations in the login flow), <Spinner /> (loading state). Status dots (such as in the Provider list) always use CSS dots (border-radius:50%), not SVG. The scripts/check-style.mjs icon-from-registry rule exempts the above and the brand mark; all other hand-written <svg> is flagged.

-

间距 Spacing

-

4px 基础网格,组件内外所有间距、间隙、内边距都来自此刻度,杜绝随机像素。

+

Spacing

+

A 4px base grid. All spacing, gaps, and padding inside and outside components come from this scale — no arbitrary pixels.

-
--space-1 · 4
图标间距、徽标内距
-
--space-2 · 8
控件间隙、小内边距
-
--space-3 · 12
按钮内距、表单项间距
-
--space-4 · 16
卡片内边距、栅格 gap
-
--space-5 · 20
弹窗内边距
-
--space-6 · 24
区块间距
-
--space-8 · 32
大区块间距
+
--space-1 · 4
icon gap, badge padding
+
--space-2 · 8
control gap, small padding
+
--space-3 · 12
button padding, form-item gap
+
--space-4 · 16
card padding, grid gap
+
--space-5 · 20
dialog padding
+
--space-6 · 24
section gap
+
--space-8 · 32
large section gap
-

密集列表 Dense list(侧栏 / 文件树)

-

侧栏这类高密度导航列表共用一套节奏,全部落在 4px 网格:行内纵向内距 --space-1(4px),行间 无外边距(hover 圆角 pill 自身提供分隔);区段间距(logo / 搜索 / 操作钮 / 分组标题 / 列表之间)统一 --space-2(8px);分组之间 --space-2;品牌页头顶部略松(--space-3)。新建同类列表时复用此刻度,不要手写 1/6/7/10px。

+

Dense list (sidebar / file tree)

+

High-density navigation lists like the sidebar share one rhythm, all on the 4px grid: in-row vertical padding --space-1 (4px), no margin between rows (the hover pill provides the separation); section gap (between logo / search / action buttons / group title / list) uniformly --space-2 (8px); between groups --space-2; the brand header is slightly looser at the top (--space-3). When building similar lists, reuse this scale — do not hand-write 1/6/7/10px.

-

圆角 Radius

-

把现有 14 个值就近归并到 7 档刻度。规则:组件类型决定圆角,而非作者手感。

+

Radius

+

Merge the existing 14 values into the nearest of 7 scale steps. Rule: the component type determines the radius, not the author's feel.

xs · 4
sm · 6
@@ -1147,171 +1157,171 @@
full · 999
- + - - - - - - - + + + + + + +
Token用途归并来源
TokenValueUsageMerged from
--radius-xs4px小徽标、内嵌标签2/3/4px →
--radius-sm6px小按钮、图标按钮、菜单项5/6px →
--radius-md8px按钮、输入、徽标、卡片7/8/9px →
--radius-lg12px下拉面板10/12px →
--radius-xl16px弹窗、底部 Sheet、Composer14/16px →
--radius-2xl20px强调容器 / 大面板20px
--radius-full999px药丸徽标、头像、发送钮999px / 50%
--radius-xs4pxsmall badge, inline tag2/3/4px →
--radius-sm6pxsmall button, icon button, menu item5/6px →
--radius-md8pxbutton, input, badge, card7/8/9px →
--radius-lg12pxdropdown panel10/12px →
--radius-xl16pxdialog, bottom Sheet, Composer14/16px →
--radius-2xl20pxaccent container / large panel20px
--radius-full999pxpill badge, avatar, send button999px / 50%
-

层级与阴影 Elevation & Z-index

-

阴影只表达「层级」,不用作装饰(无彩色 glow)。z-index 统一成阶梯,根除 9999 式的互相压盖。

+

Elevation & z-index

+

Shadows express only "elevation", never decoration (no colored glow). z-index is unified into a scale, eradicating 9999-style one-upping.

-
sm · 下拉菜单 / 吸顶
+
sm · dropdown menu / sticky
md · Toast
-
lg · 浮层(预留)
-
xl · 弹窗
+
lg · overlay (reserved)
+
xl · dialog
- + - - - - - - - + + + + + + +
Z-index Token用途
Z-index TokenValueUsage
--z-base0常规流
--z-sticky100吸顶表头 / 侧栏
--z-dropdown200下拉菜单 / 工具提示
--z-overlay300遮罩 / 底部 Sheet
--z-modal400弹窗
--z-toast600轻提示
--z-max9999保留:仅此一档用于极端兜底
--z-base0normal flow
--z-sticky100sticky header / sidebar
--z-dropdown200dropdown menu / tooltip
--z-overlay300overlay / bottom Sheet
--z-modal400dialog
--z-toast600toast
--z-max9999reserved: only this tier for extreme fallback
-

动效 Motion

+

Motion

- + - - - - - + + + + +
Token用途
TokenValueUsage
--ease-outcubic-bezier(0.16, 1, 0.3, 1)进入、悬停、展开
--ease-in-outcubic-bezier(0.4, 0, 0.2, 1)面板宽度、布局变化
--duration-fast120ms按下、焦点
--duration-base160ms悬停、显隐
--duration-slow260ms弹窗、Sheet、布局
--ease-outcubic-bezier(0.16, 1, 0.3, 1)enter, hover, expand
--ease-in-outcubic-bezier(0.4, 0, 0.2, 1)panel width, layout changes
--duration-fast120mspress, focus
--duration-base160mshover, show/hide
--duration-slow260msdialog, Sheet, layout
-

减少动态效果 Reduced motion

+

Reduced motion

i
- 在 @media (prefers-reduced-motion: reduce) 下,所有动画与过渡时长降到约 0.001ms(即关闭),MoonSpinner 月相暂停在当前帧。组件不应各自判断,统一在全局样式中处理。 + Under @media (prefers-reduced-motion: reduce), all animation and transition durations drop to about 0.001ms (effectively off), and the MoonSpinner moon phase pauses on the current frame. Components should not check this individually; it is handled uniformly in the global styles.
-

布局与断点 Layout & breakpoints

-

布局尺寸与响应式断点同样 token 化:侧栏宽度、内容阅读栏宽度、两个全局断点。组件不应各自写死像素。

+

Layout & breakpoints

+

Layout sizes and responsive breakpoints are tokenized too: sidebar width, content reading-column width, and two global breakpoints. Components should not hard-code pixels.

- + - - - - - + + + + +
Token用途
TokenValueUsage
--p-sidebar-w264px左侧会话侧栏宽度
--p-content-max760px聊天阅读栏最大宽度
--p-content-wide920px宽内容(设置 / 面板)
--p-bp-sm640px手机 / 桌面分界
--p-bp-md980px窄屏 / 宽屏分界
--p-sidebar-w264pxleft session sidebar width
--p-content-max760pxchat reading-column max width
--p-content-wide920pxwide content (settings / panel)
--p-bp-sm640pxmobile / desktop boundary
--p-bp-md980pxnarrow / wide screen boundary
i
- ≤640px 时:弹窗改为底部 Sheet、侧栏折叠为可展开抽屉、Composer 工具条控件允许换行。 + At ≤640px: dialogs become bottom Sheets, the sidebar collapses into an expandable drawer, and Composer toolbar controls are allowed to wrap.
- +
03 -

组件基元 Primitives

+

Primitives

- 组件基元是全站 UI 的「最小正确单元」。 - 每个基元只暴露 variant / size 两个维度的变体,外观由 token 驱动, - 从而天然支持亮 / 暗模式与可定制主题色。 + Component primitives are the "smallest correct units" of the site UI. + Each primitive exposes variants along only two dimensions — variant / size — with appearance driven by tokens, + so it naturally supports light / dark mode and customizable theme colors.

i
- 每个交互基元的键盘行为、焦点与 ARIA 契约见 §08 可访问性。新增基元须一并给出键盘模型,不能只实现鼠标交互。 + For every interactive primitive, the keyboard behavior, focus, and ARIA contract are in §08 Accessibility. New primitives must ship with a keyboard model — mouse-only interaction is not enough.
- -

组件选型指南

+ +

Component selection guide

- + - - - - - - - - - - - + + + + + + + + + + +
场景用什么
ScenarioUse
主操作(提交 / 确认)Button variant=primary
次操作 / 取消Button secondary / ghost
危险操作(删除 / 中止)Button danger / danger-soft
状态标记Badge
工具条筛选 / 模型切换Pill
2–4 项互斥切换SegmentedControl
顶部标签页Tabs
开关 / 多选Switch / Checkbox
浮起内容卡 / 列表动作菜单Card / Menu
内联通知 / 全局轻提示Banner / Toast
弹窗 / 确认 · 底部面板(移动)Dialog / Sheet
Primary action (submit / confirm)Button variant=primary
Secondary action / cancelButton secondary / ghost
Destructive action (delete / abort)Button danger / danger-soft
Status markerBadge
Toolbar filter / model switchPill
2–4 mutually exclusive optionsSegmentedControl
Top tabsTabs
Switch / multi-selectSwitch / Checkbox
Floating content card / list action menuCard / Menu
Inline notice / global toastBanner / Toast
Dialog / confirmation · bottom panel (mobile)Dialog / Sheet
-

Button · 按钮

-

4 个语义变体 × 3 个尺寸。主操作 primary 的颜色取自当前主题色(§05 可在蓝色系 / 黑色系间切换)。圆角统一走 --radius-md(小尺寸 --radius-sm),字重 600,带可见 focus 环。

+

Button

+

4 semantic variants × 3 sizes. The primary action primary takes its color from the current theme color (§05 can switch between the blue and black families). Radius uses --radius-md uniformly (small size --radius-sm), weight 600, with a visible focus ring.

-
变体矩阵 lightpreview
+
Variant matrix lightpreview
- medium · 默认 + medium · default
- - - - - + + + + +
small
- - - + + +
- 带图标 / 状态 + With icon / state
- - - + + +
-
暗色皮肤 dark
+
Dark skin dark
- - - - + + + +

API

-
Button.vue · 用法
-
<Button variant="primary" size="md" :loading="submitting">保存</Button>
+          
Button.vue · usage
+
<Button variant="primary" size="md" :loading="submitting">Save</Button>
 // variant: primary | secondary | ghost | danger | danger-soft
 // size:    sm | md | lg
-
状态
+
States
- - - + + +
-

IconButton · 图标按钮

-

统一为 26 / 32 / 44px 三档,hover 浅灰底,focus 环可见。替代当前各组件里散落的图标 + 点击区。

+

IconButton

+

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.

IconButton
@@ -1323,25 +1333,25 @@
i
- 桌面 IconButton 提供 sm 26 / md 32 两档;在触摸设备上点击目标应 ≥ 44px,用 lg 44px,满足 §01 的可访问性原则(移动端三件套即使用 lg)。 + The desktop IconButton comes in sm 26 / md 32; on touch devices the tap target should be ≥ 44px, so use lg 44px, satisfying the §01 accessibility principle (the mobile three-piece set uses lg).
-

Badge · Chip · Pill

-

收敛为两类:Badge(状态徽标,带可选状态点)与 Pill(composer 工具条的可点击药丸)。圆角、字号、内边距全部统一。

+

Badge · Chip · Pill

+

Collapsed into two kinds: Badge (status badge, with an optional status dot) and Pill (the clickable pill in the composer toolbar). Radius, font size, and padding are all unified.

-
Badge · 状态徽标
+
Badge · status badge
- 语义变体 + Semantic variants
- 待运行 - 运行中 - 已完成 - 需确认 - 失败 + pending + running + completed + needs confirmation + failed KIMI
- 带图标 / 小尺寸 + With icon / small size
plan passed @@ -1350,7 +1360,7 @@
-
Pill · 工具条药丸(composer)
+
Pill · toolbar pill (composer)
kimi-k2· thinking yolo @@ -1359,104 +1369,104 @@
-

Card / Surface · 卡片与表面

-

全站卡片共用一种外壳:扁平、1px 描边、圆角 --radius-md无阴影。结构上分为 head / body / foot 三段。卡片之间的区别只在头部——按视觉权重分两档,外壳始终保持一致:

+

Card / Surface

+

All cards across the site share one shell: flat, 1px border, --radius-md radius, no shadow. The structure is split into three parts — head / body / foot. Cards differ only in the head — in two tiers by visual weight, while the shell stays consistent:

    -
  • 操作卡 Operation —— 工具调用、Agent、Todo 等「过程」内容。头部紧凑 mono、无底色,默认低权重,不抢对话。
  • -
  • 注意卡 Attention —— Question / Approval 等需要用户决策的内容。头部带语义色带(accent / warning),从消息流中凸显。
  • +
  • Operation card —— "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.
  • +
  • Attention card —— 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.
-
操作卡 · 紧凑 mono 头(无底色)
+
Operation card · compact mono head (no fill)
read_file session.ts
-
头部使用 mono + 中性底色,强调其「代码 / 过程」属性;正文 sans 保证可读性。扁平、radius-md,与工具组、Agent 组同形。
+
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.
-
注意卡 · 语义色带头(accent / warning)
+
Attention card · semantic color-band head (accent / warning)
-
需要你确认一个决定question
-
头部使用语义色浅底(accent-soft / warning-soft),从消息流中凸显,提示用户必须介入。外壳与操作卡完全相同。
+
A decision needs your confirmationquestion
+
The head uses a semantic light background (accent-soft / warning-soft) to stand out from the message stream, signaling that the user must step in. The shell is exactly the same as the operation card.
-
分组 · 容器拥有边框,行间发丝分隔
+
Group · the container owns the border, rows are separated by hairlines
-
3 个工具调用· 已完成
+
3 tool calls· completed
read_filesession.ts
-
grep"jwt" · 4 处
+
grep"jwt" · 4 hits
    -
  • 统一外壳:所有卡片扁平 + 1px 描边 + radius-md,不投射阴影。
  • -
  • 差异有意为之:仅头部区分类型(mono 紧凑 vs 语义色带),外壳始终保持一致。
  • -
  • 分组:外层容器拥有边框与圆角,内部行用 border-top 发丝分隔,不再让每行各自成卡。
  • -
  • 状态点:运行中(脉冲蓝)/ 完成(绿)/ 失败(红),共用同一套颜色词汇(详见 §04 工具调用)。
  • +
  • Unified shell: all cards are flat + 1px border + radius-md, casting no shadow.
  • +
  • Differences are intentional: only the head distinguishes the type (compact mono vs semantic color band); the shell stays consistent.
  • +
  • Grouping: the outer container owns the border and radius; inner rows are separated by border-top hairlines, rather than each row being its own card.
  • +
  • Status dots: running (pulsing blue) / done (green) / failed (red), sharing one color vocabulary (see §04 tool calls).
-

Input / Select / Textarea · 表单输入

-

统一高度 38px(小尺寸 32px)、圆角 --radius-md--color-surface-raised 底、统一蓝色焦点环(0 0 0 3px accent-soft)。

+

Input / Select / Textarea

+

Unified 38px height (32px small), --radius-md radius, --color-surface-raised background, and a unified blue focus ring (0 0 0 3px accent-soft).

-
表单基元
+
Form primitives
- - - 只能包含字母、数字与连字符。 + + + Only letters, numbers, and hyphens are allowed.
- +
- - + +
-
状态
+
States
- + - 请输入有效的工作区名称 + Please enter a valid workspace name
- + - 正常态 · 通过校验 + Normal state · validation passed
-

Code / Diff · 代码与差异

-

inline code、代码块、diff 三档均使用等宽字体(--p-font-mono);代码块带文件名标题条与复制按钮;diff 用 + / - 行色表达增删——新增用成功浅底、删除用危险浅底,无渐变。

+

Code / Diff

+

Inline code, code blocks, and diffs all use the monospace font (--p-font-mono). Code blocks have a filename title bar and a copy button. Diffs use + / - row colors to express additions and deletions — additions use a success light background, deletions use a danger light background, with no gradients.

Code / Diff
inline code -
服务端用 jwt.verify(token) 校验签名,失败返回 401。
+
The server uses jwt.verify(token) to verify the signature, returning 401 on failure.
code block
session.ts - +
import { verify } from './jwt';
 
@@ -1476,154 +1486,154 @@ export function auth(token: string) {
         
-

Dialog · 弹窗

-

一套弹窗基元替代 6 套手写实现:统一圆角 --radius-xl、阴影 --shadow-xl、头部 20px、底部操作右对齐、关闭按钮用 IconButton。

+

Dialog

+

One dialog primitive replaces 6 hand-written implementations: unified --radius-xl radius, --shadow-xl shadow, 20px head padding, right-aligned footer actions, and an IconButton close button.

-
Dialog 基元
+
Dialog primitive
-
新建会话
-
为当前工作区创建一个独立的 Agent 会话。
+
New chat
+
Create an independent Agent chat in the current workspace.
- - + +
- - + +
i
- 尺寸与高度:Dialog 提供三档宽度 md 440 / lg 640 / xl 760(--p-content-max),按内容分量选择。高度分两种:auto(默认,随内容至 max-height)与 fixed(恒定高度 min(680px, 100vh - 64px),内容超出由 body 内部滚动)。内容型 / 多 tab 弹窗(设置、模型选择、提供方管理、文件夹浏览)一律用 fixed,使框体尺寸恒定、不随切换 tab 或内容多少而跳动;内容少的确认类弹窗保持 auto。 + Size & height: Dialog offers three widths — md 440 / lg 640 / xl 760 (--p-content-max) — chosen by content weight. Height comes in two kinds: auto (default, grows with content up to max-height) and fixed (constant height min(680px, 100vh - 64px), with overflow scrolled inside the body). Content / multi-tab dialogs (settings, model picker, provider manager, folder browser) always use fixed so the frame size stays constant and doesn't jump when switching tabs or content length; short confirmation dialogs keep auto.
-

Toast · 轻提示

-

统一信息架构:状态图标 + 标题 + 描述。状态色只出现在图标上,避免大面积彩色造成视觉噪音。

+

Toast

+

Unified information architecture: status icon + title + description. The status color appears only on the icon, avoiding large colored areas that create visual noise.

Toast
-
已连接到服务器
本地守护进程响应正常,可以开始新会话。
+
Connected to server
The local daemon is responding normally; you can start a new chat.
-
上下文使用 82%
建议执行 /compact 以释放空间。
+
Context usage 82%
Consider running /compact to free up space.
-

Spinner · 加载指示器

-

加载器按场景分两类,不要混用

+

Spinner

+

Loaders fall into two categories by scenario — do not mix them:

    -
  • Spinner(普通 · SVG 环形)—— 默认加载器。用于按钮 loading、应用启动(GlobalLoading)、通用内联等待等「其他所有情况」。
  • -
  • MoonSpinner(月相 · 品牌特色)—— 用于「发出消息、等待 Agent 首条响应」这一聊天等待态(ChatPane 的 sending 占位、SideChatPanel、ActivityNotice)。
  • +
  • Spinner (plain · SVG ring) —— the default loader. Used for button loading, app startup (GlobalLoading), and general inline waits — "everything else".
  • +
  • MoonSpinner (moon phase · brand signature) —— used only for the chat waiting state of "message sent, waiting for the Agent's first response" (the sending placeholder in ChatPane, SideChatPanel, ActivityNotice).
-

Spinner · 普通加载器(默认)

+

Spinner · plain loader (default)

-
Spinner · 常规场景
+
Spinner · common scenarios
- 加载中… - + Loading… +
-

MoonSpinner · 月相(仅「等待 Agent 响应」)

+

MoonSpinner · moon phase (only "waiting for the Agent")

-
MoonSpinner · 聊天等待态专属 特色
+
MoonSpinner · chat waiting state only signature
- 帧循环(8 帧) + Frame loop (8 frames)
🌑🌒🌓🌔🌕🌖🌗🌘
- 用法 · 仅聊天等待响应 + Usage · only while the chat waits for a response
- 🌔正在思考… - 🌕正在等待响应… + 🌔Thinking… + 🌕Waiting for response…
-
i
月相是 emoji-as-icon 规则的唯一豁免,且仅限「等待 Agent 首条响应」这一场景。当前它在 MoonSpinner.vueActivityNotice.vue 各实现了一遍,应合并为单个 MoonSpinner 组件,尺寸走 token、支持 prefers-reduced-motion。其余所有加载态一律用普通 Spinner。
+
i
The moon phase is the sole exception to the emoji-as-icon rule, and is limited to the "waiting for the Agent's first response" scenario. It is currently implemented twice — in MoonSpinner.vue and ActivityNotice.vue — and should be merged into a single MoonSpinner component, sized via tokens and supporting prefers-reduced-motion. All other loading states use the plain Spinner.
-

Link · 文字链接

-

行内文本链接:默认主色、无下划线,hover 显示下划线并加深;.muted 变体用次级文字色。用于文本内跳转、外链、「查看全部」等轻量操作。

+

Link

+

Inline text link: the default is the accent color with no underline; on hover it shows an underline and darkens. The .muted variant uses the secondary text color. Used for in-text jumps, external links, "view all", and other lightweight actions.

-
Link · 行内链接
+
Link · inline link
- 阅读完整 设计令牌文档 后再动手。 - 在 GitHub 查看 - 查看历史记录 + Read the full design token docs before building. + View on GitHub + View history
-

Menu / Dropdown · 菜单

-

下拉菜单面板:浮起表面 + 描边 + 轻阴影(--shadow-sm,扁平化取向)。菜单项支持图标、当前态(active)、危险态(danger)、禁用态,项与项之间用分隔线分组。触摸 / 移动端用 lg(≥44px 行高)作为菜单项。

+

Menu / Dropdown

+

Dropdown menu panel: raised surface + border + light shadow (--shadow-sm, 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 lg (≥44px row height) for menu items.

-
Menu · 下拉菜单
+
Menu · dropdown menu
-
打开文件
-
已选中项
-
不可用项
+
Open file
+
Selected item
+
Disabled item
-
删除会话
+
Delete chat
-

SegmentedControl · 分段控件

-

互斥的短选项组,常见于「浅色 / 深色 / 跟随系统」这类 2–4 项切换。当前项以浮起表面 + 微阴影突出。

+

SegmentedControl

+

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.

-
SegmentedControl · 分段控件
+
SegmentedControl
- 浅色 - 深色 - 跟随系统 + Light + Dark + Follow system
-

Tabs · 标签页

-

带底部细线的标签页,用于同级内容的分组切换。当前标签以主色文字 + 主色下划线标示。

+

Tabs

+

Tabs with a bottom hairline, used for grouping and switching sibling content. The current tab is marked with accent text + an accent underline.

-
Tabs · 标签页
+
Tabs
- 通用 + General Agent - 高级 + Advanced
-

Switch · 开关

-

二态开关,用于即时生效的设置项。轨道 36×20、圆角全圆,滑块 16px;开启时轨道变主色、滑块右移,过渡走 token。

+

Switch

+

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.

-
Switch · 开关
+
Switch
@@ -1631,20 +1641,20 @@ export function auth(token: string) {
-

Checkbox · 复选框

-

17×17 复选框,选中时填充主色并显示白色对勾(inline SVG)。常配合文本标签使用。

+

Checkbox

+

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.

-
Checkbox · 复选框
+
Checkbox
- +
-

Avatar · 头像

-

32px 默认头像,圆角 md;.sm 24px。可放首字母或图标,无图片时落回此占位。

+

Avatar

+

A 32px default avatar with md radius; .sm is 24px. Can hold an initial or an icon; falls back to this placeholder when there is no image.

Avatar
@@ -1655,28 +1665,28 @@ export function auth(token: string) {
-

EmptyState · 空状态

-

列表 / 面板无内容时的居中占位:48px 淡色图标 + 标题 + 提示,避免空白页。

+

EmptyState

+

A centered placeholder for empty lists / panels: a 48px faint icon + title + hint, avoiding blank pages.

EmptyState
-
暂无会话
-
点击「新建会话」开始与 Kimi 对话
+
No chats yet
+
Click "New chat" to start a conversation with Kimi
-

Divider · 分隔线

-

1px 水平分隔线(--p-line);.p-divider-v 为垂直分隔,用于行内元素之间。

+

Divider

+

A 1px horizontal divider (--p-line); .p-divider-v is the vertical divider, used between inline elements.

Divider
-
上方内容
+
Content above

-
下方内容
+
Content below
kimi-k2 @@ -1686,38 +1696,38 @@ export function auth(token: string) {
-

Tooltip · 工具提示

-

CSS-only 悬停提示,包在 .p-tip 内。反色底(--p-text / --p-bg),单行不换行,仅承载简短说明。

+

Tooltip

+

A CSS-only hover hint, wrapped in .p-tip. Inverted background (--p-text / --p-bg), single line, no wrapping — carries only short notes.

-
Tooltip(悬停按钮)
+
Tooltip (hover the button)
- 新建会话 + New chat
-

Banner · 横幅通知

-

内联通知条,置于内容区顶部。三态 .info / .warning / .danger,各配同色 18px 图标。

+

Banner

+

An inline notice bar placed at the top of a content area. Three states — .info / .warning / .danger — each with a matching 18px icon.

Banner
-
已连接到服务器
-
当前处于 yolo 模式,工具调用将自动执行
+
Connected to server
+
Currently in yolo mode; tool calls will run automatically
-

Sheet / BottomSheet · 底部面板

-

移动端底部上滑面板:顶部圆角 xl + drag handle,阴影 xl。≤640px 时弹窗改为锚定底部成 Sheet。

+

Sheet / BottomSheet

+

A mobile bottom slide-up panel: xl top radius + drag handle, xl shadow. At ≤640px, dialogs become bottom-anchored Sheets.

BottomSheet
-
选择模型
+
Choose a model
kimi-k2 · thinking
kimi-k2 · instant
@@ -1725,8 +1735,8 @@ export function auth(token: string) {
-

Skeleton · 骨架屏

-

内容加载中的占位,使用呼吸式透明度动画(无渐变),遵守 no-gradient-text 规则。组合成标题 / 文本行 / 头像。

+

Skeleton

+

A placeholder for loading content, using a breathing opacity animation (no gradients), following the no-gradient-text rule. Composed into titles / text lines / avatars.

Skeleton
@@ -1740,39 +1750,39 @@ export function auth(token: string) {
-

Command Bar · 命令条

-

「主操作 + 命令文本 + 复制」的内联组合,介于按钮与代码块之间,用于安装 / 引导 / 一键执行。主操作复用 Button primary,命令区用 mono 浅灰底。

+

Command Bar

+

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 Button primary; the command area uses a mono light-grey background.

-
Command Bar · 命令条
+
Command Bar
- + curl -fsSL https://code.kimi.com/install.sh | bash
-

TopBar · 顶部栏

-

应用顶部条。默认实色;.frost 变体为半透 + 背景模糊,仅用于吸顶导航栏,是 no-glassmorphism 规则的唯一例外(见 §06)。

+

TopBar

+

The application top bar. Solid by default; the .frost variant is translucent + background blur, used only for sticky navigation bars, and is the sole exception to the no-glassmorphism rule (see §06).

-
TopBar · 实色 / 毛玻璃
+
TopBar · solid / frosted glass
- 实色 TopBar + Solid TopBar
- 毛玻璃 TopBar · .frost + Frosted-glass TopBar · .frost
-

SectionLabel · 分组标题

-

侧栏列表的分组小标题,用于为下方内容分区(如侧栏的 Workspaces)。规范:13px / 700 / 大写 / 字距 .08em,色取 --color-fg-faint;左对齐到行的起始内边距(--sb-pad-x),与下方分组行保持同一缩进。中文等无大小写文字下 text-transform:uppercase 自动失效,无需特殊处理。

+

SectionLabel

+

A small group title for sidebar lists, used to section the content below (such as Workspaces in the sidebar). Spec: 13px / 700 / uppercase / letter-spacing .08em, color --color-fg-faint; left-aligned to the row's starting padding (--sb-pad-x), keeping the same indent as the group rows below. For scripts without case (such as Chinese), text-transform:uppercase simply has no effect — no special handling needed.

-
Sidebar · 分组标题
+
Sidebar · group title
@@ -1787,39 +1797,39 @@ export function auth(token: string) {
- +
04 -

聊天界面重构

+

Chat Interface Overhaul

- 消息流是 Kimi Web 的核心。改造目标:让 6 类卡片(Agent / Tool / Question / Approval / Swarm / Todo) - 共享同一套卡片骨架,仅靠头部图标与语义色区分类型;Composer 收敛为单一圆润容器。 + 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) + share one card skeleton, distinguished only by the head icon and semantic color; and collapse the Composer into a single rounded container.

-

统一后的消息流

+

Unified message stream

-
Conversation · 760px 阅读栏
+
Conversation · 760px reading column
-
帮我把登录接口改成 JWT,并补上对应的单元测试。
+
Please change the login endpoint to JWT and add the corresponding unit tests.
- 🌔正在分析认证模块… + 🌔Analyzing the auth module… - +
- 3 个工具调用 - · 已完成 · 0.8s + 3 tool calls + · completed · 0.8s
- +
@@ -1831,7 +1841,7 @@ export function auth(token: string) {
12 export function verify(token: string) {
13 return jwt.verify(token, getSecret());
14 }
- +
@@ -1840,32 +1850,32 @@ export function auth(token: string) { 0.2s
- +
grep - "jwt.verify" · 4 处匹配 + "jwt.verify" · 4 matches 0.1s
- +
-

我看了一下 src/auth 的结构,当前是基于 session cookie 的实现。改动范围如下,你确认后我开始动手。

+

I looked at the structure of src/auth; it is currently based on a session cookie. The scope of the change is below — once you confirm, I'll start.

- +
- 需要你确认一个决定 + A decision needs your confirmation
-
JWT 的过期时间希望设多长?默认 7 天,刷新令牌 30 天。
+
How long should the JWT expiry be? Default 7 days, refresh token 30 days.
- - + +
@@ -1873,36 +1883,36 @@ export function auth(token: string) {
- 需要写入权限 + Write permission required write_file
-
即将修改 src/auth/middleware.ts,共 42 行变更。是否允许?
+
About to modify src/auth/middleware.ts, 42 lines changed. Allow?
- - - + + +
-
替换 session 为 JWT 签发
-
改造认证中间件
-
补充单元测试
+
Replace session with JWT signing
+
Refactor the auth middleware
+
Add unit tests
-

工具调用:默认紧凑、分组、按需展开

-

read_file / bash / grep 这类高频调用是「操作噪音」——若每条都占一张大卡,并行触发时会迅速淹没对话。 - 新策略按视觉权重分三档,把工具调用压到最轻:

+

Tool calls: compact by default, grouped, expand on demand

+

High-frequency calls like read_file / bash / grep are "operational noise" — if each one took a full card, parallel triggers would quickly drown out the conversation. + The new strategy splits tool calls into three tiers by visual weight, pushing them as light as possible:

-
视觉权重三档
+
Three visual-weight tiers
- ① 工具行 · 最轻(默认) + ① Tool row · lightest (default)
@@ -1910,52 +1920,52 @@ export function auth(token: string) { src/auth/session.ts 0.2s
- ② 工具组 · 中(连续 / 并行自动归并,折叠只占一行) + ② Tool group · medium (consecutive / parallel auto-merged; collapsed to one line)
- 3 个工具调用 - · 已完成 · 0.8s + 3 tool calls + · completed · 0.8s
- ③ 决策卡 · 重(仅 question / approval,需用户介入) + ③ Decision card · heavy (only question / approval, needs user input)
-
需要写入权限write_file
-
即将修改 src/auth/middleware.ts,共 42 行变更。
+
Write permission requiredwrite_file
+
About to modify src/auth/middleware.ts, 42 lines changed.
    -
  • 工具调用默认渲染为紧凑行(30px 单行 mono + 状态点 + 关键参数),不再有头 / 身 / 阴影。
  • -
  • 连续或并行的调用自动归为一个工具组,折叠时整组只占一行(N 个工具调用 · 状态)。
  • -
  • 点击行就地展开细节(代码 / 输出),再点收起——细节默认不抢视觉。
  • -
  • 状态用颜色点表达:运行中(脉冲蓝)/ 完成(绿)/ 失败(红),不占额外空间。
  • -
  • 仅两类保留完整卡片Question(需回答)、Approval(需授权)——它们才真正需要用户注意力。
  • +
  • Tool calls render as compact rows by default (30px single-line mono + status dot + key argument); no head / body / shadow.
  • +
  • Consecutive or parallel calls auto-merge into one tool group; when collapsed, the whole group takes one line (N tool calls · status).
  • +
  • Clicking a row expands it in place to show details (code / output); click again to collapse — details don't grab attention by default.
  • +
  • Status is expressed with a colored dot: running (pulsing blue) / done (green) / failed (red), taking no extra space.
  • +
  • Only two types keep a full card: Question (needs an answer) and Approval (needs authorization) — they genuinely need the user's attention.
-
Tool Call · 紧凑行(按需展开)
+
Tool Call · compact row (expand on demand)
-
3 个工具调用· 已完成
+
3 tool calls· completed
read_filesession.ts
12 export function verify(…
read_filemiddleware.ts
-
grep"jwt" · 4 处
+
grep"jwt" · 4 hits
-

Composer · 输入框

-

统一为单一圆润容器:--radius-xl,聚焦时整体描边变蓝 + 软焦点环。工具条控件全部用 Pill / IconButton 基元,发送按钮 32px 圆形。

+

Composer

+

Unified into a single rounded container: --radius-xl, 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.

-
Composer
+
Composer
-
给 Kimi 发消息,/ 调用命令,@ 引用文件…
+
Message Kimi, / to run a command, @ to reference a file…
@@ -1971,122 +1981,122 @@ export function auth(token: string) {
i
- 全站统一:composer 只有一种圆角(--radius-xl · 16px)与一种高度,工具条控件全部用 Pill / IconButton 基元,发送按钮 32px 圆形——不再随主题漂移。 + Site-wide consistency: the composer has only one radius (--radius-xl · 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.
-

响应式 Responsive

-

断点见 §02 --p-bp-sm。此处仅给出聊天界面的移动端适配指针,完整移动端 mockup 不在本规范范围。

+

Responsive

+

See §02 --p-bp-sm 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.

i
- ≤640px 时:弹窗锚定底部成 Sheet(顶部圆角 xl、顶部 drag handle),侧栏折叠为可展开抽屉,Composer 工具条允许换行,聊天阅读栏去除 max-width 占满。 + 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.
- +
05 -

主题系统

+

Theming

- Kimi Web 使用一套统一主题:同一套组件、字体、圆角、阴影与表面,「换肤」只换颜色。 - 颜色收敛为 4 个种子 token——两个主题色 + 一个亮面 + 一个暗面;中性色与强调色由它们派生, - 语义状态色(success / warning / danger)作为独立调色板与种子配套,亮 / 暗各一套。 + Kimi Web uses one unified theme: the same components, fonts, radii, shadows, and surfaces — "reskinning" only changes colors. + Colors are collapsed into 4 seed tokens — two theme colors + one light surface + one dark surface; the neutrals and accent are derived from them, + and the semantic status colors (success / warning / danger) ship as independent palettes paired with the seeds, one set each for light / dark.

-

颜色种子 Color seeds

-

日常定制只需调整这 4 个种子,整站的中性色与强调色随之变化:

+

Color seeds

+

Day-to-day customization only needs these 4 seeds; the whole site's neutrals and accent change with them:

-
主题色 · 主
--accent-primary
-
主题色 · 辅
--accent-secondary
-
亮面
--surface-light
-
暗面
--surface-dark
+
Theme color · primary
--accent-primary
+
Theme color · secondary
--accent-secondary
+
Light surface
--surface-light
+
Dark surface
--surface-dark
-

色系切换 Accent families

-

一套主题之内,主题色(accent)可在多套色系间切换。当前提供两套并列色系:蓝色系(默认,品牌蓝,承载语义强调)与黑色系(中性黑,承载克制的最强操作)。两套共用同一套组件、字体、圆角与表面——切换色系只换 accent 一组 token,结构零变化;后续可继续扩展(绿 / 紫等)。下面两卡是同一个 primary 按钮在两种色系下的呈现。

+

Accent families

+

Within one theme, the theme color (accent) can switch among several color families. Two parallel families are provided today: blue (default, brand blue, carrying semantic emphasis) and black (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 primary button under the two families.

-
色系切换 · 同一 primary,不同主题色
+
Family switch · same primary, different theme color
- 蓝色系 · 默认 -
accent
+ Blue family · default +
accent
--accent #1783ff · soft #e8f3ff
- 黑色系 · 中性 -
accent
+ Black family · neutral +
accent
--accent #14171c · soft #f1f2f4
-

主题控制台 · 改 4 个色,亮/暗一起变

+

Theme console · change 4 colors, light & dark change together

Theme Console
- 主色 #1783ff - 辅色 #6b7280 - 亮面 #ffffff - 暗面 #0d1117 + Primary #1783ff + Secondary #6b7280 + Light surface #ffffff + Dark surface #0d1117
- 亮面预览 - - 白底 + 主色按钮 + 中性文字 + Light surface preview + + White background + accent button + neutral text
- 暗面预览 - - 深底 + 同一主色 + 派生文字 + Dark surface preview + + Dark background + same accent + derived text
-

亮 / 暗模式

-

--surface-light / --surface-dark 两个表面驱动:当前用哪个表面,就派生出对应的前景、描边、阴影与状态色。亮 / 暗切换只是在这两组派生 token 之间切换,结构零变化。

+

Light / dark mode

+

Driven by the two surfaces --surface-light / --surface-dark: 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.

- 一套主题的收益:组件、字体、圆角、表面全站一致;换肤只改 4 个颜色种子;亮 / 暗模式开箱即用;语义状态色独立可调。 + Benefits of one theme: 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.
- +
06 -

样式规则

+

Style Rules

- 所有 UI 代码必须遵守的反模式规则。这些规则也是 check-style 检测脚本的依据,逐条对应一条告警。 + 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.

- + - - - - - - - - - + + + + + + + + +
规则 ID检测内容处置
Rule IDWhat it detectsAction
no-gradient-text渐变文字 / 渐变背景禁止
no-glassmorphismbackdrop-filter: blurTopBar 吸顶导航栏 为唯一例外)TopBar 除外
no-color-glow彩色 / 大半径 box-shadow 发光禁止
no-emoji-icon用 emoji 充当功能性图标(月相 🌑…🌘 为唯一豁免,且仅限「等待 Agent 响应」的聊天态;其余加载态用普通 Spinner)月相除外
no-hardcoded-hex组件 <style> 内出现未登记十六进制色警告
no-hardcoded-font组件内硬编码 font-family(如 'Inter')而非 var(--font-ui)警告
radius-from-scale圆角值不在 {4,6,8,12,16,20,999}警告
z-from-scalez-index 使用未登记的大数字警告
weight-from-scalefont-weight 不在 {400,500}警告
no-gradient-textgradient text / gradient backgroundForbidden
no-glassmorphismbackdrop-filter: blur (TopBar sticky nav bar is the sole exception)TopBar exempt
no-color-glowcolored / large-radius box-shadow glowForbidden
no-emoji-iconusing emoji as a functional icon (the moon phases 🌑…🌘 are the sole exception, and only in the "waiting for the Agent to respond" chat state; all other loading states use the plain Spinner)Moon phase exempt
no-hardcoded-hexunregistered hex color inside a component <style>Warning
no-hardcoded-fonthard-coded font-family in a component (e.g. 'Inter') instead of var(--font-ui)Warning
radius-from-scaleradius value not in {4,6,8,12,16,20,999}Warning
z-from-scalez-index using an unregistered large numberWarning
weight-from-scalefont-weight not in {400,500}Warning
-

状态矩阵 State matrix

-

每个可交互基元都应在适用处定义以下状态,缺失即按样式规则告警。focus-visible 一律走 --p-focus-ring(只在键盘聚焦时出现,详见 §08),disabled 统一 opacity:.5

+

State matrix

+

Every interactive primitive should define the following states where applicable; missing ones are flagged by the style rules. focus-visible always uses --p-focus-ring (appears only on keyboard focus, see §08); disabled is uniformly opacity:.5.

- + @@ -2100,193 +2110,194 @@ export function auth(token: string) {
状态 StateButtonInputCardMenu itemSwitch
StateButtonInputCardMenu itemSwitch
default
hover
-

月相豁免

+

Moon phase exemption

- 「🌑…🌘」月相 emoji 是 Kimi Web 的品牌特色,仅用于「发出消息后、等待 Agent 首条响应」的聊天态,统一由 MoonSpinner 组件渲染;ActivityNotice 等等待态复用它,不再各自实现月相。 - 它是 no-emoji-icon 规则的唯一例外;其余所有加载态一律用普通 Spinner。 + The "🌑…🌘" moon-phase emoji are a brand signature of Kimi Web, used only in the chat state of "message sent, waiting for the Agent's first response", and are rendered uniformly by the MoonSpinner component; waiting states such as ActivityNotice reuse it rather than implementing their own moon phase. + It is the sole exception to the no-emoji-icon rule; all other loading states use the plain Spinner.
-

毛玻璃豁免

+

Glassmorphism exemption

- backdrop-filter: blur 全站禁用,唯一例外是 TopBar.frost 变体——且仅限「吸顶导航栏」这一处,用于在滚动内容上方保持可读。其余任何组件(卡片、弹窗、Toast、面板)一律不得使用毛玻璃,违者按 no-glassmorphism 告警。 + backdrop-filter: blur is banned site-wide, with the sole exception of the .frost variant of TopBar — 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 no-glassmorphism.
- +
07 -

应用壳与侧栏 App Shell & Sidebar

+

App Shell & Sidebar

- 应用壳(三栏网格 + 右侧预览面板)与左侧会话侧栏的结构规范。这些是与具体业务无关的「骨架」, - 组件、字体、圆角、表面都复用 §02 / §03,但布局与对齐有自己的一套约定。 + The structural spec for the app shell (three-column grid + right preview panel) and the left session sidebar. These are business-agnostic "skeletons" — + components, fonts, radii, and surfaces are reused from §02 / §03, but layout and alignment have their own conventions.

-

布局网格 Layout grid

-

桌面端是一行 5 轨网格,侧栏与右侧面板各占一条永久轨道,中间是会话栏;两条 0 宽轨道给 ResizeHandle 用。

+

Layout grid

+

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.

App.vue · .app
grid-template-columns: var(--side-w) 0 minmax(0, 1fr) 0 auto;
-/*           侧栏 ↑        ↑handle  ↑会话栏        ↑handle ↑右面板(auto) */
+/* sidebar ↑ ↑handle ↑conversation ↑handle ↑right panel (auto) */
- + - - - - + + + +
Token用途
TokenValueUsage
--side-w248px(可调)左侧会话栏宽度,ResizeHandle 拖动改变;应趋近 §02 的 --p-sidebar-w(264px)
--preview-w460px右侧预览面板打开时的宽度
--panel-head-h48px所有右侧面板头 + 会话栏头部统一高度,使 hairline 连成一线
--p-bp-sm640px≤640 切为移动端单列(顶栏 + 会话栏),无侧栏/手柄/右面板
--side-w248px (adjustable)left conversation column width, changed by dragging the ResizeHandle; should approach §02's --p-sidebar-w (264px)
--preview-w460pxwidth of the right preview panel when open
--panel-head-h48pxunified height for all right panel heads + the conversation column head, so the hairline runs as one line
--p-bp-sm640px≤640 switches to a mobile single column (top bar + conversation), no sidebar / handle / right panel
    -
  • 右侧面板轨道永久存在,宽度在 0 ↔ var(--preview-w) 间过渡(打开时挤压会话栏,而非切换模板)。
  • -
  • 侧栏折叠时,轨道 1 变成一条细「rail」,只放一个展开 IconButton,避免压住会话栏头部。
  • -
  • 所有网格子项须 min-height:0; min-width:0,确保只有内部滚动容器滚动,整页不跟着滚。
  • +
  • The right panel track exists permanently, with its width transitioning between 0 ↔ var(--preview-w) (when open it squeezes the conversation column, rather than switching templates).
  • +
  • When the sidebar is collapsed, track 1 becomes a thin "rail" holding only an expand IconButton, avoiding crushing the conversation column head.
  • +
  • All grid children must have min-height:0; min-width:0, so only the inner scroll containers scroll and the page itself does not scroll.
-

侧栏对齐系统 Sidebar alignment(--sb-*

-

侧栏所有行(分组头、会话行、New chat 按钮)共用 3 个自定义属性,让「会话标题」精确对齐到「工作区名称」下方。

+

Sidebar alignment system (--sb-*)

+

All sidebar rows (group head, session row, New chat button) share 3 custom properties, so the "session title" aligns precisely under the "workspace name".

- + - - - + + +
Token用途
TokenValueUsage
--sb-pad-x16px行的水平内边距
--sb-gutter20px行首图标槽宽(14px 图标 + 6px 留白)
--sb-gap6px图标槽与文字之间的 gap
--sb-pad-x16pxrow horizontal padding
--sb-gutter20pxleading icon slot width (14px icon + 6px whitespace)
--sb-gap6pxgap between the icon slot and the text
i
- 会话标题的起始 x = --sb-pad-x + --sb-gutter + --sb-gap。分组头有文件夹图标,会话行有状态槽,二者图标同宽、同位,所以标题天然对齐。 + The session title's starting x = --sb-pad-x + --sb-gutter + --sb-gap. 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.
-

侧栏结构 Sidebar structure

-

侧栏自上而下:品牌头 → 搜索 → New chat → 分组列表(工作区头 + 会话行)。控件尽量复用 §03 基元。

+

Sidebar structure

+

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.

- + - - - - - + + + + +
区块用什么说明
BlockUseNote
品牌头 brand headerlogo + 名称 + IconButton折叠 / 设置用 IconButton sm;logo 带动画(眼睛眨动)
搜索 search裸搜索行(custom)无边框、hover/focus 出 sunken 底;图标 + input + 清除 IconButton。不用 Input(38px 带边框太重)
New chat全宽左对齐按钮(custom)与同列表会话行同节奏(左对齐、hover sunken)。不用 Button(居中,破坏节奏)
分组标题 section label.p-section-label「Workspaces」这类大写 muted 小标题
工作区头 / 会话行见下两节共享 --sb-* 对齐
Brand headerlogo + name + IconButtoncollapse / settings use IconButton sm; the logo is animated (a blinking eye)
Searchbare search row (custom)no border, hover/focus shows a sunken background; icon + input + clear IconButton. Do not use Input (the 38px bordered version is too heavy)
New chatfull-width left-aligned button (custom)same rhythm as the session rows in the list (left-aligned, hover sunken). Do not use Button (centered, breaks the rhythm)
Section label.p-section-labeluppercase muted small titles like "Workspaces"
Workspace head / session rowsee next two sectionsshare --sb-* alignment
!
- 为什么 New chat / 搜索 / 行间改名不用 Button / Input:它们是「列表式」控件(全宽、左对齐、紧凑、无边框),而 Button 居中、Input 是 38px 带边框——强行套用会破坏侧栏的视觉密度与对齐。这是有意保留的定制,不是遗漏。 + Why New chat / search / inline rename don't use Button / Input: 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.
-

会话行 Session row

-

会话行是一个 inset 圆角 pill,结构:状态槽 → 标题 → 时间 → 注意力 Badge → kebab

+

Session row

+

A session row is an inset rounded pill, structured as: status slot → title → time → attention Badge → kebab.

- + - - - - - - - + + + + + + +
部位规则
PartRule
容器margin: 1px 6px; padding: 7px 10px; radius-md;hover = surface-sunken;active = accent-soft + inset 0 0 0 1px accent-bd
状态槽 lead固定 --sb-gutter 宽;运行中 = Spinner sm,否则未读 = 7px accent 圆点
标题 titleflex:1 截断;双击进入行间改名(紧凑 input,不用 Input)
时间 timemono xs、fg-faint;hover 时让位给 kebab
注意力 BadgeBadge sm:info(待回答)/ warning(待审批)/ danger(已中止)
kebabIconButton sm,hover 才显示;下拉用 Menu/MenuItem
归档确认替换标题区,Button sm(danger 确认 / secondary 取消)
Containermargin: 1px 6px; padding: 7px 10px; radius-md; hover = surface-sunken; active = accent-soft + inset 0 0 0 1px accent-bd
Status slot (lead)fixed --sb-gutter width; running = Spinner sm, otherwise unread = 7px accent dot
Titleflex:1 with truncation; double-click enters inline rename (compact input, not Input)
Timemono xs, fg-faint; yields to the kebab on hover
Attention BadgeBadge sm: info (needs answer) / warning (needs approval) / danger (aborted)
kebabIconButton sm, shown on hover; dropdown uses Menu/MenuItem
Archive confirmationreplaces the title area, Button sm (danger confirm / secondary cancel)
-

工作区分组 Workspace group

-

分组头与会话行共用 --sb-*:文件夹图标(开/合)→ 名称 → 路径副标题,hover 露出 kebab 与「+」。

+

Workspace group

+

The group head and session rows share --sb-*: folder icon (open/closed) → name → path subtitle, with the kebab and "+" revealed on hover.

    -
  • 文件夹图标放在 --sb-gutter 槽里,开合态切换图标。
  • -
  • 名称下方一行 fg-muted 的小字路径。
  • -
  • kebab(菜单)与「+」(在该工作区新建)都用 IconButton sm,hover 或键盘聚焦时显示(不 hover 时以 opacity:0 保留在 tab 序里,保持键盘可达)。
  • -
  • 分组可折叠;折叠时隐藏其会话列表。
  • +
  • The folder icon sits in the --sb-gutter slot, switching icons between open and closed states.
  • +
  • A small fg-muted path line sits below the name.
  • +
  • The kebab (menu) and "+" (new chat in this workspace) both use IconButton sm, shown on hover or keyboard focus (when not hovered they stay in the tab order via opacity:0, keeping them keyboard-reachable).
  • +
  • The group is collapsible; when collapsed its session list is hidden.
-

拖拽手柄 ResizeHandle

-

一条 4px 的竖向拖拽条,叠在 1px 列边框上(margin: 0 -2px 让 4px 整条可抓),hover / 拖拽时变 accent。

+

ResizeHandle

+

A 4px vertical drag bar, layered over the 1px column border (margin: 0 -2px makes the whole 4px grabbable), turning accent on hover / drag.

- + - - - - + + + +
规则
RuleValue
宽度 / 光标4px / col-resize
常态 / 激活透明 / accent 填充
层级--z-sticky,盖在列边框上
行为拖拽时面板宽度 1:1 跟随指针(父级关掉过渡避免 lag);松开后持久化到 localStorage
Width / cursor4px / col-resize
Normal / activetransparent / accent fill
Layer--z-sticky, over the column border
Behaviorpanel width follows the pointer 1:1 while dragging (the parent disables transitions to avoid lag); on release it is persisted to localStorage
-

右侧面板 Right panel

-

右侧面板(文件预览 / Diff / 思考 / 子 Agent / 侧聊)共用同一条轨道与同一个头部基元。

+

Right panel

+

The right panels (file preview / Diff / thinking / sub-agent / side chat) share one track and one head primitive.

    -
  • 面板头用 PanelHeader 基元(48px = --panel-head-h),与会话栏头部等高,hairline 连成一线。
  • -
  • 面板头:粗体 mono 标题 + 可选 muted 副标题 + 中间 slot(Badge / 控件 / 路径)+ 右侧关闭 IconButton。
  • -
  • 打开时面板宽度从 0 → var(--preview-w),会话栏被平滑挤压。
  • -
  • ≤640px 时面板变为全屏覆盖(position:fixed; inset:0)。
  • +
  • The panel head uses the PanelHeader primitive (48px = --panel-head-h), the same height as the conversation column head, so the hairline runs as one line.
  • +
  • Panel head: bold mono title + optional muted subtitle + middle slot (Badge / control / path) + close IconButton on the right.
  • +
  • When opened, the panel width goes from 0 → var(--preview-w), smoothly squeezing the conversation column.
  • +
  • At ≤640px the panel becomes a full-screen overlay (position:fixed; inset:0).
i
- 一句话原则:侧栏 / 壳是「列表 + 网格」骨架,复用 §02 token 与 §03 基元(Button / IconButton / Badge / Menu / Spinner / PanelHeader);凡是不 fit 基元的紧凑列表控件(search、New chat、行间改名、show-more)保留定制,并以本节为规范。 + One-sentence principle: 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.
- +
08 -

可访问性 A11y(务实版)

+

Accessibility (pragmatic edition)

- Kimi Web 是本地开发者工具,不以 WCAG 某一 conformance 级别为目标,也不维护完整的读屏 QA 矩阵。 - 本节只收「低成本、不损观感、对键盘重度用户也有直接好处」的规则,作为各基元的底线契约; - 其余昂贵且 ROI 偏低的部分(如对流式输出的实时播报编排)暂不作为强制要求。 + Kimi Web is a local developer tool; it does not target a specific WCAG conformance level, nor maintain a full screen-reader QA matrix. + 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; + the more expensive, lower-ROI parts (such as real-time announcement orchestration for streaming output) are not mandatory for now.

i
- 关于焦点环「丑」:下面要求的焦点可见性一律用 :focus-visible(而非 :focus)。 - 它只在键盘聚焦时出现,鼠标点击不会触发,因此不会污染鼠标驱动的视觉;环的强弱用 --p-focus-ring 统一调,不逐处覆盖。 + On the "ugly" focus ring: the focus visibility required below always uses :focus-visible (not :focus). + It appears only on keyboard focus; mouse clicks don't trigger it, so it doesn't pollute the mouse-driven visual; the ring's strength is tuned uniformly with --p-focus-ring, not overridden per place.
-

1. 对比度与颜色 Contrast & color

+

1. Contrast & color

    -
  • 正文文本与背景对比度 ≥ 4.5:1;控件边框、图标、关键图形 ≥ 3:1。换主题色 / 暗色模式时按 §05 一起核对。
  • -
  • 状态不只靠颜色传达。错误、选中、禁用等状态要同时有文字、图标或形态变化(例如错误态不只红,还带文案或图标)。
  • +
  • Body text vs. background contrast ≥ 4.5:1; control borders, icons, and key graphics ≥ 3:1. When changing theme colors / dark mode, verify against §05 together.
  • +
  • Button text vs. button background, and form controls (input, placeholder, helper / error text) vs. their section background 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.
  • +
  • State is not conveyed by color alone. 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).
-

2. 键盘可操作 Keyboard operable

-

鼠标能完成的操作,键盘必须也能完成;Tab 顺序跟随 DOM,不另造跳序。复合控件按下表定义键盘模型,缺失即视为不完整:

+

2. Keyboard operable

+

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:

- + - - - - + + + +
控件键盘行为
ControlKeyboard behavior
DialogTab 在弹窗内循环(焦点锁);Esc 关闭;关闭后焦点回到触发元素。
Menu / 移动高亮,Enter 选中,Esc 关闭。
Tabs / 切换标签(roving tabindex),只有当前标签在 Tab 序列里。
Switch / Segmented / Space / Enter 切换。
DialogTab cycles within the dialog (focus trap); Esc closes; focus returns to the trigger element after closing.
Menu / move the highlight, Enter selects, Esc closes.
Tabs / switch tabs (roving tabindex); only the current tab is in the Tab sequence.
Switch / Segmented / or Space / Enter to toggle.
-

3. 焦点可见 Focus visibility

+

3. Focus visibility

    -
  • 每个可交互元素在键盘聚焦时必须有可见焦点指示,统一走 :focus-visible + --p-focus-ring(主操作可用 --p-focus-ring-strong)。
  • -
  • 禁止裸 outline: none。要去掉默认轮廓,必须同时给出等价的替代样式。
  • +
  • Every interactive element must have a visible focus indicator on keyboard focus, uniformly via :focus-visible + --p-focus-ring (primary actions may use --p-focus-ring-strong).
  • +
  • Bare outline: none is forbidden. To remove the default outline, you must provide an equivalent replacement style.
-

4. 命名与语义 Labels & semantics

+

4. Labels & semantics

    -
  • 语义 HTML 优先(button / a / input / dialog…),ARIA 只在原生语义不够时补。
  • -
  • 只有图标的按钮必须有 aria-label——IconButton 已用必填的 label prop 强制。
  • -
  • 弹窗:role="dialog" + aria-modal="true",标题作为对话框的可访问名称。
  • -
  • 纯装饰性 SVG / 图标加 aria-hidden="true",避免被读屏念出。
  • +
  • Semantic HTML first (button / a / input / dialog…); ARIA is added only when native semantics fall short.
  • +
  • Icon-only buttons must have an aria-labelIconButton already enforces this with a required label prop.
  • +
  • Dialog: role="dialog" + aria-modal="true", with the title as the dialog's accessible name.
  • +
  • Purely decorative SVG / icons get aria-hidden="true" to avoid being read out by screen readers.
-

5. 目标尺寸 Target size

-

桌面可点击目标 ≥ 32px;触摸设备 ≥ 44px(与 §01 原则、IconButton 的 lg 档一致)。

+

5. Target size

+

Desktop click targets ≥ 32px; touch devices ≥ 44px (consistent with the §01 principle and the IconButton lg tier).

-

6. 减少动态效果 Reduced motion

-

统一在全局样式按 §02 的 @media (prefers-reduced-motion: reduce) 处理,组件不各自判断;MoonSpinner 月相在当前帧暂停。

+

6. Reduced motion

+

Handled uniformly in the global styles per §02's @media (prefers-reduced-motion: reduce); components do not check this individually. The MoonSpinner moon phase pauses on the current frame.

-

7. 动态内容播报 Live announcements(非强制)

-

读屏播报在本产品里不做强制契约。Toast 这类短提示用 role="status" / aria-live 即可;聊天流式输出当前不做逐字播报,属可接受取舍,后续如有真实需求再补。

+

7. Live announcements (non-mandatory)

+

Screen-reader announcements are not a mandatory contract in this product. Short hints like Toast can use role="status" / aria-live; 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.

- 明确暂不强制:WCAG conformance 级别声明、完整 ARIA 模式表、逐款读屏软件的 QA 矩阵、以及对流式输出的实时播报编排——这些不写入基元契约,避免成为无人维护的口号。 + Explicitly not mandatory for now: 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.
@@ -2295,7 +2306,7 @@ export function auth(token: string) {