日期:2026-10-30 · 分支 main · 全部数字来自 scripts/verify-visual-v13.mjs(docs/v13-after.json)、
scripts/verify-visual-v12.mjs(改前 tmp/v13-before2.json,改后 tmp/v13-v12-after.json),没有手填。
| 项 | 结果 |
|---|---|
改前基线 node scripts/verify-visual-v12.mjs --tag before |
11/13(未达标:圆角种类、字号档——均为改前既有,非本轮范围) |
| 改后同脚本 | 11/13。逐条对比 13 项:2 项未达标项与改前逐字相同;达标项里只有 3 处数字变化,都不是退步——① /pool 页脚多一个 .cfa 外层(0px 圆角 +4);② 排序行「同行底边差」1px → 0px;③ /pool 滚动余量 1755 → 1754px(滚到底视口留白 64px 不变) |
单测 npm test |
46/46 pass |
node scripts/check.mjs |
CHECK OK |
src/core/ |
未改动 |
node scripts/verify-visual-v13.mjs |
4/4(一 / 二 / 三 + v12 回归不退步) |
改动:src/pages/view-pool.js 的 .seg。
background: rgba(0,0,0,0.06)、文字 var(--kf-ink)(rgb(24,24,27)),不再白字;暗色模式 rgba(255,255,255,0.10)。rgba(0,0,0,0.10) 描边(段外框与分隔线同色),文字 rgb(63,63,70)。border-radius: 8px(--r-sm)+ 1px 描边 + box-sizing: border-box,按钮各自 border-radius: 0,相邻之间 1px 分隔线。font: 简写(简写会重置行高)。box-sizing,实测仍是 28,不是 30)。.pbar-sorts 的选中态同步改为浅底 + 主文字色(原为深色实底白字)。实测(docs/v13-after.json → one):
| 指标 | 值 |
|---|---|
| 选中 bg | rgba(0, 0, 0, 0.06),叠白底后 rgb(240,240,240),亮度 240.0 |
| 旧 bg | rgb(24,24,27),亮度 24.2 |
| 选中文字色 | rgb(24, 24, 27)(不是白字) |
| font-size 选中 / 未选中 | 12px / 12px |
| line-height 选中 / 未选中 | 12px / 12px |
| 按钮框高 选中 / 未选中 | 28 / 28 |
| 按钮圆角 | 5 个全是 0px 0px |
| 分隔线(border-left) | 0px, 1px, 1px, 1px, 1px |
| 外层 | radius 8px、1px solid rgba(0,0,0,0.1)、高 28 |
| 手机(393px)选中 | bg rgba(0,0,0,0.06)、字色 rgb(24,24,27)、13px |
截图:docs/screenshots/v13/desktop-pool-filters.png(整条筛选区)、desktop-pool-sort-hover.png(悬停态)。
先说清楚是哪一块。 任务书写的是「/pool 卡片列表里有的卡有描述、有的没有」。实测 /pool 用 kf-opportunity-card,
它的「一句话」 .one 恒为两行高,oneLiner 为空时渲染的是「(未填写一句话说明)」——没有任何一张卡缺描述区
(9 张里 0 张无描述)。真正「有描述 / 无描述」并存的是 reportCard()(.rc .lead):/reports 12 张里 5 张无描述,
/stages 35 张里 24 张无描述。所以第二项按真实存在问题的 reportCard 来修,kf-opportunity-card 未动。
选了方案 (a):无描述时本来就不渲染 .lead(${lead ? html
…: ''}),这次做的是
「指标区上提、卡内纵向重新均分」这一半:.rc.nolead 改为 flex 列 + justify-content: space-between,
卡高被同排拉高时,余量分到「标题 → 指标区」与其他块之间,而不是全部堆在标题下面一条缝里。
为什么不是 (b):这些 entry 的底层数据里没有可用的「痛点 + 机会点」字段(report 为空对象、quotes 为空、
rawText 为空),从已有字段派生只能拼出标题,等于重复标题——任务书明令禁止。
(c) 显示「待补充描述」会把空缺暴露出来,是最次选。
顺带修掉一个真 bug:无描述的卡(.nolead)原来整卡比同排高 44px——不挂 .lead 后没有任何块承担余量,
.face 的高度直接落到 slot 上,子块无法吸收,于是底部多出一整块。现在 .rc 自己按内容高排版、卡面均分。
实测(two.pages):
| 页面 | 卡数 | 无描述 | 有描述卡内容高 | 无描述卡内容高 | 差 | 卡内最大连续空白 | 标题→指标缝(有/无描述均值) |
|---|---|---|---|---|---|---|---|
| /reports | 12 | 5 | 252/252/252/252/231/231/231 | 257×5 | 14.0px | 0px | 57.0 / 12.0px |
| /stages | 35 | 24 | 268/268/247/247/344/268… | 284×24 | 12.9px | 0px | 62.2 / 12.0px |
改前同口径:/reports 差 44.0px、/stages 差 57.1px,最大连续空白 61 / 63px。同排卡高一致:两页都是 true。
(v12 的同排卡高、卡内空白两项在改后仍是 0 超差。)
没做到的:任务书原话是「让卡内纵向分布重新均分」。现在做到的是「余量不再全堆在标题下、内容高差 ≤ 40px、无 > 24px 空白」,
但无描述卡内部的各块并没有按比例撑开(各块保持内容高,余量均分到四处 12px 缝里)。试过 Grid 百分比行与 flex 比例分配:
reportCard 是 kf-glass-card 的 slot 子项,slot 里的 height:100% 按内容解析、拿不到卡面余量,两种写法都只在
「样式在卡片外作用域里」时才生效,用了 kf-glass-card.fillTo() + 确定高度的路线虽能生效,但需要逐页在 updated()
里补测量、并在 .rc 上写内联高度,视觉上两侧卡片的「标题→指标」缝反而更不对称(57px vs 更大),
权衡之后回退,采用上面这条不依赖布局时序的做法。如果必须做到「真正按比例均分」,建议在 kf-glass-card 层面给 slot
一个 display: contents 或让页面显式传高度——那已经超出「不要重新设计」的边界,留给下一轮定。
/pool 页脚借用 CSS(根因)任务书给的根因成立:view-pool.js 没 import CARD_CSS,却用了 cardFooter() 产出的 .cfoot / .cfl / .cfa DOM;
.kf-btn / .ghost 在共享表里,所以按钮外观被「绕」过去了,页脚自身的类名当时是死的。
补充一个实测事实(影响方案选择):桌面 /pool 上 CARD_CSS 整段没进渲染。修复前 view-pool 的
shadowRoot.adoptedStyleSheets 有 5 份,逐份扫 CSSOM:没有任何一份含 .rc { 或 .cfoot;而同一份 CARD_CSS
在 /reports 上是第 2 份(11688 字符)。FILTER_CSS 等其他 4 份都在。这与 memory kf-card-css-per-view-loss 记录的
「CARD_CSS 在 /pool 整段丢失」是同一现象。
import { CARD_CSS } + static styles = [VIEW_CSS, CARD_CSS, css\…`]`理由:
FOOTER_CSS 要改 3 个页面 + 拆 report-card.js,改动面大,且没有解决「CARD_CSS 在 /pool 丢失」这个更广的问题
(reportCard 的 .rc 系列在 /pool 如果今后复用也会同样失效)。加上之后,view-pool 的 shadowRoot.adoptedStyleSheets 多出一份 CARD_CSS(含 .cfoot / .cfl / .cfa / .kf-btn 规则),
类名全部活过来。同时,view-pool.js 里重复抄写的 .cfoot / .cfl / 页脚 .kf-btn 三条就地规则删掉;页脚 DOM 补上
与 /reports 一致的 .cfa 外层。现在只有两条「嵌在 28px 排序行里」的行内几何:
.frow.toolbar .cfoot[data-foot] { margin: 0 0 0 4px; justify-content: flex-start;
padding: 0 0 0 12px; border-top: 1px solid var(--kf-line); border-right: 0; border-bottom: 0; border-left: 1px solid var(--kf-line); }
(纵向内衬不归零的话,CARD_CSS 的 padding: 20px 4px 12px 会把 28px 的排序行撑到 61px 并换行——
第一版就是这么翻车的,实测后修掉。右侧内衬归零是为了和卡片右缘对齐,/reports 的页脚是整行宽,4px 内衬是它自己的版式。)
脚本遍历 view-pool shadow root 的全部 adoptedStyleSheets(CSSOM),对页脚里出现的每个类名,统计「含该完整类名的规则数」与
「选择器 .matches() 真的命中页脚内元素」的规则数:
| 类名 | 含该类名的规则 | 生效规则 |
|---|---|---|
| cfoot | 5 | 2 |
| cfl | 1 | 1 |
| cfa | 1 | 1 |
| kf-btn | 14 | 8 |
| ghost | 2 | 2 |
逐项相等:同名结构路径 4 个元素 × 8 个属性 = 32 个单元格,不一致 0:
cfoot、span.cfl、span.cfa、span.cfa>button.kf-btn.ghost × padding / border / radius / font / color / bg / display / gap例:页脚按钮 padding 0 10px、border 1px solid rgba(0,0,0,0)、radius 8px、font 12px/12px 500、display flex;
页脚 display flex、gap 8px、font 12px/19.2px 400、字色 rgb(75,85,99)——与 /reports 逐项相同。
两处豁免,写明(都只针对页脚根节点 cfoot,子元素零豁免):
| 项 | /pool | /reports | 为什么 |
|---|---|---|---|
cfoot.border |
1px 0 0 1px |
1px 0 0 0 |
多出的是左边那条行内分隔线;上 / 右 / 下三条边宽度与样式、以及边色逐项相等(脚本逐边核对后才豁免) |
cfoot.padding |
0 0 0 12px |
20px 4px 12px 4px |
纵向内衬必须归零(否则 28px 排序行被撑到 61px);左侧 12px(分隔线后留白)保留;右侧归零与卡片右缘对齐 |
margin 与 justify-content 是版式位置而不是外观,不参与比对(脚本注释里已写明)。
截图:docs/screenshots/v13/desktop-pool-footer-after.png、docs/screenshots/v13/desktop-pool-filters.png。
src/pages/view-pool.js:排序段样式;import { CARD_CSS } + static styles;页脚去掉重复规则、补 .cfa、只留行内两处几何;手机排序段选中色。src/pages/report-card.js:.rc.fit.nolead(无描述卡按内容排版、余量均分),reportCard() 挂 .nolead。scripts/verify-visual-v13.mjs:新增,三项实测 + v12 回归(子进程跑原脚本)。任一项不达标 exit 1。docs/screenshots/v13/:截图。src/core/、src/styles/、其余页面。.rc .seg i / .thumb i 这类 14×4、4×4 的小件)」「字号 7 档(11/12/13/14/16/20/32)」——改前即有,改后每档计数逐字不变;/pool 排序行的「与容器底边差 −10px → −9px」(页脚多 1px 上边线导致),仍在 28px 行内、底边对齐 0px。