@godxjp/ui 19.0.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 (445) hide show
  1. package/README.md +25 -128
  2. package/dist/app/app-provider.d.ts +1 -1
  3. package/dist/app/app-provider.js +3 -0
  4. package/dist/app/theme-axes.d.ts +4 -15
  5. package/dist/app/timezones.d.ts +1 -4
  6. package/dist/components/charts/area-chart.d.ts +2 -3
  7. package/dist/components/charts/bar-chart.d.ts +2 -3
  8. package/dist/components/charts/chart-frame.d.ts +7 -16
  9. package/dist/components/charts/chart-summary.d.ts +2 -2
  10. package/dist/components/charts/compact-bar-trend.d.ts +9 -24
  11. package/dist/components/charts/index.d.ts +1 -6
  12. package/dist/components/data-display/badge.d.ts +2 -12
  13. package/dist/components/data-display/card.d.ts +21 -41
  14. package/dist/components/data-display/carousel.d.ts +1 -2
  15. package/dist/components/data-display/code-block.d.ts +4 -0
  16. package/dist/components/data-display/code-block.js +24 -0
  17. package/dist/components/data-display/data-table.d.ts +15 -37
  18. package/dist/components/data-display/data-table.js +1 -3
  19. package/dist/components/data-display/descriptions.d.ts +2 -6
  20. package/dist/components/data-display/descriptions.js +0 -2
  21. package/dist/components/data-display/index.d.ts +4 -0
  22. package/dist/components/data-display/index.js +4 -0
  23. package/dist/components/data-display/list-row.d.ts +3 -22
  24. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  25. package/dist/components/data-display/progress.d.ts +1 -1
  26. package/dist/components/data-display/prose.d.ts +4 -0
  27. package/dist/components/data-display/prose.js +20 -0
  28. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  29. package/dist/components/data-display/table.d.ts +20 -80
  30. package/dist/components/data-display/table.js +0 -3
  31. package/dist/components/data-display/timeline.d.ts +3 -5
  32. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  33. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  34. package/dist/components/data-entry/calendar.d.ts +3 -2
  35. package/dist/components/data-entry/calendar.js +58 -3
  36. package/dist/components/data-entry/cascader.js +3 -1
  37. package/dist/components/data-entry/checkbox-group.js +12 -5
  38. package/dist/components/data-entry/checkbox.js +30 -21
  39. package/dist/components/data-entry/command-palette.d.ts +8 -22
  40. package/dist/components/data-entry/date-picker.d.ts +4 -5
  41. package/dist/components/data-entry/date-picker.js +12 -3
  42. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  43. package/dist/components/data-entry/date-range-picker.js +17 -6
  44. package/dist/components/data-entry/form-errors.d.ts +7 -18
  45. package/dist/components/data-entry/form-field.d.ts +1 -1
  46. package/dist/components/data-entry/form-field.js +15 -6
  47. package/dist/components/data-entry/form.d.ts +1 -9
  48. package/dist/components/data-entry/input.d.ts +16 -14
  49. package/dist/components/data-entry/input.js +13 -3
  50. package/dist/components/data-entry/month-picker.js +6 -4
  51. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  52. package/dist/components/data-entry/month-range-picker.js +11 -5
  53. package/dist/components/data-entry/number-input.d.ts +1 -5
  54. package/dist/components/data-entry/number-input.js +1 -0
  55. package/dist/components/data-entry/radio.js +19 -6
  56. package/dist/components/data-entry/search-select.d.ts +3 -5
  57. package/dist/components/data-entry/search-select.js +8 -2
  58. package/dist/components/data-entry/select.d.ts +15 -2
  59. package/dist/components/data-entry/select.js +57 -10
  60. package/dist/components/data-entry/switch.js +9 -2
  61. package/dist/components/data-entry/textarea.d.ts +10 -16
  62. package/dist/components/data-entry/textarea.js +8 -1
  63. package/dist/components/data-entry/time-picker.d.ts +3 -5
  64. package/dist/components/data-entry/tree-select.js +3 -1
  65. package/dist/components/data-entry/upload-types.d.ts +1 -5
  66. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  67. package/dist/components/feedback/dialog.d.ts +6 -15
  68. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  69. package/dist/components/feedback/sheet.d.ts +3 -10
  70. package/dist/components/feedback/sheet.js +1 -1
  71. package/dist/components/feedback/sonner.js +2 -3
  72. package/dist/components/general/activity.d.ts +4 -30
  73. package/dist/components/general/button.js +1 -10
  74. package/dist/components/general/logo.d.ts +6 -28
  75. package/dist/components/general/reveal.d.ts +3 -9
  76. package/dist/components/general/typography.d.ts +1 -3
  77. package/dist/components/layout/account-chip.d.ts +8 -0
  78. package/dist/components/layout/account-chip.js +45 -0
  79. package/dist/components/layout/auth-divider.d.ts +2 -9
  80. package/dist/components/layout/auth-shell.d.ts +1 -14
  81. package/dist/components/layout/breadcrumb.d.ts +1 -5
  82. package/dist/components/layout/centered-shell.d.ts +4 -18
  83. package/dist/components/layout/error-surface.d.ts +11 -28
  84. package/dist/components/layout/error-surface.js +4 -1
  85. package/dist/components/layout/index.d.ts +2 -0
  86. package/dist/components/layout/index.js +2 -0
  87. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  88. package/dist/components/layout/master-detail.d.ts +2 -18
  89. package/dist/components/layout/page-container.js +0 -1
  90. package/dist/components/layout/responsive-grid.d.ts +6 -1
  91. package/dist/components/layout/responsive-grid.js +9 -2
  92. package/dist/components/layout/service-role-panel.d.ts +7 -19
  93. package/dist/components/layout/sidebar.d.ts +5 -27
  94. package/dist/components/layout/sidebar.js +0 -1
  95. package/dist/components/layout/split-pane.d.ts +0 -7
  96. package/dist/components/layout/topbar.d.ts +1 -14
  97. package/dist/components/navigation/app-setting-picker.js +1 -3
  98. package/dist/components/navigation/filter-bar.d.ts +1 -6
  99. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  100. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  101. package/dist/components/navigation/tabs.js +4 -8
  102. package/dist/components/query/data-state.d.ts +2 -2
  103. package/dist/components/ui/credential-reveal.d.ts +1 -4
  104. package/dist/components/ui/hover-card.d.ts +1 -2
  105. package/dist/components/ui/separator.d.ts +2 -15
  106. package/dist/components/ui/toggle-group.d.ts +1 -5
  107. package/dist/components/ui/toggle.d.ts +6 -31
  108. package/dist/email/brand-mark.d.ts +6 -34
  109. package/dist/email/color.d.ts +7 -17
  110. package/dist/email/geometry.d.ts +4 -8
  111. package/dist/email/index.d.ts +4 -48
  112. package/dist/email/inline-style.d.ts +3 -9
  113. package/dist/email/urgency.d.ts +2 -7
  114. package/dist/form/form-context.d.ts +2 -5
  115. package/dist/form/form-root.d.ts +1 -2
  116. package/dist/i18n/messages/en.json +4 -0
  117. package/dist/i18n/messages/ja.json +4 -0
  118. package/dist/i18n/messages/vi.json +4 -0
  119. package/dist/inertia/index.d.ts +2 -10
  120. package/dist/lib/control-styles.d.ts +10 -21
  121. package/dist/lib/control-styles.js +4 -6
  122. package/dist/lib/datetime/format-date.d.ts +1 -4
  123. package/dist/lib/field-a11y.d.ts +31 -36
  124. package/dist/lib/field-a11y.js +16 -2
  125. package/dist/lib/format.d.ts +4 -8
  126. package/dist/lib/hooks.d.ts +6 -12
  127. package/dist/lib/permission-grid.d.ts +3 -18
  128. package/dist/lib/query-error.d.ts +3 -3
  129. package/dist/props/components/app.prop.d.ts +19 -27
  130. package/dist/props/components/charts.prop.d.ts +2 -3
  131. package/dist/props/components/data-display.prop.d.ts +48 -72
  132. package/dist/props/components/data-entry.prop.d.ts +41 -30
  133. package/dist/props/components/form.prop.d.ts +2 -6
  134. package/dist/props/components/general.prop.d.ts +11 -27
  135. package/dist/props/components/layout.prop.d.ts +89 -260
  136. package/dist/props/components/navigation.prop.d.ts +27 -42
  137. package/dist/props/registry.d.ts +31 -0
  138. package/dist/props/registry.js +33 -0
  139. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  140. package/dist/props/vocabulary/index.d.ts +1 -1
  141. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  142. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  143. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  144. package/dist/styles/alert-layout.css +1 -32
  145. package/dist/styles/badge-layout.css +4 -18
  146. package/dist/styles/base.css +14 -113
  147. package/dist/styles/card-layout.css +6 -128
  148. package/dist/styles/chart-layout.css +2 -17
  149. package/dist/styles/control.css +380 -458
  150. package/dist/styles/core.css +21 -0
  151. package/dist/styles/data-display-layout.css +175 -94
  152. package/dist/styles/data-entry-layout.css +0 -45
  153. package/dist/styles/density.css +1 -30
  154. package/dist/styles/dialog-layout.css +5 -69
  155. package/dist/styles/focus-ring.css +13 -87
  156. package/dist/styles/fonts.css +1 -31
  157. package/dist/styles/form-layout.css +7 -91
  158. package/dist/styles/index.css +2 -20
  159. package/dist/styles/layout.css +38 -456
  160. package/dist/styles/logo-layout.css +1 -35
  161. package/dist/styles/motion.css +3 -42
  162. package/dist/styles/navigation-layout.css +3 -50
  163. package/dist/styles/shell-layout.css +37 -403
  164. package/dist/styles/table-layout.css +16 -274
  165. package/dist/styles/text-layout.css +7 -21
  166. package/dist/styles/toggle.css +1 -23
  167. package/dist/theme/dxs.canonical.css +1 -55
  168. package/dist/theme/example.service.css +1 -26
  169. package/dist/theme/famgia.service.css +5 -15
  170. package/dist/tokens/axes.css +3 -40
  171. package/dist/tokens/base.css +1 -4
  172. package/dist/tokens/components/activity.css +6 -42
  173. package/dist/tokens/components/badge.css +4 -13
  174. package/dist/tokens/components/banner.css +4 -9
  175. package/dist/tokens/components/card.css +32 -88
  176. package/dist/tokens/components/chart.css +9 -26
  177. package/dist/tokens/components/control.css +37 -222
  178. package/dist/tokens/components/data-display.css +28 -79
  179. package/dist/tokens/components/data-entry.css +5 -19
  180. package/dist/tokens/components/descriptions.css +7 -27
  181. package/dist/tokens/components/email.css +38 -84
  182. package/dist/tokens/components/error-surface.css +2 -18
  183. package/dist/tokens/components/feedback.css +27 -124
  184. package/dist/tokens/components/form.css +13 -45
  185. package/dist/tokens/components/legal-document.css +16 -41
  186. package/dist/tokens/components/list-row.css +11 -36
  187. package/dist/tokens/components/logo.css +2 -57
  188. package/dist/tokens/components/navigation.css +16 -94
  189. package/dist/tokens/components/scroll-area.css +2 -18
  190. package/dist/tokens/components/separator.css +8 -30
  191. package/dist/tokens/components/sheet.css +3 -14
  192. package/dist/tokens/components/shell.css +53 -307
  193. package/dist/tokens/components/sidebar.css +5 -22
  194. package/dist/tokens/components/table.css +19 -140
  195. package/dist/tokens/components/toggle.css +3 -65
  196. package/dist/tokens/components/upload.css +7 -43
  197. package/dist/tokens/foundation.css +108 -383
  198. package/dist/tokens/semantic/layout.css +33 -207
  199. package/docs/CANONICAL-CONTRACTS.md +206 -0
  200. package/docs/COMPONENTS.md +157 -0
  201. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  202. package/docs/CONSUMER-RULES.md +14 -0
  203. package/docs/CUSTOMER-THEMING.md +162 -0
  204. package/docs/DATETIME.md +69 -0
  205. package/docs/DEVELOPMENT.md +173 -0
  206. package/docs/FORMS.md +143 -0
  207. package/docs/FRAME-A11Y-CI.md +267 -0
  208. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  209. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  210. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  211. package/docs/FRAME-COVERAGE.md +29 -0
  212. package/docs/PROPS-REGISTRY.md +61 -0
  213. package/docs/PROPS-VOCABULARY.md +100 -0
  214. package/docs/README.md +60 -0
  215. package/docs/REGISTRY.md +70 -0
  216. package/docs/SPACING.md +56 -0
  217. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  218. package/docs/TESTING.md +98 -0
  219. package/docs/TOKENS.md +347 -0
  220. package/docs/asset-modules.d.ts +46 -0
  221. package/docs/assets/cover-terrain.svg +6 -0
  222. package/docs/assets/portrait-amber.svg +5 -0
  223. package/docs/assets/portrait-clay.svg +5 -0
  224. package/docs/assets/portrait-indigo.svg +5 -0
  225. package/docs/assets/portrait-iris.svg +5 -0
  226. package/docs/assets/portrait-moss.svg +5 -0
  227. package/docs/assets/portrait-plum.svg +5 -0
  228. package/docs/assets/portrait-slate.svg +5 -0
  229. package/docs/charts/compact-bar-trend.tsx +328 -0
  230. package/docs/charts/size-tiers.tsx +192 -0
  231. package/docs/data-display/accordion.tsx +99 -0
  232. package/docs/data-display/avatar.tsx +355 -0
  233. package/docs/data-display/badge.tsx +247 -0
  234. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  235. package/docs/data-display/card/index.md +3 -0
  236. package/docs/data-display/card/index.tsx +285 -0
  237. package/docs/data-display/carousel.tsx +156 -0
  238. package/docs/data-display/charts.tsx +198 -0
  239. package/docs/data-display/code-block.tsx +90 -0
  240. package/docs/data-display/collapsible.tsx +162 -0
  241. package/docs/data-display/credential-reveal.tsx +145 -0
  242. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  243. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  244. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  245. package/docs/data-display/data-table/index.md +5 -0
  246. package/docs/data-display/data-table/index.tsx +295 -0
  247. package/docs/data-display/descriptions.tsx +143 -0
  248. package/docs/data-display/empty-state.tsx +164 -0
  249. package/docs/data-display/hover-card.tsx +181 -0
  250. package/docs/data-display/list-row.tsx +420 -0
  251. package/docs/data-display/permission-matrix.tsx +184 -0
  252. package/docs/data-display/popover-touch.tsx +27 -0
  253. package/docs/data-display/popover.tsx +245 -0
  254. package/docs/data-display/progress.tsx +84 -0
  255. package/docs/data-display/prose.tsx +105 -0
  256. package/docs/data-display/qr-code.tsx +68 -0
  257. package/docs/data-display/scroll-area.tsx +271 -0
  258. package/docs/data-display/service-launcher-card.tsx +145 -0
  259. package/docs/data-display/stat-card.tsx +99 -0
  260. package/docs/data-display/table.tsx +251 -0
  261. package/docs/data-display/timeline.tsx +112 -0
  262. package/docs/data-display/touch-actions.tsx +36 -0
  263. package/docs/data-display/tree-list.tsx +107 -0
  264. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  265. package/docs/data-entry/calendar.tsx +180 -0
  266. package/docs/data-entry/cascader.tsx +378 -0
  267. package/docs/data-entry/checkbox.tsx +256 -0
  268. package/docs/data-entry/color-picker.tsx +117 -0
  269. package/docs/data-entry/command-palette.tsx +179 -0
  270. package/docs/data-entry/command.tsx +262 -0
  271. package/docs/data-entry/country-picker-recipe.tsx +170 -0
  272. package/docs/data-entry/date-picker.tsx +191 -0
  273. package/docs/data-entry/date-range-picker.tsx +149 -0
  274. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  275. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  276. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  277. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  278. package/docs/data-entry/form-field/index.md +8 -0
  279. package/docs/data-entry/form-field/index.tsx +326 -0
  280. package/docs/data-entry/form-inertia.tsx +80 -0
  281. package/docs/data-entry/form-root.tsx +102 -0
  282. package/docs/data-entry/form.tsx +724 -0
  283. package/docs/data-entry/input-otp.tsx +231 -0
  284. package/docs/data-entry/input.tsx +114 -0
  285. package/docs/data-entry/label.tsx +100 -0
  286. package/docs/data-entry/month-picker.tsx +101 -0
  287. package/docs/data-entry/month-range-picker.tsx +115 -0
  288. package/docs/data-entry/number-input.tsx +240 -0
  289. package/docs/data-entry/password-input.tsx +106 -0
  290. package/docs/data-entry/password-strength.tsx +97 -0
  291. package/docs/data-entry/radio-group.tsx +95 -0
  292. package/docs/data-entry/rating.tsx +87 -0
  293. package/docs/data-entry/search-input.tsx +120 -0
  294. package/docs/data-entry/select-async-contracts.tsx +108 -0
  295. package/docs/data-entry/select-matrix.tsx +204 -0
  296. package/docs/data-entry/select.tsx +369 -0
  297. package/docs/data-entry/slider.tsx +130 -0
  298. package/docs/data-entry/switch.tsx +67 -0
  299. package/docs/data-entry/tag-input.tsx +108 -0
  300. package/docs/data-entry/textarea.tsx +209 -0
  301. package/docs/data-entry/time-picker.tsx +99 -0
  302. package/docs/data-entry/toggle-count.tsx +293 -0
  303. package/docs/data-entry/toggle-group.tsx +225 -0
  304. package/docs/data-entry/toggle.tsx +127 -0
  305. package/docs/data-entry/transfer.tsx +97 -0
  306. package/docs/data-entry/tree-select.tsx +204 -0
  307. package/docs/data-entry/upload.tsx +184 -0
  308. package/docs/feedback/alert-dialog.tsx +270 -0
  309. package/docs/feedback/alert.tsx +248 -0
  310. package/docs/feedback/banner.tsx +183 -0
  311. package/docs/feedback/danger-confirm.tsx +88 -0
  312. package/docs/feedback/dialog-touch.tsx +24 -0
  313. package/docs/feedback/dialog.tsx +193 -0
  314. package/docs/feedback/sheet.tsx +410 -0
  315. package/docs/feedback/skeleton.tsx +111 -0
  316. package/docs/feedback/toast.tsx +135 -0
  317. package/docs/feedback/tooltip.tsx +171 -0
  318. package/docs/feedback/two-factor-setup.tsx +68 -0
  319. package/docs/foundation/_email-specimen.ts +274 -0
  320. package/docs/foundation/colors.tsx +202 -0
  321. package/docs/foundation/density.tsx +232 -0
  322. package/docs/foundation/email-tokens.tsx +306 -0
  323. package/docs/foundation/radius-shadow.tsx +152 -0
  324. package/docs/foundation/spacing.tsx +211 -0
  325. package/docs/foundation/typography.tsx +147 -0
  326. package/docs/general/activity.tsx +224 -0
  327. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  328. package/docs/general/button/examples/form-actions.tsx +85 -0
  329. package/docs/general/button/examples/toolbar.tsx +160 -0
  330. package/docs/general/button/index.md +12 -0
  331. package/docs/general/button/index.tsx +211 -0
  332. package/docs/general/logo.tsx +131 -0
  333. package/docs/general/reveal.tsx +41 -0
  334. package/docs/general/typography.tsx +152 -0
  335. package/docs/layout/account-chip.tsx +72 -0
  336. package/docs/layout/admin-collection.tsx +122 -0
  337. package/docs/layout/app-shell.tsx +374 -0
  338. package/docs/layout/aspect-ratio.tsx +119 -0
  339. package/docs/layout/auth-account-summary.tsx +103 -0
  340. package/docs/layout/auth-divider.tsx +28 -0
  341. package/docs/layout/auth-footer.tsx +37 -0
  342. package/docs/layout/auth-identity.tsx +36 -0
  343. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  344. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  345. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  346. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  347. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  348. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  349. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  350. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  351. package/docs/layout/auth-recovery/index.md +140 -0
  352. package/docs/layout/auth-recovery/index.tsx +96 -0
  353. package/docs/layout/auth-shell-context.tsx +103 -0
  354. package/docs/layout/auth-shell-device.tsx +112 -0
  355. package/docs/layout/auth-shell-registration.tsx +335 -0
  356. package/docs/layout/auth-shell-variants.tsx +139 -0
  357. package/docs/layout/auth-shell.tsx +59 -0
  358. package/docs/layout/auth-stack.tsx +40 -0
  359. package/docs/layout/centered-shell.tsx +102 -0
  360. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  361. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  362. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  363. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  364. package/docs/layout/error-surface/index.md +153 -0
  365. package/docs/layout/error-surface/index.tsx +239 -0
  366. package/docs/layout/flex.tsx +262 -0
  367. package/docs/layout/legal-document-shell/_data.ts +110 -0
  368. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  369. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  370. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  371. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  372. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  373. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  374. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  375. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  376. package/docs/layout/legal-document-shell/index.md +51 -0
  377. package/docs/layout/legal-document-shell/index.tsx +101 -0
  378. package/docs/layout/master-detail.tsx +387 -0
  379. package/docs/layout/org-switcher.tsx +131 -0
  380. package/docs/layout/page-container.tsx +946 -0
  381. package/docs/layout/resizable-panel.tsx +419 -0
  382. package/docs/layout/responsive-grid.tsx +235 -0
  383. package/docs/layout/separator.tsx +327 -0
  384. package/docs/layout/service-role-panel.tsx +144 -0
  385. package/docs/layout/sidebar.tsx +586 -0
  386. package/docs/layout/split-pane.tsx +451 -0
  387. package/docs/layout/topbar.tsx +347 -0
  388. package/docs/navigation/app-setting-picker.tsx +141 -0
  389. package/docs/navigation/breadcrumb.tsx +128 -0
  390. package/docs/navigation/context-menu.tsx +117 -0
  391. package/docs/navigation/dropdown-menu.tsx +213 -0
  392. package/docs/navigation/filter-bar.tsx +227 -0
  393. package/docs/navigation/menubar.tsx +141 -0
  394. package/docs/navigation/navigation-menu.tsx +165 -0
  395. package/docs/navigation/pagination.tsx +241 -0
  396. package/docs/navigation/steps.tsx +263 -0
  397. package/docs/navigation/tabs-rtl.tsx +28 -0
  398. package/docs/navigation/tabs.tsx +308 -0
  399. package/docs/navigation/toolbar.tsx +339 -0
  400. package/docs/providers/app-provider.tsx +191 -0
  401. package/docs/providers/format-date.tsx +230 -0
  402. package/docs/query/button-refetch.tsx +160 -0
  403. package/docs/query/data-state.tsx +192 -0
  404. package/docs/query/infinite-query-state.tsx +93 -0
  405. package/docs/query/mutation-feedback.tsx +70 -0
  406. package/docs/query/prefetch-link.tsx +262 -0
  407. package/docs/query/touch-actions.tsx +68 -0
  408. package/docs/showcase/acme-portal.tsx +441 -0
  409. package/docs/showcase/acme-website.tsx +455 -0
  410. package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
  411. package/docs/showcase/case2-employee-me.tsx +441 -0
  412. package/docs/showcase/case3-approval-workflow.tsx +527 -0
  413. package/docs/showcase/case4-login.tsx +307 -0
  414. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  415. package/docs/showcase/case6-agency-handy.tsx +1072 -0
  416. package/docs/showcase/futurelastic-web.tsx +390 -0
  417. package/docs/showcase/org-switcher.tsx +313 -0
  418. package/docs/showcase/permission-matrix.tsx +343 -0
  419. package/docs/showcase/public-landing.tsx +210 -0
  420. package/docs/showcase/settings-account-sections.tsx +559 -0
  421. package/docs/showcase/settings-security-mfa.tsx +145 -0
  422. package/docs/showcase/table-approval-queue.tsx +199 -0
  423. package/docs/showcase/table-bulk-actions.tsx +460 -0
  424. package/docs/showcase/table-compact-kintone.tsx +438 -0
  425. package/docs/showcase/table-conditional-format.tsx +367 -0
  426. package/docs/showcase/table-crud-list.tsx +544 -0
  427. package/docs/showcase/table-density.tsx +340 -0
  428. package/docs/showcase/table-expandable-rows.tsx +471 -0
  429. package/docs/showcase/table-filter-chips.tsx +461 -0
  430. package/docs/showcase/table-footer-totals.tsx +311 -0
  431. package/docs/showcase/table-grouped-subtotals.tsx +388 -0
  432. package/docs/showcase/table-master-detail.tsx +479 -0
  433. package/docs/showcase/table-pagination.tsx +320 -0
  434. package/docs/showcase/table-states.tsx +363 -0
  435. package/docs/showcase/table-sticky-columns.tsx +373 -0
  436. package/docs/showcase/table-tree-rows.tsx +444 -0
  437. package/docs/showcase/table-view-tabs.tsx +488 -0
  438. package/package.json +10 -11
  439. package/scripts/_agent-setup.mjs +16 -2
  440. package/scripts/audit-hook.mjs +3 -13
  441. package/scripts/init-agent-kit.mjs +1 -14
  442. package/scripts/postinstall.mjs +12 -12
  443. package/scripts/ui-audit.mjs +93 -31
  444. package/scripts/visual-audit-rules.mjs +51 -7
  445. package/scripts/visual-audit.mjs +118 -47
@@ -1,101 +1,51 @@
1
- /* Foundation tokens: color, typography, raw spacing, ratio, radius, shadow. */
1
+
2
2
 
3
3
  :root {
4
- /* Color system (HSL components) — the reference design: warm hue-60 neutral spine,
5
- * SmartHR blue primary, 和色/wa-iro semantics. */
6
- --background: 60 33% 99%; /* #fdfdfb warm off-white */
7
- --foreground: 48 8% 13%; /* #23221e SmartHR TEXT_BLACK */
4
+
5
+ --background: 60 33% 99%;
6
+ --foreground: 48 8% 13%;
8
7
  --card: 60 33% 99%;
9
8
  --card-foreground: 48 8% 13%;
10
9
  --popover: 60 33% 99%;
11
10
  --popover-foreground: 48 8% 13%;
12
- /* SmartHR MAIN, two lightness steps down from #0077c7 (gh#299).
13
- *
14
- * The published blue measures 4.62:1 as TEXT on --background — compliant,
15
- * but with 0.12 of headroom, which every tint this system applies to a row
16
- * then spends: the zebra stripe (muted/0.4) takes it to 4.46 and hover
17
- * (muted/0.5) to 4.43. A link inside a striped table therefore failed AA
18
- * while the same link on a card passed, which is not a defensible place to
19
- * draw that line. 37% clears every one of those states with margin and is
20
- * indistinguishable from the original side by side. */
21
- --primary: 204 100% 37%; /* SmartHR MAIN #0071bd */
11
+
12
+ --primary: 204 100% 37%;
22
13
  --primary-foreground: 60 33% 99%;
23
- --secondary: 45 15% 95%; /* #f4f3f0 */
14
+ --secondary: 45 15% 95%;
24
15
  --secondary-foreground: 48 8% 13%;
25
16
  --muted: 45 15% 95%;
26
- --muted-foreground: 44 5% 42%; /* #706d65 SmartHR TEXT_GREY */
27
- --accent: 40 13% 91%; /* #ebe9e5 */
17
+ --muted-foreground: 44 5% 42%;
18
+ --accent: 40 13% 91%;
28
19
  --accent-foreground: 48 8% 13%;
29
- --destructive: 357 64% 44%; /* 茜 #b7282e */
20
+ --destructive: 357 64% 44%;
30
21
  --destructive-foreground: 60 33% 99%;
31
- --border: 30 7% 83%; /* #d6d3d0 SmartHR BORDER */
32
- /* CONTROL BOUNDARY role — deliberately NOT the same value as --border (gh#315).
33
- *
34
- * The two roles answer different questions and are held to different bars:
35
- * · --border is DECORATIVE chrome — table rules, card edges, section dividers. WCAG 2.2
36
- * SC 1.4.11 does not reach it (nothing about a divider is "required to identify a
37
- * component or its state"), and darkening it would make the JP-dense table grid roar.
38
- * It stays exactly where it is.
39
- * · --input is the boundary that IS the control — the 1px edge of Input, Textarea, Select,
40
- * the outline Button, TagInput, the composite date field, the topbar search. `--input`
41
- * also fills the Switch's unchecked track. A text field here has NO fill of its own
42
- * (`background: hsl(var(--background))`) and NO shadow to speak of, so that edge is the
43
- * only thing that says "you may type here". That is squarely SC 1.4.11's 3:1 minimum.
44
- *
45
- * They shipped sharing `30 7% 83%`, which measured 1.46:1 on --background/--card — the one
46
- * live WCAG failure a full DXS Platform sweep turned up. 53% clears 3:1 with margin on every
47
- * surface a control actually sits on, not just the plain page (the gh#299 lesson: a value that
48
- * passes on a card and fails inside a filter bar is not a line anyone can defend):
49
- * --background/--card/--popover 3.47:1 · --muted/--secondary 3.18:1 · zebra stripe 3.35:1 ·
50
- * row hover 3.32:1. It also lifts the Switch's unchecked track from 1.46:1 to 3.47:1 against
51
- * both the page and its own white thumb, so "off" is finally a visible state.
52
- * Guarded by src/tokens/__tests__/input-boundary-contrast.test.ts. */
53
- --input: 30 7% 53%; /* #90877f — control boundary, ≥3:1 (WCAG 2.2 SC 1.4.11) */
22
+ --border: 30 7% 83%;
23
+
24
+ --input: 30 7% 53%;
54
25
  --ring: 204 100% 39%;
55
- --success: 146 40% 58%; /* 若竹 #68be8d */
26
+ --success: 146 40% 58%;
56
27
  --success-foreground: 60 33% 99%;
57
- --warning: 44 100% 49%; /* 山吹 #f8b500 */
28
+ --warning: 44 100% 49%;
58
29
  --warning-foreground: 48 8% 13%;
59
- --info: 221 40% 50%; /* 群青 #4c6cb3 */
30
+ --info: 221 40% 50%;
60
31
  --info-foreground: 60 33% 99%;
61
- --attention: 25 99% 46%; /* 朱 #eb6101 */
32
+ --attention: 25 99% 46%;
62
33
  --attention-foreground: 60 33% 99%;
63
34
 
64
- /* IDENTITY role — the canonical GoDX emerald. This is the PRODUCT MARK colour (Logo `mark="godx"`
65
- * / `tone="success"`, its wordmark, the email brand capsule), and it is deliberately THREE-WAY
66
- * distinct:
67
- * · from --primary — a service re-theming its action colour must never recolour the mark;
68
- * · from --success — 若竹 #68be8d is the STATUS green (badges, progress, "saved" text) and
69
- * stays exactly as it is. The mark previously borrowed it, which rendered
70
- * the identity at #69bf8e instead of the canonical emerald — ΔE76 ≈ 17.5,
71
- * a plainly wrong brand colour (gh#250/#214);
72
- * · from --text-brand / --color-brand — those are the BLUE brand-numeral TEXT slot and the
73
- * Tailwind `text-brand` utility it feeds; unrelated, and not renamed here.
74
- * Canonical value: oklch(0.595 0.137 162.94) = #009766, "kept distinct from SmartHR primary".
75
- * The triplet is carried at one decimal so hsl() lands on that exact hex (an integer 160 100% 30%
76
- * would drift to #009966). Dark lifts lightness only — same hue, same full chroma — so the mark
77
- * stays the same emerald while clearing AA against the dark spine.
78
- * There is no Tailwind `bg-brand` utility on purpose: `--color-brand` is already taken by
79
- * --text-brand, so identity surfaces read `hsl(var(--brand))` directly in component CSS. */
80
- --brand: 160.5 100% 29.6%; /* 翠 GoDX emerald #009766 */
35
+ --brand: 160.5 100% 29.6%;
81
36
  --brand-foreground: 60 33% 99%;
82
37
 
83
- /* Extended text hierarchy (beyond --foreground / --muted-foreground) themeable per service.
84
- * Roles primitives bake in today: caption/meta, disabled, inline link, brand numerals. */
85
- --text-tertiary: 44 5% 55%; /* lighter than muted-foreground — captions / meta */
86
- --text-disabled: 40 6% 68%; /* disabled control text */
87
- --text-link: 204 100% 39%; /* inline link — defaults to brand blue */
88
- --text-brand: 204 100% 39%; /* brand-colored text / numerals */
89
- /* Status TEXT colours — darker than the fill roles so small coloured text (a StatCard delta, an
90
- * outline status badge label) clears WCAG AA 4.5:1 on white. The fill roles (--success/--warning/
91
- * --info) stay the brighter wa-iro for badges/bars; only TEXT reads these via text-*-strong. */
92
- --text-primary: 204 100% 30%; /* deep brand blue — AA brand text on the soft primary tint */
93
- --text-success: 152 84% 22%; /* deep 若竹 — AA green text on white */
94
- --text-warning: 36 100% 28%; /* dark 山吹 amber — yellow can never pass as text */
95
- --text-info: 221 70% 38%; /* deep 群青 — AA blue text on white */
96
- --text-error: 357 75% 38%; /* deep 茜 — AA red text on white */
97
-
98
- /* Interaction ramp — hover / active steps (services override to their own brand ramp). */
38
+ --text-tertiary: 44 5% 55%;
39
+ --text-disabled: 40 6% 68%;
40
+ --text-link: 204 100% 39%;
41
+ --text-brand: 204 100% 39%;
42
+
43
+ --text-primary: 204 100% 30%;
44
+ --text-success: 152 84% 22%;
45
+ --text-warning: 36 100% 28%;
46
+ --text-info: 221 70% 38%;
47
+ --text-error: 357 75% 38%;
48
+
99
49
  --primary-hover: 204 100% 33%;
100
50
  --primary-active: 204 100% 28%;
101
51
  --secondary-hover: 45 15% 91%;
@@ -103,24 +53,20 @@
103
53
  --destructive-hover: 357 64% 38%;
104
54
  --destructive-active: 357 64% 32%;
105
55
 
106
- /* 和色 (wa-iro) — traditional Japanese accent palette for charts, tags,
107
- * decoration. Decorative hex (NOT semantic): never remap a wa-iro to a
108
- * semantic role beyond the five canonical mappings used above. */
109
- --wa-ai: #165e83; /* 藍 indigo */
110
- --wa-gunjo: #4c6cb3; /* 群青 ultramarine */
111
- --wa-ruri: #1e50a2; /* 瑠璃 lapis */
112
- --wa-kon: #223a70; /* 紺 navy */
113
- --wa-wakatake: #68be8d; /* 若竹 young bamboo */
114
- --wa-moegi: #006e54; /* 萌葱 spring green */
115
- --wa-yamabuki: #f8b500; /* 山吹 mountain yellow */
116
- --wa-shu: #eb6101; /* 朱 vermilion */
117
- --wa-akane: #b7282e; /* 茜 madder */
118
- --wa-enji: #b94047; /* 臙脂 cochineal */
119
- --wa-sakura: #fef4f4; /* 桜 cherry (soft bg) */
120
- --wa-sumi: #595857; /* 墨 warm ink */
121
- --wa-nezu: #949495; /* 鼠 mouse-grey */
122
-
123
- /* Chart accents are neutral decorative primitives, not business semantics. */
56
+ --wa-ai: #165e83;
57
+ --wa-gunjo: #4c6cb3;
58
+ --wa-ruri: #1e50a2;
59
+ --wa-kon: #223a70;
60
+ --wa-wakatake: #68be8d;
61
+ --wa-moegi: #006e54;
62
+ --wa-yamabuki: #f8b500;
63
+ --wa-shu: #eb6101;
64
+ --wa-akane: #b7282e;
65
+ --wa-enji: #b94047;
66
+ --wa-sakura: #fef4f4;
67
+ --wa-sumi: #595857;
68
+ --wa-nezu: #949495;
69
+
124
70
  --chart-1: #0077c7;
125
71
  --chart-2: #006e54;
126
72
  --chart-3: #f8b500;
@@ -128,18 +74,13 @@
128
74
  --chart-5: #4c6cb3;
129
75
  --chart-6: #eb6101;
130
76
 
131
- /* Disabled affordance opacity — single knob (was referenced but undefined → silent failure). */
132
77
  --disabled-opacity: 0.5;
133
78
 
134
- /* Shape and elevation */
135
- /* 6px base × scaling; override to retheme every radius step */
136
79
  --radius: calc(0.375rem * var(--scaling));
137
- --radius-ratio: 1.618; /* φ — radii scale by the golden ratio (steps derive in @theme) */
138
- --radius-pill: 9999px; /* fully-round: switch / radio / slider / pill badges (NOT --radius-derived) */
139
- --radius-sharp: 0; /* squared corners: table cells, flush inputs */
140
- /* Elevation ramp. `--shadow-color` is the single brand-tint hook (space-separated RGB channels):
141
- * a service can set e.g. `--shadow-color: 12 26 49` (navy) to tint the WHOLE ramp at once. These
142
- * own `--shadow-md` too, so dropdown/popover/nav no longer borrow Tailwind's foreign gray-black. */
80
+ --radius-ratio: 1.618;
81
+ --radius-pill: 9999px;
82
+ --radius-sharp: 0;
83
+
143
84
  --shadow-color: 0 0 0;
144
85
  --shadow-xs: 0 1px 1px 0 rgb(var(--shadow-color) / 0.04);
145
86
  --shadow-sm: 0 1px 2px 0 rgb(var(--shadow-color) / 0.05);
@@ -151,18 +92,8 @@
151
92
  0 20px 25px -5px rgb(var(--shadow-color) / 0.1), 0 8px 10px -6px rgb(var(--shadow-color) / 0.1);
152
93
  --shadow-2xl: 0 25px 50px -12px rgb(var(--shadow-color) / 0.25);
153
94
 
154
- /* Brand GLOW — an opt-in coloured halo for the primary CTA (and any surface that opts in).
155
- * Quiet by default (cardinal rule #44): a zero-size transparent shadow, which is invalid as a
156
- * bare `none` inside a comma shadow list but valid as `0 0 0 0 transparent`. A service turns it
157
- * on by overriding the whole value once, e.g. `--shadow-glow: 0 8px 20px hsl(var(--primary) / .32)`
158
- * — the CTA then carries a brand glow with no component change. */
159
95
  --shadow-glow: 0 0 0 0 transparent;
160
96
 
161
- /* Brand SPOTLIGHT — a decorative radial brand halo for hero / auth backdrops (the `.ui-brand-glow`
162
- * utility paints this as a background-image on an aria-hidden layer). Every knob is a token, so a
163
- * service retints (`--brand-glow-color`), softens (`--brand-glow-alpha`), resizes
164
- * (`--brand-glow-size`) or repositions (`--brand-glow-position`) the halo with no markup change;
165
- * override the whole `--brand-glow` for a bespoke gradient. Default: a soft primary glow up top. */
166
97
  --brand-glow-color: var(--primary);
167
98
  --brand-glow-alpha: 0.18;
168
99
  --brand-glow-size: 60% 50%;
@@ -173,160 +104,77 @@
173
104
  transparent 70%
174
105
  );
175
106
 
176
- /* FOCUS RING — the two global knobs for the keyboard-focus affordance (WCAG 2.4.7 / 2.4.11).
177
- * `--focus-ring-color` is the themeable hue (HSL components, defaults to --ring) and
178
- * `--focus-ring-width` the standard thickness; override either ONCE — even scoped under a
179
- * `[data-tenant]` — to retint or resize EVERY focus ring. `--focus-ring-color` is declared
180
- * `initial` (NOT `var(--ring)`): a :root binding to a role var would freeze at the :root --ring
181
- * and a scoped [data-tenant] override of --ring alone would never reach it. Every :focus-visible
182
- * rule reads it with the live-role fallback `hsl(var(--focus-ring-color, var(--ring)))`, so the
183
- * default re-resolves at the element that paints the ring while an explicit override still wins. */
184
- --focus-ring-color: initial; /* default = the live --ring role */
107
+ --focus-ring-color: initial;
185
108
  --focus-ring-width: var(--stroke-md);
186
- /* Alpha of the ring fill. Exists so a component that needs a SOFTER ring
187
- * (a filled toggle, tinted shell chrome) tunes one knob instead of writing
188
- * its own `hsl(... / 0.35)` — which is how four incompatible ring shapes
189
- * appeared before the single-source rule in styles/focus-ring.css. */
109
+
190
110
  --focus-ring-opacity: 1;
191
- /* Gap between element and ring, for the OUTLINE form only (a star, a dot, a
192
- * heading anchor — marks where a radius-hugging shadow would touch the
193
- * glyph). The shadow form ignores it by construction. */
111
+
194
112
  --focus-ring-offset: 0px;
195
- /* Ring headroom for clipped chrome (`overflow-clip-margin` on the topbar family, gh#291).
196
- * MUST stay a plain length consumed via a bare var(): Chromium rejects any calc() in
197
- * overflow-clip-margin at parse time (even calc(2 * 2px)), silently dropping the
198
- * declaration to 0. Value = max ring paint (3px open/focus) + rounding immunity:
199
- * at 4px a flush-edge ring had only 1px of slack, which device-pixel rounding on
200
- * non-retina (dpr 1) displays or fractional browser zoom could consume, shaving the
201
- * ring's outer edge. 8px keeps ≥5px of slack under any rounding regime. */
113
+
202
114
  --focus-ring-clip-margin: 8px;
203
- /* REGION focus ring — the keyboard-scroll affordance on large scroll REGIONS (`.app-main`,
204
- * gh#271/gh#276), separate from the control ring above. A control-strength 2px brand frame
205
- * around the entire content area reads as a glitch to mouse-first users (`:focus-visible`
206
- * promotes on any keypress after a click-focus), so the DEFAULT IS OFF — a deliberate,
207
- * product-owner tradeoff against WCAG 2.4.7 for keyboard-scroll visibility. A service that
208
- * needs the visible affordance opts in with ONE token:
209
- * --region-focus-ring-width: var(--focus-ring-width);
210
- * `--region-focus-ring-color` is declared `initial` (NOT a :root var binding — the freeze
211
- * rule) and resolves to the live focus-ring hue at the element that paints it. */
115
+
212
116
  --region-focus-ring-width: 0;
213
- --region-focus-ring-color: initial; /* default = hsl(var(--focus-ring-color, var(--ring))) */
214
-
215
- /* GRADIENTS — opt-in decorative fills exposed at the token layer so a service can paint a hero
216
- * banner, a brand wash, or a radial brand glow purely by configuring tokens (cardinal rule #45).
217
- * All default to a transparent no-op so nothing renders until a theme opts in; a surface that
218
- * supports a gradient reads one of these as its background-image. Examples a service might set:
219
- * --gradient-brand: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
220
- * --gradient-hero: linear-gradient(180deg, hsl(var(--secondary)), hsl(var(--background)));
221
- * --gradient-glow: radial-gradient(60% 80% at 50% 0%, hsl(var(--primary) / .25), transparent); */
117
+ --region-focus-ring-color: initial;
118
+
222
119
  --gradient-brand: none;
223
120
  --gradient-hero: none;
224
121
  --gradient-glow: none;
225
122
 
226
- /* Sans stack — FONT-AGNOSTIC by default. The library ships NO hardcoded brand
227
- * face here: `--font-sans-base` is a pure system stack so godx renders cleanly
228
- * with zero font setup. Consumers supply their own faces (next/font, @fontsource,
229
- * self-host) and set the tokens — never edit the library.
230
- *
231
- * Two ways to theme fonts, both token-only (no [lang] selectors to write):
232
- * 1. One face everywhere → override `--font-sans-base`.
233
- * 2. Per-language faces → set the per-lang SLOT tokens; styles/base.css wires
234
- * each `[lang]` to read its slot with `--font-sans-base` as the fallback:
235
- * --font-sans-ja (lang="ja")
236
- * --font-sans-ko (lang="ko")
237
- * --font-sans-vi (lang="vi")
238
- * --font-sans-zh-hans (lang="zh" | "zh-Hans" | "zh-CN")
239
- * --font-sans-zh-hant (lang="zh-Hant" | "zh-TW")
240
- * e.g. `--font-sans-ja: "Noto Sans JP", var(--font-sans-base);`
241
- * The opt-in bundle `@godxjp/ui/styles/fonts` overwrites `--font-sans-base`
242
- * (and `--font-sans-vi`) with the DXS bundle — "Noto Sans JP" primary, "M PLUS 2"
243
- * as its fallback — so the all-in-one entry is zero-config. That fill also
244
- * lands on `:root` at THIS specificity, so `styles/fonts` MUST be imported AFTER
245
- * `styles/base`, or the system stack below silently wins (issue #210). */
246
123
  --font-sans-base:
247
124
  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui,
248
125
  sans-serif;
249
126
  --font-family-sans: var(--font-sans-base);
250
127
  --font-family-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
251
- /* Dual-font split (opt-in) — many brand designs pair a DISPLAY face for headings with a separate
252
- * BODY face (e.g. Source Sans 3 display + Inter body). Both default to --font-family-sans, so a
253
- * single-font system is unchanged; a service overrides one or both. Headings read
254
- * --font-family-display, body reads --font-family-body (wired in styles/index.css @layer base). */
128
+
255
129
  --font-family-display: var(--font-family-sans);
256
130
  --font-family-body: var(--font-family-sans);
257
- /* ── Type scale — GOLDEN-RATIO modular scale (Ant/Tailwind model). ONE base + ONE ratio; every
258
- * step is base × ratioⁿ, so the whole scale stays in golden proportion. `--font-size-ratio` is
259
- * φ^¼ (the golden ratio's quarter-step ≈ 1.1227) — a TRUE golden ratio yet dense enough that
260
- * headings stay small (h1≈20, h2≈18; pure φ=1.618 would be marketing-size). Internal apps get the
261
- * 14px DEFAULT with ZERO config; a customer overrides `--font-size-base` (and optionally
262
- * `--font-size-ratio`) and the entire scale rescales in golden proportion. */
263
- --font-size-base: 0.875rem; /* 14px — THE base (= <body>). The single knob; override to retheme. */
264
- --font-size-ratio: 1.1227; /* φ^¼ — golden-ratio step (φ=1.618, φ^¼ keeps the dense scale small) */
131
+
132
+ --font-size-base: 0.875rem;
133
+ --font-size-ratio: 1.1227;
265
134
  --font-size-2xs: calc(
266
135
  var(--font-size-base) / var(--font-size-ratio) / var(--font-size-ratio)
267
- ); /* ratio⁻² ≈ 11px */
268
- --font-size-xs: calc(var(--font-size-base) / var(--font-size-ratio)); /* ratio⁻¹ ≈ 12.5px */
269
- --font-size-sm: var(--font-size-base); /* 14px — body (alias of base) */
136
+ );
137
+ --font-size-xs: calc(var(--font-size-base) / var(--font-size-ratio));
138
+ --font-size-sm: var(--font-size-base);
270
139
  --font-size-lg: calc(
271
140
  var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio)
272
- ); /* ratio² ≈ 17.6px */
273
- --font-size-xl: calc(var(--font-size-lg) * var(--font-size-ratio)); /* ratio³ ≈ 19.8px */
274
- --font-size-2xl: calc(var(--font-size-xl) * var(--font-size-ratio)); /* ratio⁴ ≈ 22.3px */
275
-
276
- /* DISPLAY type — OPT-IN large sizes for MARKETING / hero surfaces (landing pages, CTA banners).
277
- * The enterprise heading scale stays small by design (h1 = 20px, 渋み restraint); these are a
278
- * SEPARATE bolder ramp a marketing surface opts into via the text-3xl/-4xl/-5xl utilities (wired
279
- * in styles/index.css @theme). A service rescales the whole display ramp from --font-size-display
280
- * (its own base). Nothing in the admin system uses them, so defaults are unchanged. */
281
- --font-size-display: 3.375rem; /* 54px — hero display (the single display knob) */
282
- --font-size-display-ratio: 1.28; /* bolder step than the body φ^¼ — marketing wants more contrast */
141
+ );
142
+ --font-size-xl: calc(var(--font-size-lg) * var(--font-size-ratio));
143
+ --font-size-2xl: calc(var(--font-size-xl) * var(--font-size-ratio));
144
+
145
+ --font-size-display: 3.375rem;
146
+ --font-size-display-ratio: 1.28;
283
147
  --font-size-3xl: calc(
284
148
  var(--font-size-display) / var(--font-size-display-ratio) / var(--font-size-display-ratio)
285
- ); /* ≈ 33 → 28px feature heading */
149
+ );
286
150
  --font-size-4xl: calc(
287
151
  var(--font-size-display) / var(--font-size-display-ratio)
288
- ); /* ≈ 36px section */
289
- --font-size-5xl: var(--font-size-display); /* 54px hero */
152
+ );
153
+ --font-size-5xl: var(--font-size-display);
290
154
 
291
- /* Headings — also golden-derived. h1=ratio³, h2=ratio²; h3/h4 reuse body sizes (single source). */
292
155
  --heading-h1: calc(
293
156
  var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio) * var(--font-size-ratio)
294
- ); /* ≈ 20px */
157
+ );
295
158
  --heading-h2: calc(
296
159
  var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio)
297
- ); /* ≈ 18px */
298
- --heading-h3: var(--font-size-base); /* 14px — h3 */
299
- --heading-h4: var(--font-size-xs); /* ≈ 12.5px — h4 */
160
+ );
161
+ --heading-h3: var(--font-size-base);
162
+ --heading-h4: var(--font-size-xs);
300
163
 
301
164
  --font-weight-normal: 400;
302
165
  --font-weight-medium: 500;
303
- /* the reference design uses three weights only: 400 body · 500 heading/label · 700 emphasis. 600 is
304
- * forbidden (ambiguous between 500 and 700) — the legacy "semibold" token collapses to medium
305
- * so any remaining reference renders at 500. `bold` is the 700 emphasis weight. */
166
+
306
167
  --font-weight-semibold: 500;
307
168
  --font-weight-bold: 700;
308
- /* Display/black weight — OPT-IN for marketing display type (hero/CTA). The enterprise system caps
309
- * at 700 (簡素 restraint); this is only reached via the .font-display-weight utility / a service
310
- * setting it on a display surface, so admin text is unchanged. */
169
+
311
170
  --font-weight-black: 800;
312
171
  --line-height-tight: 1.25;
313
172
  --line-height-normal: 1.5;
314
173
  --line-height-body: 1.7;
315
174
  --letter-spacing-tight: 0;
316
175
 
317
- /* ── SCALING — the one global density knob (Radix Themes model). A single
318
- * dimensionless multiplier on every SIZE token (spacing grid, control / table /
319
- * checkbox / switch heights, radius), so the whole UI rescales in proportion
320
- * from one place. `1` = the design baseline. The `density` axis sets named
321
- * presets (compact .92 · default 1 · comfortable 1.08); AppProvider's `scaling`
322
- * prop sets any value continuously. Type has its OWN base+ratio (--font-size-base)
323
- * and is NOT scaled here — fontSize stays an orthogonal axis. Touch targets
324
- * (--touch-target-min) are also exempt (a11y minimum). */
325
176
  --scaling: 1;
326
177
 
327
- /* Raw spacing scale — the 4px grid, scaled. Everything that derives from
328
- * --space-* (padding, gaps, --phi-unit, semantic spacing, chrome) inherits the
329
- * scaling automatically; this is the single highest-leverage scaling point. */
330
178
  --space-0: 0;
331
179
  --space-1: calc(0.25rem * var(--scaling));
332
180
  --space-2: calc(0.5rem * var(--scaling));
@@ -338,115 +186,31 @@
338
186
  --space-10: calc(2.5rem * var(--scaling));
339
187
  --space-12: calc(3rem * var(--scaling));
340
188
 
341
- /* ── ICON SIZE — the geometric axis that had a vocabulary but no name (gh#326).
342
- *
343
- * 28 component tokens were declaring raw numbers, and between them they only ever used NINE
344
- * values. The scale was already there; nobody had written it down. These nine names ARE that
345
- * list — naming an existing vocabulary, not inventing a new one.
346
- *
347
- * A FIXED LIST, NOT A RATIO. Unlike --font-size-* there is no `base * ratio^n` here, and that
348
- * is deliberate: 14/16 = 0.875 but 20/16 = 1.25, so no single ratio generates these steps.
349
- * Type can sit between pixels because hinting and antialiasing carry it; a 1px-stroke glyph
350
- * cannot — half a pixel of icon is a blurred icon. So every step is a whole pixel at the 16px
351
- * root, and a service retunes a STEP rather than a ratio.
352
- *
353
- * NOT SCALED HERE. --scaling is applied by the tokens that opt IN
354
- * (`calc(var(--icon-size-md) * var(--scaling))`, as --control-icon-size does), so the scale
355
- * itself stays the crisp whole-pixel list. Density is a per-token decision, not a property of
356
- * the vocabulary.
357
- *
358
- * TIER 1 / TIER 2 — where the boundary sits. These nine steps are tier 1: the value appears in
359
- * more than one place, so it earns a name and a service retunes it once. A value that appears
360
- * in exactly ONE place (the 6px status dot) is tier 2 and does NOT belong on the scale — set
361
- * that component's own `--*-icon-size` / `--*-glyph-size` token at the call site instead
362
- * (`style={{ "--menu-icon-size": "6px" }}` or a `[data-…]`-scoped rule in the app theme). An
363
- * inline custom property wins by inheritance proximity, so tier 2 needs no `!important`, no
364
- * `:root` override and no fork. Every icon rule in src/styles reads its token through `var()`
365
- * with no literal fallback, which is what keeps that route open — see docs/TOKENS.md. */
366
- --icon-size-2xs: 0.625rem; /* 10px */
367
- --icon-size-xs: 0.75rem; /* 12px */
368
- --icon-size-sm: 0.875rem; /* 14px */
369
- --icon-size-md: 1rem; /* 16px — the default icon step */
370
- --icon-size-lg: 1.25rem; /* 20px */
371
- --icon-size-xl: 1.5rem; /* 24px */
372
- --icon-size-2xl: 2.25rem; /* 36px */
373
- --icon-size-3xl: 2.5rem; /* 40px */
374
- --icon-size-4xl: 3rem; /* 48px */
375
-
376
- /* ── STROKE — the thickness of a painted LINE (gh#324, the second axis to be named).
377
- *
378
- * gh#324 measured `width` at 91% raw and called it the worst axis in the system. It is not one
379
- * axis. Three unrelated concerns wear the `-width` suffix: the thickness of a drawn line, the
380
- * measure of a container (a dialog, a reading column, a sidebar), and the content width of a
381
- * field (how wide a locale picker must be to hold its longest label). Only the FIRST is a
382
- * vocabulary — see the verdict recorded in `scripts/token-scale-bypass-rules.mjs`.
383
- *
384
- * The vocabulary was already there and repeats hard: SIX values across ~20 tokens spanning
385
- * borders, focus rings, accent rails, selected-state markers and presence strokes. Naming it is
386
- * what lets a service retune line weight once — a hi-dpi theme that wants 1.5px hairlines, or a
387
- * high-contrast theme that wants every emphasis stroke at 3px — instead of hunting 20 tokens.
388
- *
389
- * PIXELS, NOT REM, AND DELIBERATELY SO. A stroke is a DEVICE line: its job is to read as one
390
- * crisp rule at any type size, so it must not grow when the root font-size does. Every token
391
- * that moves onto this scale was already `px` for that reason; a `rem` thickness
392
- * (`--slider-track-height: 0.375rem`) is a different decision and stays where it is.
393
- *
394
- * NOT SCALED. `--scaling` is a DENSITY knob — it tightens the spacing rhythm, and a 1px divider
395
- * that became 0.92px under compact density would blur, not tighten. No token on this axis
396
- * multiplies by it today and none should.
397
- *
398
- * `--stroke-hairline` sits BELOW `--stroke-sm` rather than being called `xs`, because 1px is
399
- * not really a step: it is the device hairline, the one thickness a service retunes the
400
- * EXISTENCE of rather than the value (cardinal rule #44). The scale-bypass guard exempts a bare
401
- * `1px` for the same reason. Naming it anyway gives the retune-the-value route to the themes
402
- * that want it.
403
- *
404
- * TIER 2 — a thickness that appears in exactly one place does not belong here. Set that
405
- * component's own `--*-border-width` / `--*-ring-width` token at the call site or in the app
406
- * theme; every stroke rule in src/styles reads its token through `var()`. */
407
- --stroke-hairline: 1px; /* every resting border, divider and rule */
189
+ --icon-size-2xs: 0.625rem;
190
+ --icon-size-xs: 0.75rem;
191
+ --icon-size-sm: 0.875rem;
192
+ --icon-size-md: 1rem;
193
+ --icon-size-lg: 1.25rem;
194
+ --icon-size-xl: 1.5rem;
195
+ --icon-size-2xl: 2.25rem;
196
+ --icon-size-3xl: 2.5rem;
197
+ --icon-size-4xl: 3rem;
198
+
199
+ --stroke-hairline: 1px;
408
200
  --stroke-sm: 1.5px;
409
- --stroke-md: 2px; /* the emphasis stroke — focus rings, selected markers */
201
+ --stroke-md: 2px;
410
202
  --stroke-lg: 3px;
411
203
  --stroke-xl: 4px;
412
204
  --stroke-2xl: 6px;
413
205
 
414
- /* ── BAND HEIGHT — the vertical extent of a horizontal band that content is centred in
415
- * (gh#324, the third axis to be named).
416
- *
417
- * Same split as `width`: `height` is TWO concerns wearing one suffix. A control, a table row, a
418
- * menu item, a sidebar nav row and the app-shell top bar are all the same decision — how tall
419
- * is the band this content sits in — and they share ONE vocabulary of seven values, each of
420
- * which is declared by two to five tokens. A chart plot's height, a transfer pane's min-height
421
- * and a select popover's max-height are the OTHER concern: container measures, chosen per
422
- * surface, with almost no repeated value between them. Those are tier 2 and stay literal.
423
- *
424
- * gh#324's fourth case is the whole argument: `PageContainer`'s chrome band had no height token
425
- * while `AppShell`'s bar did, so nothing could be aligned to it. The two were never conceived
426
- * as members of one axis, because the axis had no name.
427
- *
428
- * WHY THIS IS NOT `--control-height-*`. The control tier is a RUNTIME LADDER: `--control-height`
429
- * multiplies by `--scaling`, `-sm`/`-lg`/`-xs` step off it, and `@media (pointer: coarse)` lifts
430
- * the whole ladder to the 44px tap floor. This scale is the STATIC vocabulary that the ladder is
431
- * anchored on — `--control-height-default: var(--band-height-md)` — exactly as `--font-size-base`
432
- * anchors the type scale. Do NOT point a band token at `--control-height-*` to "reuse a step":
433
- * that silently enrols it in density AND in the coarse-pointer growth, which is a geometry
434
- * change, not a rename. `--table-row-height-default` is `var(--band-height-md)` and NOT
435
- * `var(--control-height-default)` for precisely that reason.
436
- *
437
- * NOT SCALED HERE, for the gh#328 reason: whether a band breathes with density is a per-token
438
- * decision made long ago. `--control-height` opts in (`calc(… * var(--scaling))`);
439
- * `--app-shell-bar-height` deliberately does not. Baking `--scaling` into the scale would flip
440
- * every one of them at once. */
441
- --band-height-xs: 1.5rem; /* 24px */
442
- --band-height-sm: 1.75rem; /* 28px */
443
- --band-height-md: 2rem; /* 32px — the default control/row band */
444
- --band-height-lg: 2.25rem; /* 36px */
445
- --band-height-xl: 2.75rem; /* 44px — the WCAG 2.2 AA touch floor (rule #24) */
446
- --band-height-2xl: 3rem; /* 48px */
447
- --band-height-3xl: 3.5rem; /* 56px */
448
-
449
- /* Golden ratio scale */
206
+ --band-height-xs: 1.5rem;
207
+ --band-height-sm: 1.75rem;
208
+ --band-height-md: 2rem;
209
+ --band-height-lg: 2.25rem;
210
+ --band-height-xl: 2.75rem;
211
+ --band-height-2xl: 3rem;
212
+ --band-height-3xl: 3.5rem;
213
+
450
214
  --ratio-phi: 1.6180339887;
451
215
  --phi-unit: var(--space-4);
452
216
  --phi-n2: calc(var(--phi-unit) / var(--ratio-phi) / var(--ratio-phi));
@@ -456,13 +220,6 @@
456
220
  --phi-p2: calc(var(--phi-p1) * var(--ratio-phi));
457
221
  }
458
222
 
459
- /* SCALE-FIXED — pin a subtree to the baseline size (--scaling 1) so persistent
460
- * chrome (the AppShell topbar, the global search palette, …) does NOT resize with
461
- * the density axis. Setting only --scaling:1 is insufficient: the size tokens were
462
- * already substituted at :root and inherit baked, so each --scaling-derived token
463
- * (and every semantic token that aliases the spacing grid) is RE-DECLARED here to
464
- * re-resolve at baseline. Apply via `className="… ui-scale-fixed"`. Must list every
465
- * scaled token — the scale-fixed coverage test guards against drift. */
466
223
  .ui-scale-fixed {
467
224
  --scaling: 1;
468
225
  --space-1: 0.25rem;
@@ -476,10 +233,7 @@
476
233
  --space-12: 3rem;
477
234
  --radius: 0.375rem;
478
235
  --control-height: var(--control-height-default);
479
- /* baseline tier values (2rem ∓ step) read straight off the band scale — keeps the
480
- * control-sizing guard happy and avoids re-deriving from the (baked) active
481
- * --control-height. Scale steps rather than literals since gh#324, so a service that
482
- * retunes --band-height-* retunes the scale-fixed chrome with everything else. */
236
+
483
237
  --control-height-sm: var(--band-height-sm);
484
238
  --control-height-lg: var(--band-height-lg);
485
239
  --control-height-xs: var(--band-height-xs);
@@ -513,10 +267,6 @@
513
267
  --space-chrome-gap: var(--space-2);
514
268
  --field-label-gap: var(--space-2);
515
269
 
516
- /* Motion — the primitive tier for animation, so enter/transition timing reads a token
517
- * instead of a literal 0.5s / cubic-bezier(...) / translateY(10px) (cardinal rule #2).
518
- * the reference design keeps motion LOW: short durations, a calm decelerate curve, a small reveal shift.
519
- * Consumers honour prefers-reduced-motion at the call site. */
520
270
  --duration-fast: 150ms;
521
271
  --duration-base: 250ms;
522
272
  --duration-slow: 500ms;
@@ -525,38 +275,26 @@
525
275
  --ease-decelerate: cubic-bezier(0, 0, 0, 1);
526
276
  --ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
527
277
  --reveal-distance: 10px;
528
- /* One step of the Reveal stagger ladder — `<Reveal delay={n}>` waits n × this before entering,
529
- * so a column of reveals cascades. Read instead of a literal `.04s`/`.09s` per-item delay. */
278
+
530
279
  --reveal-stagger-step: 60ms;
531
280
 
532
- /* AMBIENT/LOOPING motion (gh#313) — the cycle member of the motion tier. `--duration-fast|base|
533
- * slow` time a TRANSITION (something moves from A to B and stops); a loop needs an INTERVAL, so
534
- * every ambient affordance in the product breathes at one rate. `Activity` reads these; the
535
- * remaining Activity knobs (geometry / colour) live in tokens/components/activity.css.
536
- * NOTE these two are Activity-scoped but live HERE, beside `--reveal-*`, because the motion tier
537
- * is where timing belongs and because component-token names must carry a geometry/colour
538
- * property word (`check-token-tiers`) — there is none for a duration. */
539
281
  --duration-loop: 1400ms;
540
- /* Per-component override (#45): a service tunes its typing rhythm without moving every loop. */
282
+
541
283
  --activity-interval: var(--duration-loop);
542
- /* Offset between the three `dots` marks — the loop counterpart to `--reveal-stagger-step`,
543
- * named to match. In RTL the dots reverse with the row, so the cascade follows the reading
544
- * direction with no extra rule. */
284
+
545
285
  --activity-stagger-step: 160ms;
546
286
  }
547
287
 
548
288
  .dark,
549
289
  :root[data-theme="dark"] {
550
- /* Warm-tinted dark spine — keeps the hue-60 character at low lightness.
551
- * `data-theme="dark"` is the theme axis (AppProvider theme prop → <html>); the
552
- * legacy `.dark` class stays an equal alias so existing toggles keep working. */
290
+
553
291
  --background: 48 9% 9%;
554
292
  --foreground: 60 20% 96%;
555
293
  --card: 48 8% 12%;
556
294
  --card-foreground: 60 20% 96%;
557
295
  --popover: 48 8% 12%;
558
296
  --popover-foreground: 60 20% 96%;
559
- --primary: 204 90% 60%; /* SmartHR blue lifted for dark contrast */
297
+ --primary: 204 90% 60%;
560
298
  --primary-foreground: 48 9% 9%;
561
299
  --secondary: 45 6% 18%;
562
300
  --secondary-foreground: 60 20% 96%;
@@ -564,20 +302,12 @@
564
302
  --muted-foreground: 44 6% 64%;
565
303
  --accent: 45 7% 22%;
566
304
  --accent-foreground: 60 20% 96%;
567
- /* Filled destructive surfaces (button/badge/step) must clear WCAG AA (4.5:1) with comfortable
568
- * margin, not sit on the floor (gh#199 — dark default was 4.54:1). Base darkened 52%→48% and the
569
- * on-fill text lifted to pure white → ~5.5:1; states go DARKER (never lighter, which cut contrast
570
- * against the light label). Error TEXT on dark surfaces uses --text-error, not this fill token. */
305
+
571
306
  --destructive: 357 55% 48%;
572
307
  --destructive-foreground: 0 0% 100%;
573
308
  --border: 45 6% 22%;
574
- /* Control boundary (dark) — recomputed on the dark spine, not merely lightened by eye
575
- * (gh#315). The dark pair shared `45 6% 22%`, which sat at 1.55:1 on --background and 1.43:1
576
- * on the --card/--popover surface where dialogs put their fields. 47% gives
577
- * --background 4.22:1 · --card/--popover 3.88:1 · --muted/--secondary 3.17:1 · zebra 3.81:1 ·
578
- * hover 3.71:1. --border stays at 22%: dividers are decorative and a dark grid at 47% would
579
- * read as a wireframe. See the light block above for the full reasoning. */
580
- --input: 45 6% 47%; /* #7f7b71 — control boundary, ≥3:1 (WCAG 2.2 SC 1.4.11) */
309
+
310
+ --input: 45 6% 47%;
581
311
  --ring: 204 90% 60%;
582
312
  --success: 146 45% 55%;
583
313
  --success-foreground: 48 9% 9%;
@@ -588,20 +318,15 @@
588
318
  --attention: 25 95% 56%;
589
319
  --attention-foreground: 48 9% 9%;
590
320
 
591
- /* IDENTITY (dark) — the SAME canonical emerald hue/chroma, lifted 29.6% 36% lightness so the
592
- * mark reads off the warm near-black spine (#00b87c: 6.9:1 on --background, 6.3:1 on --card;
593
- * the unlifted #009766 sat at 4.4:1 on the card). The on-fill glyph flips dark, exactly like
594
- * --success-foreground does. */
595
- --brand: 160.5 100% 36%; /* #00b87c */
321
+ --brand: 160.5 100% 36%;
596
322
  --brand-foreground: 48 9% 9%;
597
323
 
598
- /* Extended text hierarchy + interaction ramp (dark) */
599
324
  --text-tertiary: 44 6% 56%;
600
325
  --text-disabled: 45 6% 40%;
601
326
  --text-link: 204 90% 66%;
602
327
  --text-brand: 204 90% 66%;
603
- /* Status text on the dark spine reads LIGHT (AA on dark surfaces). */
604
- --text-primary: 204 90% 64%; /* lifted brand blue — AA on the dark primary tint */
328
+
329
+ --text-primary: 204 90% 64%;
605
330
  --text-success: 146 55% 64%;
606
331
  --text-warning: 44 95% 62%;
607
332
  --text-info: 221 70% 72%;