Compare commits

...

2 Commits

Author SHA1 Message Date
wangjia 9b37568fdb ci: 设计真相源检查挂 CI(PR + main push 自动跑四道闸)
Design Source Checks / design-source (push) Successful in 16s
- 新增 tools/check-l1-sync.mjs:L1 同源四道——tokens 快照逐字节、icons
  两端同集同内容、官网 token 值对齐原型主题 A、web 硬编码 hex 扫描
  (白名单 #fff/#1677ff,ds-allow 可豁免);注入测试验证红绿行为
- 新增 .gitea/workflows/checks.yml:pull_request + push(main) 触发,
  串跑 check-ds 12 道 / check-l1-sync / check_ds_code / codegen 新鲜度
  (regen→dart format→零 diff,消除重跑假 diff 问题)
- 修复 web/checkout.njk 对公转账图标底色硬编码 #8A94A6 → var(--faint)
- CLAUDE.md「设计真相源分层」登记 CI 闸与本地等价命令

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-04 07:14:49 +08:00
wangjia e0fdb8c12f docs(design): 设计真相源分层治理落地(原型漂移拍板)
- CLAUDE.md 新增「设计真相源分层」强制规则:L1 设计系统层原型单源不变;
  L2 屏级三态(同步/快照/代码先行);L3 新屏仍 design-first;漂移改定期体检
- CONTRACT 块 4 加「真相源」列(14 屏同步 / register 快照),新增代码先行
  屏小节(授权管理面板/购买卡/官网 checkout 等,不反向补原型)
- screens.mjs 注释明确只登记「同步」态屏,与 CONTRACT 互为镜像
- 附带体检:golden 84 用例全绿(failures 264 张陈留物已清);
  fidelity 36 屏×主题全部阈内(≤8%);check-ds 12 道闸全过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-04 06:56:17 +08:00
6 changed files with 211 additions and 21 deletions
+39
View File
@@ -0,0 +1,39 @@
name: Design Source Checks
# 设计真相源检查(治理规则见 CLAUDE.md「设计真相源分层」):
# PR 与合并 main 时自动跑四道闸,全部纯静态检查(node + dart format),
# 不跑 golden/fidelity(重型像素闸维持「定期体检」定位,本地手动跑)。
on:
pull_request:
push:
branches: [main]
concurrency:
group: checks-${{ gitea.ref }}
cancel-in-progress: true
jobs:
design-source:
runs-on: mac
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: 原型设计系统闸(check-ds 12 道)
run: node .superpowers/prototype/tools/check-ds.mjs
- name: L1 真相源同源闸(tokens 快照 / icons / 官网 token 值 / web hex
run: node tools/check-l1-sync.mjs
- name: Flutter 颜色单源闸(check_ds_code
run: node client/tool/check_ds_code.mjs
- name: token codegen 新鲜度(regen → format → 与入库产物零 diff
run: |
cd client
node tool/gen_tokens.mjs
dart format lib/core/theme/app_tokens.g.dart lib/core/theme/app_dims.g.dart lib/core/theme/app_chrome.g.dart
git diff --exit-code -- lib/core/theme/app_tokens.g.dart lib/core/theme/app_dims.g.dart lib/core/theme/app_chrome.g.dart
+13
View File
@@ -254,6 +254,19 @@ cd client && flutter test
- 使用 `dart:io``Platform` 类前,必须先检查 `kIsWeb``import 'package:flutter/foundation.dart'`
- Web 平台不支持 `dart:io`,直接使用会在 Web 构建时崩溃
### 设计真相源分层(原型漂移治理,2026-07-04 拍板)
原型(`.superpowers/prototype/`)与真实页面**不追求全量永久同步**,按层分治:
- **L1 设计系统层**`tokens.css` / `atoms.css` / `mobile-atoms.css` / `icons.js` + `index.html` 登记):原型是**单一真源**。新增颜色/组件/图标必须**先登记原型再同步**代码与官网(如 `web/_includes/icons.njk`)。闸:pre-commit `check-ds.mjs` 12 道(本地钩子,新机器先跑 `sh scripts/hooks/install.sh`+ 代码侧 `client/tool/check_ds_code.mjs`
- **L2 屏级三态**(台账 = `design/CONTRACT.md` 块 4「真相源」列):
- `同步`:注册于 `tools/screens.mjs`,fidelity 像素闸生效。整屏改版须原型先行;小迭代改后跑 fidelity 确认阈内,超阈则同步原型或降级快照。
- `快照`:原型退役为历史参考,**golden + CONTRACT 文字规格为准**;小迭代只更 golden,**不回填原型**。
- `代码先行`:无原型屏,golden 为唯一像素基准。
- **L3 新屏/整屏改版**design-first 不变(原型 → CONTRACT → 实现 → fidelity 验收),建成后入 `同步` 态。
- **漂移体检**:不逐提交强制同步;大版本/整屏改版前跑 `node tools/fidelity.mjs`,按报告逐屏决定「重新对齐原型」或「降级快照」,结果回填 CONTRACT。
- **CI 闸**`.gitea/workflows/checks.yml`PR + main push 自动跑):① `check-ds.mjs` 原型 12 道;② `tools/check-l1-sync.mjs` L1 同源四道(tokens 快照逐字节 / icons 两端同集同内容 / 官网 token 值对齐原型主题 A / web 硬编码 hex,白名单 #fff#1677ff`ds-allow` 可豁免);③ `client/tool/check_ds_code.mjs` Flutter 颜色单源;④ codegen 新鲜度(regen→`dart format`→与入库产物零 diff)。本地可直接跑同名命令。
### 表格与列头筛选(ds 真相源)
- 列表屏统一 `DsTable``widgets/ds/ds_table.dart`toolbar+表格+pager 连成一卡),列定义 `DsColumn`,可筛选列走其列头漏斗(`filtered` 态高亮),可隐藏列走列设置菜单
- 不要在 toolbar 放独立筛选按钮,筛选入口内嵌列头或工具栏 `DsChip`
+38 -20
View File
@@ -1,8 +1,11 @@
# 设计契约 — 岩美酒库 Flutter 还原(Phase 1 起:库存列表)
> design-distill 阶段 1 产物。像素以 `.superpowers/prototype/` 原型为**唯一基准**
> token 走 codegen 单源(已在 P0 落地);还原由截图 diff 验收,不靠目测。
> design-distill 阶段 1 产物。token 走 codegen 单源(已在 P0 落地);还原由截图 diff 验收,不靠目测。
> 本文件是**执行真相源**(与 plan `.md` 同性质,机器/diff 引用),随逐屏推进增补。
>
> **真相源分层(2026-07-04 拍板,全文见 CLAUDE.md「设计真相源分层」)**:原型仅对
> 设计系统层(tokens/atoms/icons)与「真相源=同步」态屏是唯一基准;`快照`/`代码先行`
> 态屏以 **golden + 本文件文字规格**为准,小迭代不回填原型。屏的状态登记在块 4「真相源」列。
## 阶段 0 · 归一化产物(已就位)
@@ -87,23 +90,38 @@ AppTokens 目前**仅颜色**。原型还驱动:
## 块 4 · 逐屏验收清单(每屏 × 主题;diff 闸)
| 屏 | 原型 | Flutter | a(基准) | b | c |
|---|---|---|---|---|---|
| 库存列表(桌面) | `inventory.html` | `inventory_list_screen.dart` | ✅ KPI/徽章/列/副标/toolbar 已还原 | ✅ golden 自比 | ✅ golden 自比 |
| 库存列表(移动) | `m-inventory.html` | 同上窄屏(卡片流) | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 往来单位(桌面) | `partners.html` | `partners_screen.dart` | ✅ **Phase2 重建**:单表+类型 chips/应收应付列(finance summary)/详情抽屉/frow 弹窗;fidelity 2.53.5%≤8% | ✅ fidelity | ✅ fidelity |
| 往来单位(移动) | `m-partners.html` | 同上窄屏(卡片流) | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 基础数据(桌面) | `products.html` | `products_screen.dart` | ✅ **Phase2 重建**.seg 5 tab(档案/介绍/系列/规格/仓库)+三套视图+编辑抽屉复用;fidelity 2.43.5%≤8%(已知差异见下) | ✅ fidelity | ✅ fidelity |
| 基础数据(移动) | `m-products.html` | 同上窄屏(卡片流) | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 库列表(桌/移) | `stock-in-list.html` | `stock_in_list_screen.dart` | ✅ 副标 + 共享 StatusPill(草稿/待审/已审/已拒) | ✅ golden | ✅ golden |
| 出库列表(桌/移) | `stock-out-list.html` | `stock_out_list_screen.dart` | ✅ 副标 + 共享 StatusPill | ✅ golden | ✅ golden |
| 财务(桌/移) | `finance.html` | `finance_screen.dart` | ✅ **Phase2 重建**:时间范围 chips(真实过滤)+KPI 4 卡(stock summary 环比)+收支趋势柱状图(DsBarChart, /finance/trend)+应收应付汇总(/finance/summary)+流水表+往来抽屉+登记收支(补往来单位)fidelity 3.04.2%≤8% | ✅ fidelity | ✅ fidelity |
| 设备管理(桌/移) | `devices.html` | `device_management_screen.dart` | ✅ **Phase2 重建**会话表(DsTable)+外设卡网格(custom_fields.peripherals 本地存档)+打印模板fidelity 2.43.0%≤8% | ✅ fidelity | ✅ fidelity |
| 系统设置(桌/移) | `settings.html` | `settings_screen.dart` | ✅ **Phase2 重建**:subnav 5 面板(门店/用户预览/编号规则/授权兑换券/偏好);假「系统参数」已删;fidelity 1.72.3%≤8% | ✅ fidelity | ✅ fidelity |
| 用户管理(桌/移) | `users.html` | `users_screen.dart``/settings/users` | ✅ **Phase2 新独立页**KPI 4 卡+搜索/角色筛选+rcard 弹窗,角色四级拉平;fidelity 1.32.1%≤8% | ✅ fidelity | ✅ fidelity |
| 关于我们(桌/移) | `about.html` | `about_screen.dart` | ✅ **Phase2 重建**:Hero/产品信息/授权信息/更新日志 timeline(/public/release 同源)fidelity 2.22.7%≤8% | ✅ fidelity | ✅ fidelity |
| 登录 | `login.html` | `login_screen.dart` | ✅ **Phase2 重建2026-07-03**:两栏卡片(品牌渐变面板+表单)+右上主题切换器+记住我/忘记密码+lg 主按钮;fidelity 1.42.1%≤8%(已知差异见下) | ✅ fidelity | ✅ fidelity |
| 注册新门店 | `register.html` | `register_screen.dart` | ✅ **Phase2 重建2026-07-03**:品牌面板三步时间线+grid2 表单+协议勾选;**暂不入 fidelity 闸**(少 门店编号/兑换券 两字段致结构错位,用户拍板先不加,见下) | ✅ golden ×3 | ✅ golden ×3 |
**「真相源」列三态**(治理规则见 CLAUDE.md「设计真相源分层」):
`同步` = 注册于 `tools/screens.mjs`,桌面走 fidelity 像素闸(移动走 golden),整屏改版须原型先行;
`快照` = 原型退役为历史参考,golden + 本表文字规格为准,小迭代不回填原型;
`代码先行` = 无原型屏,golden 为唯一像素基准(清单见块 4 末尾小节)。
| 屏 | 原型 | Flutter | 真相源 | a(基准) | b | c |
|---|---|---|---|---|---|---|
| 库存列表(桌面) | `inventory.html` | `inventory_list_screen.dart` | 同步 | ✅ KPI/徽章/列/副标/toolbar 已还原 | ✅ golden 自比 | ✅ golden 自比 |
| 库列表(移) | `m-inventory.html` | 同上窄屏(卡片流) | 同步 | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 往来单位(桌面) | `partners.html` | `partners_screen.dart` | 同步 | ✅ **Phase2 重建**:单表+类型 chips/应收应付列(finance summary)/详情抽屉/frow 弹窗;fidelity 2.53.5%≤8% | ✅ fidelity | ✅ fidelity |
| 往来单位(移动) | `m-partners.html` | 同上窄屏(卡片流) | 同步 | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 基础数据(桌面) | `products.html` | `products_screen.dart` | 同步 |**Phase2 重建**.seg 5 tab(档案/介绍/系列/规格/仓库)+三套视图+编辑抽屉复用fidelity 2.43.5%≤8%(已知差异见下) | ✅ fidelity | ✅ fidelity |
| 基础数据(移动) | `m-products.html` | 同上窄屏(卡片流) | 同步 | ✅ golden 自比 | ✅ golden 自比 | ✅ golden 自比 |
| 入库列表(桌/移) | `stock-in-list.html` | `stock_in_list_screen.dart` | 同步 | ✅ 副标 + 共享 StatusPill(草稿/待审/已审/已拒) | ✅ golden | ✅ golden |
| 出库列表(桌/移) | `stock-out-list.html` | `stock_out_list_screen.dart` | 同步 | ✅ 副标 + 共享 StatusPill | ✅ golden | ✅ golden |
| 财务(桌/移) | `finance.html` | `finance_screen.dart` | 同步 |**Phase2 重建**:时间范围 chips(真实过滤)+KPI 4 卡(stock summary 环比)+收支趋势柱状图(DsBarChart, /finance/trend)+应收应付汇总(/finance/summary)+流水表+往来抽屉+登记收支(补往来单位)fidelity 3.04.2%≤8% | ✅ fidelity | ✅ fidelity |
| 设备管理(桌/移) | `devices.html` | `device_management_screen.dart` | 同步 |**Phase2 重建**:会话表(DsTable)+外设卡网格(custom_fields.peripherals 本地存档)+打印模板;fidelity 2.43.0%≤8% | ✅ fidelity | ✅ fidelity |
| 系统设置(桌/移) | `settings.html` | `settings_screen.dart` | 同步 | ✅ **Phase2 重建**:subnav 5 面板(门店/用户预览/编号规则/授权管理/偏好);假「系统参数」已删;fidelity 1.7–2.3%≤8%**授权管理面板为代码先行区**(见下小节) | ✅ fidelity | ✅ fidelity |
| 用户管理(桌/移) | `users.html` | `users_screen.dart``/settings/users` | 同步 | ✅ **Phase2 新独立页**KPI 4 卡+搜索/角色筛选+rcard 弹窗,角色四级拉平;fidelity 1.32.1%≤8% | ✅ fidelity | ✅ fidelity |
| 关于我们(桌/移) | `about.html` | `about_screen.dart` | 同步 | ✅ **Phase2 重建**Hero/产品信息/更新日志 timeline(/public/release 同源)fidelity 2.22.7%≤8%;授权信息卡 2026-07-04 迁至 设置→授权管理 | ✅ fidelity | ✅ fidelity |
| 登录 | `login.html` | `login_screen.dart` | 同步 | ✅ **Phase2 重建(2026-07-03**:两栏卡片(品牌渐变面板+表单)+右上主题切换器+记住我/忘记密码+lg 主按钮;fidelity 1.42.1%≤8%(已知差异见下) | ✅ fidelity | ✅ fidelity |
| 注册新门店 | `register.html` | `register_screen.dart` | 快照 | ✅ **Phase2 重建(2026-07-03**:品牌面板三步时间线+grid2 表单+协议勾选;**不入 fidelity 闸**(少 门店编号/兑换券 两字段致结构错位,用户拍板先不加,见下) | ✅ golden ×3 | ✅ golden ×3 |
### 代码先行屏/面板(无原型,golden 为唯一像素基准)
2026-07-04 用户拍板:以下功能为代码先行交付,**不反向补建原型**;后续小迭代只更 golden 与本表规格。
| 屏/面板 | Flutter | 像素基准 | 说明 |
|---|---|---|---|
| 设置→授权管理面板(授权信息/在线购买续费/兑换券/降级规则 四卡) | `settings_screen.dart` `_LicensePanel` | settings golden ×3(仅锁面板 0 门店信息;子导航文字变更会入镜) | 2026-07 授权/购买迭代产物;原型 `settings.html` 仍是旧「授权兑换券」面板,视为历史快照 |
| 购买卡(首月特惠/标准/高级 tab + 年付月付 + 支付轮询三态) | `purchase_card.dart` | 无独立 golden;改动后人工目检 + `flutter test` 回归 | 价格展示以 `license_plans.dart` 为源,实付以 pay 侧为准 |
| 官网 定价区/checkout/license-result/profile/logout | `web/index.njk` `checkout.njk` 等 | 人工验收(web 无 golden 体系) | 原型 `pricing.html`/`checkout.html` 为当初设计参考,已漂移,视为历史快照 |
> **共享组件杠杆**`StatusBadge`(入/出库单据状态)一处升级两屏受益;`StatusPill`/`KpiCard` 现已被库存/往来/入出库/财务/设备/设置/关于复用——新屏直接套,无需重做徽章/卡片。
@@ -118,7 +136,7 @@ AppTokens 目前**仅颜色**。原型还驱动:
| Web 营销站 | ✅ **已对齐品牌**`web/assets/color.css``--brand-500:#2563AC` / `--accent` 酒红 / 灰阶 与原型令牌一致,roadmap「Web 镜像品牌」已满足 |
### 仍属「新建功能」(Phase 6,非重建既有屏)
应用内注册 / 购买·套餐·下单(设计+前端壳,**支付不接**)——这是 net-new 功能开发,需各自 spec→设计→实现,不在「既有屏设计语言升级」范围内
~~应用内注册 / 购买·套餐·下单~~ → **2026-07 已交付**(支付宝支付打通,App 内购买卡 + 官网 checkout),按「代码先行」登记于块 4 末尾小节,不再走 design-first 补票。后续 net-new 功能各自 spec→设计→实现。
> **Phase 2 已解决(2026-07-02**
> - **往来单位**:应收/应付列改由 `GET /finance/summary`(按 partner 聚合未结清)供给,两 Tab 改回原型的类型 chips 单表;详情抽屉近期单据走 `finance/records?partner_id=`。
+117
View File
@@ -0,0 +1,117 @@
#!/usr/bin/env node
// tools/check-l1-sync.mjs — L1 设计真相源同源闸(四道,纯 Node 零依赖)
//
// 治理依据:CLAUDE.md「设计真相源分层」L1 层——tokens/atoms/icons 以
// .superpowers/prototype/ 为单一真源,client 与 web 只能是它的同步副本。
// CI.gitea/workflows/checks.ymlPR + main push)与本地均可直接跑:
// node tools/check-l1-sync.mjs
//
// 四道检查(任一违规 exit 1):
// ① tokens 快照同源 原型 tokens.css ≡ client token_source/tokens.css(逐字节)
// ② icons 同源 原型 icons.js 与 web icons.njk 的 symbol 同集且同内容
// ③ 官网 token 值同源 web/assets/tokens.css 与原型(:root+主题A) 同名 token 值一致
// (官网独有 --mk-*/兼容别名层、App 外壳专属 token 不算违规)
// ④ web 硬编码色扫描 web/**/*.{njk,css,js} 禁裸 hex;白名单 #fff/#ffffff/#1677ff
// (对齐原型 check-ds 豁免口径);行内 `ds-allow` 注释可豁免;
// 排除 web/assets/tokens.csstoken 定义位)与 web/dist/。
import { readFileSync, readdirSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = fileURLToPath(new URL('..', import.meta.url));
const read = (p) => readFileSync(join(ROOT, p), 'utf8');
const problems = [];
// ── ① tokens 快照同源 ──────────────────────────────────────
{
const proto = read('.superpowers/prototype/tokens.css');
const snap = read('client/lib/core/theme/token_source/tokens.css');
if (proto !== snap) {
problems.push(
'[tokens快照] .superpowers/prototype/tokens.css 与 ' +
'client/lib/core/theme/token_source/tokens.css 不一致 —— ' +
'改原型后需拷贝快照并重跑 client/lib/core/theme/tool/gen_tokens.mjs',
);
}
}
// ── ② icons 同源 ───────────────────────────────────────────
{
const symbols = (s) => {
const map = {};
for (const [, id, body] of s.matchAll(/<symbol id="([^"]+)"[^>]*>(.*?)<\/symbol>/gs)) {
map[id] = body.trim();
}
return map;
};
const a = symbols(read('.superpowers/prototype/screens/icons.js'));
const b = symbols(read('web/_includes/icons.njk'));
for (const id of Object.keys(a)) {
if (!(id in b)) problems.push(`[icons] symbol "${id}" 仅原型有,web/_includes/icons.njk 缺 —— 改原型后同步官网`);
}
for (const id of Object.keys(b)) {
if (!(id in a)) problems.push(`[icons] symbol "${id}" 仅官网有 —— 图标必须先登记原型 icons.js 再同步`);
}
for (const id of Object.keys(a)) {
if (id in b && a[id] !== b[id]) problems.push(`[icons] symbol "${id}" 两端内容不一致`);
}
}
// ── ③ 官网 token 值同源 ────────────────────────────────────
{
const vars = (css) =>
Object.fromEntries(
[...css.matchAll(/(--[\w-]+)\s*:\s*([^;}]+)[;}]/g)].map(([, k, v]) => [k, v.replace(/\s+/g, '')]),
);
const proto = read('.superpowers/prototype/tokens.css');
const root = proto.match(/:root\s*{([^}]*)}/s)?.[1] ?? '';
const themeA = proto.match(/\[data-theme="a"\]\s*{([^}]*)}/s)?.[1] ?? '';
const pv = { ...vars(root), ...vars(themeA) };
const wv = vars(read('web/assets/tokens.css'));
for (const [k, v] of Object.entries(pv)) {
if (k in wv && wv[k] !== v) {
problems.push(`[web-token] ${k} 值漂移:原型=${v} 官网=${wv[k]} —— web/assets/tokens.css 需同步原型主题 A`);
}
}
}
// ── ④ web 硬编码色扫描 ─────────────────────────────────────
{
const ALLOW_HEX = new Set(['fff', 'ffffff', '1677ff']); // 白 + 支付宝品牌蓝(同原型 check-ds 口径)
const SKIP = new Set(['web/assets/tokens.css']); // token 定义位
const files = [];
const walk = (dir) => {
for (const name of readdirSync(join(ROOT, dir))) {
const rel = `${dir}/${name}`;
if (rel === 'web/dist' || name === 'node_modules') continue;
const st = statSync(join(ROOT, rel));
if (st.isDirectory()) walk(rel);
else if (/\.(njk|css|js)$/.test(name) && !SKIP.has(rel)) files.push(rel);
}
};
walk('web');
for (const f of files) {
const lines = read(f).split('\n');
lines.forEach((line, i) => {
if (line.includes('ds-allow')) return;
for (const [hex] of line.matchAll(/#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g)) {
const v = hex.slice(1).toLowerCase();
if (!ALLOW_HEX.has(v)) problems.push(`[web-hex] ${f}:${i + 1} 硬编码颜色 ${hex} —— 改用 var(--token)web/assets/tokens.css),确需保留加 ds-allow 注释`);
}
});
}
}
// ── 汇总 ───────────────────────────────────────────────────
const line = '='.repeat(60);
if (problems.length) {
console.error(line);
console.error(`✗ L1 真相源同源闸未过(${problems.length} 处):`);
for (const p of problems) console.error(' · ' + p);
console.error(line);
process.exit(1);
}
console.log(line);
console.log('✓ 通过:L1 真相源同源(tokens 快照 / icons / 官网 token 值 / web 无硬编码色)');
console.log(line);
+3
View File
@@ -3,6 +3,9 @@
// fidelity.mjs(自动 diff 闸)与 ds-compare.mjs(人工 montage 目检)共用此表,
// 保证「每一屏 + 外壳都跟原型比」(规则 2)。屏随 Phase 1/2 照原型重建后逐个入册。
//
// 本表只登记 design/CONTRACT.md 块 4 中「真相源 = 同步」的屏,两处互为镜像;
// 快照 / 代码先行 态屏不入册(分层规则见 CLAUDE.md「设计真相源分层」)。
//
// 字段:
// html 原型 html(仓库根相对路径)
// prefix Flutter golden 文件前缀 → client/test/golden/goldens/<prefix>_<theme>.png
+1 -1
View File
@@ -49,7 +49,7 @@ permalink: /checkout/
<div class="radio"></div>
</div>
<div class="pm off">
<div class="pic" style="background:#8A94A6"><svg class="ic"><use href="#i-ic11"/></svg></div>
<div class="pic" style="background:var(--faint)"><svg class="ic"><use href="#i-ic11"/></svg></div>
<div class="nm"><b>对公转账</b><span>需要合同与对公收款请<a href="mailto:{{ site.support.email }}">联系我们</a></span></div>
</div>
</div>