# Prompt: DS 合并 Phase 2 — 基础卡生成器（色/字/圆角/投影/图标）（交 Codex 执行 · Claude 复核）

- **日期**：2026-07-23
- **分工（PROJECT_MAP §6）**：Claude 出本 prompt + 复核；Codex 执行代码；Owner 审本 prompt 后才交 Codex。
- **STOP 约定**：Codex 执行完 **STOP**，列出改动 + 未验证项 + 风险，等 Owner/Claude 复核。**不要 commit、不要 push**（落地由 plan owner 复审后决定）。
- **上位 plan**：`docs/_archive/superpowers/plans/2026-07-23-ds-merge-two-systems.md` §Phase 2。本 prompt 是该 Phase「写脚本」任务的可执行化；架构/背景以 plan 为准，本文件给精确锚点让你不必重推。

## ⚙️ 执行环境
- **工作树（唯一）**：`/Users/nancy/Documents/AICoding/VS_Code/tvu-design-system`，分支 `master`。执行前 `pwd` 自证在此路径。所有新建文件落此工作树。
- **包管理**：`pnpm`（不是 npm/yarn）。测试用 `pnpm vitest run <file>`。
- **Node ESM**：脚本用 `.mjs`；数据源是 `.ts`——vitest 能直接 import `.ts`（现有测试即如此），生成器脚本（`.mjs`）若需读 `.ts` 数据，用 vitest 环境或 `tsx`/`esbuild-register` 跑；**推荐把生成器入口也走 vitest-toolable 或用项目已装的 ts 运行器**，先 `grep -n '"gen' package.json` 看现有 gen 脚本怎么跑 `.ts` 依赖，照抄其模式（别自造 loader）。

## 目的
两套 claude.ai/design 项目（Sync A / Sync B）的**基础层卡**（颜色 / 排版 / 圆角 / 投影 / 品牌 / 图标）目前是远端手作 9 张卡。改为**从本地 token 源程序化生成**独立自包含 `@dsCard` 卡，两项目都从它导。**本 Phase 只产出生成器 + 卡文件到本地 outDir，不上传**（上传是 Phase 5 主 session 活）。

## 硬约束
1. **只新建下列文件**，不改 `src/`、`figma-data/`、`figma-sync/`、现有 `scripts/*`（除 `package.json` 加一个 script 行）、导出管道、gate。
2. **数据只读不改**：`playground/docs/pages/designAssetData.ts`、`playground/docs/pages/atomicAssets.ts`、`src/tokens/variables.css` 是**只读数据源**，绝不修改。
3. **值取自 token，不硬编码**：卡里显示的 hex/尺寸/阴影用 `var(--token)` + 运行时 `getComputedStyle` 取显示值（与远端 9 卡同机制），**不要把 `darkValue`/`lightValue` 字面量写死进 HTML**——字面量仅用于旁注/figmaName 标签。
4. **每卡首行必须是** `<!-- @dsCard group="…" name="…" subtitle="…" -->`（DS 面板靠这行建卡索引）。group 取值见下表，**大小写/拼写精确**。
5. **明暗主题**：卡在 dark-default 与 light 覆盖下都要正确（token 会随 `[data-theme=light]` 变），swatch/字样/阴影不能只对一个主题。
6. **TDD**：每张卡先写失败测试 → 跑确认 FAIL → 实现 → 跑确认 PASS。测试断言「关键 token/图标名全覆盖 + `@dsCard` 头 group 名正确」。
7. 完成后 **STOP**，不 commit / 不 push。

## 数据源真实导出（Claude 已对活源核实 2026-07-23，直接用，勿猜）

**`playground/docs/pages/designAssetData.ts`**（颜色 + 图标）：
- `colorSections: TokenSection[]` — 色卡数据源。`TokenSection = { id, title, summary, tokens: TokenRecord[] }`；`TokenRecord = { name, figmaName, darkValue, lightValue, usage, note?, changedByTheme }`。`name` 即 `--token` 名。
- `figmaPublishedIconCategories: FigmaIconCategoryGroup[]` — **图标卡的全量分类真源**（Icon 归基础层，见 owner Q2 裁决）。读该文件确认 `FigmaIconCategoryGroup` shape（约 line 382）。
- `logoIcons` / `actionIcons` / `statusIcons: IconAsset[]` — `IconAsset = { name, svg, kind, category, usage, note?, supportsCurrentColor }`；`svg` 是内联 SVG 串。
- `iconSizeSpecs: IconSizeSpec[]`（`{ size, usage }`）— 图标尺寸档。
- 辅助：`colorThemeRows` / `colorRoleCards` / `iconToneCards`（按需，非必需）。

**`playground/docs/pages/atomicAssets.ts`**（排版 + 边框/圆角 + 效果/投影）：
- `typographyStyles: TypographyStyle[]` — 排版卡数据源。读文件确认 `TypographyStyle` shape（约 line 2）。
- `fontFamilies: FontFamilyToken[]`、`figmaTextStyleFamilies`、`typographyGuidelines` — 排版辅助。
- `borderRadiusTokens: BorderRadiusToken[]` — 圆角卡数据源（约 line 46 / 325）。
- `effectStyles: EffectStyle[]` — 投影/效果卡数据源（约 line 81 / 511）。
- 辅助：`borderWidthTokens` / `borderColorTokens` / `borderRecipes` / `effectRecipes`。

> ⚠️ 上面这些是**真实存在的 export**（已 grep 核实）。若某个 import 报「not exported」，**STOP 报告**别改数据文件——是本 prompt 锚点过时，交回 Claude 修。

## 交付物 / 接口
- **新建** `scripts/lib/foundation-card-template.mjs` — 纯函数模板：`buildColorCard(colorSections)`、`buildTypeCard(typographyStyles)`、`buildRadiusCard(borderRadiusTokens)`、`buildElevationCard(effectStyles)`、`buildBrandCard(logoIcons)`、`buildIconsCard({figmaPublishedIconCategories, actionIcons, statusIcons, logoIcons, iconSizeSpecs})`。每个返回一段以 `@dsCard` 头开头的自包含 HTML 串。
- **新建** `scripts/gen-foundation-cards.mjs` — 入口：`genFoundationCards({outDir})`，调各 `build*`，写 `<outDir>/preview/<slug>.html` + `<outDir>/preview/_card.css`；支持 `--out=<dir>` CLI 参数（默认 `./ds-foundation-out` 或 plan 指定）。
- **新建** `test/gen-foundation-cards.test.mjs` — 各卡的 TDD 断言。
- **改** `package.json`：`scripts` 加 `"gen:foundation-cards": "node scripts/gen-foundation-cards.mjs"`（若 `.mjs` 读 `.ts` 需 ts 运行器，按 §执行环境照现有 gen 脚本模式）。

**group ↔ 卡对照**（`@dsCard group=` 值精确）：

| 卡 | group | 数据源 |
|---|---|---|
| 颜色 | `Colors` | `colorSections` |
| 排版 | `Type` | `typographyStyles` |
| 间距 | `Spacing` | `src/tokens/variables.css` 的 `--sp-*`（若 atomicAssets 无间距导出，从 variables.css 解析 `--sp-` 前缀 token） |
| 投影/效果 | `Elevation` | `effectStyles` |
| 圆角 | （并入 `Elevation` 或单列，见下注） | `borderRadiusTokens` |
| 品牌 | `Brand` | `logoIcons`（logo 资产） |
| 图标 | `Icons` | `figmaPublishedIconCategories` 全量 + `actionIcons`/`statusIcons`/`logoIcons` + `iconSizeSpecs` |

> 注：plan §Phase 2 列的 group 是 Colors/Type/Spacing/Elevation/Brand/Icons 六组。圆角（radius）plan 未单列 group——**默认并入 `Elevation` 卡的一个 section，或作 `Spacing` 同类原子卡**；哪种更合适 Codex 可选一种实现并在 STOP 报告里说明，交 Claude/owner 定。**别自造第七个 group 名**。

## TDD 步骤（照 plan §Phase 2 Step 1–N+3，去掉 commit）
1. 写失败测试：色卡含 `colorSections` 全 section 每个 `tok.name` + `@dsCard group="Colors"` 头。→ `pnpm vitest run test/gen-foundation-cards.test.mjs` 确认 FAIL（`buildColorCard` 未定义）。
2. 实现 `buildColorCard`（最小）→ 跑 PASS。
3. 同法 TDD 其余卡：`buildTypeCard` / `buildRadiusCard` / `buildElevationCard` / `buildBrandCard` / `buildIconsCard`。每卡：失败测试（断言关键 token/图标名全覆盖 + `@dsCard` 头 group 正确）→ 实现 → PASS。**Icons 卡必须覆盖 `figmaPublishedIconCategories` 全量分类**（这是 Q2「Icon 并入基础层」的落点）。
4. 组装 `gen-foundation-cards.mjs`，加 `--out=`，写 `<outDir>/preview/*.html` + `_card.css`；加 `package.json` script。
5. 本地渲染回归：`pnpm gen:foundation-cards --out=scratch/foundation-out`，浏览器（或 Playwright headless）逐卡确认明暗主题下 swatch/字样/阴影正确。**`scratch/` 不提交**。

## ⚠️ 已知缺口 — `_card.css`（执行前必读）
`_card.css` **本地仓库不存在**（`find . -name _card.css` 为空）——它是远端手作卡的共享卡 chrome 样式，只在 claude.ai/design 项目里。**Codex 拿不到远端文件**（DesignSync 仅主 session）。因此：
- **默认方案**：生成器**自产**一份最小 `_card.css`（卡容器/网格/swatch chrome：如 grid 布局、swatch 方块尺寸、label 排版），自包含、不依赖远端。写进 `<outDir>/preview/_card.css`。
- 卡 HTML 本体**尽量自包含**（关键 chrome inline style 或 `_card.css` class），使单卡即便无 `_card.css` 也能读。
- 若你判断必须复用远端 `_card.css` 原样 → **不要猜内容**，STOP 报告，标记「需主 session DesignSync `get_file` 取远端 `preview/_card.css`」交回 Claude。

## STOP — 完成后停，报告以下，等复核
- 新建文件清单 + `git diff --stat`（应只有 3 新建 + `package.json` 1 行）。
- `pnpm vitest run test/gen-foundation-cards.test.mjs` 实际输出（全 PASS）。
- 6 张卡各自 `@dsCard` 头首行原文（证明 group 名正确）。
- radius 卡归属选择（并入 Elevation / 作 Spacing 类 / 其他）+ 理由。
- `_card.css` 采用哪种方案（自产 / 需远端）。
- 本地渲染回归截图或 Playwright 断言结果（证明明暗主题都对）。
- 任何 import「not exported」或数据 shape 与本 prompt 描述不符之处（别自行改数据文件）。

## Claude 复核清单（Codex STOP 后）
- [ ] 无越界改动：只碰 3 新建文件 + `package.json` 一行；`src/`/`figma-data/`/数据 `.ts` 未改。
- [ ] 各卡 `@dsCard` group 名 ∈ {Colors, Type, Spacing, Elevation, Brand, Icons}，无第七个杜撰 group。
- [ ] 显示值走 `getComputedStyle`/`var(--token)`，非硬编码 darkValue/lightValue 字面量。
- [ ] `buildIconsCard` 覆盖 `figmaPublishedIconCategories` 全量分类（抽查分类数 == 数据源分类数）。
- [ ] 测试是真断言（token/图标名全覆盖），非空跑；亲跑一遍 vitest 复核 PASS。
- [ ] 明暗主题渲染回归证据真实存在（截图/断言），非文字声明。
- [ ] `_card.css` 方案合理、自包含；若标「需远端」则记入 Phase 5 主 session 待办。
