本文档阐述熵减的 UI/UX 系统规格——组件、交互、布局、动效的参数与细则。
理念基线 :theme.md (色彩与风格理念,本文档管「How」,theme.md 管「Why」)。
三段核心机制:相变资产 (§二)· 思维显形 (§三)· 语义排印 (§四)——即 theme.md 三条「超越 Apple」思考的系统级实现。
状态:活跃(2026-08-24 建立)
间距网格 :8px 基准(4px 半档仅用于图标内边距与微间距)
桌面三栏结构 :导航栏 240px(可折叠至 56px)· 列表栏 320–400px(可隐藏)· 主内容栏(限宽 720–900px 居中)
窗口 :最小 960×640;主窗口圆角由系统/外壳负责(Tauri 配置),应用内不模拟窗口装饰
滚动 :内容区滚动,侧栏/导航不随动;滚动条细样式(6px、悬停扩展)
┌──────────┬──────────────┬────────────────────────────┐
│ 导航 240 │ 列表 320–400 │ 主内容 720–900(居中) │
│ (可折叠) │ (可隐藏) │ │
└──────────┴──────────────┴────────────────────────────┘
物态
对应实体
特征
液态
视频/音频流、原始采集
模糊、流动、不可把握;圆角最大、无边框、低不透明度
半凝固
会话产物、提取中/沉淀中
影调渐显、边缘未定;中间态参数
固体
笔记(落库后)
纸面、硬边、可批注;标准卡片参数
晶体
闪卡、组(结算后)
同构网格、锐利、可组合;圆角最小、边框最强、阴影最淡
参数
液态
半凝固
固体
晶体
圆角
20px
16px
12px
8px
背景
主题色 6% 透明
bg-sunken
bg-surface
bg-surface + 微渐变
边框
无
1px 虚线 --ed-border
1px 实线 --ed-border
1px 实线 --ed-primary 12%
内容影调
80% 透明
--ed-text-tertiary
--ed-text-secondary
--ed-text-primary
阴影
无
无
标准双层
标准双层(更淡)
出现动效
溶解
淡入 + 微位移 4px
标准入位
记忆浮现 (仅晶体,见 §七)
会话里的一段转写 :识别中=半凝固;会话结束落库=固体(可编辑)
笔记转闪卡 :草稿卡=固体;被首轮复习调度=晶体(进入组网格视图)
feed 碎片 :导入时=半凝固;归组=固体;组结算后=晶体
空状态/删除 :反向相变(固体→半凝固→消失),与「不追债」哲学一致——删除体面,无确认弹窗惊扰
相变是静默底层规则 :用户感知「内容成型了」,但不感知「有渐变动效」
相变不得用于装饰性组件(导航、按钮不入相变体系)
四态参数只允许取表内值,禁止自定义中间态(防漂移)
3.1 处理态规范(替代所有 spinner/进度条)
处理
过程可视化
参数
ASR 流式转写
音频波形上,字词逐词点亮 (随识别结果点亮,非弹字符)
点亮 150ms 淡入;已点亮的词保持 text-primary,未识别段 text-tertiary
OCR 检测
检测框逐个落定 在画面(框线细 1px,落定后内容淡入)
框落定 200ms;全部落定后框线褪去 400ms
结构判定(四维解耦)
内容右上角微标注:结构 · 高 / 形态 · 教程(11px 标签,静默出现)
常驻但弱化;悬停显示判据原因
复习调度
卡片上的「下次复习」不是数字,而是24h 弧线刻度 (刻度即时间点)
弧线 1.5px,当前时刻 = 刻度亮点(琥珀);悬停显示具体时间
AI 精修/知识补充
正文旁出现「增补」记号(琥珀下坠角标),正文以影调从浅入深完成
完成后角标保留 24h 后转为静默回链
每个处理态自带内容 :进度信息即内容本身,无空白等待页
prefers-reduced-motion:逐词点亮→整段淡入;框落定→一次淡入;弧线刻度不变(静态图形)
禁用菊花转(spinner)于任何处理场景;长任务(>2s)允许「探针」式折线扫描(1.5px 线沿内容路径行进)
语义
排印处理
示例
术语/关键概念
词重 500 + 0.05em 字距
生成效应
数值/时间戳
等宽 + tabular-nums
14:32:07 · 3,842 字
低置信内容
影调淡出(tertiary 或 opacity 70%)
转写错词、低置信 OCR 行
高置信结论
--ed-text-primary + 词重 500
提取出的结论块
来源回链(视频/画面)
脚注式:小一号 12px 下沉 + 琥珀「⨳ 回链」
⨳ 04:32 · F·0071
代码/公式
等宽 + bg-sunken 内嵌块
FSRS::next
待办/行动
左缘 2px 靛蓝竖线 + 正文
动手闭环任务
同一条内容只允许命中最多两个 语义(防花屏);冲突时优先级:置信度 > 来源 > 术语 > 数值
转写流默认「无修饰」(正文同款),语义排印在会话终止/笔记落库时 一次性应用——排印是「理解完成的标志」,不是实时装饰
笔记页布局:主文 15/22 + 回链脚注下沉 + 术语上浮一档,形成「证据集」感
组件
尺寸
圆角
状态要求
主按钮
高 36px(P)· 40px(L);内边距 16/20
8px
default=靛蓝实底白字;hover=靛蓝 90%;active=scale 0.98;disabled=40% 透明;加载=左侧 16px 微型弧线
次级按钮
高 36px
8px
透明底 + --ed-border 1px;hover=accent 8% 底色
文本输入
高 36px
8px
常态=凹陷底无边框;focus=1px 靛蓝内框 + 焦点环;disabled=60%
卡片
内容自适应
12px(相变态按 §2.2)
常态带标准阴影;hover=阴影加深一档(不位移)
侧栏/浮窗
240px / 560px max
16px
backdrop-blur 20px;浅 92% / 深 85% 透明
状态标签
高 22px
999px
文本 11px/500;底=accent 10% · 字=accent 深一档
列表行
高 44px
8px
hover=bg-sunken;selected=靛蓝 8% 底 + 左缘 2px 靛蓝
空状态
图标 48px + 标题 17 + 说明 13 + 行动按钮
—
几何插画(靛蓝→琥珀柔渐变 60% 透明);文案=邀请行动
骨架屏
与内容同位
8px
bg-sunken 微光扫过 1.2s/次;reduced-motion 静态
视图
结构
规格
每日视图
任务队列(今日复习/待处理会话)+ 采集入口
标准密度;无叙事元素;办完即走;最大信息 1 屏
周报/月报
时间轴叙事:琥珀节点(进展)+ 靛蓝曲线(能力测量)
大留白;标题 28/34;无网格线;面积渐变 12%
事件视图
全屏 accent 柔光渐晕(8–12%)+ 单卡片 + 记忆浮现
只在事件时现身;平时不可见;一次性出现 6s 后卡片保留、渐晕退去
数据可视化风格 :线 2px、无网格线、坐标轴 tertiary;平台期=虚线(停滞语义);突破=实线上折(靛蓝);记忆/证据点=琥珀实点。
场景
时长
曲线
备注
hover/激活
120ms
ease-out
仅底色/阴影变化
卡片/面板进出
200–250ms
cubic-bezier(0.2,0,0,1)
位移 ≤8px
记忆浮现(签名)
400–600ms
同上 + blur(8px→0)
仅四场景:复习揭晓/结算报告/显影报告/回归之门
骨架/探针
—
循环
reduced-motion 静态
页面切换
150ms 交叉淡入
ease-out
不滑动(桌面工具定位,避免 iOS 化)
禁止 :3D 翻转、弹性回弹(>1 次)、粒子、对用户输入的夸张响应。
线性 1.5–1.75px stroke、24px 网格、对齐整数坐标(视觉重量一致)
语义图标(产品专有):提取(漏斗→卡片)· 显影(渐显矩形)· 复习(弧线+刻度)· 组(网格聚合)· 回溯(小回链箭头)
状态图标:仅 16px(行内);颜色随语义(靛蓝/琥珀)
对比度:正文 ≥ 4.5:1;大字/图标 ≥ 3:1(色板已校验;--ed-memory 琥珀在深色主题用亮化变体 #E8A04C 保证对比)
prefers-reduced-motion:按 §3.2 / §七 降级矩阵执行
焦点:2px --ed-primary + 2px offset;列表行、卡片可独立聚焦
颜色非唯一通道:影调+图标+文本三通道;低置信内容保证文本通道完整可读
剪报底纹(--ed-mark-clip)上的文字只用 ink-3 及更深(--ed-ink-3 / --ed-ink-2 / --ed-ink-1);--ed-ink-4 禁止用于剪报底纹 —— --ed-ink-4 的 3:1 过渡态例外只在阅读面上成立,换到剪报底上亮档实测 2.8489 、暗档 3.0480 ,连该例外都不满足
文本缩放:rem 单位;200% 不破版(组件按内容自适应高度)
--ed-due 亮档第二次对比度修正(批 0-D,2026-09-11) :#A05F10 → #9F5E10 。触发底是剪报底纹 这第三种底 —— --ed-due 要承载「记忆语义」文字(如「3 天后」),而旧值在剪报底上仅 4.4950:1 ,低于正文线。实测:剪报底 4.5571 / 纸 4.9309 / 面 5.1436(暗档 #E0A44B 不动,剪报底 7.4863 本就达标)。求解规则与余量要求见 ADR-033
: root , [data-theme = "light" ] {
/* 语义双色 */
--ed-primary : # 3B5BDB ; /* 熵减靛蓝:行动/聚焦 */
--ed-memory : # C77B2E ; /* 琥珀记忆:复习/沉淀/证据 */
--ed-success : # 2F9E44 ;
--ed-danger : # E03131 ;
/* 中性灰阶(浅色·纸面) */
--ed-bg-canvas : # F7F7F5 ;
--ed-bg-surface : # FFFFFF ;
--ed-bg-sunken : # EFEFED ;
--ed-text-primary : # 1A1A1A ;
--ed-text-secondary : # 5C5C5A ;
--ed-text-tertiary : # 949490 ;
--ed-border : # E3E3E1 ;
/* 形状/材质 */
--ed-radius-control : 8px ;
--ed-radius-card : 12px ;
--ed-radius-panel : 16px ;
/* --ed-shadow-card 已被 --ed-shadow-1 取代(批 0-D Task 1 · 2026-09-11 用户裁决「纸感双层暖墨」):
低层(菜单/浮层/小卡)= --ed-shadow-1;高层(Modal/浮窗)= --ed-shadow-2。旧值不再使用。 */
--ed-shadow-1 : 0 1px 2px rgba (28 , 25 , 23 , .06 ), 0 4px 12px rgba (28 , 25 , 23 , .08 );
--ed-shadow-2 : 0 2px 4px rgba (28 , 25 , 23 , .06 ), 0 12px 32px rgba (28 , 25 , 23 , .14 );
--ed-blur : 20px ;
/* 动效 */
--ed-ease : cubic-bezier (0.2 , 0 , 0 , 1 );
--ed-dur-micro : 120ms ;
--ed-dur-card : 220ms ;
--ed-dur-reveal : 500ms ;
}
[data-theme = "dark" ] {
--ed-primary : # 5C7CFA ;
--ed-memory : # E8A04C ;
--ed-bg-canvas : # 101013 ;
--ed-bg-surface : # 1C1C20 ;
--ed-bg-sunken : # 25252A ;
--ed-text-primary : # F2F2F0 ;
--ed-text-secondary : # A0A09E ;
--ed-text-tertiary : # 6A6A68 ;
--ed-border : # 2C2C30 ;
/* 暗档做法已上升为 --ed-shadow-1/2 的统一策略:暗底不用投影(黑色投影不可见,只会让面板边缘糊成一团),改白色反相描边 */
--ed-shadow-1 : 0 0 0 1px rgba (255 , 255 , 255 , .06 );
--ed-shadow-2 : 0 0 0 1px rgba (255 , 255 , 255 , .06 );
}
@media (prefers-color-scheme : dark) { : root : not ([data-theme = "light" ]) { /* 同深色块 */ } }
主题机制 :显式 data-theme 优先,未显式时跟随系统偏好。切换时 200ms 交叉淡入。
本节记录已落地的代码事实 :app/src/ui/primitives/ 一个子域、41 个文件、唯一导出面 index.ts、逐个 ≤300 行 。
数值真源一律是 app/src/ui/tokens.css 与 app/src/ui/primitives/motion.css;§五/§十 的旧目标态参数(靛蓝主色、8/12/16px 圆角、旧灰阶)仍是 2026-08-24 版本,待批 8 统一回写 ,不要以它们为准。
迁移在批 4 (本批只交付靶子,界面外观零变化是设计意图)。
11.1 原语清单:用途 / 消费场景 / 禁止事项
原语
用途(一句话)
消费场景(批 4 迁移面)
禁止事项
Text
墨度 × 字阶的唯一出口
全部正文/标签/标题(现状 fontSize 1274 行 / 143 文件)
不做语义色决策(tone 只是「取哪一档墨度的名字」);不额外包裹 DOM;ink-4 是过渡态,不得承载唯一关键信息
Surface
面(底 / 边框 / 圆角 / 阴影)的唯一出口
卡片 / 列 / 阅读面 / 弹层底(现状 borderRadius 584 行、boxShadow 18 个不同字面值)
不承载排版(属 Text);interactive 只给视觉,键盘可达性由消费方用真实 <button>/<a> 承载
Button
四态契约的唯一出口 (hover / active / focus-visible / disabled+busy)
121 个文件的按钮与 60 个文件的按钮样式常量
无 danger 变体、绝不用 --ed-stamp ;不覆写 tabIndex/role;危险语义用 ConfirmDialog
Modal
弹层唯一实现 (createPortal + role="dialog" + aria-modal + 焦点陷阱 + ESC 栈)
28 个手写弹层
消费者不得 自建第二套 Portal / 焦点陷阱 / ESC 监听
ConfirmDialog
危险确认 (印章标记 + 级联影响清单)
23 处 window.confirm / 裸 confirm(
确认按钮保持中性(variant="secondary");级联一律不给撤销 (只给确认)
Toast
进出场 180/140 + 可打断 (新消息接管,不排队)
4 套自绘 toast(现状全部只有进、没有出)
不排队;action 点击后不自动消失;只有 err 用 aria-live="assertive"
EmptyState
空态三段槽位 + 主行动按钮
40 行 / 28 文件的「暂无…」灰字(5 套空态)
不设 role;装饰图标不给 label;不加 className/style(空态是「一处的形态」)
Loading / Skeleton / Probe
加载三形态:形状已知 → 骨架;要一句文字 → 加载;都不要 → 探针
85 处 / 30 文件的手写灰字
不写字号与颜色(排版属 Text);Probe 恒为装饰(aria-hidden);需要被朗读的加载态不许用 Probe
StatusLine
错误 / 警告 / 成功 / 信息四档语义的唯一出口
196 处 / 76 文件(三种红并存)
本原语不渲染任何按钮 (action 是纯插槽);颜色不是唯一信号 —— 「这是什么」必须由 children 的文字说清
z-index 六档标尺(批 0-A)
叠放顺序的唯一来源
32 文件 45 处硬编码(17 个不同值)
不写裸数字(一律 zIndex("modal" | "modalNested" | "toast"));迁移必须按叠放段整段推进
承载方式 = CSS 类 (.ed-<原语> + --<档> 修饰类 + -<部位>/__<部位> 子元素类),不是内联 style:
:hover / :active / :focus-visible / @keyframes / @media (prefers-reduced-motion) 都无法内联表达。
四态 :hover(Button 三档各异、Surface--interactive 升起 --ed-shadow-1 + translateY(-1px))·
active(按下微陷 1px)· focus-visible(2px --ed-ink-1 焦点环 + 2px offset;鼠标点击不留环、键盘 Tab 必须可见)·
disabled / busy(cursor: not-allowed + opacity: .55;disabled 移出 Tab 序,busy 保留焦点与 Tab 序 )。
墨度即确定度 :Text 的 tone 九档;任何交互(悬停/聚焦/选中)立即升到正文墨度 (§4.3 规则 2)。
出现场 :Modal/ConfirmDialog/Toast 一律走 [data-phase] 三态(enter / entered / exit),
退场期禁用指针事件 (见 11.3)。
11.3 动效接缝与 prefers-reduced-motion 承诺
一处改对所有地方 :所有时长/缓动只经 var(--ed-dur-*, 同值字面量) / var(--ed-ease, …) 消费,变量块在
motion.css 一处定义(真源属批 6 ,届时整块删除即生效,无需改任何规则)。
接缝锚点 :Button/Surface 的四态类 · Text 的墨度与字距 transition · Modal/Toast 的 [data-phase] ·
EmptyState 的 .ed-empty-enter · Loading 的 ed-skeleton-shimmer / ed-probe-swing(循环环境动效走 CSS @keyframes)·
StatusLine 的一次性浮现过渡。
无障碍优先 :app/src 内唯一 一条 prefers-reduced-motion 块在 motion.css,覆盖全部 .ed-* 基类
与每一处 animation 声明的选择器原文(含伪元素) (transition 与 animation 双双压到 1ms)。新原语只要根类进名单
就自动被覆盖 —— 这是规格 §11 验收 5「覆盖率 100%」的判据,由 motion-coverage.test.ts 机器守门
(判据 = 基类名单 + 动画落点名单,不是「全类集合 ⊇」 :.ed-modal-head/body/foot、.ed-confirm-seal/-impacts/-keep、
.ed-empty__title、.ed-toast-action 这些子元素类与基类同在一个元素上,逐字枚举只会假红)。
⚠️ 伪元素必须逐字列出 :animation-duration / animation-iteration-count 不是可继承属性 ,覆盖写在宿主元素上
伪元素拿不到 —— T11 评审用 headless Chromium 实测:.ed-skeleton 已静止而 .ed-skeleton::after 仍是 1.2s / infinite。
keyframes 只用于「循环环境动效」 (Loading 的骨架微光 / 探针);EmptyState 的入场(.ed-empty-enter)与
StatusLine 的浮现都走一次性 transition,状态行不做循环动画 (它是信息不是「呼吸物」,循环会在长列表里变成噪音)。
可中断、可反向 :usePresence 的退场途中 open 回 true ⇒ 清计时器、直回 entered(不重放进场);Toast 的新消息接管 而非排队。
位移上限 8px (规格 §8.4):原语层任何位移 ≤8px,批 6 的 GSAP 时间线同样不得越过(机器判据在 style-seams.test.ts)。
原语只许用 var(--ed-*) 与 zIndex();primitives/**/*.css 内零颜色字面量 (色值只在
app/scripts/gen-tokens.mjs 与产物 tokens.css)。z-index 用 TS 标尺,不作 CSS 变量 。
禁令一(危险色) :--ed-stamp 是全站唯一非中性色,绝不用于按钮,也不得出现在任何 background* 声明里 ——
它只做文字色 (StatusLine.error、Text tone="stamp"、ConfirmDialog 的印章)与描边
(ConfirmDialog 印章边框、Toast--err 的左边框)。按钮一律中性。反例守卫在 style-seams.test.ts。
禁令二(剪报底纹) :剪报底纹上只用 ink-3 及更深 (§九同款条款);--ed-ink-4 禁止用于剪报底纹。
依据 :规格 §4.3 条件 ③「进入审校模式时全部升到 ≥4.5:1」与该节的就地加注(批 4 / 批 6 / 批 7 / 批 8 T3)。
本节写的是规范面 (用户看到的审校模式是什么);🔴 实现落点登记在 12.2 末条 (它不是 生成物 ui/tokens.css)。
入口 :顶栏右簇的一个可发现按钮 (与 ⌘K / ⚙ 齿轮同簇),加快捷键 ⌘/Ctrl+Shift+R 。按钮必须带
可读文案 + 快捷键提示 (title)—— 「可发现」是条件 ① 的字面要求,不靠用户猜快捷键。
⚠️ 入口不进视图注册表 :它不是第四种「视图」,而是所有视图共同的面 (规格 §4.3① 逐字)。
作用域 :当前阅读面的全部文本节点 (NotesReadingColumn 的每一种视图、卡片流行、印样正文);
不含 编辑器(RichEditorView)与弹层外的外壳 —— 编辑态已有自己的墨度语义。切到别的对象 ⇒ 模式保持
(它是「我此刻在审读」的用户意图),但只影响当前挂载的阅读面 。
三出口(等价) :再按同一个快捷键 · 点同一个入口按钮 · Esc 。三条都必须能出;
退出后墨度立即回到未进入前的档位 (不得留任何中间态)。
缺省不落属性 :常态下 <html> 上没有 这个属性;退出走 removeAttribute,不是 写成 "off"
—— 否则「缺省态」与「显式关」在 DOM 上不可分,首屏还白多一个属性。
载体 = <html> 根元素上的 data-* 属性 (与 data-theme / data-motion / data-shell-phase 同范式),
不是类名 (规格 §8.3 逐字:载体 = data-*,禁止用类名区分)。
属性名 data-proofread-mode,取值 "on" (缺省 = 不落属性 )。🔴 命名消歧 :proofread 一名已被
LLM 文本校对占用 (commands_proofread.rs / ProofreadPanel.tsx)⇒ 本模式必须 用 data-proofread-mode,
不得 用 data-proofread(控制方 §2 B2;规格 §4.3④ 原文的三处写法由紧邻的就地加注改读)。
🔴 不新增 token :审校模式不是第五档墨度 ,而是档位覆盖 —— 模式位下把 --ed-ink-4 的值重绑到
--ed-ink-3,.ed-text--ink-4 的规则一个字不改 ⇒「全部升到 ≥4.5:1」由变量重绑 一次兑现,
调用点零改动、零逐处判断(规格 §4.3⑤ 的机制 不变,只更正落点)。暗档同样被覆盖(变量重绑一次通吃)。
模式位的单一写入方 :useProofreadMode() 在生产里只许调用一处 (App.tsx,第二、三出口的宿主),
其他面(含顶栏入口按钮)必须复用同一份状态 (经 props / context 注入)—— 属性是全局唯一 的载体,
两处各持一份 state 必然互擦(判据见 shell/proofreadMode.dom.test.tsx 的「单一写入方」用例)。
🔴 本节登记:实现落点 = app/src/ui/proofread.css (由 main.tsx 在 token CSS 之后 import),
不是 生成物 app/src/ui/tokens.css(:2-3 逐字「由 scripts/gen-tokens.mjs 生成,请勿手改。手改会被
src/ui/tokens.drift.test.ts 判失败」)⇒ 不得 手改生成物,也不得 改生成器 gen-tokens.mjs
与 ui/primitives/Text.css(控制方 §2 B1)。
落地状态(带时点,2026-09-13) :① 模式位(shell/proofreadMode.ts)· ② 纯 CSS 覆盖
(ui/proofread.css)· ③ 快捷键与 Esc 两条出口(App.tsx)已入库 (批 8 T9);
④ 顶栏入口按钮已落地 (批 8 T11):位置 = 顶栏右簇的 topbar-proofread(复用右簇动作按钮族,零新样式常量),
状态由 App.tsx 透传同一份 模式位(单一写入方)⇒ 按钮 / 快捷键 / Esc 三条出口合流 。
本文档与 theme.md 同步维护(2026-08-24 建立)。组件/参数变更须回写本文档。