@kerfjs/ui 4.5.0-beta.1 → 5.0.0-beta.100

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 (980) hide show
  1. package/README.md +461 -116
  2. package/ai/application-ui-diagnostic-ids-v1.json +23 -1
  3. package/ai/application-ui-profile-sync.cjs +21 -2
  4. package/ai/application-ui-profile.d.ts +4 -0
  5. package/ai/application-ui-profile.defaults.json +63 -8
  6. package/ai/application-ui-profile.mjs +28 -1
  7. package/ai/application-ui-profile.schema.json +10 -0
  8. package/ai/catalog-authoring.json +13 -4
  9. package/ai/catalog-authoring.schema.json +52 -8
  10. package/ai/compile-time-contracts-v1.json +63 -16
  11. package/ai/compile-time-contracts-v1.schema.json +4 -1
  12. package/ai/component-catalog-extension.schema.json +25 -0
  13. package/ai/component-catalog.json +5585 -1175
  14. package/ai/component-catalog.schema.json +78 -1
  15. package/ai/component-class-owners.cjs +83 -0
  16. package/ai/component-composition-extension.d.ts +7 -0
  17. package/ai/component-composition-extension.schema.json +7 -0
  18. package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +281 -49
  19. package/ai/component-composition.d.ts +132 -0
  20. package/ai/component-composition.json +8729 -0
  21. package/ai/component-composition.schema.json +412 -0
  22. package/ai/components/README.md +185 -0
  23. package/ai/components/anchored-surface.md +99 -0
  24. package/ai/components/application-tabs.md +65 -0
  25. package/ai/components/badge.md +76 -0
  26. package/ai/components/chip.md +76 -0
  27. package/ai/components/choice-chips.md +87 -0
  28. package/ai/components/collapsible-panel.md +103 -0
  29. package/ai/components/column-track.md +78 -0
  30. package/ai/components/combobox.md +88 -0
  31. package/ai/components/composer.md +83 -0
  32. package/ai/components/content-item.md +98 -0
  33. package/ai/components/content-swap.md +78 -0
  34. package/ai/components/corner-status.md +88 -0
  35. package/ai/components/disclosure-arrow.md +77 -0
  36. package/ai/components/document-baseline.md +77 -0
  37. package/ai/components/edge-activity-indicator.md +81 -0
  38. package/ai/components/empty-state.md +80 -0
  39. package/ai/components/feedback.md +71 -0
  40. package/ai/components/file-picker.md +88 -0
  41. package/ai/components/floating-toolbar.md +82 -0
  42. package/ai/components/foundation.md +65 -0
  43. package/ai/components/framed-list.md +80 -0
  44. package/ai/components/grid.md +101 -0
  45. package/ai/components/headers.md +63 -0
  46. package/ai/components/icon-button.md +82 -0
  47. package/ai/components/icon-toggle-button.md +80 -0
  48. package/ai/components/layout.md +75 -0
  49. package/ai/components/list-action-row.md +108 -0
  50. package/ai/components/list-header.md +91 -0
  51. package/ai/components/list-inset-control.md +74 -0
  52. package/ai/components/list-inset-text.md +72 -0
  53. package/ai/components/list-item.md +108 -0
  54. package/ai/components/list.md +125 -0
  55. package/ai/components/loading-spinner.md +73 -0
  56. package/ai/components/lucide-icon.md +97 -0
  57. package/ai/components/nav-stack.md +115 -0
  58. package/ai/components/pane.md +115 -0
  59. package/ai/components/popup-menu.md +171 -0
  60. package/ai/components/recipe-app-shell.md +57 -0
  61. package/ai/components/recipe-collapsible-sidebar.md +57 -0
  62. package/ai/components/recipe-compact-toolbar.md +57 -0
  63. package/ai/components/recipe-composer-form.md +57 -0
  64. package/ai/components/recipe-list-detail-dialog.md +57 -0
  65. package/ai/components/recipe-list-workspace-states.md +57 -0
  66. package/ai/components/recipe-loading-inspector.md +57 -0
  67. package/ai/components/recipe-navigation-sidebar.md +57 -0
  68. package/ai/components/recipe-navigation-stack.md +57 -0
  69. package/ai/components/recipe-workspace-header.md +57 -0
  70. package/ai/components/resize.md +106 -0
  71. package/ai/components/row.md +96 -0
  72. package/ai/components/segmented-control.md +82 -0
  73. package/ai/components/select.md +116 -0
  74. package/ai/components/skeleton.md +84 -0
  75. package/ai/components/spacer.md +86 -0
  76. package/ai/components/split-button.md +80 -0
  77. package/ai/components/split-view.md +105 -0
  78. package/ai/components/state-banner.md +96 -0
  79. package/ai/components/summary-row.md +85 -0
  80. package/ai/components/sunken-panel.md +79 -0
  81. package/ai/components/surface-scaffold.md +105 -0
  82. package/ai/components/tab-bar.md +114 -0
  83. package/ai/components/tab-navigator.md +100 -0
  84. package/ai/components/tabs.md +95 -0
  85. package/ai/components/text.md +90 -0
  86. package/ai/components/token-search-field.md +107 -0
  87. package/ai/components/toolbar-control-group.md +125 -0
  88. package/ai/components/toolbar-text.md +100 -0
  89. package/ai/components/toolbar.md +103 -0
  90. package/ai/components/value-table.md +80 -0
  91. package/ai/components/wa-accordion-item.md +55 -0
  92. package/ai/components/wa-accordion.md +65 -0
  93. package/ai/components/wa-animated-image.md +55 -0
  94. package/ai/components/wa-animation.md +55 -0
  95. package/ai/components/wa-avatar.md +55 -0
  96. package/ai/components/wa-badge.md +55 -0
  97. package/ai/components/wa-breadcrumb-item.md +53 -0
  98. package/ai/components/wa-breadcrumb.md +55 -0
  99. package/ai/components/wa-button-group.md +60 -0
  100. package/ai/components/wa-button.md +59 -0
  101. package/ai/components/wa-callout.md +58 -0
  102. package/ai/components/wa-card.md +59 -0
  103. package/ai/components/wa-carousel-item.md +53 -0
  104. package/ai/components/wa-carousel.md +55 -0
  105. package/ai/components/wa-checkbox-group.md +55 -0
  106. package/ai/components/wa-checkbox.md +55 -0
  107. package/ai/components/wa-color-picker.md +55 -0
  108. package/ai/components/wa-comparison.md +55 -0
  109. package/ai/components/wa-copy-button.md +55 -0
  110. package/ai/components/wa-details.md +61 -0
  111. package/ai/components/wa-dialog.md +59 -0
  112. package/ai/components/wa-divider.md +53 -0
  113. package/ai/components/wa-drawer.md +55 -0
  114. package/ai/components/wa-dropdown-item.md +60 -0
  115. package/ai/components/wa-dropdown.md +60 -0
  116. package/ai/components/wa-format-bytes.md +53 -0
  117. package/ai/components/wa-format-date.md +53 -0
  118. package/ai/components/wa-format-number.md +53 -0
  119. package/ai/components/wa-icon.md +58 -0
  120. package/ai/components/wa-include.md +53 -0
  121. package/ai/components/wa-input.md +59 -0
  122. package/ai/components/wa-intersection-observer.md +53 -0
  123. package/ai/components/wa-known-date.md +53 -0
  124. package/ai/components/wa-markdown.md +53 -0
  125. package/ai/components/wa-mutation-observer.md +53 -0
  126. package/ai/components/wa-number-input.md +55 -0
  127. package/ai/components/wa-option.md +59 -0
  128. package/ai/components/wa-otp-input.md +53 -0
  129. package/ai/components/wa-page.md +53 -0
  130. package/ai/components/wa-pagination.md +55 -0
  131. package/ai/components/wa-popover.md +55 -0
  132. package/ai/components/wa-popup.md +53 -0
  133. package/ai/components/wa-progress-bar.md +53 -0
  134. package/ai/components/wa-progress-ring.md +53 -0
  135. package/ai/components/wa-qr-code.md +53 -0
  136. package/ai/components/wa-radio-group.md +59 -0
  137. package/ai/components/wa-radio.md +55 -0
  138. package/ai/components/wa-random-content.md +53 -0
  139. package/ai/components/wa-rating.md +55 -0
  140. package/ai/components/wa-relative-time.md +53 -0
  141. package/ai/components/wa-resize-observer.md +53 -0
  142. package/ai/components/wa-scroller.md +53 -0
  143. package/ai/components/wa-select.md +63 -0
  144. package/ai/components/wa-skeleton.md +53 -0
  145. package/ai/components/wa-slider.md +55 -0
  146. package/ai/components/wa-spinner.md +58 -0
  147. package/ai/components/wa-split-panel.md +58 -0
  148. package/ai/components/wa-switch.md +53 -0
  149. package/ai/components/wa-tab-group.md +69 -0
  150. package/ai/components/wa-tab-panel.md +60 -0
  151. package/ai/components/wa-tab.md +59 -0
  152. package/ai/components/wa-tag.md +59 -0
  153. package/ai/components/wa-textarea.md +53 -0
  154. package/ai/components/wa-time-input.md +55 -0
  155. package/ai/components/wa-toast-item.md +60 -0
  156. package/ai/components/wa-toast.md +60 -0
  157. package/ai/components/wa-tooltip.md +55 -0
  158. package/ai/components/wa-tree-item.md +55 -0
  159. package/ai/components/wa-tree.md +55 -0
  160. package/ai/components/wa-zoomable-frame.md +55 -0
  161. package/ai/components/workbench.md +120 -0
  162. package/ai/public-api-signatures-v1.md +3851 -441
  163. package/ai/skill.md +402 -70
  164. package/ai/webawesome-jsx-signatures-v1.md +9 -2
  165. package/analyzer/cli.mjs +5 -2
  166. package/analyzer/component-ownership.d.mts +72 -0
  167. package/analyzer/component-ownership.mjs +429 -0
  168. package/analyzer/index.d.mts +8 -0
  169. package/analyzer/index.mjs +1687 -49
  170. package/analyzer/loud-pairs.d.mts +49 -0
  171. package/analyzer/loud-pairs.mjs +357 -0
  172. package/analyzer/selectors.d.mts +21 -0
  173. package/analyzer/selectors.mjs +212 -0
  174. package/catalog-projection-cli.mjs +96 -0
  175. package/catalog-projection.d.mts +55 -0
  176. package/catalog-projection.mjs +62 -0
  177. package/dist/anchored-surface.d.ts +69 -0
  178. package/dist/anchored-surface.js +3 -0
  179. package/dist/anchored-surface.js.map +1 -0
  180. package/dist/app-tab.d.ts +39 -4
  181. package/dist/app-tab.js +2 -1
  182. package/dist/badge.d.ts +83 -0
  183. package/dist/badge.js +4 -0
  184. package/dist/badge.js.map +1 -0
  185. package/dist/browser/anchored-surface.js +3 -0
  186. package/dist/browser/badge.js +3 -0
  187. package/dist/browser/catalog.js +28 -0
  188. package/dist/browser/chip.js +3 -0
  189. package/dist/browser/choice-chips.js +3 -0
  190. package/dist/browser/collapsible-panel.js +9 -0
  191. package/dist/browser/column-track.js +3 -0
  192. package/dist/browser/combobox.js +3 -0
  193. package/dist/browser/composer.js +4 -0
  194. package/dist/browser/content-item.js +3 -0
  195. package/dist/browser/content-swap.js +3 -0
  196. package/dist/browser/corner-status.js +3 -0
  197. package/dist/browser/edge-activity-indicator.js +3 -0
  198. package/dist/browser/file-picker.js +3 -0
  199. package/dist/browser/framed-list.js +3 -0
  200. package/dist/browser/grid.js +3 -0
  201. package/dist/browser/icon-button.js +4 -0
  202. package/dist/browser/icon-toggle-button.js +4 -0
  203. package/dist/browser/list-action-row.js +2 -0
  204. package/dist/browser/list-header.js +3 -1
  205. package/dist/browser/list-item.js +1 -0
  206. package/dist/browser/nav-stack.js +11 -0
  207. package/dist/browser/popup-menu.js +3 -0
  208. package/dist/browser/row.js +3 -0
  209. package/dist/browser/segmented-control.js +0 -1
  210. package/dist/browser/select.js +2 -1
  211. package/dist/browser/spacer.js +3 -0
  212. package/dist/browser/split-button.js +5 -0
  213. package/dist/browser/split-view.js +13 -0
  214. package/dist/browser/state-banner.js +1 -0
  215. package/dist/browser/summary-row.js +3 -0
  216. package/dist/browser/surface-scaffold.js +3 -0
  217. package/dist/browser/tab-navigator.js +4 -0
  218. package/dist/browser/text.js +3 -0
  219. package/dist/browser/toolbar-control-group.js +1 -0
  220. package/dist/browser/workbench.js +14 -0
  221. package/dist/catalog-resources.d.ts +17 -1
  222. package/dist/catalog-resources.js +5 -5
  223. package/dist/catalog-resources.js.map +1 -1
  224. package/dist/catalog.d.ts +123 -121
  225. package/dist/catalog.js +598 -269
  226. package/dist/catalog.js.map +1 -1
  227. package/dist/chip.d.ts +69 -0
  228. package/dist/chip.js +3 -0
  229. package/dist/chip.js.map +1 -0
  230. package/dist/choice-chips.d.ts +82 -0
  231. package/dist/choice-chips.js +3 -0
  232. package/dist/choice-chips.js.map +1 -0
  233. package/dist/chunk-2GOCOLQL.js +270 -0
  234. package/dist/chunk-2GOCOLQL.js.map +1 -0
  235. package/dist/chunk-2MSPNRWJ.js +82 -0
  236. package/dist/chunk-2MSPNRWJ.js.map +1 -0
  237. package/dist/chunk-34U4ANDJ.js +119 -0
  238. package/dist/chunk-34U4ANDJ.js.map +1 -0
  239. package/dist/chunk-3GLYIIFR.js +230 -0
  240. package/dist/chunk-3GLYIIFR.js.map +1 -0
  241. package/dist/{chunk-Y6LYKFXY.js → chunk-3VXDSIBJ.js} +7 -4
  242. package/dist/chunk-3VXDSIBJ.js.map +1 -0
  243. package/dist/chunk-3WYREXW4.js +120 -0
  244. package/dist/chunk-3WYREXW4.js.map +1 -0
  245. package/dist/chunk-4UB5Z3ZZ.js +68 -0
  246. package/dist/chunk-4UB5Z3ZZ.js.map +1 -0
  247. package/dist/chunk-6C6DLP3W.js +31 -0
  248. package/dist/chunk-6C6DLP3W.js.map +1 -0
  249. package/dist/chunk-7IUEBNCO.js +108 -0
  250. package/dist/chunk-7IUEBNCO.js.map +1 -0
  251. package/dist/{chunk-QO55FN2Y.js → chunk-AN5IWMTM.js} +7 -3
  252. package/dist/chunk-AN5IWMTM.js.map +1 -0
  253. package/dist/chunk-AV7CPAPT.js +82 -0
  254. package/dist/chunk-AV7CPAPT.js.map +1 -0
  255. package/dist/{chunk-PX3YSS5C.js → chunk-B53PS2LE.js} +5 -3
  256. package/dist/chunk-B53PS2LE.js.map +1 -0
  257. package/dist/chunk-CA7LNX3J.js +44 -0
  258. package/dist/chunk-CA7LNX3J.js.map +1 -0
  259. package/dist/chunk-CEJ5FK6G.js +288 -0
  260. package/dist/chunk-CEJ5FK6G.js.map +1 -0
  261. package/dist/chunk-CMETHPKR.js +175 -0
  262. package/dist/chunk-CMETHPKR.js.map +1 -0
  263. package/dist/chunk-CMLPFIC5.js +46 -0
  264. package/dist/chunk-CMLPFIC5.js.map +1 -0
  265. package/dist/{chunk-RKVQEH4J.js → chunk-CVD5IZGB.js} +10 -5
  266. package/dist/chunk-CVD5IZGB.js.map +1 -0
  267. package/dist/chunk-CXZXHZTR.js +514 -0
  268. package/dist/chunk-CXZXHZTR.js.map +1 -0
  269. package/dist/chunk-D5RGM3XA.js +38 -0
  270. package/dist/chunk-D5RGM3XA.js.map +1 -0
  271. package/dist/{chunk-KWWR5VMS.js → chunk-DZJ4GBSP.js} +19 -5
  272. package/dist/chunk-DZJ4GBSP.js.map +1 -0
  273. package/dist/chunk-EIET4QLK.js +51 -0
  274. package/dist/chunk-EIET4QLK.js.map +1 -0
  275. package/dist/chunk-ELCMSQNJ.js +49 -0
  276. package/dist/chunk-ELCMSQNJ.js.map +1 -0
  277. package/dist/chunk-EOO6PYGF.js +162 -0
  278. package/dist/chunk-EOO6PYGF.js.map +1 -0
  279. package/dist/chunk-ETCWQLJV.js +85 -0
  280. package/dist/chunk-ETCWQLJV.js.map +1 -0
  281. package/dist/chunk-FDZNYD4C.js +138 -0
  282. package/dist/chunk-FDZNYD4C.js.map +1 -0
  283. package/dist/chunk-FR76ZJQC.js +90 -0
  284. package/dist/chunk-FR76ZJQC.js.map +1 -0
  285. package/dist/chunk-G3J7JDP6.js +29 -0
  286. package/dist/chunk-G3J7JDP6.js.map +1 -0
  287. package/dist/chunk-GS2QD3N7.js +14 -0
  288. package/dist/chunk-GS2QD3N7.js.map +1 -0
  289. package/dist/chunk-HGV7J4T6.js +86 -0
  290. package/dist/chunk-HGV7J4T6.js.map +1 -0
  291. package/dist/chunk-HLDRH23D.js +84 -0
  292. package/dist/chunk-HLDRH23D.js.map +1 -0
  293. package/dist/chunk-HQZYKJ56.js +302 -0
  294. package/dist/chunk-HQZYKJ56.js.map +1 -0
  295. package/dist/chunk-HZPHCSCS.js +95 -0
  296. package/dist/chunk-HZPHCSCS.js.map +1 -0
  297. package/dist/chunk-IKS72C6P.js +53 -0
  298. package/dist/chunk-IKS72C6P.js.map +1 -0
  299. package/dist/chunk-IM3GKYOG.js +202 -0
  300. package/dist/chunk-IM3GKYOG.js.map +1 -0
  301. package/dist/{chunk-JRKSK2HX.js → chunk-INI4WDWC.js} +53 -7
  302. package/dist/chunk-INI4WDWC.js.map +1 -0
  303. package/dist/chunk-IQSRHXZR.js +164 -0
  304. package/dist/chunk-IQSRHXZR.js.map +1 -0
  305. package/dist/{chunk-M7JBER5U.js → chunk-JOR5LGYE.js} +18 -4
  306. package/dist/chunk-JOR5LGYE.js.map +1 -0
  307. package/dist/chunk-K4AT3V3J.js +545 -0
  308. package/dist/chunk-K4AT3V3J.js.map +1 -0
  309. package/dist/chunk-KCS6NJ3O.js +82 -0
  310. package/dist/chunk-KCS6NJ3O.js.map +1 -0
  311. package/dist/{chunk-SRSJO5QE.js → chunk-KH4KEMSP.js} +34 -3
  312. package/dist/chunk-KH4KEMSP.js.map +1 -0
  313. package/dist/chunk-LL45C7BB.js +122 -0
  314. package/dist/chunk-LL45C7BB.js.map +1 -0
  315. package/dist/chunk-LOSRXZAH.js +100 -0
  316. package/dist/chunk-LOSRXZAH.js.map +1 -0
  317. package/dist/{chunk-7KEUJIIC.js → chunk-MF6ZUUJZ.js} +93 -11
  318. package/dist/chunk-MF6ZUUJZ.js.map +1 -0
  319. package/dist/chunk-MHMWQ7RB.js +19 -0
  320. package/dist/chunk-MHMWQ7RB.js.map +1 -0
  321. package/dist/chunk-MJ5RU6XT.js +173 -0
  322. package/dist/chunk-MJ5RU6XT.js.map +1 -0
  323. package/dist/chunk-MXNIVEVL.js +48 -0
  324. package/dist/chunk-MXNIVEVL.js.map +1 -0
  325. package/dist/{chunk-IJBSZ4NX.js → chunk-NS2TBYM4.js} +8 -5
  326. package/dist/chunk-NS2TBYM4.js.map +1 -0
  327. package/dist/chunk-PIVY32AE.js +140 -0
  328. package/dist/chunk-PIVY32AE.js.map +1 -0
  329. package/dist/chunk-PYBBYSZ3.js +526 -0
  330. package/dist/chunk-PYBBYSZ3.js.map +1 -0
  331. package/dist/chunk-QDSZTQXL.js +28 -0
  332. package/dist/chunk-QDSZTQXL.js.map +1 -0
  333. package/dist/chunk-QH5KOFNS.js +39 -0
  334. package/dist/chunk-QH5KOFNS.js.map +1 -0
  335. package/dist/chunk-QIG4IGUP.js +139 -0
  336. package/dist/chunk-QIG4IGUP.js.map +1 -0
  337. package/dist/chunk-QLA25V2K.js +493 -0
  338. package/dist/chunk-QLA25V2K.js.map +1 -0
  339. package/dist/chunk-QROYYGWU.js +52 -0
  340. package/dist/chunk-QROYYGWU.js.map +1 -0
  341. package/dist/chunk-QYMJHS4K.js +36 -0
  342. package/dist/chunk-QYMJHS4K.js.map +1 -0
  343. package/dist/chunk-RHD7RKGI.js +176 -0
  344. package/dist/chunk-RHD7RKGI.js.map +1 -0
  345. package/dist/chunk-S2XULQEK.js +52 -0
  346. package/dist/chunk-S2XULQEK.js.map +1 -0
  347. package/dist/{chunk-LPOMRC4C.js → chunk-S3ECMF23.js} +11 -3
  348. package/dist/chunk-S3ECMF23.js.map +1 -0
  349. package/dist/chunk-S4Y3YTAI.js +35 -0
  350. package/dist/chunk-S4Y3YTAI.js.map +1 -0
  351. package/dist/chunk-S4ZGTDSG.js +18 -0
  352. package/dist/chunk-S4ZGTDSG.js.map +1 -0
  353. package/dist/{chunk-PSKN344N.js → chunk-T4WJ5VGP.js} +63 -12
  354. package/dist/chunk-T4WJ5VGP.js.map +1 -0
  355. package/dist/chunk-TDMHA7C3.js +251 -0
  356. package/dist/chunk-TDMHA7C3.js.map +1 -0
  357. package/dist/{chunk-Y45PPBDV.js → chunk-TGLUDQP2.js} +47 -14
  358. package/dist/chunk-TGLUDQP2.js.map +1 -0
  359. package/dist/chunk-TLMMFQWM.js +222 -0
  360. package/dist/chunk-TLMMFQWM.js.map +1 -0
  361. package/dist/chunk-U6QYTMDB.js +85 -0
  362. package/dist/chunk-U6QYTMDB.js.map +1 -0
  363. package/dist/chunk-UMKV7YVQ.js +20 -0
  364. package/dist/chunk-UMKV7YVQ.js.map +1 -0
  365. package/dist/chunk-VFYO3UGZ.js +45 -0
  366. package/dist/chunk-VFYO3UGZ.js.map +1 -0
  367. package/dist/chunk-W4IK7AWD.js +73 -0
  368. package/dist/chunk-W4IK7AWD.js.map +1 -0
  369. package/dist/chunk-WVS6CUCT.js +48 -0
  370. package/dist/chunk-WVS6CUCT.js.map +1 -0
  371. package/dist/chunk-Y6KT7ZTR.js +109 -0
  372. package/dist/chunk-Y6KT7ZTR.js.map +1 -0
  373. package/dist/chunk-YMUIQRWK.js +44 -0
  374. package/dist/chunk-YMUIQRWK.js.map +1 -0
  375. package/dist/chunk-YOA5W5ZH.js +807 -0
  376. package/dist/chunk-YOA5W5ZH.js.map +1 -0
  377. package/dist/chunk-YQ2AC4E2.js +59 -0
  378. package/dist/chunk-YQ2AC4E2.js.map +1 -0
  379. package/dist/chunk-ZKKO4MHC.js +25 -0
  380. package/dist/chunk-ZKKO4MHC.js.map +1 -0
  381. package/dist/chunk-ZNROKDSZ.js +54 -0
  382. package/dist/chunk-ZNROKDSZ.js.map +1 -0
  383. package/dist/collapsible-panel.d.ts +96 -17
  384. package/dist/collapsible-panel.js +104 -27
  385. package/dist/collapsible-panel.js.map +1 -1
  386. package/dist/column-track.d.ts +41 -0
  387. package/dist/column-track.js +4 -0
  388. package/dist/column-track.js.map +1 -0
  389. package/dist/combobox.d.ts +40 -0
  390. package/dist/combobox.js +3 -0
  391. package/dist/combobox.js.map +1 -0
  392. package/dist/composer.d.ts +62 -0
  393. package/dist/composer.js +5 -0
  394. package/dist/composer.js.map +1 -0
  395. package/dist/content-item.d.ts +116 -0
  396. package/dist/content-item.js +4 -0
  397. package/dist/content-item.js.map +1 -0
  398. package/dist/content-swap.d.ts +34 -0
  399. package/dist/content-swap.js +3 -0
  400. package/dist/content-swap.js.map +1 -0
  401. package/dist/corner-status.d.ts +36 -0
  402. package/dist/corner-status.js +3 -0
  403. package/dist/corner-status.js.map +1 -0
  404. package/dist/css-values.d.ts +127 -0
  405. package/dist/css-values.js +3 -0
  406. package/dist/css-values.js.map +1 -0
  407. package/dist/device-class.js +1 -1
  408. package/dist/device-class.js.map +1 -1
  409. package/dist/disclosure-arrow.d.ts +6 -1
  410. package/dist/disclosure-arrow.js +2 -1
  411. package/dist/edge-activity-indicator.d.ts +28 -0
  412. package/dist/edge-activity-indicator.js +3 -0
  413. package/dist/edge-activity-indicator.js.map +1 -0
  414. package/dist/empty-state.d.ts +5 -2
  415. package/dist/empty-state.js +2 -1
  416. package/dist/extension-attributes-mu8MFUl0.d.ts +13 -0
  417. package/dist/file-picker.d.ts +47 -0
  418. package/dist/file-picker.js +3 -0
  419. package/dist/file-picker.js.map +1 -0
  420. package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
  421. package/dist/floating-toolbar.d.ts +29 -6
  422. package/dist/floating-toolbar.js +1 -1
  423. package/dist/framed-list.d.ts +47 -0
  424. package/dist/framed-list.js +4 -0
  425. package/dist/framed-list.js.map +1 -0
  426. package/dist/grid.d.ts +58 -0
  427. package/dist/grid.js +6 -0
  428. package/dist/grid.js.map +1 -0
  429. package/dist/help-tags-register.d.ts +13 -0
  430. package/dist/help-tags-register.js +9 -0
  431. package/dist/help-tags-register.js.map +1 -0
  432. package/dist/icon-button.d.ts +46 -0
  433. package/dist/icon-button.js +6 -0
  434. package/dist/icon-button.js.map +1 -0
  435. package/dist/icon-toggle-button.d.ts +42 -0
  436. package/dist/icon-toggle-button.js +6 -0
  437. package/dist/icon-toggle-button.js.map +1 -0
  438. package/dist/index.d.ts +59 -20
  439. package/dist/index.js +66 -29
  440. package/dist/list-action-row.d.ts +69 -12
  441. package/dist/list-action-row.js +5 -1
  442. package/dist/list-header.d.ts +36 -2
  443. package/dist/list-header.js +4 -1
  444. package/dist/list-icon-tile-B8dr97OW.d.ts +18 -0
  445. package/dist/list-inset-control.d.ts +10 -4
  446. package/dist/list-inset-control.js +1 -1
  447. package/dist/list-inset-text.d.ts +17 -12
  448. package/dist/list-inset-text.js +2 -1
  449. package/dist/list-item.d.ts +49 -5
  450. package/dist/list-item.js +4 -1
  451. package/dist/list.d.ts +121 -12
  452. package/dist/list.js +5 -1
  453. package/dist/loading-spinner.d.ts +12 -2
  454. package/dist/loading-spinner.js +2 -1
  455. package/dist/lucide-icon.d.ts +15 -3
  456. package/dist/lucide-icon.js +2 -1
  457. package/dist/nav-stack-VXTumzKa.d.ts +158 -0
  458. package/dist/nav-stack.d.ts +15 -38
  459. package/dist/nav-stack.js +13 -1
  460. package/dist/pane.d.ts +111 -7
  461. package/dist/pane.js +2 -1
  462. package/dist/panel-toolbar-vg6Ir5Dy.d.ts +77 -0
  463. package/dist/popup-menu-register.d.ts +10 -0
  464. package/dist/popup-menu-register.js +336 -0
  465. package/dist/popup-menu-register.js.map +1 -0
  466. package/dist/popup-menu.d.ts +125 -0
  467. package/dist/popup-menu.js +3 -0
  468. package/dist/popup-menu.js.map +1 -0
  469. package/dist/resizable-region.d.ts +32 -3
  470. package/dist/resizable-region.js +1 -1
  471. package/dist/row.d.ts +53 -0
  472. package/dist/row.js +7 -0
  473. package/dist/row.js.map +1 -0
  474. package/dist/scroll-clearance-BikHljTc.d.ts +14 -0
  475. package/dist/segmented-control.d.ts +7 -4
  476. package/dist/segmented-control.js +1 -2
  477. package/dist/select-register.js +255 -3
  478. package/dist/select-register.js.map +1 -1
  479. package/dist/select.d.ts +95 -6
  480. package/dist/select.js +4 -1
  481. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  482. package/dist/semantic-tone-CdW013KF.d.ts +4 -0
  483. package/dist/sides-BPSWde0A.d.ts +4 -0
  484. package/dist/skeleton.d.ts +14 -7
  485. package/dist/skeleton.js +2 -1
  486. package/dist/spacer.d.ts +18 -0
  487. package/dist/spacer.js +4 -0
  488. package/dist/spacer.js.map +1 -0
  489. package/dist/split-button.d.ts +57 -0
  490. package/dist/split-button.js +7 -0
  491. package/dist/split-button.js.map +1 -0
  492. package/dist/split-view.d.ts +63 -6
  493. package/dist/split-view.js +88 -9
  494. package/dist/split-view.js.map +1 -1
  495. package/dist/state-banner.d.ts +37 -6
  496. package/dist/state-banner.js +4 -1
  497. package/dist/styles/anchored-surface.css +41 -0
  498. package/dist/styles/app-tab.css +232 -0
  499. package/dist/styles/badge.css +145 -0
  500. package/dist/styles/catalog/components/catalog-example-stack.css +14 -0
  501. package/dist/styles/catalog/components/catalog-example.css +204 -0
  502. package/dist/styles/catalog/components/catalog-stage.css +61 -0
  503. package/dist/styles/catalog/components/catalog.css +26 -0
  504. package/dist/styles/catalog.css +5 -575
  505. package/dist/styles/chip.css +208 -0
  506. package/dist/styles/choice-chips.css +154 -0
  507. package/dist/styles/collapsible-panel.css +450 -16
  508. package/dist/styles/column-track.css +57 -0
  509. package/dist/styles/combobox.css +113 -0
  510. package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
  511. package/dist/styles/components/actions/icon-button/icon-button.css +22 -0
  512. package/dist/styles/components/actions/icon-toggle-button/icon-toggle-button.css +83 -0
  513. package/dist/styles/components/actions/popup-menu/popup-menu.css +370 -0
  514. package/dist/styles/components/actions/split-button/split-button.css +95 -0
  515. package/dist/styles/components/actions/toolbar/toolbar.css +443 -0
  516. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +1069 -0
  517. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +269 -0
  518. package/dist/styles/components/collections/framed-list/framed-list.css +47 -0
  519. package/dist/styles/components/collections/list/list.css +250 -0
  520. package/dist/styles/components/collections/list-action-row/list-action-row.css +466 -0
  521. package/dist/styles/components/collections/list-header/list-header.css +229 -0
  522. package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
  523. package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
  524. package/dist/styles/components/collections/list-item/list-item.css +461 -0
  525. package/dist/styles/components/collections/summary-row/summary-row.css +161 -0
  526. package/dist/styles/components/data-display/value-table/value-table.css +183 -0
  527. package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +41 -0
  528. package/dist/styles/components/feedback/badge/badge.css +145 -0
  529. package/dist/styles/components/feedback/chip/chip.css +208 -0
  530. package/dist/styles/components/feedback/corner-status/corner-status.css +60 -0
  531. package/dist/styles/components/feedback/edge-activity-indicator/edge-activity-indicator.css +127 -0
  532. package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
  533. package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
  534. package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
  535. package/dist/styles/components/feedback/state-banner/state-banner.css +297 -0
  536. package/dist/styles/components/forms/choice-chips/choice-chips.css +154 -0
  537. package/dist/styles/components/forms/combobox/combobox.css +113 -0
  538. package/dist/styles/components/forms/composer/composer.css +100 -0
  539. package/dist/styles/components/forms/file-picker/file-picker.css +81 -0
  540. package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
  541. package/dist/styles/components/forms/select/select.css +455 -0
  542. package/dist/styles/components/forms/token-search-field/token-search-field.css +432 -0
  543. package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
  544. package/dist/styles/components/layout/column-track/column-track.css +57 -0
  545. package/dist/styles/components/layout/content-swap/content-swap.css +154 -0
  546. package/dist/styles/components/layout/grid/grid.css +88 -0
  547. package/dist/styles/components/layout/pane/pane.css +382 -0
  548. package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
  549. package/dist/styles/components/layout/row/row.css +114 -0
  550. package/dist/styles/components/layout/spacer/spacer.css +11 -0
  551. package/dist/styles/components/layout/split-view/split-view.css +146 -0
  552. package/dist/styles/components/layout/workbench/workbench.css +1086 -0
  553. package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
  554. package/dist/styles/components/navigation/app-tab/app-tab.css +384 -0
  555. package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
  556. package/dist/styles/components/navigation/nav-stack/nav-stack.css +342 -0
  557. package/dist/styles/components/navigation/tab-bar/tab-bar.css +197 -0
  558. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +325 -0
  559. package/dist/styles/components/surfaces/content-item/content-item.css +138 -0
  560. package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +31 -0
  561. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +425 -0
  562. package/dist/styles/components/typography/text/text.css +220 -0
  563. package/dist/styles/composer.css +100 -0
  564. package/dist/styles/content-item.css +138 -0
  565. package/dist/styles/content-swap.css +154 -0
  566. package/dist/styles/corner-status.css +60 -0
  567. package/dist/styles/document.css +98 -0
  568. package/dist/styles/edge-activity-indicator.css +127 -0
  569. package/dist/styles/file-picker.css +81 -0
  570. package/dist/styles/floating-toolbar.css +87 -6
  571. package/dist/styles/foundation.css +254 -53
  572. package/dist/styles/framed-list.css +47 -0
  573. package/dist/styles/grid.css +88 -0
  574. package/dist/styles/icon-button.css +22 -0
  575. package/dist/styles/icon-toggle-button.css +83 -0
  576. package/dist/styles/layout.css +1 -21
  577. package/dist/styles/list-action-row.css +323 -17
  578. package/dist/styles/list-header.css +128 -59
  579. package/dist/styles/list-inset-control.css +25 -2
  580. package/dist/styles/list-inset-text.css +27 -12
  581. package/dist/styles/list-item.css +371 -33
  582. package/dist/styles/list.css +214 -7
  583. package/dist/styles/loading-spinner.css +4 -0
  584. package/dist/styles/lucide-icon.css +9 -0
  585. package/dist/styles/nav-stack.css +280 -49
  586. package/dist/styles/pane.css +322 -2
  587. package/dist/styles/popup-menu.css +370 -0
  588. package/dist/styles/resizable-region.css +438 -4
  589. package/dist/styles/row.css +114 -0
  590. package/dist/styles/segmented-control.css +34 -3
  591. package/dist/styles/select.css +338 -23
  592. package/dist/styles/skeleton.css +64 -3
  593. package/dist/styles/spacer.css +11 -0
  594. package/dist/styles/split-button.css +95 -0
  595. package/dist/styles/split-view.css +114 -3
  596. package/dist/styles/state-banner.css +141 -42
  597. package/dist/styles/styles.css +22 -1
  598. package/dist/styles/summary-row.css +161 -0
  599. package/dist/styles/sunken-panel.css +13 -4
  600. package/dist/styles/surface-scaffold.css +425 -0
  601. package/dist/styles/tab-bar.css +161 -9
  602. package/dist/styles/tab-navigator.css +325 -0
  603. package/dist/styles/text.css +220 -0
  604. package/dist/styles/token-search-field.css +202 -59
  605. package/dist/styles/toolbar-control-group.css +886 -42
  606. package/dist/styles/toolbar-text.css +184 -7
  607. package/dist/styles/toolbar.css +363 -17
  608. package/dist/styles/value-table.css +115 -7
  609. package/dist/styles/webawesome.css +282 -20
  610. package/dist/styles/workbench.css +999 -7
  611. package/dist/summary-row.d.ts +56 -0
  612. package/dist/summary-row.js +4 -0
  613. package/dist/summary-row.js.map +1 -0
  614. package/dist/sunken-panel.d.ts +23 -4
  615. package/dist/sunken-panel.js +2 -1
  616. package/dist/surface-scaffold-register.d.ts +9 -0
  617. package/dist/surface-scaffold-register.js +151 -0
  618. package/dist/surface-scaffold-register.js.map +1 -0
  619. package/dist/surface-scaffold.d.ts +170 -0
  620. package/dist/surface-scaffold.js +4 -0
  621. package/dist/surface-scaffold.js.map +1 -0
  622. package/dist/tab-bar.d.ts +31 -6
  623. package/dist/tab-bar.js +1 -1
  624. package/dist/tab-navigator.d.ts +114 -0
  625. package/dist/tab-navigator.js +102 -0
  626. package/dist/tab-navigator.js.map +1 -0
  627. package/dist/text.d.ts +98 -0
  628. package/dist/text.js +3 -0
  629. package/dist/text.js.map +1 -0
  630. package/dist/token-search-field.d.ts +3 -59
  631. package/dist/token-search-field.js +2 -1
  632. package/dist/token-search-model-aYR0YAei.d.ts +184 -0
  633. package/dist/token-search-model.d.ts +3 -0
  634. package/dist/token-search-model.js +3 -0
  635. package/dist/token-search-model.js.map +1 -0
  636. package/dist/toolbar-control-group.d.ts +87 -4
  637. package/dist/toolbar-control-group.js +3 -1
  638. package/dist/toolbar-text.d.ts +46 -12
  639. package/dist/toolbar-text.js +2 -1
  640. package/dist/toolbar.d.ts +71 -9
  641. package/dist/toolbar.js +1 -1
  642. package/dist/types-CVgIwSdq.d.ts +189 -0
  643. package/dist/value-table.d.ts +30 -4
  644. package/dist/value-table.js +2 -1
  645. package/dist/webawesome.d.ts +8 -1
  646. package/dist/wire-catalog.d.ts +88 -13
  647. package/dist/wire-catalog.js +240 -206
  648. package/dist/wire-catalog.js.map +1 -1
  649. package/dist/wire-comboboxes.d.ts +26 -0
  650. package/dist/wire-comboboxes.js +3 -0
  651. package/dist/wire-comboboxes.js.map +1 -0
  652. package/dist/wire-composers.d.ts +16 -0
  653. package/dist/wire-composers.js +3 -0
  654. package/dist/wire-composers.js.map +1 -0
  655. package/dist/wire-content-items.d.ts +11 -0
  656. package/dist/wire-content-items.js +139 -0
  657. package/dist/wire-content-items.js.map +1 -0
  658. package/dist/wire-corner-status.d.ts +11 -0
  659. package/dist/wire-corner-status.js +3 -0
  660. package/dist/wire-corner-status.js.map +1 -0
  661. package/dist/wire-file-pickers.d.ts +26 -0
  662. package/dist/wire-file-pickers.js +3 -0
  663. package/dist/wire-file-pickers.js.map +1 -0
  664. package/dist/wire-list-focus-scroll.d.ts +16 -0
  665. package/dist/wire-list-focus-scroll.js +3 -0
  666. package/dist/wire-list-focus-scroll.js.map +1 -0
  667. package/dist/wire-list-reorder.d.ts +41 -0
  668. package/dist/wire-list-reorder.js +3 -0
  669. package/dist/wire-list-reorder.js.map +1 -0
  670. package/dist/wire-nav-stack.d.ts +4 -1
  671. package/dist/wire-nav-stack.js +312 -16
  672. package/dist/wire-nav-stack.js.map +1 -1
  673. package/dist/wire-resizable-regions.d.ts +2 -1
  674. package/dist/wire-resizable-regions.js +2 -1
  675. package/dist/wire-scroll-dividers.d.ts +87 -0
  676. package/dist/wire-scroll-dividers.js +3 -0
  677. package/dist/wire-scroll-dividers.js.map +1 -0
  678. package/dist/wire-sidebar.d.ts +24 -4
  679. package/dist/wire-sidebar.js +122 -19
  680. package/dist/wire-sidebar.js.map +1 -1
  681. package/dist/wire-tab-bars.d.ts +1 -0
  682. package/dist/wire-tab-bars.js +1 -1
  683. package/dist/wire-tab-navigator.d.ts +13 -0
  684. package/dist/wire-tab-navigator.js +153 -0
  685. package/dist/wire-tab-navigator.js.map +1 -0
  686. package/dist/wire-token-search-fields.d.ts +5 -1
  687. package/dist/wire-token-search-fields.js +2 -1
  688. package/dist/wire-toolbar-visibility.d.ts +13 -0
  689. package/dist/wire-toolbar-visibility.js +3 -0
  690. package/dist/wire-toolbar-visibility.js.map +1 -0
  691. package/dist/wire-workbench.d.ts +116 -0
  692. package/dist/wire-workbench.js +6 -0
  693. package/dist/wire-workbench.js.map +1 -0
  694. package/dist/workbench.d.ts +253 -10
  695. package/dist/workbench.js +20 -62
  696. package/dist/workbench.js.map +1 -1
  697. package/docs/accessibility.md +617 -32
  698. package/docs/anchored-surface.md +101 -0
  699. package/docs/app-layouts.md +159 -10
  700. package/docs/apple-hig.md +2 -0
  701. package/docs/catalog.md +403 -110
  702. package/docs/collapsible-panel.md +272 -16
  703. package/docs/component-contract.md +700 -79
  704. package/docs/component-integration.md +75 -0
  705. package/docs/component-selection.md +908 -79
  706. package/docs/composer.md +143 -0
  707. package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -0
  708. package/docs/design/templates/choice-chips/color-palette.svg +1 -0
  709. package/docs/design/templates/choice-chips/compact-icons-dark.svg +1 -0
  710. package/docs/design/templates/choice-chips/compact-icons.svg +1 -0
  711. package/docs/design/templates/choice-chips/multiple-dark.svg +1 -0
  712. package/docs/design/templates/choice-chips/multiple.svg +1 -0
  713. package/docs/design/templates/choice-chips-dark.svg +1 -0
  714. package/docs/design/templates/choice-chips.svg +1 -0
  715. package/docs/design/templates/composer/chat-dark.svg +1 -0
  716. package/docs/design/templates/composer/chat.svg +1 -0
  717. package/docs/design/templates/composer/prompt-dark.svg +1 -0
  718. package/docs/design/templates/composer/prompt.svg +1 -0
  719. package/docs/design/templates/composer-dark.svg +1 -0
  720. package/docs/design/templates/composer.svg +1 -0
  721. package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
  722. package/docs/design/templates/empty-state/filtered.svg +1 -1
  723. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  724. package/docs/design/templates/empty-state/with-action.svg +1 -1
  725. package/docs/design/templates/empty-state-dark.svg +1 -1
  726. package/docs/design/templates/empty-state.svg +1 -1
  727. package/docs/design/templates/list/compact-dark.svg +1 -1
  728. package/docs/design/templates/list/compact.svg +1 -1
  729. package/docs/design/templates/list/stack-dark.svg +1 -1
  730. package/docs/design/templates/list/stack.svg +1 -1
  731. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  732. package/docs/design/templates/list-action-row/default.svg +1 -1
  733. package/docs/design/templates/list-action-row/icon-tile-dark.svg +1 -0
  734. package/docs/design/templates/list-action-row/icon-tile.svg +1 -0
  735. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  736. package/docs/design/templates/list-action-row/selected.svg +1 -1
  737. package/docs/design/templates/list-action-row/trailing-menu-dark.svg +1 -0
  738. package/docs/design/templates/list-action-row/trailing-menu.svg +1 -0
  739. package/docs/design/templates/list-action-row-dark.svg +1 -1
  740. package/docs/design/templates/list-action-row.svg +1 -1
  741. package/docs/design/templates/list-dark.svg +1 -1
  742. package/docs/design/templates/list-header/action-dark.svg +1 -1
  743. package/docs/design/templates/list-header/action.svg +1 -1
  744. package/docs/design/templates/list-header/count-dark.svg +1 -1
  745. package/docs/design/templates/list-header/count.svg +1 -1
  746. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  747. package/docs/design/templates/list-header/inline-action.svg +1 -0
  748. package/docs/design/templates/list-header/size-l-dark.svg +1 -0
  749. package/docs/design/templates/list-header/size-l.svg +1 -0
  750. package/docs/design/templates/list-header/size-m-dark.svg +1 -0
  751. package/docs/design/templates/list-header/size-m.svg +1 -0
  752. package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
  753. package/docs/design/templates/list-header/size-xl.svg +1 -0
  754. package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
  755. package/docs/design/templates/list-header/size-xs.svg +1 -0
  756. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -1
  757. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -1
  758. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
  759. package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
  760. package/docs/design/templates/list-header-dark.svg +1 -1
  761. package/docs/design/templates/list-header.svg +1 -1
  762. package/docs/design/templates/list-item/default-dark.svg +1 -1
  763. package/docs/design/templates/list-item/default.svg +1 -1
  764. package/docs/design/templates/list-item/icon-tile-dark.svg +1 -0
  765. package/docs/design/templates/list-item/icon-tile.svg +1 -0
  766. package/docs/design/templates/list-item/multiline-dark.svg +1 -1
  767. package/docs/design/templates/list-item/multiline.svg +1 -1
  768. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  769. package/docs/design/templates/list-item/selected.svg +1 -1
  770. package/docs/design/templates/list-item/trailing-dark.svg +1 -1
  771. package/docs/design/templates/list-item/trailing.svg +1 -1
  772. package/docs/design/templates/list-item-dark.svg +1 -1
  773. package/docs/design/templates/list-item.svg +1 -1
  774. package/docs/design/templates/list.svg +1 -1
  775. package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
  776. package/docs/design/templates/segmented-control/equal.svg +1 -1
  777. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
  778. package/docs/design/templates/segmented-control/pill-small.svg +1 -1
  779. package/docs/design/templates/segmented-control-dark.svg +1 -1
  780. package/docs/design/templates/segmented-control.svg +1 -1
  781. package/docs/design/templates/skeleton-dark.svg +1 -1
  782. package/docs/design/templates/skeleton.svg +1 -1
  783. package/docs/design/templates/state-banner/danger-dark.svg +1 -1
  784. package/docs/design/templates/state-banner/danger.svg +1 -1
  785. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
  786. package/docs/design/templates/state-banner/info-badge.svg +1 -1
  787. package/docs/design/templates/state-banner/info-dark.svg +1 -1
  788. package/docs/design/templates/state-banner/info.svg +1 -1
  789. package/docs/design/templates/state-banner/strip-dark.svg +1 -0
  790. package/docs/design/templates/state-banner/strip.svg +1 -0
  791. package/docs/design/templates/state-banner/success-dark.svg +1 -1
  792. package/docs/design/templates/state-banner/success.svg +1 -1
  793. package/docs/design/templates/state-banner/warning-dark.svg +1 -1
  794. package/docs/design/templates/state-banner/warning.svg +1 -1
  795. package/docs/design/templates/state-banner-dark.svg +1 -1
  796. package/docs/design/templates/state-banner.svg +1 -1
  797. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
  798. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
  799. package/docs/design/templates/tab-bar-dark.svg +1 -1
  800. package/docs/design/templates/tab-bar.svg +1 -1
  801. package/docs/design/templates/token-search-field/empty-dark.svg +1 -1
  802. package/docs/design/templates/token-search-field/empty.svg +1 -1
  803. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -1
  804. package/docs/design/templates/token-search-field/tokens.svg +1 -1
  805. package/docs/design/templates/token-search-field-dark.svg +1 -1
  806. package/docs/design/templates/token-search-field.svg +1 -1
  807. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  808. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  809. package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -0
  810. package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
  811. package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
  812. package/docs/design/templates/toolbar/width-visibility-600.svg +1 -0
  813. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -1
  814. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -1
  815. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -1
  816. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -1
  817. package/docs/design/templates/toolbar-control-group/icon-tile-brand-dark.svg +1 -0
  818. package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
  819. package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
  820. package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
  821. package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
  822. package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
  823. package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
  824. package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
  825. package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
  826. package/docs/design/templates/toolbar-control-group/icon-tile-warning.svg +1 -0
  827. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -1
  828. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -1
  829. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
  830. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
  831. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  832. package/docs/design/templates/toolbar-control-group.svg +1 -1
  833. package/docs/design/templates/toolbar-dark.svg +1 -1
  834. package/docs/design/templates/toolbar-text/dark-tone-dark.svg +1 -0
  835. package/docs/design/templates/toolbar-text/dark-tone.svg +1 -0
  836. package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
  837. package/docs/design/templates/toolbar-text/default.svg +1 -1
  838. package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
  839. package/docs/design/templates/toolbar-text/large.svg +1 -1
  840. package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
  841. package/docs/design/templates/toolbar-text/small.svg +1 -1
  842. package/docs/design/templates/toolbar-text-dark.svg +1 -1
  843. package/docs/design/templates/toolbar-text.svg +1 -1
  844. package/docs/design/templates/toolbar.svg +1 -1
  845. package/docs/design/templates/value-table/details-dark.svg +1 -1
  846. package/docs/design/templates/value-table/details.svg +1 -1
  847. package/docs/design/templates/value-table-dark.svg +1 -1
  848. package/docs/design/templates/value-table.svg +1 -1
  849. package/docs/design/templates.md +19 -9
  850. package/docs/design-philosophy.md +58 -11
  851. package/docs/device-class.md +2 -1
  852. package/docs/document-baseline.md +93 -0
  853. package/docs/examples/application-ui-profile.json +8 -8
  854. package/docs/examples/command-palette-adapter.tsx +9 -7
  855. package/docs/examples/component-catalog-extension.json +8 -1
  856. package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +8 -9
  857. package/docs/layout.md +764 -40
  858. package/docs/nav-stack.md +275 -11
  859. package/docs/recipes.md +125 -69
  860. package/docs/split-view.md +94 -5
  861. package/docs/sunken-panel.md +54 -1
  862. package/docs/surface-scaffold.md +270 -0
  863. package/docs/tab-navigator.md +255 -0
  864. package/docs/type-contracts.md +57 -22
  865. package/docs/ui-analyzer.md +334 -14
  866. package/docs/ui-doctor.md +207 -10
  867. package/docs/ui-evaluator.md +17 -0
  868. package/docs/ux-demo.md +47 -16
  869. package/docs/webawesome-theme.md +148 -14
  870. package/docs/workbench.md +600 -11
  871. package/docs/writing.md +152 -0
  872. package/doctor/cli.mjs +5 -0
  873. package/doctor/component-style-checks.mjs +457 -0
  874. package/doctor/config.schema.json +26 -0
  875. package/doctor/copy-capitalization-checks.mjs +591 -0
  876. package/doctor/eslint-diagnostics.d.mts +16 -0
  877. package/doctor/eslint-diagnostics.mjs +17 -0
  878. package/doctor/index.d.mts +6 -0
  879. package/doctor/index.mjs +214 -47
  880. package/evaluator/index.mjs +73 -8
  881. package/llms.txt +702 -56
  882. package/package.json +256 -25
  883. package/scripts/component-catalog-extension-validation.mjs +28 -0
  884. package/traversal-exclusions.mjs +60 -1
  885. package/ux-demo/recipes/app-shell.tsx +181 -189
  886. package/ux-demo/recipes/collapsible-sidebar.tsx +177 -139
  887. package/ux-demo/recipes/compact-toolbar.tsx +120 -101
  888. package/ux-demo/recipes/composer-form.tsx +86 -62
  889. package/ux-demo/recipes/list-detail-dialog.tsx +219 -114
  890. package/ux-demo/recipes/list-workspace-states.tsx +95 -80
  891. package/ux-demo/recipes/loaders.ts +5 -2
  892. package/ux-demo/recipes/loading-inspector.tsx +157 -117
  893. package/ux-demo/recipes/mount-recipe.ts +0 -5
  894. package/ux-demo/recipes/navigation-sidebar.tsx +98 -83
  895. package/ux-demo/recipes/navigation-stack.tsx +42 -29
  896. package/ux-demo/recipes/types.ts +14 -1
  897. package/ux-demo/recipes/workspace-header.tsx +77 -51
  898. package/vite-ux-review.d.mts +83 -0
  899. package/vite-ux-review.mjs +120 -0
  900. package/ai/component-catalog-extension-v2.d.ts +0 -7
  901. package/ai/component-catalog-extension-v2.schema.json +0 -7
  902. package/ai/component-catalog-v2.d.ts +0 -67
  903. package/ai/component-catalog-v2.json +0 -4675
  904. package/ai/component-catalog-v2.schema.json +0 -246
  905. package/dist/browser/panel-header.js +0 -7
  906. package/dist/chunk-5VTB2BKP.js +0 -35
  907. package/dist/chunk-5VTB2BKP.js.map +0 -1
  908. package/dist/chunk-6WTETUZ6.js +0 -21
  909. package/dist/chunk-6WTETUZ6.js.map +0 -1
  910. package/dist/chunk-7KEUJIIC.js.map +0 -1
  911. package/dist/chunk-7XRDUG4Y.js +0 -58
  912. package/dist/chunk-7XRDUG4Y.js.map +0 -1
  913. package/dist/chunk-B3A3IVO5.js +0 -83
  914. package/dist/chunk-B3A3IVO5.js.map +0 -1
  915. package/dist/chunk-DPDBVKNA.js +0 -113
  916. package/dist/chunk-DPDBVKNA.js.map +0 -1
  917. package/dist/chunk-FEAMR7S4.js +0 -68
  918. package/dist/chunk-FEAMR7S4.js.map +0 -1
  919. package/dist/chunk-FEY65TBV.js +0 -15
  920. package/dist/chunk-FEY65TBV.js.map +0 -1
  921. package/dist/chunk-IJBSZ4NX.js.map +0 -1
  922. package/dist/chunk-J5BFYY7Q.js +0 -35
  923. package/dist/chunk-J5BFYY7Q.js.map +0 -1
  924. package/dist/chunk-JRKSK2HX.js.map +0 -1
  925. package/dist/chunk-KWWR5VMS.js.map +0 -1
  926. package/dist/chunk-LPOMRC4C.js.map +0 -1
  927. package/dist/chunk-M7JBER5U.js.map +0 -1
  928. package/dist/chunk-NENBUYX5.js +0 -79
  929. package/dist/chunk-NENBUYX5.js.map +0 -1
  930. package/dist/chunk-NWSEP5RT.js +0 -117
  931. package/dist/chunk-NWSEP5RT.js.map +0 -1
  932. package/dist/chunk-OJWWHFH3.js +0 -426
  933. package/dist/chunk-OJWWHFH3.js.map +0 -1
  934. package/dist/chunk-PSKN344N.js.map +0 -1
  935. package/dist/chunk-PX3YSS5C.js.map +0 -1
  936. package/dist/chunk-QO55FN2Y.js.map +0 -1
  937. package/dist/chunk-R7ZWUN64.js +0 -38
  938. package/dist/chunk-R7ZWUN64.js.map +0 -1
  939. package/dist/chunk-RKVQEH4J.js.map +0 -1
  940. package/dist/chunk-SRSJO5QE.js.map +0 -1
  941. package/dist/chunk-SYDMYBPG.js +0 -31
  942. package/dist/chunk-SYDMYBPG.js.map +0 -1
  943. package/dist/chunk-TB6DY7H5.js +0 -25
  944. package/dist/chunk-TB6DY7H5.js.map +0 -1
  945. package/dist/chunk-UFZKLBCF.js +0 -108
  946. package/dist/chunk-UFZKLBCF.js.map +0 -1
  947. package/dist/chunk-UKKSMZYT.js +0 -281
  948. package/dist/chunk-UKKSMZYT.js.map +0 -1
  949. package/dist/chunk-W2FK7ZNY.js +0 -26
  950. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  951. package/dist/chunk-W5L2JSBY.js +0 -40
  952. package/dist/chunk-W5L2JSBY.js.map +0 -1
  953. package/dist/chunk-Y45PPBDV.js.map +0 -1
  954. package/dist/chunk-Y6LYKFXY.js.map +0 -1
  955. package/dist/divider-sides-267FA7sY.d.ts +0 -4
  956. package/dist/panel-header.d.ts +0 -42
  957. package/dist/panel-header.js +0 -7
  958. package/dist/panel-header.js.map +0 -1
  959. package/dist/styles/panel-header.css +0 -64
  960. package/dist/styles/tab-scaffold.css +0 -84
  961. package/dist/tab-scaffold.d.ts +0 -30
  962. package/dist/tab-scaffold.js +0 -51
  963. package/dist/tab-scaffold.js.map +0 -1
  964. package/dist/wire-tab-scaffold.d.ts +0 -11
  965. package/dist/wire-tab-scaffold.js +0 -21
  966. package/dist/wire-tab-scaffold.js.map +0 -1
  967. package/docs/design/templates/panel-header/icon-actions-dark.svg +0 -1
  968. package/docs/design/templates/panel-header/icon-actions.svg +0 -1
  969. package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +0 -1
  970. package/docs/design/templates/panel-header/icon-summary-actions.svg +0 -1
  971. package/docs/design/templates/panel-header/no-icon-dark.svg +0 -1
  972. package/docs/design/templates/panel-header/no-icon.svg +0 -1
  973. package/docs/design/templates/panel-header/page-heading-dark.svg +0 -1
  974. package/docs/design/templates/panel-header/page-heading.svg +0 -1
  975. package/docs/design/templates/panel-header/title-only-dark.svg +0 -1
  976. package/docs/design/templates/panel-header/title-only.svg +0 -1
  977. package/docs/design/templates/panel-header-dark.svg +0 -1
  978. package/docs/design/templates/panel-header.svg +0 -1
  979. package/docs/tab-scaffold.md +0 -50
  980. package/ux-demo/recipes/recipes.css +0 -448
package/docs/catalog.md CHANGED
@@ -6,39 +6,88 @@ footer that the kerf UI catalog itself uses. Point it at your own components and
6
6
  you get the same shell without rebuilding it. Like the app layouts, it is a
7
7
  subpath-only, tree-shakeable module that adds nothing to the main barrel.
8
8
 
9
+ The shell is a [`Workbench`](workbench.md) built entirely from `@kerfjs/ui`
10
+ components: the sidebar is its left rail and the active entry its work area. So
11
+ the sidebar behaves like any Workbench rail — its standard toggle moves into the
12
+ entry toolbar while it is collapsed, and on a small screen (a Workbench narrower
13
+ than 704px) it overlays the stage, one tap from the entry toolbar, filling the
14
+ width less a 44px strip that closes it, instead of squeezing the stage. Pass the
15
+ app's `collapsed` signal to `wireCatalog` so that overlay closes on Escape, on a
16
+ press outside, and when an entry is chosen from it.
17
+
9
18
  ```bash
10
19
  npm install @kerfjs/ui # kerfjs is a peer; @kerfjs/ui/select/register is needed only if entries use `related`
11
20
  ```
12
21
 
13
22
  - `Catalog(props)` returns the shell as `SafeHtml` (a `<main class="kui-catalog">`).
14
- It is **controlled and stateless**: your app owns the `active`, `collapsed`, and
15
- `theme` signals and computes the preview `content` from `active` in its own
23
+ It is **controlled and stateless**: your app owns the `active`, `collapsed`,
24
+ `theme`, and optional display-preference signals and computes the preview `content` from `active` in its own
16
25
  `mount()` render.
17
26
  - `wireCatalog(root, options)` wires the interactions (sidebar selection, the
18
- related-entry popup menu, and the collapse/theme toggles) with one delegated
19
- listener set and returns a disposer; it can also mirror the active id into the
20
- URL and reveal the active sidebar row after a controlled render.
27
+ related-entry popup menu, the built-in sidebar filter, and the collapse/display
28
+ toggles and background chooser) with one delegated listener set and returns a disposer; it can also
29
+ mirror the active id into the URL and reveal the active sidebar row after a
30
+ controlled render.
21
31
 
22
32
  ## What you supply
23
33
 
24
34
  - **`sections`** — category-grouped entries: `{ category, entries: [{ id, name,
25
35
  description?, tags?, resources?, related? }] }`. Each entry becomes a sidebar
26
- `ListItem` under a `ListHeader` for its category. Short `tags` render as quiet
27
- trailing pills for decision metadata such as `Discouraged`.
36
+ `ListItem` under a `ListHeader` for its category. Short `tags` render through
37
+ the row's quiet status treatment for decision metadata such as `Discouraged`.
28
38
  - **`content`** — the rendered preview for the active entry. Keep a map of `id →
29
39
  () => SafeHtml` in your app and call `renderers[active]()` in your render.
30
- - **`brand`** — `{ title, subtitle?, logoUrl? }` for the sidebar header.
40
+ - **`backgroundStyle`** — the preview stage backdrop: `checkerboard` (default,
41
+ 8px squares),
42
+ `vertical-stripes` (alternating 8px bands), `layout-guide` (single-pixel
43
+ vertical rules at 15px, 23px, and 32px from the stage edge), `surface`, or `sunken`. The
44
+ patterned choices share the main Pane's sunken surface and reveal transparent
45
+ specimen edges; `surface` paints an
46
+ opaque backdrop. `sunken` leaves the stage
47
+ transparent so the main Pane's semitransparent sunken surface paints only once.
48
+ A controlled app may pass its current choice on each render.
49
+ - **Display controls** — `increasedContrast` and `reducedMotion` each show a
50
+ pressed-state toggle when their boolean value is supplied. `backgroundControl`
51
+ shows a `PopupMenu` for the five preview backdrops, marking the current
52
+ `backgroundStyle` as checked. These controls share the entry toolbar's compact,
53
+ wrapping display group with the optional theme toggle. Pass callbacks through
54
+ `wireCatalog`'s `onToggleContrast`, `onToggleMotion`, and `onSelectBackground`;
55
+ update your own signals, apply contrast/motion preferences to your app, and
56
+ persist them there if needed. `Catalog` does not change the document theme,
57
+ classes, or storage. Register `@kerfjs/ui/popup-menu/register` when showing the
58
+ background chooser.
59
+ - **`brand`** — `{ title, subtitle?, logoUrl? }` for the sidebar header. The
60
+ optional logo paints through `ToolbarControlGroup.avatarImage`.
31
61
  - **`secondarySections`** — an optional secondary "ecosystem" group shown below the
32
62
  primary sections with a quieter treatment: `{ label, sections, collapsible?,
33
63
  expanded? }`. When `collapsible`, the label is a disclosure toggle controlling
34
64
  `expanded` (the app owns it; wire it with `wireCatalog`'s `onToggleSecondary`).
35
65
  - Optional slots: `headerActions` (extra header controls), `sidebarFooter` (extra
36
66
  sidebar content), and `status` (a footer status line).
67
+ - **`settings`** — the active entry's settings (variant and state controls for
68
+ its preview). When supplied, the Catalog renders a **Settings** pane beside the
69
+ stage (its Workbench right rail) with the standard collapse toggle: in the
70
+ pane's header while it is open, at the end of the entry toolbar while it is
71
+ collapsed. Omit it (or pass `null`) for an entry with no settings; neither the
72
+ pane nor its toggle renders. Supply only the controls — compose them from
73
+ `ListInsetControl` + `Select` (or other form components) so they share the
74
+ pane's text column; the Catalog owns the pane, its title, and its toggle.
75
+
76
+ The sidebar includes a `TokenSearchField` in its fixed header for every Catalog
77
+ consumer, so the filter remains visible while the entries scroll. `wireCatalog`
78
+ filters entry names and section headings as text is typed,
79
+ ignoring case. A heading match shows all its entries; a matching secondary
80
+ group heading searches its sections too, even while that group is collapsed.
81
+ Empty sections disappear and an empty-result message appears when nothing
82
+ matches. The query survives controlled Catalog rerenders, with the field's
83
+ placeholder hidden while text remains, and clears through the field's clear
84
+ action. Filtering does not change the selected
85
+ entry or its preview.
37
86
 
38
87
  Per-entry `resources` render as "open in new tab" links in the footer, and
39
- `related` renders a "Related entries" popup menu — a `single` `ToolbarControlGroup`
40
- around a `wa-dropdown` (grouped by each entry's `group`), so register its elements
41
- with `@kerfjs/ui/select/register` when you use it.
88
+ `related` renders a "Related Entries" `PopupMenu` in a `single`
89
+ `ToolbarControlGroup` (grouped by each entry's `group`), so register its elements
90
+ with `@kerfjs/ui/popup-menu/register` when you use it.
42
91
 
43
92
  ## Catalog demo authoring contract
44
93
 
@@ -54,14 +103,25 @@ chosen component.
54
103
 
55
104
  Classify every entry before rendering it:
56
105
 
57
- | Entry kind | Preview purpose | Geometry overlay |
58
- | --------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
59
- | Focused component | Show one public component, its meaningful variants, and adverse states. | `true`; the overlay inspects each selected specimen. |
60
- | Composition or recipe | Show several components cooperating as one product surface. | `false`; child geometry remains unmarked so the composition can be read as a whole. |
61
-
62
- Keep `geometryOverlay` present and compute it from the active entry. Do not make
63
- it a permanent catalog-wide `true`, and do not give individual specimens their
64
- own overlay implementation.
106
+ | Entry kind | Preview purpose |
107
+ | --------------- | ------------------------------------------------------------------------------------------------------- |
108
+ | **Component** | Show one public component, its meaningful variants, and adverse states. |
109
+ | **Composition** | Show components commonly used together in one focused container or surface. |
110
+ | **Recipe** | Teach the recommended production approach to a specific task, including ownership and application glue. |
111
+
112
+ These three kinds are exhaustive. Theme/foundation showcases use a functional
113
+ category, third-party specimens use source metadata, and state galleries retain
114
+ the kind of the thing they demonstrate; none needs another demo kind.
115
+
116
+ Organize the catalog by functional group, with groups in descending product
117
+ importance. Within every group, list all component demos before all composition
118
+ demos. Order each kind by descending importance where a meaningful distinction
119
+ exists, then alphabetically by display name to break ties. Put recipes after all
120
+ component/composition groups, ordered by the same importance-then-alphabetical
121
+ rule. Treat source order as the authored importance order when no explicit rank
122
+ field exists. Show a `Composition` tag rather than repeating the word in a
123
+ composition's display name; the generic `Catalog` accepts that through the
124
+ entry's `tags` array.
65
125
 
66
126
  ### Required structure
67
127
 
@@ -72,24 +132,92 @@ own overlay implementation.
72
132
  Pass `label` when the stack needs an accessible name: the rendered `section`
73
133
  is then exposed as a named region. An unlabeled stack remains an ordinary
74
134
  grouping rather than adding an unnecessary landmark.
135
+ A stack holds a 736px reading measure by default; pass `width="full"` for
136
+ application-width compositions (boards, app shells, drawers, split views) so
137
+ the stack spans the stage like a `viewport.width: "full"` row instead of
138
+ clipping them.
75
139
  - `CatalogExample` is one row: optional generated `ListHeader` label, optional
76
140
  generated note, then one specimen or one intentionally coupled specimen
77
141
  cluster. Use one row per variant/state; do not hand-author the helper's private
78
- classes.
142
+ classes. A supplied `label` also names the row's `section`, so each specimen
143
+ is a named region that assistive technology and
144
+ `getByRole("region", { name })` can address.
145
+ - Example and stack labels are headings, so they use title style ("Heading
146
+ Identity Stays Whole", "Icon Trigger in a Toolbar Group"); the `note` that
147
+ explains a specimen stays sentence style. Write a label as a name, not a
148
+ sentence. See [Writing interface copy](./writing.md#capitalization);
149
+ `kerf-ui-doctor` reports a sentence-case label as `KUI-D040`.
150
+ - Focused demos do not import local stylesheets, use inline `style`, or invent
151
+ styling-only `demo-*` classes. Prefer a public Kerf component, then a Web
152
+ Awesome surface when Kerf has no equivalent, then ordinary semantic HTML.
153
+ Use `CatalogExample.viewport` for bounded specimen width, height, frame,
154
+ surface, overflow, responsive visibility, and public custom-property values;
155
+ keep those constraints catalog-owned instead of recreating a demo stylesheet.
156
+ Widths run `sidebar` (272px, a production rail, for sidebar-pane content),
157
+ `compact` (440px), `medium` (640px), and `wide` (864px), each capped at the
158
+ stage, plus `full`; `text` and `control` size a single label or control.
159
+ Component heights run `short` (220px) through `tall` (360px); frame an app
160
+ shell, whole-screen layout, or other application-sized recipe with
161
+ `height: "app"` (592px), and give its root `fill` rather than a frame `Pane`.
162
+ An app frame stands in for the screen: it is the containing block for
163
+ screen-fixed chrome, so a compact `CollapsiblePanel` overlay, its backdrop,
164
+ and restore controls dock to the frame's edges rather than the page's.
165
+ `minHeight` (`short`, `medium`, or `app` at 592px) is a floor the frame
166
+ may grow past rather than a definite height.
167
+ - A top-layer specimen (a `popover`, a modal) that production anchors to a
168
+ named region with CSS anchor positioning anchors to the frame instead when
169
+ the frame takes that name: `viewport.anchorName` is a CSS dashed-ident
170
+ (`"--app-shell-main"`, validated; anything else throws) that becomes the
171
+ frame's `anchor-name`, so the specimen's own `position-anchor` rule resolves
172
+ to the frame. Do not wrap the specimen in a stage element to name it. Anchor
173
+ names are document-wide, so give each frame on a page its own. The frame
174
+ only names the anchor: the specimen keeps owning its placement, and as a
175
+ top-layer element it is not clipped by the frame or the stage. Chromium,
176
+ Firefox, and WebKit with CSS anchor positioning place it against the frame;
177
+ an engine without anchor positioning ignores the name, and the specimen
178
+ falls back to whatever placement its own CSS gives it there.
179
+ - For a centered reading column inside a wider frame, set
180
+ `viewport.contentWidth` (`compact` 440px, `medium` 640px, or `wide` 864px,
181
+ each capped at the frame) and `contentAlign: "center"` (the default is
182
+ `start`). Each in-flow child fills that column; `[popover]` children keep
183
+ their own geometry. The column applies to block, `grid`, and `flex-column`
184
+ frames, and `contentAlign` does nothing without `contentWidth`.
185
+
186
+ ```tsx
187
+ <CatalogExample
188
+ label="Request Docked to the Main Column"
189
+ viewport={{
190
+ layout: "flex-column",
191
+ width: "full",
192
+ minHeight: "app",
193
+ anchorName: "--app-shell-main",
194
+ contentWidth: "medium",
195
+ contentAlign: "center",
196
+ }}
197
+ >
198
+ <Transcript />
199
+ <PermissionRequestPopup /> {/* its CSS: position-anchor: --app-shell-main */}
200
+ </CatalogExample>
201
+ ```
202
+
79
203
  - The specimen is an immediate child of `CatalogExample`. A focused component
80
204
  row should place the component root there, without a decorative card or
81
205
  spacing wrapper. A composition row may place the composition root there.
82
206
 
83
207
  Use `align="glyph"` for a bare glyph/text specimen, `align="inline-control"`
84
- for a control whose own inline padding contributes about 8px, and `align="none"`
85
- (the default) for a content item or composition that owns its geometry.
208
+ for a control whose own inline padding contributes about 8px, and
209
+ `align="text-trigger"` for a Web Awesome dropdown's text trigger whose visible
210
+ label needs an 8px inset (such as a plain `PopupMenu` trigger). The dropdown host
211
+ has no layout box, so this inset applies to its button child. Use
212
+ `align="none"` (the default) for a content item or composition that owns its
213
+ geometry.
86
214
 
87
215
  ```tsx
88
216
  import { CatalogExample, CatalogExampleStack } from "@kerfjs/ui/catalog";
89
217
 
90
218
  const buttonPreview = (
91
219
  <CatalogExampleStack
92
- label="Button variants"
220
+ label="Button Variants"
93
221
  rootAttributes={{ "data-demo": "button" }}
94
222
  >
95
223
  <CatalogExample label="Icon" note="A bare glyph." align="glyph">
@@ -98,29 +226,17 @@ const buttonPreview = (
98
226
  <CatalogExample label="Control" align="inline-control">
99
227
  <SegmentedControl id="view" label="View" value="list" choices={choices} />
100
228
  </CatalogExample>
101
- <CatalogExample
102
- label="Authoring note"
103
- note="Explanatory chrome is not a specimen."
104
- rootAttributes={{ "data-catalog-geometry-overlay-skip": "" }}
105
- >
229
+ <CatalogExample label="Authoring Note" note="Explain the specimen below.">
106
230
  <p>Use the public helper contract.</p>
107
231
  </CatalogExample>
108
232
  </CatalogExampleStack>
109
233
  );
110
234
  ```
111
235
 
112
- The overlay selects every immediate child of a `CatalogExample`; the helper
113
- marks its generated label and note so they are excluded automatically. It does
114
- not recursively promote a nested child to be the specimen. Outside an example
115
- row, it selects only top-level
116
- `[data-component]` roots in the canvas and ignores nested component descendants.
117
- These rules keep a row's label/group scaffolding out of the measurement and make
118
- the authored nesting determine exactly what is inspected.
119
-
120
236
  ### Metadata ownership
121
237
 
122
- Use `rootAttributes` on either helper for authoring metadata such as `data-demo`
123
- or `data-catalog-geometry-overlay-skip`; the metadata lands on that helper's
238
+ Use `rootAttributes` on either helper for authoring metadata such as `data-demo`;
239
+ the metadata lands on that helper's
124
240
  rendered root. The slot accepts only `data-*` strings. Structural
125
241
  `data-catalog-example`, `data-catalog-example-stack`, and `data-align` semantics
126
242
  remain helper-owned and are rejected case-insensitively at runtime, including
@@ -128,54 +244,72 @@ from structurally widened or JavaScript objects. Do not copy the helpers'
128
244
  private `kui-catalog-*` classes into preview markup.
129
245
 
130
246
  The app owns entry ids, `kind`, routing, sources, relationships, and test hooks.
247
+ `Catalog.stageRootAttributes` places app-owned `data-*` state on the
248
+ catalog-owned preview stage without an extra wrapper; `data-catalog-stage`
249
+ remains protected.
250
+ The stage is the main Pane's direct scrolling content and fills its available
251
+ scroller height for short specimens, so every backdrop reaches the pane's bottom.
252
+ It grows with tall specimens and scrolls without clipping. The canvas owns the
253
+ 16px inset; the main Pane keeps its sunken appearance without a deep inset. The
254
+ Catalog's shipped CSS supplies this behavior in this package's UX demo and in
255
+ other packages' demos. Consumers should import `@kerfjs/ui/catalog` with its
256
+ browser styles (or the companion CSS subpath for manual CSS pipelines) rather
257
+ than styling Pane or stage internals.
131
258
  The helpers own their structural markers, label/note anatomy, alignment marker,
132
259
  and private classes. Component metadata such as margin/border/padding ownership
133
- lives in `component-catalog.json`; do not infer or overwrite it from overlay
134
- pixels.
135
-
136
- ### Geometry overlay and legend
137
-
138
- Pass the conditional `geometryOverlay` boolean to `Catalog`, then call
139
- `wireCatalogGeometryOverlay(root)` once after the first render and retain its
140
- disposer alongside `wireCatalog`'s.
260
+ lives in `component-catalog.json`.
141
261
 
142
- | Overlay mark | Meaning | It is not |
143
- | ----------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
144
- | Orange translucent band | A positive computed margin on the selected specimen, after subtracting the helper's alignment inset. | Padding, gap, or empty content. Zero and negative margins are not drawn. |
145
- | Accent solid edge | The selected specimen's computed border widths and radius, except `none`/`hidden` styles. | A focus ring, outline, child border, or metadata ownership claim. |
146
- | Quiet dashed outline | The border-box bound of a transparent selected specimen with no visible border. | A real CSS border, padding edge, or proof that the specimen owns size. |
262
+ ### Component metadata
147
263
 
148
- The overlay recomputes from live rendered styles when specimens resize, preview
149
- markup changes, theme/root attributes change, or loaded/inline stylesheets
150
- change. Component CSS is therefore the source of truth; do not duplicate margin
151
- or border values in demo data. The overlay does not visualize padding, gaps,
152
- negative/zero margins, scroll overflow, hit targets, or nested descendants.
153
- Inspect computed styles and the machine-readable `geometry` metadata for those
154
- facts. Opaque borderless specimens do not receive the dashed bound.
264
+ Machine-readable geometry ownership metadata identifies whether the component,
265
+ its parent, or its children are responsible for margin, border, and padding.
266
+ Keep that metadata in `component-catalog.json` and use the rendered specimen to
267
+ review the actual appearance.
155
268
 
156
- ```tsx
157
- <Catalog
158
- {...props}
159
- geometryOverlay={activeEntry.kind === "component"}
160
- content={renderers[active.value]()}
161
- />
162
- ```
163
-
164
- Put `rootAttributes={{ "data-catalog-geometry-overlay-skip": "" }}` on a
165
- `CatalogExample` or `CatalogExampleStack` only when that whole subtree is
166
- explanatory chrome rather than a specimen. The marker excludes the marked root
167
- and every descendant from selection; it does not merely hide one band. It is
168
- normally unnecessary in a composition because the active entry already sets the
169
- global overlay to `false`.
170
-
171
- Use the overlay together with machine-readable geometry ownership metadata; the
172
- overlay verifies what is rendered, while metadata tells people and AI tools
173
- whether the component, its parent, or its children are responsible for margin,
174
- border, and padding. Catalogs for downstream components should conform to the
269
+ Catalogs for downstream components should conform to the
175
270
  [`component-catalog-extension.schema.json`](../ai/component-catalog-extension.schema.json)
176
271
  contract and can start from the checked
177
272
  [`component-catalog-extension.json`](./examples/component-catalog-extension.json)
178
273
  example; provide those entries beside Kerf's shipped catalog to AI tools.
274
+ Packages that keep a `kerf.components.json` can generate this file instead of
275
+ hand-maintaining it: set `kerfComponentCatalog.selectionOutput` and run
276
+ `kerf-component-catalog` (see `create-kerf-component`'s README).
277
+ An extension entry may declare `uses` with direct Kerf or extension entry ids,
278
+ plus repository-relative `source` and `demoSource` paths. Keep the ids unique
279
+ and resolvable across both catalogs; paths use `/` separators and cannot
280
+ traverse outside the repository. These fields let consumer demos derive source
281
+ links and composition relationships from the catalog.
282
+
283
+ For a consumer UX demo, `@kerfjs/ui/catalog-projection` exports
284
+ `projectConsumerCatalog(extension, kerfCatalog, options)` and
285
+ `projectCatalogEntries(entries, options)`. The projection maps `purpose` to
286
+ `description`, `uses` to related-entry ids, `source` to `componentSource`, and
287
+ `demoSource` to the demo source link. It defaults the source identity to
288
+ `consumer` and category to `Application`. Explicit paths in an extension entry
289
+ take precedence over templates. Template placeholders are `{id}`, `{name}`,
290
+ `{kind}`, and `{package}`. Design templates are omitted unless configured.
291
+
292
+ The package also ships `kerf-catalog-demo` for a committed TypeScript module:
293
+
294
+ ```sh
295
+ kerf-catalog-demo --extension ai/component-catalog-extension.json \
296
+ --out ux-demo/catalog.generated.ts \
297
+ --repo-base https://github.com/acme/app/blob/main/ \
298
+ --source-template 'src/{id}.tsx' \
299
+ --demo-template 'ux-demo/demos/{id}.tsx' --write
300
+ kerf-catalog-demo --extension ai/component-catalog-extension.json \
301
+ --out ux-demo/catalog.generated.ts \
302
+ --repo-base https://github.com/acme/app/blob/main/ \
303
+ --source-template 'src/{id}.tsx' \
304
+ --demo-template 'ux-demo/demos/{id}.tsx' --check
305
+ ```
306
+
307
+ The command uses the Kerf catalog shipped with the package to resolve `uses`;
308
+ `--kerf-catalog` selects another catalog file. `--category`,
309
+ `--documentation-template`, and `--design-template` configure optional row
310
+ fields. `--check` fails if the generated file is missing or stale. The output
311
+ exports `generatedConsumerCatalog` and `catalogRepositoryBlobUrl`; the latter
312
+ is normalized to a trailing slash for source and documentation links.
179
313
 
180
314
  ### Automated conformance and reviewed exceptions
181
315
 
@@ -185,25 +319,30 @@ facts that source can prove without guessing at rendered intent:
185
319
 
186
320
  - focused component routes import and use `CatalogExampleStack` and
187
321
  `CatalogExample` from the public package;
188
- - focused route metadata uses the helpers' `rootAttributes` slot, example rows
189
- are not empty, and composition routes do not add redundant skip markers;
322
+ - focused route metadata uses the helpers' `rootAttributes` slot and example rows
323
+ are not empty;
190
324
  - every `@kerfjs/ui` import is a published package export and relative imports
191
325
  do not reach into `ui/src`;
192
- - demo JSX does not copy private `kui-catalog-*` structural classes; and
193
- - the shell derives both geometry-overlay enablement and documented demo mode
194
- from the active entry's source and kind.
326
+ - focused demos have no relative stylesheet imports, inline style attributes,
327
+ or styling-only `demo-*`, `wa-demo-*`, and token-search class names;
328
+ - demo JSX does not copy private `kui-catalog-*` structural classes;
329
+ - recipe sources (checked by `npm run check:recipes` with the same shared
330
+ analyzer) import no stylesheet other than public `@kerfjs/ui` CSS, set no
331
+ inline style, and name only published layout and Web Awesome classes; each
332
+ recipe declares its catalog frame through an exported `presentation`; and
333
+ - the shell derives the documented demo mode from the active entry's kind.
195
334
 
196
335
  The gate deliberately does not infer component ownership from arbitrary class
197
- names, margins, borders, or nested descendants. Runtime selection and geometry
198
- remain the browser suite's job.
336
+ names, margins, borders, or nested descendants. Runtime appearance remains the
337
+ browser suite's job.
199
338
 
200
339
  A focused route may bypass the two public layout helpers only when the route's
201
340
  stage geometry is itself the reviewed specimen. Add the narrow waiver to
202
341
  [`catalog-conformance-exceptions.json`](../ux-demo/catalog-conformance-exceptions.json)
203
342
  with the exact route, source file, stable diagnostic ids, a substantive reason,
204
343
  and the reviewing `KF-*` ticket. Only helper/metadata rules are waivable;
205
- private imports, private markup, empty examples, composition overlay drift, and
206
- shell-mode drift always fail. The gate rejects duplicate, malformed, unused,
344
+ private imports, local styling, private markup, empty examples, and shell-mode
345
+ drift always fail. The gate rejects duplicate, malformed, unused,
207
346
  and stale exceptions, so delete a waiver when its route adopts the standard
208
347
  helpers.
209
348
 
@@ -213,8 +352,8 @@ Set `revealSelection: true` on `wireCatalog` for a long desktop sidebar. After
213
352
  `onSelect` updates controlled state, the helper waits one animation frame, finds
214
353
  the exact matching `data-item-id`, and scrolls it into view without changing
215
354
  focus. A newer selection or disposal cancels the pending reveal. The default
216
- media guard is the Catalog desktop layout (`min-width: 52.01rem`), so compact
217
- layouts keep their existing scroll position.
355
+ media guard follows the Workbench's inline sidebar (`min-width: 44.01rem`), so a
356
+ closed phone overlay is never scrolled behind the user's back.
218
357
 
219
358
  Pass an options object instead of `true` to customize `block`, `inline`,
220
359
  `behavior`, or `media`; `media: false` deliberately enables the behavior at all
@@ -229,14 +368,15 @@ import {
229
368
  Catalog,
230
369
  CatalogExample,
231
370
  CatalogExampleStack,
371
+ type CatalogBackgroundStyle,
232
372
  type CatalogSection,
233
373
  } from "@kerfjs/ui/catalog";
234
374
  import {
235
375
  revealCatalogEntry,
236
376
  wireCatalog,
237
- wireCatalogGeometryOverlay,
238
377
  } from "@kerfjs/ui/wire-catalog";
239
- import "@kerfjs/ui/styles.css"; // or import each primitive's CSS + @kerfjs/ui/catalog.css
378
+ import "@kerfjs/ui/popup-menu/register"; // for the background chooser
379
+ // A CSS-aware (browser-condition) bundler loads the Catalog's CSS with its import.
240
380
 
241
381
  type DemoKind = "component" | "composition";
242
382
  type DemoEntry = CatalogSection["entries"][number] & { kind: DemoKind };
@@ -262,7 +402,10 @@ const entries: DemoEntry[] = [
262
402
  const sections: CatalogSection[] = [
263
403
  {
264
404
  category: "Examples",
265
- entries: entries.map(({ kind: _kind, ...entry }) => entry),
405
+ entries: entries.map(({ kind, ...entry }) => ({
406
+ ...entry,
407
+ tags: kind === "composition" ? ["Composition"] : undefined,
408
+ })),
266
409
  },
267
410
  ];
268
411
 
@@ -270,40 +413,38 @@ const sections: CatalogSection[] = [
270
413
  const renderers: Record<string, () => SafeHtml> = {
271
414
  button: () => (
272
415
  <CatalogExampleStack
273
- label="Button states"
416
+ label="Button States"
274
417
  rootAttributes={{ "data-demo": "button" }}
275
418
  >
276
419
  <CatalogExample label="Default" align="inline-control">
277
420
  <Button label="Save" />
278
421
  </CatalogExample>
279
- <CatalogExample
280
- label="Authoring note"
281
- note="This explanatory row is deliberately excluded from inspection."
282
- rootAttributes={{ "data-catalog-geometry-overlay-skip": "" }}
283
- >
422
+ <CatalogExample label="Authoring Note" note="Explain the specimen below.">
284
423
  <p>The application owns product copy and actions.</p>
285
424
  </CatalogExample>
286
425
  </CatalogExampleStack>
287
426
  ),
288
427
  "profile-form": () => (
289
428
  <CatalogExampleStack
290
- label="Profile form composition"
429
+ label="Profile Form Composition"
291
430
  rootAttributes={{ "data-demo": "profile-form" }}
292
431
  >
293
- <CatalogExample label="Complete composition">
432
+ <CatalogExample label="Complete Composition">
294
433
  <ProfileForm />
295
434
  </CatalogExample>
296
435
  </CatalogExampleStack>
297
436
  ),
298
437
  };
299
438
 
300
- // 3. App-owned state (domain: which entry; transient: collapsed; global: theme).
439
+ // 3. App-owned state (domain: which entry; transient: collapsed; display preferences).
301
440
  const initial =
302
441
  new URLSearchParams(location.search).get("c") ?? sections[0].entries[0].id;
303
442
  const active = signal(initial);
304
443
  const collapsed = signal(false);
305
444
  const theme = signal<"light" | "dark">("light");
306
- const activeEntry = () => entries.find(({ id }) => id === active.value) ?? entries[0];
445
+ const increasedContrast = signal(false);
446
+ const reducedMotion = signal(false);
447
+ const backgroundStyle = signal<CatalogBackgroundStyle>("checkerboard");
307
448
 
308
449
  const app = document.getElementById("app")!;
309
450
  mount(app, () => (
@@ -314,7 +455,10 @@ mount(app, () => (
314
455
  content={renderers[active.value]?.() ?? <></>}
315
456
  collapsed={collapsed.value}
316
457
  theme={theme.value}
317
- geometryOverlay={activeEntry().kind === "component"}
458
+ increasedContrast={increasedContrast.value}
459
+ reducedMotion={reducedMotion.value}
460
+ backgroundControl
461
+ backgroundStyle={backgroundStyle.value}
318
462
  />
319
463
  ));
320
464
 
@@ -329,10 +473,20 @@ wireCatalog(app, {
329
473
  theme.value = theme.value === "dark" ? "light" : "dark";
330
474
  document.documentElement.dataset.theme = theme.value; // apply your theme however you like
331
475
  },
476
+ onToggleContrast: () => {
477
+ increasedContrast.value = !increasedContrast.value;
478
+ document.documentElement.classList.toggle("increased-contrast", increasedContrast.value);
479
+ },
480
+ onToggleMotion: () => {
481
+ reducedMotion.value = !reducedMotion.value;
482
+ document.documentElement.classList.toggle("reduced-motion", reducedMotion.value);
483
+ },
484
+ onSelectBackground: (style) => {
485
+ backgroundStyle.value = style;
486
+ },
332
487
  urlParam: "c", // mirror the active id into ?c=<id>
333
488
  revealSelection: true, // reveal long desktop sidebars without moving focus
334
489
  });
335
- wireCatalogGeometryOverlay(app);
336
490
 
337
491
  // Optional for an initial deep link whose row may start outside the viewport.
338
492
  revealCatalogEntry(app, initial, { block: "center" });
@@ -345,20 +499,159 @@ revealCatalogEntry(app, initial, { block: "center" });
345
499
  - **`active`** is domain state (which entry is shown) — the app's signal, updated in
346
500
  `onSelect`, read to compute `content`.
347
501
  - **`collapsed`** is transient UI — the app's signal, flipped in `onToggleSidebar`.
502
+ Pass the same signal as `wireCatalog`'s `collapsed` option so the sidebar is
503
+ wired as a Workbench rail (transient on small screens, focus handed to the
504
+ relocated toggle).
505
+ - **`headerPlacement` / `footerPlacement`** choose whether the entry toolbar and
506
+ description, and the status + resource footer, stay pinned (`fixed`), scroll with
507
+ the preview (`scroll`), or stay pinned while the entry pane is tall enough and
508
+ scroll with the preview when it is short (`auto`, the default) — so a short
509
+ window or large text never squeezes the preview out.
510
+ The resource footer uses `ToolbarControlGroup overflow="wrap"`: whole links
511
+ move to another row when they do not fit, keeping Guidance and source labels
512
+ readable without horizontal scrolling.
513
+ - **`sidebar`** configures the sidebar rail — it forwards to the Workbench's left
514
+ rail: `size` (default 288px), `resizable` (`true` or `{ min, max }`),
515
+ `separator`, `collapseMotion`, `presentation`, `responsiveOverlayAt` (default
516
+ `narrow`), `compactOverlay` (default `inset`), and `toolbar` (the sidebar
517
+ header's `ToolbarConfig`). A resizable sidebar's width is app state like
518
+ `collapsed`: render your size signal as `sidebar.size` and pass the same signal
519
+ as `wireCatalog`'s `sidebarSize` (plus `sidebarStorageKey` to remember it).
520
+ - **`settingsCollapsed`** is transient UI like `collapsed`: render your signal as
521
+ `settingsCollapsed` and pass the same signal as `wireCatalog`'s
522
+ `settingsCollapsed`. `wireCatalog` then flips it from the toggle (report it
523
+ with `onToggleSettings`, which runs after the flip) and wires the pane as a
524
+ Workbench rail: below the `narrow` breakpoint it starts collapsed and opens as
525
+ an overlay over the stage that Escape or a press outside closes, handing focus
526
+ back to the toggle. The sidebar and settings overlays are exclusive. Without
527
+ the signal, `onToggleSettings` alone reports the press and the app flips its
528
+ own state.
529
+ - **`settingsPanel`** configures the settings pane like `sidebar` configures the
530
+ sidebar: `title` (default `Settings`; it also names the toggle), `size`
531
+ (default 288px), `resizable`, `separator`, `collapseMotion`, `presentation`,
532
+ `responsiveOverlayAt`, `compactOverlay`, and `toolbar`. A resizable pane's
533
+ width is app state: render your signal as `settingsPanel.size` and pass it as
534
+ `wireCatalog`'s `settingsSize` (plus `settingsStorageKey` to remember it).
535
+ - **`mainToolbar` / `footerToolbar`** take the entry toolbar's and the resource
536
+ footer toolbar's `ToolbarConfig` (`dividerSides`, `centerAlign`, `responsive`,
537
+ `responsiveAt`, `safeAreaEdges`). The defaults are a wrapping entry toolbar
538
+ and a footer toolbar that stacks at `narrow`, all without dividers of their
539
+ own: `wireCatalog` wires `wireScrollDividers`, so the shell's panes draw
540
+ their chrome dividers only while scrolled; an omitted or
541
+ `undefined` field keeps them. Configure these instead of styling the shell.
348
542
  - **`theme`** is a global preference — the app's signal; `wireCatalog` only reports
349
543
  the toggle, the app applies the theme (the shell reads `theme` to show the toggle's
350
544
  opposite-state label). Omit `theme` to hide the toggle entirely.
351
545
 
546
+ ## UX Review capture
547
+
548
+ On a local Vite dev or preview server the catalog can offer a **Capture Region**
549
+ header link that starts a UX Review region screenshot, preset with the project
550
+ and the active entry. Static hosting has no local project, so the link never
551
+ appears there. Three pieces wire it:
552
+
553
+ ```ts
554
+ // vite.config.ts — Node only; never part of the browser bundle.
555
+ import { uxReviewPlugin } from "@kerfjs/ui/vite-ux-review";
556
+
557
+ export default defineConfig({ plugins: [uxReviewPlugin()] });
558
+ ```
559
+
560
+ ```tsx
561
+ const uxReviewProject = signal<string | null>(null);
562
+
563
+ mount(app, () => (
564
+ <Catalog
565
+ /* …the props above… */
566
+ uxReview={
567
+ uxReviewProject.value
568
+ ? { projectDirectory: uxReviewProject.value }
569
+ : undefined
570
+ }
571
+ />
572
+ ));
573
+
574
+ wireCatalog(app, {
575
+ onSelect: (id) => (active.value = id),
576
+ onUxReviewProject: (directory) => (uxReviewProject.value = directory),
577
+ });
578
+ ```
579
+
580
+ - **`uxReviewPlugin(options?)`** answers `GET …/__ux-review/project.json` with
581
+ `{ projectDirectory }` on the dev and preview servers, at any base path. The
582
+ directory defaults to the repository holding Vite's `root` (the nearest
583
+ ancestor with `.git`, or `root` itself); pass `projectDirectory` (resolved
584
+ against `root`) to name another.
585
+ - **`wireCatalog`'s `onUxReviewProject`** asks the page's server once and
586
+ reports the directory. It is never called on static hosting or a server
587
+ without the plugin. While wired, following the link stamps the current page
588
+ URL into the capture context.
589
+ - **`Catalog`'s `uxReview`** (`{ projectDirectory, name? }`) renders the link
590
+ after `headerActions`. The capture is titled `<name>: <entry>`, and its
591
+ context names the catalog, the entry's section, and the entry; `name`
592
+ defaults to `brand.title`.
593
+
594
+ The browser helpers behind it, `uxReviewCaptureUrl` and `loadUxReviewProject`,
595
+ are exported from `@kerfjs/ui/catalog` for a capture link placed elsewhere.
596
+
597
+ ### Catalogs served without Vite
598
+
599
+ A catalog served by the app's own backend (an esbuild bundle behind Hono,
600
+ Express, or a plain Node server) mounts the same endpoint from the same
601
+ Node-only subpath, on its development server only. The catalog requests
602
+ `__ux-review/project.json` relative to its page, so a page at `/ux-demo` asks
603
+ for `/__ux-review/project.json`; both helpers answer at any base path.
604
+
605
+ ```ts
606
+ import {
607
+ resolveUxReviewProject,
608
+ uxReviewMiddleware,
609
+ uxReviewProjectResponse,
610
+ } from "@kerfjs/ui/vite-ux-review";
611
+
612
+ // Resolve once at startup: the repository holding the working directory, or
613
+ // resolveUxReviewProject({ root, projectDirectory }) like the Vite plugin.
614
+ const projectDirectory = resolveUxReviewProject();
615
+
616
+ // Fetch API servers (Hono, Bun, Deno): null means "not this endpoint".
617
+ if (isDev)
618
+ app.use("*", async (c, next) =>
619
+ uxReviewProjectResponse(c.req.raw, projectDirectory) ?? next(),
620
+ );
621
+
622
+ // Node / connect servers (Express, node:http):
623
+ if (isDev) expressApp.use(uxReviewMiddleware(projectDirectory));
624
+ ```
625
+
626
+ - **`resolveUxReviewProject({ root?, projectDirectory? })`** returns the real
627
+ path the Vite plugin would serve: `projectDirectory` resolved against `root`,
628
+ or the repository holding `root` (default `process.cwd()`).
629
+ - **`uxReviewProjectResponse(request, projectDirectory)`** answers a Fetch API
630
+ `Request`: the JSON for a GET, `405` for another method, or `null` for any
631
+ other path.
632
+ - **`uxReviewMiddleware(projectDirectory)`** is the same endpoint as a
633
+ `(request, response, next)` handler; `uxReviewPlugin` mounts it on Vite.
634
+
635
+ Never register the endpoint in production: it reveals a local path, and a
636
+ deployed catalog has no local project to capture into.
637
+
352
638
  ## Custom action names
353
639
 
354
640
  The shell emits `data-action="catalog-select"` (sidebar items),
355
- `catalog-toggle-sidebar`, and `catalog-toggle-theme`. Override them with
356
- `selectAction` / `toggleSidebarAction` / `toggleThemeAction` on `Catalog` (and the
357
- matching options on `wireCatalog`) if they collide with your own action table.
641
+ `catalog-toggle-sidebar`, `catalog-toggle-theme`, `catalog-toggle-contrast`,
642
+ `catalog-toggle-motion`, and `catalog-select-background`. Override them with
643
+ the matching `*Action` props on `Catalog` and options on `wireCatalog` if they
644
+ collide with your own action table.
358
645
 
359
646
  ## CSS
360
647
 
361
- `Catalog` composes public primitives (`Toolbar`, `ListHeader`, `ListItem`, `Select`,
362
- …). Import `@kerfjs/ui/styles.css` for the whole layer, or `@kerfjs/ui/catalog.css`
363
- plus each composed primitive's CSS. The shell is theme-aware and responsive: it
364
- stacks the sidebar above the detail below ~832px and hides it when collapsed.
648
+ `Catalog` composes public components (`Workbench`, `Pane`, `Toolbar`, `List`,
649
+ `ListHeader`, `ListItem`, `ListInsetText`, `Text`, …) and owns only the preview stage
650
+ (the checkerboard and left-aligned canvas), the example viewport
651
+ options, and the brand mark's size. A bundler that honors the `browser` export
652
+ condition loads the Catalog's stylesheets and those of every component it renders
653
+ internally with the `@kerfjs/ui/catalog` import alone — no dependence on which other
654
+ subpaths the app happens to import. Without that condition, import
655
+ `@kerfjs/ui/styles.css` for the whole layer, or `@kerfjs/ui/catalog.css` plus
656
+ `@kerfjs/ui/workbench.css` and each composed primitive's CSS. Like any Workbench it needs a definite containing height — the
657
+ `@kerfjs/ui/document.css` baseline's `.kui-app-root`.