@kerfjs/ui 5.0.0-beta.3 → 5.0.0-beta.31

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 (470) hide show
  1. package/README.md +320 -107
  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 +131 -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 +486 -0
  17. package/ai/component-catalog-v2.d.ts +90 -0
  18. package/ai/component-catalog-v2.json +5455 -0
  19. package/ai/component-catalog-v2.schema.json +298 -0
  20. package/ai/component-catalog.json +2437 -419
  21. package/ai/component-catalog.schema.json +39 -0
  22. package/ai/public-api-signatures-v1.md +1442 -124
  23. package/ai/skill.md +131 -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/{menu-header.js → list-header.js} +3 -2
  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/segmented-control.js +1 -0
  41. package/dist/browser/select.js +1 -0
  42. package/dist/browser/skeleton.js +3 -0
  43. package/dist/browser/state-banner.js +1 -0
  44. package/dist/browser/sunken-panel.js +3 -0
  45. package/dist/browser/surface-scaffold.js +3 -0
  46. package/dist/browser/toolbar-text.js +1 -0
  47. package/dist/browser/value-table.js +1 -0
  48. package/dist/catalog-resources.d.ts +35 -0
  49. package/dist/catalog-resources.js +22 -0
  50. package/dist/catalog-resources.js.map +1 -0
  51. package/dist/catalog.d.ts +151 -0
  52. package/dist/catalog.js +379 -0
  53. package/dist/catalog.js.map +1 -0
  54. package/dist/chunk-6NDBE2OK.js +32 -0
  55. package/dist/chunk-6NDBE2OK.js.map +1 -0
  56. package/dist/chunk-6WTETUZ6.js +21 -0
  57. package/dist/chunk-6WTETUZ6.js.map +1 -0
  58. package/dist/chunk-AQFWBG23.js +83 -0
  59. package/dist/chunk-AQFWBG23.js.map +1 -0
  60. package/dist/chunk-B6JYRX3P.js +51 -0
  61. package/dist/chunk-B6JYRX3P.js.map +1 -0
  62. package/dist/chunk-CAB6NQ2T.js +102 -0
  63. package/dist/chunk-CAB6NQ2T.js.map +1 -0
  64. package/dist/chunk-CK6P5AUK.js +136 -0
  65. package/dist/chunk-CK6P5AUK.js.map +1 -0
  66. package/dist/chunk-DAO2VFTT.js +129 -0
  67. package/dist/chunk-DAO2VFTT.js.map +1 -0
  68. package/dist/chunk-DYBPI5O2.js +25 -0
  69. package/dist/chunk-DYBPI5O2.js.map +1 -0
  70. package/dist/{chunk-TRNBHPNW.js → chunk-E34TE2ZI.js} +12 -8
  71. package/dist/chunk-E34TE2ZI.js.map +1 -0
  72. package/dist/chunk-I45QO2IZ.js +88 -0
  73. package/dist/chunk-I45QO2IZ.js.map +1 -0
  74. package/dist/chunk-I4V3UDSA.js +79 -0
  75. package/dist/chunk-I4V3UDSA.js.map +1 -0
  76. package/dist/chunk-KFUUFNTS.js +15 -0
  77. package/dist/chunk-KFUUFNTS.js.map +1 -0
  78. package/dist/chunk-MFR2IIFG.js +20 -0
  79. package/dist/chunk-MFR2IIFG.js.map +1 -0
  80. package/dist/chunk-OC275HHS.js +128 -0
  81. package/dist/chunk-OC275HHS.js.map +1 -0
  82. package/dist/chunk-OL4TC3U2.js +156 -0
  83. package/dist/chunk-OL4TC3U2.js.map +1 -0
  84. package/dist/chunk-OMSRSL3B.js +120 -0
  85. package/dist/chunk-OMSRSL3B.js.map +1 -0
  86. package/dist/chunk-RL6COPKF.js +44 -0
  87. package/dist/chunk-RL6COPKF.js.map +1 -0
  88. package/dist/chunk-SOK5EUF7.js +25 -0
  89. package/dist/chunk-SOK5EUF7.js.map +1 -0
  90. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  91. package/dist/chunk-SRSJO5QE.js.map +1 -0
  92. package/dist/chunk-T7DOWS6T.js +61 -0
  93. package/dist/chunk-T7DOWS6T.js.map +1 -0
  94. package/dist/chunk-TIGSG6BX.js +218 -0
  95. package/dist/chunk-TIGSG6BX.js.map +1 -0
  96. package/dist/chunk-UDHHKZWO.js +41 -0
  97. package/dist/chunk-UDHHKZWO.js.map +1 -0
  98. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  99. package/dist/chunk-UKKSMZYT.js.map +1 -0
  100. package/dist/chunk-V6GQKOX2.js +39 -0
  101. package/dist/chunk-V6GQKOX2.js.map +1 -0
  102. package/dist/chunk-V6HCTCVD.js +46 -0
  103. package/dist/chunk-V6HCTCVD.js.map +1 -0
  104. package/dist/chunk-VDUJZF5G.js +515 -0
  105. package/dist/chunk-VDUJZF5G.js.map +1 -0
  106. package/dist/chunk-VXFGMDA7.js +31 -0
  107. package/dist/chunk-VXFGMDA7.js.map +1 -0
  108. package/dist/chunk-WN52USHV.js +115 -0
  109. package/dist/chunk-WN52USHV.js.map +1 -0
  110. package/dist/chunk-WSXUPSID.js +43 -0
  111. package/dist/chunk-WSXUPSID.js.map +1 -0
  112. package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
  113. package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
  114. package/dist/chunk-ZPWZIVI6.js +47 -0
  115. package/dist/chunk-ZPWZIVI6.js.map +1 -0
  116. package/dist/collapsible-panel.d.ts +77 -0
  117. package/dist/collapsible-panel.js +84 -0
  118. package/dist/collapsible-panel.js.map +1 -0
  119. package/dist/css-values.d.ts +75 -0
  120. package/dist/css-values.js +3 -0
  121. package/dist/css-values.js.map +1 -0
  122. package/dist/device-class.d.ts +62 -0
  123. package/dist/device-class.js +103 -0
  124. package/dist/device-class.js.map +1 -0
  125. package/dist/disclosure-arrow.js +1 -1
  126. package/dist/divider-sides-267FA7sY.d.ts +4 -0
  127. package/dist/empty-state.d.ts +3 -2
  128. package/dist/empty-state.js +1 -1
  129. package/dist/floating-toolbar.d.ts +29 -0
  130. package/dist/floating-toolbar.js +3 -0
  131. package/dist/floating-toolbar.js.map +1 -0
  132. package/dist/index.d.ts +23 -14
  133. package/dist/index.js +30 -23
  134. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +19 -8
  135. package/dist/list-action-row.js +7 -0
  136. package/dist/list-action-row.js.map +1 -0
  137. package/dist/list-header.d.ts +77 -0
  138. package/dist/list-header.js +8 -0
  139. package/dist/list-header.js.map +1 -0
  140. package/dist/list-inset-control.d.ts +17 -0
  141. package/dist/list-inset-control.js +3 -0
  142. package/dist/list-inset-control.js.map +1 -0
  143. package/dist/list-inset-text.d.ts +26 -0
  144. package/dist/list-inset-text.js +3 -0
  145. package/dist/list-inset-text.js.map +1 -0
  146. package/dist/list-item.d.ts +45 -0
  147. package/dist/list-item.js +7 -0
  148. package/dist/list-item.js.map +1 -0
  149. package/dist/list.d.ts +21 -0
  150. package/dist/list.js +4 -0
  151. package/dist/list.js.map +1 -0
  152. package/dist/loading-spinner.js +1 -1
  153. package/dist/nav-stack.d.ts +41 -0
  154. package/dist/nav-stack.js +6 -0
  155. package/dist/nav-stack.js.map +1 -0
  156. package/dist/pane.d.ts +50 -0
  157. package/dist/pane.js +4 -0
  158. package/dist/pane.js.map +1 -0
  159. package/dist/resizable-region.d.ts +21 -3
  160. package/dist/resizable-region.js +1 -1
  161. package/dist/segmented-control.d.ts +11 -8
  162. package/dist/segmented-control.js +3 -1
  163. package/dist/select-register.d.ts +5 -1
  164. package/dist/select-register.js +3 -0
  165. package/dist/select-register.js.map +1 -1
  166. package/dist/select.d.ts +34 -8
  167. package/dist/select.js +3 -1
  168. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  169. package/dist/skeleton.d.ts +25 -0
  170. package/dist/skeleton.js +4 -0
  171. package/dist/skeleton.js.map +1 -0
  172. package/dist/split-view.d.ts +43 -0
  173. package/dist/split-view.js +82 -0
  174. package/dist/split-view.js.map +1 -0
  175. package/dist/state-banner.d.ts +11 -5
  176. package/dist/state-banner.js +3 -1
  177. package/dist/styles/app-tab.css +26 -0
  178. package/dist/styles/catalog.css +582 -0
  179. package/dist/styles/collapsible-panel.css +212 -0
  180. package/dist/styles/floating-toolbar.css +38 -0
  181. package/dist/styles/foundation.css +80 -0
  182. package/dist/styles/layout.css +2 -20
  183. package/dist/styles/list-action-row.css +224 -0
  184. package/dist/styles/list-header.css +198 -0
  185. package/dist/styles/list-inset-control.css +7 -0
  186. package/dist/styles/list-inset-text.css +14 -0
  187. package/dist/styles/list-item.css +171 -0
  188. package/dist/styles/list.css +43 -0
  189. package/dist/styles/nav-stack.css +141 -0
  190. package/dist/styles/pane.css +62 -0
  191. package/dist/styles/resizable-region.css +158 -0
  192. package/dist/styles/segmented-control.css +10 -7
  193. package/dist/styles/select.css +115 -2
  194. package/dist/styles/skeleton.css +31 -0
  195. package/dist/styles/split-view.css +35 -0
  196. package/dist/styles/state-banner.css +49 -10
  197. package/dist/styles/styles.css +7 -5
  198. package/dist/styles/sunken-panel.css +22 -0
  199. package/dist/styles/surface-scaffold.css +51 -0
  200. package/dist/styles/tab-bar.css +24 -0
  201. package/dist/styles/tab-scaffold.css +85 -0
  202. package/dist/styles/token-search-field.css +14 -2
  203. package/dist/styles/toolbar-control-group.css +224 -6
  204. package/dist/styles/toolbar-text.css +65 -2
  205. package/dist/styles/toolbar.css +47 -2
  206. package/dist/styles/webawesome.css +165 -0
  207. package/dist/styles/workbench.css +187 -0
  208. package/dist/sunken-panel.d.ts +20 -0
  209. package/dist/sunken-panel.js +3 -0
  210. package/dist/sunken-panel.js.map +1 -0
  211. package/dist/surface-scaffold.d.ts +26 -0
  212. package/dist/surface-scaffold.js +3 -0
  213. package/dist/surface-scaffold.js.map +1 -0
  214. package/dist/tab-bar.d.ts +24 -6
  215. package/dist/tab-bar.js +1 -1
  216. package/dist/tab-scaffold.d.ts +31 -0
  217. package/dist/tab-scaffold.js +51 -0
  218. package/dist/tab-scaffold.js.map +1 -0
  219. package/dist/token-search-field.d.ts +30 -13
  220. package/dist/token-search-field.js +1 -1
  221. package/dist/toolbar-control-group.d.ts +33 -7
  222. package/dist/toolbar-control-group.js +1 -1
  223. package/dist/toolbar-text.d.ts +31 -4
  224. package/dist/toolbar-text.js +3 -1
  225. package/dist/toolbar.d.ts +10 -7
  226. package/dist/toolbar.js +1 -1
  227. package/dist/value-table.d.ts +7 -3
  228. package/dist/value-table.js +3 -1
  229. package/dist/webawesome.d.ts +1 -0
  230. package/dist/wire-catalog.d.ts +57 -0
  231. package/dist/wire-catalog.js +302 -0
  232. package/dist/wire-catalog.js.map +1 -0
  233. package/dist/wire-nav-stack.d.ts +18 -0
  234. package/dist/wire-nav-stack.js +228 -0
  235. package/dist/wire-nav-stack.js.map +1 -0
  236. package/dist/wire-resizable-regions.d.ts +1 -1
  237. package/dist/wire-resizable-regions.js +1 -1
  238. package/dist/wire-sidebar.d.ts +48 -0
  239. package/dist/wire-sidebar.js +147 -0
  240. package/dist/wire-sidebar.js.map +1 -0
  241. package/dist/wire-tab-bars.d.ts +19 -2
  242. package/dist/wire-tab-bars.js +1 -1
  243. package/dist/wire-tab-scaffold.d.ts +11 -0
  244. package/dist/wire-tab-scaffold.js +21 -0
  245. package/dist/wire-tab-scaffold.js.map +1 -0
  246. package/dist/wire-token-search-fields.d.ts +104 -4
  247. package/dist/wire-token-search-fields.js +1 -1
  248. package/dist/workbench.d.ts +44 -0
  249. package/dist/workbench.js +106 -0
  250. package/dist/workbench.js.map +1 -0
  251. package/docs/accessibility.md +137 -20
  252. package/docs/app-layouts.md +61 -0
  253. package/docs/catalog.md +364 -0
  254. package/docs/collapsible-panel.md +142 -0
  255. package/docs/component-contract.md +253 -26
  256. package/docs/component-selection.md +213 -57
  257. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  258. package/docs/design/templates/empty-state/filtered.svg +1 -0
  259. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  260. package/docs/design/templates/empty-state/with-action.svg +1 -0
  261. package/docs/design/templates/empty-state-dark.svg +1 -0
  262. package/docs/design/templates/empty-state.svg +1 -0
  263. package/docs/design/templates/list/compact-dark.svg +1 -0
  264. package/docs/design/templates/list/compact.svg +1 -0
  265. package/docs/design/templates/list/stack-dark.svg +1 -0
  266. package/docs/design/templates/list/stack.svg +1 -0
  267. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  268. package/docs/design/templates/list-action-row/default.svg +1 -0
  269. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  270. package/docs/design/templates/list-action-row/selected.svg +1 -0
  271. package/docs/design/templates/list-action-row-dark.svg +1 -0
  272. package/docs/design/templates/list-action-row.svg +1 -0
  273. package/docs/design/templates/list-dark.svg +1 -0
  274. package/docs/design/templates/list-header/action-dark.svg +1 -0
  275. package/docs/design/templates/list-header/action.svg +1 -0
  276. package/docs/design/templates/list-header/count-dark.svg +1 -0
  277. package/docs/design/templates/list-header/count.svg +1 -0
  278. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  279. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  280. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  281. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  282. package/docs/design/templates/list-header-dark.svg +1 -0
  283. package/docs/design/templates/list-header.svg +1 -0
  284. package/docs/design/templates/list-item/default-dark.svg +1 -0
  285. package/docs/design/templates/list-item/default.svg +1 -0
  286. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  287. package/docs/design/templates/list-item/multiline.svg +1 -0
  288. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  289. package/docs/design/templates/list-item/selected.svg +1 -0
  290. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  291. package/docs/design/templates/list-item/trailing.svg +1 -0
  292. package/docs/design/templates/list-item-dark.svg +1 -0
  293. package/docs/design/templates/list-item.svg +1 -0
  294. package/docs/design/templates/list.svg +1 -0
  295. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  296. package/docs/design/templates/segmented-control/equal.svg +1 -0
  297. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  298. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  299. package/docs/design/templates/segmented-control-dark.svg +1 -0
  300. package/docs/design/templates/segmented-control.svg +1 -0
  301. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  302. package/docs/design/templates/skeleton/avatar.svg +1 -0
  303. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  304. package/docs/design/templates/skeleton/block.svg +1 -0
  305. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  306. package/docs/design/templates/skeleton/lines.svg +1 -0
  307. package/docs/design/templates/skeleton-dark.svg +1 -0
  308. package/docs/design/templates/skeleton.svg +1 -0
  309. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  310. package/docs/design/templates/state-banner/danger.svg +1 -0
  311. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  312. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  313. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  314. package/docs/design/templates/state-banner/info.svg +1 -0
  315. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  316. package/docs/design/templates/state-banner/success.svg +1 -0
  317. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  318. package/docs/design/templates/state-banner/warning.svg +1 -0
  319. package/docs/design/templates/state-banner-dark.svg +1 -0
  320. package/docs/design/templates/state-banner.svg +1 -0
  321. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  322. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  323. package/docs/design/templates/tab-bar-dark.svg +1 -0
  324. package/docs/design/templates/tab-bar.svg +1 -0
  325. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  326. package/docs/design/templates/token-search-field/empty.svg +1 -0
  327. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  328. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  329. package/docs/design/templates/token-search-field-dark.svg +1 -0
  330. package/docs/design/templates/token-search-field.svg +1 -0
  331. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  332. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  333. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  334. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  335. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  336. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  337. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  338. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  339. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  340. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  341. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  342. package/docs/design/templates/toolbar-control-group.svg +1 -0
  343. package/docs/design/templates/toolbar-dark.svg +1 -0
  344. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  345. package/docs/design/templates/toolbar-text/default.svg +1 -0
  346. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  347. package/docs/design/templates/toolbar-text/large.svg +1 -0
  348. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  349. package/docs/design/templates/toolbar-text/small.svg +1 -0
  350. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  351. package/docs/design/templates/toolbar-text.svg +1 -0
  352. package/docs/design/templates/toolbar.svg +1 -0
  353. package/docs/design/templates/value-table/details-dark.svg +1 -0
  354. package/docs/design/templates/value-table/details.svg +1 -0
  355. package/docs/design/templates/value-table-dark.svg +1 -0
  356. package/docs/design/templates/value-table.svg +1 -0
  357. package/docs/design/templates.md +128 -0
  358. package/docs/design-philosophy.md +33 -11
  359. package/docs/device-class.md +54 -0
  360. package/docs/examples/application-ui-profile.json +60 -0
  361. package/docs/examples/command-palette-adapter.tsx +67 -17
  362. package/docs/examples/component-catalog-extension-v2.json +80 -0
  363. package/docs/examples/component-catalog-extension.json +45 -0
  364. package/docs/layout.md +98 -37
  365. package/docs/nav-stack.md +77 -0
  366. package/docs/recipes.md +75 -19
  367. package/docs/split-view.md +55 -0
  368. package/docs/sunken-panel.md +53 -0
  369. package/docs/surface-scaffold.md +25 -0
  370. package/docs/tab-scaffold.md +52 -0
  371. package/docs/type-contracts.md +127 -0
  372. package/docs/ui-analyzer.md +118 -0
  373. package/docs/ui-doctor.md +91 -0
  374. package/docs/ui-evaluator.md +122 -0
  375. package/docs/ux-demo.md +24 -13
  376. package/docs/webawesome-theme.md +82 -8
  377. package/docs/workbench.md +123 -0
  378. package/doctor/cli.mjs +115 -0
  379. package/doctor/config.schema.json +68 -0
  380. package/doctor/eslint-diagnostics.d.mts +24 -0
  381. package/doctor/eslint-diagnostics.mjs +24 -0
  382. package/doctor/index.d.mts +116 -0
  383. package/doctor/index.mjs +1272 -0
  384. package/doctor/report.schema.json +118 -0
  385. package/evaluator/cli.mjs +89 -0
  386. package/evaluator/index.d.mts +90 -0
  387. package/evaluator/index.mjs +1138 -0
  388. package/evaluator/report.schema.json +152 -0
  389. package/llms.txt +253 -43
  390. package/package.json +180 -37
  391. package/traversal-exclusions.mjs +27 -0
  392. package/ux-demo/recipes/app-shell.tsx +222 -13
  393. package/ux-demo/recipes/collapsible-sidebar.tsx +229 -0
  394. package/ux-demo/recipes/compact-toolbar.tsx +115 -12
  395. package/ux-demo/recipes/composer-form.tsx +119 -18
  396. package/ux-demo/recipes/list-detail-dialog.tsx +197 -0
  397. package/ux-demo/recipes/list-workspace-states.tsx +175 -9
  398. package/ux-demo/recipes/loaders.ts +13 -4
  399. package/ux-demo/recipes/loading-inspector.tsx +186 -0
  400. package/ux-demo/recipes/mount-recipe.ts +31 -5
  401. package/ux-demo/recipes/navigation-sidebar.tsx +122 -11
  402. package/ux-demo/recipes/navigation-stack.tsx +118 -0
  403. package/ux-demo/recipes/recipes.css +143 -18
  404. package/ux-demo/recipes/types.ts +9 -1
  405. package/ux-demo/recipes/workspace-header.tsx +68 -3
  406. package/dist/browser/dialog-header.js +0 -5
  407. package/dist/browser/menu-action-row.js +0 -3
  408. package/dist/browser/menu-item.js +0 -3
  409. package/dist/browser/page-header.js +0 -3
  410. package/dist/chunk-2PES33HS.js +0 -13
  411. package/dist/chunk-2PES33HS.js.map +0 -1
  412. package/dist/chunk-55DATV3A.js +0 -10
  413. package/dist/chunk-55DATV3A.js.map +0 -1
  414. package/dist/chunk-7BR3DO2A.js.map +0 -1
  415. package/dist/chunk-7LDCTU7D.js +0 -134
  416. package/dist/chunk-7LDCTU7D.js.map +0 -1
  417. package/dist/chunk-AQNKJRFH.js +0 -79
  418. package/dist/chunk-AQNKJRFH.js.map +0 -1
  419. package/dist/chunk-CTQKI2XL.js +0 -28
  420. package/dist/chunk-CTQKI2XL.js.map +0 -1
  421. package/dist/chunk-DAFFDO33.js +0 -14
  422. package/dist/chunk-DAFFDO33.js.map +0 -1
  423. package/dist/chunk-EGHL5S4P.js +0 -33
  424. package/dist/chunk-EGHL5S4P.js.map +0 -1
  425. package/dist/chunk-GY5WH7TO.js +0 -10
  426. package/dist/chunk-GY5WH7TO.js.map +0 -1
  427. package/dist/chunk-H5AGGVU5.js +0 -75
  428. package/dist/chunk-H5AGGVU5.js.map +0 -1
  429. package/dist/chunk-K3G72I6D.js +0 -24
  430. package/dist/chunk-K3G72I6D.js.map +0 -1
  431. package/dist/chunk-M5JRI6MN.js +0 -27
  432. package/dist/chunk-M5JRI6MN.js.map +0 -1
  433. package/dist/chunk-MBR3TYNL.js +0 -14
  434. package/dist/chunk-MBR3TYNL.js.map +0 -1
  435. package/dist/chunk-MFKMHK5W.js +0 -10
  436. package/dist/chunk-MFKMHK5W.js.map +0 -1
  437. package/dist/chunk-MQIZAD4A.js.map +0 -1
  438. package/dist/chunk-NPPD2A6O.js +0 -40
  439. package/dist/chunk-NPPD2A6O.js.map +0 -1
  440. package/dist/chunk-R6JHHBKQ.js +0 -19
  441. package/dist/chunk-R6JHHBKQ.js.map +0 -1
  442. package/dist/chunk-S3TPM2LP.js +0 -23
  443. package/dist/chunk-S3TPM2LP.js.map +0 -1
  444. package/dist/chunk-TRNBHPNW.js.map +0 -1
  445. package/dist/chunk-VHW5YNIB.js +0 -17
  446. package/dist/chunk-VHW5YNIB.js.map +0 -1
  447. package/dist/chunk-WVPYVDXY.js +0 -15
  448. package/dist/chunk-WVPYVDXY.js.map +0 -1
  449. package/dist/chunk-XZXRLY5Q.js +0 -33
  450. package/dist/chunk-XZXRLY5Q.js.map +0 -1
  451. package/dist/dialog-header.d.ts +0 -15
  452. package/dist/dialog-header.js +0 -5
  453. package/dist/dialog-header.js.map +0 -1
  454. package/dist/menu-action-row.js +0 -4
  455. package/dist/menu-action-row.js.map +0 -1
  456. package/dist/menu-header.d.ts +0 -41
  457. package/dist/menu-header.js +0 -6
  458. package/dist/menu-header.js.map +0 -1
  459. package/dist/menu-item.d.ts +0 -31
  460. package/dist/menu-item.js +0 -4
  461. package/dist/menu-item.js.map +0 -1
  462. package/dist/page-header.d.ts +0 -9
  463. package/dist/page-header.js +0 -3
  464. package/dist/page-header.js.map +0 -1
  465. package/dist/styles/dialog-header.css +0 -87
  466. package/dist/styles/menu-action-row.css +0 -154
  467. package/dist/styles/menu-header.css +0 -143
  468. package/dist/styles/menu-item.css +0 -118
  469. package/dist/styles/page-header.css +0 -26
  470. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
package/README.md CHANGED
@@ -4,12 +4,20 @@ Accessible, composable UI primitives for [kerf](https://github.com/brianwestphal
4
4
 
5
5
  Start interface work with the [need-first component selection matrix](./docs/component-selection.md). It distinguishes direct reuse, composition, thin application adapters, and genuinely custom semantics, with imports, required wiring, application ownership, alternatives, and recipes for every public primitive.
6
6
 
7
+ When authoring a component gallery, follow the single
8
+ [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
9
+ for focused-versus-composition modes, helper nesting, specimen selection,
10
+ geometry inspection, and metadata ownership. AI tools can discover that
11
+ contract and its public imports through the shipped
12
+ [`catalog-authoring.json`](./ai/catalog-authoring.json) artifact.
13
+
7
14
  For connective application patterns, use the seven [production composition
8
15
  recipes](./docs/recipes.md). Each has a stable catalog route, runnable state,
9
16
  public-subpath source, semantic layout ownership, and explicit application
10
17
  customization boundaries. The composer recipe demonstrates one coherent form
11
- surface with three transparent content sections; only persistent feedback adds
12
- a nested semantic `StateBanner` surface.
18
+ surface with a `Toolbar`/`ToolbarText` heading and field/action controls aligned to the
19
+ shared 8px gutter; only persistent feedback adds a nested semantic
20
+ `StateBanner` surface.
13
21
 
14
22
  When no primitive matches, keep policy application-owned while reusing the
15
23
  layout vocabulary. The typed
@@ -22,63 +30,85 @@ npm install kerfjs @kerfjs/ui
22
30
  ```
23
31
 
24
32
  ```tsx
25
- import { MenuItem } from '@kerfjs/ui/menu-item';
26
- import { MenuHeader } from '@kerfjs/ui/menu-header';
27
- import { MenuActionRow } from '@kerfjs/ui/menu-action-row';
28
- import { Toolbar } from '@kerfjs/ui/toolbar';
29
- import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
30
- import { ToolbarText } from '@kerfjs/ui/toolbar-text';
31
-
32
- mount(root, () => <>
33
- <Toolbar label="Document" leading={<ToolbarControlGroup appearance="borderless" single><ToolbarText text="Notes" /></ToolbarControlGroup>} />
34
- <section>
35
- <MenuHeader
36
- label="Workspace"
37
- action="show-workspace-actions"
38
- actionLabel="Workspace actions"
39
- rootAttributes={{ 'data-section-id': 'workspace' }}
40
- triggerAttributes={{
41
- popoverTarget: 'workspace-actions',
42
- popoverTargetAction: 'toggle',
43
- 'aria-controls': 'workspace-actions',
44
- 'aria-haspopup': 'dialog',
45
- }}
46
- />
47
- <MenuItem
48
- action="open-notes"
49
- label="Notes"
50
- selected
51
- rootAttributes={{ 'data-command-color': 'blue', 'data-drop-status': 'ready' }}
33
+ import { ListItem } from "@kerfjs/ui/list-item";
34
+ import { ListHeader } from "@kerfjs/ui/list-header";
35
+ import { ListActionRow } from "@kerfjs/ui/list-action-row";
36
+ import { Toolbar } from "@kerfjs/ui/toolbar";
37
+ import { ToolbarControlGroup } from "@kerfjs/ui/toolbar-control-group";
38
+ import { ToolbarText } from "@kerfjs/ui/toolbar-text";
39
+
40
+ mount(root, () => (
41
+ <>
42
+ <Toolbar
43
+ label="Document"
44
+ leading={<ToolbarText text="Notes" />}
52
45
  />
53
- <MenuActionRow
54
- action="open-file"
55
- itemId="src/main.ts"
56
- label="src/main.ts"
57
- trailingAction="open-file-actions"
58
- trailingActionLabel="Actions for src/main.ts"
59
- trailingActionIcon={moreIcon}
60
- />
61
- <div id="workspace-actions" popover="auto">Application-owned actions</div>
62
- </section>
63
- </>);
46
+ <section>
47
+ <ListHeader
48
+ label="Workspace"
49
+ action="show-workspace-actions"
50
+ actionLabel="Workspace actions"
51
+ rootAttributes={{ "data-section-id": "workspace" }}
52
+ triggerAttributes={{
53
+ popoverTarget: "workspace-actions",
54
+ popoverTargetAction: "toggle",
55
+ "aria-controls": "workspace-actions",
56
+ "aria-haspopup": "dialog",
57
+ }}
58
+ />
59
+ <ListItem
60
+ action="open-notes"
61
+ label="Notes"
62
+ selected
63
+ rootAttributes={{
64
+ "data-command-color": "blue",
65
+ "data-drop-status": "ready",
66
+ }}
67
+ />
68
+ <ListActionRow
69
+ action="open-file"
70
+ itemId="src/main.ts"
71
+ label="src/main.ts"
72
+ trailingAction="open-file-actions"
73
+ trailingActionLabel="Actions for src/main.ts"
74
+ trailingActionIcon={moreIcon}
75
+ />
76
+ <div id="workspace-actions" popover="auto">
77
+ Application-owned actions
78
+ </div>
79
+ </section>
80
+ </>
81
+ ));
64
82
  ```
65
83
 
66
84
  Components return Kerf `SafeHtml`. They do not own application state or attach transient listeners. Actions are stable `data-action` hooks; the application wires them once with `delegate()` or `delegateActions()` and retains the disposer.
67
85
 
68
- `MenuItem.rootAttributes`, `MenuHeader.rootAttributes`,
69
- `MenuActionRow.rootAttributes`, and `AppTab.rootAttributes` carry typed
86
+ Component content positions use one convention: `children` is the homogeneous
87
+ primary region, while semantic positions and replacement content use explicit
88
+ named `SafeHtml` props such as `header`, `footer`, `leading`, `trailing`,
89
+ `icon`, and `action`. These named `SafeHtml` prop slots are ordinary typed
90
+ function-component props—not native `<slot>` elements, wrapper slot
91
+ components, or a generic `slots` object. The v2 composition catalog publishes
92
+ sound prop bindings as `zone.jsx.prop`, allowing ESLint to validate statically
93
+ visible content and cardinality without guessing from zone names.
94
+
95
+ `ListItem.rootAttributes`, `ListHeader.rootAttributes`,
96
+ `ListActionRow.rootAttributes`, `AppTab.rootAttributes`,
97
+ `CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` carry typed
70
98
  application `data-*` metadata without
71
- teaching the package domain fields. `MenuHeader.triggerAttributes` and
72
- `MenuActionRow.trailingActionAttributes` additionally support native popover
99
+ teaching the package domain fields. `ListHeader.triggerAttributes` and
100
+ `ListActionRow.trailingActionAttributes` additionally support native popover
73
101
  target and relationship attributes. Roles and component-owned action, selection,
74
- disclosure, naming, disabled, and icon semantics remain protected props; an
102
+ disclosure, naming, disabled, icon, and catalog-structure semantics remain protected props; an
75
103
  isolated `role="menuitem"` is not an extension shortcut.
76
104
  The slots are also filtered at runtime, so structurally widened objects and
77
105
  JavaScript callers cannot bypass those protections with case-variant names.
78
- `MenuItem.trailing` is dormant metadata. Use `MenuActionRow` when a row needs
106
+ `ListItem.trailing` is dormant metadata. Use `ListActionRow` when a row needs
79
107
  sibling primary and trailing native-button actions with independent names,
80
108
  disabled states, focus, and click ownership. Its `label`, `icon`, and
81
109
  `trailingActionIcon` slots are dormant content and must not contain controls.
110
+ In either component's multiline mode, the leading icon remains aligned with
111
+ the first text line as the label wraps below it.
82
112
  For section quantities, pass a non-negative safe-integer `count` together with
83
113
  the localized full spoken phrase in `countLabel`, for example
84
114
  `count={3} countLabel="3 notes"`. This renders the standard neutral count pill
@@ -87,40 +117,79 @@ Do not concatenate a count into `label` or pass a numeric `badge`; the mutually
87
117
  exclusive legacy `badge` slot remains available for non-count `SafeHtml` such
88
118
  as a `New` marker.
89
119
 
120
+ `List.gap` accepts boolean default spacing, a direct spacing name such as
121
+ `gap="xs"` or `gap="m"`, or a branded `CssLength`. Import `space`, `rem`, `em`,
122
+ `px`, `pct`, `lengthVar`, `plus`, and `calc` from the CSS-free
123
+ `@kerfjs/ui/css-values` subpath when a named step is not enough. `plus` returns
124
+ an incomplete expression, so wrap it with `calc` before passing it to a prop.
125
+ Raw CSS strings are deliberately rejected; the opaque brands catch authoring
126
+ mistakes but are not sanitizers.
127
+
128
+ The same property-specific boundary applies beyond spacing: use `flex()` (or a
129
+ finite keyword) for `List.flex`; length builders and intrinsic-size keywords for
130
+ `Skeleton.width`/`height`; length builders for `Skeleton.radius`; and
131
+ `uiColor()` or `colorVar()` for `SelectChoice.color`. These grammars are not
132
+ interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
133
+ `style` declarations; use `className`, public tokens, and component props.
134
+
90
135
  ## Component subpaths
91
136
 
92
- | Component | Browser import (includes reachable CSS) | Manual CSS export |
93
- | --- | --- | --- |
94
- | `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
95
- | `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
96
- | `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
97
- | `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
98
- | `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
99
- | `MenuActionRow` | `@kerfjs/ui/menu-action-row` | `@kerfjs/ui/menu-action-row.css` |
100
- | `MenuItem` | `@kerfjs/ui/menu-item` | `@kerfjs/ui/menu-item.css` |
101
- | `MenuHeader` | `@kerfjs/ui/menu-header` | `@kerfjs/ui/menu-header.css` |
102
- | Pane, content, and navigation composition | — | `@kerfjs/ui/layout.css` |
103
- | `ResizableRegion` | `@kerfjs/ui/resizable-region` | `@kerfjs/ui/resizable-region.css` |
104
- | `wireResizableRegions` | `@kerfjs/ui/wire-resizable-regions` | — |
105
- | `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
106
- | `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
107
- | `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
108
- | `PageHeader` | `@kerfjs/ui/page-header` | `@kerfjs/ui/page-header.css` |
109
- | `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
110
- | `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
111
- | `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
112
- | `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
113
- | `wireTokenSearchFields` | `@kerfjs/ui/wire-token-search-fields` | — |
114
- | `StateBanner` | `@kerfjs/ui/state-banner` | `@kerfjs/ui/state-banner.css` |
115
- | `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
116
- | `DialogHeader` | `@kerfjs/ui/dialog-header` | `@kerfjs/ui/dialog-header.css` |
117
- | `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
118
-
119
- `DialogHeader` puts its 24px icon in a 34px circular background and aligns that
120
- identity group with its automatically grouped action children in a real top
121
- toolbar. Its optional summary stays on a separate row below the title. Pass a
122
- localized `actionsLabel` when the action group needs an accessible name; new
123
- callers pass action children directly rather than pre-wrapping groups.
137
+ | Component | Browser import (includes reachable CSS) | Manual CSS export |
138
+ | ------------------------------------------------------------------- | --------------------------------------- | -------------------------------------- |
139
+ | `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
140
+ | `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
141
+ | `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
142
+ | `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
143
+ | `DialogSurface`, `PopupSurface` | `@kerfjs/ui/surface-scaffold` | `@kerfjs/ui/surface-scaffold.css` |
144
+ | `FloatingToolbar` | `@kerfjs/ui/floating-toolbar` | `@kerfjs/ui/floating-toolbar.css` |
145
+ | `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
146
+ | `List` | `@kerfjs/ui/list` | `@kerfjs/ui/list.css` |
147
+ | Typed CSS dimension builders | `@kerfjs/ui/css-values` | — |
148
+ | `ListActionRow` | `@kerfjs/ui/list-action-row` | `@kerfjs/ui/list-action-row.css` |
149
+ | `ListItem` | `@kerfjs/ui/list-item` | `@kerfjs/ui/list-item.css` |
150
+ | `ListHeader` | `@kerfjs/ui/list-header` | `@kerfjs/ui/list-header.css` |
151
+ | `ListInsetControl` | `@kerfjs/ui/list-inset-control` | `@kerfjs/ui/list-inset-control.css` |
152
+ | `ListInsetText` | `@kerfjs/ui/list-inset-text` | `@kerfjs/ui/list-inset-text.css` |
153
+ | `Pane` | `@kerfjs/ui/pane` | `@kerfjs/ui/pane.css` |
154
+ | `NavStack` | `@kerfjs/ui/nav-stack` | `@kerfjs/ui/nav-stack.css` |
155
+ | `wireNavStack` | `@kerfjs/ui/wire-nav-stack` | — |
156
+ | `SplitView` | `@kerfjs/ui/split-view` | `@kerfjs/ui/split-view.css` |
157
+ | `TabScaffold` | `@kerfjs/ui/tab-scaffold` | `@kerfjs/ui/tab-scaffold.css` |
158
+ | `wireTabScaffold` | `@kerfjs/ui/wire-tab-scaffold` | — |
159
+ | `Workbench` | `@kerfjs/ui/workbench` | `@kerfjs/ui/workbench.css` |
160
+ | `CollapsiblePanel`, `CollapsiblePanelToggle` | `@kerfjs/ui/collapsible-panel` | `@kerfjs/ui/collapsible-panel.css` |
161
+ | `wireSidebar` | `@kerfjs/ui/wire-sidebar` | — |
162
+ | Content and navigation composition | — | `@kerfjs/ui/layout.css` |
163
+ | `ResizableRegion` | `@kerfjs/ui/resizable-region` | `@kerfjs/ui/resizable-region.css` |
164
+ | `wireResizableRegions` | `@kerfjs/ui/wire-resizable-regions` | — |
165
+ | `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
166
+ | `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
167
+ | `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
168
+ | `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
169
+ | `Skeleton` | `@kerfjs/ui/skeleton` | `@kerfjs/ui/skeleton.css` |
170
+ | `SunkenPanel` | `@kerfjs/ui/sunken-panel` | `@kerfjs/ui/sunken-panel.css` |
171
+ | `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
172
+ | `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
173
+ | `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
174
+ | `wireTokenSearchFields` | `@kerfjs/ui/wire-token-search-fields` | — |
175
+ | `StateBanner` | `@kerfjs/ui/state-banner` | `@kerfjs/ui/state-banner.css` |
176
+ | `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
177
+ | `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
178
+
179
+ Opt-in application layouts keep JavaScript and CSS explicit. Import each
180
+ layout from its component subpath, load the matching manual CSS export, and
181
+ add its wire subpath when the layout has interactive behavior. The catalog
182
+ entries for `nav-stack`, `split-view`, `tab-scaffold`, `workbench`, and
183
+ `collapsible-panel` document their selection rules, ownership boundaries,
184
+ public classes, tokens, and focused demos. See
185
+ [`docs/app-layouts.md`](./docs/app-layouts.md) for the layout decision matrix.
186
+
187
+ Compose panel, dialog, and page headings directly with `Toolbar`: put an optional
188
+ icon in a `ToolbarControlGroup`, use a direct extra-large `ToolbarText` for the
189
+ title, and put actions in the trailing zone inside their own control group. Set
190
+ `headingLevel` for page or section headings. Supporting copy is app-owned content
191
+ below the toolbar and should be connected to its host with `aria-describedby`
192
+ when it adds useful context.
124
193
 
125
194
  `DisclosureArrow` defaults to an 18px root-scaled decorative visual. Override
126
195
  `--kui-disclosure-arrow-size` at the narrowest useful scope when a consumer
@@ -131,14 +200,14 @@ scale of `.5` through `--kui-disclosure-icon-scale`. Author replacement
131
200
  transform is applied. Direction changes take the shortest rotation path; a
132
201
  180-degree closed-to-open tie uses counterclockwise rotation.
133
202
 
134
- `MenuHeader` supplies that production `DisclosureArrow` automatically when
203
+ `ListHeader` supplies that production `DisclosureArrow` automatically when
135
204
  `toggle` is true and `actionIcon` is omitted. Keep `expanded` synchronized with
136
205
  real controlled content and preserve the button's stable label; ordinary
137
206
  navigation must not display a disclosure arrow. A custom `actionIcon` remains
138
207
  an escape hatch and replaces the default arrow entirely. The header fills its
139
208
  available inline width, keeping a separate action at the logical end in a 44px
140
209
  target. Its visible action glyph defaults to 18px through
141
- `--kui-menu-header-action-icon-size`.
210
+ `--kui-list-header-action-icon-size`.
142
211
 
143
212
  ## Machine-readable catalog
144
213
 
@@ -149,7 +218,124 @@ delivery and side effects, companion wiring, application-owned policy,
149
218
  variants, accessibility obligations, public CSS hooks, routes, and current
150
219
  documentation/recipe links. The adjacent
151
220
  [`component-catalog.schema.json`](./ai/component-catalog.schema.json) describes
152
- the versioned format.
221
+ the versioned format. Every visual entry also declares who owns its margin,
222
+ border, and padding, so a generator can fit it into Kerf's alignment model
223
+ without guessing from a screenshot or private CSS.
224
+
225
+ Catalog demo authoring is deliberately separate from the entry inventory. Load
226
+ [`catalog-authoring.json`](./ai/catalog-authoring.json) to discover the
227
+ authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract),
228
+ the exact API-signature context, public imports/helpers, and sanctioned metadata
229
+ slot. Keeping this as a companion artifact prevents per-entry selection facts
230
+ from duplicating presentation rules.
231
+
232
+ Tools that evaluate composition may additionally load
233
+ [`component-catalog-v2.json`](./ai/component-catalog-v2.json). It is a
234
+ deterministic, package-qualified projection of every v1 entry with formal
235
+ parent/context, zone/cardinality, child, state ownership, wiring, responsive,
236
+ layout, accessibility, public-boundary, and stable-diagnostic fields. V1
237
+ remains the selection and delivery compatibility surface. V2 defaults are
238
+ deliberately permissive; only documented objective rules receive an
239
+ authoritative override and enforceable diagnostic. The adjacent schema and
240
+ [`component-catalog-v2.d.ts`](./ai/component-catalog-v2.d.ts) types describe
241
+ the same contract.
242
+
243
+ Applications and downstream design systems should publish the same facts for
244
+ their own components. Start from the reusable
245
+ [`component-catalog-extension.schema.json`](./ai/component-catalog-extension.schema.json)
246
+ and the checked
247
+ [`component-catalog-extension.json`](./docs/examples/component-catalog-extension.json)
248
+ example. Give each app-owned component or composition a stable id, selection
249
+ guidance, public hooks, and explicit geometry ownership; then concatenate its
250
+ `entries` with Kerf's shipped `entries` in the AI context. Keep package/source
251
+ identity alongside each input when ids could collide. This makes a combined
252
+ tool reason about both sides of a composition using one vocabulary without
253
+ pretending app-local components are `@kerfjs/ui` exports.
254
+
255
+ Composition-aware consumers use
256
+ [`component-catalog-extension-v2.schema.json`](./ai/component-catalog-extension-v2.schema.json),
257
+ its shipped TypeScript types, and the checked
258
+ [`component-catalog-extension-v2.json`](./docs/examples/component-catalog-extension-v2.json)
259
+ example. Preserve each catalog's package and qualify every identity and
260
+ cross-catalog reference as `package:id`; never merge entries by bare id.
261
+
262
+ [`compile-time-contracts-v1.json`](./ai/compile-time-contracts-v1.json) is the
263
+ matching declaration contract: stable `KUI-T###` ids identify the invalid prop,
264
+ state, identity, accessibility, and protected-attribute combinations TypeScript
265
+ rejects. The package gate compiles one positive/negative consumer fixture against
266
+ both source and declarations extracted from the real packed tarball. The
267
+ [compile-time contract guide](./docs/type-contracts.md) documents migrations and
268
+ the dynamic DOM/children relationships that remain runtime or catalog checks.
269
+ Packages scaffolded by `create-kerf-component` maintain this v2 input from
270
+ `kerf.components.json`: `npm run catalog:generate` emits the catalog and
271
+ `npm run catalog:check` verifies source files, named public exports, explicit
272
+ author decisions, and byte-for-byte drift. Tools index the generated consumer
273
+ entries and this catalog by full key, reject duplicate full keys, search the
274
+ consumer package first, and retain package identity across every reference.
275
+ They must not infer missing semantics or geometry from rendered appearance.
276
+
277
+ ### Application UI profile
278
+
279
+ Applications can check in `.kerf-ui-profile.json` so tools do not have to infer
280
+ project-wide UI policy. Start from the shipped
281
+ [`application-ui-profile.defaults.json`](./ai/application-ui-profile.defaults.json)
282
+ and the checked
283
+ [`application-ui-profile.json`](./docs/examples/application-ui-profile.json)
284
+ workspace example. The versioned
285
+ [`application-ui-profile.schema.json`](./ai/application-ui-profile.schema.json)
286
+ and [`application-ui-profile.d.ts`](./ai/application-ui-profile.d.ts) cover
287
+ catalog locations, concept preferences, allowed theme/density choices, semantic
288
+ token overrides, layout/responsive conventions, and narrow rule exceptions.
289
+ Profiles contain policy only—never product records, user data, or broad styling
290
+ waivers.
291
+
292
+ Catalog declarations always provide a v2 `composition` location. Consumer
293
+ packages generated with composition-only metadata omit `selection`;
294
+ `@kerfjs/ui` continues to require its v1 selection catalog.
295
+
296
+ Node-based AI and static-analysis tools may import the shipped discovery API
297
+ from `@kerfjs/ui/ai/application-ui-profile.mjs`. It discovers package defaults,
298
+ then the workspace profile, then directory profiles from parent to child;
299
+ `mergeApplicationUiProfiles()` applies later scalar/map values, replaces a
300
+ catalog by package and an exception by id, and preserves source provenance.
301
+ `loadApplicationUiProfile()` resolves catalogs and returns diagnostics with the
302
+ originating file plus JSON path. Unknown/stale components, tokens, rules, and
303
+ catalog locations are errors. Every layer is checked against its then-effective
304
+ catalogs, including parent references and catalog paths later overridden by a
305
+ child profile. Synchronous integrations can require the shipped
306
+ `application-ui-profile-sync.cjs` projection and call
307
+ `loadApplicationUiProfileSync()` with already-discovered layers. Consumers that define additional stable
308
+ diagnostics pass their ids through the additive `knownRules` option; those ids
309
+ are merged with catalog diagnostics before exception validation.
310
+
311
+ ### Static CSS and layout ownership analysis
312
+
313
+ Run `kerf-ui-analyze --root . src` (or import
314
+ `@kerfjs/ui/analyzer`) to evaluate cross-file integration facts against the
315
+ composition catalogs and application profile. It catches provable private
316
+ selector reach-through, unknown tokens, competing geometry owners, nested
317
+ scroll owners, and cataloged CSS-value violations in JavaScript/TypeScript
318
+ component calls and JSX. It reports forced dimensions, repeated insets,
319
+ exceptional spacing shorthands, and dynamic classes separately as review
320
+ findings. Text, versioned JSON,
321
+ and SARIF outputs carry stable `KUI-L###` ids, repository-relative locations,
322
+ evidence, and ownership chains. See the [analyzer guide](./docs/ui-analyzer.md).
323
+
324
+ ### Browser-backed integration evaluation
325
+
326
+ Run `kerf-ui-evaluate --url <running-app>` (or import
327
+ `@kerfjs/ui/evaluator`) after the static analyzer. Its Playwright-backed
328
+ wide/intermediate/narrow/200%-zoom, light/dark, and reduced-motion matrix checks
329
+ rendered overflow, clipping, reachability, focus/keyboard behavior, accessible
330
+ names, contrast, hit targets, scrolling, alignment, and cataloged runtime
331
+ geometry. The versioned report carries stable `KUI-B###` diagnostics, focused
332
+ DOM/computed-style evidence, hashed screenshot artifacts, explicit timeout and
333
+ retention policy, and a separate unscored human-visual rubric. See the
334
+ [browser evaluator guide](./docs/ui-evaluator.md).
335
+
336
+ ### Unified repair-loop doctor
337
+
338
+ Use `kerf-ui-doctor` for the supported application repair loop across profile/catalog validation, TypeScript, the Kerf UI ESLint preset, static layout analysis, and an optional explicitly authorized browser evaluation. Its isolated Kerf lint pass preserves each file's applicable core-rule and suppression settings without executing consumer plugin rules. It emits one portable versioned JSON report with deterministic exit codes, exact suppressions, monorepo package selection, changed/full modes, caching, and local-path redaction. See the [UI doctor guide](./docs/ui-doctor.md).
153
339
 
154
340
  For code generation, pair catalog selection guidance with the checked-in
155
341
  [`public-api-signatures-v1.md`](./ai/public-api-signatures-v1.md) declaration
@@ -185,9 +371,10 @@ that convenience import, also import `@kerfjs/ui/styles.css`, which deliberately
185
371
  contains the complete layer. Non-browser/SSR tools resolve the pure `import`
186
372
  condition automatically; `@kerfjs/ui/unstyled` is the explicit CSS-free root
187
373
  entry for a browser build with a custom styling pipeline. The exported
188
- `foundation.css` and component CSS paths remain available for fully manual
189
- delivery. Load application overrides after package styles, or scope `--kui-*`
190
- variables directly on a component instance.
374
+ `@kerfjs/ui/foundation.css` and component CSS paths remain available for fully
375
+ manual delivery. Its complete supported `--kui-*` token surface is cataloged
376
+ under the `foundation` entry. Load application overrides after package styles,
377
+ or scope variables directly on a component instance.
191
378
 
192
379
  ## Pane and content geometry
193
380
 
@@ -201,9 +388,9 @@ Add `.kui-content` to make its major children a vertical stack with 24px gaps.
201
388
  <div class="kui-pane__toolbar"><Toolbar label="Workspace" ... /></div>
202
389
  <nav class="kui-pane__content kui-content">
203
390
  <section>
204
- <MenuHeader label="Workspace" count={3} countLabel="3 workspaces" />
205
- <MenuItem action="open" label="Inbox" icon={inboxIcon} />
206
- <MenuItem action="open" label="Drafts" />
391
+ <ListHeader label="Workspace" count={3} countLabel="3 workspaces" />
392
+ <ListItem action="open" label="Inbox" icon={inboxIcon} />
393
+ <ListItem action="open" label="Drafts" />
207
394
  </section>
208
395
  <div class="kui-content-item">Workspace details</div>
209
396
  </nav>
@@ -213,7 +400,7 @@ Add `.kui-content` to make its major children a vertical stack with 24px gaps.
213
400
  Ordinary children use `.kui-content-item`: 8px inline margin, a real 1px border
214
401
  (transparent by default), 8px padding, and 12px rounded corners. The pill
215
402
  modifier uses a 22px radius. A component can expose a transparent border or
216
- background without changing layout. `MenuHeader` follows the same rule while
403
+ background without changing layout. `ListHeader` follows the same rule while
217
404
  keeping its dormant title and count-or-badge cluster separate from its optional
218
405
  44px action.
219
406
 
@@ -233,10 +420,10 @@ Apps using Web Awesome's free components can opt into the same visual universe
233
420
  with one CSS import:
234
421
 
235
422
  ```ts
236
- import type {} from '@kerfjs/ui/webawesome';
237
- import '@kerfjs/ui/webawesome.css';
238
- import '@awesome.me/webawesome/dist/components/button/button.js';
239
- import '@awesome.me/webawesome/dist/components/input/input.js';
423
+ import type {} from "@kerfjs/ui/webawesome";
424
+ import "@kerfjs/ui/webawesome.css";
425
+ import "@awesome.me/webawesome/dist/components/button/button.js";
426
+ import "@awesome.me/webawesome/dist/components/input/input.js";
240
427
  ```
241
428
 
242
429
  The type-only `@kerfjs/ui/webawesome` import adds Kerf JSX intrinsic-element
@@ -247,6 +434,9 @@ Awesome modules the application renders.
247
434
  `webawesome.css` includes Web Awesome's native/base theme and then applies the
248
435
  Hot Sheet 2 palette, surfaces, status colors, focus treatment, form geometry,
249
436
  radii, tooltips, and shadows through Web Awesome's public `--wa-*` contract.
437
+ On `wa-dialog`, the optional `hide-actions` class hides the exported
438
+ `header-actions` shadow part for compositions that provide another dismissal
439
+ affordance.
250
440
  Those tokens flow into all free component families. Every free Web Awesome 3.12
251
441
  component has an individual UX-catalog route under the collapsible ecosystem
252
442
  section, but the theme entry does not import or register component JavaScript,
@@ -262,13 +452,15 @@ classes for explicit appearance boundaries:
262
452
  ```css
263
453
  :root {
264
454
  --wa-color-brand-fill-loud: #7540a8;
265
- --wa-form-control-border-radius: .5rem;
455
+ --wa-form-control-border-radius: 0.5rem;
266
456
  }
267
457
  ```
268
458
 
269
459
  `foundation.css` follows Hot Sheet 2's Web Awesome-compatible semantic palette.
270
- Brand, neutral, success, warning, and danger each expose fill, border, and
271
- foreground roles through `--kui-color-*`; stateful components also expose
460
+ Brand, pop, neutral, success, warning, and danger each expose fill, border, and
461
+ foreground roles through `--kui-color-*`. Pop is attractive, non-status emphasis
462
+ for featured, novel, or celebratory content; it never substitutes for success,
463
+ warning, or danger. Stateful components also expose
272
464
  component variables such as `--kui-state-banner-background`. Override the
273
465
  foundation for an application theme, a tone variable for one semantic state, or
274
466
  a component variable on one instance without replacing component selectors.
@@ -277,8 +469,8 @@ needs a selector, the component catalog's `publicClasses` arrays define the
277
469
  exact stable anatomy: public-class-to-public-class selectors are supported;
278
470
  descendant tag, id, attribute-only, and unlisted-class selectors are not.
279
471
 
280
- `StateBanner` has opinionated `neutral`, `info`, `success`, `warning`, and
281
- `danger` palettes. Override an individual banner with
472
+ `StateBanner` has opinionated `neutral`, `info`, `pop`, `success`, `warning`,
473
+ and `danger` palettes. Override an individual banner with
282
474
  `--kui-state-banner-background`, `--kui-state-banner-border`,
283
475
  `--kui-state-banner-foreground`, `--kui-state-banner-detail`,
284
476
  `--kui-state-banner-action-background`, and
@@ -302,8 +494,8 @@ standalone `filled`/`outlined` appearance with `shape="rounded"` or
302
494
  appearance="toolbar"
303
495
  shape="pill"
304
496
  choices={[
305
- { value: 'list', label: 'List' },
306
- { value: 'columns', label: 'Columns' },
497
+ { value: "list", label: "List" },
498
+ { value: "columns", label: "Columns" },
307
499
  ]}
308
500
  />
309
501
  ```
@@ -323,8 +515,14 @@ after browser input to recover text plus token offsets, and
323
515
  Call `wireTokenSearchFields()` once at a stable root to make Enter submit through
324
516
  `onSubmit` without inserting a contenteditable line break and to preserve focus
325
517
  plus the text-relative caret when keyboard deletion of a chip causes controlled
326
- rendering to replace the editor. Text still wraps visually when it reaches the
327
- field edge.
518
+ rendering to replace the editor. A select-all deletion is normalized to a truly
519
+ empty editor even when the browser leaves an atomic chip or line break behind;
520
+ replacement typing consumes that intent so a later Backspace/Delete remains an
521
+ ordinary character edit.
522
+ Managed deletion keeps a collapsible replacement editor open and focused before
523
+ the next keystroke; applications must persist both query and tokens from the DOM
524
+ read. Genuine outside focus and Escape still collapse an empty field.
525
+ Text still wraps visually when it reaches the field edge.
328
526
  Clear actions should empty the editor's `textContent` before clearing app state.
329
527
  The leading icon, first text line, clear action, and trailing slot share one
330
528
  fixed alignment row; when text wraps, those controls stay pinned to that first
@@ -356,15 +554,25 @@ close button retains all close interaction.
356
554
  `Select` uses Web Awesome but does not register anything by itself. Install the optional peer, import the shared theme if desired, and explicitly import the registration entry in the application:
357
555
 
358
556
  ```ts
359
- import '@kerfjs/ui/webawesome.css';
360
- import '@kerfjs/ui/select/register';
557
+ import "@kerfjs/ui/webawesome.css";
558
+ import "@kerfjs/ui/select/register";
361
559
  ```
362
560
 
363
561
  That boundary keeps Web Awesome and its custom-element side effects out of bundles that use unrelated components. Automated consumer-bundle tests enforce it.
562
+ Use `label` for a visible label or `ariaLabel` for a visually hidden name. A
563
+ nonempty visible label takes precedence when both are supplied. Kerf names the
564
+ actual shadow combobox without adding visible label spacing; this also works
565
+ with `renderSelected`, and needs no application shadow-DOM patch. Use `hint`
566
+ for persistent supporting text below the control and `placeholderText` for the
567
+ empty value inside the closed control. Loading placeholders preserve the hint.
568
+
364
569
  `Select` also owns the Kerf/Web Awesome reconciliation boundary: option icons
365
570
  keep stable slotted elements across rerenders, and `renderSelected` content is
366
571
  replaced when the controlled value changes. Consumers do not need to add
367
- `data-key` or `data-morph-skip` workarounds around choice icons.
572
+ `data-key` or `data-morph-skip` workarounds around choice icons. Icon-bearing
573
+ options retain the standard icon-to-label gap. When a compact Select is wrapped
574
+ in a `ToolbarControlGroup`, use `focusRingOwner="group"`; the group paints the
575
+ focus ring with its configured pill or rounded geometry.
368
576
 
369
577
  For application choices and panes, prefer Kerf's purpose-built primitives:
370
578
  `Select` over direct Web Awesome selection/dropdown composition,
@@ -373,7 +581,11 @@ Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over
373
581
  Split Panel. `ResizableRegion` includes Hot Sheet 2's 1px separator and
374
582
  hover/focus grip. Its optional `handleIcon` replaces only the decorative glyph;
375
583
  the component and `wireResizableRegions()` retain separator semantics and
376
- pointer/keyboard behavior. Consider Web Awesome Popup when its anchored-positioning
584
+ pointer/keyboard behavior. Typed policies cover separator visibility,
585
+ instant-track/composited-content collapse, popup-safe overflow,
586
+ inline/overlay/hidden responsive presentation, and safe-area restore controls;
587
+ the same policies are available on `Workbench` and `CollapsiblePanel`. Consider
588
+ Web Awesome Popup when its anchored-positioning
377
589
  engine removes custom placement code; treat Tree, Animated Image, Comparison,
378
590
  Zoomable Frame, and the displaced alternatives above as exceptional rather
379
591
  than default patterns. The detailed rationale lives in the theme contract.
@@ -392,8 +604,9 @@ than default patterns. The detailed rationale lives in the theme contract.
392
604
 
393
605
  Run `npm run dev` from this directory for the category-grouped master/detail catalog. Every public visual component has a focused route; all 70 free Web Awesome 3.12 components have focused routes under the collapsible ecosystem section. Every detail visibly links its first-party demo source and existing guidance while showing the repository-relative paths; first-party components also link their implementation source, and Web Awesome entries label local guidance as Kerf integration guidance. One grouped `Related components` selector contains derived `Uses` / `Used by` navigation across both sets. Run `npm run check` for static/unit/bundle gates and `npm run test:e2e` for the real-browser suite.
394
606
 
395
- Run `npm run format:css` after editing styles. The normal `npm run check` gate
396
- uses Prettier to reject unformatted CSS in `src/` and `ux-demo/`.
607
+ Run `npm run format` after editing source or structured content. The narrower
608
+ `npm run format:css` command remains available for style-only work. The normal
609
+ `npm run lint` and `npm run check` gates use Prettier to reject formatting drift.
397
610
 
398
611
  For dimensions that should scale with the root font size, author pixels with
399
612
  `remify()`: `gap: remify(17px)` builds to `gap: 1.0625rem` using a fixed 16px