@godxjp/ui 19.1.0 → 19.2.0

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 (436) hide show
  1. package/README.md +25 -128
  2. package/dist/app/theme-axes.d.ts +4 -15
  3. package/dist/app/timezones.d.ts +1 -4
  4. package/dist/components/charts/area-chart.d.ts +2 -3
  5. package/dist/components/charts/bar-chart.d.ts +2 -3
  6. package/dist/components/charts/chart-frame.d.ts +7 -16
  7. package/dist/components/charts/chart-summary.d.ts +2 -2
  8. package/dist/components/charts/compact-bar-trend.d.ts +9 -24
  9. package/dist/components/charts/index.d.ts +1 -6
  10. package/dist/components/data-display/badge.d.ts +2 -12
  11. package/dist/components/data-display/card.d.ts +21 -41
  12. package/dist/components/data-display/carousel.d.ts +1 -2
  13. package/dist/components/data-display/code-block.d.ts +4 -0
  14. package/dist/components/data-display/code-block.js +24 -0
  15. package/dist/components/data-display/data-table.d.ts +15 -37
  16. package/dist/components/data-display/data-table.js +1 -3
  17. package/dist/components/data-display/descriptions.d.ts +2 -6
  18. package/dist/components/data-display/descriptions.js +0 -2
  19. package/dist/components/data-display/index.d.ts +4 -0
  20. package/dist/components/data-display/index.js +4 -0
  21. package/dist/components/data-display/list-row.d.ts +3 -22
  22. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  23. package/dist/components/data-display/progress.d.ts +1 -1
  24. package/dist/components/data-display/prose.d.ts +4 -0
  25. package/dist/components/data-display/prose.js +20 -0
  26. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  27. package/dist/components/data-display/table.d.ts +20 -80
  28. package/dist/components/data-display/table.js +0 -3
  29. package/dist/components/data-display/timeline.d.ts +3 -5
  30. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  31. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  32. package/dist/components/data-entry/calendar.d.ts +3 -2
  33. package/dist/components/data-entry/calendar.js +58 -3
  34. package/dist/components/data-entry/command-palette.d.ts +8 -22
  35. package/dist/components/data-entry/date-picker.d.ts +4 -5
  36. package/dist/components/data-entry/date-picker.js +6 -1
  37. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  38. package/dist/components/data-entry/date-range-picker.js +8 -3
  39. package/dist/components/data-entry/form-errors.d.ts +7 -18
  40. package/dist/components/data-entry/form-field.js +1 -5
  41. package/dist/components/data-entry/form.d.ts +1 -9
  42. package/dist/components/data-entry/input.d.ts +16 -14
  43. package/dist/components/data-entry/input.js +3 -0
  44. package/dist/components/data-entry/month-picker.js +2 -2
  45. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  46. package/dist/components/data-entry/month-range-picker.js +2 -2
  47. package/dist/components/data-entry/number-input.d.ts +1 -5
  48. package/dist/components/data-entry/number-input.js +1 -0
  49. package/dist/components/data-entry/radio.js +0 -1
  50. package/dist/components/data-entry/search-select.d.ts +2 -4
  51. package/dist/components/data-entry/select.d.ts +11 -6
  52. package/dist/components/data-entry/select.js +4 -2
  53. package/dist/components/data-entry/switch.js +0 -1
  54. package/dist/components/data-entry/textarea.d.ts +10 -16
  55. package/dist/components/data-entry/time-picker.d.ts +3 -5
  56. package/dist/components/data-entry/upload-types.d.ts +1 -5
  57. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  58. package/dist/components/feedback/dialog.d.ts +6 -15
  59. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  60. package/dist/components/feedback/sheet.d.ts +3 -10
  61. package/dist/components/feedback/sheet.js +1 -1
  62. package/dist/components/feedback/sonner.js +2 -3
  63. package/dist/components/general/activity.d.ts +4 -30
  64. package/dist/components/general/button.js +1 -10
  65. package/dist/components/general/logo.d.ts +6 -28
  66. package/dist/components/general/reveal.d.ts +3 -9
  67. package/dist/components/general/typography.d.ts +1 -3
  68. package/dist/components/layout/account-chip.d.ts +8 -0
  69. package/dist/components/layout/account-chip.js +45 -0
  70. package/dist/components/layout/auth-divider.d.ts +2 -9
  71. package/dist/components/layout/auth-shell.d.ts +1 -14
  72. package/dist/components/layout/breadcrumb.d.ts +1 -5
  73. package/dist/components/layout/centered-shell.d.ts +4 -18
  74. package/dist/components/layout/error-surface.d.ts +11 -28
  75. package/dist/components/layout/error-surface.js +4 -1
  76. package/dist/components/layout/index.d.ts +2 -0
  77. package/dist/components/layout/index.js +2 -0
  78. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  79. package/dist/components/layout/master-detail.d.ts +2 -18
  80. package/dist/components/layout/page-container.js +0 -1
  81. package/dist/components/layout/responsive-grid.d.ts +6 -1
  82. package/dist/components/layout/responsive-grid.js +9 -2
  83. package/dist/components/layout/service-role-panel.d.ts +7 -19
  84. package/dist/components/layout/sidebar.d.ts +5 -27
  85. package/dist/components/layout/sidebar.js +0 -1
  86. package/dist/components/layout/split-pane.d.ts +0 -7
  87. package/dist/components/layout/topbar.d.ts +1 -14
  88. package/dist/components/navigation/app-setting-picker.js +1 -3
  89. package/dist/components/navigation/filter-bar.d.ts +1 -6
  90. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  91. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  92. package/dist/components/navigation/tabs.js +4 -8
  93. package/dist/components/query/data-state.d.ts +2 -2
  94. package/dist/components/ui/credential-reveal.d.ts +1 -4
  95. package/dist/components/ui/hover-card.d.ts +1 -2
  96. package/dist/components/ui/separator.d.ts +2 -15
  97. package/dist/components/ui/toggle-group.d.ts +1 -5
  98. package/dist/components/ui/toggle.d.ts +6 -31
  99. package/dist/email/brand-mark.d.ts +6 -34
  100. package/dist/email/color.d.ts +7 -17
  101. package/dist/email/geometry.d.ts +4 -8
  102. package/dist/email/index.d.ts +4 -48
  103. package/dist/email/inline-style.d.ts +3 -9
  104. package/dist/email/urgency.d.ts +2 -7
  105. package/dist/form/form-context.d.ts +2 -5
  106. package/dist/form/form-root.d.ts +1 -2
  107. package/dist/i18n/messages/en.json +4 -0
  108. package/dist/i18n/messages/ja.json +4 -0
  109. package/dist/i18n/messages/vi.json +4 -0
  110. package/dist/inertia/index.d.ts +2 -10
  111. package/dist/lib/control-styles.d.ts +10 -21
  112. package/dist/lib/control-styles.js +4 -6
  113. package/dist/lib/datetime/format-date.d.ts +1 -4
  114. package/dist/lib/field-a11y.d.ts +11 -68
  115. package/dist/lib/field-a11y.js +0 -1
  116. package/dist/lib/format.d.ts +4 -8
  117. package/dist/lib/hooks.d.ts +6 -12
  118. package/dist/lib/permission-grid.d.ts +3 -18
  119. package/dist/lib/query-error.d.ts +3 -3
  120. package/dist/props/components/app.prop.d.ts +15 -38
  121. package/dist/props/components/charts.prop.d.ts +2 -3
  122. package/dist/props/components/data-display.prop.d.ts +48 -72
  123. package/dist/props/components/data-entry.prop.d.ts +35 -40
  124. package/dist/props/components/form.prop.d.ts +2 -6
  125. package/dist/props/components/general.prop.d.ts +11 -27
  126. package/dist/props/components/layout.prop.d.ts +89 -260
  127. package/dist/props/components/navigation.prop.d.ts +27 -42
  128. package/dist/props/registry.d.ts +31 -0
  129. package/dist/props/registry.js +33 -0
  130. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  131. package/dist/props/vocabulary/index.d.ts +1 -1
  132. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  133. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  134. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  135. package/dist/styles/alert-layout.css +1 -32
  136. package/dist/styles/badge-layout.css +4 -18
  137. package/dist/styles/base.css +14 -113
  138. package/dist/styles/card-layout.css +6 -128
  139. package/dist/styles/chart-layout.css +2 -17
  140. package/dist/styles/control.css +380 -458
  141. package/dist/styles/core.css +21 -0
  142. package/dist/styles/data-display-layout.css +175 -94
  143. package/dist/styles/data-entry-layout.css +0 -45
  144. package/dist/styles/density.css +1 -30
  145. package/dist/styles/dialog-layout.css +5 -69
  146. package/dist/styles/focus-ring.css +13 -87
  147. package/dist/styles/fonts.css +1 -31
  148. package/dist/styles/form-layout.css +7 -91
  149. package/dist/styles/index.css +2 -20
  150. package/dist/styles/layout.css +38 -456
  151. package/dist/styles/logo-layout.css +1 -35
  152. package/dist/styles/motion.css +3 -42
  153. package/dist/styles/navigation-layout.css +3 -50
  154. package/dist/styles/shell-layout.css +37 -403
  155. package/dist/styles/table-layout.css +16 -274
  156. package/dist/styles/text-layout.css +7 -21
  157. package/dist/styles/toggle.css +1 -23
  158. package/dist/theme/dxs.canonical.css +1 -55
  159. package/dist/theme/example.service.css +1 -26
  160. package/dist/theme/famgia.service.css +5 -15
  161. package/dist/tokens/axes.css +3 -40
  162. package/dist/tokens/base.css +1 -4
  163. package/dist/tokens/components/activity.css +6 -42
  164. package/dist/tokens/components/badge.css +4 -13
  165. package/dist/tokens/components/banner.css +4 -9
  166. package/dist/tokens/components/card.css +32 -88
  167. package/dist/tokens/components/chart.css +9 -26
  168. package/dist/tokens/components/control.css +37 -222
  169. package/dist/tokens/components/data-display.css +28 -79
  170. package/dist/tokens/components/data-entry.css +5 -19
  171. package/dist/tokens/components/descriptions.css +7 -27
  172. package/dist/tokens/components/email.css +38 -84
  173. package/dist/tokens/components/error-surface.css +2 -18
  174. package/dist/tokens/components/feedback.css +27 -124
  175. package/dist/tokens/components/form.css +13 -45
  176. package/dist/tokens/components/legal-document.css +16 -41
  177. package/dist/tokens/components/list-row.css +11 -36
  178. package/dist/tokens/components/logo.css +2 -57
  179. package/dist/tokens/components/navigation.css +16 -94
  180. package/dist/tokens/components/scroll-area.css +2 -18
  181. package/dist/tokens/components/separator.css +8 -30
  182. package/dist/tokens/components/sheet.css +3 -14
  183. package/dist/tokens/components/shell.css +53 -307
  184. package/dist/tokens/components/sidebar.css +5 -22
  185. package/dist/tokens/components/table.css +19 -140
  186. package/dist/tokens/components/toggle.css +3 -65
  187. package/dist/tokens/components/upload.css +7 -43
  188. package/dist/tokens/foundation.css +108 -383
  189. package/dist/tokens/semantic/layout.css +33 -207
  190. package/docs/CANONICAL-CONTRACTS.md +206 -0
  191. package/docs/COMPONENTS.md +157 -0
  192. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  193. package/docs/CONSUMER-RULES.md +14 -0
  194. package/docs/CUSTOMER-THEMING.md +162 -0
  195. package/docs/DATETIME.md +69 -0
  196. package/docs/DEVELOPMENT.md +173 -0
  197. package/docs/FORMS.md +143 -0
  198. package/docs/FRAME-A11Y-CI.md +267 -0
  199. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  200. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  201. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  202. package/docs/FRAME-COVERAGE.md +29 -0
  203. package/docs/PROPS-REGISTRY.md +61 -0
  204. package/docs/PROPS-VOCABULARY.md +100 -0
  205. package/docs/README.md +60 -0
  206. package/docs/REGISTRY.md +70 -0
  207. package/docs/SPACING.md +56 -0
  208. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  209. package/docs/TESTING.md +98 -0
  210. package/docs/TOKENS.md +347 -0
  211. package/docs/asset-modules.d.ts +46 -0
  212. package/docs/assets/cover-terrain.svg +6 -0
  213. package/docs/assets/portrait-amber.svg +5 -0
  214. package/docs/assets/portrait-clay.svg +5 -0
  215. package/docs/assets/portrait-indigo.svg +5 -0
  216. package/docs/assets/portrait-iris.svg +5 -0
  217. package/docs/assets/portrait-moss.svg +5 -0
  218. package/docs/assets/portrait-plum.svg +5 -0
  219. package/docs/assets/portrait-slate.svg +5 -0
  220. package/docs/charts/compact-bar-trend.tsx +328 -0
  221. package/docs/charts/size-tiers.tsx +192 -0
  222. package/docs/data-display/accordion.tsx +99 -0
  223. package/docs/data-display/avatar.tsx +355 -0
  224. package/docs/data-display/badge.tsx +247 -0
  225. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  226. package/docs/data-display/card/index.md +3 -0
  227. package/docs/data-display/card/index.tsx +285 -0
  228. package/docs/data-display/carousel.tsx +156 -0
  229. package/docs/data-display/charts.tsx +198 -0
  230. package/docs/data-display/code-block.tsx +90 -0
  231. package/docs/data-display/collapsible.tsx +162 -0
  232. package/docs/data-display/credential-reveal.tsx +145 -0
  233. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  234. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  235. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  236. package/docs/data-display/data-table/index.md +5 -0
  237. package/docs/data-display/data-table/index.tsx +295 -0
  238. package/docs/data-display/descriptions.tsx +143 -0
  239. package/docs/data-display/empty-state.tsx +164 -0
  240. package/docs/data-display/hover-card.tsx +181 -0
  241. package/docs/data-display/list-row.tsx +420 -0
  242. package/docs/data-display/permission-matrix.tsx +184 -0
  243. package/docs/data-display/popover-touch.tsx +27 -0
  244. package/docs/data-display/popover.tsx +245 -0
  245. package/docs/data-display/progress.tsx +84 -0
  246. package/docs/data-display/prose.tsx +105 -0
  247. package/docs/data-display/qr-code.tsx +68 -0
  248. package/docs/data-display/scroll-area.tsx +271 -0
  249. package/docs/data-display/service-launcher-card.tsx +145 -0
  250. package/docs/data-display/stat-card.tsx +99 -0
  251. package/docs/data-display/table.tsx +251 -0
  252. package/docs/data-display/timeline.tsx +112 -0
  253. package/docs/data-display/touch-actions.tsx +36 -0
  254. package/docs/data-display/tree-list.tsx +107 -0
  255. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  256. package/docs/data-entry/calendar.tsx +180 -0
  257. package/docs/data-entry/cascader.tsx +378 -0
  258. package/docs/data-entry/checkbox.tsx +256 -0
  259. package/docs/data-entry/color-picker.tsx +117 -0
  260. package/docs/data-entry/command-palette.tsx +179 -0
  261. package/docs/data-entry/command.tsx +262 -0
  262. package/docs/data-entry/country-picker-recipe.tsx +170 -0
  263. package/docs/data-entry/date-picker.tsx +191 -0
  264. package/docs/data-entry/date-range-picker.tsx +149 -0
  265. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  266. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  267. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  268. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  269. package/docs/data-entry/form-field/index.md +8 -0
  270. package/docs/data-entry/form-field/index.tsx +326 -0
  271. package/docs/data-entry/form-inertia.tsx +80 -0
  272. package/docs/data-entry/form-root.tsx +102 -0
  273. package/docs/data-entry/form.tsx +724 -0
  274. package/docs/data-entry/input-otp.tsx +231 -0
  275. package/docs/data-entry/input.tsx +114 -0
  276. package/docs/data-entry/label.tsx +100 -0
  277. package/docs/data-entry/month-picker.tsx +101 -0
  278. package/docs/data-entry/month-range-picker.tsx +115 -0
  279. package/docs/data-entry/number-input.tsx +240 -0
  280. package/docs/data-entry/password-input.tsx +106 -0
  281. package/docs/data-entry/password-strength.tsx +97 -0
  282. package/docs/data-entry/radio-group.tsx +95 -0
  283. package/docs/data-entry/rating.tsx +87 -0
  284. package/docs/data-entry/search-input.tsx +120 -0
  285. package/docs/data-entry/select-async-contracts.tsx +108 -0
  286. package/docs/data-entry/select-matrix.tsx +204 -0
  287. package/docs/data-entry/select.tsx +369 -0
  288. package/docs/data-entry/slider.tsx +130 -0
  289. package/docs/data-entry/switch.tsx +67 -0
  290. package/docs/data-entry/tag-input.tsx +108 -0
  291. package/docs/data-entry/textarea.tsx +209 -0
  292. package/docs/data-entry/time-picker.tsx +99 -0
  293. package/docs/data-entry/toggle-count.tsx +293 -0
  294. package/docs/data-entry/toggle-group.tsx +225 -0
  295. package/docs/data-entry/toggle.tsx +127 -0
  296. package/docs/data-entry/transfer.tsx +97 -0
  297. package/docs/data-entry/tree-select.tsx +204 -0
  298. package/docs/data-entry/upload.tsx +184 -0
  299. package/docs/feedback/alert-dialog.tsx +270 -0
  300. package/docs/feedback/alert.tsx +248 -0
  301. package/docs/feedback/banner.tsx +183 -0
  302. package/docs/feedback/danger-confirm.tsx +88 -0
  303. package/docs/feedback/dialog-touch.tsx +24 -0
  304. package/docs/feedback/dialog.tsx +193 -0
  305. package/docs/feedback/sheet.tsx +410 -0
  306. package/docs/feedback/skeleton.tsx +111 -0
  307. package/docs/feedback/toast.tsx +135 -0
  308. package/docs/feedback/tooltip.tsx +171 -0
  309. package/docs/feedback/two-factor-setup.tsx +68 -0
  310. package/docs/foundation/_email-specimen.ts +274 -0
  311. package/docs/foundation/colors.tsx +202 -0
  312. package/docs/foundation/density.tsx +232 -0
  313. package/docs/foundation/email-tokens.tsx +306 -0
  314. package/docs/foundation/radius-shadow.tsx +152 -0
  315. package/docs/foundation/spacing.tsx +211 -0
  316. package/docs/foundation/typography.tsx +147 -0
  317. package/docs/general/activity.tsx +224 -0
  318. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  319. package/docs/general/button/examples/form-actions.tsx +85 -0
  320. package/docs/general/button/examples/toolbar.tsx +160 -0
  321. package/docs/general/button/index.md +12 -0
  322. package/docs/general/button/index.tsx +211 -0
  323. package/docs/general/logo.tsx +131 -0
  324. package/docs/general/reveal.tsx +41 -0
  325. package/docs/general/typography.tsx +152 -0
  326. package/docs/layout/account-chip.tsx +72 -0
  327. package/docs/layout/admin-collection.tsx +122 -0
  328. package/docs/layout/app-shell.tsx +374 -0
  329. package/docs/layout/aspect-ratio.tsx +119 -0
  330. package/docs/layout/auth-account-summary.tsx +103 -0
  331. package/docs/layout/auth-divider.tsx +28 -0
  332. package/docs/layout/auth-footer.tsx +37 -0
  333. package/docs/layout/auth-identity.tsx +36 -0
  334. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  335. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  336. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  337. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  338. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  339. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  340. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  341. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  342. package/docs/layout/auth-recovery/index.md +140 -0
  343. package/docs/layout/auth-recovery/index.tsx +96 -0
  344. package/docs/layout/auth-shell-context.tsx +103 -0
  345. package/docs/layout/auth-shell-device.tsx +112 -0
  346. package/docs/layout/auth-shell-registration.tsx +335 -0
  347. package/docs/layout/auth-shell-variants.tsx +139 -0
  348. package/docs/layout/auth-shell.tsx +59 -0
  349. package/docs/layout/auth-stack.tsx +40 -0
  350. package/docs/layout/centered-shell.tsx +102 -0
  351. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  352. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  353. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  354. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  355. package/docs/layout/error-surface/index.md +153 -0
  356. package/docs/layout/error-surface/index.tsx +239 -0
  357. package/docs/layout/flex.tsx +262 -0
  358. package/docs/layout/legal-document-shell/_data.ts +110 -0
  359. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  360. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  361. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  362. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  363. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  364. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  365. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  366. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  367. package/docs/layout/legal-document-shell/index.md +51 -0
  368. package/docs/layout/legal-document-shell/index.tsx +101 -0
  369. package/docs/layout/master-detail.tsx +387 -0
  370. package/docs/layout/org-switcher.tsx +131 -0
  371. package/docs/layout/page-container.tsx +946 -0
  372. package/docs/layout/resizable-panel.tsx +419 -0
  373. package/docs/layout/responsive-grid.tsx +235 -0
  374. package/docs/layout/separator.tsx +327 -0
  375. package/docs/layout/service-role-panel.tsx +144 -0
  376. package/docs/layout/sidebar.tsx +586 -0
  377. package/docs/layout/split-pane.tsx +451 -0
  378. package/docs/layout/topbar.tsx +347 -0
  379. package/docs/navigation/app-setting-picker.tsx +141 -0
  380. package/docs/navigation/breadcrumb.tsx +128 -0
  381. package/docs/navigation/context-menu.tsx +117 -0
  382. package/docs/navigation/dropdown-menu.tsx +213 -0
  383. package/docs/navigation/filter-bar.tsx +227 -0
  384. package/docs/navigation/menubar.tsx +141 -0
  385. package/docs/navigation/navigation-menu.tsx +165 -0
  386. package/docs/navigation/pagination.tsx +241 -0
  387. package/docs/navigation/steps.tsx +263 -0
  388. package/docs/navigation/tabs-rtl.tsx +28 -0
  389. package/docs/navigation/tabs.tsx +308 -0
  390. package/docs/navigation/toolbar.tsx +339 -0
  391. package/docs/providers/app-provider.tsx +191 -0
  392. package/docs/providers/format-date.tsx +230 -0
  393. package/docs/query/button-refetch.tsx +160 -0
  394. package/docs/query/data-state.tsx +192 -0
  395. package/docs/query/infinite-query-state.tsx +93 -0
  396. package/docs/query/mutation-feedback.tsx +70 -0
  397. package/docs/query/prefetch-link.tsx +262 -0
  398. package/docs/query/touch-actions.tsx +68 -0
  399. package/docs/showcase/acme-portal.tsx +441 -0
  400. package/docs/showcase/acme-website.tsx +455 -0
  401. package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
  402. package/docs/showcase/case2-employee-me.tsx +441 -0
  403. package/docs/showcase/case3-approval-workflow.tsx +527 -0
  404. package/docs/showcase/case4-login.tsx +307 -0
  405. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  406. package/docs/showcase/case6-agency-handy.tsx +1072 -0
  407. package/docs/showcase/futurelastic-web.tsx +390 -0
  408. package/docs/showcase/org-switcher.tsx +313 -0
  409. package/docs/showcase/permission-matrix.tsx +343 -0
  410. package/docs/showcase/public-landing.tsx +210 -0
  411. package/docs/showcase/settings-account-sections.tsx +559 -0
  412. package/docs/showcase/settings-security-mfa.tsx +145 -0
  413. package/docs/showcase/table-approval-queue.tsx +199 -0
  414. package/docs/showcase/table-bulk-actions.tsx +460 -0
  415. package/docs/showcase/table-compact-kintone.tsx +438 -0
  416. package/docs/showcase/table-conditional-format.tsx +367 -0
  417. package/docs/showcase/table-crud-list.tsx +544 -0
  418. package/docs/showcase/table-density.tsx +340 -0
  419. package/docs/showcase/table-expandable-rows.tsx +471 -0
  420. package/docs/showcase/table-filter-chips.tsx +461 -0
  421. package/docs/showcase/table-footer-totals.tsx +311 -0
  422. package/docs/showcase/table-grouped-subtotals.tsx +388 -0
  423. package/docs/showcase/table-master-detail.tsx +479 -0
  424. package/docs/showcase/table-pagination.tsx +320 -0
  425. package/docs/showcase/table-states.tsx +363 -0
  426. package/docs/showcase/table-sticky-columns.tsx +373 -0
  427. package/docs/showcase/table-tree-rows.tsx +444 -0
  428. package/docs/showcase/table-view-tabs.tsx +488 -0
  429. package/package.json +9 -11
  430. package/scripts/_agent-setup.mjs +16 -2
  431. package/scripts/audit-hook.mjs +3 -13
  432. package/scripts/init-agent-kit.mjs +1 -14
  433. package/scripts/postinstall.mjs +12 -12
  434. package/scripts/ui-audit.mjs +93 -31
  435. package/scripts/visual-audit-rules.mjs +51 -7
  436. package/scripts/visual-audit.mjs +118 -47
@@ -1,4 +1,4 @@
1
- /* Control primitive tokens: heights, horizontal padding, adjacent control sizes. */
1
+
2
2
 
3
3
  :root {
4
4
  --control-height-compact: var(--band-height-sm);
@@ -9,8 +9,7 @@
9
9
  --control-padding-x-comfortable: var(--space-4);
10
10
 
11
11
  --control-height: calc(var(--control-height-default) * var(--scaling));
12
- /* Adjacent control sizes, derived from the active --control-height. The ±step
13
- * is scaled too so the whole control ladder stays proportional under --scaling. */
12
+
14
13
  --control-height-sm: calc(var(--control-height) - calc(0.25rem * var(--scaling)));
15
14
  --control-height-lg: calc(var(--control-height) + calc(0.25rem * var(--scaling)));
16
15
  --control-height-xs: calc(var(--control-height) - calc(0.5rem * var(--scaling)));
@@ -18,31 +17,18 @@
18
17
  --control-gap: var(--space-inline-sm);
19
18
  --control-gap-sm: var(--space-inline-xs);
20
19
  --control-radius: var(--radius);
21
- /* Button corner radius — defaults to the button's historical `rounded-md` so nothing
22
- * changes by default, but is its OWN knob so a service theme can retune the button
23
- * radius INDEPENDENTLY of input/control radius (issue #124). */
20
+
24
21
  --button-radius: var(--radius-md);
25
- /* Control surface knobs — font-size, border width and resting shadow of every
26
- * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them
27
- * once instead of each component hard-coding Tailwind utilities. Defaults preserve
28
- * the historical look (font-size-base, 1px border, shadow-xs). */
22
+
29
23
  --control-font-size: var(--font-size-base);
30
24
  --control-border-width: var(--stroke-hairline);
31
25
  --control-shadow: var(--shadow-xs);
32
26
  --control-icon-size: calc(var(--icon-size-md) * var(--scaling));
33
27
  --control-icon-size-sm: calc(var(--icon-size-sm) * var(--scaling));
34
- --control-focus-ring-width: var(--focus-ring-width);
35
28
 
36
- /* Ring knobs for the two controls that need a softer, heavier mark than the
37
- * global default — both are filled surfaces where a hard 2px ring reads as a
38
- * second border. Values preserve the look these controls always had; they are
39
- * knobs now instead of hand-written box-shadows (styles/focus-ring.css). */
40
29
  --toggle-focus-ring-width: var(--stroke-lg);
41
30
  --toggle-focus-ring-alpha: 0.35;
42
- --time-input-focus-ring-width: var(--stroke-lg);
43
- --time-input-focus-ring-alpha: 0.3;
44
31
 
45
- /* Outline-form gaps — marks where a radius-hugging ring would touch the glyph. */
46
32
  --rating-focus-ring-offset: 2px;
47
33
 
48
34
  --checkbox-size: calc(1rem * var(--scaling));
@@ -70,52 +56,23 @@
70
56
  --slider-track-height: 0.375rem;
71
57
  --slider-thumb-size: 1rem;
72
58
 
73
- /* InputOTP slot box (gh#233). Its own knob so an auth surface can widen the 6-slot challenge row
74
- * to fill a wide panel WITHOUT re-scoping --control-height (which would resize every other
75
- * control in the same card). Declared `initial` — the tier-mirror form of the role-mirror rule in
76
- * docs/TOKENS.md: the default must resolve at the CALL SITE (`var(--otp-slot-size,
77
- * var(--control-height))`), because `--otp-slot-size: var(--control-height)` here would FREEZE at
78
- * the :root tier (32px) and an OTP row inside `.ui-auth-shell[data-variant="canonical"]`, which
79
- * re-scopes --control-height to 36px, would silently shrink. Verified in Chromium: 36px before
80
- * and after. A service opts in with a NAMED tier (`var(--control-height-lg)`), never a calc. */
81
- --otp-slot-size: initial; /* default = var(--control-height) at the call site */
82
- /* Per-AXIS overrides of the slot box (gh#12). --otp-slot-size stays the square shorthand; these
83
- * two win over it when set, so a code field can be WIDER-than-tall or TALLER-than-wide without
84
- * abandoning the token. A canonical device-grant code field is 27.5x52 per slot (a 4-slot
85
- * `appearance="grouped"` box of 112x54 with its 1px group border) — not expressible with one
86
- * square knob, which is why grouped OTP measured 146x38 against that artboard. `initial` for the
87
- * same tier-mirror reason as --otp-slot-size: the whole fallback chain
88
- * (axis → square → --control-height) must resolve at the CALL SITE so a shell that re-scopes
89
- * --control-height still reaches an OTP row that sets neither axis. */
90
- --otp-slot-inline-size: initial; /* default = var(--otp-slot-size, var(--control-height)) */
91
- --otp-slot-block-size: initial; /* default = var(--otp-slot-size, var(--control-height)) */
92
- /* Main-axis alignment of the whole OTP row (rule #44/#45 — chrome is a token, default quiet).
93
- * `flex-start` is the historical behaviour, so an existing field is byte-identical; a centred
94
- * code field is `align="center"` on InputOTP (which wins over this knob) or this token set once
95
- * in a service theme. It exists because EVERY consumer was wrapping .ui-otp-container in a
96
- * flex-centring div to get a centred challenge. */
59
+ --otp-slot-size: initial;
60
+
61
+ --otp-slot-inline-size: initial;
62
+ --otp-slot-block-size: initial;
63
+
97
64
  --otp-container-align: flex-start;
98
65
 
99
- /* Checked/on/active fills — `initial` so the --primary default re-resolves at the call site
100
- * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped
101
- * [data-tenant] override of --primary never reaches it). A service retints the "selected" state
102
- * by overriding these directly. Defaults = hsl(var(--primary)) · slider track 0.2α. */
103
66
  --checkbox-checked-background: initial;
104
67
  --switch-checked-background: initial;
105
68
  --toggle-on-background: initial;
106
69
  --slider-track-background: initial;
107
70
  --slider-range-background: initial;
108
71
 
109
- /* Switch OFF track fill (gh#315) — `initial`, default hsl(var(--input)). Its own knob so a
110
- * service can quieten the off-track without dragging the --input control-boundary role back
111
- * below the WCAG SC 1.4.11 floor (rule #45); whatever you set still owes 3:1 against the page
112
- * and against the thumb (--background), or "off" stops being a visible state. */
113
72
  --switch-unchecked-background: initial;
114
73
 
115
- /* ColorPicker — width of the hex text field beside the swatch. */
116
74
  --color-picker-input-width: 6.5rem;
117
75
 
118
- /* Command / CommandPalette — list height, inner paddings and the palette's own box. */
119
76
  --command-list-max-height: min(300px, 50vh);
120
77
  --command-input-padding-x: var(--space-3);
121
78
  --command-group-padding: var(--space-1);
@@ -128,8 +85,6 @@
128
85
  --command-palette-hint-padding-x: var(--space-4);
129
86
  --command-palette-hint-gap: var(--space-4);
130
87
 
131
- /* SearchInput — the inset the leading/trailing icons sit at, and the field padding derived
132
- * from it so the text never runs under an icon. */
133
88
  --search-input-edge-inset: var(--space-3);
134
89
  --search-input-start-padding: calc(
135
90
  var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap)
@@ -138,8 +93,6 @@
138
93
  var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap)
139
94
  );
140
95
 
141
- /* The --font-size-xs tier, spelled once per control that reads it, so a service can retune a
142
- * single one of them without moving the whole scale. */
143
96
  --choice-description-font-size: var(--font-size-xs);
144
97
  --color-picker-hex-font-size: var(--font-size-xs);
145
98
  --command-group-heading-font-size: var(--font-size-xs);
@@ -149,91 +102,46 @@
149
102
  --button-sm-font-size: var(--font-size-xs);
150
103
  }
151
104
 
152
- /* Rule #24 — on touch devices (coarse pointer) interactive controls keep a ≥44px tap target
153
- * regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height
154
- * resolves through these via var(), so inputs/buttons/selects/table rows all bump together. */
155
- /* Control-family tokens added for #319.
156
- *
157
- * These MUST live in a plain :root, not inside the @media (pointer: coarse) block below —
158
- * bare declarations in a conditional group rule are invalid CSS and the parser drops them
159
- * silently. They spent this whole refactor dead for exactly that reason: the guards read the
160
- * file textually, so check-token-tiers and the geometry ratchet both passed while every one of
161
- * these resolved to nothing. */
162
105
  :root {
163
- /* TRAILING AFFIX — the clear ✕ / chevron overlay a select-family trigger parks at its inline
164
- * end. Select, SearchSelect and TagInput each hard-coded the same `end-2 size-6 rounded-sm
165
- * opacity-50` stack independently (#319), so a service retuning affix weight had to chase the
166
- * literal through several components. One shared set of knobs instead — this is a CONTROL-level
167
- * concern, not a per-component one. */
106
+
168
107
  --control-affix-inset-inline-end: var(--space-2);
169
108
  --control-affix-action-size: 1.5rem;
170
109
  --control-affix-action-radius: var(--radius-sm);
171
110
  --control-affix-icon-size: var(--icon-size-md);
172
- /* Resting weight of an affix glyph — it must read as secondary until hovered/focused. */
111
+
173
112
  --control-affix-rest-alpha: 0.5;
174
- /* Room a trigger reserves so its label never runs under the affix. */
175
- /* 2.25rem — the room a single trailing affix needs. Written as a raw rem because the
176
- * literal it replaced (`pe-9`) is a flat Tailwind step, not a density-scaled one. */
113
+
177
114
  --control-trigger-space-inline-end: 2.25rem;
178
115
 
179
- /* INSIDE-FIELD AFFIX — the leading/trailing controls Input and TimePicker render WITHIN the
180
- * field box, as opposed to the overlay affix (--control-affix-*) that Select and SearchSelect
181
- * park on top of a trigger. Both carried the identical literal stack (#319). Because these sit
182
- * on the field's own surface rather than over it, they rest a touch heavier than the overlay
183
- * pair — that difference is the reason the two sets stay separate. */
184
116
  --control-inline-affix-size: 1.25rem;
185
117
  --control-inline-affix-icon-size: var(--control-affix-icon-size);
186
118
  --control-inline-affix-space-gap: var(--space-1);
187
119
  --control-inline-affix-inset-inline: var(--space-2);
188
120
  --control-inline-affix-rest-alpha: 0.7;
189
- /* Inline room the field reserves so its text never runs under a single affix. */
121
+
190
122
  --control-inline-affix-space-inline-end: 2.25rem;
191
- /* Input centres its affix on the field's single line; a textarea has no single line to centre
192
- * on, so its clear control parks at the top-end corner instead. */
123
+
193
124
  --textarea-clear-inset-block-start: var(--space-2);
194
- /* MULTILINE BOX — the block padding of `.ui-control-multiline` (Textarea). It was a bare
195
- * `--space-2` inside the padding shorthand, which made it unreachable for a service that runs a
196
- * denser composer, AND it is the constant the auto-grow row maths has to add back, so the two
197
- * had to read the same knob or drift (#45). */
125
+
198
126
  --control-multiline-padding-block: var(--space-2);
199
- /* TEXTAREA AUTO-GROW (gh#310) — `autoGrow` grows the box with its content between a floor and a
200
- * ceiling expressed in TEXT ROWS. Rows, not pixels, because a row count survives a density
201
- * change and a `--font-size-base` retheme where a px ceiling would silently stop matching the
202
- * visible line count. Defaults reproduce today's geometry when `autoGrow` is absent (#44). */
203
- /* The unit a "row" is measured in. `initial` on purpose: the call site reads
204
- * `var(--textarea-autogrow-line-height, var(--line-height-normal))`, so a service that retunes
205
- * the multiline line-height for CJK legibility retunes the ceiling with it (#46). Unitless —
206
- * it is multiplied by `--control-font-size`. */
127
+
207
128
  --textarea-autogrow-line-height: initial;
208
- /* Floor of the grown box, in text rows. The `minRows` prop overrides per instance — the same
209
- * theme-global / prop-local priority as `--form-label-width` vs `labelWidth`. The floor is
210
- * additionally clamped up to `--control-height` so a resting one-row composer still lines up
211
- * with the Input / Button beside it instead of undercutting the control tier. */
129
+
212
130
  --textarea-autogrow-min-height-rows: 1;
213
- /* Ceiling of the grown box, in text rows; past it the control scrolls internally instead of
214
- * pushing the page. `maxRows={0}` sets this to `infinity` for an unbounded box. */
131
+
215
132
  --textarea-autogrow-max-height-rows: 8;
216
- /* The non-text part of the box the row maths must add back: block padding + border, both
217
- * edges. `.ui-textarea-autogrow--ghost` re-declares it without the border, because the ghost
218
- * variant drops its own chrome. */
133
+
219
134
  --textarea-autogrow-box-inset: calc(
220
135
  (var(--control-multiline-padding-block) + var(--control-border-width)) * 2
221
136
  );
222
- /* A field parking TWO inline affixes (TimePicker's clear+clock, DatePicker's clear+calendar)
223
- * reserves a wider end than the single-affix case. */
137
+
224
138
  --control-inline-affix-pair-space-inline-end: 3.5rem;
225
- /* COMPOSITE FIELD — the bordered box that wraps two inputs plus a separator (date/month
226
- * range pickers) or one input plus affixes. Shared so the four range/picker fields cannot
227
- * drift into four slightly different boxes. */
139
+
228
140
  --control-composite-field-space-gap: var(--space-2);
229
- /* The <input type=file> button is a browser-owned box we restyle; it sits one tier below the
230
- * field so it reads as a control INSIDE the control. */
141
+
231
142
  --input-file-button-height: var(--band-height-sm);
232
143
  --input-file-button-font-size: var(--font-size-sm);
233
144
 
234
- /* SEARCH-SELECT — the Popover+Command combobox. Its panel geometry was baked onto the
235
- * component as arbitrary values (`max-w-[min(32rem,calc(100vw-1.5rem))]`), so a service could
236
- * not widen the panel or change the viewport gutter without forking. */
237
145
  --search-select-panel-max-width: 32rem;
238
146
  --search-select-panel-viewport-inset: var(--space-6);
239
147
  --search-select-list-space-inset: var(--space-1);
@@ -243,14 +151,11 @@
243
151
  --search-select-option-sublabel-font-size: var(--font-size-xs);
244
152
  --search-select-status-space-inline: var(--space-2);
245
153
  --search-select-status-space-block: var(--space-3);
246
- /* Empty/error states sit alone in the panel, so they get a taller, centred block. */
154
+
247
155
  --search-select-placeholder-space-block: var(--space-6);
248
156
  --search-select-status-font-size: var(--font-size-sm);
249
157
  --search-select-spinner-size: 1rem;
250
158
 
251
- /* CASCADER — column browser + flat search list. Its option rows, column widths and panel
252
- * paddings were literals on the component (#319), so a service could not widen a column to fit
253
- * longer JA labels or tighten the row rhythm without forking. */
254
159
  --cascader-column-min-width: 9rem;
255
160
  --cascader-columns-max-height: min(280px, 50vh);
256
161
  --cascader-list-max-height: min(300px, 50vh);
@@ -260,27 +165,21 @@
260
165
  --cascader-option-space-gap: var(--space-1);
261
166
  --cascader-option-font-size: var(--font-size-sm);
262
167
  --cascader-option-icon-size: var(--icon-size-md);
263
- /* The flat search result row is denser than a column row — it has no chevron to balance. */
168
+
264
169
  --cascader-result-space-inline: var(--space-2);
265
170
  --cascader-result-space-block: 0.375rem;
266
171
  --cascader-result-radius: var(--radius-sm);
267
172
  --cascader-result-icon-space-inline-end: var(--space-2);
268
173
  --cascader-empty-space-block: var(--space-6);
269
174
 
270
- /* SELECT — the Radix listbox surface. Its popup shares the menu row rhythm (--menu-item-*),
271
- * so only what is genuinely its own lives here (#319). */
272
175
  --select-content-max-height: 24rem;
273
176
  --select-scroll-button-space-block: var(--space-1);
274
- /* Select rows sit slightly wider than a menu row: a listbox has no leading icon column to
275
- * absorb the optical inset, so 2.5 reads level with a menu's 2 + icon. */
177
+
276
178
  --select-item-space-inline: 0.625rem;
277
179
 
278
- /* TIME PICKER — scroll columns of hour/minute/second plus an inline affix pair. All of its
279
- * geometry was literal on the component (#319): a service could not shorten the column, widen
280
- * the panel for a 12-hour layout, or retune the row rhythm without forking. */
281
180
  --time-picker-column-height: 13rem;
282
181
  --time-picker-panel-width: 9rem;
283
- /* 12-hour mode adds an AM/PM column, so the panel is wider. */
182
+
284
183
  --time-picker-panel-width-12h: 13rem;
285
184
  --time-picker-heading-space-inline: var(--space-1);
286
185
  --time-picker-heading-space-block: 0.375rem;
@@ -293,15 +192,12 @@
293
192
 
294
193
  --time-picker-affix-space-gap: var(--control-inline-affix-space-gap);
295
194
 
296
- /* TREE SELECT — a Select whose panel holds a tree. Its rows, indent and toggle were literal
297
- * on the component, and the depth indent was a magic expression in JSX
298
- * (`depth * 1.25 + 0.5` rem) that no theme could reach at all (#319). */
299
195
  --tree-select-list-max-height: min(300px, 50vh);
300
196
  --tree-select-row-space-block: 0.375rem;
301
197
  --tree-select-row-space-inline-end: var(--space-2);
302
198
  --tree-select-row-radius: var(--radius-sm);
303
199
  --tree-select-row-font-size: var(--font-size-sm);
304
- /* Indent = base + depth × step. A denser service dials the step down without touching JSX. */
200
+
305
201
  --tree-select-depth-space-base: var(--space-2);
306
202
  --tree-select-depth-space-step: 1.25rem;
307
203
  --tree-select-toggle-size: 1.25rem;
@@ -309,17 +205,13 @@
309
205
  --tree-select-label-space-gap: var(--space-2);
310
206
  --tree-select-empty-space-block: var(--space-6);
311
207
 
312
- /* CALENDAR — the react-day-picker grid. Day/weekday cells already size from --control-height
313
- * (the system control tier), but the frame around them — root inset, month gaps, nav offset,
314
- * grid rhythm — was literal on the component (#319), so a service could not tighten the
315
- * calendar to its own density without forking the classNames map. */
316
208
  --calendar-space-inset: var(--space-3);
317
209
  --calendar-month-space-gap: var(--space-4);
318
210
  --calendar-caption-space-inline: var(--space-8);
319
211
  --calendar-caption-font-size: var(--font-size-sm);
320
212
  --calendar-nav-space-block-start: var(--space-3);
321
213
  --calendar-nav-space-inline: var(--space-1);
322
- /* Nav chevrons read as secondary until hovered — they frame the month, they are not the point. */
214
+
323
215
  --calendar-nav-rest-alpha: 0.7;
324
216
  --calendar-grid-space-block-start: var(--space-4);
325
217
  --calendar-week-space-block-start: var(--space-2);
@@ -328,10 +220,10 @@
328
220
  --calendar-day-font-size: var(--font-size-sm);
329
221
  --calendar-day-radius: var(--radius-md);
330
222
  --calendar-chevron-size: var(--icon-size-md);
223
+ --calendar-footer-space-gap: var(--space-2);
224
+ --calendar-footer-space-block-start: var(--space-2);
225
+ --calendar-footer-border-width: var(--stroke-hairline);
331
226
 
332
- /* TRANSFER — the two-pane list mover. Pane height, header rhythm and row density were literal
333
- * on the component (#319), so a service could not fit the panes to its own page grid or
334
- * tighten the row for a dense admin table without forking. */
335
227
  --transfer-pane-min-height: 14rem;
336
228
  --transfer-pane-radius: var(--radius-md);
337
229
  --transfer-panes-space-gap: var(--space-3);
@@ -346,66 +238,35 @@
346
238
  --transfer-row-space-gap: var(--space-2);
347
239
  --transfer-row-radius: var(--radius-sm);
348
240
  --transfer-row-font-size: var(--font-size-sm);
349
- /* The checkbox is top-aligned against a two-line row, so it needs a hair of optical offset to
350
- * sit level with the first line's cap height rather than its box. */
241
+
351
242
  --transfer-row-check-space-block-start: 0.125rem;
352
243
  --transfer-row-description-font-size: var(--font-size-xs);
353
244
  --transfer-empty-space-block: var(--space-8);
354
245
  --transfer-actions-space-gap: var(--space-2);
355
246
  --transfer-action-icon-size: var(--icon-size-md);
356
247
 
357
- /* MONTH PICKER — shared by MonthPicker and MonthRangePicker, which render the same year-nav +
358
- * 3-column month grid. Both carried an identical copy of every literal (#319); one set of knobs
359
- * now drives both, so they cannot drift apart the way Select and DropdownMenu once did. */
360
248
  --month-picker-panel-space-inset: var(--space-3);
361
249
  --month-picker-grid-space-block-start: var(--space-3);
362
250
  --month-picker-grid-space-gap: var(--space-1);
363
251
  --month-picker-cell-space-inline: var(--space-4);
364
252
  --month-picker-nav-font-size: var(--font-size-sm);
365
- /* Year-nav chevrons read as secondary until hovered — same treatment as the Calendar nav, so
366
- * the two panels stay visually consistent when either is retuned. */
253
+
367
254
  --month-picker-nav-rest-alpha: var(--calendar-nav-rest-alpha);
368
255
  --month-picker-icon-size: var(--icon-size-md);
369
256
  --month-picker-separator-icon-size: var(--icon-size-sm);
370
257
 
371
- /* BUTTON size-xs box + the count pill (#319, reconciled in #316).
372
- *
373
- * `size="xs"` now reads the tier, like every other control in the library. It used to be
374
- * `calc(var(--control-height) - 0.75rem)` = 1.25rem, which sat 4px BELOW `--control-height-xs`
375
- * (1.5rem) that `size="icon-xs"` already used — the same tier name, two heights, so an xs
376
- * Button never lined up with the xs control beside it. It was also the exact shape this repo's
377
- * own rule forbids: an ad-hoc `calc(var(--control-height) ± length)` silently re-derives a tier
378
- * and drifts from its siblings (the bug that made Pagination's size-changer taller than its
379
- * page buttons), and being a raw length rather than a `--scaling`-multiplied step, it did not
380
- * move with density while the tier did.
381
- *
382
- * What settled it was not consistency but MEASUREMENT: an xs Button rendered 20px tall, under
383
- * the 24x24 CSS px that WCAG 2.2 SC 2.5.8 (Target Size, Minimum) requires, while icon-xs beside
384
- * it rendered 24px and passed. So this is an accessibility fix that happens to also remove an
385
- * inconsistency, not a visual preference. It is a real visual change on the most-used component
386
- * in the library (20px -> 24px), and it stays a knob: a service that wants the old box sets
387
- * --button-xs-height back. */
388
258
  --button-xs-height: var(--control-height-xs);
389
259
  --button-xs-space-inline: var(--space-2);
390
260
  --button-xs-space-gap: var(--space-1);
391
261
  --button-xs-font-size: var(--font-size-xs);
392
262
  --button-xs-icon-size: var(--icon-size-xs);
393
- /* Icon-adjacent padding: a button whose only child is an icon needs less inline room than one
394
- * carrying a label, or the glyph floats in a too-wide box. One knob per size tier. */
263
+
395
264
  --button-icon-space-inline-md: var(--space-3);
396
265
  --button-icon-space-inline-sm: 0.625rem;
397
266
  --button-icon-space-inline-lg: var(--space-4);
398
267
  --button-icon-space-inline-xs: 0.375rem;
399
268
  --button-space-block: var(--space-2);
400
- /* Count pill — a borderless counter that reads on the button's own surface. */
401
- /* OTP separator glyph. Was a bare 1rem in styles/control.css, so the two-tier contract had no
402
- * tier-2 route here at all: a consumer wanting a different separator could only use !important
403
- * or fork the stylesheet. Same value, now reachable. */
404
- /* The OTP blinking caret. The ratchet catches it because the selector says "caret", but it is a
405
- * text CURSOR, not a chevron: a 1px bar as tall as the digit's line box. Its width belongs to
406
- * the stroke scale; its height belongs to neither the icon nor the band scale, so it is declared
407
- * rather than forced onto one.
408
- * scale-exempt: text-caret height, tracks the OTP digit's line box, not an icon or a band */
269
+
409
270
  --otp-caret-block-size: 1rem;
410
271
  --otp-caret-inline-size: var(--stroke-hairline);
411
272
  --otp-separator-icon-size: var(--icon-size-md);
@@ -414,36 +275,6 @@
414
275
  --button-count-space-inline: var(--space-1);
415
276
  --button-count-font-size: var(--font-size-xs);
416
277
 
417
- /* Count pill · COLOUR (gh#320). The pill used to tint itself translucently over whatever the
418
- * button's surface happened to be (`bg-primary-foreground/15`, `bg-foreground/8`), which means
419
- * its contrast was a FUNCTION of that surface — and five of those combinations measured below
420
- * the 4.5:1 that WCAG 2.2 SC 1.4.3 requires of small text:
421
- *
422
- * default (light) 3.88 · destructive (dark) 4.29
423
- * outline family (light, at rest) 4.32 · outline family (light, hover) 3.64
424
- * outline family (dark, hover) 3.68
425
- *
426
- * The hover rows are the reason a static sweep never caught this: `--accent` only appears under
427
- * the cursor, so no screenshot of a resting page contains the failing state. Same shape as
428
- * gh#299 and gh#315 — a value that passes on the surface someone happened to check.
429
- *
430
- * The fix is the one gh#312 already validated on Toggle: OPAQUE role fills, which make the pill's
431
- * contrast independent of the button's variant AND of hover. Each filled variant uses its own
432
- * label pair SWAPPED, so the pill is exactly as legible as the label beside it and cannot be less
433
- * legible under any theme that keeps that button readable at all:
434
- *
435
- * default --primary on --primary-foreground 5.04 light · 7.07 dark
436
- * destructive --destructive on --destructive-foreground 6.10 light · 5.53 dark
437
- * secondary --secondary on --secondary-foreground 14.25 light · 12.40 dark
438
- * outline family --foreground on --muted 14.25 light · 12.40 dark
439
- *
440
- * The outline family's `--muted` fill is 1.09:1 against the button's own ground, so at rest the
441
- * counter still reads as quiet text rather than a badge (#44) — it is legibility of the DIGITS
442
- * that went up, not loudness of the pill.
443
- *
444
- * All eight are role-mirror knobs: `initial` at :root with the role default at the CALL SITE, so
445
- * a scoped [data-tenant]/.dark override of the role still reaches them (docs/TOKENS.md ·
446
- * "Role-mirror knobs MUST be `initial`"). */
447
278
  --button-count-background: initial;
448
279
  --button-count-color: initial;
449
280
  --button-count-default-background: initial;
@@ -453,27 +284,11 @@
453
284
  --button-count-secondary-background: initial;
454
285
  --button-count-secondary-color: initial;
455
286
 
456
- /* LABEL — the Label primitive's own box and type (#319). Every one of these was a Tailwind
457
- * literal baked into label.tsx (`text-sm leading-none flex items-center gap-2`), so a service
458
- * whose form grid wanted a smaller/denser label had to hand-write font-size on every call site
459
- * (which is exactly why --form-label-font-size had to be invented as a per-instance escape).
460
- * They live under the `control` prefix because Label is a control-family primitive and
461
- * src/tokens/components/ has no `label` file of its own.
462
- *
463
- * Defaults reproduce today's rendering exactly:
464
- * font-size ← `text-sm` → --text-sm → var(--font-size-sm)
465
- * line-height ← `leading-none` → 1 (leading-none beats text-sm's companion line-height) */
466
287
  --control-label-font-size: var(--font-size-sm);
467
288
  --control-label-line-height: 1;
468
- /* Label → addon/required-marker gap. A RAW rem, deliberately NOT var(--space-2): the `gap-2` it
469
- * replaces reads Tailwind's own --spacing grid, which this repo does NOT density-scale, so a
470
- * --space-* default would silently resize every label row under a compact/comfortable density.
471
- * A service that WANTS it to follow density points the knob at var(--space-2) itself. */
289
+
472
290
  --control-label-space-gap: 0.5rem;
473
- /* Weight of a label whose `peer` control is disabled. Deliberately its OWN knob rather than the
474
- * global --disabled-opacity (0.5): a label must stay READABLE next to a disabled control — it is
475
- * still the field's accessible name — so it rests one step heavier than the control it names.
476
- * Default = the historical `peer-disabled:opacity-70`. */
291
+
477
292
  --control-label-disabled-alpha: 0.7;
478
293
  }
479
294
 
@@ -1,82 +1,53 @@
1
- /* Data-display component tokens — small-by-design text knobs (rule #45/#46). */
1
+
2
2
 
3
3
  :root {
4
- /* Accordion chevron and Carousel arrow. Both were bare 1rem literals in
5
- * data-display-layout.css — glyphs with no tier-2 route, invisible to the icon ratchet because
6
- * neither selector contains the word "icon". */
4
+
7
5
  --accordion-chevron-size: var(--icon-size-md);
8
6
  --carousel-arrow-icon-size: var(--icon-size-md);
9
7
 
10
- /* Outline-form ring gaps — a hugging ring would touch these marks
11
- * (styles/focus-ring.css). */
12
8
  --accordion-focus-ring-offset: 2px;
13
9
  --carousel-dot-focus-ring-offset: 2px;
14
10
  --progress-label-font-size: var(--font-size-xs);
11
+
12
+ --code-block-font-size: var(--font-size-sm);
13
+ --code-block-font-size-xs: var(--font-size-xs);
14
+ --code-block-line-height: var(--line-height-normal);
15
+ --code-block-space-inset: var(--space-3);
16
+ --code-block-radius: var(--radius-md);
17
+ --code-block-max-height-sm: 12rem;
18
+ --code-block-max-height-md: 20rem;
19
+ --code-block-max-height-lg: 32rem;
20
+
21
+ --prose-font-size: var(--font-size-base);
22
+ --prose-font-size-sm: var(--font-size-xs);
23
+ --prose-line-height: var(--line-height-body);
24
+ --prose-space-block: var(--space-3);
25
+ --prose-heading-space-block-start: var(--space-6);
26
+ --prose-list-space-inline: var(--space-6);
27
+ --prose-list-item-space: var(--space-1);
28
+ --prose-quote-border-width: var(--stroke-md);
29
+ --prose-quote-space-inline: var(--space-3);
30
+ --prose-code-font-size: calc(1em / var(--font-size-ratio));
31
+ --prose-code-space-inline: var(--space-1);
32
+ --prose-code-radius: var(--radius-sm);
33
+ --prose-image-radius: var(--radius-md);
15
34
  --tree-item-title-font-size: var(--font-size-xs);
16
35
  --tree-item-description-font-size: var(--font-size-xs);
17
36
  --timeline-note-font-size: var(--font-size-xs);
18
37
 
19
- /* Avatar surface — `initial` so the --muted default re-resolves at the call site under a scoped
20
- theme (a :root binding to a role var freezes at :root; a scoped role override never reaches it).
21
- A service re-tints the placeholder fill once (e.g. --avatar-background: hsl(var(--accent))).
22
- Default = hsl(var(--muted)). */
23
38
  --avatar-background: initial;
24
- /* Optional role wash over the avatar (default transparent = invisible, rule #44).
25
- Painted as an overlay so a service sets --avatar-tint: hsl(var(--primary) / 0.08). */
39
+
26
40
  --avatar-tint: transparent;
27
41
 
28
- /* Entity-header mark — `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an
29
- organization/service header uses, as opposed to the round person avatar. Every value is a knob
30
- (rule #45) so a service matches the mark to its own grid without a className override.
31
- --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the
32
- --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped
33
- [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value).
34
- Defaults = --radius-lg corners · --control-height box (same as the circle avatar, so swapping
35
- shape never reflows a header) · hsl(var(--primary)) fill · hsl(var(--primary-foreground)) glyph. */
36
42
  --avatar-square-radius: var(--radius-lg);
37
43
  --avatar-square-size: var(--control-height);
38
44
  --avatar-square-background: initial;
39
45
  --avatar-square-foreground: initial;
40
46
 
41
- /* Capability medallion — `<Avatar appearance="tinted">` (gh#12): the tinted plate a capability /
42
- feature glyph sits on, as opposed to the SOLID entity mark above. Pair it with shape="square"
43
- for the canonical rounded square. --avatar-tinted-background / --avatar-tinted-foreground are
44
- role-mirror knobs (`initial`, docs/TOKENS.md) so the --primary defaults resolve at the CALL
45
- SITE and a scoped [data-tenant]/.dark override of --primary reaches them — the exact reason
46
- this is a token and not the `hsl(var(--primary) / 0.1)` literal consumers were writing in page
47
- CSS. Defaults = hsl(var(--primary) / 0.1) wash · hsl(var(--primary)) glyph ·
48
- --control-icon-size glyph box. */
49
47
  --avatar-tinted-background: initial;
50
48
  --avatar-tinted-foreground: initial;
51
49
  --avatar-tinted-glyph-size: var(--control-icon-size);
52
50
 
53
- /* PRESENCE INDICATOR — `<Avatar presence="online|away|busy|offline">` (gh#309): the realtime
54
- reachability dot pinned to the block-end/inline-end corner of the mark. Every constant below is
55
- a knob (rule #45) and the separator ring is chrome that reads a token (rule #44), because the
56
- hand-rolled workaround this replaces —
57
- `bg-green-500 ring-2 ring-background -end-0.5 -bottom-0.5` on a wrapper span — bakes four
58
- service-tunable constants and a raw palette colour into a consumer page.
59
-
60
- --avatar-presence-size is a PROPORTION of the mark, not a px step. One value therefore tracks
61
- EVERY avatar the system paints — the --control-height default box, a `size-12` call site, the
62
- --avatar-square-size entity mark, --org-switcher-avatar-size (1.75rem), --upload-avatar-size
63
- (6rem), the 36px ListRow density="compact" leading mark — instead of freezing one diameter that
64
- is a boulder on a 24px mark and a speck on a 96px one. --avatar-presence-min-size is the
65
- legibility floor for the smallest marks; --avatar-presence-inset lets a service pull the dot
66
- further into a round mark than into a square one.
67
-
68
- --avatar-presence-ring-color and the four state colours are ROLE-MIRROR knobs: declared
69
- `initial` here so the --background / --success / --warning / --destructive / --muted-foreground
70
- defaults resolve at the CALL SITE and a scoped [data-tenant] / .dark override of the ROLE still
71
- reaches them (docs/TOKENS.md · "Role-mirror knobs MUST be `initial`"). Binding them to the role
72
- here would freeze the ring light-mode-white on a dark avatar.
73
-
74
- Presence is never colour-alone (WCAG 1.4.1): the colour rides with a SHAPE — filled · half
75
- filled · barred · hollow — and a localized sr-only string, so --avatar-presence-stroke-width and
76
- --avatar-presence-bar-* are part of the accessible encoding, not decoration.
77
-
78
- Defaults = 30% of the mark, floor 0.5rem · flush with the mark's corner · 2px separator ring in
79
- --background · 1.5px state stroke · a 56%-wide, 1.5px dnd bar. */
80
51
  --avatar-presence-size: 30%;
81
52
  --avatar-presence-min-size: var(--space-2);
82
53
  --avatar-presence-inset: 0;
@@ -90,25 +61,16 @@
90
61
  --avatar-presence-busy-color: initial;
91
62
  --avatar-presence-offline-color: initial;
92
63
 
93
- /* Progress track + fill — `initial` so the role defaults re-resolve under a scoped theme.
94
- Track reads --secondary, fill reads --success; a service re-tones once.
95
- Defaults = hsl(var(--secondary)) track · hsl(var(--success)) fill. */
96
64
  --progress-track-background: initial;
97
65
  --progress-fill-background: initial;
98
66
 
99
- /* Timeline accents — `initial` so the dot/line role defaults re-resolve under a scoped theme.
100
- Defaults = hsl(var(--success)) done · hsl(var(--primary)) current/line. */
101
67
  --timeline-dot-done-background: initial;
102
68
  --timeline-dot-current-background: initial;
103
69
  --timeline-line-completed-background: initial;
104
70
 
105
- /* Tree active item — border + soft bg tint over the --primary role. `initial` so the default
106
- re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border · 0.05 fill. */
107
71
  --tree-item-active-border: initial;
108
72
  --tree-item-active-background: initial;
109
73
 
110
- /* QR codes stay scanner-safe in light and dark application themes. Consumers may override these
111
- component tokens only when the resulting pair retains strong contrast. */
112
74
  --qr-code-foreground: 0 0% 0%;
113
75
  --qr-code-background: 0 0% 100%;
114
76
  --qr-code-size-xs: 6rem;
@@ -116,28 +78,15 @@
116
78
  --qr-code-size-md: 10rem;
117
79
  --qr-code-size-lg: 12.5rem;
118
80
 
119
- /* SCROLL AREA — the custom scrollbar rail. `.ui-scroll-area-*` did not exist at all: the whole
120
- * rail shipped as Tailwind literals on the component (`w-2.5 p-px` / `h-2.5 p-px`,
121
- * `rounded-full`), so a service could not widen the bar for a touch/coarse-pointer console or
122
- * square the thumb to match a sharp-cornered theme without forking ScrollArea (rule #45).
123
- * --scroll-area-bar-size is a RAW rem on purpose: it replaces a FLAT Tailwind step (2.5 = 10px),
124
- * not a --space-* step, so binding it to the density-scaled scale would silently change today's
125
- * rendering under a non-default --scaling. Defaults reproduce the previous rail exactly. */
126
81
  --scroll-area-bar-size: 0.625rem;
127
- /* Hairline inset that keeps the thumb off the rail edge — a service running a thicker bar
128
- * usually wants a proportionally larger gutter here. */
82
+
129
83
  --scroll-area-bar-padding: 1px;
130
84
  --scroll-area-thumb-radius: var(--radius-pill);
131
85
 
132
- /* PERMISSION MATRIX — the sticky-first-column grid. Nothing here was themeable: the class
133
- * `.ui-permission-matrix` existed as a bare hook with no CSS rule at all, so every constant
134
- * lived on the component (#319). A JA/VI service whose role names run longer than the English
135
- * ones could not widen the label column without forking. */
136
86
  --permission-matrix-label-width: 16rem;
137
87
  --permission-matrix-role-space-gap: var(--space-1);
138
88
  --permission-matrix-name-space-gap: 0.375rem;
139
89
  --permission-matrix-cell-icon-size: var(--control-icon-size);
140
- /* Floor for the scrolling body — below this the columns collapse into unreadable slivers, so
141
- * the table scrolls instead. Mirrors --table-surface-min-inline-size on DataTable. */
90
+
142
91
  --permission-matrix-min-width: 48rem;
143
92
  }