@godxjp/ui 28.9.0 → 28.12.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 (244) hide show
  1. package/agent/START-HERE.md +193 -0
  2. package/agent/anti-ai-tells.json +158 -0
  3. package/agent/components/Accordion.json +60 -0
  4. package/agent/components/AccountChip.json +59 -0
  5. package/agent/components/Actions.json +78 -0
  6. package/agent/components/Activity.json +80 -0
  7. package/agent/components/Affix.json +78 -0
  8. package/agent/components/Alert.json +65 -0
  9. package/agent/components/AlertDialog.json +109 -0
  10. package/agent/components/AlertDialogRoot.json +52 -0
  11. package/agent/components/Anchor.json +119 -0
  12. package/agent/components/AppLauncher.json +95 -0
  13. package/agent/components/AppProvider.json +105 -0
  14. package/agent/components/AppSettingPicker.json +88 -0
  15. package/agent/components/AppSettingToggle.json +70 -0
  16. package/agent/components/AppShell.json +159 -0
  17. package/agent/components/AreaChart.json +105 -0
  18. package/agent/components/AspectRatio.json +38 -0
  19. package/agent/components/Attachments.json +77 -0
  20. package/agent/components/AuthAccountSummary.json +64 -0
  21. package/agent/components/AuthDivider.json +35 -0
  22. package/agent/components/AuthFooter.json +48 -0
  23. package/agent/components/AuthIdentity.json +42 -0
  24. package/agent/components/AuthShell.json +108 -0
  25. package/agent/components/AuthStack.json +21 -0
  26. package/agent/components/Avatar.json +89 -0
  27. package/agent/components/Badge.json +96 -0
  28. package/agent/components/Banner.json +48 -0
  29. package/agent/components/BarChart.json +108 -0
  30. package/agent/components/BranchScopePicker.json +89 -0
  31. package/agent/components/Breadcrumb.json +54 -0
  32. package/agent/components/Button.json +133 -0
  33. package/agent/components/Calendar.json +259 -0
  34. package/agent/components/Callout.json +46 -0
  35. package/agent/components/Card.json +112 -0
  36. package/agent/components/CardBar.json +49 -0
  37. package/agent/components/CardContent.json +51 -0
  38. package/agent/components/Carousel.json +50 -0
  39. package/agent/components/Cascader.json +209 -0
  40. package/agent/components/CenteredShell.json +66 -0
  41. package/agent/components/ChatBubble.json +100 -0
  42. package/agent/components/ChatBubbleList.json +64 -0
  43. package/agent/components/ChatComposer.json +160 -0
  44. package/agent/components/ChatSuggestion.json +86 -0
  45. package/agent/components/Checkbox.json +68 -0
  46. package/agent/components/CheckboxGroup.json +96 -0
  47. package/agent/components/CodeBlock.json +64 -0
  48. package/agent/components/Collapsible.json +74 -0
  49. package/agent/components/ColorPicker.json +87 -0
  50. package/agent/components/Command.json +168 -0
  51. package/agent/components/CommandPalette.json +84 -0
  52. package/agent/components/CompactBarTrend.json +101 -0
  53. package/agent/components/Conversations.json +82 -0
  54. package/agent/components/CredentialReveal.json +93 -0
  55. package/agent/components/DataState.json +79 -0
  56. package/agent/components/DataTable.json +268 -0
  57. package/agent/components/DatePicker.json +275 -0
  58. package/agent/components/Descriptions.json +67 -0
  59. package/agent/components/Dialog.json +78 -0
  60. package/agent/components/DraggablePanel.json +106 -0
  61. package/agent/components/DropdownMenu.json +102 -0
  62. package/agent/components/EmptyState.json +83 -0
  63. package/agent/components/ErrorSurface.json +128 -0
  64. package/agent/components/FeatureList.json +43 -0
  65. package/agent/components/Field.json +64 -0
  66. package/agent/components/FilterBar.json +99 -0
  67. package/agent/components/Flex.json +153 -0
  68. package/agent/components/FloatButton.json +91 -0
  69. package/agent/components/Form.json +87 -0
  70. package/agent/components/FormErrors.json +51 -0
  71. package/agent/components/FormField.json +137 -0
  72. package/agent/components/FormFieldArray.json +39 -0
  73. package/agent/components/FormFieldControl.json +129 -0
  74. package/agent/components/FormRoot.json +122 -0
  75. package/agent/components/Heading.json +61 -0
  76. package/agent/components/HoverCard.json +55 -0
  77. package/agent/components/Icon.json +60 -0
  78. package/agent/components/InfiniteQueryState.json +58 -0
  79. package/agent/components/Input.json +122 -0
  80. package/agent/components/InputOTP.json +106 -0
  81. package/agent/components/Label.json +43 -0
  82. package/agent/components/LegalDocumentShell.json +102 -0
  83. package/agent/components/Legend.json +42 -0
  84. package/agent/components/LineChart.json +103 -0
  85. package/agent/components/Link.json +41 -0
  86. package/agent/components/ListRow.json +92 -0
  87. package/agent/components/Logo.json +85 -0
  88. package/agent/components/Marquee.json +91 -0
  89. package/agent/components/Masonry.json +82 -0
  90. package/agent/components/MasterDetail.json +95 -0
  91. package/agent/components/MegaMenu.json +120 -0
  92. package/agent/components/MobileShell.json +73 -0
  93. package/agent/components/NavList.json +63 -0
  94. package/agent/components/NumberInput.json +158 -0
  95. package/agent/components/OrgSwitcher.json +89 -0
  96. package/agent/components/OverlayPortalProvider.json +42 -0
  97. package/agent/components/PageContainer.json +181 -0
  98. package/agent/components/Pagination.json +132 -0
  99. package/agent/components/Paragraph.json +40 -0
  100. package/agent/components/PasswordInput.json +79 -0
  101. package/agent/components/PasswordStrength.json +51 -0
  102. package/agent/components/PermissionMatrix.json +81 -0
  103. package/agent/components/PieChart.json +99 -0
  104. package/agent/components/Popover.json +110 -0
  105. package/agent/components/PrefetchLink.json +65 -0
  106. package/agent/components/Progress.json +79 -0
  107. package/agent/components/Prose.json +57 -0
  108. package/agent/components/QrCode.json +62 -0
  109. package/agent/components/Radio.json +98 -0
  110. package/agent/components/RadioGroup.json +91 -0
  111. package/agent/components/RangeTimeline.json +80 -0
  112. package/agent/components/Rating.json +92 -0
  113. package/agent/components/ResizablePanel.json +69 -0
  114. package/agent/components/ResponsiveGrid.json +77 -0
  115. package/agent/components/Reveal.json +70 -0
  116. package/agent/components/ScrollArea.json +104 -0
  117. package/agent/components/SearchInput.json +98 -0
  118. package/agent/components/Segmented.json +96 -0
  119. package/agent/components/Select.json +397 -0
  120. package/agent/components/Separator.json +86 -0
  121. package/agent/components/ServiceCatalogCta.json +46 -0
  122. package/agent/components/ServiceLauncherCard.json +93 -0
  123. package/agent/components/ServiceRolePanel.json +83 -0
  124. package/agent/components/Sheet.json +85 -0
  125. package/agent/components/Sidebar.json +118 -0
  126. package/agent/components/Skeleton.json +57 -0
  127. package/agent/components/SkeletonArticle.json +71 -0
  128. package/agent/components/SkeletonAvatar.json +50 -0
  129. package/agent/components/SkeletonButton.json +57 -0
  130. package/agent/components/SkeletonForm.json +52 -0
  131. package/agent/components/SkeletonImage.json +37 -0
  132. package/agent/components/SkeletonInput.json +51 -0
  133. package/agent/components/SkeletonNode.json +42 -0
  134. package/agent/components/SkeletonRows.json +49 -0
  135. package/agent/components/SkeletonTable.json +45 -0
  136. package/agent/components/Slider.json +160 -0
  137. package/agent/components/SplitPane.json +66 -0
  138. package/agent/components/StatCard.json +83 -0
  139. package/agent/components/Steps.json +95 -0
  140. package/agent/components/Swatch.json +41 -0
  141. package/agent/components/Switch.json +81 -0
  142. package/agent/components/Table.json +112 -0
  143. package/agent/components/Tabs.json +158 -0
  144. package/agent/components/TagInput.json +105 -0
  145. package/agent/components/Text.json +201 -0
  146. package/agent/components/Textarea.json +126 -0
  147. package/agent/components/ThoughtChain.json +76 -0
  148. package/agent/components/Thumbnail.json +70 -0
  149. package/agent/components/TimePicker.json +200 -0
  150. package/agent/components/TimeRangePicker.json +90 -0
  151. package/agent/components/Timeline.json +47 -0
  152. package/agent/components/TimelineGrid.json +92 -0
  153. package/agent/components/Title.json +67 -0
  154. package/agent/components/Toaster.json +42 -0
  155. package/agent/components/Toggle.json +90 -0
  156. package/agent/components/ToggleGroup.json +102 -0
  157. package/agent/components/Toolbar.json +120 -0
  158. package/agent/components/Tooltip.json +110 -0
  159. package/agent/components/Topbar.json +83 -0
  160. package/agent/components/TopbarItem.json +79 -0
  161. package/agent/components/Transfer.json +141 -0
  162. package/agent/components/Tree.json +185 -0
  163. package/agent/components/TreeSelect.json +232 -0
  164. package/agent/components/TwoFactorSetup.json +79 -0
  165. package/agent/components/Typography.json +42 -0
  166. package/agent/components/Upload.json +221 -0
  167. package/agent/components/UploadCropDialog.json +60 -0
  168. package/agent/components/VisuallyHidden.json +20 -0
  169. package/agent/components/Welcome.json +65 -0
  170. package/agent/components/formatDate.json +46 -0
  171. package/agent/components/inertiaUpload.json +32 -0
  172. package/agent/components/useZodForm.json +39 -0
  173. package/agent/components-index.json +884 -0
  174. package/agent/components.json +15515 -0
  175. package/agent/index.json +56 -0
  176. package/agent/llms.txt +32 -0
  177. package/agent/patterns/account-recovery-settings.json +19 -0
  178. package/agent/patterns/async-data-state.json +20 -0
  179. package/agent/patterns/auth-recovery-panels.json +29 -0
  180. package/agent/patterns/badge-coloring.json +14 -0
  181. package/agent/patterns/common-fixes.json +16 -0
  182. package/agent/patterns/confirm-destructive.json +11 -0
  183. package/agent/patterns/data-table-page.json +18 -0
  184. package/agent/patterns/deferred-loading.json +12 -0
  185. package/agent/patterns/error-pages.json +28 -0
  186. package/agent/patterns/inertia-detail-page.json +13 -0
  187. package/agent/patterns/inertia-list-page.json +15 -0
  188. package/agent/patterns/inertia-persistent-layout.json +14 -0
  189. package/agent/patterns/organization-memberships.json +19 -0
  190. package/agent/patterns/page-sections.json +18 -0
  191. package/agent/patterns/settings-page-responsive.json +18 -0
  192. package/agent/patterns/settings-section-rows.json +23 -0
  193. package/agent/patterns/signup-form.json +13 -0
  194. package/agent/patterns/topbar-account-chip.json +18 -0
  195. package/agent/patterns/transactional-email.json +22 -0
  196. package/agent/patterns-index.json +323 -0
  197. package/agent/patterns.json +342 -0
  198. package/agent/rules.json +237 -0
  199. package/agent/tokens.json +8427 -0
  200. package/agent/vocabulary.json +198 -0
  201. package/dist/components/data-display/service-launcher-card.d.ts +19 -0
  202. package/dist/components/data-display/service-launcher-card.js +14 -1
  203. package/dist/components/data-entry/attachments.js +77 -33
  204. package/dist/components/data-entry/input.js +8 -1
  205. package/dist/components/layout/flex.d.ts +2 -2
  206. package/dist/components/layout/flex.js +2 -0
  207. package/dist/components/ui/avatar.d.ts +1 -18
  208. package/dist/components/ui/avatar.js +1 -36
  209. package/dist/components/ui/tag-input.d.ts +10 -0
  210. package/dist/components/ui/tag-input.js +35 -2
  211. package/dist/contracts/measurement.json +1 -1
  212. package/dist/i18n/messages/en.json +190 -1
  213. package/dist/i18n/messages/ja.json +188 -1
  214. package/dist/i18n/messages/vi.json +188 -1
  215. package/dist/lib/image-loading-status.d.ts +25 -0
  216. package/dist/lib/image-loading-status.js +41 -0
  217. package/dist/props/components/data-entry.prop.d.ts +21 -2
  218. package/dist/props/components/layout.prop.d.ts +42 -0
  219. package/dist/props/registry.d.ts +14 -1
  220. package/dist/props/registry.js +18 -1
  221. package/dist/styles/card-layout.css +10 -4
  222. package/dist/styles/control.css +33 -4
  223. package/dist/styles/data-display-layout.css +1 -1
  224. package/dist/styles/data-entry-layout.css +245 -2
  225. package/dist/styles/layout.css +17 -0
  226. package/dist/styles/navigation-layout.css +3 -1
  227. package/dist/styles/shell-layout.css +2 -0
  228. package/dist/styles/table-layout.css +50 -9
  229. package/dist/tokens/components/attachments.css +18 -9
  230. package/dist/tokens/components/segmented.css +7 -3
  231. package/dist/tokens/components/table.css +2 -1
  232. package/docs/COMPOSITION-VS-COMPONENT.md +41 -0
  233. package/docs/DESIGN-AUTHORITY.md +52 -0
  234. package/docs/DEVELOPMENT.md +81 -6
  235. package/docs/assets/service-mark-rose.svg +6 -0
  236. package/docs/assets/service-mark-teal.svg +5 -0
  237. package/docs/data-display/service-launcher-card.tsx +232 -92
  238. package/docs/data-entry/tag-input.tsx +37 -0
  239. package/docs/layout/flex.tsx +40 -0
  240. package/docs/roadmap/website-components.md +34 -0
  241. package/docs/showcase/marketing-page.tsx +54 -45
  242. package/docs/showcase/table-pagination.tsx +99 -18
  243. package/docs/showcase/theme-customization.tsx +25 -2
  244. package/package.json +8 -5
@@ -0,0 +1,237 @@
1
+ [
2
+ {
3
+ "body": "Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark.",
4
+ "number": 1,
5
+ "title": "Storybook is mandatory"
6
+ },
7
+ {
8
+ "body": "Visual values come from CSS custom properties in `src/tokens/` + `src/styles/theme.css`. Token-named Tailwind utilities (`bg-background`) are fine; raw value utilities (`bg-blue-500`) are forbidden.",
9
+ "number": 2,
10
+ "title": "Tokens, not utilities"
11
+ },
12
+ {
13
+ "body": "Anything with keyboard / ARIA / portal wraps the relevant Radix primitive.",
14
+ "number": 3,
15
+ "title": "Radix for interactive primitives"
16
+ },
17
+ {
18
+ "body": "Primitives are thin wrappers; consumers can fork the source in place.",
19
+ "number": 4,
20
+ "title": "shadcn-style ownership"
21
+ },
22
+ {
23
+ "body": "`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`.",
24
+ "number": 5,
25
+ "title": "One i18next singleton"
26
+ },
27
+ {
28
+ "body": "Every interactive primitive passes axe-core (keyboard nav, ARIA, focus-visible, 4.5:1 contrast, `prefers-reduced-motion`). Stories double as a11y test surfaces.",
29
+ "number": 6,
30
+ "title": "WCAG 2.1 AA baseline"
31
+ },
32
+ {
33
+ "body": "Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR.",
34
+ "number": 7,
35
+ "title": "SemVer 2.0 + Keep a Changelog 1.1"
36
+ },
37
+ {
38
+ "body": "`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced.",
39
+ "number": 8,
40
+ "title": "Inclusive naming"
41
+ },
42
+ {
43
+ "body": "Banned: \"powerful\", \"robust\", \"blazing fast\", \"best-in-class\", \"seamless\", \"enterprise-grade\". State what it does.",
44
+ "number": 9,
45
+ "title": "No marketing speak"
46
+ },
47
+ {
48
+ "body": "Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness.",
49
+ "number": 10,
50
+ "title": "English is canonical for docs"
51
+ },
52
+ {
53
+ "body": "Never push a pin to a SHA not on the submodule remote.",
54
+ "number": 11,
55
+ "title": "Submodule discipline"
56
+ },
57
+ {
58
+ "body": "`feat/<scope>` / `fix/<scope>` → submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden.",
59
+ "number": 12,
60
+ "title": "Branch + PR workflow"
61
+ },
62
+ {
63
+ "body": "Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link.",
64
+ "number": 13,
65
+ "title": "TypeScript strict"
66
+ },
67
+ {
68
+ "body": "Locked stack: Radix UI, cmdk, sonner, lucide-react, react-aria-components + `@internationalized/date`, i18next + react-i18next, class-variance-authority + clsx + tailwind-merge. New peer → ADR documenting why it's the canonical choice.",
69
+ "number": 14,
70
+ "title": "Every third-party library is shadcn / Radix-recommended"
71
+ },
72
+ {
73
+ "body": "Inside a primitive `.tsx`, don't `@apply` a Tailwind utility that re-encodes a token — reference the canonical CSS class from `tokens.css` instead. Composite token-named utilities remain fine.",
74
+ "number": 15,
75
+ "title": "No `@apply` re-encoding tokens"
76
+ },
77
+ {
78
+ "body": "A primitive that needs a new color / spacing / radius adds it there FIRST, then references it.",
79
+ "number": 16,
80
+ "title": "CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`"
81
+ },
82
+ {
83
+ "body": "Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`.",
84
+ "number": 17,
85
+ "title": "`src/stories/` ↔ `src/components/` parity"
86
+ },
87
+ {
88
+ "body": "Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`.",
89
+ "number": 18,
90
+ "title": "`docs/reference/<group>/` ↔ `src/components/<group>/` parity"
91
+ },
92
+ {
93
+ "body": "`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent=\"<palette>\"]`.",
94
+ "number": 19,
95
+ "title": "No service-specific anything"
96
+ },
97
+ {
98
+ "body": "Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported.",
99
+ "number": 20,
100
+ "title": "No \"platform-only\" exports"
101
+ },
102
+ {
103
+ "body": "`data-theme` (light / dark), `data-accent` (6 palettes), `data-density` (compact / default / comfortable), `data-font-size` (sm / base / lg / xl). Read from tokens, never hardcode values.",
104
+ "number": 21,
105
+ "title": "Every component honours every theme axis"
106
+ },
107
+ {
108
+ "body": "Every visual literal comes from `design-handoff/ui-system/<latest-bundle>/`. Token-pin canon literals; never substitute \"close enough\". If the bundle doesn't cover a case — STOP, ask the user to mock it.",
109
+ "number": 22,
110
+ "title": "100% match to the design canon"
111
+ },
112
+ {
113
+ "body": "One concept per prop. Reuse shared vocabulary (`size`, `variant`, `color`, `tone`, `accent`, `padding`, `density`, `orientation`, `placement`, `current`, `value` / `defaultValue` / `onValueChange`, `open` / `defaultOpen` / `onOpenChange`, `justify`, `sticky`, `offset`). Before adding a new prop or token: grep for an existing one.",
114
+ "number": 23,
115
+ "title": "Concept-first prop API"
116
+ },
117
+ {
118
+ "body": "Defaults target `xs` (≥0px); progressive enhancement via `sm:` / `md:` / `lg:` / `xl:` / `2xl:`. Touch targets ≥ 44 × 44 px (`--touch-target-min`, does NOT scale with density). Runtime viewport via `useBreakpoint`, never `window.innerWidth`. Stories render at narrow viewport first.",
119
+ "number": 24,
120
+ "title": "Mobile-first"
121
+ },
122
+ {
123
+ "body": "When a story looks wrong, fix the primitive / CSS / token. Never paper over with a story tweak. Story-only diff without a paired primitive / CSS / token diff is rejected.",
124
+ "number": 25,
125
+ "title": "Stories are docs; UI is the primitive"
126
+ },
127
+ {
128
+ "body": "`dist/` ships only the consumer surface. Storybook, tests, scripts, design-handoff, `dev-probe/` stay out of npm. Every `dependencies` entry is `external` in `tsup`. Verification via `pnpm pack` + grep of `dist/`.",
129
+ "number": 26,
130
+ "title": "Library isolation"
131
+ },
132
+ {
133
+ "body": "Primitives at `src/components/<group>/<Name>.tsx`; six canonical groups (general, layout, data-display, data-entry, feedback, navigation). Barrel = `src/components/primitives.ts` (single file). Stories + reference docs mirror the same group hierarchy.",
134
+ "number": 27,
135
+ "title": "Per-group folder structure"
136
+ },
137
+ {
138
+ "body": "Three classes: consumer surface (matched by `tsup` entry + `package.json::exports`), Storybook-only (`src/stories/`), build-input-only (`cn.ts`, per-group sources consumed via the barrel). No `src/lib/`, `src/utils/`, `src/internal/`, `src/clients/`, `src/screens/`. Service clients live with the composite that uses them.",
139
+ "number": 28,
140
+ "title": "`src/` folder taxonomy"
141
+ },
142
+ {
143
+ "body": "No raw `<button>` / `<input>` / hand-rolled chips when a primitive exists. HTML semantics (`<section>`, `<article>`, …) for structure are fine. Inline `style={{}}` limited to layout / positioning; no colour / radius / typography overrides.",
144
+ "number": 29,
145
+ "title": "Stories consume framework primitives only"
146
+ },
147
+ {
148
+ "body": "No opaque `<XyzDemo />` wrapper components, no zero-arg `Demo` helpers. Use `render: function StoryName() { … }` so Storybook's source panel shows runnable JSX, not `<XyzDemo />`.",
149
+ "number": 30,
150
+ "title": "Story `render` returns JSX directly"
151
+ },
152
+ {
153
+ "body": "One Radix base = one framework primitive. `<SimpleX>` over `<X>` is forbidden; add a prop to `<X>` instead. Composites under `src/components/composites/` that combine multiple primitives are NOT wrappers.",
154
+ "number": 31,
155
+ "title": "No nested wrapper / convenience primitives"
156
+ },
157
+ {
158
+ "body": "Before adding a prop / item field / variant, grep the existing surface; if a field already covers the concept, use it. Top-level prop that re-expresses an item field (Timeline `pending` ↔ `items[i].animate`) is rejected.",
159
+ "number": 32,
160
+ "title": "No redundant props"
161
+ },
162
+ {
163
+ "body": "No two names for the same export across the framework surface; no legacy aliases in stories / docs (source may keep an alias for a deprecation cycle, but the marketing surfaces use the canonical name only).",
164
+ "number": 33,
165
+ "title": "Stories / source / docs name-synchronized"
166
+ },
167
+ {
168
+ "body": "Storybook's react-docgen serializer strips every function value (`cell: ({row}) => <JSX/>`, `render: ({field}) => <Input/>`, `rowClassName`, `renderItem`, …) to `() => {}`. Any story whose `render` passes a function-valued prop, references a module-level helper (`Badge`, `EMPLOYEE_COLUMNS`, etc.), or uses a render-prop pattern MUST override `parameters.docs.source.code` with the literal copy-paste-ready snippet — type aliases, helper functions spelled out, column definitions with cell JSX visible, inline data array. The `render()` callback stays as-is (module-level constants are fine for runtime performance); `source.code` is the marketing surface. Skip ONLY for stories whose JSX is purely static primitives Storybook can serialize verbatim (`<Button variant=\"primary\">Click</Button>`).",
169
+ "number": 34,
170
+ "title": "Storybook source panel = real, copy-paste-ready code"
171
+ },
172
+ {
173
+ "body": "A `Badge` / `Badge` reads as one atomic unit. Its label must never break across lines — pin `white-space: nowrap` on the chip (done in `badge-layout.css`), especially inside narrow `DataTable` cells (スコープ / ステータス columns). If a cell is too tight, widen the column or shorten the label; never let the chip wrap.",
174
+ "number": 35,
175
+ "title": "Status chips never wrap"
176
+ },
177
+ {
178
+ "body": "For ANY other value — localized labels (公開中, アクティブ) or categorical tiers (会員ランク, 契約プラン) — pass `tone` explicitly (success | warning | destructive | info | neutral) and, for non-lifecycle tiers, `icon={null}` to drop the misleading glyph. Don't let domain labels fall back to neutral grey + ○. Map domain→tone in the CONSUMER layer; the framework only provides the props.",
179
+ "number": 36,
180
+ "title": "Badge tone/icon are the colour escape hatch"
181
+ },
182
+ {
183
+ "body": "A multi-column `DataTable` occupies its OWN row at the page's full width: `<Card><CardContent flush><DataTable …/></CardContent></Card>`. Never nest it in a `lg:col-span-2` of a `ResponsiveGrid columns={3}` beside a chart — the columns get squeezed until CJK text collapses to one character per line. Charts / KPI cards go in their own row ABOVE the table. (See the `inertia-list-page` pattern.)",
184
+ "number": 37,
185
+ "title": "DataTable is full-width — never inside a narrow grid column"
186
+ },
187
+ {
188
+ "body": "`CardContent flush` strips horizontal padding for edge-to-edge tables. A `FilterBar` placed inside it loses all padding and sticks to the card edge. Render `FilterBar` as a STANDALONE block above the table card; wrap ONLY the `DataTable` / `EmptyState` in the `Card` + `CardContent flush`. Order on a list page: KPIs → FilterBar → table card.",
189
+ "number": 38,
190
+ "title": "FilterBar stays OUT of CardContent flush"
191
+ },
192
+ {
193
+ "body": "For columns whose value can be long (name / title / segment / address), set `col.width` to a Tailwind width class (e.g. `w-64`, `w-48`) so the column reserves space instead of shrinking and wrapping to many lines; leave numeric / status columns auto. Table cells default to `white-space: nowrap`, so an over-tight table scrolls horizontally rather than crushing — give the important columns real widths so the default layout reads well before any scroll.",
194
+ "number": 39,
195
+ "title": "Long text columns get an explicit width"
196
+ },
197
+ {
198
+ "body": "Author and verify every page at 320–390px FIRST. Page sections are spaced by `PageContainer` itself (`--page-body-gap` between its direct children). Inside a section spacing comes only from `Flex` `gap` (vertical rhythm = `Flex direction=\"col\"`, control rows = the default `direction=\"row\"`) + `ResponsiveGrid columns={2|3|4}` (which collapse to a single column on narrow screens) — never raw `p-*` / `gap-*` / `space-*` utilities for page layout (the static audit rejects them). Styles are loaded whole: `@godxjp/ui/styles` or `styles/core`, never a hand-picked set of layers.",
199
+ "number": 40,
200
+ "title": "Pages are mobile-first"
201
+ },
202
+ {
203
+ "body": "Sheet/Dialog/AlertDialog footers are a pinned action bar (the Drawer footer convention): the footer sticks to the bottom, SheetFooter draws a full-bleed top border, and actions are RIGHT-aligned with the PRIMARY button rightmost (Cancel/secondary to its left). A destructive / clear / reset action goes far-LEFT — give that button `className=\"me-auto\"` — the logical edge, so the action stays on the reading-start side under RTL too. NEVER stack footer buttons full-width or center them.",
204
+ "number": 41,
205
+ "title": "Drawer & dialog footer layout"
206
+ },
207
+ {
208
+ "body": "Before reaching for a Tailwind class, inline `style`, or extra CSS, you MUST first check whether the component already supports the need via a PROP, a design TOKEN, or a layout/typography PRIMITIVE. godx-ui is meant to be enough on its own: `className` is for genuine one-offs only — never to redo what an API already does. Specifically: (1) NEVER hand-roll typography — no `text-[13px]`/`text-[11px]` arbitrary px (bypasses the golden type scale), no `font-medium`/`font-semibold`/`text-muted-foreground` on a raw `<span>`; use `<Text size tone weight tabular mono>` / `<Heading level>`. (2) NEVER hand-roll a trivial flex/grid wrapper; use `<Flex>` / `<ResponsiveGrid>` / `<PageContainer>`. (3) NEVER set a control's radius/height/colour with a utility when a `shape`/`size`/`tone`/token exists.",
209
+ "number": 42,
210
+ "title": "Props & Tokens Before Customization"
211
+ },
212
+ {
213
+ "body": "Consumers MUST wrap every labelled form control (Input, Select, DatePicker, NumberInput, Radio.Group, Checkbox groups, range pairs, ...) in FormField — it owns the label (aria-labelledby, never a dangling <label for>), auto-generates/injects the control id, and wires aria-describedby/aria-errormessage/aria-invalid. Bare controls are the rare exception (e.g. a toolbar quick-filter with its own aria-label) and must carry id/name + aria-label themselves. Never hand-roll a label+control stack with Text/Label.",
214
+ "number": 43,
215
+ "title": "Every form control goes through FormField"
216
+ },
217
+ {
218
+ "body": "Any decorative chrome a component draws — dividers, separator borders, and the padding that exists only to space that chrome — MUST read a token; never hard-code it in `src/styles/*.css` (a hard-coded `border-bottom: 1px solid hsl(var(--border))` leaves consumers no off-switch short of a variant fork). The DEFAULT is the quietest state (`none` / balanced rhythm); a service theme opts IN, e.g. `--page-header-divider: 1px solid hsl(var(--border))`.",
219
+ "number": 44,
220
+ "title": "Chrome is a token, default quiet"
221
+ },
222
+ {
223
+ "body": "When component CSS encodes a geometry choice that a service plausibly re-tunes to match its design handoff — form label column width, label↔control gap, header insets — it MUST be a documented component token (current value as the default). The theme sets it ONCE globally; props (`labelWidth`) override per instance; Form→FormField priority stays intact. The test: \"would a service theme.css want to change this to match its design grid?\" If yes and the only route is forking CSS, that is a library gap — fix the library, don't patch the app.",
224
+ "number": 45,
225
+ "title": "Every service-tunable constant gets a knob"
226
+ },
227
+ {
228
+ "body": "The DEFAULT body size is `--font-size-base`; components render body/UI text at `base`, not at the `sm` alias. Smaller-by-design text (badge, section label, caption) is a component token defaulting to a small step (`--badge-font-size: var(--font-size-xs)`), so a service re-tunes that part without moving the global scale. The `sm`/`xs` tokens stay for the explicit `<Text size>` API. Every component token is surfaced in the MCP `get_component` output (check:mcp-token-sync).",
229
+ "number": 46,
230
+ "title": "Typography is tokens, default is base"
231
+ },
232
+ {
233
+ "body": "Every rule this package ships is inside a cascade layer, and layer order beats specificity outright. Two consequences. (1) INSIDE the package: `@layer components` is EARLIER than Tailwind's `utilities`, so a utility a component emits on its own element (`<table class=\"text-sm\">`) silently outranks the component rule meant to own that property — no selector can win. A responsive re-point that must beat such a utility goes in `@layer godxjp-ui-responsive`, declared after Tailwind in `styles/base.css` and therefore LAST; it is reserved for `@container`/`@media` re-points, never static rules.",
234
+ "number": 47,
235
+ "title": "The layer contract — cascade layers, not specificity"
236
+ }
237
+ ]