cc-haha/desktop/docs/redesign-paper-ink-seal.md
程序员阿江(Relakkes) c712f52858 feat(desktop): 「纸·墨·印」全量 UI 重设计
按设计交付稿重构桌面端整体视觉,只换表现层,功能、数据契约与
交互逻辑零改动。

主题与地基:
- 6 套主题(纯白/纸墨/经典暖色/青瓷/墨夜/墨夜蓝),源色块 + 单一
  语义映射层两层结构;老设置 light→warm-classic 自动迁移
- 状态色全部成对并过 AA;新增 --color-on-brand-soft、
  --color-search-highlight 对、--color-border-strong(1.4.11 控件边界)
- 衬线标题自托管 Noto Serif SC 拉丁分片,中文回退系统衬线
- 圆角/阴影/动效阶梯按稿定稿;新组件 BrandSeal 印章

屏幕:外壳(52px 标签条陶土下划线、印章侧栏、选中会话浮起卡)、
零态、活跃会话、composer 全部弹层、技能市场、定时任务、设置全
分区、Trace、终端、⌘K,及设计稿未覆盖界面的统一收敛。

Review 修复(两轮 6 主题全量走查 + 盲区补扫挖出):
- 未分层 CSS 压死 utilities 两处(图标 24px、focus ring 被吃)
- font-[var(--font-mono)] 无效写法 35 处(mono 从未生效)
- tertiary 文字与控件边框对比度全线达标化,contrast 守门扩容
- /N alpha 修饰符清零(Safari 15 WebView 整条丢弃)
- 触屏 44px 主目标口径统一;hover 门控控件 H5 常显
- 错误态修复:定时任务静默失败、Trace/会话列表错误呈现
- 宠物窗口 ink-blue 暗色覆盖补齐

测试:264 文件 / 3162 用例全绿(新增六主题对比度、跨文件弹层
一致性、触摸目标、错误态等守门);tsc 零报错;构建通过。
2026-07-26 22:54:45 +08:00

6.5 KiB
Raw Blame History

「纸 · 墨 · 印」重设计规范

本文是桌面端整体视觉重构的执行标准。配套阅读 desktop/src/components/AGENTS.md(组件与 token 硬约束,冲突时以那份为准)。

唯一边界:只换皮,不动功能

  • 允许改:className、内联展示样式、纯展示用的 DOM 结构、i18n 文案里的视觉措辞。
  • 不允许改stores/api/hooks/ 里的任何逻辑,事件处理、状态流转、数据契约、组件 props 语义。
  • 设计稿里有、原项目没有的功能(例如零态的三个建议胶囊),不新增
  • 原项目有、设计稿没画的界面,不删,按同一套规则收敛。

判断口径:如果一处改动会让某个 .test.tsx 里的行为断言(点击、请求、状态)失败,那它就越界了;只有快照式的样式断言才应该跟着改。

设计主张

纸感暖底分层 + 墨色主按钮 + 衬线标题 + 陶土印章。层次靠底色分层与 1px 细边框建立,不靠重阴影。

Token已定稿不要改 theme/globals.css

六套主题(white 纯白 / paper 纸墨 / warm-classic 经典暖色 / celadon 青瓷 / dark 墨夜 / ink-blue 墨夜蓝)只换一组 --cc-* 源变量,:root 语义层把它们映射成 --color-*组件一律只用 --color-* / --radius-* / --shadow-* / --z-*,永远不要直接用 --cc-*

角色 token
页面底 --color-surface / --color-background
侧栏与次级面板底 --color-surface-container-low
悬停 / 选中 --color-surface-hover / --color-surface-selected
卡片内衬 --color-surface-container
常规边框 / 强边框 --color-border / --color-outline
主 / 次 / 弱文字 --color-text-primary / --color-text-secondary / --color-text-tertiary
陶土主色 / 深 / 浅底 / 描边 --color-brand / --color-brand-hover / --color-brand-soft / --color-primary-fixed-dim
陶土浅底上的文字 --color-on-brand-soft不是 --color-brand,见下)
状态色 --color-{success,warning,error,info} + -container + --color-on-*-container
主按钮墨色 --color-btn-primary-bg / --color-btn-primary-fg

状态色成对使用。 --color-<tone> 是标识色(描边、图标、下划线);--color-on-<tone>-container 才是 -container 底上的文字色。直接把 --color-brand--color-brand-soft 上的文字,在两套墨色主题下只有 4.3:1低于 AA。contrast.test.ts 会红。

圆角阶梯

--radius-sm 6小徽章/ --radius-md 10按钮、输入/ --radius-lg 13卡片内件/ --radius-xl 17卡片/ --radius-2xl 20composer/ --radius-3xl 24模态/ --radius-full 胶囊。

rounded-[var(--radius-md)]不要rounded-mdTailwind 的 rounded-lg 是 8px--radius-lg 是 13px同名不同值

阴影三级

--shadow-card(卡片静止)/ --shadow-composercomposer、卡片 hover 抬起)/ --shadow-overlay(浮层、下拉、模态)。

字体

  • 标题走 style={{ fontFamily: 'var(--font-headline)' }}:所有 h1/h2/h3、页面大标题、统计大数字、弹层里的大号数值上下文百分比、推理档位名。中文会落到系统衬线这是预期。
  • 正文默认 --font-body14px / 1.5。
  • 代码、路径、快捷键、ID、耗时、token 数走 --font-monoTailwind font-mono)。
  • 字号阶梯11 / 12 / 12.5 / 13 / 13.5 / 14 / 14.5 / 15 / 16.5 / 21 / 2428衬线页标题/ 32详情页标题

组件规则

优先用 components/ui/ 里的原语,别手写 <button>。表在 components/AGENTS.md 第一节。

已按设计稿改好、直接复用的:

  • Buttonprimary 已是墨色实心 + hover 转陶土 + 上浮 1px + active:scale(.97);禁用态是不透明的 --s1/--t3
  • Card — 新增 shadownone/card/composer)与 lifthover 抬起 2px两个 prop以及 radius="2xl"liftshadow 不要同时传,两个 shadow-[…] 不会叠加。
  • IconButton / Badge / Modal(圆角已是 24/ SegmentedControl / Switch / Progress — 都已走 token跟随主题。
  • composite/BrandSeal — 印章「哈」,sm24 / md32 / lg38 / xl80。

焦点态统一:focus-visible:ring-2 focus-visible:ring-[var(--color-border-focus)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-surface)]

动效

  • 按钮 transition-[background-color,color,border-color,box-shadow,transform] duration-150 ease-out
  • 卡片 hover 抬起用 Cardlift
  • 屏幕入场用 .animate-screen-pop
  • 已有 .animate-spin.9s)、.animate-pulse-dot1.6s)、.animate-overlay-in*
  • 任何位移动效都要配 motion-reduce: 兜底。

常见形态

  • 页头:衬线 2428px 标题 + 次级说明行 + 右侧墨色主按钮。
  • 统计卡Card + 衬线大数字2126px+ 12px --color-text-tertiary 标签。
  • 列表行:状态点 + 主标题 + 12.5px 次级信息 + 右侧 mono 指标hover 出 --color-surface-hover
  • chip / 胶囊rounded-full1px --color-borderhover 转 --color-outline;激活态 --color-brand-soft 底 + --color-on-brand-soft 字 + --color-primary-fixed-dim 描边。
  • 警示条--color-{warning,error}-container 底 + --color-on-*-container 字 + 同色描边。
  • 磨砂浮层glass-panel 类(已含 blur 18px + --shadow-overlay)。
  • 代码块--color-code-bg 底 + font-mono 13px/1.7 + 头部带 Copy。

硬约束(会让 CI 红)

  • 不用 Tailwind 原色(bg-amber-50text-red-400…)—— 它们不跟随 data-themepaletteEscapes.test.ts 拦截。
  • 不用 /N alpha 修饰符(bg-[var(--x)]/10)—— Safari 15 WebView 解析不了。需要浅底就用现成的 -soft / -container token。
  • 不写裸 zIndex: 9999z-[10000],层级只能来自 --z-*
  • 不写硬编码 hex。
  • 所有用户可见文案(含 aria-labeltitle)走 useTranslation(),五种语言(zh / zh-TW / en / jp / kr)都要加。
  • 图标按钮必须有名字(用 IconButtonlabel 必填)。
  • 会被浮层锚定的组件必须 forwardRef

参考原型

/Users/nanmi/Downloads/design_handoff_cc_haha_redesign/ 下的 CC Haha.dc.html 是高保真交互原型README.md 是像素级规格。原型用浏览器直接打开可交互。