TASK-v11b.md 9.6 KB

康师傅看板 · v11 补齐轮(text-box / U+2009 / 微图表 / 间距与动效)

上一轮(v11)跑到 350 轮上限被中断,两个核心项写了但没生效。本轮只补没做完的部分,不重做已完成项。 已经确认 OK 的不要动:数字/单位分层(32px + 11px 灰 + 1.54px)、阴影 2 变体、1px 描边做进 shadow、46/46 单测、check.mjs 全绿。


一、P0-a:text-box 没生效,必须修到实测达标

现状(实测证据,不是猜测)

src/styles/tokens.js 与各组件里写的是:

.b { font-size: 32px; line-height: 1; text-box: trim-both cap alphabetic; }

浏览器 computed style 实测结果:

font-size: 32px
line-height: 32px
text-box: "cap alphabetic"     ← trim-both 被丢弃
getBoundingClientRect().height = 32.00px   ← 行盒完全没压缩

我在同一个浏览器里做的对照实验(证明浏览器支持,是写法问题)

探针:font-size:32px; line-height:1; display:inline-block
  不带 text-box               → height = 32.00px
  带 text-box:trim-both cap alphabetic → height = 23.28px   (-27.2%)

结论:这个 Chrome 版本支持 trimming,但不接受 text-box 简写里的 trim-both,必须改用两个独立长属性。

要求

改成独立属性,两个都要写:

text-box-trim: trim-both;
text-box-edge: cap alphabetic;

如果 text-box-trim / text-box-edge 也拿不到效果,再试 text-box: trim-both cap alphabetic 配合 @supports (text-box-trim: trim-both) 兜底,但首选独立属性。

兜底方案(只有前两种都失败才用):用负 margin 或 padding-block 补偿补偿法,把行盒视觉高度压到 cap 高,但必须在代码注释里写明「浏览器不支持 trimming,用 margin 补偿」。

验收(硬性,必须实测输出,不许估算)

写一个 Node + Playwright 脚本 scripts/verify-textbox.mjs,自起 dev server,量三处:

  1. .b 主数值(32px):输出 fontSize / lineHeight / computed text-box-trim / boxHeight
  2. 达标线:boxHeight <= 26px(32px 字号 cap 高约 23.3px,留 2.7px 余量)
  3. 若 boxHeight > 26px,脚本 exit 1 并在输出里指明失败项

另外报表里给出:12px 正文、20px 小标题、32px 主数值 三档在加/不加 trim 前后的行盒高度对比表(这是本轮要向客户交代的核心数据)。


二、P0-b:U+2009 中英混排没接到渲染路径

现状(实测证据)

src/utils/type.js 里已经写好:

export const THIN = '\u2009';   // U+2009 THIN SPACE
export function mixCJK(s) { ... }   // 汉字↔拉丁/数字两侧插 U+2009

但页面实测:

元素文本 "S4 机会验证评估 · 13 条"
字符码 83,52,32,26426,...   ← 位置 2 是 32(普通空格 U+0020),不是 8201
全页 U+2009 计数 = 0

函数写了,没人调用。 必须接到实际渲染路径上。

要求

找出所有渲染「中英混排字符串」的地方并接上 mixCJK()(或等价处理),至少覆盖:

  • 阶段标签(S1 市场分析、S4 机会验证评估 · 13 条)
  • 徽标(A级、高证据、S3 机会点识别)
  • 统计单位旁的数字短语(近 7 天、人均 2.5 份)
  • 报告标题中夹英文/数字的(如 20260420 CX 复盘)
  • 时间(6 小时前、40 小时)

规则(严格):

  • 只在「汉字 ↔ 拉丁字母/阿拉伯数字」交界两侧插 U+2009
  • 全角空格、普通空格都不许冒充
  • 连续数字整体算一个单位(20260420 内部不插)
  • 已有的中英文之间如果是普通空格,替换成 U+2009(不要留两个)
  • 不要在 <code>、URL、文件名、纯英文串里插

验收(硬性)

在 scripts/verify-textbox.mjs(或另起 verify-cjk.mjs)里:

  1. 遍历页面所有文本节点,统计 U+2009 数量 → 必须 > 0,且 ≥ 20 处(页面中英混排点很多,20 是下限)
  2. 抽 3 个具体元素,输出其 textContent 的完整字符码数组,证明交界处是 8201
  3. 反向检查:不该有 汉字与英文之间的普通空格残留(正则 [\u4e00-\u9fa5] [A-Za-z0-9] 命中数应为 0,或全部来自 <code>/URL 例外)
  4. 不达标 exit 1

三、P1:微图表只做了 sparkline,补齐四类

现状:kf-spark 组件 4 个,全是同一种折线/柱状火花线。

补齐,每类都要有真实出现位置(不是造组件放着):

类型 用在哪 规格
sparkline 已有 4 处保留 宽 64-80px,高 20px,历史柱 opacity .35,最新 .95
进度环 / 进度条 机会卡评分(76/80/81.3 分)、阶段完成度、证据强度 环 直径 40-48px,描边 3px,数值居中;条 高 4px,圆角 2px
对比条(条形对比) 报告类型的份数分布(品类1/竞品25/ VOC10/痛点9/概念0)、成员产出对比 横向条,最大值占满,其余按比例;数字右对齐
热力小格 阶段 × 类型 的交叉分布、成员活跃度 格子 12-14px 方形,圆角 2px,4 档不透明度

铁律(来自调研,必须遵守):

  • sparkline / 图不替代数字,数字始终在旁边(Tufte:Print the number it summarizes beside it)
  • 纯 CSS 或 SVG,不引第三方图表库(项目零构建约束)
  • 不用渐变色填充图表
  • 所有图表元素 aria-hidden="true",旁边配文字数字给读屏

验收:截图 + 在页面实测每种图表的 DOM 数量(各 ≥ 1),并说明每种出现在哪个页面哪个位置。


四、P1:间距分级 + 「我的推进」虚线框过高

4.1 间距分级(v11 未验证)

统一成四档,不许出现第四种间距值:

卡内 padding     16px
卡内 gap         12px
卡片之间         24px   ← 1.5×
区块之间         48px   ← 3×

自查方法:把页面缩到 25% 截图,所有留白宽度一样 → 均匀呼吸(模板感);能看到明确的「块」在呼吸 → 对了。

写个脚本统计页面所有 margin/gap 的构成值种类,> 6 种就报警(排除 0、auto、百分比、负数)。

4.2 「我的推进」虚线占位框过高(客户截图级问题)

实测:该卡片里虚线占位框占近半张卡高,信息密度低。

要求:

  • 虚线占位框降到内容需要的高度(不超过 2 行文字的视觉高度 + padding)
  • 卡内其余空间要么放真实数据(阶段完成度进度条),要么让卡片自身收缩(align-items: start 而非 stretch)
  • 检查全站还有没有同类「撑高留白」:上一轮同类 bug 是 .grid2 被 align-items:stretch 拉到 220px,内容只有 78px。全页面扫一遍,stretch 导致的空隙 > 24px 的都列出来并修掉

五、P1:动效(v11 未验证)

场景 要求 禁止
数字变化 只滚变化位(1284→1301 只滚十位个位),500-750ms,cubic-bezier(.4,0,.2,1) 从 0 滚到目标值(AI 味)
卡片 hover translateY(-1px),150ms scale(1.05) 放大
列表进场 400ms,错峰 40ms 所有元素同时淡入
展开收起 grid-template-rows: 0fr → 1fr max-height: 999px
全局 只写具体属性 transition: all
无障碍 @media (prefers-reduced-motion: reduce) 全部关掉 —

验收:grep 证明 transition: all 0 命中、max-height:999px 0 命中、scale(1.0[0-9]) hover 0 命中;实测一个数字变化动画的 duration 值在 500-750ms 之间。


六、P2:15 条反例逐条自查(逐条报告,不许略过)

逐条对照现有代码,每条给出「命中/未命中 + 证据(文件:行号)」:

  1. 装饰性渐变 / 渐变文字标题
  2. glow 光晕 / blob 色块 / 条纹纹理 / 网格背景
  3. 玻璃效果用在所有卡片上(玻璃只该用于浮层)
  4. 彩色左边框告警条
  5. emoji 当图标(应使用 SVG)
  6. max-height:999px 展开动画
  7. transition: all
  8. 阴影超过 3 档
  9. 纯 #000 / #FFF
  10. 所有间距都是同一个值(均匀呼吸)
  11. box-shadow 做凸起 / 凹陷(非克制的拟物)
  12. 加班式 hover:跳动 > 2px、放大
  13. 圆角 > 16px(大圆角廉价感)
  14. 强调色面积 > 5%
  15. 所有卡片同时入场无错峰

这一节的输出是本轮交付物的一部分,写在 docs/v11b-audit.md,逐条 1-15 编号。


七、字数要求(不许反弹)

页面 上限 v11 现状
工作台 350 字 95(v10 口径,需按同口径复核)
报告类型页 300 字 96
报告中心 200 字 38

口径统一:只统计可见文本节点的中文字符 + 中文标点,排除 SVG 内文本、aria-label、隐藏元素。脚本里写清算式,输出每个页面的数。


八、交付要求

  1. 每一条验收都必须是脚本实测输出,不许写「已完成」却没有数字
  2. 失败的项如实报告失败,不许调低门槛凑通过
  3. 输出 docs/v11b-report.md:
    • 逐项验收结果表(项 / 实测值 / 达标线 / 通过与否)
    • 三档 text-box 前后对比表
    • 15 条反例自查
    • 明确列出「我没做到的 / 做不到的」(例如浏览器不支持某项时要说清楚)
  4. 所有验证脚本提交到 scripts/,可重复运行
  5. 跑完 node scripts/check.mjs 与 node --test 'test/*.test.js' 必须全绿
  6. 不要 git commit,我会自己提交

九、边界

  • 不改数据层、不造数据
  • 不引第三方依赖(零构建约束)
  • 不动已达标项(数字单位分层、阴影 2 变体、1px 描边入 shadow)
  • 无凭据写入任何文件