@kerfjs/ui 5.0.0-beta.106 → 5.0.0-beta.108

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 (283) hide show
  1. package/README.md +2 -1
  2. package/ai/application-ui-diagnostic-ids-v1.json +1 -0
  3. package/ai/application-ui-profile.defaults.json +6 -1
  4. package/ai/component-catalog.json +184 -39
  5. package/ai/component-composition-rules.json +20 -2
  6. package/ai/component-composition.d.ts +11 -0
  7. package/ai/component-composition.json +126 -21
  8. package/ai/component-composition.schema.json +32 -0
  9. package/ai/components/README.md +3 -2
  10. package/ai/components/button.md +9 -6
  11. package/ai/components/checkbox-group.md +89 -0
  12. package/ai/components/checkbox.md +3 -2
  13. package/ai/components/chip.md +1 -0
  14. package/ai/components/color-picker.md +10 -7
  15. package/ai/components/disclosure.md +6 -1
  16. package/ai/components/foundation.md +1 -1
  17. package/ai/components/list-detail-dialog.md +1 -1
  18. package/ai/components/list.md +1 -1
  19. package/ai/components/message-composer.md +2 -1
  20. package/ai/components/radio-group.md +4 -3
  21. package/ai/components/segmented-control.md +1 -0
  22. package/ai/components/split-button.md +5 -2
  23. package/ai/components/surface-scaffold.md +3 -1
  24. package/ai/components/switch.md +1 -1
  25. package/ai/components/text-field.md +3 -1
  26. package/ai/components/text.md +2 -0
  27. package/ai/components/toolbar-control-group.md +1 -0
  28. package/ai/components/toolbar.md +1 -1
  29. package/ai/components/wa-checkbox-group.md +5 -5
  30. package/ai/components/workbench-dialog.md +1 -1
  31. package/ai/public-api-signatures-v1.md +258 -35
  32. package/ai/skill.md +82 -65
  33. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  34. package/dist/browser/checkbox-group.js +5 -0
  35. package/dist/button.d.ts +18 -5
  36. package/dist/button.js +1 -1
  37. package/dist/catalog.js +11 -10
  38. package/dist/catalog.js.map +1 -1
  39. package/dist/checkbox-group.d.ts +70 -0
  40. package/dist/checkbox-group.js +7 -0
  41. package/dist/checkbox-group.js.map +1 -0
  42. package/dist/chip.d.ts +20 -2
  43. package/dist/chip.js +2 -1
  44. package/dist/{chunk-SQ2Q3OQI.js → chunk-2LM3PYHA.js} +2 -2
  45. package/dist/{chunk-SQ2Q3OQI.js.map → chunk-2LM3PYHA.js.map} +1 -1
  46. package/dist/{chunk-HYORKKYP.js → chunk-3VZ6SFD4.js} +1 -1
  47. package/dist/chunk-3VZ6SFD4.js.map +1 -0
  48. package/dist/{chunk-EKBMUXFV.js → chunk-3Z7N2NAZ.js} +141 -54
  49. package/dist/chunk-3Z7N2NAZ.js.map +1 -0
  50. package/dist/{chunk-23PPPNH6.js → chunk-4OV272LF.js} +2 -2
  51. package/dist/{chunk-23PPPNH6.js.map → chunk-4OV272LF.js.map} +1 -1
  52. package/dist/{chunk-2PXZBFEC.js → chunk-5J6Z4BWY.js} +1 -1
  53. package/dist/{chunk-2PXZBFEC.js.map → chunk-5J6Z4BWY.js.map} +1 -1
  54. package/dist/{chunk-TAHR457X.js → chunk-6CDILXF4.js} +5 -1
  55. package/dist/chunk-6CDILXF4.js.map +1 -0
  56. package/dist/{chunk-DDSCVEO5.js → chunk-CPSGUGAY.js} +6 -6
  57. package/dist/{chunk-DDSCVEO5.js.map → chunk-CPSGUGAY.js.map} +1 -1
  58. package/dist/{chunk-C3RLKKFQ.js → chunk-EYDXFOSH.js} +13 -8
  59. package/dist/chunk-EYDXFOSH.js.map +1 -0
  60. package/dist/{chunk-PE2KPZDW.js → chunk-HDXUHLTQ.js} +7 -2
  61. package/dist/chunk-HDXUHLTQ.js.map +1 -0
  62. package/dist/chunk-HU5IHXCI.js +73 -0
  63. package/dist/chunk-HU5IHXCI.js.map +1 -0
  64. package/dist/{chunk-DF2YKGIX.js → chunk-JCCN3U6X.js} +2 -2
  65. package/dist/{chunk-DF2YKGIX.js.map → chunk-JCCN3U6X.js.map} +1 -1
  66. package/dist/{chunk-UTCAOOXU.js → chunk-KPINJHIC.js} +8 -2
  67. package/dist/chunk-KPINJHIC.js.map +1 -0
  68. package/dist/{chunk-N7MBGONH.js → chunk-LMHN2TJL.js} +22 -2
  69. package/dist/chunk-LMHN2TJL.js.map +1 -0
  70. package/dist/{chunk-NS2TBYM4.js → chunk-LZUUUHNH.js} +7 -3
  71. package/dist/chunk-LZUUUHNH.js.map +1 -0
  72. package/dist/{chunk-GCAK23PU.js → chunk-MVKHSAKE.js} +2 -2
  73. package/dist/{chunk-GCAK23PU.js.map → chunk-MVKHSAKE.js.map} +1 -1
  74. package/dist/{chunk-OY2MXIBB.js → chunk-NB6POCFH.js} +3 -1
  75. package/dist/chunk-NB6POCFH.js.map +1 -0
  76. package/dist/{chunk-ECFCAKWE.js → chunk-NR6O74ST.js} +5 -1
  77. package/dist/chunk-NR6O74ST.js.map +1 -0
  78. package/dist/{chunk-7W3GKMN4.js → chunk-OQP3PFKQ.js} +7 -4
  79. package/dist/chunk-OQP3PFKQ.js.map +1 -0
  80. package/dist/{chunk-FKKJHGN5.js → chunk-P7EJ4CAD.js} +2 -2
  81. package/dist/{chunk-FKKJHGN5.js.map → chunk-P7EJ4CAD.js.map} +1 -1
  82. package/dist/{chunk-ZXZAECHZ.js → chunk-SOFPUW3O.js} +4 -4
  83. package/dist/{chunk-ZXZAECHZ.js.map → chunk-SOFPUW3O.js.map} +1 -1
  84. package/dist/{chunk-WJKHLOP5.js → chunk-TI2GV36S.js} +8 -2
  85. package/dist/chunk-TI2GV36S.js.map +1 -0
  86. package/dist/{chunk-QLA25V2K.js → chunk-WPNIKZMJ.js} +15 -1
  87. package/dist/chunk-WPNIKZMJ.js.map +1 -0
  88. package/dist/{chunk-FG6U7KQQ.js → chunk-WSEJ2FDE.js} +4 -4
  89. package/dist/{chunk-FG6U7KQQ.js.map → chunk-WSEJ2FDE.js.map} +1 -1
  90. package/dist/{chunk-ACUKTVS3.js → chunk-XWNXGFX3.js} +52 -42
  91. package/dist/chunk-XWNXGFX3.js.map +1 -0
  92. package/dist/{chunk-WU57BYYM.js → chunk-YVZCKXR3.js} +8 -2
  93. package/dist/chunk-YVZCKXR3.js.map +1 -0
  94. package/dist/{chunk-CMLPFIC5.js → chunk-ZN7KUMPY.js} +3 -1
  95. package/dist/chunk-ZN7KUMPY.js.map +1 -0
  96. package/dist/collapsible-panel.js +2 -2
  97. package/dist/color-picker.d.ts +30 -5
  98. package/dist/color-picker.js +1 -1
  99. package/dist/disclosure.d.ts +13 -4
  100. package/dist/disclosure.js.map +1 -1
  101. package/dist/help-tags-register.js +1 -1
  102. package/dist/index.d.ts +2 -1
  103. package/dist/index.js +24 -23
  104. package/dist/list-action-row.js +1 -1
  105. package/dist/list-detail-dialog.d.ts +7 -1
  106. package/dist/list-detail-dialog.js +7 -5
  107. package/dist/list-detail-dialog.js.map +1 -1
  108. package/dist/list-header.d.ts +8 -1
  109. package/dist/list-header.js +1 -1
  110. package/dist/list.d.ts +7 -1
  111. package/dist/list.js +1 -1
  112. package/dist/message-composer.js +1 -1
  113. package/dist/nav-stack.js +1 -1
  114. package/dist/popup-menu-register.js +2 -2
  115. package/dist/popup-menu.d.ts +15 -5
  116. package/dist/popup-menu.js +1 -1
  117. package/dist/segmented-control.d.ts +3 -1
  118. package/dist/segmented-control.js +1 -1
  119. package/dist/select-register.js +3 -3
  120. package/dist/split-button.d.ts +14 -2
  121. package/dist/split-button.js +1 -1
  122. package/dist/split-view.js +1 -1
  123. package/dist/styles/anchored-surface.css +3 -0
  124. package/dist/styles/button.css +57 -2
  125. package/dist/styles/catalog/components/catalog-example.css +55 -18
  126. package/dist/styles/checkbox-group.css +63 -0
  127. package/dist/styles/checkbox.css +7 -6
  128. package/dist/styles/color-picker.css +69 -34
  129. package/dist/styles/components/actions/button/button.css +57 -2
  130. package/dist/styles/components/actions/split-button/split-button.css +51 -5
  131. package/dist/styles/components/actions/toolbar/toolbar.css +9 -0
  132. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +29 -1
  133. package/dist/styles/components/collections/framed-list/framed-list.css +6 -0
  134. package/dist/styles/components/collections/list/list.css +6 -0
  135. package/dist/styles/components/collections/list-header/list-header.css +7 -0
  136. package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +3 -0
  137. package/dist/styles/components/forms/checkbox/checkbox.css +7 -6
  138. package/dist/styles/components/forms/checkbox-group/checkbox-group.css +63 -0
  139. package/dist/styles/components/forms/color-picker/color-picker.css +69 -34
  140. package/dist/styles/components/forms/radio-group/radio-group.css +7 -5
  141. package/dist/styles/components/forms/select/select.css +6 -2
  142. package/dist/styles/components/forms/switch/switch.css +3 -3
  143. package/dist/styles/components/layout/pane/pane.css +24 -0
  144. package/dist/styles/components/layout/workbench/workbench.css +4 -0
  145. package/dist/styles/components/navigation/nav-stack/nav-stack.css +77 -1
  146. package/dist/styles/components/navigation/tab-bar/tab-bar.css +6 -0
  147. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +17 -0
  148. package/dist/styles/components/surfaces/content-item/content-item.css +30 -0
  149. package/dist/styles/components/surfaces/disclosure/disclosure.css +38 -0
  150. package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +3 -0
  151. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +8 -0
  152. package/dist/styles/components/typography/text/text.css +10 -0
  153. package/dist/styles/content-item.css +30 -0
  154. package/dist/styles/disclosure.css +38 -0
  155. package/dist/styles/foundation.css +78 -13
  156. package/dist/styles/framed-list.css +6 -0
  157. package/dist/styles/list-header.css +7 -0
  158. package/dist/styles/list.css +6 -0
  159. package/dist/styles/nav-stack.css +77 -1
  160. package/dist/styles/pane.css +24 -0
  161. package/dist/styles/radio-group.css +7 -5
  162. package/dist/styles/select.css +6 -2
  163. package/dist/styles/split-button.css +51 -5
  164. package/dist/styles/styles.css +1 -0
  165. package/dist/styles/sunken-panel.css +3 -0
  166. package/dist/styles/surface-scaffold.css +8 -0
  167. package/dist/styles/switch.css +3 -3
  168. package/dist/styles/tab-bar.css +6 -0
  169. package/dist/styles/tab-navigator.css +17 -0
  170. package/dist/styles/text.css +10 -0
  171. package/dist/styles/toolbar-control-group.css +29 -1
  172. package/dist/styles/toolbar.css +9 -0
  173. package/dist/styles/webawesome.css +56 -12
  174. package/dist/styles/workbench.css +4 -0
  175. package/dist/surface-scaffold.d.ts +15 -1
  176. package/dist/surface-scaffold.js +1 -1
  177. package/dist/text-field.d.ts +7 -1
  178. package/dist/text-field.js +1 -1
  179. package/dist/toolbar-control-group.d.ts +8 -2
  180. package/dist/toolbar-control-group.js +1 -1
  181. package/dist/toolbar.d.ts +6 -1
  182. package/dist/toolbar.js +1 -1
  183. package/dist/wire-catalog.js +1 -1
  184. package/dist/wire-color-fields.js +2 -2
  185. package/dist/wire-color-pickers.d.ts +4 -3
  186. package/dist/wire-color-pickers.js +1 -1
  187. package/dist/wire-comboboxes.js +1 -1
  188. package/dist/wire-workbench.js +1 -1
  189. package/dist/workbench-dialog.d.ts +11 -2
  190. package/dist/workbench-dialog.js +6 -3
  191. package/dist/workbench-dialog.js.map +1 -1
  192. package/dist/workbench.js +1 -1
  193. package/docs/accessibility.md +58 -3
  194. package/docs/anchored-surface.md +6 -1
  195. package/docs/catalog.md +26 -1
  196. package/docs/color-picker.md +39 -8
  197. package/docs/component-contract.md +47 -3
  198. package/docs/component-selection.md +58 -21
  199. package/docs/design/templates/button/full-width-dark.svg +1 -0
  200. package/docs/design/templates/button/full-width.svg +1 -0
  201. package/docs/design/templates/button/tones-dark.svg +1 -1
  202. package/docs/design/templates/button/tones.svg +1 -1
  203. package/docs/design/templates/button-dark.svg +1 -1
  204. package/docs/design/templates/button.svg +1 -1
  205. package/docs/design/templates/checkbox/error-dark.svg +1 -1
  206. package/docs/design/templates/checkbox/error.svg +1 -1
  207. package/docs/design/templates/checkbox/states-dark.svg +1 -1
  208. package/docs/design/templates/checkbox/states.svg +1 -1
  209. package/docs/design/templates/checkbox-dark.svg +1 -1
  210. package/docs/design/templates/checkbox-group/horizontal-dark.svg +1 -0
  211. package/docs/design/templates/checkbox-group/horizontal.svg +1 -0
  212. package/docs/design/templates/checkbox-group/vertical-dark.svg +1 -0
  213. package/docs/design/templates/checkbox-group/vertical.svg +1 -0
  214. package/docs/design/templates/checkbox-group-dark.svg +1 -0
  215. package/docs/design/templates/checkbox-group.svg +1 -0
  216. package/docs/design/templates/checkbox.svg +1 -1
  217. package/docs/design/templates/color-picker/gray-dark.svg +1 -1
  218. package/docs/design/templates/color-picker/gray.svg +1 -1
  219. package/docs/design/templates/color-picker/hsb-dark.svg +1 -0
  220. package/docs/design/templates/color-picker/hsb.svg +1 -0
  221. package/docs/design/templates/color-picker/rgb-dark.svg +1 -1
  222. package/docs/design/templates/color-picker/rgb.svg +1 -1
  223. package/docs/design/templates/color-picker-dark.svg +1 -1
  224. package/docs/design/templates/color-picker.svg +1 -1
  225. package/docs/design/templates/disclosure/embedded-dark.svg +1 -0
  226. package/docs/design/templates/disclosure/embedded.svg +1 -0
  227. package/docs/design/templates/disclosure-dark.svg +1 -1
  228. package/docs/design/templates/disclosure.svg +1 -1
  229. package/docs/design/templates/radio-group/horizontal-dark.svg +1 -1
  230. package/docs/design/templates/radio-group/horizontal.svg +1 -1
  231. package/docs/design/templates/radio-group/vertical-dark.svg +1 -1
  232. package/docs/design/templates/radio-group/vertical.svg +1 -1
  233. package/docs/design/templates/radio-group-dark.svg +1 -1
  234. package/docs/design/templates/radio-group.svg +1 -1
  235. package/docs/design/templates/split-button/full-width-dark.svg +1 -0
  236. package/docs/design/templates/split-button/full-width.svg +1 -0
  237. package/docs/design/templates/split-button/pill-dark.svg +1 -0
  238. package/docs/design/templates/split-button/pill.svg +1 -0
  239. package/docs/design/templates/split-button/states-dark.svg +1 -0
  240. package/docs/design/templates/split-button/states.svg +1 -0
  241. package/docs/design/templates/split-button/tones-dark.svg +1 -0
  242. package/docs/design/templates/split-button/tones.svg +1 -0
  243. package/docs/design/templates/split-button-dark.svg +1 -0
  244. package/docs/design/templates/split-button.svg +1 -0
  245. package/docs/design/templates/switch/states-dark.svg +1 -1
  246. package/docs/design/templates/switch/states.svg +1 -1
  247. package/docs/design/templates/switch-dark.svg +1 -1
  248. package/docs/design/templates/switch.svg +1 -1
  249. package/docs/design/templates/text-field/number-dark.svg +1 -0
  250. package/docs/design/templates/text-field/number.svg +1 -0
  251. package/docs/design/templates/text-field-dark.svg +1 -1
  252. package/docs/design/templates/text-field.svg +1 -1
  253. package/docs/design/templates.md +10 -3
  254. package/docs/disclosure.md +34 -0
  255. package/docs/layout.md +16 -5
  256. package/docs/list-detail-dialog.md +4 -0
  257. package/docs/nav-stack.md +6 -2
  258. package/docs/surface-scaffold.md +6 -2
  259. package/docs/ui-doctor.md +16 -4
  260. package/docs/webawesome-migration.md +3 -1
  261. package/docs/webawesome-theme.md +56 -18
  262. package/docs/workbench-dialog.md +4 -1
  263. package/docs/workbench.md +7 -1
  264. package/docs/writing.md +3 -3
  265. package/doctor/copy-capitalization-checks.mjs +10 -7
  266. package/llms.txt +65 -23
  267. package/package.json +7 -1
  268. package/dist/chunk-7W3GKMN4.js.map +0 -1
  269. package/dist/chunk-ACUKTVS3.js.map +0 -1
  270. package/dist/chunk-C3RLKKFQ.js.map +0 -1
  271. package/dist/chunk-CMLPFIC5.js.map +0 -1
  272. package/dist/chunk-ECFCAKWE.js.map +0 -1
  273. package/dist/chunk-EKBMUXFV.js.map +0 -1
  274. package/dist/chunk-HYORKKYP.js.map +0 -1
  275. package/dist/chunk-N7MBGONH.js.map +0 -1
  276. package/dist/chunk-NS2TBYM4.js.map +0 -1
  277. package/dist/chunk-OY2MXIBB.js.map +0 -1
  278. package/dist/chunk-PE2KPZDW.js.map +0 -1
  279. package/dist/chunk-QLA25V2K.js.map +0 -1
  280. package/dist/chunk-TAHR457X.js.map +0 -1
  281. package/dist/chunk-UTCAOOXU.js.map +0 -1
  282. package/dist/chunk-WJKHLOP5.js.map +0 -1
  283. package/dist/chunk-WU57BYYM.js.map +0 -1
@@ -4,7 +4,7 @@
4
4
 
5
5
  `@kerfjs/ui:disclosure` · Kerf UI · component · Structure
6
6
 
7
- Content a person shows and hides under a summary row: a native details element with a DisclosureArrow, a title, and an optional quiet detail, on content-item geometry, with plain, framed, and sunken appearances and native exclusive (accordion) groups.
7
+ Content a person shows and hides under a summary row: a native details element with a DisclosureArrow, a title, and an optional quiet detail, on content-item geometry, with plain, framed, and sunken appearances, an embedded appearance for a compact panel inside a ContentItem, and native exclusive (accordion) groups.
8
8
 
9
9
  ## When to use
10
10
 
@@ -12,6 +12,7 @@ Keep secondary or optional content one press away under a summary, or let a pers
12
12
 
13
13
  - Optional or advanced content should stay out of the way until a person asks for it (advanced settings, a build log, release notes).
14
14
  - A list of questions or sections should open one at a time: give the Disclosures the same name for a native exclusive accordion.
15
+ - A compact details panel belongs inside a ContentItem (a note card's AI feedback): use appearance embedded so the item's own inset frames it once.
15
16
 
16
17
  **Not when:**
17
18
 
@@ -36,6 +37,7 @@ Exact prop names and types: [`@kerfjs/ui/disclosure`](../public-api-signatures-v
36
37
  **Variants (configure, do not restyle):**
37
38
 
38
39
  - plain, framed, or sunken appearance
40
+ - embedded appearance inside a ContentItem or other owner chrome: no margin, border, or padding of its own and a 24px minimum summary row
39
41
  - open or closed initially
40
42
  - a quiet detail after the title
41
43
  - an exclusive accordion group sharing a name
@@ -58,6 +60,9 @@ No wiring helper.
58
60
  Margin: self · border: self · padding: self (layout role: structure). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
59
61
 
60
62
  - The root takes the content-item geometry (8px inline margin, a 1px border, 8px padding); the content starts on the title's text column.
63
+ - appearance embedded drops that geometry inside a ContentItem, which already owns it: the arrow sits on the item's content inset, the summary row is at least 24px tall, and the content (a flush Text or other content without an inset) starts on the title's text column 8px below the summary. Do not use embedded outside owner chrome.
64
+
65
+ While `appearance="embedded"` is set, direct children must bring no content-item inset: a child that owns its margin, border, and padding double-insets this one. Use an inset-free form such as `Text flush`, or inline content (`KUI-L204`).
61
66
 
62
67
  ## Accessibility
63
68
 
@@ -55,7 +55,7 @@ Margin: none · border: none · padding: none (layout role: foundation). `self`
55
55
 
56
56
  The component owns its own styles. Configure it through its props and variants; do not override its internals.
57
57
 
58
- Public tokens it reads: `--kui-font-sans`, `--kui-font-mono`, `--kui-font-2xs`, `--kui-font-xs`, `--kui-font-s`, `--kui-font-m`, `--kui-font-l`, `--kui-font-xl`, `--kui-font-2xl`, `--kui-font-weight-semibold`, `--kui-space-none`, `--kui-space-2xs`, `--kui-space-xs`, `--kui-space-s`, `--kui-space-m`, `--kui-space-l`, `--kui-space-xl`, `--kui-bp-mobile`, `--kui-bp-tablet`, `--kui-bp-desktop`, `--kui-bp-xl-desktop`, `--kui-layout-inline-margin`, `--kui-layout-item-border-width`, `--kui-layout-item-padding`, `--kui-layout-item-gap`, `--kui-layout-content-gap`, `--kui-layout-control-gap`, `--kui-layout-metadata-gap`, `--kui-layout-highlight-inset`, `--kui-layout-rounded-radius`, `--kui-layout-pill-radius`, `--kui-toolbar-group-inner-size`, `--kui-toolbar-group-size`, `--kui-toolbar-gap`, `--kui-safe-area-block-start`, `--kui-safe-area-block-end`, `--kui-safe-area-inline-start`, `--kui-safe-area-inline-end`, `--kui-radius-s`, `--kui-radius-m`, `--kui-radius-l`, `--kui-radius-circle`, `--kui-radius-pill`, `--kui-disclosure-icon-scale`, `--kui-color-surface`, `--kui-color-surface-raised`, `--kui-color-surface-lowered`, `--kui-sunken-texture`, `--kui-sunken-surface`, `--kui-chrome-material`, `--kui-chrome-material-raised`, `--kui-chrome-material-filter`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-color-text-link`, `--kui-color-neutral-fill-quiet`, `--kui-color-neutral-fill-normal`, `--kui-color-neutral-fill-loud`, `--kui-color-neutral-border-quiet`, `--kui-color-neutral-border-normal`, `--kui-color-neutral-border-loud`, `--kui-color-neutral-on-quiet`, `--kui-color-neutral-on-normal`, `--kui-color-neutral-on-loud`, `--kui-color-brand-fill-loud`, `--kui-color-brand-fill-quiet`, `--kui-color-brand-fill-normal`, `--kui-color-brand-border-quiet`, `--kui-color-brand-border-normal`, `--kui-color-brand-border-loud`, `--kui-color-brand-on-quiet`, `--kui-color-brand-on-normal`, `--kui-color-brand-on-loud`, `--kui-color-brand-on-fill`, `--kui-color-pop-fill-loud`, `--kui-color-pop-fill-quiet`, `--kui-color-pop-fill-normal`, `--kui-color-pop-border-quiet`, `--kui-color-pop-border-normal`, `--kui-color-pop-border-loud`, `--kui-color-pop-on-quiet`, `--kui-color-pop-on-normal`, `--kui-color-pop-on-loud`, `--kui-color-pop-on-fill`, `--kui-color-success-fill-loud`, `--kui-color-success-fill-quiet`, `--kui-color-success-fill-normal`, `--kui-color-success-border-quiet`, `--kui-color-success-border-normal`, `--kui-color-success-border-loud`, `--kui-color-success-on-quiet`, `--kui-color-success-on-normal`, `--kui-color-success-on-loud`, `--kui-color-success-on-fill`, `--kui-color-warning-fill-loud`, `--kui-color-warning-fill-quiet`, `--kui-color-warning-fill-normal`, `--kui-color-warning-border-quiet`, `--kui-color-warning-border-normal`, `--kui-color-warning-border-loud`, `--kui-color-warning-on-quiet`, `--kui-color-warning-on-normal`, `--kui-color-warning-on-loud`, `--kui-color-warning-on-fill`, `--kui-color-danger-fill-loud`, `--kui-color-danger-fill-quiet`, `--kui-color-danger-fill-normal`, `--kui-color-danger-border-quiet`, `--kui-color-danger-border-normal`, `--kui-color-danger-border-loud`, `--kui-color-danger-on-quiet`, `--kui-color-danger-on-normal`, `--kui-color-danger-on-loud`, `--kui-color-danger-on-fill`, `--kui-focus-ring`, `--kui-shadow-s`, `--kui-shadow-m`, `--kui-shadow-l`. Set a token only where its public contract allows; prefer a prop.
58
+ Public tokens it reads: `--kui-font-sans`, `--kui-font-mono`, `--kui-font-2xs`, `--kui-font-xs`, `--kui-font-s`, `--kui-font-m`, `--kui-font-l`, `--kui-font-xl`, `--kui-font-2xl`, `--kui-font-weight-semibold`, `--kui-space-none`, `--kui-space-2xs`, `--kui-space-xs`, `--kui-space-s`, `--kui-space-m`, `--kui-space-l`, `--kui-space-xl`, `--kui-bp-mobile`, `--kui-bp-tablet`, `--kui-bp-desktop`, `--kui-bp-xl-desktop`, `--kui-layout-inline-margin`, `--kui-layout-item-border-width`, `--kui-layout-item-padding`, `--kui-layout-item-gap`, `--kui-layout-content-gap`, `--kui-layout-control-gap`, `--kui-layout-metadata-gap`, `--kui-layout-highlight-inset`, `--kui-layout-rounded-radius`, `--kui-layout-pill-radius`, `--kui-toolbar-group-inner-size`, `--kui-toolbar-group-size`, `--kui-toolbar-gap`, `--kui-safe-area-block-start`, `--kui-safe-area-block-end`, `--kui-safe-area-inline-start`, `--kui-safe-area-inline-end`, `--kui-radius-s`, `--kui-radius-m`, `--kui-radius-l`, `--kui-radius-circle`, `--kui-radius-pill`, `--kui-disclosure-icon-scale`, `--kui-color-surface`, `--kui-color-surface-raised`, `--kui-color-surface-lowered`, `--kui-sunken-texture`, `--kui-sunken-surface`, `--kui-color-surface-current`, `--kui-color-surface-current-region`, `--kui-color-surface-current-tint`, `--kui-chrome-material`, `--kui-chrome-material-raised`, `--kui-chrome-material-filter`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-color-text-link`, `--kui-color-neutral-fill-quiet`, `--kui-color-neutral-fill-normal`, `--kui-color-neutral-fill-loud`, `--kui-color-neutral-border-quiet`, `--kui-color-neutral-border-normal`, `--kui-color-neutral-border-loud`, `--kui-color-neutral-on-quiet`, `--kui-color-neutral-on-normal`, `--kui-color-neutral-on-loud`, `--kui-color-brand-fill-loud`, `--kui-color-brand-fill-quiet`, `--kui-color-brand-fill-normal`, `--kui-color-brand-border-quiet`, `--kui-color-brand-border-normal`, `--kui-color-brand-border-loud`, `--kui-color-brand-on-quiet`, `--kui-color-brand-on-normal`, `--kui-color-brand-on-loud`, `--kui-color-brand-on-fill`, `--kui-color-pop-fill-loud`, `--kui-color-pop-fill-quiet`, `--kui-color-pop-fill-normal`, `--kui-color-pop-border-quiet`, `--kui-color-pop-border-normal`, `--kui-color-pop-border-loud`, `--kui-color-pop-on-quiet`, `--kui-color-pop-on-normal`, `--kui-color-pop-on-loud`, `--kui-color-pop-on-fill`, `--kui-color-success-fill-loud`, `--kui-color-success-fill-quiet`, `--kui-color-success-fill-normal`, `--kui-color-success-border-quiet`, `--kui-color-success-border-normal`, `--kui-color-success-border-loud`, `--kui-color-success-on-quiet`, `--kui-color-success-on-normal`, `--kui-color-success-on-loud`, `--kui-color-success-on-fill`, `--kui-color-warning-fill-loud`, `--kui-color-warning-fill-quiet`, `--kui-color-warning-fill-normal`, `--kui-color-warning-border-quiet`, `--kui-color-warning-border-normal`, `--kui-color-warning-border-loud`, `--kui-color-warning-on-quiet`, `--kui-color-warning-on-normal`, `--kui-color-warning-on-loud`, `--kui-color-warning-on-fill`, `--kui-color-danger-fill-loud`, `--kui-color-danger-fill-quiet`, `--kui-color-danger-fill-normal`, `--kui-color-danger-border-quiet`, `--kui-color-danger-border-normal`, `--kui-color-danger-border-loud`, `--kui-color-danger-on-quiet`, `--kui-color-danger-on-normal`, `--kui-color-danger-on-loud`, `--kui-color-danger-on-fill`, `--kui-focus-ring`, `--kui-shadow-s`, `--kui-shadow-m`, `--kui-shadow-l`, `--kui-color-brand`. Set a token only where its public contract allows; prefer a prop.
59
59
 
60
60
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
61
61
 
@@ -75,7 +75,7 @@ Margin: parent · border: self · padding: child (layout role: structure). `self
75
75
  ## Accessibility
76
76
 
77
77
  - It is a native modal \<dialog> named by label: the page is inert, focus stays inside, Escape asks to close, and focus returns to the opener on close.
78
- - On roomy devices the detail title is a level-2 heading; every presentation keeps a close control named Close (closeLabel), and the compact back control is named by backLabel.
78
+ - Pass describedBy, the id of app-owned summary copy, for the dialog's accessible description; the detail description describes the selection and is not wired. On roomy devices the detail title is a level-2 heading; every presentation keeps a close control named Close (closeLabel), and the compact back control is named by backLabel.
79
79
 
80
80
  ## Styling boundary
81
81
 
@@ -61,7 +61,7 @@ Exact prop names and types: [`@kerfjs/ui/list`](../public-api-signatures-v1.md#k
61
61
  - top/right/bottom/left text and control inset combinations
62
62
  - fill: the layout root fills a definite-height parent
63
63
  - rootAttributes: safe data-\*, aria-\*, and structural role on the root
64
- - scroll dividers when named as wireScrollDividers targets chrome
64
+ - scroll dividers when named as wireScrollDividers targets chrome or scroller (by its id)
65
65
  - multi-select grid for rich ContentItem rows
66
66
  - contentWidth (compact 440px, medium 640px, wide 864px) and contentAlign for a readable, centered page column
67
67
 
@@ -50,7 +50,8 @@ Exact prop names and types: [`@kerfjs/ui/message-composer`](../public-api-signat
50
50
 
51
51
  Zones (a zone is bound to JSX only through its listed prop; never assume the zone id is a prop):
52
52
 
53
- - `actions` — JSX prop `actions`; accepts `KerfUiContent`; at least 1.
53
+ - `leading` — JSX prop `leading`; accepts `KerfUiContent`; any number.
54
+ - `trailing` — JSX prop `trailing`; accepts `KerfUiContent`; at least 1.
54
55
 
55
56
  ## State and wiring
56
57
 
@@ -24,6 +24,7 @@ Choose exactly one of a few options that should stay visible with room for a lab
24
24
  - [Radio](./wa-radio.md) (prefer-over)
25
25
  - [Select](./select.md) (nearest) — Use Select for a long list.
26
26
  - [ChoiceChips](./choice-chips.md) (nearest) — Use ChoiceChips for wrapping pill choices.
27
+ - [CheckboxGroup](./checkbox-group.md) (nearest) — Use CheckboxGroup when people may choose several.
27
28
 
28
29
  ## Imports
29
30
 
@@ -62,7 +63,7 @@ No wiring helper.
62
63
 
63
64
  Margin: none · border: none · padding: self (layout role: controls). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
64
65
 
65
- - The label and hint sit on the text column (1px + 8px); the choices sit on the 8px control column, 12px apart.
66
+ - The label and hint sit on the text column (1px + 8px); each choice's 20px circle (18px compact) sits on the group's inline-start edge, where a Checkbox draws its box, 8px (7px) before its label; choices stack 8px apart (--kui-space-xs), the same 28px pitch as Checkboxes in a List gap="xs", and a choice hint aligns with its label text.
66
67
 
67
68
  ## Accessibility
68
69
 
@@ -77,12 +78,12 @@ Public class hooks (select for layout placement only, never to change the compon
77
78
 
78
79
  Never put `kui-radio-group`, `kui-radio-group__label`, `kui-radio-group__choices`, `kui-radio-group__choice`, `kui-radio-group__row`, `kui-radio-group__control`, `kui-radio-group__input`, `kui-radio-group__circle`, `kui-radio-group__choice-label`, `kui-radio-group__choice-hint`, `kui-radio-group__hint`, `kui-radio-group__error` on an element you write; render `RadioGroup` instead (`KUI-L103`).
79
80
 
80
- Public tokens it reads: `--kui-color-brand-fill-loud`, `--kui-color-neutral-border-normal`, `--kui-color-surface`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-color-danger-border-loud`, `--kui-color-danger-on-quiet`, `--kui-focus-ring`, `--kui-font-m`, `--kui-font-s`, `--kui-font-xs`, `--kui-color-neutral-on-quiet`, `--kui-layout-item-padding`. Set a token only where its public contract allows; prefer a prop.
81
+ Public tokens it reads: `--kui-color-brand-fill-loud`, `--kui-color-neutral-border-normal`, `--kui-color-surface`, `--kui-color-text`, `--kui-color-text-quiet`, `--kui-color-danger-border-loud`, `--kui-color-danger-on-quiet`, `--kui-focus-ring`, `--kui-font-m`, `--kui-font-s`, `--kui-font-xs`, `--kui-color-neutral-on-quiet`, `--kui-layout-item-padding`, `--kui-space-xs`. Set a token only where its public contract allows; prefer a prop.
81
82
 
82
83
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
83
84
 
84
85
  ## Related
85
86
 
86
- - Components: [Radio Group](./wa-radio-group.md), [Radio](./wa-radio.md), [Select](./select.md), [ChoiceChips](./choice-chips.md).
87
+ - Components: [Radio Group](./wa-radio-group.md), [Radio](./wa-radio.md), [Select](./select.md), [ChoiceChips](./choice-chips.md), [CheckboxGroup](./checkbox-group.md).
87
88
  - Docs: [`docs/component-selection.md`](../../docs/component-selection.md), [`docs/component-selection.md#problem-to-component-matrix`](../../docs/component-selection.md#problem-to-component-matrix).
88
89
  - UX catalog route: `?component=radio-group`.
@@ -40,6 +40,7 @@ Exact prop names and types: [`@kerfjs/ui/segmented-control`](../public-api-signa
40
40
  - equal width
41
41
  - small
42
42
  - placeholder (loading)
43
+ - disabled (whole control)
43
44
 
44
45
  ## Composition
45
46
 
@@ -8,7 +8,7 @@ A primary action with an attached options trigger on one loud semantic fill.
8
8
 
9
9
  ## When to use
10
10
 
11
- Render a prominent primary action plus an options trigger (provider, model, target) as one control with a semantic tone, full-width sizing, a busy presentation, and native aria-expanded on the trigger, outside any Toolbar.
11
+ Render a prominent primary action plus an options trigger (provider, model, target) as one control with a semantic tone, full-width sizing, a rounded or pill shape, a busy presentation, and native aria-expanded on the trigger, outside any Toolbar.
12
12
 
13
13
  - A prominent primary action has a closely related set of options chosen from an attached trigger, such as Drive with a provider menu or Deploy with targets.
14
14
 
@@ -37,8 +37,10 @@ Exact prop names and types: [`@kerfjs/ui/split-button`](../public-api-signatures
37
37
 
38
38
  - brand, neutral, success, warning, or danger tone
39
39
  - content width or fill
40
+ - rounded or pill shape
40
41
  - busy
41
42
  - disabled primary or options
43
+ - focusRingInset: each half's focus ring drawn inside its box for an ancestor that clips overflow
42
44
 
43
45
  ## Composition
44
46
 
@@ -60,6 +62,7 @@ Margin: none · border: self · padding: self (layout role: controls). `self` me
60
62
  ## Accessibility
61
63
 
62
64
  - Both halves are native buttons in a group; the options trigger exposes aria-haspopup, aria-expanded, and optional aria-controls, and needs optionsLabel. busy sets aria-busy on the primary.
65
+ - Each half draws the focus ring 1px outside its box; with focusRingInset it is drawn inside, two-tone with a surface-colored line inside the ring color, so it keeps 3:1 contrast on every loud fill.
63
66
 
64
67
  ## Styling boundary
65
68
 
@@ -69,7 +72,7 @@ Public class hooks (select for layout placement only, never to change the compon
69
72
 
70
73
  Never put `kui-split-button`, `kui-split-button__options`, `kui-split-button__icon`, `kui-split-button__label` on an element you write; render `SplitButton` instead (`KUI-L103`).
71
74
 
72
- Public tokens it reads: `--kui-color-brand-fill-loud`, `--kui-color-brand-on-loud`, `--kui-color-neutral-fill-loud`, `--kui-color-neutral-on-loud`, `--kui-color-success-fill-loud`, `--kui-color-success-on-loud`, `--kui-color-warning-fill-loud`, `--kui-color-warning-on-loud`, `--kui-color-danger-fill-loud`, `--kui-color-danger-on-loud`, `--kui-focus-ring`, `--kui-font-weight-semibold`, `--kui-layout-rounded-radius`, `--kui-space-s`, `--kui-space-xs`. Set a token only where its public contract allows; prefer a prop.
75
+ Public tokens it reads: `--kui-color-brand-fill-loud`, `--kui-color-brand-on-loud`, `--kui-color-neutral-fill-loud`, `--kui-color-neutral-on-loud`, `--kui-color-success-fill-loud`, `--kui-color-success-on-loud`, `--kui-color-warning-fill-loud`, `--kui-color-warning-on-loud`, `--kui-color-danger-fill-loud`, `--kui-color-danger-on-loud`, `--kui-focus-ring`, `--kui-font-weight-semibold`, `--kui-layout-pill-radius`, `--kui-layout-rounded-radius`, `--kui-space-s`, `--kui-space-xs`. Set a token only where its public contract allows; prefer a prop.
73
76
 
74
77
  Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
75
78
 
@@ -41,6 +41,7 @@ Exact prop names and types: [`@kerfjs/ui/surface-scaffold`](../public-api-signat
41
41
  - small, medium, or large dialog
42
42
  - data-\* rootAttributes (a data-key) so sibling dialogs morph by identity
43
43
  - modal, side-sheet, fullscreen, or bottom-sheet dialog
44
+ - alert dialog (alert): role="alertdialog" on the native dialog, described by its message through describedBy
44
45
  - bottom sheet attached to the bottom edge: square bottom corners, safe-area and virtual-keyboard clearance behind the panel, slide (or standard) enter and exit motion, and an optional resizable top grabber bounded by minHeight and maxHeight
45
46
  - typed modal preferred width, viewport gutter, and maximum height, including viewport cap
46
47
  - definite viewport-bounded modal height and a fill body layout for one child
@@ -56,6 +57,7 @@ Exact prop names and types: [`@kerfjs/ui/surface-scaffold`](../public-api-signat
56
57
  - core kerfjs/overlay confirm/prompt/form/choice as a bottom sheet styled by @kerfjs/ui/overlay-sheet.css
57
58
  - resizable core kerfjs/overlay bottom sheet: the kui-overlay-sheet-resizable class plus wireOverlaySheets adds the resizable DialogSurface sheet grabber
58
59
  - header with label text or heading content, headerActions, a close button, and an optional footer; withoutHeader for content that owns its heading and close control
60
+ - accessible description by describedBy: the heading ToolbarText descriptionId or app-owned body summary copy
59
61
  - light dismiss (a backdrop press closes; otherwise the panel pulses)
60
62
 
61
63
  **CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
@@ -87,7 +89,7 @@ Margin: parent · border: child · padding: self (layout role: structure). `self
87
89
 
88
90
  - DialogSurface is a native \<dialog> opened modally (showModal): it is in the top layer, the rest of the page is inert, focus stays inside, and it returns to the opener on close. Focus starts on an autofocus element, otherwise on the panel.
89
91
  - Name it with label (also its title text) or labelledBy (the id of a heading, such as a ToolbarText). The close button is named Close (closeLabel) and Escape asks to close; the cancelable kui-request-close event reports source close-button, escape, or backdrop.
90
- - Name a PopoverDialogSurface with label or labelledBy, and describe it with describedBy (rendered as aria-describedby), usually a title ToolbarText descriptionId.
92
+ - Name a PopoverDialogSurface with label or labelledBy. Describe either surface with describedBy (rendered as aria-describedby on the dialog root), usually the heading ToolbarText descriptionId or app-owned summary copy in the body; rootAttributes accepts only data-\* attributes, so it never sets aria-describedby.
91
93
  - A floating header's title uses the normal text color, which keeps WCAG AA over the 80% raised chrome material on any content; the material turns opaque under prefers-reduced-transparency, prefers-contrast: more, forced colors, or without backdrop-filter.
92
94
  - A resizable bottom sheet's grabber is a focusable horizontal separator ("Resize sheet") with aria-valuemin, aria-valuenow, and aria-valuemax in visible px; the arrow keys, Page Up/Down, Home, and End resize it, and its slide motion is skipped under prefers-reduced-motion.
93
95
  - Use popup surfaces only for real dropdown menus with named triggers.
@@ -56,7 +56,7 @@ No wiring helper.
56
56
 
57
57
  Margin: none · border: self · padding: none (layout role: controls). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
58
58
 
59
- - A 35×20 track (31.5×18 compact) 8px (7px) before its label; the hint aligns with the label text.
59
+ - A 35×20 track (31.5×18 compact) 8px (7px) before its label; the hint sits directly under the label, on its text column, like a Checkbox hint.
60
60
 
61
61
  ## Accessibility
62
62
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  `@kerfjs/ui:text-field` · Kerf UI · component · Controls
6
6
 
7
- A labeled single-line input or multi-line textarea with hint and error text, an optional leading icon, clear button, and character count, at the 44px control height or compact.
7
+ A labeled single-line input or multi-line textarea with hint and error text, an optional leading icon, clear button, character count, and native numeric constraints, at the 44px control height or compact.
8
8
 
9
9
  ## When to use
10
10
 
@@ -13,6 +13,7 @@ Collect free text (names, addresses, notes, comments) with Kerf's field chrome,
13
13
  - A form or dialog collects a line of free text: label names it (or ariaLabel when nearby content already does), hint explains it, and error reports a validation problem.
14
14
  - People write a longer note or message: multiline with rows, or rows plus maxRows to grow with the content; maxLength with showCount shows the remaining budget.
15
15
  - A filter or search field needs a leading icon and a clear button: icon and clearable.
16
+ - An exact number needs native range or decimal-step validation: type=number with min, max, and step (including step=any).
16
17
 
17
18
  **Not when:**
18
19
 
@@ -53,6 +54,7 @@ Exact prop names and types: [`@kerfjs/ui/text-field`](../public-api-signatures-v
53
54
  - read-only
54
55
  - required
55
56
  - email, password, search, url, tel, or number type
57
+ - number type with native min, max, and step constraints
56
58
 
57
59
  ## Composition
58
60
 
@@ -64,6 +64,8 @@ Margin: self · border: self · padding: self (layout role: structure). `self` m
64
64
  - Block Text variants reset native margins and add a 1px transparent border plus the standard 8px item padding; flush removes the border and padding. Tight line height is available for compact copy. Span has no margin by default, border, or padding. FieldLabel mirrors the themed Web Awesome label typography, 9px inline inset, and bottom gap.
65
65
  - controlMargins adds the shared control gutter outside selected physical edges without changing border or padding; avoid duplicating a parent inset. Spans retain inline display and native inline margin behavior.
66
66
 
67
+ Inset-free (no margin, border, or padding) when `flush` or `variant="span"`: the form to use inside a parent that expects inset-free content (`KUI-L204`).
68
+
67
69
  ## Accessibility
68
70
 
69
71
  - Text renders a native paragraph by default; choose an h1 through h6 variant by document outline rather than appearance, or span for inline secondary text.
@@ -57,6 +57,7 @@ Exact prop names and types: [`@kerfjs/ui/toolbar-control-group`](../public-api-s
57
57
  - standard, compact, or list-zero dropdown menu inset
58
58
  - visible, horizontally scrollable, or whole-action wrapping overflow
59
59
  - always visible or compact-only responsive visibility
60
+ - yield to an expanded trailing sibling at 480px, or exactly while a trailing-priority Toolbar row is active (yield-to-priority-row)
60
61
  - relocate on panel collapse
61
62
  - avatar scrim
62
63
  - contained avatar background on a single group or selected multi-button highlight
@@ -31,7 +31,7 @@ Exact prop names and types: [`@kerfjs/ui/toolbar`](../public-api-signatures-v1.m
31
31
  **Variants (configure, do not restyle):**
32
32
 
33
33
  - no dividers (default)
34
- - scroll dividers when named as wireScrollDividers targets chrome
34
+ - scroll dividers when named as wireScrollDividers targets chrome (by its id)
35
35
  - top/right/bottom/left divider combinations
36
36
  - centered content
37
37
  - stacked zones at compact or narrow widths
@@ -6,18 +6,18 @@
6
6
 
7
7
  ## When to use
8
8
 
9
- Ecosystem checkbox group; use Kerf Checkbox rows or ChoiceChips.
9
+ Ecosystem checkbox group; use Kerf CheckboxGroup or ChoiceChips.
10
10
 
11
11
  - Labels and validates a related set of checkboxes.
12
12
 
13
13
  **Not when:**
14
14
 
15
- - Do not use it in Kerf UI; use Checkbox rows in a List, or ChoiceChips multiple for wrapping pills.
15
+ - Do not use it in Kerf UI; use CheckboxGroup for a labeled set of options, or ChoiceChips multiple for wrapping pills.
16
16
 
17
17
  **Alternatives:**
18
18
 
19
- - [Checkbox](./checkbox.md) (prefer-kerf) — Use Checkbox rows in a List, or ChoiceChips multiple for wrapping pills.
20
- - [ChoiceChips](./choice-chips.md) (prefer-kerf) — Use Checkbox rows in a List, or ChoiceChips multiple for wrapping pills.
19
+ - [CheckboxGroup](./checkbox-group.md) (prefer-kerf) — Use CheckboxGroup for a labeled set of options, or ChoiceChips multiple for wrapping pills.
20
+ - [ChoiceChips](./choice-chips.md) (prefer-kerf) — Use CheckboxGroup for a labeled set of options, or ChoiceChips multiple for wrapping pills.
21
21
 
22
22
  ## Imports
23
23
 
@@ -57,6 +57,6 @@ Theme it only through `@kerfjs/ui/webawesome.css` and cataloged tokens. Do not r
57
57
 
58
58
  ## Related
59
59
 
60
- - Components: [Checkbox](./wa-checkbox.md), [Checkbox](./checkbox.md), [ChoiceChips](./choice-chips.md).
60
+ - Components: [Checkbox](./wa-checkbox.md), [CheckboxGroup](./checkbox-group.md), [ChoiceChips](./choice-chips.md).
61
61
  - Docs: [`docs/webawesome-theme.md#coverage`](../../docs/webawesome-theme.md#coverage).
62
62
  - UX catalog route: `?component=wa-checkbox-group`.
@@ -75,7 +75,7 @@ Margin: parent · border: self · padding: child (layout role: structure). `self
75
75
  ## Accessibility
76
76
 
77
77
  - It is a native modal \<dialog> named by label: the page is inert, focus stays inside, Escape asks to close, and focus returns to the opener on close.
78
- - The title is a level-2 heading; the close control is named Close (closeLabel) and stays the outermost trailing control. An open overlay rail takes focus, keeps Tab inside it, and closes on Escape before the dialog does.
78
+ - The title is a level-2 heading, and its description (id \<id>-description) is the dialog's accessible description unless describedBy names other content; the close control is named Close (closeLabel) and stays the outermost trailing control. An open overlay rail takes focus, keeps Tab inside it, and closes on Escape before the dialog does.
79
79
 
80
80
  ## Styling boundary
81
81