本轮(v11c)没有改任何视觉参数。所有数字都是脚本实测(Chrome 153 headless,1440×960),复现命令在每节末尾。 上一轮只有
docs/v11b-audit.json,没有报告;本文补上,并标注哪些项在 v11c 重测过。
中英混排 U+2009 只在两处落,不做任何事后 DOM 改写:
| 落点 | 文件 | 管什么 |
|---|---|---|
| 数据边界 | src/services/board-service.js:61 cjkDeep(buildModel(...))(v11b 已有,未动) |
模型里所有字符串字段 |
| 渲染期 | 各模板字符串生成处调 t()(= src/pages/shared.js 的 cjkString),另有 src/core/kfs/util.js 的 fmtDate/fmtAgo/fmtAgoText 与 cjkSpace、src/core/taxonomy/taxonomy.js 的阶段 / 上传方式 label |
模板里临时拼的串:S4 ${name}、${n} 小时前、${n} 人评分、最多 ${n} 份、被 ${n} 处支撑 … |
v11c 本轮为 P0 做的改动(git diff 可查):
shared.js:导出 t;删掉渲染后遍历的 cjk(node)(已无调用方,留着会被下一轮误用)components/cjk.js:t() 的内部规则改为直接调 cjkString,与数据边界同一份 SKIP 规则core/kfs/util.js:fmtDate(…, true) / fmtAgo 在生成处走 cjkSpace;新增 fmtAgoText(卡住时长)core/taxonomy/taxonomy.js:STAGES 的 label、uploadMethodLabel('skill') 在生成处走 cjkSpacecore/library/reports.js:优先级筛选项 S 级、whenText 占位句core/opportunity/opportunity.js:排序标签 优先级 S→A→Bview-workbench、view-members、view-pool、view-ledger、view-reports、view-stages、view-report-type、view-report、filter-sheet、card-toolbar、kf-app、kf-nav、kf-opportunity-card、kf-score-panel、kf-badge 各自主持的静态文案逐个包 t() 或改到生成函数里kf-app.js:删掉抽屉正文的 requestAnimationFrame + createTreeWalker 事后改写(同类做法,一并移除)排查中修掉的两个真 bug(不是排版问题):
view-reports.js 里 c.types.map((t, i) => …) 的 t 把外层的 t() 遮蔽了 —— 运行时 t is not a function,/reports 整页白屏。已把回调参数改名 ty。view-members.js 的「卡住」时长原来是 ${m.stuckHours}h(「卡住 52h」,纯英制混排),且 stuckHours 在 lastActiveAt 缺失(老数据按会话 createdAt 算)时是 0。改为从模型 stuckHours + 模型自带的 db.now 反推时刻、经 fmtAgoText 生成「62 个小时」/「2 天前」——数字仍来自模型,不从 Date.now() 现算。仍保留的定时器:kf-app.js:79 的 setInterval(refreshMs) 是 v10 就有的数据轮询(boardService.load),不是全页 DOM 扫描,按任务书不在移除之列。MutationObserver、window.__kfCjk 全局挂载:grep 0 处(只剩注释里说明「为什么不用」)。
| 项 | 实测值 | 达标线 | 通过 |
|---|---|---|---|
| 工作台 U+2009 | 61 | ≥ 20 | ✓ |
| 8 路由合计 U+2009 | 679 | ≥ 500 | ✓ |
| 汉字↔拉丁间普通空格残留 | 0 | = 0 | ✓ |
S4 机会验证评估 第 3 位字符码 |
8201 | 8201 | ✓ |
node scripts/check.mjs |
CHECK OK | CHECK OK | ✓ |
node --test 'test/*.test.js' |
46 pass / 0 fail | 46/46 | ✓ |
| 32px 行盒(加 trim) | 23.28px | ≤ 26px | ✓ |
| 12px / 20px 行盒 | 8.73 / 14.55px | 同比例 | ✓ |
| 微图表四类出现数 | spark 10 · 环 71 · 对比条 6 · 热力格 5 | 各 ≥ 1 | ✓ |
| 版式距离档数 | 4(8/12/16/24 在版式层;区块间 48 在令牌) | ≤ 4 | ✓ |
| 卡面撑高留白 > 24px | 0 处 | 0 | ✓ |
transition: all |
源码 0 · 运行时 0 | 0 | ✓ |
max-height:999px |
0 | 0 | ✓ |
| hover | translateY(-1px),150ms |
≤ 2px,无放大 | ✓ |
| 数字滚动 | kf-roll 650ms cubic-bezier(.4,0,.2,1),1284→1301 只滚 2 位 |
500–750ms | ✓ |
| 进场错峰 | calc(var(--i) * 40ms),400ms |
400ms / 40ms | ✓ |
| reduced-motion | 过渡时长 1e-05s |
≈ 0 | ✓ |
逐路由 U+2009(node scripts/verify-cjk.mjs):
/ 可见文本节点 143 · U+2009 61 · 普通空格残留 0
/pool 可见文本节点 368 · U+2009 166 · 普通空格残留 0
/stages 可见文本节点 555 · U+2009 100 · 普通空格残留 0
/reports 可见文本节点 337 · U+2009 64 · 普通空格残留 0
/reports/competitor 可见文本节点 302 · U+2009 41 · 普通空格残留 0
/reports/voc 可见文本节点 282 · U+2009 53 · 普通空格残留 0
/members 可见文本节点 176 · U+2009 37 · 普通空格残留 0
/ledger 可见文本节点 436 · U+2009 157 · 普通空格残留 0
S4 机会验证评估 · 13 条 → [83, 52, 8201, …, 49, 51, 8201, 26465](S4 后、13 后都是 8201)。
复现:node scripts/verify-cjk.mjs、node scripts/verify-textbox.mjs、node scripts/check.mjs、node --test 'test/*.test.js'、node scripts/verify-viz.mjs、node scripts/audit-examples.mjs --json docs/v11b-audit.json、node scripts/audit-spacing.mjs
单测改了两行期望值(与行为变更同源,不是放宽门槛):test/report.test.js:83 fmtAgo 的 3 小时前 → 3 小时前;test/model.test.js:78 阶段 label S4 机会验证评估 → S4 机会验证评估。两项都是「生成处插 U+2009」的直接后果。
node scripts/verify-textbox.mjs)inline-block,line-height: 1,文本「1284」:
| 字号 | 不加 trim | 加独立长属性(trim-both / cap alphabetic) | 变化 | 行盒 / 字号 |
|---|---|---|---|---|
| 12px 正文 | 12.00px | 8.73px | -27.2% | 1.00em → 0.73em |
| 20px 小标题 | 20.00px | 14.55px | -27.3% | 1.00em → 0.73em |
| 32px 主数值 | 32.00px | 23.28px | -27.2% | 1.00em → 0.73em |
关键细节(代码里保留了注释):
display:flex 容器里的 trim 不生效:对照实验 32px + trim-both 但容器 flex → computed 仍是 trim-both,行盒实测 32.00px。值容器必须 display:block + height:max-content。text-box:Chrome 153 丢弃简写,只认 text-box-trim / text-box-edge 两个长属性。A 级 徽标 24px 均为 trim 后的 cap 高。node scripts/verify-viz.mjs)计数为 7 个路由合计。每类都满足:数字在图表旁(图表本身 aria-hidden,读屏读数字)、纯 CSS/SVG、无渐变填充、无第三方库。
| 类型 | 出现位置 | DOM 计数 | 规格实测 |
|---|---|---|---|
| sparkline | 工作台 KPI 卡(4 个数字卡右下角,view-workbench.js .kpi kf-spark,7 日趋势);报告中心 5 张类型片的「份数」右侧(view-reports.js:151);报告类型页「份数」KPI(view-report-type.js:253) |
10 | 56×16px,历史柱 .35 / 最新 .95 |
| 进度环 / 进度条 | 环:五阶段页每张阶段卡的「份数」环(view-stages.js:108,40px);报告类型页 4 个 KPI 环;机会卡评分面板平均分环(kf-score-panel.js:89,44px);报告卡 mini 环(report-card.js .rc .ring)。条:五阶段页每卡占比条 .ov .bar 与混合条 .ov .mix(view-stages.js:63-65) |
71(环) | 环 40–44px 描边 3px;条高 4px 圆角 2px 单色;环心 / 左侧印数字 |
| 对比条 | 报告中心「分类」区块 5 张类型片各自的 S1–S5 份数分布(view-reports.js:153 kf-bars stack);成员页「成员产出对比」前 8 位(view-members.js:91) |
6 | 最大值占满 100%,数字右对齐(最多 N 份) |
| 热力小格 | 台账页「阶段 × 层交叉分布」(view-ledger.js:178,5 行 × 若干列,每行右侧小计);台账 bar2(view-ledger.js:88)里横向的成员活跃度小格 |
5 | 12px 方形,圆角 2px,4 档不透明度 |
截图:docs/screenshots/v11b/viz-*.png。
src/styles/tokens.js 的 --kf-space-card / --kf-space-in / --kf-space-card-gap / --kf-space-section)。node scripts/audit-spacing.mjs:版式层实测值 8px×2、12px×2、16px×22、24px×4 —— 4 种(报警线 > 6),四档外 0 种。48 用在区块之间(.p-sec margin)。docs/screenshots/v11b/spacing-25-*.png(7 页),块与块之间的缝肉眼可分出层级。forMe,有数据放阶段完成度,.grid2 { align-items: start } + .grid2 > kf-glass-card { align-self: start }(view-workbench.js:40,42),卡收缩到内容高。audit-spacing.mjs 的「撑高留白」):卡面内容外空白 > 24px 的 0 处(.grid2 上一轮 220px 的问题已不在)。口径:可见文本节点里的中文字符 + 中文标点([一-龥 -〿-],即汉字、CJK 标点、全角符号),排除 SVG 内文本(textNodesIn 本来只收 HTML 文本节点,且跳过 svg 子树)、aria-label(属性不算文本节点)、隐藏元素(用与 verify-cjk 相同的 visible 判定),另排除含 URL / 文件名的节点;页外的导航与顶栏不计。
| 页面 | 上限 | 实测 | 通过 |
|---|---|---|---|
工作台 / |
350 | 422 | ✗ |
报告类型页 /reports/voc |
300 | 780 | ✗ |
报告中心 /reports |
200 | 818 | ✗ |
(参考:/stages 1676、/pool 1190、/ledger 786、/members 293,这三页任务书没给上限。)
未达成:三页都超。工作台超 72;报告中心 / 类型页超得多,是因为卡片自带来源行(谁 · Agent · 方式 · 时间)、筛选条、每个类型的阶段条旁都有文字。压缩到上限要删信息或改卡片结构,属于视觉改版,v11c 不做,如实列在这里。
docs/v11b-audit.md 第 3 条。verify-viz.mjs 的 KIND 只点了 spark / ring / bars / heat 四类,阶段卡上的 4px 进度条是 kf-bars 之外的 .ov .bar(纯 CSS),没有独立 DOM 计数;本文给的是源码位置,不是脚本数字。规格(高 4px / 圆角 2px)是源码读出来的。--h: 16px)。v11b 定的,本轮不改视觉,如实记录不一致。kf-app.js:79 的 setInterval 仍在(v10 起的数据刷新,不是全页扫描)。scripts/v11b-patch.mjs:文件仍在磁盘上(未删除),但源码里 0 处引用;按「我提交」的约定没动它,建议你提交前一并删掉。阶段 × 类型交叉:任务书写的热力格位置之一是「阶段 × 类型交叉」,落地的是「阶段 × 层」(台账页)。类型维度没有做热力格。