@q1travel/design-system 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.agents/skills/product-design/AGENTS.md +9 -0
  2. package/.agents/skills/product-design/SKILL.md +63 -0
  3. package/.agents/skills/product-design/exemplars/README.md +12 -0
  4. package/.agents/skills/product-design/references/copy.md +7 -0
  5. package/.agents/skills/product-design/references/coverage-gaps.md +9 -0
  6. package/.agents/skills/product-design/references/glossary.md +5 -0
  7. package/.agents/skills/product-design/references/interface-quality.md +7 -0
  8. package/.agents/skills/product-design/references/patterns.md +13 -0
  9. package/.agents/skills/product-design/references/product-judgment.md +7 -0
  10. package/.agents/skills/product-design/references/resilience.md +13 -0
  11. package/.agents/skills/product-design/references/review-geist.md +94 -0
  12. package/.agents/skills/product-design/references/rules.md +17 -0
  13. package/.agents/skills/product-design/references/surfaces-forms.md +14 -0
  14. package/.agents/skills/product-design/references/surfaces-overlays.md +12 -0
  15. package/.agents/skills/product-design/references/surfaces.md +14 -0
  16. package/bin/q1-design.mjs +464 -0
  17. package/contracts/design-engineering-principles.md +39 -0
  18. package/contracts/design.dark.md +333 -0
  19. package/contracts/design.md +333 -0
  20. package/contracts/icon-system.md +77 -0
  21. package/contracts/implementation-map.md +29 -0
  22. package/contracts/interface-guidelines.md +122 -0
  23. package/contracts/token-naming.md +82 -0
  24. package/{dist → dist-pkg}/design-system.d.ts +36 -26
  25. package/{dist → dist-pkg}/design-system.js +222 -216
  26. package/{dist → dist-pkg}/style.css +2 -2
  27. package/package.json +19 -9
  28. package/tooling/README.md +9 -0
  29. package/tooling/scripts/evals/fixtures.json +7 -0
  30. package/tooling/scripts/evals/rules-checklist.json +23 -0
  31. package/tooling/scripts/evals/transition-all/after/example.css +4 -0
  32. package/tooling/scripts/evals/transition-all/before/example.css +4 -0
@@ -0,0 +1,9 @@
1
+ # product-design — agent 入口
2
+
3
+ `@q1travel/design-system` 随包发布的产品设计判断层。
4
+
5
+ **触发**:改动任何用户能看到、理解、选择或执行的界面前,加载 `SKILL.md`,先判断模式(Shape / Implement / Review / Copy / Harden),再按 surface 加载 `contracts/` 里对应的 canonical 段落。
6
+
7
+ **唯一 canonical 源**:`contracts/`(随包发布)。本目录的 `references/` 只指路,不另立正文。
8
+
9
+ **在消费者仓库**:本目录是由 npm 版本生成的只读缓存(gitignored、可重建)。不要手改;不要在消费者里新建本地设计文档(`DESIGN.md` / `docs/design/`)。设计权威只有这个包。
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: product-design
3
+ description: q1travel 产品设计 agent 框架。凡改动用户能看到、理解、选择或执行的界面,在动手/评审前加载本 skill 做模式判断与规则路由。Use when shaping, implementing, reviewing, copy-editing, or hardening any UI that consumes @q1travel/design-system.
4
+ ---
5
+
6
+ # q1travel 产品设计(product-design)
7
+
8
+ ## 这是什么
9
+
10
+ `@q1travel/design-system` 随包发布的产品设计判断层。它把「已被接受的设计决策」当代码管理:规范落在 `contracts/`,规则由 linter 强制,证据经 review loop 回流。它的作用是**路由到 canonical 源**,不是复制判断。
11
+
12
+ - **Canonical 源恒为 `contracts/`**(随包发布):`design-engineering-principles.md`、`interface-guidelines.md`、`design.md` / `design.dark.md`、`icon-system.md`、`token-naming.md`、`implementation-map.md`。
13
+ - 本 skill 的 `references/` 只是**指路条**,指向上面的 canonical 文件;正文永远读 `contracts/`,不在 references 里另立一份。
14
+ - Token 恒用 `--q1-*`。product 仓里的 `--ds-*` 是 legacy,不作新决策的源命名(见 `contracts/token-naming.md`)。
15
+
16
+ ## 在消费者仓库里(硬边界)
17
+
18
+ 当本 skill 出现在消费 `@q1travel/design-system` 的仓库(如 q1travel-web)时:
19
+
20
+ - 它是**由 npm 版本生成的只读缓存**(gitignored、可重建)。**不要手改**;要改设计判断,改上游的包,重新发版、重新生成。
21
+ - 消费者**不得**新建或维护本地设计规范(`DESIGN.md`、`docs/design/`、可编辑的本地 design skill)。设计权威只有一个:这个包。
22
+ - 消费者只保留**可执行的 app 专属校验**(baseline、路由/权限矩阵、业务字段语言)——这些不是设计判断,留在本地。
23
+
24
+ ## 何时使用
25
+
26
+ 改动任何用户能看到、理解、选择或执行的界面之前,先判断落在哪个模式,再按 surface 加载对应 canonical 段落。纯后端、纯数据、与界面无关的改动不需要本 skill。
27
+
28
+ ## 五模式
29
+
30
+ 每次先把请求归到一个模式,再加载该模式所需的 canonical 段落。
31
+
32
+ | 模式 | 何时 | 加载(canonical) | 产出 |
33
+ |---|---|---|---|
34
+ | **Shape** 立题 | 需求模糊/多解,先框问题、比方案 | `design-engineering-principles.md`(Usefulness / Constraints);`interface-guidelines.md` 相关章 | 问题陈述 + 方案取舍,不写实现 |
35
+ | **Implement** 落地 | 明确范围内端到端做 | 按 surface 路由(见下)+ `design.md` token + `icon-system.md` | 改动 + 自测 |
36
+ | **Review** 评审 | 审代码 + 审**渲染后**的界面 | 全量 `interface-guidelines.md` + `design-engineering-principles.md`;评审本仓组件对齐 Geist 时加载 `references/review-geist.md` | 差异单(见 `references/rules.md`) |
37
+ | **Copy** 文案 | 只改用户可见文字 | `interface-guidelines.md` §Copy | 文案 diff,不动结构 |
38
+ | **Harden** 收口 | 打磨 + 边界态 | `interface-guidelines.md`(Interactions / Content / Accessibility Tiers / Performance);`references/resilience.md` | 每个可达态齐备 |
39
+
40
+ Review 与 Harden 必须核**渲染后的界面**,不能只看代码(见 `design-engineering-principles.md` §Whole Experience)。
41
+
42
+ ## 按 surface 路由
43
+
44
+ Implement / Harden 时,按改动落在哪种 surface 加载对应段落:
45
+
46
+ | Surface | 加载 |
47
+ |---|---|
48
+ | 表单 / 输入 | `interface-guidelines.md` §Forms;`references/surfaces.md` |
49
+ | 弹层(modal / drawer / menu / combobox…) | `interface-guidelines.md` §Interactions + §Accessibility Tiers(Tier A APG 键盘模型) |
50
+ | 表格 / 列表 / 分页 | §Layout + §Performance(长列表虚拟化)+ §Content(tabular numbers) |
51
+ | 破坏性动作 | §Interactions(确认 / 撤销);`references/rules.md`(命名 scope + 后果) |
52
+ | 空 / 加载 / 错误 / 无权限态 | `references/resilience.md`(每个可达态都要设计) |
53
+ | 图标 | `icon-system.md`;§Content(icon-only 必须有可访问名) |
54
+ | 动效 | §Animation(honor reduced-motion;禁 `transition: all`) |
55
+ | 主题 / 颜色 | §Theming;`design.md` / `design.dark.md` token;`token-naming.md` |
56
+ | 文案 | §Copy;`references/glossary.md` |
57
+
58
+ ## 红线
59
+
60
+ - 在消费者仓库手改本缓存、或另立本地设计文档 = 违规。改判断走上游包。
61
+ - `references/` 里重抄 `contracts/` 正文 = 违规。references 只指路。(review-geist.md 是收编的流程文档,属例外,其权威边界见该文件头部。)
62
+ - 用 `--ds-*` 作新决策的源命名 = 违规。新代码 `--q1-*`。
63
+ - 声称"看着对"就算过 = 未验证。Review / Harden 必须核渲染后的界面。
@@ -0,0 +1,12 @@
1
+ # exemplars(范例)
2
+
3
+ 从**已合并 PR** 收录的真实决策范例:记录做了什么、观察得到的决策、以及踩过的错,给 agent 在新界面上迁移判断用(而不是靠模糊形容词)。
4
+
5
+ 格式(每个 `pr-<name>.md`):
6
+
7
+ - 背景 / surface
8
+ - 观察到的决策(可验证,不用 "clear / polished / intuitive" 这类空形容词)
9
+ - 对应的 canonical 依据(`contracts/` 里哪条)
10
+ - 反例 / 踩过的错
11
+
12
+ **现状**:空。首批范例待从 q1travel-web / chrome-extension 的已合并 PR 收录(见 `../references/coverage-gaps.md`)。
@@ -0,0 +1,7 @@
1
+ # copy(指路)
2
+
3
+ **Canonical**:`contracts/interface-guidelines.md` §Copy。
4
+
5
+ 用户可见文字的规则:公开、中性、具体;跨页用词一致;短动作导向标签;数字 / 单位格式一致。Copy 模式只改文字、不动结构。
6
+
7
+ 术语一致性见 `references/glossary.md`。正文只在 canonical 里维护。
@@ -0,0 +1,9 @@
1
+ # coverage-gaps(已知缺口)
2
+
3
+ 记录目前**缺规范 / 缺规则**的地方,作为 review loop 的下一轮输入。有稳定证据 + 明确范围后,再决定归到 rule / reference / exemplar / lint / eval。
4
+
5
+ - **稳定 ID 规则层部分完成**:`q1-design lint` 已实现 `Q1-DS-001`(`--ds-*`)/`Q1-DS-401`(`transition: all`)/`Q1-DS-501`(裸颜色字面量)三条纯机械规则;其余 `Q1-DS-*` 规则(含带判断成分的 deterministic 规则与全部 judgment 规则)尚未落地(见 `references/rules.md`)。
6
+ - **per-surface 细粒度契约未展开**:`implementation-map.md` 的组件契约还没按 modal / drawer / table 等逐一展开组合约束(见 `references/surfaces.md`)。
7
+ - **术语表未成形**:统一 glossary 待消费者黑话清理产出回流(见 `references/glossary.md`)。
8
+ - **exemplars 为空**:还没有从已合并 PR 收录的范例(见 `../exemplars/`)。
9
+ - **review loop 未接线**:消费者证据 → 包决策的回流路径(复用轻量 register + `gh`)尚未搭。
@@ -0,0 +1,5 @@
1
+ # glossary(术语表)
2
+
3
+ 用户可见文字与契约里的名词以此为准,跨页 / 表格 / 示例保持一致(`contracts/interface-guidelines.md` §Copy 要求 "consistent nouns")。
4
+
5
+ **Coverage gap**:统一术语表尚未成形。消费者(如 q1travel-web)正在做「内部黑话清理」,清理产出的中性术语应回流到这里,成为 canonical 词表。在此之前,遇到术语一致性问题记入 `references/coverage-gaps.md`。
@@ -0,0 +1,7 @@
1
+ # interface-quality(指路)
2
+
3
+ **Canonical**:`contracts/interface-guidelines.md`(Interactions / Forms / Layout / Content & Accessibility / Accessibility Tiers / Animation / Theming / Performance / Copy)。
4
+
5
+ 界面质量的可执行准则(MUST / SHOULD / NEVER)。Implement / Review / Harden 按 surface 加载对应章(路由见 `SKILL.md`「按 surface 路由」)。
6
+
7
+ 正文只在 canonical 里维护,本文件不复制。
@@ -0,0 +1,13 @@
1
+ # patterns(指路)
2
+
3
+ 跨组件的复用模式(command menu、tile grid、page rhythm、footer nav、破坏性确认…):先查既有配方、复用,不新开 page-local pattern。
4
+
5
+ **Canonical**:`contracts/implementation-map.md`(reference intent → q1travel semantic → canonical component 的映射表)+ `contracts/interface-guidelines.md`。
6
+
7
+ 关键规则(正文见 `implementation-map.md` §Implementation Rules):
8
+
9
+ - 参考行为必须先映射到 q1travel semantic,再进 `src`。
10
+ - 共享组件缺能力时,**先给该组件加能力**,别再起 page-local pattern。
11
+ - canonical 组件拥有重复结构;page-local 自定义结构只允许用于目的狭窄的视觉样例。
12
+
13
+ 只指路,不复制正文。
@@ -0,0 +1,7 @@
1
+ # product-judgment(指路)
2
+
3
+ **Canonical**:`contracts/design-engineering-principles.md`(Usefulness / Whole Experience / Constraints / Inclusion / Craft / Team Defaults)。
4
+
5
+ 评估任何设计改动的标准。Shape 立题时读 Usefulness / Constraints 判断「该不该做、边界在哪」;Review 时读全量,判断「是否达标」。
6
+
7
+ 正文只在 canonical 里维护,本文件不复制。
@@ -0,0 +1,13 @@
1
+ # resilience(每个可达态都要设计)
2
+
3
+ **Canonical 依据**:`contracts/design-engineering-principles.md` §Whole Experience("Design empty, sparse, dense, loading, error, hover, active, focus, and disabled states before calling a component complete")+ `contracts/interface-guidelines.md` §Content。
4
+
5
+ Harden / Review 时,任何 surface 都要核这些可达态:
6
+
7
+ - 空 / 稀疏 / 密集
8
+ - 加载(骨架与最终布局一致、无闪烁)
9
+ - 错误(就地、可恢复、指明出路)
10
+ - 无权限
11
+ - hover / active / focus / disabled(禁用态在亮 / 暗两主题都要可读)
12
+
13
+ **Coverage gap**:尚无独立的稳定 ID 规则强制「每个可达态齐备」;目前靠本条 + Review 人工核(见 `references/coverage-gaps.md`)。
@@ -0,0 +1,94 @@
1
+ # Review 模式 — 评审本仓组件对齐 Geist
2
+
3
+ 这是 product-design **Review 模式**在「评审本仓组件对齐 Geist」场景下的完整流程。Review 评审消费者产品界面(如 q1travel-web)时用 `SKILL.md` 的通用路由;评审**本仓组件**(`q1travel-design-system` 自身的组件页,对齐 Geist)时用本文件。权威边界:本文件是收编的评审**流程**;设计判断的 canonical 恒为 `contracts/`,二者冲突时以 `contracts/` 为准。Geist 是外部参照(实测对齐的工作方法),不是实现源(见 review/decision-log/0002)。
4
+
5
+ # Geist 对齐评审(逐组件)
6
+
7
+ ## Overview
8
+
9
+ 参照物是 Geist 的**实测渲染值**,不是记忆、截图目测或猜测。每件组件独立走完本清单,产出差异单,交用户逐件拍板。队列与进度唯一源:`tasks/v1-queue.md`。
10
+
11
+ ## 何时使用
12
+
13
+ - 打磨/复核任何组件页;验收自己或子代理的组件改动
14
+ - 不适用:纯文档措辞调整、与 Geist 无对应物的自有页面(但"量化门槛"节仍然执行)
15
+
16
+ ## 评审步骤(REQUIRED,按序)
17
+
18
+ 1. **/web-design-guidelines 定向扫描**:用 Skill 工具调用 `web-design-guidelines`,扫描目标**只有一个 URL——该组件的 Geist 同名页**(如 Avatar → `https://vercel.com/geist/avatar`),不扫整站、不带其他页;发现项全部并入差异单。无 Skill 工具的子代理不得跳过此步——由主编排者代跑并把发现项注入子任务。
19
+ 2. **章节大纲对照**:同一 URL 上列出该页**全部章节**,逐章判定:已覆盖 / 需补齐 / 记 non-goal(书面理由)。demo 与文档两头核;冲突时以 demo 的整体观感为准(用户看的是 demo)。
20
+ 3. **实测度量**:浏览器读 Geist 的 computed style 与真实几何,逐项对照:尺寸档、padding、radius、字号字重、颜色(oklch)、动效时长与缓动。
21
+ 4. **感知复查(两主题)**:亮/暗两主题下测**渲染后的实际对比度**;结构/aria/契约全对 ≠ 可读(暗色禁用态曾三次漏检)。
22
+ 5. **逐元素交互探测 + 边界**(最易漏维度,见下方专章):
23
+ - **探测**:对每一个"长得像能点"的元素(图标 / 按钮样 / pill / 链接样)用扩展真的 hover+click——查它是不是 `button/a/[role]`、有没有 `cursor:pointer`/`tabindex`/`aria-label`、点击后有无状态变化(图标切换 / DOM / 剪贴板)。**"判定某物是纯装饰"是最危险的预设,必须逐元素实测反证**(Browser 把可点的复制按钮当装饰漏了)。图标不只查"有没有"、还要查"是哪个"(渲染真实 SVG path 放大确认,别照抄旧实现——Browser 锁/复制照抄反了)。
24
+ - **边界**:已知交互元素测键盘全路径(Tab/方向键/Esc/Enter/Space)、焦点环完整、disabled 不可聚焦;长文案/换行/极窄容器/空列表;浮层组件测视口边缘碰撞翻转。
25
+ - 每个确认为真交互的元素,再逐条过下方「交互完整性清单」。
26
+ 6. **家族配方优先**:改配方前先查下表既有规则,复用不新开。品牌层永远不跟 Geist:indigo #533afd 守「动作」、绿守「成功」、蓝守「info」。任何偏离 Geist 必须留书面理由(页面注释或 memory)。
27
+ 7. **组件化**:该件若仍是页面内联 specimen,按先例(Tabs/Switch/Skeleton/StatusDot)提升为 `components/ui/` 真组件 + barrel 导出 + 契约。
28
+
29
+ ## 交互完整性清单(Browser 连栽三层的教训 —— 复核每件都过一遍)
30
+
31
+ **根因**:此前复核只测"看起来对不对"(视觉/几何/章节/对比度),几乎没测"每个元素能不能点、该不该能点"。用户三次复核 Browser 才逼出:图标反了 → 复制按钮被当纯装饰(漏了它是真 button)→ 补了交互又漏配套。**凡是判定"纯装饰/静态组件"的组件,都要用第 5 步探测反证一遍;凡确认为真交互的元素,下表缺一即漏:**
32
+
33
+ | 配套项 | 要求 | Browser 栽点 |
34
+ |---|---|---|
35
+ | 点击目标 | ≥24×24px(WCAG 2.2);过小用 `min-width/height` + 负 margin 扩大命中区、不撑高容器 | 复制按钮只有 16px |
36
+ | 状态可感知 | 视觉状态切换必须配 `role="status"`/`aria-live` 播报;`aria-label` 恒为动作名(如"复制网址"),状态另走 live region,**不把 label 当状态切** | 只切图标,读屏听不到成功 |
37
+ | 卸载清理 | `setTimeout`/事件监听/订阅在 `useEffect` return 里清理,防已卸载组件 setState | timer 无 cleanup |
38
+ | 键盘可达 | `tabindex` 正确 + `focus-visible` 焦点环 + Enter/Space 触发 | — |
39
+ | a11y 联动 | 可交互元素**绝不**能落在 `aria-hidden` 容器内(WCAG);一旦发现漏了交互 → 整个 aria-hidden 策略要**连带重构**(装饰各自 hidden、交互元素可达),不能局部补丁 | 整个 chrome aria-hidden 吞掉复制按钮 |
40
+ | 契约层 | 断言交互**行为**不只结构存在:点击后状态切换、失败路径、Tab 可达、装饰全量 aria-hidden、交互元素无 aria-hidden 祖先 | 断言只覆盖"元素存在" |
41
+ | Provider 依赖 | 可独立组合的 building block 若需复制等交互,直接用 `lib/clipboard` 边界 + 就地反馈,**不接 useCopy/ToastProvider**(否则单独取用会崩) | — |
42
+
43
+ 测试局限记录:自动化点击(preview/CDP)无 user-activation,`execCommand('copy')` 返回 false → 就地复制反馈触发不了;成功路径靠代码与 `useCopy` 同源 + Codex 逻辑复审背书,契约层测结构+尺寸+aria、不强测剪贴板写入。
44
+
45
+ ## 家族配方速查
46
+
47
+ | 领域 | 既有配方 |
48
+ |---|---|
49
+ | 语义色面 | `--q1-tone-{bg,border,fg}-{info,success,warning,danger}` |
50
+ | 禁用态 | bg-subtle + text-muted(opacity 恒 1) |
51
+ | 字段尺寸档 | xs 24 / sm 32 / md 36 / lg 48 |
52
+ | Button 刻度 | 高 32/40/48,radius 6/6/8,字重 500 |
53
+ | 暗色阴影 | 恒用 `--q1-color-shadow`(黑) |
54
+ | 浮层边框 | 恒用 `--q1-color-border-overlay` |
55
+ | 可作 Tooltip 触发器的组件 | 必须 `{...rest}` 透传原生/ARIA/事件属性(cloneElement 注入;Button/Badge 两案教训) |
56
+ | 纯图标可访问名 | title 属性读屏不可靠,升格 role="img"+aria-label(StatusDot/Badge 配方) |
57
+
58
+ ## 测量工具坑(先疑方法,再下结论)
59
+
60
+ | 症状 | 正确做法 |
61
+ |---|---|
62
+ | "子元素溢出了"(rect 比较得出) | getBoundingClientRect 不能证明可见溢出;用 elementFromPoint 正反对照做命中测试 |
63
+ | 视口边缘测试出现负坐标 | 用 position:fixed 模拟贴边,margin 会触发 Chrome scroll anchoring 补偿 |
64
+ | "动画不可见 / 冻在 opacity:0" | 自动化标签页常为 visibilityState:hidden,动画冻结;查 Animation.currentTime 或 finish() 后读定格态 |
65
+ | "hover 无动效"(hidden 页实测) | rAF 与 JS 弹簧在 hidden 页完全不跑,悬停后读恒等矩阵≠无动效,该结论一律无效;hover 后用 getAnimations() 读冻结 CSSTransition 的关键帧取证(Book 案:据此挖出 rotateY(-20deg) scale(1.066) translateX(-16px)) |
66
+ | 截图看出"布纹/颗粒/材质感"等细腻纹理 | 大片纯色区域截图会被 JPEG 压缩出块状伪影,酷似编织纹理;先注入同色纯色 div 做对照截图,伪影会同样出现就证伪;真凭据是 computed style 的 background-image/filter/mask-image/backdrop-filter/mix-blend-mode(Book 案:Geist"Textured"节色带经查全部 none,视觉纹理是截图伪影,非真实设计) |
67
+ | 子部件脱离原生父级上下文单独渲染(如"单独组合"演示) | 结构完整+geometry 数字对 ≠ 颜色对——若样式靠 `--x-var` 只在父级选择器定义,脱离上下文后 `var()` 静默退化(border-color→currentColor、background→transparent),肉眼截图可能看不出;必须给每个 `var()` 补 token fallback(`var(--x, var(--q1-color-y))`)并单独断言 computed 颜色值,不能只信"渲染出来了、geometry 对了"(Browser 案:Codex 揪出,自查两轮都没测颜色) |
68
+ | 黑盒行为测不出/自相矛盾 | 先查工具签名与事件可信度(真信任输入 vs 合成 dispatchEvent),再谈"不可知" |
69
+
70
+ ## 量化门槛(全过才算完成)
71
+
72
+ - `npm run check` 全绿(= build + check:shell + check:browser)。**裸 `tsc --noEmit` 恒过 = 没测**(根 tsconfig 是 files:[] 的 solution 文件);类型检查用 `tsc -b tsconfig.app.json --noEmit` 或走 build。
73
+ - 契约与守卫**同步**更新;新断言必须断言规则体/真实几何不变量,不只断言 class 名存在。
74
+ - 浏览器 console 零新错误/警告。
75
+ - 守卫既有坑:fixed-width 黑名单(用 `min(420px,…)`/`20rem` 等值绕)、禁 `rgba(` 字面量(用 color-mix 表达)、hex 守卫下品牌字面量用 oklch。
76
+
77
+ ## 完成后双盲复审(REQUIRED,定稿前)
78
+
79
+ check 全绿、提交后、标记已定稿前,必须过两道**互相独立**的评审,再按严重程度合并呈报:
80
+
81
+ 1. **自查 diff**:不只看语法和明显 bug,重点检查——隐藏副作用、破坏兼容性、边界情况、性能风险、安全风险、命名误导、测试不足、未来维护成本;并逐条回答四问:这个改动会不会破坏旧逻辑?有没有漏掉边界情况?测试是不是只覆盖了最顺利的路径?以后维护的人会不会被这个命名误导?
82
+ 2. **Codex 独立复审**:把同一评审要求原文交给 Codex,**不喂自查结论**,双方独立得出发现后再合并对照。
83
+
84
+ 真问题修复后重跑量化门槛再定稿;判定不修的发现必须记书面理由。发现清单按严重程度排序呈报用户。
85
+
86
+ ## 产出:差异单(交用户拍板的唯一格式)
87
+
88
+ 差异单合并两个来源:/web-design-guidelines 扫描发现项 + Geist 实测差异。每条四栏:**Geist 实测值(或 guideline 条目) | 我们现值 | 层级判定(跟/不跟 + 理由) | 建议**。
89
+ 拍板通过后,每组件独立 commit(混合文件按 hunk 切分),中文提交说明含:问题/思路/验证结果。
90
+
91
+ ## 红线
92
+
93
+ - 未呈差异单就把改动落库 = 违规;批量处理、跳过用户逐件拍板 = 违规——即使该件此前磨过。
94
+ - "check 太慢先跳过"、"截图看着一样" = 未验证;跑完门槛再说完成。
@@ -0,0 +1,17 @@
1
+ # rules(稳定 ID 规则层 —— 建设中)
2
+
3
+ 目标:把 `contracts/interface-guidelines.md` 里确定性的 MUST / NEVER 条目提炼成带**稳定 ID** 的规则(如 `Q1-DS-*`),由包提供的 linter CLI 在每个消费者运行,人工判断留给本 skill。
4
+
5
+ **稳定 ID 清单**:`tooling/scripts/evals/rules-checklist.json`(种子已建;每条带稳定 ID + canonical 出处 + `kind`:deterministic 可静态强制 / judgment 留给 skill·Review)。
6
+
7
+ **现状(coverage gap)**:`q1-design lint` 已实现 `Q1-DS-001`(`--ds-*`)/`Q1-DS-401`(`transition: all`)/`Q1-DS-501`(裸颜色字面量)三条纯机械规则,`q1-design eval` 已实现;其余规则(含带判断成分的 deterministic 规则与全部 judgment 规则)待后续批次。eval 种子见 `tooling/scripts/evals/`(fixtures.json + before/after)。
8
+
9
+ 首批种子规则(取自 `interface-guidelines.md` / `token-naming.md` 的确定性条目):
10
+
11
+ - 禁 `transition: all`(§Animation)
12
+ - 必须 honor `prefers-reduced-motion`(§Animation)
13
+ - icon-only 控件必须有可访问名(§Content)
14
+ - 主题用 token,不用页面局部颜色常量(§Theming)
15
+ - 新代码用 `--q1-*`,不用 `--ds-*`(`token-naming.md`)
16
+
17
+ Review 产出差异单(每条四栏:guideline 条目 / 现值 / 跟不跟 + 理由 / 建议),格式沿用现有评审惯例。
@@ -0,0 +1,14 @@
1
+ # surfaces: forms(表单 / 输入)
2
+
3
+ **Canonical**:`contracts/interface-guidelines.md` §Forms + §Accessibility Tiers(Tier B)。
4
+
5
+ 要点(正文见 canonical):
6
+
7
+ - 每个 input / textarea / select / checkbox / radio / switch 必须有 label 或可访问名。
8
+ - 输入后校验,不拦正常打字;错误就地显示,提交时焦点移到首个阻塞错误。
9
+ - 允许粘贴与密码管理器,除非有书面安全理由。
10
+ - 移动端输入文字 ≥16px;placeholder 仅作示例 / 模式,以 `…` 结尾。
11
+
12
+ **Tier**:多数表单控件是 Tier B —— 靠原生元素拿键盘与 role,共享 focus token,不自造键处理。
13
+
14
+ 相关规则:`tooling/scripts/evals/rules-checklist.json` 的 `2xx`(表单)。只指路,不复制正文。
@@ -0,0 +1,12 @@
1
+ # surfaces: overlays(弹层:modal / drawer / menu / combobox…)
2
+
3
+ **Canonical**:`contracts/interface-guidelines.md` §Interactions + §Accessibility Tiers(Tier A)。
4
+
5
+ 要点(正文见 canonical):
6
+
7
+ - **Tier A**:必须实现对应 APG 模式的完整键盘模型 —— roving tabindex;方向 / `Home` / `End` / `PageUp` / `PageDown`;`Enter` / `Space` 激活;`Esc` 关闭并把焦点还给触发器。
8
+ - 打开 / 关闭都要管理焦点;暴露必需 ARIA(`role`、`aria-expanded` / `aria-selected` / `aria-controls`、状态变化处 `aria-live`)。
9
+ - 键位以「按键 | 行为」表记入页面可访问性节,并由 `check-browser.mjs` 的 runtime 键盘断言锁住。
10
+ - 浮层在视口边缘做碰撞翻转。
11
+
12
+ **参考实现**:Calendar / Tabs(见 §Accessibility Tiers)。只指路,不复制正文。
@@ -0,0 +1,14 @@
1
+ # surfaces(指路)
2
+
3
+ 按 surface 类型把 `contracts/interface-guidelines.md` 的章节与组件契约对应起来。
4
+
5
+ **Canonical**:`contracts/interface-guidelines.md` + `contracts/implementation-map.md`(组件 → 契约映射)。
6
+
7
+ Surface → 章节的路由表见 `SKILL.md`「按 surface 路由」。
8
+
9
+ **已展开的 per-surface**(命名约定 `surfaces-<surface>.md`):
10
+
11
+ - `surfaces-forms.md` —— 表单 / 输入(Tier B)
12
+ - `surfaces-overlays.md` —— 弹层 modal / drawer / menu / combobox(Tier A)
13
+
14
+ **Coverage gap**:其余 surface(table / list、破坏性动作等)的细粒度契约尚未从 `implementation-map.md` 完全展开,见 `references/coverage-gaps.md`。