@kerfjs/ui 5.0.0-beta.7 → 5.0.0-beta.71

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 (723) hide show
  1. package/README.md +501 -139
  2. package/ai/application-ui-diagnostic-ids-v1.json +109 -0
  3. package/ai/application-ui-profile-sync.cjs +548 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +106 -0
  6. package/ai/application-ui-profile.defaults.json +96 -0
  7. package/ai/application-ui-profile.mjs +653 -0
  8. package/ai/application-ui-profile.schema.json +140 -0
  9. package/ai/catalog-authoring.json +36 -0
  10. package/ai/catalog-authoring.schema.json +109 -0
  11. package/ai/compile-time-contracts-v1.json +149 -0
  12. package/ai/compile-time-contracts-v1.schema.json +52 -0
  13. package/ai/component-catalog-extension.schema.json +104 -0
  14. package/ai/component-catalog.json +3905 -446
  15. package/ai/component-catalog.schema.json +94 -1
  16. package/ai/component-class-owners.cjs +83 -0
  17. package/ai/component-composition-extension.d.ts +7 -0
  18. package/ai/component-composition-extension.schema.json +7 -0
  19. package/ai/component-composition-rules.json +524 -0
  20. package/ai/component-composition.d.ts +129 -0
  21. package/ai/component-composition.json +7140 -0
  22. package/ai/component-composition.schema.json +408 -0
  23. package/ai/components/README.md +171 -0
  24. package/ai/components/application-tabs.md +65 -0
  25. package/ai/components/badge.md +72 -0
  26. package/ai/components/chip.md +72 -0
  27. package/ai/components/collapsible-panel.md +102 -0
  28. package/ai/components/content-item.md +93 -0
  29. package/ai/components/disclosure-arrow.md +77 -0
  30. package/ai/components/document-baseline.md +75 -0
  31. package/ai/components/empty-state.md +80 -0
  32. package/ai/components/feedback.md +71 -0
  33. package/ai/components/floating-toolbar.md +82 -0
  34. package/ai/components/foundation.md +65 -0
  35. package/ai/components/grid.md +98 -0
  36. package/ai/components/headers.md +63 -0
  37. package/ai/components/layout.md +75 -0
  38. package/ai/components/list-action-row.md +91 -0
  39. package/ai/components/list-header.md +89 -0
  40. package/ai/components/list-inset-control.md +74 -0
  41. package/ai/components/list-inset-text.md +72 -0
  42. package/ai/components/list-item.md +94 -0
  43. package/ai/components/list.md +105 -0
  44. package/ai/components/loading-spinner.md +73 -0
  45. package/ai/components/lucide-icon.md +78 -0
  46. package/ai/components/nav-stack.md +104 -0
  47. package/ai/components/pane.md +101 -0
  48. package/ai/components/popup-menu.md +171 -0
  49. package/ai/components/recipe-app-shell.md +57 -0
  50. package/ai/components/recipe-collapsible-sidebar.md +57 -0
  51. package/ai/components/recipe-compact-toolbar.md +57 -0
  52. package/ai/components/recipe-composer-form.md +57 -0
  53. package/ai/components/recipe-list-detail-dialog.md +57 -0
  54. package/ai/components/recipe-list-workspace-states.md +57 -0
  55. package/ai/components/recipe-loading-inspector.md +57 -0
  56. package/ai/components/recipe-navigation-sidebar.md +57 -0
  57. package/ai/components/recipe-navigation-stack.md +57 -0
  58. package/ai/components/recipe-workspace-header.md +57 -0
  59. package/ai/components/resize.md +106 -0
  60. package/ai/components/row.md +96 -0
  61. package/ai/components/segmented-control.md +82 -0
  62. package/ai/components/select.md +113 -0
  63. package/ai/components/skeleton.md +84 -0
  64. package/ai/components/spacer.md +86 -0
  65. package/ai/components/split-view.md +102 -0
  66. package/ai/components/state-banner.md +94 -0
  67. package/ai/components/sunken-panel.md +79 -0
  68. package/ai/components/surface-scaffold.md +78 -0
  69. package/ai/components/tab-bar.md +113 -0
  70. package/ai/components/tab-scaffold.md +94 -0
  71. package/ai/components/tabs.md +95 -0
  72. package/ai/components/text.md +85 -0
  73. package/ai/components/token-search-field.md +106 -0
  74. package/ai/components/toolbar-control-group.md +102 -0
  75. package/ai/components/toolbar-text.md +79 -0
  76. package/ai/components/toolbar.md +97 -0
  77. package/ai/components/value-table.md +73 -0
  78. package/ai/components/wa-accordion-item.md +55 -0
  79. package/ai/components/wa-accordion.md +65 -0
  80. package/ai/components/wa-animated-image.md +55 -0
  81. package/ai/components/wa-animation.md +55 -0
  82. package/ai/components/wa-avatar.md +55 -0
  83. package/ai/components/wa-badge.md +55 -0
  84. package/ai/components/wa-breadcrumb-item.md +53 -0
  85. package/ai/components/wa-breadcrumb.md +55 -0
  86. package/ai/components/wa-button-group.md +59 -0
  87. package/ai/components/wa-button.md +55 -0
  88. package/ai/components/wa-callout.md +58 -0
  89. package/ai/components/wa-card.md +59 -0
  90. package/ai/components/wa-carousel-item.md +53 -0
  91. package/ai/components/wa-carousel.md +55 -0
  92. package/ai/components/wa-checkbox-group.md +55 -0
  93. package/ai/components/wa-checkbox.md +55 -0
  94. package/ai/components/wa-color-picker.md +55 -0
  95. package/ai/components/wa-comparison.md +55 -0
  96. package/ai/components/wa-copy-button.md +55 -0
  97. package/ai/components/wa-details.md +61 -0
  98. package/ai/components/wa-dialog.md +59 -0
  99. package/ai/components/wa-divider.md +53 -0
  100. package/ai/components/wa-drawer.md +55 -0
  101. package/ai/components/wa-dropdown-item.md +60 -0
  102. package/ai/components/wa-dropdown.md +60 -0
  103. package/ai/components/wa-format-bytes.md +53 -0
  104. package/ai/components/wa-format-date.md +53 -0
  105. package/ai/components/wa-format-number.md +53 -0
  106. package/ai/components/wa-icon.md +58 -0
  107. package/ai/components/wa-include.md +53 -0
  108. package/ai/components/wa-input.md +59 -0
  109. package/ai/components/wa-intersection-observer.md +53 -0
  110. package/ai/components/wa-known-date.md +53 -0
  111. package/ai/components/wa-markdown.md +53 -0
  112. package/ai/components/wa-mutation-observer.md +53 -0
  113. package/ai/components/wa-number-input.md +55 -0
  114. package/ai/components/wa-option.md +59 -0
  115. package/ai/components/wa-otp-input.md +53 -0
  116. package/ai/components/wa-page.md +53 -0
  117. package/ai/components/wa-pagination.md +55 -0
  118. package/ai/components/wa-popover.md +55 -0
  119. package/ai/components/wa-popup.md +53 -0
  120. package/ai/components/wa-progress-bar.md +53 -0
  121. package/ai/components/wa-progress-ring.md +53 -0
  122. package/ai/components/wa-qr-code.md +53 -0
  123. package/ai/components/wa-radio-group.md +59 -0
  124. package/ai/components/wa-radio.md +55 -0
  125. package/ai/components/wa-random-content.md +53 -0
  126. package/ai/components/wa-rating.md +55 -0
  127. package/ai/components/wa-relative-time.md +53 -0
  128. package/ai/components/wa-resize-observer.md +53 -0
  129. package/ai/components/wa-scroller.md +53 -0
  130. package/ai/components/wa-select.md +63 -0
  131. package/ai/components/wa-skeleton.md +53 -0
  132. package/ai/components/wa-slider.md +55 -0
  133. package/ai/components/wa-spinner.md +58 -0
  134. package/ai/components/wa-split-panel.md +58 -0
  135. package/ai/components/wa-switch.md +53 -0
  136. package/ai/components/wa-tab-group.md +69 -0
  137. package/ai/components/wa-tab-panel.md +60 -0
  138. package/ai/components/wa-tab.md +59 -0
  139. package/ai/components/wa-tag.md +59 -0
  140. package/ai/components/wa-textarea.md +53 -0
  141. package/ai/components/wa-time-input.md +55 -0
  142. package/ai/components/wa-toast-item.md +60 -0
  143. package/ai/components/wa-toast.md +60 -0
  144. package/ai/components/wa-tooltip.md +55 -0
  145. package/ai/components/wa-tree-item.md +55 -0
  146. package/ai/components/wa-tree.md +55 -0
  147. package/ai/components/wa-zoomable-frame.md +55 -0
  148. package/ai/components/workbench.md +118 -0
  149. package/ai/public-api-signatures-v1.md +2748 -210
  150. package/ai/skill.md +286 -66
  151. package/ai/webawesome-jsx-signatures-v1.md +9 -2
  152. package/analyzer/cli.mjs +49 -0
  153. package/analyzer/component-ownership.d.mts +72 -0
  154. package/analyzer/component-ownership.mjs +401 -0
  155. package/analyzer/index.d.mts +53 -0
  156. package/analyzer/index.mjs +2307 -0
  157. package/analyzer/loud-pairs.d.mts +49 -0
  158. package/analyzer/loud-pairs.mjs +357 -0
  159. package/analyzer/report.schema.json +66 -0
  160. package/analyzer/selectors.d.mts +21 -0
  161. package/analyzer/selectors.mjs +212 -0
  162. package/catalog-projection-cli.mjs +96 -0
  163. package/catalog-projection.d.mts +55 -0
  164. package/catalog-projection.mjs +62 -0
  165. package/dist/app-tab.d.ts +39 -4
  166. package/dist/app-tab.js +2 -1
  167. package/dist/badge.d.ts +52 -0
  168. package/dist/badge.js +3 -0
  169. package/dist/badge.js.map +1 -0
  170. package/dist/browser/badge.js +3 -0
  171. package/dist/browser/catalog.js +26 -0
  172. package/dist/browser/chip.js +3 -0
  173. package/dist/browser/collapsible-panel.js +9 -0
  174. package/dist/browser/content-item.js +3 -0
  175. package/dist/browser/floating-toolbar.js +3 -0
  176. package/dist/browser/grid.js +3 -0
  177. package/dist/browser/list-action-row.js +5 -0
  178. package/dist/browser/{menu-header.js → list-header.js} +4 -2
  179. package/dist/browser/list-inset-control.js +3 -0
  180. package/dist/browser/list-inset-text.js +3 -0
  181. package/dist/browser/list-item.js +5 -0
  182. package/dist/browser/list.js +3 -0
  183. package/dist/browser/{panel-header.js → nav-stack.js} +5 -3
  184. package/dist/browser/pane.js +3 -0
  185. package/dist/browser/popup-menu.js +3 -0
  186. package/dist/browser/row.js +3 -0
  187. package/dist/browser/segmented-control.js +0 -1
  188. package/dist/browser/select.js +1 -0
  189. package/dist/browser/spacer.js +3 -0
  190. package/dist/browser/split-view.js +11 -0
  191. package/dist/browser/state-banner.js +1 -0
  192. package/dist/browser/sunken-panel.js +3 -0
  193. package/dist/browser/surface-scaffold.js +3 -0
  194. package/dist/browser/tab-scaffold.js +4 -0
  195. package/dist/browser/text.js +3 -0
  196. package/dist/browser/toolbar-control-group.js +1 -0
  197. package/dist/browser/workbench.js +14 -0
  198. package/dist/catalog-resources.d.ts +48 -0
  199. package/dist/catalog-resources.js +22 -0
  200. package/dist/catalog-resources.js.map +1 -0
  201. package/dist/catalog.d.ts +92 -0
  202. package/dist/catalog.js +503 -0
  203. package/dist/catalog.js.map +1 -0
  204. package/dist/chip.d.ts +35 -0
  205. package/dist/chip.js +3 -0
  206. package/dist/chip.js.map +1 -0
  207. package/dist/chunk-2G2ZJQYK.js +152 -0
  208. package/dist/chunk-2G2ZJQYK.js.map +1 -0
  209. package/dist/chunk-3BYFWTP3.js +108 -0
  210. package/dist/chunk-3BYFWTP3.js.map +1 -0
  211. package/dist/chunk-47CKKLBE.js +34 -0
  212. package/dist/chunk-47CKKLBE.js.map +1 -0
  213. package/dist/chunk-4SQK27MR.js +202 -0
  214. package/dist/chunk-4SQK27MR.js.map +1 -0
  215. package/dist/chunk-5I7QGQVT.js +24 -0
  216. package/dist/chunk-5I7QGQVT.js.map +1 -0
  217. package/dist/chunk-6DFDTWGG.js +288 -0
  218. package/dist/chunk-6DFDTWGG.js.map +1 -0
  219. package/dist/chunk-7OKX3EF6.js +135 -0
  220. package/dist/chunk-7OKX3EF6.js.map +1 -0
  221. package/dist/chunk-AHEG27M7.js +66 -0
  222. package/dist/chunk-AHEG27M7.js.map +1 -0
  223. package/dist/chunk-AYUHMAI6.js +48 -0
  224. package/dist/chunk-AYUHMAI6.js.map +1 -0
  225. package/dist/chunk-B2ZMR7NY.js +85 -0
  226. package/dist/chunk-B2ZMR7NY.js.map +1 -0
  227. package/dist/chunk-BFPBS5Y4.js +250 -0
  228. package/dist/chunk-BFPBS5Y4.js.map +1 -0
  229. package/dist/chunk-DB5ADJKF.js +775 -0
  230. package/dist/chunk-DB5ADJKF.js.map +1 -0
  231. package/dist/chunk-DC6CN2DS.js +123 -0
  232. package/dist/chunk-DC6CN2DS.js.map +1 -0
  233. package/dist/chunk-DG6G5EPF.js +35 -0
  234. package/dist/chunk-DG6G5EPF.js.map +1 -0
  235. package/dist/{chunk-56RJXPHG.js → chunk-G4S2QU6V.js} +7 -4
  236. package/dist/chunk-G4S2QU6V.js.map +1 -0
  237. package/dist/chunk-GLDWRCAM.js +49 -0
  238. package/dist/chunk-GLDWRCAM.js.map +1 -0
  239. package/dist/chunk-I3Q7KKYM.js +33 -0
  240. package/dist/chunk-I3Q7KKYM.js.map +1 -0
  241. package/dist/chunk-IA7TMD4Y.js +288 -0
  242. package/dist/chunk-IA7TMD4Y.js.map +1 -0
  243. package/dist/chunk-J3KGJ6P6.js +135 -0
  244. package/dist/chunk-J3KGJ6P6.js.map +1 -0
  245. package/dist/chunk-K47P7QZC.js +17 -0
  246. package/dist/chunk-K47P7QZC.js.map +1 -0
  247. package/dist/chunk-K67Y2JNF.js +222 -0
  248. package/dist/chunk-K67Y2JNF.js.map +1 -0
  249. package/dist/chunk-KCCEH7RF.js +492 -0
  250. package/dist/chunk-KCCEH7RF.js.map +1 -0
  251. package/dist/chunk-KLJKU6ZL.js +109 -0
  252. package/dist/chunk-KLJKU6ZL.js.map +1 -0
  253. package/dist/chunk-KVBRMEPM.js +44 -0
  254. package/dist/chunk-KVBRMEPM.js.map +1 -0
  255. package/dist/chunk-M6DEEBEF.js +156 -0
  256. package/dist/chunk-M6DEEBEF.js.map +1 -0
  257. package/dist/chunk-MEY33VWB.js +44 -0
  258. package/dist/chunk-MEY33VWB.js.map +1 -0
  259. package/dist/chunk-MP2GDBQZ.js +50 -0
  260. package/dist/chunk-MP2GDBQZ.js.map +1 -0
  261. package/dist/chunk-NC4CFOID.js +188 -0
  262. package/dist/chunk-NC4CFOID.js.map +1 -0
  263. package/dist/chunk-NCSWXG7G.js +80 -0
  264. package/dist/chunk-NCSWXG7G.js.map +1 -0
  265. package/dist/chunk-NN6GYOA2.js +47 -0
  266. package/dist/chunk-NN6GYOA2.js.map +1 -0
  267. package/dist/chunk-OXO2QJWV.js +55 -0
  268. package/dist/chunk-OXO2QJWV.js.map +1 -0
  269. package/dist/chunk-P7D3EMXM.js +52 -0
  270. package/dist/chunk-P7D3EMXM.js.map +1 -0
  271. package/dist/chunk-PSHUSWQH.js +18 -0
  272. package/dist/chunk-PSHUSWQH.js.map +1 -0
  273. package/dist/chunk-Q6YU3BT7.js +138 -0
  274. package/dist/chunk-Q6YU3BT7.js.map +1 -0
  275. package/dist/chunk-QJ5VFCW3.js +131 -0
  276. package/dist/chunk-QJ5VFCW3.js.map +1 -0
  277. package/dist/chunk-RGS4WX2M.js +44 -0
  278. package/dist/chunk-RGS4WX2M.js.map +1 -0
  279. package/dist/chunk-RNQNEENY.js +146 -0
  280. package/dist/chunk-RNQNEENY.js.map +1 -0
  281. package/dist/chunk-RVERAFFY.js +291 -0
  282. package/dist/chunk-RVERAFFY.js.map +1 -0
  283. package/dist/chunk-SLWCCHNP.js +491 -0
  284. package/dist/chunk-SLWCCHNP.js.map +1 -0
  285. package/dist/chunk-SMZGAPCU.js +70 -0
  286. package/dist/chunk-SMZGAPCU.js.map +1 -0
  287. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  288. package/dist/chunk-SRSJO5QE.js.map +1 -0
  289. package/dist/chunk-TJK44RQC.js +452 -0
  290. package/dist/chunk-TJK44RQC.js.map +1 -0
  291. package/dist/chunk-UIDKY4UB.js +14 -0
  292. package/dist/chunk-UIDKY4UB.js.map +1 -0
  293. package/dist/chunk-V3DX3K65.js +43 -0
  294. package/dist/chunk-V3DX3K65.js.map +1 -0
  295. package/dist/chunk-VZOFZPSO.js +71 -0
  296. package/dist/chunk-VZOFZPSO.js.map +1 -0
  297. package/dist/chunk-W2AC6Q2A.js +83 -0
  298. package/dist/chunk-W2AC6Q2A.js.map +1 -0
  299. package/dist/chunk-WF75U3V4.js +33 -0
  300. package/dist/chunk-WF75U3V4.js.map +1 -0
  301. package/dist/chunk-WTSNV5RG.js +52 -0
  302. package/dist/chunk-WTSNV5RG.js.map +1 -0
  303. package/dist/{chunk-YGN7OMLT.js → chunk-X5QSICJ3.js} +8 -5
  304. package/dist/chunk-X5QSICJ3.js.map +1 -0
  305. package/dist/chunk-YDGNU2OD.js +61 -0
  306. package/dist/chunk-YDGNU2OD.js.map +1 -0
  307. package/dist/collapsible-panel.d.ts +133 -0
  308. package/dist/collapsible-panel.js +131 -0
  309. package/dist/collapsible-panel.js.map +1 -0
  310. package/dist/content-item.d.ts +81 -0
  311. package/dist/content-item.js +4 -0
  312. package/dist/content-item.js.map +1 -0
  313. package/dist/css-values.d.ts +107 -0
  314. package/dist/css-values.js +3 -0
  315. package/dist/css-values.js.map +1 -0
  316. package/dist/device-class.js +33 -5
  317. package/dist/device-class.js.map +1 -1
  318. package/dist/disclosure-arrow.d.ts +6 -1
  319. package/dist/disclosure-arrow.js +2 -1
  320. package/dist/empty-state.d.ts +5 -2
  321. package/dist/empty-state.js +2 -1
  322. package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
  323. package/dist/floating-toolbar.d.ts +51 -0
  324. package/dist/floating-toolbar.js +3 -0
  325. package/dist/floating-toolbar.js.map +1 -0
  326. package/dist/grid.d.ts +50 -0
  327. package/dist/grid.js +5 -0
  328. package/dist/grid.js.map +1 -0
  329. package/dist/help-tags-register.d.ts +13 -0
  330. package/dist/help-tags-register.js +9 -0
  331. package/dist/help-tags-register.js.map +1 -0
  332. package/dist/index.d.ts +34 -14
  333. package/dist/index.js +43 -23
  334. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +21 -9
  335. package/dist/list-action-row.js +8 -0
  336. package/dist/list-action-row.js.map +1 -0
  337. package/dist/list-header.d.ts +99 -0
  338. package/dist/list-header.js +10 -0
  339. package/dist/list-header.js.map +1 -0
  340. package/dist/list-inset-control.d.ts +22 -0
  341. package/dist/list-inset-control.js +3 -0
  342. package/dist/list-inset-control.js.map +1 -0
  343. package/dist/list-inset-text.d.ts +30 -0
  344. package/dist/list-inset-text.js +4 -0
  345. package/dist/list-inset-text.js.map +1 -0
  346. package/dist/list-item.d.ts +62 -0
  347. package/dist/list-item.js +8 -0
  348. package/dist/list-item.js.map +1 -0
  349. package/dist/list.d.ts +63 -0
  350. package/dist/list.js +6 -0
  351. package/dist/list.js.map +1 -0
  352. package/dist/loading-spinner.d.ts +9 -2
  353. package/dist/loading-spinner.js +2 -1
  354. package/dist/lucide-icon.d.ts +9 -2
  355. package/dist/lucide-icon.js +2 -1
  356. package/dist/nav-stack.d.ts +66 -10
  357. package/dist/nav-stack.js +6 -1
  358. package/dist/pane.d.ts +108 -0
  359. package/dist/pane.js +4 -0
  360. package/dist/pane.js.map +1 -0
  361. package/dist/panel-toolbar-DDKh4uKd.d.ts +72 -0
  362. package/dist/popup-menu-register.d.ts +9 -0
  363. package/dist/popup-menu-register.js +244 -0
  364. package/dist/popup-menu-register.js.map +1 -0
  365. package/dist/popup-menu.d.ts +100 -0
  366. package/dist/popup-menu.js +3 -0
  367. package/dist/popup-menu.js.map +1 -0
  368. package/dist/resizable-region.d.ts +32 -3
  369. package/dist/resizable-region.js +1 -1
  370. package/dist/row.d.ts +48 -0
  371. package/dist/row.js +6 -0
  372. package/dist/row.js.map +1 -0
  373. package/dist/segmented-control.d.ts +12 -9
  374. package/dist/segmented-control.js +1 -2
  375. package/dist/select-register.d.ts +5 -1
  376. package/dist/select-register.js +243 -2
  377. package/dist/select-register.js.map +1 -1
  378. package/dist/select.d.ts +102 -8
  379. package/dist/select.js +3 -1
  380. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  381. package/dist/sides-BPSWde0A.d.ts +4 -0
  382. package/dist/skeleton.d.ts +14 -7
  383. package/dist/skeleton.js +2 -1
  384. package/dist/spacer.d.ts +18 -0
  385. package/dist/spacer.js +4 -0
  386. package/dist/spacer.js.map +1 -0
  387. package/dist/split-view.d.ts +39 -7
  388. package/dist/split-view.js +120 -10
  389. package/dist/split-view.js.map +1 -1
  390. package/dist/state-banner.d.ts +18 -6
  391. package/dist/state-banner.js +3 -1
  392. package/dist/styles/app-tab.css +224 -0
  393. package/dist/styles/badge.css +118 -0
  394. package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
  395. package/dist/styles/catalog/components/catalog-example.css +168 -0
  396. package/dist/styles/catalog/components/catalog-stage.css +55 -0
  397. package/dist/styles/catalog/components/catalog.css +12 -0
  398. package/dist/styles/catalog.css +5 -0
  399. package/dist/styles/chip.css +132 -0
  400. package/dist/styles/collapsible-panel.css +575 -0
  401. package/dist/styles/content-item.css +75 -0
  402. package/dist/styles/document.css +23 -0
  403. package/dist/styles/floating-toolbar.css +119 -0
  404. package/dist/styles/foundation.css +178 -40
  405. package/dist/styles/grid.css +35 -0
  406. package/dist/styles/layout.css +3 -41
  407. package/dist/styles/list-action-row.css +258 -0
  408. package/dist/styles/list-header.css +229 -0
  409. package/dist/styles/list-inset-control.css +30 -0
  410. package/dist/styles/list-inset-text.css +29 -0
  411. package/dist/styles/list-item.css +255 -0
  412. package/dist/styles/list.css +133 -0
  413. package/dist/styles/loading-spinner.css +4 -0
  414. package/dist/styles/lucide-icon.css +5 -0
  415. package/dist/styles/nav-stack.css +172 -47
  416. package/dist/styles/pane.css +263 -0
  417. package/dist/styles/popup-menu.css +285 -0
  418. package/dist/styles/resizable-region.css +438 -4
  419. package/dist/styles/row.css +111 -0
  420. package/dist/styles/segmented-control.css +36 -9
  421. package/dist/styles/select.css +337 -21
  422. package/dist/styles/skeleton.css +64 -3
  423. package/dist/styles/spacer.css +11 -0
  424. package/dist/styles/split-view.css +114 -3
  425. package/dist/styles/state-banner.css +94 -19
  426. package/dist/styles/styles.css +13 -4
  427. package/dist/styles/sunken-panel.css +29 -0
  428. package/dist/styles/surface-scaffold.css +56 -0
  429. package/dist/styles/tab-bar.css +147 -9
  430. package/dist/styles/tab-scaffold.css +126 -3
  431. package/dist/styles/text.css +112 -0
  432. package/dist/styles/token-search-field.css +155 -55
  433. package/dist/styles/toolbar-control-group.css +608 -29
  434. package/dist/styles/toolbar-text.css +101 -8
  435. package/dist/styles/toolbar.css +343 -12
  436. package/dist/styles/value-table.css +34 -4
  437. package/dist/styles/webawesome.css +365 -10
  438. package/dist/styles/workbench.css +980 -7
  439. package/dist/sunken-panel.d.ts +27 -0
  440. package/dist/sunken-panel.js +3 -0
  441. package/dist/sunken-panel.js.map +1 -0
  442. package/dist/surface-scaffold.d.ts +30 -0
  443. package/dist/surface-scaffold.js +3 -0
  444. package/dist/surface-scaffold.js.map +1 -0
  445. package/dist/tab-bar.d.ts +39 -6
  446. package/dist/tab-bar.js +1 -1
  447. package/dist/tab-scaffold.d.ts +57 -7
  448. package/dist/tab-scaffold.js +83 -9
  449. package/dist/tab-scaffold.js.map +1 -1
  450. package/dist/text.d.ts +56 -0
  451. package/dist/text.js +3 -0
  452. package/dist/text.js.map +1 -0
  453. package/dist/token-search-field-CVGwDn2y.d.ts +154 -0
  454. package/dist/token-search-field.d.ts +3 -43
  455. package/dist/token-search-field.js +2 -1
  456. package/dist/token-search-model.d.ts +3 -0
  457. package/dist/token-search-model.js +3 -0
  458. package/dist/token-search-model.js.map +1 -0
  459. package/dist/toolbar-control-group.d.ts +77 -7
  460. package/dist/toolbar-control-group.js +3 -1
  461. package/dist/toolbar-text.d.ts +35 -4
  462. package/dist/toolbar-text.js +2 -1
  463. package/dist/toolbar.d.ts +59 -7
  464. package/dist/toolbar.js +1 -1
  465. package/dist/types-BuHELdXR.d.ts +117 -0
  466. package/dist/value-table.d.ts +11 -3
  467. package/dist/value-table.js +2 -1
  468. package/dist/webawesome.d.ts +8 -1
  469. package/dist/wire-catalog.d.ts +82 -0
  470. package/dist/wire-catalog.js +327 -0
  471. package/dist/wire-catalog.js.map +1 -0
  472. package/dist/wire-content-items.d.ts +11 -0
  473. package/dist/wire-content-items.js +114 -0
  474. package/dist/wire-content-items.js.map +1 -0
  475. package/dist/wire-nav-stack.d.ts +4 -1
  476. package/dist/wire-nav-stack.js +147 -7
  477. package/dist/wire-nav-stack.js.map +1 -1
  478. package/dist/wire-resizable-regions.d.ts +2 -1
  479. package/dist/wire-resizable-regions.js +2 -1
  480. package/dist/wire-scroll-dividers.d.ts +72 -0
  481. package/dist/wire-scroll-dividers.js +3 -0
  482. package/dist/wire-scroll-dividers.js.map +1 -0
  483. package/dist/wire-sidebar.d.ts +63 -0
  484. package/dist/wire-sidebar.js +231 -0
  485. package/dist/wire-sidebar.js.map +1 -0
  486. package/dist/wire-tab-bars.d.ts +19 -2
  487. package/dist/wire-tab-bars.js +1 -1
  488. package/dist/wire-tab-scaffold.js +9 -4
  489. package/dist/wire-tab-scaffold.js.map +1 -1
  490. package/dist/wire-token-search-fields.d.ts +65 -3
  491. package/dist/wire-token-search-fields.js +2 -1
  492. package/dist/wire-workbench.d.ts +116 -0
  493. package/dist/wire-workbench.js +6 -0
  494. package/dist/wire-workbench.js.map +1 -0
  495. package/dist/workbench.d.ts +244 -9
  496. package/dist/workbench.js +17 -15
  497. package/dist/workbench.js.map +1 -1
  498. package/docs/accessibility.md +476 -24
  499. package/docs/app-layouts.md +106 -8
  500. package/docs/apple-hig.md +1 -0
  501. package/docs/catalog.md +483 -0
  502. package/docs/collapsible-panel.md +371 -0
  503. package/docs/component-contract.md +667 -56
  504. package/docs/component-integration.md +75 -0
  505. package/docs/component-selection.md +540 -95
  506. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  507. package/docs/design/templates/empty-state/filtered.svg +1 -0
  508. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  509. package/docs/design/templates/empty-state/with-action.svg +1 -0
  510. package/docs/design/templates/empty-state-dark.svg +1 -0
  511. package/docs/design/templates/empty-state.svg +1 -0
  512. package/docs/design/templates/list/compact-dark.svg +1 -0
  513. package/docs/design/templates/list/compact.svg +1 -0
  514. package/docs/design/templates/list/stack-dark.svg +1 -0
  515. package/docs/design/templates/list/stack.svg +1 -0
  516. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  517. package/docs/design/templates/list-action-row/default.svg +1 -0
  518. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  519. package/docs/design/templates/list-action-row/selected.svg +1 -0
  520. package/docs/design/templates/list-action-row-dark.svg +1 -0
  521. package/docs/design/templates/list-action-row.svg +1 -0
  522. package/docs/design/templates/list-dark.svg +1 -0
  523. package/docs/design/templates/list-header/action-dark.svg +1 -0
  524. package/docs/design/templates/list-header/action.svg +1 -0
  525. package/docs/design/templates/list-header/count-dark.svg +1 -0
  526. package/docs/design/templates/list-header/count.svg +1 -0
  527. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  528. package/docs/design/templates/list-header/inline-action.svg +1 -0
  529. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  530. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  531. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  532. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  533. package/docs/design/templates/list-header-dark.svg +1 -0
  534. package/docs/design/templates/list-header.svg +1 -0
  535. package/docs/design/templates/list-item/default-dark.svg +1 -0
  536. package/docs/design/templates/list-item/default.svg +1 -0
  537. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  538. package/docs/design/templates/list-item/multiline.svg +1 -0
  539. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  540. package/docs/design/templates/list-item/selected.svg +1 -0
  541. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  542. package/docs/design/templates/list-item/trailing.svg +1 -0
  543. package/docs/design/templates/list-item-dark.svg +1 -0
  544. package/docs/design/templates/list-item.svg +1 -0
  545. package/docs/design/templates/list.svg +1 -0
  546. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  547. package/docs/design/templates/segmented-control/equal.svg +1 -0
  548. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  549. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  550. package/docs/design/templates/segmented-control-dark.svg +1 -0
  551. package/docs/design/templates/segmented-control.svg +1 -0
  552. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  553. package/docs/design/templates/skeleton/avatar.svg +1 -0
  554. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  555. package/docs/design/templates/skeleton/block.svg +1 -0
  556. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  557. package/docs/design/templates/skeleton/lines.svg +1 -0
  558. package/docs/design/templates/skeleton-dark.svg +1 -0
  559. package/docs/design/templates/skeleton.svg +1 -0
  560. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  561. package/docs/design/templates/state-banner/danger.svg +1 -0
  562. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  563. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  564. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  565. package/docs/design/templates/state-banner/info.svg +1 -0
  566. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  567. package/docs/design/templates/state-banner/success.svg +1 -0
  568. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  569. package/docs/design/templates/state-banner/warning.svg +1 -0
  570. package/docs/design/templates/state-banner-dark.svg +1 -0
  571. package/docs/design/templates/state-banner.svg +1 -0
  572. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  573. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  574. package/docs/design/templates/tab-bar-dark.svg +1 -0
  575. package/docs/design/templates/tab-bar.svg +1 -0
  576. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  577. package/docs/design/templates/token-search-field/empty.svg +1 -0
  578. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  579. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  580. package/docs/design/templates/token-search-field-dark.svg +1 -0
  581. package/docs/design/templates/token-search-field.svg +1 -0
  582. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  583. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  584. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  585. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  586. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  587. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  588. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  589. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  590. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  591. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  592. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  593. package/docs/design/templates/toolbar-control-group.svg +1 -0
  594. package/docs/design/templates/toolbar-dark.svg +1 -0
  595. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  596. package/docs/design/templates/toolbar-text/default.svg +1 -0
  597. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  598. package/docs/design/templates/toolbar-text/large.svg +1 -0
  599. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  600. package/docs/design/templates/toolbar-text/small.svg +1 -0
  601. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  602. package/docs/design/templates/toolbar-text.svg +1 -0
  603. package/docs/design/templates/toolbar.svg +1 -0
  604. package/docs/design/templates/value-table/details-dark.svg +1 -0
  605. package/docs/design/templates/value-table/details.svg +1 -0
  606. package/docs/design/templates/value-table-dark.svg +1 -0
  607. package/docs/design/templates/value-table.svg +1 -0
  608. package/docs/design/templates.md +138 -0
  609. package/docs/design-philosophy.md +48 -20
  610. package/docs/device-class.md +10 -9
  611. package/docs/document-baseline.md +38 -0
  612. package/docs/examples/application-ui-profile.json +60 -0
  613. package/docs/examples/command-palette-adapter.tsx +69 -17
  614. package/docs/examples/component-catalog-extension.json +52 -0
  615. package/docs/examples/component-composition-extension.json +80 -0
  616. package/docs/layout.md +534 -59
  617. package/docs/nav-stack.md +138 -14
  618. package/docs/recipes.md +137 -54
  619. package/docs/split-view.md +74 -6
  620. package/docs/sunken-panel.md +87 -0
  621. package/docs/surface-scaffold.md +28 -0
  622. package/docs/tab-scaffold.md +99 -10
  623. package/docs/type-contracts.md +134 -0
  624. package/docs/ui-analyzer.md +384 -0
  625. package/docs/ui-doctor.md +153 -0
  626. package/docs/ui-evaluator.md +139 -0
  627. package/docs/ux-demo.md +41 -16
  628. package/docs/webawesome-theme.md +218 -16
  629. package/docs/workbench.md +608 -12
  630. package/doctor/cli.mjs +120 -0
  631. package/doctor/config.schema.json +94 -0
  632. package/doctor/eslint-diagnostics.d.mts +24 -0
  633. package/doctor/eslint-diagnostics.mjs +24 -0
  634. package/doctor/index.d.mts +122 -0
  635. package/doctor/index.mjs +1364 -0
  636. package/doctor/report.schema.json +118 -0
  637. package/evaluator/cli.mjs +89 -0
  638. package/evaluator/index.d.mts +90 -0
  639. package/evaluator/index.mjs +1203 -0
  640. package/evaluator/report.schema.json +152 -0
  641. package/llms.txt +445 -48
  642. package/package.json +249 -37
  643. package/scripts/component-catalog-extension-validation.mjs +28 -0
  644. package/traversal-exclusions.mjs +27 -0
  645. package/ux-demo/recipes/app-shell.tsx +205 -17
  646. package/ux-demo/recipes/collapsible-sidebar.tsx +260 -0
  647. package/ux-demo/recipes/compact-toolbar.tsx +135 -14
  648. package/ux-demo/recipes/composer-form.tsx +133 -21
  649. package/ux-demo/recipes/list-detail-dialog.tsx +282 -0
  650. package/ux-demo/recipes/list-workspace-states.tsx +183 -11
  651. package/ux-demo/recipes/loaders.ts +15 -5
  652. package/ux-demo/recipes/loading-inspector.tsx +204 -0
  653. package/ux-demo/recipes/mount-recipe.ts +28 -10
  654. package/ux-demo/recipes/navigation-sidebar.tsx +139 -13
  655. package/ux-demo/recipes/navigation-stack.tsx +79 -24
  656. package/ux-demo/recipes/types.ts +23 -2
  657. package/ux-demo/recipes/workspace-header.tsx +86 -5
  658. package/dist/browser/menu-action-row.js +0 -4
  659. package/dist/browser/menu-item.js +0 -4
  660. package/dist/chunk-2RJBFNB6.js +0 -172
  661. package/dist/chunk-2RJBFNB6.js.map +0 -1
  662. package/dist/chunk-2Z5TWHKQ.js +0 -34
  663. package/dist/chunk-2Z5TWHKQ.js.map +0 -1
  664. package/dist/chunk-3YD6ZNRA.js +0 -34
  665. package/dist/chunk-3YD6ZNRA.js.map +0 -1
  666. package/dist/chunk-55DATV3A.js +0 -10
  667. package/dist/chunk-55DATV3A.js.map +0 -1
  668. package/dist/chunk-56RJXPHG.js.map +0 -1
  669. package/dist/chunk-7BR3DO2A.js.map +0 -1
  670. package/dist/chunk-7LDCTU7D.js +0 -134
  671. package/dist/chunk-7LDCTU7D.js.map +0 -1
  672. package/dist/chunk-AQNKJRFH.js +0 -79
  673. package/dist/chunk-AQNKJRFH.js.map +0 -1
  674. package/dist/chunk-B24C4A6T.js +0 -22
  675. package/dist/chunk-B24C4A6T.js.map +0 -1
  676. package/dist/chunk-DAFFDO33.js +0 -14
  677. package/dist/chunk-DAFFDO33.js.map +0 -1
  678. package/dist/chunk-H6URQGJI.js +0 -42
  679. package/dist/chunk-H6URQGJI.js.map +0 -1
  680. package/dist/chunk-I7INRJO4.js +0 -17
  681. package/dist/chunk-I7INRJO4.js.map +0 -1
  682. package/dist/chunk-KJYXOTG3.js +0 -10
  683. package/dist/chunk-KJYXOTG3.js.map +0 -1
  684. package/dist/chunk-LC3YSAZC.js +0 -39
  685. package/dist/chunk-LC3YSAZC.js.map +0 -1
  686. package/dist/chunk-M5JRI6MN.js +0 -27
  687. package/dist/chunk-M5JRI6MN.js.map +0 -1
  688. package/dist/chunk-MBR3TYNL.js +0 -14
  689. package/dist/chunk-MBR3TYNL.js.map +0 -1
  690. package/dist/chunk-MFKMHK5W.js +0 -10
  691. package/dist/chunk-MFKMHK5W.js.map +0 -1
  692. package/dist/chunk-MQIZAD4A.js +0 -227
  693. package/dist/chunk-MQIZAD4A.js.map +0 -1
  694. package/dist/chunk-N3SUXLLS.js +0 -23
  695. package/dist/chunk-N3SUXLLS.js.map +0 -1
  696. package/dist/chunk-PONXLV5U.js +0 -19
  697. package/dist/chunk-PONXLV5U.js.map +0 -1
  698. package/dist/chunk-TZNCCM5H.js +0 -20
  699. package/dist/chunk-TZNCCM5H.js.map +0 -1
  700. package/dist/chunk-W2FK7ZNY.js +0 -26
  701. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  702. package/dist/chunk-WVPYVDXY.js +0 -15
  703. package/dist/chunk-WVPYVDXY.js.map +0 -1
  704. package/dist/chunk-YGN7OMLT.js.map +0 -1
  705. package/dist/chunk-YKUUZPED.js +0 -24
  706. package/dist/chunk-YKUUZPED.js.map +0 -1
  707. package/dist/menu-action-row.js +0 -5
  708. package/dist/menu-action-row.js.map +0 -1
  709. package/dist/menu-header.d.ts +0 -43
  710. package/dist/menu-header.js +0 -7
  711. package/dist/menu-header.js.map +0 -1
  712. package/dist/menu-item.d.ts +0 -33
  713. package/dist/menu-item.js +0 -5
  714. package/dist/menu-item.js.map +0 -1
  715. package/dist/panel-header.d.ts +0 -28
  716. package/dist/panel-header.js +0 -7
  717. package/dist/panel-header.js.map +0 -1
  718. package/dist/styles/menu-action-row.css +0 -160
  719. package/dist/styles/menu-header.css +0 -160
  720. package/dist/styles/menu-item.css +0 -123
  721. package/dist/styles/panel-header.css +0 -64
  722. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
  723. package/ux-demo/recipes/recipes.css +0 -355
package/llms.txt CHANGED
@@ -6,12 +6,27 @@
6
6
  > generate correct, good-looking kerf UI — it is not a catalog to browse.
7
7
 
8
8
  ```bash
9
- npm install kerfjs @kerfjs/ui # kerfjs is a peer; Web Awesome is an optional peer
9
+ npm install kerfjs @kerfjs/ui # kerfjs is a peer; Web Awesome is an optional peer
10
10
  ```
11
11
 
12
- Import each component from its own subpath (`@kerfjs/ui/menu-item`, `@kerfjs/ui/toolbar`,
12
+ Import each component from its own subpath (`@kerfjs/ui/list-item`, `@kerfjs/ui/toolbar`,
13
13
  …); the browser build pulls that component's reachable CSS automatically, so do not
14
14
  maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
15
+ For a public subpath containing several visual components, use a folder with one
16
+ component per source file and one owned stylesheet per visual component. Keep its
17
+ compatibility entrypoints implementation-free: JavaScript/TypeScript only re-exports
18
+ the folder modules, and CSS only imports their owner stylesheets.
19
+
20
+ ## The rule: components own their styles
21
+
22
+ Configure components through their typed props (size, density, inset,
23
+ presentation, `ToolbarConfig`, `PaneConfig`, …); never restyle one from outside.
24
+ No application or parent CSS may select a `.kui-*` class, a `[data-component]`
25
+ root, a `wa-*` element a Kerf component renders, or its `::part()`s, and no
26
+ writing another component's `--_kui-*` / `--kui-*` variables where a prop
27
+ exists. When a component adapts inside another, it styles itself in that
28
+ context in its own stylesheet. A missing prop is a component gap to report,
29
+ not a reason to override — and your own components follow the same rule.
15
30
 
16
31
  ## How to build a screen (retrieval order)
17
32
 
@@ -21,25 +36,245 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
21
36
  2. **Get exact signatures before emitting code** — read
22
37
  [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) (real prop names,
23
38
  callback shapes, disposer return types).
24
- 3. **For exhaustive, structured facts** (ids, exports, variants, `publicClasses`,
25
- relationships, side effects) load the
26
- [Machine-readable component catalog](./ai/component-catalog.json) — the
27
- canonical checked-in source; its schema is alongside it.
28
- 4. **Apply the rules below and in** [skill.md](./ai/skill.md).
39
+ 3. **Look up each component you use** in the
40
+ [component reference index](./ai/components/README.md) — one line per
41
+ entry — then read only those `ai/components/<id>.md` pages (1–7 KB each):
42
+ use/avoid, imports and side effects, a link to exact props, legal parents,
43
+ zones with their JSX prop and child count, app- and wiring-owned state,
44
+ geometry, accessibility, the styling boundary (configure through props;
45
+ never override internals), and `KUI-C###` diagnostics. Do not load the
46
+ large JSON catalogs just to choose or compose components; the pages are
47
+ generated from them.
48
+ **Tools and mechanical checks** use the JSON sources instead: the
49
+ [Machine-readable component catalog](./ai/component-catalog.json) (ids,
50
+ exports, variants, `publicClasses`, relationships, side effects, and
51
+ geometry ownership) — the canonical checked-in source; its schema is
52
+ alongside it. Also load the
53
+ consuming application's catalog extension when present; generate one from the
54
+ [Consumer catalog extension schema](./ai/component-catalog-extension.schema.json)
55
+ when app-owned components must participate in selection or alignment.
56
+ A tool loads the [Composition catalog](./ai/component-composition.json) — a
57
+ generated composition layer beside the component catalog, not a replacement
58
+ for it — to mechanically evaluate parents, contexts, zones/cardinality,
59
+ children, state, wiring (including the wiring-owned `stateAttributes` an app
60
+ must never render or remove), responsive/layout/accessibility rules, and
61
+ public boundaries. The component catalog stays the selection and delivery
62
+ surface; the composition layer joins catalogs by `package:id`. Consumer
63
+ composition catalogs use
64
+ [the composition extension schema](./ai/component-composition-extension.schema.json).
65
+ Load [compile-time contracts](./ai/compile-time-contracts-v1.json) for stable
66
+ `KUI-T###` ids, exact declaration symbols, and the boundary between rejected
67
+ source states and relationships that still require runtime/catalog checks.
68
+ Before generating application UI, discover `.kerf-ui-profile.json` with the
69
+ shipped [application profile API](./ai/application-ui-profile.mjs). Merge
70
+ package defaults, workspace policy, then parent-to-child directory policy;
71
+ honor its package-qualified preferences, approved theme/density, semantic
72
+ tokens, layout conventions, and narrow source-located exceptions. Validation
73
+ is catalog-aware per layer, including parent values later overridden by a
74
+ child; synchronous hosts use [application-ui-profile-sync.cjs](./ai/application-ui-profile-sync.cjs).
75
+ See the
76
+ [workspace profile example](./docs/examples/application-ui-profile.json).
77
+ A zone's optional `jsx.prop` is its only authoritative JSX binding; never
78
+ infer one from the zone id. Use `children` for one homogeneous primary
79
+ region and explicit named content prop slots for semantic positions or
80
+ replacement content. These slots use the recursive `KerfUiContent` type:
81
+ `SafeHtml`, runtime-empty boolean/nullish values, and readonly nested arrays.
82
+ Put conditionals and mapped component arrays directly in them; do not add a
83
+ `Fragment` only to satisfy types. Arbitrary strings, numbers, and signals are
84
+ rejected unless a component explicitly exposes a text position such as
85
+ `ListInsetText`. These are typed props, not native `<slot>` elements,
86
+ wrapper slot components, or a generic `slots` object. Leave unresolved
87
+ dynamic expressions unknown.
88
+ Stable single-root Kerf UI components separately accept the explicit native
89
+ `slot="name"` prop for light-DOM composition inside a custom element and
90
+ preserve it across rerenders. Do not infer arbitrary native-attribute
91
+ spreading from this narrow interop contract. `ResizableRegion` and
92
+ `CollapsiblePanel` remain excluded because their optional restore controls
93
+ make their output multi-root; `CollapsiblePanelToggle` remains slot-capable.
94
+ 4. **When authoring a component gallery**, load
95
+ [catalog-authoring.json](./ai/catalog-authoring.json), then follow its
96
+ authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract).
97
+ Use its component/composition/recipe taxonomy and functional-group,
98
+ importance, alphabetical-tie, and recipes-last ordering policy. Focused
99
+ demos and recipes use public components plus `CatalogExample.viewport`,
100
+ never local stylesheets, inline styles, or styling-only classes.
101
+ 5. **Apply the rules below and in** [skill.md](./ai/skill.md).
102
+ 6. **Before calling an integration complete**, run
103
+ [`kerf-ui-doctor`](./docs/ui-doctor.md). Its portable JSON report merges
104
+ profile/catalog, TypeScript, Kerf ESLint, and static analyzer diagnostics;
105
+ CSS-adjacent component props are checked from catalog `cssValueProps`, so
106
+ prefer its canonical shorthand or typed helper over raw CSS strings; a
107
+ `--wa-color-{tone}-fill-loud` override without a governing `on-loud` (same
108
+ or ancestor scope, possibly in a co-loaded stylesheet), or whose literal
109
+ pair measures below 4.5:1, is review finding `KUI-L018` (set both); CSS that restyles a component
110
+ (`KUI-L019`), touches its private `--_*` variables (`KUI-L020`), overrides a token a typed prop sets
111
+ (`KUI-L021`), or styles it through a hook class on its root (`KUI-L022`) is an error: configure the
112
+ component instead, and report a component gap when no prop exists; application-component imports may use TypeScript `paths` aliases; use `"ownership": "component"` with catalog `styleSources` to apply this boundary between an app's own components; repair source-located errors until exit 0. Use full mode for release gates;
113
+ generated `dist`/`coverage`, dependency, cache, evidence, and nested-worktree
114
+ directories are excluded consistently from every static stage.
115
+ [`kerf-ui-analyze`](./docs/ui-analyzer.md) remains available when only static
116
+ layout diagnostics are wanted; its review findings are a bounded human/AI
117
+ review queue rather than an objective aesthetic score.
118
+ 7. **Evaluate the running application** by explicitly enabling the doctor's
119
+ browser stage or directly invoking
120
+ [`kerf-ui-evaluate`](./docs/ui-evaluator.md). Preserve its `KUI-B###`
121
+ browser evidence and screenshots; record hierarchy/rhythm/density/aesthetic
122
+ ratings separately with a named reviewer rather than presenting them as
123
+ objective assertions.
29
124
 
30
125
  ## Core rules (do the right thing)
31
126
 
127
+ - **Prefer a Kerf UI component over a Web Awesome component over a raw HTML
128
+ tag**, using each for what it is good at. Never render a `Discouraged` Web
129
+ Awesome element (`wa-dropdown`, `wa-button-group`, `wa-select`, `wa-tab-group`,
130
+ `wa-icon`, …) directly; reach it only through the Kerf component that wraps or
131
+ replaces it (`PopupMenu`, `SegmentedControl`, `Select`, `TabBar`,
132
+ `LucideIcon`), and file a component gap rather than dropping to the raw tag.
32
133
  - **Reach for the primitive, not for CSS.** The package is built to look right
33
- *unstyled*. Before adding `padding`, `margin`, `width`, `height`, `border`,
34
- `background`, a wrapper card, or a decoration, check whether the component, the
35
- pane, or the content-item already owns it — it almost always does. Prefer a
36
- component prop or a `--kui-*` token; write CSS only for genuinely new structure,
37
- and then only join a component's documented `publicClasses` (never reach in by
38
- tag/id/attribute or an unlisted class).
134
+ without an application customization layer. Before adding `padding`, `margin`,
135
+ `width`, `height`, `border`, `background`, a wrapper card, or a decoration,
136
+ check whether the component, pane, or content-item already owns it. Prefer a
137
+ component prop — `FloatingToolbar inset`, `DisclosureArrow size`, `ListHeader
138
+ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
139
+ visibly bounded content item — over overriding its `--kui-*` token. CSS for genuinely new structure
140
+ belongs to the application-owned component that renders it and must not select
141
+ nested Kerf or Web Awesome components.
39
142
  - **Never double-inset.** A `.kui-pane` has no padding; its `.kui-content` children
40
- own the geometry (8px inline margin + 1px border + 8px padding). Do not add a
143
+ own the geometry (8px inline margin + 1px border + 8px padding). Render an
144
+ ordinary surface-like child as `ContentItem` (`@kerfjs/ui/content-item`) with
145
+ typed `frame` (`none`/`framed`) and `shape` (`rounded`/`pill`) props instead
146
+ of hand-writing `<div class="kui-content-item">`. Do not add a
41
147
  container padding on top of a content-item's own margin — pick one owner. Use
42
148
  `.kui-content` for 24px major vertical rhythm.
149
+ - **Opt into document globals explicitly.** Import `@kerfjs/ui/document.css`
150
+ once for border-box sizing, token-backed body/link presentation, and zero body
151
+ margin. Put `.kui-app-root` on the one direct mount container only when a
152
+ percentage-height shell needs the provided `html` → `body` → app-root height
153
+ chain. The baseline is not part of `styles.css` or component browser imports.
154
+ - **Use compact layout options where needed.** `Text flush lineHeight="tight"`
155
+ fits short dialog copy; `ValueTable density="compact"` reduces row spacing,
156
+ with public row column, padding, and gap tokens for specific metadata layouts.
157
+ `ToolbarText size="xsmall"` suits a dense rail heading. The
158
+ `TokenSearchField` editor shrinks in narrow groups; its minimum width can be
159
+ set with `--kui-token-search-editor-min-width`.
160
+ - **Label read-only field previews.** Use `FieldLabel` from `@kerfjs/ui/text`
161
+ in `ListInsetControl sides="trl"` above a `ContentItem` value. Connect its
162
+ id to the preview group's `aria-labelledby`; use the live control's own
163
+ `label` while editing.
164
+ - **Use Toolbar zone options.** `responsive="trailing-priority"` moves an
165
+ expanded trailing control to a full second row at `responsiveAt`; the leading
166
+ title remains above it. Public leading-min-width, trailing-gap/justify, and
167
+ per-zone inline-padding tokens cover app-specific toolbar geometry.
168
+ In a stacked Toolbar, `ToolbarControlGroup placement="end"` places a collapsed
169
+ search at its row's trailing edge; `sizing="fill"` gives its expanded state a
170
+ full row and a reduced-motion-aware downward entrance.
171
+ `--kui-toolbar-inset: 0px` removes an embedded Toolbar's outer padding and
172
+ corresponding minimum-height allowance while preserving its zone gap and
173
+ safe-area compensation.
174
+ - **Position region restore controls declaratively.** A ResizableRegion has a
175
+ background token, `contentOverflow="visible"` for an anchored popup,
176
+ top/bottom `restorePosition`, typed `restoreInset`, and
177
+ `restorePlacement="inline"` for normal flow. FloatingToolbar also has
178
+ `placement="inline"`, per-edge inset tokens, and `safeAreaInsets`.
179
+ - **Configure list rows through their APIs.** `ListItem density="spacious"`
180
+ gives option rows more room. `multiline` wraps labels, with
181
+ `multilineIconAlign="center"` when the icon should center on the whole copy.
182
+ `divider` owns row separators and `state="drag-target"` paints the drop
183
+ target. Public ListItem tokens set row, icon, label, and trailing geometry;
184
+ ListHeader height, title padding, and border tokens tune section density.
185
+ For a filled command list, scope `--kui-list-item-background`,
186
+ `--kui-list-item-color`, `--kui-list-item-border`,
187
+ `--kui-list-item-hover-background`, `--kui-list-item-hover-border`,
188
+ `--kui-list-item-selected-background`, `--kui-list-item-selected-color`,
189
+ and `--kui-list-item-selected-border` at the list or row boundary.
190
+ - **Use `Row` for horizontal and `List` for vertical layout.** Both expose
191
+ physical `hAlign`/`vAlign` props and typed gaps. Row defaults to left/full,
192
+ an `xs` gap, and no wrapping; List retains full/top and zero-gap defaults.
193
+ Use canonical physical `textInsets` or `controlInsets` sides in
194
+ `t`/`r`/`b`/`l` order; text geometry wins on overlapping sides.
195
+ `ListInsetText` and `ListInsetControl` inset every side by default and accept
196
+ the same `sides` grammar for selective edges.
197
+ List additionally supplies
198
+ optional typed `gap`, `flex`, vertical scrolling, and canonical
199
+ `dividerSides` (`t`/`r`/`b`/`l` order). It adds no list semantics; children own
200
+ those, and only one bounded region should own scrolling. Pass a finite spacing
201
+ shorthand (`gap="xs"`, `gap="m"`) or a complete `CssLength` from the CSS-free
202
+ `@kerfjs/ui/css-values` builders; raw CSS strings are rejected. Use `flex()`
203
+ for List flex, typed lengths for Skeleton geometry, and
204
+ foreground colors for choice icons: `uiColor()` with an `*-on-*`/text token
205
+ or `foregroundColorVar()`; fill tokens such as `uiColor('success-fill-quiet')` do not
206
+ type-check. These brands are intentionally
207
+ not interchangeable; rows use classes/tokens/props rather than raw `style`.
208
+ - **Use `Grid` for equal-width columns.** Set a fixed positive `columns` count
209
+ or typed `minColumnWidth` for automatic container-width collapse, never both.
210
+ The app owns the outer width and child semantics; use custom CSS grid for
211
+ asymmetric/intrinsic tracks and `ResizableRegion` for adjustable boundaries.
212
+ `Grid.gap` and `Grid.flex` use the same typed grammars as Row.
213
+ For selectable document tiles, use `selectionMode="multiple"` and a required
214
+ `ariaLabel`, with `ContentItem selectionMode="multiple"` children. Wire
215
+ `wireContentItems` for spatial arrow navigation and Enter/Space activation.
216
+ - **Give a layout root `fill`, not a frame `Pane`.** A Row, List, or Grid that
217
+ is the sole layout root of a definite-height parent takes its full height
218
+ with `fill` and carries safe `data-*` markers through `rootAttributes`.
219
+ Inside a flex layout use `flex` instead.
220
+ - **Keep Web Awesome on the shared inset tiers.** `webawesome.css` uses
221
+ `--kui-wa-control-inset` (8px controls/items) and
222
+ `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside
223
+ Accordion, Card, Details, Callout, and Include), while
224
+ plain Details keep their body flush while plain Accordion items inset both
225
+ trigger and body, framed Details use the 16px container inset only on the
226
+ trigger, and framed Accordion items use it on both regions;
227
+ `--kui-wa-container-inset` keeps Tab Panel at 16px. Dialog body and footer use
228
+ the surface (8px) and container (16px) tiers respectively, independent of the
229
+ dialog's shared `--spacing`. Override the tier at the narrowest useful scope
230
+ instead of restyling individual shadow parts.
231
+ Filled badges use each semantic variant's quiet fill with normal text for
232
+ WCAG-AA compact-copy contrast. Override
233
+ `--kui-wa-badge-filled-background` and
234
+ `--kui-wa-badge-filled-foreground` as a contrast-safe pair instead of adding
235
+ host selectors.
236
+ When a dialog provides another dismissal affordance, add `hide-actions` to
237
+ the `wa-dialog` host; the theme hides its directly exported `header-actions`
238
+ part without an unsupported chained `::part()` selector.
239
+ Checkbox and Radio Group option regions also receive the shared 8px inline
240
+ outer inset because those groups have no bordered field shell. The Color
241
+ Picker trigger receives the same inset for the same unbordered geometry.
242
+ Slider's complete interactive region uses the shared 8px logical inline outer
243
+ inset without shifting its already-aligned label.
244
+ Known Date's Month/Day/Year captions and bordered text-like field hints align
245
+ with field values at the shared 9px border-plus-padding inset. OTP Input's
246
+ label uses the same uppercase xs/650 treatment and its label and hint share
247
+ that 9px alignment.
248
+ - `Select` requires a visible `label` or an `ariaLabel` for a visually hidden
249
+ accessible name. Set `multiple` with an array `value` for any number of
250
+ choices: the popup stays open while choices toggle and closes on an outside
251
+ press or Escape, and the closed control summarizes the chosen labels. A
252
+ toolbar filter menu adds `selectedPresentation="icon-only"` and a fixed
253
+ `triggerIcon`: the trigger shows that icon plus a count badge while any
254
+ choice is chosen, and its accessible name ends with the chosen labels.
255
+ Set `caret={false}` on an icon-only toolbar Select to make a round trigger;
256
+ a custom `renderSelected` icon stays centered, and the default keeps the
257
+ visible caret.
258
+ `SelectChoice.disabled` keeps an unavailable option visible but unselectable;
259
+ `disabledReason` adds its tooltip. For multiple selects, opt in to
260
+ `selectAllLabel` and `clearLabel` footer buttons to select enabled choices
261
+ or clear the value through ordinary change events. The app owns the updated
262
+ controlled value and localized action labels.
263
+ Icon-only Selects (single or multiple) and icon-only `PopupMenu`s show an
264
+ `aria-hidden` Web Awesome help tag repeating that name (and a Select's
265
+ choice) on hover and keyboard focus, hidden while the popup is open; the
266
+ register import installs it, so do not add a `title` or tooltip of your own.
267
+ The same installer tags an icon-only `<button>` or link inside a
268
+ `ToolbarControlGroup` named by `aria-label` (no visible text or `title`);
269
+ import `@kerfjs/ui/help-tags/register` once when a toolbar has such buttons
270
+ but no registered Select or PopupMenu.
271
+ The package names the internal combobox, including custom
272
+ selected content; consumers do not need shadow-DOM naming workarounds.
273
+ Import `select/register` once for the canonical animation lifecycle: stale
274
+ close/show completions cannot override a later request. Consumers must not
275
+ repair popup timing or anchor placement; raw Web Awesome selects stay native.
276
+ Use `hint` for supporting text below the control and `placeholderText` only
277
+ for the empty value inside it; loading placeholders retain the visible hint.
43
278
  - **Trust the defaults.** Render a control at its natural size and color (a
44
279
  `LucideIcon` is 24px); if it looks wrong, fix the surrounding layout, not the
45
280
  control. Never force a component's width/height to size it — that leaves a halo
@@ -47,23 +282,89 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
47
282
  - **Toolbars hold only `ToolbarText` and `ToolbarControlGroup`.** Never put a bare
48
283
  button, input, link, or loose markup in a `leading`/`center`/`trailing` zone.
49
284
  Wrap every control — `SegmentedControl`, `Select`, a collapsible
50
- `TokenSearchField`, Web Awesome controls — inside a `ToolbarControlGroup`. A
51
- toolbar popup menu is a `single` `ToolbarControlGroup` around a `wa-dropdown`
52
- (its `slot="trigger"` `wa-button` is the toolbar button, kept under
53
- `data-morph-skip-children`).
54
- - **`PanelHeader` is *the* panel/dialog/page heading.** A plain toolbar with an
55
- optional bordered icon group, an extra-large `ToolbarText` title, the trailing
56
- controls you pass, and an optional subtitle below — do not hand-build a heading
57
- row or restyle a toolbar into one.
285
+ `TokenSearchField`, Web Awesome controls — inside a `ToolbarControlGroup`. For an
286
+ ordinary icon/action control inside the group use a **plain `<button>`** (the
287
+ group styles it fully) — that is the default; reach for `wa-button` only when you
288
+ need a Web Awesome feature. A toolbar popup menu is a `PopupMenu`
289
+ (`@kerfjs/ui/popup-menu`, registered once via `@kerfjs/ui/popup-menu/register`)
290
+ in a `single` `ToolbarControlGroup` with `nestedDropdown`; never hand-write
291
+ `wa-dropdown` markup for a menu. Let the group size the trigger from its icon,
292
+ localized text, and caret. Set `overflow="wrap"` for independent action links
293
+ that must remain fully visible at narrow widths; whole links move to a second
294
+ row, as in the catalog resource footer. `PopupMenu` items also support nested `submenu`
295
+ actions, headings, dividers, checked or trailing choice marks, danger tone,
296
+ and disabled reasons; nested headings/dividers stay out of keyboard choices;
297
+ use `context` with `openPopupMenuAt`/`closePopupMenu` for pointer-anchored row
298
+ menus. Do not force a dropdown or button width. Nothing
299
+ wraps inside a group: an icon sits beside its label on one row, and a
300
+ `ToolbarText` is one ellipsized line unless you opt into `wrap`/`maxLines`. A
301
+ Select or PopupMenu trigger drops its focus ring while its popup is open and
302
+ the ring follows the control's shape; never add ring CSS. Compact
303
+ mixed groups keep standard item padding and raised selected chrome without an
304
+ internal separator; the selected item paints over the outer border. For an
305
+ avatar control, set `content="avatar"` and `avatarImage` on the group instead of
306
+ inserting an `img`; a lone control paints the group and a multi-button group
307
+ paints only its pressed highlight. Dividers earn their place: a `Toolbar`
308
+ draws none by default and pinned chrome gets its line from scroll state (see
309
+ the scroll-divider rule below); never fake one with a border or pad below a
310
+ divider to make it look right.
311
+ - **Use one direct toolbar composition for panel/dialog/page headings.** Put an
312
+ optional icon in a `ToolbarControlGroup`, an extra-large `ToolbarText` directly
313
+ in the leading zone, and actions in a trailing group. Supporting copy is
314
+ app-owned content below. Do not create a private heading wrapper or restyle the
315
+ toolbar. A narrow peripheral rail or drawer, where extra-large would truncate
316
+ at its minimum size, names itself with the default `ToolbarText` size.
317
+ `ToolbarText size="xlarge-fixed"` keeps the 20px `--kui-font-l` heading step;
318
+ `xlarge` retains the responsive page-title clamp.
319
+ - **Use `Text` for ordinary semantic headings, paragraphs, and inline secondary
320
+ text outside toolbar title zones.** Omit `variant` for the default `p`, pass
321
+ `h1`–`h6` based on the document outline, or use `variant="span"` inside a row,
322
+ label, or table cell without adding box geometry. Independently compose `tone="quiet|danger"`,
323
+ `size="compact|large|xlarge"`, and `font="monospace"` for supporting, error,
324
+ compact, prominent, display, and code roles instead of global utility classes. It passes native attributes
325
+ through; block variants own the standard transparent border plus item padding, while `span` owns none. Keep
326
+ toolbar titles on `ToolbarText` and list-aligned bare prose on `ListInsetText`.
58
327
  - **Space by the five-step scale, by relationship not by eye.** `0`
59
328
  `--kui-space-none`, `4px` `--kui-space-2xs`, `8px` `--kui-space-xs` (inside a
60
329
  group), `16px` `--kui-space-m`, `24px` `--kui-space-l` (between major differing
61
- regions). 12px/32px are off-scale exceptions.
330
+ regions). 12px/32px are off-scale exceptions. Prefer direct `Row.gap`/`List.gap`
331
+ shorthands for repeated rhythm; use `Spacer` for one typed empty width/height
332
+ or flexible main-axis gap. Use `space`, `px`, `rem`, `em`, `pct`, `lengthVar`, and
333
+ `calc(plus(...))` for typed runtime composition. `remify()` is source-CSS only.
334
+ - **Keep nested highlight corners concentric.** Inset hover and selection surfaces
335
+ follow the owning control's pill or rounded shape; their radius is the outer
336
+ radius minus `--kui-layout-highlight-inset`. Do not give an inner highlight an
337
+ unrelated radius.
62
338
  - **Panes share one child-owned geometry.** Sidebars, main areas, inspectors, and
63
- dialogs all use an unpadded `.kui-pane` (optional `.kui-pane__toolbar`, one
64
- scrolling `.kui-pane__content`, optional `.kui-pane__footer`). A visible pane owns
65
- its collapse control; a hidden pane's restore moves to the adjacent main
66
- toolbar's matching edge — no icon-only rail. Keep one scroll owner per region.
339
+ dialogs all render `Pane`: an unpadded `.kui-pane` (optional header, one
340
+ scrolling `.kui-pane__content`, optional footer). Never write a component's
341
+ anatomy classes onto your own element to recreate it (`KUI-L103`); only
342
+ the catalog's `placeableClasses` (layout utilities, `.kui-app-root`,
343
+ `.kui-content-item` on a non-div carrier) belong there. A visible pane owns
344
+ its collapse control (the last control of its last group); a hidden pane's
345
+ restore moves to the adjacent main toolbar's matching edge — no icon-only
346
+ rail — and a collapsed drawer's restore sits in the bottom toolbar or a
347
+ `FloatingToolbar` beside the drawer, near where its effect appears. Align
348
+ text to text and icons to icons across a pane; a border is decoration, never
349
+ the alignment anchor. Keep one scroll owner per region.
350
+ - **Dividers between pinned chrome and scrolling content are scroll state.**
351
+ Toolbars draw no divider by default. Call `wireScrollDividers(appRoot)`
352
+ (`@kerfjs/ui/wire-scroll-dividers`) once and keep its disposer: every `Pane`
353
+ with `chromeDividers="scroll"` then draws the line under its header only while content is scrolled beneath
354
+ it and the line over its footer only while more content lies below (never
355
+ when the content fits), every `NavStack`'s top chrome and bottom toolbar and
356
+ every `TabScaffold` bar do the same around the active view or scene, and
357
+ every `TabBar` marks each side of its strip with tabs scrolled out of view. Configure a pane with `chromeDividers`
358
+ (`scroll` for a plain pane by default, `always` for a sunken pane by default,
359
+ or explicit `scroll`, `always`, `none`), and a `NavStack` or `TabScaffold`
360
+ with its own `chromeDividers` (same values; a `SplitView` forwards it through
361
+ `compactStack`); name app-owned chrome in `targets`.
362
+ Never add a border, or a permanent `dividerSides`, to fake one.
363
+ While a side overlay is open (a Workbench rail overlay, a `wireSidebar` compact
364
+ overlay, an overlay `CollapsiblePanel` or horizontal `ResizableRegion`), the
365
+ layout hides the covered work area's `FloatingToolbar`s and restore corners
366
+ itself (unfocusable, out of the accessibility tree) until it closes — do not
367
+ hide them from overlay state yourself.
67
368
  - **State and behavior live in the app.** Components take semantic `data-action`
68
369
  strings and controlled values; wire them once with `delegate()`/`delegateActions()`
69
370
  or the disposer-returning `wire…` helpers, and own domain copy, transport, and
@@ -72,37 +373,130 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
72
373
  - **App state is domain/persisted; helpers own only ephemeral mechanics.** Keep
73
374
  navigation stacks, tab selection and order, pane sizes, and `collapsed`/`expanded`
74
375
  disclosure flags in the app — they are data or persisted layout, and the app reads
75
- them to render. The `wire…` helpers own the *ephemeral* parts: `wireNavStack` the
76
- push/pop animation, `wireTabBars` the overflow autoscroll and drag preview,
77
- `wireResizableRegions` the live drag preview; they report committed changes via
78
- callbacks. The one richer case is `wireTokenSearchFields`, which manages the
376
+ them to render. The `wire…` helpers own the _ephemeral_ parts: `wireNavStack` the
377
+ content-slide, per-view top/bottom chrome cross-fade, and focus move/restore
378
+ (mark a preferred new-view target with `data-nav-focus`), `wireTabBars` the
379
+ overflow autoscroll, drag preview, and
380
+ replacement focus after controlled automatic tab activation,
381
+ `wireResizableRegions` the live drag preview, `wireScrollDividers` the
382
+ scroll-state attributes from which a `Pane` draws its chrome dividers and a
383
+ `TabBar` its overflow dividers; they report committed changes via
384
+ callbacks. For a tab-local action plus a separate far-edge action, set
385
+ `TabBar trailingPlacement="adjacent"`, put the local action in `trailing`, and
386
+ the workspace action in `end`; the component keeps both visible while its tab
387
+ list shrinks and scrolls, without application descendant CSS. Each action
388
+ zone accepts one ToolbarControlGroup or a standalone `wa-button` for its own
389
+ Web Awesome chrome. Managed
390
+ TokenSearchField clear also preserves open state and replacement
391
+ editor focus before the next input task, so shortcut-letter typing stays in search.
392
+ Select All deletion does the same; deletion
393
+ restoration finishes before the next keystroke rather than on a delayed frame.
394
+ Persist both query and remaining tokens read from an edited field; change
395
+ `revision` to replace unmanaged DOM-owned text programmatically, or call
396
+ `model.replace({ query, tokens })` for a model-managed field. In grammar-assisted
397
+ search, a model rule's `suggest(input, state)` receives current committed tokens
398
+ so suggestions can omit selected values; one-argument callbacks still work.
399
+ A sibling helper can call `model.commit(value)` for the active `name:` prefix
400
+ even when that value is not suggested; invalid values and missing prefixes
401
+ leave state unchanged.
402
+ The one richer case is `wireTokenSearchFields`, which manages the
79
403
  collapsible field's expand/collapse/focus by default (on, per-behavior opt-out) and
80
404
  exposes the `expanded` signal on its handle — bind it in render or hand in your own
81
405
  via `collapsible.signals`. Do not hand-roll open/collapse/focus that helper
82
406
  provides; but do keep a plain disclosure toggle (a one-line boolean the app already
83
- renders from) in the app.
407
+ renders from) in the app. For real-app composition it also offers a focusout
408
+ keep-open exception (`data-token-search-keep-open` regions or `collapsible.keepOpenOn`,
409
+ so a sibling suggestions/date popover does not collapse an empty field), opt-in
410
+ atomic-chip keyboard (`keyboard`: Backspace/Delete remove the adjacent chip via
411
+ `onRemoveToken`, ArrowRight moves the caret past a trailing chip), and an
412
+ `onEdit({id, editor, event})` input callback (the `InputEvent` lets you gate on `inputType`/`data`) — so the app can drop its own keydown/input
413
+ boilerplate while still owning parsing and controlled token state.
84
414
  - **Placeholder loading state, don't rebuild it.** For a value or component that is
85
- still loading, set `placeholder` on the component (`Select`, `MenuHeader`,
86
- `MenuItem`, `ValueTableRow`, `PanelHeader`, `SegmentedControl`, `StateBanner`,
87
- `AppTab`, `ToolbarText`, `MenuActionRow`): it renders its real chrome with value
88
- slots as subtle **unanimated** skeleton blocks and interactivity disabled, so a
89
- parent composes a faithful loading view (e.g. an inspector) without hand-rebuilding
90
- markup. Use the standalone `Skeleton` for a custom slot. Prefer it over `wa-skeleton`
415
+ still loading, set `placeholder` on the component (`Select`, `ListHeader`,
416
+ `ListItem`, `ValueTableRow`, `SegmentedControl`, `StateBanner`,
417
+ `AppTab`, `ToolbarText`, `ListActionRow`): it renders its real chrome with value
418
+ slots as subtle **unanimated** skeleton blocks and interactivity disabled. Only
419
+ unknown values change: a placeholder is never dimmed or styled as disabled (a
420
+ control you disabled keeps its live disabled tone), so a parent composes a
421
+ faithful loading view (e.g. an inspector) without hand-rebuilding markup.
422
+ Component-drawn chrome stays live: a `ListItem` or `ListActionRow` keeps its
423
+ `busy` spinner while its `status` (and a `ListItem`'s `trailing`) content
424
+ become skeletons. Use the standalone `Skeleton` for a custom slot. Prefer it over `wa-skeleton`
91
425
  (the pure-Kerf primitives avoid Web Awesome), and never animate it — use
92
- `LoadingSpinner` for known busy activity instead.
426
+ `LoadingSpinner` for known busy activity instead. Set its `size` prop to a
427
+ named icon step or positive pixel number when the inherited 1em is unsuitable.
428
+ - **Keep ListItem content inside the row.** The rounded `ListItem` root clips
429
+ overflowing label, status, and dormant trailing content. Set `multiline` when
430
+ the primary label should wrap; use `ListActionRow` instead when trailing content
431
+ must be interactive.
432
+ - **Dialog bodies are lists by default.** Compose rows and sections in `List`,
433
+ use `DialogSurface bodyInset="none"` when those children own their geometry,
434
+ and wrap bare prose in `ListInsetText` so it shares the standard list gutter
435
+ without stacking a second body inset.
436
+ - **Use a StateBanner badge only for compact supporting status.** Pass the
437
+ optional string `badge` for a terse count or status beside the title. It
438
+ inherits the banner tone and is announced with the banner, so keep its text
439
+ meaningful and never rely on color alone.
440
+ - **Configure StateBanner copy and action placement.** `copyLayout="stacked"`
441
+ puts detail below the title and badge; `actionPlacement="below"` gives the
442
+ action a separate trailing row. The inline defaults remain compact.
443
+ - **Size a Select through its API.** `triggerWidth` chooses `fit-content`,
444
+ `max-content`, or `fill`; `--kui-select-trigger-max-width` caps it. For custom
445
+ selected text, use the public color, font-size, and font-weight tokens; the
446
+ closed value ellipsizes when space runs out. `presentation="title"` gives a
447
+ rail view heading a 36px bold, flush-start trigger and adjacent caret;
448
+ `focusRingInset` keeps its ring inside clipping ancestors.
449
+ - **Configure application tabs at their owners.** AppTab's `icon-only`
450
+ presentation keeps `name` accessible, `labelMaxWidth` ellipsizes a long name,
451
+ `nameOverflow="visible"` shows the full name during inline loading, and
452
+ `dropTarget` highlights a drag-over without changing selection. `attention`
453
+ uses `--kui-app-tab-attention-color`. TabBar's public
454
+ `--kui-tab-bar-strip-*` tokens set compact strip geometry.
455
+ Set `pinned` on the first AppTab to keep it visible within a scrolling
456
+ tablist; it remains in keyboard order. Use `--kui-app-tab-pinned-background`
457
+ for the surrounding surface and keep that backdrop opaque.
458
+ - **Use `Badge` for compact non-interactive metadata.** Configure its semantic
459
+ tone, appearance, shape, and size instead of creating badge CSS in an app or
460
+ consuming component. Use a real button or link for interactive content.
461
+ For new content without a count, use the text-free `size="dot"` form: it
462
+ takes no children, and needs a `label` (announced as an image) or
463
+ `ariaHidden` when its owner announces it. A `TabScaffold` tab shows the dot
464
+ with `badge: true` plus its required `badgeLabel`.
465
+ - **Use `Chip` for removable tags.** Give the native remove button a delegated
466
+ `removeAction` and a specific `removeLabel`; the application updates the tag
467
+ list. `itemId` identifies the chip to the action handler. `size="compact"`
468
+ gives a 20px chip and 16px remove button; `disabled` disables removal.
93
469
 
94
470
  ## Public exports
95
471
 
96
- `LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `ToolbarText`,
97
- `PanelHeader`, `MenuItem`, `MenuActionRow`, `MenuHeader`, `SegmentedControl`,
472
+ `Badge`, `LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `ToolbarActionLink`, `FloatingToolbar`, `ToolbarText`, `Text`,
473
+ `ListItem`, `ListActionRow`, `ListHeader`, `ListInsetControl`,
474
+ `ListInsetText`, `SegmentedControl`,
98
475
  `Select`, `TokenSearchField` (+ `readTokenSearchField`, `placeTokenSearchCaret`,
99
476
  `wireTokenSearchFields`), `AppTab`, `TabBar` (+ `wireTabBars`, `reorderTabs`),
477
+ `wireScrollDividers` (scroll-state dividers for every `Pane`, `NavStack`,
478
+ `TabScaffold`, and `TabBar`),
100
479
  `ResizableRegion` (+ `wireResizableRegions`), `StateBanner`, `EmptyState`,
101
480
  `LoadingSpinner`, `Skeleton`, `ValueTable`, `ValueTableRow`. Whole-screen layouts (opt-in,
102
- tree-shakeable, declarative with `wire…` helpers, each with a companion CSS import):
481
+ tree-shakeable, declarative with `wire…` helpers; the browser build of each layout
482
+ subpath loads its CSS and that of the components it renders, and a companion
483
+ CSS subpath remains for pipelines without the `browser` condition):
103
484
  `NavStack`, `SplitView`, `Workbench`, `TabScaffold`, driven by `deviceClass()` from
104
- `@kerfjs/ui/device-class`. `@kerfjs/ui/webawesome` is a type-only boundary for
105
- `wa-*` JSX; `@kerfjs/ui/select/register` and the CSS are the declared side effects.
485
+ `@kerfjs/ui/device-class`. For a standalone collapsible rail/drawer outside a full
486
+ shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelToggle`)
487
+
488
+ - `@kerfjs/ui/wire-sidebar` (`wireSidebar`: toggle, focus, compact overlay, persistence; a compact overlay starts closed and opens only on a user action, and `inlineCollapsed` declares a panel's inline default).
489
+ `@kerfjs/ui/catalog` is another opt-in shell — a
490
+ `Catalog` component + `wireCatalog` helper for building a component-gallery catalog
491
+ (collapsible category sidebar + preview stage + resources footer, with an opt-in
492
+ transparent-bound and margin geometry overlay plus focus-preserving active-row
493
+ reveal for long desktop sidebars) from your own
494
+ entries; controlled/stateless like the layouts. For any Catalog demo, follow
495
+ the [authoritative authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
496
+ rather than inferring structure from the shell or private CSS.
497
+ `@kerfjs/ui/webawesome` is a
498
+ type-only boundary for `wa-*` JSX; `@kerfjs/ui/select/register` and the CSS are the
499
+ declared side effects.
106
500
 
107
501
  ## Reference
108
502
 
@@ -111,8 +505,11 @@ tree-shakeable, declarative with `wire…` helpers, each with a companion CSS im
111
505
  - [layout.md](./docs/layout.md): the pane/content-item geometry, public roles/tokens, and the spacing scale.
112
506
  - [component-contract.md](./docs/component-contract.md): what a component owns vs. what the app owns.
113
507
  - [accessibility.md](./docs/accessibility.md): keyboard and ARIA contracts per component.
114
- - [recipes.md](./docs/recipes.md): production compositions (app shell, master-detail dialog, composer form, …) as copyable references.
115
- - [app-layouts.md](./docs/app-layouts.md): choosing `NavStack`/`SplitView`/`Workbench`/`TabScaffold` by data + interaction + device, and dialog presentation.
116
- - [webawesome-theme.md](./docs/webawesome-theme.md): the optional Web Awesome theme; catalog coverage means themed-and-supported, not preferred (prefer the Kerf primitive when one exists).
117
- - [component-catalog.json](./ai/component-catalog.json) + [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) + [webawesome-jsx-signatures-v1.md](./ai/webawesome-jsx-signatures-v1.md): machine-readable facts and exact signatures.
508
+ - [recipes.md](./docs/recipes.md): production compositions (app shell, list-detail dialog, composer form, …) as copyable references.
509
+ - [workbench.md](./docs/workbench.md): the `Workbench` multi-panel shell, its collapse policies, and opt-in `resizable` panels driven by `wireWorkbench` (`@kerfjs/ui/wire-workbench`: drag, keyboard, min/max, persistence, compact suspension), the `mainMinSize` / `mainMinHeight` work-area minimums (default 320px wide beside any inline rail, 120px tall above the drawer) that resizable panels stop at and inline panels shrink around, and a panel's `responsiveOverlayAt` (`narrow` / `compact`, rails and the bottom drawer) that presents it as an overlay below a Workbench container breakpoint without a device-class check; a panel given its `collapsed` signal is a transient overlay (collapsed on entering the breakpoint, takes focus and keeps Tab inside while open, closed by Escape or an outside press, focus returned; `dismissOverlays`), and overlays are exclusive by default (opening one closes the others; `exclusiveOverlays: false` opts out).
510
+ - [app-layouts.md](./docs/app-layouts.md): choosing `NavStack`/`SplitView`/`Workbench`/`TabScaffold` by data + interaction + device, and dialog presentation, plus the safe-area model (surfaces paint through unsafe areas; content pads only the edges it reaches; `Pane.safeAreaEdges` for app-owned arrangements, `Toolbar.safeAreaEdges` for an app bar or bottom bar at a screen edge).
511
+ - [webawesome-theme.md](./docs/webawesome-theme.md): the optional Web Awesome theme; catalog coverage means themed-and-supported, not preferred (prefer the Kerf primitive when one exists). The UX sidebar visibly tags superseded and exceptional Web Awesome choices as `Discouraged`; Popup remains an available conditional positioning primitive.
512
+ - [ai/components/README.md](./ai/components/README.md): the generated per-component markdown reference — the assistant entry point over both JSON catalogs.
513
+ - [component-catalog.json](./ai/component-catalog.json) + [component-catalog-extension.schema.json](./ai/component-catalog-extension.schema.json) + [catalog-authoring.json](./ai/catalog-authoring.json) + [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) + [webawesome-jsx-signatures-v1.md](./ai/webawesome-jsx-signatures-v1.md): machine-readable selection facts, a reusable app-component extension contract, Catalog authoring discovery, and exact signatures.
514
+ - [compile-time-contracts-v1.json](./ai/compile-time-contracts-v1.json) + [type-contracts.md](./docs/type-contracts.md): stable compile diagnostics, packed-declaration proof, migrations, and explicit non-goals.
118
515
  - [README.md](./README.md): package overview and the component subpath table.