@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
@@ -13,8 +13,28 @@ npx kerf-ui-analyze --root . --format sarif --output artifacts/kerf-ui.sarif
13
13
  The analyzer is opt-in. Add a project script such as
14
14
  `"check:kerf-ui-layout": "kerf-ui-analyze --root . src"`; it never executes
15
15
  application code. It discovers `.kerf-ui-profile.json`, joins every declared
16
- composition catalog by `package:id`, parses literal TSX/JSX class usage and CSS,
17
- and reports portable repository-relative locations.
16
+ composition catalog by `package:id`, parses literal JavaScript/TypeScript
17
+ component calls, TSX/JSX, and CSS, and reports portable repository-relative
18
+ locations.
19
+
20
+ An imported component name is resolved to a catalog entry by `package:id`, not
21
+ by display name: several entries share one (the Kerf `Select` and the Web
22
+ Awesome `wa-select` are both "Select"), so the analyzer joins each composition
23
+ entry to its selection-catalog public exports and import subpaths and picks
24
+ the entry that the import actually names. That keeps the Kerf component's
25
+ CSS-value contracts (`KUI-L013`–`KUI-L017`) in force for `Select` and
26
+ `Skeleton`.
27
+
28
+ Only component exports resolve to an entry. A selection-catalog
29
+ `publicExports` list also carries the helpers a component's props consume
30
+ (`Select` ships `uiColor`, `List` ships `px`, `rem`, and `flex`), and a helper
31
+ never inherits its entry's contracts, so `uiColor({ choices: [...] })` is not
32
+ checked as a `Select` call. A component export is one whose name starts with
33
+ an uppercase letter, the same rule JSX uses to tell a component tag from an
34
+ intrinsic element; `eslint-plugin-kerfjs` applies the identical rule, and the
35
+ package's catalog check fails if a cataloged render function (a value
36
+ returning `SafeHtml`) is lowercase or any other runtime value is uppercase.
37
+ Third-party catalogs should follow the same naming convention.
18
38
 
19
39
  Analysis is scoped per source file. Each TSX/JSX file resolves package,
20
40
  workspace, and parent-to-child directory profiles from its own location, then
@@ -35,17 +55,35 @@ policy, or analysis inputs to the containing application.
35
55
 
36
56
  ## Diagnostics and exit behavior
37
57
 
38
- | Rule | Kind | Meaning |
39
- | ---------- | ------ | ----------------------------------------------------------------- |
40
- | `KUI-L001` | error | A stylesheet reaches into a private or unknown `.kui-*` selector. |
41
- | `KUI-L002` | error | A stylesheet references an unknown or private `--kui-*` token. |
42
- | `KUI-L003` | error | One element combines public classes that claim the same geometry. |
43
- | `KUI-L004` | review | Nested literal classes both add a content inset. |
44
- | `KUI-L005` | review | Consumer CSS forces a public component's dimensions. |
45
- | `KUI-L006` | review | Literal spacing falls outside Kerf's approved scale. |
46
- | `KUI-L007` | error | A declared scroll owner is nested inside another scroll owner. |
47
- | `KUI-L008` | review | A dynamic class expression cannot be classified soundly. |
48
- | `KUI-L009` | error | A stylesheet cannot be parsed. |
58
+ | Rule | Kind | Meaning |
59
+ | ---------- | ------ | ------------------------------------------------------------------------------------- |
60
+ | `KUI-L001` | error | A stylesheet reaches into a private or unknown `.kui-*` selector. |
61
+ | `KUI-L002` | error | A stylesheet references an unknown or private `--kui-*` token. |
62
+ | `KUI-L003` | error | One element combines public classes that claim the same geometry. |
63
+ | `KUI-L004` | review | Nested literal classes both add a content inset. |
64
+ | `KUI-L005` | — | Retired; folded into `KUI-L019` (see below). |
65
+ | `KUI-L006` | review | Literal spacing falls outside Kerf's approved scale. |
66
+ | `KUI-L007` | error | A declared scroll owner is nested inside another scroll owner. |
67
+ | `KUI-L008` | review | A dynamic class expression cannot be classified soundly. |
68
+ | `KUI-L009` | error | A stylesheet cannot be parsed. |
69
+ | `KUI-L010` | error | A selector reaches a private Kerf descendant from a public root. |
70
+ | `KUI-L011` | error | A `::part()` target is not cataloged as a public extension point. |
71
+ | `KUI-L012` | error | CSS assigns a Kerf token without a public configuration contract. |
72
+ | `KUI-L013` | error | A CSS-adjacent prop uses an unknown shorthand or raw literal. |
73
+ | `KUI-L014` | error | A typed helper produces the wrong property grammar. |
74
+ | `KUI-L015` | error | An expression-only helper is passed without a composer. |
75
+ | `KUI-L016` | error | A removed declaration-list escape hatch is used. |
76
+ | `KUI-L017` | review | A valid but exceptional off-scale shorthand needs justification. |
77
+ | `KUI-L018` | review | A loud fill override lacks a governing `on-loud`, or the literal pair is below 4.5:1. |
78
+ | `KUI-L019` | error | A rule's subject is another package's component (class, `data-component`, or tag). |
79
+ | `KUI-L020` | error | CSS reads or writes another component's private `--_*` variable. |
80
+ | `KUI-L021` | error | CSS overrides a component token that a typed prop sets. |
81
+ | `KUI-L022` | error | A class placed on a component's root is styled by the application (a hook class). |
82
+ | `KUI-L023` | error | A source module renders another component's public class as its own markup. |
83
+
84
+ For `KUI-L004` and `KUI-L007`, scroll and inset declarations belong to the
85
+ subject of each CSS selector. An ancestor class used only to qualify a
86
+ descendant selector is not treated as a scroll owner or inset source.
49
87
 
50
88
  Errors are provable contract violations and make the command exit 1. Review
51
89
  findings are deliberately heuristic and do not fail by default; pass
@@ -53,6 +91,285 @@ findings are deliberately heuristic and do not fail by default; pass
53
91
  gate CI. Text, versioned JSON, and SARIF carry the same stable rule ids,
54
92
  source locations, evidence, and ownership chain.
55
93
 
94
+ For staged adoption, pass `--adoption`. Ownership-boundary diagnostics are
95
+ reported as review findings so a team can inventory and migrate its baseline;
96
+ combine it with the exact file-and-rule exceptions below for intentional legacy
97
+ integrations. Remove `--adoption` to make unsupported overrides blocking.
98
+
99
+ Catalog `boundaries.publicClasses` and `boundaries.publicTokens` are explicit
100
+ CSS extension points. A component catalog may additionally list shadow-part
101
+ names in `boundaries.publicParts`; all other `::part()` targets are private.
102
+ Part names are scoped to that entry's `boundaries.rootClass`, so an extension
103
+ point on one component does not authorize the same-named part on another.
104
+ Selectors for application-owned content remain allowed, including in a
105
+ component's context (`.kui-pane > .my-content`): a public class is an
106
+ extension point for naming a context, not for restyling the component itself,
107
+ which `KUI-L019` reports.
108
+
109
+ Catalog entries may also publish `cssValueProps`. Each path names its grammar,
110
+ finite shorthands, canonical and exceptional scale steps, accepted typed
111
+ helpers, expression-only helpers, raw escape policy, and examples. The analyzer
112
+ uses that same metadata for direct component calls and JSX, including nested
113
+ paths such as `choices[].color` (each array item's member) and
114
+ `iconTile.color` (an object-valued prop's member, skipped when the prop is a
115
+ tone string); consumer catalogs receive identical checks.
116
+ Dynamic values remain a type-system responsibility rather than being guessed.
117
+
118
+ ## Component ownership (`KUI-L019`–`KUI-L023`)
119
+
120
+ Components own their styles and are configured, never overridden. These
121
+ diagnostics apply the package's own `check:css-ownership` rules to
122
+ applications and component packages; the selector parsing is the same module
123
+ (`analyzer/selectors.mjs`), so the package rule and the consumer rule agree on
124
+ which element a selector styles.
125
+
126
+ A component may freely style raw HTML and Web Awesome elements it renders and
127
+ controls in its own stylesheet. A nested Kerf or application component remains
128
+ a separate owner. A thin composition that only connects children should
129
+ normally have no stylesheet; if it owns raw wrapper markup or layout, its CSS
130
+ may style that markup while these diagnostics continue to reject child
131
+ overrides. “Thin composition” is architectural guidance rather than a static
132
+ classification, so Doctor reports concrete ownership violations instead of
133
+ rejecting every stylesheet attached to a `kind: composition` catalog entry.
134
+
135
+ - **`KUI-L019` — a rule restyles a cataloged component.** The rule's subject
136
+ (the rightmost compound of each selector, ignoring `:has()` and `:not()`
137
+ arguments) names a public class of a cataloged component (`.kui-toolbar`,
138
+ `.kui-list-item__label`, `.acme-meter`), its `[data-component="…"]` root, or
139
+ a Web Awesome tag the package themes (`wa-button`, `wa-select`), and the rule
140
+ sets at least one ordinary property. It also catches a raw descendant of
141
+ cataloged component anatomy, such as `.kui-app-tab__select > svg`, even when
142
+ the component class is not the final compound. A component root used only as
143
+ context (`.kui-toolbar > .my-widget`) and app-named descendants remain
144
+ available for app-owned content. In component mode, classless element subjects
145
+ are also reported below a hook class placed on an imported component, below
146
+ another entry's root in the same package, or at a direct child root whose
147
+ JSX parent composes only a component with that cataloged `rootElement` type.
148
+ Descendant selectors also see a composed child's cataloged root and
149
+ `descendantElements` below an own wrapper. `LucideIcon` publishes `svg` and
150
+ its Lucide SVG child tags, so `.wrapper > svg`, `.wrapper svg`, and
151
+ `.wrapper path` can name the composed icon. Ambiguous evidence from multiple
152
+ different child components is discarded. For arbitrary custom `IconNode`
153
+ child tags outside the cataloged SVG tag list, a selector rooted at
154
+ `svg[data-lucide]` identifies the descendant as
155
+ LucideIcon-owned (for example `svg[data-lucide] filter`). Without that root
156
+ marker, an unknown tag beneath a wrapper remains ambiguous and is not
157
+ attributed to LucideIcon or to unrelated HTML.
158
+ The scan follows returned JSX from
159
+ same-module function and arrow-function components at their call sites,
160
+ recursively with a cycle guard; their intrinsic elements remain app-owned.
161
+ The finding names the composing
162
+ class and component. A `::part()` subject is left to
163
+ `KUI-L011`; a rule that only sets custom properties is configuration, judged
164
+ by the token rules. Forcing a component's dimensions is one such restyle
165
+ and reports here once: `.kui-pane { width: 300px }`.
166
+ - **`KUI-L020` — another component's private variable.** CSS reads or writes a
167
+ `--_<root>-*` variable of a cataloged component (`--_kui-list-gap`), or any
168
+ `--_kui-*` variable.
169
+ - **`KUI-L021` — a token a typed prop sets.** CSS assigns `--<root>-<prop>`
170
+ where the component has that typed prop (`--kui-list-gap` is `List gap`,
171
+ `--kui-floating-toolbar-inset` is `FloatingToolbar inset`). The message
172
+ quotes the prop's cataloged example.
173
+ - **`KUI-L022` — a hook class on a component's root.** A literal class on an
174
+ imported component's JSX (`<Toolbar className="header" />`) is the subject
175
+ of a rule in a stylesheet that file imports, so the application restyles the
176
+ component through it. This also checks components nested in JSX prop values
177
+ (such as `Toolbar.leading`) and application-owned classes placed on another
178
+ component's root. The evidence names the stylesheet, line, and selector.
179
+ For cataloged application components, the import may be direct and relative
180
+ or use an exact or wildcard TypeScript `paths` alias from the nearest
181
+ `tsconfig.json` inside the analyzed root (including inherited options).
182
+ Unresolved aliases remain unclassified; the analyzer does not execute code.
183
+ - **`KUI-L023` — borrowed component markup.** An intrinsic JSX element, raw
184
+ HTML class attribute, `classList.add`/`toggle`/`replace`, `className`
185
+ assignment, or `setAttribute('class', …)` writes another cataloged
186
+ component's public class. The package boundary applies by default;
187
+ component mode also protects sibling modules through `componentSource`.
188
+ A component's own source and its `placeableClasses` remain allowed. Findings
189
+ name the class, owner, write site, and configuration route. This diagnostic
190
+ scans raw HTML in plain strings and the static segments of interpolated
191
+ template literals. When a substitution interrupts a class value, only
192
+ complete literal tokens are reported; split tokens are not guessed. It
193
+ skips test modules (`*.test.*`, `*.spec.*`, and files under `__tests__/`),
194
+ where HTML literals commonly assert on output rather than render markup.
195
+
196
+ Every message names the configuration to use (the component's typed props,
197
+ public tokens, and variants from its catalog entry) and ends with the same
198
+ route for a real need that has none: report the component gap to the owning
199
+ package (open a feature request) instead of overriding it.
200
+
201
+ What stays allowed mirrors the package rule, where a child styles itself in a
202
+ parent's context:
203
+
204
+ ```css
205
+ /* Your own element in a component's context. */
206
+ .kui-toolbar > .my-widget {
207
+ margin-inline-start: auto;
208
+ }
209
+ /* Keying your own element on a component's state. */
210
+ .shell:has(.kui-select[open]) .my-status {
211
+ opacity: 0.5;
212
+ }
213
+ /* Configuring a component through a public token with no typed prop. */
214
+ .kui-list {
215
+ --kui-list-divider-color: var(--kui-color-neutral-border-quiet);
216
+ }
217
+
218
+ /* KUI-L019, KUI-L020, KUI-L021. */
219
+ .kui-toolbar {
220
+ padding: 0;
221
+ }
222
+ .app {
223
+ --_kui-list-gap: 2px;
224
+ --kui-list-gap: 4px;
225
+ }
226
+ ```
227
+
228
+ Ownership is decided per package: a stylesheet belongs to the package whose
229
+ `package.json` is nearest it, and only other packages' catalog entries are
230
+ foreign to it. A component package built on Kerf UI therefore styles its own
231
+ cataloged components (including `.kui-toolbar > .acme-meter` from its own
232
+ stylesheet) without findings, while an application that restyles
233
+ `.acme-meter` is reported against `@acme/widgets`. All four ids are
234
+ ownership-boundary diagnostics, so `--adoption` reports them as review
235
+ findings. `eslint-plugin-kerfjs`'s `ui-component-ownership` rule reports
236
+ `KUI-L020` and `KUI-L021` in JavaScript and TypeScript (style strings, style
237
+ objects, and `style.setProperty()`), where this analyzer reads only CSS.
238
+
239
+ Pass `ownership: 'component'` to `analyzeUiProject` to enforce the boundary
240
+ between components in one package. Selection entries with `source` participate
241
+ even without a composition entry. Each entry owns its declared `styleSources`
242
+ for CSS and its selection `source` module for JSX; when `styleSources` is absent,
243
+ direct relative CSS imports from that source are used. The analyzer also derives
244
+ literal JSX `class` and `className` values whose BEM block is styled in those
245
+ stylesheets. A root or styled literal establishes ownership of the whole BEM
246
+ block: `block`, `block__*`, and `block--*`, including dynamically constructed
247
+ element and modifier names. The boundary applies to selectors and markup class
248
+ writes, including a class prop on an imported component. Modules that share a
249
+ stylesheet co-own its classes, whether the stylesheet was declared or directly
250
+ imported; a source that imports none of an owner's stylesheets remains foreign.
251
+ When several entries infer the same class from a shared stylesheet, the
252
+ analyzer does not arbitrarily assign that class to one of them for `KUI-L019`.
253
+ It reports one `KUI-L019` for a rule whose subject is that class or a dynamic
254
+ member of its BEM block when the stylesheet is foreign to every co-owner. The
255
+ finding names the co-owner set in `evidence.components`; their shared
256
+ stylesheet remains allowed.
257
+ Other sibling files are foreign.
258
+ Paths are relative to the entry's package root. Set
259
+ `implicitComponentOwnership: true` to apply the same source and stylesheet
260
+ inference to modules with direct CSS imports that have no catalog entry.
261
+ For a shell stylesheet imported once but used by style-less modules, pass
262
+ `ownershipGroups: [{ styleSources: ['src/style.css'], sources: ['src/main.tsx', 'src/app/'] }]`.
263
+ The paths are relative to the analyzed package root. A source ending in `/`
264
+ matches every module below that directory; other source paths match exactly.
265
+ Each group owns the subject classes in its stylesheets for `KUI-L019` and
266
+ `KUI-L023`. Its stylesheet and listed source modules share one owner, while
267
+ sibling stylesheets and modules remain foreign. This option applies only with
268
+ `ownership: 'component'`.
269
+ Set `ownershipContext: 'any'` alongside component ownership when one sibling
270
+ component must not mention another sibling's class anywhere in a CSS selector.
271
+ The default, `'subject'`, checks the styled subject. Strict findings use
272
+ `KUI-L019` with `evidence.via: 'context'` and a `position` of `ancestor`,
273
+ `sibling`, `has`, `is`, `where`, or `not`. Set
274
+ `ownershipContext: 'any-package'` to apply the same context rule to components
275
+ from other packages, including their public classes and `[data-component]`
276
+ roots. The `'any'` mode continues to allow cross-package context.
277
+
278
+ ### Retired: `KUI-L005` (forced component dimension)
279
+
280
+ `KUI-L005` used to report, as a review finding, any `width`/`height`/`min-*`/
281
+ `max-*` declaration in a rule that mentioned a public component class
282
+ anywhere in its selector. `KUI-L019` now reports every restyle whose subject is
283
+ a cataloged component — dimensions included — so the subject case was
284
+ double-reported (an error and a review finding for one declaration). Its only
285
+ other shape, a public class as an ancestor
286
+ (`.kui-pane .app-sidebar { width: 240px }`), sizes the application's own
287
+ element in the component's context, which the ownership rules explicitly
288
+ allow. With no unique true positive left,
289
+ the rule was retired rather than narrowed. The analyzer no longer emits it;
290
+ the id stays in `ai/application-ui-diagnostic-ids-v1.json` (listed under
291
+ `retired`) so a profile exception that already names it still loads. Remove
292
+ such exceptions at your convenience.
293
+
294
+ `KUI-C101` was likewise retired when Toolbar zones were aligned with their
295
+ `KerfUiContent` props. Direct content is valid; `ToolbarControlGroup` remains a
296
+ presentation choice for shared control chrome. The id stays in the registry so
297
+ existing profile exceptions still load, but new profiles should not use it.
298
+
299
+ ## Loud fill / on-loud pairing (`KUI-L018`)
300
+
301
+ The shipped Web Awesome theme pairs every `--wa-color-{tone}-fill-loud` with a
302
+ `--wa-color-{tone}-on-loud` foreground that clears WCAG AA (4.5:1), for the
303
+ `neutral`, `brand`, `success`, `warning`, `danger`, and `pop` tones. A
304
+ stylesheet that overrides a loud fill without also setting that tone's
305
+ `on-loud` keeps the theme's foreground on an unknown fill, so the guarantee no
306
+ longer holds. `KUI-L018` reports such a fill and names each scope that lacks a
307
+ pair, and it reports a pair that is present but measurably fails.
308
+
309
+ **Which `on-loud` governs a fill.** Each individual selector of the fill
310
+ (after resolving CSS nesting and splitting selector lists) inside its chain of
311
+ at-rules is one scope. An `on-loud` of the same tone governs it when declared:
312
+
313
+ - in the same scope, in the same or a separate rule, in either order; or
314
+ - in an ancestor scope: a document-root selector (`:root`, `html`, `:host`,
315
+ `*`), or the leading part of a descendant or child chain (`.shell` governs
316
+ `.shell .panel` and `.frame > .tile`, but not `.shell-alt .panel` or
317
+ `.shell.dense`); and
318
+ - under no at-rule, or the same at-rule chain (an unconditional `on-loud`
319
+ applies inside `@media`, but one under `@media` or `@supports` is not proven
320
+ to apply to an unconditional fill).
321
+
322
+ That `on-loud` may live in the same stylesheet or in another one the same
323
+ entry loads: a source module that imports both stylesheets, or a stylesheet
324
+ that reaches both through `@import`. A stylesheet no entry loads with the fill
325
+ does not count. When several candidates apply, the same scope wins (this
326
+ stylesheet first), then the nearest ancestor.
327
+
328
+ **Contrast, when it can be proven.** When the fill and its governing `on-loud`
329
+ are both literal opaque colors (hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`,
330
+ `white`/`black`, or a `light-dark()` of two of them), the analyzer computes the
331
+ WCAG contrast ratio in each color scheme and reports a pair below 4.5:1, with
332
+ the ratio and scheme in its evidence. An unpaired literal fill is accepted when
333
+ it clears 4.5:1 in both schemes against the theme's default `on-loud` for its
334
+ tone (`light-dark(#fff, #111113)` for `brand` and `danger`, `#1d1d1f` for
335
+ `success` and `warning`); `neutral` follows a surface token and `pop` has no
336
+ Web Awesome default, so their unpaired fills are always reported. Values it
337
+ cannot prove (`var()`, `color-mix()`, translucent colors, keywords) are not
338
+ measured: a present pair is accepted, and an unpaired fill is reported.
339
+
340
+ ```css
341
+ /* KUI-L018: brand fill moves, its foreground does not. */
342
+ .billing {
343
+ --wa-color-brand-fill-loud: #7540a8;
344
+ }
345
+
346
+ /* Paired: both in the same scope. */
347
+ .billing {
348
+ --wa-color-brand-fill-loud: #7540a8;
349
+ --wa-color-brand-on-loud: #ffffff;
350
+ }
351
+
352
+ /* Paired through an ancestor scope (6.87:1). */
353
+ :root {
354
+ --wa-color-brand-on-loud: #ffffff;
355
+ }
356
+ .billing {
357
+ --wa-color-brand-fill-loud: #7540a8;
358
+ }
359
+
360
+ /* KUI-L018: present, but white on this fill measures 2.14:1. */
361
+ .billing {
362
+ --wa-color-brand-fill-loud: #7fb3ff;
363
+ --wa-color-brand-on-loud: #ffffff;
364
+ }
365
+ ```
366
+
367
+ It is a review finding rather than an error because the analyzer cannot see
368
+ every cascade: an `on-loud` set inline, by script, or by a stylesheet it does
369
+ not analyze may still govern the fill. Set the `on-loud` explicitly beside the
370
+ fill, which also documents the pair; use `--fail-on-review` to gate it in CI.
371
+ See [the Web Awesome theme customization notes](./webawesome-theme.md#customization).
372
+
56
373
  The JSON report schema is exported as
57
374
  `@kerfjs/ui/analyzer/report.schema.json`.
58
375
 
@@ -82,5 +399,8 @@ validator.
82
399
  ```
83
400
 
84
401
  Review findings remain visible until explicitly suppressed. Avoid suppressing
85
- `KUI-L001`, `KUI-L002`, `KUI-L003`, `KUI-L007`, or `KUI-L009`: those indicate a
402
+ `KUI-L001`, `KUI-L002`, `KUI-L003`, `KUI-L007`, `KUI-L009`, `KUI-L010`,
403
+ `KUI-L011`, `KUI-L012`, `KUI-L013`, `KUI-L014`, `KUI-L015`, `KUI-L016`,
404
+ `KUI-L019`, `KUI-L020`, `KUI-L021`, `KUI-L022`, or `KUI-L023`:
405
+ those indicate a
86
406
  definite boundary or parsing failure rather than an aesthetic judgment.
package/docs/ui-doctor.md CHANGED
@@ -7,6 +7,7 @@ npx kerf-ui-doctor --full
7
7
  npx kerf-ui-doctor --changed
8
8
  npx kerf-ui-doctor --package @acme/admin --changed
9
9
  npx kerf-ui-doctor --full --browser-url http://127.0.0.1:4173
10
+ npx kerf-ui-doctor --full --fail-on warning
10
11
  ```
11
12
 
12
13
  The default terminal output is short and repair-oriented. `--format json` emits the schema-version-1 report; `--output report.json` writes the same representation. The package exports its contract from `@kerfjs/ui/doctor`, its configuration schema from `@kerfjs/ui/doctor/config.schema.json`, and its report schema from `@kerfjs/ui/doctor/report.schema.json`.
@@ -15,24 +16,216 @@ The default terminal output is short and repair-oriented. `--format json` emits
15
16
 
16
17
  The catalog stage discovers the package-default application UI profile and workspace/root-to-leaf directory layers. It validates referenced selection/composition catalogs and, when a workspace declares `package.json#kerfComponentCatalog`, invokes the installed `create-kerf-component` catalog checker to validate metadata, source exports, schema conformance, and generated-output drift. This checker reads source text; it does not import application modules.
17
18
 
18
- TypeScript uses the compiler API with `noEmit`. ESLint loads the installed `eslint-plugin-kerfjs` `recommended-ui` preset (`--eslint strict-ui` opts into advisory rules as errors). This is deliberately an isolated Kerf lint pass rather than the consumer's complete ESLint configuration. Inline directives for consumer-owned plugins, such as `@typescript-eslint`, therefore do not produce false "rule definition not found" diagnostics; the consumer's normal ESLint command remains authoritative for those rules. Unknown `kerfjs/*` directives still fail the doctor pass. Stable KUI identifiers come from the packaged `application-ui-diagnostic-ids-v1.json` registry; the doctor also reads installed ESLint message metadata for semantic conflict detection instead of duplicating rule definitions. The analyzer calls the public `@kerfjs/ui/analyzer` contract. None of these stages executes generated application code.
19
+ TypeScript uses the compiler API with `noEmit`. ESLint loads the installed `eslint-plugin-kerfjs` `recommended-ui` preset (`--eslint strict-ui` opts into advisory rules as errors). This is deliberately an isolated Kerf lint pass rather than the consumer's complete ESLint configuration. For each file, the doctor projects the applicable core ESLint rules and `linterOptions` from the consumer configuration so core-rule suppression directives retain the same used/unused semantics as the application's normal lint command. Consumer plugin rules are not executed, and inline directives for plugins such as `@typescript-eslint` therefore do not produce false "rule definition not found" diagnostics; the consumer's normal ESLint command remains authoritative for those rules. Unknown `kerfjs/*` directives still fail the doctor pass. Stable KUI identifiers come from the packaged `application-ui-diagnostic-ids-v1.json` registry; the doctor also reads installed ESLint message metadata for semantic conflict detection instead of duplicating rule definitions. The analyzer calls the public `@kerfjs/ui/analyzer` contract. None of these stages executes generated application code.
20
+
21
+ Property-specific CSS values are evaluated from each first- or third-party
22
+ catalog entry's `cssValueProps`. `KUI-L013`–`KUI-L016` are blocking grammar
23
+ violations and name a preferred shorthand/helper; `KUI-L017` keeps an
24
+ exceptional but valid spacing choice in the review queue. The ESLint and
25
+ analyzer stages share these ids, messages, and severities, so each finding
26
+ merges into one diagnostic and the normalized report can be consumed as one
27
+ repair loop without tool-specific translations. ESLint has no `review`
28
+ severity: the presets configure `ui-exceptional-shorthands` (`KUI-L017`) as
29
+ `warn`, and the doctor reads an ESLint warning for a code the analyzer
30
+ classifies as `review` as that review finding.
31
+
32
+ The analyzer stage also reads consumer stylesheets for theme overrides:
33
+ `KUI-L018` is a review finding for a `--wa-color-{tone}-fill-loud` override
34
+ that lacks a governing `--wa-color-{tone}-on-loud` (in the same or an ancestor
35
+ scope, in any stylesheet the same entry loads), or whose literal pair measures
36
+ below 4.5:1 (see [the analyzer rule](./ui-analyzer.md#loud-fill--on-loud-pairing-kui-l018)).
37
+
38
+ Component ownership is part of the same loop. The analyzer stage reports
39
+ application or third-party CSS that restyles another package's component
40
+ (`KUI-L019`), touches its private `--_*` variables (`KUI-L020`), overrides a
41
+ token a typed prop sets (`KUI-L021`), or styles it through a hook class on its
42
+ root (`KUI-L022`), including components nested in JSX prop values and hooks
43
+ owned by the surrounding application. It also reports source modules that render another
44
+ component's public classes as their own markup (`KUI-L023`), including raw HTML
45
+ and DOM class writes. Raw HTML checks include complete static class tokens in
46
+ interpolated template literals. `KUI-L023` skips `*.test.*`, `*.spec.*`, and `__tests__/`
47
+ modules so output assertions are not mistaken for rendered markup. The ESLint
48
+ stage's `ui-component-ownership` rule reports
49
+ `KUI-L020` / `KUI-L021` in script. Each finding's `action` points at the
50
+ component's configuration, and its message routes a need with no prop to a
51
+ component-gap report instead of an override (see
52
+ [the analyzer rule](./ui-analyzer.md#component-ownership-kui-l019kui-l023)).
53
+ In component mode, `KUI-L019` also follows an owned wrapper to a composed
54
+ child's cataloged root and descendant element types. For example, a wrapper
55
+ around `LucideIcon` cannot size its `svg` or `path` with an element selector;
56
+ use the icon's props or style an app-owned element. The same check follows
57
+ local function components returned from the owner module and treats their
58
+ intrinsic markup as app-owned.
59
+ Unknown custom `IconNode` tags are identified when a selector explicitly
60
+ passes through the icon's `svg[data-lucide]` root; unrelated HTML descendants
61
+ without that marker remain app-owned.
62
+ The analyzer resolves a cataloged application component imported through an
63
+ exact or wildcard TypeScript `paths` alias from the nearest consumer tsconfig,
64
+ so the same root hook-class check applies in those files.
65
+
66
+ ## Component style naming
67
+
68
+ The analyzer stage also checks colocated JSX/TSX components and stylesheets.
69
+ When a stylesheet has a same-basename component module, or exactly one
70
+ component module imports it, Doctor checks that the stylesheet filename is
71
+ the component's kebab-case name (`KUI-D031`). A component whose returned root
72
+ is its own HTML element must put that kebab-case class on rendered markup
73
+ (`KUI-D030`). Static base tokens in template, concatenated, and conditional
74
+ class expressions count only when every path contains the token.
75
+ An opaque class expression stays unclassified instead of producing a missing
76
+ root-class error.
77
+ For example, `WorkspaceHeader` pairs with `workspace-header.css` and renders
78
+ `.workspace-header`. A local composition catalog can explicitly declare a
79
+ different `boundaries.rootClass` or `publicClasses` and list its stylesheet
80
+ under the selection entry's `styleSources`; Doctor honors that declared alias
81
+ for both checks. The catalog stage remains responsible for validating the
82
+ metadata. Thin components that return another component need no root class,
83
+ even when they render nested HTML as children. Helpers declared in the same
84
+ module share that module's CSS ownership; a module exporting several visual
85
+ components can use a shared stylesheet name. Shared stylesheets declared in
86
+ `ownershipGroups` are exempt from the naming check.
87
+
88
+ Doctor reports `KUI-D032` when a paired stylesheet selects another module's
89
+ local component class or its BEM descendants or modifiers. Move that
90
+ rule to the owning component's stylesheet or use the component's public
91
+ configuration. This check uses source declarations and CSS selectors; it does
92
+ not execute component code. In changed mode, it reads other component sources
93
+ to resolve ownership but reports only pairs containing a selected path. For
94
+ broader cross-component ownership, including
95
+ cataloged package components and hook classes, enable `ownership: "component"`
96
+ with `implicitComponentOwnership: true` as described above.
97
+
98
+ Set `"ownership": "component"` in `.kerf-ui-doctor.json` to enforce the same
99
+ boundary between a consumer package's own cataloged components. The default is
100
+ `"package"`. Selection-only entries participate too. A component owns its
101
+ `styleSources` (relative to its package root), or its direct relative CSS
102
+ imports when that list is absent, and its selection catalog `source` module.
103
+ Literal rendered BEM classes are inferred when those stylesheets style their
104
+ block. An owned root or styled literal owns its whole `block__*` and `block--*`
105
+ family, including dynamic names and classes placed on imported components.
106
+ Modules sharing one of those stylesheets co-own its classes, so their
107
+ own markup does not borrow from one another. A class inferred by several
108
+ co-owners has no arbitrary single owner for CSS subject diagnostics. A
109
+ stylesheet foreign to all co-owners receives one `KUI-L019` per subject rule,
110
+ including dynamic BEM modifiers; `evidence.components` names the co-owner set.
111
+ Set `"implicitComponentOwnership": true` to include uncataloged modules
112
+ that directly import CSS. Component mode reports sibling CSS and hook-class
113
+ restyles while allowing a component's own stylesheet and module.
114
+ For an application with reusable or app-level components, the recommended
115
+ policy is `"ownership": "component"`, `"implicitComponentOwnership": true`,
116
+ and `"ownershipContext": "any-package"`. This lets components style raw HTML
117
+ and Web Awesome elements they own while blocking overrides of nested Kerf and
118
+ application components. Thin glue compositions should normally omit CSS; when
119
+ they own wrapper markup or layout, Doctor permits that own CSS and reports any
120
+ selector that crosses into a child component.
121
+ For an entry stylesheet shared by modules without direct CSS imports, configure
122
+ `"ownershipGroups": [{ "styleSources": ["src/style.css"], "sources": ["src/main.tsx", "src/app/"] }]`.
123
+ These package-relative paths define one owner: its stylesheet and every listed
124
+ source file or directory prefix. Doctor reports sibling CSS restyles and markup
125
+ class use as `KUI-L019` and `KUI-L023`. Source paths ending in `/` match a
126
+ directory subtree; other paths match exactly. When implicit ownership is also
127
+ enabled, the group takes precedence over listed source modules and any direct
128
+ import of its stylesheet. An unrelated importer still borrows the group's
129
+ classes; its other stylesheets can retain their own implicit ownership.
130
+
131
+ Set `"ownershipContext": "any"` to also report a same-package sibling's class
132
+ used as ancestor or sibling context or within `:has()`, `:is()`, `:where()`, or
133
+ `:not()`. The default `"subject"` keeps subject-only context policy; classes
134
+ from another package may still provide context. Set
135
+ `"ownershipContext": "any-package"` to include cross-package component
136
+ classes and `[data-component]` roots in the same selector-context checks.
19
137
 
20
138
  The browser evaluator is different: it runs the application and is disabled by default. It only runs when configuration supplies `browser.url` or the command receives `--browser-url`. Start and authorize the target application separately.
21
139
 
22
140
  An unavailable or failed stage does not prevent independent stages from reporting. Its final exit is still a configuration failure, so a partial run cannot appear clean.
23
141
 
142
+ ## Interface copy capitalization
143
+
144
+ The analyzer stage also checks visible label copy against the package
145
+ capitalization rule in [Writing interface copy](./writing.md#capitalization).
146
+ Names of commands, controls, views, and fields use title style, following
147
+ Apple's guidance. `KUI-D040` (warning) reports a string or template literal
148
+ passed to a known title-style prop that leaves a word lowercase where title style
149
+ capitalizes it. For example, `<wa-button>Save draft</wa-button>` should be
150
+ "Save Draft", and `<ListHeader label="Needs attention" />` should be "Needs
151
+ Attention". The action names the repaired label.
152
+
153
+ The check reads `.tsx` and `.jsx` source text only and skips test modules.
154
+ Fixture components that tests render (for example
155
+ `tests/browser/fixtures/*.tsx`) are not test modules and are checked: they
156
+ stand in for application screens, so their copy follows the same rule. It
157
+ covers these string literals:
158
+
159
+ - `ToolbarText` titles: text with `headingLevel`, a large size, or in a
160
+ toolbar or panel `title`, `header`, or (unless small) `leading` slot;
161
+ - `ListHeader`, `ListActionRow`, `SplitButton`, and `Combobox` labels;
162
+ - `CatalogExample` and `CatalogExampleStack` labels, which render as a
163
+ `ListHeader` heading (their `note` stays sentence style and is not read);
164
+ - `EmptyState` and `StateBanner` titles;
165
+ - `PopupMenu` trigger text and item and heading labels, including submenus
166
+ declared in the same file;
167
+ - `SegmentedControl`, `Select`, and `TabNavigator` choice and tab labels;
168
+ - `NavStack` view titles and `backText`, and `SplitView` `backLabel`;
169
+ - `FieldLabel` text and the static text of a `button` or `wa-button`;
170
+ - the `name` of a panel toolbar's `toggle: { action, name }` object literal
171
+ (Workbench panels, `CollapsiblePanel`), which names the toggle group and
172
+ completes its "Show …" / "Hide …" label;
173
+ - region and landmark names: the `label` of `Pane`, `Workbench`, `Toolbar`,
174
+ `ToolbarControlGroup`, `TabBar`, `NavStack`, `CollapsiblePanel`,
175
+ `FloatingToolbar`, and `ResizableRegion`; the `ariaLabel` of `SunkenPanel`
176
+ and `List`; a `Pane`'s `contentLabel`; the panel, toolbar, and pane labels
177
+ in `Workbench` (`leftRail`, `rightRail`, `bottomDrawer`, `mainToolbar`,
178
+ `mainBottomToolbar`, `mainPane`), `CollapsiblePanel` (`toolbar`,
179
+ `bottomToolbar`, `pane`), and `NavStack` (`views`, `bottomToolbar`)
180
+ configuration declared in the same file; and the `aria-label` of a
181
+ `section`, `nav`, `aside`, `main`, `header`, `footer`, `form`, or `search`
182
+ element or an element with a landmark `role`;
183
+ - the `label` of a raw `wa-input`, `wa-select`, `wa-textarea`, or
184
+ `wa-radio-group`, which is a field or group label;
185
+ - the accessible names of icon-only controls, which the rule also gives title
186
+ style: `IconButton` and `IconToggleButton` `label`, `PopupMenu` `label`,
187
+ `SplitButton` `optionsLabel`, `TokenSearchField` `clearLabel`, and the
188
+ `aria-label` of a `button` or `wa-button` whose only content is an icon. A
189
+ button with visible text is judged by that text, never by its `aria-label`.
190
+
191
+ The check is deliberately one-directional, to keep false positives rare:
192
+
193
+ - It reports only lowercase words. It never reports a capitalized short word,
194
+ because Apple capitalizes a phrasal verb's particle ("Log In to the
195
+ Server").
196
+ - It leaves text ending in `.`, `!`, or `?` to sentence style.
197
+ - It judges only a template literal's static words, so
198
+ `` `Edit ${name} shortcut` `` is reported and the interpolated value never
199
+ is. A word joined to an interpolation (`` `${count}s` ``) is skipped.
200
+ - It ignores other dynamic values and every sentence-style surface: descriptions,
201
+ details, placeholders, tooltips, status text, and option text, including
202
+ `wa-checkbox`, `wa-switch`, and `wa-radio` labels. It does not read
203
+ `LoadingSpinner` or `Skeleton` labels, which announce a status.
204
+ - It skips tokens containing digits, code, paths, or URLs, and lowercase-led
205
+ brands such as iOS and macOS.
206
+ - It keeps a minor word inside a longer hyphenated compound lowercase, as
207
+ between separate words ("Edge-to-Edge", "Up-to-Date").
208
+ - It does not read `ContentItem` `title`, which is a native tooltip.
209
+
210
+ Suppress `KUI-D040` for a file whose copy is a lowercase brand or product
211
+ name.
212
+
24
213
  ## Full and changed modes
25
214
 
26
215
  `--full` is the default and analyzes the selected package. `--changed` reads tracked and untracked paths from Git unless one or more `--path` values are supplied. An empty changed set is a configuration error instead of a false-clean success. With `--package`, workspace-relative Git paths are converted to package-relative paths before TypeScript, ESLint, and analyzer selection; paths outside the selected package are ignored.
27
216
 
28
217
  Full traversal treats generated/tool-owned directories (`dist`, `coverage`,
29
- `node_modules`, `.git`, `.kerf-cache`, `kerf-ui-evidence`, and nested
30
- `.claude/worktrees` checkouts) as outside application source. Their files are
31
- excluded consistently from TypeScript, the isolated ESLint pass, analyzer
32
- discovery, and cache inputs, even when one lives below another application
33
- directory.
218
+ `node_modules`, `.git`, `.kerf-cache`, `kerf-ui-evidence`, Playwright's
219
+ `playwright-report`, `test-results`, and `blob-report`, and nested
220
+ `.claude/worktrees` checkouts) as outside application source. Inside a Git work
221
+ tree it also skips every path the project's ignore rules (`.gitignore`,
222
+ `.git/info/exclude`, and the global excludes file) ignore, so a local test run
223
+ that writes gitignored reports or caches never changes the doctor result.
224
+ These files are excluded consistently from TypeScript, the isolated ESLint
225
+ pass, analyzer discovery, and cache inputs, even when one lives below another
226
+ application directory; a `.gitignore` change invalidates the cache.
34
227
 
35
- TypeScript constructs the selected package's program so compiler options retain their real meaning, while its root inputs are narrowed to changed source files. Use `--full` for release gates.
228
+ TypeScript constructs the selected package's program so compiler options retain their real meaning. In changed mode, its root inputs are narrowed to changed source files plus the tsconfig's declaration roots, so ambient globals still participate; reported source diagnostics stay scoped to the changed files. Use `--full` for release gates.
36
229
 
37
230
  ## Configuration and suppressions
38
231
 
@@ -43,8 +236,12 @@ Place `.kerf-ui-doctor.json` at the workspace root:
43
236
  "$schema": "./node_modules/@kerfjs/ui/doctor/config.schema.json",
44
237
  "schemaVersion": 1,
45
238
  "mode": "full",
239
+ "ownership": "component",
240
+ "ownershipContext": "any-package",
241
+ "implicitComponentOwnership": true,
46
242
  "stages": { "browser": false },
47
243
  "cache": true,
244
+ "failOn": "warning",
48
245
  "suppressions": [
49
246
  {
50
247
  "id": "legacy-toolbar",
@@ -68,14 +265,14 @@ Reports replace the workspace's absolute path with `<repo-root>` and express in-
68
265
 
69
266
  Every diagnostic has a stable `id`, `severity`, `stage`, message, and—when applicable—an exact source location with JSON path or DOM context/selector. Analyzer evidence, catalog facts, documentation links, and safe next actions are preserved when the source tool provides them. Identical findings merge with their source stages; same identifiers with conflicting severities remain separate and add `KUI-D003`.
70
267
 
71
- Exit codes are deterministic:
268
+ Exit codes are deterministic. `failOn` defaults to `error`; `--fail-on error|review|warning` overrides the config for a run. `review` fails on errors or review findings; `warning` also fails on warnings. Suppressed diagnostics never count. The effective threshold is part of the cache key.
72
269
 
73
- - `0`: no active error diagnostics;
270
+ - `0`: no active diagnostics at or above the selected threshold;
74
271
  - `1`: repairable application findings;
75
272
  - `2`: malformed configuration, unavailable required tooling, or a failed stage;
76
273
  - `130`: cancellation.
77
274
 
78
- Warnings and review findings remain visible but do not fail unless their originating preset promotes them to errors. A cached report keeps its original exit code and labels previously run stages `cached`.
275
+ Warnings and review findings remain visible at every threshold. A cached report keeps its original exit code and labels previously run stages `cached`.
79
276
 
80
277
  ## Monorepos and repair loops
81
278