Files
tty7/docs/design-system.md
T
l0ng-ai c103a57c01 feat(settings): every pick-one setting is a dropdown (#979)
Single choices were drawn two ways — segmented buttons for most, a
dropdown for a few — and the segmented rows ran to their labels' width,
so the right-hand column never lined up. settings_choice now renders a
dropdown; an off-preset value shows as a checked "Custom (N)" row.
The SSH strip's forward form keeps the segmented control: it lives
outside the settings window and has no popover state to use.
2026-09-27 17:12:03 +08:00

15 KiB
Raw Blame History

tty7 界面设计规范

本规范约束应用界面,不重写 shell、TUI、代码语法的颜色。实现入口是 src/ui/presets.rs 的 Neutrals、Interactions、Semantics,以及 src/ui/theme.rs 的组件映射。组件应引用这些角色,不在页面里另配颜色。

信息优先级

  1. 工作内容:终端、正在编辑的文档、正在查看的 diff。主区域最大,正文对比度最高。
  2. 当前位置与下一步:当前工作区/标签页、键盘当前选项、可执行的主操作。
  3. 辅助导航:右侧信息/Git/文件页签、展开收起、新建、更多。中性图标,始终可见。
  4. 说明与元数据:路径、分支、数量、快捷键、设置描述。次级文字,不用饱和色抢正文。
  5. 异常:失败、冲突、需要处理的警告。局部状态色,加文字或形状,不单靠颜色。

同屏不能把所有选中项都画成主按钮。当前标签页用中性灰底 + medium;右侧面板当前页签用 正文色文字 + medium 字重;真正可执行的主按钮才使用实色强调色。每个任务区只突出一个主操作。

颜色角色

角色 使用位置 规则
Neutrals.background 工作内容、设置内容、输入框 安静的基础表面。输入框未聚焦时不能像已选中列表行
Neutrals.rail 左侧标签栏 内容底向正文色偏 3%(默认 #F5F5F3 / #1E1E20),细分隔线划界
Neutrals.sidebar 右侧面板 与内容同色;只用细分隔线划界
Neutrals.popover 菜单、随处搜索、对话框 浅色下保持明亮,深色下抬高亮度;只给浮层阴影
foreground 正文、标题、当前项 正常文字至少 4.5:1;不把普通正文全部加粗
muted_foreground 描述、路径、快捷键 与主文字明确区分,但仍保持可读性
border / divider 控件边界 / 区域分隔 控件边界较强,区域分隔较弱;不能把页面画成表格线框
Interactions.input_border 输入框与普通按钮轮廓 对应组件库的 input 边框角色,不能误用内容背景色导致边界消失
Interactions.primary 保存、连接等主操作 强调色实底,成对配置前景色;hover/pressed 保持标签对比度。Git 提交按钮例外:可提交时用反色中性(正文色底),见 Git 面板
Surfaces.rail.selected 当前标签页 中性 selected 阶 + medium;不用强调色,蓝色留给可按的东西
Interactions.choice 菜单的键盘当前行 强调色浅底,区别于鼠标经过的中性 hover。随处搜索例外:与工作区切换器同用中性 selected 阶
中性 secondary 面板页签、分段选项、普通按钮 次级导航不能与主要操作争夺注意力
Semantics.danger 失败、Git 冲突、破坏性动作 红;必须同时有文字/图标/确认语义
Semantics.warning 需要留意的状态 琥珀;Git 普通修改只用于尾部标记,不能染黄整个文件树
Semantics.success 成功、Git 新增标记 绿;不用于装饰性按钮
Semantics.info/link 信息、可点击链接 使用当前主题的强调色,与焦点指示同族

默认浅色以暖白 #FCFCFB 为底,正文 #1C1C1E,蓝色 #1F6BF0 为强调色(光标同强调色)。 默认深色以 #18181A 为内容底,#ECECED 为正文,#78A8F5 为强调色。 Git 的新增/修改标记种子为绿 #2F8A52 / #4CC27A、琥珀 #B7791F / #E0A345(浅/深),再按对比度下限校正。 其他主题保留自己的背景与强调色,但红/绿/琥珀的状态含义不随 ANSI 槽位变化。 所有文字、状态色和主按钮前景色须在实际背景上验证对比度。

状态不能混用

  • Rest:中性、稳定。工具按钮不因鼠标移出而消失。
  • Hover:轻微中性填充,只用于可交互目标。设置说明行不整体发亮。
  • Selected:表达持久的当前位置。侧栏当前行用中性底 + medium,右侧页签用正文色 + medium 字重,不画横条也不画底。
  • Keyboard focus:清晰的强调色焦点环/当前行,不能仅靠 hover 表达。
  • Pressed:同一色系的短暂加深,不能跳到另一个主题色。
  • Disabled:保留边界与标签;降低对比,不能像可执行的主按钮。
  • Error:状态色、说明和恢复入口一起出现。普通 Git 修改不升级为错误/警报。

标签页关闭按钮、渐变遮挡等局部覆盖层必须使用所在行的实际背景,不能复用过期色值。

图标、文字与间距

  • 界面 SVG 使用 24×24 坐标系、1.8 线宽、圆端点;工具栏按 16px 显示,命中区 32px。
  • 行内辅助按钮至少保留现有 24px 命中区域;增大图标不能挤掉文本预算。
  • 工具图标使用中性文字色。品牌用小图形识别,饱和色留给状态点。
  • 字号跟随界面缩放;正文 14/16rem,说明 12/16rem,章节标题 16/16rem。
  • 左侧栏分组标题为 11.5/16rem、medium、辅助色;右侧紧凑分组标题为 12/16rem、semibold;设置页只有页标题为 16/16rem semibold,页内分组标题与信息页同为 11.5/16rem medium 辅助色。Session 字段名和值同为正文尺寸,以颜色区分层级。
  • 辅助文字必须在实际的内容、侧栏、浮层背景上均达到 4.5:1;普通路径、数量和说明不再叠加透明度。静态 PID 使用中性文字。
  • 放大界面字号时,Git 行高与设置导航宽度同步调整;窄侧栏优先保留分支名,长文件名须明确省略并可查看完整路径。
  • 侧栏当前标签页标题用 medium(测宽与渲染同一字重),分组标题用 medium;正文和辅助说明保持 regular。
  • 右侧面板和侧栏的紧凑标题不再大写,靠字重与颜色区分层级。
  • 以 4px 为间距基础:紧密内容 4–8,行内 8–12,区块 24–32。列表外边距与文字预算同步。
  • 形状:侧栏标签页行 ROW_RADIUS(7px),侧栏搜索框与工作区切换 7px,侧栏顶部图标按钮 26px / 6px 圆角, 图标按钮圆角方形(rounded_lg / 小号 4px);右侧面板文字页签没有 hover 底,只变文字色。浮层 POPOVER_RADIUS 10px。
  • 标题栏高 48px(左栏、终端、右侧面板一致);终端上方居中显示当前标签页标题,12px 辅助色。
  • 侧栏单行标签页行高 30px,带分支行 42px,行间距 1px,组间距 16px;头像 16px 圆形品牌底;分支行 11.5px 辅助色、从开头省略;运行中的 agent 在行尾显示 5px 状态点(工作中闪烁,等待时空心,未读时显示数字)。搜索框与工作区切换同为 28px,位于 48px 顶栏之下(上 4 / 下 16 / 左右 12,间距 10)。

各界面约束

  • 侧栏:名称优先于分支和 diff 数量;当前项清晰,品牌头像不形成彩色墙。分组标题用辅助色 medium(22px 行),右侧 分支 · +增 −删 为等宽数字的辅助色;展开的分组不画 chevron,折叠后才显示。
  • 侧栏顶部:导航与内容用留白衔接,不加贯穿的 header 底部分隔线;左栏是唯一带底色的侧面,右侧面板与内容同色。
  • 右侧面板页签:文字页签(信息 / 更改 / 文件),12.5/16rem,首个页签距左缘 22px、 页签间距 18px;当前页签正文色 + medium,其余辅助色,hover 只把文字提到正文色。页签栏 下方不画横条、不画分隔线。「更改」后附改动数(辅助色、regular)。尾部是面板开关与「更多」。
  • 信息页:Session / Processes / Ports 三节,节间 16px、不画分隔线;节标题 28px 高、 11.5/16rem medium 辅助色。Session 为两列(标签列至少 76px,行高 28px),值用正文色; cwd 的父路径弱化、末级正文色,从头部省略。进程行 26px,子进程以 └ 缩进,PID 辅助色 mono。Ports 标题尾部带「+」转发按钮,空状态一行辅助色说明。
  • 右侧文字层级:文件树名称使用侧栏标题色,不能整体降为辅助灰;当前项使用 selected 文字色与 medium 字重,根目录以字重区分。Git 普通文件名使用 resting 文字色与界面字体,路径、数量与说明保持次级;信息页的路径前缀弱化,末级名称突出。
  • 文件树:顶部是 28px 的浅底搜索框(圆角 7)。行高 26px、圆角 6;目录前有展开 chevron, 文件留空同宽;文件名中性;A/M/? 等尾部字符承载 Git 状态;目录用 5px 小点表示子项变化; 忽略项文字辅助色、图标半透明,不用斜体;冲突才整行提升。
  • Git 面板:改动列表是主体。顶部固定块(分支行 28px / 提交信息框 / 提交行)上 8、块间 10、下 14。 分支名 medium,末尾同步按钮 26px。提交信息框静止 56px、淡底、ROW_RADIUS。 提交按钮是分体控件(26px、圆角 6、0.5px 内嵌分隔):可提交时整体反色中性(正文色底 + 表面色字), 这是面板里唯一的实心形状;不可提交时回到信息框同款淡底,不宣传不能执行的动作。 分组之间空 16px,组标题 22px、11.5/16rem medium 辅助色、句首大写(不再全大写),数量右对齐。 文件行 26px、圆角 6:状态字母等宽 semibold 按状态着色,文件名正文色优先占宽(下限 40px), 目录右对齐、从开头省略。History 区以细线分隔,标题 32px;提交行 26px,1px 连线 + 7px 节点, HEAD 实心、其余空心环;整页只有一条 lane 时连线与节点改用中性色;时间列固定宽度右对齐, HEAD 引用用淡底胶囊。
  • 设置:页标题 > 分组标题 > 标签 > 描述。左侧导航用 Neutrals.rail 底与其 surface 阶,右缘细分隔线; 搜索框 28px 浅底(圆角 7);导航行 28px、圆角 7、左右内边距 8,当前项为 selected 阶 + medium,不用强调色。 页标题立在 48px 标题栏带内;分组标题 28px、11.5/16rem medium 辅助色;分组之间是 0.5px 分隔线,上下各 16px。 设置行:标签正文色 regular,描述 12/16rem 辅助色,行最低 28px、内边距 8(hover/搜索命中的底色外扩 8px); 搜索命中行用浅中性底,不用强调色。输入框与下拉框 28px,按钮、步进器 26px(圆角 6); 输入框/下拉框/次要按钮都用同一浅底(surface 半阶)且无描边。控件一义一种:开关管开/关,下拉管单选 (不再用分段控件),滑块管连续值,步进器管整数微调。 每个视图唯一的主操作(保存主题草稿、连接、安装更新)用反色中性,同 Git 提交按钮;不可执行时回到浅底。 开关与滑块仍用强调色。SSH 主机列表:标题行带 26px 图标按钮,28px 浅底搜索,分组标题 22px, 主机行 42px 两行(标题正文、地址 11.5/16rem 辅助色);主机表单字段名为辅助色右对齐标签列。 主题卡片为浅底无描边,展开时为 selected 阶;主题面板与内容同色、左缘细分隔线,标题立在标题栏带内。 快捷键键帽为浅底无描边,行间 0.5px 分隔线。
  • 菜单与随处搜索:亮度抬升、有限阴影;当前键盘行清楚,普通项不着色;小窗口内可滚动。
  • 工作区切换器:760px 浮层,距顶 112px,圆角 12px;搜索行 48px(右侧 esc 键帽), 主体 420px 分两栏、只用细线分隔,页脚 40px(左「新建工作区」幽灵按钮,右键帽提示 ↑↓ 导航 / ↵ 打开 / ⌘↵ 新窗口)。左栏 340px 工作区行 52px:26px 首字母圆 + 8px 连接 状态点(在线绿、离线淡、连接中琥珀、失败红,外圈为行底色),名称 medium,下行 「机器 · 路径 · 时间」次级文字,右侧标签数 + 状态词。右栏为预览:28px 标题行, 44px 标签页行(18px 品牌头像、分支与增删数全部次级、「当前」字样、工作中 5px 绿点 与侧栏同步闪烁)。当前行只用中性 selected 阶,不用强调色。
  • 随处搜索:切换器的同胞浮层——同样的 12px 圆角、浮层阴影、距顶 112px(矮窗口按比例上移), 最宽 600px;搜索行由组件库列表自带(45px,空时右侧 esc 键帽),页脚 40px 细线分隔、右侧键帽提示 ↑↓ 导航 / ↵ 打开。命令行 32px、圆角 8、列表四周 8px、行内 10px;当前行为中性 selected 阶 + 标题 medium,不用强调色。分组标题 28px、11.5/16rem medium 辅助色、与行文字同列。快捷键逐键 18px 淡底键帽。
  • 分屏与文档栏:分屏分隔线静止时为一个设备像素的 divider 色细线,hover/拖动时变 1px 强调色, 与侧栏、右侧面板的拖拽边一致。文件查看器标题栏 48px:文件名正文字号 medium,未保存 5px 琥珀点, 关闭为 26px / 6px 圆角图标块,下接 divider 细线;底部状态栏 26px、12/16rem 辅助色、行列号等宽数字。
  • SFTP 浏览器:行与本地文件树一致(26px、圆角 6、16px 图标辅助色、文件名侧栏标题色、大小等宽数字); 编辑框为无边框淡底井(圆角 7);传输进度为正文色细条压在淡底轨道上,失败才转红。
  • 面板里的主按钮(SFTP 确认、添加转发、SSH 断线条的重连):反色中性,同对话框主按钮。
  • 对话框(SSH 认证/主机密钥、新建 worktree):ui::dialog 统一外壳,同切换器的 12px 圆角、 浮层阴影与遮罩、距顶 112px;标题行 48px(正文字号 medium,右侧 esc 键帽,下接细线), 内容区左右 18px、字段间距 14px;字段名 11.5/16rem medium 辅助色,输入框为无边框 28px 淡底井(muted、圆角 7)。页脚 40px 细线分隔,按钮 28px / 圆角 6、右对齐、主操作在最右: 主按钮为反色中性(同提交按钮),次按钮透明、hover 取所在表面的 hover 阶;不可用时实心按钮 退回淡底 + 辅助色且不响应点击。主机名与指纹放在淡底信息井里用等宽字。唯一的红色按钮是 「主机密钥已变更」的 Override,该卡片也是唯一带红色描边的对话框。
  • 浮动提示条:边缘保持中性细线,严重程度只由行首 6px 状态点表达(警告琥珀、断开红)。
  • 首页:快捷操作列表 340px 宽,行高 28px、圆角 7,静止无底、hover 取窗口 hover 阶; 快捷键用 18px 淡底键帽。
  • 终端:ANSI 是用户内容,不拿来充当 UI 错误/成功配色;应用设计调整不得反转状态含义。

验证要求

cargo test -p tty7 --bin tty7-app --locked ui:: 覆盖内置主题的文字、语义色、 交互状态对比度及已有 UI 行为。另需在真实窗口检查浅色/深色、宽/窄窗口、侧栏、文件、 Git、设置、菜单与随处搜索。测试通过不能替代视觉层级检查。