agentcss 0.0.0-stage → 0.11.3

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 (274) hide show
  1. package/01-tokens/README.md +236 -0
  2. package/01-tokens/behavior/dismissable.js +132 -0
  3. package/01-tokens/behavior/emit.js +76 -0
  4. package/01-tokens/behavior/focus-return.js +81 -0
  5. package/01-tokens/behavior/roving.js +152 -0
  6. package/01-tokens/behavior/typeahead.js +124 -0
  7. package/01-tokens/focus-ring-demo.html +133 -0
  8. package/01-tokens/focus-ring.css +102 -0
  9. package/01-tokens/page.css +244 -0
  10. package/01-tokens/polyfill.js +116 -0
  11. package/01-tokens/responsive-demo.html +171 -0
  12. package/01-tokens/scrollbar-demo.html +194 -0
  13. package/01-tokens/scrollbar.css +179 -0
  14. package/01-tokens/theme-toggle.js +103 -0
  15. package/01-tokens/tokens.css +972 -0
  16. package/01-tokens/typography.css +156 -0
  17. package/02-primitives/badge/README.md +71 -0
  18. package/02-primitives/badge/badge.css +141 -0
  19. package/02-primitives/badge/demo.html +101 -0
  20. package/02-primitives/button/README.md +99 -0
  21. package/02-primitives/button/button.css +353 -0
  22. package/02-primitives/button/demo.html +200 -0
  23. package/02-primitives/card/README.md +145 -0
  24. package/02-primitives/card/card.css +246 -0
  25. package/02-primitives/card/demo.html +170 -0
  26. package/02-primitives/choice/README.md +161 -0
  27. package/02-primitives/choice/choice.css +395 -0
  28. package/02-primitives/choice/demo.html +277 -0
  29. package/02-primitives/combobox/README.md +79 -0
  30. package/02-primitives/combobox/combobox.css +223 -0
  31. package/02-primitives/combobox/combobox.js +485 -0
  32. package/02-primitives/combobox/demo.html +109 -0
  33. package/02-primitives/date-range/README.md +100 -0
  34. package/02-primitives/date-range/date-range.css +206 -0
  35. package/02-primitives/date-range/date-range.js +301 -0
  36. package/02-primitives/date-range/demo.html +104 -0
  37. package/02-primitives/input/README.md +170 -0
  38. package/02-primitives/input/demo.html +246 -0
  39. package/02-primitives/input/input.css +239 -0
  40. package/02-primitives/popover/README.md +80 -0
  41. package/02-primitives/popover/demo.html +150 -0
  42. package/02-primitives/popover/popover.css +187 -0
  43. package/02-primitives/popover/popover.js +331 -0
  44. package/02-primitives/progress/README.md +82 -0
  45. package/02-primitives/progress/demo.html +154 -0
  46. package/02-primitives/progress/progress.css +172 -0
  47. package/02-primitives/select/README.md +95 -0
  48. package/02-primitives/select/demo.html +121 -0
  49. package/02-primitives/select/select.css +151 -0
  50. package/02-primitives/select/select.js +549 -0
  51. package/02-primitives/separator/README.md +63 -0
  52. package/02-primitives/separator/demo.html +84 -0
  53. package/02-primitives/separator/separator.css +73 -0
  54. package/02-primitives/skeleton/README.md +69 -0
  55. package/02-primitives/skeleton/demo.html +110 -0
  56. package/02-primitives/skeleton/skeleton.css +96 -0
  57. package/02-primitives/switch/README.md +65 -0
  58. package/02-primitives/switch/demo.html +115 -0
  59. package/02-primitives/switch/switch.css +370 -0
  60. package/03-patterns/accordion/README.md +121 -0
  61. package/03-patterns/accordion/accordion.css +453 -0
  62. package/03-patterns/accordion/accordion.js +369 -0
  63. package/03-patterns/accordion/demo.html +223 -0
  64. package/03-patterns/content/README.md +103 -0
  65. package/03-patterns/content/content.css +286 -0
  66. package/03-patterns/content/demo.html +88 -0
  67. package/03-patterns/drawer/README.md +79 -0
  68. package/03-patterns/drawer/demo.html +101 -0
  69. package/03-patterns/drawer/drawer.css +129 -0
  70. package/03-patterns/drawer/drawer.js +258 -0
  71. package/03-patterns/dropdown/README.md +78 -0
  72. package/03-patterns/dropdown/demo.html +101 -0
  73. package/03-patterns/dropdown/dropdown.css +135 -0
  74. package/03-patterns/dropdown/dropdown.js +451 -0
  75. package/03-patterns/form-validation/README.md +147 -0
  76. package/03-patterns/form-validation/demo.html +280 -0
  77. package/03-patterns/form-validation/form-validation.css +263 -0
  78. package/03-patterns/list/README.md +150 -0
  79. package/03-patterns/list/demo.html +225 -0
  80. package/03-patterns/list/flip.js +201 -0
  81. package/03-patterns/list/list.css +162 -0
  82. package/03-patterns/nav/README.md +225 -0
  83. package/03-patterns/nav/demo.html +131 -0
  84. package/03-patterns/nav/nav.css +314 -0
  85. package/03-patterns/nav/nav.js +430 -0
  86. package/03-patterns/nav/toc.js +111 -0
  87. package/03-patterns/overlay/README.md +196 -0
  88. package/03-patterns/overlay/demo.html +241 -0
  89. package/03-patterns/overlay/overlay.css +319 -0
  90. package/03-patterns/overlay/overlay.js +563 -0
  91. package/03-patterns/pagination/README.md +114 -0
  92. package/03-patterns/pagination/demo.html +165 -0
  93. package/03-patterns/pagination/pagination.css +195 -0
  94. package/03-patterns/pagination/pagination.js +395 -0
  95. package/03-patterns/reveal/README.md +91 -0
  96. package/03-patterns/reveal/demo.html +106 -0
  97. package/03-patterns/reveal/reveal.css +93 -0
  98. package/03-patterns/reveal/reveal.js +172 -0
  99. package/03-patterns/states/README.md +141 -0
  100. package/03-patterns/states/demo.html +240 -0
  101. package/03-patterns/states/states.css +252 -0
  102. package/03-patterns/tabs/README.md +84 -0
  103. package/03-patterns/tabs/demo.html +139 -0
  104. package/03-patterns/tabs/tabs.css +172 -0
  105. package/03-patterns/tabs/tabs.js +307 -0
  106. package/03-patterns/tooltip/README.md +96 -0
  107. package/03-patterns/tooltip/demo.html +78 -0
  108. package/03-patterns/tooltip/tooltip.css +89 -0
  109. package/03-patterns/tooltip/tooltip.js +288 -0
  110. package/03-patterns/tree/README.md +94 -0
  111. package/03-patterns/tree/demo.html +138 -0
  112. package/03-patterns/tree/tree.css +113 -0
  113. package/03-patterns/tree/tree.js +456 -0
  114. package/04-recipes/analysis-report/README.md +80 -0
  115. package/04-recipes/analysis-report/analysis-report.css +187 -0
  116. package/04-recipes/analysis-report/demo.html +274 -0
  117. package/04-recipes/data-showcase/README.md +45 -0
  118. package/04-recipes/data-showcase/demo.html +247 -0
  119. package/04-recipes/detail-page/README.md +93 -0
  120. package/04-recipes/detail-page/demo.html +55 -0
  121. package/04-recipes/detail-page/detail-page.css +190 -0
  122. package/04-recipes/detail-page/full.html +60 -0
  123. package/04-recipes/detail-page/null.html +60 -0
  124. package/04-recipes/detail-page/partial.html +60 -0
  125. package/04-recipes/detail-page/verify-skeleton.py +19 -0
  126. package/04-recipes/longform/README.md +93 -0
  127. package/04-recipes/longform/agc-memory.svg +4 -0
  128. package/04-recipes/longform/content.html +610 -0
  129. package/04-recipes/longform/content.md +51 -0
  130. package/04-recipes/longform/longform.html +627 -0
  131. package/04-recipes/report/README.md +176 -0
  132. package/04-recipes/report/demo.html +355 -0
  133. package/04-recipes/report/report.css +364 -0
  134. package/04-recipes/table/README.md +103 -0
  135. package/04-recipes/table/demo.html +455 -0
  136. package/04-recipes/table/table.css +372 -0
  137. package/04-recipes/tierA-tokens.css +189 -0
  138. package/09-assets/README.md +74 -0
  139. package/09-assets/bar/README.md +94 -0
  140. package/09-assets/bar/bar.css +166 -0
  141. package/09-assets/bar/bar.js +320 -0
  142. package/09-assets/bar/demo.html +176 -0
  143. package/09-assets/echarts-adapter/demo.html +192 -0
  144. package/09-assets/echarts-adapter/echarts-adapter.js +277 -0
  145. package/09-assets/model-viewer/README.md +155 -0
  146. package/09-assets/model-viewer/demo.html +105 -0
  147. package/09-assets/model-viewer/model-viewer.css +143 -0
  148. package/09-assets/model-viewer/model-viewer.js +423 -0
  149. package/09-assets/scientific-plot/README.md +94 -0
  150. package/09-assets/scientific-plot/demo.html +252 -0
  151. package/09-assets/scientific-plot/scientific-plot.css +141 -0
  152. package/09-assets/scientific-plot/scientific-plot.js +610 -0
  153. package/09-assets/sparkline/README.md +153 -0
  154. package/09-assets/sparkline/demo.html +163 -0
  155. package/09-assets/sparkline/sparkline.css +158 -0
  156. package/09-assets/sparkline/sparkline.js +508 -0
  157. package/API.md +332 -0
  158. package/CHANGELOG.md +3138 -0
  159. package/CODE_OF_CONDUCT.md +64 -0
  160. package/CONTRIBUTING.md +89 -0
  161. package/ERRORS.md +1658 -0
  162. package/LICENSE +21 -0
  163. package/README.md +497 -2
  164. package/SECURITY.md +72 -0
  165. package/START-HERE.md +164 -0
  166. package/SUPPORT.md +109 -0
  167. package/adapters/presentation/README.md +113 -0
  168. package/adapters/presentation/check.js +101 -0
  169. package/adapters/presentation/deck.schema.json +74 -0
  170. package/adapters/presentation/to-doc.js +138 -0
  171. package/ai/START-HERE.md +104 -0
  172. package/ai/behaviors.json +380 -0
  173. package/ai/behaviors.schema.json +61 -0
  174. package/ai/capabilities.json +56 -0
  175. package/ai/cli.js +387 -0
  176. package/ai/components.json +1944 -0
  177. package/ai/components.meta.json +168 -0
  178. package/ai/components.schema.json +220 -0
  179. package/ai/contract.schema.json +147 -0
  180. package/ai/deprecations.json +55 -0
  181. package/ai/deprecations.schema.json +85 -0
  182. package/ai/motion-policy.json +22 -0
  183. package/ai/patch.js +323 -0
  184. package/ai/patch.schema.json +63 -0
  185. package/ai/profiles.json +92 -0
  186. package/ai/tokens.audience.json +55 -0
  187. package/ai/tokens.audience.schema.json +73 -0
  188. package/ai/tokens.json +762 -0
  189. package/ai/tokens.schema.json +58 -0
  190. package/ai/tokens.tree.json +752 -0
  191. package/ai/tokens.tree.schema.json +56 -0
  192. package/ai/validate.js +383 -0
  193. package/dist/01-tokens/behavior/dismissable.js +60 -0
  194. package/dist/01-tokens/behavior/emit.js +21 -0
  195. package/dist/01-tokens/behavior/focus-return.js +31 -0
  196. package/dist/01-tokens/behavior/roving.js +77 -0
  197. package/dist/01-tokens/behavior/typeahead.js +61 -0
  198. package/dist/01-tokens/focus-ring.css +1 -0
  199. package/dist/01-tokens/page.css +1 -0
  200. package/dist/01-tokens/polyfill.js +78 -0
  201. package/dist/01-tokens/scrollbar.css +1 -0
  202. package/dist/01-tokens/theme-toggle.js +61 -0
  203. package/dist/01-tokens/tokens.css +1 -0
  204. package/dist/01-tokens/typography.css +1 -0
  205. package/dist/02-primitives/badge/badge.css +1 -0
  206. package/dist/02-primitives/button/button.css +1 -0
  207. package/dist/02-primitives/card/card.css +1 -0
  208. package/dist/02-primitives/choice/choice.css +1 -0
  209. package/dist/02-primitives/combobox/combobox.css +1 -0
  210. package/dist/02-primitives/combobox/combobox.js +439 -0
  211. package/dist/02-primitives/date-range/date-range.css +1 -0
  212. package/dist/02-primitives/date-range/date-range.js +267 -0
  213. package/dist/02-primitives/input/input.css +1 -0
  214. package/dist/02-primitives/popover/popover.css +1 -0
  215. package/dist/02-primitives/popover/popover.js +257 -0
  216. package/dist/02-primitives/progress/progress.css +1 -0
  217. package/dist/02-primitives/select/select.css +1 -0
  218. package/dist/02-primitives/select/select.js +449 -0
  219. package/dist/02-primitives/separator/separator.css +1 -0
  220. package/dist/02-primitives/skeleton/skeleton.css +1 -0
  221. package/dist/02-primitives/switch/switch.css +1 -0
  222. package/dist/03-patterns/accordion/accordion.css +1 -0
  223. package/dist/03-patterns/accordion/accordion.js +219 -0
  224. package/dist/03-patterns/content/content.css +1 -0
  225. package/dist/03-patterns/drawer/drawer.css +1 -0
  226. package/dist/03-patterns/drawer/drawer.js +229 -0
  227. package/dist/03-patterns/dropdown/dropdown.css +1 -0
  228. package/dist/03-patterns/dropdown/dropdown.js +365 -0
  229. package/dist/03-patterns/form-validation/form-validation.css +1 -0
  230. package/dist/03-patterns/list/flip.js +117 -0
  231. package/dist/03-patterns/list/list.css +1 -0
  232. package/dist/03-patterns/nav/nav.css +1 -0
  233. package/dist/03-patterns/nav/nav.js +322 -0
  234. package/dist/03-patterns/nav/toc.js +76 -0
  235. package/dist/03-patterns/overlay/overlay.css +1 -0
  236. package/dist/03-patterns/overlay/overlay.js +398 -0
  237. package/dist/03-patterns/pagination/pagination.css +1 -0
  238. package/dist/03-patterns/pagination/pagination.js +273 -0
  239. package/dist/03-patterns/reveal/reveal.css +1 -0
  240. package/dist/03-patterns/reveal/reveal.js +138 -0
  241. package/dist/03-patterns/states/states.css +1 -0
  242. package/dist/03-patterns/tabs/tabs.css +1 -0
  243. package/dist/03-patterns/tabs/tabs.js +242 -0
  244. package/dist/03-patterns/tooltip/tooltip.css +1 -0
  245. package/dist/03-patterns/tooltip/tooltip.js +213 -0
  246. package/dist/03-patterns/tree/tree.css +1 -0
  247. package/dist/03-patterns/tree/tree.js +383 -0
  248. package/dist/04-recipes/analysis-report/analysis-report.css +1 -0
  249. package/dist/04-recipes/detail-page/detail-page.css +1 -0
  250. package/dist/04-recipes/report/report.css +1 -0
  251. package/dist/04-recipes/table/table.css +1 -0
  252. package/dist/04-recipes/tierA-tokens.css +1 -0
  253. package/dist/09-assets/bar/bar.css +1 -0
  254. package/dist/09-assets/bar/bar.js +222 -0
  255. package/dist/09-assets/echarts-adapter/echarts-adapter.js +185 -0
  256. package/dist/09-assets/model-viewer/model-viewer.css +1 -0
  257. package/dist/09-assets/model-viewer/model-viewer.js +320 -0
  258. package/dist/09-assets/scientific-plot/scientific-plot.css +1 -0
  259. package/dist/09-assets/scientific-plot/scientific-plot.js +568 -0
  260. package/dist/09-assets/sparkline/sparkline.css +1 -0
  261. package/dist/09-assets/sparkline/sparkline.js +265 -0
  262. package/dist/COSTS.md +56 -0
  263. package/docs/AI-CONTRACT.md +197 -0
  264. package/docs/BACKLOG.md +127 -0
  265. package/docs/BENCHMARK.md +252 -0
  266. package/docs/GUIDANCE.md +154 -0
  267. package/docs/INVARIANT.md +372 -0
  268. package/docs/LAYER-BASELINE.md +158 -0
  269. package/docs/RELEASING.md +311 -0
  270. package/docs/RFC-THEME-SCOPE.md +141 -0
  271. package/docs/ROADMAP.md +182 -0
  272. package/index.html +82 -0
  273. package/package.json +107 -4
  274. package/types/index.d.ts +310 -0
@@ -0,0 +1,252 @@
1
+ # 对标基准
2
+
3
+ > 我们抄了谁、故意不抄谁、以及每一条背后的前提。
4
+ >
5
+ > 这份文档存在的唯一理由:**让"这里为什么是这样"有据可查**。
6
+ > 没有它,同一个问题会在半年后被重新争论一遍——而争论的双方都拿不出当时的理由。
7
+
8
+ ---
9
+
10
+ ## 这份文档怎么用
11
+
12
+ 对标一个项目时问三件事,按顺序问:
13
+
14
+ 1. **它做了什么我们没做的?**(事实)
15
+ 2. **它的做法依赖什么前提?**(前提)
16
+ 3. **我们的前提和它一样吗?**(判定)
17
+
18
+ 只有第 3 问答"一样",才谈得上"学"。
19
+ **前提不同却硬学,是把别人的约束当成自己的目标**——这是对标最常见的翻车方式。
20
+
21
+ 下面五节的每一节都按这个顺序写,并且把"不学"的理由写得和"学"一样详细。
22
+ 理由是:**"不做"也是决策,写下来就不算缺口;不写下来,下次就被当成遗漏。**
23
+
24
+ ---
25
+
26
+ ## 一、Pico CSS —— 产品理念最像我们
27
+
28
+ ### 它是什么
29
+
30
+ 纯 CSS、零构建、零依赖。写语义化 HTML,不用加 class,直接就好看。
31
+ 强制明暗色是**纯 CSS** 实现:`[data-theme="dark"]` 覆盖令牌,**不需要 JS**。
32
+
33
+ ### 🔴 我们故意不同:标签选择器
34
+
35
+ 我们**禁止**裸标签选择器(`input { }`)。理由不是偏好,是作用域事实:
36
+ 一条 `input { }` 的作用域是**整个文档**,包括使用者的页面。
37
+ 详见 `INVARIANT.md` I-1。
38
+
39
+ > 这条是 Pico 的立身之本,也是我们不能要的那部分。
40
+ > 前提不同:Pico 假设自己就是页面的全部;我们假设自己是**嵌进别人页面的组件**。
41
+
42
+ ### 🟢 学到的:强制暗色不该需要 JS
43
+
44
+ 我们的暗色过去靠 JS 写 27 条 inline 属性实现。代价见 `INVARIANT.md` I-4:
45
+ inline style 压过一切样式表,使用者只能加 `!important` 反击。
46
+
47
+ **处置**:改为纯 CSS `data-theme`,JS 不再持有任何色值。
48
+
49
+ ---
50
+
51
+ ## 二、Radix —— 复杂行为最值得研究
52
+
53
+ ### 它是什么
54
+
55
+ 无样式的行为原语库。复杂交互(组合框、弹出层、焦点陷阱)的**可访问性行为**由它负责。
56
+
57
+ ### 🟢 学到的:状态是枚举,写在 DOM 上
58
+
59
+ Radix 把状态写成 `data-state="open"` / `"closed"` / `"indeterminate"`,枚举字符串。
60
+
61
+ 对比另一种写法:状态写成 class(`.is-open`)。
62
+ 差别不在于好不好看,在于**它是不是可被观察的事实**:
63
+
64
+ | | 写在 DOM 属性上 | 写在 class 上 |
65
+ |---|---|---|
66
+ | 取值集合 | 有限、可枚举、可校验 | 无限,拼错不报错 |
67
+ | 能否被查询 | `querySelectorAll('[data-state=open]')` 直接可得 | 只能靠约定 |
68
+ | 出问题时 | 看一眼元素就知道状态 | 要去找哪段 JS 加了这个类 |
69
+
70
+ **处置**:全库状态表达收敛到 `data-*` 枚举,`is-*` 类不再作为状态来源。
71
+
72
+ ---
73
+
74
+ ## 三、Open Props —— 令牌基础设施
75
+
76
+ ### 它是什么
77
+
78
+ 令牌库。一份设计变量,导出成多种格式供不同消费方使用。
79
+
80
+ ### 🔴 我们故意不同:真值来源的方向反着来
81
+
82
+ | | 真值来源 | 产物 |
83
+ |---|---|---|
84
+ | Open Props | JS / JSON | CSS(生成出来的) |
85
+ | 我们 | **CSS** | JSON(生成出来的) |
86
+
87
+ **为什么反着来**:`01-tokens/tokens.css` 里有大量**实测对比度注释**——
88
+ 每个色值配着"这个组合实测对比度是多少、为什么这么选"。
89
+ 这类注释是知识,不是格式;一旦把 CSS 变成生成产物,它们就无处安放。
90
+
91
+ **代价与对策**:反着来就意味着 JSON 会漂移(`INVARIANT.md` I-7)。
92
+ 对策不是"记得同步",而是**同步门禁**:CSS 改了不重新生成,门禁红。
93
+
94
+ ### 🟢 学到的:令牌必须有机器可读导出
95
+
96
+ 散文里的令牌对程序不可用。使用者(包括自动化工具)需要的是能读的结构。
97
+ **处置**:`ai/tokens.json` 由 CSS 生成,`--check` 门禁保证不漂移。
98
+
99
+ ---
100
+
101
+ ## 四、Web Awesome —— framework-agnostic 组件 API
102
+
103
+ ### 它是什么
104
+
105
+ 原生自定义元素,在任何框架里行为一致,不需要适配层。
106
+ 每个组件按**六类 API 面**文档化:slots / 属性 / 方法 / 事件 / CSS 自定义属性 / CSS parts。
107
+
108
+ ### 🔴 我们故意不同:不做自定义元素
109
+
110
+ 我们的前提是"把组件放进宿主页面"。Shadow DOM 会**切断与宿主令牌的继承**,
111
+ 与前提直接冲突。零依赖、零构建是本库存在的理由,不能为了形态一致而牺牲它。
112
+
113
+ ### 🟢 学到的两件事
114
+
115
+ 1. **契约要按面分类**:一个组件不只"有个 class 名",它有插槽、状态、属性、事件。
116
+ 散文描述不清这些边界。→ 结构化进 `ai/components.json`。
117
+ 2. **级联分层**——见下一节,它值得单独讲。
118
+
119
+ ---
120
+
121
+ ## 五、Primer —— 长期治理
122
+
123
+ ### 它是什么
124
+
125
+ GitHub 的设计系统,跨 React / Rails View Component / Figma 多端。
126
+
127
+ ### 🟢 学到的:成熟度是分级,而且每级有判据
128
+
129
+ 组件有 Alpha → Beta → Stable 的生命周期,每级有**明确判据**。
130
+
131
+ 这条为什么重要:**它让约束可以不是一刀切的。**
132
+
133
+ - Stable 组件:约束收紧,改它要过全量门禁
134
+ - Alpha 组件:约束放宽,允许快速迭代、允许不兼容变更
135
+
136
+ ⇒ 不再需要"所有东西都按最严的来",也不再需要"也许以后会放宽"的空头承诺。
137
+
138
+ **处置**:成熟度进 `ai/components.json`,并且**由门禁算出来,不由人声明**。
139
+ (人声明的成熟度会撒谎——没人会主动把自己的组件标成 alpha。)
140
+
141
+ ### 🟢 学到的:把决策也写下来
142
+
143
+ Primer 的原话是 "Document decisions as well as outcomes"。
144
+ 只记结论不记理由,等于半年后重开一遍争论。这份文档就是这条的实践。
145
+
146
+ ---
147
+
148
+ ## 六、级联分层的决定(`@layer`)
149
+
150
+ 这是五家里技术含量最高、也最容易被误用的一条,所以单独写。
151
+
152
+ ### 它解决什么问题
153
+
154
+ 先问:使用者(或自动化工具)为什么会写 `!important`?
155
+ 因为它想改一个样式,**改了不生效**,于是加码。不生效的原因是库的选择器特异性更高。
156
+
157
+ `@layer` 的解法很干净:**把库样式整体放进分层里**。
158
+ 未分层样式**永远**赢过已分层样式,**与特异性无关**。
159
+ ⇒ 使用者写一句 `.card { padding: 20px }` 就够了,不需要比特异性、不需要 `!important`、不需要加长选择器。
160
+
161
+ 这直接拆掉三类失控:
162
+
163
+ 1. `!important` 军备竞赛
164
+ 2. 选择器越写越长(`.page-3 .card .card__body h3`)
165
+ 3. "改不动就去改 `tokens.css`"——因为那是唯一能生效的地方
166
+
167
+ ### 为什么现在不做
168
+
169
+ **目标环境是移动 WebView,基线没有确认。**
170
+
171
+ `@layer` 需要 Chrome 99+ / Safari 15.4+ / Firefox 97+。
172
+ 在桌面浏览器这不算门槛;在移动 WebView 里,**使用者手里那批机型的基线是未知数**。
173
+ 在未知基线上切换层叠模型,等于拿使用者的线上页面去赌。
174
+
175
+ 另外两个真实代价,一并写明:
176
+
177
+ - 分层后**库内部**的覆盖关系会变(同层内仍按特异性,跨层按层序)⇒ 必须全量视觉回归;
178
+ - 库自己若有 `!important`,分层后它的层序**会反转**——早层里的 `!important`
179
+ 会赢过使用者的 `!important`。所以每一处都得说清"它凭什么必须赢"。
180
+
181
+ ### ⚠️ 因此前提不是「清零」,而是「每一处都能归类」
182
+
183
+ 第一版我们把判据写成「交付 CSS 里 `!important` 必须为 0」。**实测后推翻**:
184
+
185
+ ```
186
+ grep 命中 11 处 ⇒ 真解析后 10 处(1 处是注释里的文本,属假命中)
187
+ 10 处全部正当:
188
+ · 9 处在 @media (prefers-reduced-motion: reduce) 内 —— 无障碍
189
+ · 1 处是 [hidden] { display: none } —— 正确性
190
+ ```
191
+
192
+ 清零会逼人删掉 `prefers-reduced-motion` 兜底,那是**让门禁去破坏正确性**。
193
+ 而且对"操作系统级偏好"来说,分层后它赢过使用者的 `!important` 恰恰是对的。
194
+
195
+ ⇒ 判据改成:**每一处都要能归到一个已批准的理由**,归不了类的才红。
196
+
197
+ ### 切换的前提条件(可判)
198
+
199
+ 三条全绿才切,缺一条不切:
200
+
201
+ | # | 前提 | 现状 | 怎么判 |
202
+ |---|---|---|---|
203
+ | 1 | 目标 WebView 基线确认支持 `@layer` | ❌ 未确认 | 实测数据落档,不是"应该支持" |
204
+ | 2 | 每处 `!important` 都能归到已批准理由 | ✅ 10/10 | `05-audit/cascade-layer-gate.py` |
205
+ | 3 | 分层后全量视觉回归绿 | ❌ 未执行 | 现有视觉回归基线全过 |
206
+
207
+ ### 现在做了什么
208
+
209
+ 不是"什么都不做"。门控已经就位,它守着三件事:
210
+
211
+ 1. `@layer` 计数(当前 0);
212
+ 2. 每处 `!important` 的分类(当前 10/10 全归类,注释与字符串里的文本不算命中);
213
+ 3. **一旦有人加了第一条 `@layer`,门禁立刻要求前提 1、3 的实测记录落档**
214
+ (`docs/LAYER-BASELINE.md` 不存在就红)。
215
+
216
+ ⇒ 切换那天不需要重新摸清现状,也不会有人"顺手先切一点"。直接看门禁。
217
+
218
+ ---
219
+
220
+ ## 七、明确不做的事(写了就不算缺口)
221
+
222
+ | 不做 | 为什么 |
223
+ |---|---|
224
+ | 改成 JSON → CSS(Open Props 方向) | 实测对比度注释是知识,生成会丢。改为 CSS 是真值 + JSON 是导出物 + 同步门禁 |
225
+ | 变成自定义元素库 | Shadow DOM 切断宿主令牌继承,与"嵌进宿主页面"的前提冲突 |
226
+ | 自带运行时框架 / 构建步骤 | 零依赖、零构建是本库的存在理由 |
227
+ | 把幻灯片 / 演示语义做进核心 | 核心只提供组件与契约;呈现形态是适配层的事,见 `adapters/presentation/` |
228
+ | 现在就切级联分层 | 移动 WebView 基线未确认,切换等于拿使用者赌 |
229
+
230
+ ---
231
+
232
+ ## 八、怎么验证这批工作没白做
233
+
234
+ | 声称 | 验证方式 |
235
+ |---|---|
236
+ | 令牌有机器可读导出且不漂移 | 改 `tokens.css` 不重新生成 ⇒ 门禁红 |
237
+ | 组件契约是结构化数据 | 注入假组件名 ⇒ 校验器拒 |
238
+ | 成熟度不是人写上去的 | 篡改 JSON 里的成熟度 ⇒ 门禁检出与源码不符 |
239
+ | 档位之间有真实区别 | 同一份文档在 strict 下报错数 > creative 下报错数 |
240
+ | 编辑操作不会破坏文档 | 非法操作 ⇒ 文档字节级不变 |
241
+ | 旧版校验器能读新版文档 | 带未知 `extensions` 的文档被忽略而非判非法 |
242
+ | 演示语义没进核心 | 核心目录检索呈现类关键词 ⇒ 0 命中 |
243
+ | 不变式层没被污染 | `INVARIANT.md` 出现组件名 / 令牌名 / 版本号 / 档位名 ⇒ 门禁红 |
244
+
245
+ ---
246
+
247
+ ## 附:这份文档什么时候该改
248
+
249
+ - **对标了新项目** ⇒ 加一节,按"事实 / 前提 / 判定"三段写
250
+ - **某个"不做"被推翻** ⇒ 不要删行,改成"过去不做,X 起做,因为 Y"——
251
+ 保留推翻的痕迹,否则同样的争论会再来一次
252
+ - **前提条件变了**(比如 WebView 基线确认了)⇒ 改第六节,并按表里的三条判据执行切换
@@ -0,0 +1,154 @@
1
+ # 指引(Guidance)
2
+
3
+ > **这一层是可以整份推翻的。**
4
+ > 它记录的是「以当前模型的能力,怎么做最不容易翻车」。
5
+ > 模型变强 ⇒ 这一层就该变短。**它变短是好事,不是退步。**
6
+
7
+ ---
8
+
9
+ ## 这一层为什么存在,以及它为什么不该被写死
10
+
11
+ 对照 `INVARIANT.md`:那里写的是**事实**(裸标签选择器的作用域是整个文档),
12
+ 这里写的是**补丁**(模型看不全全局 ⇒ 让它改之前先跑影响面报告)。
13
+
14
+ 事实不会变。补丁会失效。
15
+
16
+ 所以:
17
+
18
+ - ❌ 不要把这一层的内容写进门禁——否则三个月后门禁就在拦一个已经不存在的风险,
19
+ 而且**没人敢删**(因为"它一直在那儿,删了会不会出事?")。
20
+ - ✅ 这一层应该定期被拿出来问一句:**这条现在还成立吗?**
21
+ - ✅ 判断标准很简单:**"如果模型是无限强的,还需要这条吗?"**
22
+ 不需要 ⇒ 它随时可以删。
23
+
24
+ ---
25
+
26
+ ## 一、当前模型下有效的做法
27
+
28
+ ### G-1 改之前先看影响面
29
+
30
+ ```bash
31
+ python3 05-audit/impact-report.py
32
+ ```
33
+
34
+ **为什么现在需要**:模型倾向于"就改这一处",看不到它改的文件被谁依赖。
35
+
36
+ **什么时候可以删**:当模型能在一次上下文里可靠地推导出跨文件依赖时。
37
+ (至今还没观察到,所以保留。)
38
+
39
+ ### G-2 一次只改一个语义单元
40
+
41
+ 改完立刻验证,再改下一个。
42
+
43
+ **为什么现在需要**:连续改 5 处再验证,出错时无法定位是哪一处。
44
+ PPT 事故的形态就是"14 页一起改,改完一起崩"。
45
+
46
+ **什么时候可以删**:当验证本身足够快、且失败定位足够精确时。
47
+
48
+ ### G-3 发现自己在写页面级 override ⇒ 停下来
49
+
50
+ ```css
51
+ .slide-3 h1 { ... } /* ← 这是信号,不是解法 */
52
+ ```
53
+
54
+ **为什么现在需要**:模型遇到"改不动"的本能反应是加特异性,而不是改根因。
55
+
56
+ > ⚠️ 注意:这条的**根因部分**是 `INVARIANT.md` I-2(特异性只增不减),
57
+ > 那是事实;"停下来"这个动作是建议。**只有后者属于这一层。**
58
+
59
+ ### G-4 优先改组件,而不是改页面
60
+
61
+ **适用范围**:在 frontend-lib 仓库内改动,或明确按本库范式产出页面时。
62
+
63
+ 本库提供**可选**的组件与骨架,但它不是所有页面的强制实现规范。
64
+ 在本库范式内,要表达"两栏""卡片网格",优先用组件组合而不是手写布局。
65
+
66
+ 组件不适用、或宿主项目已有自己的布局体系时,**用别的实现方式** ——
67
+ 不要为了满足本库的实现偏好而牺牲任务结果。
68
+ 修改已有网站时,宿主原有的框架、组件和样式体系优先。
69
+
70
+ **为什么现在需要**:模型容易写出 `width: 612px; margin-left: 37px` 这类 magic number。
71
+ 它们既不能被门禁检查,也不能在暗色模式下自适应。
72
+
73
+ **什么时候可以删**:当模型默认倾向于复用已有抽象时。
74
+
75
+ ### G-5 需要"Esc 关闭 / 点外部关闭 / 焦点归位 / 方向键游走 / 首字母跳转"时,用核,别自己写
76
+
77
+ 真值源在 `01-tokens/behavior/`(现有 `dismissable`、`focus-return`、`roving`、`typeahead`,
78
+ 以及工具核 `emit`)。用法:
79
+
80
+ 1. 在组件文件里留出注入标记
81
+ `/* ==== BEHAVIOR INJECT BEGIN: roving ==== */` … `END`
82
+ 2. 跑 `python 05-audit/gen-behavior.py`,把核写进来
83
+ 3. 调它(如 `flRoving({ container, items, movable, axis, onMove })`),并在 `destroy()` 里成对销毁
84
+
85
+ ⚠️ 先确认**这个核管的是不是你这件事** —— "看起来像"不等于"是":
86
+
87
+ | 你要的 | 用不用核 |
88
+ |---|---|
89
+ | Esc / 点外部关闭 | `dismissable` |
90
+ | 关闭后焦点还给谁 | `focus-return` |
91
+ | 一组项里用方向键**移动 DOM 焦点** | `roving` |
92
+ | 打字母/汉字**跳到**匹配项(不是过滤) | `typeahead` |
93
+ | 组件要**对外发通知** | `emit`(`flEmit(root, 'fl-change', { value })`) |
94
+ | 方向键是**翻页 / 展开收起**这类命令 | **不用** —— 那不是游走,是命令键 |
95
+ | 焦点常驻触发器、靠 `aria-activedescendant` 报位置 | **不用** —— 核靠 `e.target` 判断当前项,这种模式下焦点根本不在项上 |
96
+ | APG 菜单(菜单项按规范全 `tabindex="-1"`) | 用 `roving`,但传 `tabindex: false`(只接管步进,不碰 tabindex) |
97
+ | 有输入框、**打字即过滤** | **不用 `typeahead`** —— 那是过滤,不是跳转 |
98
+
99
+ **为什么现在需要**:14 个组件 JS 里,Esc 关闭被手写了 10 处、点击外部 7 处、
100
+ roving tabindex 33 处。每多一个副本,就多一个"这处忘了修"的机会 ——
101
+ 而且这种漏**不报错**(同一件事在不同组件里手感不一样,只有键盘用户会遇到)。
102
+
103
+ **什么时候可以删**:当这类行为只剩一处实现时(那正是本条的目的)。
104
+
105
+ ### G-6 贴进 system prompt 的极简版
106
+
107
+ > 🔴 **先把适用范围说清楚(这段被误读过)**
108
+ >
109
+ > 下面这段的适用范围是:**在 frontend-lib 仓库里改代码**,
110
+ > 或**明确要按本库范式产出页面**这两类任务。
111
+ >
112
+ > 它**不是**所有 HTML / 网站任务的通用规则:
113
+ >
114
+ > - 改一个已有网站时,宿主项目原有的框架、组件和样式体系**优先**;
115
+ > - 本库组件不适用时,用别的实现方式,不要为满足本库的偏好牺牲任务结果;
116
+ > - PPT、文档、邮件等非网页输出形态**不适用**这一段。
117
+
118
+ ```
119
+ 维护 frontend-lib 或严格按本库范式写页面时,遵守以下编辑边界:
120
+ 1. 不写裸标签选择器(a{} h1{} button{})——一律挂组件根类
121
+ 2. 不新增裸颜色与裸间距——用 tokens
122
+ 3. 不改 01-tokens/tokens.css,除非任务明确要求改令牌
123
+ 4. 局部改动优先改组件/改令牌;确需页面级 override 时要知道它的代价
124
+ (特异性只增不减,见 INVARIANT I-2),不是"绝对不许写"
125
+ 5. 改组件样式后必须重跑该组件的视觉基线
126
+ 6. 改之前先跑 impact-report.py 看影响范围
127
+ 7. 需要 Esc 关闭 / 点外部关闭 / 焦点归位 / 方向键游走 / 打字定位 这类行为时,用 01-tokens/behavior/ 里的核,别自己重写
128
+ 发现自己在写页面级 override ⇒ 先问一句"根因是不是在组件里"
129
+ ```
130
+
131
+ > 这段是**可替换的**。它是"当前最好用的一段提示词",不是规范。
132
+ > 换模型、换版本 ⇒ 改这段,不需要改任何门禁。
133
+ > 它的**适用范围**同样可以改 —— 但改之前先想清楚:放宽给谁,会不会又变成别人的天花板。
134
+
135
+ ---
136
+
137
+ ## 二、这一层**不**做的事
138
+
139
+ | 不做 | 归属 |
140
+ |---|---|
141
+ | 不定义"哪些组件存在" | `ai/components.json`(Contract) |
142
+ | 不定义"strict 档能用什么" | `ai/profiles.json`(Contract) |
143
+ | 不断言"裸选择器会污染宿主" | `INVARIANT.md` I-1(事实) |
144
+ | 不把上面任何一条接进 `check-all.sh` | —— 门禁只管事实和契约 |
145
+
146
+ ---
147
+
148
+ ## 三、维护规则
149
+
150
+ 1. **每条 G-n 必须写明「什么时候可以删」。** 写不出删除条件的,说明它不是指引,
151
+ 要么它其实是 Invariant(搬走),要么它其实什么都没说(删掉)。
152
+ 2. **每次模型换代,过一遍这一层。** 能删的就删,删不掉的要写清楚为什么还删不掉。
153
+ 3. **这一层的长度是健康指标。** 它越短,说明模型越强、我们的补丁越少。
154
+ **不要以"这一层写得很全"为荣。**