@xihan-ui/styles 3.2.0 → 4.0.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 (232) hide show
  1. package/CHANGELOG.md +441 -0
  2. package/component-tokens.d.ts +229 -60
  3. package/components.tokens.json +5124 -1555
  4. package/css/accordion.css +47 -20
  5. package/css/alert.css +14 -15
  6. package/css/anchor.css +2 -2
  7. package/css/approval.css +37 -13
  8. package/css/avatar-group.css +9 -12
  9. package/css/avatar.css +20 -18
  10. package/css/back-top.css +21 -7
  11. package/css/badge.css +5 -5
  12. package/css/breadcrumb.css +18 -16
  13. package/css/button-group.css +4 -6
  14. package/css/button.css +4 -7
  15. package/css/calendar-picker.css +177 -94
  16. package/css/calendar-range-picker.css +206 -121
  17. package/css/card.css +34 -6
  18. package/css/carousel.css +65 -49
  19. package/css/cascader.css +41 -29
  20. package/css/checkbox-group.css +9 -6
  21. package/css/checkbox.css +5 -4
  22. package/css/citation.css +7 -2
  23. package/css/clipboard.css +20 -4
  24. package/css/collapsible.css +29 -14
  25. package/css/color-field.css +4 -4
  26. package/css/color-picker.css +77 -23
  27. package/css/color-slider.css +10 -8
  28. package/css/color-swatch-picker.css +5 -5
  29. package/css/combobox.css +14 -10
  30. package/css/command.css +13 -8
  31. package/css/context-menu.css +10 -5
  32. package/css/date-field.css +4 -4
  33. package/css/date-picker.css +165 -102
  34. package/css/date-range-picker.css +186 -123
  35. package/css/description.css +10 -6
  36. package/css/descriptions.css +47 -19
  37. package/css/dialog.css +50 -35
  38. package/css/drawer.css +75 -21
  39. package/css/editable.css +15 -41
  40. package/css/empty-state.css +21 -3
  41. package/css/field-array.css +4 -1
  42. package/css/field.css +17 -18
  43. package/css/fieldset.css +33 -13
  44. package/css/file-upload.css +65 -32
  45. package/css/float-button.css +25 -15
  46. package/css/floating-panel.css +1 -1
  47. package/css/form.css +24 -10
  48. package/css/grid-list.css +1 -1
  49. package/css/highlight.css +4 -4
  50. package/css/hover-card.css +19 -12
  51. package/css/image-viewer.css +77 -27
  52. package/css/image.css +12 -4
  53. package/css/infinite-scroll.css +8 -4
  54. package/css/input-group.css +74 -26
  55. package/css/kbd.css +1 -1
  56. package/css/label.css +27 -11
  57. package/css/layout.css +17 -10
  58. package/css/list.css +13 -9
  59. package/css/listbox.css +12 -7
  60. package/css/loading-bar.css +3 -0
  61. package/css/mention.css +10 -8
  62. package/css/menu.css +10 -5
  63. package/css/menubar.css +13 -8
  64. package/css/navigation-menu.css +2 -2
  65. package/css/notification.css +114 -31
  66. package/css/number-animation.css +2 -2
  67. package/css/number-field.css +60 -37
  68. package/css/page-header.css +63 -26
  69. package/css/pagination.css +35 -38
  70. package/css/password-input.css +10 -66
  71. package/css/pin-input.css +18 -26
  72. package/css/popconfirm.css +20 -11
  73. package/css/popover.css +18 -12
  74. package/css/progress.css +14 -13
  75. package/css/prompt-input.css +3 -3
  76. package/css/question-flow.css +33 -7
  77. package/css/radio-group.css +120 -55
  78. package/css/rating.css +31 -14
  79. package/css/select.css +14 -10
  80. package/css/separator.css +22 -4
  81. package/css/side-nav.css +16 -11
  82. package/css/signature-pad.css +23 -9
  83. package/css/skeleton.css +7 -7
  84. package/css/slider.css +71 -42
  85. package/css/sparkline.css +8 -2
  86. package/css/spinner.css +40 -20
  87. package/css/statistic.css +14 -14
  88. package/css/steps.css +115 -84
  89. package/css/switch.css +9 -7
  90. package/css/table.css +27 -10
  91. package/css/tabs.css +35 -12
  92. package/css/tag-group.css +17 -6
  93. package/css/tag.css +54 -29
  94. package/css/tags-input.css +38 -19
  95. package/css/text-field.css +5 -5
  96. package/css/time-field.css +4 -4
  97. package/css/time-picker.css +150 -64
  98. package/css/time-range-picker.css +91 -62
  99. package/css/timeline.css +37 -20
  100. package/css/timer.css +3 -3
  101. package/css/toggle-group.css +4 -4
  102. package/css/tool-call.css +6 -4
  103. package/css/toolbar.css +6 -5
  104. package/css/tooltip.css +15 -16
  105. package/css/tour.css +14 -7
  106. package/css/transfer.css +22 -16
  107. package/css/tree-select.css +10 -10
  108. package/css/tree.css +26 -25
  109. package/css/typography.css +28 -25
  110. package/dist/css/accordion.css +47 -20
  111. package/dist/css/alert.css +14 -15
  112. package/dist/css/anchor.css +2 -2
  113. package/dist/css/approval.css +37 -13
  114. package/dist/css/avatar-group.css +9 -12
  115. package/dist/css/avatar.css +20 -18
  116. package/dist/css/back-top.css +21 -7
  117. package/dist/css/badge.css +5 -5
  118. package/dist/css/breadcrumb.css +18 -16
  119. package/dist/css/button-group.css +4 -6
  120. package/dist/css/button.css +4 -7
  121. package/dist/css/calendar-picker.css +177 -94
  122. package/dist/css/calendar-range-picker.css +206 -121
  123. package/dist/css/card.css +34 -6
  124. package/dist/css/carousel.css +65 -49
  125. package/dist/css/cascader.css +41 -29
  126. package/dist/css/checkbox-group.css +9 -6
  127. package/dist/css/checkbox.css +5 -4
  128. package/dist/css/citation.css +7 -2
  129. package/dist/css/clipboard.css +20 -4
  130. package/dist/css/collapsible.css +29 -14
  131. package/dist/css/color-field.css +4 -4
  132. package/dist/css/color-picker.css +77 -23
  133. package/dist/css/color-slider.css +10 -8
  134. package/dist/css/color-swatch-picker.css +5 -5
  135. package/dist/css/combobox.css +14 -10
  136. package/dist/css/command.css +13 -8
  137. package/dist/css/context-menu.css +10 -5
  138. package/dist/css/date-field.css +4 -4
  139. package/dist/css/date-picker.css +165 -102
  140. package/dist/css/date-range-picker.css +186 -123
  141. package/dist/css/description.css +10 -6
  142. package/dist/css/descriptions.css +47 -19
  143. package/dist/css/dialog.css +50 -35
  144. package/dist/css/drawer.css +75 -21
  145. package/dist/css/editable.css +15 -41
  146. package/dist/css/empty-state.css +21 -3
  147. package/dist/css/field-array.css +4 -1
  148. package/dist/css/field.css +17 -18
  149. package/dist/css/fieldset.css +33 -13
  150. package/dist/css/file-upload.css +65 -32
  151. package/dist/css/float-button.css +25 -15
  152. package/dist/css/floating-panel.css +1 -1
  153. package/dist/css/form.css +24 -10
  154. package/dist/css/grid-list.css +1 -1
  155. package/dist/css/highlight.css +4 -4
  156. package/dist/css/hover-card.css +19 -12
  157. package/dist/css/image-viewer.css +77 -27
  158. package/dist/css/image.css +12 -4
  159. package/dist/css/infinite-scroll.css +8 -4
  160. package/dist/css/input-group.css +74 -26
  161. package/dist/css/kbd.css +1 -1
  162. package/dist/css/label.css +27 -11
  163. package/dist/css/layout.css +17 -10
  164. package/dist/css/list.css +13 -9
  165. package/dist/css/listbox.css +12 -7
  166. package/dist/css/loading-bar.css +3 -0
  167. package/dist/css/mention.css +10 -8
  168. package/dist/css/menu.css +10 -5
  169. package/dist/css/menubar.css +13 -8
  170. package/dist/css/navigation-menu.css +2 -2
  171. package/dist/css/notification.css +114 -31
  172. package/dist/css/number-animation.css +2 -2
  173. package/dist/css/number-field.css +60 -37
  174. package/dist/css/page-header.css +63 -26
  175. package/dist/css/pagination.css +35 -38
  176. package/dist/css/password-input.css +10 -66
  177. package/dist/css/pin-input.css +18 -26
  178. package/dist/css/popconfirm.css +20 -11
  179. package/dist/css/popover.css +18 -12
  180. package/dist/css/progress.css +14 -13
  181. package/dist/css/prompt-input.css +3 -3
  182. package/dist/css/question-flow.css +33 -7
  183. package/dist/css/radio-group.css +120 -55
  184. package/dist/css/rating.css +31 -14
  185. package/dist/css/select.css +14 -10
  186. package/dist/css/separator.css +22 -4
  187. package/dist/css/side-nav.css +16 -11
  188. package/dist/css/signature-pad.css +23 -9
  189. package/dist/css/skeleton.css +7 -7
  190. package/dist/css/slider.css +71 -42
  191. package/dist/css/sparkline.css +8 -2
  192. package/dist/css/spinner.css +40 -20
  193. package/dist/css/statistic.css +14 -14
  194. package/dist/css/steps.css +115 -84
  195. package/dist/css/switch.css +9 -7
  196. package/dist/css/table.css +27 -10
  197. package/dist/css/tabs.css +35 -12
  198. package/dist/css/tag-group.css +17 -6
  199. package/dist/css/tag.css +54 -29
  200. package/dist/css/tags-input.css +38 -19
  201. package/dist/css/text-field.css +5 -5
  202. package/dist/css/time-field.css +4 -4
  203. package/dist/css/time-picker.css +150 -64
  204. package/dist/css/time-range-picker.css +91 -62
  205. package/dist/css/timeline.css +37 -20
  206. package/dist/css/timer.css +3 -3
  207. package/dist/css/toggle-group.css +4 -4
  208. package/dist/css/tool-call.css +6 -4
  209. package/dist/css/toolbar.css +6 -5
  210. package/dist/css/tooltip.css +15 -16
  211. package/dist/css/tour.css +14 -7
  212. package/dist/css/transfer.css +22 -16
  213. package/dist/css/tree-select.css +10 -10
  214. package/dist/css/tree.css +26 -25
  215. package/dist/css/typography.css +28 -25
  216. package/dist/family/action-control.css +30 -24
  217. package/dist/family/chart.css +57 -0
  218. package/dist/family/collection-item.css +12 -8
  219. package/dist/family/field-chrome.css +28 -19
  220. package/dist/family/loading-ring.css +20 -13
  221. package/dist/family/swatch.css +4 -4
  222. package/dist/family/tag-list.css +6 -0
  223. package/family/action-control.css +30 -24
  224. package/family/chart.css +57 -0
  225. package/family/collection-item.css +12 -8
  226. package/family/field-chrome.css +28 -19
  227. package/family/loading-ring.css +20 -13
  228. package/family/swatch.css +4 -4
  229. package/family/tag-list.css +6 -0
  230. package/index.css +3580 -2060
  231. package/index.unlayered.css +3579 -2060
  232. package/package.json +2 -2
package/css/grid-list.css CHANGED
@@ -74,7 +74,7 @@
74
74
  padding-inline: var(--xh-grid-list-label-px, var(--xh-control-px-md));
75
75
  color: var(--xh-grid-list-label-fg, var(--xh-fg-default));
76
76
  font-size: var(--xh-grid-list-label-font-size, var(--xh-text-label-size));
77
- font-weight: var(--xh-grid-list-label-font-weight, var(--xh-font-weight-semibold));
77
+ font-weight: var(--xh-grid-list-label-font-weight, var(--xh-font-weight-medium));
78
78
  line-height: var(--xh-leading-normal);
79
79
  }
80
80
 
package/css/highlight.css CHANGED
@@ -18,13 +18,13 @@
18
18
  }
19
19
 
20
20
  /* 浏览器给 mark 的默认底色是一个固定的亮黄,暗色主题下压在深底上刺眼、
21
- 配的黑字也不随主题走;这里整份换成随主题走的品牌淡底。
22
- 槽名带 mark 段与部件对上 */
21
+ 配的黑字也不随主题走;这里换成随主题走的标记底(亮色浅黄、暗色深黄),字仍取正文色。
22
+ 不用品牌淡底:那一支专属选中 / 当前。槽名带 mark 段与部件对上 */
23
23
  [data-scope='highlight'][data-part='mark'] {
24
24
  padding-inline: var(--xh-highlight-mark-px, var(--xh-space-0_5));
25
25
  border-radius: var(--xh-highlight-mark-radius, var(--xh-shape-inset));
26
- background: var(--xh-highlight-mark-bg, var(--xh-bg-brand-subtle));
27
- color: var(--xh-highlight-mark-fg, var(--xh-fg-brand-strong));
26
+ background: var(--xh-highlight-mark-bg, var(--xh-bg-mark));
27
+ color: var(--xh-highlight-mark-fg, var(--xh-fg-default));
28
28
  font-weight: var(--xh-highlight-mark-font-weight, var(--xh-font-weight-medium));
29
29
  /* 命中片段跨行时两半各自收边,否则圆角与内边距只画在整段的首尾。
30
30
  两条都写:WebKit 只认带前缀那条 */
@@ -124,15 +124,18 @@
124
124
  --xh-frosted-shadow: var(--xh-hover-card-shadow, var(--xh-_material-shadow));
125
125
  --xh-frosted-backdrop: var(--xh-hover-card-backdrop, var(--xh-_material-backdrop));
126
126
 
127
- /* 尺寸档只换这两个私有槽。size 落在 content 上而非 root:root 是可选部件,
128
- 面板几何也长在 content 上。语气不接:卡片是内容容器,语气该由里面的内容表达 */
129
- --xh-_hover-card-pad: var(--xh-surface-pad-md);
127
+ /* 尺寸档只换这三个私有槽。size 落在 content 上而非 root:root 是可选部件,
128
+ 面板几何也长在 content 上。横向内衬比纵向高一档(缺省纵 12 横 16),与 popover 同一套。
129
+ 语气不接:卡片是内容容器,语气该由里面的内容表达 */
130
+ --xh-_hover-card-py: var(--xh-surface-pad-md);
131
+ --xh-_hover-card-px: var(--xh-surface-pad-lg);
130
132
  --xh-_hover-card-max-w: var(--xh-overlay-max-w);
131
133
 
132
134
  position: relative;
133
135
  display: flex;
134
136
  flex-direction: column;
135
- gap: var(--xh-hover-card-gap, var(--xh-space-2));
137
+ /* 标题与正文贴着排:两行之间只留 4px */
138
+ gap: var(--xh-hover-card-gap, var(--xh-space-1));
136
139
  inline-size: max-content;
137
140
  /* 静态档与落位后的可用宽度取小:窄视口下面板伸出去,最右侧的内容就点不到了 */
138
141
  max-inline-size: min(var(--xh-hover-card-max-w, var(--xh-_hover-card-max-w)), var(--xh-_hover-card-available-w));
@@ -141,8 +144,8 @@
141
144
  overflow-y: auto;
142
145
  /* 浮在页面之上的 Overlay 滚动面:滚到头不把页面一起带走 */
143
146
  overscroll-behavior: contain;
144
- padding-block: var(--xh-hover-card-py, var(--xh-_hover-card-pad));
145
- padding-inline: var(--xh-hover-card-px, var(--xh-_hover-card-pad));
147
+ padding-block: var(--xh-hover-card-py, var(--xh-_hover-card-py));
148
+ padding-inline: var(--xh-hover-card-px, var(--xh-_hover-card-px));
146
149
  border-radius: var(--xh-hover-card-radius, var(--xh-shape-overlay));
147
150
  pointer-events: auto;
148
151
  /* 进退场的缩放锚在贴着锚点的那条边上;两个分量由 positioner 按 placement 写进私有槽 */
@@ -172,28 +175,32 @@
172
175
  }
173
176
 
174
177
  /* —— 尺寸 —— */
175
- /* 缺省档写在 content 的基础规则里;四边等宽的面板内衬三档取 surface-pad 那把尺 */
178
+ /* 缺省档写在 content 的基础规则里;内衬三档取 surface-pad 那把尺,横向始终比纵向高一档 */
176
179
  [data-scope='hover-card'][data-part='content'][data-size='sm'] {
177
- --xh-_hover-card-pad: var(--xh-surface-pad-sm);
180
+ --xh-_hover-card-py: var(--xh-surface-pad-sm);
181
+ --xh-_hover-card-px: var(--xh-surface-pad-md);
178
182
  --xh-_hover-card-max-w: var(--xh-overlay-max-w-sm);
179
183
  }
180
184
 
181
185
  [data-scope='hover-card'][data-part='content'][data-size='lg'] {
182
- --xh-_hover-card-pad: var(--xh-surface-pad-lg);
186
+ --xh-_hover-card-py: var(--xh-surface-pad-lg);
187
+ --xh-_hover-card-px: var(--xh-surface-pad-xl);
183
188
  --xh-_hover-card-max-w: var(--xh-overlay-max-w-lg);
184
189
  }
185
190
 
191
+ /* 气泡标题:14px / medium / 正文色 */
186
192
  [data-scope='hover-card'][data-part='title'] {
187
193
  margin: 0;
188
194
  font-size: var(--xh-hover-card-title-font-size, var(--xh-text-label-size));
189
- font-weight: var(--xh-hover-card-title-font-weight, var(--xh-font-weight-semibold));
195
+ font-weight: var(--xh-hover-card-title-font-weight, var(--xh-font-weight-medium));
190
196
  color: var(--xh-hover-card-title-fg, var(--xh-fg-default));
191
197
  }
192
198
 
193
- /* 说明文字走说明档:13px + fg-muted */
199
+ /* 说明就是卡片的正文:14px 正文字号 + fg-muted 次级色 */
194
200
  [data-scope='hover-card'][data-part='description'] {
195
201
  margin: 0;
196
- font-size: var(--xh-hover-card-description-font-size, var(--xh-text-secondary-size));
202
+ font-size: var(--xh-hover-card-description-font-size, var(--xh-text-body-size));
203
+ line-height: var(--xh-leading-normal);
197
204
  color: var(--xh-hover-card-description-fg, var(--xh-fg-muted));
198
205
  }
199
206
 
@@ -21,8 +21,8 @@
21
21
  position: fixed;
22
22
  inset: 0;
23
23
  z-index: var(--xh-image-viewer-backdrop-layer, var(--xh-_layer, var(--xh-layer-modal)));
24
- /* 看片要压住页面底色,遮罩比普通对话框更深 */
25
- background: var(--xh-image-viewer-backdrop-bg, color-mix(in oklab, var(--xh-color-neutral-950) 78%, transparent));
24
+ /* 与对话框同一层全局遮罩:看片台的深浅由遮罩令牌统一定 */
25
+ background: var(--xh-image-viewer-backdrop-bg, var(--xh-bg-overlay));
26
26
  }
27
27
 
28
28
  /* 同一层底色之上再糊背后的页面 */
@@ -45,6 +45,12 @@
45
45
  }
46
46
 
47
47
  [data-scope='image-viewer'][data-part='positioner'] {
48
+ /* 工具条是页面主题的实体面,看片层(content)却整层是白墨域:页面主题下的面色、描边与字色
49
+ 在域外的这一层取一次,交给工具条 */
50
+ --xh-_image-viewer-page-surface: var(--xh-bg-surface);
51
+ --xh-_image-viewer-page-border: var(--xh-border-default);
52
+ --xh-_image-viewer-page-fg: var(--xh-fg-muted);
53
+
48
54
  position: fixed;
49
55
  inset: 0;
50
56
  z-index: var(--xh-image-viewer-layer, var(--xh-_layer, var(--xh-layer-modal)));
@@ -60,10 +66,11 @@
60
66
 
61
67
  /* 作者塞进浮层的图标:内容层给一档 md 的尺,十颗钮各自再按 Action Control 档位覆盖 */
62
68
  --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-glyph-size-md));
63
- /* 十颗钮共用的深色 chrome:压在使用者的图片上的半透明深底,是这一层自己的面,不取页面语义面 */
64
- --xh-_image-viewer-chrome-bg: var(--xh-image-viewer-chrome-bg, color-mix(in oklab, var(--xh-color-neutral-950) 55%, transparent));
65
- --xh-_image-viewer-chrome-bg-hover: var(--xh-image-viewer-action-bg-hover, color-mix(in oklab, var(--xh-color-neutral-950) 70%, transparent));
66
- --xh-_image-viewer-chrome-bg-active: var(--xh-image-viewer-action-bg-active, color-mix(in oklab, var(--xh-color-neutral-950) 80%, transparent));
69
+ /* 翻页钮、关闭钮与计数共用的深色 chrome:压在使用者的图片上的半透明深底,取画面控件面那组令牌,
70
+ 不取页面语义面。白面压在亮图上分不出来(白 30% 的面压亮图不到 1.4:1),这几件留在深纱上 */
71
+ --xh-_image-viewer-chrome-bg: var(--xh-image-viewer-chrome-bg, var(--xh-bg-media-chrome));
72
+ --xh-_image-viewer-chrome-bg-hover: var(--xh-image-viewer-action-bg-hover, var(--xh-bg-media-chrome-hover));
73
+ --xh-_image-viewer-chrome-bg-active: var(--xh-image-viewer-action-bg-active, var(--xh-bg-media-chrome-active));
67
74
 
68
75
  position: relative;
69
76
  inline-size: 100%;
@@ -73,7 +80,7 @@
73
80
  justify-content: center;
74
81
  outline: none;
75
82
  /* 深色底上的工具条与计数固定用浅字,不随主题翻 */
76
- color: var(--xh-image-viewer-fg, var(--xh-color-neutral-0));
83
+ color: var(--xh-image-viewer-fg, var(--xh-fg-on-media-chrome));
77
84
  }
78
85
 
79
86
  /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
@@ -169,7 +176,7 @@
169
176
  will-change: translate;
170
177
  }
171
178
 
172
- /* —— 悬浮件共用:半透明深底加浅字 ——
179
+ /* —— 悬浮件 ——
173
180
  四件都钉在铺满视口的那一层的边上,贴边一律与安全区取大的一头:刘海、圆角与
174
181
  底部横条压住的那一段由系统给出,贴边比它窄时钮会被切掉一角;桌面上 env() 恒为 0。
175
182
  安全区只有物理方向的四个名字,行内轴上两侧同取较宽的那一段,RTL 下不会翻错边。
@@ -179,20 +186,33 @@
179
186
  [data-scope='image-viewer'][data-part='counter'] {
180
187
  position: absolute;
181
188
  z-index: 1;
189
+ }
190
+
191
+ /* 计数:一行浅字压在深纱上 */
192
+ [data-scope='image-viewer'][data-part='counter'] {
182
193
  background: var(--xh-_image-viewer-chrome-bg);
183
194
  color: inherit;
184
195
  border: none;
185
196
  }
186
197
 
198
+ /* 工具条:页面主题的实体面(亮色白面、暗色深面)+ 1px 描边。面色在看片层的白墨域之外取
199
+ (定位层捕获的页面取值),连接层在它身上打 data-xh-ink-surface:七颗钮与作者放进来的内容
200
+ 按这块底自成墨色域,字色、悬停阶梯与焦点环都随面的深浅走,不再钉在浅字上。
201
+ 强制色下面被换成 Canvas、与遮罩同色,边界只剩这圈描边 */
187
202
  [data-scope='image-viewer'][data-part='toolbar'] {
203
+ --xh-ink-surface: var(--xh-image-viewer-toolbar-bg, var(--xh-_image-viewer-page-surface));
204
+
188
205
  inset-block-end: max(var(--xh-space-6), env(safe-area-inset-bottom));
189
206
  inset-inline-start: 50%;
190
207
  translate: -50% 0;
191
208
  display: flex;
192
209
  align-items: center;
193
210
  gap: var(--xh-image-viewer-toolbar-gap, var(--xh-space-1));
194
- padding: var(--xh-image-viewer-toolbar-padding, var(--xh-space-1_5) var(--xh-space-3));
211
+ padding: var(--xh-image-viewer-toolbar-padding, var(--xh-space-1_5) var(--xh-space-4));
212
+ border: var(--xh-stroke-thin) solid var(--xh-_image-viewer-page-border);
195
213
  border-radius: var(--xh-image-viewer-toolbar-radius-outer, var(--xh-image-viewer-overlay-radius, var(--xh-shape-surface)));
214
+ background: var(--xh-image-viewer-toolbar-bg, var(--xh-_image-viewer-page-surface));
215
+ color: var(--xh-_image-viewer-page-fg);
196
216
  }
197
217
 
198
218
  /* 起点是逻辑属性、平移是物理通道:rtl 下行内分量掉头,工具条与计数才落回中线 */
@@ -200,20 +220,23 @@
200
220
  translate: 50% 0;
201
221
  }
202
222
 
203
- /* 工具条里的七颗钮:接 Action Control icon 档 xs(24px 视觉盒),底色交给工具条,本体只管命中区与按压。
204
- 悬停 / 按下的底从 chrome 那层深底派生,不取页面的 --xh-bg-subtle-* 阶梯。
223
+ /* 工具条里的七颗钮:接 Action Control icon 档 xs(字形 16px),视觉盒放大到 box md(36px),
224
+ 底色交给工具条,本体只管命中区与按压。钮是工具条这块面上的墨色域:悬停 / 按下走白底阶梯
225
+ (100 → 200),字取次要字色,都按工具条的底色求值。
205
226
  position 交给配方的 relative:粗指针下 44px 命中区 ::after 以钮自身为包含块;
206
227
  这里若写 static,七块命中区会一起以工具条为包含块、彼此盖住,触屏上只剩最后一颗可点 */
207
228
  [data-scope='image-viewer'][data-part='toolbar'] > [data-part] {
229
+ --xh-action-visual-size: var(--xh-control-box-md);
230
+ --xh-action-min-inline-size: var(--xh-control-box-md);
208
231
  --xh-action-bg-rest: transparent;
209
- --xh-action-bg-hover: var(--xh-_image-viewer-chrome-bg-hover);
210
- --xh-action-bg-pressed: var(--xh-_image-viewer-chrome-bg-active);
232
+ --xh-action-bg-hover: var(--xh-bg-subtle);
233
+ --xh-action-bg-pressed: var(--xh-bg-subtle-hover);
211
234
  --xh-action-bg-focus-visible: transparent;
212
235
  --xh-action-bg-disabled: transparent;
213
- --xh-action-fg-rest: currentColor;
214
- --xh-action-fg-hover: currentColor;
215
- --xh-action-fg-pressed: currentColor;
216
- --xh-action-fg-focus-visible: currentColor;
236
+ --xh-action-fg-rest: var(--xh-fg-muted);
237
+ --xh-action-fg-hover: var(--xh-fg-muted);
238
+ --xh-action-fg-pressed: var(--xh-fg-muted);
239
+ --xh-action-fg-focus-visible: var(--xh-fg-muted);
217
240
  --xh-action-fg-disabled: var(--xh-fg-disabled);
218
241
  --xh-action-border-rest: transparent;
219
242
  --xh-action-border-hover: transparent;
@@ -237,7 +260,23 @@
237
260
  translate: 50% 0;
238
261
  }
239
262
 
240
- /* 两颗翻页钮:浮在图上的单图标圆钮,接 Action Control floating 档 md(48px,正方盒取 circle)。
263
+ /* 翻页与关闭钮的尺:看片台上的媒体控制钮与同档控件等高(control-h,md 32px),字形比控件内
264
+ 图标低一档(sm / md 16px、lg 20px),不压画面。三颗钮与组件同档 */
265
+ [data-scope='image-viewer']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger']) {
266
+ --xh-_image-viewer-nav-size: var(--xh-control-h-md);
267
+ --xh-_image-viewer-nav-glyph: var(--xh-glyph-size-sm);
268
+ }
269
+
270
+ [data-scope='image-viewer']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger'])[data-xh-action-size='sm'] {
271
+ --xh-_image-viewer-nav-size: var(--xh-control-h-sm);
272
+ }
273
+
274
+ [data-scope='image-viewer']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger'])[data-xh-action-size='lg'] {
275
+ --xh-_image-viewer-nav-size: var(--xh-control-h-lg);
276
+ --xh-_image-viewer-nav-glyph: var(--xh-glyph-size-md);
277
+ }
278
+
279
+ /* 两颗翻页钮:浮在图上的单图标圆钮,接 Action Control floating 档(正方盒取 circle),视觉盒改走上面的尺。
241
280
  面桥接到自家深色 chrome:跟的是图上那层半透明深底不是页面底色,所以不取 frosted 缺省面,
242
281
  也不取语义档的 --xh-bg-subtle-*;到头时是原生 disabled,压不动的东西不给回应 */
243
282
  [data-scope='image-viewer'][data-part='prev-trigger'],
@@ -258,26 +297,28 @@
258
297
  --xh-action-border-focus-visible: transparent;
259
298
  --xh-action-border-disabled: transparent;
260
299
  --xh-action-radius: var(--xh-image-viewer-overlay-radius, var(--xh-_action-profile-radius));
261
- --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-_action-profile-glyph-size));
300
+ --xh-action-visual-size: var(--xh-image-viewer-nav-size, var(--xh-_image-viewer-nav-size));
301
+ --xh-action-min-inline-size: var(--xh-image-viewer-nav-size, var(--xh-_image-viewer-nav-size));
302
+ --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-_image-viewer-nav-glyph));
262
303
 
263
304
  position: absolute;
264
305
  z-index: 1;
265
306
  }
266
307
 
267
308
  [data-scope='image-viewer'][data-part='prev-trigger'] {
268
- inset-inline-start: max(var(--xh-space-6), env(safe-area-inset-left), env(safe-area-inset-right));
309
+ inset-inline-start: max(var(--xh-space-5), env(safe-area-inset-left), env(safe-area-inset-right));
269
310
  inset-block-start: 50%;
270
311
  translate: 0 -50%;
271
312
  }
272
313
 
273
314
  [data-scope='image-viewer'][data-part='next-trigger'] {
274
- inset-inline-end: max(var(--xh-space-6), env(safe-area-inset-left), env(safe-area-inset-right));
315
+ inset-inline-end: max(var(--xh-space-5), env(safe-area-inset-left), env(safe-area-inset-right));
275
316
  inset-block-start: 50%;
276
317
  translate: 0 -50%;
277
318
  }
278
319
 
279
- /* 右上角的关闭钮:悬浮在媒体上的单图标动作,与翻页钮同走 Action Control floating 档(sm = 40px、圆形);
280
- 面与翻页钮同一层深色 chrome */
320
+ /* 右上角的关闭钮:悬浮在媒体上的单图标动作,与翻页钮同走 Action Control floating 档、同一把尺(圆形);
321
+ 面与翻页钮同一层深色 chrome,离右上角比翻页钮离边远一档,不与画面边角的内容挤在一起 */
281
322
  [data-scope='image-viewer'][data-part='close-trigger'] {
282
323
  --xh-action-bg-rest: var(--xh-_image-viewer-chrome-bg);
283
324
  --xh-action-bg-hover: var(--xh-image-viewer-close-bg-hover, var(--xh-_image-viewer-chrome-bg-hover));
@@ -296,13 +337,14 @@
296
337
  --xh-action-border-focus-visible: transparent;
297
338
  --xh-action-border-disabled: transparent;
298
339
  --xh-action-radius: var(--xh-image-viewer-close-radius, var(--xh-shape-circle));
299
- --xh-action-visual-size: var(--xh-image-viewer-close-size, var(--xh-_action-profile-visual-size));
300
- --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-_action-profile-glyph-size));
340
+ --xh-action-visual-size: var(--xh-image-viewer-close-size, var(--xh-_image-viewer-nav-size));
341
+ --xh-action-min-inline-size: var(--xh-image-viewer-close-size, var(--xh-_image-viewer-nav-size));
342
+ --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-_image-viewer-nav-glyph));
301
343
 
302
344
  position: absolute;
303
345
  z-index: 1;
304
- inset-block-start: max(var(--xh-space-6), env(safe-area-inset-top));
305
- inset-inline-end: max(var(--xh-space-6), env(safe-area-inset-left), env(safe-area-inset-right));
346
+ inset-block-start: max(var(--xh-space-8), env(safe-area-inset-top));
347
+ inset-inline-end: max(var(--xh-space-8), env(safe-area-inset-left), env(safe-area-inset-right));
306
348
  }
307
349
 
308
350
  /* liquid 档:data-material="liquid" 下控制层换成液态面,深色纱那一套只属于 standard 档。
@@ -324,7 +366,11 @@
324
366
  box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
325
367
  }
326
368
 
369
+ /* 液态工具条自己就是墨色域(按下层写 data-xh-ink):钮不再按页面面色另取墨色,
370
+ 撤掉 ink-surface,钮里的墨色随这块液态面的域走 */
327
371
  :where([data-material='liquid']) [data-scope='image-viewer'][data-part='toolbar'][data-xh-liquid] {
372
+ --xh-ink-surface: initial;
373
+
328
374
  border-radius: var(--xh-image-viewer-toolbar-radius-outer, var(--xh-image-viewer-overlay-radius, var(--xh-shape-pill)));
329
375
  }
330
376
 
@@ -336,6 +382,10 @@
336
382
  :where([data-material='liquid']) [data-scope='image-viewer'][data-part='toolbar'][data-xh-liquid] > [data-part] {
337
383
  --xh-action-bg-hover: var(--xh-image-viewer-action-bg-hover, var(--xh-bg-subtle));
338
384
  --xh-action-bg-pressed: var(--xh-image-viewer-action-bg-active, var(--xh-bg-subtle-hover));
385
+ --xh-action-fg-rest: currentColor;
386
+ --xh-action-fg-hover: currentColor;
387
+ --xh-action-fg-pressed: currentColor;
388
+ --xh-action-fg-focus-visible: currentColor;
339
389
  }
340
390
 
341
391
  :where([data-material='liquid']) [data-scope='image-viewer'][data-part='prev-trigger'][data-xh-liquid],
package/css/image.css CHANGED
@@ -56,7 +56,7 @@
56
56
  display: flex;
57
57
  align-items: center;
58
58
  justify-content: center;
59
- background: var(--xh-image-placeholder-bg, var(--xh-bg-subtle-hover-opaque));
59
+ background: var(--xh-image-placeholder-bg, var(--xh-bg-subtle-opaque));
60
60
  color: var(--xh-image-placeholder-fg, var(--xh-fg-subtle));
61
61
  }
62
62
 
@@ -70,17 +70,25 @@
70
70
  display: none;
71
71
  }
72
72
 
73
+ /* 回退内容:图标在上、说明在下竖排居中。自带不透明淡底,说明字的对比只看这一层,
74
+ 不透出页底(次要字色压在半透明淡底上透出页底时到不了 4.5:1) */
73
75
  [data-scope='image'][data-part='fallback'] {
76
+ box-sizing: border-box;
74
77
  display: flex;
78
+ flex-direction: column;
75
79
  align-items: center;
76
80
  justify-content: center;
77
81
  inline-size: 100%;
78
82
  block-size: 100%;
79
83
  /* 没给 ratio 时根盒子高度是 auto,回退内容自己撑出一个不塌的高度 */
80
84
  min-block-size: var(--xh-image-fallback-min-h, var(--xh-control-h-lg));
81
- color: var(--xh-image-fallback-fg, var(--xh-fg-muted));
82
- font-size: var(--xh-image-fallback-font-size, var(--xh-text-secondary-size));
83
- line-height: var(--xh-leading-none);
85
+ padding-block: var(--xh-image-fallback-py, var(--xh-space-2));
86
+ padding-inline: var(--xh-image-fallback-px, var(--xh-space-4));
87
+ background: var(--xh-image-fallback-bg, var(--xh-bg-subtle-opaque));
88
+ color: var(--xh-image-fallback-fg, var(--xh-fg-subtle));
89
+ font-size: var(--xh-image-fallback-font-size, var(--xh-text-caption-size));
90
+ line-height: var(--xh-leading-relaxed);
91
+ text-align: center;
84
92
  user-select: none;
85
93
  }
86
94
 
@@ -40,8 +40,7 @@
40
40
  * 取下一页的按钮:与哨兵同一条通路的键盘入口,摆在列表末尾自成一行——铺满一行的独立动作条目,
41
41
  * 接 Action Control 的 row 档、outline 形态:宽度由容器给、高度随内容、按下只换面不缩放;
42
42
  * 盒几何、中性描边与透明底、悬停 / 按下 / 禁用面、焦点环与粗指针热区全由家族给,
43
- * 白底承载 hover 100 → pressed 200。这里只把使用者槽映射到桥接槽,并把文案居中:
44
- * 它是一行里唯一的东西,靠起始缘会像一条没对齐的列表项。
43
+ * 白底承载 hover 100 → pressed 200。这里只把使用者槽映射到桥接槽,文案居中写在下一条。
45
44
  * 行高不吃家族的单行档:row 档允许换行、高度随内容,折行的文案走正文行高
46
45
  */
47
46
  [data-scope='infinite-scroll'][data-part='load-more-trigger'] {
@@ -62,13 +61,18 @@
62
61
  /* 作者塞进钮里的图标按档取字形尺寸,与文案同一把尺 */
63
62
  --xh-icon-size: var(--xh-infinite-scroll-load-more-icon-size, var(--xh-_action-profile-glyph-size));
64
63
 
65
- justify-content: center;
66
- text-align: center;
67
64
  line-height: var(--xh-leading-normal);
68
65
  /* 到底了连点是常态,触屏上默认会当成双击缩放 */
69
66
  touch-action: manipulation;
70
67
  }
71
68
 
69
+ /* 文案居中(单行整段居中,折行逐行居中),盖掉 row 档的靠起始缘排布:它是一行里唯一的东西,
70
+ 靠起始缘会像一条没对齐的列表项。选择器点名 row 档,有层与无层两份产物里都压得住它 */
71
+ [data-scope='infinite-scroll'][data-part='load-more-trigger'][data-xh-action-profile='row'] {
72
+ justify-content: center;
73
+ text-align: center;
74
+ }
75
+
72
76
  /* 声明过 display 就盖掉了 UA 的 [hidden]{display:none},作者要藏哨兵时得自己补回来 */
73
77
  [data-scope='infinite-scroll'][data-part='sentinel'][hidden],
74
78
  [data-scope='infinite-scroll'][data-part='load-more-trigger'][hidden] {
@@ -21,11 +21,13 @@
21
21
  --xh-_input-group-h: var(--xh-control-h-md);
22
22
  --xh-_input-group-px: var(--xh-control-px-md);
23
23
  --xh-_input-group-font-size: var(--xh-control-font-md);
24
- --xh-_input-group-bg: transparent;
25
- --xh-_input-group-bg-hover: color-mix(in oklab, var(--xh-bg-subtle) 45%, transparent);
26
- /* 组壳按字段外壳画 outline 描边:静息 --xh-border-control、悬停升 -hover、聚焦换 -focus,无影 */
24
+ /* 组壳与字段外壳同形:静息字段淡底 + --xh-border-control;悬停底不变、描边升 --xh-border-strong;
25
+ 聚焦换承载面 + --xh-border-control-focus,不画聚焦环(强制色档补一圈 Highlight 环);无影 */
26
+ --xh-_input-group-bg: var(--xh-bg-field);
27
+ --xh-_input-group-bg-hover: var(--xh-bg-field);
28
+ --xh-_input-group-bg-focus: var(--xh-bg-surface);
27
29
  --xh-_input-group-border: var(--xh-border-control);
28
- --xh-_input-group-border-hover: var(--xh-border-control-hover);
30
+ --xh-_input-group-border-hover: var(--xh-border-strong);
29
31
  --xh-_input-group-border-focus: var(--xh-border-control-focus);
30
32
  --xh-_input-group-shadow: none;
31
33
 
@@ -36,7 +38,10 @@
36
38
  /* 整组是一个字段:不传尺寸时与单个字段同宽,组里的字段让位占满前后缀之外的那段 */
37
39
  inline-size: var(--xh-input-group-w, var(--xh-control-w));
38
40
  border-radius: var(--xh-input-group-radius, var(--xh-shape-control));
39
- background: var(--xh-input-group-bg, var(--xh-_input-group-bg));
41
+ /* 面只在这一处画:各状态只换 --xh-_input-group-face 这一个槽,静息、悬停、失效、只读、禁用与聚焦
42
+ 顺着同一条声明换色,过渡也只认这一处 */
43
+ --xh-_input-group-face: var(--xh-input-group-bg, var(--xh-_input-group-bg));
44
+ background: var(--xh-_input-group-face);
40
45
  box-shadow: var(--xh-input-group-shadow, var(--xh-_input-group-shadow));
41
46
 
42
47
  /* 父容器给不出这么宽时整组跟着收,不越出父容器 */
@@ -62,6 +67,7 @@
62
67
  [data-scope='input-group'][data-part='root'][data-variant='subtle'] {
63
68
  --xh-_input-group-bg: var(--xh-bg-subtle);
64
69
  --xh-_input-group-bg-hover: var(--xh-bg-subtle-hover);
70
+ --xh-_input-group-bg-focus: var(--xh-bg-subtle);
65
71
  --xh-_input-group-border: transparent;
66
72
  --xh-_input-group-border-hover: var(--xh-border-control);
67
73
  --xh-_input-group-shadow: none;
@@ -70,34 +76,55 @@
70
76
  /* ghost:静息不画壳,悬停与聚焦沿用下面的 hover / focus 规则浮出 --xh-border-control 与底 */
71
77
  [data-scope='input-group'][data-part='root'][data-variant='ghost'] {
72
78
  --xh-_input-group-bg: transparent;
79
+ --xh-_input-group-bg-hover: color-mix(in oklab, var(--xh-bg-subtle) 45%, transparent);
80
+ --xh-_input-group-bg-focus: transparent;
73
81
  --xh-_input-group-border: transparent;
74
82
  --xh-_input-group-border-hover: var(--xh-border-control);
75
83
  --xh-_input-group-shadow: none;
76
84
  }
77
85
 
78
- [data-scope='input-group'][data-part='root']:not(:has([data-disabled])):hover {
79
- background: var(--xh-input-group-bg-hover, var(--xh-_input-group-bg-hover));
86
+ /* 悬停浮出描边与底:组里的字段只读、禁用或失效时不浮。只读与禁用和下面的禁用面一样只认带字段外壳的那一段,
87
+ 组里单独禁用一颗按钮不让整组失去悬停 */
88
+ [data-scope='input-group'][data-part='root']:not(:has([data-xh-field-chrome]:is([data-disabled], [data-readonly]), [data-invalid], [aria-invalid='true'])):not(:focus-within):hover {
89
+ --xh-_input-group-face: var(--xh-input-group-bg-hover, var(--xh-_input-group-bg-hover));
80
90
  }
81
91
 
82
- [data-scope='input-group'][data-part='root']:not(:has([data-disabled])):hover::before {
92
+ [data-scope='input-group'][data-part='root']:not(:has([data-xh-field-chrome]:is([data-disabled], [data-readonly]), [data-invalid], [aria-invalid='true'])):not(:focus-within):hover::before {
83
93
  border-color: var(--xh-input-group-border-hover, var(--xh-_input-group-border-hover));
84
94
  }
85
95
 
86
- [data-scope='input-group'][data-part='root']:focus-within {
87
- outline: var(--xh-ring-width) solid var(--xh-input-group-ring-focus, var(--xh-ring-focus));
88
- outline-offset: var(--xh-ring-offset);
89
- }
90
-
91
- [data-scope='input-group'][data-part='root']:focus-within::before {
92
- border-color: var(--xh-input-group-border-focus, var(--xh-_input-group-border-focus));
96
+ /* 组里的字段校验失败:失效描边 + 4% 失效色淡底,与字段外壳的失效档同一副面 */
97
+ [data-scope='input-group'][data-part='root']:has([data-invalid], [aria-invalid='true']) {
98
+ --xh-_input-group-face: var(--xh-input-group-bg-invalid, var(--xh-bg-field-invalid));
93
99
  }
94
100
 
95
101
  [data-scope='input-group'][data-part='root']:has([data-invalid], [aria-invalid='true'])::before {
96
102
  border-color: var(--xh-input-group-border-invalid, var(--xh-border-invalid));
97
103
  }
98
104
 
99
- [data-scope='input-group'][data-part='root']:has([data-invalid], [aria-invalid='true']):focus-within {
100
- outline-color: var(--xh-input-group-ring-invalid, var(--xh-ring-invalid));
105
+ /* 组里的字段只读 / 禁用:组壳换淡底,禁用另把描边退到 --xh-border-default;
106
+ 只认带字段外壳的那一段,组里单独禁用一颗按钮不让整组变灰。
107
+ 只读用 :where() 压低特指度,拿到焦点时与字段外壳一样让位给聚焦态 */
108
+ [data-scope='input-group'][data-part='root']:has(:where([data-xh-field-chrome][data-readonly])) {
109
+ --xh-_input-group-face: var(--xh-input-group-bg-read-only, var(--xh-bg-subtle));
110
+ }
111
+
112
+ [data-scope='input-group'][data-part='root']:has([data-xh-field-chrome][data-disabled]) {
113
+ --xh-_input-group-face: var(--xh-input-group-bg-disabled, var(--xh-bg-subtle));
114
+ }
115
+
116
+ [data-scope='input-group'][data-part='root']:has([data-xh-field-chrome][data-disabled])::before {
117
+ border-color: var(--xh-input-group-border-disabled, var(--xh-border-default));
118
+ }
119
+
120
+ /* 聚焦排在失效之后:校验失败的字段拿到焦点时让位给聚焦态。
121
+ 焦点由描边换色与承载面的底色差标出,不画聚焦环 */
122
+ [data-scope='input-group'][data-part='root']:focus-within {
123
+ --xh-_input-group-face: var(--xh-input-group-bg-focus, var(--xh-_input-group-bg-focus));
124
+ }
125
+
126
+ [data-scope='input-group'][data-part='root']:focus-within::before {
127
+ border-color: var(--xh-input-group-border-focus, var(--xh-_input-group-border-focus));
101
128
  }
102
129
 
103
130
  /* 给了 display 的角色节点必须补这条:display 声明会盖掉 UA 的 [hidden]{display:none},
@@ -162,7 +189,7 @@
162
189
  transition: none;
163
190
  }
164
191
 
165
- /* 焦点环由组的外表面绘制,子输入保留焦点语义但不再重复画第二圈。 */
192
+ /* 聚焦换色由组的外表面承担(强制色档的系统色环也画在组壳上),子输入保留焦点语义但不再自己画一圈。 */
166
193
  [data-scope='input-group'][data-part='root'] [data-xh-field-chrome]:focus-within {
167
194
  outline: none;
168
195
  }
@@ -222,7 +249,8 @@
222
249
  }
223
250
 
224
251
  /* —— 前后缀块 —— */
225
- /* 前后缀是输入表面里的静态内容,不单独绘制底色、描边或焦点状态。 */
252
+ /* 前后缀是输入表面里的静态内容:铺一层淡底与可输入的那一段分开、取正文色,两侧内距对称;
253
+ 不单独绘制外框或焦点状态,外轮廓与聚焦换色归组壳 */
226
254
  [data-scope='input-group'][data-part='item'] {
227
255
  display: inline-flex;
228
256
  box-sizing: border-box;
@@ -230,25 +258,32 @@
230
258
  align-items: center;
231
259
  block-size: var(--xh-input-group-item-h, var(--xh-_input-group-h));
232
260
  padding-inline: var(--xh-input-group-item-px, var(--xh-_input-group-px));
233
- color: var(--xh-input-group-item-fg, var(--xh-fg-muted));
261
+ background-color: var(--xh-input-group-item-bg, var(--xh-bg-subtle));
262
+ color: var(--xh-input-group-item-fg, var(--xh-fg-default));
234
263
  font-size: var(--xh-input-group-item-font-size, var(--xh-_input-group-font-size));
235
264
  line-height: var(--xh-leading-none);
236
265
  white-space: nowrap;
237
266
  }
238
267
 
239
- /* 与输入控件相邻的一侧由控件自己的内距留白,避免前后缀之间出现双份间距。 */
240
- [data-scope='input-group'][data-part='root'] > [data-scope='input-group'][data-part='item']:first-child {
241
- padding-inline-end: 0;
268
+ /* 与相邻段之间一道满高的缺省描边,只画在朝里的那一侧,外侧交给组壳的外轮廓。
269
+ 两块前后缀挨着时只由后一块画:半透明描边两道相叠会叠深 */
270
+ [data-scope='input-group'][data-part='root'] > [data-scope='input-group'][data-part='item']:not(:first-child) {
271
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-input-group-item-divider, var(--xh-border-default));
242
272
  }
243
273
 
244
- [data-scope='input-group'][data-part='root'] > [data-scope='input-group'][data-part='item']:last-child {
245
- padding-inline-start: 0;
274
+ [data-scope='input-group'][data-part='root'] > [data-scope='input-group'][data-part='item']:not(:last-child):not(:has(+ [data-scope='input-group'][data-part='item'])) {
275
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-input-group-item-divider, var(--xh-border-default));
246
276
  }
247
277
 
248
278
  [data-scope='input-group'][data-part='item'][hidden] {
249
279
  display: none;
250
280
  }
251
281
 
282
+ /* 组里的字段禁用:前后缀块的字随字段禁用面换 --xh-fg-disabled,与组壳的禁用面同一个判据 */
283
+ [data-scope='input-group'][data-part='root']:has([data-xh-field-chrome][data-disabled]) > [data-scope='input-group'][data-part='item'] {
284
+ color: var(--xh-fg-disabled);
285
+ }
286
+
252
287
  @media (forced-colors: active) {
253
288
  [data-scope='input-group'][data-part='root'] {
254
289
  background: Canvas;
@@ -259,8 +294,10 @@
259
294
  border-color: ButtonText;
260
295
  }
261
296
 
297
+ /* 常规档不画环、只换描边色;这一档里描边换色未必分得出来,补一圈系统色环 */
262
298
  [data-scope='input-group'][data-part='root']:focus-within {
263
- outline-color: Highlight;
299
+ outline: var(--xh-ring-width) solid Highlight;
300
+ outline-offset: var(--xh-ring-offset);
264
301
  }
265
302
 
266
303
  [data-scope='input-group'][data-part='root']:focus-within::before,
@@ -268,8 +305,19 @@
268
305
  border-color: Highlight;
269
306
  }
270
307
 
308
+ [data-scope='input-group'][data-part='root']:has([data-xh-field-chrome][data-disabled])::before {
309
+ border-color: GrayText;
310
+ }
311
+
312
+ /* 淡底在这一档被抹成 Canvas,前后缀与输入段只剩分隔线分得开:线换系统色 */
271
313
  [data-scope='input-group'][data-part='item'] {
314
+ background-color: Canvas;
272
315
  color: CanvasText;
316
+ border-color: ButtonText;
317
+ }
318
+
319
+ [data-scope='input-group'][data-part='root']:has([data-xh-field-chrome][data-disabled]) > [data-scope='input-group'][data-part='item'] {
320
+ color: GrayText;
273
321
  }
274
322
  }
275
323
  }
package/css/kbd.css CHANGED
@@ -27,7 +27,7 @@
27
27
  font-family: var(--xh-kbd-font, inherit);
28
28
  /* 快捷键是次级标注,字号取 caption 档 */
29
29
  font-size: var(--xh-kbd-font-size, var(--xh-text-caption-size));
30
- font-weight: var(--xh-kbd-font-weight, var(--xh-font-weight-medium));
30
+ font-weight: var(--xh-kbd-font-weight, var(--xh-font-weight-regular));
31
31
  line-height: var(--xh-leading-none);
32
32
  text-align: center;
33
33
  text-decoration: none;