# 鼎味运营后台 · 视觉方向稿 v1
**案板 · 切割线 · 计量 · 熟成**
| | |
|---|---|
| 状态 | **已拍板(2026-09-29)**。四项决策见下方「拍板记录」。**本稿停在设计稿,不改 `workbench/`**(见 §10) |
| 日期 | 2026-09-29 |
| 派生源 | `docs/design/DESIGN.md@v0.3.0`(**provisional**,尚未发布锁定)/ Surface `SUR-02` |
| 数据 | 全部为合成数据,人名、订单号、金额均为虚构 |
| 看稿 | 需通过 HTTP 打开(波谱用 mask 引 SVG,`file://` 会被跨源策略拦掉) |
```bash
cd docs/design/prototypes/admin-console/study-20260929
./serve.sh # 默认 18104,绑 0.0.0.0
# → http://100.90.0.100:18104/index.html
```
## 拍板记录
| 问题 | 决定 | 影响 |
|---|---|---|
| 品牌调性 | **案板 · 切割线 · 计量 · 熟成**,四个词定死 | §3 全部 token 表 |
| 右侧设计注解栏 | **保留,304px 常驻**,不折叠 | 六类页面全部保留注解栏;台账/看板页正文宽度按此让位 |
| 「本次停送」 | **保持中性色,不涂红** | 停送靠断轨 + 文字区分,不靠颜色 |
| 肌理 / 质感 | **补材质、光影、走向三件事**,不许靠叠滤镜充数 | 见 §3.1 与本轮第二次返工 |
| 木质 / 烟熏 | **木纹加重 + 加拼板缝 + 引入烟熏** | 见 §3.1 与本轮第三次返工 |
| 肌理喧宾夺主 | **退回参考包的做法:壳层纯色,纹理只出现在一个位置** | 见 §3.1「纹理的位置」与本轮第四次返工 |
| 太难看 / 重点层次 | **材质改类纸,删净花纹;一屏一重心,焦点面领先,周带降为上下文** | 见 §3.1「类纸」与本轮第五次返工 |
| 老土 / 平庸 | **拆灯。删拟物光源,深度改由明度链与灰阶边线给;纹理往灰阶偏,不往白黑偏** | 见 §3.1「光影 · 拆灯」与本轮第六次返工 |
| 本轮范围 | **只停在设计稿,不改 `workbench/`** | 见 §10 |
拍板前后的六次返工,都记在这里,因为它们改的是判断,不是参数:
1. **熟成状态**原本是八个自绘小图标(虚线框 / 三角 / 点阵…),被指出"稍显低级"。
返工后改为**熟度刻度**——状态不再是图标集,而是同一条切割线走了一段之后的读数,
八态共用一个几何、靠结构区分。见 §3 熟成。
2. **整稿被指出"永远停留在平面和拼凑"**。诊断结果不是"肌理不够",是三处硬伤:
六个面各自朝不同方向渐变(实测 180/168/146/100 四个角并存)、
全稿零纹理、深墨焦点面上盖着一张与木纹垂直走向的半调网点。
返工后立了**一条切割线走向**,见 §3.1;第六轮又把拟物的光源整条拆了——现在靠**明度链 + 边线**立住板。
这一版是本稿与参考包拉开差距的地方,也是唯一一处参考包没做的。
3. **要求"木质和烟熏感更重"**。这一轮改的是两样东西的性质,不是权重:
木纹那一版 `.17/.07/.12` 是在"别读成塑料"前提下调的平衡点,木头是有了但不够厚——
加重走的是**低频层**(年轮、不匀),不是细纤维,抬纤维只会把它推向灯芯绒。
真正让它读成木头的其实是新加的**拼板缝**:噪点再准也只是米色加纹理,
让人读出木头的,是这块料**被拼起来**这件事。
烟熏则是从零建的一层:先按"悬浮颗粒散射光"推演出该用 `screen` 而不是 `soft-light`,
再发现它最先该落在**色**上(提黑)而不是纹理上。
两处都推翻过方案,过程记在 §3.1,别只抄结论。
4. **被指出「太杂乱,底纹抢走了全部的注意力」,要求参考示例包的做法。**
回头把参考包翻到底,答案在 `proto.css` 里写着:**`background-image` 出现 0 次**。
它全包唯一的纹理是焦点面板一角那张 `opacity: .2`、`height: 220%`、`top: -60%`、
被 `overflow: hidden` 裁掉三分之二的图——不是"把纹理调轻",是"纹理只出现在一个位置"。
这一轮的错不在参数,在**把"有肌理"当成了目标**:第三轮一听说要加重木纹,
就把四层纹理铺成了每个面的材质,那正是参考包 README 里点名的
「铺在数据正文上」。它一直没禁止纹理,它禁止的是**推广**。
返工后案板面、轨、焦点面、注解栏全部退回纯色,只留周带那一层拼板缝;
烟从满面板收到左上角 `58%×70%` 的一团。
顺带修了一处自查出来的对比度欠账:面变平之后 `multiply` 撤了、底色浅了半档,
`--dw-content-meta` 在熟成面上只剩 3.79:1——压深到 `#6B5D52`(4.63:1),
`--dw-content-locator` 压到 `#835639`(4.57:1);
上一轮为了跟木纹较劲而加深的「待确认 / 本次停送」两支退回原位,
否则会跟新的辅助字撞成同一支。
5. **被指出「太难看了,不要为了做而做」——真正的诉求不是花纹,是页面的均衡和重点层次;
并且「木很容易联想到纸,只需要类纸材质,温和通顺即可」。**
这一轮和第四轮不是同一件事。第四轮是"纹理太重",处理办法是减层;
这一轮是**"我一直在跟一个不需要赢的联想较劲"**。
木头和纸本来就是近亲,把木纹压下去并不等于得到纸——压到底只剩一堵米色墙。
所以这次不是继续减,而是**换材质**:删净 `--dw-plank` 与三支 `--dw-grain-*`
(不是"标记为已退出"再留在文件里等下轮复活——留在 token 文件里的东西
没有任何东西会报错,它只会等着被再用一次),换成一层各向同性的 `--dw-paper-fibre`。
层次上的四处实改,都是对着 1440px 截图量出来的:
**深色从三块减到两块**——常数条原本是全宽近黑底白字,承载的却是最少的业务信息
(稿子自己的版本号 / 路由 / Surface 编号),是全页单位像素最重的一块;
退回成 11.5px 的浅色注脚之后,页面上只剩轨(壳)和焦点面(主体)两块深色。
**顺序倒过来**——焦点面原本排在周带下面,而这一屏的设计意图明写「每屏一块,
回答现在该做什么」:上下文压着主体,层次就是反的。p1 / p5 两页调成焦点面在前。
**衬线归位**——原先衬线在页标题(30px)、焦点面用无衬线 24px,
同一件事被两种字体说了两遍;现在衬线只长在焦点面上(26px),
页标题降到区块级(16px),一屏一次大字号、一个重心。
**注解栏减框**——它天然是全页密度最高的一块(304px 装 12.5px / 1.9 行高),
密度本身就是一种强调。减的不是字,是框:行高松一档、块间距开到 34px、
K-xx 编号从带底色的小方块退回成一行定位色。
异常块也退掉填色,一句话不值得一整片底。
这一轮还查出两处**对照度欠账**,都和上一轮那句"4.9:1 / 4.7:1"是同一个病:
拿中间调当最坏情况。明度链重排之后(板面压深、刮面提亮、熟成面提亮一档),
`--dw-content-meta` 掉到 4.41:1,压到 `#675A4F`(熟成面 4.63:1);
`--dw-measure-muted` 名义 4.7:1、实测五块浅面里四块不过线(熟成面 3.41),
这一支直接撤销,四个落点并回 `--dw-content-meta`——两支色本来就在做同一件事,
12px 的字不该有两种灰。熟度刻度停送 `#857A6D` 在刮面上 3.63 看着是过的,
掉到熟成面只剩 2.92,压到 `#7D7266`(3.27)。
判据统一成一句话:**比的是两端,不是中间调**。
6. **被指出「老土、平庸」,要求探索更先锋的编排。**
诊断结果和前五轮都不同:问题不在配色、不在参数,
**在于前五轮一直在优化一个不该存在的维度。**
它们把光调得更统一(`180/168/146/100` → 单一 `162deg`),
却从没质疑过那盏灯该不该在。**收拢方向只是让灯更整齐。**
灯在,界面就永远停在"一群被照亮的物件"上——这是拟物的老土感,
换任何配色都治不好,因为它不是配色问题。
这一轮拆灯,深度改由两样东西给:**明度链**(面与面只差明度)
和**边线**(外侧一条实边 + 内侧一条线,亮面内浅、暗面内暗)。
判据定得很硬:**边里不许出现白或黑**——纯白是全系统唯一一支
不在案板色系里的颜色,而它原本出现在每张卡的每一条上沿,以及每张卡的悬停态上。
同时按「在主色基础上,纹理和点缀往灰色色阶偏,而不是往白、黑去强调」,
把两支纹理色从暖色换成灰,量出来是这样:
| | 修之前 | 修之后 | 底色自己的值 |
|---|---|---|---|
| 案板面(含纤维) | 19.73 | **16.45** | 16 |
| 深墨焦点面左上(含烟) | **25.17** | **17.79** | 17 |
| 纤维 / 烟的明度起伏(像素标准差) | 7.26 / 9.9 | **7.56 / 10.76** | — |
彩度掉回底色自己的值,**而明度起伏反而更大**:纹理变得更像纹理,
不再像一层颜色。总则写进 `tokens.css`:**纹理只许改明度,不许改色相。**
附带查出一处**被自己的量测推翻的旧结论**——第五轮写过
「烟色取暖,中性灰会把暖底洗成灰纱,同一个病不犯第二次」,
而 `#C79A5E` 的彩度是 105,`screen` 叠到 R−B 只有 17 的深墨上落点彩度 93。
**它犯的正是它自己刚犯过的病。** 完整记录在 §3.1「烟的叠法」。
状态色(八态熟度刻度)这一轮**不动**,理由记在 §3 熟成:
颜色只长在 16×6px 的刻度上,正文永远是墨色,八态靠**几何**区分
(填充 0/5/11/16px、落刀位置、形状)。它已经是点缀,不是抢眼。
**收尾时按同一条总则复查,翻出三处漏网的:**
一,焦点面底下那道波 `rgba(160,138,110,·)`,R−B = 50,是深墨基准面(14)
的三倍半,而且写死在组件里(违反「渐变是 token 的一部分」)。
逐格扫描焦点面 35 格,C 全部落在 14–17——**它没把面顶出带外,
但那是 α 小、欠债小,不是它站得住**。等亮度解出 `#948C86`,
落点 R−B 从 21.9 回到 14.0,抬亮的量一点没少。
二,十支**零引用**的 token。其中 `--dw-content-inverse` 与
`--dw-measure-on-shadow-hover` 同值——一支色两个名字,正是本文件
反复说的那个毛病。按「靠注释守的规则等于没有规则」全部删掉,
并给 `verify.cjs` 加了 DEAD-TOKENS 检查(判据必须扫全目录:
在页面里查看不见 `index.html` 的内联样式,会把 `--dw-attention-end`
误报成死的——第一版就是这么写错的)。
三,`tokens.css` 自己还在用光描述**当前**状态:「受光角落/背光角落」
是量测区域标签,改成「浓角/淡角」;纸的锚点那段还写着
「和 `--dw-light` 同一个来源」,而那个 token 上一轮已经改名
`--dw-tone`。拆灯要拆到注释里才算拆完——**注释里的光是下一次
把灯装回去的图纸**。历史记述(「上一稿有 162deg 受光角」)保留,
那是变更记录,不是现状描述。
---
## 1 · 先说清楚三件事
**这不是一次换肤。** 现有 `workbench/` 原型已经带了参考包的相当一部分规则(开放式台账、mono 行序、每屏一块深墨焦点、语义化 token)。真正让它"看起来只是一个很普通的系统"的是另外几件事,下面第 2 节逐条列证据。
**这一稿不动业务层。** 82 个工作区的业务定义(`design-source.py`)、206 个动作、`stories.md` / `flows.md`、localStorage 格式、`catalog.json` 全部原样保留。本稿只重写视觉层与六类页面的结构范式;其余 76 个工作区在拍板后继承同一套皮肤,抽样验收,不逐页定版。
**这一稿不代表 Foundation。** 它派生自 `SUR-02`,该条明确写着"运营/后台面可以有更高密度与自己的表达,**不主张与消费面同一套皮肤**"。所以下面不会去和消费端对齐,反而是借这条把差异写清楚。
---
## 2 · 现状诊断(为什么是"很普通")
对照现有 `proof/visual-20260929/` 截图和 `workbench.css`:
| # | 症状 | 证据 | 后果 |
|---|---|---|---|
| D1 | 焦点面是一整块 ~500px 的单色深墨 | `workbench.css` 的 `.focus` 无内部层级 | 深色预算一次花光,第二屏开始整页发平 |
| D2 | 全站没有数字语言 | 金额、重量、行序、计数全是正文字体 | 生鲜零售最该被一眼读到的东西(斤、两、元)不可扫读 |
| D3 | 首屏之下有两块闭合描边的白卡 | `overview.png` 首屏 | 通用后台的默认样貌,与品牌无关 |
| D4 | 设计推导藏在工具栏按钮后面 | `MODULE-DESIGN.md` 的说明只写在文档里 | 评审看不见推导,理由变成"我觉得" |
| D5 | 壳层只有两栏,没有页签条与常数条 | 82 个工作区挤在一条竖轨里 | 从一个工作区跳到另一个要回到顶部 |
| D6 | 深色波谱是贴图,不是裁切图形 | `foundation/spectrum.svg` 直接铺 | 换尺寸就变形,签名感丢失 |
**D2 是最要紧的一条。** 肉市后台的每一个判断都压在数字上:这一单几斤、多少钱、免不免运费、还有几分钟确认截止。这些数字现在和说明文字同权,运营只能逐行读,读不出来。
---
## 3 · 品牌方向:为什么是这四个词
不是给一套配色,是给一套**可复用的判断**。每一段内容的起手方式、数字怎么写、状态怎么表示,都由这四个词推出。
### 案板 —— 材质
**类纸**暖色面,靠明度与微温分层,不靠描边。第五轮把材质从"木头"换成了"纸":
木头要走向、要拼缝、要年轮,纸一样都不要——把这三样压下去并不能得到纸,
只会得到一堵米色墙。纸只留一样东西:绒面(见 §3.1)。
明度排成一条链,**比的是两端,不是中间调**:
| 面 | 渐变两端 | R−B | 语义 |
|---|---|---|---|
| 熟成面 cure | `#EDE7DE → #ECE6DD` | 15 / 15 | 注解栏与次级分区 · 全系统最深的一块 |
| 案板面 block | `#F2ECE2 → #EEE9DF` | 16 / 15 | 页面底 |
| 刮面 scrape | `#F3EDE2 → #F1EBE1 → #EFEAE0` | 17 / 16 / 15 | 卡片与台账 · 全系统最浅,卡片压在板上 |
| 案下阴影 shadow | `#382E27 → #272019` | 17 / 23 | 深墨焦点面 · 板上挖的洞 |
| 关注面 attention | `#F8EEDF → #F0E4C9` | 25 / 39 | 需人工判断但未阻断 · **信号面** |
| 阻断面 alert | `#F4E7DD → #EDD9CB` | 23 / 34 | 已阻断,不可继续 · **信号面** |
三条硬规则,都是量出来之后补上的:
1. **两端都要成立。** 上一版刮面起点 `#FBF6EB` 比板面起点 `#F9F4EA` 亮,
止点 `#EDE3D1` 却比板面止点 `#EFE4D3` 暗——同一张卡片在屏幕左上比页面亮、
在右下比页面暗,明度关系在屏幕上翻了个个儿,于是没有任何东西读得出
「放在板上」,整页成了一片没有层次的黄。
2. **色温也要排成一条,而且三块结构面必须同温。** 注解栏紧挨着板面,
两块面并排时色相差太远,读出来是"贴上去的一块纸"。判据是 R−B 的差。
第五轮把三面压到 19 / 24 附近,第六轮收得更死——案板 16→15、
刮面 17→15、熟成面 15→15,**锁在两格之内,三面合计明度跨度 0.0547**。
修之前是 9–24 的散值:一块面之内暖度自己走了 15,那张纸就不是一张纸。
3. **结构面共色度,信号面不管。** 关注面与阻断面**故意**留在外面
(R−B 25→39 / 23→34,明显更艳),因为它们在做信息工作。
判据是结构面彼此之间不许有色差;信号面不参与这条。
每个面自带渐变 token(`--dw-block-start/-end` 等),**组件里不许现调渐变**。分层靠面,不靠线。
### 3.1 · 类纸 · 纹理的位置 · 拆灯 · 烟
面只解决"是什么颜色",不解决"看起来像不像一块料"。但第三轮在这里走错了方向:
**把"有肌理"当成了目标,于是把纹理铺成了材质。** 第四轮被指出
「太杂乱,底纹抢走了全部的注意力」之后回头看参考包,才看见它真正的做法。
第五轮又错在更前面一格:**木纹减到底并不等于得到纸**——
木头和纸本来就是近亲,把木纹压下去只是拿掉了一层,剩下的仍是一堵米色墙。
这一轮的结论是"类纸",不是"更轻的木"。
#### 纹理的位置(第四轮补的,第五轮仍然成立)
参考包 `proto.css` 里 **`background-image` 出现 0 次**——整个后台壳层是纯色的。
全包唯一的纹理是 `dashboard.html` 里的一张 `
`:
```css
.ux-summary > img { position: absolute; z-index: -1; right: -12%; top: -60%;
width: 62%; height: 220%; object-fit: cover; opacity: .2; }
```
四个数字就是全部答案:**`.2` 的浓度**、**2.2 倍高度挂在面板外**、**被 `overflow:hidden` 裁掉三分之二**、
**落在面板空白的一角而不是文字那一列**。台账表体是纯白,连 hover 都只是 `color-mix` 的一层薄色。
它的 README 把禁止项写死了:「重画随机网点、变形拉伸、**铺在数据正文上**、冒充行情」。
所以规则不是"纹理要轻",是**纹理要出现在一个位置**:
| | 第三轮(错:铺) | 第四轮(减) | 第五轮(换材质) | **第六轮(拆灯)** |
|---|---|---|---|---|
| 案板面 | 四层木纹平铺 1700px 整页 | 纯色板 + 单一光源渐变 | 纯色板 + 锚在一角的一层类纸绒面 | 不变,但绒面改**中性灰**——只改明度 |
| 轨 | 两层木纹 + 烟 | 纯色深墨 + 一角薄烟 | 纯色深墨,**烟也撤了** | 不变 |
| 焦点面 | 两层木纹 + 满面板烟 `.22` | 纯色深墨 + `58%×70%` 的烟 `.17` | 不变(洞里本来就看不到面上的纹) | 烟色改**灰**;四条光边改一条中性暗边 |
| 注解栏 | 一层木纹压在 12.5px 正文后面 | 纯色 | 不变,另减框(行距 / 块距 / 编号底色) | 不变 |
| 周带 | 三层木纹 + 拼板缝 | 只留拼板缝一层 | **纯色 + 刀口**,拼板缝也撤了 | 「今天」不再加白色透光,只留 2px 刀口条 + 字重 |
判据是可执行的,不是感觉:**案板的身份由边线、切割线、计量承担,纹理不承担。**
把这五条拿掉,案板还在;把它们全留着,板就变成一张脏纸。这不是取舍,是分工。
第四轮留了个尾巴:三支木纹 token 标着「已退出界面」但仍留在 `tokens.css` 里,
`index.html` 的取样区还展示它们。第五轮把这个尾巴剪了。
留着的理由是「落真实原型时值得再看一眼」——但这句话本身就是个"为了做而做":
**token 文件里没有任何东西会报错**,一支没被引用的 `--dw-grain-fiber` 不会警告任何人,
它只是安静地等着下一次被人抄进 `background-image`。靠注释守的规则等于没有规则。
所以这一轮是**删文件**,不是**改注释**:`--dw-plank` 与三支 `--dw-grain-*` 全部移除。
#### 类纸 · 第五轮的材质(这一节现在的主条)
木纹减到底不等于纸。要纸就得换掉木纹赖以成立的那三样东西:**走向、缝、年轮**。
纸一样都没有,因为纸是浆铺平压出来的,不是长出来的。留下的只有一样:**绒面**。
`--dw-paper-fibre` 一层,各向同性、高频、无方向,锚在一角
(`--dw-paper-anchor`,`72% × 78% at 8% -4%`),叠法恒为 `multiply`——纸不发光。
**第六轮给它换了一支中性灰 `--dw-fibre-tint #959595`**:取原来那支暖色
`#C79A5E` 三通道乘法系数 `[0.9649, 0.9366, 0.8990]` 的均值 `0.9335` 反解
`1 − .16(1 − v/255) = 0.9335` 得 `v = 149`。压暗的总量一点没变
(三通道现在同为 `0.9335`),变的是它不再给底色加暖——
修之前板面渲染色度 19.73、底色只有 16,**页面左上角比右下角暖**。
**它是全系统唯一一层材质**,也是唯一一层允许铺到 1700px 宽的面上的东西。
案板面、轨、焦点面、注解栏的数据区都没有它。
三条参数是量出来的,不是调出来的,因为第一版量出来是**零**:
| | `fractalNoise` + `oct 1`(初版) | `turbulence` + `oct 3`(现版) | 裸板对照 |
|---|---|---|---|
| 锚点角落平均明度 | 230.77(比裸板低 0.86) | 低 2.5 | 231.63 |
| 像素标准差 | **0.678**(比裸板自己的 0.688 还低) | **0.981** | 0.688 |
| 2–98 分位跨度 | 2.3 | 3.9 | 2.1 |
| 对角 | 与裸板逐像素相同 | 与裸板逐像素相同 | — |
`fractalNoise` 配 `oct 1` 的输出几乎是平的灰(明度全挤在 0.5 附近),
压到 `.055` 之后整层等于没加:它把板压暗了,**但没有造出任何绒**,
标准差甚至低于裸板自己的抖动。`turbulence` 的脊线把方差撑起来,
`.16` 下锚点角落的微观起伏大约放大一倍半。
最后一行是这一节真正要证明的东西:**对角与裸板逐像素相同。**
「锚定」不是一个主张,是一层都没铺。1× 下看不出任何东西,3× 下看得到不平——
这就是"温和通顺"的可验证定义。
**拼板缝为什么撤。** 第三轮给它的论证是"端拼案板本来就由横条胶合,缝是结构决定的",
第四轮把它收到只剩周带一处。第五轮连这一处也撤了,理由不是它不好看,
是**它没有来由**:这条带子上没有人在看它是端拼的,它被看见的方式是"有十个竖条"。
**十条竖条就是花纹,不管它是用什么理由做出来的。**
留刀口就够了——七道横刀口已经把"一块料被分成七份"说完了,
纵向的缝是在重复这句话,而重复的那一份正好是眼睛先看到的那一份。
#### 光影 · 拆灯(第六轮)
**这一轮把光源删掉了。** 前面五轮一直在把光调得更统一——从 `180/168/146/100`
四个角收到单一 `162deg`,理由是"四个方向各自渐变看上去是六块布拼的"。
那个理由是对的,但结论下早了:**收拢方向只是让灯更整齐,没有质疑那盏灯该不该在。**
灯在,意味着屏幕外站着一个假想光源,每一块面都要被它解释一遍——
上/左受光就抬白高光,下/右背光就压暗边。八张卡片就是八个小物件摆在一张纸上,
而不是一张纸上的八块。**老土感主要来自这里,不来自配色。**
这也是本文件第一次承认:前五轮一直在优化一个不该存在的维度。
拆灯之后,深度改由两样东西给:
| | 原来(拟物) | 现在(排版) |
|---|---|---|
| 面的层次 | 受光面抬白高光、背光面压暗边 | **明度链**——面与面之间只差明度 |
| 卡片的厚度 | 四条光边,上/左受下/右背 | **外侧一条实边 + 内侧一条线**,亮面内浅、暗面内暗 |
| 「今天」 | 叠一层 `rgba(255,253,247,.30)` 的透光 | 2px 刀口条 + 字重差 |
| 按钮悬停 | `#fff` | `--dw-measure-on-shadow-hover #FBF6EE` |
**判据是硬的:边里不许出现白或黑。** 亮面两支线 `#E2D9C9`(R−B 25)与
`#F6F1E7`(R−B 15)都在案板自己的暖度范围里;暗面两支 `#1C1712` / `#241D17`
是深墨的同色相加深。**哪一支跳出来当光源,哪一支就是错的。**
纯白是全系统唯一一支不在案板色系里的颜色,而它原本出现在每张卡的每一条上沿
——以及每张卡的悬停态上。
**token 改名是防回归的一部分。** `--dw-light: 162deg` → `--dw-tone: 180deg`,
`--dw-lit-edge` → `--dw-edge`。只改注释不改名字,等于给下一次「顺手把角度调回去」
留一个入口:下一个人看到 `180deg` 挂在名为 `light` 的 token 上,
会以为哪里写错了,而实际上错的是那个名字。
#### 走向
木纹的三种走向全部退场:横向年轮没有了,纵向拼条没有了,
与木纹垂直的半调网点第三轮就撤了。留在系统里的走向只剩一种:
**横向刀口**(切割线 / 周带 / 熟度刻度)。
剩下无走向的那一层是烟——它不在面上,本来就不该有走向。
**烟 · 唯一没有走向的纹理,因为它不在面上。** 烟是悬在板面**上方空气**里的东西,
和木纹不是一回事,处理方式必须不同,否则"统一"就变成"糊成一层"。
木纹有走向(它在面上),烟没有(它在空气里),各向同性才是对的。
灯拆掉之后,「没有走向不等于没有方向」这条论证也就没有了依托,
但**锚点必须留着,换一条理由**:满铺的浓烟读出来是"加了一层滤镜",
有浓有淡才读得出"空气里有东西"。**锚点是为浓度差服务的,不是为光源服务的。**
浓度仍锚在一角(`--dw-smoke-anchor` 原点 `10% -8%`,不是居中)。
**烟的范围 · 第四轮收的。** 半径从 `100% × 132%` 收到 **`58% × 70%`**,
雾在面板下缘 62% 处散尽。落在雾里的只剩眉标和标题——大字号、高余量的字;
四行计量和它们的来源行落回干净的墨,第三轮把它们泡在暖雾里,
读出来的是"面板脏了",不是"空气里有东西"。这一条是照参考包
`height:220%; top:-60%` 那个裁切手法来的(见本节开头)。
**烟的叠法 · 推翻过两次,第六轮推翻了记录它的那个理由。**
先试 `soft-light`,在近黑底上等于没加——`soft-light` 是中调算子,
底色压到 15% 明度之后它没有可作用的空间,`.14 / .26 / .26+回弹` 三档看上去完全一样。
改 `screen` 才出来:烟是悬浮颗粒,它**散射光**,所以在暗面是加法不是减法。
浓度 `.22 → .17`:雾缩到角落后,落在雾里的字不再有 4.5:1 的约束。
> **这里有一条被自己的量测推翻的旧结论,值得单独记下来。**
> 第五轮写的是:「烟色 `#C79A5E` 取暖,与案下回弹同一个色相;
> 中性灰那档试过(`#8A7A66`),会把暖底洗成灰纱,同一个病不犯第二次。」
>
> **那句"同一个病"是错的,而且它犯的正是它自己刚犯过的病。**
> `#C79A5E` 的彩度 `C = 105`,是全稿最响的状态色(`--dw-ripe-review`,106)那一档的东西。
> `screen` 叠到 `R−B` 只有 17 的深墨上,落点彩度是 **93**:
> 烟在一块几乎无彩的墨上加出了 93 的彩度。实测焦点面左上渲染色度 **25.17**,
> 是全稿最深的一面,比案板面(19.73)还艳 28%。
> **唯一的锚染上琥珀的那一刻,「案板」就变成了一块打了橙光的黑板。**
>
> 换成与底墨同一条色相射线上的灰 `#B3B0AD`(`R−B = 6`)之后,
> `screen` 落点彩度 11,焦点面左上实测降到 **17.79**,与底墨的 17 只差半格。
> 同一块板上,**烟的明度起伏反而更大**(像素标准差 9.9 → 10.76)。
> 亮起来的那一下没有消失,它只是从色相变成了明度。
>
> 「灰纱」那个担心也是自己吓自己:案板的暖本来就来自**底色**
> (`--dw-block-start #F2ECE2`,`R−B 16`),纹理对它没有发言权。
> 这就是第六轮写进 `tokens.css` 的总则:
> **纹理只许改明度,不许改色相。**
**烟最先落在色上,不在纹理上。** `--dw-shadow-*` 最深处从 `#221B16` 提到 `#2C231C`:
纯黑是个洞,有烟的黑是有厚度的颜色。调参台上先提色、再上烟,色是骨、烟是肉——
单上烟,那层烟在纯黑上没有落脚点。
**灰阶边线 = 抬起 / 挖下。** `--dw-edge` 是外侧一条实边 + 内侧一条线,
亮面内浅(抬起)、暗面内暗(挖下)——一个系统里一套边法,只换极性,不换光源。
深墨焦点面用同一套结构、极性相反,它读成板上挖的一个洞。
面板因此是"放在板上的一件东西"而不是"涂在板上的一块颜色",
但给出这个的是**线**,不是从左上打下来的那盏灯。
**结构面共色度,信号面不管。** 三块结构面(案板 / 刮 / 熟成)的 `R−B`
必须锁在 15–17 的两格之内、只差明度——修之前是 9–24 的散值,
一块面之内暖度自己走了 15,那张纸就不是一张纸。
关注面与阻断面**故意**留在外面(`R−B 25→39` / `23→34`),它们在做信息工作。
判据:结构面彼此之间不许有色差;信号面不管。
**洞里没有木纹。** 焦点面原先也铺了两层 `--dw-grain-fiber / -line`,
这轮撤了,理由是物理的:木纹长在板面上,挖下去之后看到的是木头的**截面**,
不是它的纹。焦点面靠光影分层(眉标 / 标题 / 说明 / 计量 / 行动),不靠纹理。
**纹理不上任何承载文字的面。** 卡片、台账、按钮、表单、计量格、注解栏——一律不带。
注解栏尤其:304px 装 12.5px 正文,是全稿字号最小、文字最密的一面,
一个像素的纹理都在吃字。`LAW-CC-04` 拒绝的是"强推局部肌理",这条是它的具体形式。
**周带是这套语言最要紧的一处。** 一块板横切成七份,拼条竖着走、刀口横着走,
**两种走向在同一块料上交叉**:纵向的拼条跨过全部七天不归零,是"一整块板"最硬的证据;
横向的刀口把七天分开,是"一份一份分开确认"。
原来的 `2px` 网格缝 + 每格各自底色,读出来是七张白纸拼在一条线上——
语义上错(一份计划是一块料,不是七份),视觉上就是拼凑。
「今天」与「已过去」因此都改成**同一块板上的透光 / 蒙暗**,不换材质。
周带底色原先 `#FDFAF4` 那支太白,铺在案板上读成"板上放了一张白卡",
而且底色越亮 `multiply` 咬得越轻、拼板缝沉不下去,缝没了那块板就不是拼的——
所以刮面整体压回 `#FBF6EB → #EDE3D1`,比板面亮一档,但只是一档。
### 切割线 —— 分段
取代通用后台的通用短横线。线身由浓到淡,末端留一个方形切口(刀停下的位置)。
```
.cut 2px × 56px 段落起手
.cut--hair 1px × 40px 密集段落分隔
.cut--strong 3px × 88px 焦点区起手
.cut--on-shadow 深墨面上使用
```
线身 `linear-gradient(90deg, emphasis 0%, base 42%, transparent 100%)`,`::after` 在起点落一个 3px 实心方块。**每一段的起手是一刀,不是一个框。** 这也呼应周计划机制——一份一份分开确认。
**第六轮 · 签名手势的普查。** 上面这套衰减线是全稿最像样的一处,但拿它当尺子量一遍,结论很难看:
| | 出现次数 |
|---|---|
| `.cut` 系列(衰减 + 刀口 + 固定长度 40/56/88px,**不触边**) | **4** |
| `1px solid var(--dw-cut-*)`(均匀、硬停、**触边**) | **23** |
签名手势只占 15%,另外 85% 是触边的均匀发丝线。所以第五轮那句「底纹抢走注意力」是找错了对象——**抢注意力的一直是那 23 条线,不是纹理。** 它们和衰减线用的是同一支 `--dw-cut-hair`,但两者职责相反:边界的职责是「到此为止」,分割的职责是「从这里开始」。把两个矛盾的要求塞进一支色,是这 23 处的病根。
**第 ① 条先做,因为它最便宜。** 见下面「字阶 · 坐标字距」。
### 3.2 · 字距 —— 全稿唯一一处非颜色的质感来源
眉标 `01 / TODAY` 一直是全稿字距最宽的字。量一遍才发现它比第二名宽 1.8 倍——**这个手法此前只长在一个地方**:
| | 字号 | 字距 | 比值 |
|---|---|---|---|
| 眉标 `01 / TODAY` | 11.5px | 1.8px | **0.157em** |
| 轨分组号 | 12px | 1px | 0.083em |
| 周带星期 | 11px | 1px | 0.091em |
| 轨计数 | 10px | 0.5px | 0.050em |
| 注解编号 | 11px | 0.4px | 0.036em |
| 脚注行 | 11.5px | 0.3px | 0.026em |
**宽字距的小字读起来是「刻」出来的,不是「打」出来的。** 这是全系统唯一一处高级感不来自颜色而来自排版的地方。
于是把它收成一条可执行的规则。token 从 `--dw-track-eyebrow`(按第一个使用者命名)改名 `--dw-track-coord`,单位从 `1.8px` 改成 `.157em`——**起作用的是比值本身,写成 px 就钉死在 11.5px 上,换字号比值就散了。**
判据只有一条:**给坐标,不给句子。**
- **给**——命名系统里某个位置的短字:眉标、区块标题、编号、ID、路由、序号、Surface 号。短,且不构成可读的句子。
- **不给**——成句的正文。中文正文加字距是排版错误不是精致:字的方块被拉开,方块之间互相咬合的密排节奏就没了。
已落到 9 处:`.eyebrow` `.annot__title`(原有)+ `.rail__group-index` `.rail__count` `.constants code` `.annot__id` `.task__id` `.taskline__idx` `.detail__id .cid` `.stepper li b` `.pager button`。
两个坑,记在这里:
**一、字距在末字之后也留一格。** 右对齐和居中的元素会被这一格推偏,`.rail__count` / `.stepper li b` / `.pager button` 三处都补了同量 `text-indent` 抵消。不补的话轨上的 `08` 会比 `7` 缩进半格。
**二、同一行里混着中文标签时,字距只能落在坐标上。** `.detail__id` 原文是 `ORD-0031 · PLAN-1147 · 更新于 09-26 14:22 · 版本 3`——整行加 0.157em 之后,`ORD-0031` 是对的,`更新于` 是松散的。**给中文标签加宽字距,读起来是字被拉开了,不是字被排版了。** 所以 markup 里把坐标单独立成 `.cid`,只给这一层字距。改完之后坐标和标签的差别自己就显出来了:`更新于` 是标签,`ORD-0031` 是坐标——这一层差别原先是靠颜色分的,现在靠字形分。
`.stamp`(`09-21 周一`)**故意不给**,它保持 `-.01em`:时间戳是等宽对齐的计量,负字距是为了列对齐,不是坐标。
### 3.3 · 分割线 —— 四种职责,四种对待
第六轮普查的结论要写在前面,因为它是这一节的全部理由:**`.cut` 那套衰减线只占全稿 4 处,另外 23 处是 `1px solid` 的均匀触边发丝线。** 一开始我提的方案是「让 1px solid 全面退休,全部换成衰减线」——**这条作废,方向反了。**
理由是衰减线的性质:它是**手势**,不是**纹理**。手势的力量全部来自它稀有,重复二十次就不是二十个减号,是二十道抹痕,比实线吵得多。**衰减线只能在关键地方用来缓解视觉疲劳,用多了就成了新的杂乱源——它自己变成了它本来要治的那个病。**
所以正确的做法不是「让衰减成为默认」,是**先把线按职责分开**。量了一遍全稿的框和线:
| 职责 | 落点 | 每屏数量 | 怎么对待 |
|---|---|---|---|
| **框** | 表单框、卡片、按钮 | 36–92 | 实线、触边、**绝不衰减**。它的工作是「这是一个盒子」,不是分区 |
| **边界** | 页签条底线、`annot` 左线 | 2–3 | 实线、触边。工作是「到此为止」 |
| **分割** | `th` 底、`annot__title` 底、`taskline` 底 | 8–12 | 实线、触边、**短**。密集区靠它吃饭,密集区不能没有它 |
| **起手** | `.cut` | **7 屏 4 处** | 全系统唯一的衰减线。只在区块开头用一次 |
四类里只有最后一类衰减。**这不是妥协,这是把「切割线」这个签名手势的稀缺性保住了。**
**硬判据:同屏满幅长线 ≤ 3。** 「≤ 3」的意思是**到了就得停手**,不是「三条都合理」。
这条判据的来源是一次失败。第六轮据此撤掉了脚注行的底边线,想让顶部从三条满幅长线降到两条。结果被否掉了,反馈原话:
> 觉得太空,会很困惑,不知道这个位置为啥空了一行出来
**错在哪:** 我把那条线当成分隔线来删,它实际在做的是**收口**。脚注行有 `8px 上 + 9px 下` 的 padding,删掉底线之后它还占着高度,却不再读成一个有边界的单元——读出来是「一行浮着的字 + 下面一段说不清来由的空白」。**那条线是让这一行成为「一行」的东西,不是把它和别的东西分开的东西。**
所以从这条失败里收出一条更硬的规则,**它管的是所有带子,不只是这一行**:
> **一个带子要么收口,要么根本不是带子。**
> 不存在「保留高度、不收口」——那是一个说不清的东西,比不做还糟。
> 想让一个区域「松开」,正确做法是把它的 padding 和边界一起拿掉、让它彻底不再是一个区域,而不是只抽掉其中一条边。
这条比「满幅长线 ≤ 3」更基础:长度是量的收口,收口是结构。**先定结构,再限量。** 当初直接去数长线、没先问「这一行到底是不是一个带子」,方向就错了。
脚注行的底线已加回。顶部三条满幅长线维持原状——**不是「三条都合理」,是这一处没有更好的解法**(见下)。
#### 这一行真正的毛病,不是那条线
撤线失败之后回头看,发现这一行本身就不该存在于壳层里。它和轨底脚注**内容重复**:
| 脚注行(顶部壳层) | 轨底脚注 | 关系 |
|---|---|---|
| `设计稿 v1 · 案板` | `设计稿 v1 · 案板` | **完全重复** |
| `Surface SUR-02` | `…provisional / SUR-02` | **完全重复** |
| `更新 2026-09-29` | — | 独有 |
| `路由 /ops/today` | — | 与面包屑 `运营中心 / 交易与交付 / 今日工作台` **是同一条路径的两种写法** |
**四项里两项重复、一项和面包屑重复。** 真正独有的只有「更新日期」一个。
所以「那条线留不留」是个问错了的问题。真正该问的是:**一条一半内容在别处已经有的信息,为什么还在壳层里占一条通宽的带子?** 这个问题还没有答案,是下一轮的入口。
### 3.4 · 会走的部分 —— 第七轮实验(可证伪)
前面六轮全在做减法:抽纹理、收线、去重复。这条不一样,加东西。
**为什么加。** 七个参考站(getlayers / smoothui / norrly / bookofshapes / SwiftUI / bencho / finexus)有一个共同点,而这一点是鼎味现在完全没有的:它们的配色全是**故意平的**——smoothui 直接用 Tailwind 默认色板,norrly 写明自己是「让灵感主导的中性界面」,bookofshapes 写明「minimal」。它们卖的是**动**。
它们共同缺的一样东西,鼎味有:**这七个里没有一个的主对象自带一只钟。** 通用 SaaS 后面台没有理由动,动起来是硬做的,所以是装饰。鼎味的业务对象是**会熟的**(待确认 → 在途 → 已签收),15:00 是一条真截止线,「今天」真的沿周带走。
> **高级感 = 静止的部分做得准 + 动的部分有来由。**
> 前六轮只做了前一半。这一轮试后一半。
**这一轮只动一个点。** 壳层常数条里放一只真在走的钟,页内焦点头放一个真在减的倒计时。不铺开熟度刻度走位、状态迁移——如果这一条不成立,铺开也没意义。
#### 稿内的「现在」是声明出来的,不是系统时间
倒计时目标 `09-27 15:00`,而稿内日期框架是 09-21 至 09-27(周一带到周日),所以**稿内的现在固定在 2026-09-26 09:48:00**。这个数不是随手挑的,是稿里本来就有的:K-02 那句写死的「5 小时 12 分」正好等于 `15:00 − 09:48`——原作者手算过,基准时刻一直都在,只是没被算出来。
`DW_T0` 是那个基准,`setInterval` 是真的每秒走。
这跟「写死的数字假装自己是实测值」不是一回事:**那是假装,这是不假装**。基准写在源码里(可核对),走时是真的(可观察)。
顺带查出一处真错:写死的「5 小时 12 分」**少算了一整天**。09-26 09:48 到 09-27 15:00 是 **1 天 5 小时 12 分**。这就是「写死的数字假装自己是实测值」的具体后果——它连自己假装的那个数都没算对。
#### 三条落点
| 落点 | 形态 | 为什么这么放 |
|---|---|---|
| 常数条 `稿内现在 09-26 09:48:04` | 等宽 + 呼吸点 | 常数条是全稿唯一有理由活着的一块。带日期,因为左边就是「更新 2026-09-29」,一个不带日期的「现在」会被读成今天 |
| 焦点头 `还有 29:11:54` | 衬线句里嵌等宽计时 | 计量是全系统唯一允许变大的东西,这一个数就是全屏最大的量 |
| 呼吸点 2.4s | 只有常数条一个 | 「有东西在走」不靠动效曲线,靠这一个点 |
倒计时写 `29:11:54` 不写 `1 天 05:11:54`:**仪表里不出现汉字**。「天」落在等宽栈上会掉回 fallback,汉字和数字并排读出来是断的;`29:11:54` 才是一台计时器。而且总小时本来就是倒计时该给的那个数——运营问的是「还够不够联系完 47 户」,不是「隔几天」。
#### 对比度
倒计时 `#C79A5E` 在深墨焦点区上,对该区**最亮**像素 **4.53:1**(24.4px,大字门槛 3:1),往坏的一侧算过。
#### 这一轮的可证伪判据(先写下来,再看结果)
- 动了之后,如果这一页从「一份仔细的规格」变成「一个仪器」 → 公式成立,熟度刻度走位 / 倒计时 / 状态迁移就有依据地铺开
- 动了也没区别 → **动也不是杠杆,这一条也否**
判据是拿眼睛,不是拿参数。
#### 本轮记下的债(不在这一轮改)
1. **`--dw-content-locator` 在常数条右下角 4.46:1,差 AA 0.04。** 既存问题(`路由` / `SUR-02` 一直同色),本轮只是加了第三个实例。修法是把这个 token 压暗一档(`#7F5337 → #7B4F33` 实测 4.74:1),但那是全局改动,不塞进实验里。
2. **验证脚本 `contrast.cjs` 的判据方向错了。** 它只卡「最亮背景像素」。深色字压浅底时,**最暗**那一侧才是坏的一侧——所以上面这条 4.46 它一直没报。判据要分方向:浅底深字卡最暗,浅色字压深底卡最亮。
### 3.5 · 坐标错了,不是执行错了 —— 第八轮
前七轮一直在把一件事做得更准。第八轮去查了当下「比较高级的表达」是什么,
结论打到前面七轮的立足点上,所以单列一节。
#### 三条独立信源,同一个判断
| 来源 | 原话/要点 |
|---|---|
| **iF 2026 趋势报告**(Age of Average / Zero Glam / Recoupling Design) | 「AI 可以轻松生成『高级感』的时代,高级感本身已经不再稀缺。」——**AI 的底层逻辑并非创造,而是预测** |
| **Adobe 2026 创意趋势**(All the Feels / Connectioneering / Local Flavor) | 82% 的消费者期待感官被调动;趋势是「日常的地方性生活、传承、手艺」 |
| **AI slop 研究** | 模型坍缩先丢分布的尾巴,而「design's long long tail is exactly where taste lives」;tell 不是丑,是**没有做过决定** |
三条合起来是一句话:
> **凡是能被预测的,都不再是壁垒。**
而克制、精准、去噪、留白、hairline、tabular——**全在分布中心**。前七轮做的每一件事都在中心里。
所以用户那句「我们跟高级感的距离还是很远」不是执行问题:**距离不随执行力缩短,因为执行不是变量。**
#### 拿自己跑了一遍:换牌测试
研究里最狠的一条测试是「换掉 logo 和产品名,还会觉得独特吗」。实测鼎味:
| 表层(陌生人先看见的) | 对不对得上「editorial default」 |
|---|---|
| 暖米底 `#F2ECE2` | 参照值 `#F4F1EA`——**几乎是同一块** |
| 衬线大标题 | 是(Noto Serif CJK SC) |
| 青铜强调色 `#A8763F` | **就是那个色系** |
| 结构层(只有对比才看得出) | 命中几条 tell |
|---|---|
| 居中容器 | **0 个**(全稿左锚定) |
| `rounded-lg` | **0px×276、3px×24** |
| 柔和投影 | **3 个元素** |
| 紫渐变 / Inter | 无 |
**表层正中那个模板,骨架一条没中。** 骨架是对的——但骨架是看不见的那一半,
而换牌测试测的就是那一半。所以这稿子过不了换牌测试。
#### 真正缺的东西:稿里有它的名字,没有它本身
四个品牌词,逐一核对它们在稿里真正承载了什么:
- **案板** — 真在用(一层纸绒 + 明度链 + 灰阶边线,第六轮已拆灯)
- **切割线** — 真在用(`有起点 · 有方向 · 有衰减 · 不触边`)
- **计量** — 真在用(斤两、金额、时点,全精度等宽)
- **熟成** — **名不副实。** `ripe` 轴的八个状态是 `pending/picked/enroute/delivered/skipped/review/blocking/info`,
全是**履约进度**,不是肉的熟成度。一家肉市的界面里,没有任何一处是关于**肉本身**的。
台账里那列原文是 `排骨 2.0 斤 · 番茄 1.5 斤`——**分割和配菜是同一根灰线上的同一种东西**。
鼎味有肉市的词汇(斤、里脊、排骨),没有一个肉市的判断。
一个切肉的人不会把「排骨 2.0 斤」和「番茄 1.5 斤」读成同一个东西。
#### 这一轮只切了一刀
`p3-detail` 逐日安排的「内容」列拆成两级:**分割走墨 + 斤两走计量(等宽全精度)**,
**配菜退到 meta**。没有新增任何视觉语言,用的是稿里本来就有的那一套内容级差。
**这是全稿第一处超市的界面做不出来的列。** 换掉 logo 和产品名之后,
米色 + 衬线 + 青铜那层免费表层还在,但这一列的分法跟着「这家店卖肉」一起走了。
对比度(两种真实行底):分割 11.14 / 10.22,斤两 13.06 / 11.98,配菜 5.80 / 5.32。
**这一刀不炸,这是对的。** 它不是要做成一个奇观,是把一个本来就该有的判断放回原位。
判据仍然是:这一列读起来是「一个切肉的人的台账」,还是「又一列 UI 装饰」。
#### 下一刀该往哪(还没做,记在这里)
`熟成` 那个词现在是空的。真正属于长尾的是**眼色**——新鲜度是用眼睛看的,
不是用状态枚举的。iF 的 Recoupling(手工痕迹、地方性叙事)和 Adobe 的 All the Feels
在这一点上是同一件事,而它之所以 AI 生成不出来,正因为**它是一次观察,不是一次预测**。
但这一刀要动数据(部位、出肉率、损耗),而「保留 206 actions 和业务定义」是拍板过的边界。
所以先记下,不动。见 §9 范围。
### 计量 —— 数字
生鲜按斤两卖。所以数字是这个系统的第一语言,不是装饰。
- 金额、重量、计数、时点、行序:等宽(`--dw-font-measure`),全精度,**永不超过两位小数、永不四舍五入到元**
- 焦点面计量 40px,台账计量对齐右对齐
- 单位与数字分离:`¥1,240.00` / `11.4 斤` / `214.6 斤`
- **未知不是 0。** 收款记录缺失写"收款记录缺失",不写 `¥0.00`——0 是一个断言,缺失是另一回事(`MODELING-RULES`:来源缺失不能填零)
### 熟成 —— 状态
一条从"生"到"熟"的成熟度轴。状态**不是一套图标**,是**同一条切割线走了一段之后的读数**:
一条 16px 的轨、一段 2px 的进、末端一个 2×6px 方块(刀停)。
八个状态共用这一个几何,只靠三件事区分:
| 状态 | 走了多远 | 末端怎么收 | 轨 | 色 | 含义 |
|---|---|---|---|---|---|
| 待确认 | 0px | 收在轨首 | 连续 | `#7C6E60` | 未动 |
| 已拣配 | 5px | 实心方块 | 连续 | `#8A5A2B` | 处理中 |
| 在途 | 11px | 实心方块 | 连续 | `#9C4A38` | 已发生、未完成 |
| 已交付 | 16px(满) | 实心方块 | 连续 | `#4F6B45` | 完成 |
| **本次停送** | 0px | 收在轨首 | **中段断开** | `#7D7266` | **未发生,合法** |
| 阻断 | 0px | 方块压在轨首 | 连续 | `#8A2E28` | 走不动了 |
| 待复核 | 11px | **空框**(1px 描边) | 连续 | `#8A6A20` | 交了但没生效 |
| 系统 | — | 无 | 连续,**只有 8px 宽** | `#5F6B5A` | 中性 |
全部用 CSS 画(`linear-gradient` 两条轨 + 两个伪元素),不引图标字体。深墨焦点面上有一套亮色变体,全部 ≥ 6:1。
**为什么不是图标:** 通用后台的状态图标是一批外来词汇——八个小方块,谁也不认识谁。
把它们收成"一条线的长度"之后,熟成状态轴和切割线、案板、计量并列为**同一套语法**,
而不是系统里唯一一段借来的装饰。而且八态的区分靠的是**结构**(长度、末端、轨的完整性),
不是颜色——这是灰度可读、色觉障碍可读的前提。
> **第六轮:八支状态色一支没动,这是量出来的决定,不是默认。**
> 底色和纹理全部走灰阶之后,很容易顺手把状态色也拉过去——那会把一套
> 正在工作的信息通道当成装饰一起灰掉。查过渲染结果才敢不动:
> **状态色只长在 16×6px 的刻度上,正文永远是墨色。**
> 16×6px 就是「点缀」的定义;八态的区分靠填充长度(0/5/11/16px)、
> 落刀位置和形状,不靠色相。
> 而且已经有四支的明度差只有 0–2/100,它们**本来就**是靠色相区分的——
> 把色相抽掉,这四支会塌成一支。
> 结论:**灰阶管质感,彩色管信息,职责分开。**
**三条硬规则:**
1. 任何状态 = 刻度结构 + 准确文字,色彩只作辅助。灰度打印和色觉障碍下信息量不减。
2. **"本次停送"的轨从中段断开。** 它与"待确认"的区别必须是结构上的,不能只是颜色不同——否则灰度下两者无法分辨,运营会把一个已经合法结束的日期当成待办。
3. **"本次停送"是合法的第三态,不涂红。** 停送是一个已经发生的正常结果。涂红会让运营去"修"一件本来正确的事——这是这套系统里最容易犯、代价最大的视觉错误。
---
## 4 · token 表
完整数值见 `tokens.css`(本目录的数值权威)。命名只允许:
```
surface.* content.* measure.* cut.* action.* status.* brand.*
```
页面级命名(`page-login-button-hover`)一律禁止。
### 墨 content
对比度一栏是**实测的**,不是抄进 `tokens.css` 的:算的是**该墨实际会落到的那个面上最亮的一档**。面是渐变,取最亮端才算最坏情况;`tokens.css` 里几支注释写的 4.63:1 / 4.57:1 / 10.2:1 复算不出来(旧色 `#7A6A5D` 对熟成面是 4.22:1,新色是 5.42:1,没有一个值等于 4.63),已按实测改写。
| token | 值 | 对比度(最坏面) | 用途 |
|---|---|---|---|
| `--dw-content-ink` | `#3B302A` | 10.4:1 对熟成面 · 10.9:1 对案板面 | 正文 14px |
| `--dw-content-ink-strong` | `#241D18` | 13.5:1 对熟成面 | 标题与焦点数字 |
| `--dw-content-meta` | `#675A4F` | 5.42:1 对熟成面 | 辅助 11–13.5px |
| `--dw-content-locator` | `#7F5337` | 5.35:1 对熟成面 | 来源、行序、引证 |
| ~~`--dw-content-inverse`~~ | ~~`#FBF6EE`~~ | — | **已删**:零引用。深墨面按钮悬停那一格用的是同值的 `--dw-measure-on-shadow-hover`——一支色两个名字,正是本文件反复说的那个毛病 |
| `--dw-content-on-shadow` | `#F7F1E6` | 11.8:1 对深墨最亮端 | 深墨面正文 |
| `--dw-content-on-shadow-meta` | `#C6B7A5` | 6.75:1 对深墨最亮端 | 深墨面辅助 |
`--dw-measure-on-shadow-muted` **已删**,并入 `--dw-content-meta`:这两支色本来就在做同一件事——12px 的字不该有两种灰。这条和下面「结构面共色度」是同一条道理,只是发生在字上。
### 字阶
| token | 值 | 底线说明 |
|---|---|---|
| `--dw-size-section` | 16px | 区块标题 · **页标题也用这一档**(原先页标题是 30px 衬线,和焦点面 24px 讲同一句话,两处都像结论) |
| `--dw-size-body` | 14px | 正文下限,不可再小 |
| `--dw-size-meta` | 12px | 辅助下限 |
| `--dw-size-micro` | 11px | 仅重复性台账标注与计数,**不承载判断** |
| `--dw-track-coord` | `.157em` | 坐标字距。只给坐标,不给句子,见 §3.2 |
| `--dw-track-count` | `0.5px` | 密集重复计数(周带计数) |
`--dw-size-display` `--dw-size-metric` `--dw-size-headline` `--dw-track-brand` **已删**:第五轮把衬线从页标题搬进焦点面之后,这四支就没有任何落点了。留着它们和第五轮删掉的木纹 token 是同一个毛病——**token 文件里没有任何东西会报错**,一支没被引用的 `--dw-size-headline` 不会警告任何人,它只是安静地等着下一次被人抄回 `font-size`。靠注释守的规则等于没有规则,所以删掉,不改注释。
### 材质 material —— 第六轮新增
这一组是「拆灯」以后剩下的全部。**它们只许改明度,不许改色相**;判定方法见 §3.1。
| token | 值 | 干什么 | 为什么不是别的 |
|---|---|---|---|
| `--dw-tone` | `180deg` | 全系统面层渐变角 | 叫 `tone` 不叫 `light`。**改名是防回归**:token 只要还叫 `light`,下一个人看到 180deg 就会以为写错了,顺手改回 162deg,灯就又点上 |
| `--dw-fibre-tint` | `#959595` | 木纤维 multiply 的色 | 解出来的不是挑的:三通道系数同为 0.9335,压暗总量不变,**但不再改色相**。渲染实测案板面 C:旧 19.73 → 新 16.45(裸板是 16)——旧的把纹路画成了颜色 |
| `--dw-smoke-tint` | `#B3B0AD` | 烟 screen 的色 | 取「白 → 底墨」那条射线上 k=0.38 的一点。旧色 `#C79A5E` 的 R−B=105,screen 之后在 R−B 只有 17 的墨上**加出了 93 的彩度** |
| `--dw-wave-tint` | `#948C86` | 焦点面底下那道波 | 原来是写死在组件里的 `rgba(160,138,110,·)`,R−B=50。实测没把整块焦点面顶出带外——**但那是 α 小、欠债小,不是它站得住**。等亮度解,与旧值亮度差 0.0001,落点 R−B 从 21.9 回到 14.0 |
| `--dw-edge-hair` | `#E2D9C9` | 亮面外侧实边 | 案板本色再暗一档 |
| `--dw-edge-inner` | `#F6F1E7` | 亮面内侧浅边 | 抬起的那一下。**不叫 `lit-edge`:这里已经没有光了** |
| `--dw-edge` | 复合 `box-shadow` | **L1 铺面**:上面两条的装配 + 一档贴板影 | 留着 `lit` 这个词,是给下一次「顺手把角度调回去」留入口 |
| `--dw-lay-cast` | `0 1px 1px rgb(0 0 0/.05)` | L1 的影,展不开 | 刮面塑料片压在案板上,影只有一像素高 |
| `--dw-lay-blade` | `0 2px 6px -2px rgb(0 0 0/.11)` | L2 案面的影,展得开 | 全稿只有焦点面是 L2 |
| `--dw-edge-deep` | 复合 `box-shadow` | **L2 案面**:暗面版边法 + 那一档影 | 和 `--dw-edge` 同一套边法,只换极性和影的展度 |
| `--dw-shadow-edge` | `#1C1712` | 暗面外侧实边 | 暗面用「内暗」表示内凹,**同一套边法换极性,不引入第二个光源** |
| `--dw-shadow-edge-inner` | `#241D17` | 暗面内侧更暗 | 同上 |
| `--dw-measure-on-shadow-hover` | `#FBF6EE` | 深墨面按钮悬停 | 原来是 `#fff`。纯白是全系统唯一不在案板色系里的颜色,**而且只在鼠标经过时出现**——一个只有悬停才看得见的、屏幕外那盏灯 |
**`#C79A5E` 现在是双面的,别当成一支被否掉的颜色。** 同一个色值:铺满一屏当烟用,已否(上一行);两像素宽当轨上的当前位置竖条用,必须留着。判据不是这个色好不好看,是**它占多少像素**——同样的色,铺满是滤镜,细线是指引。这正是「结构面共色度,信号面不管」在切割线上的落法。
**`--dw-surface-scrape` / `--dw-surface-cure` / `--dw-surface-block` 三支平色不是 §3 那三张渐变面的替代品。** §3 表里记的是渐变两端(真正铺满一整块的那个面),这三支平色只用在局部填充:页签悬停、`.task`、`.review__row`。两者都要留着,各有落点。
### 行动 action
| token | 值 | 对比度 |
|---|---|---|
| `--dw-action-promise` | `#8A3A32` 深胭脂 | 6.54:1 对案板面 |
| `--dw-action-on-promise` | `#FBF6EE` | 7.14:1 对胭脂底 |
| `--dw-action-quiet` | `#7A6A5D` | 安静操作:导出、重置、取消 |
**一个任务区一个主行动。** 稀缺强调是这个系统里最容易丢的一条。
### 尺度
```
圆角 3px 按钮 / 5px 面板 / 7px 浮层 —— 只有三档
阴影 只给浮层。页面内的分隔靠面和线
空间 4 / 8 / 16 / 24 / 32 / 48
壳层 轨 232px · 批注 304px · 顶栏 60px · 页签条 44px
```
---
## 5 · 壳层:三层 + 常驻批注
```
┌──────────┬────────────────────────────────────────────┐
│ │ 顶栏 面包屑 / 全局搜索 / 岗位与范围 │ 60
│ 导航轨 ├────────────────────────────────────────────┤
│ 232 │ 页签条 当前分组内的兄弟工作区 │ 44
│ ├────────────────────────────────────────────┤
│ 00 今日 │ 脚注行 设计稿 / 更新 / 路由 / Surface │ 30
│ 01 交易 ├──────────────────────────┬─────────────────┤
│ 02 商品 │ │ │
│ 03 客户 │ 页面正文 │ 设计推导 │
│ 04 经营 │ │ (常驻 304) │
└──────────┴──────────────────────────┴─────────────────┘
```
- **导航轨** 分 5 组,带组序号与 mono 计数(`08` / `10`)。82 个工作区需要分组才有可用性。
- **页签条** = 当前分组内的兄弟工作区,详情/表单页归到它所属的工作区上。这是**导航,不是访问历史**——所以它标的是分组号与分组名(`00 今日` / `01 交易与交付`),不写"最近访问"。
- **脚注行** 把路由、Surface、更新日期、Foundation 版本写在每一屏。评审时能立刻确认自己在看哪一版。第五轮把它从 40px 的近黑满幅条降成 30px 的浅底细线、11.5px 灰字——**信息一个字没删,只是不再用一整块深色去举它**。深色从三块减到两块之后,剩下的两块(导航轨、焦点面)各自都有职责了。
- **批注列常驻右侧**,不是工具栏按钮。每一页的"本原型目标 / 设计推导 / PM 决策 / 对照参考包"直接印在页面上,评审和开发看的是同一块屏幕。
---
## 6 · 六类页面原型
| # | 文件 | 页面 | 回答的问题 | 核心手法 |
|---|---|---|---|---|
| 01 | `p1-today.html` | 今日工作台 | 今天该做什么 | 7 列周带 + 深墨焦点 + 待处理三行 + 一份安排的去向四步 |
| 02 | `p2-ledger.html` | 订单台账 | 哪几单不对劲 | 每行可自证展开:谁改的 / 改前 / 改后 / 依据 |
| 03 | `p3-detail.html` | 对象详情 | 这个对象现在怎么样 | 身份 → 状态 → 事实 → 记录 → 可用动作;主体是**七天历史** |
| 04 | `p4-action.html` | 处理表单 | 我这一笔会改什么 | 填写依据 → 核对影响 → 明确确认 → 保存回执(含失败与重复) |
| 05 | `p5-week.html` | 周确认视图 | 这周这户送不送 | 逐日确认是主线;周付款不再重复征询 |
| 06 | `p6-board.html` | 作业看板 | 现在卡在哪、卡住需要谁动手 | 列是事实状态不是工位分工;阻断不提供跳过入口 |
另有 `index.html` 汇总签名元素、案板材质色板与本轮未覆盖清单。
### 每类原型都写清了三件事
每一页的批注列固定三段:
1. **本原型目标** —— 这一页要证明什么
2. **设计推导** —— 每条都引到具体的域事实或 Foundation 条款(`LAW-CC-05` / `INV-CC-01` / `TRANSACTION-INTEGRITY` / `MODELING-RULES`)
3. **PM 决策** —— 设计稿替产品做了哪些选择、为什么,以及哪些留给他们定
示例(`p5-week.html` K-03):
> 配送费列单独成列,用状态像表达「免运费 / 分档 ¥8.00」。这是周计划机制里最容易做错的一条:**费用线不是关单线**。所以它是一个并排的独立事实,不参与状态判断,也不涂成警告色。
---
## 7 · 与参考包逐条对照
参考包:`web-admin-prototype-REQ-005-e225b1e.tar.gz`(HKB Signal v0.11.0)。
### 继承(它做对的,照做)
| 项 | 说明 |
|---|---|
| DTCG 分层 | `tokens.json → tokens.css → 组件 css`,三层单向,组件不写裸值 |
| 语义角色命名 | 只有角色名,没有颜色名。鼎味进一步限制到 7 个前缀 |
| 三层壳层 | 深色轨 + 顶栏 + 页签条 + 常数条 |
| 每屏一块深墨焦点 | 关键——但鼎味的焦点面**有内部层级**(见下方"超出 1") |
| 开放式台账 | 无外框、无纵线、无斑马纹,只有表头发丝线 |
| mono 行序 `#` | 鼎味的行序改成纯数字 `01`(`#` 是 Markdown 头语义,在表格里是噪声) |
| 像素状态像 + 文字 | 鼎味扩到 8 种,并加了深墨面上的亮色变体 |
| 数字对齐 | 全部 `tabular-nums` + `font-variant-numeric` |
| 圆角三档 3/5/7 | 直接沿用 |
| 阴影只给浮层 | 直接沿用 |
| 自托管中文 woff2 子集 | OFL,400/500/600。鼎味在真实原型阶段同样自托管,不引 Google Fonts CDN |
| 空态解释"为什么空" | 鼎味在 `p6-board.html` 底部专门给一组空班次演示 |
### 超出(它没做或做不好的)
| # | 项 | 参考包 | 鼎味 |
|---|---|---|---|
| 超出 1 | 深墨焦点面的内部结构 | 一整块单色,约 500px,第二屏开始整页发平 | 焦点面分**眉标 / 标题 / 说明 / 四格计量 / 行动**五层,计量是 40px mono 并带来源行;焦点面本身读成**板上挖下去的一个洞**(边缘极性与受光面板相反),不是浮着的深色板 |
| 超出 2 | 数字语言 | 无独立数字语言 | `--dw-measure` 独立色板 + 等宽栈 + 全精度规则 + 焦点面 64/40px 两级计量 |
| 超出 3 | 状态的**第三态**与**自绘刻度** | 成功/警告二分 + 一批外来小图标 | 八态成熟度轴,含"本次停送"这一合法未发生态且**不涂红**;状态不画成图标集,而是收成一条线的长度,灰度下八态仍可分辨 |
| 超出 4 | 台账行可自证 | 行可展开看详情 | 行可展开看**谁改的 / 改前 / 改后 / 依据**——把 INV-CC-01 的可核对性做进台账本身 |
| 超出 5 | 写操作前的"核对影响" | 无 | `p4-action.html` 逐行列出**会变什么**和**不会变什么**,并列出被写入的三个对象 id、注明"不是一个事务" |
| 超出 6 | 限界上下文归属 | 未显式化 | 详情页有"这条记录归谁拥有":Demand / Commerce / Fulfillment / Finance 各持一类事实 |
| 超出 7 | 空值处理 | 部分页面用 `¥0.00` 或 `—` | 一律写"收款记录缺失""尚未统计""无法判定",**来源缺失不填零** |
| 超出 8 | 无权限动作 | 直接消失 | 保留位置 + `aria-disabled` + 说明"无权限:需要履约负责人" |
| 超出 9 | 批注可核对 | 有批注列,但内容是设计说明 | 批注每条引到具体域事实或 Foundation 条款,可被逐条反驳 |
| 超出 10 | 域内容 | 用户/角色/菜单/部门/字典 + cron 表达式台账 | 周计划、门禁、暂留资金、逐日确认——参考包里没有的业务形状 |
| 超出 11 | **材质 · 明度链 · 边线** | 纯色面 + 描边 + 投影,靠卡片边界分区;全稿零纹理 | **一条明度链**(面与面只差明度)、**一套边线**(外实边 + 内线,亮面内浅 / 暗面内暗两种极性)、**一层走向**(切割线横贯页面,周带是一块板横切七份)。第六轮把拟物光源整条拆掉——**边里不许出现白或黑**。业务语义(「一份一份分开确认」)与材质语言仍在同一处对上,但不再需要一层木纹、也不需要一盏灯来提示它。见 §3.1 |
| 超出 12 | **面与面之间是有序的,不是各有各的** | 只有一张 `spectrum.svg` 半调贴图 | 五块浅面排成一条**单向的明度链**:`cure-end`(最暗)< `block-end` < `cure-start` < `attention-end` < `scrape`(最亮)。链是**单调**的——比的是两端,不是中间调。色温用 R−B 差校验,同一面族落在 16–24 之内,所以面与面靠**明度**分开,不靠色相吵。周带作为「被放上案板的东西」是全页最亮的一块,两端都比下面的板亮 |
| 超出 13 | **一层锚定同时约束有走向与无走向的纹理** | 半调网点满铺,是花纹不是材质(见修正 3) | 纤维与烟都没有走向。第五轮的论证是「两者都只有被光穿过才看得见,所以锚点都取在光来的地方」;**第六轮拆灯之后这条论证失效,但锚点必须留,换一条理由:满铺的浓烟读出来是加了一层滤镜,有浓有淡才读得出空气里有东西——锚点是为浓度差服务的,不是为光源服务的。** 纤维锚 `72% × 78% at 8% -4%`,烟锚 `58% × 70% at 10% -8%`,雾都在下缘散尽——计量和来源行落回干净的墨。两支纹理色都是灰:**纹理只许改明度,不许改色相** |
| 超出 14 | **纹理的位置,不是纹理的浓度** | 做法是对的(`.2` 裁片),但没写下判据,后人容易把它推广成"给每个面加一点" | 判据写死成可执行的三条,全都能用 grep 数出来:**`core.css` 里字面 `url(` 出现 0 次**(贴图只以 token 存在);**`mask-image` 出现 2 次**——壳层一层类纸纤维、焦点面一团烟,此外全稿无纹理;**周带与注解栏是纯色**。两层都必须**裁切、锚在光源、避开正文**,且都只在字面层上做减法,不用 `filter` 压全页 |
### 修正(它做错了,鼎味不跟)
| # | 参考包的问题 | 鼎味的做法 |
|---|---|---|
| 修正 1 | 批注列吃掉 304–330px 正文宽度,窄屏几乎不可用 | 批注列仍是设计期常驻(它的价值在评审),但 `@media (max-width:1280px)` 直接落到正文下方;同时把批注宽度收到 304px 并在批注内部再分两栏编排 |
| 修正 2 | 表格最后一列被裁切(`运f` / `违f`),没有横向滚动兜底 | 台账放 `.ledger-scroll` 容器 + `min-width`,窄屏横向滚动而不是静默裁字 |
| 修正 3 | 同一个半调波谱贴在每一块焦点面上 | **整块撤掉,换成一层站得住物理的烟**。网点各向同性,与横向木纹是两种走向;且它从右缘打光,与 `--dw-light` 的左上受光相反。**但要记清楚它原来错在哪**:不是"深墨面不许有纹理",是"这张贴图没有来由"。第四轮才发现参考包自己也是这么处理的——`.ux-summary > img` 把同一张图裁成 `width:62%; height:220%; right:-12%; top:-60%`、`opacity:.2` 挂在焦点面板的一角,被 `overflow:hidden` 切掉三分之二。**有来由的纹理可以留,没来由的才要撤。** `spectrum.svg` 作为来源资产保留在包内(指纹见 PROVENANCE),本稿不落它 |
| 修正 4 | `⌕` 之类符号依赖字体,缺字变豆腐块 | 搜索镜等小图形全部 CSS 画(圆 + 旋转短杠),状态像同理,不引图标字体 |
| 修正 5 | 域内容是通用 CRUD,看不出这套系统在解决什么问题 | 每一页的文案都是这个域的事实;评审时不需要额外解释 |
---
## 8 · 本轮不做(明确划界)
| 项 | 原因 |
|---|---|
| 登录 / 认证页 | 品牌表达需要重新设计,表单保持安静。不直接复制参考包的后台摘要布局 |
| 监控 / 通知面 | 真实事件优先,摘要只显示可解释数字;不捏造 KPI |
| 窄屏与 200% 缩放逐页验收 | 设计稿只声明意图,未执行。本轮停在设计稿(§9),补验随落原型一起做 |
| 键盘全流程 / 读屏核验 | 同上。当前只做了语义化标记(`aria-current` / `aria-disabled` / `` 自证) |
| 76 个非原型工作区 | 落原型时继承同一套皮肤,抽样验收,不逐页定版 |
| 消费者端(小程序) | `SUR-02` 明确主张两面不必同一套皮肤。这一稿不碰 |
| 真实字体子集切分 | `workbench/` 阶段做,本稿用系统栈 |
---
### 3.6 · 为什么示例包统一、我们要这么多调整(第八轮附)
测量过,不是感觉。
**先否掉一个显然的解释**——「锁定不到位」被数据直接否掉:
| | 参考包 | 鼎味 |
|---|---|---|
| token 数 / 族数 | 80 / 18 | **97 / 27** |
| 组件层 CSS 行 | 824 | **1099** |
| 页面数 | 20 | 7 |
| 每页 class 共享率 | 19/20 页在 93–100% | 99 / 97 / 91 / 80 / **74** / 80 |
锁得更紧的是鼎味。共享率低的正好是**没有先例的那两页**(p4 核对影响 74%、p6 看板 80%)。
**真正的原因一:16/20 是同一个原型。**
参考包的 users/role/menu/dept/dict/post 是**同一个页面的不同列**——20 页是**实体的宽度**,不是**形状的深度**。
第二个页面直接继承第一个页面做过的每个决定,所以统一几乎白送。
鼎味 6 页是 **6 个形状**:焦点+任务线 / 事实格+七行台账 / 写前核对 / 周带+台账 / 看板 / 台账+筛选。
p4 和 p6 在参考包里**没有对应物**,继承不了任何决定。
**真正的原因二:这个税是拍板收的。**
参考包 42 个颜色 token(primitive 21 + surface 21),本质是一个**颜色系统**:
一个颜色、一条边、一个圆角、一层投影,**4 条不变量**。
鼎味因为「案板·切割线·计量·熟成」,加了**互斥材料律**:
三块结构面同温(R−B 锁在 15–17)、明度链单调、**边里无白无黑**、两层纹理改明度不改色相、8 态灰度可辨、数值唯一寄存器——约 9 条,**其中 5 条互相耦合**。
> **材料律是加法,也是乘法。** 耦合意味着不能逐条独立验证,校验成本按组合数走。
> 这就是「简单系统难做深、深系统难扩展」的来源。
对称性:**越具体的材料律,单组件越对,横向越难扩展。**
参考包用通用色阶 + 边框,扩展几乎免费,代价是没有一个元素让人记得住它卖什么。
鼎味要那一点,付的是每个新组件都要重新校准一次材料律。这笔账拍板时是知道的。
**可改进且没做的一条:**
p4 / p6 这种无先例的原型,应该**先拆成可复用模板再落地**,而不是每次现场发挥。
参考包是「一个形状 × 20 次」,鼎味是「6 个形状 × 各 1 次」——**n=1 没有回归测试**,这个差异就是复杂度本身。
### 3.7 · 载荷 —— 一格必须声明它装的是什么(第八轮·第二个模板)
上面那条「应该先拆成可复用模板」落地了。做法不是先设计,是**先把毛病数一遍**:
| 页 | 槽位 | 一格里塞着的类目 |
|----|------|------------------|
| p1 | `taskline__sub` | 时点 · 状态 |
| p2 | `ledger__second` | 坐标 · 计数 · 计量 |
| p3 | `td` 内容 | 分割 · 配菜 |
| p4 | `review dd` | 计量 · 状态 · 时点 |
| p5 | `ledger__second` | 坐标 · 计数 · 计量 |
| p6 | `task__items` | 做法 · 计量 |
**六页里五页中招。** 共性只有一条:**一格灰色小字里塞着两三种不同类目的东西,
没有一种被声明过。** 数出来是 5/6,这就不是巧合,是一个类型。
规则一句话:**一格载荷必须声明它装的是什么类目。类目决定排版。**
落成 13 个类:`.chop` / `.chop__kg`(分割,ink + 计量)· `.veg` / `.veg__kg`(配菜,meta + 计量)
· `.dish`(菜名)· `.prep`(做法)· `.at`(时点,等宽 + tabular)· `.count`(计数,等宽 + tabular)
· `.qty`(计量,等宽 + 计量栈)· `.ref`(坐标,等宽 + 坐标字距)· `.blocked`(阻断事实)
· `.joiner`(类目分隔点)· `.qual`(限定语)。
**这不是一套新样式,是把稿里早就有的那一套内容级差用在该用的地方。**
拆开之后重量那一项自己站到最重的位置——不需要额外强调,
因为「11.4 斤」本来就比「5 项」重要。
**反例也是规则的一部分:类目说不出来的时候,不要把它塞进某一类。**
p1 三个 `taskline__sub` 里有两格是单条说明(「结果未知时保留额度,先查询,不重复发起」),
拆不开,也**不应该**拆——给它套一个 `.prep` 或 `.qual` 是撒谎。
所以 39 格里 37 格定型,2 格有意留白,**定型率 95%,缺的 2 格是判断不是遗漏**。
**这个模板是被自己的验证抓出来一次漏网的。**
按类名 grep 出来 6 页全有覆盖,但按格子数对一遍,发现 p3 的 3 个 `taskline__sub`
和 p1 已定型的那一个**是同一个形状**(「人名 · 时点 · 一句说明」),当时没被扫到。
两条数不一致,才把它翻出来。
**一条写下来但不量的规矩,实际只会被应用到 5/6 的地方。**
**可证伪的那一项,失败了,如实记:**
上一轮说「p4 74% / p6 80% 的共用率会动」。抽完模板重测,**一格没动**:
| | p1 | p2 | p3 | p4 | p5 | p6 | 合计 |
|---|---|---|---|---|---|---|---|
| 上一轮 | 97% | 92% | 88% | 74% | 99% | 80% | 89% |
| 抽之后 | 97% | 92% | 89% | **72%** | 99% | **78%** | 89% |
**这个指标量错了东西。** 它给「类名的继承度」打分,而模板的活儿是给**格子**定型:
`.qual` 只出现在 p4,可它恰恰是模板的成果——下一格有了先例,不是发明。
新加的 13 个类名按定义就只出现在部分页上,所以各页的私有词表变长,共用率必然不涨甚至微降。
p4 74→72、p6 80→78 的那两格,是这个口径的必然结果,不是模板没起作用。
真正该记的数字是上面那个:**39 格载荷槽,37 格有声明**,
以及跨页对比度 28 个格子实例全部 ≥ 4.5:1(最差 10.49:1,p6 泳道底)。
**这一条由眼睛判,不由参数判。** 同一格里并排放着「5 项」和「11.4 斤」,
问:眼睛先落在哪个上。**答:11.4 斤。**
这就是「类目决定排版」要的那件事——重量没有获得任何额外强调,
它只是被放进了计量那一类,于是自动继承了计量该有的最深一档墨。
**如果不成立,说明类目表还差一条没说清的规则**,模板也就没有真的抽象出来。
判据就这一句,写在这里,下次改动之后重新问一遍。
**剩下的债,说清楚:13 个类目里 4 个仍然只有 1 处先例**
(`.dish` / `.prep` / `.blocked` / `.qual`)——**n=1 又回来了,只是搬到了载荷层**。
下一处用到它们时仍然没有回归测试。这是本轮明确没有解决的。
### 3.8 · 深度与标尺 —— 第九轮
**来由是一句判断**:「没什么特别艳的,但也没什么特别的,第一眼给我的感觉十分平庸」。
不艳是拍板要的(§3.5 已经把「比较高级的表达」查过一遍),所以「不特别」不能靠加色解决。
这一轮先去找平庸**长在哪儿**,找到两处,都是结构问题,不是颜色问题。
#### 一、全稿只有一级深度
拆灯那一轮落下一句规则:**「深度由线给出,不由光给出」**。
这句话对了一半。线给的是**界**,不是**层**——1px 实边加 1px 内浅能告诉你哪里是边界,
永远告诉不了你哪块东西离眼睛更近。查了一遍 `box-shadow`,全目录只有一支 `--dw-edge`,
四个抬起的面(周带 / 台账 / 事实栏 / 看板列)全都用它,**平得像一张线框图**。
线框加一层端纹,仍然是线框——材质救不了结构。
所以:**线全留(它是清晰),补一档投影(它是层)**。三级,一套边法:
| 级 | 面 | 影 | 是什么 |
|---|---|---|---|
| L0 | 案板 | 无 | 原物。其余都压在它上面 |
| L1 | 铺面(刮面、卡片、台账、周带、看板列) | `0 1px 1px rgb(0 0 0/.05)` | 塑料片贴板,影展不开 |
| L2 | 案面(焦点井) | `0 2px 6px -2px rgb(0 0 0/.11)` | 洞口。全稿唯一一块 L2 |
外加一道:轨是框、板是嵌在框里的原物,所以 `.rail` 往板上投 `6px 0 12px -6px rgb(0 0 0/.22)`。
再宽就变成浮起来的抽屉。
**投影一律中性黑**,因为黑没有色相,落在暖底上只降明度。实测铺面影压过 `#F2ECE2` 之后
C 由 16 降到 15.2、R−B 由 16 到 15.2——是阴影本来就该有的那点去饱和,不是欠的色债。
这条和 `--dw-fibre-tint` / `--dw-wave-tint` 是同一个判据的第三次应用。
#### 二、四个计量是通用后台的默认长相
焦点井里那四个数,原来的排法是 `repeat(4, 1fr)` 等宽格子,标签/数字/来源三行四列。
**每一个 SaaS 首页都有这么一行**,所以它越长,这页越平庸——这一行是「平庸」的元凶,
材质和影都改不了它。
换个读法。这四个数在页里的角色不是「值」,是**指针**(INV-CC-01:必须能一路点到
那一条具体记录)。指针该被标成像指针,不该被排成会计栏。
改成一把**标尺**:一条贯通的基准线,四个刻度立在上面,高度递减 24/16/12/9px,
用 `--dw-cut-on-shadow-emphasis`(两像素宽——正好是那支色该在的地方,判据见 §4)。
递减由「有多急」排到「只是挂着」,对上 阻断→待办→待核→暂留。
**递减是固定节奏,不是数据**,已在 core.css 里写死,别以后有人拿它做比较。
窄屏退成 2×2 再退成 1 列,但基准线始终是同一条,刻度仍立在各自的线上——
退的是每行几个,不是这把尺的读法。560px 那一档它变成一把**竖着的尺**。
p5 上第三格是「未单列」(衬线体)。这是意外,也是对的:标尺里空一格,
读出来正好是「这一格没量」。
#### 这一轮改了什么、没改什么
改:深度三级(`--dw-edge` 加一档影,新增 `--dw-lay-blade` / `--dw-edge-deep` / `.rail` 投影)、
焦点井计量行(网格 → 标尺)、DIRECTION.md 里一张被 `#C79A5E` 段落截断的表(顺手接好)。
没改:轨、顶栏、页签条、常数条、注解栏、周带、其余五类原型。卡面、焦点井、轨、注解栏
一律不沾端纹——**满铺的材质一定是花纹,锚定的材质才还是材质**(§3.1)。
校验:7 页 × 4 断点,0 溢出、0 空 token、96 声明 / 96 引用 / 0 死 token、0 JS 错误。
## 9 · 本轮范围:停在设计稿
**已拍板:只停在设计稿,不改 `workbench/`。** 这一条覆盖了此前"拍板之后再改原型"的流程安排。
原因是治理链,不是工作量:
- `docs/design/DESIGN.md@v0.3.0` 的状态是 **provisional**,它自己写着
「不得作为已发布 Foundation 锁定新 UI REQ」。
- `requirement-funnel` 步骤 0.5(b) 要求 **F0–F6 Foundation 先发布**,
才能锁定 Core / Extended 层的 UI REQ。
- 也就是说:现在动 `workbench/` 等于绕过发布门禁直接改产品代码。
Loop 停在 S0、`bound_req: null`、`DEBT-CC-01` 挂着,正是这个状态该有的样子。
**本轮实际改动范围**:`study-20260929/` 目录内的 9 个文件
(`tokens.css` / `core.css` / `index.html` / p1–p6 / 本文件)。
`workbench/` 全程零改动,已核验:目录无 modified 记录,全库无 `--dw-*` token 混入。
---
## 10 · 落到真实原型:路径与前置(尚未启动)
路径本身没有变,变的是它前面多了一道门。按下面走,每步可独立回退:
1. **发布 Foundation F0–F6** —— 解掉 `DESIGN.md` 的 provisional 状态。
这一步不做,下面全部不能开始。
2. **走 `requirement-funnel` 锁定一条 UI REQ** —— 覆盖 Core / Extended 层的视觉层改造。
3. **搬 token 层** —— `tokens.css` 并入 `workbench/tokens.css`,但**保留**现有
`--color-*` / `--ops-*` 作为过渡别名,避免 82 个工作区的既有类名一次性全断。
命名仍限制在 `surface.* / content.* / measure.* / cut.* / action.* / status.* / brand.*`。
4. **换共享组件层** —— `core.css` 覆盖 `workbench/workbench.css` 的壳、台账、表单三段。
**熟度刻度**替换旧状态像是唯一影响既有标记的改动,需要逐 class 核对。
5. **补数字语言** —— 金额 / 重量 / 计数 / 行序走 `--dw-font-measure` + `tabular-nums`,
全精度带单位。这是现状诊断 D2 说的"全站没有数字语言",也是改动量最大的一块。
6. **六类页面定版,其余 76 个继承皮肤** —— p1–p6 落到对应工作区路由,
其余按分组抽样验收,不逐页定版。
7. **浏览器核验 + 存证** —— 截图存 `proof/`,与现有 `proof/visual-20260929/` 并排可比。
**本轮未覆盖**(沿用第 8 节):登录/认证页、监控/通知面、200% 缩放与窄屏逐页验收、
键盘全流程、读屏核验。这几项在设计稿里只声明了意图,没有执行,也不假装做过。