@godxjp/ui 19.1.0 → 19.3.1

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 (437) 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 +20 -14
  11. package/dist/components/data-display/badge.js +18 -4
  12. package/dist/components/data-display/card.d.ts +21 -41
  13. package/dist/components/data-display/carousel.d.ts +1 -2
  14. package/dist/components/data-display/code-block.d.ts +4 -0
  15. package/dist/components/data-display/code-block.js +24 -0
  16. package/dist/components/data-display/data-table.d.ts +15 -37
  17. package/dist/components/data-display/data-table.js +1 -3
  18. package/dist/components/data-display/descriptions.d.ts +2 -6
  19. package/dist/components/data-display/descriptions.js +0 -2
  20. package/dist/components/data-display/index.d.ts +4 -0
  21. package/dist/components/data-display/index.js +4 -0
  22. package/dist/components/data-display/list-row.d.ts +3 -22
  23. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  24. package/dist/components/data-display/progress.d.ts +1 -1
  25. package/dist/components/data-display/prose.d.ts +4 -0
  26. package/dist/components/data-display/prose.js +20 -0
  27. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  28. package/dist/components/data-display/table.d.ts +20 -80
  29. package/dist/components/data-display/table.js +0 -3
  30. package/dist/components/data-display/timeline.d.ts +3 -5
  31. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  32. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  33. package/dist/components/data-entry/calendar.d.ts +3 -2
  34. package/dist/components/data-entry/calendar.js +58 -3
  35. package/dist/components/data-entry/command-palette.d.ts +8 -22
  36. package/dist/components/data-entry/date-picker.d.ts +4 -5
  37. package/dist/components/data-entry/date-picker.js +6 -1
  38. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  39. package/dist/components/data-entry/date-range-picker.js +8 -3
  40. package/dist/components/data-entry/form-errors.d.ts +7 -18
  41. package/dist/components/data-entry/form-field.js +1 -5
  42. package/dist/components/data-entry/form.d.ts +1 -9
  43. package/dist/components/data-entry/input.d.ts +16 -14
  44. package/dist/components/data-entry/input.js +3 -0
  45. package/dist/components/data-entry/month-picker.js +2 -2
  46. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  47. package/dist/components/data-entry/month-range-picker.js +2 -2
  48. package/dist/components/data-entry/number-input.d.ts +1 -5
  49. package/dist/components/data-entry/number-input.js +1 -0
  50. package/dist/components/data-entry/radio.js +0 -1
  51. package/dist/components/data-entry/search-select.d.ts +2 -4
  52. package/dist/components/data-entry/select.d.ts +11 -6
  53. package/dist/components/data-entry/select.js +4 -2
  54. package/dist/components/data-entry/switch.js +0 -1
  55. package/dist/components/data-entry/textarea.d.ts +10 -16
  56. package/dist/components/data-entry/time-picker.d.ts +3 -5
  57. package/dist/components/data-entry/upload-types.d.ts +1 -5
  58. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  59. package/dist/components/feedback/dialog.d.ts +6 -15
  60. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  61. package/dist/components/feedback/sheet.d.ts +3 -10
  62. package/dist/components/feedback/sheet.js +1 -1
  63. package/dist/components/feedback/sonner.js +2 -3
  64. package/dist/components/general/activity.d.ts +4 -30
  65. package/dist/components/general/button.js +1 -10
  66. package/dist/components/general/logo.d.ts +6 -28
  67. package/dist/components/general/reveal.d.ts +3 -9
  68. package/dist/components/general/typography.d.ts +1 -3
  69. package/dist/components/layout/account-chip.d.ts +8 -0
  70. package/dist/components/layout/account-chip.js +45 -0
  71. package/dist/components/layout/auth-divider.d.ts +2 -9
  72. package/dist/components/layout/auth-shell.d.ts +1 -14
  73. package/dist/components/layout/breadcrumb.d.ts +1 -5
  74. package/dist/components/layout/centered-shell.d.ts +4 -18
  75. package/dist/components/layout/error-surface.d.ts +11 -28
  76. package/dist/components/layout/error-surface.js +4 -1
  77. package/dist/components/layout/index.d.ts +2 -0
  78. package/dist/components/layout/index.js +2 -0
  79. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  80. package/dist/components/layout/master-detail.d.ts +2 -18
  81. package/dist/components/layout/page-container.js +0 -1
  82. package/dist/components/layout/responsive-grid.d.ts +6 -1
  83. package/dist/components/layout/responsive-grid.js +9 -2
  84. package/dist/components/layout/service-role-panel.d.ts +7 -19
  85. package/dist/components/layout/sidebar.d.ts +5 -27
  86. package/dist/components/layout/sidebar.js +0 -1
  87. package/dist/components/layout/split-pane.d.ts +0 -7
  88. package/dist/components/layout/topbar.d.ts +1 -14
  89. package/dist/components/navigation/app-setting-picker.js +1 -3
  90. package/dist/components/navigation/filter-bar.d.ts +1 -6
  91. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  92. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  93. package/dist/components/navigation/tabs.js +4 -8
  94. package/dist/components/query/data-state.d.ts +2 -2
  95. package/dist/components/ui/credential-reveal.d.ts +1 -4
  96. package/dist/components/ui/hover-card.d.ts +1 -2
  97. package/dist/components/ui/separator.d.ts +2 -15
  98. package/dist/components/ui/toggle-group.d.ts +1 -5
  99. package/dist/components/ui/toggle.d.ts +6 -31
  100. package/dist/email/brand-mark.d.ts +6 -34
  101. package/dist/email/color.d.ts +7 -17
  102. package/dist/email/geometry.d.ts +4 -8
  103. package/dist/email/index.d.ts +4 -48
  104. package/dist/email/inline-style.d.ts +3 -9
  105. package/dist/email/urgency.d.ts +2 -7
  106. package/dist/form/form-context.d.ts +2 -5
  107. package/dist/form/form-root.d.ts +1 -2
  108. package/dist/i18n/messages/en.json +4 -0
  109. package/dist/i18n/messages/ja.json +4 -0
  110. package/dist/i18n/messages/vi.json +4 -0
  111. package/dist/inertia/index.d.ts +2 -10
  112. package/dist/lib/control-styles.d.ts +10 -21
  113. package/dist/lib/control-styles.js +4 -6
  114. package/dist/lib/datetime/format-date.d.ts +1 -4
  115. package/dist/lib/field-a11y.d.ts +11 -68
  116. package/dist/lib/field-a11y.js +0 -1
  117. package/dist/lib/format.d.ts +4 -8
  118. package/dist/lib/hooks.d.ts +6 -12
  119. package/dist/lib/permission-grid.d.ts +3 -18
  120. package/dist/lib/query-error.d.ts +3 -3
  121. package/dist/props/components/app.prop.d.ts +15 -38
  122. package/dist/props/components/charts.prop.d.ts +2 -3
  123. package/dist/props/components/data-display.prop.d.ts +55 -72
  124. package/dist/props/components/data-entry.prop.d.ts +35 -40
  125. package/dist/props/components/form.prop.d.ts +2 -6
  126. package/dist/props/components/general.prop.d.ts +11 -27
  127. package/dist/props/components/layout.prop.d.ts +89 -260
  128. package/dist/props/components/navigation.prop.d.ts +27 -42
  129. package/dist/props/registry.d.ts +36 -1
  130. package/dist/props/registry.js +45 -1
  131. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  132. package/dist/props/vocabulary/index.d.ts +1 -1
  133. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  134. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  135. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  136. package/dist/styles/alert-layout.css +1 -32
  137. package/dist/styles/badge-layout.css +19 -18
  138. package/dist/styles/base.css +14 -113
  139. package/dist/styles/card-layout.css +6 -128
  140. package/dist/styles/chart-layout.css +2 -17
  141. package/dist/styles/control.css +380 -458
  142. package/dist/styles/core.css +21 -0
  143. package/dist/styles/data-display-layout.css +175 -94
  144. package/dist/styles/data-entry-layout.css +0 -45
  145. package/dist/styles/density.css +1 -30
  146. package/dist/styles/dialog-layout.css +5 -69
  147. package/dist/styles/focus-ring.css +13 -87
  148. package/dist/styles/fonts.css +1 -31
  149. package/dist/styles/form-layout.css +7 -91
  150. package/dist/styles/index.css +2 -20
  151. package/dist/styles/layout.css +38 -456
  152. package/dist/styles/logo-layout.css +1 -35
  153. package/dist/styles/motion.css +3 -42
  154. package/dist/styles/navigation-layout.css +3 -50
  155. package/dist/styles/shell-layout.css +37 -403
  156. package/dist/styles/table-layout.css +16 -274
  157. package/dist/styles/text-layout.css +7 -21
  158. package/dist/styles/toggle.css +1 -23
  159. package/dist/theme/dxs.canonical.css +1 -55
  160. package/dist/theme/example.service.css +1 -26
  161. package/dist/theme/famgia.service.css +5 -15
  162. package/dist/tokens/axes.css +3 -40
  163. package/dist/tokens/base.css +1 -4
  164. package/dist/tokens/components/activity.css +6 -42
  165. package/dist/tokens/components/badge.css +12 -13
  166. package/dist/tokens/components/banner.css +4 -9
  167. package/dist/tokens/components/card.css +32 -88
  168. package/dist/tokens/components/chart.css +9 -26
  169. package/dist/tokens/components/control.css +37 -222
  170. package/dist/tokens/components/data-display.css +28 -79
  171. package/dist/tokens/components/data-entry.css +5 -19
  172. package/dist/tokens/components/descriptions.css +7 -27
  173. package/dist/tokens/components/email.css +38 -84
  174. package/dist/tokens/components/error-surface.css +2 -18
  175. package/dist/tokens/components/feedback.css +27 -124
  176. package/dist/tokens/components/form.css +13 -45
  177. package/dist/tokens/components/legal-document.css +16 -41
  178. package/dist/tokens/components/list-row.css +11 -36
  179. package/dist/tokens/components/logo.css +2 -57
  180. package/dist/tokens/components/navigation.css +16 -94
  181. package/dist/tokens/components/scroll-area.css +2 -18
  182. package/dist/tokens/components/separator.css +8 -30
  183. package/dist/tokens/components/sheet.css +3 -14
  184. package/dist/tokens/components/shell.css +53 -307
  185. package/dist/tokens/components/sidebar.css +5 -22
  186. package/dist/tokens/components/table.css +19 -140
  187. package/dist/tokens/components/toggle.css +3 -65
  188. package/dist/tokens/components/upload.css +7 -43
  189. package/dist/tokens/foundation.css +108 -383
  190. package/dist/tokens/semantic/layout.css +33 -207
  191. package/docs/CANONICAL-CONTRACTS.md +206 -0
  192. package/docs/COMPONENTS.md +157 -0
  193. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  194. package/docs/CONSUMER-RULES.md +14 -0
  195. package/docs/CUSTOMER-THEMING.md +162 -0
  196. package/docs/DATETIME.md +69 -0
  197. package/docs/DEVELOPMENT.md +173 -0
  198. package/docs/FORMS.md +143 -0
  199. package/docs/FRAME-A11Y-CI.md +267 -0
  200. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  201. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  202. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  203. package/docs/FRAME-COVERAGE.md +29 -0
  204. package/docs/PROPS-REGISTRY.md +61 -0
  205. package/docs/PROPS-VOCABULARY.md +100 -0
  206. package/docs/README.md +60 -0
  207. package/docs/REGISTRY.md +70 -0
  208. package/docs/SPACING.md +56 -0
  209. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  210. package/docs/TESTING.md +98 -0
  211. package/docs/TOKENS.md +347 -0
  212. package/docs/asset-modules.d.ts +46 -0
  213. package/docs/assets/cover-terrain.svg +6 -0
  214. package/docs/assets/portrait-amber.svg +5 -0
  215. package/docs/assets/portrait-clay.svg +5 -0
  216. package/docs/assets/portrait-indigo.svg +5 -0
  217. package/docs/assets/portrait-iris.svg +5 -0
  218. package/docs/assets/portrait-moss.svg +5 -0
  219. package/docs/assets/portrait-plum.svg +5 -0
  220. package/docs/assets/portrait-slate.svg +5 -0
  221. package/docs/charts/compact-bar-trend.tsx +328 -0
  222. package/docs/charts/size-tiers.tsx +192 -0
  223. package/docs/data-display/accordion.tsx +99 -0
  224. package/docs/data-display/avatar.tsx +355 -0
  225. package/docs/data-display/badge.tsx +283 -0
  226. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  227. package/docs/data-display/card/index.md +3 -0
  228. package/docs/data-display/card/index.tsx +285 -0
  229. package/docs/data-display/carousel.tsx +160 -0
  230. package/docs/data-display/charts.tsx +198 -0
  231. package/docs/data-display/code-block.tsx +90 -0
  232. package/docs/data-display/collapsible.tsx +162 -0
  233. package/docs/data-display/credential-reveal.tsx +145 -0
  234. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  235. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  236. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  237. package/docs/data-display/data-table/index.md +5 -0
  238. package/docs/data-display/data-table/index.tsx +295 -0
  239. package/docs/data-display/descriptions.tsx +143 -0
  240. package/docs/data-display/empty-state.tsx +164 -0
  241. package/docs/data-display/hover-card.tsx +181 -0
  242. package/docs/data-display/list-row.tsx +420 -0
  243. package/docs/data-display/permission-matrix.tsx +188 -0
  244. package/docs/data-display/popover-touch.tsx +27 -0
  245. package/docs/data-display/popover.tsx +246 -0
  246. package/docs/data-display/progress.tsx +84 -0
  247. package/docs/data-display/prose.tsx +105 -0
  248. package/docs/data-display/qr-code.tsx +68 -0
  249. package/docs/data-display/scroll-area.tsx +303 -0
  250. package/docs/data-display/service-launcher-card.tsx +145 -0
  251. package/docs/data-display/stat-card.tsx +99 -0
  252. package/docs/data-display/table.tsx +251 -0
  253. package/docs/data-display/timeline.tsx +112 -0
  254. package/docs/data-display/touch-actions.tsx +36 -0
  255. package/docs/data-display/tree-list.tsx +107 -0
  256. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  257. package/docs/data-entry/calendar.tsx +180 -0
  258. package/docs/data-entry/cascader.tsx +378 -0
  259. package/docs/data-entry/checkbox.tsx +256 -0
  260. package/docs/data-entry/color-picker.tsx +117 -0
  261. package/docs/data-entry/command-palette.tsx +179 -0
  262. package/docs/data-entry/command.tsx +262 -0
  263. package/docs/data-entry/country-picker-recipe.tsx +175 -0
  264. package/docs/data-entry/date-picker.tsx +191 -0
  265. package/docs/data-entry/date-range-picker.tsx +149 -0
  266. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  267. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  268. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  269. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  270. package/docs/data-entry/form-field/index.md +8 -0
  271. package/docs/data-entry/form-field/index.tsx +330 -0
  272. package/docs/data-entry/form-inertia.tsx +80 -0
  273. package/docs/data-entry/form-root.tsx +102 -0
  274. package/docs/data-entry/form.tsx +724 -0
  275. package/docs/data-entry/input-otp.tsx +231 -0
  276. package/docs/data-entry/input.tsx +114 -0
  277. package/docs/data-entry/label.tsx +100 -0
  278. package/docs/data-entry/month-picker.tsx +101 -0
  279. package/docs/data-entry/month-range-picker.tsx +115 -0
  280. package/docs/data-entry/number-input.tsx +240 -0
  281. package/docs/data-entry/password-input.tsx +102 -0
  282. package/docs/data-entry/password-strength.tsx +97 -0
  283. package/docs/data-entry/radio-group.tsx +95 -0
  284. package/docs/data-entry/rating.tsx +87 -0
  285. package/docs/data-entry/search-input.tsx +120 -0
  286. package/docs/data-entry/select-async-contracts.tsx +108 -0
  287. package/docs/data-entry/select-matrix.tsx +204 -0
  288. package/docs/data-entry/select.tsx +369 -0
  289. package/docs/data-entry/slider.tsx +130 -0
  290. package/docs/data-entry/switch.tsx +67 -0
  291. package/docs/data-entry/tag-input.tsx +108 -0
  292. package/docs/data-entry/textarea.tsx +209 -0
  293. package/docs/data-entry/time-picker.tsx +99 -0
  294. package/docs/data-entry/toggle-count.tsx +293 -0
  295. package/docs/data-entry/toggle-group.tsx +225 -0
  296. package/docs/data-entry/toggle.tsx +127 -0
  297. package/docs/data-entry/transfer.tsx +97 -0
  298. package/docs/data-entry/tree-select.tsx +204 -0
  299. package/docs/data-entry/upload.tsx +184 -0
  300. package/docs/feedback/alert-dialog.tsx +270 -0
  301. package/docs/feedback/alert.tsx +248 -0
  302. package/docs/feedback/banner.tsx +183 -0
  303. package/docs/feedback/danger-confirm.tsx +88 -0
  304. package/docs/feedback/dialog-touch.tsx +24 -0
  305. package/docs/feedback/dialog.tsx +193 -0
  306. package/docs/feedback/sheet.tsx +420 -0
  307. package/docs/feedback/skeleton.tsx +111 -0
  308. package/docs/feedback/toast.tsx +135 -0
  309. package/docs/feedback/tooltip.tsx +171 -0
  310. package/docs/feedback/two-factor-setup.tsx +68 -0
  311. package/docs/foundation/_email-specimen.ts +274 -0
  312. package/docs/foundation/colors.tsx +204 -0
  313. package/docs/foundation/density.tsx +232 -0
  314. package/docs/foundation/email-tokens.tsx +323 -0
  315. package/docs/foundation/radius-shadow.tsx +154 -0
  316. package/docs/foundation/spacing.tsx +211 -0
  317. package/docs/foundation/typography.tsx +147 -0
  318. package/docs/general/activity.tsx +224 -0
  319. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  320. package/docs/general/button/examples/form-actions.tsx +85 -0
  321. package/docs/general/button/examples/toolbar.tsx +160 -0
  322. package/docs/general/button/index.md +12 -0
  323. package/docs/general/button/index.tsx +211 -0
  324. package/docs/general/logo.tsx +131 -0
  325. package/docs/general/reveal.tsx +41 -0
  326. package/docs/general/typography.tsx +152 -0
  327. package/docs/layout/account-chip.tsx +72 -0
  328. package/docs/layout/admin-collection.tsx +122 -0
  329. package/docs/layout/app-shell.tsx +374 -0
  330. package/docs/layout/aspect-ratio.tsx +135 -0
  331. package/docs/layout/auth-account-summary.tsx +103 -0
  332. package/docs/layout/auth-divider.tsx +28 -0
  333. package/docs/layout/auth-footer.tsx +37 -0
  334. package/docs/layout/auth-identity.tsx +36 -0
  335. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  336. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  337. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  338. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  339. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  340. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  341. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  342. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  343. package/docs/layout/auth-recovery/index.md +140 -0
  344. package/docs/layout/auth-recovery/index.tsx +96 -0
  345. package/docs/layout/auth-shell-context.tsx +103 -0
  346. package/docs/layout/auth-shell-device.tsx +112 -0
  347. package/docs/layout/auth-shell-registration.tsx +335 -0
  348. package/docs/layout/auth-shell-variants.tsx +139 -0
  349. package/docs/layout/auth-shell.tsx +59 -0
  350. package/docs/layout/auth-stack.tsx +40 -0
  351. package/docs/layout/centered-shell.tsx +102 -0
  352. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  353. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  354. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  355. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  356. package/docs/layout/error-surface/index.md +153 -0
  357. package/docs/layout/error-surface/index.tsx +239 -0
  358. package/docs/layout/flex.tsx +266 -0
  359. package/docs/layout/legal-document-shell/_data.ts +110 -0
  360. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  361. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  362. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  363. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  364. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  365. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  366. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  367. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  368. package/docs/layout/legal-document-shell/index.md +51 -0
  369. package/docs/layout/legal-document-shell/index.tsx +101 -0
  370. package/docs/layout/master-detail.tsx +387 -0
  371. package/docs/layout/org-switcher.tsx +131 -0
  372. package/docs/layout/page-container.tsx +954 -0
  373. package/docs/layout/resizable-panel.tsx +419 -0
  374. package/docs/layout/responsive-grid.tsx +243 -0
  375. package/docs/layout/separator.tsx +327 -0
  376. package/docs/layout/service-role-panel.tsx +144 -0
  377. package/docs/layout/sidebar.tsx +609 -0
  378. package/docs/layout/split-pane.tsx +468 -0
  379. package/docs/layout/topbar.tsx +349 -0
  380. package/docs/navigation/app-setting-picker.tsx +142 -0
  381. package/docs/navigation/breadcrumb.tsx +135 -0
  382. package/docs/navigation/context-menu.tsx +123 -0
  383. package/docs/navigation/dropdown-menu.tsx +213 -0
  384. package/docs/navigation/filter-bar.tsx +227 -0
  385. package/docs/navigation/menubar.tsx +141 -0
  386. package/docs/navigation/navigation-menu.tsx +158 -0
  387. package/docs/navigation/pagination.tsx +241 -0
  388. package/docs/navigation/steps.tsx +265 -0
  389. package/docs/navigation/tabs-rtl.tsx +28 -0
  390. package/docs/navigation/tabs.tsx +314 -0
  391. package/docs/navigation/toolbar.tsx +339 -0
  392. package/docs/providers/app-provider.tsx +191 -0
  393. package/docs/providers/format-date.tsx +230 -0
  394. package/docs/query/button-refetch.tsx +160 -0
  395. package/docs/query/data-state.tsx +192 -0
  396. package/docs/query/infinite-query-state.tsx +93 -0
  397. package/docs/query/mutation-feedback.tsx +70 -0
  398. package/docs/query/prefetch-link.tsx +262 -0
  399. package/docs/query/touch-actions.tsx +68 -0
  400. package/docs/showcase/acme-portal.tsx +455 -0
  401. package/docs/showcase/acme-website.tsx +461 -0
  402. package/docs/showcase/case1-warehouse-dashboard.tsx +359 -0
  403. package/docs/showcase/case2-employee-me.tsx +444 -0
  404. package/docs/showcase/case3-approval-workflow.tsx +529 -0
  405. package/docs/showcase/case4-login.tsx +313 -0
  406. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  407. package/docs/showcase/case6-agency-handy.tsx +1113 -0
  408. package/docs/showcase/futurelastic-web.tsx +392 -0
  409. package/docs/showcase/org-switcher.tsx +313 -0
  410. package/docs/showcase/permission-matrix.tsx +346 -0
  411. package/docs/showcase/public-landing.tsx +210 -0
  412. package/docs/showcase/settings-account-sections.tsx +559 -0
  413. package/docs/showcase/settings-security-mfa.tsx +145 -0
  414. package/docs/showcase/table-approval-queue.tsx +199 -0
  415. package/docs/showcase/table-bulk-actions.tsx +460 -0
  416. package/docs/showcase/table-compact-kintone.tsx +438 -0
  417. package/docs/showcase/table-conditional-format.tsx +367 -0
  418. package/docs/showcase/table-crud-list.tsx +544 -0
  419. package/docs/showcase/table-density.tsx +347 -0
  420. package/docs/showcase/table-expandable-rows.tsx +480 -0
  421. package/docs/showcase/table-filter-chips.tsx +456 -0
  422. package/docs/showcase/table-footer-totals.tsx +314 -0
  423. package/docs/showcase/table-grouped-subtotals.tsx +391 -0
  424. package/docs/showcase/table-master-detail.tsx +484 -0
  425. package/docs/showcase/table-pagination.tsx +327 -0
  426. package/docs/showcase/table-states.tsx +366 -0
  427. package/docs/showcase/table-sticky-columns.tsx +376 -0
  428. package/docs/showcase/table-tree-rows.tsx +444 -0
  429. package/docs/showcase/table-view-tabs.tsx +488 -0
  430. package/package.json +9 -12
  431. package/scripts/_agent-setup.mjs +16 -2
  432. package/scripts/audit-hook.mjs +3 -13
  433. package/scripts/init-agent-kit.mjs +1 -14
  434. package/scripts/postinstall.mjs +12 -12
  435. package/scripts/ui-audit.mjs +93 -31
  436. package/scripts/visual-audit-rules.mjs +51 -7
  437. package/scripts/visual-audit.mjs +118 -47
@@ -0,0 +1,461 @@
1
+ /**
2
+ * Showcase · ACME marketing website — a TOKEN-ONLY rebuild of the Claude Design `ui_kits/website`.
3
+ *
4
+ * Proves the hard brief: a CONSUMER agent, given a Claude Design export, reproduces a full marketing
5
+ * landing page from **token configuration + a brand stylesheet + REAL @godxjp/ui primitives** — with
6
+ * NO new framework components. Per docs/COMPOSITION-VS-COMPONENT.md, marketing sections (Navbar,
7
+ * Hero, CTA, Footer) FAIL the Framework-Component Test, so they are COMPOSITION: layout `<section>`s
8
+ * arranging Card / Button / Text / Avatar / ResponsiveGrid / Flex.
9
+ *
10
+ * The brand-specific styling lives in the `THEME` <style> block (a consumer's own stylesheet) — the
11
+ * design's tokens + a few marketing type/section classes + per-region role scoping for the navy
12
+ * sections. The TSX stays clean: real primitives + semantic class names, no arbitrary utilities.
13
+ */
14
+ import * as React from "react";
15
+ import {
16
+ ArrowRight,
17
+ ChevronDown,
18
+ CreditCard,
19
+ Globe,
20
+ Link2,
21
+ Mail,
22
+ PackageCheck,
23
+ Phone,
24
+ Plus,
25
+ Receipt,
26
+ Scale,
27
+ Search,
28
+ ShieldCheck,
29
+ ShoppingCart,
30
+ Ship,
31
+ UserPlus,
32
+ Warehouse,
33
+ } from "lucide-react";
34
+
35
+ import { Button, Text } from "@godxjp/ui/general";
36
+ import { Avatar, AvatarFallback, Card, CardContent, CardCover } from "@godxjp/ui/data-display";
37
+ import { Flex, ResponsiveGrid } from "@godxjp/ui/layout";
38
+
39
+ // ── Brand stylesheet: the design's tokens + marketing type/section classes + navy role-scoping. ───
40
+ // This is what a consumer ships as their own theme.css — raw brand values live HERE (CSS), not as
41
+ // arbitrary utilities in the markup. The page below reads it via semantic class names only.
42
+ const THEME = `
43
+ @import url('https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@400;600;700;800;900&family=Inter:wght@400;500;600;700&display=swap');
44
+ [data-tenant="acme-web"] {
45
+ --primary: 41 73% 53%; --primary-foreground: 217 61% 12%; --ring: 41 73% 53%;
46
+ --accent: 42 81% 96%; --accent-foreground: 41 72% 44%;
47
+ --background: 210 33% 97%; --foreground: 217 61% 12%;
48
+ --card: 0 0% 100%; --card-foreground: 217 61% 12%;
49
+ --secondary: 217 61% 12%; --secondary-foreground: 0 0% 100%;
50
+ --muted: 214 27% 95%; --muted-foreground: 216 14% 37%;
51
+ /* --input is the CONTROL boundary, held to 3:1 (SC 1.4.11): 3.33 on the page, 3.57 on a card,
52
+ 3.18 on --muted. It was 216 16% 80% = 1.46:1. --border is decorative chrome; it stays. */
53
+ --border: 214 27% 90%; --input: 216 16% 55%;
54
+ --success: 152 100% 25%; --warning: 41 73% 53%; --destructive: 11 82% 56%; --info: 203 100% 37%;
55
+ --radius: 0.875rem; --radius-md: 10px; --radius-lg: 14px;
56
+ --card-radius: var(--radius); --control-radius: var(--radius);
57
+ --shadow-color: 38 79 145;
58
+ --card-shadow: 0 1px 3px rgb(38 79 145 / 0.08), 0 1px 2px rgb(38 79 145 / 0.06);
59
+ --shadow-glow: 0 8px 20px hsl(41 73% 53% / 0.32);
60
+ --focus-ring-color: 41 73% 53%;
61
+ --font-family-display: "Source Sans 3", system-ui, sans-serif;
62
+ --font-family-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
63
+ --font-family-sans: var(--font-family-body);
64
+ --text-brand: 41 84% 26%; /* dark gold, eyebrows clear AA on light sections */
65
+ }
66
+ /* Marketing layout + type (a consumer's section stylesheet) */
67
+ [data-tenant="acme-web"] .tx-shell { margin-inline: auto; width: 100%; max-width: 1200px; padding-inline: 2rem;
68
+ /* ResponsiveGrid uses @container queries, so establish the container here (PageContainer does this
69
+ * in an app; a marketing composition provides it on its own shell). */
70
+ container-type: inline-size; }
71
+ [data-tenant="acme-web"] .tx-section { padding-block: 5rem; }
72
+ [data-tenant="acme-web"] .tx-navbar { position: sticky; top: 0; z-index: 30; background: hsl(var(--background) / 0.85);
73
+ backdrop-filter: blur(10px); border-bottom: 1px solid hsl(var(--border)); }
74
+ [data-tenant="acme-web"] .tx-navbar-inner { height: 72px; display: flex; align-items: center; gap: 2.25rem; }
75
+ [data-tenant="acme-web"] .tx-brand { font-family: var(--font-family-display); font-weight: 800; font-size: 1.375rem; letter-spacing: -0.01em; color: hsl(var(--foreground)); }
76
+ [data-tenant="acme-web"] .tx-eyebrow { font-family: var(--font-family-display); font-weight: 700; font-size: 0.8125rem;
77
+ letter-spacing: 0.12em; text-transform: uppercase; color: hsl(var(--text-brand)); }
78
+ [data-tenant="acme-web"] .tx-display { font-family: var(--font-family-display); font-weight: 900; font-size: 3.5rem;
79
+ line-height: 1.05; letter-spacing: -0.02em; margin: 1rem 0; color: hsl(var(--foreground)); }
80
+ [data-tenant="acme-web"] .tx-h2 { font-family: var(--font-family-display); font-weight: 800; font-size: 2.25rem;
81
+ line-height: 1.15; letter-spacing: -0.02em; margin: 0.75rem 0 0.625rem; color: hsl(var(--foreground)); }
82
+ [data-tenant="acme-web"] .tx-lead { font-size: 1.1875rem; line-height: 1.6; color: hsl(var(--muted-foreground)); max-width: 480px; }
83
+ [data-tenant="acme-web"] .tx-gold { color: hsl(var(--primary)); }
84
+ [data-tenant="acme-web"] .tx-stat { font-family: var(--font-family-display); font-weight: 800; font-size: 1.75rem; color: hsl(var(--primary)); }
85
+ [data-tenant="acme-web"] .tx-hero-grid { display: grid; gap: 3rem; align-items: center; padding-block: 6rem; }
86
+ @media (min-width: 1024px) { [data-tenant="acme-web"] .tx-hero-grid { grid-template-columns: 1.1fr 0.9fr; } }
87
+ [data-tenant="acme-web"] .tx-glow { position: absolute; inset: 0; pointer-events: none; }
88
+ [data-tenant="acme-web"] .tx-glow-tr { background: radial-gradient(40% 50% at 88% -10%, hsl(41 73% 53% / 0.22), transparent 70%); }
89
+ [data-tenant="acme-web"] .tx-glow-bl { background: radial-gradient(40% 50% at 12% 120%, hsl(41 73% 53% / 0.18), transparent 70%); }
90
+ [data-tenant="acme-web"] .tx-field { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem;
91
+ background: hsl(0 0% 100% / 0.08); border-radius: var(--radius-md); }
92
+ [data-tenant="acme-web"] .tx-quote-total { display: flex; align-items: center; justify-content: space-between;
93
+ padding: 0.875rem 1rem; background: hsl(var(--primary)); border-radius: var(--radius-md); }
94
+ [data-tenant="acme-web"] .tx-route-flag { height: 80px; display: flex; align-items: center; justify-content: center; background: hsl(217 49% 24%); }
95
+ [data-tenant="acme-web"] .tx-route-code { font-family: var(--font-family-display); font-weight: 800; font-size: 1.75rem; letter-spacing: 0.05em; color: hsl(var(--primary)); }
96
+ [data-tenant="acme-web"] .tx-footer-grid { display: grid; gap: 2.25rem; }
97
+ @media (min-width: 768px) { [data-tenant="acme-web"] .tx-footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
98
+ [data-tenant="acme-web"] .tx-footer-bottom { display: flex; align-items: center; justify-content: space-between;
99
+ margin-top: 2.25rem; padding-top: 1.25rem; border-top: 1px solid hsl(0 0% 100% / 0.1); }
100
+ [data-tenant="acme-web"] .tx-medallion svg { width: 1.25rem; height: 1.25rem; }
101
+ [data-tenant="acme-web"] .tx-icon-18 { width: 1.125rem; height: 1.125rem; }
102
+ [data-tenant="acme-web"] .tx-icon-22 { width: 1.375rem; height: 1.375rem; }
103
+ /* Navy region: role scoping so descendants render on-dark (white text, glass cards, outline btns). */
104
+ [data-tenant="acme-web"] .tx-navy {
105
+ background: hsl(217 61% 12%); --foreground: 0 0% 100%;
106
+ --card: 217 45% 18%; --card-foreground: 0 0% 100%;
107
+ --card-background: hsl(0 0% 100% / 0.06); --card-border: 0 0% 100% / 0.12;
108
+ --muted-foreground: 214 36% 80%; --border: 214 30% 30%; --input: 214 24% 60%; --background: 217 61% 12%;
109
+ --text-brand: 41 80% 62%; /* light gold, eyebrows clear AA on the navy regions */
110
+ }
111
+ [data-tenant="acme-web"] .tx-navy-deep { background: hsl(217 61% 9%); }
112
+ `;
113
+
114
+ const SHELL = "tx-shell";
115
+
116
+ function Navbar() {
117
+ const links = ["Mua hộ", "Vận chuyển", "Bảng giá", "Tra cứu", "Về chúng tôi"];
118
+ return (
119
+ <header className="tx-navbar">
120
+ <div className={`${SHELL} tx-navbar-inner`}>
121
+ <span className="tx-brand" data-logotype="">
122
+ TIXI<span className="tx-gold">MAX</span>
123
+ </span>
124
+ <Flex direction="row" gap="xs" align="center">
125
+ {links.map((l, i) => (
126
+ <Button key={l} variant="ghost" size="sm" aria-current={i === 0 ? "page" : undefined}>
127
+ {l}
128
+ </Button>
129
+ ))}
130
+ </Flex>
131
+ <Flex direction="row" gap="sm" align="center" className="ms-auto">
132
+ <Button variant="ghost" size="sm">
133
+ Đăng nhập
134
+ </Button>
135
+ <Button size="sm">
136
+ <Plus aria-hidden="true" />
137
+ Tạo đơn mua hộ
138
+ </Button>
139
+ </Flex>
140
+ </div>
141
+ </header>
142
+ );
143
+ }
144
+
145
+ function Hero() {
146
+ const stats: Array<[string, string]> = [
147
+ ["120K+", "Đơn đã giao"],
148
+ ["6", "Quốc gia"],
149
+ ["12–18", "Ngày vận chuyển"],
150
+ ];
151
+ const fields: Array<[typeof Globe, string, string]> = [
152
+ [Globe, "Quốc gia", "Nhật Bản"],
153
+ [Scale, "Cân nặng (kg)", "3.5 kg"],
154
+ ];
155
+ return (
156
+ <section className="tx-navy relative overflow-hidden">
157
+ <div className="tx-glow tx-glow-tr" />
158
+ <div className={`${SHELL} tx-hero-grid relative`}>
159
+ <Flex direction="col" gap="xl">
160
+ <div className="tx-eyebrow">Mua hộ &amp; vận chuyển quốc tế</div>
161
+ <h1 className="tx-display">
162
+ Mua sắm toàn cầu,
163
+ <br />
164
+ <span className="tx-gold">ACME</span> lo phần còn lại.
165
+ </h1>
166
+ <p className="tx-lead">
167
+ Đặt mua, thanh toán và vận chuyển hàng từ Nhật, Hàn, Indonesia và Mỹ về tận nhà. Minh
168
+ bạch chi phí, theo dõi từng bước.
169
+ </p>
170
+ <Flex direction="row" gap="md">
171
+ <Button size="lg">
172
+ Nhận báo giá miễn phí
173
+ <ArrowRight aria-hidden="true" />
174
+ </Button>
175
+ <Button variant="outline" size="lg">
176
+ <Search aria-hidden="true" />
177
+ Tra cứu đơn
178
+ </Button>
179
+ </Flex>
180
+ <Flex direction="row" gap="lg">
181
+ {stats.map(([n, l]) => (
182
+ <div key={l}>
183
+ <div className="tx-stat">{n}</div>
184
+ <Text as="div" size="xs" tone="muted">
185
+ {l}
186
+ </Text>
187
+ </div>
188
+ ))}
189
+ </Flex>
190
+ </Flex>
191
+
192
+ <Card>
193
+ <CardContent>
194
+ <Flex direction="col" gap="md">
195
+ <div className="tx-eyebrow">Ước tính phí vận chuyển</div>
196
+ <Flex direction="col" gap="sm">
197
+ {fields.map(([Icon, label, value]) => (
198
+ <div key={label} className="tx-field">
199
+ <Icon aria-hidden="true" className="tx-gold tx-icon-18" />
200
+ <div className="min-w-0 flex-1">
201
+ <Text as="div" size="2xs" tone="muted">
202
+ {label}
203
+ </Text>
204
+ <Text as="div" weight="bold">
205
+ {value}
206
+ </Text>
207
+ </div>
208
+ <ChevronDown aria-hidden="true" className="tx-icon-18" />
209
+ </div>
210
+ ))}
211
+ <div className="tx-quote-total">
212
+ <Text as="span" weight="bold" className="text-primary-foreground">
213
+ Tạm tính
214
+ </Text>
215
+ <Text as="span" weight="bold" size="2xl" className="text-primary-foreground">
216
+ 525.000đ
217
+ </Text>
218
+ </div>
219
+ </Flex>
220
+ </Flex>
221
+ </CardContent>
222
+ </Card>
223
+ </div>
224
+ </section>
225
+ );
226
+ }
227
+
228
+ function SectionHead({
229
+ eyebrow,
230
+ title,
231
+ sub,
232
+ center,
233
+ }: {
234
+ eyebrow: string;
235
+ title: string;
236
+ sub?: string;
237
+ center?: boolean;
238
+ }) {
239
+ return (
240
+ <div className={center ? "mx-auto mb-10 text-center" : "mb-8"}>
241
+ <div className="tx-eyebrow">{eyebrow}</div>
242
+ <h2 className="tx-h2">{title}</h2>
243
+ {sub ? <p className="tx-lead mx-auto">{sub}</p> : null}
244
+ </div>
245
+ );
246
+ }
247
+
248
+ function Medallion({ icon: Icon }: { icon: typeof Globe }) {
249
+ return (
250
+ <Avatar className="rounded-md">
251
+ <AvatarFallback className="bg-primary/10 text-primary tx-medallion rounded-md">
252
+ <Icon aria-hidden="true" />
253
+ </AvatarFallback>
254
+ </Avatar>
255
+ );
256
+ }
257
+
258
+ function Services() {
259
+ const items: Array<[typeof Globe, string, string]> = [
260
+ [
261
+ ShoppingCart,
262
+ "Mua hộ",
263
+ "Gửi link sản phẩm, ACME đặt mua và thanh toán giúp bạn với tỷ giá minh bạch.",
264
+ ],
265
+ [Ship, "Vận chuyển", "Đường biển và đường bay từ Nhật, Hàn, Indonesia, Mỹ về Việt Nam."],
266
+ [Warehouse, "Gom hàng", "Gom nhiều đơn vào một kiện để tiết kiệm tối đa chi phí vận chuyển."],
267
+ [
268
+ ShieldCheck,
269
+ "Bảo hiểm hàng hóa",
270
+ "Bảo vệ giá trị đơn hàng trong suốt quá trình vận chuyển quốc tế.",
271
+ ],
272
+ ];
273
+ return (
274
+ <section className="bg-card tx-section">
275
+ <div className={SHELL}>
276
+ <SectionHead
277
+ center
278
+ eyebrow="Dịch vụ"
279
+ title="Một điểm chạm, trọn quy trình"
280
+ sub="Từ lúc bạn thấy món hàng ở nước ngoài đến khi nó nằm trong tay bạn."
281
+ />
282
+ <ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
283
+ {items.map(([icon, t, d]) => (
284
+ <Card key={t}>
285
+ <CardContent>
286
+ <Flex direction="col" gap="md">
287
+ <Medallion icon={icon} />
288
+ <Text as="div" weight="bold" size="lg">
289
+ {t}
290
+ </Text>
291
+ <Text as="p" size="sm" tone="muted">
292
+ {d}
293
+ </Text>
294
+ </Flex>
295
+ </CardContent>
296
+ </Card>
297
+ ))}
298
+ </ResponsiveGrid>
299
+ </div>
300
+ </section>
301
+ );
302
+ }
303
+
304
+ function Steps() {
305
+ const steps: Array<[typeof Globe, string, string]> = [
306
+ [Link2, "Gửi link sản phẩm", "Dán đường link món hàng bạn muốn mua từ bất kỳ trang nào."],
307
+ [Receipt, "Nhận báo giá", "ACME báo giá tiền hàng và phí vận chuyển trong vài phút."],
308
+ [CreditCard, "Thanh toán", "Đặt cọc hoặc thanh toán toàn bộ, chúng tôi đặt mua ngay."],
309
+ [PackageCheck, "Nhận hàng tận nơi", "Theo dõi đơn theo thời gian thực đến khi giao tận nhà."],
310
+ ];
311
+ return (
312
+ <section className="bg-background tx-section">
313
+ <div className={SHELL}>
314
+ <SectionHead eyebrow="Quy trình" title="Mua hàng quốc tế trong 4 bước" />
315
+ <ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
316
+ {steps.map(([Icon, t, d], i) => (
317
+ <Flex direction="col" gap="md" key={t}>
318
+ <Flex direction="row" gap="sm" align="center">
319
+ <Avatar>
320
+ <AvatarFallback className="bg-secondary text-primary font-bold">
321
+ {i + 1}
322
+ </AvatarFallback>
323
+ </Avatar>
324
+ <Icon aria-hidden="true" className="text-brand tx-icon-22" />
325
+ </Flex>
326
+ <Text as="div" weight="bold" size="lg">
327
+ {t}
328
+ </Text>
329
+ <Text as="p" size="sm" tone="muted">
330
+ {d}
331
+ </Text>
332
+ </Flex>
333
+ ))}
334
+ </ResponsiveGrid>
335
+ </div>
336
+ </section>
337
+ );
338
+ }
339
+
340
+ function Routes() {
341
+ const routes: Array<[string, string, string, string]> = [
342
+ ["Nhật Bản", "JP", "Đường bay · 5–7 ngày", "210.000đ/kg"],
343
+ ["Hàn Quốc", "KR", "Đường bay · 4–6 ngày", "180.000đ/kg"],
344
+ ["Indonesia", "ID", "Đường biển · 12–18 ngày", "38.000đ/kg"],
345
+ ["Hoa Kỳ", "US", "Đường bay · 7–10 ngày", "260.000đ/kg"],
346
+ ];
347
+ return (
348
+ <section className="bg-card tx-section">
349
+ <div className={SHELL}>
350
+ <SectionHead eyebrow="Tuyến vận chuyển" title="Giá cước rõ ràng theo từng tuyến" />
351
+ <ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
352
+ {routes.map(([c, code, mode, price]) => (
353
+ <Card key={c} className="overflow-hidden">
354
+ <CardCover className="tx-route-flag">
355
+ <span className="tx-route-code">{code}</span>
356
+ </CardCover>
357
+ <CardContent>
358
+ <Flex direction="col" gap="md">
359
+ <Text as="div" weight="bold" size="lg">
360
+ {c}
361
+ </Text>
362
+ <Text as="div" size="xs" tone="muted">
363
+ {mode}
364
+ </Text>
365
+ <Text as="div" weight="bold" size="2xl">
366
+ {price}
367
+ </Text>
368
+ </Flex>
369
+ </CardContent>
370
+ </Card>
371
+ ))}
372
+ </ResponsiveGrid>
373
+ </div>
374
+ </section>
375
+ );
376
+ }
377
+
378
+ function CtaBanner() {
379
+ return (
380
+ <section className="tx-navy tx-section relative overflow-hidden">
381
+ <div className="tx-glow tx-glow-bl" />
382
+ <div className={`${SHELL} relative text-center`}>
383
+ <h2 className="tx-h2">Sẵn sàng cho đơn hàng đầu tiên?</h2>
384
+ <p className="tx-lead mx-auto">Tạo tài khoản miễn phí và nhận báo giá trong 5 phút.</p>
385
+ <Flex direction="row" gap="md" justify="center">
386
+ <Button size="lg">
387
+ <UserPlus aria-hidden="true" />
388
+ Đăng ký ngay
389
+ </Button>
390
+ <Button variant="outline" size="lg">
391
+ Liên hệ tư vấn
392
+ </Button>
393
+ </Flex>
394
+ </div>
395
+ </section>
396
+ );
397
+ }
398
+
399
+ function Footer() {
400
+ const cols: Array<[string, string[]]> = [
401
+ ["Dịch vụ", ["Mua hộ", "Vận chuyển", "Gom hàng", "Bảng giá"]],
402
+ ["Công ty", ["Về ACME", "Tuyển dụng", "Tin tức", "Liên hệ"]],
403
+ ["Hỗ trợ", ["Tra cứu đơn", "Câu hỏi thường gặp", "Chính sách", "Điều khoản"]],
404
+ ];
405
+ return (
406
+ <footer className="tx-navy tx-navy-deep">
407
+ <div className={`${SHELL} tx-footer-grid`} style={{ paddingBlock: "3.5rem 2rem" }}>
408
+ <Flex direction="col" gap="md">
409
+ <span className="tx-brand">
410
+ TIXI<span className="tx-gold">MAX</span>
411
+ </span>
412
+ <Text as="p" size="sm" tone="muted">
413
+ Dịch vụ mua hộ &amp; vận chuyển quốc tế uy tín, minh bạch về tận nhà bạn.
414
+ </Text>
415
+ </Flex>
416
+ {cols.map(([h, items]) => (
417
+ <Flex direction="col" gap="md" key={h}>
418
+ <div className="tx-eyebrow">{h}</div>
419
+ <Flex direction="col" gap="xs">
420
+ {items.map((i) => (
421
+ <Button
422
+ key={i}
423
+ variant="link"
424
+ size="sm"
425
+ className="text-muted-foreground justify-start"
426
+ >
427
+ {i}
428
+ </Button>
429
+ ))}
430
+ </Flex>
431
+ </Flex>
432
+ ))}
433
+ </div>
434
+ <div className={`${SHELL} tx-footer-bottom`}>
435
+ <Text as="span" size="xs" tone="muted">
436
+ 2026 ACME Logistics. All rights reserved.
437
+ </Text>
438
+ <Flex direction="row" gap="md">
439
+ {[Mail, Phone, Globe].map((Icon, i) => (
440
+ <Icon key={i} aria-hidden="true" className="text-muted-foreground tx-icon-18" />
441
+ ))}
442
+ </Flex>
443
+ </div>
444
+ </footer>
445
+ );
446
+ }
447
+
448
+ export default function AcmeWebsiteShowcase() {
449
+ return (
450
+ <div data-tenant="acme-web" className="bg-background min-h-screen">
451
+ <style>{THEME}</style>
452
+ <Navbar />
453
+ <Hero />
454
+ <Services />
455
+ <Steps />
456
+ <Routes />
457
+ <CtaBanner />
458
+ <Footer />
459
+ </div>
460
+ );
461
+ }