# v13 收尾修复报告(三项) 日期: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)`。 - 未选中:透明底 + 1px `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:` 简写(简写会重置行高)。 - 段高 28px(加了 `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 整段丢失」是同一现象。 ### 所选方案:(A) 补 `import { CARD_CSS }` + `static styles = [VIEW_CSS, CARD_CSS, css\`…\`]` 理由: 1. 最小改动,且页脚与报告中心共用同一份规则,本来就该是「照着一份样式对齐」,而不是抄一份; 2. (B) 抽 `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 排序行里」的行内几何: ```css .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 内衬是它自己的版式。) ### 验证:类名逐项命中 + 与 /reports 同名元素逐项相等 脚本遍历 `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/`、其余页面。 ## 已知未修(不在本轮范围) - v12 的「圆角 2px×12(`.rc .seg i` / `.thumb i` 这类 14×4、4×4 的小件)」「字号 7 档(11/12/13/14/16/20/32)」——改前即有,改后每档计数逐字不变; - `/pool` 排序行的「与容器底边差 −10px → −9px」(页脚多 1px 上边线导致),仍在 28px 行内、底边对齐 0px。