@kerfjs/ui 5.0.0-beta.4 → 5.0.0-beta.40

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 (498) hide show
  1. package/README.md +342 -108
  2. package/ai/application-ui-diagnostic-ids-v1.json +100 -0
  3. package/ai/application-ui-profile-sync.cjs +529 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +102 -0
  6. package/ai/application-ui-profile.defaults.json +41 -0
  7. package/ai/application-ui-profile.mjs +626 -0
  8. package/ai/application-ui-profile.schema.json +130 -0
  9. package/ai/catalog-authoring.json +25 -0
  10. package/ai/catalog-authoring.schema.json +61 -0
  11. package/ai/compile-time-contracts-v1.json +132 -0
  12. package/ai/compile-time-contracts-v1.schema.json +51 -0
  13. package/ai/component-catalog-extension-v2.d.ts +7 -0
  14. package/ai/component-catalog-extension-v2.schema.json +7 -0
  15. package/ai/component-catalog-extension.schema.json +79 -0
  16. package/ai/component-catalog-v2-overrides.json +496 -0
  17. package/ai/component-catalog-v2.d.ts +90 -0
  18. package/ai/component-catalog-v2.json +5678 -0
  19. package/ai/component-catalog-v2.schema.json +298 -0
  20. package/ai/component-catalog.json +2694 -417
  21. package/ai/component-catalog.schema.json +39 -0
  22. package/ai/public-api-signatures-v1.md +1591 -126
  23. package/ai/skill.md +140 -54
  24. package/ai/webawesome-jsx-signatures-v1.md +2 -1
  25. package/analyzer/cli.mjs +49 -0
  26. package/analyzer/index.d.mts +46 -0
  27. package/analyzer/index.mjs +1086 -0
  28. package/analyzer/report.schema.json +66 -0
  29. package/dist/app-tab.d.ts +15 -4
  30. package/dist/app-tab.js +3 -1
  31. package/dist/browser/app-tab.js +1 -0
  32. package/dist/browser/floating-toolbar.js +3 -0
  33. package/dist/browser/list-action-row.js +5 -0
  34. package/dist/browser/list-header.js +7 -0
  35. package/dist/browser/list-inset-control.js +3 -0
  36. package/dist/browser/list-inset-text.js +3 -0
  37. package/dist/browser/list-item.js +5 -0
  38. package/dist/browser/list.js +3 -0
  39. package/dist/browser/pane.js +3 -0
  40. package/dist/browser/row.js +3 -0
  41. package/dist/browser/segmented-control.js +1 -0
  42. package/dist/browser/select.js +1 -0
  43. package/dist/browser/skeleton.js +3 -0
  44. package/dist/browser/spacer.js +3 -0
  45. package/dist/browser/state-banner.js +1 -0
  46. package/dist/browser/sunken-panel.js +3 -0
  47. package/dist/browser/surface-scaffold.js +3 -0
  48. package/dist/browser/text.js +3 -0
  49. package/dist/browser/toolbar-text.js +1 -0
  50. package/dist/browser/value-table.js +1 -0
  51. package/dist/catalog-resources.d.ts +35 -0
  52. package/dist/catalog-resources.js +22 -0
  53. package/dist/catalog-resources.js.map +1 -0
  54. package/dist/catalog.d.ts +151 -0
  55. package/dist/catalog.js +396 -0
  56. package/dist/catalog.js.map +1 -0
  57. package/dist/chunk-2TYUFZUC.js +22 -0
  58. package/dist/chunk-2TYUFZUC.js.map +1 -0
  59. package/dist/chunk-6NDBE2OK.js +32 -0
  60. package/dist/chunk-6NDBE2OK.js.map +1 -0
  61. package/dist/chunk-6WTETUZ6.js +21 -0
  62. package/dist/chunk-6WTETUZ6.js.map +1 -0
  63. package/dist/chunk-AQFWBG23.js +83 -0
  64. package/dist/chunk-AQFWBG23.js.map +1 -0
  65. package/dist/chunk-B6JYRX3P.js +51 -0
  66. package/dist/chunk-B6JYRX3P.js.map +1 -0
  67. package/dist/chunk-C34NZOLJ.js +53 -0
  68. package/dist/chunk-C34NZOLJ.js.map +1 -0
  69. package/dist/chunk-CAB6NQ2T.js +102 -0
  70. package/dist/chunk-CAB6NQ2T.js.map +1 -0
  71. package/dist/chunk-CK6P5AUK.js +136 -0
  72. package/dist/chunk-CK6P5AUK.js.map +1 -0
  73. package/dist/chunk-DAO2VFTT.js +129 -0
  74. package/dist/chunk-DAO2VFTT.js.map +1 -0
  75. package/dist/chunk-DEYOGDE7.js +141 -0
  76. package/dist/chunk-DEYOGDE7.js.map +1 -0
  77. package/dist/chunk-DYBPI5O2.js +25 -0
  78. package/dist/chunk-DYBPI5O2.js.map +1 -0
  79. package/dist/{chunk-TRNBHPNW.js → chunk-E34TE2ZI.js} +12 -8
  80. package/dist/chunk-E34TE2ZI.js.map +1 -0
  81. package/dist/chunk-EYALJQQD.js +25 -0
  82. package/dist/chunk-EYALJQQD.js.map +1 -0
  83. package/dist/chunk-I45QO2IZ.js +88 -0
  84. package/dist/chunk-I45QO2IZ.js.map +1 -0
  85. package/dist/chunk-I4V3UDSA.js +79 -0
  86. package/dist/chunk-I4V3UDSA.js.map +1 -0
  87. package/dist/chunk-OGTJNHRG.js +42 -0
  88. package/dist/chunk-OGTJNHRG.js.map +1 -0
  89. package/dist/chunk-OL4TC3U2.js +156 -0
  90. package/dist/chunk-OL4TC3U2.js.map +1 -0
  91. package/dist/chunk-OMSRSL3B.js +120 -0
  92. package/dist/chunk-OMSRSL3B.js.map +1 -0
  93. package/dist/chunk-R3EBGEAW.js +46 -0
  94. package/dist/chunk-R3EBGEAW.js.map +1 -0
  95. package/dist/chunk-SOK5EUF7.js +25 -0
  96. package/dist/chunk-SOK5EUF7.js.map +1 -0
  97. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  98. package/dist/chunk-SRSJO5QE.js.map +1 -0
  99. package/dist/chunk-T7DOWS6T.js +61 -0
  100. package/dist/chunk-T7DOWS6T.js.map +1 -0
  101. package/dist/chunk-TIGSG6BX.js +218 -0
  102. package/dist/chunk-TIGSG6BX.js.map +1 -0
  103. package/dist/chunk-UDHHKZWO.js +41 -0
  104. package/dist/chunk-UDHHKZWO.js.map +1 -0
  105. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  106. package/dist/chunk-UKKSMZYT.js.map +1 -0
  107. package/dist/chunk-V6GQKOX2.js +39 -0
  108. package/dist/chunk-V6GQKOX2.js.map +1 -0
  109. package/dist/chunk-V6HCTCVD.js +46 -0
  110. package/dist/chunk-V6HCTCVD.js.map +1 -0
  111. package/dist/chunk-VDUJZF5G.js +515 -0
  112. package/dist/chunk-VDUJZF5G.js.map +1 -0
  113. package/dist/chunk-VXFGMDA7.js +31 -0
  114. package/dist/chunk-VXFGMDA7.js.map +1 -0
  115. package/dist/chunk-WN52USHV.js +115 -0
  116. package/dist/chunk-WN52USHV.js.map +1 -0
  117. package/dist/chunk-WSXUPSID.js +43 -0
  118. package/dist/chunk-WSXUPSID.js.map +1 -0
  119. package/dist/chunk-X5GRDQ7V.js +50 -0
  120. package/dist/chunk-X5GRDQ7V.js.map +1 -0
  121. package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
  122. package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
  123. package/dist/chunk-ZASJJMGV.js +17 -0
  124. package/dist/chunk-ZASJJMGV.js.map +1 -0
  125. package/dist/chunk-ZPWZIVI6.js +47 -0
  126. package/dist/chunk-ZPWZIVI6.js.map +1 -0
  127. package/dist/collapsible-panel.d.ts +77 -0
  128. package/dist/collapsible-panel.js +84 -0
  129. package/dist/collapsible-panel.js.map +1 -0
  130. package/dist/css-values.d.ts +75 -0
  131. package/dist/css-values.js +3 -0
  132. package/dist/css-values.js.map +1 -0
  133. package/dist/device-class.d.ts +62 -0
  134. package/dist/device-class.js +103 -0
  135. package/dist/device-class.js.map +1 -0
  136. package/dist/disclosure-arrow.js +1 -1
  137. package/dist/divider-sides-BzB6rphT.d.ts +6 -0
  138. package/dist/empty-state.d.ts +3 -2
  139. package/dist/empty-state.js +1 -1
  140. package/dist/flex-alignment-CF8NLj7i.d.ts +4 -0
  141. package/dist/floating-toolbar.d.ts +29 -0
  142. package/dist/floating-toolbar.js +3 -0
  143. package/dist/floating-toolbar.js.map +1 -0
  144. package/dist/index.d.ts +28 -14
  145. package/dist/index.js +34 -23
  146. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +19 -8
  147. package/dist/list-action-row.js +7 -0
  148. package/dist/list-action-row.js.map +1 -0
  149. package/dist/list-header.d.ts +80 -0
  150. package/dist/list-header.js +9 -0
  151. package/dist/list-header.js.map +1 -0
  152. package/dist/list-inset-control.d.ts +20 -0
  153. package/dist/list-inset-control.js +3 -0
  154. package/dist/list-inset-control.js.map +1 -0
  155. package/dist/list-inset-text.d.ts +29 -0
  156. package/dist/list-inset-text.js +3 -0
  157. package/dist/list-inset-text.js.map +1 -0
  158. package/dist/list-item.d.ts +45 -0
  159. package/dist/list-item.js +7 -0
  160. package/dist/list-item.js.map +1 -0
  161. package/dist/list.d.ts +30 -0
  162. package/dist/list.js +5 -0
  163. package/dist/list.js.map +1 -0
  164. package/dist/loading-spinner.js +1 -1
  165. package/dist/nav-stack.d.ts +41 -0
  166. package/dist/nav-stack.js +6 -0
  167. package/dist/nav-stack.js.map +1 -0
  168. package/dist/pane.d.ts +50 -0
  169. package/dist/pane.js +4 -0
  170. package/dist/pane.js.map +1 -0
  171. package/dist/resizable-region.d.ts +21 -3
  172. package/dist/resizable-region.js +1 -1
  173. package/dist/row.d.ts +28 -0
  174. package/dist/row.js +5 -0
  175. package/dist/row.js.map +1 -0
  176. package/dist/segmented-control.d.ts +11 -8
  177. package/dist/segmented-control.js +3 -1
  178. package/dist/select-register.d.ts +5 -1
  179. package/dist/select-register.js +129 -1
  180. package/dist/select-register.js.map +1 -1
  181. package/dist/select.d.ts +34 -8
  182. package/dist/select.js +3 -1
  183. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  184. package/dist/skeleton.d.ts +25 -0
  185. package/dist/skeleton.js +4 -0
  186. package/dist/skeleton.js.map +1 -0
  187. package/dist/spacer.d.ts +16 -0
  188. package/dist/spacer.js +4 -0
  189. package/dist/spacer.js.map +1 -0
  190. package/dist/split-view.d.ts +43 -0
  191. package/dist/split-view.js +82 -0
  192. package/dist/split-view.js.map +1 -0
  193. package/dist/state-banner.d.ts +11 -5
  194. package/dist/state-banner.js +3 -1
  195. package/dist/styles/app-tab.css +26 -0
  196. package/dist/styles/catalog.css +582 -0
  197. package/dist/styles/collapsible-panel.css +212 -0
  198. package/dist/styles/floating-toolbar.css +38 -0
  199. package/dist/styles/foundation.css +80 -0
  200. package/dist/styles/layout.css +2 -20
  201. package/dist/styles/list-action-row.css +224 -0
  202. package/dist/styles/list-header.css +224 -0
  203. package/dist/styles/list-inset-control.css +23 -0
  204. package/dist/styles/list-inset-text.css +30 -0
  205. package/dist/styles/list-item.css +171 -0
  206. package/dist/styles/list.css +118 -0
  207. package/dist/styles/nav-stack.css +141 -0
  208. package/dist/styles/pane.css +62 -0
  209. package/dist/styles/resizable-region.css +158 -0
  210. package/dist/styles/row.css +92 -0
  211. package/dist/styles/segmented-control.css +10 -7
  212. package/dist/styles/select.css +115 -2
  213. package/dist/styles/skeleton.css +31 -0
  214. package/dist/styles/spacer.css +11 -0
  215. package/dist/styles/split-view.css +35 -0
  216. package/dist/styles/state-banner.css +49 -10
  217. package/dist/styles/styles.css +10 -5
  218. package/dist/styles/sunken-panel.css +22 -0
  219. package/dist/styles/surface-scaffold.css +51 -0
  220. package/dist/styles/tab-bar.css +24 -0
  221. package/dist/styles/tab-scaffold.css +85 -0
  222. package/dist/styles/text.css +5 -0
  223. package/dist/styles/token-search-field.css +14 -2
  224. package/dist/styles/toolbar-control-group.css +235 -8
  225. package/dist/styles/toolbar-text.css +65 -2
  226. package/dist/styles/toolbar.css +47 -2
  227. package/dist/styles/webawesome.css +171 -0
  228. package/dist/styles/workbench.css +187 -0
  229. package/dist/sunken-panel.d.ts +20 -0
  230. package/dist/sunken-panel.js +3 -0
  231. package/dist/sunken-panel.js.map +1 -0
  232. package/dist/surface-scaffold.d.ts +26 -0
  233. package/dist/surface-scaffold.js +3 -0
  234. package/dist/surface-scaffold.js.map +1 -0
  235. package/dist/tab-bar.d.ts +24 -6
  236. package/dist/tab-bar.js +1 -1
  237. package/dist/tab-scaffold.d.ts +31 -0
  238. package/dist/tab-scaffold.js +51 -0
  239. package/dist/tab-scaffold.js.map +1 -0
  240. package/dist/text.d.ts +20 -0
  241. package/dist/text.js +3 -0
  242. package/dist/text.js.map +1 -0
  243. package/dist/token-search-field.d.ts +30 -13
  244. package/dist/token-search-field.js +1 -1
  245. package/dist/toolbar-control-group.d.ts +33 -7
  246. package/dist/toolbar-control-group.js +1 -1
  247. package/dist/toolbar-text.d.ts +31 -4
  248. package/dist/toolbar-text.js +3 -1
  249. package/dist/toolbar.d.ts +10 -7
  250. package/dist/toolbar.js +1 -1
  251. package/dist/value-table.d.ts +7 -3
  252. package/dist/value-table.js +3 -1
  253. package/dist/webawesome.d.ts +1 -0
  254. package/dist/wire-catalog.d.ts +57 -0
  255. package/dist/wire-catalog.js +302 -0
  256. package/dist/wire-catalog.js.map +1 -0
  257. package/dist/wire-nav-stack.d.ts +18 -0
  258. package/dist/wire-nav-stack.js +228 -0
  259. package/dist/wire-nav-stack.js.map +1 -0
  260. package/dist/wire-resizable-regions.d.ts +1 -1
  261. package/dist/wire-resizable-regions.js +1 -1
  262. package/dist/wire-sidebar.d.ts +48 -0
  263. package/dist/wire-sidebar.js +147 -0
  264. package/dist/wire-sidebar.js.map +1 -0
  265. package/dist/wire-tab-bars.d.ts +19 -2
  266. package/dist/wire-tab-bars.js +1 -1
  267. package/dist/wire-tab-scaffold.d.ts +11 -0
  268. package/dist/wire-tab-scaffold.js +21 -0
  269. package/dist/wire-tab-scaffold.js.map +1 -0
  270. package/dist/wire-token-search-fields.d.ts +104 -4
  271. package/dist/wire-token-search-fields.js +1 -1
  272. package/dist/workbench.d.ts +44 -0
  273. package/dist/workbench.js +106 -0
  274. package/dist/workbench.js.map +1 -0
  275. package/docs/accessibility.md +155 -20
  276. package/docs/app-layouts.md +61 -0
  277. package/docs/catalog.md +364 -0
  278. package/docs/collapsible-panel.md +142 -0
  279. package/docs/component-contract.md +258 -28
  280. package/docs/component-integration.md +63 -0
  281. package/docs/component-selection.md +219 -57
  282. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  283. package/docs/design/templates/empty-state/filtered.svg +1 -0
  284. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  285. package/docs/design/templates/empty-state/with-action.svg +1 -0
  286. package/docs/design/templates/empty-state-dark.svg +1 -0
  287. package/docs/design/templates/empty-state.svg +1 -0
  288. package/docs/design/templates/list/compact-dark.svg +1 -0
  289. package/docs/design/templates/list/compact.svg +1 -0
  290. package/docs/design/templates/list/stack-dark.svg +1 -0
  291. package/docs/design/templates/list/stack.svg +1 -0
  292. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  293. package/docs/design/templates/list-action-row/default.svg +1 -0
  294. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  295. package/docs/design/templates/list-action-row/selected.svg +1 -0
  296. package/docs/design/templates/list-action-row-dark.svg +1 -0
  297. package/docs/design/templates/list-action-row.svg +1 -0
  298. package/docs/design/templates/list-dark.svg +1 -0
  299. package/docs/design/templates/list-header/action-dark.svg +1 -0
  300. package/docs/design/templates/list-header/action.svg +1 -0
  301. package/docs/design/templates/list-header/count-dark.svg +1 -0
  302. package/docs/design/templates/list-header/count.svg +1 -0
  303. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  304. package/docs/design/templates/list-header/inline-action.svg +1 -0
  305. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  306. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  307. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  308. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  309. package/docs/design/templates/list-header-dark.svg +1 -0
  310. package/docs/design/templates/list-header.svg +1 -0
  311. package/docs/design/templates/list-item/default-dark.svg +1 -0
  312. package/docs/design/templates/list-item/default.svg +1 -0
  313. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  314. package/docs/design/templates/list-item/multiline.svg +1 -0
  315. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  316. package/docs/design/templates/list-item/selected.svg +1 -0
  317. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  318. package/docs/design/templates/list-item/trailing.svg +1 -0
  319. package/docs/design/templates/list-item-dark.svg +1 -0
  320. package/docs/design/templates/list-item.svg +1 -0
  321. package/docs/design/templates/list.svg +1 -0
  322. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  323. package/docs/design/templates/segmented-control/equal.svg +1 -0
  324. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  325. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  326. package/docs/design/templates/segmented-control-dark.svg +1 -0
  327. package/docs/design/templates/segmented-control.svg +1 -0
  328. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  329. package/docs/design/templates/skeleton/avatar.svg +1 -0
  330. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  331. package/docs/design/templates/skeleton/block.svg +1 -0
  332. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  333. package/docs/design/templates/skeleton/lines.svg +1 -0
  334. package/docs/design/templates/skeleton-dark.svg +1 -0
  335. package/docs/design/templates/skeleton.svg +1 -0
  336. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  337. package/docs/design/templates/state-banner/danger.svg +1 -0
  338. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  339. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  340. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  341. package/docs/design/templates/state-banner/info.svg +1 -0
  342. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  343. package/docs/design/templates/state-banner/success.svg +1 -0
  344. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  345. package/docs/design/templates/state-banner/warning.svg +1 -0
  346. package/docs/design/templates/state-banner-dark.svg +1 -0
  347. package/docs/design/templates/state-banner.svg +1 -0
  348. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  349. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  350. package/docs/design/templates/tab-bar-dark.svg +1 -0
  351. package/docs/design/templates/tab-bar.svg +1 -0
  352. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  353. package/docs/design/templates/token-search-field/empty.svg +1 -0
  354. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  355. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  356. package/docs/design/templates/token-search-field-dark.svg +1 -0
  357. package/docs/design/templates/token-search-field.svg +1 -0
  358. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  359. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  360. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  361. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  362. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  363. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  364. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  365. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  366. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  367. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  368. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  369. package/docs/design/templates/toolbar-control-group.svg +1 -0
  370. package/docs/design/templates/toolbar-dark.svg +1 -0
  371. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  372. package/docs/design/templates/toolbar-text/default.svg +1 -0
  373. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  374. package/docs/design/templates/toolbar-text/large.svg +1 -0
  375. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  376. package/docs/design/templates/toolbar-text/small.svg +1 -0
  377. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  378. package/docs/design/templates/toolbar-text.svg +1 -0
  379. package/docs/design/templates/toolbar.svg +1 -0
  380. package/docs/design/templates/value-table/details-dark.svg +1 -0
  381. package/docs/design/templates/value-table/details.svg +1 -0
  382. package/docs/design/templates/value-table-dark.svg +1 -0
  383. package/docs/design/templates/value-table.svg +1 -0
  384. package/docs/design/templates.md +128 -0
  385. package/docs/design-philosophy.md +33 -11
  386. package/docs/device-class.md +54 -0
  387. package/docs/examples/application-ui-profile.json +60 -0
  388. package/docs/examples/command-palette-adapter.tsx +68 -17
  389. package/docs/examples/component-catalog-extension-v2.json +80 -0
  390. package/docs/examples/component-catalog-extension.json +45 -0
  391. package/docs/layout.md +169 -38
  392. package/docs/nav-stack.md +77 -0
  393. package/docs/recipes.md +64 -16
  394. package/docs/split-view.md +55 -0
  395. package/docs/sunken-panel.md +53 -0
  396. package/docs/surface-scaffold.md +25 -0
  397. package/docs/tab-scaffold.md +52 -0
  398. package/docs/type-contracts.md +127 -0
  399. package/docs/ui-analyzer.md +118 -0
  400. package/docs/ui-doctor.md +91 -0
  401. package/docs/ui-evaluator.md +122 -0
  402. package/docs/ux-demo.md +29 -10
  403. package/docs/webawesome-theme.md +82 -8
  404. package/docs/workbench.md +123 -0
  405. package/doctor/cli.mjs +115 -0
  406. package/doctor/config.schema.json +68 -0
  407. package/doctor/eslint-diagnostics.d.mts +24 -0
  408. package/doctor/eslint-diagnostics.mjs +24 -0
  409. package/doctor/index.d.mts +116 -0
  410. package/doctor/index.mjs +1272 -0
  411. package/doctor/report.schema.json +118 -0
  412. package/evaluator/cli.mjs +89 -0
  413. package/evaluator/index.d.mts +90 -0
  414. package/evaluator/index.mjs +1138 -0
  415. package/evaluator/report.schema.json +152 -0
  416. package/llms.txt +260 -32
  417. package/package.json +205 -38
  418. package/traversal-exclusions.mjs +27 -0
  419. package/ux-demo/recipes/app-shell.tsx +223 -13
  420. package/ux-demo/recipes/collapsible-sidebar.tsx +230 -0
  421. package/ux-demo/recipes/compact-toolbar.tsx +116 -12
  422. package/ux-demo/recipes/composer-form.tsx +120 -19
  423. package/ux-demo/recipes/list-detail-dialog.tsx +205 -0
  424. package/ux-demo/recipes/list-workspace-states.tsx +176 -9
  425. package/ux-demo/recipes/loaders.ts +13 -4
  426. package/ux-demo/recipes/loading-inspector.tsx +191 -0
  427. package/ux-demo/recipes/mount-recipe.ts +31 -5
  428. package/ux-demo/recipes/navigation-sidebar.tsx +123 -11
  429. package/ux-demo/recipes/navigation-stack.tsx +121 -0
  430. package/ux-demo/recipes/recipes.css +125 -16
  431. package/ux-demo/recipes/types.ts +9 -1
  432. package/ux-demo/recipes/workspace-header.tsx +72 -3
  433. package/dist/browser/dialog-header.js +0 -5
  434. package/dist/browser/menu-action-row.js +0 -3
  435. package/dist/browser/menu-header.js +0 -5
  436. package/dist/browser/menu-item.js +0 -3
  437. package/dist/browser/page-header.js +0 -3
  438. package/dist/chunk-2PES33HS.js +0 -13
  439. package/dist/chunk-2PES33HS.js.map +0 -1
  440. package/dist/chunk-55DATV3A.js +0 -10
  441. package/dist/chunk-55DATV3A.js.map +0 -1
  442. package/dist/chunk-7BR3DO2A.js.map +0 -1
  443. package/dist/chunk-7LDCTU7D.js +0 -134
  444. package/dist/chunk-7LDCTU7D.js.map +0 -1
  445. package/dist/chunk-AQNKJRFH.js +0 -79
  446. package/dist/chunk-AQNKJRFH.js.map +0 -1
  447. package/dist/chunk-CTQKI2XL.js +0 -28
  448. package/dist/chunk-CTQKI2XL.js.map +0 -1
  449. package/dist/chunk-DAFFDO33.js +0 -14
  450. package/dist/chunk-DAFFDO33.js.map +0 -1
  451. package/dist/chunk-EGHL5S4P.js +0 -33
  452. package/dist/chunk-EGHL5S4P.js.map +0 -1
  453. package/dist/chunk-GY5WH7TO.js +0 -10
  454. package/dist/chunk-GY5WH7TO.js.map +0 -1
  455. package/dist/chunk-H5AGGVU5.js +0 -75
  456. package/dist/chunk-H5AGGVU5.js.map +0 -1
  457. package/dist/chunk-K3G72I6D.js +0 -24
  458. package/dist/chunk-K3G72I6D.js.map +0 -1
  459. package/dist/chunk-M5JRI6MN.js +0 -27
  460. package/dist/chunk-M5JRI6MN.js.map +0 -1
  461. package/dist/chunk-MBR3TYNL.js +0 -14
  462. package/dist/chunk-MBR3TYNL.js.map +0 -1
  463. package/dist/chunk-MFKMHK5W.js +0 -10
  464. package/dist/chunk-MFKMHK5W.js.map +0 -1
  465. package/dist/chunk-MQIZAD4A.js.map +0 -1
  466. package/dist/chunk-NPPD2A6O.js +0 -40
  467. package/dist/chunk-NPPD2A6O.js.map +0 -1
  468. package/dist/chunk-R6JHHBKQ.js +0 -19
  469. package/dist/chunk-R6JHHBKQ.js.map +0 -1
  470. package/dist/chunk-S3TPM2LP.js +0 -23
  471. package/dist/chunk-S3TPM2LP.js.map +0 -1
  472. package/dist/chunk-TRNBHPNW.js.map +0 -1
  473. package/dist/chunk-VHW5YNIB.js +0 -17
  474. package/dist/chunk-VHW5YNIB.js.map +0 -1
  475. package/dist/chunk-WVPYVDXY.js +0 -15
  476. package/dist/chunk-WVPYVDXY.js.map +0 -1
  477. package/dist/chunk-XZXRLY5Q.js +0 -33
  478. package/dist/chunk-XZXRLY5Q.js.map +0 -1
  479. package/dist/dialog-header.d.ts +0 -15
  480. package/dist/dialog-header.js +0 -5
  481. package/dist/dialog-header.js.map +0 -1
  482. package/dist/menu-action-row.js +0 -4
  483. package/dist/menu-action-row.js.map +0 -1
  484. package/dist/menu-header.d.ts +0 -41
  485. package/dist/menu-header.js +0 -6
  486. package/dist/menu-header.js.map +0 -1
  487. package/dist/menu-item.d.ts +0 -31
  488. package/dist/menu-item.js +0 -4
  489. package/dist/menu-item.js.map +0 -1
  490. package/dist/page-header.d.ts +0 -9
  491. package/dist/page-header.js +0 -3
  492. package/dist/page-header.js.map +0 -1
  493. package/dist/styles/dialog-header.css +0 -87
  494. package/dist/styles/menu-action-row.css +0 -160
  495. package/dist/styles/menu-header.css +0 -143
  496. package/dist/styles/menu-item.css +0 -123
  497. package/dist/styles/page-header.css +0 -33
  498. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
@@ -18,25 +18,161 @@ package delivery paths, Web Awesome's installed manifest, AI guidance, and
18
18
  documentation links. Nuanced prose in this contract and the selection guide
19
19
  remains authored rather than generated.
20
20
 
21
+ ### Composition catalog v2
22
+
23
+ [`component-catalog-v2.json`](../ai/component-catalog-v2.json) adds a formal,
24
+ machine-evaluable composition layer without changing the v1 selection and
25
+ delivery contract. Every v1 entry projects once, in order, under the stable
26
+ qualified key `package:id`. Each v2 entry explicitly covers parents/contexts,
27
+ named zones and cardinality, optional explicit JSX prop bindings, child concepts, state ownership, required wiring,
28
+ responsive ownership, layout and geometry, accessibility obligations, public
29
+ CSS boundaries, diagnostics, and provenance.
30
+
31
+ An entry's optional `cssValueProps` makes CSS-adjacent prop grammar equally
32
+ machine-evaluable. Each path records the property grammar, finite shorthands,
33
+ canonical versus exceptional spacing choices, standalone and expression-only
34
+ helpers, raw/unsafe policy, and serialization examples. Nested paths use the
35
+ bounded `items[].property` form. Consumer catalogs can publish the same facts;
36
+ ESLint, `kerf-ui-analyze`, and `kerf-ui-doctor` then issue the same stable
37
+ `KUI-L013`–`KUI-L017` feedback for application and third-party components.
38
+
39
+ The generator starts with permissive defaults. An `any` mode records that the
40
+ catalog has no defensible prohibition; it does not claim every composition is
41
+ recommended. Objective rules live in
42
+ `component-catalog-v2-overrides.json` and may carry stable `KUI-C###`
43
+ diagnostics. A tool reports a diagnostic only after proving its exact `when`
44
+ condition. Subjective choice, product policy, and visual taste remain prose.
45
+
46
+ Kerf UI calls component content positions **named `SafeHtml` prop slots**.
47
+ Use `children` for one homogeneous primary region; use explicit named
48
+ `SafeHtml` props for semantic positions or replacement content such as
49
+ `header`, `footer`, `leading`, `trailing`, `icon`, and `action`. These are typed
50
+ function-component props, not native web-component `<slot>` elements and not a
51
+ generic `slots={{...}}` object. A v2 zone declares `jsx.prop` only when tooling
52
+ can soundly bind that zone to one public JSX prop; `children` is spelled
53
+ explicitly. Zones without that binding remain guidance and are never guessed
54
+ from their ids. Static tools inspect only visible JSX structure and leave
55
+ dynamic `SafeHtml` expressions to runtime and accessibility evaluation.
56
+
57
+ V1 consumers continue unchanged. V2 consumers read v1 for selection/delivery
58
+ and v2 for composition. `npm run catalog:sync` projects every new component,
59
+ recipe, and supported Web Awesome entry, and the completeness gate prevents
60
+ silent omissions. Downstream catalogs use the v2 extension schema and types,
61
+ retain their own package identity, and qualify cross-catalog references. See
62
+ the checked
63
+ [`component-catalog-extension-v2.json`](./examples/component-catalog-extension-v2.json)
64
+ application-owned example.
65
+
66
+ ### Compile-time contract boundary
67
+
68
+ The versioned
69
+ [`compile-time-contracts-v1.json`](../ai/compile-time-contracts-v1.json)
70
+ artifact maps stable `KUI-T###` ids to public imports, emitted symbols, and
71
+ catalog identities. Its positive/negative fixture compiles against both source
72
+ and a freshly packed package, so source declarations and shipped declarations
73
+ cannot silently diverge. See [Compile-time contracts](./type-contracts.md) for
74
+ the full audit, migration guidance, and the relationships deliberately left to
75
+ runtime/catalog checks because TypeScript cannot prove them.
76
+
77
+ ### Application UI profile
78
+
79
+ The component catalogs describe what packages provide; an application profile
80
+ describes which supported choices a project has approved. A workspace may
81
+ check in `.kerf-ui-profile.json` conforming to
82
+ [`application-ui-profile.schema.json`](../ai/application-ui-profile.schema.json).
83
+ Keep package-qualified catalog locations and recurring-concept preferences,
84
+ allowed color schemes and density, public semantic-token overrides,
85
+ layout/responsive conventions, and narrow rule exceptions there. Product
86
+ records, copy, permissions, user preferences, and transport state do not belong
87
+ in this policy file.
88
+
89
+ Every catalog location names a v2 composition artifact. `selection` is optional
90
+ for consumer packages whose generated metadata declares v1 selection guidance
91
+ not applicable; `@kerfjs/ui` retains its required v1 selection artifact. This
92
+ lets a generated `component-catalog-v2.json` participate directly without a
93
+ fabricated compatibility file.
94
+
95
+ Discovery and precedence are deterministic:
96
+
97
+ 1. Load `application-ui-profile.defaults.json` from `@kerfjs/ui`.
98
+ 2. Load `.kerf-ui-profile.json` at the workspace root when present.
99
+ 3. Walk from the workspace root toward the target directory and load each
100
+ directory-local profile in parent-to-child order.
101
+
102
+ Later scalar and object-map values win. Catalogs merge by package; preferences
103
+ and token overrides merge by key; exceptions merge by stable id. Lists such as
104
+ allowed themes/densities replace the earlier list rather than accumulating.
105
+ Every resolved field retains its source file. The shipped
106
+ `application-ui-profile.mjs` API implements discovery, merge, loading, and
107
+ validation and reports actionable originating file + JSON-path diagnostics for stale
108
+ catalogs, unknown component/rule/token references, preference conflicts, and
109
+ broad exceptions. Each raw layer is validated against the catalogs effective at
110
+ that exact precedence point before merge, so a broken parent catalog, stale
111
+ parent reference, invalid value, or unknown field cannot disappear merely
112
+ because a child profile replaces it. The shipped
113
+ `application-ui-profile-sync.cjs` projects the same merge and validation contract
114
+ for synchronous hosts such as ESLint rules; it deliberately performs no async
115
+ I/O.
116
+ See the
117
+ [`application-ui-profile.json`](./examples/application-ui-profile.json) example.
118
+
119
+ Catalog detail footers use one standard resource vocabulary and order. Build
120
+ them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo source`
121
+ first, optional `Component source` and `Design template`, then `Guidance`.
122
+ Third-party entries use the typed `integrationGuidance` kind, which renders
123
+ `Integration guidance`, and omit `Component source` when the implementation is
124
+ not owned by the catalog's project. Prefer these semantic kinds over local labels
125
+ such as “View source” or “Read UI guidance”; the helper makes that convention a
126
+ compile-time choice while still returning ordinary `CatalogResource[]` values.
127
+
21
128
  ## Ownership boundaries
22
129
 
130
+ ### Geometry ownership metadata
131
+
132
+ The canonical [`component-catalog.json`](../ai/component-catalog.json) records
133
+ the margin, border, and padding owner for every component and composition under
134
+ `geometry`. Read it before adding a wrapper or local spacing rule:
135
+
136
+ - `self` means the entry's public visual contract supplies that geometry.
137
+ - `parent` means the embedding layout must supply it.
138
+ - `child` means composed descendants supply it; the entry's outer shell does not.
139
+ - `none` means that dimension is intentionally absent from the standard contract.
140
+ - `conditional` means a variant, part, or configuration changes ownership; the
141
+ accompanying `notes` explain the boundary.
142
+
143
+ The values describe public ownership, including themed shadow parts, rather
144
+ than merely asking whether a CSS declaration appears on the host element.
145
+ Recipes are exempt because they arrange entries whose individual ownership is
146
+ already cataloged.
147
+
148
+ Downstream packages and applications should publish the same contract for their
149
+ reusable visual components. Use
150
+ [`component-catalog-extension.schema.json`](../ai/component-catalog-extension.schema.json)
151
+ and copy the structure of the checked
152
+ [`component-catalog-extension.json`](./examples/component-catalog-extension.json)
153
+ example. Keep app and Kerf entries as package-qualified inputs, then let people
154
+ or AI tools search their combined entries and compare `geometry` before adding
155
+ wrappers or insets. Do not add app-owned entries to Kerf's canonical catalog or
156
+ claim Kerf delivery paths for them.
157
+
23
158
  - Components own semantic markup, stable anatomy, documented variants, ARIA projection, and package CSS hooks.
24
159
  - Applications own signals/stores, product copy, domain-state mapping, persistence, routing, permissions, and transport.
25
160
  - Actions are `data-action` strings. Wire them at a stable root with `delegate()` or `delegateActions()` and retain the disposer.
26
161
  - A reusable component never owns per-instance mutable module state.
27
- - Consumers style through `--kui-*` semantic tokens and public component classes. Foundation tokens provide opinionated neutral, brand/info, success, warning, and danger fill/border/foreground roles. Stateful components expose local override variables; prefer an equivalent prop or token before writing a selector.
162
+ - Consumers style through `--kui-*` semantic tokens and public component classes. Foundation tokens provide opinionated neutral, brand/info, non-status pop, success, warning, and danger fill/border/foreground roles. Stateful components expose local override variables; prefer an equivalent prop or token before writing a selector.
28
163
 
29
- `MenuItem.rootAttributes`, `MenuActionRow.rootAttributes`,
30
- `MenuHeader.rootAttributes`, and `AppTab.rootAttributes` accept
164
+ `ListItem.rootAttributes`, `ListActionRow.rootAttributes`,
165
+ `ListHeader.rootAttributes`, `AppTab.rootAttributes`,
166
+ `CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` accept
31
167
  application-owned `data-*` metadata without
32
- adding product fields to the shared API. A `MenuActionRow` trailing action uses
33
- `trailingActionAttributes`, and a `MenuHeader` action/disclosure uses
168
+ adding product fields to the shared API. A `ListActionRow` trailing action uses
169
+ `trailingActionAttributes`, and a `ListHeader` action/disclosure uses
34
170
  `triggerAttributes`, for `data-*`, native popover target/action attributes, and
35
171
  the corresponding `aria-controls`/`aria-haspopup` relationship. These slots do
36
172
  not accept roles or component-owned action, selection, disclosure, accessible
37
173
  name, disabled, or icon fields. Extension objects are filtered at runtime,
38
174
  including case-insensitive rejection of protected `data-*` names, and the
39
- component writes its protected attributes after the accepted metadata. Typed,
175
+ component or helper writes its protected attributes after the accepted metadata. Typed,
40
176
  structurally widened, and JavaScript callers therefore cannot replace its
41
177
  contract.
42
178
 
@@ -46,10 +182,10 @@ component continues to own the named close button or focusable separator, and
46
182
  `wireTabBars()` / `wireResizableRegions()` continue to own transient behavior
47
183
  and disposal.
48
184
 
49
- `MenuItem.trailing`, `MenuActionRow.label`, `MenuActionRow.icon`, and
50
- `MenuActionRow.trailingActionIcon` are dormant SafeHtml slots. They must not
185
+ `ListItem.trailing`, `ListActionRow.label`, `ListActionRow.icon`, and
186
+ `ListActionRow.trailingActionIcon` are dormant SafeHtml slots. They must not
51
187
  contain controls. When a row needs an independently interactive trailing
52
- region, `MenuActionRow` owns the noninteractive root and the two sibling native
188
+ region, `ListActionRow` owns the noninteractive root and the two sibling native
53
189
  buttons; the application owns their delegated behavior and controlled state.
54
190
  Both row components align a leading icon with the first label line when
55
191
  `multiline` allows the label to wrap; additional lines extend below that fixed
@@ -65,12 +201,25 @@ layout cannot be expressed by a prop or token. A class being public does not
65
201
  make copied component markup an invocation or transfer state and accessibility
66
202
  ownership to the application.
67
203
 
204
+ The v2 composition catalog additionally requires `boundaries.rootClass` to be
205
+ either one exact member of `publicClasses` or `null` when the entry has no
206
+ rendered class root. Runtime geometry tooling uses this explicit field; array
207
+ order never implies root ownership.
208
+
68
209
  Do not select a component's descendant by element name, id, attribute alone, or
69
210
  an unlisted implementation class. Selectors such as `.kui-state-banner span`,
70
- `.kui-menu-item [data-state]`, and `.kui-menu-item .local-label` depend on
211
+ `.kui-list-item [data-state]`, and `.kui-list-item .local-label` depend on
71
212
  private structure. If no prop, token, or cataloged class expresses a recurring
72
213
  need, request a supported hook instead of inferring one from rendered markup.
73
214
 
215
+ `ListItem` renders its leading icon and nested SVG at a root-scaled 18px by
216
+ default while retaining the row's 44px minimum interactive target. Multiline
217
+ rows align that 18px visual with the first inherited text line. The row clips
218
+ descendant painting to its rounded root so labels, status, and dormant trailing
219
+ content cannot escape its visible boundary. Rows with descriptions grow enough
220
+ to keep their owned two-line label stack readable; use `multiline` when the
221
+ primary label should wrap rather than truncate.
222
+
74
223
  `DisclosureArrow` uses an 18px root-scaled visual by default. Override
75
224
  `--kui-disclosure-arrow-size` on the component or its containing scope when a
76
225
  consumer needs another size. Kerf `Select` uses a separate Web Awesome expand
@@ -78,17 +227,22 @@ glyph contract, `--kui-disclosure-icon-scale: .5`; changing one contract does
78
227
  not implicitly change the other. Direction changes take the shortest rotation
79
228
  path; a 180-degree closed-to-open tie uses counterclockwise rotation.
80
229
 
81
- In `MenuHeader` toggle mode, omitting `actionIcon` composes the production
230
+ In `ListHeader` toggle mode, omitting `actionIcon` composes the production
82
231
  `DisclosureArrow` and derives its visual direction from `expanded`. The app
83
232
  must update that controlled state and reveal or hide real content. Passing a
84
233
  custom `actionIcon` replaces the default rather than layering or rotating both.
85
- The root fills the available inline width after its standard margins. A
86
- separate action stays at the logical end in its 44px target while the visible
87
- glyph defaults to 18px through `--kui-menu-header-action-icon-size`.
234
+ The root fills the available inline width after its standard margins by
235
+ default. Set `inline` when it must shrink-wrap beside surrounding content; that
236
+ presentation removes the root margin, border, and padding while retaining the
237
+ title and optional action's own control geometry. A separate action stays at
238
+ the logical end while the visible glyph defaults to 18px through
239
+ `--kui-list-header-action-icon-size`.
88
240
 
89
241
  `StateBanner` exposes instance-level `--kui-state-banner-background`,
90
242
  `--kui-state-banner-border`, `--kui-state-banner-foreground`,
91
- `--kui-state-banner-detail`, and action background variables. Its five built-in
243
+ `--kui-state-banner-detail`, `--kui-state-banner-badge-background`,
244
+ `--kui-state-banner-badge-foreground`, and action background variables. Its optional
245
+ badge is a compact pill beside the title and follows the banner tone by default. Its five built-in
92
246
  tones can be rethemed globally with
93
247
  `--kui-state-banner-{tone}-{background|border|foreground}`. Toolbar control,
94
248
  segmented-control, app-tab, and tab-bar colors likewise use their public
@@ -96,6 +250,13 @@ segmented-control, app-tab, and tab-bar colors likewise use their public
96
250
  hover, and selected-state variables, so rounded, pill, and toolbar presentations
97
251
  remain opinionated but locally overridable.
98
252
 
253
+ Inset hover and selection surfaces follow the outer control shape instead of
254
+ choosing an independent radius. `--kui-layout-highlight-inset` is the full
255
+ distance between those edges; the inner radius is the outer radius minus that
256
+ inset. `ToolbarControlGroup` publishes its derived radius to nested toolbar
257
+ `SegmentedControl` choices, keeping both direct buttons and exclusive-choice
258
+ highlights concentric when the group switches between pill and rounded shapes.
259
+
99
260
  `ResizableRegion` owns the Hot Sheet 2 split treatment: a persistent 1px
100
261
  separator with a compact grip that appears on hover or keyboard focus. Override
101
262
  `--kui-resizable-region-separator-color`,
@@ -103,9 +264,32 @@ separator with a compact grip that appears on hover or keyboard focus. Override
103
264
  `--kui-resizable-region-handle-active-color` on a region when its containing
104
265
  surface needs a different contrast level.
105
266
 
106
- `@kerfjs/ui/layout.css` defines one structural model for sidebars, main areas,
107
- inspectors, and dialogs. `.kui-pane` is unpadded and contains an optional
108
- toolbar, one scrolling `.kui-pane__content`, and an optional footer.
267
+ `Pane` defines one structural model for sidebars, main areas, inspectors, and
268
+ dialogs. Its `.kui-pane` root is unpadded and contains an optional vertical
269
+ header, one scrolling vertical `.kui-pane__content`, and an optional footer.
270
+ Logical-edge separator lines are independently opt-in and default off.
271
+ `@kerfjs/ui/layout.css` retains the pane roles and supplies the related content
272
+ geometry classes.
273
+ `List` is the corresponding layout-only vertical stack: its children stretch by
274
+ default, while `gap`, `flex`, and `scrollable` opt into typed spacing,
275
+ flex growth, and vertical scroll ownership. `Row.flex` uses the same typed flex
276
+ participation contract on the horizontal counterpart. `dividerSides` accepts canonical
277
+ physical top/right/bottom/left combinations such as `tr` and `trbl`; the stack
278
+ adds no list semantics, margin, or padding of its own. Use a direct finite
279
+ spacing shorthand such as `gap="2xs"`, or pass a `CssLength` created by the
280
+ CSS-free `@kerfjs/ui/css-values` helpers: `space('m')`, `rem(0.25)`,
281
+ `lengthVar('--app-gap')`, or `calc(plus(rem(0.25), pct(10)))`. `plus` returns a
282
+ non-standalone `CssLengthExpression`; only `calc` turns it into a complete
283
+ length. Raw CSS strings and source-only `remify(4px)` are not valid runtime
284
+ props. The `CssLength` name intentionally includes percentages for UI dimension
285
+ props. Its opaque string brand improves authoring correctness; it is not a CSS
286
+ sanitizer or security boundary.
287
+ `Row.flex` and `List.flex` likewise accept their boolean default, finite keywords, or `CssFlex`
288
+ from `flex(grow, shrink, basis)`. `Skeleton` width/height use `CssSize`, radius
289
+ uses `CssLength`, and `SelectChoice.color` uses `CssColor` from `uiColor()` or
290
+ `colorVar()`. Never exchange these property grammars. List rows expose
291
+ `className`, public tokens, and semantic props instead of unrestricted `style`
292
+ declarations.
109
293
  `.kui-content` gives major children 24px vertical separation.
110
294
  `.kui-content-item` gives one child 8px inline margin, a real 1px border,
111
295
  8px padding, and 12px corners; border and background may be transparent without
@@ -113,7 +297,19 @@ changing geometry. `.kui-content-item--pill` selects the 22px radius.
113
297
 
114
298
  `ToolbarControlGroup` is the unit of toolbar organization, even for dormant
115
299
  text. Each group reserves `calc(2px + remify(42px))`, or 44px, with 8px between
116
- groups and inside items. `MenuHeader` similarly separates its dormant title and
300
+ groups and inside items. For an ordinary icon/action control inside a group, use
301
+ a plain `<button>` — the group styles `> button` fully, and it keeps the group
302
+ free of a Web Awesome dependency and shadow DOM. Reach for `wa-button` only when
303
+ you need a Web Awesome feature, chiefly the `slot="trigger"` button of a
304
+ `wa-dropdown` popup menu. For a compact mixed-content group, set
305
+ `nestedDropdown`; a text-and-caret trigger grows to its intrinsic width while an
306
+ icon-only trigger can remain square. Compact mixed controls retain the standard
307
+ item padding, omit an internal separator, and let the raised selected item paint
308
+ over the outer border instead of shrinking to an inset highlight. The short text
309
+ trigger has an engine-stable 66px floor because WebKit
310
+ does not include the shadow caret in the custom-element host's intrinsic width;
311
+ raise `--kui-toolbar-dropdown-trigger-width` for longer localized copy.
312
+ `ListHeader` similarly separates its dormant title and
117
313
  optional count or badge from its optional 44px action. Use the mutually
118
314
  exclusive `count`/`countLabel` pair for non-negative safe-integer section
119
315
  quantities; reserve `badge` for non-count `SafeHtml`. Do not concatenate counts
@@ -121,14 +317,11 @@ into the section label. Do not add padding to pane shells,
121
317
  double child-owned geometry with wrapper insets, or create competing scroll
122
318
  owners. The [layout contract](./layout.md) lists the public roles and tokens.
123
319
 
124
- `DialogHeader` composes its icon and first title line inside a borderless
125
- `ToolbarControlGroup` in a real top `Toolbar`. Direct `actions` children are
126
- automatically placed in one contained `ToolbarControlGroup`; use the optional
127
- localized `actionsLabel` when that group needs an accessible name. Existing
128
- pre-grouped action content remains layout-compatible, but new callers should
129
- pass the action children rather than groups. The optional summary is a separate
130
- row aligned below the title, so it cannot pull the 24px icon or 34px circular
131
- icon background out of vertical alignment with the 44px action row.
320
+ Panel, dialog, and page headings are direct `Toolbar` compositions. The leading
321
+ zone holds an optional icon `ToolbarControlGroup` and a direct extra-large
322
+ `ToolbarText`; app actions belong in a trailing `ToolbarControlGroup`. Omit the
323
+ icon group when it has no content. Supporting copy is app-owned content below
324
+ the toolbar so it cannot pull the icon or actions out of alignment.
132
325
 
133
326
  `ValueTable` composes typed `ValueTableRow` entries. A row owns its `dt`/`dd`
134
327
  semantics and may receive a leading `SafeHtml` icon. Every row keeps 8px of
@@ -153,10 +346,47 @@ overrides load later in the cascade or set scoped `--kui-*` variables. JavaScrip
153
346
  modules are pure except the browser style wrappers and `@kerfjs/ui/select/register`,
154
347
  which registers exactly the Web Awesome elements used by `Select`. Eventful
155
348
  helpers such as `wireResizableRegions` and `wireTabBars` attach listeners only
156
- when called and return disposers. CSS, the generated wrappers that make it
349
+ when called and return disposers. `wireTokenSearchFields` goes one step further:
350
+ by default it also owns the collapsible field's transient expand/collapse/focus
351
+ (activate to reveal and focus, Escape or empty blur to collapse), holding that
352
+ state in a signal it exposes on the returned handle. An app reads that signal in
353
+ render, hands in its own via `collapsible.signals`, drives it through
354
+ `handle.open`/`handle.close`, or disables any individual behavior — so transient
355
+ UI is consistent by default without every app reinventing it.
356
+
357
+ `wireTokenSearchFields` is a deliberate exception, not the rule for `wire…`
358
+ helpers. Its collapse behavior was _rich and error-prone_ — reveal, focus
359
+ transfer, Escape, empty-blur collapse, focus return — the kind of transient chrome
360
+ apps kept reimplementing inconsistently, so the helper owns it. Everywhere else the
361
+ app's state is **domain or persisted, not transient chrome, and stays app-owned**: a
362
+ `NavStack`'s view stack is navigation history, a `TabBar`/`TabScaffold`'s selection
363
+ and tab order are data, a `ResizableRegion`'s committed size and a
364
+ `Workbench`/`SplitView` rail's `collapsed` flag are persisted layout preferences.
365
+ Each helper already owns only the _ephemeral mechanics_ around that state —
366
+ `wireNavStack` the push/pop animation, `wireTabBars` the overflow autoscroll and
367
+ drag preview, `wireResizableRegions` the live drag preview — and reports committed
368
+ changes through callbacks. A `ListHeader` `toggle` disclosure's `expanded` is
369
+ likewise app-owned: it is a one-line boolean the app already tracks and must read to
370
+ render the section body, so a managed helper would remove no real complexity. Reach
371
+ for a managed default only when the transient behavior is substantial enough that
372
+ hand-rolling it produces genuine, inconsistent variation.
373
+
374
+ CSS, the generated wrappers that make it
157
375
  reachable, and the registration module are the package's only declared side
158
376
  effects.
159
377
 
378
+ A value-bearing component's `placeholder` prop is a first-class loading mode: the
379
+ component renders its own real chrome (labels, icon and action affordances,
380
+ container geometry) while replacing each **value** slot with a subtle, deliberately
381
+ unanimated `Skeleton` block and disabling its own interactive controls
382
+ (`aria-busy`, dropped `data-action`, disabled buttons). Sizes and shapes stay
383
+ identical to the populated component, so a parent composes a faithful loading view —
384
+ an inspector, a detail pane — from placeholder children without hand-rebuilding
385
+ markup. The application still owns the loading lifecycle (when to pass `placeholder`)
386
+ and which slots are unknown; the standalone `Skeleton` covers custom slots. It is a
387
+ placeholder, not progress: use `LoadingSpinner` for known busy activity, and never
388
+ animate the skeleton.
389
+
160
390
  Package source styles express root-scaled geometry with `remify(<px>)`; the
161
391
  build converts it against the 16px authoring baseline and exposes only ordinary
162
392
  `rem` CSS. Literal pixels remain for intentional hairlines, and `em` remains
@@ -0,0 +1,63 @@
1
+ # Public component integration workflow
2
+
3
+ The canonical `ai/component-catalog.json` is also the integration manifest for
4
+ first-party public components. Every entry with `source: "kerf"` and
5
+ `kind: "component"` projects into the package, build, root API, catalog demo,
6
+ and AI authoring surfaces. This keeps a new List-like primitive from reaching a
7
+ late build or release gate before an omitted surface is discovered.
8
+
9
+ Author the implementation, CSS, catalog facts, demo, and behavior tests first.
10
+ Then run:
11
+
12
+ ```bash
13
+ npm run component-integrations:dry-run
14
+ ```
15
+
16
+ The dry run reports every mismatched projection together, using diff-like
17
+ `expected` and `actual` lines without changing files or failing the command.
18
+ Resolve the complete report, build the package, regenerate signatures with
19
+ `npm run ai:signatures:sync`, and refresh reviewed compatibility digests with
20
+ `npm run ai:compatibility:sync`. `npm run check:component-integrations` runs the
21
+ same validator in failing CI mode, and the package `check` gate includes it.
22
+
23
+ For each catalog component, the validator checks:
24
+
25
+ - the source module and stylesheet;
26
+ - the tsup entry and typed package subpath, including the browser-conditioned
27
+ entry when the catalog declares `browserImport`;
28
+ - the CSS package export;
29
+ - root-barrel exposure for browser-conditioned components;
30
+ - the stable catalog route, demo module, and exhaustive demo registry; and
31
+ - inclusion of the public subpath in the generated AI signature reference.
32
+
33
+ The existing catalog sync and compatibility gates remain responsible for the
34
+ typed catalog projections, catalog count/order, and artifact digests. Public
35
+ API signatures derive component subpaths from the catalog, so a newly cataloged
36
+ component can no longer be silently omitted from that corpus.
37
+
38
+ Non-component helpers, wiring modules, compositions, recipes, and development
39
+ tools remain explicit package surfaces. They do not masquerade as visual
40
+ components merely to enter this workflow.
41
+
42
+ ## Change-local verification and bundle review
43
+
44
+ Run `npm run check:change` after changing a public component. It synchronizes
45
+ both catalog projections, declarations, AI signatures, and compatibility
46
+ digests; names every checked-in projection changed by that synchronization;
47
+ runs the catalog/component contracts, unit coverage, consumer bundle tests,
48
+ source and packed type contracts; builds the production catalog; and reports
49
+ the exact gzip byte delta from the last reviewed baseline. The broader
50
+ `npm run check` remains the release gate.
51
+
52
+ Intentional bundle changes use the same workflow with an explicit review
53
+ reason:
54
+
55
+ ```bash
56
+ npm run check:change -- --update-bundle-budget \
57
+ --reason "Added the reviewed List detail states and keyboard behavior"
58
+ ```
59
+
60
+ That mode writes `demo-bundle-budget.json`, records the previous and new exact
61
+ measurements and budgets with the reason and timestamp, and rounds the total
62
+ budget to the next 100 bytes. Do not edit the budget or add a history comment
63
+ by hand.