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

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
@@ -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,11 +182,14 @@ 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.
190
+ Both row components align a leading icon with the first label line when
191
+ `multiline` allows the label to wrap; additional lines extend below that fixed
192
+ visual anchor.
54
193
 
55
194
  ### Public CSS anatomy
56
195
 
@@ -62,12 +201,25 @@ layout cannot be expressed by a prop or token. A class being public does not
62
201
  make copied component markup an invocation or transfer state and accessibility
63
202
  ownership to the application.
64
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
+
65
209
  Do not select a component's descendant by element name, id, attribute alone, or
66
210
  an unlisted implementation class. Selectors such as `.kui-state-banner span`,
67
- `.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
68
212
  private structure. If no prop, token, or cataloged class expresses a recurring
69
213
  need, request a supported hook instead of inferring one from rendered markup.
70
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
+
71
223
  `DisclosureArrow` uses an 18px root-scaled visual by default. Override
72
224
  `--kui-disclosure-arrow-size` on the component or its containing scope when a
73
225
  consumer needs another size. Kerf `Select` uses a separate Web Awesome expand
@@ -75,17 +227,19 @@ glyph contract, `--kui-disclosure-icon-scale: .5`; changing one contract does
75
227
  not implicitly change the other. Direction changes take the shortest rotation
76
228
  path; a 180-degree closed-to-open tie uses counterclockwise rotation.
77
229
 
78
- In `MenuHeader` toggle mode, omitting `actionIcon` composes the production
230
+ In `ListHeader` toggle mode, omitting `actionIcon` composes the production
79
231
  `DisclosureArrow` and derives its visual direction from `expanded`. The app
80
232
  must update that controlled state and reveal or hide real content. Passing a
81
233
  custom `actionIcon` replaces the default rather than layering or rotating both.
82
234
  The root fills the available inline width after its standard margins. A
83
235
  separate action stays at the logical end in its 44px target while the visible
84
- glyph defaults to 18px through `--kui-menu-header-action-icon-size`.
236
+ glyph defaults to 18px through `--kui-list-header-action-icon-size`.
85
237
 
86
238
  `StateBanner` exposes instance-level `--kui-state-banner-background`,
87
239
  `--kui-state-banner-border`, `--kui-state-banner-foreground`,
88
- `--kui-state-banner-detail`, and action background variables. Its five built-in
240
+ `--kui-state-banner-detail`, `--kui-state-banner-badge-background`,
241
+ `--kui-state-banner-badge-foreground`, and action background variables. Its optional
242
+ badge is a compact pill beside the title and follows the banner tone by default. Its five built-in
89
243
  tones can be rethemed globally with
90
244
  `--kui-state-banner-{tone}-{background|border|foreground}`. Toolbar control,
91
245
  segmented-control, app-tab, and tab-bar colors likewise use their public
@@ -93,6 +247,13 @@ segmented-control, app-tab, and tab-bar colors likewise use their public
93
247
  hover, and selected-state variables, so rounded, pill, and toolbar presentations
94
248
  remain opinionated but locally overridable.
95
249
 
250
+ Inset hover and selection surfaces follow the outer control shape instead of
251
+ choosing an independent radius. `--kui-layout-highlight-inset` is the full
252
+ distance between those edges; the inner radius is the outer radius minus that
253
+ inset. `ToolbarControlGroup` publishes its derived radius to nested toolbar
254
+ `SegmentedControl` choices, keeping both direct buttons and exclusive-choice
255
+ highlights concentric when the group switches between pill and rounded shapes.
256
+
96
257
  `ResizableRegion` owns the Hot Sheet 2 split treatment: a persistent 1px
97
258
  separator with a compact grip that appears on hover or keyboard focus. Override
98
259
  `--kui-resizable-region-separator-color`,
@@ -100,9 +261,31 @@ separator with a compact grip that appears on hover or keyboard focus. Override
100
261
  `--kui-resizable-region-handle-active-color` on a region when its containing
101
262
  surface needs a different contrast level.
102
263
 
103
- `@kerfjs/ui/layout.css` defines one structural model for sidebars, main areas,
104
- inspectors, and dialogs. `.kui-pane` is unpadded and contains an optional
105
- toolbar, one scrolling `.kui-pane__content`, and an optional footer.
264
+ `Pane` defines one structural model for sidebars, main areas, inspectors, and
265
+ dialogs. Its `.kui-pane` root is unpadded and contains an optional vertical
266
+ header, one scrolling vertical `.kui-pane__content`, and an optional footer.
267
+ Logical-edge separator lines are independently opt-in and default off.
268
+ `@kerfjs/ui/layout.css` retains the pane roles and supplies the related content
269
+ geometry classes.
270
+ `List` is the corresponding layout-only vertical stack: its children stretch by
271
+ default, while `gap`, `flex`, and `scrollable` opt into typed spacing,
272
+ flex growth, and vertical scroll ownership. `dividerSides` accepts canonical
273
+ physical top/right/bottom/left combinations such as `tr` and `trbl`; the stack
274
+ adds no list semantics, margin, or padding of its own. Use a direct finite
275
+ spacing shorthand such as `gap="2xs"`, or pass a `CssLength` created by the
276
+ CSS-free `@kerfjs/ui/css-values` helpers: `space('m')`, `rem(0.25)`,
277
+ `lengthVar('--app-gap')`, or `calc(plus(rem(0.25), pct(10)))`. `plus` returns a
278
+ non-standalone `CssLengthExpression`; only `calc` turns it into a complete
279
+ length. Raw CSS strings and source-only `remify(4px)` are not valid runtime
280
+ props. The `CssLength` name intentionally includes percentages for UI dimension
281
+ props. Its opaque string brand improves authoring correctness; it is not a CSS
282
+ sanitizer or security boundary.
283
+ `List.flex` likewise accepts its boolean default, finite keywords, or `CssFlex`
284
+ from `flex(grow, shrink, basis)`. `Skeleton` width/height use `CssSize`, radius
285
+ uses `CssLength`, and `SelectChoice.color` uses `CssColor` from `uiColor()` or
286
+ `colorVar()`. Never exchange these property grammars. List rows expose
287
+ `className`, public tokens, and semantic props instead of unrestricted `style`
288
+ declarations.
106
289
  `.kui-content` gives major children 24px vertical separation.
107
290
  `.kui-content-item` gives one child 8px inline margin, a real 1px border,
108
291
  8px padding, and 12px corners; border and background may be transparent without
@@ -110,7 +293,17 @@ changing geometry. `.kui-content-item--pill` selects the 22px radius.
110
293
 
111
294
  `ToolbarControlGroup` is the unit of toolbar organization, even for dormant
112
295
  text. Each group reserves `calc(2px + remify(42px))`, or 44px, with 8px between
113
- groups and inside items. `MenuHeader` similarly separates its dormant title and
296
+ groups and inside items. For an ordinary icon/action control inside a group, use
297
+ a plain `<button>` — the group styles `> button` fully, and it keeps the group
298
+ free of a Web Awesome dependency and shadow DOM. Reach for `wa-button` only when
299
+ you need a Web Awesome feature, chiefly the `slot="trigger"` button of a
300
+ `wa-dropdown` popup menu. For a compact mixed-content group, set
301
+ `nestedDropdown`; a text-and-caret trigger grows to its intrinsic width while an
302
+ icon-only trigger can remain square, keeping the separator and caret inside the
303
+ group. The short text trigger has an engine-stable 66px floor because WebKit
304
+ does not include the shadow caret in the custom-element host's intrinsic width;
305
+ raise `--kui-toolbar-dropdown-trigger-width` for longer localized copy.
306
+ `ListHeader` similarly separates its dormant title and
114
307
  optional count or badge from its optional 44px action. Use the mutually
115
308
  exclusive `count`/`countLabel` pair for non-negative safe-integer section
116
309
  quantities; reserve `badge` for non-count `SafeHtml`. Do not concatenate counts
@@ -118,14 +311,11 @@ into the section label. Do not add padding to pane shells,
118
311
  double child-owned geometry with wrapper insets, or create competing scroll
119
312
  owners. The [layout contract](./layout.md) lists the public roles and tokens.
120
313
 
121
- `DialogHeader` composes its icon and first title line inside a borderless
122
- `ToolbarControlGroup` in a real top `Toolbar`. Direct `actions` children are
123
- automatically placed in one contained `ToolbarControlGroup`; use the optional
124
- localized `actionsLabel` when that group needs an accessible name. Existing
125
- pre-grouped action content remains layout-compatible, but new callers should
126
- pass the action children rather than groups. The optional summary is a separate
127
- row aligned below the title, so it cannot pull the 24px icon or 34px circular
128
- icon background out of vertical alignment with the 44px action row.
314
+ Panel, dialog, and page headings are direct `Toolbar` compositions. The leading
315
+ zone holds an optional icon `ToolbarControlGroup` and a direct extra-large
316
+ `ToolbarText`; app actions belong in a trailing `ToolbarControlGroup`. Omit the
317
+ icon group when it has no content. Supporting copy is app-owned content below
318
+ the toolbar so it cannot pull the icon or actions out of alignment.
129
319
 
130
320
  `ValueTable` composes typed `ValueTableRow` entries. A row owns its `dt`/`dd`
131
321
  semantics and may receive a leading `SafeHtml` icon. Every row keeps 8px of
@@ -150,10 +340,47 @@ overrides load later in the cascade or set scoped `--kui-*` variables. JavaScrip
150
340
  modules are pure except the browser style wrappers and `@kerfjs/ui/select/register`,
151
341
  which registers exactly the Web Awesome elements used by `Select`. Eventful
152
342
  helpers such as `wireResizableRegions` and `wireTabBars` attach listeners only
153
- when called and return disposers. CSS, the generated wrappers that make it
343
+ when called and return disposers. `wireTokenSearchFields` goes one step further:
344
+ by default it also owns the collapsible field's transient expand/collapse/focus
345
+ (activate to reveal and focus, Escape or empty blur to collapse), holding that
346
+ state in a signal it exposes on the returned handle. An app reads that signal in
347
+ render, hands in its own via `collapsible.signals`, drives it through
348
+ `handle.open`/`handle.close`, or disables any individual behavior — so transient
349
+ UI is consistent by default without every app reinventing it.
350
+
351
+ `wireTokenSearchFields` is a deliberate exception, not the rule for `wire…`
352
+ helpers. Its collapse behavior was _rich and error-prone_ — reveal, focus
353
+ transfer, Escape, empty-blur collapse, focus return — the kind of transient chrome
354
+ apps kept reimplementing inconsistently, so the helper owns it. Everywhere else the
355
+ app's state is **domain or persisted, not transient chrome, and stays app-owned**: a
356
+ `NavStack`'s view stack is navigation history, a `TabBar`/`TabScaffold`'s selection
357
+ and tab order are data, a `ResizableRegion`'s committed size and a
358
+ `Workbench`/`SplitView` rail's `collapsed` flag are persisted layout preferences.
359
+ Each helper already owns only the _ephemeral mechanics_ around that state —
360
+ `wireNavStack` the push/pop animation, `wireTabBars` the overflow autoscroll and
361
+ drag preview, `wireResizableRegions` the live drag preview — and reports committed
362
+ changes through callbacks. A `ListHeader` `toggle` disclosure's `expanded` is
363
+ likewise app-owned: it is a one-line boolean the app already tracks and must read to
364
+ render the section body, so a managed helper would remove no real complexity. Reach
365
+ for a managed default only when the transient behavior is substantial enough that
366
+ hand-rolling it produces genuine, inconsistent variation.
367
+
368
+ CSS, the generated wrappers that make it
154
369
  reachable, and the registration module are the package's only declared side
155
370
  effects.
156
371
 
372
+ A value-bearing component's `placeholder` prop is a first-class loading mode: the
373
+ component renders its own real chrome (labels, icon and action affordances,
374
+ container geometry) while replacing each **value** slot with a subtle, deliberately
375
+ unanimated `Skeleton` block and disabling its own interactive controls
376
+ (`aria-busy`, dropped `data-action`, disabled buttons). Sizes and shapes stay
377
+ identical to the populated component, so a parent composes a faithful loading view —
378
+ an inspector, a detail pane — from placeholder children without hand-rebuilding
379
+ markup. The application still owns the loading lifecycle (when to pass `placeholder`)
380
+ and which slots are unknown; the standalone `Skeleton` covers custom slots. It is a
381
+ placeholder, not progress: use `LoadingSpinner` for known busy activity, and never
382
+ animate the skeleton.
383
+
157
384
  Package source styles express root-scaled geometry with `remify(<px>)`; the
158
385
  build converts it against the 16px authoring baseline and exposes only ordinary
159
386
  `rem` CSS. Literal pixels remain for intentional hairlines, and `em` remains