v15-before-after.md 11 KB

v15 报告:按 dr6 + dr1 重构工作台视觉

任务书:TASK-v15-bento.md。本页数字全部来自 scripts/verify-v15.mjs 与 scripts/verify-visual-v12.mjs 的实测输出, 没有手填。截图:docs/v15-before-desktop.png(旧版)、docs/v15-after-desktop.png、docs/v15-after-mobile.png。

0. 先看图(没做到 vision_analyze,用 Read 直接看)

本轮环境里没有 vision_analyze,用 Read 直接看了 refs/dr6.png 与 refs/dr1.png。看清的结构:

  • dr6:12 栅格 Bento;一行四张短数据卡(标签 / 大数字 / 一行说明);整页浅色只有一块深色卡(右侧 Time Tracker); 强调色只有一种,只出现在进度、关键数字和一个按钮上;其余全是灰阶。
  • dr1:单色(森林绿)+ 大量留白;数据卡「标签 + 大数字 + 一行说明」;状态用色点 / 标签,不用整块色底;右侧一块深色「Onboarding Task」卡。
  • 两者共同的骨架是:浅底 → 一块深卡锚注意力 → 一排短数据卡 → 内容块。本轮照这个骨架重排工作台。

1. 改前 / 改后(verify-v15:桌面 1440,确定性数据)

「确定性数据」= 同一份页面数据,但卡池只取前 5 张(改前快照里有 5 张)——状态 / 进程数随时间漂,直接对比两张时间点不同��页面不公平。 基线用 git archive e2eb778 导出旧代码单独起服务测量,代码指纹:改前 view-workbench.js sha1 e8a2dac26a26,改后见每次运行的头部输出。

项 改前 改后 要求
A / B 列宽 左卡 50% / 右卡 50%(1.2fr 1fr 两栏) 8 : 4(744px : 360px) A 8 列、B 4 列
A / B 高度差 同高(两栏 stretch) 0px ≤2px
B 卡底色 粉红整块(tone-danger 6% 染底) 亮度 0.009(rgb(24,24,27)) <0.35
B 卡最差对比度 —(粉底黑字,无深卡) 8.6 : 1 ≥7
C/D/E 四张 KPI 卡 + sparkline,高 77px 三张短卡,高 194 / 194 / 194,差 0px ≤2px
区块间距(主列相邻块) -16 / 24 / 12 / 12 / 0 32 / 32 / 32 / 47(页头→Bento 32;三行之间 32;Bento→页脚含分隔线 47) 区块 32
卡片内边距 16px × 6 20px × 8 20
字号档 6 档:11 / 13 / 14 / 16 / 20 / 32(11px × 82) 5 档:12 / 14 / 16 / 20 / 32(无 11px) ≤5 档、无 11px
kf-spark 残留 工作台 4 个 工作台 0,全站 0 0
普通卡片 backdrop-filter(四页) 11 / 12 / 42 / 26 0 / 0 / 0 / 6(/reports 的 6 个全是打开着的筛选下拉 .panel,属于浮层) 普通卡片 0
普通卡片 box-shadow(四页) 13 / 14 / 44 / 27 1 / 1 / 1 / 6(1 = 隐藏且转换的侧滑抽屉,页面上不可见) 普通卡片无阴影
空态:未选身份 左卡换全员进度(v12 已做) 保留;A 卡 363px,五阶段全员数据 实测
空态:本月无成果 有「本月还没有你的成果」 保留;A 卡 561px,C 卡「我的环节 —」 实测
空态:没人卡住 粉红卡 + 「大家都在动」 仍深底,绿点 + 正向文案;A/B 同高 381 / 381 实测
移动端 393 无溢出 scrollWidth 393 = clientWidth 393;A/B 上下堆叠;C/D/E 一行三张等高;字号 5 档 无溢出、竖排
v12 视觉回归 11/13 9/13 见 §5,两项均为 P3 的误报

2. 结构:A / B / C·D·E / F

┌───────────────────────────────┬──────────────┐
│ A 我的推进(8 列,浅)          │ B 现场(4 列,深)│
│ 身份 + 五阶段               │ 1 人卡住 + 名单  │
│ 卡池进度 | 待评分 | 队友动态   │ 各阶段已交        │
├──────────┬──────────┬─────────┴──────────────┤
│ C 卡池    │ D 最高分   │ E 我的环节                │   ← 三张近方形短卡
├──────────┴──────────┴────────────────────────┤
│ F 最近动过:左 2 张机会卡 + 右「最近动过」时间线     │
└──────────────────────────────────────────────┘
  • A:阶段格加阶段名;下半拆分「卡池进度 / 待评分 / 队友动态(没卡住但空闲最久的人)」。所有数据来自现有 core,无新算���。
  • B:kf-glass-card dark(新增变体),--kf-ink 底 + 反白。有卡住的人 → 橙点 + 大数字 + 名单;没有 → 绿点 + 正向文案。 下方「各阶段已交」在两种状态下都渲染(有数据就画)。
  • C/D/E:标签 → 大数字 → 一行说明。C 卡上是全页唯一的强调色实心元素(「全部 →」按钮)。 原来的「已决策」和 A 卡卡池进度重复,换成「我的环节」(最近一条成果落在哪个阶段)—— 更像「我」的推进,不再是管理员视角的汇总。
  • F:两张「安静」机会卡(playCard:是什么 / 三个数 / 快捷决策)+ 右侧「最近动过」时间线(5 条)。 点卡打开 app 统一的机会卡抽屉(决策 / 多人评分 / 来源 / 关联报告),和卡池里点开是同一个。

3. 去玻璃(kf-glass-card 与全站卡片)

  • .kf-card / .kf-glass:实底 #fff + 1px rgba(0,0,0,.06) 描边 + 无阴影;不再有 backdrop-filter、半透明白面、顶部白斑。
  • 只有 浮层允许模糊与阴影:div.panel.kf-glass.is-overlay(筛选下拉)、kf-drawer、kf-filter-sheet、kf-toast。顶栏与侧栏改成实底白 + 发丝线(常驻首屏,稳定比「透」重要)。
  • 状态色(tone)只改 1px 描边,不再给卡片裹一层 6% 染底。
  • 页面背景:去掉了彩色光斑(卡片实底后,玻璃后面的色斑只剩「页面上乱飘的色块」),改中性灰白 #EFF0F3 + 左上角一缕极淡白光。

4. 顺带修掉的问题(都不在任务书字面上,但不修页面就是错的)

  1. 卡片高度约定(P3 的根因):kf-glass-card 总是 height:100%,一行里最高的卡会把同排所有卡的内容「拉散」(43px 空档)。 新增 fill-to 属性:默认卡面按内容收缩,只有需要等高铺满的调用方(A/B/C/D/E、卡池/报告卡)显式开启。
  2. 入场动画可能把内容永久停在 opacity:0:kf-app 只在 IntersectionObserver 回调里放行 .kf-enter[data-enter=pending], 观察器漏掉的块(不在首屏、之后又没滚进视口)就永远不可见(实测:工作台底行整块消失)。加 1.2s 兜底释放。
  3. 工作台机会卡点开没有反应:kf-app 刷新视图时会把 _drawer 清空;工作台自己再挂一个 kf-drawer 会和它打架(两套抽屉)。改为走 opportunity-open → app 统一抽屉。
  4. forMe 未选身份时没有 pendingScores:工作台展开它直接 TypeError(整页空白)。已修。
  5. 报告中心类型卡:字号上调后「最多 N 份」被挤成竖条、来源行压扁;改成阶段条独占一行、标签右上角、来源行贴底。

5. v12 回归:11/13 → 9/13,两项都是 P3 的误报

检查 改前 改后 说明
字号档 ≤5 ✗ 7 档 ✓ 5 档(12×999 / 14×131 / 16×157 / 20×54 / 32×9) 本轮唯一提升的项
同排卡片高度差 ✓ 0 ✓ 0
可点元素 hover 反馈 ✓ ✓ 显式换底色(/ 上 37 个可见)
P1 筛选栏 ✓ ✓
P2 来源/操作条底边 ✓ ✓
底部空白 ✓ ✓
圆角 / 原生控件 / 描边 / 纯黑 ✓ ✓
P3:工作台两栏等高 + 左卡连续空白 ≤32px ✓(两栏 271/271,空白 0px) ✗(两栏 363/363,差 0,空白 56px) 误报,见下

P3 为什么判失败,以及为什么我没有为它硬改:

  • 旧版能过 0px,是因为旧左卡没有被人为拉高:右卡只有 271px。现在右卡(B,深)多了一块「各阶段已交」(5 行),行高变成 363px; 左卡被拉高 90px,多出的空间必然出现在某处。
  • v12 的空白算法只取「有自己的文字节点」的叶子元素(.stg 这类只装子元素的容器被跳过), 所以它看到的是「阶段格里的阶段名 → 卡池进度」这一段竖线空白 —— 那一段上方是整行阶段格(有徽标、数值、进度条),并不是空白。
  • 我试过的「硬凑」:把阶段格撑满、把下半区贴底、把行距压到 0 —— 都只能把 56px 挪个位置,要么让阶段格内部空 3/4,要么让卡片中段出现更大的洞; 任何一个都更难看,所以没有提交。
  • 结论:不达标。如果判定以这个数为准,需要的结果是「A 卡内不要有任何 32px 以上的竖直空隙」, 在当前数据(我的成果 2 份、五阶段只填了 1 格)下,只能靠往卡片里塞与「我的推进」无关的内容去填满,我没做。

6. 没做到 / 打了折的

  1. vision_analyze 不存在:用 Read 看图(见 §0)。
  2. 「像不像一个时代」:这一条只能主观判断。我的判断是:骨架(Bento + 浅底深卡 + 一排短卡 + 灰阶为主、强调色只在一个按钮) 已经和 dr6/dr1 同一套语言;页面的「现代感」差距主要在字体(只有 Inter latin 子集,中文走系统雅黑)和内容密度上,本轮没有动字体。
  3. P3 连续空白 56px 未达标(见 §5)。
  4. A 卡「待评分」的说明行:「候选卡里还没有你打分的卡,按最近上传排」——这行只在 me.pendingScores 有数据时显示, 文案是固定说明排序口径,不是编造数据。
  5. B 卡「各阶段已交」:为了让 B 卡与 A 卡同高、并且深卡里不是一块空黑,加了这块内容;它属于「现场」的合理范围(每阶段的在册人数), 但确实是为了视觉平衡新增的信息,如实记录。
  6. --kf-accent 使用面:只用在 C 卡的「全部」按钮、链接/评分数字(沿用既有语义),没有新增强调色用法;导航品牌块仍是强调色实底(沿用 v10 的既有做法)。

7. 提交

969795b feat(v15): 工作台 Bento 骨架 A/B → C/D/E → F + 深色卡 + 内边距 20 + verify-v15 测量脚本
1f5f7dd feat(v15): 去玻璃 —— 普通卡片/面板实底+1px 极浅描边+无阴影,只有浮层保留模糊与阴影
3cb0950 feat(v15): 中性灰白底 + 实底按钮/侧栏/顶栏 + A 卡填满 8 列 + 移动端 393 适配
56dffac feat(v15): kf-glass-card 加 fill-to(卡面按内容收缩,A/B 显式铺满同高);B 卡补各阶段已交;A 卡填满 8 列
41db7ac feat(v15): 字号收敛到 5 档(11/13 → 12/14)+ 工作台底行 = 机会卡 + 时间线 + 卡片抽屉
be97bd6 fix(v15): 工作台卡片全貌改走 app 的统一抽屉……

复现:

node scripts/verify-v15.mjs --tag after --from worktree --json docs/v15-after.json
node scripts/verify-visual-v12.mjs --tag before
npm test          # 46/46
node scripts/verify-modules.mjs

verify-v15.mjs --from <rev> 会把该 revision 导出到临时目录并起自己的 server(git archive 不会带 lib/vendor,脚本会拷一份)再测。