agentcss 0.15.0 → 0.16.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.
@@ -440,6 +440,35 @@
440
440
  ========================================================================== */
441
441
  }
442
442
 
443
+ /* ============================================================================
444
+ 容器查询的**槽位标记**(0.16.0)
445
+
446
+ `[data-cq]` 让一个元素成为"查询容器":里面的组件按**自己所在的槽宽**
447
+ 自适应,而不是按视口宽度。`card--row` 与 `analysis-report` 已用它切换布局。
448
+
449
+ 🔴 为什么是显式属性,而不是给组件自动加 `container-type`
450
+ ① `container-type: inline-size` 会带上 `contain: layout style inline-size`
451
+ ⇒ 元素变成 fixed / absolute 后代的**包含块**。
452
+ 若给 `.page` 或抽屉的宿主自动加上,抽屉(position: fixed)
453
+ 会被关进那个盒子里 —— 静默的、只在特定嵌套下出现的破坏。
454
+ ② 库不知道"槽"在哪:同一张卡片既可能在 320px 侧栏,也可能在 900px 主列。
455
+ 只有页面作者知道该把哪一层声明成容器。
456
+
457
+ ⇒ 契约:**加了 `data-cq` 的那一层,就是组件眼里的"窗口"**。
458
+ 不加 ⇒ 整条容器查询不生效(实测:没有容器时 `@container` **不会**退回视口),
459
+ 组件仍按视口断点工作 —— 与 0.15.0 完全一致。
460
+
461
+ ⚠️ 不要把它加在会承载抽屉 / 全屏浮层的祖先上(理由见 ①)。
462
+ 它下面可以放 popover / dropdown(那些用 absolute,不受影响)。
463
+
464
+ ⚠️ 为什么在 tokens.css 而不是 page.css:tokens.css 是**唯一必须引入**的文件
465
+ ("只拿一个组件"的最小页面也带着它)。放在 page.css 里,
466
+ 按需取用的页面会拿到一份永远不生效的 `@container`。
467
+ ========================================================================= */
468
+ [data-cq] {
469
+ container-type: inline-size;
470
+ }
471
+
443
472
  /* ============================================================================
444
473
  无障碍兜底 —— 这一段必须随 token 一起走,不许删
445
474
  ========================================================================= */
@@ -85,10 +85,30 @@ hover 只改 **`transform`** 和 **`box-shadow`**,这两个属性不触发回
85
85
  | `.card--linked` | 整卡可点 | 内部必须有真实 `<a>`/`<button>` |
86
86
  | `.card--selected` | 选中态 | inset shadow,不是改 border |
87
87
  | `.card--compact` | 紧凑 | 两档够了,第三档说明密度没规划 | —— demo 未演示,是留给复用者的钩子
88
- | `.card--row` | 横向 | 560px 以下自动回退纵向 |
88
+ | `.card--row` | 横向 | 560px 以下回退纵向;槽位标了 `data-cq` 时按**槽宽**判断(见下) |
89
89
 
90
90
  ---
91
91
 
92
+ ## 横向卡片看槽宽,不看屏幕
93
+
94
+ `.card--row` 有两套断点,按有没有容器祖先分流:
95
+
96
+ ```html
97
+ <!-- 侧栏里:1440px 的屏幕上依然是竖排,因为槽只有 320px。
98
+ 宽度由你的布局决定;这一层就是组件眼里的"槽"。 -->
99
+ <aside data-cq>
100
+ <div class="card card--row">…</div>
101
+ </aside>
102
+ ```
103
+
104
+ - **没有 `data-cq`** ⇒ `@media (max-width: 560px)` 说了算,与本版之前完全一致。
105
+ - **有 `data-cq`** ⇒ 以**槽宽**为准(35rem = 560px):槽窄则竖排、槽宽则横排,
106
+ 连"视口很窄但槽很宽"那种情况也以槽为准。
107
+ - 为什么必须显式标记:`container-type` 会让元素成为 `position: fixed` 后代的包含块。
108
+ 组件自己加会把抽屉/浮层关进卡片里 —— 这个决定只能由页面作者做。
109
+
110
+ 判据:`container-query-check.js`(含"剥掉 `@container` 布局不塌"的降级验证)。
111
+
92
112
  ## 🔴 整卡可点:正确做法 vs 错误做法
93
113
 
94
114
  **错误**:给 `<div>` 加 `onclick`。
@@ -209,6 +209,43 @@
209
209
  }
210
210
  }
211
211
 
212
+ /* ---------------------------------------------------------------- 按槽宽(0.16.0)
213
+ 🔴 上面那条是**视口**断点,它在一种真实布局里是错的:
214
+ 1440px 的页面上,右侧 320px 栏里放一张 `.card--row` ——
215
+ 视口很宽,于是 `@media` 不触发,卡片保持横排:
216
+ 160px 的图 + 160px 的文字,标题换行三行。
217
+ 症状不来自组件,来自"拿视口宽度替槽宽度做了决定"。
218
+
219
+ ⇒ 槽位被标成 `[data-cq]`(见 01-tokens/tokens.css 的「容器查询的槽位标记」)时,以**槽宽**为准。
220
+ 两条都写,是因为"窄槽 + 宽视口"和"宽槽 + 窄视口"是两个方向:
221
+ 槽窄 ⇒ 竖排;槽宽 ⇒ 横排(后者覆盖上面那条视口断点)。
222
+ ⚠️ 容器查询不匹配时**不会**撤销任何规则 —— 所以"退回去"必须显式写一条。
223
+ 这也是为什么不能只写 `@container (max-width)` 一条。
224
+
225
+ ⚠️ 没有 `[data-cq]` 祖先时这两条整段不生效(实测:`@container` 不会退回视口),
226
+ 行为与 0.15.0 完全一致 —— 这条改动对未标记的页面是**零影响**。
227
+ ---------------------------------------------------------------- */
228
+ @container (max-width: 35rem) {
229
+ .card--row { flex-direction: column; }
230
+ .card--row .card__media {
231
+ width: 100%;
232
+ aspect-ratio: 16 / 9;
233
+ border-radius: calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;
234
+ }
235
+ }
236
+ @container (min-width: 35rem) {
237
+ .card--row {
238
+ flex-direction: row;
239
+ align-items: stretch;
240
+ }
241
+ .card--row .card__media {
242
+ flex: none;
243
+ width: 160px;
244
+ aspect-ratio: auto;
245
+ border-radius: calc(var(--r-md) - 1px) 0 0 calc(var(--r-md) - 1px);
246
+ }
247
+ }
248
+
212
249
  /* ---------------------------------------------------------------- 无障碍兜底
213
250
  card 的 hover 位移属于"小幅位移",reduced-motion 下应当去掉抬起,
214
251
  只保留阴影变化 —— 阴影不属于前庭敏感类动效。
@@ -60,6 +60,24 @@ analysis-report.css ← 本示例的局部样式
60
60
  3. 辅助栏 `position: sticky` 必须配 `align-self: start`,
61
61
  否则 sticky 在 Grid 里不生效(默认 stretch 会撑满整列高度)。
62
62
 
63
+ ### 分屏 / 嵌入:断点看槽宽
64
+
65
+ 上面那条断点对**分屏**是错的:1440px 的屏幕上把报告放进 700px 的阅读栏,
66
+ 视口 ≥1024 ⇒ 硬排 `1fr + 15rem`,正文每行只剩七八个字。
67
+
68
+ ```html
69
+ <!-- 700px 的阅读栏;宽度由你的布局决定,这一层就是"槽" -->
70
+ <div data-cq>
71
+ <div class="report">…</div>
72
+ </div>
73
+ ```
74
+
75
+ 槽位标了 `[data-cq]` ⇒ 以槽宽为准:槽 < 64rem 时回到单栏(`aside` 同时退回
76
+ `position: static`,否则空侧栏会跟着滚)。没有标记 ⇒ 行为与本版之前一致。
77
+
78
+ ⚠️ `data-cq` 不要加在承载抽屉/全屏浮层的祖先上(`container-type` 会成为
79
+ `position: fixed` 的包含块)。
80
+
63
81
  ## 已知限制
64
82
 
65
83
  - 断点写不了 `var()` —— 媒体查询里的 `64rem` 与令牌 `--bp-lg`
@@ -58,6 +58,45 @@
58
58
  }
59
59
  }
60
60
 
61
+ /* ---------------------------------------------------------------- 按槽宽(0.16.0)
62
+ 🔴 上面那条断点对"分屏 / 嵌入"是错的:
63
+ 1440px 的屏幕上,报告被放进右侧 700px 的阅读栏(列表在左)——
64
+ 视口 ≥1024,于是硬排成 `1fr + 15rem`:正文 460px、侧栏 240px,
65
+ 正文每行只剩七八个字,而侧栏空空荡荡。
66
+
67
+ ⇒ 槽位标了 `[data-cq]`(见 tokens.css 的「容器查询的槽位标记」)时,以**槽宽**为准。两条方向都写:
68
+ 窄槽 ⇒ 回到单栏(撤销上面的并排)
69
+ 宽槽 ⇒ 并排(覆盖"窄视口"那条)
70
+ ⚠️ 容器查询不匹配**不会**撤销规则,所以"退回去"必须显式写 ——
71
+ 只写 `@container (min-width)` 一条,窄槽在宽视口上仍然是并排的。
72
+
73
+ ⚠️ 没有 `[data-cq]` 祖先时整段不生效,未标记的页面行为不变。
74
+ ---------------------------------------------------------------- */
75
+ @container (max-width: 63.99rem) {
76
+ .report__body {
77
+ grid-template-columns: minmax(0, 1fr);
78
+ gap: var(--sp-6);
79
+ }
80
+ .report__aside {
81
+ position: static;
82
+ max-height: none;
83
+ overflow: visible;
84
+ }
85
+ }
86
+ @container (min-width: 64rem) {
87
+ .report__body {
88
+ grid-template-columns: minmax(0, 1fr) 15rem;
89
+ gap: var(--sp-7);
90
+ }
91
+ .report__aside {
92
+ position: sticky;
93
+ top: var(--sp-4);
94
+ align-self: start;
95
+ max-height: calc(100vh - var(--sp-8));
96
+ overflow: auto;
97
+ }
98
+ }
99
+
61
100
  /* ---------- 正文节奏 ---------- */
62
101
  .report__main > section + section { margin-top: var(--sp-6); }
63
102
  .report__main h2 { margin-top: 0; }
package/CHANGELOG.md CHANGED
@@ -16,6 +16,78 @@
16
16
 
17
17
  (无)
18
18
 
19
+ ## [0.16.0] - 2026-10-31
20
+
21
+ ### 布局 · 断点看**槽宽**,不看视口(`[data-cq]` + `@container`)
22
+
23
+ 全库 44 个 CSS 文件里 `@container` 曾经是 **0 处**,所有断点都是 `@media`。
24
+ 有一类布局因此是错的,而且**在库自己的 demo 里永远测不出来**:
25
+
26
+ - 1440px 页面上,右侧 320px 栏里放 `.card--row` ⇒ 视口断点不触发 ⇒
27
+ 卡片保持横排:160px 图 + 160px 文字,标题折三行;
28
+ - 同一个页面上,报告被放进 700px 阅读栏 ⇒ 视口 ≥1024 ⇒ 硬排 `1fr + 15rem`,
29
+ 正文每行七八个字。
30
+
31
+ 这是**参考系错了**:视口宽度不等于组件所在槽位的宽度。
32
+
33
+ 做法是显式标记 + 两个方向都写:
34
+
35
+ ```html
36
+ <aside class="rail" data-cq> <!-- 这一层就是组件眼里的"窗口" -->
37
+ <div class="card card--row">…</div>
38
+ </aside>
39
+ ```
40
+
41
+ - `[data-cq] { container-type: inline-size }` 放在 **`tokens.css`**(唯一必须引入的文件),
42
+ 不是 `page.css` —— 否则"只拿一个组件"的页面会拿到一份永不生效的 `@container`;
43
+ - **不自动给组件加 `container-type`**:它会带上 `contain: layout`,
44
+ 让元素成为 `position: fixed` 后代的包含块 ⇒ 抽屉/全屏浮层会被关进那个盒子;
45
+ - **没有 `data-cq` 时整条不生效**(实测:没有容器祖先时 `@container` **不会**退回视口),
46
+ 未标记页面的渲染与 0.15.0 完全一致;
47
+ - **两个方向都写**:`@container (max-width)` 只能"变窄",撤销不了一条已生效的
48
+ `@media`(不匹配不会撤销任何规则),所以"标记过的槽以槽为准"还得写 `min-width` 那条。
49
+
50
+ 判据 `container-query-check.js` 10 条,覆盖 card 与 report 的
51
+ 「槽窄 / 槽宽 / 未标记 / 视口回退 / 容器盖过视口」五种情形,外加一条
52
+ **降级证明**:把 `@container` 整块从 CSS 文本里剥掉再跑 —— 布局必须不再按槽切换、
53
+ 且不塌(`cardH>0`、图片仍 160px)。老引擎(Chromium 97)看到的就是剥掉后的那一份。
54
+
55
+ ### 判据 · 文档事实漏了两种写法,英文 README 因此落后两个版本
56
+
57
+ `doc-facts` 只认中文句式「共 N 个(stable A / beta B)」与「N 个组件」,
58
+ 而英文 README 写的是 `**35** components (31 stable / 4 beta)`:
59
+
60
+ | | 文档 | 实际 |
61
+ |---|---|---|
62
+ | 组件数 | 35(31 stable / 4 beta) | **37(37 stable / 0 beta)** |
63
+ | primitives 条数 | 13 | **15** |
64
+ | 表里缺的行 | — | `metric`、`delta` |
65
+
66
+ 两个版本(0.14.0、0.15.0)里它每轮都通过,因为门禁**读不到那种写法**。
67
+ 现在补两条判据:英文的 `N components (X stable / Y beta)`(两种语序都认)、
68
+ 分档标题 `### primitives (N)`;自检各加一条反向用例,另加一条正向基线
69
+ (写对了必须绿)。**"清单里少了什么"比"数字错"更难发现** —— 所以分档条数也进了门禁。
70
+
71
+ ### 更正 · 上一轮盘点里把 `@layer` 排成 P1,是错的
72
+
73
+ `docs/CONVENTIONS.md` 第七节与 `docs/LAYER-BASELINE.md` 早有结论:7 行真机实测里
74
+ Android 14 · 百度浏览器(Chromium 97)**缺 `@layer`**,而 `@layer { … }` 不支持时是
75
+ **整块丢弃** ⇒ 那一层样式直接消失。切层在这个库里不是改进,是会让部分浏览器变白屏。
76
+ 记进 `internal/ERRORS.md` E167:**"0 处"只说明现状,不说明原因;有门禁守着的"没有",
77
+ 几乎都是决定。**
78
+
79
+ ### 体积
80
+
81
+ 分两个口径写,因为这两个数差 **16 倍**,只看一个会得出相反结论:
82
+
83
+ | 口径 | 变化 |
84
+ |---|---|
85
+ | **发布载荷**(`dist/*.css` gzip) | card **+35 B** · report **+51 B** · tokens **+36 B**(合计 **+122 B**) |
86
+ | **源码**(含注释,`size-baseline` 量的就是这个) | 全库 gzip 259.7 → 261.5 KB(**+0.71%**);card +16.9%、report +17.4% |
87
+
88
+ 差异全在注释:`dist/` 剥注释,源码保留 —— 而"为什么两个方向都要写"这件事
89
+ 必须留在源码里,否则下一个人会删掉一半。基线按显式重录记下(`--record`)。
90
+
19
91
  ## [0.15.0] - 2026-10-31
20
92
 
21
93
  ### 行为 · dropdown 的「打字跳项」收编 typeahead 核(**最后一个 beta 升 stable**)
package/CONTRIBUTING.md CHANGED
@@ -8,7 +8,7 @@ npm run gate # 全量:含浏览器类
8
8
  npm run gate:fast # 只跑静态层,不用装浏览器
9
9
  ```
10
10
 
11
- 全量是 **214 道门禁**(4 路并发实测约 9 分钟 / 退出码 0;单道耗时累加 1691 秒,
11
+ 全量是 **215 道门禁**(4 路并发实测约 9 分钟 / 退出码 0;单道耗时累加 1691 秒,
12
12
  组件层要起浏览器,还要逐张比 96 张视觉截图。0.11.15 起默认 4 路并发)。
13
13
  只想确认没改坏静态契约的话用 `gate:fast`,几秒到几分钟。
14
14
 
package/README.md CHANGED
@@ -171,9 +171,9 @@ Three mistakes the template above already avoids:
171
171
 
172
172
  ## Components
173
173
 
174
- **35** components (31 stable / 4 beta). Each directory holds a `README.md` (why it is built this way) and a `demo.html` (markup you can copy).
174
+ **37** components (stable 37 / beta 0). Each directory holds a `README.md` (why it is built this way) and a `demo.html` (markup you can copy).
175
175
 
176
- ### primitives (13)
176
+ ### primitives (15)
177
177
 
178
178
  | Component | Root class | Purpose |
179
179
  |---|---|---|
@@ -183,7 +183,9 @@ Three mistakes the template above already avoids:
183
183
  | `choice` | `choice` | One control for radio, checkbox and native-select appearance |
184
184
  | `combobox` | `combo` | Searchable input that can hold multiple tags |
185
185
  | `date-range` | `drange` | Start/end date range with preset shortcuts |
186
+ | `delta` | `delta` | Change value: direction and sign, **describes direction only, never judges good or bad** |
186
187
  | `input` | `field` | Text field plus its label, hint and error |
188
+ | `metric` | `metric` | Metric block: one label, one value, one line of context; missing data is a first-class state |
187
189
  | `popover` | `popover` | Floating panel anchored to its trigger |
188
190
  | `progress` | `progress` | Progress bar and ring |
189
191
  | `select` | `select` | Custom dropdown (not the native element) |
package/START-HERE.md CHANGED
@@ -37,7 +37,7 @@
37
37
  | 按钮 | `02-primitives/button/button.css` | 357 | — | 几乎总要 |
38
38
  | 输入框 | `02-primitives/input/input.css` | 239 | — | 有表单就要 |
39
39
  | 标签 / 徽章 | `02-primitives/badge/badge.css` | 141 | — | 有状态标记就要("已披露""停牌") |
40
- | 卡片 | `02-primitives/card/card.css` | 246 | — | 有分组内容就要 |
40
+ | 卡片 | `02-primitives/card/card.css` | 283 | — | 有分组内容就要 |
41
41
  | 单选 / 多选 | `02-primitives/choice/choice.css` | 395 | — | 单选 / 多选就要 |
42
42
  | 下拉选择 | `02-primitives/select/select.css` | 151 | **必需 541** (`select.js`) | 原生 select 的外观或交互不够用就要 |
43
43
  | 可搜索选择 | `02-primitives/combobox/combobox.css` | 223 | **必需 477** (`combobox.js`) | 选项多到要搜索,或要选多个并留成标签就要 |
@@ -63,7 +63,7 @@
63
63
  | delta | `02-primitives/delta/delta.css` | 113 | — | |
64
64
  | metric | `02-primitives/metric/metric.css` | 157 | — | |
65
65
  | reveal | `03-patterns/reveal/reveal.css` | 93 | 可选 175 (`reveal.js`,入场动效,纯增强;没有它内容直接可见) | |
66
- | analysis-report | `04-recipes/analysis-report/analysis-report.css` | 187 | — | |
66
+ | analysis-report | `04-recipes/analysis-report/analysis-report.css` | 226 | — | |
67
67
  | detail-page | `04-recipes/detail-page/detail-page.css` | 190 | — | |
68
68
  | report | `04-recipes/report/report.css` | 364 | — | |
69
69
  | table | `04-recipes/table/table.css` | 387 | — | |
package/SUPPORT.md CHANGED
@@ -94,6 +94,10 @@ grep 一条都数不到),还有 `skip "…"`(这台机器跑不了的门
94
94
  3. **`conic-gradient`**(环形进度)—— Safari 15.4+ 才支持
95
95
  4. **滚动条样式** —— `::-webkit-scrollbar` 与 Firefox 的 `scrollbar-width` 是两套语法,组件里都写了
96
96
  5. **iOS 输入框的 `font-size < 16px` 会触发缩放** —— 输入类组件已避免
97
+ 6. **`@container`**(0.16.0 起使用,`[data-cq]` 标记的槽位)—— 与 `@layer` 同类:
98
+ 不支持时**整块丢弃**。区别在于**基础样式不在块里**,所以降级后与标记前完全一致;
99
+ `container-query-check.js` 每次运行都会把 `@container` 剥掉再跑一遍,证明布局不塌。
100
+ Chromium 97 不会白屏,只会"按视口断点"(即旧行为)。
97
101
 
98
102
  ## 已知限制(已验证存在,不是"待验证")
99
103
 
@@ -114,3 +118,6 @@ grep 一条都数不到),还有 `skip "…"`(这台机器跑不了的门
114
118
  3. popover 的碰撞翻转(上面"已知限制"第 1 条)
115
119
 
116
120
  ⚠️ 在补齐之前,请勿把「移动 WebView 支持」当作已验证的能力对外承诺。
121
+
122
+ > 2026-10-31 记:前两项**卡在设备上** —— 手上没有可用的安卓机,也没有 iOS 设备,
123
+ > 云真机需要账号。这条不是"忘了做",是"缺外部条件",所以不写进版本承诺。
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "generatedBy": "05-audit/gen-ai-contract.py",
4
- "libraryVersion": "0.15.0",
4
+ "libraryVersion": "0.16.0",
5
5
  "$comment": "机器可读的组件契约。slots = BEM 元素名(在本库里元素名就是插槽名),states.enum = 组件会在 DOM 上写出的 data-* 取值,states.legacyClass = 仍未收敛到 data 属性的历史状态类(INVARIANT I-8 未达标)。",
6
6
  "maturityCriteria": {
7
7
  "alpha": "缺 demo.html 或缺 05-audit 下的专属门禁 ⇒ 还没被机器验证过,不要用",
@@ -1 +1 @@
1
- :root {--raw-paper:#f6f7f8;--raw-surface:#ffffff;--raw-surface-sunken:#f1f3f5;--raw-surface-raised:#ffffff;--raw-scrollbar-thumb:#7A808A;--raw-scrollbar-thumb-hov:#6E747E;--raw-text-primary:#15181c;--raw-text-secondary:#4f555e;--raw-text-tertiary:#606770;--raw-text-on-accent:#ffffff;--raw-text-on-solid:#ffffff;--raw-skeleton-bg:#e9ecef;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.72);--raw-border-control:#868b94;--raw-border-decor:#e2e5e9;--raw-border-decor-str:#c8cdd4;--raw-danger:#c0392b;--raw-danger-hover:#8f1e17;--raw-scrim:rgba(21, 24, 28, 0.4);--raw-success:#2f6b3a;--raw-warning:#8a5a00;--raw-info:#1d5f8a;--raw-danger-bg:#fdeeec;--raw-success-bg:#eaf2e6;--raw-warning-bg:#fbf1dd;--raw-info-bg:#e8f1f8;--raw-dir-up:#c0392b;--raw-dir-down:#2f6b3a;--raw-accent:#1b4d8f;--raw-switch-on:#1b4d8f;--raw-accent-hover:#163a6d;--raw-accent-soft:#e6eef7;--raw-tooltip-bg:#15181c;--raw-tooltip-fg:#f6f7f8;--raw-tooltip-border:#15181c;--paper:var(--raw-paper);--surface:var(--raw-surface);--surface-sunken:var(--raw-surface-sunken);--surface-raised:var(--raw-surface-raised);--scrollbar-size:10px;--scrollbar-size-thin:6px;--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--scrollbar-radius:5px;--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--skeleton-h:1em;--skeleton-size:40px;--skeleton-duration:1.4s;--ease-out:cubic-bezier(0.23, 1, 0.32, 1);--progress-h:6px;--progress-dur:240ms;--r-full:999px;--ring-size:64px;--ring-thickness:8px;--progress:0%;--progress-num:0;--z-popover:60;--popover-min-w:200px;--popover-max-w:320px;--popover-p:var(--sp-3);--popover-gap:8px;--popover-dur:140ms;--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-hover:var(--raw-danger-hover);--scrim:var(--raw-scrim);--success:var(--raw-success);--warning:var(--raw-warning);--info:var(--raw-info);--danger-bg:var(--raw-danger-bg);--success-bg:var(--raw-success-bg);--warning-bg:var(--raw-warning-bg);--info-bg:var(--raw-info-bg);--dir-up:var(--raw-dir-up);--dir-down:var(--raw-dir-down);--accent:var(--raw-accent);--switch-on:var(--raw-switch-on);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-fg:var(--raw-tooltip-fg);--tooltip-border:var(--raw-tooltip-border);--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:clamp(1rem, 0.95rem + 0.3vw, 1.25rem);--sp-5:clamp(1.25rem, 1.15rem + 0.7vw, 1.75rem);--sp-6:clamp(1.5rem, 1.3rem + 1.2vw, 2.25rem);--sp-7:clamp(2rem, 1.7rem + 1.8vw, 3.5rem);--sp-8:clamp(2.5rem, 2.1rem + 2.4vw, 4.5rem);--bp-sm:30rem;--bp-md:48rem;--bp-lg:64rem;--bp-xl:80rem;--fs-xs:0.75rem;--fs-sm:0.875rem;--fs-base:clamp(1rem, 0.95rem + 0.3vw, 1.125rem);--fs-md:clamp(1.125rem, 1.05rem + 0.5vw, 1.3125rem);--fs-lg:clamp(1.3125rem, 1.2rem + 0.7vw, 1.5rem);--fs-xl:clamp(1.5rem, 1.3rem + 1.2vw, 1.875rem);--fs-2xl:clamp(1.75rem, 1.45rem + 1.8vw, 2.5rem);--lh-tight:1.25;--lh-base:1.7;--lh-loose:1.85;--measure-page:52rem;--tracking-title:-0.02em;--r-sm:6px;--r-xs:3px;--r-md:10px;--r-lg:14px;--r-pill:999px;--shadow-1:0 1px 2px rgba(31, 29, 25, 0.05), 0 1px 3px rgba(31, 29, 25, 0.06);--shadow-2:0 2px 4px rgba(31, 29, 25, 0.05), 0 6px 16px rgba(31, 29, 25, 0.08);--dur-fast:120ms;--dur-base:180ms;--dur-slow:280ms;--ease-out:cubic-bezier(0.23, 1, 0.32, 1);--ease-in-out:cubic-bezier(0.77, 0, 0.175, 1);--ease-drawer:cubic-bezier(0.32, 0.72, 0, 1);--lift-sm:1px;--lift-md:2px;--lift-lg:8px;--z-base:0;--z-sticky:10;--z-header:20;--z-raised:5;--z-overlay:30;--z-modal:40;--z-toast:50;--sz-touch:44px;--sz-touch-sm:32px;}@media (prefers-reduced-motion:reduce) {*, *::before, *::after {animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;scroll-behavior:auto !important;}}:focus-visible {outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm);}:root {--measure-prose:34em;--measure-title:20em;--measure-lede:32em;--measure-pull:30em;--measure-aside:32em;}:root:lang(en), :root:lang(en-US), :root:lang(en-GB), :root:lang(fr), :root:lang(de), :root:lang(es), :root:lang(pt), :root:lang(ru), :root:lang(el), :root:lang(tr), :root:lang(vi) {--measure-prose:68ch;--measure-title:34ch;--measure-lede:62ch;--measure-pull:58ch;--measure-aside:56ch;}:root:lang(ar) {--measure-prose:60ch;--measure-title:30ch;--measure-lede:56ch;--measure-pull:52ch;--measure-aside:50ch;}:root:lang(hi), :root:lang(th), :root:lang(km), :root:lang(my) {--measure-prose:56ch;--measure-title:28ch;--measure-lede:52ch;--measure-pull:48ch;--measure-aside:46ch;}:root:lang(zh), :root:lang(zh-CN), :root:lang(zh-TW), :root:lang(ja), :root:lang(ko) {--measure-prose:34em;--measure-title:20em;--measure-lede:32em;--measure-pull:30em;--measure-aside:32em;}@media (prefers-color-scheme:dark) {:root:not([data-theme="light"]) {--raw-paper:#14171A;--raw-surface:#1C2024;--raw-surface-raised:#232830;--raw-surface-sunken:#1A1D21;--raw-scrollbar-thumb:#6E747E;--raw-scrollbar-thumb-hov:#7D828A;--raw-border-decor:#2A3038;--raw-border-decor-str:#3A424C;--raw-border-control:#8A9099;--raw-text-primary:#E4E7EA;--raw-text-secondary:#AEB6C0;--raw-text-tertiary:#9BA3AD;--raw-text-on-accent:#0D1114;--raw-text-on-solid:#0D1114;--raw-skeleton-bg:#2E343C;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.06);--raw-danger:#E07A6E;--raw-danger-hover:#F09A90;--raw-danger-bg:#341D1A;--raw-success:#6FAA7A;--raw-success-bg:#16241A;--raw-dir-up:#E07A6E;--raw-dir-down:#6FAA7A;--raw-warning:#C99A3F;--raw-warning-bg:#242A31;--raw-info:#5B9BC4;--raw-info-bg:#13242F;--raw-accent:#7AA9DE;--raw-switch-on:#3E6EA8;--raw-accent-hover:#8FB8E6;--raw-accent-soft:#1C2C3D;--raw-tooltip-bg:#232830;--raw-tooltip-fg:#E4E7EA;--raw-tooltip-border:#2A3038;--raw-scrim:rgba(0, 0, 0, 0.62);}}[data-theme="light"] {--raw-accent:#1b4d8f;--raw-accent-hover:#163a6d;--raw-accent-soft:#e6eef7;--raw-border-control:#868b94;--raw-border-decor:#e2e5e9;--raw-border-decor-str:#c8cdd4;--raw-danger:#c0392b;--raw-danger-bg:#fdeeec;--raw-danger-hover:#8f1e17;--raw-dir-down:#2f6b3a;--raw-dir-up:#c0392b;--raw-info:#1d5f8a;--raw-info-bg:#e8f1f8;--raw-paper:#f6f7f8;--raw-scrim:rgba(21, 24, 28, 0.4);--raw-scrollbar-thumb:#7A808A;--raw-scrollbar-thumb-hov:#6E747E;--raw-skeleton-bg:#e9ecef;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.72);--raw-success:#2f6b3a;--raw-success-bg:#eaf2e6;--raw-surface:#ffffff;--raw-surface-raised:#ffffff;--raw-surface-sunken:#f1f3f5;--raw-switch-on:#1b4d8f;--raw-text-on-accent:#ffffff;--raw-text-on-solid:#ffffff;--raw-text-primary:#15181c;--raw-text-secondary:#4f555e;--raw-text-tertiary:#606770;--raw-tooltip-bg:#15181c;--raw-tooltip-border:#15181c;--raw-tooltip-fg:#f6f7f8;--raw-warning:#8a5a00;--raw-warning-bg:#fbf1dd;--accent:var(--raw-accent);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-bg:var(--raw-danger-bg);--danger-hover:var(--raw-danger-hover);--dir-down:var(--raw-dir-down);--dir-up:var(--raw-dir-up);--info:var(--raw-info);--info-bg:var(--raw-info-bg);--paper:var(--raw-paper);--scrim:var(--raw-scrim);--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--success:var(--raw-success);--success-bg:var(--raw-success-bg);--surface:var(--raw-surface);--surface-raised:var(--raw-surface-raised);--surface-sunken:var(--raw-surface-sunken);--switch-on:var(--raw-switch-on);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-border:var(--raw-tooltip-border);--tooltip-fg:var(--raw-tooltip-fg);--warning:var(--raw-warning);--warning-bg:var(--raw-warning-bg);}:root[data-theme="dark"], [data-theme="dark"] {--raw-accent:#7AA9DE;--raw-accent-hover:#8FB8E6;--raw-accent-soft:#1C2C3D;--raw-border-control:#8A9099;--raw-border-decor:#2A3038;--raw-border-decor-str:#3A424C;--raw-danger:#E07A6E;--raw-danger-bg:#341D1A;--raw-danger-hover:#F09A90;--raw-dir-down:#6FAA7A;--raw-dir-up:#E07A6E;--raw-info:#5B9BC4;--raw-info-bg:#13242F;--raw-paper:#14171A;--raw-scrim:rgba(0, 0, 0, 0.62);--raw-scrollbar-thumb:#6E747E;--raw-scrollbar-thumb-hov:#7D828A;--raw-skeleton-bg:#2E343C;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.06);--raw-success:#6FAA7A;--raw-success-bg:#16241A;--raw-surface:#1C2024;--raw-surface-raised:#232830;--raw-surface-sunken:#1A1D21;--raw-switch-on:#3E6EA8;--raw-text-on-accent:#0D1114;--raw-text-on-solid:#0D1114;--raw-text-primary:#E4E7EA;--raw-text-secondary:#AEB6C0;--raw-text-tertiary:#9BA3AD;--raw-tooltip-bg:#232830;--raw-tooltip-border:#2A3038;--raw-tooltip-fg:#E4E7EA;--raw-warning:#C99A3F;--raw-warning-bg:#242A31;--accent:var(--raw-accent);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-bg:var(--raw-danger-bg);--danger-hover:var(--raw-danger-hover);--dir-down:var(--raw-dir-down);--dir-up:var(--raw-dir-up);--info:var(--raw-info);--info-bg:var(--raw-info-bg);--paper:var(--raw-paper);--scrim:var(--raw-scrim);--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--success:var(--raw-success);--success-bg:var(--raw-success-bg);--surface:var(--raw-surface);--surface-raised:var(--raw-surface-raised);--surface-sunken:var(--raw-surface-sunken);--switch-on:var(--raw-switch-on);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-border:var(--raw-tooltip-border);--tooltip-fg:var(--raw-tooltip-fg);--warning:var(--raw-warning);--warning-bg:var(--raw-warning-bg);}:root {--sans:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans SC', 'Noto Sans CJK SC', 'Geeza Pro', 'Segoe UI Historic', sans-serif;--mono:ui-monospace, 'SF Mono', 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', Menlo, Consolas, 'Sarasa Mono SC', 'Microsoft YaHei Mono', monospace;--serif:'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Songti SC', 'SimSun', 'Noto Serif CJK SC', 'Source Han Serif SC', serif;--tracking-normal:0;}:root:lang(ar), :root:lang(fa), :root:lang(he), :root:lang(ur) {--tracking-normal:0.01em;}a, button, label, summary, input[type="checkbox"], input[type="radio"], input[type="button"], input[type="submit"], [role="button"], [role="switch"], [role="tab"], [role="option"], .choice, .switch, .btn, .accordion__trigger, .tabs__tab, .card, .list__row {-webkit-tap-highlight-color:transparent;}.choice:active, .switch:active, .btn:active, .list__row:active, .card:active {opacity:0.82;}@media (hover:hover) and (pointer:fine) {.choice:active, .switch:active, .btn:active, .list__row:active, .card:active {opacity:1;}}
1
+ :root {--raw-paper:#f6f7f8;--raw-surface:#ffffff;--raw-surface-sunken:#f1f3f5;--raw-surface-raised:#ffffff;--raw-scrollbar-thumb:#7A808A;--raw-scrollbar-thumb-hov:#6E747E;--raw-text-primary:#15181c;--raw-text-secondary:#4f555e;--raw-text-tertiary:#606770;--raw-text-on-accent:#ffffff;--raw-text-on-solid:#ffffff;--raw-skeleton-bg:#e9ecef;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.72);--raw-border-control:#868b94;--raw-border-decor:#e2e5e9;--raw-border-decor-str:#c8cdd4;--raw-danger:#c0392b;--raw-danger-hover:#8f1e17;--raw-scrim:rgba(21, 24, 28, 0.4);--raw-success:#2f6b3a;--raw-warning:#8a5a00;--raw-info:#1d5f8a;--raw-danger-bg:#fdeeec;--raw-success-bg:#eaf2e6;--raw-warning-bg:#fbf1dd;--raw-info-bg:#e8f1f8;--raw-dir-up:#c0392b;--raw-dir-down:#2f6b3a;--raw-accent:#1b4d8f;--raw-switch-on:#1b4d8f;--raw-accent-hover:#163a6d;--raw-accent-soft:#e6eef7;--raw-tooltip-bg:#15181c;--raw-tooltip-fg:#f6f7f8;--raw-tooltip-border:#15181c;--paper:var(--raw-paper);--surface:var(--raw-surface);--surface-sunken:var(--raw-surface-sunken);--surface-raised:var(--raw-surface-raised);--scrollbar-size:10px;--scrollbar-size-thin:6px;--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--scrollbar-radius:5px;--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--skeleton-h:1em;--skeleton-size:40px;--skeleton-duration:1.4s;--ease-out:cubic-bezier(0.23, 1, 0.32, 1);--progress-h:6px;--progress-dur:240ms;--r-full:999px;--ring-size:64px;--ring-thickness:8px;--progress:0%;--progress-num:0;--z-popover:60;--popover-min-w:200px;--popover-max-w:320px;--popover-p:var(--sp-3);--popover-gap:8px;--popover-dur:140ms;--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-hover:var(--raw-danger-hover);--scrim:var(--raw-scrim);--success:var(--raw-success);--warning:var(--raw-warning);--info:var(--raw-info);--danger-bg:var(--raw-danger-bg);--success-bg:var(--raw-success-bg);--warning-bg:var(--raw-warning-bg);--info-bg:var(--raw-info-bg);--dir-up:var(--raw-dir-up);--dir-down:var(--raw-dir-down);--accent:var(--raw-accent);--switch-on:var(--raw-switch-on);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-fg:var(--raw-tooltip-fg);--tooltip-border:var(--raw-tooltip-border);--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:clamp(1rem, 0.95rem + 0.3vw, 1.25rem);--sp-5:clamp(1.25rem, 1.15rem + 0.7vw, 1.75rem);--sp-6:clamp(1.5rem, 1.3rem + 1.2vw, 2.25rem);--sp-7:clamp(2rem, 1.7rem + 1.8vw, 3.5rem);--sp-8:clamp(2.5rem, 2.1rem + 2.4vw, 4.5rem);--bp-sm:30rem;--bp-md:48rem;--bp-lg:64rem;--bp-xl:80rem;--fs-xs:0.75rem;--fs-sm:0.875rem;--fs-base:clamp(1rem, 0.95rem + 0.3vw, 1.125rem);--fs-md:clamp(1.125rem, 1.05rem + 0.5vw, 1.3125rem);--fs-lg:clamp(1.3125rem, 1.2rem + 0.7vw, 1.5rem);--fs-xl:clamp(1.5rem, 1.3rem + 1.2vw, 1.875rem);--fs-2xl:clamp(1.75rem, 1.45rem + 1.8vw, 2.5rem);--lh-tight:1.25;--lh-base:1.7;--lh-loose:1.85;--measure-page:52rem;--tracking-title:-0.02em;--r-sm:6px;--r-xs:3px;--r-md:10px;--r-lg:14px;--r-pill:999px;--shadow-1:0 1px 2px rgba(31, 29, 25, 0.05), 0 1px 3px rgba(31, 29, 25, 0.06);--shadow-2:0 2px 4px rgba(31, 29, 25, 0.05), 0 6px 16px rgba(31, 29, 25, 0.08);--dur-fast:120ms;--dur-base:180ms;--dur-slow:280ms;--ease-out:cubic-bezier(0.23, 1, 0.32, 1);--ease-in-out:cubic-bezier(0.77, 0, 0.175, 1);--ease-drawer:cubic-bezier(0.32, 0.72, 0, 1);--lift-sm:1px;--lift-md:2px;--lift-lg:8px;--z-base:0;--z-sticky:10;--z-header:20;--z-raised:5;--z-overlay:30;--z-modal:40;--z-toast:50;--sz-touch:44px;--sz-touch-sm:32px;}[data-cq] {container-type:inline-size;}@media (prefers-reduced-motion:reduce) {*, *::before, *::after {animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;scroll-behavior:auto !important;}}:focus-visible {outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm);}:root {--measure-prose:34em;--measure-title:20em;--measure-lede:32em;--measure-pull:30em;--measure-aside:32em;}:root:lang(en), :root:lang(en-US), :root:lang(en-GB), :root:lang(fr), :root:lang(de), :root:lang(es), :root:lang(pt), :root:lang(ru), :root:lang(el), :root:lang(tr), :root:lang(vi) {--measure-prose:68ch;--measure-title:34ch;--measure-lede:62ch;--measure-pull:58ch;--measure-aside:56ch;}:root:lang(ar) {--measure-prose:60ch;--measure-title:30ch;--measure-lede:56ch;--measure-pull:52ch;--measure-aside:50ch;}:root:lang(hi), :root:lang(th), :root:lang(km), :root:lang(my) {--measure-prose:56ch;--measure-title:28ch;--measure-lede:52ch;--measure-pull:48ch;--measure-aside:46ch;}:root:lang(zh), :root:lang(zh-CN), :root:lang(zh-TW), :root:lang(ja), :root:lang(ko) {--measure-prose:34em;--measure-title:20em;--measure-lede:32em;--measure-pull:30em;--measure-aside:32em;}@media (prefers-color-scheme:dark) {:root:not([data-theme="light"]) {--raw-paper:#14171A;--raw-surface:#1C2024;--raw-surface-raised:#232830;--raw-surface-sunken:#1A1D21;--raw-scrollbar-thumb:#6E747E;--raw-scrollbar-thumb-hov:#7D828A;--raw-border-decor:#2A3038;--raw-border-decor-str:#3A424C;--raw-border-control:#8A9099;--raw-text-primary:#E4E7EA;--raw-text-secondary:#AEB6C0;--raw-text-tertiary:#9BA3AD;--raw-text-on-accent:#0D1114;--raw-text-on-solid:#0D1114;--raw-skeleton-bg:#2E343C;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.06);--raw-danger:#E07A6E;--raw-danger-hover:#F09A90;--raw-danger-bg:#341D1A;--raw-success:#6FAA7A;--raw-success-bg:#16241A;--raw-dir-up:#E07A6E;--raw-dir-down:#6FAA7A;--raw-warning:#C99A3F;--raw-warning-bg:#242A31;--raw-info:#5B9BC4;--raw-info-bg:#13242F;--raw-accent:#7AA9DE;--raw-switch-on:#3E6EA8;--raw-accent-hover:#8FB8E6;--raw-accent-soft:#1C2C3D;--raw-tooltip-bg:#232830;--raw-tooltip-fg:#E4E7EA;--raw-tooltip-border:#2A3038;--raw-scrim:rgba(0, 0, 0, 0.62);}}[data-theme="light"] {--raw-accent:#1b4d8f;--raw-accent-hover:#163a6d;--raw-accent-soft:#e6eef7;--raw-border-control:#868b94;--raw-border-decor:#e2e5e9;--raw-border-decor-str:#c8cdd4;--raw-danger:#c0392b;--raw-danger-bg:#fdeeec;--raw-danger-hover:#8f1e17;--raw-dir-down:#2f6b3a;--raw-dir-up:#c0392b;--raw-info:#1d5f8a;--raw-info-bg:#e8f1f8;--raw-paper:#f6f7f8;--raw-scrim:rgba(21, 24, 28, 0.4);--raw-scrollbar-thumb:#7A808A;--raw-scrollbar-thumb-hov:#6E747E;--raw-skeleton-bg:#e9ecef;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.72);--raw-success:#2f6b3a;--raw-success-bg:#eaf2e6;--raw-surface:#ffffff;--raw-surface-raised:#ffffff;--raw-surface-sunken:#f1f3f5;--raw-switch-on:#1b4d8f;--raw-text-on-accent:#ffffff;--raw-text-on-solid:#ffffff;--raw-text-primary:#15181c;--raw-text-secondary:#4f555e;--raw-text-tertiary:#606770;--raw-tooltip-bg:#15181c;--raw-tooltip-border:#15181c;--raw-tooltip-fg:#f6f7f8;--raw-warning:#8a5a00;--raw-warning-bg:#fbf1dd;--accent:var(--raw-accent);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-bg:var(--raw-danger-bg);--danger-hover:var(--raw-danger-hover);--dir-down:var(--raw-dir-down);--dir-up:var(--raw-dir-up);--info:var(--raw-info);--info-bg:var(--raw-info-bg);--paper:var(--raw-paper);--scrim:var(--raw-scrim);--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--success:var(--raw-success);--success-bg:var(--raw-success-bg);--surface:var(--raw-surface);--surface-raised:var(--raw-surface-raised);--surface-sunken:var(--raw-surface-sunken);--switch-on:var(--raw-switch-on);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-border:var(--raw-tooltip-border);--tooltip-fg:var(--raw-tooltip-fg);--warning:var(--raw-warning);--warning-bg:var(--raw-warning-bg);}:root[data-theme="dark"], [data-theme="dark"] {--raw-accent:#7AA9DE;--raw-accent-hover:#8FB8E6;--raw-accent-soft:#1C2C3D;--raw-border-control:#8A9099;--raw-border-decor:#2A3038;--raw-border-decor-str:#3A424C;--raw-danger:#E07A6E;--raw-danger-bg:#341D1A;--raw-danger-hover:#F09A90;--raw-dir-down:#6FAA7A;--raw-dir-up:#E07A6E;--raw-info:#5B9BC4;--raw-info-bg:#13242F;--raw-paper:#14171A;--raw-scrim:rgba(0, 0, 0, 0.62);--raw-scrollbar-thumb:#6E747E;--raw-scrollbar-thumb-hov:#7D828A;--raw-skeleton-bg:#2E343C;--raw-skeleton-shimmer:rgba(255, 255, 255, 0.06);--raw-success:#6FAA7A;--raw-success-bg:#16241A;--raw-surface:#1C2024;--raw-surface-raised:#232830;--raw-surface-sunken:#1A1D21;--raw-switch-on:#3E6EA8;--raw-text-on-accent:#0D1114;--raw-text-on-solid:#0D1114;--raw-text-primary:#E4E7EA;--raw-text-secondary:#AEB6C0;--raw-text-tertiary:#9BA3AD;--raw-tooltip-bg:#232830;--raw-tooltip-border:#2A3038;--raw-tooltip-fg:#E4E7EA;--raw-warning:#C99A3F;--raw-warning-bg:#242A31;--accent:var(--raw-accent);--accent-hover:var(--raw-accent-hover);--accent-soft:var(--raw-accent-soft);--border-control:var(--raw-border-control);--border-decor:var(--raw-border-decor);--border-decor-str:var(--raw-border-decor-str);--danger:var(--raw-danger);--danger-bg:var(--raw-danger-bg);--danger-hover:var(--raw-danger-hover);--dir-down:var(--raw-dir-down);--dir-up:var(--raw-dir-up);--info:var(--raw-info);--info-bg:var(--raw-info-bg);--paper:var(--raw-paper);--scrim:var(--raw-scrim);--scrollbar-thumb:var(--raw-scrollbar-thumb);--scrollbar-thumb-hov:var(--raw-scrollbar-thumb-hov);--skeleton-bg:var(--raw-skeleton-bg);--skeleton-shimmer:var(--raw-skeleton-shimmer);--success:var(--raw-success);--success-bg:var(--raw-success-bg);--surface:var(--raw-surface);--surface-raised:var(--raw-surface-raised);--surface-sunken:var(--raw-surface-sunken);--switch-on:var(--raw-switch-on);--text-on-accent:var(--raw-text-on-accent);--text-on-solid:var(--raw-text-on-solid);--text-primary:var(--raw-text-primary);--text-secondary:var(--raw-text-secondary);--text-tertiary:var(--raw-text-tertiary);--tooltip-bg:var(--raw-tooltip-bg);--tooltip-border:var(--raw-tooltip-border);--tooltip-fg:var(--raw-tooltip-fg);--warning:var(--raw-warning);--warning-bg:var(--raw-warning-bg);}:root {--sans:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans SC', 'Noto Sans CJK SC', 'Geeza Pro', 'Segoe UI Historic', sans-serif;--mono:ui-monospace, 'SF Mono', 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', Menlo, Consolas, 'Sarasa Mono SC', 'Microsoft YaHei Mono', monospace;--serif:'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Songti SC', 'SimSun', 'Noto Serif CJK SC', 'Source Han Serif SC', serif;--tracking-normal:0;}:root:lang(ar), :root:lang(fa), :root:lang(he), :root:lang(ur) {--tracking-normal:0.01em;}a, button, label, summary, input[type="checkbox"], input[type="radio"], input[type="button"], input[type="submit"], [role="button"], [role="switch"], [role="tab"], [role="option"], .choice, .switch, .btn, .accordion__trigger, .tabs__tab, .card, .list__row {-webkit-tap-highlight-color:transparent;}.choice:active, .switch:active, .btn:active, .list__row:active, .card:active {opacity:0.82;}@media (hover:hover) and (pointer:fine) {.choice:active, .switch:active, .btn:active, .list__row:active, .card:active {opacity:1;}}
@@ -1 +1 @@
1
- .card {position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border-decor);border-radius:var(--r-md);transition:transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);}.card__media {aspect-ratio:16 / 9;overflow:hidden;border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;background:var(--surface-sunken);}.card__media img {width:100%;height:100%;object-fit:cover;display:block;}.card__media + .card__body {border-radius:0;}.card__body {padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-2);}.card__title {margin:0;font-size:var(--fs-md);font-weight:500;line-height:var(--lh-tight);color:var(--text-primary);}.card__desc {margin:0;font-size:var(--fs-sm);color:var(--text-secondary);line-height:var(--lh-base);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;}.card__footer {padding:var(--sp-3) var(--sp-5);border-top:1px solid var(--border-decor);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--text-tertiary);}.card--flat {border-color:transparent;background:var(--surface);}.card--elevated {border-color:transparent;box-shadow:var(--shadow-1);}.card--interactive {cursor:pointer;}@media (hover:hover) and (pointer:fine) {.card--interactive:hover {transform:translateY(calc(-1 * var(--lift-md)));box-shadow:var(--shadow-2);}}.card--interactive:active {transform:translateY(0);box-shadow:var(--shadow-1);}.card--linked {position:relative;}.card__link {color:inherit;text-decoration:none;}.card__link::after {content:"";position:absolute;inset:0;border-radius:var(--r-md);z-index:var(--z-base);}.card__body :is(button, a, input, select, textarea, [role="button"], [role="checkbox"], [role="switch"], [tabindex]):not(.card__link) {position:relative;z-index:var(--z-raised);}.card--linked:focus-within {outline:2px solid var(--accent);outline-offset:2px;}.card__link:focus-visible {outline:none;}.card--selected {box-shadow:inset 0 0 0 2px var(--accent);}.card--compact .card__body {padding:var(--sp-4);gap:var(--sp-1);}.card--compact .card__title {font-size:var(--fs-base);}.card--row {flex-direction:row;align-items:stretch;}.card--row .card__media {flex:none;width:160px;aspect-ratio:auto;border-radius:calc(var(--r-md) - 1px) 0 0 calc(var(--r-md) - 1px);}@media (max-width:560px) {.card--row {flex-direction:column;}.card--row .card__media {width:100%;aspect-ratio:16 / 9;border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;}}@media (prefers-reduced-motion:reduce) {@media (hover:hover) and (pointer:fine) {.card--interactive:hover, .card--interactive:active {transform:none;}}}
1
+ .card {position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border-decor);border-radius:var(--r-md);transition:transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);}.card__media {aspect-ratio:16 / 9;overflow:hidden;border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;background:var(--surface-sunken);}.card__media img {width:100%;height:100%;object-fit:cover;display:block;}.card__media + .card__body {border-radius:0;}.card__body {padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-2);}.card__title {margin:0;font-size:var(--fs-md);font-weight:500;line-height:var(--lh-tight);color:var(--text-primary);}.card__desc {margin:0;font-size:var(--fs-sm);color:var(--text-secondary);line-height:var(--lh-base);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;}.card__footer {padding:var(--sp-3) var(--sp-5);border-top:1px solid var(--border-decor);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--text-tertiary);}.card--flat {border-color:transparent;background:var(--surface);}.card--elevated {border-color:transparent;box-shadow:var(--shadow-1);}.card--interactive {cursor:pointer;}@media (hover:hover) and (pointer:fine) {.card--interactive:hover {transform:translateY(calc(-1 * var(--lift-md)));box-shadow:var(--shadow-2);}}.card--interactive:active {transform:translateY(0);box-shadow:var(--shadow-1);}.card--linked {position:relative;}.card__link {color:inherit;text-decoration:none;}.card__link::after {content:"";position:absolute;inset:0;border-radius:var(--r-md);z-index:var(--z-base);}.card__body :is(button, a, input, select, textarea, [role="button"], [role="checkbox"], [role="switch"], [tabindex]):not(.card__link) {position:relative;z-index:var(--z-raised);}.card--linked:focus-within {outline:2px solid var(--accent);outline-offset:2px;}.card__link:focus-visible {outline:none;}.card--selected {box-shadow:inset 0 0 0 2px var(--accent);}.card--compact .card__body {padding:var(--sp-4);gap:var(--sp-1);}.card--compact .card__title {font-size:var(--fs-base);}.card--row {flex-direction:row;align-items:stretch;}.card--row .card__media {flex:none;width:160px;aspect-ratio:auto;border-radius:calc(var(--r-md) - 1px) 0 0 calc(var(--r-md) - 1px);}@media (max-width:560px) {.card--row {flex-direction:column;}.card--row .card__media {width:100%;aspect-ratio:16 / 9;border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;}}@container (max-width:35rem) {.card--row {flex-direction:column;}.card--row .card__media {width:100%;aspect-ratio:16 / 9;border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;}}@container (min-width:35rem) {.card--row {flex-direction:row;align-items:stretch;}.card--row .card__media {flex:none;width:160px;aspect-ratio:auto;border-radius:calc(var(--r-md) - 1px) 0 0 calc(var(--r-md) - 1px);}}@media (prefers-reduced-motion:reduce) {@media (hover:hover) and (pointer:fine) {.card--interactive:hover, .card--interactive:active {transform:none;}}}
@@ -1 +1 @@
1
- .report {max-width:calc(var(--measure-page) + 16rem);}.report__kicker {margin:0 0 var(--sp-2);font-size:var(--fs-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary);}.report__meta {display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-4);margin:var(--sp-4) 0 0;padding-top:var(--sp-3);border-top:1px solid var(--border-decor);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__meta b {font-weight:500;color:var(--text-secondary);}.report__body {display:grid;grid-template-columns:minmax(0, 1fr);gap:var(--sp-6);margin-top:var(--sp-6);}@media (min-width:64rem) {.report__body {grid-template-columns:minmax(0, 1fr) 15rem;gap:var(--sp-7);}.report__aside {position:sticky;top:var(--sp-4);align-self:start;max-height:calc(100vh - var(--sp-8));overflow:auto;}}.report__main > section + section {margin-top:var(--sp-6);}.report__main h2 {margin-top:0;}.report__main p {margin:var(--sp-3) 0;}.report__main ul, .report__main ol {margin:var(--sp-3) 0;padding-inline-start:var(--sp-5);}.report__main li + li {margin-top:var(--sp-1);}.kf {margin:var(--sp-4) 0;padding:var(--sp-4);background:var(--info-bg);border-radius:var(--r-md);}.kf__title {margin:0 0 var(--sp-2);font-size:var(--fs-sm);font-weight:600;color:var(--text-secondary);}.kf ol {margin:0;padding-inline-start:var(--sp-5);}.kf li {margin-top:var(--sp-2);}.kf strong {color:var(--text-primary);}.report__quote {margin:var(--sp-4) 0;padding:var(--sp-3) var(--sp-4);border-inline-start:3px solid var(--border-decor);color:var(--text-secondary);font-style:italic;}.report__quote cite {display:block;margin-top:var(--sp-2);font-size:var(--fs-xs);font-style:normal;color:var(--text-tertiary);}.report__code {margin:var(--sp-4) 0;padding:var(--sp-3) var(--sp-4);background:var(--surface-sunken);border:1px solid var(--border-decor);border-radius:var(--r-md);overflow-x:auto;font-family:var(--mono);font-size:var(--fs-xs);line-height:var(--lh-loose);color:var(--text-secondary);white-space:pre;}.report__aside .card + .card {margin-top:var(--sp-3);}.report__aside .card__title {font-size:var(--fs-xs);letter-spacing:.04em;text-transform:uppercase;color:var(--text-tertiary);}.report__aside dl {margin:var(--sp-2) 0 0;font-size:var(--fs-sm);}.report__aside dt {margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__aside dd {margin:0;color:var(--text-primary);}.report__aside p {margin:0;font-size:var(--fs-sm);color:var(--text-secondary);}.report__fig {margin:var(--sp-5) 0;padding:var(--sp-3);background:var(--surface);border:1px solid var(--border-decor);border-radius:var(--r-md);overflow-x:auto;}.report__fig figcaption {margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__foot {margin-top:var(--sp-8);padding-top:var(--sp-4);border-top:1px solid var(--border-decor);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__foot ol {padding-inline-start:var(--sp-5);}.report__foot li + li {margin-top:var(--sp-1);}@media print {.report__aside {position:static;max-height:none;overflow:visible;}.report__body {grid-template-columns:1fr;}}
1
+ .report {max-width:calc(var(--measure-page) + 16rem);}.report__kicker {margin:0 0 var(--sp-2);font-size:var(--fs-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary);}.report__meta {display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-4);margin:var(--sp-4) 0 0;padding-top:var(--sp-3);border-top:1px solid var(--border-decor);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__meta b {font-weight:500;color:var(--text-secondary);}.report__body {display:grid;grid-template-columns:minmax(0, 1fr);gap:var(--sp-6);margin-top:var(--sp-6);}@media (min-width:64rem) {.report__body {grid-template-columns:minmax(0, 1fr) 15rem;gap:var(--sp-7);}.report__aside {position:sticky;top:var(--sp-4);align-self:start;max-height:calc(100vh - var(--sp-8));overflow:auto;}}@container (max-width:63.99rem) {.report__body {grid-template-columns:minmax(0, 1fr);gap:var(--sp-6);}.report__aside {position:static;max-height:none;overflow:visible;}}@container (min-width:64rem) {.report__body {grid-template-columns:minmax(0, 1fr) 15rem;gap:var(--sp-7);}.report__aside {position:sticky;top:var(--sp-4);align-self:start;max-height:calc(100vh - var(--sp-8));overflow:auto;}}.report__main > section + section {margin-top:var(--sp-6);}.report__main h2 {margin-top:0;}.report__main p {margin:var(--sp-3) 0;}.report__main ul, .report__main ol {margin:var(--sp-3) 0;padding-inline-start:var(--sp-5);}.report__main li + li {margin-top:var(--sp-1);}.kf {margin:var(--sp-4) 0;padding:var(--sp-4);background:var(--info-bg);border-radius:var(--r-md);}.kf__title {margin:0 0 var(--sp-2);font-size:var(--fs-sm);font-weight:600;color:var(--text-secondary);}.kf ol {margin:0;padding-inline-start:var(--sp-5);}.kf li {margin-top:var(--sp-2);}.kf strong {color:var(--text-primary);}.report__quote {margin:var(--sp-4) 0;padding:var(--sp-3) var(--sp-4);border-inline-start:3px solid var(--border-decor);color:var(--text-secondary);font-style:italic;}.report__quote cite {display:block;margin-top:var(--sp-2);font-size:var(--fs-xs);font-style:normal;color:var(--text-tertiary);}.report__code {margin:var(--sp-4) 0;padding:var(--sp-3) var(--sp-4);background:var(--surface-sunken);border:1px solid var(--border-decor);border-radius:var(--r-md);overflow-x:auto;font-family:var(--mono);font-size:var(--fs-xs);line-height:var(--lh-loose);color:var(--text-secondary);white-space:pre;}.report__aside .card + .card {margin-top:var(--sp-3);}.report__aside .card__title {font-size:var(--fs-xs);letter-spacing:.04em;text-transform:uppercase;color:var(--text-tertiary);}.report__aside dl {margin:var(--sp-2) 0 0;font-size:var(--fs-sm);}.report__aside dt {margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__aside dd {margin:0;color:var(--text-primary);}.report__aside p {margin:0;font-size:var(--fs-sm);color:var(--text-secondary);}.report__fig {margin:var(--sp-5) 0;padding:var(--sp-3);background:var(--surface);border:1px solid var(--border-decor);border-radius:var(--r-md);overflow-x:auto;}.report__fig figcaption {margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__foot {margin-top:var(--sp-8);padding-top:var(--sp-4);border-top:1px solid var(--border-decor);font-size:var(--fs-xs);color:var(--text-tertiary);}.report__foot ol {padding-inline-start:var(--sp-5);}.report__foot li + li {margin-top:var(--sp-1);}@media print {.report__aside {position:static;max-height:none;overflow:visible;}.report__body {grid-template-columns:1fr;}}
package/dist/COSTS.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  实测两笔账,一笔不省:
11
11
 
12
- - `tokens` 源码版 gzip **19.6 KB** → min 版 **2.7 KB**(省 86%)——
12
+ - `tokens` 源码版 gzip **20.4 KB** → min 版 **2.7 KB**(省 87%)——
13
13
  源码多的那部分**全是注释**(全库 CSS 有 67% 是注释,字节口径),而注释是给维护者的,不是给浏览器的。
14
14
  - tokens 的 min 版 2.7 KB **比任何一个组件自己都贵** ⇒
15
15
  "只用一个组件"的真实起步价就是它。不公开这张表,等于让人盲买。
@@ -18,40 +18,40 @@
18
18
 
19
19
  | 档 | 组件 | tokens(必付) | CSS | JS | **合计** | 源码版合计 | 差 |
20
20
  |---|---|---:|---:|---:|---:|---:|---:|
21
- | primitive | `badge` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 22.4 KB | −19.2 KB |
22
- | primitive | `button` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 26.0 KB | −22.4 KB |
23
- | primitive | `card` | 2.7 KB | 0.9 KB | — | **3.6 KB** | 23.1 KB | −19.5 KB |
24
- | primitive | `choice` | 2.7 KB | 1.1 KB | — | **3.8 KB** | 25.0 KB | −21.2 KB |
25
- | primitive | `combobox` | 2.7 KB | 1.0 KB | 5.4 KB | **9.0 KB** | 29.2 KB | −20.1 KB |
26
- | primitive | `date-range` | 2.7 KB | 0.8 KB | 2.5 KB | **6.1 KB** | 26.1 KB | −20.1 KB |
27
- | primitive | `delta` | 2.7 KB | 0.3 KB | — | **3.0 KB** | 22.4 KB | −19.4 KB |
28
- | primitive | `input` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 23.2 KB | −19.5 KB |
29
- | primitive | `metric` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 22.8 KB | −19.7 KB |
30
- | primitive | `popover` | 2.7 KB | 0.8 KB | 2.2 KB | **5.7 KB** | 26.9 KB | −21.2 KB |
31
- | primitive | `progress` | 2.7 KB | 0.7 KB | — | **3.4 KB** | 22.5 KB | −19.1 KB |
32
- | primitive | `select` | 2.7 KB | 0.8 KB | 3.5 KB | **7.0 KB** | 29.2 KB | −22.2 KB |
33
- | primitive | `separator` | 2.7 KB | 0.2 KB | — | **2.9 KB** | 20.9 KB | −18.0 KB |
34
- | primitive | `skeleton` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 21.1 KB | −17.9 KB |
35
- | primitive | `switch` | 2.7 KB | 0.8 KB | — | **3.4 KB** | 26.8 KB | −23.3 KB |
36
- | pattern | `accordion` | 2.7 KB | 1.3 KB | 1.8 KB | **5.8 KB** | 34.1 KB | −28.3 KB |
37
- | pattern | `content` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 24.2 KB | −20.5 KB |
38
- | pattern | `drawer` | 2.7 KB | 0.8 KB | 2.4 KB | **5.9 KB** | 26.1 KB | −20.2 KB |
39
- | pattern | `dropdown` | 2.7 KB | 0.8 KB | 3.4 KB | **6.9 KB** | 29.1 KB | −22.2 KB |
40
- | pattern | `form-validation` | 2.7 KB | 0.8 KB | — | **3.5 KB** | 24.1 KB | −20.7 KB |
41
- | pattern | `list` | 2.7 KB | 0.6 KB | — | **3.3 KB** | 22.0 KB | −18.7 KB |
42
- | pattern | `nav` | 2.7 KB | 1.2 KB | 2.6 KB | **6.6 KB** | 30.7 KB | −24.1 KB |
43
- | pattern | `overlay` | 2.7 KB | 1.1 KB | 3.3 KB | **7.1 KB** | 34.5 KB | −27.4 KB |
44
- | pattern | `pagination` | 2.7 KB | 0.8 KB | 2.6 KB | **6.0 KB** | 30.1 KB | −24.1 KB |
45
- | pattern | `reveal` | 2.7 KB | 0.3 KB | 1.2 KB | **4.2 KB** | 24.2 KB | −20.0 KB |
46
- | pattern | `states` | 2.7 KB | 0.8 KB | — | **3.5 KB** | 23.6 KB | −20.1 KB |
47
- | pattern | `tabs` | 2.7 KB | 0.7 KB | 2.0 KB | **5.4 KB** | 26.8 KB | −21.4 KB |
48
- | pattern | `tooltip` | 2.7 KB | 0.5 KB | 1.9 KB | **5.1 KB** | 26.0 KB | −20.9 KB |
49
- | pattern | `tree` | 2.7 KB | 0.6 KB | 2.9 KB | **6.2 KB** | 27.8 KB | −21.6 KB |
21
+ | primitive | `badge` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 23.1 KB | −19.9 KB |
22
+ | primitive | `button` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 26.8 KB | −23.1 KB |
23
+ | primitive | `card` | 2.7 KB | 0.9 KB | — | **3.7 KB** | 24.5 KB | −20.8 KB |
24
+ | primitive | `choice` | 2.7 KB | 1.1 KB | — | **3.8 KB** | 25.8 KB | −22.0 KB |
25
+ | primitive | `combobox` | 2.7 KB | 1.0 KB | 5.4 KB | **9.1 KB** | 29.9 KB | −20.9 KB |
26
+ | primitive | `date-range` | 2.7 KB | 0.8 KB | 2.5 KB | **6.1 KB** | 26.9 KB | −20.8 KB |
27
+ | primitive | `delta` | 2.7 KB | 0.3 KB | — | **3.0 KB** | 23.1 KB | −20.2 KB |
28
+ | primitive | `input` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 24.0 KB | −20.3 KB |
29
+ | primitive | `metric` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 23.6 KB | −20.4 KB |
30
+ | primitive | `popover` | 2.7 KB | 0.8 KB | 2.2 KB | **5.7 KB** | 27.7 KB | −22.0 KB |
31
+ | primitive | `progress` | 2.7 KB | 0.7 KB | — | **3.4 KB** | 23.3 KB | −19.9 KB |
32
+ | primitive | `select` | 2.7 KB | 0.8 KB | 3.5 KB | **7.1 KB** | 30.0 KB | −22.9 KB |
33
+ | primitive | `separator` | 2.7 KB | 0.2 KB | — | **3.0 KB** | 21.7 KB | −18.7 KB |
34
+ | primitive | `skeleton` | 2.7 KB | 0.5 KB | — | **3.2 KB** | 21.8 KB | −18.6 KB |
35
+ | primitive | `switch` | 2.7 KB | 0.8 KB | — | **3.5 KB** | 27.5 KB | −24.1 KB |
36
+ | pattern | `accordion` | 2.7 KB | 1.3 KB | 1.8 KB | **5.8 KB** | 34.9 KB | −29.1 KB |
37
+ | pattern | `content` | 2.7 KB | 1.0 KB | — | **3.7 KB** | 25.0 KB | −21.2 KB |
38
+ | pattern | `drawer` | 2.7 KB | 0.8 KB | 2.4 KB | **5.9 KB** | 26.9 KB | −21.0 KB |
39
+ | pattern | `dropdown` | 2.7 KB | 0.8 KB | 3.4 KB | **6.9 KB** | 29.8 KB | −22.9 KB |
40
+ | pattern | `form-validation` | 2.7 KB | 0.8 KB | — | **3.5 KB** | 24.9 KB | −21.4 KB |
41
+ | pattern | `list` | 2.7 KB | 0.6 KB | — | **3.3 KB** | 22.8 KB | −19.5 KB |
42
+ | pattern | `nav` | 2.7 KB | 1.2 KB | 2.6 KB | **6.6 KB** | 31.5 KB | −24.9 KB |
43
+ | pattern | `overlay` | 2.7 KB | 1.1 KB | 3.3 KB | **7.1 KB** | 35.3 KB | −28.1 KB |
44
+ | pattern | `pagination` | 2.7 KB | 0.8 KB | 2.6 KB | **6.1 KB** | 30.9 KB | −24.9 KB |
45
+ | pattern | `reveal` | 2.7 KB | 0.3 KB | 1.2 KB | **4.2 KB** | 24.9 KB | −20.7 KB |
46
+ | pattern | `states` | 2.7 KB | 0.8 KB | — | **3.6 KB** | 24.4 KB | −20.9 KB |
47
+ | pattern | `tabs` | 2.7 KB | 0.7 KB | 2.0 KB | **5.4 KB** | 27.6 KB | −22.2 KB |
48
+ | pattern | `tooltip` | 2.7 KB | 0.5 KB | 1.9 KB | **5.1 KB** | 26.8 KB | −21.7 KB |
49
+ | pattern | `tree` | 2.7 KB | 0.6 KB | 2.9 KB | **6.3 KB** | 28.6 KB | −22.3 KB |
50
50
 
51
51
  ## 三、全库
52
52
 
53
- - 全部组件都用上(min,含 tokens 一份):**62.6 KB**
54
- - 源码版(带注释)全库 gzip:305.5 KB
53
+ - 全部组件都用上(min,含 tokens 一份):**62.7 KB**
54
+ - 源码版(带注释)全库 gzip:307.3 KB
55
55
 
56
56
  > ⚠️ 源码版那个数字**不是**要付的钱:它包含我们的注释(全库 CSS 有 67% 是注释,字节口径)。
57
57
  > 它的用途只有一个 —— 让人看清"dist 到底省了多少"。
@@ -5,7 +5,7 @@
5
5
 
6
6
  | 项目 | 值 |
7
7
  |---|---|
8
- | 声明适用版本 | agentcss `0.15.0` |
8
+ | 声明适用版本 | agentcss `0.16.0` |
9
9
  | 声明日期 | 2026-10-30 |
10
10
  | 复核节奏 | 每次发版前重跑(`npm run gate` 内含全部证据) |
11
11
  | 范围 | 本库交付的 CSS / JS、全部 `demo.html`(组件页 + 图表页 + 组合页)、以及文档站生成的页面 |
@@ -207,7 +207,34 @@
207
207
  `0` 与「四舍五入到 0」(如精度 1 下的 `0.0004`)都不加 `+` / `−`
208
208
  —— 「+0.0%」等于把持平念成上涨。会计列与市场列是同一条规则。
209
209
 
210
- ## 十一 · 每条规则由什么挡住
210
+ ## 十一 · 断点看槽宽,不看视口
211
+
212
+ `@media` 回答的是"**屏幕**多宽",而组件关心的是"**我**多宽"。这两件事在
213
+ 侧栏、分屏、嵌入卡片里不等,而且 demo 页永远暴露不出来。
214
+
215
+ ```html
216
+ <div class="rail" data-cq> <!-- 这一层就是组件眼里的"窗口" -->
217
+ <div class="card card--row">…</div>
218
+ </div>
219
+ ```
220
+
221
+ - **`data-cq` 是显式选择**:加了它,里面的组件按槽宽切换;不加,行为与本版之前**完全一致**
222
+ (实测:没有容器祖先时 `@container` 不会退回视口,整条不生效)。
223
+ - **不自动给组件加 `container-type`**:它会带上 `contain: layout`,
224
+ 让元素变成 `position: fixed` 后代的包含块 —— 抽屉、全屏浮层会被关进那个盒子。
225
+ 所以 `data-cq` 不许加在承载抽屉/全屏浮层的祖先上。
226
+ - **两个方向都要写**:`@container (max-width)` 只能"变窄",
227
+ 无法撤销一条已经生效的 `@media`(不匹配不会撤销任何规则)。
228
+ 要表达"标记过的槽以槽为准",`min-width` 那一条也得写。
229
+ - **基础样式不许住进 `@container`**:老引擎(Chromium 97)丢弃整块,
230
+ 写进去等于那些浏览器上组件直接没有样式。判据会把 `@container` 剥掉再跑一遍,
231
+ 布局必须不塌。
232
+ - 不需要 `@supports at-rule(@container)`:不支持时整块被丢弃,检测只会带来双写。
233
+
234
+ 挡住它的:`container-query-check.js`(10 条:两组件 × 槽窄/槽宽/未标记 ×
235
+ 两个方向 + 剥块降级)。
236
+
237
+ ## 十二 · 每条规则由什么挡住
211
238
 
212
239
  规则只有落到判据上才会被遵守。对应关系如下(文件都在 `05-audit/`):
213
240
 
@@ -225,6 +252,7 @@
225
252
  | 键盘可达(Tab 顺序、Esc 关闭) | `keyboard-nav.js` |
226
253
  | 减少动效策略双向一致 | `motion.py --reduced-audit` |
227
254
  | 逻辑属性全覆盖 | `rtl-check.js` |
255
+ | 断点看槽宽(`data-cq`)、未标记页面不变、剥掉 `@container` 不塌 | `container-query-check.js` |
228
256
  | `@layer` 计数与 `!important` 分类 | `cascade-layer-gate.py` |
229
257
  | 触控目标 44px | `a11y.py`(静态) + 行为脚本(运行时) |
230
258
  | 页面骨架只有一份(改令牌能牵动全部页面) | `skeleton-lever-check.js` |
package/index.html CHANGED
@@ -94,7 +94,7 @@ li a:active { background: var(--surface-sunken); }
94
94
  </p>
95
95
  </main>
96
96
  <footer class="wrap">
97
- <p class="note">0.15.0 · 零第三方运行时依赖</p>
97
+ <p class="note">0.16.0 · 零第三方运行时依赖</p>
98
98
  </footer>
99
99
  </body>
100
100
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcss",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "移动 Web 组件库:CSS + 可选行为脚本,零第三方运行时依赖。样式用 bundler 引入,交互行为用 script 标签引入。",
5
5
  "keywords": [
6
6
  "css",