@godxjp/ui-mcp 0.5.0 → 0.7.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.
- package/dist/index.js +5620 -312
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/data/components.ts","../src/data/prop-vocabulary.ts","../src/data/tokens.ts","../src/data/rules.ts","../src/data/patterns.ts","../src/data/skills-index.ts","../src/data/anti-ai-tells.ts","../src/data/redesign-audit.ts","../src/tools/registry.ts","../src/resources/registry.ts"],"sourcesContent":["/**\n * @godxjp/ui-mcp — MCP server entry.\n *\n * Spawned over stdio by an MCP-aware agent (Claude Desktop, Cursor,\n * Continue, Cline, etc.) per the consumer's `.mcp.json` /\n * `claude_desktop_config.json`. Exposes a curated catalogue of the\n * @godxjp/ui framework so the agent can:\n *\n * - list primitives (with group / tagline / props / example)\n * - look up a single component's full API\n * - search by name / use-case / feature\n * - read the shared prop-vocabulary (`SizeProp`, `ColorProp`, …)\n * - read design tokens (per category)\n * - read cardinal rules (by number or all)\n * - fetch canonical code patterns (registration form, settings,\n * data table, app shell, …) — copy-paste-ready snippets\n * - lint a JSX snippet against the most common rule violations\n *\n * The server reads ONLY its own bundled data files. Zero filesystem\n * access into consumer projects, no network, no shell. Safe to mount\n * read-only.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { TOOL_DEFINITIONS, dispatchTool } from \"./tools/registry.js\";\nimport { RESOURCE_DEFINITIONS, readResource } from \"./resources/registry.js\";\n\nasync function main() {\n const server = new Server(\n {\n name: \"godx-ui-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n },\n );\n\n // ── tools ──────────────────────────────────────────────────────\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOL_DEFINITIONS,\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const result = await dispatchTool(name, (args ?? {}) as Record<string, unknown>);\n return { content: [{ type: \"text\", text: result }] };\n });\n\n // ── resources ──────────────────────────────────────────────────\n server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: RESOURCE_DEFINITIONS,\n }));\n\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n const text = await readResource(uri);\n return {\n contents: [\n {\n uri,\n mimeType: uri.endsWith(\".json\") ? \"application/json\" : \"text/markdown\",\n text,\n },\n ],\n };\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // Log to stderr so it doesn't pollute the stdio JSON-RPC channel.\n console.error(\"[godx-ui-mcp] connected (stdio)\");\n}\n\nmain().catch((err) => {\n console.error(\"[godx-ui-mcp] fatal:\", err);\n process.exit(1);\n});\n","/**\n * Component catalog — the REAL published `@godxjp/ui` v6 primitive surface.\n * The MCP bundles this so an agent can author pages with the actual API\n * (PageContainer, Stack, ResponsiveGrid, DataTable + ColumnDef, StatusBadge,\n * FormField, Select, Dialog, FilterBar, …) instead of guessing.\n *\n * Each entry maps to a real export. Import via the subpath in every example,\n * e.g. `import { DataTable } from \"@godxjp/ui/data-display\"`.\n *\n * Each entry carries:\n * - `name` — canonical export name\n * - `group` — entry-point group\n * - `tagline` — one-line elevator pitch\n * - `props` — most-used real props with type + description\n * - `example` — copy-paste-ready JSX using the real API\n * - `storyPath` — relative path under `src/stories/`\n * - `rules` — cardinal rules relevant to this primitive\n */\n\nexport type ComponentGroup =\n | \"general\"\n | \"layout\"\n | \"data-display\"\n | \"data-entry\"\n | \"feedback\"\n | \"navigation\"\n | \"composites\"\n | \"shell\"\n | \"providers\";\n\nexport interface ComponentProp {\n name: string;\n type: string;\n required?: boolean;\n description: string;\n defaultValue?: string;\n}\n\nexport interface ComponentEntry {\n name: string;\n group: ComponentGroup;\n tagline: string;\n props: ComponentProp[];\n example: string;\n docPath?: string;\n storyPath: string;\n rules: number[];\n}\n\nexport const COMPONENTS: ComponentEntry[] = [\n // ─── layout ─────────────────────────────────────────────────────────────\n {\n name: \"PageContainer\",\n group: \"layout\",\n tagline: \"Mandatory page shell — EVERY page wraps its content in PageContainer (title/subtitle/extra/footer/breadcrumb).\",\n props: [\n { name: \"title\", type: \"string\", required: true, description: \"Page heading rendered as <h1>.\" },\n { name: \"subtitle\", type: \"string\", description: \"Secondary line beneath the title.\" },\n { name: \"extra\", type: \"ReactNode\", description: \"Action buttons / controls rendered right of the title row.\" },\n { name: \"footer\", type: \"ReactNode\", description: \"Content area pinned below the page body.\" },\n { name: \"breadcrumb\", type: \"BreadcrumbItemProp[]\", description: \"Ordered trail of { label, to? } segments above the title.\" },\n { name: \"variant\", type: '\"default\" | \"narrow\" | \"flush\" | \"ghost\"', defaultValue: '\"default\"', description: \"Page shell layout; flush removes padding for full-bleed content.\" },\n { name: \"density\", type: '\"compact\" | \"default\" | \"comfortable\"', defaultValue: '\"default\"', description: \"Spacing density across the page subtree.\" },\n { name: \"stickyFooter\", type: \"boolean\", defaultValue: \"false\", description: \"Pin footer to viewport bottom on scroll — pairs with variant=\\\"narrow\\\".\" },\n ],\n example: `import { PageContainer, Stack } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\nexport default function OrdersPage() {\n return (\n <PageContainer\n title=\"注文一覧\"\n subtitle=\"直近30日間の受注データ\"\n breadcrumb={[{ label: \"ホーム\", to: \"/\" }, { label: \"注文一覧\" }]}\n extra={<Button>新規注文</Button>}\n >\n <Stack gap=\"lg\">{/* page content */}</Stack>\n </PageContainer>\n );\n}`,\n storyPath: \"layout/PageContainer.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Stack\",\n group: \"layout\",\n tagline: \"Vertical flex column with token gap — the default block-stacking primitive (use instead of space-y-*).\",\n props: [\n { name: \"gap\", type: '\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"', defaultValue: '\"md\"', description: \"Vertical space between children (design tokens).\" },\n { name: \"className\", type: \"string\", description: \"Extra classes merged via cn().\" },\n { name: \"children\", type: \"ReactNode\", description: \"Block-level children to stack.\" },\n ],\n example: `import { Stack } from \"@godxjp/ui/layout\";\n\n<Stack gap=\"lg\">\n <KpiRow />\n <FilterBarBlock />\n <TableCard />\n</Stack>`,\n storyPath: \"layout/Stack.stories.tsx\",\n rules: [2, 40],\n },\n {\n name: \"Inline\",\n group: \"layout\",\n tagline: \"Horizontal flex row with token gap — the default inline/row arrangement (use instead of gap-* on a flex div).\",\n props: [\n { name: \"gap\", type: '\"xs\" | \"sm\" | \"md\" | \"lg\"', defaultValue: '\"sm\"', description: \"Horizontal space between children.\" },\n { name: \"className\", type: \"string\", description: \"Extra classes merged via cn().\" },\n { name: \"children\", type: \"ReactNode\", description: \"Inline children in a row.\" },\n ],\n example: `import { Inline } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Inline gap=\"sm\">\n <Button>保存</Button>\n <Button variant=\"outline\">キャンセル</Button>\n</Inline>`,\n storyPath: \"layout/Inline.stories.tsx\",\n rules: [2],\n },\n {\n name: \"ResponsiveGrid\",\n group: \"layout\",\n tagline: \"Auto-responsive card grid — columns collapse to 1 on mobile, scale up on wider breakpoints.\",\n props: [\n { name: \"columns\", type: \"2 | 3 | 4\", defaultValue: \"3\", description: \"Target column count at desktop; collapses to 1 on mobile.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Grid items — typically Card or CardStat.\" },\n ],\n example: `import { ResponsiveGrid } from \"@godxjp/ui/layout\";\nimport { CardStat } from \"@godxjp/ui/data-display\";\n\n<ResponsiveGrid columns={4}>\n <CardStat label=\"総会員数\" value=\"12,400\" />\n <CardStat label=\"公開中クーポン\" value=\"8\" />\n <CardStat label=\"月間利用数\" value=\"3,210\" />\n <CardStat label=\"割引総額\" value=\"¥480,000\" />\n</ResponsiveGrid>`,\n storyPath: \"layout/ResponsiveGrid.stories.tsx\",\n rules: [24, 40],\n },\n {\n name: \"AppShell\",\n group: \"layout\",\n tagline: \"Root application shell — composes sidebar, topbar rail, main content area, and optional footer.\",\n props: [\n { name: \"sidebar\", type: \"ReactNode\", required: true, description: \"Sidebar node — typically a <Sidebar>.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Main page content rendered in <main>.\" },\n { name: \"topbar\", type: \"ReactNode\", description: \"Full topbar override; else a rail is built from topbarLeft/topbarRight/logo.\" },\n { name: \"topbarRight\", type: \"ReactNode\", description: \"Right slot of the auto-built topbar rail (user menu, switcher).\" },\n { name: \"topbarLeft\", type: \"ReactNode\", description: \"Left slot of the auto-built topbar rail.\" },\n { name: \"logo\", type: \"ReactNode\", description: \"Logo at the far-left of the auto-built topbar rail.\" },\n { name: \"sidebarCollapsed\", type: \"boolean\", defaultValue: \"false\", description: \"Collapse the sidebar to icon-only mode.\" },\n { name: \"footer\", type: \"ReactNode\", description: \"App-level footer outside the main content area.\" },\n ],\n example: `import { AppShell, Sidebar } from \"@godxjp/ui/layout\";\nimport { LayoutDashboard, Users } from \"lucide-react\";\nimport { router } from \"@inertiajs/react\";\n\nconst sidebar = (\n <Sidebar\n activeId=\"/dashboard\"\n onSelect={(id) => router.visit(id)}\n sections={[{ items: [\n { id: \"/dashboard\", label: \"ダッシュボード\", icon: LayoutDashboard },\n { id: \"/users\", label: \"ユーザー\", icon: Users },\n ] }]}\n product={{ name: \"JOVY CRM\", role: \"本部\", color: \"var(--color-primary)\" }}\n />\n);\n\nexport function CrmLayout({ children }: { children: React.ReactNode }) {\n return <AppShell sidebar={sidebar}>{children}</AppShell>;\n}`,\n storyPath: \"layout/AppShell.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Sidebar\",\n group: \"layout\",\n tagline: \"Navigation sidebar with sections, items, product header, and collapsible icon-only mode.\",\n props: [\n { name: \"activeId\", type: \"string\", required: true, description: \"Id of the active nav item; drives highlight.\" },\n { name: \"sections\", type: \"SidebarSectionProp[]\", required: true, description: \"Array of { label?, items: SidebarItemProp[] } where item = { id, label, icon, badge? }.\" },\n { name: \"onSelect\", type: \"(id: string) => void\", description: \"Called on item click; typically router.visit(id).\" },\n { name: \"product\", type: \"{ name: string; role?: string; color?: string }\", description: \"Product/workspace block at the top.\" },\n { name: \"brand\", type: \"ReactNode\", description: \"Custom brand node replacing the product block.\" },\n { name: \"collapsed\", type: \"boolean\", defaultValue: \"false\", description: \"Icon-only mode; labels/section headings hidden.\" },\n { name: \"footer\", type: \"ReactNode\", description: \"Bottom slot (user info, logout). The .sb-footer wrapper supplies the top border + padding; YOUR content must use SEMANTIC token classes — `text-muted-foreground text-xs` outer with a `text-foreground font-medium` primary line. Do NOT use raw `opacity-*` / arbitrary `text-[11px]` (washed-out, off-design).\" },\n ],\n example: `import { Sidebar } from \"@godxjp/ui/layout\";\nimport { Stack } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { LayoutDashboard, Users, LogOut } from \"lucide-react\";\nimport { router, usePage } from \"@inertiajs/react\";\n\nexport function AppSidebar() {\n const { url } = usePage();\n return (\n <Sidebar\n activeId={url}\n onSelect={(id) => router.visit(id)}\n sections={[{ label: \"メイン\", items: [\n { id: \"/dashboard\", label: \"ダッシュボード\", icon: LayoutDashboard },\n { id: \"/members\", label: \"会員管理\", icon: Users },\n ] }]}\n product={{ name: \"JOVY CRM\", role: \"本部\" }}\n footer={\n // Canonical footer: semantic tokens only (see Sidebar story).\n <Stack gap=\"sm\">\n <div className=\"text-muted-foreground text-xs\">\n <div className=\"text-foreground font-medium\">山田 花子</div>\n <div>ABCファーマシー</div>\n </div>\n <Button variant=\"ghost\" size=\"sm\" className=\"w-full justify-start\" onClick={() => router.post(\"/logout\")}>\n <LogOut className=\"size-4\" />ログアウト\n </Button>\n </Stack>\n }\n />\n );\n}`,\n storyPath: \"layout/Sidebar.stories.tsx\",\n rules: [2, 23],\n },\n {\n name: \"Topbar\",\n group: \"layout\",\n tagline: \"Application topbar with product/project switcher and search/notification slots (or use AppShell's topbarRight).\",\n props: [\n { name: \"product\", type: \"{ name: string; color?: string }\", required: true, description: \"Current product chip.\" },\n { name: \"project\", type: \"{ name: string } | null\", description: \"Current project chip; null shows placeholder.\" },\n { name: \"onSearchOpen\", type: \"() => void\", description: \"Called when the search bar is clicked.\" },\n { name: \"onProductOpen\", type: \"() => void\", description: \"Called when the product chip is clicked.\" },\n ],\n example: `import { Topbar } from \"@godxjp/ui/layout\";\n\n<Topbar product={{ name: \"JOVY CRM\" }} project={{ name: \"本番環境\" }} />`,\n storyPath: \"layout/Topbar.stories.tsx\",\n rules: [23],\n },\n {\n name: \"PageInset\",\n group: \"layout\",\n tagline: \"Padded horizontal strip aligned with the page header — use inside variant=\\\"flush\\\" for filter bars / intros.\",\n props: [\n { name: \"children\", type: \"ReactNode\", description: \"Content rendered with standard page horizontal padding.\" },\n { name: \"className\", type: \"string\", description: \"Extra classes.\" },\n ],\n example: `import { PageContainer, PageInset } from \"@godxjp/ui/layout\";\n\n<PageContainer title=\"商品一覧\" variant=\"flush\">\n <PageInset><FilterBarBlock /></PageInset>\n {/* full-bleed table below */}\n</PageContainer>`,\n storyPath: \"layout/PageInset.stories.tsx\",\n rules: [],\n },\n {\n name: \"SplitPane\",\n group: \"layout\",\n tagline: \"Two-column layout with a main content area and a fixed-width aside panel.\",\n props: [\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Main (left) content.\" },\n { name: \"aside\", type: \"ReactNode\", required: true, description: \"Aside (right) panel content.\" },\n { name: \"asideWidth\", type: '\"sm\" | \"md\"', defaultValue: '\"md\"', description: \"Width preset for the aside column.\" },\n ],\n example: `import { SplitPane } from \"@godxjp/ui/layout\";\n\n<SplitPane aside={<DetailPanel />} asideWidth=\"sm\">\n <MainContent />\n</SplitPane>`,\n storyPath: \"layout/SplitPane.stories.tsx\",\n rules: [24],\n },\n {\n name: \"Breadcrumb\",\n group: \"layout\",\n tagline: \"Standalone breadcrumb nav rendering an ordered trail of page segments.\",\n props: [\n { name: \"items\", type: \"BreadcrumbItemProp[]\", required: true, description: \"Array of { label, to? } — omit `to` on the last (current) segment.\" },\n ],\n example: `import { Breadcrumb } from \"@godxjp/ui/layout\";\n\n<Breadcrumb items={[\n { label: \"ホーム\", to: \"/\" },\n { label: \"会員管理\", to: \"/members\" },\n { label: \"田中 太郎\" },\n]} />`,\n storyPath: \"layout/Breadcrumb.stories.tsx\",\n rules: [],\n },\n\n // ─── general ────────────────────────────────────────────────────────────\n {\n name: \"Button\",\n group: \"general\",\n tagline: \"Core button with variant + size presets, built on cva and Radix Slot (asChild).\",\n props: [\n { name: \"variant\", type: '\"default\" | \"destructive\" | \"outline\" | \"secondary\" | \"ghost\" | \"link\"', defaultValue: '\"default\"', description: \"Visual style.\" },\n { name: \"size\", type: '\"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\"', defaultValue: '\"default\"', description: \"Size preset (height, padding, icon dims).\" },\n { name: \"asChild\", type: \"boolean\", defaultValue: \"false\", description: \"Render as Radix Slot — merge props onto the child (<a>/<Link>).\" },\n { name: \"disabled\", type: \"boolean\", description: \"Disable the button.\" },\n { name: \"onClick\", type: \"React.MouseEventHandler<HTMLButtonElement>\", description: \"Click handler.\" },\n ],\n example: `import { Button } from \"@godxjp/ui/general\";\nimport { Trash2 } from \"lucide-react\";\n\n<>\n <Button>保存</Button>\n <Button variant=\"outline\" size=\"sm\">編集</Button>\n <Button variant=\"ghost\" size=\"icon-sm\"><Trash2 className=\"size-4\" /></Button>\n</>`,\n storyPath: \"general/Button.stories.tsx\",\n rules: [23],\n },\n\n // ─── data-display ───────────────────────────────────────────────────────\n {\n name: \"DataTable\",\n group: \"data-display\",\n tagline: \"Full-width admin list. Lives in its OWN row (Card + CardContent flush) — never inside a narrow grid column. Cells default to white-space:nowrap (scroll, don't crush).\",\n props: [\n { name: \"data\", type: \"T[]\", required: true, description: \"Row data array.\" },\n { name: \"columns\", type: \"ColumnDef<T>[]\", required: true, description: \"Each: { key, header, render?(row), align?: 'left'|'center'|'right', sortable?, width? }. width is a Tailwind class string e.g. 'w-64'.\" },\n { name: \"getRowId\", type: \"(row: T) => string\", description: \"Row key extractor (falls back to row.id). Required when selectable.\" },\n { name: \"onRowClick\", type: \"(row: T) => void\", description: \"Navigate on row click; ignored when target is interactive.\" },\n { name: \"selectable\", type: \"boolean\", defaultValue: \"false\", description: \"Enable checkbox column + bulk selection.\" },\n { name: \"selected\", type: \"Set<string>\", description: \"Controlled selection set.\" },\n { name: \"onSelectChange\", type: \"(next: Set<string>) => void\", description: \"Selection change handler.\" },\n { name: \"onSortChange\", type: \"(sort | undefined) => void\", description: \"Fires when a sortable header is clicked; undefined clears sort.\" },\n ],\n example: `import { Card, CardContent, DataTable, StatusBadge } from \"@godxjp/ui/data-display\";\nimport type { ColumnDef } from \"@godxjp/ui/data-display\";\nimport { router } from \"@inertiajs/react\";\n\ntype Member = { id: string; name: string; status: string };\nconst columns: ColumnDef<Member>[] = [\n { key: \"name\", header: \"氏名\", width: \"w-64\", render: (m) => <span className=\"font-medium\">{m.name}</span> },\n { key: \"status\", header: \"ステータス\", render: (m) => <StatusBadge status={m.status} /> },\n];\n\n<Card>\n <CardContent flush>\n <DataTable data={members} columns={columns} getRowId={(m) => m.id}\n onRowClick={(m) => router.visit(\"/members/\" + m.id)} />\n </CardContent>\n</Card>`,\n storyPath: \"data-display/DataTable.stories.tsx\",\n rules: [37, 39, 35],\n },\n {\n name: \"Card\",\n group: \"data-display\",\n tagline: \"Surface container with optional accent stripe, variant fill, size, and density. Compose with CardHeader/CardTitle/CardContent/CardFooter.\",\n props: [\n { name: \"accent\", type: '\"primary\" | \"success\" | \"warning\" | \"info\" | \"attention\" | \"destructive\"', description: \"3px left-edge semantic accent stripe.\" },\n { name: \"variant\", type: '\"default\" | \"muted\" | \"outline\" | \"featured\"', defaultValue: '\"default\"', description: \"Surface fill style.\" },\n { name: \"size\", type: '\"default\" | \"compact\"', defaultValue: '\"default\"', description: \"Card size preset.\" },\n { name: \"density\", type: '\"tight\" | \"cozy\"', description: \"Internal padding density (base 16 / tight 12 / cozy 20).\" },\n ],\n example: `import { Card, CardHeader, CardTitle, CardContent } from \"@godxjp/ui/data-display\";\n\n<Card accent=\"success\">\n <CardHeader><CardTitle>注文サマリー</CardTitle></CardHeader>\n <CardContent>総売上: ¥1,234,567</CardContent>\n</Card>`,\n storyPath: \"data-display/Card.stories.tsx\",\n rules: [],\n },\n {\n name: \"CardContent\",\n group: \"data-display\",\n tagline: \"Card body. flush = edge-to-edge (for DataTable/tabs); tight = no top gap; solo = no header above. NEVER put a FilterBar inside flush (it loses padding).\",\n props: [\n { name: \"flush\", type: \"boolean\", description: \"Remove horizontal padding for edge-to-edge tables / tabs lists.\" },\n { name: \"tight\", type: \"boolean\", description: \"No top gap after header — pair with flush toolbars/tabs.\" },\n { name: \"solo\", type: \"boolean\", description: \"No header above: top padding matches the card shell.\" },\n ],\n example: `import { Card, CardContent, DataTable } from \"@godxjp/ui/data-display\";\n\n<Card>\n <CardContent flush>\n <DataTable data={rows} columns={columns} />\n </CardContent>\n</Card>`,\n storyPath: \"data-display/Card.stories.tsx\",\n rules: [37, 38],\n },\n {\n name: \"CardStat\",\n group: \"data-display\",\n tagline: \"KPI tile. ⚠️ CardStat IS ALREADY a bordered Card — render it DIRECTLY in ResponsiveGrid. NEVER wrap it in <Card>/<CardContent> (that double-borders it → looks too thick). NO accent prop (accent is a Card prop).\",\n props: [\n { name: \"label\", type: \"ReactNode\", required: true, description: \"Metric name.\" },\n { name: \"value\", type: \"ReactNode\", required: true, description: \"Metric value (string/number/ReactNode).\" },\n { name: \"hint\", type: \"ReactNode\", description: \"Secondary context below the value.\" },\n { name: \"delta\", type: \"ReactNode\", description: \"Compact trend text beside the value. Sign-aware tone (+ green / - red).\" },\n { name: \"layout\", type: '\"stacked\" | \"inline\"', defaultValue: '\"stacked\"', description: \"stacked = label over value; inline = label left / value right.\" },\n { name: \"align\", type: '\"start\" | \"end\"', description: \"Align the metric group.\" },\n ],\n example: `import { CardStat } from \"@godxjp/ui/data-display\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n// ✅ CardStat sits directly in the grid — it draws its own card + border.\n<ResponsiveGrid columns={3}>\n <CardStat label=\"総会員数\" value=\"12,450\" hint=\"先月比 +3%\" />\n <CardStat label=\"月次売上\" value=\"¥8,200,000\" delta=\"+12%\" />\n <CardStat label=\"利用率\" value=\"68.4%\" />\n</ResponsiveGrid>\n\n// ❌ Double border — do NOT wrap CardStat in a Card:\n// <Card><CardContent><CardStat label=\"x\" value=\"1\" /></CardContent></Card>`,\n storyPath: \"data-display/CardStat.stories.tsx\",\n rules: [],\n },\n {\n name: \"StatusBadge\",\n group: \"data-display\",\n tagline: \"Lifecycle chip that auto-maps English keys (active/draft/pending/failed/…) to tone + icon. For localized labels or tiers, pass tone explicitly; pass icon={null} for tiers. Chips never wrap.\",\n props: [\n { name: \"status\", type: \"string\", required: true, description: \"Lifecycle key or any domain string. Unknown strings fall back to neutral unless tone is set.\" },\n { name: \"tone\", type: '\"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\"', description: \"Override the resolved tone (escape hatch for localized / tier values).\" },\n { name: \"icon\", type: \"LucideIcon | null\", description: \"Override the icon; null hides it — preferred for tier / category badges.\" },\n { name: \"label\", type: \"ReactNode\", description: \"Override display text (default: i18n of key, or raw status).\" },\n ],\n example: `import { StatusBadge } from \"@godxjp/ui/data-display\";\n\n<>\n <StatusBadge status=\"active\" label=\"公開中\" /> {/* green check */}\n <StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} /> {/* tier pill, no icon */}\n <StatusBadge status=\"ゴールド\" tone=\"warning\" icon={null} />\n</>`,\n storyPath: \"data-display/StatusBadge.stories.tsx\",\n rules: [35, 36],\n },\n {\n name: \"Badge\",\n group: \"data-display\",\n tagline: \"Plain label chip with semantic variants. Use for static category tags; use StatusBadge for lifecycle status.\",\n props: [\n { name: \"variant\", type: '\"default\" | \"secondary\" | \"destructive\" | \"outline\" | \"success\" | \"warning\"', defaultValue: '\"default\"', description: \"Visual variant.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Badge text/content.\" },\n ],\n example: `import { Badge } from \"@godxjp/ui/data-display\";\n\n<Badge variant=\"secondary\">A/B</Badge>\n<Badge variant=\"success\">承認済</Badge>`,\n storyPath: \"data-display/Badge.stories.tsx\",\n rules: [35],\n },\n {\n name: \"KeyValueGrid\",\n group: \"data-display\",\n tagline: \"Responsive definition grid for detail-page metadata. COMPOUND — value goes in KeyValueGrid.Item children.\",\n props: [\n { name: \"columns\", type: \"1 | 2 | 3\", defaultValue: \"2\", description: \"Column count; collapses to 1 on mobile.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"KeyValueGrid.Item elements.\" },\n ],\n example: `import { KeyValueGrid } from \"@godxjp/ui/data-display\";\n\n<KeyValueGrid columns={2}>\n <KeyValueGrid.Item label=\"会員ID\" mono>{member.id}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"プラン\">{member.plan}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"メモ\" span={2}>{member.note}</KeyValueGrid.Item>\n</KeyValueGrid>`,\n storyPath: \"data-display/KeyValueGrid.stories.tsx\",\n rules: [],\n },\n {\n name: \"EmptyState\",\n group: \"data-display\",\n tagline: \"Centred empty placeholder with icon, title, description, and optional CTA.\",\n props: [\n { name: \"title\", type: \"string\", required: true, description: \"Primary empty message.\" },\n { name: \"description\", type: \"string\", description: \"Secondary helper text.\" },\n { name: \"icon\", type: \"LucideIcon\", description: \"Icon above the title.\" },\n { name: \"action\", type: \"ReactNode\", description: \"CTA element (e.g. a Button).\" },\n ],\n example: `import { EmptyState } from \"@godxjp/ui/data-display\";\n\n<EmptyState title=\"該当データがありません\" description=\"検索条件を変更してください。\" />`,\n storyPath: \"data-display/EmptyState.stories.tsx\",\n rules: [],\n },\n {\n name: \"ProgressMeter\",\n group: \"data-display\",\n tagline: \"Horizontal progress bar 0–100 with optional label and semantic tone.\",\n props: [\n { name: \"value\", type: \"number\", required: true, description: \"Progress percentage 0–100 (clamped).\" },\n { name: \"label\", type: \"string\", description: \"Text label beside/below the bar.\" },\n { name: \"tone\", type: '\"success\" | \"warning\"', defaultValue: '\"success\"', description: \"Bar colour tone.\" },\n ],\n example: `import { ProgressMeter } from \"@godxjp/ui/data-display\";\n\n<ProgressMeter value={pct} label={pct + \"% 使用中\"} tone={pct >= 80 ? \"warning\" : \"success\"} />`,\n storyPath: \"data-display/ProgressMeter.stories.tsx\",\n rules: [],\n },\n {\n name: \"Timeline\",\n group: \"data-display\",\n tagline: \"Vertical event list with an icon rail. Current item gets a highlighted glyph.\",\n props: [\n { name: \"items\", type: \"TimelineItem[]\", required: true, description: \"Array of { title, location?, time?, note?, current? }.\" },\n ],\n example: `import { Timeline } from \"@godxjp/ui/data-display\";\n\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />`,\n storyPath: \"data-display/Timeline.stories.tsx\",\n rules: [],\n },\n {\n name: \"Table\",\n group: \"data-display\",\n tagline: \"Primitive table shell (Table/TableHeader/TableBody/TableRow/TableHead/TableCell). Prefer DataTable for admin lists; use these for custom one-off tables.\",\n props: [\n { name: \"children\", type: \"ReactNode\", required: true, description: \"TableHeader / TableBody composition.\" },\n { name: \"className\", type: \"string\", description: \"Extra classes on the table element.\" },\n ],\n example: `import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"@godxjp/ui/data-display\";\n\n<Table>\n <TableHeader><TableRow><TableHead>項目</TableHead><TableHead className=\"text-right\">金額</TableHead></TableRow></TableHeader>\n <TableBody><TableRow><TableCell>送料</TableCell><TableCell className=\"text-right\">¥500</TableCell></TableRow></TableBody>\n</Table>`,\n storyPath: \"data-display/Table.stories.tsx\",\n rules: [],\n },\n {\n name: \"DataState\",\n group: \"data-display\",\n tagline: \"TanStack Query lifecycle widget — skeleton / error / empty / success for one useQuery block. Import from @godxjp/ui/query.\",\n props: [\n { name: \"query\", type: \"UseQueryResult<T>\", required: true, description: \"The useQuery result.\" },\n { name: \"skeleton\", type: \"ReactNode\", required: true, description: \"Shown while loading.\" },\n { name: \"children\", type: \"(data) => ReactNode\", required: true, description: \"Render function with resolved data.\" },\n { name: \"empty\", type: \"ReactNode\", description: \"Shown when isEmpty(data) is true.\" },\n { name: \"isEmpty\", type: \"(data) => boolean\", description: \"Custom empty check.\" },\n ],\n example: `import { DataState } from \"@godxjp/ui/query\";\n\n<DataState query={membersQuery} skeleton={<SkeletonTable />} isEmpty={(d) => d.items.length === 0} empty={<EmptyState title=\"会員なし\" />}>\n {(d) => <MemberTable items={d.items} />}\n</DataState>`,\n storyPath: \"query/DataState.stories.tsx\",\n rules: [],\n },\n {\n name: \"InfiniteQueryState\",\n group: \"data-display\",\n tagline: \"useInfiniteQuery widget — flatten pages, skeleton/empty/error, load-more footer. Import from @godxjp/ui/query.\",\n props: [\n { name: \"query\", type: \"UseInfiniteQueryResult\", required: true, description: \"The useInfiniteQuery result.\" },\n { name: \"skeleton\", type: \"ReactNode\", required: true, description: \"Shown while initial load pends.\" },\n { name: \"flatten\", type: \"(data) => TFlat\", required: true, description: \"Reduce pages to a flat list (use flattenItemPages helper).\" },\n { name: \"children\", type: \"(flat, helpers) => ReactNode\", required: true, description: \"Render with flat data + { fetchNextPage, hasNextPage, isFetchingNextPage }.\" },\n ],\n example: `import { InfiniteQueryState, flattenItemPages } from \"@godxjp/ui/query\";\n\n<InfiniteQueryState query={q} skeleton={<SkeletonRows />} flatten={flattenItemPages} isEmpty={(it) => it.length === 0}>\n {(items) => items.map((a) => <ActivityRow key={a.id} activity={a} />)}\n</InfiniteQueryState>`,\n storyPath: \"query/InfiniteQueryState.stories.tsx\",\n rules: [],\n },\n {\n name: \"MutationFeedback\",\n group: \"data-display\",\n tagline: \"Inline mutation error — renders nothing when idle/successful. Import from @godxjp/ui/query.\",\n props: [\n { name: \"mutation\", type: \"{ isError, error, isPending }\", required: true, description: \"useMutation result.\" },\n { name: \"onRetry\", type: \"() => void\", description: \"Retry handler.\" },\n ],\n example: `import { MutationFeedback } from \"@godxjp/ui/query\";\n\n<MutationFeedback mutation={saveMutation} />`,\n storyPath: \"query/MutationFeedback.stories.tsx\",\n rules: [],\n },\n\n // ─── data-entry ─────────────────────────────────────────────────────────\n {\n name: \"FormField\",\n group: \"data-entry\",\n tagline: \"Wraps a control with label, helper, and error; injects aria-describedby/aria-invalid onto the child.\",\n props: [\n { name: \"id\", type: \"string\", required: true, description: \"Forwarded to Label htmlFor + builds helper/error ids.\" },\n { name: \"label\", type: \"ReactNode\", required: true, description: \"Field label above the control.\" },\n { name: \"required\", type: \"boolean\", defaultValue: \"false\", description: \"Red asterisk + aria-required on the child.\" },\n { name: \"helper\", type: \"string\", description: \"Muted hint shown when there is no error.\" },\n { name: \"error\", type: \"string\", description: \"Destructive error message (role=alert); overrides helper.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"The single control to render.\" },\n ],\n example: `import { FormField, Input } from \"@godxjp/ui/data-entry\";\n\n<FormField id=\"coupon-name\" label=\"クーポン名\" required error={errors.name} helper=\"最大50文字\">\n <Input id=\"coupon-name\" placeholder=\"春の花粉症対策15%OFF\" value={name} onChange={(e) => setName(e.target.value)} />\n</FormField>`,\n storyPath: \"data-entry/FormField.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Input\",\n group: \"data-entry\",\n tagline: \"Styled wrapper around native <input>; accepts all HTML input attributes. Pair with FormField for labelled fields.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Associates with a <label htmlFor>.\" },\n { name: \"type\", type: \"string\", defaultValue: '\"text\"', description: \"Native input type.\" },\n { name: \"placeholder\", type: \"string\", description: \"Placeholder.\" },\n { name: \"value\", type: \"string | number\", description: \"Controlled value.\" },\n { name: \"onChange\", type: \"React.ChangeEventHandler<HTMLInputElement>\", description: \"Native change handler.\" },\n ],\n example: `import { Input } from \"@godxjp/ui/data-entry\";\n\n<Input id=\"qty\" type=\"number\" placeholder=\"例: 500\" value={value} onChange={(e) => setValue(e.target.value)} />`,\n storyPath: \"data-entry/Input.stories.tsx\",\n rules: [],\n },\n {\n name: \"SearchInput\",\n group: \"data-entry\",\n tagline: \"Debounced search box with a clear button. Fires onSearch (NOT onChange) after the debounce. Controlled (value) or uncontrolled (defaultValue).\",\n props: [\n { name: \"onSearch\", type: \"(q: string) => void\", required: true, description: \"Called with the query after the debounce. Use this to drive filtering — NOT onChange.\" },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n { name: \"defaultValue\", type: \"string\", defaultValue: '\"\"', description: \"Initial uncontrolled value.\" },\n { name: \"placeholder\", type: \"string\", description: \"Input placeholder.\" },\n { name: \"debounce\", type: \"number\", defaultValue: \"250\", description: \"Debounce delay (ms).\" },\n ],\n example: `import { SearchInput } from \"@godxjp/ui/data-entry\";\n\n<SearchInput placeholder=\"クーポン名・IDで検索\" value={search} onSearch={setSearch} />`,\n storyPath: \"data-entry/SearchInput.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Select\",\n group: \"data-entry\",\n tagline: \"Radix compound select. Controlled via value + onValueChange on <Select>; compose SelectTrigger>SelectValue and SelectContent>SelectItem. This is the filter/select pattern the app uses.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled selected value.\" },\n { name: \"defaultValue\", type: \"string\", description: \"Uncontrolled initial value.\" },\n { name: \"onValueChange\", type: \"(value: string) => void\", description: \"Called when the user picks an item.\" },\n { name: \"disabled\", type: \"boolean\", defaultValue: \"false\", description: \"Disable the trigger.\" },\n ],\n example: `import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"@godxjp/ui/data-entry\";\n\n<Select value={status} onValueChange={setStatus}>\n <SelectTrigger><SelectValue placeholder=\"全ステータス\" /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">全ステータス</SelectItem>\n <SelectItem value=\"active\">公開中</SelectItem>\n <SelectItem value=\"draft\">下書き</SelectItem>\n </SelectContent>\n</Select>`,\n storyPath: \"data-entry/Select.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Switch\",\n group: \"data-entry\",\n tagline: \"Radix toggle switch (bare). For a labelled row with a hidden form input use SwitchField.\",\n props: [\n { name: \"checked\", type: \"boolean\", description: \"Controlled checked state.\" },\n { name: \"onCheckedChange\", type: \"(checked: boolean) => void\", description: \"Fires when toggled.\" },\n { name: \"id\", type: \"string\", description: \"Links to a <Label htmlFor>.\" },\n { name: \"disabled\", type: \"boolean\", defaultValue: \"false\", description: \"Disable the toggle.\" },\n ],\n example: `import { Switch, Label } from \"@godxjp/ui/data-entry\";\n\n<div className=\"flex items-center gap-2\">\n <Switch id=\"stackable\" checked={stackable} onCheckedChange={setStackable} />\n <Label htmlFor=\"stackable\">他クーポンとの併用を許可</Label>\n</div>`,\n storyPath: \"data-entry/Switch.stories.tsx\",\n rules: [],\n },\n {\n name: \"Textarea\",\n group: \"data-entry\",\n tagline: \"Styled wrapper around native <textarea>. Pair with FormField for labelled fields.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Associates with a <Label htmlFor>.\" },\n { name: \"rows\", type: \"number\", description: \"Visible text rows.\" },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n { name: \"onChange\", type: \"React.ChangeEventHandler<HTMLTextAreaElement>\", description: \"Change handler.\" },\n ],\n example: `import { Textarea } from \"@godxjp/ui/data-entry\";\n\n<Textarea id=\"notes\" rows={4} placeholder=\"自由記述\" value={notes} onChange={(e) => setNotes(e.target.value)} />`,\n storyPath: \"data-entry/Textarea.stories.tsx\",\n rules: [],\n },\n {\n name: \"Label\",\n group: \"data-entry\",\n tagline: \"Styled Radix Label; use htmlFor to associate with a control.\",\n props: [\n { name: \"htmlFor\", type: \"string\", description: \"Id of the associated control.\" },\n { name: \"children\", type: \"ReactNode\", description: \"Label content.\" },\n ],\n example: `import { Label } from \"@godxjp/ui/data-entry\";\n\n<Label htmlFor=\"stackable\">併用を許可</Label>`,\n storyPath: \"data-entry/Label.stories.tsx\",\n rules: [],\n },\n {\n name: \"Checkbox\",\n group: \"data-entry\",\n tagline: \"Radix checkbox; standalone or via CheckboxGroup with an options array.\",\n props: [\n { name: \"checked\", type: \"boolean | 'indeterminate'\", description: \"Controlled checked state.\" },\n { name: \"onCheckedChange\", type: \"(checked) => void\", description: \"Fires when checked state changes.\" },\n { name: \"id\", type: \"string\", description: \"Links to a <Label htmlFor>.\" },\n ],\n example: `import { Checkbox, Label } from \"@godxjp/ui/data-entry\";\n\n<div className=\"flex items-center gap-2\">\n <Checkbox id=\"agree\" checked={agreed} onCheckedChange={(v) => setAgreed(!!v)} />\n <Label htmlFor=\"agree\">利用規約に同意する</Label>\n</div>`,\n storyPath: \"data-entry/Checkbox.stories.tsx\",\n rules: [],\n },\n {\n name: \"RadioGroup\",\n group: \"data-entry\",\n tagline: \"Radio group accepting an options array or RadioItem children.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled selected value.\" },\n { name: \"onValueChange\", type: \"(value: string) => void\", description: \"Fires on selection change.\" },\n { name: \"options\", type: \"ChoiceOptionProp[]\", description: \"Declarative list: { label, value, disabled?, description? }.\" },\n { name: \"orientation\", type: '\"horizontal\" | \"vertical\"', defaultValue: '\"vertical\"', description: \"Layout direction.\" },\n ],\n example: `import { RadioGroup } from \"@godxjp/ui/data-entry\";\n\n<RadioGroup value={trigger} onValueChange={setTrigger} orientation=\"horizontal\" options={[\n { label: \"初回購入\", value: \"first_purchase\" },\n { label: \"誕生日\", value: \"birthday\" },\n]} />`,\n storyPath: \"data-entry/RadioGroup.stories.tsx\",\n rules: [23],\n },\n {\n name: \"DatePicker\",\n group: \"data-entry\",\n tagline: \"Calendar popover for a single date; controlled via value (Date) + onChange.\",\n props: [\n { name: \"value\", type: \"Date\", description: \"Controlled selected date.\" },\n { name: \"onChange\", type: \"(date: Date | undefined) => void\", description: \"Fires when picked/cleared.\" },\n { name: \"placeholder\", type: \"string\", description: \"Trigger label when empty.\" },\n ],\n example: `import { DatePicker, FormField } from \"@godxjp/ui/data-entry\";\n\n<FormField id=\"valid-from\" label=\"有効開始日\">\n <DatePicker id=\"valid-from\" value={validFrom} onChange={setValidFrom} placeholder=\"日付を選択\" />\n</FormField>`,\n storyPath: \"data-entry/DatePicker.stories.tsx\",\n rules: [],\n },\n\n // ─── feedback ───────────────────────────────────────────────────────────\n {\n name: \"Dialog\",\n group: \"feedback\",\n tagline: \"Compound modal. Controlled via open + onOpenChange. Parts available flat (DialogTrigger/DialogContent/…) or as Dialog.Trigger/Dialog.Content. mode=\\\"confirm\\\" switches to alertdialog.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n { name: \"onOpenChange\", type: \"(open: boolean) => void\", description: \"Open-state change handler.\" },\n { name: \"mode\", type: '\"form\" | \"confirm\"', defaultValue: '\"form\"', description: \"form = Radix Dialog (× close); confirm = AlertDialog (no ×).\" },\n ],\n example: `import { useState } from \"react\";\nimport { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from \"@godxjp/ui/feedback\";\nimport { Button } from \"@godxjp/ui/general\";\n\nfunction CreateDialog() {\n const [open, setOpen] = useState(false);\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild><Button size=\"sm\">新規作成</Button></DialogTrigger>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>新規クーポン作成</DialogTitle>\n <DialogDescription>クーポン情報を入力してください。</DialogDescription>\n </DialogHeader>\n {/* fields */}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setOpen(false)}>キャンセル</Button>\n <Button onClick={() => setOpen(false)}>保存</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}`,\n storyPath: \"feedback/Dialog.stories.tsx\",\n rules: [23, 3],\n },\n {\n name: \"Sheet\",\n group: \"feedback\",\n tagline: \"Side-panel drawer (Radix Dialog). Parts: Sheet/SheetTrigger/SheetContent(side=right|left|top|bottom)/SheetHeader/SheetTitle/SheetFooter.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n { name: \"onOpenChange\", type: \"(open: boolean) => void\", description: \"Open-state change handler.\" },\n ],\n example: `import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle } from \"@godxjp/ui/feedback\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Sheet open={open} onOpenChange={setOpen}>\n <SheetTrigger asChild><Button variant=\"outline\" size=\"sm\">絞り込み</Button></SheetTrigger>\n <SheetContent side=\"right\">\n <SheetHeader><SheetTitle>フィルター設定</SheetTitle></SheetHeader>\n {/* filter fields */}\n </SheetContent>\n</Sheet>`,\n storyPath: \"feedback/Sheet.stories.tsx\",\n rules: [3],\n },\n {\n name: \"Alert\",\n group: \"feedback\",\n tagline: \"Inline alert banner with variant-aware icon + optional dismiss. Parts: Alert/AlertTitle/AlertDescription/AlertActions/AlertQueryError.\",\n props: [\n { name: \"variant\", type: '\"default\" | \"destructive\" | \"warning\" | \"success\"', defaultValue: '\"default\"', description: \"Colour scheme + default icon.\" },\n { name: \"onDismiss\", type: \"() => void\", description: \"Renders an × dismiss button when provided.\" },\n { name: \"icon\", type: \"LucideIcon | false\", description: \"Override or hide (false) the icon.\" },\n ],\n example: `import { Alert, AlertTitle, AlertDescription } from \"@godxjp/ui/feedback\";\n\n<Alert variant=\"warning\">\n <AlertTitle>3 件の打刻漏れがあります</AlertTitle>\n <AlertDescription>本日中に確認してください。</AlertDescription>\n</Alert>`,\n storyPath: \"feedback/Alert.stories.tsx\",\n rules: [],\n },\n {\n name: \"SkeletonTable\",\n group: \"feedback\",\n tagline: \"Loading placeholder matching the DataTable layout (header + N rows). Drop-in while data loads (deferred props).\",\n props: [\n { name: \"rows\", type: \"number\", defaultValue: \"8\", description: \"Body skeleton rows.\" },\n { name: \"columns\", type: \"number\", defaultValue: \"5\", description: \"Columns in header + body.\" },\n ],\n example: `import { SkeletonTable } from \"@godxjp/ui/feedback\";\n\n{!coupons ? <SkeletonTable rows={10} columns={6} /> : <DataTable data={coupons} columns={columns} />}`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [],\n },\n {\n name: \"SkeletonCard\",\n group: \"feedback\",\n tagline: \"Loading placeholder shaped like a CardStat tile. Use inside a ResponsiveGrid while KPIs load.\",\n props: [],\n example: `import { SkeletonCard } from \"@godxjp/ui/feedback\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n<ResponsiveGrid columns={4}><SkeletonCard /><SkeletonCard /><SkeletonCard /><SkeletonCard /></ResponsiveGrid>`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [],\n },\n {\n name: \"Toaster\",\n group: \"feedback\",\n tagline: \"Mount once at app root to enable toasts. IMPORTANT: trigger toasts via `import { toast } from \\\"sonner\\\"` — NOT from @godxjp/ui.\",\n props: [\n { name: \"position\", type: '\"top-right\" | \"top-center\" | \"bottom-right\" | \"…\"', defaultValue: '\"bottom-right\"', description: \"Toast stack anchor.\" },\n { name: \"richColors\", type: \"boolean\", description: \"Enable Sonner rich variant colours.\" },\n ],\n example: `// app root — mount once\nimport { Toaster } from \"@godxjp/ui/feedback\";\n<>{children}<Toaster richColors /></>\n\n// anywhere — import toast from \"sonner\"\nimport { toast } from \"sonner\";\ntoast.success(\"クーポンを公開しました\");\ntoast.error(\"保存に失敗しました\");`,\n storyPath: \"feedback/Toaster.stories.tsx\",\n rules: [],\n },\n\n // ─── navigation ─────────────────────────────────────────────────────────\n {\n name: \"Tabs\",\n group: \"navigation\",\n tagline: \"Radix tab container. Compose Tabs/TabsList/TabsTrigger/TabsContent. Controlled (value/onValueChange) or uncontrolled (defaultValue).\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled active tab key.\" },\n { name: \"defaultValue\", type: \"string\", description: \"Uncontrolled initial tab key.\" },\n { name: \"onValueChange\", type: \"(value: string) => void\", description: \"Active-tab change handler.\" },\n ],\n example: `import { Tabs, TabsList, TabsTrigger, TabsContent } from \"@godxjp/ui/navigation\";\n\n<Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">概要</TabsTrigger>\n <TabsTrigger value=\"history\">履歴</TabsTrigger>\n </TabsList>\n <TabsContent value=\"overview\">概要コンテンツ</TabsContent>\n <TabsContent value=\"history\">履歴コンテンツ</TabsContent>\n</Tabs>`,\n storyPath: \"navigation/Tabs.stories.tsx\",\n rules: [],\n },\n {\n name: \"FilterBar\",\n group: \"navigation\",\n tagline: \"Standard list-page filter strip. Place ABOVE the table Card — NEVER inside CardContent flush (it strips padding). Compose with FilterGroup + SearchInput + Select.\",\n props: [\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Filter controls + FilterGroup wrappers.\" },\n { name: \"hasActiveFilters\", type: \"boolean\", description: \"Shows a clear-all button when true.\" },\n { name: \"onClear\", type: \"() => void\", description: \"Clear-all handler.\" },\n ],\n example: `import { FilterBar, FilterGroup } from \"@godxjp/ui/navigation\";\nimport { SearchInput, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"@godxjp/ui/data-entry\";\n\n<FilterBar hasActiveFilters={search !== \"\"} onClear={() => setSearch(\"\")}>\n <SearchInput placeholder=\"名前で検索\" value={search} onSearch={setSearch} />\n <FilterGroup label=\"ステータス\">\n <Select value={status} onValueChange={setStatus}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">すべて</SelectItem>\n <SelectItem value=\"active\">有効</SelectItem>\n </SelectContent>\n </Select>\n </FilterGroup>\n</FilterBar>`,\n storyPath: \"navigation/FilterBar.stories.tsx\",\n rules: [38, 40],\n },\n {\n name: \"FilterGroup\",\n group: \"navigation\",\n tagline: \"Labelled filter slot inside FilterBar — wraps a single Select/DatePicker.\",\n props: [\n { name: \"label\", type: \"ReactNode\", required: true, description: \"Label shown with the child control.\" },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"The filter control.\" },\n ],\n example: `import { FilterGroup } from \"@godxjp/ui/navigation\";\n\n<FilterGroup label=\"スコープ\"><Select>{/* ... */}</Select></FilterGroup>`,\n storyPath: \"navigation/FilterBar.stories.tsx\",\n rules: [38],\n },\n {\n name: \"Pagination\",\n group: \"navigation\",\n tagline: \"Offset/page-based pagination bar. Sits below a table card.\",\n props: [\n { name: \"current\", type: \"number\", defaultValue: \"1\", description: \"Current page (1-indexed).\" },\n { name: \"total\", type: \"number\", description: \"Total number of items.\" },\n { name: \"pageSize\", type: \"number\", defaultValue: \"10\", description: \"Items per page.\" },\n { name: \"showTotal\", type: \"boolean | (total, range) => ReactNode\", description: \"Show total count, or a custom label fn.\" },\n { name: \"onChange\", type: \"(page: number, pageSize: number) => void\", description: \"Page / page-size change handler.\" },\n ],\n example: `import { Pagination } from \"@godxjp/ui/navigation\";\n\n<Pagination current={page} total={filtered.length} pageSize={10} showTotal onChange={(p) => setPage(p)} />`,\n storyPath: \"navigation/Pagination.stories.tsx\",\n rules: [40],\n },\n {\n name: \"DropdownMenu\",\n group: \"navigation\",\n tagline: \"Radix dropdown menu. Compose DropdownMenu/DropdownMenuTrigger/DropdownMenuContent/DropdownMenuItem/DropdownMenuSeparator.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n { name: \"onOpenChange\", type: \"(open: boolean) => void\", description: \"Open-state change handler.\" },\n ],\n example: `import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from \"@godxjp/ui/navigation\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<DropdownMenu>\n <DropdownMenuTrigger asChild><Button variant=\"outline\" size=\"sm\">操作</Button></DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem>編集</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem variant=\"destructive\">削除</DropdownMenuItem>\n </DropdownMenuContent>\n</DropdownMenu>`,\n storyPath: \"navigation/DropdownMenu.stories.tsx\",\n rules: [],\n },\n {\n name: \"Steps\",\n group: \"navigation\",\n tagline: \"Multi-step progress indicator — horizontal or vertical, default or dot style.\",\n props: [\n { name: \"items\", type: \"StepItemProp[]\", description: \"Array of { title, subTitle?, description?, icon?, status? }.\" },\n { name: \"current\", type: \"number\", defaultValue: \"0\", description: \"Active step index (0-based).\" },\n { name: \"orientation\", type: '\"horizontal\" | \"vertical\"', defaultValue: '\"horizontal\"', description: \"Layout direction.\" },\n ],\n example: `import { Steps } from \"@godxjp/ui/navigation\";\n\n<Steps current={1} items={[{ title: \"申請\" }, { title: \"審査中\" }, { title: \"完了\" }]} />`,\n storyPath: \"navigation/Steps.stories.tsx\",\n rules: [],\n },\n\n // ─── providers / datetime ───────────────────────────────────────────────\n {\n name: \"AppProvider\",\n group: \"providers\",\n tagline: \"Root locale/timezone/date-time context — wrap the app ONCE. All pickers + formatDate read from it. Import from @godxjp/ui/app.\",\n props: [\n { name: \"defaultLocale\", type: '\"ja\" | \"en\" | \"vi\"', defaultValue: '\"vi\"', description: \"Initial locale.\" },\n { name: \"defaultTimezone\", type: 'string | \"browser\" | \"system\"', defaultValue: '\"browser\"', description: \"Initial IANA timezone.\" },\n { name: \"defaultDateFormat\", type: '\"iso\" | \"dmy\" | \"mdy\" | \"locale\"', defaultValue: '\"locale\"', description: \"Initial date display format.\" },\n { name: \"defaultTimeFormat\", type: '\"24h\" | \"12h\" | \"locale\"', defaultValue: '\"locale\"', description: \"Initial clock format.\" },\n ],\n example: `import { AppProvider } from \"@godxjp/ui/app\";\n\n<AppProvider defaultLocale=\"ja\" defaultTimezone=\"Asia/Tokyo\" defaultDateFormat=\"iso\" defaultTimeFormat=\"24h\">\n {children}\n</AppProvider>`,\n storyPath: \"app/AppProvider.stories.tsx\",\n rules: [5],\n },\n {\n name: \"formatDate\",\n group: \"providers\",\n tagline: \"MANDATORY for all date/time display. Auto-detects ISO date / HH:mm / instant; reads AppProvider context. Import from @godxjp/ui/datetime.\",\n props: [\n { name: \"value\", type: \"string | Date | null | undefined\", required: true, description: \"ISO date, ISO datetime, HH:mm, or Date.\" },\n { name: \"options.kind\", type: '\"auto\" | \"date\" | \"datetime\" | \"time\" | \"long\" | \"relative\"', defaultValue: '\"auto\"', description: \"Output preset; auto infers from the value.\" },\n ],\n example: `import { formatDate } from \"@godxjp/ui/datetime\";\n\nformatDate(coupon.validFrom); // \"2026-05-01\"\nformatDate(order.createdAt, { kind: \"relative\" }); // \"3日前\"`,\n storyPath: \"app/formatDate.stories.tsx\",\n rules: [5],\n },\n];\n\nexport function findComponent(name: string): ComponentEntry | undefined {\n const normalized = name.trim().toLowerCase();\n return COMPONENTS.find((c) => c.name.toLowerCase() === normalized);\n}\n\nexport function componentsByGroup(group: ComponentGroup): ComponentEntry[] {\n return COMPONENTS.filter((c) => c.group === group);\n}\n\nexport function searchComponents(query: string): ComponentEntry[] {\n const q = query.trim().toLowerCase();\n if (q === \"\") {\n return COMPONENTS;\n }\n return COMPONENTS.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.group.includes(q) ||\n c.tagline.toLowerCase().includes(q) ||\n c.props.some((p) => p.name.toLowerCase().includes(q)),\n );\n}\n","/**\n * Shared prop-vocabulary catalog — mirrors `src/props/` in the\n * framework. Consumers reach for this to know the canonical value\n * unions before authoring a new primitive or a wrapper.\n *\n * See also: `docs/specs/04-prop-vocabulary.md` (the rule) +\n * `docs/specs/06-prop-vocabulary-audit.md` (the audit findings).\n */\n\nexport interface PropVocabEntry {\n /** Canonical type name (matches `src/props/{file}.ts`). */\n name: string;\n /** Concept the union represents. */\n concept: string;\n /** Literal values. */\n values: string[];\n /** Primitives that use this exact vocabulary (or alias to it). */\n usedBy: string[];\n /** Optional notes (subtypes, related aliases, gotchas). */\n notes?: string;\n}\n\nexport const PROP_VOCABULARY: PropVocabEntry[] = [\n {\n name: \"SizeProp\",\n concept: \"Dimensional scale for most primitives.\",\n values: [\"small\", \"default\", \"large\"],\n usedBy: [\n \"InputSize\", \"CheckboxGroupSize\", \"ColorPickerSize\", \"MediaUploadSize\",\n \"ProgressSize\", \"RadioGroupSize\", \"RateSize\", \"TransferSize\",\n \"SegmentedControlSize (subset)\", \"SpaceSize (+ number)\",\n \"FlexGap (+ number)\", \"GridGap (+ number)\", \"MasonryGap (+ number)\",\n ],\n },\n {\n name: \"SizeWithXSProp\",\n concept: 'Extension of `SizeProp` with `\"x-small\"` for compact icon-bar / table-row contexts.',\n values: [\"x-small\", \"small\", \"default\", \"large\"],\n usedBy: [\"ButtonSize\"],\n },\n {\n name: \"IconSizeProp\",\n concept: \"Icon-symbol shaped primitives (visual axis = glyph size, not height).\",\n values: [\"sm\", \"md\", \"lg\"],\n usedBy: [\"SpinnerSize\", \"IconButtonSize\"],\n },\n {\n name: \"StatusProp\",\n concept: \"Form-field validation state.\",\n values: [\"default\", \"error\", \"warning\", \"success\"],\n usedBy: [\"InputStatus\"],\n notes: 'Form errors use `\"error\"` (not `\"destructive\"`) — different concern from destructive actions.',\n },\n {\n name: \"ToneProp\",\n concept: \"Same values as StatusProp — name chosen when describing surface colouring rather than validation.\",\n values: [\"default\", \"error\", \"warning\", \"success\"],\n usedBy: [\"(alias of StatusProp)\"],\n },\n {\n name: \"HelpToneProp\",\n concept: \"Help-line / Alert colour ladder. Adds `info` + `warn` to StatusProp.\",\n values: [\"default\", \"info\", \"warn\", \"error\", \"success\"],\n usedBy: [\"FieldHelpTone\"],\n },\n {\n name: \"OrientationProp\",\n concept: \"Layout axis.\",\n values: [\"horizontal\", \"vertical\"],\n usedBy: [\n \"AnchorOrientation\", \"MenuOrientation\", \"RadioGroupOrientation\",\n \"CheckboxGroupOrientation\", \"SegmentedControlOrientation\",\n \"StepsOrientation\", \"TabsOrientation\",\n ],\n },\n {\n name: \"DensityProp\",\n concept: \"Internal row-height / padding scale (distinct from SizeProp — density rescales chrome, size rescales the primitive's own visual axis).\",\n values: [\"compact\", \"default\", \"comfortable\"],\n usedBy: [\"TreeDensity\", \"TableDensity\"],\n },\n {\n name: \"SideProp\",\n concept: \"Edge a floating panel docks against.\",\n values: [\"top\", \"right\", \"bottom\", \"left\"],\n usedBy: [\"SheetSide\", \"TabsPlacement\", \"TableStickySide (subset)\"],\n },\n {\n name: \"PlacementProp\",\n concept: \"Extension of SideProp with a centred anchor (Tabs placement, Tour spotlight).\",\n values: [\"top\", \"right\", \"bottom\", \"left\", \"center\"],\n usedBy: [\"TourPlacement\"],\n },\n {\n name: \"PaddingProp\",\n concept: \"Outer gutter scale for surface containers.\",\n values: [\"tight\", \"default\", \"cozy\", \"none\"],\n usedBy: [\"CardPadding\", \"PageHeaderPadding\", \"PageContentPadding\"],\n },\n {\n name: \"AlignProp\",\n concept: \"CSS-flexbox cross-axis alignment ladder.\",\n values: [\"start\", \"end\", \"center\", \"stretch\", \"baseline\"],\n usedBy: [\"FlexAlign\"],\n },\n {\n name: \"ColorProp\",\n concept: \"Full semantic palette — every CSS variable slot.\",\n values: [\"default\", \"info\", \"success\", \"warning\", \"destructive\", \"attention\", \"primary\", \"secondary\"],\n usedBy: [\"TagPresetColor (− secondary)\", \"TimelineColor (− secondary)\", \"SpinnerTone (+ muted)\"],\n notes:\n 'Each value maps 1:1 to a CSS variable (`--info`, `--success`, `--warning`, `--destructive`, `--attention`, `--primary`, `--secondary`). The `data-accent` axis rebinds `--primary`\\'s hue without renaming the slot.',\n },\n {\n name: \"FeedbackColorProp\",\n concept: \"Subset of ColorProp accepted by feedback primitives (no brand `primary` since they are themselves informational).\",\n values: [\"default\", \"info\", \"success\", \"warning\", \"destructive\"],\n usedBy: [\"AlertColor\", \"ResultColor\", \"ProgressColor\"],\n },\n {\n name: \"LoadingProp\",\n concept: \"Loading-state union — shared across Form / FormField / data-entry primitives.\",\n values: [\"true\", \"false\", '{ kind: \"spinner\" }', '{ kind: \"skeleton\" }', '{ kind, label }'],\n usedBy: [\"FormProps.loading\", \"FormFieldProps.loading\"],\n notes:\n 'Cascade: `<Form loading>` sets a default for every nested `<FormField>`. Per-field `loading` overrides Form\\'s. `true` → spinner (default). `{ kind: \"skeleton\" }` → use for INITIAL fetch state. UX nuance: skeleton on init, spinner on save.',\n },\n];\n\nexport function findVocab(name: string): PropVocabEntry | undefined {\n const normalized = name.trim().toLowerCase().replace(/prop$/i, \"\");\n return PROP_VOCABULARY.find(\n (v) => v.name.toLowerCase().replace(/prop$/i, \"\") === normalized,\n );\n}\n","/**\n * Design tokens catalog — mirrors `src/tokens/tailwind.css` +\n * `src/styles/theme.css` in the framework. CSS variable name +\n * the slot's role + (for fixed values) the literal value.\n *\n * Token values that change per `data-theme` / `data-accent` /\n * `data-density` / `data-font-size` axis are NOT listed with a\n * literal — only the slot name + axis name. Consumers read the\n * runtime value via `getComputedStyle(:root).getPropertyValue(...)`.\n */\n\nexport type TokenCategory =\n | \"color\"\n | \"spacing\"\n | \"typography\"\n | \"radius\"\n | \"shadow\"\n | \"motion\"\n | \"breakpoint\"\n | \"density\"\n | \"z-index\";\n\nexport interface TokenEntry {\n name: string;\n category: TokenCategory;\n role: string;\n /** Fixed value if non-axis. Otherwise omitted. */\n value?: string;\n /** Axis the token re-binds against, if any. */\n axis?: \"data-theme\" | \"data-accent\" | \"data-density\" | \"data-font-size\";\n}\n\nexport const TOKENS: TokenEntry[] = [\n // Color — semantic slots (rebound by `data-theme` + `data-accent`)\n { name: \"--background\", category: \"color\", role: \"Base surface\", axis: \"data-theme\" },\n { name: \"--foreground\", category: \"color\", role: \"Base text\", axis: \"data-theme\" },\n { name: \"--card\", category: \"color\", role: \"Card surface\", axis: \"data-theme\" },\n { name: \"--popover\", category: \"color\", role: \"Popover / dropdown surface\", axis: \"data-theme\" },\n { name: \"--popover-foreground\", category: \"color\", role: \"Popover text\", axis: \"data-theme\" },\n { name: \"--primary\", category: \"color\", role: \"Brand accent (Buttons, links)\", axis: \"data-accent\" },\n { name: \"--primary-foreground\", category: \"color\", role: \"Text on primary surface\", axis: \"data-accent\" },\n { name: \"--secondary\", category: \"color\", role: \"Secondary surface / text dimming\", axis: \"data-theme\" },\n { name: \"--accent\", category: \"color\", role: \"Hover / focus tint\" },\n { name: \"--muted\", category: \"color\", role: \"Muted surface\" },\n { name: \"--muted-foreground\", category: \"color\", role: \"Muted text\" },\n { name: \"--border\", category: \"color\", role: \"Default border color\", axis: \"data-theme\" },\n { name: \"--input\", category: \"color\", role: \"Input field border\" },\n { name: \"--ring\", category: \"color\", role: \"Focus ring\", axis: \"data-accent\" },\n { name: \"--success\", category: \"color\", role: \"Success semantic slot\" },\n { name: \"--warning\", category: \"color\", role: \"Warning semantic slot\" },\n { name: \"--destructive\", category: \"color\", role: \"Danger / destructive action slot\" },\n { name: \"--info\", category: \"color\", role: \"Info / neutral notice slot\" },\n { name: \"--attention\", category: \"color\", role: \"Attention / non-destructive alert slot\" },\n\n // Spacing — fixed scale\n { name: \"--spacing-1\", category: \"spacing\", role: \"4px\", value: \"0.25rem\" },\n { name: \"--spacing-2\", category: \"spacing\", role: \"8px\", value: \"0.5rem\" },\n { name: \"--spacing-3\", category: \"spacing\", role: \"12px\", value: \"0.75rem\" },\n { name: \"--spacing-4\", category: \"spacing\", role: \"16px\", value: \"1rem\" },\n { name: \"--spacing-5\", category: \"spacing\", role: \"20px\", value: \"1.25rem\" },\n { name: \"--spacing-6\", category: \"spacing\", role: \"24px\", value: \"1.5rem\" },\n { name: \"--spacing-8\", category: \"spacing\", role: \"32px\", value: \"2rem\" },\n\n // Typography — fixed scale\n { name: \"--text-2xs\", category: \"typography\", role: \"10px\", value: \"0.625rem\" },\n { name: \"--text-xs\", category: \"typography\", role: \"12px\", value: \"0.75rem\" },\n { name: \"--text-sm\", category: \"typography\", role: \"14px\", value: \"0.875rem\" },\n { name: \"--text-base\", category: \"typography\", role: \"16px\", value: \"1rem\" },\n { name: \"--text-lg\", category: \"typography\", role: \"18px\", value: \"1.125rem\" },\n { name: \"--text-xl\", category: \"typography\", role: \"20px\", value: \"1.25rem\" },\n { name: \"--text-2xl\", category: \"typography\", role: \"24px\", value: \"1.5rem\" },\n { name: \"--font-mono\", category: \"typography\", role: \"Monospace stack\" },\n\n // Radius — fixed scale\n { name: \"--radius-sm\", category: \"radius\", role: \"Small (chips, inputs)\", value: \"0.25rem\" },\n { name: \"--radius-md\", category: \"radius\", role: \"Medium (cards)\", value: \"0.5rem\" },\n { name: \"--radius-lg\", category: \"radius\", role: \"Large (dialogs)\", value: \"0.75rem\" },\n { name: \"--radius-full\", category: \"radius\", role: \"Pill / circle\", value: \"9999px\" },\n\n // Breakpoints — mobile-first min-widths\n { name: \"--breakpoint-xs\", category: \"breakpoint\", role: \"Mobile-first base (≥0px)\", value: \"0\" },\n { name: \"--breakpoint-sm\", category: \"breakpoint\", role: \"Phone landscape / tablet portrait\", value: \"640px\" },\n { name: \"--breakpoint-md\", category: \"breakpoint\", role: \"Tablet landscape\", value: \"768px\" },\n { name: \"--breakpoint-lg\", category: \"breakpoint\", role: \"Laptop\", value: \"1024px\" },\n { name: \"--breakpoint-xl\", category: \"breakpoint\", role: \"Desktop\", value: \"1280px\" },\n { name: \"--breakpoint-xxl\", category: \"breakpoint\", role: \"Wide desktop\", value: \"1536px\" },\n\n // Density — rebound by `data-density`\n { name: \"--density-element\", category: \"density\", role: \"Element height (Input/Button)\", axis: \"data-density\" },\n { name: \"--density-element-sm\", category: \"density\", role: \"Small element\", axis: \"data-density\" },\n { name: \"--density-element-lg\", category: \"density\", role: \"Large element\", axis: \"data-density\" },\n { name: \"--density-card\", category: \"density\", role: \"Card padding\", axis: \"data-density\" },\n { name: \"--density-page\", category: \"density\", role: \"Page (PageContent) padding\", axis: \"data-density\" },\n { name: \"--density-section\", category: \"density\", role: \"Section padding (cozy variant)\", axis: \"data-density\" },\n { name: \"--header-height\", category: \"density\", role: \"Topbar height\", axis: \"data-density\" },\n { name: \"--sidebar-width\", category: \"density\", role: \"Sidebar width (expanded)\", axis: \"data-density\" },\n { name: \"--sidebar-width-collapsed\", category: \"density\", role: \"Sidebar icon-only width\", axis: \"data-density\" },\n { name: \"--touch-target-min\", category: \"density\", role: \"Mobile touch target (does NOT scale)\", value: \"44px\" },\n\n // Motion — fixed timings\n { name: \"--transition-base\", category: \"motion\", role: \"Standard transition duration\", value: \"200ms\" },\n { name: \"--ease-out\", category: \"motion\", role: \"Out easing curve\", value: \"cubic-bezier(0, 0, 0.2, 1)\" },\n { name: \"--ease-in-out\", category: \"motion\", role: \"In-out easing\", value: \"cubic-bezier(0.4, 0, 0.2, 1)\" },\n];\n\nexport function tokensByCategory(category: TokenCategory): TokenEntry[] {\n return TOKENS.filter((t) => t.category === category);\n}\n","/**\n * Cardinal rules — mirrors the cardinal rules in `CLAUDE.md`. The MCP\n * server exposes them via `get_cardinal_rules` so consumer agents\n * can quote them when reviewing PRs or authoring new primitives.\n */\n\nexport interface CardinalRule {\n number: number;\n title: string;\n body: string;\n}\n\nexport const CARDINAL_RULES: CardinalRule[] = [\n { number: 1, title: \"Storybook is mandatory\", body: \"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark.\" },\n { number: 2, title: \"Tokens, not utilities\", 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. (ADR-0003)\" },\n { number: 3, title: \"Radix for interactive primitives\", body: \"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)\" },\n { number: 4, title: \"shadcn-style ownership\", body: \"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)\" },\n { number: 5, title: \"One i18next singleton\", body: \"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)\" },\n { number: 6, title: \"WCAG 2.1 AA baseline\", 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.\" },\n { number: 7, title: \"SemVer 2.0 + Keep a Changelog 1.1\", body: \"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR.\" },\n { number: 8, title: \"Inclusive naming\", body: \"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced.\" },\n { number: 9, title: \"No marketing speak\", body: 'Banned: \"powerful\", \"robust\", \"blazing fast\", \"best-in-class\", \"seamless\", \"enterprise-grade\". State what it does.' },\n { number: 10, title: \"English is canonical for docs\", body: \"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness.\" },\n { number: 11, title: \"Submodule discipline\", body: \"Two-PR workflow: (1) submodule PR → `main`, (2) umbrella PR → bump pin. Never push a pin to a SHA not on the submodule remote.\" },\n { number: 12, title: \"Branch + PR workflow\", body: \"`feat/<scope>` / `fix/<scope>` → submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden.\" },\n { number: 13, title: \"TypeScript strict\", body: \"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link.\" },\n { number: 14, title: \"Every third-party library is shadcn / Radix-recommended\", 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.\" },\n { number: 15, title: \"No `@apply` re-encoding tokens\", 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.\" },\n { number: 16, title: \"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`\", body: \"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it.\" },\n { number: 17, title: \"`src/stories/` ↔ `src/components/` parity\", body: \"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`.\" },\n { number: 18, title: \"`docs/reference/<group>/` ↔ `src/components/<group>/` parity\", body: \"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`.\" },\n { number: 19, title: \"No service-specific anything\", body: \"`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent=\\\"<palette>\\\"]`.\" },\n { number: 20, title: \"No \\\"platform-only\\\" exports\", body: \"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported.\" },\n { number: 21, title: \"Every component honours every theme axis\", 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. Verify every PR via the Storybook toolbar sweep.\" },\n { number: 22, title: \"100% match to the design canon\", 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.' },\n { number: 23, title: \"Concept-first prop API\", 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.\" },\n { number: 24, title: \"Mobile-first\", 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.\" },\n { number: 25, title: \"Stories are docs; UI is the primitive\", 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.\" },\n { number: 26, title: \"Library isolation\", 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/`.\" },\n { number: 27, title: \"Per-group folder structure\", 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.\" },\n { number: 28, title: \"`src/` folder taxonomy\", 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.\" },\n { number: 29, title: \"Stories consume framework primitives only\", 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.\" },\n { number: 30, title: \"Story `render` returns JSX directly\", 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 />`.\" },\n { number: 31, title: \"No nested wrapper / convenience primitives\", 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.\" },\n { number: 32, title: \"No redundant props\", 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.\" },\n { number: 33, title: \"Stories / source / docs name-synchronized\", 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). Rename PR runs `grep -rn '<oldName>' src docs` and clears it.\" },\n { number: 34, title: \"Storybook source panel = real, copy-paste-ready code\", 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 (`StatusBadge`, `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>`). The exemplar is `Table.Default` in `src/stories/data-display/Table.stories.tsx`.\" },\n { number: 35, title: \"Status chips never wrap\", body: \"A `StatusBadge` / `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.\" },\n { number: 36, title: \"StatusBadge tone/icon are the colour escape hatch\", body: \"`StatusBadge` auto-maps a fixed set of English lifecycle keys (active, draft, pending, scheduled, cancelled, failed, …) to tone + icon. 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.\" },\n { number: 37, title: \"DataTable is full-width — never inside a narrow grid column\", 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.)\" },\n { number: 38, title: \"FilterBar stays OUT of CardContent flush\", 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.\" },\n { number: 39, title: \"Long text columns get an explicit width\", 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.\" },\n { number: 40, title: \"Pages are mobile-first\", body: \"Author and verify every page at 320–390px FIRST. Spacing comes only from `Stack` / `Inline` `gap` + `ResponsiveGrid columns={2|3|4}` (which collapse to a single column on narrow screens) — never raw `p-*` / `gap-*` / `space-*` utilities for page layout. Wide tables scroll horizontally on small screens (don't force-fit them); dialogs and sheets are full-height on mobile. Touch targets ≥ 44×44px.\" },\n];\n\nexport function findRule(num: number): CardinalRule | undefined {\n return CARDINAL_RULES.find((r) => r.number === num);\n}\n","/**\n * Canonical code patterns for common consumer scenarios. The MCP\n * server returns one of these whenever a consumer asks \"how do I X\n * with @godxjp/ui?\" — saves the LLM from synthesising from primitive\n * docs over and over.\n *\n * Every pattern is copy-paste-ready: imports listed at top, types\n * spelled out, inline JSX with no opaque helpers.\n */\n\nexport interface PatternEntry {\n /** URL-safe slug. */\n name: string;\n /** One-line elevator pitch. */\n tagline: string;\n /** Categories — used for search. */\n tags: string[];\n /** Full snippet. */\n code: string;\n}\n\nexport const PATTERNS: PatternEntry[] = [\n {\n name: \"common-fixes\",\n tagline: \"Fix the most common @godxjp/ui consumer mistakes & visual bugs (CardStat double-border, grey StatusBadge, crushed/empty table headers, washed-out sidebar footer, Inertia layout crash, SSR hydration). Before → after.\",\n tags: [\"fixes\", \"migration\", \"bug\", \"cardstat\", \"statusbadge\", \"datatable\", \"sidebar\", \"gotcha\", \"review\"],\n code: `// ───────────────────────────────────────────────────────────────────────\n// 1) CardStat shows a DOUBLE border (too thick)\n// Cause: CardStat IS already a bordered Card. Don't wrap it.\n// ❌ <Card><CardContent><CardStat label=\"x\" value=\"1\" /></CardContent></Card>\n// ✅ <ResponsiveGrid columns={4}><CardStat label=\"x\" value=\"1\" /></ResponsiveGrid>\n// Need a section title? Use a heading, NOT a Card:\n// ✅ <Stack gap=\"sm\"><div className=\"text-sm font-medium\">KPI</div>\n// <ResponsiveGrid columns={4}><CardStat .../></ResponsiveGrid></Stack>\n\n// 2) StatusBadge renders grey with a ○ (no colour) for localized/tier labels\n// Cause: it auto-maps only English lifecycle keys. (@godxjp/ui >= 6.1)\n// ❌ <StatusBadge status=\"プレミアム\" />\n// ✅ <StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} /> // tier → pill, no icon\n// ✅ <StatusBadge status=\"active\" label=\"公開中\" /> // lifecycle → keep icon\n\n// 3) Table text collapses to one char per line, or a chip wraps\n// Cause: pre-6.1.2. (@godxjp/ui >= 6.1.2 → cells + chips are nowrap)\n// ✅ npm i @godxjp/ui@^6.2.0\n// ✅ give long columns a width: { key: \"name\", header: \"氏名\", width: \"w-64\" }\n\n// 4) Empty (icon/action) column header shows a blank grey block\n// (@godxjp/ui >= 6.2.0 auto-hides it: [data-slot=table-head][data-empty] → transparent)\n// ✅ npm i @godxjp/ui@^6.2.0 // header: \"\" now renders a transparent cell\n\n// 5) DataTable columns are crushed / squeezed\n// Cause: the table is nested in a narrow grid column.\n// ❌ <ResponsiveGrid columns={3}><div className=\"lg:col-span-2\"><Card><DataTable/></Card></div></ResponsiveGrid>\n// ✅ Table gets its OWN full-width row: <Card><CardContent flush><DataTable/></CardContent></Card>\n\n// 6) FilterBar has no padding (sticks to the edge)\n// Cause: it's inside CardContent flush (flush strips padding — that's for tables).\n// ❌ <Card><CardContent flush><FilterBar/><DataTable/></CardContent></Card>\n// ✅ <FilterBar/> then <Card><CardContent flush><DataTable/></CardContent></Card>\n\n// 7) Sidebar footer looks washed-out / off-design\n// Cause: raw opacity-*/text-[11px]. Use semantic tokens.\n// ✅ <div className=\"text-muted-foreground text-xs\">\n// <div className=\"text-foreground font-medium\">{name}</div><div>{role}</div></div>\n\n// 8) Inertia: \"Objects are not valid as a React child {errors, auth, …}\"\n// Cause: persistent layout passed as a render fn. Use the ARRAY form.\n// ❌ Page.layout = (page) => <Layout>{page}</Layout>\n// ✅ Page.layout = [Layout] // Layout is ({children}) => ...\n\n// 9) Inertia v3 hydration mismatch (\"server rendered text didn't match the client\")\n// Cause: Math.random()/argless new Date() during render (SSR ≠ client).\n// ✅ seed deterministically by index, or compute in an event handler.\n\n// 10) Hide a column on mobile / sign-aware KPI delta (@godxjp/ui >= 6.2.0)\n// ✅ columns: [{ key: \"email\", header: \"メール\", hiddenOnMobile: true }]\n// ✅ <CardStat label=\"売上\" value=\"¥8.2M\" delta=\"+12%\" /> // + green / - red; inverse flips`,\n },\n\n {\n name: \"signup-form\",\n tagline: \"Card-wrapped sign-up form using react-hook-form + zod with FormField/Input and a CardFooter action bar (real @godxjp/ui API).\",\n tags: [\"form\", \"auth\", \"sign-up\", \"zod\", \"validation\", \"react-hook-form\"],\n code: `import { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { z } from \"zod\";\nimport { Card, CardHeader, CardTitle, CardContent, CardFooter } from \"@godxjp/ui/data-display\";\nimport { FormField, Input } from \"@godxjp/ui/data-entry\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { Stack } from \"@godxjp/ui/layout\";\n\nconst schema = z.object({\n name: z.string().min(1, \"氏名は必須です\"),\n email: z.string().email(\"有効なメールアドレスを入力してください\"),\n});\ntype Values = z.infer<typeof schema>;\n\nexport function SignUpCard() {\n const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<Values>({ resolver: zodResolver(schema) });\n const onSubmit = handleSubmit(async (v) => {\n await fetch(\"/api/signup\", { method: \"POST\", body: JSON.stringify(v) });\n });\n return (\n <Card>\n <CardHeader><CardTitle>アカウント作成</CardTitle></CardHeader>\n <CardContent>\n <form id=\"signup\" onSubmit={onSubmit}>\n <Stack gap=\"md\">\n <FormField id=\"name\" label=\"氏名\" required error={errors.name?.message}>\n <Input id=\"name\" {...register(\"name\")} />\n </FormField>\n <FormField id=\"email\" label=\"メールアドレス\" required error={errors.email?.message}>\n <Input id=\"email\" type=\"email\" {...register(\"email\")} />\n </FormField>\n </Stack>\n </form>\n </CardContent>\n <CardFooter separated>\n <Button type=\"submit\" form=\"signup\" disabled={isSubmitting}>アカウントを作成</Button>\n </CardFooter>\n </Card>\n );\n}`,\n },\n\n {\n name: \"settings-tabs\",\n tagline: \"Sectioned settings inside a Card with Tabs + FormField + Select + Switch (real @godxjp/ui API).\",\n tags: [\"settings\", \"form\", \"tabs\", \"admin\"],\n code: `import { Card, CardContent } from \"@godxjp/ui/data-display\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@godxjp/ui/navigation\";\nimport { FormField, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch, Label } from \"@godxjp/ui/data-entry\";\nimport { Stack } from \"@godxjp/ui/layout\";\n\nexport function WorkspaceSettings() {\n return (\n <Card>\n <CardContent>\n <Tabs defaultValue=\"general\">\n <TabsList>\n <TabsTrigger value=\"general\">基本情報</TabsTrigger>\n <TabsTrigger value=\"notify\">通知</TabsTrigger>\n </TabsList>\n <TabsContent value=\"general\">\n <Stack gap=\"md\">\n <FormField id=\"ws-name\" label=\"名前\" required><Input id=\"ws-name\" /></FormField>\n <FormField id=\"visibility\" label=\"公開範囲\">\n <Select defaultValue=\"internal\">\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"private\">プライベート</SelectItem>\n <SelectItem value=\"internal\">社内公開</SelectItem>\n <SelectItem value=\"public\">公開</SelectItem>\n </SelectContent>\n </Select>\n </FormField>\n </Stack>\n </TabsContent>\n <TabsContent value=\"notify\">\n <div className=\"flex items-center gap-2\">\n <Switch id=\"notify-comment\" defaultChecked />\n <Label htmlFor=\"notify-comment\">コメント通知を受け取る</Label>\n </div>\n </TabsContent>\n </Tabs>\n </CardContent>\n </Card>\n );\n}`,\n },\n\n {\n name: \"confirm-destructive\",\n tagline: \"Type-to-confirm destructive dialog — Dialog mode=\\\"confirm\\\" + Input gate + toast (real @godxjp/ui API).\",\n tags: [\"dialog\", \"confirm\", \"destructive\", \"delete\"],\n code: `import { useState } from \"react\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from \"@godxjp/ui/feedback\";\nimport { Input } from \"@godxjp/ui/data-entry\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { Stack } from \"@godxjp/ui/layout\";\nimport { toast } from \"sonner\";\n\nexport function DeleteProjectDialog({ open, onOpenChange, slug }: { open: boolean; onOpenChange: (v: boolean) => void; slug: string }) {\n const [confirm, setConfirm] = useState(\"\");\n return (\n <Dialog open={open} onOpenChange={onOpenChange} mode=\"confirm\">\n <DialogContent>\n <DialogHeader>\n <DialogTitle>プロジェクトを削除</DialogTitle>\n <DialogDescription>この操作は取り消せません。確認のためプロジェクト名 \"{slug}\" と入力してください。</DialogDescription>\n </DialogHeader>\n <Stack gap=\"md\">\n <Input value={confirm} onChange={(e) => setConfirm(e.target.value)} placeholder={slug} />\n </Stack>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>キャンセル</Button>\n <Button variant=\"destructive\" disabled={confirm !== slug} onClick={() => { toast.success(\"削除しました\"); onOpenChange(false); }}>完全に削除</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}`,\n },\n\n {\n name: \"deferred-loading\",\n tagline: \"Inertia deferred props with a Skeleton fallback — SkeletonTable while data loads, then DataTable (real @godxjp/ui API).\",\n tags: [\"loading\", \"skeleton\", \"deferred\", \"inertia\", \"table\"],\n code: `// Server (Laravel): defer the heavy prop\n// Inertia::render('crm/coupons/index', [\n// 'coupons' => Inertia::defer(fn () => Coupon::all()),\n// ]);\nimport { Card, CardContent, DataTable } from \"@godxjp/ui/data-display\";\nimport type { ColumnDef } from \"@godxjp/ui/data-display\";\nimport { SkeletonTable } from \"@godxjp/ui/feedback\";\n\ntype Coupon = { id: string; name: string };\nconst columns: ColumnDef<Coupon>[] = [{ key: \"name\", header: \"クーポン名\" }];\n\n// coupons is undefined until the deferred request resolves\nexport default function Coupons({ coupons }: { coupons?: Coupon[] }) {\n return (\n <Card>\n <CardContent flush>\n {!coupons\n ? <SkeletonTable rows={10} columns={6} />\n : <DataTable data={coupons} columns={columns} getRowId={(c) => c.id} />}\n </CardContent>\n </Card>\n );\n}`,\n },\n\n {\n name: \"inertia-list-page\",\n tagline: \"Inertia + @godxjp/ui list page — PageContainer + FilterBar + DataTable + StatusBadge + Pagination (current primitive API).\",\n tags: [\"inertia\", \"list\", \"table\", \"page\", \"filter\", \"pagination\", \"datatable\", \"crm\"],\n code: `import { Head, router } from \"@inertiajs/react\"\nimport { useMemo, useState } from \"react\"\nimport { PageContainer, ResponsiveGrid, Stack } from \"@godxjp/ui/layout\"\nimport { Card, CardContent, CardStat, DataTable, EmptyState, StatusBadge, type ColumnDef } from \"@godxjp/ui/data-display\"\nimport { SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@godxjp/ui/data-entry\"\nimport { FilterBar, FilterGroup, Pagination } from \"@godxjp/ui/navigation\"\nimport { formatDate } from \"@godxjp/ui/datetime\"\nimport { withCrmLayout } from \"@/layouts/crm-layout\" // see \"inertia-persistent-layout\"\n\ntype Coupon = { id: string; name: string; status: string; scope: string; validFrom: string; validTo: string; usage: number }\nconst PAGE_SIZE = 10\n\nfunction Coupons({ coupons }: { coupons: Coupon[] }) {\n const [q, setQ] = useState(\"\")\n const [status, setStatus] = useState(\"all\")\n const [page, setPage] = useState(1)\n\n const filtered = useMemo(() => coupons.filter((c) => {\n if (q && !c.name.toLowerCase().includes(q.toLowerCase())) return false\n if (status !== \"all\" && c.status !== status) return false\n return true\n }), [coupons, q, status])\n const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE)\n\n // ColumnDef = { key, header, render?, align?: \"left\"|\"center\"|\"right\", sortable?, width? }\n const columns: ColumnDef<Coupon>[] = [\n { key: \"name\", header: \"クーポン名\", render: (c) => <span className=\"font-medium\">{c.name}</span> },\n { key: \"scope\", header: \"スコープ\", render: (c) => <StatusBadge status={c.scope} tone=\"info\" icon={null} /> },\n { key: \"status\", header: \"ステータス\", render: (c) => <StatusBadge status={c.status} /> },\n { key: \"valid\", header: \"有効期間\", render: (c) => \\`\\${formatDate(c.validFrom)} 〜 \\${formatDate(c.validTo)}\\` },\n { key: \"usage\", header: \"利用数\", align: \"right\", render: (c) => c.usage.toLocaleString() },\n ]\n\n return (\n <>\n <Head title=\"クーポン管理\" />\n {/* RULE: every page wraps in PageContainer; spacing via Stack/ResponsiveGrid, never p-*/gap-* */}\n <PageContainer title=\"クーポン管理\" subtitle=\"配信中のクーポン一覧\">\n <Stack gap=\"lg\">\n <ResponsiveGrid columns={3}>\n <CardStat label=\"公開中\" value={coupons.filter((c) => c.status === \"公開中\").length} />\n <CardStat label=\"総利用数\" value={coupons.reduce((s, c) => s + c.usage, 0).toLocaleString()} />\n <CardStat label=\"件数\" value={coupons.length} />\n </ResponsiveGrid>\n\n <FilterBar hasActiveFilters={q !== \"\" || status !== \"all\"} onClear={() => { setQ(\"\"); setStatus(\"all\"); setPage(1) }}>\n {/* SearchInput is value + onSearch(v) — NOT onChange */}\n <SearchInput placeholder=\"クーポン名で検索\" value={q} onSearch={(v) => { setQ(v); setPage(1) }} />\n <FilterGroup label=\"ステータス\">\n <Select value={status} onValueChange={(v) => { setStatus(v); setPage(1) }}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">全ステータス</SelectItem>\n <SelectItem value=\"公開中\">公開中</SelectItem>\n <SelectItem value=\"下書き\">下書き</SelectItem>\n </SelectContent>\n </Select>\n </FilterGroup>\n </FilterBar>\n\n <Card>\n <CardContent flush>\n {filtered.length === 0\n ? <EmptyState title=\"該当するクーポンがありません\" description=\"検索条件を変更してください。\" />\n : <DataTable data={paged} columns={columns} getRowId={(c) => c.id} onRowClick={(c) => router.visit(\\`/coupons/\\${c.id}\\`)} />}\n </CardContent>\n </Card>\n\n {filtered.length > PAGE_SIZE && (\n <Pagination current={page} total={filtered.length} pageSize={PAGE_SIZE} showTotal onChange={(p) => setPage(p)} />\n )}\n </Stack>\n </PageContainer>\n </>\n )\n}\n\nCoupons.layout = withCrmLayout\nexport default Coupons`,\n },\n\n {\n name: \"inertia-detail-page\",\n tagline: \"Inertia detail page — receives {id} prop, KeyValueGrid (compound) + CardStat + EmptyState fallback.\",\n tags: [\"inertia\", \"detail\", \"show\", \"page\", \"keyvaluegrid\", \"crm\"],\n code: `import { Head, router } from \"@inertiajs/react\"\nimport { PageContainer, ResponsiveGrid, Stack } from \"@godxjp/ui/layout\"\nimport { Card, CardContent, CardStat, EmptyState, KeyValueGrid, StatusBadge } from \"@godxjp/ui/data-display\"\nimport { Button } from \"@godxjp/ui/general\"\nimport { formatDate } from \"@godxjp/ui/datetime\"\nimport { ArrowLeft } from \"lucide-react\"\nimport { withCrmLayout } from \"@/layouts/crm-layout\"\n\n// Detail routes pass the param as an Inertia prop:\n// Route::get('/members/{id}', fn ($id) => Inertia::render('crm/members/show', ['id' => $id]))\nfunction MemberShow({ id }: { id: string }) {\n const member = MEMBERS.find((m) => m.id === id)\n\n if (!member) {\n return (\n <>\n <Head title=\"会員詳細\" />\n <PageContainer title=\"会員詳細\" subtitle=\"会員が見つかりません\">\n <EmptyState title=\"会員が見つかりません\" description={\\`ID「\\${id}」は存在しません。\\`} />\n <Button variant=\"outline\" onClick={() => router.visit(\"/members\")}><ArrowLeft className=\"size-4\" />一覧へ戻る</Button>\n </PageContainer>\n </>\n )\n }\n\n return (\n <>\n <Head title={member.name} />\n <PageContainer title={member.name} subtitle={\\`\\${member.id} / \\${member.rank}\\`}>\n <Stack gap=\"lg\">\n <ResponsiveGrid columns={4}>\n <CardStat label=\"累計購入額\" value={\\`¥\\${member.total.toLocaleString()}\\`} />\n <CardStat label=\"来店回数\" value={member.visits} />\n <CardStat label=\"ポイント\" value={member.points.toLocaleString()} />\n <CardStat label=\"LTV\" value={\\`¥\\${member.ltv.toLocaleString()}\\`} />\n </ResponsiveGrid>\n <Card>\n <CardContent>\n {/* KeyValueGrid is COMPOUND — value goes in children, not a prop */}\n <KeyValueGrid columns={2}>\n <KeyValueGrid.Item label=\"氏名\">{member.name}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"ランク\"><StatusBadge status={member.rank} tone=\"info\" icon={null} /></KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"ステータス\"><StatusBadge status={member.status} /></KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"登録日\">{formatDate(member.registeredAt)}</KeyValueGrid.Item>\n </KeyValueGrid>\n </CardContent>\n </Card>\n </Stack>\n </PageContainer>\n </>\n )\n}\n\nMemberShow.layout = withCrmLayout\nexport default MemberShow`,\n },\n\n {\n name: \"inertia-persistent-layout\",\n tagline: \"Inertia persistent layout (AppShell+Sidebar) — the array-form gotcha + the SSR/Math.random gotcha.\",\n tags: [\"inertia\", \"layout\", \"appshell\", \"sidebar\", \"ssr\", \"hydration\", \"gotcha\"],\n code: `// resources/js/layouts/crm-layout.tsx\nimport { router, usePage } from \"@inertiajs/react\"\nimport { AppShell, Sidebar } from \"@godxjp/ui/layout\"\nimport { LayoutDashboard } from \"lucide-react\"\nimport type { ReactNode } from \"react\"\n\nexport function CrmLayout({ children }: { children: ReactNode }) {\n const { url } = usePage()\n const sections = [{ label: \"メイン\", items: [{ id: \"/dashboard\", label: \"ダッシュボード\", icon: LayoutDashboard }] }]\n return (\n <AppShell sidebar={<Sidebar activeId={url} onSelect={(id) => router.visit(id)} sections={sections} product={{ name: \"JOVY CRM\" }} />}>\n {children}\n </AppShell>\n )\n}\n\n// ⚠️ GOTCHA 1 — persistent layout MUST be the ARRAY form.\n// A render fn \\`(page) => <CrmLayout>{page}</CrmLayout>\\` is indistinguishable from a\n// component; Inertia React calls it with the page-PROPS object and renders that\n// object as a child → \"Objects are not valid as a React child {errors, auth, …}\".\nexport const withCrmLayout = [CrmLayout] // ✅ array → Inertia passes the page as children\n// page usage: Dashboard.layout = withCrmLayout\n\n// ⚠️ GOTCHA 2 — Inertia v3 SSRs even in \\`npm run dev\\`. NEVER call Math.random() or\n// argless new Date() during render (e.g. fabricating chart/demo numbers) → React\n// hydration mismatch (\"server rendered text didn't match the client\"). Seed\n// deterministically by index, or compute inside an event handler:\nconst seeded = (n: number) => { const x = Math.sin((n + 1) * 99.71) * 1e4; return x - Math.floor(x) }`,\n },\n\n {\n name: \"status-badge-coloring\",\n tagline: \"Colour a StatusBadge for localized labels and tiers via tone + icon (escape-hatch props, @godxjp/ui ≥ 6.1).\",\n tags: [\"statusbadge\", \"badge\", \"tone\", \"color\", \"status\", \"tier\", \"table\"],\n code: `import { StatusBadge } from \"@godxjp/ui/data-display\"\n\n// StatusBadge auto-colours a fixed set of English LIFECYCLE keys:\n// active/completed (success ✓) · draft (neutral ○) · pending/temporary (warning ⏱)\n// scheduled/sending (info) · cancelled (neutral) · failed/deleted/bounced (destructive ✕)\n// Anything else (localized labels, tiers) falls back to neutral grey ○ unless you override.\n\n// 1) Lifecycle with localized text — map to the key, keep JP via \\`label\\` (icon stays):\n<StatusBadge status=\"active\" label=\"公開中\" /> // green ✓ 公開中\n\n// 2) Unknown label — set tone explicitly (no icon, since the key is unknown):\n<StatusBadge status=\"公開中\" tone=\"success\" />\n\n// 3) Tier / category — coloured pill, drop the misleading glyph with icon={null}:\n<StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} />\n<StatusBadge status=\"ゴールド\" tone=\"warning\" icon={null} />\n<StatusBadge status=\"法人共通\" tone=\"info\" icon={null} />\n\n// tone: \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\" (import type StatusBadgeTone)\n// RULE: a chip never wraps — it is pinned white-space: nowrap, so it stays one line in\n// narrow table cells. Centralize the domain→tone map in ONE small consumer wrapper and\n// import that instead of the raw StatusBadge across pages.`,\n },\n];\n\nexport function findPattern(name: string): PatternEntry | undefined {\n const slug = name.trim().toLowerCase();\n return PATTERNS.find((p) => p.name === slug);\n}\n\nexport function searchPatterns(query: string): PatternEntry[] {\n const q = query.trim().toLowerCase();\n if (q === \"\") return PATTERNS;\n return PATTERNS.filter(\n (p) =>\n p.name.includes(q) ||\n p.tagline.toLowerCase().includes(q) ||\n p.tags.some((t) => t.includes(q)),\n );\n}\n","/**\n * Skills index — TOKEN-EFFICIENT registry of every taste / design\n * skill the MCP exposes. The agent uses `list_skills` to discover\n * (returns just id + name + tagline + section list) then\n * `get_skill_section` to drill into one section.\n *\n * Sources synthesised from Leonxlnx/taste-skill + framework-native\n * design knowledge. Body strings are stored separately in their\n * existing data files (design-thinking.ts, anti-ai-tells.ts, etc.)\n * to avoid duplication.\n */\n\nexport interface SkillSection {\n /** URL-safe section id. */\n id: string;\n /** Display title. */\n title: string;\n /** One-line tagline of what this section covers. */\n tagline: string;\n /** Body — Markdown. */\n body: string;\n}\n\nexport interface Skill {\n id: string;\n name: string;\n /** When to reach for this skill — written so the router can match a task to it. */\n whenToUse: string;\n /** Source attribution. */\n source: string;\n sections: SkillSection[];\n}\n\nexport const SKILLS: Skill[] = [\n // ── taste (foundational) ───────────────────────────────────────\n {\n id: \"taste\",\n name: \"Taste baseline — Senior UI/UX engineering\",\n whenToUse:\n \"Default for any production app screen. Metric-based rules, strict component architecture, CSS hardware acceleration, balanced design engineering.\",\n source: \"Leonxlnx/taste-skill (root) + @godxjp/ui design-thinking.ts\",\n sections: [\n {\n id: \"mobile-first\",\n title: \"Mobile-first non-negotiable\",\n tagline:\n \"Defaults target xs (≥0px); enhance via sm: / md: / lg: / xl: / 2xl:\",\n body: `Cardinal rule 24. Touch targets ≥ 44×44 px. NEVER read\nwindow.innerWidth — use useBreakpoint(). Stories render at narrow\nviewport first. Multi-column layouts: grid grid-cols-1 sm:grid-cols-N.\nEXCEPTION: name pairs (姓+名) use grid-cols-2 always.`,\n },\n {\n id: \"one-intent-per-screen\",\n title: \"One intent per screen\",\n tagline: \"Pick the ONE primary question this page answers. 60-80% visual weight to it.\",\n body: `Wall-of-cards dashboards are AI slop. Show 1-2 hero metrics\n+ ONE primary list + contextual actions. Tertiary content lives in\nSheet / DropdownMenu / next page. The 8-stat-card grid pattern is a\nRED FLAG — it means \"I couldn't decide what mattered\".`,\n },\n {\n id: \"type-hierarchy\",\n title: \"Type does the hierarchy work\",\n tagline: \"Weight + size + color, NOT colored background blocks.\",\n body: `Typography.Title size={1..5} is the canonical scale. h2 → h3 → h4\neach ~75% of previous. Don't skip levels. Body = Typography.Paragraph.\nMetadata = Typography.Text color=\"secondary\". Type contrast alone IS\nthe hierarchy — colored background blocks for every section is AI\nslop. Reserve colored bg for genuinely different surfaces (Card vs\npage, Alert vs body).`,\n },\n {\n id: \"whitespace-is-content\",\n title: \"Whitespace IS content\",\n tagline: \"Use the smallest spacing step that visually separates concepts.\",\n body: `Spacing ladder: --spacing-1 (4px) for tight groups, -2 (8) for\ncontrol pairs, -3 (12) for related controls in form, -4 (16) for\nsections, -6 (24) for cards in grid, -8 (32) for page rhythm.\n\"Premium via excess padding\" (everything spacing-6 to feel premium)\nis wrong — undersized content lost in oceans of grey. Premium = VARIED\nspacing — tight where related, generous where not.`,\n },\n {\n id: \"two-accents\",\n title: \"Two accents do real work — not eight\",\n tagline: \"ONE brand color for action + ONE semantic color contextually. Not a rainbow.\",\n body: `Use --primary for actions (Button, link, focus ring) + ONE\nsemantic (destructive for delete confirm, warning for deadline alert,\nsuccess for completed state). NEVER a rainbow tag wall. Tag variety\nvia appearance (soft/solid/outline) of the SAME hue, not different\nhues.`,\n },\n {\n id: \"form-discipline\",\n title: \"Form discipline — label, help, error always\",\n tagline: \"Every input has explicit label + help + error wired via FormField.\",\n body: `Never placeholder-as-label (disappears on focus). Use\n<FormField label description /> — it wires the Radix Label, the\ndescription text, and the error via aria-describedby + role=\"alert\"\nautomatically. Server errors as inline near the field, NOT as toasts\n(SR can't announce a disappearing toast).`,\n },\n {\n id: \"loading-states\",\n title: \"Skeleton for INIT, Spinner for ACTIVE work\",\n tagline: \"Different states for different moments — never mix.\",\n body: `<Form loading={{ kind: \"skeleton\" }}> while fetching existing\nvalues (no data yet — maintain layout, prevent flash). <Form loading>\n(boolean true) while saving (data is there, you're transforming).\nSkeleton during save is wrong (user sees structure they already saw —\nbroken). Spinner during init is wrong (nothing to spin over).`,\n },\n ],\n },\n\n // ── soft (Awwwards / premium agency) ───────────────────────────\n {\n id: \"soft\",\n name: \"Awwwards-tier — $150k agency build\",\n whenToUse:\n \"Premium agency brief — marketing site, hero pages, product showcase. NOT every internal SaaS screen. Apply when the brief asks for 'Linear-tier', 'Apple-esque', 'Awwwards-style'.\",\n source: \"Leonxlnx/taste-skill/soft-skill\",\n sections: [\n {\n id: \"absolute-zero\",\n title: \"Absolute Zero — banned defaults\",\n tagline: \"Inter / Roboto / Lucide / shadow-md / 3-col Bootstrap / linear easing — banned.\",\n body: `BANNED FONTS: Inter, Roboto, Arial, Open Sans, Helvetica → use Geist\n/ Clash Display / PP Editorial New / Plus Jakarta Sans.\nBANNED ICONS: standard thick Lucide / Material → use Phosphor Light /\nRemix Line.\nBANNED BORDERS: generic 1px solid gray → hairline rings (ring-1\nring-black/5), tinted borders, OR whitespace as separator.\nBANNED SHADOWS: shadow-md, rgba(0,0,0,0.3) → ultra-diffuse low-opacity\n(<0.05), TINTED to background.\nBANNED LAYOUTS: edge-to-edge sticky navbars, symmetric 3-col → floating\nglass nav pills, asymmetric bento grids.\nBANNED MOTION: linear / ease-in-out / instant → custom cubic-bezier\n(0.32, 0.72, 0, 1), spring physics, scroll interpolation.`,\n },\n {\n id: \"vibe-archetypes\",\n title: \"3 Vibe Archetypes (pick 1)\",\n tagline: \"Ethereal Glass (SaaS/AI) | Editorial Luxury (Lifestyle/Agency) | Soft Structuralism (Consumer/Health)\",\n body: `1. ETHEREAL GLASS (SaaS / AI / Tech): OLED black #050505, radial\n mesh gradients (purple/emerald orbs), Vantablack cards with heavy\n backdrop-blur-2xl, white/10 hairlines. Wide geometric Grotesk.\n2. EDITORIAL LUXURY (Lifestyle / Real Estate / Agency): Warm creams\n #FDFBF7, muted sage, deep espresso. High-contrast Variable Serif\n for massive headings. CSS noise overlay opacity-0.03 for paper.\n3. SOFT STRUCTURALISM (Consumer / Health / Portfolio): Silver-grey\n or pure white. Massive bold Grotesk typography. Airy floating\n components, unbelievably soft diffused ambient shadows\n (shadow-[0_30px_60px_-30px_rgba(0,0,0,0.06)]).`,\n },\n {\n id: \"layout-archetypes\",\n title: \"3 Layout Archetypes (pick 1)\",\n tagline: \"Asymmetric Bento | Z-Axis Cascade | Editorial Split — ALL collapse to single-col on mobile.\",\n body: `1. ASYMMETRIC BENTO: Masonry CSS Grid varying card sizes\n (col-span-8 row-span-2 next to stacked col-span-4). Mobile:\n grid-cols-1, gap-6, all col-span reset to 1.\n2. Z-AXIS CASCADE: Elements stacked like physical cards, slightly\n overlapping with varying depth + -2deg/3deg rotations. Mobile:\n REMOVE rotations + negative-margin overlaps below 768px (touch\n conflicts), stack vertically.\n3. EDITORIAL SPLIT: Massive typography w-1/2 left, interactive\n scrollable content right. Mobile: full-width vertical stack,\n typography on top, content below with horizontal scroll preserved.\n\nUNIVERSAL MOBILE OVERRIDE: w-full, px-4, py-8 below 768px. NEVER\nh-screen — always min-h-[100dvh] (iOS Safari viewport jump fix).`,\n },\n {\n id: \"double-bezel\",\n title: \"Double-Bezel / Doppelrand architecture\",\n tagline: \"Cards nested like physical hardware — glass plate in aluminum tray.\",\n body: `Never flat. Wrap every premium card in two nested enclosures:\n\nOUTER SHELL: subtle bg (bg-black/5 or bg-white/5), hairline outer\nborder (ring-1 ring-black/5 or border border-white/10), padding\np-1.5 / p-2, large outer radius (rounded-[2rem]).\n\nINNER CORE: distinct background, inner highlight\n(shadow-[inset_0_1px_1px_rgba(255,255,255,0.15)]), mathematically\nsmaller radius (rounded-[calc(2rem-0.375rem)]) for concentric curves.\n\nThe math gives \"machined hardware\" look. Concentric curves = human\neye reads \"precision\".`,\n },\n {\n id: \"button-in-button\",\n title: \"Button-in-Button trailing icon\",\n tagline: \"Trailing arrow lives in its OWN nested pill — not naked next to text.\",\n body: `Primary buttons: rounded-full, px-6 py-3 generous padding. Trailing\narrow/icon NEVER sits naked next to text. Nests in its own circular\nwrapper: w-8 h-8 rounded-full bg-black/5 flex items-center justify-\ncenter, flush with main button's right inner padding. On hover, inner\nicon translates diagonally + scales up — internal kinetic tension.`,\n },\n {\n id: \"magnetic-hover\",\n title: \"Magnetic button hover physics\",\n tagline: \"Custom cubic-bezier, scale on press, internal translate on hover. NO linear easing.\",\n body: `Use group utility. Hover ≠ background color change. On hover:\nnested inner icon circle translates diagonally (group-hover:translate-\nx-1 group-hover:-translate-y-[1px]) AND scales up (scale-105). On\npress: scale entire button down slightly (active:scale-[0.98]) —\nsimulates physical click. Custom cubic-bezier on ALL transitions\n(NEVER linear / ease-in-out).`,\n },\n {\n id: \"scroll-entry\",\n title: \"Scroll-interpolation entry animations\",\n tagline: \"Elements never appear statically — gentle fade-up from below with blur.\",\n body: `As elements enter viewport: translate-y-16 blur-md opacity-0 →\ntranslate-y-0 blur-0 opacity-100 over 800ms+. Use IntersectionObserver\nor Framer Motion's whileInView. NEVER window.addEventListener(\"scroll\")\n— continuous reflows kill mobile perf.`,\n },\n {\n id: \"performance-guardrails\",\n title: \"Performance guardrails\",\n tagline: \"GPU-safe transforms, blur only on fixed/sticky, noise on pointer-events-none.\",\n body: `- Animate transform + opacity ONLY. NEVER top/left/width/height\n (layout reflow). will-change: transform sparingly.\n- backdrop-blur only on FIXED/STICKY elements. NEVER on scrolling\n containers — continuous GPU repaints, severe mobile frame drops.\n- grain/noise: FIXED pointer-events-none pseudo-element (position:\n fixed; inset: 0; z-index: 50). Never on scrolling containers.\n- Z-index discipline: no arbitrary z-50 or z-[9999]. Reserve for\n systemic layers (sticky nav, modals, overlays, tooltips).`,\n },\n ],\n },\n\n // ── minimalist (editorial workspace) ───────────────────────────\n {\n id: \"minimalist\",\n name: \"Minimalist — editorial workspace\",\n whenToUse:\n \"Document-style apps (Notion-clone, knowledge base, blog admin). Warm monochrome + spot pastels. Bento grids. Editorial serif headings + sans body + monospace for data.\",\n source: \"Leonxlnx/taste-skill/minimalist-skill\",\n sections: [\n {\n id: \"negative-constraints\",\n title: \"Banned defaults\",\n tagline: \"Inter / Roboto / Lucide / shadow-md / pill containers / emojis / Acme — banned.\",\n body: `BANNED: Inter / Roboto / Open Sans fonts. Lucide / Feather / Heroicons\ndefault icons. Tailwind heavy shadows (md/lg/xl). Primary-colored hero\nbackgrounds. Gradients, neon, full glassmorphism. rounded-full on\nlarge containers. Emojis anywhere in markup. Generic names (John Doe,\nAcme, Lorem Ipsum). AI clichés (Elevate, Seamless, Unleash, Next-Gen).`,\n },\n {\n id: \"typography\",\n title: \"Editorial typography\",\n tagline: \"Serif heading + character sans body + mono data. Off-black for body, never pure.\",\n body: `Pair: editorial serif (Lyon Text / Newsreader / Playfair / Instrument\nSerif) for headings WITH character sans (SF Pro Display / Geist Sans /\nSwitzer) body WITH monospace (Geist Mono / JetBrains Mono / SF Mono)\nfor data + keystrokes.\n\nTight tracking on serif headings (-0.02em to -0.04em). Tight\nline-height (1.1). Body line-height 1.6. Body color: off-black\n#111111 or #2F3437 — NEVER pure #000. Secondary text: muted gray\n#787774.`,\n },\n {\n id: \"palette\",\n title: \"Warm monochrome + spot pastels\",\n tagline: \"Canvas warm bone #F7F6F3. Accents from 4 desaturated pastels only.\",\n body: `Canvas: #FFFFFF or warm bone #F7F6F3 / #FBFBFA.\nCards: #FFFFFF or #F9F9F8.\nBorders: ultra-light #EAEAEA or rgba(0,0,0,0.06).\n\nAccents EXCLUSIVELY from 4 muted pastels:\n- Pale Red: bg #FDEBEC | text #9F2F2D\n- Pale Blue: bg #E1F3FE | text #1F6C9F\n- Pale Green: bg #EDF3EC | text #346538\n- Pale Yellow: bg #FBF3DB | text #956400`,\n },\n {\n id: \"bento-grids\",\n title: \"Asymmetric bento grids\",\n tagline: \"Cards: 1px solid #EAEAEA, 8-12px radius MAX, 24-40px padding, NO shadow.\",\n body: `Asymmetric CSS Grid layouts (1x1, 1x2, 2x1, 2x2). Cards:\nborder: 1px solid #EAEAEA, border-radius 8px or 12px MAX (never larger),\ngenerous internal padding (24-40px), no box-shadow. Use raw CSS Grid\nwith gridColumn/gridRow span for the bento layout.`,\n },\n {\n id: \"components\",\n title: \"Component refinements\",\n tagline: \"Primary CTA: solid black bg, 4-6px radius. Tags: pill + uppercase + 0.05em tracking + pastel.\",\n body: `PRIMARY CTA: solid #111 bg, white text, 4-6px radius (NOT full pill),\nno shadow. Hover: shift to #333 or active:scale(0.98).\nTAGS/BADGES: pill (border-radius 9999px), text-xs UPPERCASE,\nletter-spacing 0.05em. Background = muted pastel. Deep text color.\nACCORDIONS (FAQ): strip ALL container chrome. Items separated by\nborder-bottom: 1px solid #EAEAEA only. Toggle: sharp + / − icons.\nKBD: <kbd> as physical key — 1px solid #EAEAEA, 4px radius, #F7F6F3\nbg, monospace.\nFAUX-OS chrome (for product previews): white top bar + 3 small light-\ngray circles (macOS replica).`,\n },\n {\n id: \"motion\",\n title: \"Subtle invisible motion\",\n tagline: \"Scroll-entry fade-up 600ms cubic-bezier(.16,1,.3,1). Card hover lift via shadow shift only.\",\n body: `Scroll entry: translateY(12px) + opacity(0) → 0/1 over 600ms with\ncubic-bezier(0.16, 1, 0.3, 1). IntersectionObserver, never raw scroll.\nHover lift: box-shadow 0 → 0 2px 8px rgba(0,0,0,0.04) over 200ms.\nButtons: scale(0.98) on :active. Staggered list reveals: animation-\ndelay calc(var(--index) * 80ms). Background ambient: optional slow\nradial gradient blob, 20s+ duration, opacity 0.02-0.04, on\nposition:fixed pointer-events-none layer.`,\n },\n ],\n },\n\n // ── brutalist ──────────────────────────────────────────────────\n {\n id: \"brutalist\",\n name: \"Brutalist — Swiss print + military terminal\",\n whenToUse:\n \"Data-heavy dashboards, declassified-blueprint feel, portfolios needing raw mechanical aesthetic. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects.\",\n source: \"Leonxlnx/taste-skill/brutalist-skill\",\n sections: [\n {\n id: \"principles\",\n title: \"Brutalist principles\",\n tagline: \"Raw mechanical interfaces — rigid grids, extreme type contrast, utilitarian color, analog degradation.\",\n body: `Rejects ornament. Embraces structure as aesthetic. Grids are visible\n(via borders or rules). Type scale is dramatically contrasted (massive\ndisplay heading next to small tabular body). Color is utilitarian —\nblack, off-white, single signal color (red, amber, terminal green).\nAnalog effects (printer-bleed, halftone, screenprint registration\nerrors) add character without becoming kitsch. Best for: dev tools,\ndeclassified-data presentations, raw-fact dashboards, technical\nportfolios.`,\n },\n ],\n },\n\n // ── gpt-tasteskill ─────────────────────────────────────────────\n {\n id: \"gpt-tasteskill\",\n name: \"GPT taste — editorial + advanced GSAP motion\",\n whenToUse:\n \"Long-scroll marketing pages with cinematic scroll choreography. Pins, stacks, scrubbed timelines. AIDA structure. Wide editorial typography. Bans 6-line wraps. Gapless bento grids.\",\n source: \"Leonxlnx/taste-skill/gpt-tasteskill\",\n sections: [\n {\n id: \"principles\",\n title: \"GSAP motion + AIDA structure\",\n tagline: \"Python-driven layout randomization, strict ScrollTrigger choreography, wide editorial typography.\",\n body: `AIDA (Attention/Interest/Desire/Action) page spine. Wide editorial\ntypography — bans 6-line wraps (line lengths cap at ~5). Gapless bento\ngrids (cards flush against each other, no gutter — outline borders\ndo the separation). Inline micro-images (small contextual photos\nwithin a section, not just hero). Massive section spacing (180-240px\nbetween sections, not 80). GSAP ScrollTriggers: pinning (section\nlocks while sub-content scrolls), stacking (next section slides\nover current), scrubbing (animation tied to scroll progress).`,\n },\n ],\n },\n\n // ── redesign ───────────────────────────────────────────────────\n {\n id: \"redesign\",\n name: \"Redesign — audit + upgrade existing UI\",\n whenToUse:\n \"Working on an existing project (not greenfield). Find generic patterns, weak points, missing states. Apply fixes in priority order — font swap first, palette cleanup second, etc.\",\n source: \"Leonxlnx/taste-skill/redesign-skill + redesign-audit.ts\",\n sections: [\n {\n id: \"fix-priority\",\n title: \"Fix priority order\",\n tagline: \"Font → palette → states → layout → components → loading/empty/error → typography polish.\",\n body: `Apply in THIS order for max visual impact at min risk:\n\n1. FONT SWAP — biggest instant improvement, lowest risk.\n2. COLOR PALETTE CLEANUP — remove clashing / oversaturated colors.\n3. HOVER + ACTIVE STATES — makes interface feel alive.\n4. LAYOUT + SPACING — proper grid, max-width, consistent padding.\n5. REPLACE GENERIC COMPONENTS — cliche → modern alternatives.\n6. LOADING / EMPTY / ERROR STATES — makes it feel finished.\n7. TYPOGRAPHY SCALE + SPACING POLISH — premium final touch.\n\nRules: work with existing stack, don't migrate frameworks, don't break\nfunctionality, test after every change. Small targeted improvements\nover big rewrites.`,\n },\n {\n id: \"audit-checklist\",\n title: \"Audit checklist (8 categories)\",\n tagline: \"Typography / color / layout / interactivity / content / components / iconography / code / omissions.\",\n body: `See redesign-audit.ts (50+ checks). Common findings:\n\nTYPOGRAPHY: Inter everywhere, weak headlines, full-width paragraphs,\nonly 400/700 weights, proportional numbers in data, Title Case On\nEvery Header.\nCOLOR: pure #000, oversaturated accents, multiple competing accents,\npurple/blue AI gradient, generic black shadows, empty flat sections.\nLAYOUT: 3-equal-card columns (most generic AI pattern), height:100vh\niOS jump, no max-width container, dashboard always left sidebar.\nINTERACTIVITY: no hover, no active feedback, no focus ring, generic\nspinners, no empty states, alert() for errors, dead links.\nCONTENT: John Doe / Acme / Lorem Ipsum, AI clichés, exclamation marks\nin success, passive voice errors.\nOMISSIONS: no legal links, no back nav, no 404, no form validation,\nno skip-to-content.`,\n },\n ],\n },\n\n // ── output (full-output enforcement) ───────────────────────────\n {\n id: \"output\",\n name: \"Full-output enforcement\",\n whenToUse:\n \"Always. Bans the // ... / // TODO / 'I'll leave this as an exercise' patterns. Treat every task as production-critical.\",\n source: \"Leonxlnx/taste-skill/output-skill + output-quality.ts\",\n sections: [\n {\n id: \"banned\",\n title: \"Banned patterns\",\n tagline: \"// ... / // TODO / 'for brevity' / 'rest follows pattern' — HARD FAILURES.\",\n body: `In code: // ..., // rest of code, // implement here, // TODO,\n/* ... */, // similar to above, // continue pattern, // add more\nas needed, bare ... standing for omitted code.\n\nIn prose: \"Let me know if you want me to continue\", \"for brevity\",\n\"the rest follows the same pattern\", \"similarly for the remaining\",\n\"and so on\" (replacing actual content), \"I'll leave that as an\nexercise\".\n\nStructural: skeleton when full implementation was requested, first +\nlast section skipping middle, describing what code should do instead\nof writing it.`,\n },\n {\n id: \"long-output-protocol\",\n title: \"Long-output protocol\",\n tagline: \"Write at full quality to clean breakpoint, then [PAUSED] marker, never compress.\",\n body: `When response approaches token limit:\n- Do NOT compress remaining sections.\n- Write at FULL QUALITY up to clean breakpoint (end of function /\n file / section).\n- End with: [PAUSED — X of Y complete. Send \"continue\" to resume\n from: <section name>]\n- On \"continue\": pick up EXACTLY where stopped. No recap, no\n repetition.`,\n },\n ],\n },\n\n // ── brandkit ───────────────────────────────────────────────────\n {\n id: \"brandkit\",\n name: \"Brandkit — identity guidelines boards\",\n whenToUse:\n \"Designing a brand identity board first (before screens). Logo system, color palette, typography lockup, icon system, photography direction, brand voice.\",\n source: \"Leonxlnx/taste-skill/brandkit\",\n sections: [\n {\n id: \"principles\",\n title: \"Brandkit principles\",\n tagline: \"Premium brand-guidelines boards — minimalist / cinematic / editorial / dark-tech / luxury / cultural variants.\",\n body: `Compositions for brand identity decks. Minimalist (workspace),\ncinematic (entertainment), editorial (publishing), dark-tech (SaaS),\nluxury (lifestyle), cultural (heritage), security (defense / fintech),\ngaming, developer-tool, consumer-app. Logo concepts with intentional\nsymbolic meaning. Refined composition (asymmetric grid, generous\nbreathing). Sparse typography. Premium mockups. Art-directed\nimagery. Flexible grid layouts.`,\n },\n ],\n },\n\n // ── stitch ─────────────────────────────────────────────────────\n {\n id: \"stitch\",\n name: \"Stitch — semantic DESIGN.md for Google Stitch\",\n whenToUse:\n \"Pairing with Google Stitch (or similar AI UI generator). Generate DESIGN.md files that enforce premium standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion.\",\n source: \"Leonxlnx/taste-skill/stitch-skill\",\n sections: [\n {\n id: \"principles\",\n title: \"Stitch DESIGN.md principles\",\n tagline: \"Agent-friendly design specs — strict type, calibrated color, asymmetric layout, micro-motion, hardware acceleration.\",\n body: `DESIGN.md = instruction set for downstream AI UI generators.\nEnforces: strict typography (no Inter, specific fonts named),\ncalibrated color (specific hex, not \"blue\"), asymmetric layouts\n(specific grid template strings), perpetual micro-motion (specific\ntiming functions), hardware-accelerated performance (transform/\nopacity only). Output is consumable by AI agents — explicit beats\nexpressive.`,\n },\n ],\n },\n\n // ── imagegen-mobile ────────────────────────────────────────────\n {\n id: \"imagegen-mobile\",\n name: \"Imagegen mobile — app screen reference images\",\n whenToUse:\n \"Pre-code phase. Generate mobile screen mockups before implementing. Onboarding flows, auth, home dashboards, profile, settings, chat, ecommerce, fintech, health, productivity.\",\n source: \"Leonxlnx/taste-skill/imagegen-frontend-mobile\",\n sections: [\n {\n id: \"principles\",\n title: \"Mobile image direction principles\",\n tagline: \"App-native, premium, readable, flow-aware, platform-aware. Wrap in subtle premium phone mockup. Multi-screen consistency.\",\n body: `Generate premium app-native mobile screen images + flow images\n(NOT generic AI mockups, NOT phone-shaped websites). Default mockup\npresence: subtle premium iPhone frame with visible chrome, focus\nstays on app content. Generate 3-5 screens per flow (onboarding,\nauth, home, detail, settings). Logical flow (each screen continues\nthe user's task). First-screen cleanliness (don't dump every feature\non the entry screen). Safe-area awareness (status bar + home\nindicator preserved). Mobile anti-tells: no purple-blue fintech\ngradients, no random glass cards, no ambient blobs, no fake neon, no\ndribbble floating widgets, no oversized corner radii on everything,\nno rainbow chip walls, no fake chart dashboard spam, no cloned\nscreens in flows.`,\n },\n ],\n },\n\n // ── imagegen-web ───────────────────────────────────────────────\n {\n id: \"imagegen-web\",\n name: \"Imagegen web — landing page section images\",\n whenToUse:\n \"Pre-code phase for landing / marketing sites. Generate ONE image per section (8 sections → 8 images). Hero composition variety (NOT always left-text/right-image).\",\n source: \"Leonxlnx/taste-skill/imagegen-frontend-web\",\n sections: [\n {\n id: \"hard-output-rule\",\n title: \"Hard output rule — one image per section\",\n tagline: \"8 sections requested → 8 separate images. NEVER combine sections.\",\n body: `Each image = one section, own image call. NEVER combine multiple\nsections into one frame. NEVER return a single tall image with the\nwhole page. Default to 6 sections if \"landing page\" with no count.\n8 sections for \"full website template\". Announce each (\"Section 1\nof 8: Hero\", \"Section 2 of 8: Trust bar\").`,\n },\n {\n id: \"hero-composition-bias\",\n title: \"Hero composition variety\",\n tagline: \"Left-text / right-image hero is the most overused AI pattern. Pick from 10 alternatives first.\",\n body: `Before reaching for left-text/right-image hero, consider:\n- centered over background image\n- bottom-left over image\n- bottom-right over image\n- top-left lead\n- stacked center\n- image-as-canvas\n- off-grid editorial\n- mini minimalist\n- right-text / left-image (inverted classic)\nUse left-text/right-image ONLY when genuinely the strongest choice\nfor the brand.`,\n },\n ],\n },\n\n // ── image-to-code ──────────────────────────────────────────────\n {\n id: \"image-to-code\",\n name: \"Image-to-code — generate design first, then implement\",\n whenToUse:\n \"Visual-first brief in Codex. First generate the design image yourself, deeply analyze, THEN implement code matching it.\",\n source: \"Leonxlnx/taste-skill/image-to-code-skill\",\n sections: [\n {\n id: \"workflow\",\n title: \"Image-to-code workflow\",\n tagline: \"Generate design image → analyze → implement. Prefer large readable section-specific images.\",\n body: `Workflow:\n1. Generate the design image FIRST (one per section, large + readable).\n2. Deeply analyze: composition, hierarchy, palette, typography, motion.\n3. Implement React/HTML/CSS matching as closely as possible.\n\nPrefer LARGE, readable, section-specific images over tiny compressed\nboards. Generate fresh standalone images for sections / detail views\ninstead of cropping old. Avoid lazy under-generation. Avoid cards-\ninside-cards-inside-cards UI. Keep the hero clean, spacious, readable,\nvisible on a small laptop.`,\n },\n ],\n },\n];\n\nexport function findSkill(id: string): Skill | undefined {\n return SKILLS.find((s) => s.id === id);\n}\n\nexport function findSection(skillId: string, sectionId: string): SkillSection | undefined {\n return findSkill(skillId)?.sections.find((s) => s.id === sectionId);\n}\n\n/**\n * Naïve task router — keyword match. Replace with embedding-based\n * matcher in v2 if it proves useful.\n */\nexport interface RouteResult {\n skill: string;\n section: string | \"<see whenToUse>\";\n why: string;\n alsoSee?: string[];\n}\n\nexport function routeTask(task: string): RouteResult[] {\n const q = task.toLowerCase();\n const matches: RouteResult[] = [];\n\n const route = (\n kw: string[],\n skill: string,\n section: string | \"<see whenToUse>\",\n why: string,\n alsoSee?: string[],\n ) => {\n if (kw.some((k) => q.includes(k))) matches.push({ skill, section, why, alsoSee });\n };\n\n // Premium / agency / Awwwards\n route([\"premium\", \"awwwards\", \"agency\", \"linear\", \"apple\", \"high-end\", \"luxury\"],\n \"soft\", \"vibe-archetypes\",\n \"Premium tier — pick a Vibe + Layout archetype + apply Double-Bezel.\",\n [\"soft/double-bezel\", \"soft/magnetic-hover\"]);\n\n // Marketing / landing\n route([\"landing page\", \"marketing\", \"hero\", \"long scroll\"],\n \"imagegen-web\", \"hero-composition-bias\",\n \"Landing pages benefit from hero composition variety + per-section image generation.\",\n [\"gpt-tasteskill/principles\", \"soft/layout-archetypes\"]);\n\n // Mobile app screens\n route([\"mobile app\", \"ios\", \"android\", \"phone screen\", \"onboarding flow\"],\n \"imagegen-mobile\", \"principles\",\n \"Mobile app design — generate screens first, avoid phone-shaped-website.\",\n [\"taste/mobile-first\"]);\n\n // Workspace / Notion-like\n route([\"workspace\", \"notion\", \"document\", \"editorial\", \"knowledge base\"],\n \"minimalist\", \"palette\",\n \"Editorial workspace = warm monochrome + spot pastels + serif headings.\",\n [\"minimalist/typography\", \"minimalist/bento-grids\"]);\n\n // Data dashboard\n route([\"dashboard\", \"data heavy\", \"tabular\", \"ops table\"],\n \"brutalist\", \"principles\",\n \"Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).\",\n [\"taste/one-intent-per-screen\"]);\n\n // Brand work\n route([\"brand\", \"identity\", \"logo\", \"guidelines\"],\n \"brandkit\", \"principles\",\n \"Brand identity work — boards before screens.\");\n\n // Existing project upgrade\n route([\"refactor\", \"redesign\", \"upgrade existing\", \"audit\"],\n \"redesign\", \"fix-priority\",\n \"Existing project = run audit first, fix in priority order (font → palette → states → ...).\",\n [\"redesign/audit-checklist\"]);\n\n // Form work\n route([\"form\", \"validation\", \"submit\", \"sign up\", \"registration\"],\n \"taste\", \"form-discipline\",\n \"Form must have explicit label + help + error wired via FormField (rule 34).\");\n\n // Loading / saving\n route([\"loading\", \"saving\", \"skeleton\", \"spinner\"],\n \"taste\", \"loading-states\",\n \"Skeleton for INIT fetch, Spinner for active work. Never mix.\");\n\n // Mobile-first concerns\n route([\"mobile first\", \"responsive\", \"breakpoint\"],\n \"taste\", \"mobile-first\",\n \"Default styles target xs. Touch targets ≥ 44px. Use useBreakpoint().\");\n\n // Output quality\n route([\"complete code\", \"full implementation\", \"no placeholder\"],\n \"output\", \"banned\",\n \"Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code.\");\n\n // GSAP motion\n route([\"gsap\", \"scrolltrigger\", \"scroll choreography\", \"pinning\"],\n \"gpt-tasteskill\", \"principles\",\n \"GSAP ScrollTrigger — pinning, stacking, scrubbing.\");\n\n // Image-first / design-first\n route([\"from image\", \"image to code\", \"design first\"],\n \"image-to-code\", \"workflow\",\n \"Generate design image first → analyze → implement.\");\n\n if (matches.length === 0) {\n return [{\n skill: \"taste\",\n section: \"<see whenToUse>\",\n why: `No keyword match for \"${task}\". Default to the \"taste\" baseline — see whenToUse for sections.`,\n }];\n }\n\n return matches;\n}\n","/**\n * Anti-AI-tells catalog — specific patterns that signal \"this UI was\n * synthesised by an LLM without taste\". Adapted from the taste-skill\n * SKILL.md (mobile + web) and the @godxjp/ui review log. The MCP\n * exposes this so consumer agents can self-audit BEFORE shipping.\n */\n\nexport interface AiTell {\n /** The pattern, by category. */\n category: \"visual\" | \"layout\" | \"copy\" | \"interaction\" | \"imagery\" | \"structure\";\n /** Short name. */\n name: string;\n /** What it looks like + why it's a tell. */\n body: string;\n /** What to do instead — concrete fix. */\n fix: string;\n}\n\nexport const ANTI_AI_TELLS: AiTell[] = [\n // ── visual ─────────────────────────────────────────────────────\n {\n category: \"visual\",\n name: \"Purple-blue gradient hero\",\n body: `The default LLM color palette — purple → blue → cyan radial /\nlinear gradient as hero background. Looks like every AI-generated\nSaaS landing page from 2023.`,\n fix: `Use the framework's accent palette (\\`data-accent=\"blue\"\\` /\n\"violet\" / \"cyan\" / \"green\" / \"orange\" / \"rose\"). Solid surface\ncolors with semantic meaning. If you want depth, use a SINGLE\nsubtle gradient that supports brand (not decoration).`,\n },\n {\n category: \"visual\",\n name: \"Glassmorphism without purpose\",\n body: `Frosted-glass cards stacked on a colorful blurry background.\nLooked novel in 2020 — now a tell that the designer reached for\ntrend instead of solving a problem.`,\n fix: `Solid surface tiers (Card on background, Popover on Card,\nDialog on backdrop). The framework's elevation system already\nencodes 3 surface tiers — use them.`,\n },\n {\n category: \"visual\",\n name: \"Ambient blobs / floating shapes\",\n body: `Random gradient blobs floating behind content with no narrative\npurpose. The \"creative space-filler\" AI pattern. Reads as\ndistracting noise.`,\n fix: `If the page needs visual interest, use a REAL image (product\nphoto, founder photo, branded illustration). If you need\n\"breathing room\", use whitespace. Never use shapes as filler.`,\n },\n {\n category: \"visual\",\n name: \"Oversized border-radius on everything\",\n body: `Every Card / Button / Input with \\`border-radius: 24px\\`. Reads\nas \"I picked one radius and applied it globally\". Premium design\nuses ROLES — small radius on inputs (4-6px), medium on cards\n(8-12px), pill on chips (full).`,\n fix: `Use the framework's radius scale (\\`--radius-sm | -md | -lg | -full\\`).\nEach primitive defaults to the right role; only override when the\ndesign canon specifically calls for it.`,\n },\n {\n category: \"visual\",\n name: \"Rainbow chip wall\",\n body: `Row of Tags / Badges each in a different color (red, orange,\nyellow, green, blue, purple) — usually navigation or filter\ncategories. Reads as chaos; eye can't anchor.`,\n fix: `Pick ONE accent for the tag row. Use \\`appearance\\` (\"soft\" vs\n\"solid\" vs \"outline\") for variety within the same hue. Reserve\nnon-neutral colors (success / warning / destructive) for tags\nthat genuinely carry that meaning.`,\n },\n\n // ── layout ─────────────────────────────────────────────────────\n {\n category: \"layout\",\n name: \"8-card stat dashboard\",\n body: `Homepage with a 4x2 grid of \"stat cards\" — each with an icon, a\nnumber, a sparkline, a delta. None of them relate to a real\nbusiness question; they were chosen because \"more cards = more\ndata\". Classic AI dashboard slop.`,\n fix: `Show 1-2 hero metrics (the ones executives ASK about), then the\ntop action list (orders waiting, tasks due, alerts). If the user\nneeds more analytics, link to a dedicated Reports page.`,\n },\n {\n category: \"layout\",\n name: \"Phone-shaped website\",\n body: `Mobile screen rendered as a vertical strip with the same density\n+ same layout as desktop — just narrower. Cramped tap targets,\nhorizontal scrolling for overflow, no system bar awareness.`,\n fix: `Mobile is its OWN design. Use full-width inputs (\\`block\\` Button),\nstacked layout, larger tap targets, Sheet/Drawer for secondary\ncontent, system-bar safe area. The framework's \\`useBreakpoint\\`\n+ Tailwind \\`sm:\\` variants give you the canvas.`,\n },\n {\n category: \"layout\",\n name: \"Wall-of-tabs navigation\",\n body: `10+ tabs at the top of a screen, no priority. User has to read all\nof them to find the right one. AI default: \"more tabs = more\nfeatures = better\".`,\n fix: `2-4 tabs max. If you have more categories, use a sidebar (Menu),\nor a Cascader / Tree picker. Tabs are for switching between PEERS\n(2-4 mutually exclusive views of the same data).`,\n },\n {\n category: \"layout\",\n name: \"Identical clone screens\",\n body: `5 onboarding steps where every screen has the same headline +\nillustration + 2 buttons layout. Reads as \"I copy-pasted the\ntemplate\" — and devalues the user's time at each step.`,\n fix: `Each step has a distinct visual + interactive feel. Step 1 might\nbe a centered question, step 2 a side-by-side comparison, step 3\na multi-field form, step 4 a single yes/no card. Same palette +\ntype system for coherence; different composition for engagement.`,\n },\n\n // ── copy ───────────────────────────────────────────────────────\n {\n category: \"copy\",\n name: \"Filler corporate phrases\",\n body: `\"Elevate your potential\", \"unlock seamless productivity\",\n\"transform your workflow\", \"next-generation experience\". Reads as\nnothing because it MEANS nothing.`,\n fix: `Write what the feature DOES, specifically. \"Sync 1,000 rows in 2\nseconds\" beats \"Lightning-fast performance\". \"Replaces 3 manual\nsteps\" beats \"Streamline your workflow\".`,\n },\n {\n category: \"copy\",\n name: \"Generic brand placeholders\",\n body: `Acme, NovaCore, Flowbit, Quantix, VeloPay, Lumen, Apex — the\ngo-to AI brand names that scream \"I couldn't think of one\".`,\n fix: `Use believable real-sounding names: 株式会社ABC商事, Tanaka\nTrading, Yokohama Coffee Roasters, Mountain View Bakery. Or use\nyour actual project's brand if known.`,\n },\n {\n category: \"copy\",\n name: \"Vague empty-state copy\",\n body: `\"Get started\", \"Begin your journey\", \"No items yet\" — without\nsaying WHAT to do or WHY there's nothing.`,\n fix: `Be specific + actionable: \"まだ注文がありません。商品を追加して\n最初の注文を作成しましょう。\" + a clear next-action Button.\nEmpty states are TEACHING MOMENTS — use them to onboard.`,\n },\n {\n category: \"copy\",\n name: \"Apologetic / passive-voice error messages\",\n body: `\"Sorry, something went wrong\" / \"An error has occurred\" — no\ninformation about WHAT, no recovery action.`,\n fix: `Specific + actionable: \"メールアドレスの形式が正しくありません\n(例: name@example.com)\". For server errors: \"通信エラー\n(再試行 ボタン)\". Never apologise if you can't say what failed\nor what to do.`,\n },\n\n // ── interaction ────────────────────────────────────────────────\n {\n category: \"interaction\",\n name: \"Hover-only affordances\",\n body: `Action buttons that only appear on hover (table row actions\nhidden until mouseover). Breaks on mobile (no hover), inaccessible\n(keyboard users can't discover).`,\n fix: `Show actions inline or in a kebab menu (DropdownMenu) that's\nALWAYS visible. If you must hide on desktop for density, ensure\nthe same actions are reachable via keyboard (Tab to row, Enter to\nexpand a row-actions DropdownMenu).`,\n },\n {\n category: \"interaction\",\n name: \"Auto-advancing carousel\",\n body: `Hero carousel that rotates every 3 seconds. Users haven't\nfinished reading slide 1; now slide 2 is gone. Accessibility\nnightmare (cognitive load, motion-sensitive).`,\n fix: `Carousel ONLY rotates on explicit user action (arrow click,\ndot click, swipe). \\`<Carousel autoplay={false}>\\` is the default\nin the framework for this reason.`,\n },\n {\n category: \"interaction\",\n name: \"Drag-without-handle\",\n body: `Cards / list items reorderable by long-press anywhere — no\nvisual indicator that they ARE draggable. Users discover it by\naccident or never.`,\n fix: `Show a drag handle icon (\\`<GripVertical>\\`) on the left of the\nrow. Users see it, understand \"this row is draggable\", reach for\nit deliberately.`,\n },\n {\n category: \"interaction\",\n name: \"Disappearing focus ring\",\n body: `\\`outline: none\\` on focus to \"look cleaner\". Keyboard users\ncan't see where they are; total navigation failure.`,\n fix: `Use \\`:focus-visible\\` (Radix primitives do automatically) so the\nring shows on keyboard focus, hides on mouse-click. Don't strip.`,\n },\n\n // ── imagery ────────────────────────────────────────────────────\n {\n category: \"imagery\",\n name: \"Stock photo of generic smiling team\",\n body: `Empty state / About page with a photo of a \"diverse team in an\nopen office laughing at a laptop\". Reads as 2010 corporate stock.\nNo relationship to your product.`,\n fix: `Real photos of YOUR team / users (with consent), product\nscreenshots, branded illustrations. Avatar's INITIALS fallback is\nbetter than a generic stock person.`,\n },\n {\n category: \"imagery\",\n name: \"Floating 3D crypto icon\",\n body: `Empty state with a chrome / pastel 3D icon (coin, key, shield)\nfloating in the center. Looks like every NFT marketplace from\n2021.`,\n fix: `Simple lucide-react line icon (\\`<Inbox size={48} />\\`) +\ndescriptive title. Or a flat illustration matching the brand\npalette. Skip the 3D entirely unless your brand IS 3D.`,\n },\n {\n category: \"imagery\",\n name: \"Decorative gradient mesh background\",\n body: `Page sections with a colorful gradient mesh (\"Stripe-style\")\nbehind text. Looks \"premium\" until you realize every AI design\nuses it. Often hurts text contrast.`,\n fix: `Solid background (\\`--background\\`). If you need depth, use a\nsubtle 1px border + \\`--card\\` background tint. Reserve high-effort\nbackgrounds for pages where they matter (marketing hero, product\nshowcase) — not every internal screen.`,\n },\n\n // ── structure ──────────────────────────────────────────────────\n {\n category: \"structure\",\n name: \"Settings as one long form\",\n body: `Settings page with 40 form fields in a single scroll. User\nloses their place, can't find the field they came for.`,\n fix: `Section the form with \\`<Typography.Title size={5}>\\` subheaders\n+ \\`<Separator />\\`. Group by concern (基本情報 / 公開範囲 / 通知 /\nセキュリティ). If 40 fields is still too many, split into Tabs\nor a Sidebar-driven multi-page settings flow.`,\n },\n {\n category: \"structure\",\n name: \"Modal-in-modal-in-modal\",\n body: `Click a Button → Dialog opens → click \"Edit\" → another Dialog\nopens → click \"Confirm\" → AlertDialog opens. Triple stack;\nuser loses context.`,\n fix: `Use Sheet for the FIRST level (side panel), Dialog for the\nconfirm. Or, redesign the flow so the edit is INLINE in the\nfirst Dialog (no second Dialog needed). AlertDialog for confirm\nis correct — but ONE deep, not three.`,\n },\n {\n category: \"structure\",\n name: \"Spinner-only loading state\",\n body: `Page-level spinner while data loads. User stares at an empty\nshell with a centered spinner. Layout shifts when content\narrives.`,\n fix: `Use Skeleton placeholders matching the eventual content shape.\nThe framework's \\`<Form loading={{ kind: \"skeleton\" }}>\\` cascades\nto every field; \\`<Skeleton className=\"h-9 w-full rounded-md\" />\\`\nfor individual blocks. Layout stays stable, perceived speed\nimproves.`,\n },\n];\n\nexport function aiTellsByCategory(cat: AiTell[\"category\"]): AiTell[] {\n return ANTI_AI_TELLS.filter((t) => t.category === cat);\n}\n","/**\n * Redesign audit checklist — for upgrading an existing project (or\n * critiquing a new design before shipping). Adapted from\n * Leonxlnx/taste-skill `redesign-existing-projects` SKILL. The MCP\n * exposes this so consumer agents can run a structured audit on a\n * page they're working on.\n *\n * Fix priority is ordered for MAXIMUM visual impact at MINIMUM\n * risk — agents should apply in this order.\n */\n\nexport interface AuditCheck {\n category:\n | \"typography\"\n | \"color-surface\"\n | \"layout\"\n | \"interactivity\"\n | \"content\"\n | \"components\"\n | \"iconography\"\n | \"code-quality\"\n | \"omissions\";\n /** What to look for. */\n symptom: string;\n /** Concrete fix. */\n fix: string;\n /** @godxjp/ui-specific notes if applicable. */\n uiNote?: string;\n}\n\nexport const REDESIGN_CHECKS: AuditCheck[] = [\n // ── typography ─────────────────────────────────────────────────\n {\n category: \"typography\",\n symptom: \"Inter / Roboto / Open Sans everywhere — the AI default.\",\n fix: \"Pick a font with character: Geist, Outfit, Cabinet Grotesk, Satoshi for sans. For editorial / creative — pair a serif heading (Newsreader, Lyon, Playfair) with a sans body.\",\n uiNote: \"Override --font-sans + --font-serif at the consumer's root CSS. Framework reads from these tokens.\",\n },\n {\n category: \"typography\",\n symptom: \"Headlines lack presence — small + thin + default tracking.\",\n fix: \"Increase display size, tighten letter-spacing (-0.02em to -0.04em), reduce line-height (1.1). Headlines should feel HEAVY and INTENTIONAL.\",\n uiNote: \"Typography.Title size={1} for hero; override fontFamily + letterSpacing inline.\",\n },\n {\n category: \"typography\",\n symptom: \"Body paragraphs full-width — hard to read.\",\n fix: \"Limit paragraph max-width to ~65ch. Increase line-height to 1.6+.\",\n uiNote: \"Wrap Typography.Paragraph in `<div style={{ maxWidth: '65ch' }}>`.\",\n },\n {\n category: \"typography\",\n symptom: \"Only Regular (400) + Bold (700) weights — flat hierarchy.\",\n fix: \"Introduce Medium (500) + SemiBold (600) for subtle weight contrasts.\",\n },\n {\n category: \"typography\",\n symptom: \"Numbers in proportional font — columns jitter in tables.\",\n fix: \"`font-variant-numeric: tabular-nums` for data, or a monospace font like Geist Mono.\",\n uiNote: \"Table primitive already uses `tabular-nums` on `.num` cells. For ad-hoc numeric labels, add the CSS prop manually.\",\n },\n {\n category: \"typography\",\n symptom: \"Orphaned words — single word on the last line of a heading.\",\n fix: \"`text-wrap: balance` (h1/h2/h3) or `text-wrap: pretty` (body).\",\n },\n {\n category: \"typography\",\n symptom: \"Title Case On Every Header.\",\n fix: \"Use sentence case instead. More modern, easier to read.\",\n },\n\n // ── color / surface ────────────────────────────────────────────\n {\n category: \"color-surface\",\n symptom: \"Pure #000000 background.\",\n fix: \"Replace with off-black (#0A0A0A) / dark charcoal (#121212) / tinted dark (deep navy).\",\n uiNote: \"Framework dark theme already uses tinted dark values — verify the consumer's override didn't force pure black.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Oversaturated accent colors.\",\n fix: \"Keep saturation below 80%. Desaturate so accents BLEND with neutrals rather than scream.\",\n },\n {\n category: \"color-surface\",\n symptom: \"More than one accent color competing.\",\n fix: \"Pick ONE. Remove the rest. Consistency beats variety in palette.\",\n uiNote: \"Set ONE `data-accent` at `<html>` root. Use semantic colors (success / warning / destructive) only for genuinely semantic content.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Purple/blue 'AI gradient' aesthetic — most common AI fingerprint.\",\n fix: \"Replace with neutral base + ONE considered accent. Drop the gradient entirely if it has no narrative purpose.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Generic black `box-shadow` everywhere.\",\n fix: \"Tint shadow to match background hue (e.g. cool gray bg → cool gray shadow). Colored shadows over pure black.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Random dark section breaking an otherwise light page.\",\n fix: \"Either commit to full dark mode OR keep light consistently. If contrast needed, use a SLIGHTLY darker shade of the same palette — not a sudden jump to #111.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Empty flat sections with no visual depth.\",\n fix: \"Add subtle background imagery at low opacity (`/picsum.photos/seed/{name}/1920/1080`) OR ambient gradient at 0.02-0.05 opacity. Empty flat = unfinished.\",\n },\n\n // ── layout ─────────────────────────────────────────────────────\n {\n category: \"layout\",\n symptom: \"Everything centered + symmetric.\",\n fix: \"Break symmetry: offset margins, mixed aspect ratios, left-aligned header over centered body.\",\n },\n {\n category: \"layout\",\n symptom: \"Three equal card columns as feature row — the most generic AI layout.\",\n fix: \"Replace with 2-column zig-zag, asymmetric grid, horizontal scroll, or masonry. The 3-equal-cols pattern is RED FLAG #1.\",\n uiNote: \"Use Bento Grid (custom CSS grid with `gridColumn: 'span N'`) instead of `<Grid cols={3}>` for hero sections.\",\n },\n {\n category: \"layout\",\n symptom: \"`height: 100vh` causing iOS Safari jump.\",\n fix: \"Use `min-height: 100dvh` (dynamic viewport) instead.\",\n },\n {\n category: \"layout\",\n symptom: \"No max-width container — content stretches edge-to-edge.\",\n fix: \"Add a container constraint (1200-1440px) with `margin: auto`. Or use `max-w-4xl / max-w-5xl` for content-heavy pages.\",\n uiNote: \"Framework's PageContent constrains via `var(--container-max-width)`. Consumer may override.\",\n },\n {\n category: \"layout\",\n symptom: \"Cards forced to same height by flexbox.\",\n fix: \"Allow variable heights or use masonry when content varies.\",\n uiNote: \"Use Masonry primitive — handles variable heights without flexbox stretch.\",\n },\n {\n category: \"layout\",\n symptom: \"Buttons at random vertical positions in card rows.\",\n fix: \"Pin CTAs to card bottom — same Y-position across the row regardless of content above.\",\n uiNote: \"Card's `actions` footer slot bottom-aligns automatically.\",\n },\n {\n category: \"layout\",\n symptom: \"Feature lists starting at different vertical positions in pricing tables.\",\n fix: \"Fixed-height title/price block + consistent spacing above the feature list. Cards align across columns.\",\n },\n {\n category: \"layout\",\n symptom: \"Dashboard ALWAYS has a left sidebar.\",\n fix: \"Consider top navigation, floating command menu, or collapsible panel. Sidebar isn't the only chrome.\",\n uiNote: \"Framework supports both — AppShell with sidebar slot is optional; can use Topbar-only for some flows.\",\n },\n\n // ── interactivity ──────────────────────────────────────────────\n {\n category: \"interactivity\",\n symptom: \"No hover states on buttons.\",\n fix: \"Background shift, scale, or translate on hover — 150-200ms ease.\",\n uiNote: \"Framework Button has built-in hover. If overridden — restore.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No active/pressed feedback.\",\n fix: \"`scale(0.98)` or `translateY(1px)` on `:active`. Simulates a physical click.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No focus ring (`outline: none`).\",\n fix: \"Restore visible `:focus-visible` ring. Accessibility requirement, not optional.\",\n },\n {\n category: \"interactivity\",\n symptom: \"Generic circular spinner for page-level loading.\",\n fix: \"Replace with Skeleton placeholders matching the eventual content shape.\",\n uiNote: \"Framework Skeleton + Form `loading={{ kind: 'skeleton' }}` handles cascading initial-fetch state.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No empty states — empty dashboard shows nothing.\",\n fix: \"Design a composed 'getting started' view: Empty primitive with title + description + next-action button.\",\n },\n {\n category: \"interactivity\",\n symptom: \"`window.alert()` for errors.\",\n fix: \"Inline error in the relevant Field, OR toast for non-form errors, OR Dialog for blocking errors.\",\n },\n {\n category: \"interactivity\",\n symptom: \"Dead links (`href='#'`).\",\n fix: \"Either link to real destinations or visually disable the button.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No indication of current page in navigation.\",\n fix: \"Style the active nav link distinctly.\",\n uiNote: \"Sidebar handles via `activeId` — pass it.\",\n },\n\n // ── content ────────────────────────────────────────────────────\n {\n category: \"content\",\n symptom: \"Generic names — 'John Doe', 'Jane Smith'.\",\n fix: \"Diverse, realistic names. For Japanese apps: 田中 太郎, 佐藤 美咲, Nguyễn Lan, Maria Cruz.\",\n },\n {\n category: \"content\",\n symptom: \"Fake round numbers — '99.99%', '50%', '$100.00'.\",\n fix: \"Organic data: '47.2%', '$99.00', '+1 (312) 847-1928'.\",\n },\n {\n category: \"content\",\n symptom: \"Placeholder brand names — Acme, Nexus, SmartFlow.\",\n fix: \"Invent contextual believable brands or use the consumer's real brand.\",\n },\n {\n category: \"content\",\n symptom: \"AI copy clichés — 'elevate', 'seamless', 'unleash', 'next-gen', 'game-changer', 'delve', 'tapestry', 'in the world of'.\",\n fix: \"Plain specific language. Numbers, nouns, verbs.\",\n uiNote: \"Framework's cardinal rule 9 bans this in framework docs; same discipline applies to consumer copy.\",\n },\n {\n category: \"content\",\n symptom: \"Exclamation marks in success messages.\",\n fix: \"Remove. Be confident, not loud.\",\n },\n {\n category: \"content\",\n symptom: \"'Oops!' or apologetic error messages.\",\n fix: \"Direct + specific: 'Connection failed. Please try again.' / 'メールアドレスの形式が正しくありません'.\",\n },\n {\n category: \"content\",\n symptom: \"Lorem Ipsum.\",\n fix: \"Real draft copy. Even rough placeholder beats Latin.\",\n },\n\n // ── components ─────────────────────────────────────────────────\n {\n category: \"components\",\n symptom: \"Generic card look (border + shadow + white).\",\n fix: \"Remove border OR shadow OR background — keep ONE. Cards exist only when elevation communicates hierarchy.\",\n },\n {\n category: \"components\",\n symptom: \"Always one filled + one ghost button.\",\n fix: \"Add text links / tertiary styles for variety.\",\n uiNote: \"Button has `variant='link'` for tertiary actions.\",\n },\n {\n category: \"components\",\n symptom: \"3-card carousel testimonials with dots.\",\n fix: \"Replace with masonry wall of quotes, embedded social posts, or single rotating quote.\",\n },\n {\n category: \"components\",\n symptom: \"Pricing table with 3 equal towers.\",\n fix: \"Highlight recommended tier with COLOR and emphasis, not just extra height.\",\n },\n {\n category: \"components\",\n symptom: \"Modals for everything.\",\n fix: \"Use inline editing, Sheet (slide-over), or expandable Collapse for simple actions. Reserve Dialog for true blocking decisions.\",\n },\n {\n category: \"components\",\n symptom: \"Footer link farm with 4 columns.\",\n fix: \"Simplify. Main nav paths + legally required links. No marketing kitchen sink.\",\n },\n\n // ── iconography ────────────────────────────────────────────────\n {\n category: \"iconography\",\n symptom: \"Lucide or Feather icons exclusively.\",\n fix: \"Use Phosphor (Bold / Fill), Heroicons, or a custom set. AI default tell.\",\n uiNote: \"Framework ships with lucide as locked dependency (rule 14). For editorial differentiation, layer Phosphor on top.\",\n },\n {\n category: \"iconography\",\n symptom: \"Cliche icon metaphors — rocketship 'launch', shield 'security'.\",\n fix: \"Less obvious: bolt, fingerprint, spark, vault, gem.\",\n },\n {\n category: \"iconography\",\n symptom: \"Stock 'diverse team in office' photo.\",\n fix: \"Real team photos, candid shots, or a consistent illustration style. Avatar initials fallback > generic stock person.\",\n },\n\n // ── code quality ───────────────────────────────────────────────\n {\n category: \"code-quality\",\n symptom: \"Div soup — no semantic HTML.\",\n fix: \"`<nav>`, `<main>`, `<article>`, `<aside>`, `<section>` for landmarks.\",\n uiNote: \"AppShell renders the canonical landmark structure automatically.\",\n },\n {\n category: \"code-quality\",\n symptom: \"Inline styles mixed with CSS classes haphazardly.\",\n fix: \"Move styling into the project's system. Inline `style={{}}` only for layout / positioning (rule 29).\",\n },\n {\n category: \"code-quality\",\n symptom: \"Missing alt text on images.\",\n fix: \"Describe content for SR. Never leave `alt=''` or `alt='image'` on meaningful images.\",\n },\n {\n category: \"code-quality\",\n symptom: \"Arbitrary z-index values like `9999`.\",\n fix: \"Establish a clean z-index scale in CSS variables.\",\n },\n\n // ── strategic omissions ────────────────────────────────────────\n {\n category: \"omissions\",\n symptom: \"No legal links in footer.\",\n fix: \"Add Privacy Policy + Terms of Service.\",\n },\n {\n category: \"omissions\",\n symptom: \"Dead ends in user flows — no 'back'.\",\n fix: \"Every page has a way back. Breadcrumb, back button, OR clear nav state.\",\n },\n {\n category: \"omissions\",\n symptom: \"No custom 404 page.\",\n fix: \"Design a helpful branded 404 with a way home and search.\",\n },\n {\n category: \"omissions\",\n symptom: \"No form validation.\",\n fix: \"Client-side validation via zod schema. Framework's Form + FormField handle field-level errors automatically.\",\n },\n {\n category: \"omissions\",\n symptom: \"No 'skip to content' link.\",\n fix: \"Hidden skip-link, first focusable element. Essential for keyboard users.\",\n uiNote: \"AppShell renders one automatically.\",\n },\n];\n\nexport const FIX_PRIORITY = [\n \"1. Font swap — biggest instant improvement, lowest risk\",\n \"2. Color palette cleanup — remove clashing / oversaturated colors\",\n \"3. Hover + active states — makes the interface feel alive\",\n \"4. Layout + spacing — proper grid, max-width, consistent padding\",\n \"5. Replace generic components — swap cliche patterns for modern alternatives\",\n \"6. Add loading, empty, error states — makes it feel finished\",\n \"7. Polish typography scale + spacing — the premium final touch\",\n];\n\nexport const REDESIGN_RULES = [\n \"Work with the existing tech stack. Do NOT migrate frameworks or styling libraries.\",\n \"Do NOT break existing functionality. Test after every change.\",\n \"Before importing any new library, check `package.json` first.\",\n \"Keep changes reviewable + focused. Small targeted improvements over big rewrites.\",\n \"Run the audit before fixing — listing issues first prevents accidental scope creep.\",\n];\n\nexport function checksByCategory(cat: AuditCheck[\"category\"]): AuditCheck[] {\n return REDESIGN_CHECKS.filter((c) => c.category === cat);\n}\n","/**\n * Tool registry — declares MCP tool schemas + dispatches calls.\n *\n * Token-efficient design (per PLAN.md):\n * - `list_*` returns SMALL metadata (1-line each).\n * - `get_*` / `get_*_section` returns ONE focused unit.\n * - `route_task` returns a SMALL pointer to skill+section.\n *\n * The agent walks: list → narrow → drill into one section. Avoids\n * dumping 50KB blobs.\n */\n\nimport {\n COMPONENTS,\n componentsByGroup,\n findComponent,\n type ComponentGroup,\n} from \"../data/components.js\";\nimport { PROP_VOCABULARY, findVocab } from \"../data/prop-vocabulary.js\";\nimport { TOKENS, tokensByCategory, type TokenCategory } from \"../data/tokens.js\";\nimport { CARDINAL_RULES, findRule } from \"../data/rules.js\";\nimport { PATTERNS, findPattern, searchPatterns } from \"../data/patterns.js\";\nimport { SKILLS, findSkill, findSection, routeTask } from \"../data/skills-index.js\";\nimport { ANTI_AI_TELLS, aiTellsByCategory, type AiTell } from \"../data/anti-ai-tells.js\";\nimport { REDESIGN_CHECKS, FIX_PRIORITY, REDESIGN_RULES, checksByCategory, type AuditCheck } from \"../data/redesign-audit.js\";\n\nexport const TOOL_DEFINITIONS = [\n // ── DISCOVERY (small responses) ────────────────────────────────\n {\n name: \"list_skills\",\n description:\n \"List every design / taste skill bundled by this MCP (taste / soft / minimalist / brutalist / gpt-tasteskill / redesign / output / brandkit / stitch / imagegen-mobile / imagegen-web / image-to-code). Returns id + name + whenToUse + section ids. ~1KB. Use FIRST to discover what skills exist; then `get_skill_section` to drill in.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_primitives\",\n description:\n \"List every @godxjp/ui primitive / composite / shell. Returns group + tagline per entry. ~3KB. Optionally filter by group.\",\n inputSchema: {\n type: \"object\",\n properties: {\n group: {\n type: \"string\",\n enum: [\"general\", \"layout\", \"data-display\", \"data-entry\", \"feedback\", \"navigation\", \"composites\", \"shell\", \"providers\"],\n },\n },\n },\n },\n {\n name: \"list_patterns\",\n description: \"List every canonical code pattern (registration-form / settings-page / data-table / confirm-destructive / app-shell / filter-bar / loading-states). ~500 bytes. Use before `get_pattern`.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_anti_ai_tells\",\n description:\n \"List every AI-tell pattern to AVOID (organised by category: visual / layout / copy / interaction / imagery / structure). ~2KB. Use to self-audit a design before shipping.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: { type: \"string\", enum: [\"visual\", \"layout\", \"copy\", \"interaction\", \"imagery\", \"structure\"] },\n },\n },\n },\n {\n name: \"list_redesign_checks\",\n description:\n \"List the redesign audit checklist (50+ checks across 9 categories: typography / color-surface / layout / interactivity / content / components / iconography / code-quality / omissions). ~5KB. Use when auditing an existing project.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: { type: \"string\", enum: [\"typography\", \"color-surface\", \"layout\", \"interactivity\", \"content\", \"components\", \"iconography\", \"code-quality\", \"omissions\"] },\n },\n },\n },\n\n // ── DRILL-DOWN (medium responses) ──────────────────────────────\n {\n name: \"get_anti_ai_tell\",\n description: \"Fetch ONE anti-AI-tell — full body + concrete fix. Use after `list_anti_ai_tells`.\",\n inputSchema: {\n type: \"object\",\n properties: { name: { type: \"string\", description: \"Exact tell name from list_anti_ai_tells.\" } },\n required: [\"name\"],\n },\n },\n {\n name: \"get_redesign_check\",\n description: \"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.\",\n inputSchema: {\n type: \"object\",\n properties: { symptom: { type: \"string\", description: \"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh').\" } },\n required: [\"symptom\"],\n },\n },\n {\n name: \"get_skill_section\",\n description:\n \"Fetch ONE section of ONE skill — token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.\",\n inputSchema: {\n type: \"object\",\n properties: {\n skill: { type: \"string\", description: \"Skill id (e.g. 'soft', 'minimalist', 'taste').\" },\n section: { type: \"string\", description: \"Section id within that skill.\" },\n },\n required: [\"skill\", \"section\"],\n },\n },\n {\n name: \"get_component\",\n description: \"Full API for one @godxjp/ui component — props, types, default, example, story + doc paths, cardinal rules. ~2KB.\",\n inputSchema: {\n type: \"object\",\n properties: { name: { type: \"string\", description: \"Component name (e.g. 'Button', 'DataTable').\" } },\n required: [\"name\"],\n },\n },\n {\n name: \"get_pattern\",\n description: \"Full code snippet for one canonical pattern — copy-paste-ready.\",\n inputSchema: {\n type: \"object\",\n properties: { name: { type: \"string\", description: \"Pattern slug (use list_patterns first).\" } },\n required: [\"name\"],\n },\n },\n {\n name: \"get_rule\",\n description: \"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.\",\n inputSchema: {\n type: \"object\",\n properties: { number: { type: \"number\", description: \"Rule number (1-N).\" } },\n },\n },\n {\n name: \"get_vocab\",\n description: \"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.\",\n inputSchema: {\n type: \"object\",\n properties: { name: { type: \"string\", description: \"Vocab type name.\" } },\n },\n },\n {\n name: \"get_tokens\",\n description: \"Read design tokens, optionally filtered by category.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: { type: \"string\", enum: [\"color\", \"spacing\", \"typography\", \"radius\", \"shadow\", \"motion\", \"breakpoint\", \"density\", \"z-index\"] },\n },\n },\n },\n\n // ── TASK ROUTING (smallest response — pointer) ─────────────────\n {\n name: \"route_task\",\n description:\n \"Natural-language task → skill+section pointer. ~300 bytes. E.g. 'I want to design a premium agency hero' → `{skill:'soft', section:'vibe-archetypes', why:'...'}`. Use FIRST when you don't know which skill applies.\",\n inputSchema: {\n type: \"object\",\n properties: { task: { type: \"string\", description: \"Describe what you want to build.\" } },\n required: [\"task\"],\n },\n },\n {\n name: \"suggest_primitive\",\n description:\n \"Use case → primitive recommendation. E.g. 'confirm a destructive delete' → DangerZone pattern + Dialog suggestion.\",\n inputSchema: {\n type: \"object\",\n properties: { use_case: { type: \"string\" } },\n required: [\"use_case\"],\n },\n },\n {\n name: \"search_components\",\n description: \"Fuzzy-search primitives by name / tagline / prop. Returns ranked matches.\",\n inputSchema: {\n type: \"object\",\n properties: { query: { type: \"string\" } },\n required: [\"query\"],\n },\n },\n\n // ── LINT / AUDIT (one-shot critique) ───────────────────────────\n {\n name: \"lint_jsx\",\n description:\n \"Heuristic check of a JSX snippet for common violations — raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.\",\n inputSchema: {\n type: \"object\",\n properties: { jsx: { type: \"string\" } },\n required: [\"jsx\"],\n },\n },\n];\n\nexport async function dispatchTool(\n name: string,\n args: Record<string, unknown>,\n): Promise<string> {\n switch (name) {\n // Discovery\n case \"list_skills\": return listSkills();\n case \"list_primitives\": return listPrimitives(args.group as ComponentGroup | undefined);\n case \"list_patterns\": return listPatterns();\n case \"list_anti_ai_tells\": return listAntiAiTells(args.category as AiTell[\"category\"] | undefined);\n case \"list_redesign_checks\": return listRedesignChecks(args.category as AuditCheck[\"category\"] | undefined);\n case \"get_anti_ai_tell\": return getAntiAiTell(String(args.name ?? \"\"));\n case \"get_redesign_check\": return getRedesignCheck(String(args.symptom ?? \"\"));\n // Drill-down\n case \"get_skill_section\": return getSkillSection(String(args.skill ?? \"\"), String(args.section ?? \"\"));\n case \"get_component\": return getComponent(String(args.name ?? \"\"));\n case \"get_pattern\": return getPattern(String(args.name ?? \"\"));\n case \"get_rule\": return getRule(typeof args.number === \"number\" ? args.number : undefined);\n case \"get_vocab\": return getVocab(args.name as string | undefined);\n case \"get_tokens\": return getTokens(args.category as TokenCategory | undefined);\n // Task routing\n case \"route_task\": return routeTaskTool(String(args.task ?? \"\"));\n case \"suggest_primitive\": return suggestPrimitive(String(args.use_case ?? \"\"));\n case \"search_components\": return searchComponents(String(args.query ?? \"\"));\n // Lint\n case \"lint_jsx\": return lintJsx(String(args.jsx ?? \"\"));\n default: return `Unknown tool: ${name}`;\n }\n}\n\n// ── implementations ───────────────────────────────────────────────\n\nfunction listSkills(): string {\n let out = `# Available skills (${SKILLS.length})\\n\\n`;\n out += `Use \\`get_skill_section skill=\"...\" section=\"...\"\\` to drill in.\\n\\n`;\n for (const s of SKILLS) {\n out += `## ${s.id} — ${s.name}\\n`;\n out += `**When to use:** ${s.whenToUse}\\n\\n`;\n out += `**Sections:** ${s.sections.map((sec) => `\\`${sec.id}\\``).join(\", \")}\\n\\n`;\n }\n out += `\\n_Source: ${SKILLS.map((s) => s.source).filter((v, i, a) => a.indexOf(v) === i).slice(0, 3).join(\"; \")}, …_`;\n return out;\n}\n\nfunction listPrimitives(group?: ComponentGroup): string {\n const list = group ? componentsByGroup(group) : COMPONENTS;\n if (list.length === 0) return `No components${group ? ` in group \"${group}\"` : \"\"}.`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, c) => {\n (acc[c.group] ??= []).push(c);\n return acc;\n }, {});\n let out = `# @godxjp/ui primitives${group ? ` — ${group}` : \"\"}\\n\\n${list.length} components.\\n\\n`;\n for (const [g, items] of Object.entries(grouped)) {\n out += `## ${g}\\n\\n`;\n for (const c of items) out += `- **${c.name}** — ${c.tagline}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction listPatterns(): string {\n let out = `# Canonical patterns (${PATTERNS.length})\\n\\n`;\n for (const p of PATTERNS) {\n out += `- **${p.name}** — ${p.tagline} \\n _tags: ${p.tags.join(\", \")}_\\n`;\n }\n return out;\n}\n\nfunction listAntiAiTells(cat?: AiTell[\"category\"]): string {\n const list = cat ? aiTellsByCategory(cat) : ANTI_AI_TELLS;\n // Compact list — names only. Use `get_anti_ai_tell` for full body + fix.\n let out = `# AI tells to AVOID${cat ? ` — ${cat}` : \"\"} (${list.length})\\n\\n`;\n out += `_Compact list. Use \\`get_anti_ai_tell name=\"<name>\"\\` for the full body + fix._\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, t) => {\n (acc[t.category] ??= []).push(t);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n`;\n for (const t of items) out += `- ${t.name}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction getAntiAiTell(name: string): string {\n const t = ANTI_AI_TELLS.find((x) => x.name.toLowerCase() === name.trim().toLowerCase());\n if (!t) {\n let out = `Anti-AI-tell \"${name}\" not found. Use \\`list_anti_ai_tells\\` to discover. Closest:\\n\\n`;\n for (const x of ANTI_AI_TELLS.slice(0, 8)) out += `- ${x.name} (${x.category})\\n`;\n return out;\n }\n return `# ${t.name}\\n\\n**Category:** ${t.category}\\n\\n## Symptom\\n\\n${t.body}\\n\\n## Fix\\n\\n${t.fix}\\n`;\n}\n\nfunction listRedesignChecks(cat?: AuditCheck[\"category\"]): string {\n const list = cat ? checksByCategory(cat) : REDESIGN_CHECKS;\n // Compact list — symptoms only. Use `get_redesign_check` for the full fix + ui-note.\n let out = `# Redesign audit${cat ? ` — ${cat}` : \"\"} (${list.length} checks)\\n\\n`;\n if (!cat) {\n out += `## Fix priority\\n${FIX_PRIORITY.map((p) => p).join(\"\\n\")}\\n\\n`;\n out += `## Rules\\n${REDESIGN_RULES.map((r) => `- ${r}`).join(\"\\n\")}\\n\\n`;\n }\n out += `_Compact list of symptoms. Use \\`get_redesign_check symptom=\"<text snippet>\"\\` for the full fix + UI note._\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, c) => {\n (acc[c.category] ??= []).push(c);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n`;\n for (const item of items) out += `- ${item.symptom}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction getRedesignCheck(snippet: string): string {\n const q = snippet.trim().toLowerCase();\n if (!q) return \"Pass `symptom` — a fragment matching the audit check symptom (e.g. 'Inter everywhere' / '100vh' / 'Acme').\";\n const matches = REDESIGN_CHECKS.filter(\n (c) => c.symptom.toLowerCase().includes(q) || c.fix.toLowerCase().includes(q),\n );\n if (!matches.length) {\n return `No redesign check matches \"${snippet}\". Use \\`list_redesign_checks\\` to see all.`;\n }\n let out = `# Redesign checks matching \"${snippet}\" (${matches.length})\\n\\n`;\n for (const c of matches) {\n out += `## ${c.category}\\n\\n**Symptom:** ${c.symptom}\\n\\n**Fix:** ${c.fix}\\n${c.uiNote ? `\\n_UI note:_ ${c.uiNote}\\n` : \"\"}\\n`;\n }\n return out;\n}\n\nfunction getSkillSection(skillId: string, sectionId: string): string {\n const skill = findSkill(skillId);\n if (!skill) return `Skill \"${skillId}\" not found. Use \\`list_skills\\` for available ids.`;\n if (!sectionId) {\n let out = `# ${skill.name}\\n\\n${skill.whenToUse}\\n\\n## Sections\\n`;\n for (const sec of skill.sections) out += `- \\`${sec.id}\\` — ${sec.tagline}\\n`;\n return out;\n }\n const section = findSection(skillId, sectionId);\n if (!section) {\n let out = `Section \"${sectionId}\" not in skill \"${skillId}\". Available:\\n`;\n for (const sec of skill.sections) out += `- \\`${sec.id}\\` — ${sec.tagline}\\n`;\n return out;\n }\n return `# ${skill.name} → ${section.title}\\n\\n${section.tagline}\\n\\n${section.body}\\n\\n_Source: ${skill.source}_`;\n}\n\nfunction getComponent(name: string): string {\n const c = findComponent(name);\n if (!c) return `Component \"${name}\" not found. Use \\`list_primitives\\` to discover.`;\n let out = `# ${c.name}\\n\\n**Group:** ${c.group}\\n\\n${c.tagline}\\n\\n## Props\\n\\n`;\n out += `| Name | Type | Required | Default | Description |\\n|---|---|---|---|---|\\n`;\n for (const p of c.props) {\n out += `| \\`${p.name}\\` | \\`${p.type}\\` | ${p.required ? \"✓\" : \"\"} | ${p.defaultValue ? `\\`${p.defaultValue}\\`` : \"\"} | ${p.description} |\\n`;\n }\n out += `\\n## Example\\n\\n\\`\\`\\`tsx\\n${c.example}\\n\\`\\`\\`\\n\\n`;\n if (c.docPath) out += `**Reference doc:** \\`docs/reference/${c.docPath}\\`\\n\\n`;\n out += `**Storybook:** \\`src/stories/${c.storyPath}\\`\\n\\n`;\n out += `**Cardinal rules:** ${c.rules.map((n) => `#${n}`).join(\", \")}\\n`;\n return out;\n}\n\nfunction getPattern(name: string): string {\n const p = findPattern(name);\n if (!p) {\n const candidates = searchPatterns(name);\n if (candidates.length === 0) return `Pattern \"${name}\" not found.`;\n let out = `Pattern \"${name}\" not found. Closest:\\n`;\n for (const c of candidates) out += `- ${c.name} — ${c.tagline}\\n`;\n return out;\n }\n return `# Pattern: ${p.name}\\n\\n${p.tagline}\\n\\n**Tags:** ${p.tags.join(\", \")}\\n\\n\\`\\`\\`tsx\\n${p.code}\\n\\`\\`\\`\\n`;\n}\n\nfunction getRule(num?: number): string {\n if (num !== undefined) {\n const r = findRule(num);\n if (!r) return `Rule ${num} not found. Valid: 1-${CARDINAL_RULES.length}.`;\n return `# Rule ${r.number} — ${r.title}\\n\\n${r.body}\\n`;\n }\n let out = `# Cardinal rules (${CARDINAL_RULES.length})\\n\\n`;\n for (const r of CARDINAL_RULES) out += `## ${r.number}. ${r.title}\\n\\n${r.body}\\n\\n`;\n return out;\n}\n\nfunction getVocab(name?: string): string {\n if (name) {\n const v = findVocab(name);\n if (!v) return `Vocab \"${name}\" not found.`;\n let out = `# ${v.name}\\n\\n${v.concept}\\n\\n`;\n out += `**Values:** ${v.values.map((x) => `\\`${x}\\``).join(\" | \")}\\n\\n`;\n out += `**Used by:** ${v.usedBy.map((x) => `\\`${x}\\``).join(\", \")}\\n\\n`;\n if (v.notes) out += `**Notes:** ${v.notes}\\n`;\n return out;\n }\n let out = `# Prop vocabulary\\n\\n${PROP_VOCABULARY.length} shared types.\\n\\n`;\n for (const v of PROP_VOCABULARY) {\n out += `## ${v.name}\\n${v.concept}\\n\\nValues: ${v.values.map((x) => `\\`${x}\\``).join(\" | \")}\\n\\n`;\n }\n return out;\n}\n\nfunction getTokens(cat?: TokenCategory): string {\n const list = cat ? tokensByCategory(cat) : TOKENS;\n if (list.length === 0) return `No tokens${cat ? ` in \"${cat}\"` : \"\"}.`;\n let out = `# Design tokens${cat ? ` — ${cat}` : \"\"}\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, t) => {\n (acc[t.category] ??= []).push(t);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n\\n| Name | Role | Value | Axis |\\n|---|---|---|---|\\n`;\n for (const t of items) out += `| \\`${t.name}\\` | ${t.role} | ${t.value ?? \"—\"} | ${t.axis ?? \"—\"} |\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction routeTaskTool(task: string): string {\n if (!task.trim()) return \"Describe the task (e.g. 'design a premium agency hero', 'audit existing settings page').\";\n const results = routeTask(task);\n let out = `# Routing \"${task}\"\\n\\n`;\n for (const r of results) {\n out += `- **skill:** \\`${r.skill}\\`, **section:** \\`${r.section}\\` \\n ${r.why}\\n`;\n if (r.alsoSee?.length) out += ` _Also see:_ ${r.alsoSee.map((s) => `\\`${s}\\``).join(\", \")}\\n`;\n }\n out += `\\nFetch with: \\`get_skill_section skill=\"X\" section=\"Y\"\\``;\n return out;\n}\n\nfunction suggestPrimitive(useCase: string): string {\n const q = useCase.trim().toLowerCase();\n if (!q) return \"Describe your use case.\";\n const suggestions: Array<{ component: string; rationale: string; score: number }> = [];\n const check = (kw: string[], component: string, rationale: string, weight = 2) => {\n if (kw.some((k) => q.includes(k))) suggestions.push({ component, rationale, score: weight });\n };\n check([\"form\", \"submit\", \"validation\", \"register\", \"sign up\"], \"Form + FormField\", \"RHF + zod composition.\", 5);\n check([\"table\", \"rows\", \"columns\"], \"DataTable / Table\", \"DataTable for chrome (toolbar+pagination+batch). Table for slim primitive.\", 5);\n check([\"modal\", \"dialog\", \"confirm\"], \"Dialog / AlertDialog\", \"Radix Dialog. AlertDialog for destructive.\", 4);\n check([\"drawer\", \"side panel\", \"sheet\"], \"Sheet\", \"Side panel for filters/settings.\", 4);\n check([\"toast\", \"notification\"], \"toast / Toaster\", \"Sonner-backed.\", 4);\n check([\"loading\", \"saving\", \"spinner\"], \"Spinner / Form loading prop\", \"Spinner=active work, Skeleton=init fetch.\", 3);\n check([\"alert\", \"banner\"], \"Alert\", \"5 semantic colors × outlined/banner.\", 3);\n check([\"select\", \"dropdown\"], \"Select / AutoComplete\", \"Select=discrete options, AutoComplete=free-text+suggestions.\", 3);\n check([\"filter\"], \"Form layout='inline' + pattern 'filter-bar'\", \"Inline form above table.\", 4);\n check([\"delete\", \"destructive\"], \"Pattern 'confirm-destructive'\", \"Card accent='destructive' + typed-name confirm.\", 4);\n if (!suggestions.length) return `No direct match for \"${useCase}\". Try \\`list_primitives\\` or \\`search_components\\`.`;\n suggestions.sort((a, b) => b.score - a.score);\n let out = `# Suggestions for \"${useCase}\"\\n\\n`;\n for (const s of suggestions) out += `- **${s.component}** — ${s.rationale}\\n`;\n return out;\n}\n\nfunction searchComponents(query: string): string {\n const q = query.trim().toLowerCase();\n if (!q) return listPrimitives();\n const matches = COMPONENTS.map((c) => {\n let score = 0;\n if (c.name.toLowerCase().includes(q)) score += 5;\n if (c.tagline.toLowerCase().includes(q)) score += 2;\n if (c.props.some((p) => p.name.toLowerCase().includes(q))) score += 1;\n return { c, score };\n })\n .filter((m) => m.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, 12);\n if (!matches.length) return `No matches for \"${query}\".`;\n let out = `# Search \"${query}\" — ${matches.length} matches\\n\\n`;\n for (const { c, score } of matches) out += `- **${c.name}** (${c.group}, ${score}) — ${c.tagline}\\n`;\n return out;\n}\n\nfunction lintJsx(jsx: string): string {\n const issues: string[] = [];\n const check = (regex: RegExp, msg: string) => { if (regex.test(jsx)) issues.push(msg); };\n // Lowercase HTML tags only — React PascalCase (Button) MUST NOT match.\n check(/<button[\\s>]/, \"Use `<Button>` instead of raw `<button>` (rule 29).\");\n check(/<input[\\s>]/, \"Use `<Input>` instead of raw `<input>` (rule 29).\");\n check(/<select[\\s>]/, \"Use `<Select>` instead of raw `<select>` (rule 29).\");\n check(/<textarea[\\s>]/, \"Use `<Textarea>` instead of raw `<textarea>` (rule 29).\");\n check(/bg-(red|blue|green|yellow|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|indigo|violet|purple|fuchsia|pink|rose)-\\d{2,3}\\b/, \"Use semantic token utilities (`bg-primary`/`bg-destructive`) not raw color scales (rule 2).\");\n check(/<Tag[\\s\\S]*?color=[\"']error[\"']/i, 'Tag `color=\"error\"` → `\"destructive\"` (v5.0, PR #60).');\n check(/<Badge[\\s\\S]*?variant=[\"']error[\"']/i, 'Badge `variant=\"error\"` → `\"destructive\"` (v5.0, PR #63).');\n check(/(Flex|Space|Grid|Masonry)[\\s\\S]*?(gap|size)=[\"']middle[\"']/i, '`\"middle\"` → `\"default\"` for Flex/Space/Grid/Masonry (v5.0).');\n check(/<IconButton[\\s\\S]*?size=[\"']default[\"']/i, 'IconButton `size=\"default\"` → `\"md\"` (v5.0).');\n check(/<SegmentedControl[\\s\\S]*?size=[\"']sm[\"']/i, 'SegmentedControl `size=\"sm\"` → `\"small\"` (v5.0).');\n check(/<PageContent[\\s\\S]*?padding=[\"'](compact|comfortable)[\"']/i, 'PageContent `padding=\"compact\"/\"comfortable\"` → `\"tight\"/\"cozy\"` (v5.0).');\n check(/<Pagination[\\s\\S]*?justify=[\"']between[\"']/i, 'Pagination `justify=\"between\"` → `\"space-between\"` (v5.0).');\n if (/<IconButton(?![^>]*aria-label)/i.test(jsx) && !/asChild/i.test(jsx)) {\n issues.push(\"`<IconButton>` should have `aria-label` (rule 6 — WCAG).\");\n }\n if (/cell:\\s*\\(\\{?\\s*row\\s*\\}?\\)\\s*=>/i.test(jsx) && /export\\s+const\\s+\\w+\\s*:\\s*Story/i.test(jsx)) {\n if (!/parameters[\\s\\S]{0,200}source[\\s\\S]{0,100}code:/i.test(jsx)) {\n issues.push(\"Stories with function-valued cell renderers MUST override `parameters.docs.source.code` (rule 34).\");\n }\n }\n // Anti-AI tells\n if (/text-(red|blue|green|yellow)-\\d{2,3}\\b/.test(jsx)) issues.push(\"Hard-coded color scales — use semantic tokens. Tells AI-slop palette (rule 2 + anti-AI-tells.visual.rainbow-chip-wall).\");\n if (/h-\\[?100vh\\]?/.test(jsx)) issues.push(\"`100vh` causes iOS Safari viewport jump — use `min-h-[100dvh]` (redesign.layout / soft.absolute-zero).\");\n if (/className=[\"'][^\"']*(?:shadow-md|shadow-lg|shadow-xl)[\"']/.test(jsx)) issues.push(\"Tailwind heavy shadows are an AI tell — use ultra-diffuse low-opacity (< 0.05) or tinted shadows (soft.absolute-zero, minimalist).\");\n if (/Inter|Roboto|Helvetica|Open\\s*Sans/i.test(jsx)) issues.push(\"Banned default fonts (Inter/Roboto/Helvetica/Open Sans). Use Geist/Clash Display/PP Editorial New (soft.absolute-zero, minimalist.negative-constraints).\");\n if (/Acme|NovaCore|Flowbit|Quantix|VeloPay|John\\s+Doe|Jane\\s+Smith|Lorem\\s+Ipsum/i.test(jsx)) issues.push(\"Generic placeholder content (Acme/NovaCore/John Doe/Lorem Ipsum). Use believable real-sounding names (anti-AI-tells.copy).\");\n if (issues.length === 0) return \"✅ No issues found against the heuristic checks.\";\n let out = `# Lint findings — ${issues.length} issue${issues.length === 1 ? \"\" : \"s\"}\\n\\n`;\n for (const i of issues) out += `- ${i}\\n`;\n out += `\\nNote: heuristic only — not a substitute for the full CI gate.\\n`;\n return out;\n}\n","/**\n * Resource registry — exposes catalogs as MCP resources so agents\n * can discover + browse them without invoking tools.\n *\n * godx-ui://components — full component catalog (JSON)\n * godx-ui://components/{name} — single component (Markdown)\n * godx-ui://prop-vocabulary — full vocab (JSON)\n * godx-ui://tokens — all tokens (JSON)\n * godx-ui://tokens/{category} — tokens in category (JSON)\n * godx-ui://rules — all cardinal rules (Markdown)\n * godx-ui://rules/{number} — single rule (Markdown)\n * godx-ui://patterns — pattern catalog (JSON)\n * godx-ui://patterns/{name} — single pattern (Markdown)\n */\n\nimport { COMPONENTS, findComponent } from \"../data/components.js\";\nimport { PROP_VOCABULARY } from \"../data/prop-vocabulary.js\";\nimport { TOKENS, tokensByCategory, type TokenCategory } from \"../data/tokens.js\";\nimport { CARDINAL_RULES, findRule } from \"../data/rules.js\";\nimport { PATTERNS, findPattern } from \"../data/patterns.js\";\n\nexport const RESOURCE_DEFINITIONS = [\n {\n uri: \"godx-ui://components\",\n name: \"All components\",\n description: \"Full component catalog as JSON — name, group, tagline, props, example, rules.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://prop-vocabulary\",\n name: \"Shared prop vocabulary\",\n description: \"Cross-cutting prop types (SizeProp, StatusProp, ColorProp, LoadingProp, …) as JSON.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://tokens\",\n name: \"All design tokens\",\n description: \"Every CSS variable + role + value + axis as JSON.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://rules\",\n name: \"Cardinal rules (34)\",\n description: \"The 34 binding rules from CLAUDE.md as Markdown.\",\n mimeType: \"text/markdown\",\n },\n {\n uri: \"godx-ui://patterns\",\n name: \"Code patterns\",\n description: \"Canonical pattern catalog (registration-form, settings-page, data-table, …) as JSON.\",\n mimeType: \"application/json\",\n },\n];\n\nexport async function readResource(uri: string): Promise<string> {\n // godx-ui://components\n if (uri === \"godx-ui://components\") {\n return JSON.stringify(COMPONENTS, null, 2);\n }\n // godx-ui://components/{name}\n if (uri.startsWith(\"godx-ui://components/\")) {\n const name = uri.slice(\"godx-ui://components/\".length);\n const c = findComponent(name);\n if (!c) throw new Error(`Component not found: ${name}`);\n return formatComponentMarkdown(c);\n }\n\n if (uri === \"godx-ui://prop-vocabulary\") {\n return JSON.stringify(PROP_VOCABULARY, null, 2);\n }\n\n if (uri === \"godx-ui://tokens\") {\n return JSON.stringify(TOKENS, null, 2);\n }\n if (uri.startsWith(\"godx-ui://tokens/\")) {\n const cat = uri.slice(\"godx-ui://tokens/\".length) as TokenCategory;\n return JSON.stringify(tokensByCategory(cat), null, 2);\n }\n\n if (uri === \"godx-ui://rules\") {\n let out = `# Cardinal rules (${CARDINAL_RULES.length})\\n\\n`;\n for (const r of CARDINAL_RULES) {\n out += `## ${r.number}. ${r.title}\\n\\n${r.body}\\n\\n`;\n }\n return out;\n }\n if (uri.startsWith(\"godx-ui://rules/\")) {\n const num = Number(uri.slice(\"godx-ui://rules/\".length));\n const r = findRule(num);\n if (!r) throw new Error(`Rule not found: ${num}`);\n return `# Rule ${r.number} — ${r.title}\\n\\n${r.body}\\n`;\n }\n\n if (uri === \"godx-ui://patterns\") {\n return JSON.stringify(PATTERNS.map(({ name, tagline, tags }) => ({ name, tagline, tags })), null, 2);\n }\n if (uri.startsWith(\"godx-ui://patterns/\")) {\n const name = uri.slice(\"godx-ui://patterns/\".length);\n const p = findPattern(name);\n if (!p) throw new Error(`Pattern not found: ${name}`);\n return `# ${p.name}\\n\\n${p.tagline}\\n\\n**Tags:** ${p.tags.join(\", \")}\\n\\n\\`\\`\\`tsx\\n${p.code}\\n\\`\\`\\`\\n`;\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n}\n\nfunction formatComponentMarkdown(c: ReturnType<typeof findComponent> & object): string {\n let out = `# ${c.name}\\n\\n**Group:** ${c.group}\\n\\n${c.tagline}\\n\\n`;\n out += `## Props\\n\\n`;\n out += `| Name | Type | Required | Default | Description |\\n|---|---|---|---|---|\\n`;\n for (const p of c.props) {\n out += `| \\`${p.name}\\` | \\`${p.type}\\` | ${p.required ? \"✓\" : \"\"} | ${p.defaultValue ? `\\`${p.defaultValue}\\`` : \"\"} | ${p.description} |\\n`;\n }\n out += `\\n## Example\\n\\n\\`\\`\\`tsx\\n${c.example}\\n\\`\\`\\`\\n`;\n return out;\n}\n"],"mappings":"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","names":["out"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/data/components.ts","../src/data/prop-vocabulary.ts","../src/data/tokens.ts","../src/data/rules.ts","../src/data/patterns.ts","../src/data/skills-index.ts","../src/data/anti-ai-tells.ts","../src/data/redesign-audit.ts","../src/tools/registry.ts","../src/resources/registry.ts"],"sourcesContent":["/**\n * @godxjp/ui-mcp — MCP server entry.\n *\n * Spawned over stdio by an MCP-aware agent (Claude Desktop, Cursor,\n * Continue, Cline, etc.) per the consumer's `.mcp.json` /\n * `claude_desktop_config.json`. Exposes a curated catalogue of the\n * @godxjp/ui framework so the agent can:\n *\n * - list primitives (with group / tagline / props / example)\n * - look up a single component's full API\n * - search by name / use-case / feature\n * - read the shared prop-vocabulary (`SizeProp`, `ColorProp`, …)\n * - read design tokens (per category)\n * - read cardinal rules (by number or all)\n * - fetch canonical code patterns (registration form, settings,\n * data table, app shell, …) — copy-paste-ready snippets\n * - lint a JSX snippet against the most common rule violations\n *\n * The server reads ONLY its own bundled data files. Zero filesystem\n * access into consumer projects, no network, no shell. Safe to mount\n * read-only.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { TOOL_DEFINITIONS, dispatchTool } from \"./tools/registry.js\";\nimport { RESOURCE_DEFINITIONS, readResource } from \"./resources/registry.js\";\n\nasync function main() {\n const server = new Server(\n {\n name: \"godx-ui-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n },\n );\n\n // ── tools ──────────────────────────────────────────────────────\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOL_DEFINITIONS,\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const result = await dispatchTool(name, (args ?? {}) as Record<string, unknown>);\n return { content: [{ type: \"text\", text: result }] };\n });\n\n // ── resources ──────────────────────────────────────────────────\n server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: RESOURCE_DEFINITIONS,\n }));\n\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n const text = await readResource(uri);\n return {\n contents: [\n {\n uri,\n mimeType: uri.endsWith(\".json\") ? \"application/json\" : \"text/markdown\",\n text,\n },\n ],\n };\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // Log to stderr so it doesn't pollute the stdio JSON-RPC channel.\n console.error(\"[godx-ui-mcp] connected (stdio)\");\n}\n\nmain().catch((err) => {\n console.error(\"[godx-ui-mcp] fatal:\", err);\n process.exit(1);\n});\n","/**\n * Component catalog — the REAL published `@godxjp/ui` v6 primitive surface.\n * The MCP bundles this so an agent can author pages with the actual API\n * (PageContainer, Stack, ResponsiveGrid, DataTable + ColumnDef, StatusBadge,\n * FormField, Select, Dialog, FilterBar, …) instead of guessing.\n *\n * Each entry maps to a real export. Import via the subpath in every example,\n * e.g. `import { DataTable } from \"@godxjp/ui/data-display\"`.\n *\n * Each entry carries:\n * - `name` — canonical export name\n * - `group` — entry-point group\n * - `tagline` — one-line elevator pitch\n * - `props` — most-used real props with type + description\n * - `example` — copy-paste-ready JSX using the real API\n * - `storyPath` — relative path under `src/stories/`\n * - `rules` — cardinal rules relevant to this primitive\n */\n\nexport type ComponentGroup =\n | \"general\"\n | \"layout\"\n | \"data-display\"\n | \"data-entry\"\n | \"feedback\"\n | \"navigation\"\n | \"composites\"\n | \"shell\"\n | \"providers\";\n\nexport interface ComponentProp {\n name: string;\n type: string;\n required?: boolean;\n description: string;\n defaultValue?: string;\n}\n\nexport interface ComponentEntry {\n name: string;\n group: ComponentGroup;\n /** Import subpath when it differs from the group convention (e.g. query helpers → \"@godxjp/ui/query\"). */\n importPath?: string;\n tagline: string;\n props: ComponentProp[];\n /** Detailed how-to-use guidance — DO/DON'T bullets (composition, controlled state, form name, a11y). */\n usage?: string[];\n /** Concrete scenarios this component is the right choice for. */\n useCases?: string[];\n /** Sibling/replacement components it is confused with, and when to pick each. */\n related?: string[];\n /** Deprecated components stay catalogued (so agents are steered to the replacement) but are flagged. */\n deprecated?: boolean;\n example: string;\n docPath?: string;\n storyPath: string;\n rules: number[];\n}\n\nexport const COMPONENTS: ComponentEntry[] = [\n // ─── layout ─────────────────────────────────────────────────────────────\n {\n name: \"PageContainer\",\n group: \"layout\",\n tagline:\n \"Mandatory page shell — EVERY page wraps its content in PageContainer (title/subtitle/extra/footer/breadcrumb).\",\n props: [\n {\n name: \"title\",\n type: \"string\",\n required: true,\n description: \"Page heading rendered as <h1>.\",\n },\n { name: \"subtitle\", type: \"string\", description: \"Secondary line beneath the title.\" },\n {\n name: \"extra\",\n type: \"ReactNode\",\n description: \"Action buttons / controls rendered right of the title row.\",\n },\n {\n name: \"footer\",\n type: \"ReactNode\",\n description: \"Content area pinned below the page body.\",\n },\n {\n name: \"breadcrumb\",\n type: \"BreadcrumbItemProp[]\",\n description: \"Ordered trail of { label, to? } segments above the title.\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"narrow\" | \"flush\" | \"ghost\"',\n defaultValue: '\"default\"',\n description: \"Page shell layout; flush removes padding for full-bleed content.\",\n },\n {\n name: \"density\",\n type: '\"compact\" | \"default\" | \"comfortable\"',\n defaultValue: '\"default\"',\n description: \"Spacing density across the page subtree.\",\n },\n {\n name: \"stickyFooter\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: 'Pin footer to viewport bottom on scroll — pairs with variant=\"narrow\".',\n },\n ],\n example: `import { PageContainer, Stack } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\nexport default function OrdersPage() {\n return (\n <PageContainer\n title=\"注文一覧\"\n subtitle=\"直近30日間の受注データ\"\n breadcrumb={[{ label: \"ホーム\", to: \"/\" }, { label: \"注文一覧\" }]}\n extra={<Button>新規注文</Button>}\n >\n <Stack gap=\"lg\">{/* page content */}</Stack>\n </PageContainer>\n );\n}`,\n storyPath: \"layout/PageContainer.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Stack\",\n group: \"layout\",\n tagline:\n \"Vertical flex column with token gap — the default block-stacking primitive (use instead of space-y-*).\",\n props: [\n {\n name: \"gap\",\n type: '\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"',\n defaultValue: '\"md\"',\n description: \"Vertical space between children (design tokens).\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes merged via cn().\" },\n { name: \"children\", type: \"ReactNode\", description: \"Block-level children to stack.\" },\n ],\n example: `import { Stack } from \"@godxjp/ui/layout\";\n\n<Stack gap=\"lg\">\n <KpiRow />\n <FilterBarBlock />\n <TableCard />\n</Stack>`,\n storyPath: \"layout/Stack.stories.tsx\",\n rules: [2, 40],\n },\n {\n name: \"Inline\",\n group: \"layout\",\n tagline:\n \"Horizontal flex row with token gap — the default inline/row arrangement (use instead of gap-* on a flex div).\",\n props: [\n {\n name: \"gap\",\n type: '\"xs\" | \"sm\" | \"md\" | \"lg\"',\n defaultValue: '\"sm\"',\n description: \"Horizontal space between children.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes merged via cn().\" },\n { name: \"children\", type: \"ReactNode\", description: \"Inline children in a row.\" },\n ],\n example: `import { Inline } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Inline gap=\"sm\">\n <Button>保存</Button>\n <Button variant=\"outline\">キャンセル</Button>\n</Inline>`,\n storyPath: \"layout/Inline.stories.tsx\",\n rules: [2],\n },\n {\n name: \"ResponsiveGrid\",\n group: \"layout\",\n tagline:\n \"Auto-responsive card grid — columns collapse to 1 on mobile, scale up on wider breakpoints.\",\n props: [\n {\n name: \"columns\",\n type: \"2 | 3 | 4\",\n defaultValue: \"3\",\n description: \"Target column count at desktop; collapses to 1 on mobile.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"Grid items — typically Card or CardStat.\",\n },\n ],\n example: `import { ResponsiveGrid } from \"@godxjp/ui/layout\";\nimport { CardStat } from \"@godxjp/ui/data-display\";\n\n<ResponsiveGrid columns={4}>\n <CardStat label=\"総会員数\" value=\"12,400\" />\n <CardStat label=\"公開中クーポン\" value=\"8\" />\n <CardStat label=\"月間利用数\" value=\"3,210\" />\n <CardStat label=\"割引総額\" value=\"¥480,000\" />\n</ResponsiveGrid>`,\n storyPath: \"layout/ResponsiveGrid.stories.tsx\",\n rules: [24, 40],\n },\n {\n name: \"AppShell\",\n group: \"layout\",\n tagline:\n \"Root application shell — composes sidebar, topbar rail, main content area, and optional footer.\",\n props: [\n {\n name: \"sidebar\",\n type: \"ReactNode\",\n required: true,\n description: \"Sidebar node — typically a <Sidebar>.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"Main page content rendered in <main>.\",\n },\n {\n name: \"topbar\",\n type: \"ReactNode\",\n description: \"Full topbar override; else a rail is built from topbarLeft/topbarRight/logo.\",\n },\n {\n name: \"topbarRight\",\n type: \"ReactNode\",\n description: \"Right slot of the auto-built topbar rail (user menu, switcher).\",\n },\n {\n name: \"topbarLeft\",\n type: \"ReactNode\",\n description: \"Left slot of the auto-built topbar rail.\",\n },\n {\n name: \"logo\",\n type: \"ReactNode\",\n description: \"Logo at the far-left of the auto-built topbar rail.\",\n },\n {\n name: \"sidebarCollapsed\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Collapse the sidebar to icon-only mode.\",\n },\n {\n name: \"footer\",\n type: \"ReactNode\",\n description: \"App-level footer outside the main content area.\",\n },\n ],\n example: `import { AppShell, Sidebar } from \"@godxjp/ui/layout\";\nimport { LayoutDashboard, Users } from \"lucide-react\";\nimport { router } from \"@inertiajs/react\";\n\nconst sidebar = (\n <Sidebar\n activeId=\"/dashboard\"\n onSelect={(id) => router.visit(id)}\n sections={[{ items: [\n { id: \"/dashboard\", label: \"ダッシュボード\", icon: LayoutDashboard },\n { id: \"/users\", label: \"ユーザー\", icon: Users },\n ] }]}\n product={{ name: \"JOVY CRM\", role: \"本部\", color: \"var(--color-primary)\" }}\n />\n);\n\nexport function CrmLayout({ children }: { children: React.ReactNode }) {\n return <AppShell sidebar={sidebar}>{children}</AppShell>;\n}`,\n storyPath: \"layout/AppShell.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Sidebar\",\n group: \"layout\",\n tagline:\n \"Data-driven vertical nav rail with collapsible submenu groups and a collapsed icon-only mode — never build nav manually with raw buttons.\",\n props: [\n {\n name: \"activeId\",\n type: \"string\",\n required: true,\n description:\n \"The id of the currently active nav item. For group items, the parent is automatically highlighted when any descendant id matches.\",\n },\n {\n name: \"sections\",\n type: \"SidebarSectionProp[]\",\n required: true,\n description:\n \"Ordered list of nav sections. Each section has an optional string label and a required items array of SidebarItemProp.\",\n },\n {\n name: \"onSelect\",\n type: \"(id: string) => void\",\n description:\n \"Called with the item id when a leaf nav item is clicked. Not called for group triggers or disabled items.\",\n },\n {\n name: \"collapsed\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, renders the icon-only collapsed rail. Labels become Tooltips on hover; group items open a portaled flyout popover on click. Section labels are hidden.\",\n },\n {\n name: \"product\",\n type: \"SidebarProductProp\",\n description:\n \"Renders a product/app chip at the top of the sidebar (name, optional role subtitle, optional color swatch). Mutually exclusive with brand — brand takes precedence.\",\n },\n {\n name: \"onProductClick\",\n type: \"() => void\",\n description:\n \"Click handler for the product chip button. Use to open an entity/workspace switcher sheet or dropdown.\",\n },\n {\n name: \"brand\",\n type: \"ReactNode\",\n description:\n \"Custom brand slot rendered above the nav scroll area. When provided, the product chip is not rendered.\",\n },\n {\n name: \"footer\",\n type: \"ReactNode\",\n description:\n \"Slot pinned to the bottom of the sidebar below the scrollable nav area. Commonly used for user identity, online status, or version info.\",\n },\n ],\n usage: [\n \"DO: Define all nav items as a SidebarSectionProp[] data structure and pass it to sections — never hand-roll nav buttons alongside or instead of the Sidebar.\",\n \"DO: Add children: SidebarItemProp[] to any SidebarItemProp to create a collapsible submenu group. The parent item's icon is required even for groups. The group auto-opens and highlights when activeId matches any descendant.\",\n \"DO: Mirror the collapsed boolean between AppShell's sidebarCollapsed prop and Sidebar's collapsed prop — they must stay in sync so the shell layout grid adjusts correctly.\",\n \"DO: Use the footer prop for user info or status — it is pinned below the scroll area and does not scroll away.\",\n \"DON'T: Manage collapse state inside the Sidebar — it is stateless. Hoist the boolean to your shell/page state and pass it down via both AppShell.sidebarCollapsed and Sidebar.collapsed.\",\n \"DON'T: Nest children more than one level deep — only top-level items can have children; grandchild items are not rendered.\",\n ],\n useCases: [\n \"Admin application shell nav with grouped sections (e.g. Operations / Fulfillment / Administration) where the sidebar can be collapsed to an icon rail for more content space.\",\n \"Accounting app with a collapsible 'Ledger' group containing Journal, Chart of Accounts, and Period Close sub-pages — activeId reflects the current sub-page and the group stays open automatically.\",\n \"Multi-tenant SaaS where onProductClick opens an entity/legal-entity switcher sheet and product.role shows the active tenant name beneath the product logo.\",\n \"Any app using AppShell where navigation must degrade gracefully to an icon-only rail on narrow viewports or via a user toggle in the Topbar.\",\n \"Apps with infrequent-access admin pages (Users, Roles, Password) grouped in a dedicated section that appears below primary operations sections.\",\n ],\n related: [\n \"AppShell — the shell that hosts Sidebar in its sidebar slot and owns the sidebarCollapsed layout grid; always compose Sidebar inside AppShell, not standalone in a page.\",\n \"Topbar — the horizontal bar that renders the collapse toggle (onToggleCollapsed) and its collapsed prop must mirror the sidebar's collapsed state.\",\n \"PageContainer — used for page-level title/subtitle/extra/breadcrumb inside AppShell's children slot, not inside Sidebar.\",\n ],\n example: `\n{\\`import { useState } from \"react\";\nimport { LayoutDashboard, FileText, Users, Shield, CreditCard, BookOpen } from \"lucide-react\";\nimport { AppShell } from \"@godxjp/ui/layout\";\nimport { Sidebar, type SidebarSection } from \"@godxjp/ui/layout\";\nimport { Topbar } from \"@godxjp/ui/layout\";\n\nconst sections: SidebarSection[] = [\n {\n label: \"Accounting\",\n items: [\n { id: \"dashboard\", label: \"Dashboard\", icon: LayoutDashboard },\n {\n id: \"ledger\",\n label: \"Ledger\",\n icon: BookOpen,\n children: [\n { id: \"journal\", label: \"Journal\", icon: FileText },\n { id: \"chart-of-accounts\", label: \"Chart of Accounts\", icon: CreditCard },\n ],\n },\n ],\n },\n {\n label: \"Administration\",\n items: [\n { id: \"users\", label: \"Users\", icon: Users },\n { id: \"roles\", label: \"Roles\", icon: Shield, disabled: true },\n ],\n },\n];\n\nexport default function Shell() {\n const [activeId, setActiveId] = useState(\"dashboard\");\n const [collapsed, setCollapsed] = useState(false);\n\n return (\n <AppShell\n sidebarCollapsed={collapsed}\n sidebar={\n <Sidebar\n activeId={activeId}\n collapsed={collapsed}\n onSelect={setActiveId}\n sections={sections}\n product={{ name: \"CoreBooks\", role: \"Admin Console\", color: \"hsl(var(--primary))\" }}\n onProductClick={() => {/* open entity switcher */}}\n footer={\n <div className=\"text-muted-foreground text-xs\">\n <div className=\"text-foreground font-medium\">Satoshi Yamamoto</div>\n <div>Online · Tokyo branch</div>\n </div>\n }\n />\n }\n topbar={\n <Topbar\n product={{ name: \"CoreBooks\", color: \"hsl(var(--primary))\" }}\n collapsed={collapsed}\n onToggleCollapsed={() => setCollapsed((c) => !c)}\n onSearchOpen={() => {}}\n />\n }\n >\n {/* page content */}\n </AppShell>\n );\n}\\`}\n`,\n storyPath: \"layout/Sidebar.preview.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"Topbar\",\n group: \"layout\",\n tagline:\n \"App-shell top bar with product/project chip switchers, search, notifications, and sidebar toggle — pass DropdownMenuContent to productMenu/projectMenu to turn any chip into a real dropdown switcher; the project chip is hidden entirely when neither project nor projectMenu is set.\",\n props: [\n {\n name: \"product\",\n type: \"TopbarProductProp\",\n required: true,\n description:\n \"The active product identity shown in the left chip. Shape: `{ name: string; color?: string }`. `color` sets the chip icon background (defaults to `hsl(var(--attention))`); the first letter of `name` is used as the icon glyph.\",\n },\n {\n name: \"project\",\n type: \"TopbarProjectProp | null\",\n defaultValue: \"undefined\",\n description:\n \"Optional active project shown after the product chip as `/ ProjectName`. Shape: `{ name: string }`. When both `project` and `projectMenu` are omitted the project chip is not rendered at all.\",\n },\n {\n name: \"productMenu\",\n type: \"ReactNode\",\n defaultValue: \"undefined\",\n description:\n \"A `DropdownMenuContent` node. When provided, wraps the product chip in a `DropdownMenu` and renders this content as the dropdown body — turning the chip into an interactive switcher (e.g. an active-entity picker). When omitted, clicking the chip fires `onProductOpen` instead.\",\n },\n {\n name: \"projectMenu\",\n type: \"ReactNode\",\n defaultValue: \"undefined\",\n description:\n \"A `DropdownMenuContent` node. When provided, wraps the project chip in a `DropdownMenu`. Also causes the project chip to be rendered even when `project` is null — useful for a 'Pick project' state with a real dropdown. When omitted, clicking the chip fires `onProjectOpen`.\",\n },\n {\n name: \"onProductOpen\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description:\n \"Called when the product chip is clicked and `productMenu` is NOT set. Use for custom modals / sheet-based switchers.\",\n },\n {\n name: \"onProjectOpen\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description: \"Called when the project chip is clicked and `projectMenu` is NOT set.\",\n },\n {\n name: \"onSearchOpen\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description:\n \"Called when the search bar button (⌘K) is clicked. Wire this to your command-palette or search dialog.\",\n },\n {\n name: \"onTweaksOpen\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description:\n \"Called when the tweaks/settings icon button is clicked. The button is not rendered when this prop is omitted.\",\n },\n {\n name: \"collapsed\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Whether the sidebar is currently collapsed. Controls which icon (`PanelLeftOpen` vs `PanelLeftClose`) is shown on the toggle button and sets its `aria-pressed` state.\",\n },\n {\n name: \"onToggleCollapsed\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description:\n \"Called when the sidebar-toggle icon button is clicked. The button is not rendered when this prop is omitted.\",\n },\n {\n name: \"rightSlot\",\n type: \"ReactNode\",\n defaultValue: \"undefined\",\n description:\n \"Arbitrary content injected between the search bar and the notifications bell. Use for custom action buttons, locale switchers, or env badges.\",\n },\n {\n name: \"unread\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When `true`, renders a red dot badge on the notifications bell to indicate unread notifications.\",\n },\n {\n name: \"onNotificationsOpen\",\n type: \"() => void\",\n defaultValue: \"undefined\",\n description:\n \"Called when the notifications bell button is clicked. The bell button is not rendered when this prop is omitted.\",\n },\n {\n name: \"user\",\n type: \"ReactNode\",\n defaultValue: \"undefined\",\n description:\n \"User avatar / profile menu node rendered at the far right of the topbar, after the notifications bell and before the tweaks button.\",\n },\n ],\n usage: [\n \"DO pass a `DropdownMenuContent` to `productMenu` or `projectMenu` to make a chip a real inline dropdown switcher (e.g. an entity/tenant picker). DO NOT combine both `productMenu` and `onProductOpen` — when `productMenu` is present, `onProductOpen` is ignored.\",\n \"DO omit both `project` and `projectMenu` when the app has no project concept — the project chip is hidden entirely. If you want a 'Pick project' placeholder with a real dropdown, pass only `projectMenu` (leave `project` null/undefined) so the chip renders in its empty state with the dropdown attached.\",\n \"DO render `Topbar` inside `AppShell`'s `topbar` prop — Topbar renders as a fragment of buttons/slots and relies on `AppShell`'s `app-topbar` CSS grid for layout. NEVER render it standalone outside of an `AppShell` or equivalent `<header>` container.\",\n \"DO wire `onSearchOpen` to your command-palette/dialog — the search bar button always renders (it is not conditional on this prop), so omitting the handler leaves users with a non-functional control.\",\n \"DO use `rightSlot` for extra topbar actions (e.g. locale switcher, environment badge, custom toolbar buttons) rather than adding children or extending the component.\",\n \"DON'T hand-roll a topbar from scratch — Topbar ships the sidebar toggle, product/project switcher, search, notifications bell, user slot, and tweaks button with correct `aria-label`/`aria-pressed` attributes already.\",\n ],\n useCases: [\n \"Admin / SaaS shell where the header shows the active legal entity (product chip) and users switch between entities via a `DropdownMenuContent` passed to `productMenu`.\",\n \"Multi-project app where the project chip shows the current project and `projectMenu` provides a `DropdownMenuContent` to switch projects inline without opening a modal.\",\n \"App-shell with a collapsible sidebar: pass `collapsed` + `onToggleCollapsed` to let users toggle the sidebar from the topbar without building a custom toggle button.\",\n \"Notification-aware shell: pass `onNotificationsOpen` + `unread={hasUnread}` to render a bell icon with a red-dot badge that opens a notifications panel.\",\n \"Apps needing a locale switcher or environment badge in the header: put it in `rightSlot` to slot it between the search bar and the notifications bell without modifying the component.\",\n \"Read-only / minimal shell where sidebar toggling, tweaks, and notifications are not needed — simply omit `onToggleCollapsed`, `onTweaksOpen`, and `onNotificationsOpen`; their buttons are not rendered.\",\n ],\n related: [\n \"AppShell — the parent shell component that places Topbar inside its `app-topbar` header region via the `topbar` prop. Always use Topbar inside AppShell, not standalone.\",\n \"Sidebar — the companion left-rail nav; pair with Topbar's `collapsed`/`onToggleCollapsed` to keep sidebar and topbar toggle state in sync.\",\n \"DropdownMenu / DropdownMenuContent — pass a `DropdownMenuContent` as `productMenu` or `projectMenu` to turn a chip into an inline switcher. Topbar handles the `DropdownMenuTrigger` wrapping internally; only the Content node is needed.\",\n \"ShellApp — a higher-level opinionated shell that already composes AppShell + Topbar with hardcoded product/project chips; use it for prototypes but use AppShell + Topbar directly for production apps that need real switcher props.\",\n ],\n example: `import { Topbar } from \"@godxjp/ui/layout\";\nimport { AppShell } from \"@godxjp/ui/layout\";\nimport {\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"@godxjp/ui/navigation\";\n\n// Entity-switcher example: product chip opens an entity dropdown,\n// project chip is hidden (no project concept in this app).\nfunction MyShell({ children }: { children: React.ReactNode }) {\n const [collapsed, setCollapsed] = React.useState(false);\n const [unread, setUnread] = React.useState(true);\n\n return (\n <AppShell\n sidebar={<MySidebar />}\n sidebarCollapsed={collapsed}\n topbar={\n <Topbar\n product={{ name: \"CoreBooks\", color: \"hsl(220 70% 50%)\" }}\n productMenu={\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem onSelect={() => switchEntity(\"acme\")}>\n Acme Corp\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => switchEntity(\"globex\")}>\n Globex Ltd\n </DropdownMenuItem>\n </DropdownMenuContent>\n }\n collapsed={collapsed}\n onToggleCollapsed={() => setCollapsed((c) => !c)}\n onSearchOpen={() => openCommandPalette()}\n unread={unread}\n onNotificationsOpen={() => openNotificationsPanel()}\n user={<UserAvatar />}\n />\n }\n >\n {children}\n </AppShell>\n );\n}`,\n storyPath: \"layout/Topbar.stories.tsx\",\n rules: [2, 3, 5, 6],\n },\n {\n name: \"PageInset\",\n group: \"layout\",\n tagline:\n 'Padded horizontal strip aligned with the page header — use inside variant=\"flush\" for filter bars / intros.',\n props: [\n {\n name: \"children\",\n type: \"ReactNode\",\n description: \"Content rendered with standard page horizontal padding.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes.\" },\n ],\n example: `import { PageContainer, PageInset } from \"@godxjp/ui/layout\";\n\n<PageContainer title=\"商品一覧\" variant=\"flush\">\n <PageInset><FilterBarBlock /></PageInset>\n {/* full-bleed table below */}\n</PageContainer>`,\n storyPath: \"layout/PageInset.stories.tsx\",\n rules: [],\n },\n {\n name: \"SplitPane\",\n group: \"layout\",\n tagline: \"Two-column layout with a main content area and a fixed-width aside panel.\",\n props: [\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Main (left) content.\" },\n {\n name: \"aside\",\n type: \"ReactNode\",\n required: true,\n description: \"Aside (right) panel content.\",\n },\n {\n name: \"asideWidth\",\n type: '\"sm\" | \"md\"',\n defaultValue: '\"md\"',\n description: \"Width preset for the aside column.\",\n },\n ],\n example: `import { SplitPane } from \"@godxjp/ui/layout\";\n\n<SplitPane aside={<DetailPanel />} asideWidth=\"sm\">\n <MainContent />\n</SplitPane>`,\n storyPath: \"layout/SplitPane.stories.tsx\",\n rules: [24],\n },\n {\n name: \"Breadcrumb\",\n group: \"layout\",\n tagline: \"Standalone breadcrumb nav rendering an ordered trail of page segments.\",\n props: [\n {\n name: \"items\",\n type: \"BreadcrumbItemProp[]\",\n required: true,\n description: \"Array of { label, to? } — omit `to` on the last (current) segment.\",\n },\n ],\n example: `import { Breadcrumb } from \"@godxjp/ui/layout\";\n\n<Breadcrumb items={[\n { label: \"ホーム\", to: \"/\" },\n { label: \"会員管理\", to: \"/members\" },\n { label: \"田中 太郎\" },\n]} />`,\n storyPath: \"layout/Breadcrumb.stories.tsx\",\n rules: [],\n },\n\n // ─── general ────────────────────────────────────────────────────────────\n {\n name: \"Button\",\n group: \"general\",\n tagline: \"Core button with variant + size presets, built on cva and Radix Slot (asChild).\",\n props: [\n {\n name: \"variant\",\n type: '\"default\" | \"destructive\" | \"outline\" | \"secondary\" | \"ghost\" | \"link\"',\n defaultValue: '\"default\"',\n description: \"Visual style.\",\n },\n {\n name: \"size\",\n type: '\"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\"',\n defaultValue: '\"default\"',\n description: \"Size preset (height, padding, icon dims).\",\n },\n {\n name: \"asChild\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Render as Radix Slot — merge props onto the child (<a>/<Link>).\",\n },\n { name: \"disabled\", type: \"boolean\", description: \"Disable the button.\" },\n {\n name: \"onClick\",\n type: \"React.MouseEventHandler<HTMLButtonElement>\",\n description: \"Click handler.\",\n },\n ],\n example: `import { Button } from \"@godxjp/ui/general\";\nimport { Trash2 } from \"lucide-react\";\n\n<>\n <Button>保存</Button>\n <Button variant=\"outline\" size=\"sm\">編集</Button>\n <Button variant=\"ghost\" size=\"icon-sm\"><Trash2 className=\"size-4\" /></Button>\n</>`,\n storyPath: \"general/Button.stories.tsx\",\n rules: [23],\n },\n\n // ─── data-display ───────────────────────────────────────────────────────\n {\n name: \"DataTable\",\n group: \"data-display\",\n tagline:\n \"Compound admin list component with sticky header, sorting, bulk selection, cursor pagination, and built-in empty/loading states — never hand-roll a data.length===0 guard around it.\",\n props: [\n {\n name: \"data\",\n type: \"T[]\",\n required: true,\n description:\n \"Array of row data. When empty and loading is false, a built-in EmptyState renders automatically inside the table body — no external guard needed.\",\n },\n {\n name: \"columns\",\n type: \"ColumnDef<T>[]\",\n required: true,\n description:\n \"Column definitions. Each column: { key: string; header: ReactNode; render?: (row: T) => ReactNode; sortable?: boolean; width?: string; align?: 'left'|'center'|'right'; hiddenOnMobile?: boolean }. If render is omitted, the raw value at row[key] is rendered as a string.\",\n },\n {\n name: \"getRowId\",\n type: \"(row: T) => string\",\n defaultValue: \"(row) => String(row.id)\",\n description:\n \"Extracts a stable unique string key per row. Required when selectable is true or rows lack an 'id' field. Falls back to row.id cast to string.\",\n },\n {\n name: \"selectable\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Adds a checkbox column and a SelectAll header checkbox. Use with selected + onSelectChange for controlled selection, or omit both for uncontrolled.\",\n },\n {\n name: \"selected\",\n type: \"Set<string>\",\n description:\n \"Controlled set of selected row IDs. Pair with onSelectChange. Omit for uncontrolled.\",\n },\n {\n name: \"onSelectChange\",\n type: \"(next: Set<string>) => void\",\n description: \"Called with the full new selection set after any checkbox interaction.\",\n },\n {\n name: \"onRowClick\",\n type: \"(row: T) => void\",\n description:\n \"Makes rows clickable for navigation. Row click is suppressed when the user clicks an interactive descendant (button, a, input, select, textarea, [role=menuitem]).\",\n },\n {\n name: \"density\",\n type: \"'compact' | 'comfortable'\",\n defaultValue: \"'compact'\",\n description:\n \"Controlled row density. Omit to let DataTable manage density internally (user can toggle via DataTable.DensityToggle).\",\n },\n {\n name: \"onDensityChange\",\n type: \"(density: 'compact' | 'comfortable') => void\",\n description:\n \"Called when the user toggles density. Only needed when density is controlled.\",\n },\n {\n name: \"sort\",\n type: \"{ key: string; direction: 'asc' | 'desc' }\",\n description:\n \"Active sort state. When provided alongside onSortChange, sortable columns show directional arrow icons and are clickable. Clicking the active column twice clears sort (calls onSortChange(undefined)).\",\n },\n {\n name: \"onSortChange\",\n type: \"(sort: { key: string; direction: 'asc' | 'desc' } | undefined) => void\",\n description:\n \"Called when a sortable column header is clicked. Receives undefined when sort is cleared (third click on same column).\",\n },\n {\n name: \"loading\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, renders a full-width loading row instead of data rows or the empty state. Use during initial fetch or pagination transitions.\",\n },\n {\n name: \"empty\",\n type: \"ReactNode\",\n description:\n \"Custom content rendered inside the table body when data is empty and loading is false. Defaults to a built-in EmptyState with a localised 'No data' message. Pass a custom <EmptyState title='...' description='...' action={...}/> to tailor the message.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra classes applied to the root wrapper div (ui-data-table-root).\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n description:\n \"Compound sub-parts: DataTable.Toolbar, DataTable.BulkActions, DataTable.DensityToggle, DataTable.Pagination, DataTable.Content. If no DataTable.Content is present in children, one is auto-rendered.\",\n },\n ],\n usage: [\n \"DO pass loading={isFetching} during data fetches — it renders a loading row in the table body and suppresses the empty state. Never show a spinner outside DataTable while the table is visible.\",\n \"DO NOT add a data.length===0 conditional around DataTable. When data is empty and loading is false, the built-in EmptyState renders automatically. Pass empty={<EmptyState title='...'/>} only when you need a custom message.\",\n \"DO provide getRowId when selectable is true or when rows do not have a string/number 'id' field — the default falls back to row.id and silently returns '' for missing IDs, which breaks selection.\",\n \"DO use DataTable.Toolbar as the immediate child that wraps search/filter controls on the left and DataTable.DensityToggle/action buttons on the right. DataTable.BulkActions inside the toolbar auto-hides when selection count is 0.\",\n \"DO use ColumnDef.render for custom cell content (Badge, Link, RowActions). For plain string/number fields render can be omitted — DataTable falls back to String(row[key]).\",\n \"DO NOT nest DataTable.Content in a conditional — it is already guarded internally. If you need to override the table body slot, drop exactly one <DataTable.Content /> in children; DataTable auto-detects it by displayName and skips the default.\",\n ],\n useCases: [\n \"Admin list pages (invoices, customers, orders, accounts) where rows are clickable for detail navigation via onRowClick.\",\n \"Bulk-action workflows (e.g. mark invoices paid, export selected rows) — use selectable + DataTable.BulkActions to show contextual action buttons only when something is selected.\",\n \"Server-side sorted tables: pass sort + onSortChange and update the data prop after the API call; DataTable renders asc/desc/neutral icons on the header automatically.\",\n \"Cursor-paginated lists: add DataTable.Pagination with cursor + hasMore + onChange inside children to get First/Next navigation without offset arithmetic.\",\n \"Responsive admin tables where lower-priority columns (e.g. internal IDs, dates) should collapse below mobile breakpoints — set hiddenOnMobile: true on those ColumnDef entries.\",\n \"Loading skeletons during initial page load or filter change: set loading={true} alongside an empty data={[]} to show the loading row without flashing an empty state.\",\n ],\n related: [\n \"Table — raw primitive (TableHeader/TableBody/TableRow/TableCell). Use DataTable instead; only reach for Table directly when you need a non-standard layout that DataTable cannot express.\",\n \"SkeletonTable — standalone skeleton placeholder rendered before any DataTable mounts (e.g. in a Suspense fallback or deferred-prop skeleton slot). DataTable.loading covers in-table loading; SkeletonTable covers pre-mount skeletons.\",\n \"EmptyState — standalone empty state for non-table lists. DataTable already embeds EmptyState in its body; only use bare EmptyState for card content, non-tabular lists, or zero-state pages outside a DataTable.\",\n \"DataState / InfiniteQueryState — TanStack Query lifecycle widgets from @godxjp/ui/query. Prefer these over DataTable when your list is driven by useQuery/useInfiniteQuery and you want automatic skeleton/empty/error handling at the query level rather than at the table level.\",\n ],\n example: `import { useState } from \"react\";\nimport { Badge, DataTable, type ColumnDef } from \"@godxjp/ui/data-display\";\nimport { EmptyState } from \"@godxjp/ui/data-display\";\n\ntype Invoice = {\n id: string;\n customer: string;\n amount: number;\n status: \"paid\" | \"pending\" | \"overdue\";\n};\n\nconst columns: ColumnDef<Invoice>[] = [\n { key: \"id\", header: \"Invoice #\", width: \"w-32\" },\n { key: \"customer\", header: \"Customer\" },\n {\n key: \"status\",\n header: \"Status\",\n render: (row) => (\n <Badge\n variant={\n row.status === \"paid\" ? \"success\" : row.status === \"overdue\" ? \"destructive\" : \"secondary\"\n }\n >\n {row.status}\n </Badge>\n ),\n },\n { key: \"amount\", header: \"Amount\", align: \"right\", sortable: true },\n];\n\nexport default function InvoiceList({\n invoices,\n loading,\n}: {\n invoices: Invoice[];\n loading: boolean;\n}) {\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [sort, setSort] = useState<{ key: string; direction: \"asc\" | \"desc\" } | undefined>();\n\n return (\n <DataTable\n data={invoices}\n columns={columns}\n getRowId={(row) => row.id}\n selectable\n selected={selected}\n onSelectChange={setSelected}\n sort={sort}\n onSortChange={setSort}\n loading={loading}\n empty={\n <EmptyState\n title=\"No invoices found\"\n description=\"Adjust your filters or create a new invoice.\"\n />\n }\n >\n <DataTable.Toolbar>\n <DataTable.BulkActions>\n <button type=\"button\" onClick={() => setSelected(new Set())}>\n Mark paid\n </button>\n </DataTable.BulkActions>\n <DataTable.DensityToggle />\n </DataTable.Toolbar>\n </DataTable>\n );\n}`,\n storyPath: \"data-display/DataTable.stories.tsx\",\n rules: [24, 31, 35, 37],\n },\n {\n name: \"Card\",\n group: \"data-display\",\n tagline:\n 'Surface container with optional accent stripe, variant fill, size, and density. ⚠️ The bare <Card> has NO inner padding — body content MUST be wrapped in <CardContent> (titles in <CardHeader>), or it sits FLUSH against the card edges. Never hand-roll padding with className=\"p-4\"; use <CardContent>. Compose with CardHeader/CardTitle/CardContent/CardFooter.',\n props: [\n {\n name: \"accent\",\n type: '\"primary\" | \"success\" | \"warning\" | \"info\" | \"attention\" | \"destructive\"',\n description: \"3px left-edge semantic accent stripe.\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"muted\" | \"outline\" | \"featured\"',\n defaultValue: '\"default\"',\n description: \"Surface fill style.\",\n },\n {\n name: \"size\",\n type: '\"default\" | \"compact\"',\n defaultValue: '\"default\"',\n description: \"Card size preset.\",\n },\n {\n name: \"density\",\n type: '\"tight\" | \"cozy\"',\n description: \"Internal padding density (base 16 / tight 12 / cozy 20).\",\n },\n ],\n example: `import { Card, CardHeader, CardTitle, CardContent } from \"@godxjp/ui/data-display\";\n\n<Card accent=\"success\">\n <CardHeader><CardTitle>注文サマリー</CardTitle></CardHeader>\n <CardContent>総売上: ¥1,234,567</CardContent>\n</Card>`,\n storyPath: \"data-display/Card.stories.tsx\",\n rules: [],\n },\n {\n name: \"CardContent\",\n group: \"data-display\",\n tagline:\n \"Card body. flush = edge-to-edge (for DataTable/tabs); tight = no top gap; solo = no header above. NEVER put a FilterBar inside flush (it loses padding).\",\n props: [\n {\n name: \"flush\",\n type: \"boolean\",\n description: \"Remove horizontal padding for edge-to-edge tables / tabs lists.\",\n },\n {\n name: \"tight\",\n type: \"boolean\",\n description: \"No top gap after header — pair with flush toolbars/tabs.\",\n },\n {\n name: \"solo\",\n type: \"boolean\",\n description: \"No header above: top padding matches the card shell.\",\n },\n ],\n example: `import { Card, CardContent, DataTable } from \"@godxjp/ui/data-display\";\n\n<Card>\n <CardContent flush>\n <DataTable data={rows} columns={columns} />\n </CardContent>\n</Card>`,\n storyPath: \"data-display/Card.stories.tsx\",\n rules: [37, 38],\n },\n {\n name: \"CardStat\",\n group: \"data-display\",\n tagline:\n \"KPI tile. ⚠️ CardStat IS ALREADY a bordered Card — render it DIRECTLY in ResponsiveGrid. NEVER wrap it in <Card>/<CardContent> (that double-borders it → looks too thick). NO accent prop (accent is a Card prop).\",\n props: [\n { name: \"label\", type: \"ReactNode\", required: true, description: \"Metric name.\" },\n {\n name: \"value\",\n type: \"ReactNode\",\n required: true,\n description: \"Metric value (string/number/ReactNode).\",\n },\n { name: \"hint\", type: \"ReactNode\", description: \"Secondary context below the value.\" },\n {\n name: \"delta\",\n type: \"ReactNode\",\n description: \"Compact trend text beside the value. Sign-aware tone (+ green / - red).\",\n },\n {\n name: \"layout\",\n type: '\"stacked\" | \"inline\"',\n defaultValue: '\"stacked\"',\n description: \"stacked = label over value; inline = label left / value right.\",\n },\n { name: \"align\", type: '\"start\" | \"end\"', description: \"Align the metric group.\" },\n ],\n example: `import { CardStat } from \"@godxjp/ui/data-display\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n// ✅ CardStat sits directly in the grid — it draws its own card + border.\n<ResponsiveGrid columns={3}>\n <CardStat label=\"総会員数\" value=\"12,450\" hint=\"先月比 +3%\" />\n <CardStat label=\"月次売上\" value=\"¥8,200,000\" delta=\"+12%\" />\n <CardStat label=\"利用率\" value=\"68.4%\" />\n</ResponsiveGrid>\n\n// ❌ Double border — do NOT wrap CardStat in a Card:\n// <Card><CardContent><CardStat label=\"x\" value=\"1\" /></CardContent></Card>`,\n storyPath: \"data-display/CardStat.stories.tsx\",\n rules: [],\n },\n {\n name: \"StatusBadge\",\n group: \"data-display\",\n tagline:\n \"Lifecycle chip that auto-maps English keys (active/draft/pending/failed/…) to tone + icon. For localized labels or tiers, pass tone explicitly; pass icon={null} for tiers. Chips never wrap.\",\n props: [\n {\n name: \"status\",\n type: \"string\",\n required: true,\n description:\n \"Lifecycle key or any domain string. Unknown strings fall back to neutral unless tone is set.\",\n },\n {\n name: \"tone\",\n type: '\"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\"',\n description: \"Override the resolved tone (escape hatch for localized / tier values).\",\n },\n {\n name: \"icon\",\n type: \"LucideIcon | null\",\n description: \"Override the icon; null hides it — preferred for tier / category badges.\",\n },\n {\n name: \"label\",\n type: \"ReactNode\",\n description: \"Override display text (default: i18n of key, or raw status).\",\n },\n ],\n example: `import { StatusBadge } from \"@godxjp/ui/data-display\";\n\n<>\n <StatusBadge status=\"active\" label=\"公開中\" /> {/* green check */}\n <StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} /> {/* tier pill, no icon */}\n <StatusBadge status=\"ゴールド\" tone=\"warning\" icon={null} />\n</>`,\n storyPath: \"data-display/StatusBadge.stories.tsx\",\n rules: [35, 36],\n },\n {\n name: \"Badge\",\n group: \"data-display\",\n tagline:\n \"Plain label chip with semantic variants. Use for static category tags; use StatusBadge for lifecycle status.\",\n props: [\n {\n name: \"variant\",\n type: '\"default\" | \"secondary\" | \"destructive\" | \"outline\" | \"success\" | \"warning\"',\n defaultValue: '\"default\"',\n description: \"Visual variant.\",\n },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"Badge text/content.\" },\n ],\n example: `import { Badge } from \"@godxjp/ui/data-display\";\n\n<Badge variant=\"secondary\">A/B</Badge>\n<Badge variant=\"success\">承認済</Badge>`,\n storyPath: \"data-display/Badge.stories.tsx\",\n rules: [35],\n },\n {\n name: \"KeyValueGrid\",\n group: \"data-display\",\n tagline:\n \"Responsive definition grid for detail-page metadata. COMPOUND — value goes in KeyValueGrid.Item children.\",\n props: [\n {\n name: \"columns\",\n type: \"1 | 2 | 3\",\n defaultValue: \"2\",\n description: \"Column count; collapses to 1 on mobile.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"KeyValueGrid.Item elements.\",\n },\n ],\n example: `import { KeyValueGrid } from \"@godxjp/ui/data-display\";\n\n<KeyValueGrid columns={2}>\n <KeyValueGrid.Item label=\"会員ID\" mono>{member.id}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"プラン\">{member.plan}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"メモ\" span={2}>{member.note}</KeyValueGrid.Item>\n</KeyValueGrid>`,\n storyPath: \"data-display/KeyValueGrid.stories.tsx\",\n rules: [],\n },\n {\n name: \"EmptyState\",\n group: \"data-display\",\n tagline: \"Centred empty placeholder with icon, title, description, and optional CTA.\",\n props: [\n { name: \"title\", type: \"string\", required: true, description: \"Primary empty message.\" },\n { name: \"description\", type: \"string\", description: \"Secondary helper text.\" },\n { name: \"icon\", type: \"LucideIcon\", description: \"Icon above the title.\" },\n { name: \"action\", type: \"ReactNode\", description: \"CTA element (e.g. a Button).\" },\n ],\n example: `import { EmptyState } from \"@godxjp/ui/data-display\";\n\n<EmptyState title=\"該当データがありません\" description=\"検索条件を変更してください。\" />`,\n storyPath: \"data-display/EmptyState.stories.tsx\",\n rules: [],\n },\n {\n name: \"ProgressMeter\",\n group: \"data-display\",\n tagline: \"Horizontal progress bar 0–100 with optional label and semantic tone.\",\n props: [\n {\n name: \"value\",\n type: \"number\",\n required: true,\n description: \"Progress percentage 0–100 (clamped).\",\n },\n { name: \"label\", type: \"string\", description: \"Text label beside/below the bar.\" },\n {\n name: \"tone\",\n type: '\"success\" | \"warning\"',\n defaultValue: '\"success\"',\n description: \"Bar colour tone.\",\n },\n ],\n example: `import { ProgressMeter } from \"@godxjp/ui/data-display\";\n\n<ProgressMeter value={pct} label={pct + \"% 使用中\"} tone={pct >= 80 ? \"warning\" : \"success\"} />`,\n storyPath: \"data-display/ProgressMeter.stories.tsx\",\n rules: [],\n },\n {\n name: \"Timeline\",\n group: \"data-display\",\n tagline: \"Vertical event list with an icon rail. Current item gets a highlighted glyph.\",\n props: [\n {\n name: \"items\",\n type: \"TimelineItem[]\",\n required: true,\n description: \"Array of { title, location?, time?, note?, current? }.\",\n },\n ],\n example: `import { Timeline } from \"@godxjp/ui/data-display\";\n\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />`,\n storyPath: \"data-display/Timeline.stories.tsx\",\n rules: [],\n },\n {\n name: \"Table\",\n group: \"data-display\",\n tagline:\n \"Primitive table shell (Table/TableHeader/TableBody/TableRow/TableHead/TableCell). Prefer DataTable for admin lists; use these for custom one-off tables.\",\n props: [\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"TableHeader / TableBody composition.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes on the table element.\" },\n ],\n example: `import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"@godxjp/ui/data-display\";\n\n<Table>\n <TableHeader><TableRow><TableHead>項目</TableHead><TableHead className=\"text-right\">金額</TableHead></TableRow></TableHeader>\n <TableBody><TableRow><TableCell>送料</TableCell><TableCell className=\"text-right\">¥500</TableCell></TableRow></TableBody>\n</Table>`,\n storyPath: \"data-display/Table.stories.tsx\",\n rules: [],\n },\n {\n name: \"DataState\",\n group: \"data-display\",\n tagline:\n \"TanStack Query lifecycle widget — skeleton / error / empty / success for one useQuery block. Import from @godxjp/ui/query.\",\n props: [\n {\n name: \"query\",\n type: \"UseQueryResult<T>\",\n required: true,\n description: \"The useQuery result.\",\n },\n { name: \"skeleton\", type: \"ReactNode\", required: true, description: \"Shown while loading.\" },\n {\n name: \"children\",\n type: \"(data) => ReactNode\",\n required: true,\n description: \"Render function with resolved data.\",\n },\n { name: \"empty\", type: \"ReactNode\", description: \"Shown when isEmpty(data) is true.\" },\n { name: \"isEmpty\", type: \"(data) => boolean\", description: \"Custom empty check.\" },\n ],\n example: `import { DataState } from \"@godxjp/ui/query\";\n\n<DataState query={membersQuery} skeleton={<SkeletonTable />} isEmpty={(d) => d.items.length === 0} empty={<EmptyState title=\"会員なし\" />}>\n {(d) => <MemberTable items={d.items} />}\n</DataState>`,\n storyPath: \"query/DataState.stories.tsx\",\n rules: [],\n },\n {\n name: \"InfiniteQueryState\",\n group: \"data-display\",\n tagline:\n \"useInfiniteQuery widget — flatten pages, skeleton/empty/error, load-more footer. Import from @godxjp/ui/query.\",\n props: [\n {\n name: \"query\",\n type: \"UseInfiniteQueryResult\",\n required: true,\n description: \"The useInfiniteQuery result.\",\n },\n {\n name: \"skeleton\",\n type: \"ReactNode\",\n required: true,\n description: \"Shown while initial load pends.\",\n },\n {\n name: \"flatten\",\n type: \"(data) => TFlat\",\n required: true,\n description: \"Reduce pages to a flat list (use flattenItemPages helper).\",\n },\n {\n name: \"children\",\n type: \"(flat, helpers) => ReactNode\",\n required: true,\n description: \"Render with flat data + { fetchNextPage, hasNextPage, isFetchingNextPage }.\",\n },\n ],\n example: `import { InfiniteQueryState, flattenItemPages } from \"@godxjp/ui/query\";\n\n<InfiniteQueryState query={q} skeleton={<SkeletonRows />} flatten={flattenItemPages} isEmpty={(it) => it.length === 0}>\n {(items) => items.map((a) => <ActivityRow key={a.id} activity={a} />)}\n</InfiniteQueryState>`,\n storyPath: \"query/InfiniteQueryState.stories.tsx\",\n rules: [],\n },\n {\n name: \"MutationFeedback\",\n group: \"data-display\",\n tagline:\n \"Inline mutation error — renders nothing when idle/successful. Import from @godxjp/ui/query.\",\n props: [\n {\n name: \"mutation\",\n type: \"{ isError, error, isPending }\",\n required: true,\n description: \"useMutation result.\",\n },\n { name: \"onRetry\", type: \"() => void\", description: \"Retry handler.\" },\n ],\n example: `import { MutationFeedback } from \"@godxjp/ui/query\";\n\n<MutationFeedback mutation={saveMutation} />`,\n storyPath: \"query/MutationFeedback.stories.tsx\",\n rules: [],\n },\n\n // ─── data-entry ─────────────────────────────────────────────────────────\n {\n name: \"FormField\",\n group: \"data-entry\",\n tagline:\n \"Wraps a control with label, helper, and error; injects aria-describedby/aria-invalid onto the child.\",\n props: [\n {\n name: \"id\",\n type: \"string\",\n required: true,\n description: \"Forwarded to Label htmlFor + builds helper/error ids.\",\n },\n {\n name: \"label\",\n type: \"ReactNode\",\n required: true,\n description: \"Field label above the control.\",\n },\n {\n name: \"required\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Red asterisk + aria-required on the child.\",\n },\n { name: \"helper\", type: \"string\", description: \"Muted hint shown when there is no error.\" },\n {\n name: \"error\",\n type: \"string\",\n description: \"Destructive error message (role=alert); overrides helper.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"The single control to render.\",\n },\n ],\n example: `import { FormField, Input } from \"@godxjp/ui/data-entry\";\n\n<FormField id=\"coupon-name\" label=\"クーポン名\" required error={errors.name} helper=\"最大50文字\">\n <Input id=\"coupon-name\" placeholder=\"春の花粉症対策15%OFF\" value={name} onChange={(e) => setName(e.target.value)} />\n</FormField>`,\n storyPath: \"data-entry/FormField.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Input\",\n group: \"data-entry\",\n tagline:\n \"Styled wrapper around native <input>; accepts all HTML input attributes. Pair with FormField for labelled fields.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Associates with a <label htmlFor>.\" },\n { name: \"type\", type: \"string\", defaultValue: '\"text\"', description: \"Native input type.\" },\n { name: \"placeholder\", type: \"string\", description: \"Placeholder.\" },\n { name: \"value\", type: \"string | number\", description: \"Controlled value.\" },\n {\n name: \"onChange\",\n type: \"React.ChangeEventHandler<HTMLInputElement>\",\n description: \"Native change handler.\",\n },\n ],\n example: `import { Input } from \"@godxjp/ui/data-entry\";\n\n<Input id=\"qty\" type=\"number\" placeholder=\"例: 500\" value={value} onChange={(e) => setValue(e.target.value)} />`,\n storyPath: \"data-entry/Input.stories.tsx\",\n rules: [],\n },\n {\n name: \"SearchInput\",\n group: \"data-entry\",\n tagline:\n \"Debounced search box with a clear button. Fires onSearch (NOT onChange) after the debounce. Controlled (value) or uncontrolled (defaultValue).\",\n props: [\n {\n name: \"onSearch\",\n type: \"(q: string) => void\",\n required: true,\n description:\n \"Called with the query after the debounce. Use this to drive filtering — NOT onChange.\",\n },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n {\n name: \"defaultValue\",\n type: \"string\",\n defaultValue: '\"\"',\n description: \"Initial uncontrolled value.\",\n },\n { name: \"placeholder\", type: \"string\", description: \"Input placeholder.\" },\n {\n name: \"debounce\",\n type: \"number\",\n defaultValue: \"250\",\n description: \"Debounce delay (ms).\",\n },\n ],\n example: `import { SearchInput } from \"@godxjp/ui/data-entry\";\n\n<SearchInput placeholder=\"クーポン名・IDで検索\" value={search} onSearch={setSearch} />`,\n storyPath: \"data-entry/SearchInput.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Select\",\n group: \"data-entry\",\n tagline:\n \"Polymorphic single-select: pass options/loadOptions for the data-driven (Ant-style) API, or compose sub-parts manually — never use a raw <select>.\",\n props: [\n {\n name: \"options\",\n type: \"SearchSelectOptionProp[]\",\n description:\n \"Static option list. Passing this (or loadOptions) switches Select from the compound API to the data-driven API. Each option has { value, label, sublabel?, group?, disabled? }. group buckets the option under an optgroup-style heading.\",\n },\n {\n name: \"loadOptions\",\n type: \"(params: SearchSelectLoadParamsProp) => Promise<SearchSelectLoadResultProp>\",\n description:\n \"Async remote fetcher. Receives { query, page } (1-based). Must return { options, hasMore? }. Implies showSearch=true automatically. Drives debounced search + infinite-scroll pagination.\",\n },\n {\n name: \"showSearch\",\n type: \"boolean\",\n defaultValue: \"true when loadOptions is set, false otherwise\",\n description:\n \"Toggle the searchable combobox mode (SearchSelect engine) vs a plain Radix listbox. Set to true on a static options list to enable client-side filtering.\",\n },\n {\n name: \"value\",\n type: \"string\",\n defaultValue: '\"\"',\n description:\n \"Controlled selected value (data-driven API). Pass an empty string to represent no selection.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string, option?: SearchSelectOptionProp) => void\",\n description:\n \"Change handler for the data-driven API. Receives the new value string and the matching option object.\",\n },\n {\n name: \"renderOption\",\n type: \"(option: SearchSelectOptionProp) => React.ReactNode\",\n description:\n \"Custom per-option renderer (Ant-Design style). Defaults to label + optional sublabel.\",\n },\n {\n name: \"selectedLabel\",\n type: \"string\",\n description:\n \"Display label for the current value when its option is not in the loaded page (async). Prevents a flash of the raw id.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description: \"Placeholder shown in the trigger when no value is selected.\",\n },\n {\n name: \"searchPlaceholder\",\n type: \"string\",\n description: \"Placeholder inside the search input (combobox mode only).\",\n },\n {\n name: \"emptyMessage\",\n type: \"string\",\n description: \"Message rendered when the filtered list is empty.\",\n },\n {\n name: \"loadingMessage\",\n type: \"string\",\n description: \"Message rendered while loadOptions is resolving.\",\n },\n {\n name: \"clearable\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Show a clear row when a value is selected (data-driven API). Set to false for required fields.\",\n },\n {\n name: \"clearLabel\",\n type: \"string\",\n description: \"Label for the clear row (data-driven combobox mode).\",\n },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the entire select.\" },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"Form field name. Submits the selected value via a hidden input (data-driven API). Required for uncontrolled form submission.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description: \"HTML id for the trigger element. Wire to a <label htmlFor> for a11y.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional CSS classes applied to the trigger.\",\n },\n {\n name: \"data-testid\",\n type: \"string\",\n description:\n \"Test id on the trigger. Option items get ${data-testid}-option-${value} automatically.\",\n },\n {\n name: \"SelectTrigger size\",\n type: '\"sm\" | \"default\"',\n defaultValue: '\"default\"',\n description: \"Compound API only. Size variant on the SelectTrigger sub-component.\",\n },\n ],\n usage: [\n \"DO use the data-driven API (options/loadOptions) for straightforward selects — it handles grouping, search, async, and custom rendering automatically. Only reach for the compound API when you need to inject arbitrary content into the trigger or listbox.\",\n \"DO pass name= on the data-driven Select so the value is submitted with a native form or Inertia useForm. Without name= the value is React-only and will not appear in form data.\",\n \"DO use loadOptions + selectedLabel together for async selects: selectedLabel prevents a flash of the raw id string while the first page loads.\",\n \"DO pair id= with a <label htmlFor={id}> for a11y. The trigger renders as a button; screen readers announce the label.\",\n \"DON'T mix the two APIs: once you pass options or loadOptions, Select is data-driven — all compound sub-parts (SelectTrigger, SelectContent, SelectItem) are rendered internally. Do not wrap them manually.\",\n \"DON'T use a raw <select> element. Select is the one control for all single-select use cases. The only allowed raw <select> is a hidden aria-hidden sr-only element kept as an e2e hook paired with a visible Select.\",\n \"COMPOUND API sub-parts (when NOT using options/loadOptions): Select → SelectTrigger (contains SelectValue) → SelectContent → SelectItem. Optionally wrap items in SelectGroup + SelectLabel for headings, or add SelectSeparator between sections.\",\n ],\n useCases: [\n \"Status filter on an invoice list — pass options=[{value:'draft',label:'Draft'},{value:'paid',label:'Paid'}] with onChange to drive a query param; no search needed so omit showSearch.\",\n \"Legal-entity switcher — static options list with showSearch=true for client-side filtering when there are many entities; use selectedLabel to show the entity name before the full list loads.\",\n \"Account category picker backed by an API — pass loadOptions to stream pages of accounts as the user types; use renderOption to show account code + name side by side; pass selectedLabel so the trigger shows the name on first render.\",\n \"Grouped currency picker — set option.group='Asia' / 'Europe' on each option; the plain (non-search) data-driven mode renders SelectGroup headings automatically.\",\n \"Form field in an accounting entry — use the compound API when the trigger must show a currency flag icon alongside the SelectValue; wire SelectTrigger size='sm' for dense table rows.\",\n \"Required department select in a HR form — pass clearable=false so the user cannot clear the field once set; pair with name='department_id' for Inertia useForm submission.\",\n ],\n related: [\n \"SearchSelect — the combobox engine Select delegates to when showSearch=true or loadOptions is set. Prefer Select with showSearch instead of reaching for SearchSelect directly (SearchSelect is now deprecated as a public API).\",\n \"TreeSelect — use when options are hierarchical (parent/child tree). Not a drop-in for Select; has expand/collapse and a separate treeData prop.\",\n \"Autocomplete — deprecated thin wrapper; replaced by Select with options + showSearch.\",\n \"RadioGroup — use instead of Select when there are 2-4 mutually exclusive choices that must all be visible at once without opening a popover.\",\n \"Combobox (if present) — compound cmdk-powered combobox for free-text + suggestion; Select is for strict value lists only.\",\n ],\n example: `import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"@godxjp/ui/data-entry\";\n\n// ── 1. Data-driven (Ant-style) — static list, no search ──────────────────────\nexport function StatusSelect({ value, onChange }) {\n return (\n <Select\n value={value}\n onChange={onChange}\n options={[\n { value: \"draft\", label: \"Draft\" },\n { value: \"sent\", label: \"Sent\" },\n { value: \"paid\", label: \"Paid\" },\n { value: \"overdue\", label: \"Overdue\" },\n ]}\n placeholder=\"Select status\"\n name=\"status\"\n id=\"status\"\n />\n );\n}\n\n// ── 2. Data-driven, searchable static list with groups ────────────────────────\nexport function CurrencySelect({ value, onChange }) {\n return (\n <Select\n value={value}\n onChange={onChange}\n showSearch\n options={[\n { value: \"JPY\", label: \"Japanese Yen\", group: \"Asia\" },\n { value: \"VND\", label: \"Vietnamese Dong\", group: \"Asia\" },\n { value: \"EUR\", label: \"Euro\", group: \"Europe\" },\n { value: \"GBP\", label: \"Pound Sterling\", group: \"Europe\" },\n ]}\n placeholder=\"Select currency\"\n searchPlaceholder=\"Search currencies…\"\n clearable={false}\n name=\"currency\"\n />\n );\n}\n\n// ── 3. Data-driven, async (loadOptions) ──────────────────────────────────────\nexport function AccountSelect({ value, onChange, selectedLabel }) {\n async function loadOptions({ query, page }) {\n const res = await fetch(\\`/api/accounts?q=\\${query}&page=\\${page}\\`);\n const json = await res.json();\n return { options: json.data, hasMore: json.hasMore };\n }\n return (\n <Select\n value={value}\n onChange={onChange}\n loadOptions={loadOptions}\n selectedLabel={selectedLabel}\n placeholder=\"Search accounts…\"\n renderOption={(opt) => (\n <span className=\"flex gap-2\">\n <span className=\"text-muted-foreground font-mono\">{opt.value}</span>\n {opt.label}\n </span>\n )}\n name=\"account_id\"\n />\n );\n}\n\n// ── 4. Compound API — custom trigger content ──────────────────────────────────\nexport function PrioritySelect({ value, onValueChange }) {\n return (\n <Select value={value} onValueChange={onValueChange}>\n <SelectTrigger size=\"sm\" id=\"priority\">\n <SelectValue placeholder=\"Priority\" />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectLabel>Urgency</SelectLabel>\n <SelectItem value=\"high\">High</SelectItem>\n <SelectItem value=\"medium\">Medium</SelectItem>\n </SelectGroup>\n <SelectSeparator />\n <SelectItem value=\"low\">Low</SelectItem>\n </SelectContent>\n </Select>\n );\n}`,\n storyPath: \"data-entry/Select.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"Switch\",\n group: \"data-entry\",\n tagline:\n \"Radix toggle switch (bare). For a labelled row with a hidden form input use SwitchField.\",\n props: [\n { name: \"checked\", type: \"boolean\", description: \"Controlled checked state.\" },\n {\n name: \"onCheckedChange\",\n type: \"(checked: boolean) => void\",\n description: \"Fires when toggled.\",\n },\n { name: \"id\", type: \"string\", description: \"Links to a <Label htmlFor>.\" },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disable the toggle.\",\n },\n ],\n example: `import { Switch, Label } from \"@godxjp/ui/data-entry\";\n\n<div className=\"flex items-center gap-2\">\n <Switch id=\"stackable\" checked={stackable} onCheckedChange={setStackable} />\n <Label htmlFor=\"stackable\">他クーポンとの併用を許可</Label>\n</div>`,\n storyPath: \"data-entry/Switch.stories.tsx\",\n rules: [],\n },\n {\n name: \"Textarea\",\n group: \"data-entry\",\n tagline: \"Styled wrapper around native <textarea>. Pair with FormField for labelled fields.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Associates with a <Label htmlFor>.\" },\n { name: \"rows\", type: \"number\", description: \"Visible text rows.\" },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n {\n name: \"onChange\",\n type: \"React.ChangeEventHandler<HTMLTextAreaElement>\",\n description: \"Change handler.\",\n },\n ],\n example: `import { Textarea } from \"@godxjp/ui/data-entry\";\n\n<Textarea id=\"notes\" rows={4} placeholder=\"自由記述\" value={notes} onChange={(e) => setNotes(e.target.value)} />`,\n storyPath: \"data-entry/Textarea.stories.tsx\",\n rules: [],\n },\n {\n name: \"Label\",\n group: \"data-entry\",\n tagline: \"Styled Radix Label; use htmlFor to associate with a control.\",\n props: [\n { name: \"htmlFor\", type: \"string\", description: \"Id of the associated control.\" },\n { name: \"children\", type: \"ReactNode\", description: \"Label content.\" },\n ],\n example: `import { Label } from \"@godxjp/ui/data-entry\";\n\n<Label htmlFor=\"stackable\">併用を許可</Label>`,\n storyPath: \"data-entry/Label.stories.tsx\",\n rules: [],\n },\n {\n name: \"Checkbox\",\n group: \"data-entry\",\n tagline: \"Radix checkbox; standalone or via CheckboxGroup with an options array.\",\n props: [\n {\n name: \"checked\",\n type: \"boolean | 'indeterminate'\",\n description: \"Controlled checked state.\",\n },\n {\n name: \"onCheckedChange\",\n type: \"(checked) => void\",\n description: \"Fires when checked state changes.\",\n },\n { name: \"id\", type: \"string\", description: \"Links to a <Label htmlFor>.\" },\n ],\n example: `import { Checkbox, Label } from \"@godxjp/ui/data-entry\";\n\n<div className=\"flex items-center gap-2\">\n <Checkbox id=\"agree\" checked={agreed} onCheckedChange={(v) => setAgreed(!!v)} />\n <Label htmlFor=\"agree\">利用規約に同意する</Label>\n</div>`,\n storyPath: \"data-entry/Checkbox.stories.tsx\",\n rules: [],\n },\n {\n name: \"RadioGroup\",\n group: \"data-entry\",\n tagline: \"Radio group accepting an options array or RadioItem children.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled selected value.\" },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Fires on selection change.\",\n },\n {\n name: \"options\",\n type: \"ChoiceOptionProp[]\",\n description: \"Declarative list: { label, value, disabled?, description? }.\",\n },\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"vertical\"',\n description: \"Layout direction.\",\n },\n ],\n example: `import { RadioGroup } from \"@godxjp/ui/data-entry\";\n\n<RadioGroup value={trigger} onValueChange={setTrigger} orientation=\"horizontal\" options={[\n { label: \"初回購入\", value: \"first_purchase\" },\n { label: \"誕生日\", value: \"birthday\" },\n]} />`,\n storyPath: \"data-entry/RadioGroup.stories.tsx\",\n rules: [23],\n },\n {\n name: \"DatePicker\",\n group: \"data-entry\",\n tagline:\n \"WAI-ARIA date combobox with a real typeable ISO-8601 input — give it a `name` for form submission and fill the input in e2e tests; the calendar is the visual-only affordance.\",\n props: [\n {\n name: \"value\",\n type: \"Date | undefined\",\n description:\n \"Controlled selected date. When provided the input text and the calendar selection stay in sync with this value.\",\n },\n {\n name: \"onChange\",\n type: \"(date: Date | undefined) => void\",\n description:\n \"Called when the user commits a date — either by typing a valid ISO string into the input or clicking a day in the calendar popover. Called with `undefined` when the input is cleared.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML `name` attribute placed on the underlying `<input>`. The input emits the value as an ISO-8601 `yyyy-MM-dd` string so the field is natively form-submittable without a hidden input.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description: \"HTML `id` placed on the underlying `<input>`, used to associate a `<label>`.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n defaultValue: '\"yyyy-mm-dd\" (or locale-translated equivalent)',\n description:\n \"Placeholder text shown in the input when no date is selected. Defaults to the i18n key `dataEntry.datePicker.placeholder` then falls back to the literal hint `yyyy-mm-dd`.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables both the text input and the calendar icon button.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra CSS classes applied to the outermost wrapper `<div>`. Use for width/margin overrides.\",\n },\n {\n name: \"locale\",\n type: 'DayPickerProps[\"locale\"]',\n description:\n \"Locale object (from `date-fns/locale`) forwarded to the calendar popover. Controls month/day names shown in the grid. The input always accepts `yyyy-MM-dd` regardless of locale.\",\n },\n {\n name: \"fromDate\",\n type: \"Date\",\n description:\n \"Earliest selectable date in the calendar. Days before this date are disabled in the grid, and the calendar navigation starts at this month.\",\n },\n {\n name: \"toDate\",\n type: \"Date\",\n description:\n \"Latest selectable date in the calendar. Days after this date are disabled in the grid, and the calendar navigation ends at this month.\",\n },\n ],\n usage: [\n \"DO use `name` to make the field form-submittable — the underlying `<input>` emits the value as an ISO-8601 `yyyy-MM-dd` string. No hidden input is needed.\",\n \"DO test by filling the input directly: `await user.type(screen.getByRole('combobox'), '2024-04-15')` or with Playwright `page.fill('[role=combobox]', '2024-04-15')`. The calendar popover is secondary and not required for testing.\",\n \"DO use `fromDate` / `toDate` to restrict selectable dates (e.g. ETD must be after today, period end must be after period start).\",\n \"DON'T wrap DatePicker in an extra `<div>` for a form field — use `name` directly and pair it with a `<label htmlFor={id}>` for a11y.\",\n \"DON'T hand-roll a date text input + calendar popover — this component IS that pattern at WAI-ARIA combobox spec level.\",\n \"DON'T use DatePicker for a date range — use `DateRangePicker` instead (it exposes two ISO inputs named `${name}_from` and `${name}_to`).\",\n ],\n useCases: [\n \"Invoice due-date field in an accounting form — attach `name='due_date'` and submit natively.\",\n \"ETD / ETA date entry on a shipment create/edit form where the field must be form-submittable and e2e-fillable.\",\n \"Filter bar date input (e.g. 'From date' in a report filter) where the user typically types the date rather than clicking through a calendar.\",\n \"Restricting a 'closing date' to only future dates by passing `fromDate={new Date()}` to block past selection.\",\n \"Locale-aware date picker in a multi-language admin panel — pass a `date-fns` locale object to show the calendar grid in the user's language while keeping the ISO input format consistent.\",\n ],\n related: [\n \"DateRangePicker — use instead of DatePicker when you need a from/to date pair; exposes two ISO inputs named `${name}_from` / `${name}_to`.\",\n \"TimePicker — companion for HH:mm time selection; same form-submittable-input pattern with a `name` prop.\",\n \"Calendar — the bare calendar grid used inside DatePicker; use it only when you need a always-visible month grid with no input.\",\n ],\n example: `import { useState } from \"react\";\nimport { DatePicker } from \"@godxjp/ui/data-entry\";\n\n// Controlled — single date field with form name\nexport function InvoiceDueDateField() {\n const [dueDate, setDueDate] = useState<Date | undefined>(undefined);\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor=\"due-date\" className=\"text-sm font-medium\">\n Due Date\n </label>\n <DatePicker\n id=\"due-date\"\n name=\"due_date\"\n value={dueDate}\n onChange={setDueDate}\n fromDate={new Date()}\n placeholder=\"yyyy-mm-dd\"\n />\n </div>\n );\n}`,\n storyPath: \"data-entry/DatePicker.stories.tsx\",\n rules: [3, 6, 13, 31],\n },\n\n // ─── feedback ───────────────────────────────────────────────────────────\n {\n name: \"Dialog\",\n group: \"feedback\",\n tagline:\n 'Compound modal. Controlled via open + onOpenChange. Parts available flat (DialogTrigger/DialogContent/…) or as Dialog.Trigger/Dialog.Content. mode=\"confirm\" switches to alertdialog.',\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state change handler.\",\n },\n {\n name: \"mode\",\n type: '\"form\" | \"confirm\"',\n defaultValue: '\"form\"',\n description: \"form = Radix Dialog (× close); confirm = AlertDialog (no ×).\",\n },\n ],\n example: `import { useState } from \"react\";\nimport { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from \"@godxjp/ui/feedback\";\nimport { Button } from \"@godxjp/ui/general\";\n\nfunction CreateDialog() {\n const [open, setOpen] = useState(false);\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild><Button size=\"sm\">新規作成</Button></DialogTrigger>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>新規クーポン作成</DialogTitle>\n <DialogDescription>クーポン情報を入力してください。</DialogDescription>\n </DialogHeader>\n {/* fields */}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setOpen(false)}>キャンセル</Button>\n <Button onClick={() => setOpen(false)}>保存</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}`,\n storyPath: \"feedback/Dialog.stories.tsx\",\n rules: [23, 3],\n },\n {\n name: \"Sheet\",\n group: \"feedback\",\n tagline:\n \"Side-panel drawer (Radix Dialog). Parts: Sheet/SheetTrigger/SheetContent(side=right|left|top|bottom)/SheetHeader/SheetTitle/SheetFooter.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state change handler.\",\n },\n ],\n example: `import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle } from \"@godxjp/ui/feedback\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Sheet open={open} onOpenChange={setOpen}>\n <SheetTrigger asChild><Button variant=\"outline\" size=\"sm\">絞り込み</Button></SheetTrigger>\n <SheetContent side=\"right\">\n <SheetHeader><SheetTitle>フィルター設定</SheetTitle></SheetHeader>\n {/* filter fields */}\n </SheetContent>\n</Sheet>`,\n storyPath: \"feedback/Sheet.stories.tsx\",\n rules: [3],\n },\n {\n name: \"Alert\",\n group: \"feedback\",\n tagline:\n \"Inline alert banner with variant-aware icon + optional dismiss. Parts: Alert/AlertTitle/AlertDescription/AlertActions/AlertQueryError.\",\n props: [\n {\n name: \"variant\",\n type: '\"default\" | \"destructive\" | \"warning\" | \"success\"',\n defaultValue: '\"default\"',\n description: \"Colour scheme + default icon.\",\n },\n {\n name: \"onDismiss\",\n type: \"() => void\",\n description: \"Renders an × dismiss button when provided.\",\n },\n {\n name: \"icon\",\n type: \"LucideIcon | false\",\n description: \"Override or hide (false) the icon.\",\n },\n ],\n example: `import { Alert, AlertTitle, AlertDescription } from \"@godxjp/ui/feedback\";\n\n<Alert variant=\"warning\">\n <AlertTitle>3 件の打刻漏れがあります</AlertTitle>\n <AlertDescription>本日中に確認してください。</AlertDescription>\n</Alert>`,\n storyPath: \"feedback/Alert.stories.tsx\",\n rules: [],\n },\n {\n name: \"SkeletonTable\",\n group: \"feedback\",\n tagline:\n \"Loading placeholder matching the DataTable layout (header + N rows). Drop-in while data loads (deferred props).\",\n props: [\n { name: \"rows\", type: \"number\", defaultValue: \"8\", description: \"Body skeleton rows.\" },\n {\n name: \"columns\",\n type: \"number\",\n defaultValue: \"5\",\n description: \"Columns in header + body.\",\n },\n ],\n example: `import { SkeletonTable } from \"@godxjp/ui/feedback\";\n\n{!coupons ? <SkeletonTable rows={10} columns={6} /> : <DataTable data={coupons} columns={columns} />}`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [],\n },\n {\n name: \"SkeletonCard\",\n group: \"feedback\",\n tagline:\n \"Loading placeholder shaped like a CardStat tile. Use inside a ResponsiveGrid while KPIs load.\",\n props: [],\n example: `import { SkeletonCard } from \"@godxjp/ui/feedback\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n<ResponsiveGrid columns={4}><SkeletonCard /><SkeletonCard /><SkeletonCard /><SkeletonCard /></ResponsiveGrid>`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [],\n },\n {\n name: \"Toaster\",\n group: \"feedback\",\n tagline:\n 'Mount once at app root to enable toasts. IMPORTANT: trigger toasts via `import { toast } from \"sonner\"` — NOT from @godxjp/ui.',\n props: [\n {\n name: \"position\",\n type: '\"top-right\" | \"top-center\" | \"bottom-right\" | \"…\"',\n defaultValue: '\"bottom-right\"',\n description: \"Toast stack anchor.\",\n },\n { name: \"richColors\", type: \"boolean\", description: \"Enable Sonner rich variant colours.\" },\n ],\n example: `// app root — mount once\nimport { Toaster } from \"@godxjp/ui/feedback\";\n<>{children}<Toaster richColors /></>\n\n// anywhere — import toast from \"sonner\"\nimport { toast } from \"sonner\";\ntoast.success(\"クーポンを公開しました\");\ntoast.error(\"保存に失敗しました\");`,\n storyPath: \"feedback/Toaster.stories.tsx\",\n rules: [],\n },\n\n // ─── navigation ─────────────────────────────────────────────────────────\n {\n name: \"Tabs\",\n group: \"navigation\",\n tagline:\n \"Radix tab container. Compose Tabs/TabsList/TabsTrigger/TabsContent. Controlled (value/onValueChange) or uncontrolled (defaultValue).\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled active tab key.\" },\n { name: \"defaultValue\", type: \"string\", description: \"Uncontrolled initial tab key.\" },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Active-tab change handler.\",\n },\n ],\n example: `import { Tabs, TabsList, TabsTrigger, TabsContent } from \"@godxjp/ui/navigation\";\n\n<Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">概要</TabsTrigger>\n <TabsTrigger value=\"history\">履歴</TabsTrigger>\n </TabsList>\n <TabsContent value=\"overview\">概要コンテンツ</TabsContent>\n <TabsContent value=\"history\">履歴コンテンツ</TabsContent>\n</Tabs>`,\n storyPath: \"navigation/Tabs.stories.tsx\",\n rules: [],\n },\n {\n name: \"FilterBar\",\n group: \"navigation\",\n tagline:\n \"Standard list-page filter strip. Place ABOVE the table Card — NEVER inside CardContent flush (it strips padding). Compose with FilterGroup + SearchInput + Select.\",\n props: [\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"Filter controls + FilterGroup wrappers.\",\n },\n {\n name: \"hasActiveFilters\",\n type: \"boolean\",\n description: \"Shows a clear-all button when true.\",\n },\n { name: \"onClear\", type: \"() => void\", description: \"Clear-all handler.\" },\n ],\n example: `import { FilterBar, FilterGroup } from \"@godxjp/ui/navigation\";\nimport { SearchInput, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"@godxjp/ui/data-entry\";\n\n<FilterBar hasActiveFilters={search !== \"\"} onClear={() => setSearch(\"\")}>\n <SearchInput placeholder=\"名前で検索\" value={search} onSearch={setSearch} />\n <FilterGroup label=\"ステータス\">\n <Select value={status} onValueChange={setStatus}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">すべて</SelectItem>\n <SelectItem value=\"active\">有効</SelectItem>\n </SelectContent>\n </Select>\n </FilterGroup>\n</FilterBar>`,\n storyPath: \"navigation/FilterBar.stories.tsx\",\n rules: [38, 40],\n },\n {\n name: \"FilterGroup\",\n group: \"navigation\",\n tagline: \"Labelled filter slot inside FilterBar — wraps a single Select/DatePicker.\",\n props: [\n {\n name: \"label\",\n type: \"ReactNode\",\n required: true,\n description: \"Label shown with the child control.\",\n },\n { name: \"children\", type: \"ReactNode\", required: true, description: \"The filter control.\" },\n ],\n example: `import { FilterGroup } from \"@godxjp/ui/navigation\";\n\n<FilterGroup label=\"スコープ\"><Select>{/* ... */}</Select></FilterGroup>`,\n storyPath: \"navigation/FilterBar.stories.tsx\",\n rules: [38],\n },\n {\n name: \"Pagination\",\n group: \"navigation\",\n tagline: \"Offset/page-based pagination bar. Sits below a table card.\",\n props: [\n {\n name: \"current\",\n type: \"number\",\n defaultValue: \"1\",\n description: \"Current page (1-indexed).\",\n },\n { name: \"total\", type: \"number\", description: \"Total number of items.\" },\n { name: \"pageSize\", type: \"number\", defaultValue: \"10\", description: \"Items per page.\" },\n {\n name: \"showTotal\",\n type: \"boolean | (total, range) => ReactNode\",\n description: \"Show total count, or a custom label fn.\",\n },\n {\n name: \"onChange\",\n type: \"(page: number, pageSize: number) => void\",\n description: \"Page / page-size change handler.\",\n },\n ],\n example: `import { Pagination } from \"@godxjp/ui/navigation\";\n\n<Pagination current={page} total={filtered.length} pageSize={10} showTotal onChange={(p) => setPage(p)} />`,\n storyPath: \"navigation/Pagination.stories.tsx\",\n rules: [40],\n },\n {\n name: \"DropdownMenu\",\n group: \"navigation\",\n tagline:\n \"Radix dropdown menu. Compose DropdownMenu/DropdownMenuTrigger/DropdownMenuContent/DropdownMenuItem/DropdownMenuSeparator.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state change handler.\",\n },\n ],\n example: `import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from \"@godxjp/ui/navigation\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<DropdownMenu>\n <DropdownMenuTrigger asChild><Button variant=\"outline\" size=\"sm\">操作</Button></DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem>編集</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem variant=\"destructive\">削除</DropdownMenuItem>\n </DropdownMenuContent>\n</DropdownMenu>`,\n storyPath: \"navigation/DropdownMenu.stories.tsx\",\n rules: [],\n },\n {\n name: \"Steps\",\n group: \"navigation\",\n tagline: \"Multi-step progress indicator — horizontal or vertical, default or dot style.\",\n props: [\n {\n name: \"items\",\n type: \"StepItemProp[]\",\n description: \"Array of { title, subTitle?, description?, icon?, status? }.\",\n },\n {\n name: \"current\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Active step index (0-based).\",\n },\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Layout direction.\",\n },\n ],\n example: `import { Steps } from \"@godxjp/ui/navigation\";\n\n<Steps current={1} items={[{ title: \"申請\" }, { title: \"審査中\" }, { title: \"完了\" }]} />`,\n storyPath: \"navigation/Steps.stories.tsx\",\n rules: [],\n },\n\n // ─── providers / datetime ───────────────────────────────────────────────\n {\n name: \"AppProvider\",\n group: \"providers\",\n tagline:\n \"Root locale/timezone/date-time context — wrap the app ONCE. All pickers + formatDate read from it. Import from @godxjp/ui/app.\",\n props: [\n {\n name: \"defaultLocale\",\n type: '\"ja\" | \"en\" | \"vi\"',\n defaultValue: '\"vi\"',\n description: \"Initial locale.\",\n },\n {\n name: \"defaultTimezone\",\n type: 'string | \"browser\" | \"system\"',\n defaultValue: '\"browser\"',\n description: \"Initial IANA timezone.\",\n },\n {\n name: \"defaultDateFormat\",\n type: '\"iso\" | \"dmy\" | \"mdy\" | \"locale\"',\n defaultValue: '\"locale\"',\n description: \"Initial date display format.\",\n },\n {\n name: \"defaultTimeFormat\",\n type: '\"24h\" | \"12h\" | \"locale\"',\n defaultValue: '\"locale\"',\n description: \"Initial clock format.\",\n },\n ],\n example: `import { AppProvider } from \"@godxjp/ui/app\";\n\n<AppProvider defaultLocale=\"ja\" defaultTimezone=\"Asia/Tokyo\" defaultDateFormat=\"iso\" defaultTimeFormat=\"24h\">\n {children}\n</AppProvider>`,\n storyPath: \"app/AppProvider.stories.tsx\",\n rules: [5],\n },\n {\n name: \"formatDate\",\n group: \"providers\",\n tagline:\n \"MANDATORY for all date/time display. Auto-detects ISO date / HH:mm / instant; reads AppProvider context. Import from @godxjp/ui/datetime.\",\n props: [\n {\n name: \"value\",\n type: \"string | Date | null | undefined\",\n required: true,\n description: \"ISO date, ISO datetime, HH:mm, or Date.\",\n },\n {\n name: \"options.kind\",\n type: '\"auto\" | \"date\" | \"datetime\" | \"time\" | \"long\" | \"relative\"',\n defaultValue: '\"auto\"',\n description: \"Output preset; auto infers from the value.\",\n },\n ],\n example: `import { formatDate } from \"@godxjp/ui/datetime\";\n\nformatDate(coupon.validFrom); // \"2026-05-01\"\nformatDate(order.createdAt, { kind: \"relative\" }); // \"3日前\"`,\n storyPath: \"app/formatDate.stories.tsx\",\n rules: [5],\n },\n // ─── backfill 2026-06 (Tooltip, pickers, advanced data-entry, query helpers) ───\n {\n name: \"TimePicker\",\n group: \"data-entry\",\n tagline:\n \"24h HH:mm time combobox with a scrollable hour/minute popover — the visible input IS the form field; give it a `name` prop and it submits directly, no hidden mirror needed.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled value in HH:mm (24h) format. When provided the component is fully controlled — you must update it via `onChange`.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description:\n \"Uncontrolled initial value in HH:mm format. Used only when `value` is not provided.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string) => void\",\n description:\n \"Called with the canonical HH:mm string whenever the user commits a time (picks from columns or types and blurs/presses Enter). Not called for every keystroke.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form field name. The visible `<input>` carries this name and emits the canonical HH:mm value on native form submission — no hidden element needed.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description:\n \"HTML id for the visible input — use with a `<label htmlFor>` for accessibility.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n defaultValue: \"hh:mm (i18n fallback)\",\n description:\n \"Placeholder text shown when the input is empty. Falls back to the i18n key `dataEntry.timePicker.placeholder`.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables both the visible input and the clock-icon popover trigger.\",\n },\n {\n name: \"minuteStep\",\n type: \"number\",\n defaultValue: \"5\",\n description:\n \"Step for the minute column (1–60). Only multiples of this step appear in the picker; typed values are still free-form and normalized on blur.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra Tailwind classes applied to the outer wrapper `<div>`. Use for width overrides (e.g. `w-32`).\",\n },\n ],\n usage: [\n \"DO give it a `name` prop whenever it lives inside a `<form>` — the visible input carries the name and emits `HH:mm` on native submission. You do NOT need a hidden element.\",\n \"DO use the controlled pattern (`value` + `onChange`) in React-managed forms (e.g. useForm). For simple HTML forms without React state, omit `value` and use `defaultValue` for the uncontrolled pattern.\",\n \"DON'T pass a raw `<input type='time'>` alongside or instead — this component IS the input, fully accessible (role='combobox', aria-expanded, aria-haspopup) and e2e-testable by filling the text input directly.\",\n \"DO pair with a `<label htmlFor={id}>` for screen-reader accessibility — the component renders a plain `<input>` internally that `id` connects to.\",\n \"DON'T expect `onChange` on every keystroke — it fires only when a valid HH:mm is committed (column pick closes popover; typed value normalised on blur or Enter). Guard downstream logic accordingly.\",\n \"DO adjust `minuteStep` for domain needs (e.g. `minuteStep={15}` for scheduling, `minuteStep={1}` for precise entry) — the minute column only shows multiples, but the type-in field accepts any valid HH:mm.\",\n ],\n useCases: [\n \"Shift/schedule entry forms where workers select start and end times from a scrollable hour/minute grid (use `minuteStep={15}` or `minuteStep={30}`).\",\n \"Invoice or transaction timestamp fields that require a 24h HH:mm time alongside a DatePicker — pair the two in a flex row.\",\n \"Logistics cut-off time configuration (e.g. 'last order by') where the default `minuteStep={5}` aligns with typical operational granularity.\",\n \"Admin settings panels that persist a canonical HH:mm string to the database — the `name` prop makes native form submission trivial.\",\n \"Time-range pickers (from/to) — render two TimePicker instances side-by-side with separate controlled values and validate that `to > from` in `onChange`.\",\n \"E2E-tested forms — test helpers can fill the text input directly (it accepts typed HH:mm) without needing to interact with the popover columns.\",\n ],\n related: [\n \"DatePicker — use for calendar date selection; combine with TimePicker in a flex row when you need a full datetime. DatePicker emits an ISO date string; TimePicker emits HH:mm.\",\n \"Input — the raw primitive TimePicker wraps internally. Use Input directly only when you need a plain text field with no time semantics or popover.\",\n \"ColorPicker — another popover-backed input primitive in the same group; structurally similar pattern but for hex colour values.\",\n ],\n example: `import { TimePicker } from \"@godxjp/ui/data-entry\";\nimport { useState } from \"react\";\n\n// Controlled usage inside a React form\nexport function ShiftStartField() {\n const [startTime, setStartTime] = useState(\"09:00\");\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor=\"shift-start\" className=\"text-sm font-medium\">\n Shift start\n </label>\n <TimePicker\n id=\"shift-start\"\n name=\"shift_start\"\n value={startTime}\n onChange={setStartTime}\n minuteStep={15}\n className=\"w-36\"\n />\n </div>\n );\n}\n\n// Uncontrolled usage inside a native form\nexport function CutoffTimeForm() {\n return (\n <form method=\"post\" action=\"/settings/cutoff\">\n <TimePicker\n id=\"cutoff\"\n name=\"cutoff_time\"\n defaultValue=\"17:00\"\n minuteStep={30}\n placeholder=\"hh:mm\"\n />\n <button type=\"submit\">Save</button>\n </form>\n );\n}`,\n storyPath: \"data-entry/TimePicker.stories.tsx\",\n rules: [3, 6, 13, 23],\n },\n {\n name: \"DateRangePicker\",\n group: \"data-entry\",\n tagline:\n \"WAI-ARIA date-range control with two typeable ISO inputs + popover calendar — form-submits as `${name}_from` / `${name}_to`, never hand-roll two DatePickers side-by-side.\",\n props: [\n {\n name: \"value\",\n type: \"DateRange | undefined\",\n description:\n \"Controlled value — object with optional `from: Date` and `to: Date` from react-day-picker. Pass undefined to clear.\",\n },\n {\n name: \"onChange\",\n type: \"(range: DateRange | undefined) => void\",\n description:\n \"Called whenever either text input commits or the calendar selects a range. Receives undefined when both edges are cleared.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form field name prefix. Emits two native hidden-compatible inputs: `${name}_from` and `${name}_to`, each as an ISO yyyy-MM-dd string. Required for native form submission.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description:\n \"DOM id wired to the FROM input. Used by FormField's htmlFor to attach the label to the first focusable control.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n defaultValue: \"i18n key dataEntry.dateRangePicker.placeholder or 'yyyy-mm-dd'\",\n description:\n \"Placeholder shown in both inputs when empty. Defaults to the project i18n translation or the literal ISO hint 'yyyy-mm-dd'.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n description: \"Disables both text inputs and the calendar trigger button.\",\n },\n {\n name: \"locale\",\n type: 'DayPickerProps[\"locale\"]',\n description:\n \"react-day-picker locale object forwarded to the Calendar popover. Overrides the project-level locale resolved from usePickerLocales.\",\n },\n {\n name: \"fromDate\",\n type: \"Date\",\n description:\n \"Earliest selectable date. Disables calendar days before this date and pins the calendar's startMonth.\",\n },\n {\n name: \"toDate\",\n type: \"Date\",\n description:\n \"Latest selectable date. Disables calendar days after this date and pins the calendar's endMonth.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra CSS classes applied to the root flex container (flex items-center gap-1). Use to constrain width or adjust layout; avoid overriding token colors.\",\n },\n ],\n usage: [\n \"DO use controlled mode (`value` + `onChange`) in all form contexts — this component has no `defaultValue` prop; initialize state with `useState<DateRange | undefined>()`.\",\n \"DO set `name` when the form is submitted natively or via Inertia useForm: the component emits `${name}_from` and `${name}_to` as ISO yyyy-MM-dd strings — read them as separate fields on the server.\",\n 'DO wrap in `<FormField id=\"...\" label=\"...\">` to attach the label; pass the same string to both `FormField`\\'s `id` and `DateRangePicker`\\'s `id` so the label targets the FROM input.',\n \"DON'T compose two `<DatePicker>` components side-by-side to achieve a range — `DateRangePicker` handles range state, calendar highlight, and dual form submission in one atomic control.\",\n \"DON'T rely on the calendar popover alone for e2e testing — both inputs are real typeable `<input>` elements; fill them directly with ISO strings (e.g. `fill('#from-id', '2026-01-01')`) in Playwright/Pest browser tests.\",\n \"Use `fromDate` / `toDate` to constrain the selectable window (e.g. fiscal year bounds, invoice cutoff), not just visual decoration — they also disable out-of-range keyboard navigation in the calendar.\",\n ],\n useCases: [\n \"Invoice period filter on an accounting list page: let the user pick a start/end date; submit as `period_from` + `period_to` query params.\",\n \"Manifest / shipment date range in a logistics form: wrap in FormField with label 'Kỳ lô hàng', constrain with `fromDate`/`toDate` to the valid manifest window.\",\n \"Report generation wizard where users define a custom reporting period (e.g. fiscal quarter start to end).\",\n \"Dashboard date-range filter in a toolbar: controlled state drives a TanStack Query `queryKey` to refetch charts when the range changes.\",\n \"Booking or reservation form that requires both an arrival and departure date in a single field, with `fromDate={today}` to block past dates.\",\n \"Admin audit log search where start and end timestamps are captured as ISO date strings for a backend query.\",\n ],\n related: [\n \"DatePicker — single-date variant; use DateRangePicker when TWO boundary dates are required. Never place two DatePickers side-by-side to fake a range.\",\n \"Calendar — the headless month grid used internally by DateRangePicker; use directly only for custom embedded calendar UI, not as a form control.\",\n \"TimePicker — companion for HH:mm selection; combine with DateRangePicker when datetime ranges are needed (store separately).\",\n ],\n example: `import { useState } from \"react\";\nimport type { DateRange } from \"react-day-picker\";\nimport { DateRangePicker, FormField } from \"@godxjp/ui/data-entry\";\n\nexport function InvoicePeriodFilter() {\n const [range, setRange] = useState<DateRange | undefined>({\n from: new Date(2026, 0, 1),\n to: new Date(2026, 11, 31),\n });\n\n return (\n <FormField id=\"invoice-period\" label=\"Invoice period\" className=\"max-w-sm\">\n <DateRangePicker\n id=\"invoice-period\"\n name=\"period\"\n value={range}\n onChange={setRange}\n fromDate={new Date(2020, 0, 1)}\n toDate={new Date(2030, 11, 31)}\n />\n </FormField>\n // Submits: period_from=2026-01-01, period_to=2026-12-31\n );\n}`,\n storyPath: \"data-entry/DateRangePicker.stories.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"SwitchField\",\n group: \"data-entry\",\n tagline:\n \"Labelled boolean switch with a hidden 0/1 input for HTML form submission — use this instead of bare Switch whenever you need a label or a form name.\",\n props: [\n {\n name: \"label\",\n type: \"string\",\n required: true,\n description: \"Visible text label rendered to the right of the switch toggle.\",\n },\n {\n name: \"name\",\n type: \"string\",\n required: true,\n description:\n \"HTML name attribute used by the hidden input — the value submitted is '1' (on) or '0' (off).\",\n },\n {\n name: \"id\",\n type: \"string\",\n description:\n \"ID wired to the Switch and Label htmlFor. Auto-generated via useId() when omitted.\",\n },\n {\n name: \"checked\",\n type: \"boolean\",\n description:\n \"Controlled checked state. When provided the component is fully controlled; onCheckedChange must also be supplied.\",\n },\n {\n name: \"defaultChecked\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Uncontrolled initial checked state. Ignored when checked is provided.\",\n },\n {\n name: \"onCheckedChange\",\n type: \"(checked: boolean) => void\",\n description: \"Fires with the new boolean value whenever the switch is toggled.\",\n },\n {\n name: \"required\",\n type: \"boolean\",\n description:\n \"Marks the field as required — renders a red asterisk next to the label and sets aria-required on the switch.\",\n },\n {\n name: \"helper\",\n type: \"string\",\n description: \"Secondary hint text shown below the label. Hidden when error is set.\",\n },\n {\n name: \"error\",\n type: \"string\",\n description:\n \"Validation error message. Renders below the row as a role=alert paragraph and sets aria-invalid on the switch.\",\n },\n {\n name: \"labelAddon\",\n type: \"React.ReactNode\",\n description:\n \"Optional node rendered inline after the label text (e.g. a Badge or tooltip trigger).\",\n },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the switch toggle.\" },\n {\n name: \"size\",\n type: '\"sm\" | \"default\"',\n description: \"Switch toggle size. Forwarded to the inner Switch primitive.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra class names applied to the outer wrapper div.\",\n },\n ],\n usage: [\n \"DO use SwitchField (not bare Switch) whenever a form name is required — it automatically mirrors a hidden input with value '1'/'0' so native HTML form.submit() and FormData work without extra wiring.\",\n \"DO NOT use SwitchField without the name prop if you are not submitting via HTML form — pass name anyway; it is required by the type signature and is a safe no-op when FormData is not read.\",\n \"Controlled mode: supply both checked and onCheckedChange. Uncontrolled mode: use defaultChecked only. Never mix — passing checked without onCheckedChange leaves the switch frozen.\",\n \"The error prop replaces the helper text — both cannot appear simultaneously. Show validation errors via error, not as helper text that is always visible.\",\n \"labelAddon is rendered inline after the label text at the same font size — use it for a small Badge ('Beta'), InfoTooltip, or similar inline decoration, NOT for a full action button.\",\n \"NEVER hand-roll a Switch + Label + hidden-input pattern yourself; SwitchField already composes Switch, Label, hidden input, aria-describedby, aria-required, aria-invalid, and role=alert in a single component.\",\n ],\n useCases: [\n \"Settings toggles in an admin form (e.g. 'Enable auto-invoice', 'Allow concurrent sessions') where the page POSTs via Inertia useForm — the hidden 0/1 input is picked up by FormData automatically.\",\n \"Permissions or feature-flag checkboxes on a user/role edit page where the UI needs a helper hint ('Allows access to billing module') alongside the toggle.\",\n \"Inline required toggles in a multi-step wizard step where validation errors need to surface below the row via the error prop.\",\n \"Accounting app: 'Mark as reconciled', 'Exclude from report', 'Apply tax-exempt status' — boolean flags that must be submitted with the record form.\",\n \"Row-level status toggles in a card layout (e.g. 'Active' on a payment method card) using the sm size to keep the toggle compact.\",\n \"Any boolean setting that needs a visible label + accessible association (htmlFor / aria) without writing the Switch + Label wiring manually.\",\n ],\n related: [\n \"Switch — bare Radix toggle with no label, no hidden input, and no error/helper. Use Switch when you are managing the label yourself (e.g. inside a custom flex row) and do not need HTML form submission. Use SwitchField for any form field that needs a label, helper, error, or native form submission.\",\n \"Checkbox / CheckboxField — semantically for multi-select or tri-state (indeterminate). Use Checkbox for 'agree to terms' or multi-option selection. Use SwitchField for a single on/off boolean setting where the switch affordance fits better than a checkbox.\",\n \"FormField — generic field wrapper used by Input, Select, etc. SwitchField already bundles its own label/error layout; do NOT also wrap it in FormField.\",\n ],\n example: `import { SwitchField } from \"@godxjp/ui/data-entry\";\nimport { useState } from \"react\";\n\n// Uncontrolled — defaultChecked, value submitted as hidden 0/1\n<SwitchField\n name=\"auto_invoice\"\n label=\"自動請求を有効にする\"\n helper=\"有効にすると月末に自動で請求書が発行されます\"\n defaultChecked={false}\n/>\n\n// Controlled with validation error\nfunction ReconcileToggle({ value, onChange }: { value: boolean; onChange: (v: boolean) => void }) {\n return (\n <SwitchField\n name=\"reconciled\"\n label=\"照合済み\"\n checked={value}\n onCheckedChange={onChange}\n required\n error={!value ? \"照合を完了してください\" : undefined}\n />\n );\n}`,\n storyPath: \"data-entry/SwitchField.stories.tsx\",\n rules: [3, 6, 13, 23],\n },\n {\n name: \"Cascader\",\n group: \"data-entry\",\n tagline:\n \"Multi-level hierarchical path picker (Popover + cascading columns); value is always a string[] path, never a flat ID — passing a bare string breaks it.\",\n props: [\n {\n name: \"options\",\n type: \"TreeOptionProp[]\",\n required: true,\n description:\n \"The hierarchical option tree. Each node has { value: string; label: ReactNode; disabled?: boolean; isLeaf?: boolean; children?: TreeOptionProp[] }. Normalised internally via fieldNames.\",\n },\n {\n name: \"value\",\n type: \"string[] | string[][]\",\n description:\n \"Controlled value. Single mode: string[] path (e.g. ['vn','hcm','q1']). Multiple mode: string[][] array of paths. Omit for uncontrolled.\",\n },\n {\n name: \"defaultValue\",\n type: \"string[] | string[][]\",\n description: \"Initial value for uncontrolled mode. Same shape as value.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string[] | string[][], selectedOptions?: TreeOptionProp[] | TreeOptionProp[][]) => void\",\n description:\n \"Fires when selection changes. First arg is the selected path(s); second is the matching node objects. On clear, called with [].\",\n },\n {\n name: \"multiple\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Enable multi-path selection. Renders checkboxes in columns and search results. Panel stays open on each pick. value/defaultValue become string[][].\",\n },\n {\n name: \"changeOnSelect\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, clicking any node (including branch nodes with children) commits that path immediately instead of waiting for a leaf selection.\",\n },\n {\n name: \"showSearch\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Renders a CommandInput at the top of the popover. Filters to matching leaf paths across the whole tree when a query is typed; reverts to cascade columns when the query is cleared.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description:\n \"Trigger button placeholder text when no value is selected. Defaults to the i18n key dataEntry.cascader.placeholder.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables the trigger button and prevents the popover from opening.\",\n },\n {\n name: \"expandTrigger\",\n type: '\"click\" | \"hover\"',\n defaultValue: '\"click\"',\n description:\n \"How child columns are expanded. 'hover' expands on mouseenter and collapses back on mouseleave.\",\n },\n {\n name: \"fieldNames\",\n type: \"TreeFieldNamesProp\",\n description:\n \"Remap custom data keys: { label?: string; value?: string; children?: string }. Use when your data uses e.g. 'name' and 'id' instead of 'label' and 'value'.\",\n },\n {\n name: \"allowClear\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Shows an X icon on the trigger when a value is selected. Clicking it calls onChange([]) and resets to placeholder.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra Tailwind classes applied to the trigger button.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description: \"HTML id forwarded to the trigger button. Use to associate a <label htmlFor>.\",\n },\n ],\n usage: [\n \"DO pass a string[] path as value in single mode (e.g. ['country','region','city']). DON'T pass a flat string ID — the component treats value as an ordered path array and will render nothing if you pass a bare string.\",\n \"DO use value + onChange together for controlled mode, or defaultValue alone for uncontrolled. DON'T mix both — providing value without onChange makes the field read-only (the internal state won't update).\",\n \"DO set multiple={true} and pass value as string[][] (array of paths) for multi-selection. onChange receives string[][] in that mode. Mixing single-mode shape with multiple={true} silently produces no selection.\",\n \"DON'T hand-roll a search input next to Cascader. Use showSearch={true} — it adds a built-in CommandInput that filters leaf paths across the full tree and reverts to cascade columns when cleared.\",\n \"DO use fieldNames to remap data keys ({label:'name', value:'id', children:'nodes'}) rather than pre-transforming your API data. This keeps options in their original shape.\",\n \"For form submission, Cascader has no 'name' prop. Wrap in a controlled pattern and store the path array in your form state (useForm/useState). For Inertia useForm, keep the field as an array (e.g. data.categoryPath = ['a','b','c']).\",\n ],\n useCases: [\n \"Geographic drilldown (Country → Prefecture → City) for address or branch-office pickers in accounting or logistics forms.\",\n \"Expense category selection (e.g. Operating Expenses → Marketing → Digital Ads) where the full classification path is required for the general ledger.\",\n \"Product taxonomy navigation (Department → Category → Sub-category) in inventory or invoice line-item entry.\",\n \"Organisational unit picker (Company → Division → Department) in budget allocation or approval-routing configurations.\",\n \"Multi-region filter in a report or dashboard filter bar, using multiple={true} to allow selecting several leaf locations at once.\",\n \"Any deeply nested classification where the relationship between levels is meaningful and must be captured — not just the leaf value.\",\n ],\n related: [\n \"TreeSelect — use when the hierarchy is a collapsible tree (expand/collapse nodes) rather than side-by-side columns, and when a single flat value string (node key) is sufficient instead of a full ancestor path. TreeSelect also supports treeCheckable for multi-select.\",\n \"Select — use for a flat (non-hierarchical) list of options. Cascader is only needed when items have meaningful parent–child levels.\",\n \"Transfer — use when the user needs to shuttle multiple items between two panels; not for hierarchical path selection.\",\n ],\n example: `{\\`import { Cascader } from \"@godxjp/ui/data-entry\";\n\nconst REGIONS = [\n {\n value: \"jp\",\n label: \"日本\",\n children: [\n {\n value: \"tokyo\",\n label: \"東京都\",\n children: [\n { value: \"shinjuku\", label: \"新宿区\" },\n { value: \"shibuya\", label: \"渋谷区\" },\n ],\n },\n ],\n },\n {\n value: \"vn\",\n label: \"Việt Nam\",\n children: [\n {\n value: \"hcm\",\n label: \"TP. Hồ Chí Minh\",\n children: [\n { value: \"q1\", label: \"Quận 1\" },\n { value: \"q3\", label: \"Quận 3\" },\n ],\n },\n ],\n },\n];\n\n// Controlled single-path\nfunction RegionPicker() {\n const [path, setPath] = React.useState<string[]>([]);\n\n return (\n <Cascader\n options={REGIONS}\n value={path}\n onChange={(v) => setPath(v as string[])}\n showSearch\n placeholder=\"Select region…\"\n />\n );\n}\n\n// Multi-path (multiple selection)\nfunction MultiRegionPicker() {\n const [paths, setPaths] = React.useState<string[][]>([]);\n\n return (\n <Cascader\n options={REGIONS}\n multiple\n value={paths}\n onChange={(v) => setPaths(v as string[][])}\n showSearch\n />\n );\n}\n\n// With custom field names (data uses 'name'/'id'/'nodes')\n<Cascader\n options={rawApiData}\n fieldNames={{ label: \"name\", value: \"id\", children: \"nodes\" }}\n defaultValue={[\"dept-1\", \"team-3\"]}\n/>\n\n// changeOnSelect: lets user pick a branch node (not only leaves)\n<Cascader\n options={REGIONS}\n changeOnSelect\n onChange={(v) => console.log(\"path\", v)}\n/>\n\\`}`,\n storyPath: \"data-entry/Cascader.stories.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"TreeSelect\",\n group: \"data-entry\",\n tagline:\n \"Hierarchical tree picker in a Popover (single or multi-select with checkboxes) — `onChange` receives `string` in single mode and `string[]` in multi/checkable mode; never use a raw `<select>` for tree-structured data.\",\n props: [\n {\n name: \"treeData\",\n type: \"TreeOptionProp[]\",\n required: true,\n description:\n \"The tree data. Each node: `{ value: string; label: ReactNode; disabled?: boolean; disableCheckbox?: boolean; isLeaf?: boolean; children?: TreeOptionProp[] }`. Use `fieldNames` to remap custom keys.\",\n },\n {\n name: \"value\",\n type: \"string | string[]\",\n description:\n \"Controlled selected value(s). Pass `string` in single mode, `string[]` in multi/checkable mode. When undefined the component is uncontrolled.\",\n },\n {\n name: \"defaultValue\",\n type: \"string | string[]\",\n description: \"Initial value for uncontrolled usage. Ignored once `value` is provided.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string | string[] | undefined) => void\",\n description:\n \"Called on selection change. Returns `string` in single mode, `string[]` in multi/checkable mode, or `undefined` when cleared.\",\n },\n {\n name: \"multiple\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Enable multi-select without checkboxes. When true, `onChange` always fires with `string[]`.\",\n },\n {\n name: \"treeCheckable\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Render Checkbox controls beside each node. Implies multi-select; cascade-selects all descendants by default unless `treeCheckStrictly` is set.\",\n },\n {\n name: \"treeCheckStrictly\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true (only with `treeCheckable`), parent and child selections are independent — checking a parent does NOT auto-check its children.\",\n },\n {\n name: \"showCheckedStrategy\",\n type: '\"SHOW_CHILD\" | \"SHOW_PARENT\" | \"SHOW_ALL\"',\n defaultValue: '\"SHOW_CHILD\"',\n description:\n \"Controls which values appear in the trigger label when checkboxes are used. `SHOW_CHILD` (default) — show only leaf nodes selected; `SHOW_PARENT` — show nearest ancestor when all children selected; `SHOW_ALL` — show every checked node. Use the exported constants `TreeSelect.SHOW_CHILD`, `TreeSelect.SHOW_PARENT`, `TreeSelect.SHOW_ALL` instead of raw strings.\",\n },\n {\n name: \"showSearch\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Show a CommandInput search box at the top of the dropdown. Filters visible tree nodes by label text.\",\n },\n {\n name: \"treeDefaultExpandAll\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Expand all nodes when the dropdown first opens. Initialised once; does not re-expand on re-render.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description:\n \"Trigger button placeholder text when nothing is selected. Defaults to the i18n key `dataEntry.treeSelect.placeholder`.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables the trigger button and all interactions.\",\n },\n {\n name: \"allowClear\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Show an `X` icon in the trigger to clear the selection. Set to `false` to make selection mandatory.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional Tailwind classes applied to the trigger Button.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description:\n \"HTML `id` placed on the trigger Button — use this to associate a `<label htmlFor>` for accessibility.\",\n },\n {\n name: \"fieldNames\",\n type: \"{ label?: string; value?: string; children?: string }\",\n description:\n \"Remap data object keys. Example: `{ label: 'name', value: 'id', children: 'items' }` so you don't have to transform your API response before passing it to `treeData`.\",\n },\n ],\n usage: [\n \"DO pair with a `<label htmlFor={id}>` and pass the matching `id` prop so screen readers announce the control correctly. The underlying trigger is a `<Button role='combobox'>` — not a native `<select>` — so an explicit label is required.\",\n \"DO use `treeCheckable` (+ optionally `showCheckedStrategy`) for selecting multiple nodes with parent–child cascade; use `multiple` only when you want multi-select WITHOUT the checkbox cascade behaviour.\",\n \"DO use the static constants `TreeSelect.SHOW_CHILD`, `TreeSelect.SHOW_PARENT`, `TreeSelect.SHOW_ALL` (or the named exports `SHOW_CHILD`/`SHOW_PARENT`/`SHOW_ALL` from the same import path) instead of raw string literals for `showCheckedStrategy`.\",\n \"DON'T pass `value` and `defaultValue` simultaneously — pick controlled (`value` + `onChange`) OR uncontrolled (`defaultValue` only). Mixing them causes the component to silently prefer the controlled path.\",\n \"DON'T hand-roll `onChange` type narrowing: in single mode the callback receives `string | undefined`; in multi/checkable mode it receives `string[]`. Branch on `multiple || treeCheckable` if you need to handle both shapes in the same handler.\",\n \"DON'T use a raw `<select>` or a flat `Select` component for hierarchical/nested data — TreeSelect is the correct primitive. If hierarchy is irrelevant and data is flat, use `Select` instead.\",\n ],\n useCases: [\n \"Chart-of-accounts picker in an accounting app where accounts belong to groups (Assets > Current Assets > Cash) and the user must select one leaf account.\",\n \"Multi-select department or cost-centre filter where selecting a parent division should auto-select all child departments (treeCheckable + SHOW_PARENT).\",\n \"Category assignment on invoice line items where categories have up to 3 levels of nesting and users can assign a parent or a leaf.\",\n \"Permission scope selector where roles are structured in a tree and selecting a parent role should cascade to all child scopes (treeCheckable + treeCheckStrictly=false).\",\n \"Location picker (Country > Prefecture > City) in a form where only leaf-level cities are valid selections (single mode, no checkboxes).\",\n \"Large GL hierarchy browser with showSearch enabled so users can type to filter thousands of account codes instead of manually expanding nodes.\",\n ],\n related: [\n \"Select — flat single/multi picker; use when data has no parent-child hierarchy. Pick TreeSelect as soon as items have `children`.\",\n \"Cascader — also renders tree data but in a multi-column panel where the user drills down column by column; pick Cascader for strict path selection (select a full path Country→Region→City). Pick TreeSelect when the user may select any node at any level or needs checkboxes.\",\n \"Checkbox / CheckboxGroup — use for a small, always-visible flat list of options. Use TreeSelect when options are hierarchical or the list is long enough to warrant a dropdown.\",\n \"Command / CommandInput — low-level search primitive; TreeSelect already embeds this internally. Do NOT compose your own tree dropdown out of Command — use TreeSelect.\",\n ],\n example: `import { useState } from \"react\";\nimport { TreeSelect } from \"@godxjp/ui/data-entry\";\n\nconst accountTree = [\n {\n value: \"assets\",\n label: \"Assets\",\n children: [\n { value: \"current-assets\", label: \"Current Assets\", children: [\n { value: \"cash\", label: \"Cash\" },\n { value: \"ar\", label: \"Accounts Receivable\" },\n ],\n },\n { value: \"fixed-assets\", label: \"Fixed Assets\", children: [\n { value: \"equipment\", label: \"Equipment\" },\n ],\n },\n ],\n },\n {\n value: \"liabilities\",\n label: \"Liabilities\",\n children: [\n { value: \"ap\", label: \"Accounts Payable\" },\n ],\n },\n];\n\n// Single-select (returns string | undefined)\nexport function AccountPicker() {\n const [account, setAccount] = useState<string | undefined>();\n return (\n <div className=\"flex flex-col gap-1\">\n <label htmlFor=\"account-picker\" className=\"text-sm font-medium\">\n GL Account\n </label>\n <TreeSelect\n id=\"account-picker\"\n treeData={accountTree}\n value={account}\n onChange={(v) => setAccount(v as string | undefined)}\n showSearch\n treeDefaultExpandAll\n placeholder=\"Select account…\"\n allowClear\n />\n </div>\n );\n}\n\n// Multi-select with checkboxes + cascade + SHOW_PARENT display\nexport function DepartmentFilter() {\n const [selected, setSelected] = useState<string[]>([]);\n return (\n <TreeSelect\n id=\"dept-filter\"\n treeData={accountTree}\n value={selected}\n onChange={(v) => setSelected(v as string[])}\n treeCheckable\n showCheckedStrategy={TreeSelect.SHOW_PARENT}\n showSearch\n placeholder=\"Filter by department…\"\n />\n );\n}`,\n storyPath: \"data-entry/TreeSelect.stories.tsx\",\n rules: [3, 6, 13, 23],\n },\n {\n name: \"Transfer\",\n group: \"data-entry\",\n tagline:\n \"Dual-list shuttle that moves items between source and target via Checkbox selection — you own targetKeys state; never hand-roll a two-panel picker.\",\n props: [\n {\n name: \"dataSource\",\n type: \"TransferItemProp[]\",\n required: true,\n description:\n \"Full flat list of all items (both source and target). Each item needs a unique `key` string, a `title` (ReactNode rendered in the list row), an optional `description` (shown as a secondary line), and an optional `disabled` boolean to lock individual items.\",\n },\n {\n name: \"targetKeys\",\n type: \"string[]\",\n required: true,\n description:\n \"Keys of items currently in the right (target) panel. Items whose key is NOT in this array appear in the left (source) panel. This is the primary controlled state — you must update it inside `onChange`.\",\n },\n {\n name: \"onChange\",\n type: \"(targetKeys: string[], direction: 'left' | 'right', moveKeys: string[]) => void\",\n description:\n \"Called after the user clicks a move button. Receives the new full targetKeys array, the direction of movement ('right' = source→target, 'left' = target→source), and the keys that were actually moved. Update your targetKeys state here.\",\n },\n {\n name: \"titles\",\n type: \"[React.ReactNode, React.ReactNode]\",\n description:\n \"Panel header labels. Index 0 = left/source panel, index 1 = right/target panel. Defaults to i18n strings (dataEntry.transfer.source / dataEntry.transfer.target).\",\n },\n {\n name: \"showSearch\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, renders a SearchInput inside each panel that filters items by title and description text (debounce=0). Does not affect the underlying data; purely a client-side filter.\",\n },\n {\n name: \"oneWay\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, hides the left-pointing move button so items can only flow source → target. Useful for append-only assignment flows.\",\n },\n {\n name: \"disabled\",\n type: \"DisabledProp (boolean)\",\n defaultValue: \"false\",\n description:\n \"Disables the entire component: all checkboxes, the search input (pointer-events-none), and both move buttons.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra Tailwind classes applied to the outer flex wrapper. Use to constrain width or add margin.\",\n },\n {\n name: \"selectedKeys\",\n type: \"[string[], string[]]\",\n description:\n \"Controlled selection state as a tuple: index 0 = keys checked in the source panel, index 1 = keys checked in the target panel. Omit to use internal (uncontrolled) selection state. Must be paired with `onSelectChange` when provided.\",\n },\n {\n name: \"onSelectChange\",\n type: \"(sourceSelectedKeys: string[], targetSelectedKeys: string[]) => void\",\n description:\n \"Called whenever the checked selection in either panel changes. Provides updated arrays for source and target selections. Required when `selectedKeys` is controlled.\",\n },\n ],\n usage: [\n \"DO own `targetKeys` in state and update it inside `onChange`: `const [targetKeys, setTargetKeys] = useState<string[]>([]); onChange={(next) => setTargetKeys(next)}`.\",\n \"DO NOT hand-roll a two-panel checkbox picker — Transfer ships the full shuttle UX (select-all header, indeterminate state, search, move buttons, empty state) out of the box.\",\n \"DO enable `showSearch` for lists longer than ~10 items; the built-in SearchInput filters by both `title` and `description` text content, including ReactNode content via `reactNodeText`.\",\n \"DO use `oneWay={true}` for append-only flows (e.g. adding permissions to a role) where items must never be moved back.\",\n \"DO control `selectedKeys` / `onSelectChange` only when you need to read which items are currently checked (e.g. for a bulk-action toolbar outside the component). For most cases, leave both props out and let Transfer manage selection internally.\",\n \"AVOID using Transfer for simple single-select or toggle scenarios — use a Checkbox list, Select, or MultiSelect instead. Transfer is specifically for shuttle/dual-panel assignment flows.\",\n ],\n useCases: [\n \"Assigning roles or permissions to a user: source panel shows available roles, target panel shows assigned roles; `oneWay={false}` allows removal.\",\n \"Building a report column picker: source = all available columns, target = columns included in the report, user orders and moves them across.\",\n \"Account mapping in an accounting app: map external chart-of-accounts entries (source) to canonical internal accounts (target) in a bulk import wizard.\",\n \"Tag / label assignment in a CMS: move content tags from an available pool into a 'selected' set for a document.\",\n \"Feature-flag targeting: move user segments from an 'all segments' list into the 'targeted segments' panel for a flag.\",\n \"Permission set builder in an admin UI: shuttle individual API scopes from 'available' to 'granted' for an API key or OAuth client.\",\n ],\n related: [\n \"MultiSelect — picks multiple values from a dropdown; prefer when the option set is large and a panel layout is not needed.\",\n \"Checkbox (list) — use for a simple flat multi-select without a shuttle/move metaphor.\",\n \"Select (compound) — single or multi-value dropdown; not a dual-panel component.\",\n \"Tree — hierarchical item display; combine with Transfer's dataSource if items have a tree structure but the shuttle UX is still needed.\",\n ],\n example: `import { useState } from \"react\";\nimport { Transfer } from \"@godxjp/ui/data-entry\";\n\nconst ALL_ACCOUNTS = [\n { key: \"1010\", title: \"Cash\", description: \"Asset\" },\n { key: \"1020\", title: \"Accounts Receivable\", description: \"Asset\" },\n { key: \"2010\", title: \"Accounts Payable\", description: \"Liability\" },\n { key: \"3010\", title: \"Revenue\", description: \"Income\" },\n { key: \"4010\", title: \"Cost of Goods Sold\", description: \"Expense\", disabled: true },\n];\n\nexport function AccountMapping() {\n const [targetKeys, setTargetKeys] = useState<string[]>([\"1010\"]);\n\n return (\n <Transfer\n dataSource={ALL_ACCOUNTS}\n targetKeys={targetKeys}\n onChange={(nextKeys) => setTargetKeys(nextKeys)}\n titles={[\"Available Accounts\", \"Mapped Accounts\"]}\n showSearch\n />\n );\n}`,\n storyPath: \"data-entry/Transfer.stories.tsx\",\n rules: [23, 31],\n },\n {\n name: \"Upload\",\n group: \"data-entry\",\n tagline:\n \"Drag-and-drop / button / avatar / picture file uploader in six variants — wire onUpload to your media-service and call collectUploadCommitActions on form submit; never submit raw File objects from form state.\",\n props: [\n {\n name: \"variant\",\n type: '\"dropzone\" | \"button\" | \"picture-card\" | \"picture\" | \"avatar\" | \"avatar-crop\"',\n defaultValue: '\"dropzone\"',\n description:\n \"Controls the visual rendering mode. dropzone = large dashed drop area + file list; button = compact outline button + file list; picture-card = grid of 96×96 image thumbnails; picture = single image preview with change/remove actions; avatar = circular single-image picker; avatar-crop = avatar with an in-dialog crop step before the item is staged.\",\n },\n {\n name: \"value\",\n type: \"UploadFileItem[]\",\n description:\n \"Controlled list of file items. When provided the component is controlled — you own the state. Omit to run uncontrolled.\",\n },\n {\n name: \"defaultValue\",\n type: \"UploadFileItem[]\",\n description:\n \"Initial list of file items for uncontrolled usage. Ignored once value is provided.\",\n },\n {\n name: \"onChange\",\n type: \"(items: UploadFileItem[]) => void\",\n description:\n \"Fires every time the item list changes (add, remove, status transitions). In controlled mode this is your state setter.\",\n },\n {\n name: \"accept\",\n type: \"string\",\n description:\n 'MIME / extension accept string passed to the hidden <input type=\"file\">. avatar/avatar-crop/picture/picture-card default to \"image/*\"; dropzone and button default to unrestricted.',\n },\n {\n name: \"multiple\",\n type: \"boolean\",\n description:\n \"Allow multi-file selection. Auto-derived: false when maxCount is 1 (or when variant is avatar/avatar-crop/picture); otherwise true.\",\n },\n {\n name: \"maxCount\",\n type: \"number\",\n description:\n \"Hard upper bound on the number of items. avatar/avatar-crop/picture auto-default to 1. Once the limit is reached the add button is hidden (picture-card) or new picks replace the existing item.\",\n },\n {\n name: \"maxSizeBytes\",\n type: \"number\",\n description:\n \"Files larger than this byte limit are silently discarded before being added to the list. No built-in error message — show your own validation feedback if needed.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n description:\n \"Disables all interactive surfaces (drop zone, buttons). Visual opacity + pointer-events-none applied.\",\n },\n {\n name: \"removable\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Show the remove/delete control on each item. Set false to make uploads permanent within the session.\",\n },\n {\n name: \"onUpload\",\n type: \"(file: File, item: UploadFileItem) => Promise<{ mediaId: string; previewUrl?: string }>\",\n description:\n \"Called immediately after a file is picked (before form submit). Transitions the item to status='uploading', then 'done' on resolve or 'error' on reject. Wire this to your media-service issue/PUT/complete cycle. If omitted files stay in status='idle' and the raw File object remains in item.file.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra CSS class applied to the outer wrapper div.\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n description:\n \"Custom button label for variant='button'. Falls back to the i18n 'Upload file' string.\",\n },\n ],\n usage: [\n \"DO provide onUpload to auto-upload on pick. The callback must return { mediaId, previewUrl? } — the component transitions item.status through uploading → done/error automatically. Without onUpload the File object sits in item.file until you manually process it.\",\n \"DO call collectUploadCommitActions(items) on form submit to get { deleteMediaIds, promoteMediaIds } for your media-service. Never send raw File objects or blob URLs to the server — those are local-only.\",\n \"DO use createUploadItem(file) to build UploadFileItem objects when pre-populating value from server data (e.g. edit forms). Set status='done' and mediaId on existing server media so the draft/undo machinery tracks them correctly.\",\n \"DON'T put an Upload inside a form expecting it to serialize files via a native form submission — the hidden input is sr-only and not named. Upload is a controlled/uncontrolled React state component. Submit by reading items state and calling collectUploadCommitActions.\",\n \"Avatar/picture variants (maxCount=1) use internal soft-delete draft logic: removing an item marks it pendingDelete so the user can undo before committing. On form submit, collectUploadCommitActions converts pendingDelete → deleteMediaIds and done mediaIds → promoteMediaIds.\",\n \"For avatar-crop: a crop dialog opens after pick. The cropped Blob is staged as a new UploadFileItem. The original file never enters the list — only the cropped version is passed to onUpload.\",\n ],\n useCases: [\n \"Profile / user avatar editor: use variant='avatar-crop' so users can crop the image before upload; wire onUpload to your media-service; call collectUploadCommitActions on profile form submit to promote or delete.\",\n \"Invoice / document attachment list: use variant='dropzone' with accept='.pdf,.xlsx' and maxSizeBytes to let accountants drag-drop supporting documents; show the file list with status indicators below the drop zone.\",\n \"Product gallery (multiple images): use variant='picture-card' with maxCount to display a grid of thumbnails; each item gets an individual remove ✕ button; collectUploadCommitActions on product save.\",\n \"Single cover-image picker on a content form: use variant='picture' with maxCount=1 to show a preview rectangle with change/remove controls and undo-delete support.\",\n \"CSV / bulk-import button in an admin table header: use variant='button' with accept='.csv' and custom children label ('Import CSV') to keep the UI compact; process item.file in the onChange handler.\",\n \"Inline document replacement on an accounting record (replace, not append): use variant='avatar' (single-slot logic) or picture; onUpload returns the new mediaId; collectUploadCommitActions delivers replacesMediaId → deleteMediaIds.\",\n ],\n related: [\n \"Input (type='file') — never hand-roll a raw file input; use Upload instead. Upload provides drag-drop, preview, upload lifecycle, and soft-delete draft.\",\n \"Avatar (display-only) — the godx-ui Avatar component renders a user's existing image; use Upload variant='avatar' or 'avatar-crop' when you need the user to change it.\",\n \"DataTable — unrelated to Upload but both appear together in bulk-import flows: Upload (button variant) triggers the import, DataTable shows the result.\",\n ],\n example: `import { useState } from \"react\";\nimport { Upload, type UploadFileItem, collectUploadCommitActions } from \"@godxjp/ui/data-entry\";\n\n// Example: avatar picker with server upload\nexport function AvatarUploadForm() {\n const [items, setItems] = useState<UploadFileItem[]>([]);\n\n async function handleUpload(file: File, _item: UploadFileItem) {\n const fd = new FormData();\n fd.append(\"file\", file);\n const res = await fetch(\"/api/media/upload\", { method: \"POST\", body: fd });\n const { mediaId, previewUrl } = await res.json();\n return { mediaId, previewUrl };\n }\n\n function handleSubmit(e: React.FormEvent) {\n e.preventDefault();\n const { deleteMediaIds, promoteMediaIds } = collectUploadCommitActions(items);\n // Send to your API — never send raw File objects\n console.log({ deleteMediaIds, promoteMediaIds });\n }\n\n return (\n <form onSubmit={handleSubmit}>\n <Upload\n variant=\"avatar-crop\"\n value={items}\n onChange={setItems}\n onUpload={handleUpload}\n maxSizeBytes={5 * 1024 * 1024}\n />\n <button type=\"submit\">Save Profile</button>\n </form>\n );\n}\n\n// Example: multi-file dropzone\nexport function DocumentUploadDropzone() {\n const [items, setItems] = useState<UploadFileItem[]>([]);\n\n return (\n <Upload\n variant=\"dropzone\"\n value={items}\n onChange={setItems}\n accept=\".pdf,.xlsx\"\n maxCount={10}\n maxSizeBytes={20 * 1024 * 1024}\n onUpload={async (file) => {\n const res = await fetch(\"/api/media/upload\", {\n method: \"POST\",\n body: Object.assign(new FormData(), { file }),\n });\n return res.json();\n }}\n />\n );\n}`,\n storyPath: \"data-entry/Upload.stories.tsx\",\n rules: [3, 23],\n },\n {\n name: \"UploadCropDialog\",\n group: \"data-entry\",\n tagline:\n 'Modal crop dialog for a single image file — always controlled (open + file + onConfirm required); do NOT use standalone when Upload variant=\"avatar-crop\" already embeds it.',\n props: [\n {\n name: \"open\",\n type: \"boolean\",\n required: true,\n description:\n \"Controls dialog visibility. Drive this with useState; the component never auto-opens.\",\n },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n required: true,\n description:\n \"Called when the dialog requests close (Cancel button or overlay click). Set your open state to false here.\",\n },\n {\n name: \"file\",\n type: \"File | null\",\n required: true,\n description:\n \"The raw File object to crop. An object URL is created internally and revoked on cleanup. Pass null when no file is selected (dialog renders empty).\",\n },\n {\n name: \"onConfirm\",\n type: \"(cropped: File) => void\",\n required: true,\n description:\n \"Called with the cropped result — always a JPEG File (256x256, quality 0.92) regardless of the original format. The dialog closes itself after calling this.\",\n },\n ],\n usage: [\n \"DO pass a File object selected by the user (e.g. from an <input type='file'> or drag-drop handler) to `file`; the dialog creates and revokes its own object URL — never create one yourself before passing.\",\n \"DO close the dialog in onOpenChange: `onOpenChange={(open) => !open && setCropFile(null)}` — always clear cropFile state on close to avoid a stale image on the next open.\",\n \"DO handle the cropped File in onConfirm and then upload or store it; the output is always image/jpeg 256×256 named `<originalName>.jpg`.\",\n \"DON'T use UploadCropDialog directly if you are already using `<Upload variant='avatar-crop'>` — that variant already embeds UploadCropDialog internally. Using both will double-mount the dialog.\",\n \"DON'T try to control the zoom slider from outside — scale state is fully internal; the user controls zoom in-dialog via a Slider (1–2.5×, step 0.05).\",\n \"DON'T submit the dialog's output File as a form field directly; pass it to your upload handler (e.g. onUpload prop on Upload, or a manual FormData POST), since File objects cannot survive a standard HTML form serialisation.\",\n ],\n useCases: [\n \"Avatar / profile photo upload flow: show a file picker, pass the chosen File to UploadCropDialog, upload the cropped 256×256 JPEG to the server on confirm.\",\n \"Admin user management: let admins set or replace a team member's avatar with consistent square crop instead of accepting arbitrary-shaped originals.\",\n \"Legal-entity logo upload in an accounting app: enforce a square, web-ready JPEG from any source image before storing it as the entity's icon.\",\n \"Any single-image form field that needs browser-side crop before upload — avoids a round-trip to a server-side image processor.\",\n \"Building a custom avatar picker UI on top of the godx-ui Upload primitives when the built-in variant='avatar-crop' does not fit your layout.\",\n ],\n related: [\n \"Upload (variant='avatar-crop') — the preferred way to get crop-on-upload for avatars; it wraps UploadCropDialog automatically. Use UploadCropDialog directly only when you need a custom file-picking trigger or a non-avatar crop flow.\",\n \"Upload (variant='avatar') — same circular avatar UI without the crop step; the file is used as-is.\",\n \"Upload (variant='picture') — rectangular single-image upload without crop; no dialog.\",\n \"Upload (variant='picture-card') — multi-image grid upload without crop.\",\n ],\n example: `{\\`import { useState } from \"react\";\nimport { UploadCropDialog } from \"@godxjp/ui/data-entry\";\n\nexport function AvatarField() {\n const [cropFile, setCropFile] = useState<File | null>(null);\n\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0] ?? null;\n setCropFile(file);\n e.target.value = \"\"; // reset so re-selecting same file fires onChange\n };\n\n const handleConfirm = (cropped: File) => {\n // cropped is always image/jpeg 256×256\n const form = new FormData();\n form.append(\"avatar\", cropped);\n fetch(\"/api/avatar\", { method: \"POST\", body: form });\n };\n\n return (\n <>\n <input type=\"file\" accept=\"image/*\" onChange={handleFileChange} />\n <UploadCropDialog\n open={cropFile !== null}\n onOpenChange={(open) => { if (!open) setCropFile(null); }}\n file={cropFile}\n onConfirm={handleConfirm}\n />\n </>\n );\n}\\`}`,\n storyPath: \"data-entry/UploadCropDialog.stories.tsx\",\n rules: [3, 13, 23],\n },\n {\n name: \"ColorPicker\",\n group: \"data-entry\",\n tagline:\n \"Native color-swatch picker with an optional editable hex input — always pass a valid 3- or 6-digit hex `value`; invalid hex is silently ignored and the previous value is restored.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n defaultValue: '\"#2563eb\"',\n description:\n \"The current hex color string (3- or 6-digit, with leading #). Component auto-prepends # if missing. Invalid hex values are discarded and the previous valid value is kept.\",\n },\n {\n name: \"onChange\",\n type: \"(hex: string) => void\",\n defaultValue: \"undefined\",\n description:\n \"Called with the normalized, validated hex string whenever the user commits a new color — via the native swatch picker or by pressing Enter / blurring the hex input. Not called for invalid hex drafts.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"undefined\",\n description:\n \"Disables both the swatch input and the hex text input, preventing all user interaction.\",\n },\n {\n name: \"showHexInput\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"When true (default), renders an editable godx-ui Input alongside the swatch that shows the current hex value and lets the user type a hex string. Set to false for a compact swatch-only control.\",\n },\n {\n name: \"className\",\n type: \"string\",\n defaultValue: \"undefined\",\n description:\n \"Extra CSS class(es) applied to the root wrapper div. Use for layout sizing; avoid overriding design-token colours.\",\n },\n {\n name: \"id\",\n type: \"string\",\n defaultValue: \"undefined\",\n description:\n \"DOM id applied to the hidden native <input type='color'>. Pass the FormField id here so the label's htmlFor targets this control correctly.\",\n },\n ],\n usage: [\n \"DO wrap in FormField when a label or validation message is needed — pass the same id to both FormField and ColorPicker so htmlFor wires up correctly: `<FormField id='brand' label='Brand color'><ColorPicker id='brand' value={v} onChange={setV} /></FormField>`.\",\n \"DO use controlled mode (value + onChange) — there is no defaultValue/uncontrolled path; always supply value.\",\n \"DON'T pass an invalid or empty string to value — the component will flash the invalid color on the preview swatch. Always initialize state to a valid 3- or 6-digit hex (e.g. '#2563eb').\",\n \"The hex Input is a live draft field — onChange is NOT called until the user presses Enter or blurs; only then is the value validated and the parent notified. Do not rely on onChange firing on every keystroke.\",\n \"Set showHexInput={false} only for compact/inline contexts (icon pickers, table cells) where space is tight and keyboard hex entry is not needed.\",\n \"NEVER hand-roll a color picker with raw <input type='color'> — always use this component; it normalizes hex, debounces draft state, and respects the design-token control styles.\",\n ],\n useCases: [\n \"Brand / campaign color selection in settings or campaign creation forms where users need to pick or type an exact hex value.\",\n \"Invoice or document theme customization — letting users pick accent colors that are stored and applied to PDF output.\",\n \"Accounting dashboard category tagging — assigning a color code to GL account categories or chart-of-accounts nodes for visual grouping.\",\n \"Product or inventory label colors in admin panels where a compact swatch (showHexInput={false}) fits inside a table cell or sidebar.\",\n \"Design-token or CSS variable editor pages where the user needs precise hex entry alongside a visual swatch preview.\",\n \"User-profile or team avatar color personalization forms.\",\n ],\n related: [\n \"Input — use for plain text/number entry; use ColorPicker when the value is specifically a color hex code and you want a visual swatch.\",\n \"Select / SearchSelect — use for choosing from a fixed palette of named colors (e.g. 'Red', 'Blue'); use ColorPicker for freeform hex color entry.\",\n ],\n example: `import { useState } from \"react\";\nimport { ColorPicker, FormField } from \"@godxjp/ui/data-entry\";\n\nexport function BrandColorField() {\n const [color, setColor] = useState(\"#2563eb\");\n\n return (\n <FormField id=\"brand-color\" label=\"Brand color\" className=\"max-w-xs\">\n <ColorPicker\n id=\"brand-color\"\n value={color}\n onChange={setColor}\n />\n </FormField>\n );\n}\n\n// Compact swatch-only variant (no hex input)\nexport function SwatchOnly() {\n const [color, setColor] = useState(\"#16a34a\");\n return <ColorPicker value={color} onChange={setColor} showHexInput={false} />;\n}\n\n// Disabled state\nexport function DisabledColor() {\n return <ColorPicker value=\"#6b7280\" disabled />;\n}`,\n storyPath: \"data-entry/ColorPicker.stories.tsx\",\n rules: [2, 3, 6, 13],\n },\n {\n name: \"Slider\",\n group: \"data-entry\",\n tagline:\n \"Numeric range slider (Radix Slider) — value/defaultValue must be number[], not a plain number.\",\n props: [\n {\n name: \"value\",\n type: \"number[]\",\n description:\n \"Controlled value. Must be an array — single-thumb: [50], dual-thumb (range): [20,80]. Drives thumb count.\",\n },\n {\n name: \"defaultValue\",\n type: \"number[]\",\n description:\n \"Uncontrolled initial value. Must be an array. Defaults to [min, max] (dual-thumb) when neither value nor defaultValue is provided.\",\n },\n {\n name: \"min\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Minimum value of the range.\",\n },\n {\n name: \"max\",\n type: \"number\",\n defaultValue: \"100\",\n description: \"Maximum value of the range.\",\n },\n {\n name: \"step\",\n type: \"number\",\n defaultValue: \"1\",\n description: \"Step increment between values.\",\n },\n {\n name: \"minStepsBetweenThumbs\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Minimum number of steps between two thumbs when using a range slider.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: number[]) => void\",\n description:\n \"Fires on every drag move. Receives the full number[] of current thumb values.\",\n },\n {\n name: \"onValueCommit\",\n type: \"(value: number[]) => void\",\n description:\n \"Fires only when the user releases the thumb (pointer-up or key-up). Prefer for expensive operations.\",\n },\n {\n name: \"orientation\",\n type: \"'horizontal' | 'vertical'\",\n defaultValue: \"'horizontal'\",\n description: \"Layout direction of the slider track.\",\n },\n {\n name: \"dir\",\n type: \"'ltr' | 'rtr'\",\n description: \"Text direction. Affects which end is the minimum.\",\n },\n {\n name: \"inverted\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Invert the track so the filled range is on the opposite side.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables all thumb interaction.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form field name. Radix submits one hidden input per thumb when this is set — use for native form submission.\",\n },\n {\n name: \"form\",\n type: \"string\",\n description: \"Associates the slider with a form by id, same as the HTML form attribute.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra classes applied to the root element.\",\n },\n ],\n usage: [\n \"DO: Pass value/defaultValue as a number array — single thumb: `value={[50]}`, range: `value={[20, 80]}`. Passing a plain number will break rendering.\",\n \"DO: Use `onValueChange` for live UI feedback and `onValueCommit` for expensive side-effects (API calls, heavy computations) — commit fires only on pointer/key release.\",\n \"DO: Set `name` when inside a native `<form>` — Radix emits one hidden `<input>` per thumb automatically, no extra wiring needed.\",\n \"DON'T: Omit both value and defaultValue if you want a single-thumb slider — the component defaults to dual-thumb (renders [min, max]) when neither is provided. Always pass `defaultValue={[0]}` or `value={[val]}` for single-thumb.\",\n \"DON'T: Hand-roll Track/Range/Thumb sub-parts — the godxjp-ui Slider composes them internally. Just use `<Slider />` as a single leaf element.\",\n \"DO: For a11y supply `aria-label` or `aria-labelledby` on the Slider root when there is no visible `<label>` — Radix forwards it to each thumb span.\",\n ],\n useCases: [\n \"Budget / price-range filter: dual-thumb range slider (`value={[minPrice, maxPrice]}`) for accounting invoice list filtering by amount.\",\n \"Single numeric setting: audio volume, zoom level, or confidence threshold — single-thumb (`defaultValue={[50]}`) with a live readout next to it.\",\n \"Percentage allocation: splitting a budget across categories with `step={5}` and `min={0}` `max={100}`.\",\n \"Date-range scrubber over a fixed window (e.g. fiscal quarters) — map quarter index to thumb values, display labels above the track.\",\n \"Risk / priority dial in a form (`name='priority'`) submitted natively without JavaScript form libraries.\",\n \"Read-only visual indicator — pass `disabled` with a controlled `value` to show a progress-style bar that cannot be interacted with.\",\n ],\n related: [\n \"ProgressMeter — use ProgressMeter (not a disabled Slider) to show read-only progress; Slider with disabled is semantically a control, not a status indicator.\",\n \"Input (type number) — use Input for free-form numeric entry; use Slider when the range is bounded and dragging is the expected UX.\",\n \"Switch — for boolean on/off; Slider is for continuous or stepped numeric ranges.\",\n \"RangeField (if present) — check the MCP first; if a composed range-input field exists, prefer it over wiring two Slider thumbs manually.\",\n ],\n example: `{\\`import { Slider } from \"@godxjp/ui/data-entry\";\nimport { useState } from \"react\";\n\n// Single-thumb controlled slider\nfunction VolumeSlider() {\n const [volume, setVolume] = useState([70]);\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"text-sm font-medium text-foreground\">\n Volume: {volume[0]}%\n </label>\n <Slider\n value={volume}\n onValueChange={setVolume}\n min={0}\n max={100}\n step={1}\n aria-label=\"Volume\"\n />\n </div>\n );\n}\n\n// Dual-thumb range slider (e.g. price filter)\nfunction PriceRangeSlider() {\n const [range, setRange] = useState([2000, 8000]);\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"text-sm font-medium text-foreground\">\n Price: ¥{range[0].toLocaleString()} – ¥{range[1].toLocaleString()}\n </label>\n <Slider\n value={range}\n onValueChange={setRange}\n onValueCommit={(v) => console.log(\"committed\", v)}\n min={0}\n max={10000}\n step={500}\n minStepsBetweenThumbs={1}\n aria-label=\"Price range\"\n />\n </div>\n );\n}\n\n// Native form submission (no JS form library needed)\nfunction FormSlider() {\n return (\n <form method=\"post\" action=\"/settings\">\n <Slider name=\"priority\" defaultValue={[50]} min={0} max={100} step={10} />\n <button type=\"submit\">Save</button>\n </form>\n );\n}\\`}`,\n storyPath: \"data-entry/Slider.stories.tsx\",\n rules: [3, 6, 31],\n },\n {\n name: \"Calendar\",\n group: \"data-entry\",\n tagline:\n \"A styled react-day-picker grid for picking single dates, multiple dates, or date ranges — always embed it inside a Popover for full date-picker UX; use DatePicker or DateRangePicker instead when you need a form-submittable input.\",\n props: [\n {\n name: \"mode\",\n type: \"'single' | 'multiple' | 'range' | undefined\",\n description:\n \"Selection mode. 'single' picks one day, 'multiple' picks several, 'range' picks a from/to span. Omit or set undefined for a display-only calendar with no selection.\",\n },\n {\n name: \"selected\",\n type: \"Date | Date[] | DateRange | undefined\",\n description:\n \"Controlled selected value. Shape depends on mode: Date for 'single', Date[] for 'multiple', { from?: Date; to?: Date } for 'range'.\",\n },\n {\n name: \"onSelect\",\n type: \"(date: Date | Date[] | DateRange | undefined, triggerDate: Date, modifiers: Modifiers, e: MouseEvent) => void\",\n description:\n \"Callback fired when the user clicks a day. Receives the new selection, the clicked date, active modifiers, and the event.\",\n },\n {\n name: \"defaultMonth\",\n type: \"Date\",\n description:\n \"Uncontrolled initial month shown. For controlled month navigation use month + onMonthChange.\",\n },\n {\n name: \"month\",\n type: \"Date\",\n description:\n \"Controlled currently-displayed month. Pair with onMonthChange to drive navigation programmatically.\",\n },\n {\n name: \"onMonthChange\",\n type: \"(month: Date) => void\",\n description: \"Fired when the user navigates to a different month.\",\n },\n {\n name: \"numberOfMonths\",\n type: \"number\",\n defaultValue: \"1\",\n description: \"Number of month grids to show side-by-side.\",\n },\n {\n name: \"startMonth\",\n type: \"Date | undefined\",\n description:\n \"Earliest month reachable via navigation. Also constrains the dropdown range when captionLayout includes 'dropdown'.\",\n },\n {\n name: \"endMonth\",\n type: \"Date | undefined\",\n description: \"Latest month reachable via navigation.\",\n },\n {\n name: \"disabled\",\n type: \"Matcher | Matcher[] | undefined\",\n description:\n \"Days to disable. Accepts a Date, Date[], { before: Date }, { after: Date }, { from: Date; to: Date }, { dayOfWeek: number[] }, or an array of any of these.\",\n },\n {\n name: \"hidden\",\n type: \"Matcher | Matcher[] | undefined\",\n description: \"Days to hide entirely from the grid.\",\n },\n {\n name: \"showOutsideDays\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Show greyed-out days from adjacent months. godx-ui defaults this to true (overrides react-day-picker's false default).\",\n },\n {\n name: \"showWeekNumber\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Show ISO/locale week-number column on the left.\",\n },\n {\n name: \"fixedWeeks\",\n type: \"boolean\",\n description: \"Always render 6 weeks per month, padding with days from the next month.\",\n },\n {\n name: \"captionLayout\",\n type: \"'label' | 'dropdown' | 'dropdown-months' | 'dropdown-years'\",\n defaultValue: \"'label'\",\n description:\n \"Caption area layout. 'dropdown' shows month/year select dropdowns for faster large-range navigation.\",\n },\n {\n name: \"locale\",\n type: \"Partial<DayPickerLocale> | undefined\",\n description:\n \"date-fns locale object imported from 'react-day-picker/locale'. Defaults to enUS. Pass ja, vi, etc. for i18n.\",\n },\n {\n name: \"weekStartsOn\",\n type: \"0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined\",\n description:\n \"Day index (0=Sun) for the first column of the week grid. Overrides locale default.\",\n },\n {\n name: \"modifiers\",\n type: \"Record<string, Matcher | Matcher[] | undefined>\",\n description:\n \"Custom named modifiers applied to matched days. Pair with modifiersClassNames or modifiersStyles to style them.\",\n },\n {\n name: \"modifiersClassNames\",\n type: \"ModifiersClassNames\",\n description: \"CSS class names keyed by modifier name.\",\n },\n {\n name: \"footer\",\n type: \"React.ReactNode | string\",\n description:\n \"Content rendered below the grid as a live ARIA region. Use a string to communicate selection status to screen readers.\",\n },\n {\n name: \"autoFocus\",\n type: \"boolean\",\n description:\n \"Focus the first selected day (or today) when the calendar mounts — recommended when opening inside a Popover.\",\n },\n {\n name: \"today\",\n type: \"Date\",\n description:\n \"Override the 'today' date used for the today modifier and default navigation. Defaults to new Date().\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra class added to the root wrapper element (adds to the built-in p-3 padding).\",\n },\n {\n name: \"classNames\",\n type: \"Partial<ClassNames>\",\n description:\n \"Override individual part class names (months, weekday, day, selected, today, range_start, range_end, range_middle, disabled, outside, etc.). Merged with godx-ui defaults.\",\n },\n {\n name: \"components\",\n type: \"Partial<CustomComponents>\",\n description:\n \"Swap out internal sub-components (Chevron is already replaced by lucide icons). Use for advanced custom rendering.\",\n },\n {\n name: \"animate\",\n type: \"boolean\",\n description: \"Animate month-to-month navigation transitions (react-day-picker >=9.6).\",\n },\n {\n name: \"dir\",\n type: \"string\",\n description: \"'ltr' (default) or 'rtl' for right-to-left layouts.\",\n },\n {\n name: \"aria-label\",\n type: \"string\",\n description:\n \"aria-label on the container. Provide a meaningful label when the calendar is not described by a visible heading.\",\n },\n {\n name: \"role\",\n type: \"'application' | 'dialog' | undefined\",\n description:\n \"ARIA role for the container element. Use 'dialog' when rendering inside a modal Popover.\",\n },\n {\n name: \"required\",\n type: \"boolean | undefined\",\n description:\n \"When true the user cannot deselect the currently selected day (mode must also be set).\",\n },\n {\n name: \"pagedNavigation\",\n type: \"boolean\",\n description:\n \"When numberOfMonths > 1, advance all visible months at once instead of one at a time.\",\n },\n {\n name: \"reverseMonths\",\n type: \"boolean\",\n description:\n \"Render months newest-first (right-to-left reading order) when numberOfMonths > 1.\",\n },\n {\n name: \"hideNavigation\",\n type: \"boolean\",\n description: \"Hide the prev/next navigation buttons without disabling keyboard navigation.\",\n },\n {\n name: \"disableNavigation\",\n type: \"boolean\",\n description:\n \"Disable month navigation entirely (buttons hidden and keyboard navigation locked).\",\n },\n {\n name: \"hideWeekdays\",\n type: \"boolean\",\n description: \"Hide the row of weekday abbreviation headers (Mon, Tue, ...).\",\n },\n {\n name: \"ISOWeek\",\n type: \"boolean\",\n description:\n \"Use ISO week numbering (Monday first week, ignores weekStartsOn and firstWeekContainsDate).\",\n },\n ],\n usage: [\n \"DO set mode explicitly ('single', 'multiple', 'range') — omitting it renders a display-only grid with no selection. The value passed to selected and the argument shape of onSelect both depend on mode.\",\n \"DO embed Calendar inside a Popover + PopoverContent when building a date-picker UI (set PopoverContent className='w-auto p-0'). For form-submittable single-date or range inputs prefer the higher-level DatePicker / DateRangePicker components — they own the input, icon, locale wiring, and ISO form submission natively.\",\n \"DO pass a locale object imported from 'react-day-picker/locale' (e.g. import { ja } from 'react-day-picker/locale') for i18n — weekday names, month names, and first-day-of-week all come from the locale.\",\n \"DO use the disabled prop with Matcher objects ({ before: minDate }, { after: maxDate }, { dayOfWeek: [0, 6] }) to restrict selectable days — never render your own disabled overlay on top.\",\n \"DON'T add inner padding on the wrapping PopoverContent — Calendar already has p-3 via its className. Use PopoverContent className='w-auto p-0' to avoid double padding.\",\n \"DON'T hand-roll a calendar grid — Calendar wraps react-day-picker which is keyboard-navigable, ARIA-annotated, and screen-reader friendly out of the box. Provide a footer string for screen-reader status announcements when the selection changes.\",\n ],\n useCases: [\n \"Inline date picker within a form section where the calendar grid must always be visible (e.g., a booking page or a date-of-issue field on an invoice creation form).\",\n \"Date range selection inside a Popover triggered by a filter button on an accounting report page (use mode='range', pass selected={dateRange}, onSelect updates the filter state).\",\n \"Multi-date selection for picking recurring reminder dates or batch-action target dates (mode='multiple').\",\n \"Custom calendar with highlighted days (e.g., marking invoice due dates or shipment ETDs with a custom modifier + modifiersClassNames) overlaid on a standard single-select grid.\",\n \"Month navigator with year/month dropdowns for jumping to a historical accounting period quickly (captionLayout='dropdown', startMonth set to earliest fiscal year).\",\n \"Display-only calendar (no mode set) showing booked or blocked dates using the modifiers prop with read-only styling, embedded in a dashboard card.\",\n ],\n related: [\n \"DatePicker — the complete single-date form control (typeable ISO input + calendar icon + Popover). Use DatePicker instead of Calendar when you need a form-submittable field with an input box.\",\n \"DateRangePicker — the complete date-range form control (two ISO inputs + calendar icon + Popover). Use DateRangePicker instead of Calendar when you need from/to form fields.\",\n \"Popover / PopoverContent — the shell you must provide when you want Calendar inside a trigger. Set PopoverContent className='w-auto p-0' to avoid double padding.\",\n ],\n example: `import { useState } from \"react\";\nimport { Calendar } from \"@godxjp/ui/data-entry\";\nimport { ja } from \"react-day-picker/locale\";\n\n// --- Single-date example (controlled) ---\nexport function InvoiceDateCalendar() {\n const [date, setDate] = useState<Date | undefined>(new Date());\n\n return (\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n locale={ja}\n disabled={{ before: new Date(2024, 0, 1) }}\n footer={date ? \\`選択日: \\${date.toLocaleDateString(\"ja-JP\")}\\` : \"日付を選択してください\"}\n aria-label=\"発行日カレンダー\"\n />\n );\n}\n\n// --- Range example inside a Popover (mirrors DateRangePicker internals) ---\nimport { Popover, PopoverContent, PopoverTrigger } from \"@godxjp/ui/data-display\";\nimport { Button } from \"@godxjp/ui/general\";\nimport type { DateRange } from \"react-day-picker\";\n\nexport function ReportRangeFilter() {\n const [range, setRange] = useState<DateRange | undefined>();\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"outline\">期間を選択</Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"end\">\n <Calendar\n mode=\"range\"\n selected={range}\n onSelect={setRange}\n locale={ja}\n numberOfMonths={2}\n disabled={{ after: new Date() }}\n autoFocus\n />\n </PopoverContent>\n </Popover>\n );\n}`,\n storyPath: \"data-entry/Calendar.stories.tsx\",\n rules: [3, 5, 6, 23],\n },\n {\n name: \"CountrySelect\",\n group: \"data-entry\",\n tagline:\n \"Flag-and-name country picker built on Select; always uncontrolled — pass `name` for form submission and `defaultValue` to pre-select, not `value`/`onChange`.\",\n props: [\n {\n name: \"id\",\n type: \"string\",\n required: true,\n description: \"HTML id forwarded to the SelectTrigger for label association and a11y.\",\n },\n {\n name: \"name\",\n type: \"string\",\n required: true,\n description:\n \"Form field name. The selected country code (value) is submitted under this key via the hidden native select that Select wraps.\",\n },\n {\n name: \"options\",\n type: \"CountryOptionProp[]\",\n required: true,\n description:\n \"List of country options. Each entry must have at least `name` and either `value` or `code` (the country ISO code). Optionally include `nativeName`, `flagSvgPath`, and `label`.\",\n },\n {\n name: \"defaultValue\",\n type: \"string | null\",\n description:\n \"Pre-selected country code. When omitted (and allowEmpty is false), defaults to the first option's value. Pass null or empty string to show the placeholder.\",\n },\n {\n name: \"required\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Marks the field as required via aria-required on the trigger.\",\n },\n {\n name: \"allowEmpty\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, prepends an empty sentinel option (value '0') rendered as emptyLabel. Lets the user submit no country. Without this, the picker always has a real country selected.\",\n },\n {\n name: \"emptyLabel\",\n type: \"string\",\n defaultValue: \"—\",\n description: \"Label shown for the empty option when allowEmpty is true.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description:\n \"Placeholder text shown inside the trigger when no value is selected (relevant when defaultValue is null/empty and allowEmpty is true).\",\n },\n {\n name: \"invalid\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Sets aria-invalid on the SelectTrigger to indicate a validation error.\",\n },\n ],\n usage: [\n \"DO: Always pass both `id` and `name` — `id` wires up a `<label htmlFor>`, `name` is the form submission key for the selected country code.\",\n \"DO NOT: Pass `value`/`onChange` — CountrySelect is UNCONTROLLED only. It uses `defaultValue` (passed to the underlying Select). For controlled scenarios wrap the underlying `Select` primitive directly.\",\n \"DO: Populate `options` with objects satisfying CountryOptionProp — each needs `name` plus either `value` (preferred) or `code` as the ISO code. Add `flagSvgPath` for flag images and `nativeName` for bilingual display.\",\n \"DO: Use `allowEmpty` when the country field is optional — it inserts a sentinel '0' entry. Without it, a country is always pre-selected (falls back to options[0] if defaultValue is absent), so the form will always submit a real code.\",\n \"DO: Set `invalid={true}` in error state to surface aria-invalid to assistive technology; pair it with a visible error message adjacent to the control.\",\n \"DO NOT: Hand-roll a flag+name row or a custom country dropdown — use CountrySelect (for form submission) or CountryOptionLabel standalone (for display-only read-only rows).\",\n ],\n useCases: [\n \"Billing / shipping address forms where the user must pick a country before proceeding and the code is submitted to the server.\",\n \"Account settings pages where a user sets their home country or tax residency — use `defaultValue` with the stored ISO code to pre-populate.\",\n \"Invoice creation forms in an accounting app that require a supplier or customer country, with `allowEmpty={false}` to guarantee a code is always present.\",\n \"Optional 'country of origin' filter fields — use `allowEmpty={true}` so users can clear the selection back to 'no filter'.\",\n \"Multi-step onboarding flows that must pre-select a country inferred from the user's locale, then let them correct it.\",\n \"Read-only display of a country name + flag in a KeyValueGrid or DataTable cell — use `CountryOptionLabel` directly (not CountrySelect) for non-interactive display.\",\n ],\n related: [\n \"Select — the generic primitive CountrySelect is built on; use Select directly when you need a controlled picker or options that are not country objects.\",\n \"CountryOptionLabel — the flag + name row exported from the same module; use it standalone in read-only contexts (table cells, detail views) where no picker interaction is needed.\",\n \"DatePicker — another uncontrolled data-entry primitive that submits via a hidden form value; same pattern but for dates.\",\n ],\n example: `import { CountrySelect } from \"@godxjp/ui/data-entry\";\n\nconst countries = [\n { value: \"JP\", name: \"Japan\", nativeName: \"日本\", flagSvgPath: \"/flags/jp.svg\" },\n { value: \"US\", name: \"United States\", nativeName: \"United States\", flagSvgPath: \"/flags/us.svg\" },\n { value: \"VN\", name: \"Vietnam\", nativeName: \"Việt Nam\", flagSvgPath: \"/flags/vn.svg\" },\n];\n\n// Required country field — pre-select Japan\n<CountrySelect\n id=\"billing-country\"\n name=\"billingCountry\"\n options={countries}\n defaultValue=\"JP\"\n required\n invalid={!!errors.billingCountry}\n/>\n\n// Optional country field — allow clearing\n<CountrySelect\n id=\"filter-country\"\n name=\"filterCountry\"\n options={countries}\n allowEmpty\n emptyLabel=\"All countries\"\n placeholder=\"Select a country\"\n/>`,\n storyPath: \"data-entry/CountrySelect.stories.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"ChoiceField\",\n group: \"data-entry\",\n tagline:\n \"Layout wrapper that pairs a checkbox/radio control with a Label and optional description — the `id` prop MUST match the control's `id` for the label click to work.\",\n props: [\n {\n name: \"id\",\n type: \"string\",\n required: true,\n description:\n \"ID shared with the inner control (checkbox/radio). Used as `htmlFor` on the Label so clicking the label toggles the control. Must be unique per page.\",\n },\n {\n name: \"label\",\n type: \"React.ReactNode\",\n required: true,\n description:\n \"The visible label text rendered beside the control. Accepts rich content (string, JSX, badges, etc.).\",\n },\n {\n name: \"description\",\n type: \"React.ReactNode\",\n description:\n \"Optional secondary line rendered below the label as a <p> element. Use for help text, hints, or elaborating on the choice.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra CSS classes merged onto the outer wrapper div (ui-choice-field).\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n required: true,\n description:\n \"The interactive control to render — must be a single Checkbox or Radio.Item element with an `id` matching the `id` prop.\",\n },\n ],\n usage: [\n \"DO: always pass the same value to both `id` on ChoiceField and `id` on the inner control (Checkbox / Radio.Item). The Label uses `htmlFor={id}` — mismatching IDs breaks click-to-toggle.\",\n \"DO: use `React.useId()` to generate unique IDs when rendering ChoiceField inside a list or map, as the parent Radio.Group and CheckboxGroup already do internally.\",\n \"DON'T: use ChoiceField to wrap a raw `<input type='checkbox'>` or `<input type='radio'>` — always use the godx-ui Checkbox or Radio.Item primitives as children.\",\n \"DON'T: hand-roll this layout (flex + label + description paragraph) yourself. ChoiceField already provides the correct ui-choice-field / ui-choice-control / ui-choice-content / ui-choice-label / ui-choice-description class structure.\",\n \"PREFER: Radio.Group or Checkbox.Group with the `options` prop when you have a list of choices — they create ChoiceField internally with auto-generated IDs. Only reach for bare ChoiceField for custom compositions.\",\n \"SKIP ChoiceField for standalone checkboxes that need NO label or description — use Checkbox directly in that case.\",\n ],\n useCases: [\n \"Rendering a single opt-in checkbox with a descriptive sub-line, e.g. 'Receive email notifications / You can unsubscribe at any time'.\",\n \"Custom radio group where each option needs a rich label (e.g. icon + text + badge) that the standard options API cannot express.\",\n \"Building an agreement / terms-of-service checkbox where the label is a React node with a link inside.\",\n \"Composing a vertically or horizontally oriented list of choices when you need full control over each item's checked state and ID.\",\n \"Wrapping a Radix-based Radio.Item or Checkbox inside a settings panel where each row needs a two-line label + description layout.\",\n \"Accessibility-correct label pairing when a third-party or custom control must appear beside descriptive text and clicking the text must activate the control.\",\n ],\n related: [\n \"Radio.Group / RadioGroup — use this (not bare ChoiceField) for a full group of radio options; it creates ChoiceField internally with correct IDs and orientation.\",\n \"Checkbox.Group / CheckboxGroup — same as Radio.Group but for multi-select; wraps ChoiceField automatically when you pass the `options` prop.\",\n \"Checkbox — use standalone (no ChoiceField) when you need a bare control with no label or when the label is already provided by a FormField wrapper.\",\n \"Radio / Radio.Item — the inner control that goes inside ChoiceField as children in a custom radio composition.\",\n \"Label — ChoiceField renders Label internally; do NOT add a second Label around ChoiceField or you will double-label the control.\",\n ],\n example: `{\\`import { Checkbox, Radio, ChoiceField } from \"@godxjp/ui/data-entry\";\nimport * as React from \"react\";\n\n// Example 1: Custom checkbox with description\nfunction NotificationToggle() {\n const id = React.useId();\n const [checked, setChecked] = React.useState(false);\n\n return (\n <ChoiceField\n id={id}\n label=\"Receive email notifications\"\n description=\"We will send updates about your account activity.\"\n >\n <Checkbox\n id={id}\n checked={checked}\n onCheckedChange={(v) => setChecked(Boolean(v))}\n />\n </ChoiceField>\n );\n}\n\n// Example 2: Custom radio item with rich label\nfunction PlanOption({ planId, name, price }: { planId: string; name: string; price: string }) {\n const id = \\\\\\`plan-\\\\\\${planId}\\\\\\`;\n return (\n <ChoiceField\n id={id}\n label={<span className=\"font-semibold\">{name}</span>}\n description={\\\\\\`\\\\\\${price} / month\\\\\\`}\n >\n <Radio.Item id={id} value={planId} />\n </ChoiceField>\n );\n}\\`}`,\n storyPath: \"data-entry/ChoiceField.stories.tsx\",\n rules: [6, 13, 23, 31],\n },\n {\n name: \"Command\",\n group: \"data-entry\",\n tagline:\n \"Accessible, keyboard-navigable command palette / combobox list built on cmdk — always pair CommandInput inside its own wrapper div, never render items outside CommandList.\",\n props: [\n {\n name: \"label\",\n type: \"string\",\n description:\n \"Accessible label for the command menu. Not shown visually — used by screen readers.\",\n },\n {\n name: \"shouldFilter\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Set to false to disable automatic filtering and sorting. When false, you must conditionally render matching items yourself based on the search query.\",\n },\n {\n name: \"filter\",\n type: \"(value: string, search: string, keywords?: string[]) => number\",\n description:\n \"Custom filter function. Returns a score between 0 (hidden) and 1 (best match). Defaults to command-score library scoring.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Default selected item value on initial render (uncontrolled).\",\n },\n {\n name: \"value\",\n type: \"string\",\n description: \"Controlled state of the currently selected item value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Called when the selected item changes.\",\n },\n {\n name: \"loop\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, keyboard arrow-key navigation wraps from last item back to first and vice versa.\",\n },\n {\n name: \"disablePointerSelection\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"When true, pointer events cannot select items — keyboard only.\",\n },\n {\n name: \"vimBindings\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Set to false to disable ctrl+n/j/p/k vim-style navigation shortcuts.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional CSS classes merged onto the root div via cn().\",\n },\n {\n name: \"CommandInput.value\",\n type: \"string\",\n description: \"Controlled search string for the input.\",\n },\n {\n name: \"CommandInput.onValueChange\",\n type: \"(search: string) => void\",\n description: \"Called when the search input text changes.\",\n },\n {\n name: \"CommandList.label\",\n type: \"string\",\n description: \"Accessible label for the list of suggestions. Not shown visually.\",\n },\n {\n name: \"CommandItem.value\",\n type: \"string\",\n description:\n \"Unique value for this item. If omitted, inferred from children textContent — must be stable; provide explicitly when text changes between renders.\",\n },\n {\n name: \"CommandItem.onSelect\",\n type: \"(value: string) => void\",\n description: \"Called when this item is selected via click or keyboard.\",\n },\n {\n name: \"CommandItem.disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Prevents this item from being selected.\",\n },\n {\n name: \"CommandItem.keywords\",\n type: \"string[]\",\n description:\n \"Additional keywords matched during filtering that are not part of the visible label.\",\n },\n {\n name: \"CommandItem.forceMount\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"When true, renders this item regardless of filtering results.\",\n },\n {\n name: \"CommandGroup.heading\",\n type: \"React.ReactNode\",\n description: \"Visible heading rendered above items in this group.\",\n },\n {\n name: \"CommandGroup.value\",\n type: \"string\",\n description: \"Required unique identifier for the group when no heading is provided.\",\n },\n {\n name: \"CommandGroup.forceMount\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"When true, renders this group regardless of filtering.\",\n },\n {\n name: \"CommandEmpty\",\n type: \"React.ReactNode (children)\",\n description:\n \"Renders automatically only when there are no matching results. Place inside CommandList.\",\n },\n ],\n usage: [\n \"DO compose the full tree: Command > CommandInput + CommandList > (CommandEmpty | CommandGroup > CommandItem | CommandItem). Every interactive element must live inside CommandList; items outside it are invisible to the keyboard engine.\",\n \"DO set shouldFilter={false} and manage filtering yourself when the options list comes from a server/async source (e.g. SearchSelect pattern). With shouldFilter=true the default client-side scoring runs over all rendered items automatically.\",\n \"DO always provide a stable explicit value prop on CommandItem when the item's text content can change between renders — relying on inferred textContent with dynamic labels causes selection bugs.\",\n \"DO include CommandEmpty inside CommandList to show a no-results message. It renders automatically only when the filtered count is zero; do not conditionally render it yourself.\",\n \"DON'T use CommandInput as a standalone search input — it is only meaningful inside a Command root (the root manages shared filter state). For a standalone search field use SearchInput instead.\",\n \"DON'T hand-roll keyboard navigation on a list of items; Command handles arrow keys, Enter, Escape, Home/End, and vim bindings. Adding your own keyDown handlers on top creates conflicts — use onSelect on CommandItem for selection logic.\",\n ],\n useCases: [\n \"Command palette / global action launcher (Cmd+K menu): wraps Command + CommandInput + grouped CommandItems for quick navigation across pages or actions.\",\n \"Popover-based combobox with server-side search: Command with shouldFilter={false} inside a Popover, managing the query state externally and filtering options before rendering — this is exactly how SearchSelect is built internally.\",\n \"Tree/cascader search panel: inject Command + CommandInput as a search header above a custom scroll area (no CommandList needed for the tree body) to get a styled, accessible search input — as used by CascaderSelect and TreeSelect.\",\n \"Multi-group option picker: use CommandGroup with heading to visually separate option categories (e.g. 'Accounts', 'Contacts', 'Documents') inside one dropdown with a single search box.\",\n \"Keyboard-first admin shortcut bar: embed Command with loop={true} and vimBindings={true} in a persistent sidebar for power-user keyboard navigation without page reloads.\",\n ],\n related: [\n \"SearchSelect — higher-level compound component that composes Command + Popover + server search; use SearchSelect for a fully managed async combobox instead of building your own with Command.\",\n \"Select — simple dropdown for static option lists without type-to-filter; use Select when there are fewer than ~10 options and no search is needed.\",\n \"SearchInput — standalone text input with a search icon; use SearchInput for filtering visible page content (tables, lists) not for selecting from a command menu.\",\n \"CommandInput (sub-part) — the styled search input that only works inside a Command root; never use it alone as a general search field.\",\n ],\n example: `{\\`import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@godxjp/ui/data-entry\";\n\nfunction AccountQuickPick({ onSelect }: { onSelect: (id: string) => void }) {\n return (\n <Command label=\"Quick pick account\" loop>\n <CommandInput placeholder=\"Search accounts…\" />\n <CommandList>\n <CommandEmpty>No accounts found.</CommandEmpty>\n <CommandGroup heading=\"Revenue\">\n <CommandItem value=\"4001\" onSelect={onSelect}>\n Sales Revenue\n </CommandItem>\n <CommandItem value=\"4002\" onSelect={onSelect}>\n Service Revenue\n </CommandItem>\n </CommandGroup>\n <CommandGroup heading=\"Expenses\">\n <CommandItem value=\"6001\" onSelect={onSelect}>\n Rent Expense\n </CommandItem>\n <CommandItem value=\"6002\" disabled onSelect={onSelect}>\n Deprecated Account\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n );\n}\\`}`,\n storyPath: \"data-entry/Command.stories.tsx\",\n rules: [2, 3, 6, 23],\n },\n {\n name: \"CheckboxGroup\",\n group: \"data-entry\",\n tagline:\n \"Multi-select checkbox list from an options array or manual children — use `options` prop for the data-driven path, never hand-roll individual Checkbox items in a group.\",\n props: [\n {\n name: \"options\",\n type: \"ChoiceOptionProp[]\",\n description:\n \"Data-driven mode: array of { label, value, disabled?, description? }. When provided and non-empty, renders all checkboxes automatically. When omitted, renders `children` instead.\",\n },\n {\n name: \"value\",\n type: \"string[]\",\n description:\n \"Controlled selected values. When provided, the component is controlled and won't manage state internally — you must handle onChange to update it.\",\n },\n {\n name: \"defaultValue\",\n type: \"string[]\",\n defaultValue: \"[]\",\n description:\n \"Uncontrolled initial selection. Use this instead of `value` when you don't need to control state externally.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string[]) => void\",\n description:\n \"Called with the full updated selection array whenever any checkbox is toggled. Works in both controlled and uncontrolled modes.\",\n },\n {\n name: \"orientation\",\n type: '\"vertical\" | \"horizontal\"',\n defaultValue: '\"vertical\"',\n description:\n \"Layout direction of the checkbox items. Vertical stacks items; horizontal places them in a row.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n description:\n \"Disables the entire group. Individual options can also set their own disabled flag via ChoiceOptionProp.disabled.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form name applied to each underlying checkbox input. Required for native form submission — all checkboxes share the same name so the form collects multiple values.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra CSS class on the group container div.\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n description:\n \"Manual children mode: used when `options` is omitted or empty. Render Checkbox items directly as children. You are responsible for composing each Checkbox with a ChoiceField for correct label/description layout.\",\n },\n ],\n usage: [\n \"DO use the `options` prop for any data-driven list — it auto-generates IDs, handles checked state, and wires up ChoiceField (label + description) for each item. NEVER hand-roll individual `<Checkbox>` elements inside a loop when you have an options array.\",\n \"DO pass `name` when inside an HTML form so each checkbox submits its value under the same field name, giving the server a multi-value array. Without `name`, native form submission silently drops all values.\",\n \"Controlled vs uncontrolled: pass `value` + `onChange` together for controlled usage (e.g. react-hook-form). Pass `defaultValue` alone for uncontrolled usage. Do NOT mix both — if `value` is provided, `defaultValue` is ignored and onChange must update value externally or the UI freezes.\",\n \"Each option's `description` renders as a secondary line below its label via ChoiceField — use it for help text or sub-copy; keep `label` short.\",\n \"Group-level `disabled` disables all checkboxes. Individual `options[n].disabled` disables only that item. Both can coexist.\",\n 'DO NOT wrap this inside another ARIA group or fieldset without removing the built-in `role=\"group\"` — it already provides the correct grouping semantics. Pair the group with a `<legend>` or visible heading for a11y.',\n ],\n useCases: [\n \"Permission / role selectors in admin forms — e.g. 'Select applicable roles: Admin, Editor, Viewer' where users can pick multiple.\",\n \"Filter panels — e.g. 'Filter by status: Active, Pending, Archived' with horizontal orientation for compact toolbar layout.\",\n \"Feature flag or settings toggles where multiple independent boolean flags share a label/description pair, loaded from a config array.\",\n \"Multi-category tagging forms — e.g. 'Tag this invoice: Recurring, Billable, Internal' driven by an options array fetched from an API.\",\n \"Onboarding checklists or multi-step preference screens where selections persist across steps via controlled `value`.\",\n \"Accounting module: select which cost centres or account codes apply to a transaction, driven by a normalized options list.\",\n ],\n related: [\n \"RadioGroup — use when only ONE selection is allowed at a time (mutually exclusive). CheckboxGroup = multiple, RadioGroup = single.\",\n \"Checkbox (standalone) — use a bare `Checkbox` for a single boolean toggle (e.g. 'I agree to terms'). Use CheckboxGroup when you have 2+ related choices.\",\n \"Checkbox.Group — alias; the same component is also accessible as `Checkbox.Group` (the Checkbox export attaches CheckboxGroup as `.Group`). Both are equivalent — prefer the named `CheckboxGroup` import for clarity in larger files.\",\n \"Switch / SwitchField — for a single binary on/off toggle with immediate effect (not a form submission value). Do not use CheckboxGroup to fake toggle rows.\",\n \"Select (multi) — for a long list (10+ items) where space is limited; CheckboxGroup is better for ≤10 visible options that benefit from scanning all at once.\",\n ],\n example: `import { CheckboxGroup } from \"@godxjp/ui/data-entry\";\nimport { useState } from \"react\";\n\nconst PERMISSIONS = [\n { label: \"View invoices\", value: \"invoices:read\" },\n { label: \"Create invoices\", value: \"invoices:write\", description: \"Includes editing and deleting\" },\n { label: \"Manage users\", value: \"users:manage\", disabled: true },\n];\n\n// Uncontrolled — use defaultValue\nexport function PermissionsForm() {\n return (\n <form method=\"post\">\n <CheckboxGroup\n name=\"permissions\"\n options={PERMISSIONS}\n defaultValue={[\"invoices:read\"]}\n orientation=\"vertical\"\n />\n </form>\n );\n}\n\n// Controlled — use value + onChange\nexport function ControlledExample() {\n const [selected, setSelected] = useState<string[]>([\"invoices:read\"]);\n return (\n <CheckboxGroup\n name=\"permissions\"\n options={PERMISSIONS}\n value={selected}\n onChange={setSelected}\n />\n );\n}`,\n storyPath: \"data-entry/CheckboxGroup.stories.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"Radio\",\n group: \"data-entry\",\n tagline:\n \"Radix-backed radio group with an options-array shorthand — always use Radio.Group, never a bare radio input.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled selected value. Must be paired with onValueChange to update state.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description:\n \"Uncontrolled initial value. Use when you do not need to track selection in state.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description:\n \"Callback fired when the user selects a different option. Required when value is controlled.\",\n },\n {\n name: \"options\",\n type: \"ChoiceOptionProp[]\",\n description:\n \"Declarative option list: { label: ReactNode; value: string; disabled?: boolean; description?: ReactNode }[]. When provided, Radio.Group renders each option as a labelled ChoiceField automatically. Omit to compose children manually.\",\n },\n {\n name: \"orientation\",\n type: '\"vertical\" | \"horizontal\"',\n defaultValue: '\"vertical\"',\n description:\n \"Layout direction for the option list. Vertical stacks options; horizontal lays them side by side.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n description:\n \"Disables the entire group when true. Individual options can also be disabled via options[].disabled.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form field name. Required for native form submission — Radix renders a hidden <input> with this name carrying the selected value.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional CSS class applied to the group root.\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n description:\n \"Manual composition fallback — used only when options is not provided. Render Radio.Item (+ ChoiceField wrapper) children directly inside Radio.Group.\",\n },\n ],\n usage: [\n \"DO use Radio.Group (not the bare Radio export) as the root — it wires up Radix context, keyboard navigation, and the hidden form input. A lone Radio.Item outside a Radio.Group has no context and will not function.\",\n \"DO prefer the options array API for static/data-driven option lists: pass options={[{ label, value, description?, disabled? }]} and Radio.Group renders each as a correctly-labelled ChoiceField automatically — no manual id/label wiring needed.\",\n \"DO pass name to Radio.Group when the selection must be submitted via a native HTML form. Radix injects a hidden <input name={name} value={selected}> so the value is picked up by FormData/fetch without extra wiring.\",\n \"DO use controlled mode (value + onValueChange) when the selection drives other UI (conditional fields, preview panels). Use defaultValue for fire-and-forget uncontrolled forms.\",\n \"DON'T hand-roll a label-plus-radio row with raw <input type='radio'> — use Radio.Group with options or compose Radio.Item inside ChoiceField for custom markup. Every option must be wrapped in ChoiceField (or equivalent) for the label htmlFor/id linkage.\",\n \"DON'T disable individual options inside the options array and ALSO set disabled on the group — group-level disabled wins and overrides all per-item disabled states.\",\n ],\n useCases: [\n \"Payment method selection (Credit Card / Bank Transfer / Invoice) on a checkout or invoice-creation form — mutually exclusive, 2-4 options, use options array + name for form submission.\",\n \"Account type picker (Asset / Liability / Equity / Revenue / Expense) on a chart-of-accounts create/edit page — use options with descriptions to explain each type.\",\n \"Report frequency chooser (Daily / Weekly / Monthly / Quarterly) in a scheduled-report settings panel — horizontal orientation when options are short labels.\",\n \"Tax regime selector on an entity or vendor profile form where exactly one option must always be active — controlled mode so adjacent fields can react to the selection.\",\n \"Approval workflow step type (Automatic / Manual / Conditional) in a workflow builder — use descriptions inside options to explain each mode without extra tooltip markup.\",\n \"Filter scope toggle (All entities / Current entity only) in an admin dashboard filter bar — horizontal orientation, no name needed (state managed in React, not submitted).\",\n ],\n related: [\n \"Checkbox.Group — use when users may select multiple options simultaneously; Radio.Group enforces single-selection only.\",\n \"Switch / SwitchField — use for a single boolean on/off toggle (e.g. enable notifications); Radio.Group is for choosing one among three or more named options.\",\n \"Select — use when there are many options (5+) and vertical screen space is limited; Radio.Group is preferable for 2-4 short options where all choices should be visible at a glance.\",\n ],\n example: `{\\`import { Radio } from \"@godxjp/ui/data-entry\";\n\n// --- Options-array API (recommended for most cases) ---\nconst PAYMENT_METHODS = [\n { label: \"Credit Card\", value: \"card\", description: \"Charged immediately on save.\" },\n { label: \"Bank Transfer\", value: \"bank\" },\n { label: \"Invoice\", value: \"invoice\", disabled: true },\n];\n\nfunction PaymentMethodPicker() {\n const [method, setMethod] = React.useState(\"card\");\n\n return (\n <Radio.Group\n name=\"payment_method\"\n value={method}\n onValueChange={setMethod}\n options={PAYMENT_METHODS}\n orientation=\"vertical\"\n />\n );\n}\n\n// --- Manual composition (when you need custom layout) ---\nfunction CustomRadioGroup() {\n return (\n <Radio.Group name=\"account_type\" defaultValue=\"asset\">\n <Radio.Item id=\"opt-asset\" value=\"asset\" />\n {/* wrap each item in ChoiceField for label + description */}\n </Radio.Group>\n );\n}\\`}`,\n storyPath: \"data-entry/Radio.stories.tsx\",\n rules: [3, 6, 13, 23],\n },\n {\n name: \"SearchSelect\",\n group: \"data-entry\",\n deprecated: true,\n tagline:\n \"DEPRECATED searchable single-select combobox (static or async) — use <Select options showSearch> instead; SearchSelect stays exported but Select is now the single data-driven entry point.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n defaultValue: '\"\"',\n description: \"Controlled selected value. Empty string means nothing selected.\",\n },\n {\n name: \"onChange\",\n type: \"(value: string, option?: SearchSelectOptionProp) => void\",\n description:\n \"Called with the new value string and the full option object on selection, or with ('', undefined) when cleared.\",\n },\n {\n name: \"options\",\n type: \"SearchSelectOptionProp[]\",\n description:\n \"Static option list — filtered client-side by query. Provide this OR loadOptions, not both.\",\n },\n {\n name: \"loadOptions\",\n type: \"(params: SearchSelectLoadParamsProp) => Promise<SearchSelectLoadResultProp>\",\n description:\n \"Async fetcher called with { query, page } — supports debounced search and infinite-scroll pagination. Provide this OR options, not both.\",\n },\n {\n name: \"renderOption\",\n type: \"(option: SearchSelectOptionProp) => React.ReactNode\",\n description:\n \"Custom per-option renderer (Ant-Design style). Defaults to label + optional sublabel layout.\",\n },\n {\n name: \"selectedLabel\",\n type: \"string\",\n description:\n \"Label to display for the current value when its option is not in the currently loaded page (prevents a flash of the raw ID string).\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description:\n \"Trigger button placeholder when no value is selected. Defaults to i18n key dataEntry.searchSelect.placeholder.\",\n },\n {\n name: \"searchPlaceholder\",\n type: \"string\",\n description:\n \"Placeholder inside the search input inside the popover. Defaults to i18n key dataEntry.searchSelect.search.\",\n },\n {\n name: \"emptyMessage\",\n type: \"string\",\n description:\n \"Message shown when no options match the search query. Defaults to i18n key dataEntry.searchSelect.empty.\",\n },\n {\n name: \"loadingMessage\",\n type: \"string\",\n description:\n \"Message shown during async fetch. Defaults to i18n key dataEntry.searchSelect.loading.\",\n },\n {\n name: \"clearLabel\",\n type: \"string\",\n description:\n \"Label for the clear row that appears at the top when a value is selected and clearable is true.\",\n },\n {\n name: \"clearable\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Show a clear row at the top of the list when a value is selected.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables the trigger button and prevents opening the popover.\",\n },\n {\n name: \"name\",\n type: \"string\",\n description:\n \"HTML form field name — injects a hidden <input> so the selected value submits with native forms.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description: \"ID forwarded to the trigger button, used to associate a <label htmlFor>.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Additional Tailwind classes applied to the trigger button (w-full by default).\",\n },\n {\n name: \"data-testid\",\n type: \"string\",\n description:\n \"Test ID on the trigger button. Each option gets a derived ID: ${data-testid}-option-${value}. The clear row gets ${data-testid}-option-none.\",\n },\n ],\n usage: [\n \"DEPRECATED — prefer <Select options={...} showSearch /> or <Select loadOptions={...} showSearch /> which uses the same engine internally. SearchSelect remains exported for backwards compatibility only.\",\n \"Provide exactly ONE of `options` (static, client-side filtered) or `loadOptions` (async, debounced, paginated). Passing both is unsupported; loadOptions takes precedence.\",\n \"Always pass `name` when used inside a native <form> so the hidden input submits the value correctly. Without `name` the selection does not participate in FormData.\",\n \"When using `loadOptions` with a paginated endpoint, return `hasMore: true` in the result to enable infinite scroll — the component appends the next page when scrolled within 48px of the bottom.\",\n \"Pass `selectedLabel` when `value` might not appear in the first loaded page (e.g. an edit form pre-populated from the server) — otherwise the trigger shows the placeholder text instead of the selected item's label.\",\n \"Do NOT render a SearchSelect inside a form and also pass a compound <Select> — choose one API. For new code always prefer <Select options showSearch> from @godxjp/ui/data-entry to avoid the deprecated path.\",\n ],\n useCases: [\n \"Legacy code that already uses SearchSelect and has not yet been migrated to <Select options showSearch>.\",\n \"A vendor/account picker with a large server-side list: pass loadOptions calling your API endpoint, return pages of results with hasMore, and use selectedLabel to display the pre-saved label on an edit form.\",\n \"A client-side filtered dropdown over a moderate static list (e.g. currency codes, department names) where the list fits in memory — pass options array.\",\n \"A grouped picker (e.g. account chart by category) — add option.group to each option; the component auto-renders optgroup-style headings in first-seen order.\",\n \"Custom option rendering (e.g. showing an avatar + name + role) — pass renderOption returning JSX; the default label+sublabel layout is bypassed.\",\n ],\n related: [\n \"Select — THE modern replacement: pass options or loadOptions to <Select> and add showSearch to get the same combobox behavior. For all new code use Select, not SearchSelect.\",\n \"Autocomplete — also deprecated; Autocomplete is a thin wrapper around SearchSelect kept for older call-sites. Do not use for new code.\",\n \"Command — low-level primitive (Popover + Command list) that SearchSelect is built on; reach for it only if you need a fully custom command-palette UI that does not fit either Select or SearchSelect.\",\n ],\n example: `import { SearchSelect } from \"@godxjp/ui/data-entry\";\n\n// Static list (client-side filtered) — DEPRECATED pattern, prefer <Select options showSearch>\nfunction LegacyAccountPicker({ value, onChange }) {\n return (\n <SearchSelect\n value={value}\n onChange={onChange}\n options={[\n { value: \"acc-001\", label: \"Cash\", sublabel: \"Current assets\", group: \"Assets\" },\n { value: \"acc-002\", label: \"Accounts Receivable\", group: \"Assets\" },\n { value: \"acc-010\", label: \"Revenue\", group: \"Income\" },\n ]}\n placeholder=\"Select account\"\n name=\"account_id\"\n data-testid=\"account-picker\"\n />\n );\n}\n\n// Async / paginated — DEPRECATED pattern, prefer <Select loadOptions showSearch>\nasync function fetchVendors({ query, page }) {\n const res = await fetch(\\`/api/vendors?q=\\${query}&page=\\${page}\\`);\n const json = await res.json();\n return { options: json.data, hasMore: json.meta.hasNextPage };\n}\n\nfunction LegacyVendorPicker({ value, currentVendorName, onChange }) {\n return (\n <SearchSelect\n value={value}\n onChange={onChange}\n loadOptions={fetchVendors}\n selectedLabel={currentVendorName}\n placeholder=\"Select vendor\"\n name=\"vendor_id\"\n data-testid=\"vendor-picker\"\n />\n );\n}`,\n storyPath: \"data-entry/SearchSelect.stories.tsx\",\n rules: [3, 6, 33],\n },\n {\n name: \"Autocomplete\",\n group: \"data-entry\",\n deprecated: true,\n tagline:\n \"DEPRECATED thin wrapper over SearchSelect — use <Select options showSearch> instead; kept only for backward compatibility.\",\n props: [\n {\n name: \"options\",\n type: \"{ value: string; label: string }[]\",\n required: true,\n description:\n \"Static list of option rows. Each entry must have a string value and a display label.\",\n },\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled selected value. When provided the component is fully controlled; omit for uncontrolled.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description:\n \"Callback fired with the newly selected string value. Required for controlled usage.\",\n },\n {\n name: \"placeholder\",\n type: \"string\",\n description: \"Trigger button placeholder shown when no value is selected.\",\n },\n {\n name: \"searchPlaceholder\",\n type: \"string\",\n description: \"Placeholder text inside the search input in the dropdown.\",\n },\n {\n name: \"emptyMessage\",\n type: \"string\",\n description: \"Message shown in the dropdown when no options match the search query.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Disables the control entirely — trigger becomes non-interactive.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra Tailwind classes applied to the trigger wrapper.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description:\n \"HTML id forwarded to the underlying trigger element; wire to a <label> for a11y.\",\n },\n ],\n usage: [\n \"DEPRECATED — do NOT use for new code. Replace with `<Select options={opts} showSearch />` (single data-driven entry point) or `<SearchSelect options={opts} />` for more control. Autocomplete is a thin shim kept only for backward compatibility.\",\n \"DO pass a controlled `value` + `onValueChange` pair to keep state outside; without `value` the component is uncontrolled and you cannot read the selected item.\",\n \"DO NOT expect optgroup grouping, sublabels, async loading, or a custom `renderOption` — Autocomplete's option type only has `{ value, label }`. Use SearchSelect or Select with showSearch for those features.\",\n \"DO NOT use this inside an HTML `<form>` for native form submission — there is no `name` prop and no hidden input. Pair with React Hook Form or manage state manually via `onValueChange`.\",\n \"Always provide a matching `<label htmlFor={id}>` when using `id` for screen-reader accessibility.\",\n \"The internal clearable button is always hidden (hardcoded `clearable={false}`). If you need a clear/reset action use `<SearchSelect clearable />` or `<Select showSearch clearable />`.\",\n ],\n useCases: [\n \"Migrating legacy code that already imports Autocomplete — keep it running without a rewrite while you schedule the migration to Select/SearchSelect.\",\n \"Simple static list with client-side search where no grouping, sublabels, or async fetch is needed — though even here, prefer Select with showSearch for future-proofing.\",\n \"Rapid prototyping where the exact API doesn't matter yet and you know it will be replaced before shipping.\",\n ],\n related: [\n \"Select (with showSearch + options) — the CURRENT canonical replacement for Autocomplete; supports grouping, sublabels, async loadOptions, custom renderOption, clearable, multi, and form name prop. Use this for all new code.\",\n \"SearchSelect — the direct engine Autocomplete delegates to; exported and stable, supports optgroups, sublabels, async infinite-scroll, and clearable. Use if you need SearchSelect-specific async or render props not yet exposed by Select.\",\n \"Input with datalist — never hand-roll; use Select/SearchSelect primitives instead.\",\n ],\n example: `{\\`// ❌ DEPRECATED — do not use in new code\nimport { Autocomplete } from \"@godxjp/ui/data-entry\";\n\n// ✅ Replace with:\n// import { Select } from \"@godxjp/ui/data-entry\";\n// <Select options={options} showSearch placeholder=\"Search…\" onChange={setValue} value={value} />\n\n// Legacy usage (backward compat only):\nimport { Autocomplete } from \"@godxjp/ui/data-entry\";\n\nconst options = [\n { value: \"acme\", label: \"Acme Corp\" },\n { value: \"globex\", label: \"Globex Inc\" },\n];\n\nfunction LegacyVendorPicker() {\n const [value, setValue] = React.useState(\"\");\n return (\n <Autocomplete\n id=\"vendor\"\n options={options}\n value={value}\n onValueChange={setValue}\n placeholder=\"Select vendor…\"\n searchPlaceholder=\"Search vendors…\"\n emptyMessage=\"No vendor found\"\n />\n );\n}\\`}`,\n storyPath: \"data-entry/Autocomplete.stories.tsx\",\n rules: [6, 13, 23, 31],\n },\n {\n name: \"Popover\",\n group: \"data-display\",\n tagline:\n \"Radix-backed floating panel anchored to a trigger — always compose with PopoverTrigger + PopoverContent; never use a raw div overlay.\",\n props: [\n {\n name: \"open\",\n type: \"boolean\",\n description: \"Controls open state in controlled mode. Pair with onOpenChange.\",\n },\n {\n name: \"defaultOpen\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Initial open state for uncontrolled usage.\",\n },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description:\n \"Callback fired when the popover open state changes. Required when using controlled mode (open prop).\",\n },\n {\n name: \"modal\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, interaction outside the popover is blocked and focus is trapped inside (Radix Root prop).\",\n },\n {\n name: \"align\",\n type: \"'start' | 'center' | 'end'\",\n defaultValue: '\"center\"',\n description:\n \"PopoverContent prop. Horizontal alignment of the popover relative to the trigger.\",\n },\n {\n name: \"sideOffset\",\n type: \"number\",\n defaultValue: \"4\",\n description:\n \"PopoverContent prop. Distance in pixels between the popover panel and its anchor.\",\n },\n {\n name: \"side\",\n type: \"'top' | 'right' | 'bottom' | 'left'\",\n defaultValue: '\"bottom\"',\n description:\n \"PopoverContent prop. Which side of the trigger the panel prefers to open on (auto-flips on overflow).\",\n },\n {\n name: \"asChild\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"PopoverTrigger prop. Merges trigger props onto the immediate child element (e.g. a Button) instead of rendering an extra DOM node. Strongly recommended to avoid a wrapping <button>.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"PopoverContent prop. Extra Tailwind classes merged onto the panel (default: w-72 p-4 rounded-md border shadow-md z-50).\",\n },\n ],\n usage: [\n \"DO compose: <Popover> → <PopoverTrigger asChild> → <Button/> and <PopoverContent>. All four parts are required for any popover to function; omitting PopoverTrigger or PopoverContent produces nothing.\",\n \"DO use asChild on PopoverTrigger when the trigger is already a Button or link — this avoids a nested <button><button> violation and extra DOM nesting.\",\n \"DO use controlled mode (open + onOpenChange) when external code must open/close the popover programmatically (e.g., form validation reveal, keyboard shortcut). For toggle-only interactions, uncontrolled (defaultOpen) is simpler.\",\n \"DO structure panel content with PopoverHeader > PopoverTitle + PopoverDescription for labelled panels. This is purely presentational but establishes the correct font-weight and muted-foreground on the description.\",\n \"DON'T hand-roll a floating div or use a CSS show/hide toggle — Popover provides portal rendering, focus trap, Escape-to-close, and ARIA automatically.\",\n \"DON'T place a Popover inside a Dialog without setting modal={false} on the Popover — nested modals conflict with Radix's focus management and produce stuck focus.\",\n ],\n useCases: [\n \"Advanced filter panel: a 'Filters' Button triggers a Popover containing filter inputs (date range, status selects); panel width overridden via className='w-96'.\",\n \"Row action menu overflow: when a DataTable row has too many actions for inline display, a Popover holds the secondary actions (Edit, Archive, Delete) without navigating away.\",\n \"Contextual help / tooltip-rich: a small '?' icon button opens a Popover with PopoverTitle + PopoverDescription explaining a form field — richer than a Tooltip but less intrusive than a Dialog.\",\n \"Inline record preview: clicking a reference number in an invoice list opens a Popover showing a summary card of the linked document before the user decides to navigate.\",\n \"Column visibility picker: a 'Columns' button above a DataTable opens a Popover containing checkboxes to show/hide columns, with controlled state managed in parent.\",\n \"Quick-edit cell: for an admin table, clicking a status badge opens a Popover with a RadioGroup to change status in-place without a full Dialog.\",\n ],\n related: [\n \"Tooltip — use Tooltip for brief, non-interactive label-like hints (hover-only, no inputs). Use Popover when the floating content is interactive (buttons, inputs, forms).\",\n \"Dialog/Sheet — use Dialog or Sheet for full modal actions that require user confirmation or significant input. Use Popover for lightweight, anchor-relative panels that dismiss on outside click.\",\n \"DropdownMenu — use DropdownMenu for a flat list of clickable actions or links. Use Popover when the floating panel needs arbitrary layout (forms, grids, rich content) rather than a menu list.\",\n ],\n example: `import {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverHeader,\n PopoverTitle,\n PopoverDescription,\n} from \"@godxjp/ui/data-display\";\nimport { Button } from \"@godxjp/ui/general\";\n\n// Uncontrolled — basic usage\nexport function InvoiceFilterPopover() {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"outline\">Advanced filters</Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-96\">\n <PopoverHeader>\n <PopoverTitle>Filter invoices</PopoverTitle>\n <PopoverDescription>Narrow results by date range and status.</PopoverDescription>\n </PopoverHeader>\n {/* place form controls here */}\n </PopoverContent>\n </Popover>\n );\n}\n\n// Controlled — programmatic open/close\nimport * as React from \"react\";\n\nexport function ControlledPopover() {\n const [open, setOpen] = React.useState(false);\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label=\"Show details\">\n ?\n </Button>\n </PopoverTrigger>\n <PopoverContent side=\"right\" sideOffset={8}>\n <PopoverHeader>\n <PopoverTitle>About this field</PopoverTitle>\n <PopoverDescription>\n The MF ID is the unique identifier assigned by Money Forward.\n </PopoverDescription>\n </PopoverHeader>\n </PopoverContent>\n </Popover>\n );\n}`,\n storyPath: \"data-display/Popover.stories.tsx\",\n rules: [3, 23, 31, 35],\n },\n {\n name: \"ScrollArea\",\n group: \"data-display\",\n tagline:\n \"Radix-backed custom scrollbar container — always set an explicit height/max-height on the wrapper or the scrollbar never appears.\",\n props: [\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra classes applied to the root element. Must include a height constraint (h-*, max-h-*) — without one, the viewport expands to fit its content and no scrollbar is rendered.\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n required: true,\n description:\n \"The content to make scrollable. Wrap it in a single element so the Viewport can measure its full size correctly.\",\n },\n {\n name: \"dir\",\n type: '\"ltr\" | \"rtl\"',\n description:\n \"Text direction forwarded to the Radix Root. Defaults to the document direction.\",\n },\n {\n name: \"scrollHideDelay\",\n type: \"number\",\n defaultValue: \"600\",\n description:\n \"Milliseconds before the scrollbar auto-hides after the pointer leaves. Applies to both axes.\",\n },\n {\n name: \"type\",\n type: '\"auto\" | \"always\" | \"scroll\" | \"hover\"',\n defaultValue: '\"hover\"',\n description:\n \"Scrollbar visibility strategy. 'auto' mirrors browser overflow; 'always' keeps it visible; 'scroll' shows while scrolling; 'hover' shows while hovering the scroll area.\",\n },\n ],\n usage: [\n 'DO set an explicit height or max-height on ScrollArea via className (e.g. `className=\"h-64\"` or `className=\"max-h-[min(300px,50vh)]\"`). Without a height constraint the viewport grows to fit content and the scrollbar is never rendered.',\n \"DO wrap content in a single child element inside ScrollArea — the Viewport observes its single child's size to decide whether overflow exists.\",\n 'DO add `<ScrollBar orientation=\"horizontal\" />` explicitly (after the children, before closing ScrollArea) when you need horizontal scrolling. The default ScrollBar rendered by ScrollArea is vertical-only.',\n \"DON'T use a native browser `overflow-auto` div as an alternative — ScrollArea provides the design-system-styled thumb/track and respects the semantic token palette.\",\n \"DON'T put ScrollArea inside a flex parent without giving it a `flex-1` or fixed size — it will collapse to zero height and appear broken.\",\n 'For horizontal-only scrolling, still wrap in ScrollArea with `className=\"w-full\"`, put the wide content inside, and place `<ScrollBar orientation=\"horizontal\" />` explicitly after the content.',\n ],\n useCases: [\n \"Long dropdown lists inside Popovers or Selects where the list height must be capped (e.g. TreeSelect, Cascader columns, Combobox options).\",\n \"Sidebar navigation panels or filter drawers whose content can exceed viewport height.\",\n \"Transfer-list panels with a fixed height that must scroll through a large item list.\",\n \"Cascader multi-column layouts where the horizontal axis may overflow (use ScrollBar orientation=horizontal).\",\n \"Detail panels or audit-log timelines inside a fixed-height Card that should not stretch the page.\",\n \"Code or JSON viewers with a fixed max-height needing both axes scrollable.\",\n ],\n related: [\n \"DataTable — use DataTable (not ScrollArea) when data is tabular and needs sorting/selection; DataTable manages its own overflow internally.\",\n \"Collapsible — use Collapsible to show/hide a section; pair with ScrollArea when the revealed content can itself overflow.\",\n \"Card/CardContent — when the card body should scroll, put ScrollArea inside CardContent rather than applying overflow directly to CardContent.\",\n ],\n example: `import { ScrollArea, ScrollBar } from \"@godxjp/ui/data-display\";\n\n// Vertical-only (default)\n<ScrollArea className=\"h-64 w-full rounded-md border\">\n <div className=\"p-4 space-y-2\">\n {entries.map((entry) => (\n <div key={entry.id} className=\"text-sm\">{entry.label}</div>\n ))}\n </div>\n</ScrollArea>\n\n// Horizontal + vertical (e.g. wide Cascader columns)\n<ScrollArea className=\"w-full\">\n <div className=\"flex max-h-[min(280px,50vh)]\">\n {columns.map((col, i) => (\n <ul key={i} className=\"min-w-36 border-r last:border-r-0\">\n {col.map((item) => <li key={item.value}>{item.label}</li>)}\n </ul>\n ))}\n </div>\n <ScrollBar orientation=\"horizontal\" />\n</ScrollArea>`,\n storyPath: \"data-display/ScrollArea.stories.tsx\",\n rules: [2, 3, 24, 31],\n },\n {\n name: \"Collapsible\",\n group: \"data-display\",\n tagline:\n \"Three-part compound (Collapsible + CollapsibleTrigger + CollapsibleContent) that toggles a region open/closed — never use just one part alone.\",\n props: [\n {\n name: \"open\",\n type: \"boolean\",\n description:\n \"Controlled open state. When provided, pair with onOpenChange to keep in sync. Omit for uncontrolled behaviour.\",\n },\n {\n name: \"defaultOpen\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Initial open state when used uncontrolled. Useful for auto-expanding when a child is active (e.g. sidebar nav group).\",\n },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Callback fired when the open state changes. Required in controlled mode.\",\n },\n {\n name: \"disabled\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"Prevents the trigger from toggling the content. The trigger is still rendered but inert.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Applied to the root Collapsible element. Use for layout (e.g. sb-nav-group) — the root renders a div.\",\n },\n {\n name: \"asChild (CollapsibleTrigger)\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"On CollapsibleTrigger only — merges Radix trigger behaviour onto the single child element (e.g. a godx-ui Button) instead of rendering a default button. The child must accept onClick and aria-* props.\",\n },\n ],\n usage: [\n \"DO compose all three parts together: <Collapsible> wraps both <CollapsibleTrigger> and <CollapsibleContent>. Never render CollapsibleContent without a parent Collapsible — the open state lives on the root.\",\n \"DO use asChild on CollapsibleTrigger when you want a godx-ui Button (or any styled element) to act as the trigger: <CollapsibleTrigger asChild><Button>Toggle</Button></CollapsibleTrigger>. Without asChild the trigger renders its own plain button.\",\n \"DO pass defaultOpen={true} (uncontrolled) when the section should auto-expand on mount — for example, a sidebar nav group whose active child matches the current route.\",\n \"DO use controlled mode (open + onOpenChange) when external UI — a separate button, route change, or search filter — needs to drive the open state independently of the trigger.\",\n \"DON'T add hidden native <details>/<summary> as a fallback — the Radix primitive is already accessible (aria-expanded, aria-controls) out of the box.\",\n \"DON'T put interactive controls (Buttons, links, inputs) inside CollapsibleTrigger itself unless using asChild — nested focusable elements break keyboard navigation. Put them inside CollapsibleContent instead.\",\n ],\n useCases: [\n \"Sidebar navigation group: a top-level nav item with children collapses/expands its sub-items in the rail (used directly in the godx-ui Sidebar component with defaultOpen={active}).\",\n \"Invoice line-item detail: an invoice row that expands inline to show tax breakdown, allocation notes, or audit trail without navigating away.\",\n \"Filter panel section: a labelled group of filter controls (date range, entity, status) that can be collapsed to save vertical space in a dense accounting dashboard.\",\n \"Read-more / long description: a truncated journal entry or payment memo that expands to full text on demand.\",\n \"Settings sub-section: an optional advanced settings block that is hidden by default and revealed only when the user opts in.\",\n \"Audit log detail: a compact log entry row that expands to show full diff, user, timestamp, and before/after values.\",\n ],\n related: [\n \"Accordion (from @godxjp/ui/data-entry or Radix) — use Accordion when only ONE section can be open at a time across a group; use Collapsible when each section is independent and can be open simultaneously.\",\n \"Popover — use Popover when the revealed content should float above the layout in a portal overlay; use Collapsible when the content should push surrounding content down inline.\",\n \"Dialog/Sheet — use Dialog or Sheet for modal or slide-over panels that demand full user attention; Collapsible stays in-flow and non-modal.\",\n \"TreeList (@godxjp/ui/data-display) — use TreeList for hierarchical data that needs recursive nesting with built-in indentation and expand/collapse; use Collapsible for ad-hoc single-level toggle regions.\",\n ],\n example: `{\\`import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from \"@godxjp/ui/data-display\";\nimport { Button } from \"@godxjp/ui\";\n\n// --- Uncontrolled (simplest) ---\nexport function InvoiceLineDetail() {\n return (\n <Collapsible>\n <CollapsibleTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\">\n <ChevronDown className=\"mr-1 h-4 w-4\" aria-hidden=\"true\" />\n Show tax breakdown\n </Button>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <div className=\"mt-2 rounded-md border p-3 text-sm\">\n <p>Consumption tax (10%): ¥1,234</p>\n <p>Withholding tax: ¥0</p>\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n\n// --- Controlled (open driven externally) ---\nexport function FilterSection() {\n const [open, setOpen] = useState(false);\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <CollapsibleTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n Advanced filters\n <ChevronDown className=\"ml-1 h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </CollapsibleTrigger>\n <CollapsibleContent>\n {/* place filter controls here */}\n <p className=\"mt-2 text-sm text-muted-foreground\">Date range, entity, status…</p>\n </CollapsibleContent>\n </Collapsible>\n );\n}\\`}`,\n storyPath: \"data-display/Collapsible.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"TreeList\",\n group: \"data-display\",\n tagline:\n \"Renders a flat array of items as an indented tree-style list with chevron + package icon; depth indentation is data-driven — never nest DOM manually.\",\n props: [\n {\n name: \"items\",\n type: \"TreeListItem[]\",\n required: true,\n description:\n \"Ordered flat array of items to render. Each item carries its own depth so the tree structure is expressed in data, not DOM nesting.\",\n },\n ],\n usage: [\n \"DO pass a flat array ordered top-to-bottom with each item's `depth` set to the correct nesting level (0 = root, 1 = first child, etc.). TreeList does NOT accept nested children — the tree shape is encoded in data.\",\n \"DO set `item.active = true` on the currently selected row; the component applies `data-active` for styling — never manually add an active class.\",\n \"DO use `item.badge` (ReactNode) to surface a secondary label (count, status chip) — it is rendered as a `Badge variant='secondary'` automatically; do NOT wrap the value in a Badge yourself.\",\n \"DON'T hand-roll padding or indentation — depth-based indentation is applied via `data-depth` CSS; adding manual padding breaks the visual rhythm.\",\n \"DON'T use TreeList for interactive selection (click handlers, routing) — it has no `onItemClick` prop. Wrap items in a navigation list or add a Link inside `item.title` when interactivity is needed.\",\n \"DO provide a unique string `item.id` for every item; it is used as the React key and must be stable across renders.\",\n ],\n useCases: [\n \"Displaying a chart-of-accounts hierarchy (root accounts at depth 0, sub-accounts at depth 1+) in an accounting admin panel.\",\n \"Showing a package/module dependency tree where each node has a name, optional description, and an item-count badge.\",\n \"Rendering a category tree (e.g., product categories, tax codes) in a read-only reference list alongside a detail panel.\",\n \"Listing a filtered/searched subset of a hierarchy — because the flat-array model lets you pre-filter server-side and still show correct depth context.\",\n \"Sidebar or drawer content showing a tree of navigation nodes where the active branch item is highlighted via `active: true`.\",\n ],\n related: [\n \"Timeline — use Timeline for chronological event sequences with timestamps; use TreeList for hierarchical parent-child structures.\",\n \"KeyValueGrid — use KeyValueGrid for label/value pairs; use TreeList when items have a parent-child depth relationship.\",\n \"DataTable — use DataTable for tabular data with columns, sorting, and selection; use TreeList for a single-column hierarchical list without those features.\",\n \"EmptyState — pair with EmptyState when the items array may be empty; TreeList renders nothing (no empty row) when given an empty array.\",\n ],\n example: `import { TreeList } from \"@godxjp/ui/data-display\";\n\nconst accounts = [\n { id: \"1000\", title: \"Assets\", depth: 0 },\n { id: \"1100\", title: \"Current Assets\", depth: 1, active: true },\n { id: \"1110\", title: \"Cash & Equivalents\", description: \"Bank + petty cash\", depth: 2, badge: \"3 accounts\" },\n { id: \"1120\", title: \"Accounts Receivable\", depth: 2 },\n { id: \"2000\", title: \"Liabilities\", depth: 0 },\n];\n\nexport function ChartOfAccounts() {\n return <TreeList items={accounts} />;\n}`,\n storyPath: \"data-display/TreeList.stories.tsx\",\n rules: [3, 6, 23, 31],\n },\n {\n name: \"ScanPanel\",\n group: \"data-display\",\n tagline:\n \"Square dashed placeholder panel with a scan-line icon — for empty/waiting states where content is scanned or uploaded; never hand-roll this pattern with a raw div.\",\n props: [\n {\n name: \"title\",\n type: \"string\",\n required: true,\n description: \"Primary label rendered below the scan-line icon in semibold large text.\",\n },\n {\n name: \"description\",\n type: \"string\",\n description:\n \"Optional secondary line rendered below the title in muted small text. Omit if no additional context is needed.\",\n },\n ],\n usage: [\n \"DO use ScanPanel for any empty/awaiting-input area that represents a 'scan something here' or 'drop/upload file' prompt — it provides the icon, border, background tint, and typography in one call.\",\n \"DON'T hand-roll a dashed-border div with a lucide icon and centered text — ScanPanel is exactly that pattern and keeps visual consistency across the app.\",\n \"The panel renders 1:1 aspect-ratio (square) via CSS; constrain its width from the parent container (e.g. max-w-xs) rather than trying to override aspect-ratio.\",\n \"DO pass a concise `title` (required) that names the action or state (e.g. 'Scan invoice', 'No file selected'). Use `description` only for a secondary instruction or status line.\",\n \"DON'T put interactive controls inside ScanPanel — it is a pure display/empty-state element. Pair it with a nearby Button or file-input for the actual action.\",\n \"ScanPanel is NOT a general EmptyState — use godx-ui EmptyState for table/list zero-row states. ScanPanel is specifically for scan/upload affordance panels.\",\n ],\n useCases: [\n \"An invoice-scanning workflow step where the user must point a camera or upload an image — show ScanPanel while no file is selected.\",\n \"A QR-code / barcode reader pane rendered before the camera stream is active, indicating the scan target area.\",\n \"A document upload dropzone placeholder in an accounting app (expense receipts, purchase orders) before any file is chosen.\",\n \"An OCR processing panel shown while the system awaits a document scan input from a connected scanner device.\",\n \"A 'no attachment yet' state in an accounting record detail view that invites the user to attach a scanned document.\",\n ],\n related: [\n \"EmptyState — use for zero-row table/list states or generic no-data screens; ScanPanel is specifically scan/upload affordance with its own icon and square layout.\",\n \"DataState / InfiniteQueryState — use for TanStack Query lifecycle (loading/empty/error) in list views; not for scan prompts.\",\n \"SkeletonTable — use while data is loading into a table; not for scan/upload placeholder states.\",\n ],\n example: `import { ScanPanel } from \"@godxjp/ui/data-display\";\n\nexport function InvoiceScanStep() {\n return (\n <div className=\"max-w-xs mx-auto\">\n <ScanPanel\n title=\"Scan invoice\"\n description=\"Point your camera at the invoice barcode or upload a file.\"\n />\n </div>\n );\n}`,\n storyPath: \"data-display/ScanPanel.stories.tsx\",\n rules: [31],\n },\n {\n name: \"CodeBadge\",\n group: \"data-display\",\n tagline:\n \"Compact labelled icon-chip for displaying typed reference codes (internal, seller, or carrier); never use Badge or a raw span for these domain codes.\",\n props: [\n {\n name: \"kind\",\n type: '\"internal\" | \"seller\" | \"yamato\"',\n required: true,\n description:\n 'Determines the icon and abbreviated label prefix rendered inside the chip. \"internal\" → Hash icon + \"INT\"; \"seller\" → ShoppingBag + \"SLR\"; \"yamato\" → Truck + \"YMT\". Falls back to \"internal\" if an unknown kind is supplied.',\n },\n {\n name: \"value\",\n type: \"string\",\n required: true,\n description:\n \"The actual reference code string to display after the icon (e.g. an order number, shipment tracking ID, or internal SKU).\",\n },\n ],\n usage: [\n \"DO: always supply both `kind` and `value` — both are required; omitting either leaves the chip meaningless or broken.\",\n 'DO: use `kind=\"internal\"` for internal system IDs/SKUs, `kind=\"seller\"` for seller/merchant reference codes, and `kind=\"yamato\"` for Yamato carrier/shipment tracking codes.',\n \"DON'T: use a raw `<Badge>` or a plain `<span>` for domain reference codes — `CodeBadge` encodes the correct icon, label prefix, and semantic `data-kind` attribute that CSS/tests rely on.\",\n \"DON'T: pass display-formatted values (e.g. with leading/trailing whitespace or HTML entities) — `value` is rendered as plain text inside a `<span>`.\",\n \"DON'T: attempt to extend `kind` inline — if a new code type is needed, add it to `CodeBadgeKind` in the source and export; never pass an arbitrary string and expect the chip to render correctly (it silently falls back to `internal`).\",\n 'A11Y: the icon is rendered with `aria-hidden=\"true\"` so screen readers see only the label prefix and value text — keep `value` human-readable (e.g. the actual code, not an opaque hash).',\n ],\n useCases: [\n \"Displaying an order's internal system reference code alongside seller and carrier codes in an order detail panel or DataTable column.\",\n \"Rendering a Yamato shipment tracking number in a logistics/fulfillment table so operators can visually distinguish it from internal IDs at a glance.\",\n \"Showing a seller's own reference code (e.g. merchant PO number) in an invoice or accounting line-item row.\",\n \"Pairing multiple CodeBadge instances in a KeyValueGrid row — e.g. INT code next to SLR code — to show all reference IDs for a single transaction.\",\n \"In a DataTable cell renderer, wrapping a code field so the column's kind is immediately obvious without a separate column header.\",\n ],\n related: [\n \"Badge — generic variant-styled pill (default/secondary/destructive/outline/success/warning). Use Badge for arbitrary status labels or counts. Use CodeBadge specifically for typed domain reference codes (internal/seller/yamato) that need a fixed icon+prefix.\",\n 'StatusBadge — displays a status string with a semantic tone. Use StatusBadge for workflow/order status chips (e.g. \"Paid\", \"Pending\"). Use CodeBadge for reference/ID codes, not status labels.',\n ],\n example: `{\\`import { CodeBadge } from \"@godxjp/ui/data-display\";\n\n// Internal system reference code\n<CodeBadge kind=\"internal\" value=\"ORD-00123\" />\n\n// Seller reference code\n<CodeBadge kind=\"seller\" value=\"SLR-98765\" />\n\n// Yamato carrier tracking code\n<CodeBadge kind=\"yamato\" value=\"YMT-4444-5555-6666\" />\n\n// Multiple codes for one order\n<div className=\"flex flex-wrap gap-2\">\n <CodeBadge kind=\"internal\" value=\"ORD-00123\" />\n <CodeBadge kind=\"seller\" value=\"SLR-98765\" />\n <CodeBadge kind=\"yamato\" value=\"YMT-4444-5555-6666\" />\n</div>\\`}`,\n storyPath: \"data-display/CodeBadge.stories.tsx\",\n rules: [3, 6, 13, 35],\n },\n {\n name: \"PageHeader\",\n group: \"navigation\",\n deprecated: true,\n tagline:\n \"DEPRECATED header-only shell — use PageContainer instead; PageHeader renders only the title/breadcrumb/actions strip with no body or footer slots.\",\n props: [\n {\n name: \"title\",\n type: \"React.ReactNode\",\n required: true,\n description: \"Page heading text rendered as an <h1>. Accepts a string or any ReactNode.\",\n },\n {\n name: \"description\",\n type: \"React.ReactNode\",\n description: \"Optional subtitle rendered as a <p> below the title.\",\n },\n {\n name: \"breadcrumb\",\n type: \"BreadcrumbItemProp[]\",\n description:\n \"Ordered breadcrumb trail. Each item is { label: ReactNode; to?: string }. The last item is always rendered as a plain span (current page); earlier items with 'to' are router <Link>s.\",\n },\n {\n name: \"actions\",\n type: \"React.ReactNode\",\n description:\n \"Action controls (buttons, menus) rendered in the trailing slot of the header row. Equivalent to PageContainer's 'extra' prop.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional CSS class names applied to the <header> element.\",\n },\n ],\n usage: [\n \"DEPRECATED — always prefer PageContainer for new pages. PageContainer provides body and footer slots, density/variant controls, and sticky footer support that PageHeader lacks.\",\n \"DO pass breadcrumb items in order from root to current page. The last item is automatically marked aria-current='page' and rendered without a link regardless of whether 'to' is set.\",\n \"DON'T place body content as children — PageHeader has no children slot. Use PageContainer with its children prop for page body content.\",\n \"The 'actions' prop (not 'extra') is the slot for action buttons or menus in the trailing position. Note that PageContainer uses 'extra' for the same slot — they are intentionally different prop names.\",\n \"Use 'description' (not 'subtitle') for the secondary text beneath the title — again, PageContainer uses 'subtitle' for the same concept.\",\n \"If you must keep PageHeader for a legacy page, avoid adding new body layout inside the same file; migrate to PageContainer to get density and variant props for responsive layout.\",\n ],\n useCases: [\n \"Maintaining or reading legacy pages that already use PageHeader and cannot be migrated in the current sprint.\",\n \"Quick title + breadcrumb strip for a read-only display panel that embeds inside another layout shell (not a full page).\",\n \"Regression tests and snapshot tests for the navigation module that must cover the legacy component path.\",\n \"Any scenario where you intentionally render only a header row with no body — though even then, PageContainer with no children is the preferred modern approach.\",\n ],\n related: [\n \"PageContainer — the current replacement for PageHeader; use this for all new pages. It adds children, footer, density, variant, stickyFooter, and uses 'subtitle'/'extra' instead of 'description'/'actions'.\",\n \"AppShell — top-level layout shell that wraps sidebar, topbar, and the page area; PageContainer lives inside AppShell's content area.\",\n \"Topbar — the fixed top bar with product/project chips and search; distinct from the per-page header rendered by PageContainer/PageHeader.\",\n ],\n example: `import { PageHeader } from \"@godxjp/ui/navigation\";\nimport { Button } from \"@godxjp/ui/general\";\n\n// DEPRECATED — use PageContainer for new pages.\n// Legacy usage only:\nexport function LegacyInvoiceHeader() {\n return (\n <PageHeader\n title=\"Invoices\"\n description=\"All issued invoices for the current entity\"\n breadcrumb={[\n { label: \"Home\", to: \"/\" },\n { label: \"Accounting\", to: \"/accounting\" },\n { label: \"Invoices\" }, // last item — no 'to', rendered as current page\n ]}\n actions={\n <Button variant=\"default\" size=\"sm\">\n New Invoice\n </Button>\n }\n />\n );\n}`,\n storyPath: \"navigation/PageHeader.stories.tsx\",\n rules: [3, 23, 24, 33],\n },\n {\n name: \"LocalePicker\",\n group: \"navigation\",\n tagline:\n \"Language selector that reads/writes AppProvider locale automatically — throws if used without AppProvider AND without controlled value+onChange.\",\n props: [\n {\n name: \"value\",\n type: \"AppLocale\",\n description:\n \"Controlled locale value. Must be one of 'vi' | 'en' | 'ja'. When omitted, reads the current locale from AppProvider context.\",\n },\n {\n name: \"onChange\",\n type: \"(locale: AppLocale) => void\",\n description:\n \"Controlled change handler. When omitted, calls AppProvider's setLocale. Required when value is provided without AppProvider.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Extra CSS classes merged onto the SelectTrigger element. Default trigger width is w-full sm:w-40.\",\n },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the Select control.\" },\n {\n name: \"id\",\n type: \"string\",\n description: \"HTML id forwarded to the SelectTrigger for label association.\",\n },\n ],\n usage: [\n \"DO: Wrap the component in AppProvider for zero-config uncontrolled use — locale is read and written via context automatically, no props needed. DO NOT use without AppProvider unless you also supply both value and onChange.\",\n \"DO: Use controlled mode (value + onChange) when you need to manage locale state outside of AppProvider — for example in a standalone settings form or a Storybook story. Both props are required together in this mode.\",\n \"DO NOT: Pass only value without onChange, or only onChange without value in controlled mode. The component throws at render time if neither AppProvider context nor both controlled props are present: 'LocalePicker requires <AppProvider> or controlled value + onChange'.\",\n \"DO: The locale list is fixed to APP_LOCALES = ['vi', 'en', 'ja']. Option labels are rendered via the translation system (t('locale.vi') etc.) — ensure AppProvider is initialized with the correct defaultLocale so labels display in the right language.\",\n \"DO: Use the id prop to associate a <label> element with the trigger for accessible forms. The trigger already carries an aria-label from the translation key navigation.localePicker.ariaLabel, so a visible label is optional but still preferred for sighted users.\",\n \"DON'T hand-roll a locale Select with raw <select> or godx-ui Select — LocalePicker already composes the full Select + Languages icon + translated options + context wiring. Use it directly.\",\n ],\n useCases: [\n \"App shell / top-nav language switcher that persists the user's locale preference via AppProvider and localStorage without any extra state.\",\n \"Settings page 'Language' field where locale is part of a form submitted to the backend — use controlled mode: value={form.locale} onChange={(v) => form.setLocale(v)}.\",\n \"Onboarding wizard step that lets the user pick their language before the rest of the app is configured — mount with AppProvider persist={false} and a controlled value to keep state local to the wizard.\",\n \"Admin user-profile form where locale is one of several preferences (alongside timezone and date/time format) — pair with TimezonePicker, DateFormatPicker, TimeFormatPicker under the same AppProvider.\",\n \"Storybook / test harness where AppProvider is not present — render in fully controlled mode: <LocalePicker value='en' onChange={fn} />.\",\n \"Localization QA tool that cycles through locales programmatically — drive via controlled value to switch the UI language without user interaction.\",\n ],\n related: [\n \"TimezonePicker — same family, same pattern (uncontrolled via AppProvider or controlled). Pick LocalePicker for language, TimezonePicker for IANA timezone.\",\n \"DateFormatPicker — picks 'dmy' | 'mdy' | 'iso' display format. Use alongside LocalePicker in a preferences form; locale defaults the format automatically.\",\n \"TimeFormatPicker — picks '12h' | '24h'. Same composition pattern; locale defaults it. Use all four pickers together in a unified settings panel.\",\n \"AppProvider — required peer unless running in fully controlled mode. Provides the locale, setLocale, and i18n context that LocalePicker depends on.\",\n ],\n example: `{\\`// Uncontrolled — AppProvider manages state and persists to localStorage\nimport { AppProvider } from \"@godxjp/ui/providers\";\nimport { LocalePicker } from \"@godxjp/ui/navigation\";\n\nexport function AppShell() {\n return (\n <AppProvider defaultLocale=\"vi\">\n {/* Anywhere inside the tree */}\n <LocalePicker />\n </AppProvider>\n );\n}\n\n// Controlled — no AppProvider required (e.g. a standalone settings form)\nimport { useState } from \"react\";\nimport { LocalePicker } from \"@godxjp/ui/navigation\";\nimport type { AppLocale } from \"@godxjp/ui/navigation\";\n\nexport function LocaleField() {\n const [locale, setLocale] = useState<AppLocale>(\"en\");\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor=\"locale-picker\">Language</label>\n <LocalePicker id=\"locale-picker\" value={locale} onChange={setLocale} />\n </div>\n );\n}\\`}`,\n storyPath: \"navigation/LocalePicker.stories.tsx\",\n rules: [3, 5, 6, 23],\n },\n {\n name: \"TimezonePicker\",\n group: \"navigation\",\n tagline:\n \"Globe-icon Select for picking an IANA timezone — throws at runtime if neither AppProvider context nor controlled value+onChange is supplied.\",\n props: [\n {\n name: \"value\",\n type: \"AppTimezone\",\n description:\n 'Controlled IANA timezone string (e.g. \"Asia/Tokyo\", \"UTC\"). Required when used outside AppProvider; reads from AppProvider context when omitted.',\n },\n {\n name: \"onChange\",\n type: \"(timezone: AppTimezone) => void\",\n description:\n \"Change handler receiving the selected IANA id. Required when used outside AppProvider; falls back to AppProvider setTimezone when omitted.\",\n },\n {\n name: \"options\",\n type: \"readonly AppTimezone[]\",\n description:\n \"Restrict the dropdown to this list of IANA ids. Omit to inherit AppProvider timezoneOptions, or fall back to the full runtime IANA list. The current value is always injected at the top if absent from the list.\",\n },\n {\n name: \"id\",\n type: \"string\",\n description: \"HTML id forwarded to the trigger element, useful for pairing with a <label>.\",\n },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the picker trigger.\" },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"Additional Tailwind classes merged onto the SelectTrigger (default width: w-full sm:w-56).\",\n },\n ],\n usage: [\n \"DO: Wrap with <AppProvider> and omit value/onChange — the picker reads and writes context automatically. This is the canonical zero-prop usage: <TimezonePicker />.\",\n \"DO: Pass value + onChange for fully controlled standalone usage (e.g. a form field that posts the timezone string): <TimezonePicker value={tz} onChange={setTz} />. AppProvider is not required in this mode.\",\n \"DON'T: Omit BOTH AppProvider context AND controlled props — the component throws at runtime: 'TimezonePicker requires <AppProvider> or controlled value + onChange'.\",\n \"DO: Pass options={['Asia/Tokyo', 'UTC']} to restrict the list. The current value is automatically prepended if it is missing from the list, so the picker never shows an empty/invalid selection.\",\n \"DON'T: Hand-roll a timezone <select> or a custom combobox — TimezonePicker already handles locale-aware labels (translated city + GMT offset), the full IANA list, and ARIA semantics.\",\n \"NOTE: Labels are locale-aware via i18n keys (e.g. 'Japan (Tokyo)' in en, translated equivalents in vi/ja). Labels are derived from AppProvider locale; in controlled mode outside AppProvider the locale defaults to the library fallback. No extra i18n wiring is needed.\",\n ],\n useCases: [\n \"User profile / settings page: let the user pick their display timezone; pair with DateFormatPicker and TimeFormatPicker in a settings panel.\",\n \"AppProvider bootstrap: pass timezoneOptions={APP_TIMEZONE_PRESET} to AppProvider to restrict the dropdown to a curated Asia-Pacific list, then render <TimezonePicker /> anywhere in the tree.\",\n \"Multi-tenant admin: render TimezonePicker in a form that POSTs a per-organization timezone; use controlled mode (value/onChange) and submit the selected IANA string.\",\n \"Shell / top-bar: drop <TimezonePicker /> into an AppShell header or Sidebar alongside LocalePicker so users can adjust timezone globally without a full settings page.\",\n \"System-timezone default: pass defaultTimezone='system' systemTimezone='Asia/Tokyo' to AppProvider so the picker initializes to the backend timezone; users can still override it.\",\n ],\n related: [\n \"LocalePicker — sibling picker for language/locale; use alongside TimezonePicker in settings panels. Both read/write AppProvider context.\",\n \"TimeFormatPicker — picks 12h/24h clock format; same controlled/context dual-mode API.\",\n \"DateFormatPicker — picks date display format (dmy/mdy/iso); same dual-mode API.\",\n \"Select — the underlying primitive TimezonePicker is built on; use Select directly only when you need a non-timezone dropdown, not for timezone selection.\",\n ],\n example: `import { useState } from \"react\";\nimport type { AppTimezone } from \"@godxjp/ui/app\";\nimport { TimezonePicker } from \"@godxjp/ui/navigation\";\n\n// --- Controlled (no AppProvider required) ---\nexport function TimezoneField() {\n const [tz, setTz] = useState<AppTimezone>(\"Asia/Tokyo\");\n return (\n <TimezonePicker\n value={tz}\n onChange={setTz}\n options={[\"Asia/Tokyo\", \"Asia/Ho_Chi_Minh\", \"UTC\"]}\n />\n );\n}\n\n// --- Context-driven (zero props inside AppProvider) ---\nimport { AppProvider } from \"@godxjp/ui/app\";\nimport { APP_TIMEZONE_PRESET } from \"@godxjp/ui/navigation\";\n\nexport function Shell({ children }: { children: React.ReactNode }) {\n return (\n <AppProvider\n defaultLocale=\"ja\"\n fallbackLocale=\"en\"\n defaultTimezone=\"system\"\n systemTimezone=\"Asia/Tokyo\"\n timezoneOptions={APP_TIMEZONE_PRESET}\n >\n {children}\n </AppProvider>\n );\n}\n\n// Anywhere inside Shell:\n// <TimezonePicker /> ← reads/writes AppProvider context automatically`,\n storyPath: \"navigation/TimezonePicker.stories.tsx\",\n rules: [3, 5, 23, 31],\n },\n {\n name: \"DateFormatPicker\",\n group: \"navigation\",\n tagline:\n \"Locale-aware date format selector (ISO / DMY / MDY) — throws at runtime if neither AppProvider nor controlled value+onChange is provided.\",\n props: [\n {\n name: \"value\",\n type: \"AppDateFormat | undefined\",\n description:\n 'Controlled date format value. One of `\"iso\"` (yyyy-MM-dd), `\"dmy\"` (dd/MM/yyyy), or `\"mdy\"` (MM/dd/yyyy). When omitted the component reads from AppProvider context.',\n },\n {\n name: \"onChange\",\n type: \"((dateFormat: AppDateFormat) => void) | undefined\",\n description:\n \"Callback fired when the user picks a new format. When omitted the component writes back to AppProvider context via `ctx.setDateFormat`.\",\n },\n {\n name: \"className\",\n type: \"string | undefined\",\n description:\n \"Extra CSS classes merged onto the SelectTrigger. Trigger defaults to `w-full sm:w-44`.\",\n },\n {\n name: \"disabled\",\n type: \"boolean | undefined\",\n description: \"Disables the select trigger and prevents user interaction.\",\n },\n {\n name: \"id\",\n type: \"string | undefined\",\n description:\n \"HTML id forwarded to the SelectTrigger; use with a `<label htmlFor>` for accessible form binding.\",\n },\n ],\n usage: [\n \"DO wrap with `<AppProvider>` (uncontrolled) OR supply both `value` and `onChange` (controlled). Omitting both causes a runtime throw: `DateFormatPicker requires <AppProvider> or controlled value + onChange`.\",\n \"DO NOT pass `value` without `onChange` or vice-versa in controlled mode — the component falls back to context for whichever prop is missing, which produces split ownership bugs.\",\n \"DO use `id` + `<label htmlFor={id}>` for accessible form labeling; the trigger already carries an i18n `aria-label` but an explicit label wins for sighted users.\",\n 'DO NOT hand-roll a date format `<select>` — `DateFormatPicker` reads the locale from context and shows human-readable, locale-translated option labels (e.g. `\"Ngày / Tháng / Năm\"` in vi, `\"YYYY-MM-DD(年-月-日)\"` in ja). A raw select cannot do this.',\n \"When AppProvider is present and you need to react to changes globally (e.g. re-format all displayed dates), use `AppProvider`'s `onDateFormatChange` callback instead of threading `onChange` through every picker.\",\n 'The `AppDateFormat` type is `\"iso\" | \"dmy\" | \"mdy\"`. Import it from `@godxjp/ui/navigation` alongside the component (it is re-exported) — do not duplicate the string-union inline.',\n ],\n useCases: [\n \"Settings / Preferences page: let users switch how dates are displayed app-wide (place inside AppProvider, omit value/onChange and it auto-reads/writes context).\",\n \"Controlled preview panel: show the effect of a date format choice before saving — pass `value` + `onChange` to a local state and commit only on Save.\",\n \"Admin user-profile form: bind with `id` and a visible `<label>` alongside other pickers (LocalePicker, TimezonePicker, TimeFormatPicker) in a preferences card.\",\n \"Multi-entity accounting dashboard where different entities prefer different regional date conventions — render a per-entity DateFormatPicker in controlled mode, persist choice per entity.\",\n \"Onboarding wizard step: collect locale + date format + time format together before creating the user account; all four app pickers compose naturally inside a single AppProvider.\",\n \"Export/report dialog: let the user choose the date format for a CSV or PDF export independently of the global app setting — use controlled mode so the choice is scoped to the dialog.\",\n ],\n related: [\n \"LocalePicker — picks the UI language (AppLocale). Use DateFormatPicker alongside LocalePicker, not instead of it; locale affects translation strings while date format controls the display pattern.\",\n \"TimeFormatPicker — picks 12h vs 24h clock. Sister component; same AppProvider / controlled-mode contract.\",\n \"TimezonePicker — picks the IANA timezone. Same contract; also accepts an `options` prop to restrict the list.\",\n \"DatePicker — a calendar-based date input for picking a specific calendar date. Use DatePicker for data entry; use DateFormatPicker in settings to control how those dates are displayed.\",\n ],\n example: `{\\`// Uncontrolled — reads/writes AppProvider context automatically\nimport { AppProvider } from \"@godxjp/ui/navigation\";\nimport { DateFormatPicker } from \"@godxjp/ui/navigation\";\n\nexport function AppSettings() {\n return (\n <AppProvider defaultLocale=\"vi\" defaultDateFormat=\"locale\" persist>\n <div className=\"flex flex-col gap-4\">\n <label htmlFor=\"date-fmt\">Date format</label>\n <DateFormatPicker id=\"date-fmt\" />\n </div>\n </AppProvider>\n );\n}\n\n// Controlled — local state, no AppProvider required\nimport { useState } from \"react\";\nimport { DateFormatPicker } from \"@godxjp/ui/navigation\";\nimport type { AppDateFormat } from \"@godxjp/ui/navigation\";\n\nexport function ExportDialog() {\n const [fmt, setFmt] = useState<AppDateFormat>(\"iso\");\n\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor=\"export-fmt\">Export date format</label>\n <DateFormatPicker id=\"export-fmt\" value={fmt} onChange={setFmt} />\n </div>\n );\n}\\`}`,\n storyPath: \"navigation/DateFormatPicker.stories.tsx\",\n rules: [3, 5, 6, 13],\n },\n {\n name: \"TimeFormatPicker\",\n group: \"navigation\",\n tagline:\n \"Clock-format selector (12h / 24h) that reads/writes AppProvider context by default — throws if neither AppProvider nor controlled value+onChange is supplied.\",\n props: [\n {\n name: \"value\",\n type: \"AppTimeFormat | undefined\",\n description:\n \"Controlled clock format ('12h' | '24h'). If omitted the picker reads from the nearest AppProvider context.\",\n },\n {\n name: \"onChange\",\n type: \"(timeFormat: AppTimeFormat) => void | undefined\",\n description:\n \"Controlled change handler. If omitted the picker writes back to AppProvider via setTimeFormat.\",\n },\n {\n name: \"className\",\n type: \"string | undefined\",\n description:\n \"Additional CSS classes merged onto the SelectTrigger. Default width is 'w-full sm:w-44'.\",\n },\n {\n name: \"disabled\",\n type: \"boolean | undefined\",\n description: \"Disables the underlying Select control.\",\n },\n {\n name: \"id\",\n type: \"string | undefined\",\n description: \"HTML id forwarded to the SelectTrigger, useful for associating a <label>.\",\n },\n ],\n usage: [\n \"DO use inside <AppProvider> with no extra props to let it read/write the global time-format automatically: <AppProvider defaultTimeFormat='24h'><TimeFormatPicker /></AppProvider>\",\n \"DO switch to fully controlled mode when you need to manage the value yourself — supply BOTH value and onChange, or the component will throw: <TimeFormatPicker value={fmt} onChange={setFmt} />\",\n \"DON'T omit both AppProvider and controlled props — the component throws an Error at render time: 'TimeFormatPicker requires <AppProvider> or controlled value + onChange'. There is no silent fallback.\",\n \"DON'T hand-roll a time-format <select> — the locale-aware labels (e.g. '24 giờ' for vi, '24-hour' for en) are generated internally from the i18n layer; reinventing this loses those translations.\",\n \"DO wire a <label htmlFor={id}> when using the id prop for accessibility; the SelectTrigger already sets aria-label from i18n but a visible label improves discoverability.\",\n \"AppTimeFormat is exported from '@godxjp/ui/app' — import it from there for type-safe controlled state: import type { AppTimeFormat } from '@godxjp/ui/app'.\",\n ],\n useCases: [\n \"User preferences / settings panel — place alongside LocalePicker, TimezonePicker, and DateFormatPicker so users can configure their entire display environment in one block.\",\n \"AppShell top-bar or sidebar controls — the default sm:w-44 width makes it compact enough to sit inline in a toolbar without a wrapper.\",\n \"Admin dashboard that serves multiple locales (vi/ja default 24h, en defaults 12h) — AppProvider + resolveDefaultTimeFormat already handle the per-locale default, so no manual logic is needed.\",\n \"Controlled settings form where the time format is saved to a server — use value+onChange, call your API in onChange, then update state on success.\",\n \"Onboarding wizard step that collects user preferences before creating an account — use controlled mode (no AppProvider yet) and collect all picker values into a single form state.\",\n \"Multi-entity accounting app (e.g. CoreBooks) where different legal entities may have different locale settings — wrap each entity's UI subtree in its own AppProvider with the entity's persisted preferences.\",\n ],\n related: [\n \"LocalePicker (@godxjp/ui/navigation) — sibling picker for UI language; often placed adjacent to TimeFormatPicker in a preferences panel.\",\n \"TimezonePicker (@godxjp/ui/navigation) — sibling for IANA timezone selection; shares the same AppProvider context pattern.\",\n \"DateFormatPicker (@godxjp/ui/navigation) — sibling for date display format (dmy/mdy/iso); use all four together for a complete locale preferences block.\",\n \"AppProvider (@godxjp/ui/app) — required context provider when using any picker in uncontrolled mode; set defaultTimeFormat='locale' to auto-derive from the selected locale.\",\n ],\n example: `\n{\\`// Uncontrolled — reads/writes AppProvider automatically\nimport { AppProvider } from \"@godxjp/ui/app\";\nimport { TimeFormatPicker } from \"@godxjp/ui/navigation\";\n\nexport function PreferencesPanel() {\n return (\n <AppProvider defaultLocale=\"vi\" defaultTimeFormat=\"24h\" persist>\n <TimeFormatPicker />\n </AppProvider>\n );\n}\n\n// Controlled — manage value yourself (no AppProvider needed)\nimport { useState } from \"react\";\nimport type { AppTimeFormat } from \"@godxjp/ui/app\";\nimport { TimeFormatPicker } from \"@godxjp/ui/navigation\";\n\nexport function SettingsForm() {\n const [fmt, setFmt] = useState<AppTimeFormat>(\"12h\");\n return (\n <div>\n <label htmlFor=\"time-fmt\">Time format</label>\n <TimeFormatPicker id=\"time-fmt\" value={fmt} onChange={setFmt} />\n </div>\n );\n}\\`}\n`,\n storyPath: \"navigation/TimeFormatPicker.stories.tsx\",\n rules: [3, 5, 6, 13],\n },\n {\n name: \"TabsItems\",\n group: \"navigation\",\n tagline:\n \"Ant Design-style items-array tabs wrapper over Radix Tabs — pass a flat `items` array instead of composing TabsList/TabsTrigger/TabsContent by hand; first item is the default tab unless you specify otherwise.\",\n props: [\n {\n name: \"items\",\n type: \"TabItemProp[]\",\n required: true,\n description:\n \"Array of tab definitions. Each entry has: `key: string` (unique, used as the Radix value), `label: React.ReactNode` (trigger label), `children: React.ReactNode` (panel content), `disabled?: boolean`, `icon?: React.ReactNode` (rendered left of label inside the trigger).\",\n },\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled active tab key. When provided the component is fully controlled — you must also provide `onValueChange`. Do NOT combine with `defaultValue` in controlled mode.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description:\n \"Uncontrolled initial active tab key. Defaults to `items[0].key` when omitted. Ignored when `value` is provided.\",\n },\n {\n name: \"onValueChange\",\n type: \"(key: string) => void\",\n description:\n \"Callback fired when the user switches tabs. Receives the selected item's `key`. Required in controlled mode.\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"line\" | \"card\"',\n defaultValue: '\"default\"',\n description:\n \"Visual style. `default` = pill/box tabs (Radix default). `line` = underline-only tabs (border-b indicator, transparent background). `card` = card-style tabs with a subtle shadow on the active trigger.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra Tailwind classes applied to the outer Radix `Tabs` root element.\",\n },\n {\n name: \"listClassName\",\n type: \"string\",\n description:\n \"Extra classes applied to the `TabsList` wrapper (the trigger bar). Useful to control width, alignment, or border overrides.\",\n },\n {\n name: \"contentClassName\",\n type: \"string\",\n description:\n \"Extra classes applied to every `TabsContent` panel. Use for padding, min-height, or background overrides shared across all panels.\",\n },\n ],\n usage: [\n \"DO: pass a flat `items` array with unique `key` strings — TabsItems renders the full TabsList + all TabsContent panels for you. NEVER hand-compose TabsList/TabsTrigger/TabsContent inside TabsItems; they are rendered internally.\",\n \"DO: use `defaultValue` (uncontrolled) for simple local tab state. Use `value` + `onValueChange` together (controlled) when the active tab is driven by router state, query params, or parent state. DO NOT set both `value` and `defaultValue` simultaneously.\",\n \"DO: choose `variant='line'` for page-level section navigation (full-width underline style) and `variant='default'` for contained widget tabs (pill/box). `variant='card'` suits dashboard card contexts.\",\n \"DON'T: rely on tab position for the default tab — always supply `defaultValue` explicitly when the first item should not be active, or when items order may change.\",\n \"DO: use `icon` on each `TabItemProp` to prepend an icon node (e.g. a Lucide icon) inside the trigger. Icons are rendered in an inline-flex span with `mr-1.5` spacing; pass sized icon components, not raw SVG strings.\",\n \"DON'T: use TabsItems to replace a full Radix Tabs composition when you need per-panel extra attributes (e.g. `forceMount`, custom `TabsContent` event handlers) — drop down to the lower-level `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` primitives from the same import subpath.\",\n ],\n useCases: [\n \"Admin detail pages with multiple sections (Overview / Transactions / Attachments / Audit Log) where all content is known up-front and switching is purely client-side.\",\n \"Accounting invoice or journal-entry detail drawers that split metadata, line items, and comments into named tabs without needing URL routing.\",\n \"Dashboard widgets presenting the same data in different views (e.g. Chart / Table / Raw) using controlled `value` driven by a toolbar toggle.\",\n \"Settings pages with a vertical or horizontal tab strip (line variant) separating General / Notifications / Billing / Security sections.\",\n \"Entity profile pages (company, partner, employee) where each tab loads deferred or lazy content — combine with Inertia deferred props per panel.\",\n \"Any place where Ant Design-style `<Tabs items={[...]} />` would have been used — TabsItems is the direct godx-ui equivalent.\",\n ],\n related: [\n \"Tabs / TabsList / TabsTrigger / TabsContent (@godxjp/ui/navigation) — lower-level Radix primitives. Use these when you need per-panel forceMount, custom data attributes on individual panels, or full control over trigger/content rendering. TabsItems wraps these internally.\",\n \"Steps (@godxjp/ui/navigation) — sequential wizard/progress indicator. Use Steps for multi-step flows where order matters and completion state must be tracked; use TabsItems for non-sequential switchable views.\",\n \"FilterBar / FilterGroup (@godxjp/ui/navigation) — horizontal filter chip row. Use FilterBar when the 'tabs' are really dataset filters (not content panels). Visually similar to line-variant tabs but semantically and behaviourally different.\",\n ],\n example: `{\\`import { TabsItems } from \"@godxjp/ui/navigation\";\nimport { FileText, List, BarChart2 } from \"lucide-react\";\n\n// Uncontrolled — first item active by default\nexport function InvoiceDetailTabs() {\n return (\n <TabsItems\n variant=\"line\"\n items={[\n {\n key: \"overview\",\n label: \"Overview\",\n icon: <FileText size={14} />,\n children: <OverviewPanel />,\n },\n {\n key: \"line-items\",\n label: \"Line Items\",\n icon: <List size={14} />,\n children: <LineItemsTable />,\n },\n {\n key: \"analytics\",\n label: \"Analytics\",\n icon: <BarChart2 size={14} />,\n disabled: false,\n children: <AnalyticsChart />,\n },\n ]}\n />\n );\n}\n\n// Controlled — active tab driven by URL search param\nexport function ControlledTabs() {\n const [tab, setTab] = React.useState(\"overview\");\n\n return (\n <TabsItems\n variant=\"default\"\n value={tab}\n onValueChange={setTab}\n items={[\n { key: \"overview\", label: \"Overview\", children: <OverviewPanel /> },\n { key: \"history\", label: \"History\", children: <HistoryPanel /> },\n ]}\n />\n );\n}\\`}`,\n storyPath: \"navigation/TabsItems.stories.tsx\",\n rules: [3, 23, 31, 37],\n },\n {\n name: \"Menu\",\n group: \"layout\",\n tagline:\n \"A simplified sidebar-backed navigation menu — pass sections with active flags and Menu resolves the activeId automatically; never set activeId manually.\",\n props: [\n {\n name: \"items\",\n type: \"MenuSection[]\",\n required: true,\n description:\n \"Array of navigation sections. Each section has an optional label and an array of MenuItem objects. The first item with active: true becomes the active route; if none is marked the very first item is treated as active.\",\n },\n ],\n usage: [\n \"DO: set `active: true` on the single MenuItem that matches the current route — Menu derives `activeId` from this flag automatically. DON'T try to pass `activeId` (it does not exist on Menu).\",\n \"DO: supply every item with a unique `id` string — it is required by the underlying SidebarItemProp. Duplicate ids cause incorrect active/highlight state.\",\n \"DO: provide a Lucide (or compatible SVG) icon component via the `icon` field on each MenuItem. The icon is required by SidebarItemProp and will cause a render error if omitted.\",\n \"DO: nest child pages under an item using `children: SidebarItemProp[]` — this renders a collapsible submenu that auto-opens when any child is active.\",\n \"DON'T use Menu when you need to control collapse state, show a product switcher, render a custom brand slot, or attach an onSelect handler — use Sidebar directly for those scenarios.\",\n \"MenuItem extends SidebarItem so you may also pass `badge` (ReactNode), `disabled` (boolean), and `children` (nested items) on each item.\",\n ],\n useCases: [\n \"App-shell left-rail navigation where the current route is already known from the router and active state can be derived from a simple boolean flag on each item.\",\n \"Admin dashboards with a small, fixed set of top-level nav entries (Dashboard, Invoices, Settings) grouped into labelled sections (e.g. 'Accounting', 'Admin').\",\n \"Multi-section sidebars where some sections have nested child pages (e.g. Reports > Income Statement, Balance Sheet) and you want collapsible submenu groups without wiring up Sidebar manually.\",\n \"Situations where the product branding chip shown in the sidebar is purely cosmetic and does not need a real switcher — Menu hard-codes a placeholder product; use Sidebar when the product chip must be interactive or the brand slot needs a custom node.\",\n \"Rapid prototyping: quickly render a working sidebar nav by passing a flat MenuSection array without needing to understand Sidebar's full API.\",\n ],\n related: [\n \"Sidebar — the underlying component Menu wraps. Use Sidebar directly when you need: a real product/brand switcher (onProductClick, brand slot, productMenu), an onSelect handler to intercept navigation, a collapsed/rail mode toggle, or a custom footer node. Menu is a thin convenience layer on top of Sidebar that trades configurability for simplicity.\",\n \"AppShell — the page-level shell that accepts a sidebar node. Pass a Menu (or Sidebar) as its sidebar prop.\",\n \"Topbar — the horizontal bar that pairs with AppShell; not a replacement for Menu/Sidebar nav.\",\n ],\n example: `\nimport { Menu } from \"@godxjp/ui/layout\";\nimport { LayoutDashboard, FileText, Settings, Users } from \"lucide-react\";\n\nconst sections = [\n {\n label: \"Accounting\",\n items: [\n { id: \"dashboard\", label: \"Dashboard\", icon: LayoutDashboard, active: true },\n { id: \"invoices\", label: \"Invoices\", icon: FileText },\n ],\n },\n {\n label: \"Admin\",\n items: [\n {\n id: \"users\",\n label: \"Users\",\n icon: Users,\n children: [\n { id: \"users-list\", label: \"All Users\", icon: Users },\n { id: \"users-invite\", label: \"Invite\", icon: Users },\n ],\n },\n { id: \"settings\", label: \"Settings\", icon: Settings },\n ],\n },\n];\n\nexport default function AppSidebar() {\n return <Menu items={sections} />;\n}\n`,\n storyPath: \"layout/Menu.stories.tsx\",\n rules: [23],\n },\n {\n name: \"ShellApp\",\n group: \"layout\",\n tagline:\n \"Opinionated full-page shell (AppShell + a hardcoded Topbar) — use AppShell directly if you need to configure the topbar.\",\n props: [\n {\n name: \"menu\",\n type: \"ReactNode\",\n required: true,\n description:\n \"Sidebar content — pass a configured <Sidebar> component here. Rendered inside the left rail.\",\n },\n {\n name: \"breadcrumb\",\n type: \"ReactNode\",\n description:\n \"Optional breadcrumb strip rendered above the main content area, inside the app-breadcrumb div.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description:\n \"Main page content — rendered inside <main class='app-main'>. Typically a <PageContainer> or a list of page-level components.\",\n },\n ],\n usage: [\n \"DO pass a fully configured <Sidebar> (with activeId, onSelect, sections) as the `menu` prop — ShellApp only renders what you give it; it has no built-in nav state.\",\n \"DO use ShellApp when you want the default GodX Topbar (product chip 'GodX', no live search/notification handlers) and only need sidebar + breadcrumb configuration. For any custom topbar (entity switcher, real onSearchOpen, onNotificationsOpen, user slot) use <AppShell> directly with your own <Topbar> passed to its `topbar` prop.\",\n \"DO NOT nest a second shell or AppShell inside ShellApp's children — ShellApp renders the root app-root div with sidebar, header, and main; nesting shells breaks layout.\",\n \"DO NOT pass layout-wrapper divs as children expecting them to fill the full viewport — ShellApp's <main> already provides the scroll container; add padding via <PageContainer> or <PageInset> inside children.\",\n \"DO pass a <Breadcrumb> (from @godxjp/ui/layout) node to the `breadcrumb` prop for breadcrumb navigation — do not hand-roll a breadcrumb strip inside children.\",\n \"The built-in Topbar rendered by ShellApp has no-op handlers for search and notifications (both fire () => undefined). Wire those interactions by switching to AppShell + Topbar directly.\",\n ],\n useCases: [\n \"Rapid admin panel scaffolding where the default GodX branding topbar is acceptable and the only variable parts are the sidebar menu and page content.\",\n \"Internal tools and dashboards that need a consistent three-zone shell (sidebar / topbar / main) without customising the product chip or notification system.\",\n \"Prototyping or demo apps where you want a full AppShell layout with minimal boilerplate — three props (menu, children, optional breadcrumb) vs AppShell's seven.\",\n \"Multi-page Inertia SPA where the sidebar, topbar chrome, and layout are shared across all pages via a persistent layout and each page only provides its own <PageContainer> as children.\",\n ],\n related: [\n \"AppShell — the underlying primitive ShellApp wraps. Use AppShell directly when you need to supply your own <Topbar> (custom product chip, entity switcher via productMenu, real search/notification handlers, user avatar slot, rightSlot) or any of topbarLeft/topbarRight/logo/footer/sidebarCollapsed.\",\n \"Sidebar — pass as the `menu` prop; handles activeId, collapsing, section labels, nested groups with Collapsible, and collapsed popover flyouts.\",\n \"Topbar — ShellApp renders a frozen Topbar internally; import Topbar from @godxjp/ui/layout and pass it to AppShell's topbar prop when you need live handlers.\",\n \"PageContainer — the right component to use as the direct child of ShellApp to get a titled, padded page with actions/breadcrumb/footer.\",\n \"PageInset — use inside a flush PageContainer for padded strips (filter bars, intros) that sit above a full-bleed DataTable.\",\n ],\n example: `{\\`import { ShellApp, Sidebar, PageContainer, Breadcrumb } from \"@godxjp/ui/layout\";\nimport { LayoutDashboard, FileText, Settings } from \"lucide-react\";\n\nconst NAV_SECTIONS = [\n {\n items: [\n { id: \"dashboard\", label: \"Dashboard\", icon: LayoutDashboard },\n { id: \"invoices\", label: \"Invoices\", icon: FileText },\n { id: \"settings\", label: \"Settings\", icon: Settings },\n ],\n },\n];\n\nexport default function AdminLayout({ children }: { children: React.ReactNode }) {\n const [activeId, setActiveId] = React.useState(\"dashboard\");\n\n return (\n <ShellApp\n menu={\n <Sidebar\n activeId={activeId}\n onSelect={setActiveId}\n sections={NAV_SECTIONS}\n product={{ name: \"CoreBooks\", color: \"hsl(var(--attention))\" }}\n />\n }\n breadcrumb={\n <Breadcrumb items={[{ label: \"Home\", href: \"/\" }, { label: \"Dashboard\" }]} />\n }\n >\n {children}\n </ShellApp>\n );\n}\\`}`,\n storyPath: \"layout/ShellApp.stories.tsx\",\n rules: [23, 24, 31, 35],\n },\n {\n name: \"MobileFrame\",\n group: \"layout\",\n tagline:\n \"Simulated smartphone chrome (header + scrollable body + bottom nav) for handheld/PWA screens — it is a full-page layout shell, not a modal or decoration.\",\n props: [\n {\n name: \"title\",\n type: \"string\",\n required: true,\n description:\n \"Primary heading shown in the mobile header bar (e.g. page name or branch name).\",\n },\n {\n name: \"subtitle\",\n type: \"string\",\n description:\n \"Secondary line rendered beneath the title — typically a context descriptor such as location or mode.\",\n },\n {\n name: \"status\",\n type: \"string\",\n description:\n \"Domain status string rendered as a secondary Badge in the header (e.g. 'Online', 'Offline'). Omit to suppress the badge.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"Main body content rendered inside the scrollable <main> region of the frame.\",\n },\n {\n name: \"navItems\",\n type: \"MobileFrameNavItem[]\",\n defaultValue: \"[]\",\n description:\n \"Array of bottom-navigation tab descriptors. Each item has { label: string; icon: ComponentType<SVGProps<SVGSVGElement>>; active?: boolean }. The footer is only rendered when the array is non-empty. Mark exactly one item active at a time to indicate the current tab.\",\n },\n ],\n usage: [\n \"DO: Use MobileFrame as a full-page layout shell for handheld/PWA screens — wrap the entire screen content in it, not a subsection of a desktop page.\",\n \"DO: Pass lucide-react (or equivalent) icon components directly as `icon` values in navItems; the frame renders them as SVG children and adds aria-hidden automatically.\",\n \"DO: Mark the active nav item with `active: true` on exactly one navItems entry; multiple or zero active states are valid but only the first receives the active highlight.\",\n \"DO NOT: Nest MobileFrame inside PageContainer or AppShell — it is an independent shell; mixing shells breaks the layout semantics.\",\n \"DO NOT: Hand-roll a phone frame with raw divs, CSS borders and overflow — MobileFrame already owns the stage/frame/header/main/nav CSS tokens (ui-mobile-stage, ui-mobile-frame, etc.).\",\n \"DO NOT: Use MobileFrame for desktop admin pages — it renders a narrow, phone-sized canvas. Use PageContainer + AppShell for desktop screens.\",\n ],\n useCases: [\n \"Warehouse handheld scanners: a picker/packer app where staff scan barcodes on a phone — title='Tokyo scan', subtitle='Branch handheld', status='Online', navItems for Scan/Receive/Pack/Flight tabs.\",\n \"Field-agent PWA screens where the same codebase serves a desktop admin shell (AppShell) and a mobile companion app (MobileFrame) rendered at the phone viewport.\",\n \"Storybook/design-review previews of a mobile screen at realistic size — set Storybook viewport to 'mobile1' and wrap the page in MobileFrame to see the chrome.\",\n \"Prototype or demo of a consumer-facing mobile app embedded inside an admin dashboard as a live preview widget.\",\n \"Delivery dispatch or order-tracking app rendered on a handheld device where bottom-tab navigation is the primary navigation affordance.\",\n ],\n related: [\n \"AppShell — the desktop counterpart (sidebar + topbar shell); use AppShell for admin/desktop layouts, MobileFrame for handheld/phone layouts. Never nest one inside the other.\",\n \"PageContainer — the page-level content wrapper used inside AppShell for desktop pages; do not substitute for MobileFrame on mobile screens.\",\n \"ShellApp — another desktop shell variant; same rule as AppShell — mutually exclusive with MobileFrame.\",\n ],\n example: `import { Archive, CalendarClock, Package, ScanLine } from \"lucide-react\";\nimport { MobileFrame, type MobileFrameNavItem } from \"@godxjp/ui/layout\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@godxjp/ui/data-display\";\nimport { Stack } from \"@godxjp/ui/layout\";\n\nconst navItems: MobileFrameNavItem[] = [\n { label: \"Scan\", icon: ScanLine, active: true },\n { label: \"Receive\", icon: Archive },\n { label: \"Pack\", icon: Package },\n { label: \"Schedule\", icon: CalendarClock },\n];\n\nexport default function HandheldScanPage() {\n return (\n <MobileFrame\n title=\"Tokyo scan\"\n subtitle=\"Branch handheld\"\n status=\"Online\"\n navItems={navItems}\n >\n <Stack gap=\"md\">\n <Card>\n <CardHeader banded>\n <CardTitle>Last scan</CardTitle>\n </CardHeader>\n <CardContent>\n Ready to scan vendor or internal code.\n </CardContent>\n </Card>\n </Stack>\n </MobileFrame>\n );\n}`,\n storyPath: \"layout/MobileFrame.stories.tsx\",\n rules: [2, 3, 23, 24],\n },\n {\n name: \"Tooltip\",\n group: \"feedback\",\n tagline:\n \"Radix-based hover/focus tooltip — self-providing, no app-level TooltipProvider required; compose Tooltip > TooltipTrigger > TooltipContent every time.\",\n props: [\n {\n name: \"delayDuration\",\n type: \"number\",\n defaultValue: \"200\",\n description:\n \"Milliseconds of hover before the tooltip opens. Accepted on both Tooltip (per-instance) and TooltipProvider (subtree-wide override).\",\n },\n {\n name: \"open\",\n type: \"boolean\",\n description:\n \"Controlled open state. Pair with onOpenChange to drive the tooltip programmatically.\",\n },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description:\n \"Callback fired when the open state changes. Required when using controlled 'open'.\",\n },\n {\n name: \"defaultOpen\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Uncontrolled initial open state.\",\n },\n {\n name: \"disableHoverableContent\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"When true, the tooltip closes as soon as the pointer leaves the trigger (content is not hoverable). Passed through to Radix Root.\",\n },\n {\n name: \"side\",\n type: \"'top' | 'right' | 'bottom' | 'left'\",\n defaultValue: '\"top\"',\n description:\n \"On TooltipContent — preferred side for the tooltip panel. Radix flips automatically when there is not enough space.\",\n },\n {\n name: \"sideOffset\",\n type: \"number\",\n defaultValue: \"6\",\n description:\n \"On TooltipContent — pixel gap between the trigger edge and the tooltip panel.\",\n },\n {\n name: \"align\",\n type: \"'start' | 'center' | 'end'\",\n defaultValue: '\"center\"',\n description: \"On TooltipContent — alignment relative to the trigger along the cross-axis.\",\n },\n {\n name: \"alignOffset\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"On TooltipContent — pixel offset applied to the align position.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description:\n \"On TooltipContent — extra Tailwind classes merged with the built-in panel styles (z-50, max-w-xs, rounded-md, shadow-md, text-xs).\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n required: true,\n description: \"On TooltipContent — the text or JSX rendered inside the floating panel.\",\n },\n {\n name: \"asChild\",\n type: \"boolean\",\n defaultValue: \"false\",\n description:\n \"On TooltipTrigger — merges props onto the immediate child instead of wrapping with a <button>. Use when the trigger is already an interactive element.\",\n },\n ],\n usage: [\n \"DO compose the full three-part structure every time: <Tooltip> wraps <TooltipTrigger> (the element that triggers the tip) and <TooltipContent> (the floating panel). Omitting any part silently produces nothing.\",\n \"DO NOT add an app-level <TooltipProvider> — every <Tooltip> self-provides its own Radix Provider. Only add <TooltipProvider> at a subtree root when you need a shared delayDuration different from the default 200ms across many tooltips.\",\n \"DO use asChild on TooltipTrigger when the trigger is already a Button, IconButton, or other interactive element — this avoids nesting a <button> inside a <button>, which is invalid HTML and breaks keyboard focus.\",\n \"DON'T put non-interactive elements (plain <div>, <span>) as the direct TooltipTrigger child without asChild — Radix needs a focusable element for keyboard accessibility. Wrap the target in a <span tabIndex={0}> or use a Button.\",\n \"For controlled usage (e.g. programmatic show/hide or testing), pass open + onOpenChange to <Tooltip>. For typical hover/focus behaviour, leave both unset (uncontrolled).\",\n \"TooltipContent renders inside a Radix Portal appended to document.body — z-index and overflow:hidden on ancestors do NOT clip it. Use className to extend max width beyond the built-in max-w-xs if long text is expected.\",\n ],\n useCases: [\n \"Explaining an icon-only Button action (e.g. a trash icon, a copy-to-clipboard icon) in a DataTable action column — show the label on hover without cluttering the row.\",\n \"Annotating a truncated cell value in a DataTable (e.g. a long account name clipped with text-ellipsis) — reveal the full text on hover without a modal.\",\n \"Providing contextual help for a form field label or an info icon next to an accounting term (e.g. 'AR Balance' with a short definition).\",\n \"Surfacing keyboard shortcut hints next to toolbar buttons (e.g. '⌘K — open search') without adding visible text to the UI.\",\n \"Displaying a disabled Button's reason — wrap the disabled Button in a TooltipTrigger with asChild and explain why the action is unavailable.\",\n ],\n related: [\n \"Popover — use Popover (also @godxjp/ui/feedback) when the floating panel needs interactive content (forms, links, action menus) rather than read-only text. Tooltip is read-only; Popover is interactive.\",\n \"HoverCard — for rich preview cards (user profiles, link previews) that appear on hover with more complex layout. Tooltip is for short text hints only.\",\n \"Badge / StatusChip — for persistent, always-visible short labels inline with text; not hover-triggered. Use Tooltip when the hint should be hidden until hovered.\",\n ],\n example: `import {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n} from \"@godxjp/ui/feedback\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { Trash2Icon } from \"lucide-react\";\n\n// Icon-only button with tooltip label\nexport function DeleteAction() {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label=\"Delete invoice\">\n <Trash2Icon className=\"size-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">Delete invoice</TooltipContent>\n </Tooltip>\n );\n}\n\n// Controlled tooltip (e.g. force-open for a tutorial)\nexport function ControlledExample() {\n const [open, setOpen] = React.useState(false);\n return (\n <Tooltip open={open} onOpenChange={setOpen}>\n <TooltipTrigger asChild>\n <Button variant=\"outline\" onMouseEnter={() => setOpen(true)}>\n Hover me\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" sideOffset={8}>\n This is a controlled tooltip\n </TooltipContent>\n </Tooltip>\n );\n}`,\n storyPath: \"feedback/Tooltip.stories.tsx\",\n rules: [3, 6, 23, 39],\n },\n {\n name: \"PrefetchLink\",\n group: \"data-display\",\n importPath: \"@godxjp/ui/query\",\n tagline:\n \"React Router Link that fires prefetchQuery on hover/focus so detail pages feel instant — requires a TanStack Query QueryClient in context.\",\n props: [\n {\n name: \"queryKey\",\n type: \"QueryKey\",\n required: true,\n description:\n \"TanStack Query cache key for the data to prefetch. Must match the key used by the destination page's useQuery call.\",\n },\n {\n name: \"queryFn\",\n type: \"() => Promise<unknown>\",\n required: true,\n description:\n \"Fetch function passed to queryClient.prefetchQuery. Same function (or equivalent) as the one used in the destination page's useQuery.\",\n },\n {\n name: \"prefetchOn\",\n type: '\"hover\" | \"focus\" | \"both\" | \"none\"',\n defaultValue: '\"both\"',\n description:\n \"Which interaction triggers prefetching. 'both' fires on either mouseenter or focus. 'none' disables prefetching entirely (useful for conditional opt-out without unmounting the component).\",\n },\n {\n name: \"staleTime\",\n type: \"number\",\n defaultValue: \"30000\",\n description:\n \"Milliseconds before the prefetched cache entry is considered stale. Matches queryClient.prefetchQuery staleTime. Defaults to 30 s — set higher for rarely-changing data (e.g. reference tables), lower for live feeds.\",\n },\n {\n name: \"...linkProps\",\n type: \"LinkProps (react-router-dom)\",\n description:\n \"All standard React Router v6 Link props are spread through: to, replace, state, relative, reloadDocument, preventScrollReset, viewTransition, className, children, etc. onMouseEnter and onFocus are merged (your handler still fires).\",\n },\n ],\n usage: [\n \"DO: provide a queryKey that exactly matches the destination page's useQuery key — a mismatch means the prefetch populates a different cache slot and the page still loads cold.\",\n \"DO: keep queryFn lightweight and side-effect-free; it runs speculatively on hover. Avoid mutations or write operations inside queryFn.\",\n \"DO: tune staleTime to your data's freshness requirement. The default 30 s is fine for most detail views; set it lower (e.g. 5000) for real-time data or higher (e.g. 300_000) for static reference data.\",\n \"DON'T: use PrefetchLink when the destination page's data is user-specific per request (e.g. contains a nonce or CSRF token embedded in the payload) — the prefetched response may be stale or unusable.\",\n \"DON'T: hand-roll a Link + useQueryClient prefetch pattern when PrefetchLink already ships it. Using raw Link loses the hover/focus prefetch behaviour and duplicates logic.\",\n \"REQUIRES: a TanStack Query QueryClient provider (QueryClientProvider) above this component in the tree. It calls useQueryClient internally — rendering without a provider throws.\",\n ],\n useCases: [\n \"List-to-detail navigation in an accounting app: hovering an invoice row in a DataTable triggers prefetch of that invoice's detail data so the detail page renders immediately on click.\",\n \"Sidebar navigation links where the destination is a dashboard or summary page — prefetch on focus covers keyboard-only users tabbing through the nav.\",\n \"Paginated table rows where each row links to a resource detail page (partner, journal entry, account). prefetchOn='hover' avoids wasted prefetches from keyboard navigation.\",\n \"Admin list pages with 'Edit' action links: the edit form data is prefetched on hover so the form appears populated without a loading spinner.\",\n \"Breadcrumb links on deep-nested pages where clicking 'back' should feel instant — prefetch the parent page's query on mount/focus of the breadcrumb link.\",\n ],\n related: [\n \"Link (react-router-dom) — use bare Link when no prefetching is needed or when the destination has no TanStack Query data (e.g. a static page or a form page that fetches nothing on load).\",\n \"DataState — the companion lifecycle widget for the destination page; ensures PrefetchLink's prefetch is consumed correctly via useQuery.\",\n \"InfiniteQueryState — use instead of PrefetchLink when the list itself is infinitely paginated and items are loaded lazily rather than navigated to.\",\n \"QueryRefetchButton — for triggering a manual cache refresh on an already-loaded page, not for navigation prefetching.\",\n ],\n example: `import { PrefetchLink } from \"@godxjp/ui/query\";\nimport { fetchInvoice } from \"@/api/invoices\";\n\n// Inside a table row or list item:\n<PrefetchLink\n to={\\`/invoices/\\${invoice.id}\\`}\n queryKey={[\"invoice\", invoice.id]}\n queryFn={() => fetchInvoice(invoice.id)}\n staleTime={60_000}\n className=\"font-medium hover:underline\"\n>\n {invoice.number}\n</PrefetchLink>\n\n// Disable prefetch for rows where data is not yet stable:\n<PrefetchLink\n to={\\`/invoices/\\${invoice.id}\\`}\n queryKey={[\"invoice\", invoice.id]}\n queryFn={() => fetchInvoice(invoice.id)}\n prefetchOn=\"none\"\n>\n {invoice.number}\n</PrefetchLink>`,\n storyPath: \"data-display/PrefetchLink.stories.tsx\",\n rules: [2, 3, 31],\n },\n {\n name: \"QueryRefetchButton\",\n group: \"data-display\",\n importPath: \"@godxjp/ui/query\",\n tagline:\n \"Page-header Refresh button wired directly to a TanStack Query result — auto-disables and spins while fetching; never pass onClick or disabled yourself.\",\n props: [\n {\n name: \"query\",\n type: \"Pick<UseQueryResult<unknown>, 'isFetching' | 'refetch'>\",\n required: true,\n description:\n \"The TanStack Query result object. The button calls query.refetch() on click and is disabled while query.isFetching is true. Pass the full useQuery result; only isFetching and refetch are consumed.\",\n },\n {\n name: \"label\",\n type: \"React.ReactNode\",\n defaultValue: '\"Refresh\"',\n description: \"Text label rendered inside the button. Ignored when children is provided.\",\n },\n {\n name: \"children\",\n type: \"React.ReactNode\",\n description:\n \"If provided, overrides label. Use for custom label content (e.g. translated strings, icons).\",\n },\n {\n name: \"variant\",\n type: \"ButtonProp['variant']\",\n defaultValue: '\"outline\"',\n description: \"Visual variant forwarded to the underlying Button primitive.\",\n },\n {\n name: \"size\",\n type: \"ButtonProp['size']\",\n defaultValue: '\"sm\"',\n description: \"Size forwarded to the underlying Button primitive.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Additional CSS classes applied to the Button root.\",\n },\n ],\n usage: [\n \"DO pass the raw useQuery result directly — the component only reads isFetching and refetch, so any UseQueryResult shape is safe: `<QueryRefetchButton query={invoicesQuery} />`\",\n \"DON'T pass onClick or disabled — both are owned by QueryRefetchButton and forwarded internally. They are omitted from the prop type (Omit<ButtonProp, 'onClick' | 'disabled'>) so TypeScript will reject them at compile time.\",\n \"DON'T use this for mutation triggers — it is wired to query.refetch(), not a mutation. For mutation actions use a plain Button + useMutation.\",\n \"DO place it in a page header or toolbar beside a title — it renders as size='sm' variant='outline' by default, matching header action patterns.\",\n \"The RefreshCw icon is always rendered automatically with a spin animation driven by data-fetching={query.isFetching} — do NOT add your own icon or loading spinner.\",\n \"For i18n, pass a translated string as label or children: `<QueryRefetchButton query={q} label={t('refresh')} />` — the default label is the English string 'Refresh'.\",\n ],\n useCases: [\n \"Toolbar 'Refresh' button on an invoice list page that re-fetches from the server without a full navigation.\",\n \"Dashboard header action that re-polls live financial summaries when the user wants fresh data.\",\n \"Admin data table header where stale data is a concern and users need manual control over re-fetching.\",\n \"Any page using useQuery where you want a consistent, accessible Refresh affordance without wiring up onClick/disabled logic manually.\",\n \"Pairing with DataState or a DataTable — place QueryRefetchButton in the page header while DataState manages the content area lifecycle.\",\n ],\n related: [\n \"DataState — use DataState (not QueryRefetchButton) to handle the full query lifecycle (pending/error/empty/data states) in the content area; QueryRefetchButton is only the header action button.\",\n \"InfiniteQueryState — for infinite-scroll / load-more lists; has its own refetch wiring; QueryRefetchButton is redundant alongside it.\",\n \"MutationFeedback — for displaying mutation errors and a retry action; do not use QueryRefetchButton for mutation retries.\",\n \"Button — the raw primitive; use Button directly when you need custom onClick logic or are not wired to a TanStack Query result.\",\n ],\n example: `{\\`import { useQuery } from \"@tanstack/react-query\";\nimport { QueryRefetchButton } from \"@godxjp/ui/query\";\n\nexport function InvoiceListHeader() {\n const invoicesQuery = useQuery({\n queryKey: [\"invoices\"],\n queryFn: fetchInvoices,\n });\n\n return (\n <div className=\"flex items-center justify-between\">\n <h1 className=\"text-xl font-semibold\">Invoices</h1>\n <QueryRefetchButton query={invoicesQuery} label=\"Refresh\" />\n </div>\n );\n}\\`}`,\n storyPath: \"data-display/QueryRefetchButton.stories.tsx\",\n rules: [3, 5, 6, 13],\n },\n];\n\nexport function findComponent(name: string): ComponentEntry | undefined {\n const normalized = name.trim().toLowerCase();\n return COMPONENTS.find((c) => c.name.toLowerCase() === normalized);\n}\n\nexport function componentsByGroup(group: ComponentGroup): ComponentEntry[] {\n return COMPONENTS.filter((c) => c.group === group);\n}\n\nexport function searchComponents(query: string): ComponentEntry[] {\n const q = query.trim().toLowerCase();\n if (q === \"\") {\n return COMPONENTS;\n }\n return COMPONENTS.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.group.includes(q) ||\n c.tagline.toLowerCase().includes(q) ||\n c.props.some((p) => p.name.toLowerCase().includes(q)),\n );\n}\n","/**\n * Shared prop-vocabulary catalog — mirrors `src/props/` in the\n * framework. Consumers reach for this to know the canonical value\n * unions before authoring a new primitive or a wrapper.\n *\n * See also: `docs/specs/04-prop-vocabulary.md` (the rule) +\n * `docs/specs/06-prop-vocabulary-audit.md` (the audit findings).\n */\n\nexport interface PropVocabEntry {\n /** Canonical type name (matches `src/props/{file}.ts`). */\n name: string;\n /** Concept the union represents. */\n concept: string;\n /** Literal values. */\n values: string[];\n /** Primitives that use this exact vocabulary (or alias to it). */\n usedBy: string[];\n /** Optional notes (subtypes, related aliases, gotchas). */\n notes?: string;\n}\n\nexport const PROP_VOCABULARY: PropVocabEntry[] = [\n {\n name: \"SizeProp\",\n concept: \"Dimensional scale for most primitives.\",\n values: [\"small\", \"default\", \"large\"],\n usedBy: [\n \"InputSize\", \"CheckboxGroupSize\", \"ColorPickerSize\", \"MediaUploadSize\",\n \"ProgressSize\", \"RadioGroupSize\", \"RateSize\", \"TransferSize\",\n \"SegmentedControlSize (subset)\", \"SpaceSize (+ number)\",\n \"FlexGap (+ number)\", \"GridGap (+ number)\", \"MasonryGap (+ number)\",\n ],\n },\n {\n name: \"SizeWithXSProp\",\n concept: 'Extension of `SizeProp` with `\"x-small\"` for compact icon-bar / table-row contexts.',\n values: [\"x-small\", \"small\", \"default\", \"large\"],\n usedBy: [\"ButtonSize\"],\n },\n {\n name: \"IconSizeProp\",\n concept: \"Icon-symbol shaped primitives (visual axis = glyph size, not height).\",\n values: [\"sm\", \"md\", \"lg\"],\n usedBy: [\"SpinnerSize\", \"IconButtonSize\"],\n },\n {\n name: \"StatusProp\",\n concept: \"Form-field validation state.\",\n values: [\"default\", \"error\", \"warning\", \"success\"],\n usedBy: [\"InputStatus\"],\n notes: 'Form errors use `\"error\"` (not `\"destructive\"`) — different concern from destructive actions.',\n },\n {\n name: \"ToneProp\",\n concept: \"Same values as StatusProp — name chosen when describing surface colouring rather than validation.\",\n values: [\"default\", \"error\", \"warning\", \"success\"],\n usedBy: [\"(alias of StatusProp)\"],\n },\n {\n name: \"HelpToneProp\",\n concept: \"Help-line / Alert colour ladder. Adds `info` + `warn` to StatusProp.\",\n values: [\"default\", \"info\", \"warn\", \"error\", \"success\"],\n usedBy: [\"FieldHelpTone\"],\n },\n {\n name: \"OrientationProp\",\n concept: \"Layout axis.\",\n values: [\"horizontal\", \"vertical\"],\n usedBy: [\n \"AnchorOrientation\", \"MenuOrientation\", \"RadioGroupOrientation\",\n \"CheckboxGroupOrientation\", \"SegmentedControlOrientation\",\n \"StepsOrientation\", \"TabsOrientation\",\n ],\n },\n {\n name: \"DensityProp\",\n concept: \"Internal row-height / padding scale (distinct from SizeProp — density rescales chrome, size rescales the primitive's own visual axis).\",\n values: [\"compact\", \"default\", \"comfortable\"],\n usedBy: [\"TreeDensity\", \"TableDensity\"],\n },\n {\n name: \"SideProp\",\n concept: \"Edge a floating panel docks against.\",\n values: [\"top\", \"right\", \"bottom\", \"left\"],\n usedBy: [\"SheetSide\", \"TabsPlacement\", \"TableStickySide (subset)\"],\n },\n {\n name: \"PlacementProp\",\n concept: \"Extension of SideProp with a centred anchor (Tabs placement, Tour spotlight).\",\n values: [\"top\", \"right\", \"bottom\", \"left\", \"center\"],\n usedBy: [\"TourPlacement\"],\n },\n {\n name: \"PaddingProp\",\n concept: \"Outer gutter scale for surface containers.\",\n values: [\"tight\", \"default\", \"cozy\", \"none\"],\n usedBy: [\"CardPadding\", \"PageHeaderPadding\", \"PageContentPadding\"],\n },\n {\n name: \"AlignProp\",\n concept: \"CSS-flexbox cross-axis alignment ladder.\",\n values: [\"start\", \"end\", \"center\", \"stretch\", \"baseline\"],\n usedBy: [\"FlexAlign\"],\n },\n {\n name: \"ColorProp\",\n concept: \"Full semantic palette — every CSS variable slot.\",\n values: [\"default\", \"info\", \"success\", \"warning\", \"destructive\", \"attention\", \"primary\", \"secondary\"],\n usedBy: [\"TagPresetColor (− secondary)\", \"TimelineColor (− secondary)\", \"SpinnerTone (+ muted)\"],\n notes:\n 'Each value maps 1:1 to a CSS variable (`--info`, `--success`, `--warning`, `--destructive`, `--attention`, `--primary`, `--secondary`). The `data-accent` axis rebinds `--primary`\\'s hue without renaming the slot.',\n },\n {\n name: \"FeedbackColorProp\",\n concept: \"Subset of ColorProp accepted by feedback primitives (no brand `primary` since they are themselves informational).\",\n values: [\"default\", \"info\", \"success\", \"warning\", \"destructive\"],\n usedBy: [\"AlertColor\", \"ResultColor\", \"ProgressColor\"],\n },\n {\n name: \"LoadingProp\",\n concept: \"Loading-state union — shared across Form / FormField / data-entry primitives.\",\n values: [\"true\", \"false\", '{ kind: \"spinner\" }', '{ kind: \"skeleton\" }', '{ kind, label }'],\n usedBy: [\"FormProps.loading\", \"FormFieldProps.loading\"],\n notes:\n 'Cascade: `<Form loading>` sets a default for every nested `<FormField>`. Per-field `loading` overrides Form\\'s. `true` → spinner (default). `{ kind: \"skeleton\" }` → use for INITIAL fetch state. UX nuance: skeleton on init, spinner on save.',\n },\n];\n\nexport function findVocab(name: string): PropVocabEntry | undefined {\n const normalized = name.trim().toLowerCase().replace(/prop$/i, \"\");\n return PROP_VOCABULARY.find(\n (v) => v.name.toLowerCase().replace(/prop$/i, \"\") === normalized,\n );\n}\n","/**\n * Design tokens catalog — mirrors `src/tokens/tailwind.css` +\n * `src/styles/theme.css` in the framework. CSS variable name +\n * the slot's role + (for fixed values) the literal value.\n *\n * Token values that change per `data-theme` / `data-accent` /\n * `data-density` / `data-font-size` axis are NOT listed with a\n * literal — only the slot name + axis name. Consumers read the\n * runtime value via `getComputedStyle(:root).getPropertyValue(...)`.\n */\n\nexport type TokenCategory =\n | \"color\"\n | \"spacing\"\n | \"typography\"\n | \"radius\"\n | \"shadow\"\n | \"motion\"\n | \"breakpoint\"\n | \"density\"\n | \"z-index\";\n\nexport interface TokenEntry {\n name: string;\n category: TokenCategory;\n role: string;\n /** Fixed value if non-axis. Otherwise omitted. */\n value?: string;\n /** Axis the token re-binds against, if any. */\n axis?: \"data-theme\" | \"data-accent\" | \"data-density\" | \"data-font-size\";\n}\n\nexport const TOKENS: TokenEntry[] = [\n // Color — semantic slots (rebound by `data-theme` + `data-accent`)\n { name: \"--background\", category: \"color\", role: \"Base surface\", axis: \"data-theme\" },\n { name: \"--foreground\", category: \"color\", role: \"Base text\", axis: \"data-theme\" },\n { name: \"--card\", category: \"color\", role: \"Card surface\", axis: \"data-theme\" },\n { name: \"--popover\", category: \"color\", role: \"Popover / dropdown surface\", axis: \"data-theme\" },\n { name: \"--popover-foreground\", category: \"color\", role: \"Popover text\", axis: \"data-theme\" },\n { name: \"--primary\", category: \"color\", role: \"Brand accent (Buttons, links)\", axis: \"data-accent\" },\n { name: \"--primary-foreground\", category: \"color\", role: \"Text on primary surface\", axis: \"data-accent\" },\n { name: \"--secondary\", category: \"color\", role: \"Secondary surface / text dimming\", axis: \"data-theme\" },\n { name: \"--accent\", category: \"color\", role: \"Hover / focus tint\" },\n { name: \"--muted\", category: \"color\", role: \"Muted surface\" },\n { name: \"--muted-foreground\", category: \"color\", role: \"Muted text\" },\n { name: \"--border\", category: \"color\", role: \"Default border color\", axis: \"data-theme\" },\n { name: \"--input\", category: \"color\", role: \"Input field border\" },\n { name: \"--ring\", category: \"color\", role: \"Focus ring\", axis: \"data-accent\" },\n { name: \"--success\", category: \"color\", role: \"Success semantic slot\" },\n { name: \"--warning\", category: \"color\", role: \"Warning semantic slot\" },\n { name: \"--destructive\", category: \"color\", role: \"Danger / destructive action slot\" },\n { name: \"--info\", category: \"color\", role: \"Info / neutral notice slot\" },\n { name: \"--attention\", category: \"color\", role: \"Attention / non-destructive alert slot\" },\n\n // Spacing — fixed scale\n { name: \"--spacing-1\", category: \"spacing\", role: \"4px\", value: \"0.25rem\" },\n { name: \"--spacing-2\", category: \"spacing\", role: \"8px\", value: \"0.5rem\" },\n { name: \"--spacing-3\", category: \"spacing\", role: \"12px\", value: \"0.75rem\" },\n { name: \"--spacing-4\", category: \"spacing\", role: \"16px\", value: \"1rem\" },\n { name: \"--spacing-5\", category: \"spacing\", role: \"20px\", value: \"1.25rem\" },\n { name: \"--spacing-6\", category: \"spacing\", role: \"24px\", value: \"1.5rem\" },\n { name: \"--spacing-8\", category: \"spacing\", role: \"32px\", value: \"2rem\" },\n\n // Typography — fixed scale\n { name: \"--text-2xs\", category: \"typography\", role: \"10px\", value: \"0.625rem\" },\n { name: \"--text-xs\", category: \"typography\", role: \"12px\", value: \"0.75rem\" },\n { name: \"--text-sm\", category: \"typography\", role: \"14px\", value: \"0.875rem\" },\n { name: \"--text-base\", category: \"typography\", role: \"16px\", value: \"1rem\" },\n { name: \"--text-lg\", category: \"typography\", role: \"18px\", value: \"1.125rem\" },\n { name: \"--text-xl\", category: \"typography\", role: \"20px\", value: \"1.25rem\" },\n { name: \"--text-2xl\", category: \"typography\", role: \"24px\", value: \"1.5rem\" },\n { name: \"--font-mono\", category: \"typography\", role: \"Monospace stack\" },\n\n // Radius — fixed scale\n { name: \"--radius-sm\", category: \"radius\", role: \"Small (chips, inputs)\", value: \"0.25rem\" },\n { name: \"--radius-md\", category: \"radius\", role: \"Medium (cards)\", value: \"0.5rem\" },\n { name: \"--radius-lg\", category: \"radius\", role: \"Large (dialogs)\", value: \"0.75rem\" },\n { name: \"--radius-full\", category: \"radius\", role: \"Pill / circle\", value: \"9999px\" },\n\n // Breakpoints — mobile-first min-widths\n { name: \"--breakpoint-xs\", category: \"breakpoint\", role: \"Mobile-first base (≥0px)\", value: \"0\" },\n { name: \"--breakpoint-sm\", category: \"breakpoint\", role: \"Phone landscape / tablet portrait\", value: \"640px\" },\n { name: \"--breakpoint-md\", category: \"breakpoint\", role: \"Tablet landscape\", value: \"768px\" },\n { name: \"--breakpoint-lg\", category: \"breakpoint\", role: \"Laptop\", value: \"1024px\" },\n { name: \"--breakpoint-xl\", category: \"breakpoint\", role: \"Desktop\", value: \"1280px\" },\n { name: \"--breakpoint-xxl\", category: \"breakpoint\", role: \"Wide desktop\", value: \"1536px\" },\n\n // Density — rebound by `data-density`\n { name: \"--density-element\", category: \"density\", role: \"Element height (Input/Button)\", axis: \"data-density\" },\n { name: \"--density-element-sm\", category: \"density\", role: \"Small element\", axis: \"data-density\" },\n { name: \"--density-element-lg\", category: \"density\", role: \"Large element\", axis: \"data-density\" },\n { name: \"--density-card\", category: \"density\", role: \"Card padding\", axis: \"data-density\" },\n { name: \"--density-page\", category: \"density\", role: \"Page (PageContent) padding\", axis: \"data-density\" },\n { name: \"--density-section\", category: \"density\", role: \"Section padding (cozy variant)\", axis: \"data-density\" },\n { name: \"--header-height\", category: \"density\", role: \"Topbar height\", axis: \"data-density\" },\n { name: \"--sidebar-width\", category: \"density\", role: \"Sidebar width (expanded)\", axis: \"data-density\" },\n { name: \"--sidebar-width-collapsed\", category: \"density\", role: \"Sidebar icon-only width\", axis: \"data-density\" },\n { name: \"--touch-target-min\", category: \"density\", role: \"Mobile touch target (does NOT scale)\", value: \"44px\" },\n\n // Motion — fixed timings\n { name: \"--transition-base\", category: \"motion\", role: \"Standard transition duration\", value: \"200ms\" },\n { name: \"--ease-out\", category: \"motion\", role: \"Out easing curve\", value: \"cubic-bezier(0, 0, 0.2, 1)\" },\n { name: \"--ease-in-out\", category: \"motion\", role: \"In-out easing\", value: \"cubic-bezier(0.4, 0, 0.2, 1)\" },\n];\n\nexport function tokensByCategory(category: TokenCategory): TokenEntry[] {\n return TOKENS.filter((t) => t.category === category);\n}\n","/**\n * Cardinal rules — mirrors the cardinal rules in `CLAUDE.md`. The MCP\n * server exposes them via `get_cardinal_rules` so consumer agents\n * can quote them when reviewing PRs or authoring new primitives.\n */\n\nexport interface CardinalRule {\n number: number;\n title: string;\n body: string;\n}\n\nexport const CARDINAL_RULES: CardinalRule[] = [\n { number: 1, title: \"Storybook is mandatory\", body: \"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark.\" },\n { number: 2, title: \"Tokens, not utilities\", 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. (ADR-0003)\" },\n { number: 3, title: \"Radix for interactive primitives\", body: \"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)\" },\n { number: 4, title: \"shadcn-style ownership\", body: \"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)\" },\n { number: 5, title: \"One i18next singleton\", body: \"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)\" },\n { number: 6, title: \"WCAG 2.1 AA baseline\", 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.\" },\n { number: 7, title: \"SemVer 2.0 + Keep a Changelog 1.1\", body: \"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR.\" },\n { number: 8, title: \"Inclusive naming\", body: \"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced.\" },\n { number: 9, title: \"No marketing speak\", body: 'Banned: \"powerful\", \"robust\", \"blazing fast\", \"best-in-class\", \"seamless\", \"enterprise-grade\". State what it does.' },\n { number: 10, title: \"English is canonical for docs\", body: \"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness.\" },\n { number: 11, title: \"Submodule discipline\", body: \"Two-PR workflow: (1) submodule PR → `main`, (2) umbrella PR → bump pin. Never push a pin to a SHA not on the submodule remote.\" },\n { number: 12, title: \"Branch + PR workflow\", body: \"`feat/<scope>` / `fix/<scope>` → submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden.\" },\n { number: 13, title: \"TypeScript strict\", body: \"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link.\" },\n { number: 14, title: \"Every third-party library is shadcn / Radix-recommended\", 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.\" },\n { number: 15, title: \"No `@apply` re-encoding tokens\", 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.\" },\n { number: 16, title: \"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`\", body: \"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it.\" },\n { number: 17, title: \"`src/stories/` ↔ `src/components/` parity\", body: \"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`.\" },\n { number: 18, title: \"`docs/reference/<group>/` ↔ `src/components/<group>/` parity\", body: \"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`.\" },\n { number: 19, title: \"No service-specific anything\", body: \"`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent=\\\"<palette>\\\"]`.\" },\n { number: 20, title: \"No \\\"platform-only\\\" exports\", body: \"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported.\" },\n { number: 21, title: \"Every component honours every theme axis\", 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. Verify every PR via the Storybook toolbar sweep.\" },\n { number: 22, title: \"100% match to the design canon\", 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.' },\n { number: 23, title: \"Concept-first prop API\", 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.\" },\n { number: 24, title: \"Mobile-first\", 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.\" },\n { number: 25, title: \"Stories are docs; UI is the primitive\", 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.\" },\n { number: 26, title: \"Library isolation\", 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/`.\" },\n { number: 27, title: \"Per-group folder structure\", 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.\" },\n { number: 28, title: \"`src/` folder taxonomy\", 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.\" },\n { number: 29, title: \"Stories consume framework primitives only\", 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.\" },\n { number: 30, title: \"Story `render` returns JSX directly\", 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 />`.\" },\n { number: 31, title: \"No nested wrapper / convenience primitives\", 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.\" },\n { number: 32, title: \"No redundant props\", 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.\" },\n { number: 33, title: \"Stories / source / docs name-synchronized\", 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). Rename PR runs `grep -rn '<oldName>' src docs` and clears it.\" },\n { number: 34, title: \"Storybook source panel = real, copy-paste-ready code\", 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 (`StatusBadge`, `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>`). The exemplar is `Table.Default` in `src/stories/data-display/Table.stories.tsx`.\" },\n { number: 35, title: \"Status chips never wrap\", body: \"A `StatusBadge` / `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.\" },\n { number: 36, title: \"StatusBadge tone/icon are the colour escape hatch\", body: \"`StatusBadge` auto-maps a fixed set of English lifecycle keys (active, draft, pending, scheduled, cancelled, failed, …) to tone + icon. 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.\" },\n { number: 37, title: \"DataTable is full-width — never inside a narrow grid column\", 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.)\" },\n { number: 38, title: \"FilterBar stays OUT of CardContent flush\", 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.\" },\n { number: 39, title: \"Long text columns get an explicit width\", 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.\" },\n { number: 40, title: \"Pages are mobile-first\", body: \"Author and verify every page at 320–390px FIRST. Spacing comes only from `Stack` / `Inline` `gap` + `ResponsiveGrid columns={2|3|4}` (which collapse to a single column on narrow screens) — never raw `p-*` / `gap-*` / `space-*` utilities for page layout. Wide tables scroll horizontally on small screens (don't force-fit them); dialogs and sheets are full-height on mobile. Touch targets ≥ 44×44px.\" },\n];\n\nexport function findRule(num: number): CardinalRule | undefined {\n return CARDINAL_RULES.find((r) => r.number === num);\n}\n","/**\n * Canonical code patterns for common consumer scenarios. The MCP\n * server returns one of these whenever a consumer asks \"how do I X\n * with @godxjp/ui?\" — saves the LLM from synthesising from primitive\n * docs over and over.\n *\n * Every pattern is copy-paste-ready: imports listed at top, types\n * spelled out, inline JSX with no opaque helpers.\n */\n\nexport interface PatternEntry {\n /** URL-safe slug. */\n name: string;\n /** One-line elevator pitch. */\n tagline: string;\n /** Categories — used for search. */\n tags: string[];\n /** Full snippet. */\n code: string;\n}\n\nexport const PATTERNS: PatternEntry[] = [\n {\n name: \"common-fixes\",\n tagline: \"Fix the most common @godxjp/ui consumer mistakes & visual bugs (CardStat double-border, grey StatusBadge, crushed/empty table headers, washed-out sidebar footer, Inertia layout crash, SSR hydration). Before → after.\",\n tags: [\"fixes\", \"migration\", \"bug\", \"cardstat\", \"statusbadge\", \"datatable\", \"sidebar\", \"gotcha\", \"review\"],\n code: `// ───────────────────────────────────────────────────────────────────────\n// 0) ★ MOST COMMON: <Card> body has NO padding (content is flush against the edges)\n// Cause: the bare <Card> has ZERO inner padding — it MUST contain <CardContent>.\n// Don't hand-roll padding with className=\"p-4\" on the Card either.\n// ❌ <Card><Stack gap=\"md\">…fields…</Stack></Card> // flush, no padding\n// ❌ <Card className=\"p-4\">…fields…</Card> // hand-rolled padding\n// ✅ <Card><CardContent><Stack gap=\"md\">…fields…</Stack></CardContent></Card>\n// Titles → <CardHeader><CardTitle>. Only go flush deliberately for a full-bleed table:\n// ✅ <Card><CardContent flush><DataTable/></CardContent></Card>\n// GENERAL RULE — compose godx-ui primitives FULLY; never hand-roll what one ships:\n// padding → CardContent (not p-4) · controls → Input/Select/Button (not raw <input>/<select>/<button>)\n// empty rows → DataTable's built-in empty / <EmptyState> (not a custom data.length===0 guard).\n// If a primitive exists, USE it — don't reinvent it.\n\n// 1) CardStat shows a DOUBLE border (too thick)\n// Cause: CardStat IS already a bordered Card. Don't wrap it.\n// ❌ <Card><CardContent><CardStat label=\"x\" value=\"1\" /></CardContent></Card>\n// ✅ <ResponsiveGrid columns={4}><CardStat label=\"x\" value=\"1\" /></ResponsiveGrid>\n// Need a section title? Use a heading, NOT a Card:\n// ✅ <Stack gap=\"sm\"><div className=\"text-sm font-medium\">KPI</div>\n// <ResponsiveGrid columns={4}><CardStat .../></ResponsiveGrid></Stack>\n\n// 2) StatusBadge renders grey with a ○ (no colour) for localized/tier labels\n// Cause: it auto-maps only English lifecycle keys. (@godxjp/ui >= 6.1)\n// ❌ <StatusBadge status=\"プレミアム\" />\n// ✅ <StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} /> // tier → pill, no icon\n// ✅ <StatusBadge status=\"active\" label=\"公開中\" /> // lifecycle → keep icon\n\n// 3) Table text collapses to one char per line, or a chip wraps\n// Cause: pre-6.1.2. (@godxjp/ui >= 6.1.2 → cells + chips are nowrap)\n// ✅ npm i @godxjp/ui@^6.2.0\n// ✅ give long columns a width: { key: \"name\", header: \"氏名\", width: \"w-64\" }\n\n// 4) Empty (icon/action) column header shows a blank grey block\n// (@godxjp/ui >= 6.2.0 auto-hides it: [data-slot=table-head][data-empty] → transparent)\n// ✅ npm i @godxjp/ui@^6.2.0 // header: \"\" now renders a transparent cell\n\n// 5) DataTable columns are crushed / squeezed\n// Cause: the table is nested in a narrow grid column.\n// ❌ <ResponsiveGrid columns={3}><div className=\"lg:col-span-2\"><Card><DataTable/></Card></div></ResponsiveGrid>\n// ✅ Table gets its OWN full-width row: <Card><CardContent flush><DataTable/></CardContent></Card>\n\n// 6) FilterBar has no padding (sticks to the edge)\n// Cause: it's inside CardContent flush (flush strips padding — that's for tables).\n// ❌ <Card><CardContent flush><FilterBar/><DataTable/></CardContent></Card>\n// ✅ <FilterBar/> then <Card><CardContent flush><DataTable/></CardContent></Card>\n\n// 7) Sidebar footer looks washed-out / off-design\n// Cause: raw opacity-*/text-[11px]. Use semantic tokens.\n// ✅ <div className=\"text-muted-foreground text-xs\">\n// <div className=\"text-foreground font-medium\">{name}</div><div>{role}</div></div>\n\n// 8) Inertia: \"Objects are not valid as a React child {errors, auth, …}\"\n// Cause: persistent layout passed as a render fn. Use the ARRAY form.\n// ❌ Page.layout = (page) => <Layout>{page}</Layout>\n// ✅ Page.layout = [Layout] // Layout is ({children}) => ...\n\n// 9) Inertia v3 hydration mismatch (\"server rendered text didn't match the client\")\n// Cause: Math.random()/argless new Date() during render (SSR ≠ client).\n// ✅ seed deterministically by index, or compute in an event handler.\n\n// 10) Hide a column on mobile / sign-aware KPI delta (@godxjp/ui >= 6.2.0)\n// ✅ columns: [{ key: \"email\", header: \"メール\", hiddenOnMobile: true }]\n// ✅ <CardStat label=\"売上\" value=\"¥8.2M\" delta=\"+12%\" /> // + green / - red; inverse flips`,\n },\n\n {\n name: \"signup-form\",\n tagline: \"Card-wrapped sign-up form using react-hook-form + zod with FormField/Input and a CardFooter action bar (real @godxjp/ui API).\",\n tags: [\"form\", \"auth\", \"sign-up\", \"zod\", \"validation\", \"react-hook-form\"],\n code: `import { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { z } from \"zod\";\nimport { Card, CardHeader, CardTitle, CardContent, CardFooter } from \"@godxjp/ui/data-display\";\nimport { FormField, Input } from \"@godxjp/ui/data-entry\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { Stack } from \"@godxjp/ui/layout\";\n\nconst schema = z.object({\n name: z.string().min(1, \"氏名は必須です\"),\n email: z.string().email(\"有効なメールアドレスを入力してください\"),\n});\ntype Values = z.infer<typeof schema>;\n\nexport function SignUpCard() {\n const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<Values>({ resolver: zodResolver(schema) });\n const onSubmit = handleSubmit(async (v) => {\n await fetch(\"/api/signup\", { method: \"POST\", body: JSON.stringify(v) });\n });\n return (\n <Card>\n <CardHeader><CardTitle>アカウント作成</CardTitle></CardHeader>\n <CardContent>\n <form id=\"signup\" onSubmit={onSubmit}>\n <Stack gap=\"md\">\n <FormField id=\"name\" label=\"氏名\" required error={errors.name?.message}>\n <Input id=\"name\" {...register(\"name\")} />\n </FormField>\n <FormField id=\"email\" label=\"メールアドレス\" required error={errors.email?.message}>\n <Input id=\"email\" type=\"email\" {...register(\"email\")} />\n </FormField>\n </Stack>\n </form>\n </CardContent>\n <CardFooter separated>\n <Button type=\"submit\" form=\"signup\" disabled={isSubmitting}>アカウントを作成</Button>\n </CardFooter>\n </Card>\n );\n}`,\n },\n\n {\n name: \"settings-tabs\",\n tagline: \"Sectioned settings inside a Card with Tabs + FormField + Select + Switch (real @godxjp/ui API).\",\n tags: [\"settings\", \"form\", \"tabs\", \"admin\"],\n code: `import { Card, CardContent } from \"@godxjp/ui/data-display\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@godxjp/ui/navigation\";\nimport { FormField, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch, Label } from \"@godxjp/ui/data-entry\";\nimport { Stack } from \"@godxjp/ui/layout\";\n\nexport function WorkspaceSettings() {\n return (\n <Card>\n <CardContent>\n <Tabs defaultValue=\"general\">\n <TabsList>\n <TabsTrigger value=\"general\">基本情報</TabsTrigger>\n <TabsTrigger value=\"notify\">通知</TabsTrigger>\n </TabsList>\n <TabsContent value=\"general\">\n <Stack gap=\"md\">\n <FormField id=\"ws-name\" label=\"名前\" required><Input id=\"ws-name\" /></FormField>\n <FormField id=\"visibility\" label=\"公開範囲\">\n <Select defaultValue=\"internal\">\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"private\">プライベート</SelectItem>\n <SelectItem value=\"internal\">社内公開</SelectItem>\n <SelectItem value=\"public\">公開</SelectItem>\n </SelectContent>\n </Select>\n </FormField>\n </Stack>\n </TabsContent>\n <TabsContent value=\"notify\">\n <div className=\"flex items-center gap-2\">\n <Switch id=\"notify-comment\" defaultChecked />\n <Label htmlFor=\"notify-comment\">コメント通知を受け取る</Label>\n </div>\n </TabsContent>\n </Tabs>\n </CardContent>\n </Card>\n );\n}`,\n },\n\n {\n name: \"confirm-destructive\",\n tagline: \"Type-to-confirm destructive dialog — Dialog mode=\\\"confirm\\\" + Input gate + toast (real @godxjp/ui API).\",\n tags: [\"dialog\", \"confirm\", \"destructive\", \"delete\"],\n code: `import { useState } from \"react\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from \"@godxjp/ui/feedback\";\nimport { Input } from \"@godxjp/ui/data-entry\";\nimport { Button } from \"@godxjp/ui/general\";\nimport { Stack } from \"@godxjp/ui/layout\";\nimport { toast } from \"sonner\";\n\nexport function DeleteProjectDialog({ open, onOpenChange, slug }: { open: boolean; onOpenChange: (v: boolean) => void; slug: string }) {\n const [confirm, setConfirm] = useState(\"\");\n return (\n <Dialog open={open} onOpenChange={onOpenChange} mode=\"confirm\">\n <DialogContent>\n <DialogHeader>\n <DialogTitle>プロジェクトを削除</DialogTitle>\n <DialogDescription>この操作は取り消せません。確認のためプロジェクト名 \"{slug}\" と入力してください。</DialogDescription>\n </DialogHeader>\n <Stack gap=\"md\">\n <Input value={confirm} onChange={(e) => setConfirm(e.target.value)} placeholder={slug} />\n </Stack>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>キャンセル</Button>\n <Button variant=\"destructive\" disabled={confirm !== slug} onClick={() => { toast.success(\"削除しました\"); onOpenChange(false); }}>完全に削除</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}`,\n },\n\n {\n name: \"deferred-loading\",\n tagline: \"Inertia deferred props with a Skeleton fallback — SkeletonTable while data loads, then DataTable (real @godxjp/ui API).\",\n tags: [\"loading\", \"skeleton\", \"deferred\", \"inertia\", \"table\"],\n code: `// Server (Laravel): defer the heavy prop\n// Inertia::render('crm/coupons/index', [\n// 'coupons' => Inertia::defer(fn () => Coupon::all()),\n// ]);\nimport { Card, CardContent, DataTable } from \"@godxjp/ui/data-display\";\nimport type { ColumnDef } from \"@godxjp/ui/data-display\";\nimport { SkeletonTable } from \"@godxjp/ui/feedback\";\n\ntype Coupon = { id: string; name: string };\nconst columns: ColumnDef<Coupon>[] = [{ key: \"name\", header: \"クーポン名\" }];\n\n// coupons is undefined until the deferred request resolves\nexport default function Coupons({ coupons }: { coupons?: Coupon[] }) {\n return (\n <Card>\n <CardContent flush>\n {!coupons\n ? <SkeletonTable rows={10} columns={6} />\n : <DataTable data={coupons} columns={columns} getRowId={(c) => c.id} />}\n </CardContent>\n </Card>\n );\n}`,\n },\n\n {\n name: \"inertia-list-page\",\n tagline: \"Inertia + @godxjp/ui list page — PageContainer + FilterBar + DataTable + StatusBadge + Pagination (current primitive API).\",\n tags: [\"inertia\", \"list\", \"table\", \"page\", \"filter\", \"pagination\", \"datatable\", \"crm\"],\n code: `import { Head, router } from \"@inertiajs/react\"\nimport { useMemo, useState } from \"react\"\nimport { PageContainer, ResponsiveGrid, Stack } from \"@godxjp/ui/layout\"\nimport { Card, CardContent, CardStat, DataTable, EmptyState, StatusBadge, type ColumnDef } from \"@godxjp/ui/data-display\"\nimport { SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@godxjp/ui/data-entry\"\nimport { FilterBar, FilterGroup, Pagination } from \"@godxjp/ui/navigation\"\nimport { formatDate } from \"@godxjp/ui/datetime\"\nimport { withCrmLayout } from \"@/layouts/crm-layout\" // see \"inertia-persistent-layout\"\n\ntype Coupon = { id: string; name: string; status: string; scope: string; validFrom: string; validTo: string; usage: number }\nconst PAGE_SIZE = 10\n\nfunction Coupons({ coupons }: { coupons: Coupon[] }) {\n const [q, setQ] = useState(\"\")\n const [status, setStatus] = useState(\"all\")\n const [page, setPage] = useState(1)\n\n const filtered = useMemo(() => coupons.filter((c) => {\n if (q && !c.name.toLowerCase().includes(q.toLowerCase())) return false\n if (status !== \"all\" && c.status !== status) return false\n return true\n }), [coupons, q, status])\n const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE)\n\n // ColumnDef = { key, header, render?, align?: \"left\"|\"center\"|\"right\", sortable?, width? }\n const columns: ColumnDef<Coupon>[] = [\n { key: \"name\", header: \"クーポン名\", render: (c) => <span className=\"font-medium\">{c.name}</span> },\n { key: \"scope\", header: \"スコープ\", render: (c) => <StatusBadge status={c.scope} tone=\"info\" icon={null} /> },\n { key: \"status\", header: \"ステータス\", render: (c) => <StatusBadge status={c.status} /> },\n { key: \"valid\", header: \"有効期間\", render: (c) => \\`\\${formatDate(c.validFrom)} 〜 \\${formatDate(c.validTo)}\\` },\n { key: \"usage\", header: \"利用数\", align: \"right\", render: (c) => c.usage.toLocaleString() },\n ]\n\n return (\n <>\n <Head title=\"クーポン管理\" />\n {/* RULE: every page wraps in PageContainer; spacing via Stack/ResponsiveGrid, never p-*/gap-* */}\n <PageContainer title=\"クーポン管理\" subtitle=\"配信中のクーポン一覧\">\n <Stack gap=\"lg\">\n <ResponsiveGrid columns={3}>\n <CardStat label=\"公開中\" value={coupons.filter((c) => c.status === \"公開中\").length} />\n <CardStat label=\"総利用数\" value={coupons.reduce((s, c) => s + c.usage, 0).toLocaleString()} />\n <CardStat label=\"件数\" value={coupons.length} />\n </ResponsiveGrid>\n\n <FilterBar hasActiveFilters={q !== \"\" || status !== \"all\"} onClear={() => { setQ(\"\"); setStatus(\"all\"); setPage(1) }}>\n {/* SearchInput is value + onSearch(v) — NOT onChange */}\n <SearchInput placeholder=\"クーポン名で検索\" value={q} onSearch={(v) => { setQ(v); setPage(1) }} />\n <FilterGroup label=\"ステータス\">\n <Select value={status} onValueChange={(v) => { setStatus(v); setPage(1) }}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">全ステータス</SelectItem>\n <SelectItem value=\"公開中\">公開中</SelectItem>\n <SelectItem value=\"下書き\">下書き</SelectItem>\n </SelectContent>\n </Select>\n </FilterGroup>\n </FilterBar>\n\n <Card>\n <CardContent flush>\n {filtered.length === 0\n ? <EmptyState title=\"該当するクーポンがありません\" description=\"検索条件を変更してください。\" />\n : <DataTable data={paged} columns={columns} getRowId={(c) => c.id} onRowClick={(c) => router.visit(\\`/coupons/\\${c.id}\\`)} />}\n </CardContent>\n </Card>\n\n {filtered.length > PAGE_SIZE && (\n <Pagination current={page} total={filtered.length} pageSize={PAGE_SIZE} showTotal onChange={(p) => setPage(p)} />\n )}\n </Stack>\n </PageContainer>\n </>\n )\n}\n\nCoupons.layout = withCrmLayout\nexport default Coupons`,\n },\n\n {\n name: \"inertia-detail-page\",\n tagline: \"Inertia detail page — receives {id} prop, KeyValueGrid (compound) + CardStat + EmptyState fallback.\",\n tags: [\"inertia\", \"detail\", \"show\", \"page\", \"keyvaluegrid\", \"crm\"],\n code: `import { Head, router } from \"@inertiajs/react\"\nimport { PageContainer, ResponsiveGrid, Stack } from \"@godxjp/ui/layout\"\nimport { Card, CardContent, CardStat, EmptyState, KeyValueGrid, StatusBadge } from \"@godxjp/ui/data-display\"\nimport { Button } from \"@godxjp/ui/general\"\nimport { formatDate } from \"@godxjp/ui/datetime\"\nimport { ArrowLeft } from \"lucide-react\"\nimport { withCrmLayout } from \"@/layouts/crm-layout\"\n\n// Detail routes pass the param as an Inertia prop:\n// Route::get('/members/{id}', fn ($id) => Inertia::render('crm/members/show', ['id' => $id]))\nfunction MemberShow({ id }: { id: string }) {\n const member = MEMBERS.find((m) => m.id === id)\n\n if (!member) {\n return (\n <>\n <Head title=\"会員詳細\" />\n <PageContainer title=\"会員詳細\" subtitle=\"会員が見つかりません\">\n <EmptyState title=\"会員が見つかりません\" description={\\`ID「\\${id}」は存在しません。\\`} />\n <Button variant=\"outline\" onClick={() => router.visit(\"/members\")}><ArrowLeft className=\"size-4\" />一覧へ戻る</Button>\n </PageContainer>\n </>\n )\n }\n\n return (\n <>\n <Head title={member.name} />\n <PageContainer title={member.name} subtitle={\\`\\${member.id} / \\${member.rank}\\`}>\n <Stack gap=\"lg\">\n <ResponsiveGrid columns={4}>\n <CardStat label=\"累計購入額\" value={\\`¥\\${member.total.toLocaleString()}\\`} />\n <CardStat label=\"来店回数\" value={member.visits} />\n <CardStat label=\"ポイント\" value={member.points.toLocaleString()} />\n <CardStat label=\"LTV\" value={\\`¥\\${member.ltv.toLocaleString()}\\`} />\n </ResponsiveGrid>\n <Card>\n <CardContent>\n {/* KeyValueGrid is COMPOUND — value goes in children, not a prop */}\n <KeyValueGrid columns={2}>\n <KeyValueGrid.Item label=\"氏名\">{member.name}</KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"ランク\"><StatusBadge status={member.rank} tone=\"info\" icon={null} /></KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"ステータス\"><StatusBadge status={member.status} /></KeyValueGrid.Item>\n <KeyValueGrid.Item label=\"登録日\">{formatDate(member.registeredAt)}</KeyValueGrid.Item>\n </KeyValueGrid>\n </CardContent>\n </Card>\n </Stack>\n </PageContainer>\n </>\n )\n}\n\nMemberShow.layout = withCrmLayout\nexport default MemberShow`,\n },\n\n {\n name: \"inertia-persistent-layout\",\n tagline: \"Inertia persistent layout (AppShell+Sidebar) — the array-form gotcha + the SSR/Math.random gotcha.\",\n tags: [\"inertia\", \"layout\", \"appshell\", \"sidebar\", \"ssr\", \"hydration\", \"gotcha\"],\n code: `// resources/js/layouts/crm-layout.tsx\nimport { router, usePage } from \"@inertiajs/react\"\nimport { AppShell, Sidebar } from \"@godxjp/ui/layout\"\nimport { LayoutDashboard } from \"lucide-react\"\nimport type { ReactNode } from \"react\"\n\nexport function CrmLayout({ children }: { children: ReactNode }) {\n const { url } = usePage()\n const sections = [{ label: \"メイン\", items: [{ id: \"/dashboard\", label: \"ダッシュボード\", icon: LayoutDashboard }] }]\n return (\n <AppShell sidebar={<Sidebar activeId={url} onSelect={(id) => router.visit(id)} sections={sections} product={{ name: \"JOVY CRM\" }} />}>\n {children}\n </AppShell>\n )\n}\n\n// ⚠️ GOTCHA 1 — persistent layout MUST be the ARRAY form.\n// A render fn \\`(page) => <CrmLayout>{page}</CrmLayout>\\` is indistinguishable from a\n// component; Inertia React calls it with the page-PROPS object and renders that\n// object as a child → \"Objects are not valid as a React child {errors, auth, …}\".\nexport const withCrmLayout = [CrmLayout] // ✅ array → Inertia passes the page as children\n// page usage: Dashboard.layout = withCrmLayout\n\n// ⚠️ GOTCHA 2 — Inertia v3 SSRs even in \\`npm run dev\\`. NEVER call Math.random() or\n// argless new Date() during render (e.g. fabricating chart/demo numbers) → React\n// hydration mismatch (\"server rendered text didn't match the client\"). Seed\n// deterministically by index, or compute inside an event handler:\nconst seeded = (n: number) => { const x = Math.sin((n + 1) * 99.71) * 1e4; return x - Math.floor(x) }`,\n },\n\n {\n name: \"status-badge-coloring\",\n tagline: \"Colour a StatusBadge for localized labels and tiers via tone + icon (escape-hatch props, @godxjp/ui ≥ 6.1).\",\n tags: [\"statusbadge\", \"badge\", \"tone\", \"color\", \"status\", \"tier\", \"table\"],\n code: `import { StatusBadge } from \"@godxjp/ui/data-display\"\n\n// StatusBadge auto-colours a fixed set of English LIFECYCLE keys:\n// active/completed (success ✓) · draft (neutral ○) · pending/temporary (warning ⏱)\n// scheduled/sending (info) · cancelled (neutral) · failed/deleted/bounced (destructive ✕)\n// Anything else (localized labels, tiers) falls back to neutral grey ○ unless you override.\n\n// 1) Lifecycle with localized text — map to the key, keep JP via \\`label\\` (icon stays):\n<StatusBadge status=\"active\" label=\"公開中\" /> // green ✓ 公開中\n\n// 2) Unknown label — set tone explicitly (no icon, since the key is unknown):\n<StatusBadge status=\"公開中\" tone=\"success\" />\n\n// 3) Tier / category — coloured pill, drop the misleading glyph with icon={null}:\n<StatusBadge status=\"プレミアム\" tone=\"success\" icon={null} />\n<StatusBadge status=\"ゴールド\" tone=\"warning\" icon={null} />\n<StatusBadge status=\"法人共通\" tone=\"info\" icon={null} />\n\n// tone: \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\" (import type StatusBadgeTone)\n// RULE: a chip never wraps — it is pinned white-space: nowrap, so it stays one line in\n// narrow table cells. Centralize the domain→tone map in ONE small consumer wrapper and\n// import that instead of the raw StatusBadge across pages.`,\n },\n];\n\nexport function findPattern(name: string): PatternEntry | undefined {\n const slug = name.trim().toLowerCase();\n return PATTERNS.find((p) => p.name === slug);\n}\n\nexport function searchPatterns(query: string): PatternEntry[] {\n const q = query.trim().toLowerCase();\n if (q === \"\") return PATTERNS;\n return PATTERNS.filter(\n (p) =>\n p.name.includes(q) ||\n p.tagline.toLowerCase().includes(q) ||\n p.tags.some((t) => t.includes(q)),\n );\n}\n","/**\n * Skills index — TOKEN-EFFICIENT registry of every taste / design\n * skill the MCP exposes. The agent uses `list_skills` to discover\n * (returns just id + name + tagline + section list) then\n * `get_skill_section` to drill into one section.\n *\n * Sources synthesised from Leonxlnx/taste-skill + framework-native\n * design knowledge. Body strings are stored separately in their\n * existing data files (design-thinking.ts, anti-ai-tells.ts, etc.)\n * to avoid duplication.\n */\n\nexport interface SkillSection {\n /** URL-safe section id. */\n id: string;\n /** Display title. */\n title: string;\n /** One-line tagline of what this section covers. */\n tagline: string;\n /** Body — Markdown. */\n body: string;\n}\n\nexport interface Skill {\n id: string;\n name: string;\n /** When to reach for this skill — written so the router can match a task to it. */\n whenToUse: string;\n /** Source attribution. */\n source: string;\n sections: SkillSection[];\n}\n\nexport const SKILLS: Skill[] = [\n // ── taste (foundational) ───────────────────────────────────────\n {\n id: \"taste\",\n name: \"Taste baseline — Senior UI/UX engineering\",\n whenToUse:\n \"Default for any production app screen. Metric-based rules, strict component architecture, CSS hardware acceleration, balanced design engineering.\",\n source: \"Leonxlnx/taste-skill (root) + @godxjp/ui design-thinking.ts\",\n sections: [\n {\n id: \"mobile-first\",\n title: \"Mobile-first non-negotiable\",\n tagline:\n \"Defaults target xs (≥0px); enhance via sm: / md: / lg: / xl: / 2xl:\",\n body: `Cardinal rule 24. Touch targets ≥ 44×44 px. NEVER read\nwindow.innerWidth — use useBreakpoint(). Stories render at narrow\nviewport first. Multi-column layouts: grid grid-cols-1 sm:grid-cols-N.\nEXCEPTION: name pairs (姓+名) use grid-cols-2 always.`,\n },\n {\n id: \"one-intent-per-screen\",\n title: \"One intent per screen\",\n tagline: \"Pick the ONE primary question this page answers. 60-80% visual weight to it.\",\n body: `Wall-of-cards dashboards are AI slop. Show 1-2 hero metrics\n+ ONE primary list + contextual actions. Tertiary content lives in\nSheet / DropdownMenu / next page. The 8-stat-card grid pattern is a\nRED FLAG — it means \"I couldn't decide what mattered\".`,\n },\n {\n id: \"type-hierarchy\",\n title: \"Type does the hierarchy work\",\n tagline: \"Weight + size + color, NOT colored background blocks.\",\n body: `Typography.Title size={1..5} is the canonical scale. h2 → h3 → h4\neach ~75% of previous. Don't skip levels. Body = Typography.Paragraph.\nMetadata = Typography.Text color=\"secondary\". Type contrast alone IS\nthe hierarchy — colored background blocks for every section is AI\nslop. Reserve colored bg for genuinely different surfaces (Card vs\npage, Alert vs body).`,\n },\n {\n id: \"whitespace-is-content\",\n title: \"Whitespace IS content\",\n tagline: \"Use the smallest spacing step that visually separates concepts.\",\n body: `Spacing ladder: --spacing-1 (4px) for tight groups, -2 (8) for\ncontrol pairs, -3 (12) for related controls in form, -4 (16) for\nsections, -6 (24) for cards in grid, -8 (32) for page rhythm.\n\"Premium via excess padding\" (everything spacing-6 to feel premium)\nis wrong — undersized content lost in oceans of grey. Premium = VARIED\nspacing — tight where related, generous where not.`,\n },\n {\n id: \"two-accents\",\n title: \"Two accents do real work — not eight\",\n tagline: \"ONE brand color for action + ONE semantic color contextually. Not a rainbow.\",\n body: `Use --primary for actions (Button, link, focus ring) + ONE\nsemantic (destructive for delete confirm, warning for deadline alert,\nsuccess for completed state). NEVER a rainbow tag wall. Tag variety\nvia appearance (soft/solid/outline) of the SAME hue, not different\nhues.`,\n },\n {\n id: \"form-discipline\",\n title: \"Form discipline — label, help, error always\",\n tagline: \"Every input has explicit label + help + error wired via FormField.\",\n body: `Never placeholder-as-label (disappears on focus). Use\n<FormField label description /> — it wires the Radix Label, the\ndescription text, and the error via aria-describedby + role=\"alert\"\nautomatically. Server errors as inline near the field, NOT as toasts\n(SR can't announce a disappearing toast).`,\n },\n {\n id: \"loading-states\",\n title: \"Skeleton for INIT, Spinner for ACTIVE work\",\n tagline: \"Different states for different moments — never mix.\",\n body: `<Form loading={{ kind: \"skeleton\" }}> while fetching existing\nvalues (no data yet — maintain layout, prevent flash). <Form loading>\n(boolean true) while saving (data is there, you're transforming).\nSkeleton during save is wrong (user sees structure they already saw —\nbroken). Spinner during init is wrong (nothing to spin over).`,\n },\n ],\n },\n\n // ── soft (Awwwards / premium agency) ───────────────────────────\n {\n id: \"soft\",\n name: \"Awwwards-tier — $150k agency build\",\n whenToUse:\n \"Premium agency brief — marketing site, hero pages, product showcase. NOT every internal SaaS screen. Apply when the brief asks for 'Linear-tier', 'Apple-esque', 'Awwwards-style'.\",\n source: \"Leonxlnx/taste-skill/soft-skill\",\n sections: [\n {\n id: \"absolute-zero\",\n title: \"Absolute Zero — banned defaults\",\n tagline: \"Inter / Roboto / Lucide / shadow-md / 3-col Bootstrap / linear easing — banned.\",\n body: `BANNED FONTS: Inter, Roboto, Arial, Open Sans, Helvetica → use Geist\n/ Clash Display / PP Editorial New / Plus Jakarta Sans.\nBANNED ICONS: standard thick Lucide / Material → use Phosphor Light /\nRemix Line.\nBANNED BORDERS: generic 1px solid gray → hairline rings (ring-1\nring-black/5), tinted borders, OR whitespace as separator.\nBANNED SHADOWS: shadow-md, rgba(0,0,0,0.3) → ultra-diffuse low-opacity\n(<0.05), TINTED to background.\nBANNED LAYOUTS: edge-to-edge sticky navbars, symmetric 3-col → floating\nglass nav pills, asymmetric bento grids.\nBANNED MOTION: linear / ease-in-out / instant → custom cubic-bezier\n(0.32, 0.72, 0, 1), spring physics, scroll interpolation.`,\n },\n {\n id: \"vibe-archetypes\",\n title: \"3 Vibe Archetypes (pick 1)\",\n tagline: \"Ethereal Glass (SaaS/AI) | Editorial Luxury (Lifestyle/Agency) | Soft Structuralism (Consumer/Health)\",\n body: `1. ETHEREAL GLASS (SaaS / AI / Tech): OLED black #050505, radial\n mesh gradients (purple/emerald orbs), Vantablack cards with heavy\n backdrop-blur-2xl, white/10 hairlines. Wide geometric Grotesk.\n2. EDITORIAL LUXURY (Lifestyle / Real Estate / Agency): Warm creams\n #FDFBF7, muted sage, deep espresso. High-contrast Variable Serif\n for massive headings. CSS noise overlay opacity-0.03 for paper.\n3. SOFT STRUCTURALISM (Consumer / Health / Portfolio): Silver-grey\n or pure white. Massive bold Grotesk typography. Airy floating\n components, unbelievably soft diffused ambient shadows\n (shadow-[0_30px_60px_-30px_rgba(0,0,0,0.06)]).`,\n },\n {\n id: \"layout-archetypes\",\n title: \"3 Layout Archetypes (pick 1)\",\n tagline: \"Asymmetric Bento | Z-Axis Cascade | Editorial Split — ALL collapse to single-col on mobile.\",\n body: `1. ASYMMETRIC BENTO: Masonry CSS Grid varying card sizes\n (col-span-8 row-span-2 next to stacked col-span-4). Mobile:\n grid-cols-1, gap-6, all col-span reset to 1.\n2. Z-AXIS CASCADE: Elements stacked like physical cards, slightly\n overlapping with varying depth + -2deg/3deg rotations. Mobile:\n REMOVE rotations + negative-margin overlaps below 768px (touch\n conflicts), stack vertically.\n3. EDITORIAL SPLIT: Massive typography w-1/2 left, interactive\n scrollable content right. Mobile: full-width vertical stack,\n typography on top, content below with horizontal scroll preserved.\n\nUNIVERSAL MOBILE OVERRIDE: w-full, px-4, py-8 below 768px. NEVER\nh-screen — always min-h-[100dvh] (iOS Safari viewport jump fix).`,\n },\n {\n id: \"double-bezel\",\n title: \"Double-Bezel / Doppelrand architecture\",\n tagline: \"Cards nested like physical hardware — glass plate in aluminum tray.\",\n body: `Never flat. Wrap every premium card in two nested enclosures:\n\nOUTER SHELL: subtle bg (bg-black/5 or bg-white/5), hairline outer\nborder (ring-1 ring-black/5 or border border-white/10), padding\np-1.5 / p-2, large outer radius (rounded-[2rem]).\n\nINNER CORE: distinct background, inner highlight\n(shadow-[inset_0_1px_1px_rgba(255,255,255,0.15)]), mathematically\nsmaller radius (rounded-[calc(2rem-0.375rem)]) for concentric curves.\n\nThe math gives \"machined hardware\" look. Concentric curves = human\neye reads \"precision\".`,\n },\n {\n id: \"button-in-button\",\n title: \"Button-in-Button trailing icon\",\n tagline: \"Trailing arrow lives in its OWN nested pill — not naked next to text.\",\n body: `Primary buttons: rounded-full, px-6 py-3 generous padding. Trailing\narrow/icon NEVER sits naked next to text. Nests in its own circular\nwrapper: w-8 h-8 rounded-full bg-black/5 flex items-center justify-\ncenter, flush with main button's right inner padding. On hover, inner\nicon translates diagonally + scales up — internal kinetic tension.`,\n },\n {\n id: \"magnetic-hover\",\n title: \"Magnetic button hover physics\",\n tagline: \"Custom cubic-bezier, scale on press, internal translate on hover. NO linear easing.\",\n body: `Use group utility. Hover ≠ background color change. On hover:\nnested inner icon circle translates diagonally (group-hover:translate-\nx-1 group-hover:-translate-y-[1px]) AND scales up (scale-105). On\npress: scale entire button down slightly (active:scale-[0.98]) —\nsimulates physical click. Custom cubic-bezier on ALL transitions\n(NEVER linear / ease-in-out).`,\n },\n {\n id: \"scroll-entry\",\n title: \"Scroll-interpolation entry animations\",\n tagline: \"Elements never appear statically — gentle fade-up from below with blur.\",\n body: `As elements enter viewport: translate-y-16 blur-md opacity-0 →\ntranslate-y-0 blur-0 opacity-100 over 800ms+. Use IntersectionObserver\nor Framer Motion's whileInView. NEVER window.addEventListener(\"scroll\")\n— continuous reflows kill mobile perf.`,\n },\n {\n id: \"performance-guardrails\",\n title: \"Performance guardrails\",\n tagline: \"GPU-safe transforms, blur only on fixed/sticky, noise on pointer-events-none.\",\n body: `- Animate transform + opacity ONLY. NEVER top/left/width/height\n (layout reflow). will-change: transform sparingly.\n- backdrop-blur only on FIXED/STICKY elements. NEVER on scrolling\n containers — continuous GPU repaints, severe mobile frame drops.\n- grain/noise: FIXED pointer-events-none pseudo-element (position:\n fixed; inset: 0; z-index: 50). Never on scrolling containers.\n- Z-index discipline: no arbitrary z-50 or z-[9999]. Reserve for\n systemic layers (sticky nav, modals, overlays, tooltips).`,\n },\n ],\n },\n\n // ── minimalist (editorial workspace) ───────────────────────────\n {\n id: \"minimalist\",\n name: \"Minimalist — editorial workspace\",\n whenToUse:\n \"Document-style apps (Notion-clone, knowledge base, blog admin). Warm monochrome + spot pastels. Bento grids. Editorial serif headings + sans body + monospace for data.\",\n source: \"Leonxlnx/taste-skill/minimalist-skill\",\n sections: [\n {\n id: \"negative-constraints\",\n title: \"Banned defaults\",\n tagline: \"Inter / Roboto / Lucide / shadow-md / pill containers / emojis / Acme — banned.\",\n body: `BANNED: Inter / Roboto / Open Sans fonts. Lucide / Feather / Heroicons\ndefault icons. Tailwind heavy shadows (md/lg/xl). Primary-colored hero\nbackgrounds. Gradients, neon, full glassmorphism. rounded-full on\nlarge containers. Emojis anywhere in markup. Generic names (John Doe,\nAcme, Lorem Ipsum). AI clichés (Elevate, Seamless, Unleash, Next-Gen).`,\n },\n {\n id: \"typography\",\n title: \"Editorial typography\",\n tagline: \"Serif heading + character sans body + mono data. Off-black for body, never pure.\",\n body: `Pair: editorial serif (Lyon Text / Newsreader / Playfair / Instrument\nSerif) for headings WITH character sans (SF Pro Display / Geist Sans /\nSwitzer) body WITH monospace (Geist Mono / JetBrains Mono / SF Mono)\nfor data + keystrokes.\n\nTight tracking on serif headings (-0.02em to -0.04em). Tight\nline-height (1.1). Body line-height 1.6. Body color: off-black\n#111111 or #2F3437 — NEVER pure #000. Secondary text: muted gray\n#787774.`,\n },\n {\n id: \"palette\",\n title: \"Warm monochrome + spot pastels\",\n tagline: \"Canvas warm bone #F7F6F3. Accents from 4 desaturated pastels only.\",\n body: `Canvas: #FFFFFF or warm bone #F7F6F3 / #FBFBFA.\nCards: #FFFFFF or #F9F9F8.\nBorders: ultra-light #EAEAEA or rgba(0,0,0,0.06).\n\nAccents EXCLUSIVELY from 4 muted pastels:\n- Pale Red: bg #FDEBEC | text #9F2F2D\n- Pale Blue: bg #E1F3FE | text #1F6C9F\n- Pale Green: bg #EDF3EC | text #346538\n- Pale Yellow: bg #FBF3DB | text #956400`,\n },\n {\n id: \"bento-grids\",\n title: \"Asymmetric bento grids\",\n tagline: \"Cards: 1px solid #EAEAEA, 8-12px radius MAX, 24-40px padding, NO shadow.\",\n body: `Asymmetric CSS Grid layouts (1x1, 1x2, 2x1, 2x2). Cards:\nborder: 1px solid #EAEAEA, border-radius 8px or 12px MAX (never larger),\ngenerous internal padding (24-40px), no box-shadow. Use raw CSS Grid\nwith gridColumn/gridRow span for the bento layout.`,\n },\n {\n id: \"components\",\n title: \"Component refinements\",\n tagline: \"Primary CTA: solid black bg, 4-6px radius. Tags: pill + uppercase + 0.05em tracking + pastel.\",\n body: `PRIMARY CTA: solid #111 bg, white text, 4-6px radius (NOT full pill),\nno shadow. Hover: shift to #333 or active:scale(0.98).\nTAGS/BADGES: pill (border-radius 9999px), text-xs UPPERCASE,\nletter-spacing 0.05em. Background = muted pastel. Deep text color.\nACCORDIONS (FAQ): strip ALL container chrome. Items separated by\nborder-bottom: 1px solid #EAEAEA only. Toggle: sharp + / − icons.\nKBD: <kbd> as physical key — 1px solid #EAEAEA, 4px radius, #F7F6F3\nbg, monospace.\nFAUX-OS chrome (for product previews): white top bar + 3 small light-\ngray circles (macOS replica).`,\n },\n {\n id: \"motion\",\n title: \"Subtle invisible motion\",\n tagline: \"Scroll-entry fade-up 600ms cubic-bezier(.16,1,.3,1). Card hover lift via shadow shift only.\",\n body: `Scroll entry: translateY(12px) + opacity(0) → 0/1 over 600ms with\ncubic-bezier(0.16, 1, 0.3, 1). IntersectionObserver, never raw scroll.\nHover lift: box-shadow 0 → 0 2px 8px rgba(0,0,0,0.04) over 200ms.\nButtons: scale(0.98) on :active. Staggered list reveals: animation-\ndelay calc(var(--index) * 80ms). Background ambient: optional slow\nradial gradient blob, 20s+ duration, opacity 0.02-0.04, on\nposition:fixed pointer-events-none layer.`,\n },\n ],\n },\n\n // ── brutalist ──────────────────────────────────────────────────\n {\n id: \"brutalist\",\n name: \"Brutalist — Swiss print + military terminal\",\n whenToUse:\n \"Data-heavy dashboards, declassified-blueprint feel, portfolios needing raw mechanical aesthetic. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects.\",\n source: \"Leonxlnx/taste-skill/brutalist-skill\",\n sections: [\n {\n id: \"principles\",\n title: \"Brutalist principles\",\n tagline: \"Raw mechanical interfaces — rigid grids, extreme type contrast, utilitarian color, analog degradation.\",\n body: `Rejects ornament. Embraces structure as aesthetic. Grids are visible\n(via borders or rules). Type scale is dramatically contrasted (massive\ndisplay heading next to small tabular body). Color is utilitarian —\nblack, off-white, single signal color (red, amber, terminal green).\nAnalog effects (printer-bleed, halftone, screenprint registration\nerrors) add character without becoming kitsch. Best for: dev tools,\ndeclassified-data presentations, raw-fact dashboards, technical\nportfolios.`,\n },\n ],\n },\n\n // ── gpt-tasteskill ─────────────────────────────────────────────\n {\n id: \"gpt-tasteskill\",\n name: \"GPT taste — editorial + advanced GSAP motion\",\n whenToUse:\n \"Long-scroll marketing pages with cinematic scroll choreography. Pins, stacks, scrubbed timelines. AIDA structure. Wide editorial typography. Bans 6-line wraps. Gapless bento grids.\",\n source: \"Leonxlnx/taste-skill/gpt-tasteskill\",\n sections: [\n {\n id: \"principles\",\n title: \"GSAP motion + AIDA structure\",\n tagline: \"Python-driven layout randomization, strict ScrollTrigger choreography, wide editorial typography.\",\n body: `AIDA (Attention/Interest/Desire/Action) page spine. Wide editorial\ntypography — bans 6-line wraps (line lengths cap at ~5). Gapless bento\ngrids (cards flush against each other, no gutter — outline borders\ndo the separation). Inline micro-images (small contextual photos\nwithin a section, not just hero). Massive section spacing (180-240px\nbetween sections, not 80). GSAP ScrollTriggers: pinning (section\nlocks while sub-content scrolls), stacking (next section slides\nover current), scrubbing (animation tied to scroll progress).`,\n },\n ],\n },\n\n // ── redesign ───────────────────────────────────────────────────\n {\n id: \"redesign\",\n name: \"Redesign — audit + upgrade existing UI\",\n whenToUse:\n \"Working on an existing project (not greenfield). Find generic patterns, weak points, missing states. Apply fixes in priority order — font swap first, palette cleanup second, etc.\",\n source: \"Leonxlnx/taste-skill/redesign-skill + redesign-audit.ts\",\n sections: [\n {\n id: \"fix-priority\",\n title: \"Fix priority order\",\n tagline: \"Font → palette → states → layout → components → loading/empty/error → typography polish.\",\n body: `Apply in THIS order for max visual impact at min risk:\n\n1. FONT SWAP — biggest instant improvement, lowest risk.\n2. COLOR PALETTE CLEANUP — remove clashing / oversaturated colors.\n3. HOVER + ACTIVE STATES — makes interface feel alive.\n4. LAYOUT + SPACING — proper grid, max-width, consistent padding.\n5. REPLACE GENERIC COMPONENTS — cliche → modern alternatives.\n6. LOADING / EMPTY / ERROR STATES — makes it feel finished.\n7. TYPOGRAPHY SCALE + SPACING POLISH — premium final touch.\n\nRules: work with existing stack, don't migrate frameworks, don't break\nfunctionality, test after every change. Small targeted improvements\nover big rewrites.`,\n },\n {\n id: \"audit-checklist\",\n title: \"Audit checklist (8 categories)\",\n tagline: \"Typography / color / layout / interactivity / content / components / iconography / code / omissions.\",\n body: `See redesign-audit.ts (50+ checks). Common findings:\n\nTYPOGRAPHY: Inter everywhere, weak headlines, full-width paragraphs,\nonly 400/700 weights, proportional numbers in data, Title Case On\nEvery Header.\nCOLOR: pure #000, oversaturated accents, multiple competing accents,\npurple/blue AI gradient, generic black shadows, empty flat sections.\nLAYOUT: 3-equal-card columns (most generic AI pattern), height:100vh\niOS jump, no max-width container, dashboard always left sidebar.\nINTERACTIVITY: no hover, no active feedback, no focus ring, generic\nspinners, no empty states, alert() for errors, dead links.\nCONTENT: John Doe / Acme / Lorem Ipsum, AI clichés, exclamation marks\nin success, passive voice errors.\nOMISSIONS: no legal links, no back nav, no 404, no form validation,\nno skip-to-content.`,\n },\n ],\n },\n\n // ── output (full-output enforcement) ───────────────────────────\n {\n id: \"output\",\n name: \"Full-output enforcement\",\n whenToUse:\n \"Always. Bans the // ... / // TODO / 'I'll leave this as an exercise' patterns. Treat every task as production-critical.\",\n source: \"Leonxlnx/taste-skill/output-skill + output-quality.ts\",\n sections: [\n {\n id: \"banned\",\n title: \"Banned patterns\",\n tagline: \"// ... / // TODO / 'for brevity' / 'rest follows pattern' — HARD FAILURES.\",\n body: `In code: // ..., // rest of code, // implement here, // TODO,\n/* ... */, // similar to above, // continue pattern, // add more\nas needed, bare ... standing for omitted code.\n\nIn prose: \"Let me know if you want me to continue\", \"for brevity\",\n\"the rest follows the same pattern\", \"similarly for the remaining\",\n\"and so on\" (replacing actual content), \"I'll leave that as an\nexercise\".\n\nStructural: skeleton when full implementation was requested, first +\nlast section skipping middle, describing what code should do instead\nof writing it.`,\n },\n {\n id: \"long-output-protocol\",\n title: \"Long-output protocol\",\n tagline: \"Write at full quality to clean breakpoint, then [PAUSED] marker, never compress.\",\n body: `When response approaches token limit:\n- Do NOT compress remaining sections.\n- Write at FULL QUALITY up to clean breakpoint (end of function /\n file / section).\n- End with: [PAUSED — X of Y complete. Send \"continue\" to resume\n from: <section name>]\n- On \"continue\": pick up EXACTLY where stopped. No recap, no\n repetition.`,\n },\n ],\n },\n\n // ── brandkit ───────────────────────────────────────────────────\n {\n id: \"brandkit\",\n name: \"Brandkit — identity guidelines boards\",\n whenToUse:\n \"Designing a brand identity board first (before screens). Logo system, color palette, typography lockup, icon system, photography direction, brand voice.\",\n source: \"Leonxlnx/taste-skill/brandkit\",\n sections: [\n {\n id: \"principles\",\n title: \"Brandkit principles\",\n tagline: \"Premium brand-guidelines boards — minimalist / cinematic / editorial / dark-tech / luxury / cultural variants.\",\n body: `Compositions for brand identity decks. Minimalist (workspace),\ncinematic (entertainment), editorial (publishing), dark-tech (SaaS),\nluxury (lifestyle), cultural (heritage), security (defense / fintech),\ngaming, developer-tool, consumer-app. Logo concepts with intentional\nsymbolic meaning. Refined composition (asymmetric grid, generous\nbreathing). Sparse typography. Premium mockups. Art-directed\nimagery. Flexible grid layouts.`,\n },\n ],\n },\n\n // ── stitch ─────────────────────────────────────────────────────\n {\n id: \"stitch\",\n name: \"Stitch — semantic DESIGN.md for Google Stitch\",\n whenToUse:\n \"Pairing with Google Stitch (or similar AI UI generator). Generate DESIGN.md files that enforce premium standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion.\",\n source: \"Leonxlnx/taste-skill/stitch-skill\",\n sections: [\n {\n id: \"principles\",\n title: \"Stitch DESIGN.md principles\",\n tagline: \"Agent-friendly design specs — strict type, calibrated color, asymmetric layout, micro-motion, hardware acceleration.\",\n body: `DESIGN.md = instruction set for downstream AI UI generators.\nEnforces: strict typography (no Inter, specific fonts named),\ncalibrated color (specific hex, not \"blue\"), asymmetric layouts\n(specific grid template strings), perpetual micro-motion (specific\ntiming functions), hardware-accelerated performance (transform/\nopacity only). Output is consumable by AI agents — explicit beats\nexpressive.`,\n },\n ],\n },\n\n // ── imagegen-mobile ────────────────────────────────────────────\n {\n id: \"imagegen-mobile\",\n name: \"Imagegen mobile — app screen reference images\",\n whenToUse:\n \"Pre-code phase. Generate mobile screen mockups before implementing. Onboarding flows, auth, home dashboards, profile, settings, chat, ecommerce, fintech, health, productivity.\",\n source: \"Leonxlnx/taste-skill/imagegen-frontend-mobile\",\n sections: [\n {\n id: \"principles\",\n title: \"Mobile image direction principles\",\n tagline: \"App-native, premium, readable, flow-aware, platform-aware. Wrap in subtle premium phone mockup. Multi-screen consistency.\",\n body: `Generate premium app-native mobile screen images + flow images\n(NOT generic AI mockups, NOT phone-shaped websites). Default mockup\npresence: subtle premium iPhone frame with visible chrome, focus\nstays on app content. Generate 3-5 screens per flow (onboarding,\nauth, home, detail, settings). Logical flow (each screen continues\nthe user's task). First-screen cleanliness (don't dump every feature\non the entry screen). Safe-area awareness (status bar + home\nindicator preserved). Mobile anti-tells: no purple-blue fintech\ngradients, no random glass cards, no ambient blobs, no fake neon, no\ndribbble floating widgets, no oversized corner radii on everything,\nno rainbow chip walls, no fake chart dashboard spam, no cloned\nscreens in flows.`,\n },\n ],\n },\n\n // ── imagegen-web ───────────────────────────────────────────────\n {\n id: \"imagegen-web\",\n name: \"Imagegen web — landing page section images\",\n whenToUse:\n \"Pre-code phase for landing / marketing sites. Generate ONE image per section (8 sections → 8 images). Hero composition variety (NOT always left-text/right-image).\",\n source: \"Leonxlnx/taste-skill/imagegen-frontend-web\",\n sections: [\n {\n id: \"hard-output-rule\",\n title: \"Hard output rule — one image per section\",\n tagline: \"8 sections requested → 8 separate images. NEVER combine sections.\",\n body: `Each image = one section, own image call. NEVER combine multiple\nsections into one frame. NEVER return a single tall image with the\nwhole page. Default to 6 sections if \"landing page\" with no count.\n8 sections for \"full website template\". Announce each (\"Section 1\nof 8: Hero\", \"Section 2 of 8: Trust bar\").`,\n },\n {\n id: \"hero-composition-bias\",\n title: \"Hero composition variety\",\n tagline: \"Left-text / right-image hero is the most overused AI pattern. Pick from 10 alternatives first.\",\n body: `Before reaching for left-text/right-image hero, consider:\n- centered over background image\n- bottom-left over image\n- bottom-right over image\n- top-left lead\n- stacked center\n- image-as-canvas\n- off-grid editorial\n- mini minimalist\n- right-text / left-image (inverted classic)\nUse left-text/right-image ONLY when genuinely the strongest choice\nfor the brand.`,\n },\n ],\n },\n\n // ── image-to-code ──────────────────────────────────────────────\n {\n id: \"image-to-code\",\n name: \"Image-to-code — generate design first, then implement\",\n whenToUse:\n \"Visual-first brief in Codex. First generate the design image yourself, deeply analyze, THEN implement code matching it.\",\n source: \"Leonxlnx/taste-skill/image-to-code-skill\",\n sections: [\n {\n id: \"workflow\",\n title: \"Image-to-code workflow\",\n tagline: \"Generate design image → analyze → implement. Prefer large readable section-specific images.\",\n body: `Workflow:\n1. Generate the design image FIRST (one per section, large + readable).\n2. Deeply analyze: composition, hierarchy, palette, typography, motion.\n3. Implement React/HTML/CSS matching as closely as possible.\n\nPrefer LARGE, readable, section-specific images over tiny compressed\nboards. Generate fresh standalone images for sections / detail views\ninstead of cropping old. Avoid lazy under-generation. Avoid cards-\ninside-cards-inside-cards UI. Keep the hero clean, spacious, readable,\nvisible on a small laptop.`,\n },\n ],\n },\n];\n\nexport function findSkill(id: string): Skill | undefined {\n return SKILLS.find((s) => s.id === id);\n}\n\nexport function findSection(skillId: string, sectionId: string): SkillSection | undefined {\n return findSkill(skillId)?.sections.find((s) => s.id === sectionId);\n}\n\n/**\n * Naïve task router — keyword match. Replace with embedding-based\n * matcher in v2 if it proves useful.\n */\nexport interface RouteResult {\n skill: string;\n section: string | \"<see whenToUse>\";\n why: string;\n alsoSee?: string[];\n}\n\nexport function routeTask(task: string): RouteResult[] {\n const q = task.toLowerCase();\n const matches: RouteResult[] = [];\n\n const route = (\n kw: string[],\n skill: string,\n section: string | \"<see whenToUse>\",\n why: string,\n alsoSee?: string[],\n ) => {\n if (kw.some((k) => q.includes(k))) matches.push({ skill, section, why, alsoSee });\n };\n\n // Premium / agency / Awwwards\n route([\"premium\", \"awwwards\", \"agency\", \"linear\", \"apple\", \"high-end\", \"luxury\"],\n \"soft\", \"vibe-archetypes\",\n \"Premium tier — pick a Vibe + Layout archetype + apply Double-Bezel.\",\n [\"soft/double-bezel\", \"soft/magnetic-hover\"]);\n\n // Marketing / landing\n route([\"landing page\", \"marketing\", \"hero\", \"long scroll\"],\n \"imagegen-web\", \"hero-composition-bias\",\n \"Landing pages benefit from hero composition variety + per-section image generation.\",\n [\"gpt-tasteskill/principles\", \"soft/layout-archetypes\"]);\n\n // Mobile app screens\n route([\"mobile app\", \"ios\", \"android\", \"phone screen\", \"onboarding flow\"],\n \"imagegen-mobile\", \"principles\",\n \"Mobile app design — generate screens first, avoid phone-shaped-website.\",\n [\"taste/mobile-first\"]);\n\n // Workspace / Notion-like\n route([\"workspace\", \"notion\", \"document\", \"editorial\", \"knowledge base\"],\n \"minimalist\", \"palette\",\n \"Editorial workspace = warm monochrome + spot pastels + serif headings.\",\n [\"minimalist/typography\", \"minimalist/bento-grids\"]);\n\n // Data dashboard\n route([\"dashboard\", \"data heavy\", \"tabular\", \"ops table\"],\n \"brutalist\", \"principles\",\n \"Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).\",\n [\"taste/one-intent-per-screen\"]);\n\n // Brand work\n route([\"brand\", \"identity\", \"logo\", \"guidelines\"],\n \"brandkit\", \"principles\",\n \"Brand identity work — boards before screens.\");\n\n // Existing project upgrade\n route([\"refactor\", \"redesign\", \"upgrade existing\", \"audit\"],\n \"redesign\", \"fix-priority\",\n \"Existing project = run audit first, fix in priority order (font → palette → states → ...).\",\n [\"redesign/audit-checklist\"]);\n\n // Form work\n route([\"form\", \"validation\", \"submit\", \"sign up\", \"registration\"],\n \"taste\", \"form-discipline\",\n \"Form must have explicit label + help + error wired via FormField (rule 34).\");\n\n // Loading / saving\n route([\"loading\", \"saving\", \"skeleton\", \"spinner\"],\n \"taste\", \"loading-states\",\n \"Skeleton for INIT fetch, Spinner for active work. Never mix.\");\n\n // Mobile-first concerns\n route([\"mobile first\", \"responsive\", \"breakpoint\"],\n \"taste\", \"mobile-first\",\n \"Default styles target xs. Touch targets ≥ 44px. Use useBreakpoint().\");\n\n // Output quality\n route([\"complete code\", \"full implementation\", \"no placeholder\"],\n \"output\", \"banned\",\n \"Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code.\");\n\n // GSAP motion\n route([\"gsap\", \"scrolltrigger\", \"scroll choreography\", \"pinning\"],\n \"gpt-tasteskill\", \"principles\",\n \"GSAP ScrollTrigger — pinning, stacking, scrubbing.\");\n\n // Image-first / design-first\n route([\"from image\", \"image to code\", \"design first\"],\n \"image-to-code\", \"workflow\",\n \"Generate design image first → analyze → implement.\");\n\n if (matches.length === 0) {\n return [{\n skill: \"taste\",\n section: \"<see whenToUse>\",\n why: `No keyword match for \"${task}\". Default to the \"taste\" baseline — see whenToUse for sections.`,\n }];\n }\n\n return matches;\n}\n","/**\n * Anti-AI-tells catalog — specific patterns that signal \"this UI was\n * synthesised by an LLM without taste\". Adapted from the taste-skill\n * SKILL.md (mobile + web) and the @godxjp/ui review log. The MCP\n * exposes this so consumer agents can self-audit BEFORE shipping.\n */\n\nexport interface AiTell {\n /** The pattern, by category. */\n category: \"visual\" | \"layout\" | \"copy\" | \"interaction\" | \"imagery\" | \"structure\";\n /** Short name. */\n name: string;\n /** What it looks like + why it's a tell. */\n body: string;\n /** What to do instead — concrete fix. */\n fix: string;\n}\n\nexport const ANTI_AI_TELLS: AiTell[] = [\n // ── visual ─────────────────────────────────────────────────────\n {\n category: \"visual\",\n name: \"Purple-blue gradient hero\",\n body: `The default LLM color palette — purple → blue → cyan radial /\nlinear gradient as hero background. Looks like every AI-generated\nSaaS landing page from 2023.`,\n fix: `Use the framework's accent palette (\\`data-accent=\"blue\"\\` /\n\"violet\" / \"cyan\" / \"green\" / \"orange\" / \"rose\"). Solid surface\ncolors with semantic meaning. If you want depth, use a SINGLE\nsubtle gradient that supports brand (not decoration).`,\n },\n {\n category: \"visual\",\n name: \"Glassmorphism without purpose\",\n body: `Frosted-glass cards stacked on a colorful blurry background.\nLooked novel in 2020 — now a tell that the designer reached for\ntrend instead of solving a problem.`,\n fix: `Solid surface tiers (Card on background, Popover on Card,\nDialog on backdrop). The framework's elevation system already\nencodes 3 surface tiers — use them.`,\n },\n {\n category: \"visual\",\n name: \"Ambient blobs / floating shapes\",\n body: `Random gradient blobs floating behind content with no narrative\npurpose. The \"creative space-filler\" AI pattern. Reads as\ndistracting noise.`,\n fix: `If the page needs visual interest, use a REAL image (product\nphoto, founder photo, branded illustration). If you need\n\"breathing room\", use whitespace. Never use shapes as filler.`,\n },\n {\n category: \"visual\",\n name: \"Oversized border-radius on everything\",\n body: `Every Card / Button / Input with \\`border-radius: 24px\\`. Reads\nas \"I picked one radius and applied it globally\". Premium design\nuses ROLES — small radius on inputs (4-6px), medium on cards\n(8-12px), pill on chips (full).`,\n fix: `Use the framework's radius scale (\\`--radius-sm | -md | -lg | -full\\`).\nEach primitive defaults to the right role; only override when the\ndesign canon specifically calls for it.`,\n },\n {\n category: \"visual\",\n name: \"Rainbow chip wall\",\n body: `Row of Tags / Badges each in a different color (red, orange,\nyellow, green, blue, purple) — usually navigation or filter\ncategories. Reads as chaos; eye can't anchor.`,\n fix: `Pick ONE accent for the tag row. Use \\`appearance\\` (\"soft\" vs\n\"solid\" vs \"outline\") for variety within the same hue. Reserve\nnon-neutral colors (success / warning / destructive) for tags\nthat genuinely carry that meaning.`,\n },\n\n // ── layout ─────────────────────────────────────────────────────\n {\n category: \"layout\",\n name: \"8-card stat dashboard\",\n body: `Homepage with a 4x2 grid of \"stat cards\" — each with an icon, a\nnumber, a sparkline, a delta. None of them relate to a real\nbusiness question; they were chosen because \"more cards = more\ndata\". Classic AI dashboard slop.`,\n fix: `Show 1-2 hero metrics (the ones executives ASK about), then the\ntop action list (orders waiting, tasks due, alerts). If the user\nneeds more analytics, link to a dedicated Reports page.`,\n },\n {\n category: \"layout\",\n name: \"Phone-shaped website\",\n body: `Mobile screen rendered as a vertical strip with the same density\n+ same layout as desktop — just narrower. Cramped tap targets,\nhorizontal scrolling for overflow, no system bar awareness.`,\n fix: `Mobile is its OWN design. Use full-width inputs (\\`block\\` Button),\nstacked layout, larger tap targets, Sheet/Drawer for secondary\ncontent, system-bar safe area. The framework's \\`useBreakpoint\\`\n+ Tailwind \\`sm:\\` variants give you the canvas.`,\n },\n {\n category: \"layout\",\n name: \"Wall-of-tabs navigation\",\n body: `10+ tabs at the top of a screen, no priority. User has to read all\nof them to find the right one. AI default: \"more tabs = more\nfeatures = better\".`,\n fix: `2-4 tabs max. If you have more categories, use a sidebar (Menu),\nor a Cascader / Tree picker. Tabs are for switching between PEERS\n(2-4 mutually exclusive views of the same data).`,\n },\n {\n category: \"layout\",\n name: \"Identical clone screens\",\n body: `5 onboarding steps where every screen has the same headline +\nillustration + 2 buttons layout. Reads as \"I copy-pasted the\ntemplate\" — and devalues the user's time at each step.`,\n fix: `Each step has a distinct visual + interactive feel. Step 1 might\nbe a centered question, step 2 a side-by-side comparison, step 3\na multi-field form, step 4 a single yes/no card. Same palette +\ntype system for coherence; different composition for engagement.`,\n },\n\n // ── copy ───────────────────────────────────────────────────────\n {\n category: \"copy\",\n name: \"Filler corporate phrases\",\n body: `\"Elevate your potential\", \"unlock seamless productivity\",\n\"transform your workflow\", \"next-generation experience\". Reads as\nnothing because it MEANS nothing.`,\n fix: `Write what the feature DOES, specifically. \"Sync 1,000 rows in 2\nseconds\" beats \"Lightning-fast performance\". \"Replaces 3 manual\nsteps\" beats \"Streamline your workflow\".`,\n },\n {\n category: \"copy\",\n name: \"Generic brand placeholders\",\n body: `Acme, NovaCore, Flowbit, Quantix, VeloPay, Lumen, Apex — the\ngo-to AI brand names that scream \"I couldn't think of one\".`,\n fix: `Use believable real-sounding names: 株式会社ABC商事, Tanaka\nTrading, Yokohama Coffee Roasters, Mountain View Bakery. Or use\nyour actual project's brand if known.`,\n },\n {\n category: \"copy\",\n name: \"Vague empty-state copy\",\n body: `\"Get started\", \"Begin your journey\", \"No items yet\" — without\nsaying WHAT to do or WHY there's nothing.`,\n fix: `Be specific + actionable: \"まだ注文がありません。商品を追加して\n最初の注文を作成しましょう。\" + a clear next-action Button.\nEmpty states are TEACHING MOMENTS — use them to onboard.`,\n },\n {\n category: \"copy\",\n name: \"Apologetic / passive-voice error messages\",\n body: `\"Sorry, something went wrong\" / \"An error has occurred\" — no\ninformation about WHAT, no recovery action.`,\n fix: `Specific + actionable: \"メールアドレスの形式が正しくありません\n(例: name@example.com)\". For server errors: \"通信エラー\n(再試行 ボタン)\". Never apologise if you can't say what failed\nor what to do.`,\n },\n\n // ── interaction ────────────────────────────────────────────────\n {\n category: \"interaction\",\n name: \"Hover-only affordances\",\n body: `Action buttons that only appear on hover (table row actions\nhidden until mouseover). Breaks on mobile (no hover), inaccessible\n(keyboard users can't discover).`,\n fix: `Show actions inline or in a kebab menu (DropdownMenu) that's\nALWAYS visible. If you must hide on desktop for density, ensure\nthe same actions are reachable via keyboard (Tab to row, Enter to\nexpand a row-actions DropdownMenu).`,\n },\n {\n category: \"interaction\",\n name: \"Auto-advancing carousel\",\n body: `Hero carousel that rotates every 3 seconds. Users haven't\nfinished reading slide 1; now slide 2 is gone. Accessibility\nnightmare (cognitive load, motion-sensitive).`,\n fix: `Carousel ONLY rotates on explicit user action (arrow click,\ndot click, swipe). \\`<Carousel autoplay={false}>\\` is the default\nin the framework for this reason.`,\n },\n {\n category: \"interaction\",\n name: \"Drag-without-handle\",\n body: `Cards / list items reorderable by long-press anywhere — no\nvisual indicator that they ARE draggable. Users discover it by\naccident or never.`,\n fix: `Show a drag handle icon (\\`<GripVertical>\\`) on the left of the\nrow. Users see it, understand \"this row is draggable\", reach for\nit deliberately.`,\n },\n {\n category: \"interaction\",\n name: \"Disappearing focus ring\",\n body: `\\`outline: none\\` on focus to \"look cleaner\". Keyboard users\ncan't see where they are; total navigation failure.`,\n fix: `Use \\`:focus-visible\\` (Radix primitives do automatically) so the\nring shows on keyboard focus, hides on mouse-click. Don't strip.`,\n },\n\n // ── imagery ────────────────────────────────────────────────────\n {\n category: \"imagery\",\n name: \"Stock photo of generic smiling team\",\n body: `Empty state / About page with a photo of a \"diverse team in an\nopen office laughing at a laptop\". Reads as 2010 corporate stock.\nNo relationship to your product.`,\n fix: `Real photos of YOUR team / users (with consent), product\nscreenshots, branded illustrations. Avatar's INITIALS fallback is\nbetter than a generic stock person.`,\n },\n {\n category: \"imagery\",\n name: \"Floating 3D crypto icon\",\n body: `Empty state with a chrome / pastel 3D icon (coin, key, shield)\nfloating in the center. Looks like every NFT marketplace from\n2021.`,\n fix: `Simple lucide-react line icon (\\`<Inbox size={48} />\\`) +\ndescriptive title. Or a flat illustration matching the brand\npalette. Skip the 3D entirely unless your brand IS 3D.`,\n },\n {\n category: \"imagery\",\n name: \"Decorative gradient mesh background\",\n body: `Page sections with a colorful gradient mesh (\"Stripe-style\")\nbehind text. Looks \"premium\" until you realize every AI design\nuses it. Often hurts text contrast.`,\n fix: `Solid background (\\`--background\\`). If you need depth, use a\nsubtle 1px border + \\`--card\\` background tint. Reserve high-effort\nbackgrounds for pages where they matter (marketing hero, product\nshowcase) — not every internal screen.`,\n },\n\n // ── structure ──────────────────────────────────────────────────\n {\n category: \"structure\",\n name: \"Settings as one long form\",\n body: `Settings page with 40 form fields in a single scroll. User\nloses their place, can't find the field they came for.`,\n fix: `Section the form with \\`<Typography.Title size={5}>\\` subheaders\n+ \\`<Separator />\\`. Group by concern (基本情報 / 公開範囲 / 通知 /\nセキュリティ). If 40 fields is still too many, split into Tabs\nor a Sidebar-driven multi-page settings flow.`,\n },\n {\n category: \"structure\",\n name: \"Modal-in-modal-in-modal\",\n body: `Click a Button → Dialog opens → click \"Edit\" → another Dialog\nopens → click \"Confirm\" → AlertDialog opens. Triple stack;\nuser loses context.`,\n fix: `Use Sheet for the FIRST level (side panel), Dialog for the\nconfirm. Or, redesign the flow so the edit is INLINE in the\nfirst Dialog (no second Dialog needed). AlertDialog for confirm\nis correct — but ONE deep, not three.`,\n },\n {\n category: \"structure\",\n name: \"Spinner-only loading state\",\n body: `Page-level spinner while data loads. User stares at an empty\nshell with a centered spinner. Layout shifts when content\narrives.`,\n fix: `Use Skeleton placeholders matching the eventual content shape.\nThe framework's \\`<Form loading={{ kind: \"skeleton\" }}>\\` cascades\nto every field; \\`<Skeleton className=\"h-9 w-full rounded-md\" />\\`\nfor individual blocks. Layout stays stable, perceived speed\nimproves.`,\n },\n];\n\nexport function aiTellsByCategory(cat: AiTell[\"category\"]): AiTell[] {\n return ANTI_AI_TELLS.filter((t) => t.category === cat);\n}\n","/**\n * Redesign audit checklist — for upgrading an existing project (or\n * critiquing a new design before shipping). Adapted from\n * Leonxlnx/taste-skill `redesign-existing-projects` SKILL. The MCP\n * exposes this so consumer agents can run a structured audit on a\n * page they're working on.\n *\n * Fix priority is ordered for MAXIMUM visual impact at MINIMUM\n * risk — agents should apply in this order.\n */\n\nexport interface AuditCheck {\n category:\n | \"typography\"\n | \"color-surface\"\n | \"layout\"\n | \"interactivity\"\n | \"content\"\n | \"components\"\n | \"iconography\"\n | \"code-quality\"\n | \"omissions\";\n /** What to look for. */\n symptom: string;\n /** Concrete fix. */\n fix: string;\n /** @godxjp/ui-specific notes if applicable. */\n uiNote?: string;\n}\n\nexport const REDESIGN_CHECKS: AuditCheck[] = [\n // ── typography ─────────────────────────────────────────────────\n {\n category: \"typography\",\n symptom: \"Inter / Roboto / Open Sans everywhere — the AI default.\",\n fix: \"Pick a font with character: Geist, Outfit, Cabinet Grotesk, Satoshi for sans. For editorial / creative — pair a serif heading (Newsreader, Lyon, Playfair) with a sans body.\",\n uiNote: \"Override --font-sans + --font-serif at the consumer's root CSS. Framework reads from these tokens.\",\n },\n {\n category: \"typography\",\n symptom: \"Headlines lack presence — small + thin + default tracking.\",\n fix: \"Increase display size, tighten letter-spacing (-0.02em to -0.04em), reduce line-height (1.1). Headlines should feel HEAVY and INTENTIONAL.\",\n uiNote: \"Typography.Title size={1} for hero; override fontFamily + letterSpacing inline.\",\n },\n {\n category: \"typography\",\n symptom: \"Body paragraphs full-width — hard to read.\",\n fix: \"Limit paragraph max-width to ~65ch. Increase line-height to 1.6+.\",\n uiNote: \"Wrap Typography.Paragraph in `<div style={{ maxWidth: '65ch' }}>`.\",\n },\n {\n category: \"typography\",\n symptom: \"Only Regular (400) + Bold (700) weights — flat hierarchy.\",\n fix: \"Introduce Medium (500) + SemiBold (600) for subtle weight contrasts.\",\n },\n {\n category: \"typography\",\n symptom: \"Numbers in proportional font — columns jitter in tables.\",\n fix: \"`font-variant-numeric: tabular-nums` for data, or a monospace font like Geist Mono.\",\n uiNote: \"Table primitive already uses `tabular-nums` on `.num` cells. For ad-hoc numeric labels, add the CSS prop manually.\",\n },\n {\n category: \"typography\",\n symptom: \"Orphaned words — single word on the last line of a heading.\",\n fix: \"`text-wrap: balance` (h1/h2/h3) or `text-wrap: pretty` (body).\",\n },\n {\n category: \"typography\",\n symptom: \"Title Case On Every Header.\",\n fix: \"Use sentence case instead. More modern, easier to read.\",\n },\n\n // ── color / surface ────────────────────────────────────────────\n {\n category: \"color-surface\",\n symptom: \"Pure #000000 background.\",\n fix: \"Replace with off-black (#0A0A0A) / dark charcoal (#121212) / tinted dark (deep navy).\",\n uiNote: \"Framework dark theme already uses tinted dark values — verify the consumer's override didn't force pure black.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Oversaturated accent colors.\",\n fix: \"Keep saturation below 80%. Desaturate so accents BLEND with neutrals rather than scream.\",\n },\n {\n category: \"color-surface\",\n symptom: \"More than one accent color competing.\",\n fix: \"Pick ONE. Remove the rest. Consistency beats variety in palette.\",\n uiNote: \"Set ONE `data-accent` at `<html>` root. Use semantic colors (success / warning / destructive) only for genuinely semantic content.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Purple/blue 'AI gradient' aesthetic — most common AI fingerprint.\",\n fix: \"Replace with neutral base + ONE considered accent. Drop the gradient entirely if it has no narrative purpose.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Generic black `box-shadow` everywhere.\",\n fix: \"Tint shadow to match background hue (e.g. cool gray bg → cool gray shadow). Colored shadows over pure black.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Random dark section breaking an otherwise light page.\",\n fix: \"Either commit to full dark mode OR keep light consistently. If contrast needed, use a SLIGHTLY darker shade of the same palette — not a sudden jump to #111.\",\n },\n {\n category: \"color-surface\",\n symptom: \"Empty flat sections with no visual depth.\",\n fix: \"Add subtle background imagery at low opacity (`/picsum.photos/seed/{name}/1920/1080`) OR ambient gradient at 0.02-0.05 opacity. Empty flat = unfinished.\",\n },\n\n // ── layout ─────────────────────────────────────────────────────\n {\n category: \"layout\",\n symptom: \"Everything centered + symmetric.\",\n fix: \"Break symmetry: offset margins, mixed aspect ratios, left-aligned header over centered body.\",\n },\n {\n category: \"layout\",\n symptom: \"Three equal card columns as feature row — the most generic AI layout.\",\n fix: \"Replace with 2-column zig-zag, asymmetric grid, horizontal scroll, or masonry. The 3-equal-cols pattern is RED FLAG #1.\",\n uiNote: \"Use Bento Grid (custom CSS grid with `gridColumn: 'span N'`) instead of `<Grid cols={3}>` for hero sections.\",\n },\n {\n category: \"layout\",\n symptom: \"`height: 100vh` causing iOS Safari jump.\",\n fix: \"Use `min-height: 100dvh` (dynamic viewport) instead.\",\n },\n {\n category: \"layout\",\n symptom: \"No max-width container — content stretches edge-to-edge.\",\n fix: \"Add a container constraint (1200-1440px) with `margin: auto`. Or use `max-w-4xl / max-w-5xl` for content-heavy pages.\",\n uiNote: \"Framework's PageContent constrains via `var(--container-max-width)`. Consumer may override.\",\n },\n {\n category: \"layout\",\n symptom: \"Cards forced to same height by flexbox.\",\n fix: \"Allow variable heights or use masonry when content varies.\",\n uiNote: \"Use Masonry primitive — handles variable heights without flexbox stretch.\",\n },\n {\n category: \"layout\",\n symptom: \"Buttons at random vertical positions in card rows.\",\n fix: \"Pin CTAs to card bottom — same Y-position across the row regardless of content above.\",\n uiNote: \"Card's `actions` footer slot bottom-aligns automatically.\",\n },\n {\n category: \"layout\",\n symptom: \"Feature lists starting at different vertical positions in pricing tables.\",\n fix: \"Fixed-height title/price block + consistent spacing above the feature list. Cards align across columns.\",\n },\n {\n category: \"layout\",\n symptom: \"Dashboard ALWAYS has a left sidebar.\",\n fix: \"Consider top navigation, floating command menu, or collapsible panel. Sidebar isn't the only chrome.\",\n uiNote: \"Framework supports both — AppShell with sidebar slot is optional; can use Topbar-only for some flows.\",\n },\n\n // ── interactivity ──────────────────────────────────────────────\n {\n category: \"interactivity\",\n symptom: \"No hover states on buttons.\",\n fix: \"Background shift, scale, or translate on hover — 150-200ms ease.\",\n uiNote: \"Framework Button has built-in hover. If overridden — restore.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No active/pressed feedback.\",\n fix: \"`scale(0.98)` or `translateY(1px)` on `:active`. Simulates a physical click.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No focus ring (`outline: none`).\",\n fix: \"Restore visible `:focus-visible` ring. Accessibility requirement, not optional.\",\n },\n {\n category: \"interactivity\",\n symptom: \"Generic circular spinner for page-level loading.\",\n fix: \"Replace with Skeleton placeholders matching the eventual content shape.\",\n uiNote: \"Framework Skeleton + Form `loading={{ kind: 'skeleton' }}` handles cascading initial-fetch state.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No empty states — empty dashboard shows nothing.\",\n fix: \"Design a composed 'getting started' view: Empty primitive with title + description + next-action button.\",\n },\n {\n category: \"interactivity\",\n symptom: \"`window.alert()` for errors.\",\n fix: \"Inline error in the relevant Field, OR toast for non-form errors, OR Dialog for blocking errors.\",\n },\n {\n category: \"interactivity\",\n symptom: \"Dead links (`href='#'`).\",\n fix: \"Either link to real destinations or visually disable the button.\",\n },\n {\n category: \"interactivity\",\n symptom: \"No indication of current page in navigation.\",\n fix: \"Style the active nav link distinctly.\",\n uiNote: \"Sidebar handles via `activeId` — pass it.\",\n },\n\n // ── content ────────────────────────────────────────────────────\n {\n category: \"content\",\n symptom: \"Generic names — 'John Doe', 'Jane Smith'.\",\n fix: \"Diverse, realistic names. For Japanese apps: 田中 太郎, 佐藤 美咲, Nguyễn Lan, Maria Cruz.\",\n },\n {\n category: \"content\",\n symptom: \"Fake round numbers — '99.99%', '50%', '$100.00'.\",\n fix: \"Organic data: '47.2%', '$99.00', '+1 (312) 847-1928'.\",\n },\n {\n category: \"content\",\n symptom: \"Placeholder brand names — Acme, Nexus, SmartFlow.\",\n fix: \"Invent contextual believable brands or use the consumer's real brand.\",\n },\n {\n category: \"content\",\n symptom: \"AI copy clichés — 'elevate', 'seamless', 'unleash', 'next-gen', 'game-changer', 'delve', 'tapestry', 'in the world of'.\",\n fix: \"Plain specific language. Numbers, nouns, verbs.\",\n uiNote: \"Framework's cardinal rule 9 bans this in framework docs; same discipline applies to consumer copy.\",\n },\n {\n category: \"content\",\n symptom: \"Exclamation marks in success messages.\",\n fix: \"Remove. Be confident, not loud.\",\n },\n {\n category: \"content\",\n symptom: \"'Oops!' or apologetic error messages.\",\n fix: \"Direct + specific: 'Connection failed. Please try again.' / 'メールアドレスの形式が正しくありません'.\",\n },\n {\n category: \"content\",\n symptom: \"Lorem Ipsum.\",\n fix: \"Real draft copy. Even rough placeholder beats Latin.\",\n },\n\n // ── components ─────────────────────────────────────────────────\n {\n category: \"components\",\n symptom: \"Generic card look (border + shadow + white).\",\n fix: \"Remove border OR shadow OR background — keep ONE. Cards exist only when elevation communicates hierarchy.\",\n },\n {\n category: \"components\",\n symptom: \"Always one filled + one ghost button.\",\n fix: \"Add text links / tertiary styles for variety.\",\n uiNote: \"Button has `variant='link'` for tertiary actions.\",\n },\n {\n category: \"components\",\n symptom: \"3-card carousel testimonials with dots.\",\n fix: \"Replace with masonry wall of quotes, embedded social posts, or single rotating quote.\",\n },\n {\n category: \"components\",\n symptom: \"Pricing table with 3 equal towers.\",\n fix: \"Highlight recommended tier with COLOR and emphasis, not just extra height.\",\n },\n {\n category: \"components\",\n symptom: \"Modals for everything.\",\n fix: \"Use inline editing, Sheet (slide-over), or expandable Collapse for simple actions. Reserve Dialog for true blocking decisions.\",\n },\n {\n category: \"components\",\n symptom: \"Footer link farm with 4 columns.\",\n fix: \"Simplify. Main nav paths + legally required links. No marketing kitchen sink.\",\n },\n\n // ── iconography ────────────────────────────────────────────────\n {\n category: \"iconography\",\n symptom: \"Lucide or Feather icons exclusively.\",\n fix: \"Use Phosphor (Bold / Fill), Heroicons, or a custom set. AI default tell.\",\n uiNote: \"Framework ships with lucide as locked dependency (rule 14). For editorial differentiation, layer Phosphor on top.\",\n },\n {\n category: \"iconography\",\n symptom: \"Cliche icon metaphors — rocketship 'launch', shield 'security'.\",\n fix: \"Less obvious: bolt, fingerprint, spark, vault, gem.\",\n },\n {\n category: \"iconography\",\n symptom: \"Stock 'diverse team in office' photo.\",\n fix: \"Real team photos, candid shots, or a consistent illustration style. Avatar initials fallback > generic stock person.\",\n },\n\n // ── code quality ───────────────────────────────────────────────\n {\n category: \"code-quality\",\n symptom: \"Div soup — no semantic HTML.\",\n fix: \"`<nav>`, `<main>`, `<article>`, `<aside>`, `<section>` for landmarks.\",\n uiNote: \"AppShell renders the canonical landmark structure automatically.\",\n },\n {\n category: \"code-quality\",\n symptom: \"Inline styles mixed with CSS classes haphazardly.\",\n fix: \"Move styling into the project's system. Inline `style={{}}` only for layout / positioning (rule 29).\",\n },\n {\n category: \"code-quality\",\n symptom: \"Missing alt text on images.\",\n fix: \"Describe content for SR. Never leave `alt=''` or `alt='image'` on meaningful images.\",\n },\n {\n category: \"code-quality\",\n symptom: \"Arbitrary z-index values like `9999`.\",\n fix: \"Establish a clean z-index scale in CSS variables.\",\n },\n\n // ── strategic omissions ────────────────────────────────────────\n {\n category: \"omissions\",\n symptom: \"No legal links in footer.\",\n fix: \"Add Privacy Policy + Terms of Service.\",\n },\n {\n category: \"omissions\",\n symptom: \"Dead ends in user flows — no 'back'.\",\n fix: \"Every page has a way back. Breadcrumb, back button, OR clear nav state.\",\n },\n {\n category: \"omissions\",\n symptom: \"No custom 404 page.\",\n fix: \"Design a helpful branded 404 with a way home and search.\",\n },\n {\n category: \"omissions\",\n symptom: \"No form validation.\",\n fix: \"Client-side validation via zod schema. Framework's Form + FormField handle field-level errors automatically.\",\n },\n {\n category: \"omissions\",\n symptom: \"No 'skip to content' link.\",\n fix: \"Hidden skip-link, first focusable element. Essential for keyboard users.\",\n uiNote: \"AppShell renders one automatically.\",\n },\n];\n\nexport const FIX_PRIORITY = [\n \"1. Font swap — biggest instant improvement, lowest risk\",\n \"2. Color palette cleanup — remove clashing / oversaturated colors\",\n \"3. Hover + active states — makes the interface feel alive\",\n \"4. Layout + spacing — proper grid, max-width, consistent padding\",\n \"5. Replace generic components — swap cliche patterns for modern alternatives\",\n \"6. Add loading, empty, error states — makes it feel finished\",\n \"7. Polish typography scale + spacing — the premium final touch\",\n];\n\nexport const REDESIGN_RULES = [\n \"Work with the existing tech stack. Do NOT migrate frameworks or styling libraries.\",\n \"Do NOT break existing functionality. Test after every change.\",\n \"Before importing any new library, check `package.json` first.\",\n \"Keep changes reviewable + focused. Small targeted improvements over big rewrites.\",\n \"Run the audit before fixing — listing issues first prevents accidental scope creep.\",\n];\n\nexport function checksByCategory(cat: AuditCheck[\"category\"]): AuditCheck[] {\n return REDESIGN_CHECKS.filter((c) => c.category === cat);\n}\n","/**\n * Tool registry — declares MCP tool schemas + dispatches calls.\n *\n * Token-efficient design (per PLAN.md):\n * - `list_*` returns SMALL metadata (1-line each).\n * - `get_*` / `get_*_section` returns ONE focused unit.\n * - `route_task` returns a SMALL pointer to skill+section.\n *\n * The agent walks: list → narrow → drill into one section. Avoids\n * dumping 50KB blobs.\n */\n\nimport {\n COMPONENTS,\n componentsByGroup,\n findComponent,\n type ComponentGroup,\n} from \"../data/components.js\";\nimport { PROP_VOCABULARY, findVocab } from \"../data/prop-vocabulary.js\";\nimport { TOKENS, tokensByCategory, type TokenCategory } from \"../data/tokens.js\";\nimport { CARDINAL_RULES, findRule } from \"../data/rules.js\";\nimport { PATTERNS, findPattern, searchPatterns } from \"../data/patterns.js\";\nimport { SKILLS, findSkill, findSection, routeTask } from \"../data/skills-index.js\";\nimport { ANTI_AI_TELLS, aiTellsByCategory, type AiTell } from \"../data/anti-ai-tells.js\";\nimport {\n REDESIGN_CHECKS,\n FIX_PRIORITY,\n REDESIGN_RULES,\n checksByCategory,\n type AuditCheck,\n} from \"../data/redesign-audit.js\";\n\nexport const TOOL_DEFINITIONS = [\n // ── DISCOVERY (small responses) ────────────────────────────────\n {\n name: \"list_skills\",\n description:\n \"List every design / taste skill bundled by this MCP (taste / soft / minimalist / brutalist / gpt-tasteskill / redesign / output / brandkit / stitch / imagegen-mobile / imagegen-web / image-to-code). Returns id + name + whenToUse + section ids. ~1KB. Use FIRST to discover what skills exist; then `get_skill_section` to drill in.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_primitives\",\n description:\n \"List every @godxjp/ui primitive / composite / shell. Returns group + tagline per entry. ~3KB. Optionally filter by group.\",\n inputSchema: {\n type: \"object\",\n properties: {\n group: {\n type: \"string\",\n enum: [\n \"general\",\n \"layout\",\n \"data-display\",\n \"data-entry\",\n \"feedback\",\n \"navigation\",\n \"composites\",\n \"shell\",\n \"providers\",\n ],\n },\n },\n },\n },\n {\n name: \"list_patterns\",\n description:\n \"List every canonical code pattern (registration-form / settings-page / data-table / confirm-destructive / app-shell / filter-bar / loading-states). ~500 bytes. Use before `get_pattern`.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_anti_ai_tells\",\n description:\n \"List every AI-tell pattern to AVOID (organised by category: visual / layout / copy / interaction / imagery / structure). ~2KB. Use to self-audit a design before shipping.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: {\n type: \"string\",\n enum: [\"visual\", \"layout\", \"copy\", \"interaction\", \"imagery\", \"structure\"],\n },\n },\n },\n },\n {\n name: \"list_redesign_checks\",\n description:\n \"List the redesign audit checklist (50+ checks across 9 categories: typography / color-surface / layout / interactivity / content / components / iconography / code-quality / omissions). ~5KB. Use when auditing an existing project.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: {\n type: \"string\",\n enum: [\n \"typography\",\n \"color-surface\",\n \"layout\",\n \"interactivity\",\n \"content\",\n \"components\",\n \"iconography\",\n \"code-quality\",\n \"omissions\",\n ],\n },\n },\n },\n },\n\n // ── DRILL-DOWN (medium responses) ──────────────────────────────\n {\n name: \"get_anti_ai_tell\",\n description:\n \"Fetch ONE anti-AI-tell — full body + concrete fix. Use after `list_anti_ai_tells`.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Exact tell name from list_anti_ai_tells.\" },\n },\n required: [\"name\"],\n },\n },\n {\n name: \"get_redesign_check\",\n description:\n \"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.\",\n inputSchema: {\n type: \"object\",\n properties: {\n symptom: {\n type: \"string\",\n description: \"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh').\",\n },\n },\n required: [\"symptom\"],\n },\n },\n {\n name: \"get_skill_section\",\n description:\n \"Fetch ONE section of ONE skill — token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.\",\n inputSchema: {\n type: \"object\",\n properties: {\n skill: { type: \"string\", description: \"Skill id (e.g. 'soft', 'minimalist', 'taste').\" },\n section: { type: \"string\", description: \"Section id within that skill.\" },\n },\n required: [\"skill\", \"section\"],\n },\n },\n {\n name: \"get_component\",\n description:\n \"Full guide for one @godxjp/ui component — import path, props/types/defaults, HOW to use it (DO/DON'T), WHEN to reach for it (use cases), related components (don't reinvent/confuse), a copy-paste example, story path, and cardinal rules. Use this before hand-rolling anything.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Component name (e.g. 'Button', 'DataTable').\" },\n },\n required: [\"name\"],\n },\n },\n {\n name: \"get_pattern\",\n description: \"Full code snippet for one canonical pattern — copy-paste-ready.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Pattern slug (use list_patterns first).\" },\n },\n required: [\"name\"],\n },\n },\n {\n name: \"get_rule\",\n description: \"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.\",\n inputSchema: {\n type: \"object\",\n properties: { number: { type: \"number\", description: \"Rule number (1-N).\" } },\n },\n },\n {\n name: \"get_vocab\",\n description:\n \"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.\",\n inputSchema: {\n type: \"object\",\n properties: { name: { type: \"string\", description: \"Vocab type name.\" } },\n },\n },\n {\n name: \"get_tokens\",\n description: \"Read design tokens, optionally filtered by category.\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: {\n type: \"string\",\n enum: [\n \"color\",\n \"spacing\",\n \"typography\",\n \"radius\",\n \"shadow\",\n \"motion\",\n \"breakpoint\",\n \"density\",\n \"z-index\",\n ],\n },\n },\n },\n },\n\n // ── TASK ROUTING (smallest response — pointer) ─────────────────\n {\n name: \"route_task\",\n description:\n \"Natural-language task → skill+section pointer. ~300 bytes. E.g. 'I want to design a premium agency hero' → `{skill:'soft', section:'vibe-archetypes', why:'...'}`. Use FIRST when you don't know which skill applies.\",\n inputSchema: {\n type: \"object\",\n properties: { task: { type: \"string\", description: \"Describe what you want to build.\" } },\n required: [\"task\"],\n },\n },\n {\n name: \"suggest_primitive\",\n description:\n \"Use case → primitive recommendation. E.g. 'confirm a destructive delete' → DangerZone pattern + Dialog suggestion.\",\n inputSchema: {\n type: \"object\",\n properties: { use_case: { type: \"string\" } },\n required: [\"use_case\"],\n },\n },\n {\n name: \"search_components\",\n description: \"Fuzzy-search primitives by name / tagline / prop. Returns ranked matches.\",\n inputSchema: {\n type: \"object\",\n properties: { query: { type: \"string\" } },\n required: [\"query\"],\n },\n },\n\n // ── LINT / AUDIT (one-shot critique) ───────────────────────────\n {\n name: \"lint_jsx\",\n description:\n \"Heuristic check of a JSX snippet for common violations — raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.\",\n inputSchema: {\n type: \"object\",\n properties: { jsx: { type: \"string\" } },\n required: [\"jsx\"],\n },\n },\n];\n\nexport async function dispatchTool(name: string, args: Record<string, unknown>): Promise<string> {\n switch (name) {\n // Discovery\n case \"list_skills\":\n return listSkills();\n case \"list_primitives\":\n return listPrimitives(args.group as ComponentGroup | undefined);\n case \"list_patterns\":\n return listPatterns();\n case \"list_anti_ai_tells\":\n return listAntiAiTells(args.category as AiTell[\"category\"] | undefined);\n case \"list_redesign_checks\":\n return listRedesignChecks(args.category as AuditCheck[\"category\"] | undefined);\n case \"get_anti_ai_tell\":\n return getAntiAiTell(String(args.name ?? \"\"));\n case \"get_redesign_check\":\n return getRedesignCheck(String(args.symptom ?? \"\"));\n // Drill-down\n case \"get_skill_section\":\n return getSkillSection(String(args.skill ?? \"\"), String(args.section ?? \"\"));\n case \"get_component\":\n return getComponent(String(args.name ?? \"\"));\n case \"get_pattern\":\n return getPattern(String(args.name ?? \"\"));\n case \"get_rule\":\n return getRule(typeof args.number === \"number\" ? args.number : undefined);\n case \"get_vocab\":\n return getVocab(args.name as string | undefined);\n case \"get_tokens\":\n return getTokens(args.category as TokenCategory | undefined);\n // Task routing\n case \"route_task\":\n return routeTaskTool(String(args.task ?? \"\"));\n case \"suggest_primitive\":\n return suggestPrimitive(String(args.use_case ?? \"\"));\n case \"search_components\":\n return searchComponents(String(args.query ?? \"\"));\n // Lint\n case \"lint_jsx\":\n return lintJsx(String(args.jsx ?? \"\"));\n default:\n return `Unknown tool: ${name}`;\n }\n}\n\n// ── implementations ───────────────────────────────────────────────\n\nfunction listSkills(): string {\n let out = `# Available skills (${SKILLS.length})\\n\\n`;\n out += `Use \\`get_skill_section skill=\"...\" section=\"...\"\\` to drill in.\\n\\n`;\n for (const s of SKILLS) {\n out += `## ${s.id} — ${s.name}\\n`;\n out += `**When to use:** ${s.whenToUse}\\n\\n`;\n out += `**Sections:** ${s.sections.map((sec) => `\\`${sec.id}\\``).join(\", \")}\\n\\n`;\n }\n out += `\\n_Source: ${SKILLS.map((s) => s.source)\n .filter((v, i, a) => a.indexOf(v) === i)\n .slice(0, 3)\n .join(\"; \")}, …_`;\n return out;\n}\n\nfunction listPrimitives(group?: ComponentGroup): string {\n const list = group ? componentsByGroup(group) : COMPONENTS;\n if (list.length === 0) return `No components${group ? ` in group \"${group}\"` : \"\"}.`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, c) => {\n (acc[c.group] ??= []).push(c);\n return acc;\n }, {});\n let out = `# @godxjp/ui primitives${group ? ` — ${group}` : \"\"}\\n\\n${list.length} components.\\n\\n`;\n for (const [g, items] of Object.entries(grouped)) {\n out += `## ${g}\\n\\n`;\n for (const c of items) out += `- **${c.name}** — ${c.tagline}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction listPatterns(): string {\n let out = `# Canonical patterns (${PATTERNS.length})\\n\\n`;\n for (const p of PATTERNS) {\n out += `- **${p.name}** — ${p.tagline} \\n _tags: ${p.tags.join(\", \")}_\\n`;\n }\n return out;\n}\n\nfunction listAntiAiTells(cat?: AiTell[\"category\"]): string {\n const list = cat ? aiTellsByCategory(cat) : ANTI_AI_TELLS;\n // Compact list — names only. Use `get_anti_ai_tell` for full body + fix.\n let out = `# AI tells to AVOID${cat ? ` — ${cat}` : \"\"} (${list.length})\\n\\n`;\n out += `_Compact list. Use \\`get_anti_ai_tell name=\"<name>\"\\` for the full body + fix._\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, t) => {\n (acc[t.category] ??= []).push(t);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n`;\n for (const t of items) out += `- ${t.name}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction getAntiAiTell(name: string): string {\n const t = ANTI_AI_TELLS.find((x) => x.name.toLowerCase() === name.trim().toLowerCase());\n if (!t) {\n let out = `Anti-AI-tell \"${name}\" not found. Use \\`list_anti_ai_tells\\` to discover. Closest:\\n\\n`;\n for (const x of ANTI_AI_TELLS.slice(0, 8)) out += `- ${x.name} (${x.category})\\n`;\n return out;\n }\n return `# ${t.name}\\n\\n**Category:** ${t.category}\\n\\n## Symptom\\n\\n${t.body}\\n\\n## Fix\\n\\n${t.fix}\\n`;\n}\n\nfunction listRedesignChecks(cat?: AuditCheck[\"category\"]): string {\n const list = cat ? checksByCategory(cat) : REDESIGN_CHECKS;\n // Compact list — symptoms only. Use `get_redesign_check` for the full fix + ui-note.\n let out = `# Redesign audit${cat ? ` — ${cat}` : \"\"} (${list.length} checks)\\n\\n`;\n if (!cat) {\n out += `## Fix priority\\n${FIX_PRIORITY.map((p) => p).join(\"\\n\")}\\n\\n`;\n out += `## Rules\\n${REDESIGN_RULES.map((r) => `- ${r}`).join(\"\\n\")}\\n\\n`;\n }\n out += `_Compact list of symptoms. Use \\`get_redesign_check symptom=\"<text snippet>\"\\` for the full fix + UI note._\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, c) => {\n (acc[c.category] ??= []).push(c);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n`;\n for (const item of items) out += `- ${item.symptom}\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction getRedesignCheck(snippet: string): string {\n const q = snippet.trim().toLowerCase();\n if (!q)\n return \"Pass `symptom` — a fragment matching the audit check symptom (e.g. 'Inter everywhere' / '100vh' / 'Acme').\";\n const matches = REDESIGN_CHECKS.filter(\n (c) => c.symptom.toLowerCase().includes(q) || c.fix.toLowerCase().includes(q),\n );\n if (!matches.length) {\n return `No redesign check matches \"${snippet}\". Use \\`list_redesign_checks\\` to see all.`;\n }\n let out = `# Redesign checks matching \"${snippet}\" (${matches.length})\\n\\n`;\n for (const c of matches) {\n out += `## ${c.category}\\n\\n**Symptom:** ${c.symptom}\\n\\n**Fix:** ${c.fix}\\n${c.uiNote ? `\\n_UI note:_ ${c.uiNote}\\n` : \"\"}\\n`;\n }\n return out;\n}\n\nfunction getSkillSection(skillId: string, sectionId: string): string {\n const skill = findSkill(skillId);\n if (!skill) return `Skill \"${skillId}\" not found. Use \\`list_skills\\` for available ids.`;\n if (!sectionId) {\n let out = `# ${skill.name}\\n\\n${skill.whenToUse}\\n\\n## Sections\\n`;\n for (const sec of skill.sections) out += `- \\`${sec.id}\\` — ${sec.tagline}\\n`;\n return out;\n }\n const section = findSection(skillId, sectionId);\n if (!section) {\n let out = `Section \"${sectionId}\" not in skill \"${skillId}\". Available:\\n`;\n for (const sec of skill.sections) out += `- \\`${sec.id}\\` — ${sec.tagline}\\n`;\n return out;\n }\n return `# ${skill.name} → ${section.title}\\n\\n${section.tagline}\\n\\n${section.body}\\n\\n_Source: ${skill.source}_`;\n}\n\nfunction getComponent(name: string): string {\n const c = findComponent(name);\n if (!c) return `Component \"${name}\" not found. Use \\`list_primitives\\` to discover.`;\n let out = `# ${c.name}\\n\\n**Group:** ${c.group}`;\n const importPath = c.importPath ?? `@godxjp/ui/${c.group === \"providers\" ? \"app\" : c.group}`;\n out += ` · **Import:** \\`import { ${c.name} } from \"${importPath}\"\\`\\n\\n`;\n if (c.deprecated) {\n out += `> ⚠️ **DEPRECATED.** Kept catalogued so you're steered to the replacement — see the tagline / Related below. Do not use in new code.\\n\\n`;\n }\n out += `${c.tagline}\\n\\n## Props\\n\\n`;\n out += `| Name | Type | Required | Default | Description |\\n|---|---|---|---|---|\\n`;\n for (const p of c.props) {\n out += `| \\`${p.name}\\` | \\`${p.type}\\` | ${p.required ? \"✓\" : \"\"} | ${p.defaultValue ? `\\`${p.defaultValue}\\`` : \"\"} | ${p.description} |\\n`;\n }\n if (c.usage && c.usage.length) {\n out += `\\n## How to use it\\n\\n`;\n for (const u of c.usage) out += `- ${u}\\n`;\n }\n if (c.useCases && c.useCases.length) {\n out += `\\n## When to reach for it (use cases)\\n\\n`;\n for (const u of c.useCases) out += `- ${u}\\n`;\n }\n out += `\\n## Example\\n\\n\\`\\`\\`tsx\\n${c.example}\\n\\`\\`\\`\\n\\n`;\n if (c.related && c.related.length) {\n out += `## Related — don't confuse / don't reinvent\\n\\n`;\n for (const r of c.related) out += `- ${r}\\n`;\n out += `\\n`;\n }\n if (c.docPath) out += `**Reference doc:** \\`docs/reference/${c.docPath}\\`\\n\\n`;\n out += `**Storybook:** \\`src/stories/${c.storyPath}\\`\\n\\n`;\n if (c.rules.length) {\n out += `**Cardinal rules:**\\n`;\n for (const n of c.rules) {\n const rule = findRule(n);\n out += rule ? `- #${n} — ${rule.title}\\n` : `- #${n}\\n`;\n }\n }\n return out;\n}\n\nfunction getPattern(name: string): string {\n const p = findPattern(name);\n if (!p) {\n const candidates = searchPatterns(name);\n if (candidates.length === 0) return `Pattern \"${name}\" not found.`;\n let out = `Pattern \"${name}\" not found. Closest:\\n`;\n for (const c of candidates) out += `- ${c.name} — ${c.tagline}\\n`;\n return out;\n }\n return `# Pattern: ${p.name}\\n\\n${p.tagline}\\n\\n**Tags:** ${p.tags.join(\", \")}\\n\\n\\`\\`\\`tsx\\n${p.code}\\n\\`\\`\\`\\n`;\n}\n\nfunction getRule(num?: number): string {\n if (num !== undefined) {\n const r = findRule(num);\n if (!r) return `Rule ${num} not found. Valid: 1-${CARDINAL_RULES.length}.`;\n return `# Rule ${r.number} — ${r.title}\\n\\n${r.body}\\n`;\n }\n let out = `# Cardinal rules (${CARDINAL_RULES.length})\\n\\n`;\n for (const r of CARDINAL_RULES) out += `## ${r.number}. ${r.title}\\n\\n${r.body}\\n\\n`;\n return out;\n}\n\nfunction getVocab(name?: string): string {\n if (name) {\n const v = findVocab(name);\n if (!v) return `Vocab \"${name}\" not found.`;\n let out = `# ${v.name}\\n\\n${v.concept}\\n\\n`;\n out += `**Values:** ${v.values.map((x) => `\\`${x}\\``).join(\" | \")}\\n\\n`;\n out += `**Used by:** ${v.usedBy.map((x) => `\\`${x}\\``).join(\", \")}\\n\\n`;\n if (v.notes) out += `**Notes:** ${v.notes}\\n`;\n return out;\n }\n let out = `# Prop vocabulary\\n\\n${PROP_VOCABULARY.length} shared types.\\n\\n`;\n for (const v of PROP_VOCABULARY) {\n out += `## ${v.name}\\n${v.concept}\\n\\nValues: ${v.values.map((x) => `\\`${x}\\``).join(\" | \")}\\n\\n`;\n }\n return out;\n}\n\nfunction getTokens(cat?: TokenCategory): string {\n const list = cat ? tokensByCategory(cat) : TOKENS;\n if (list.length === 0) return `No tokens${cat ? ` in \"${cat}\"` : \"\"}.`;\n let out = `# Design tokens${cat ? ` — ${cat}` : \"\"}\\n\\n`;\n const grouped = list.reduce<Record<string, typeof list>>((acc, t) => {\n (acc[t.category] ??= []).push(t);\n return acc;\n }, {});\n for (const [c, items] of Object.entries(grouped)) {\n out += `## ${c}\\n\\n| Name | Role | Value | Axis |\\n|---|---|---|---|\\n`;\n for (const t of items)\n out += `| \\`${t.name}\\` | ${t.role} | ${t.value ?? \"—\"} | ${t.axis ?? \"—\"} |\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction routeTaskTool(task: string): string {\n if (!task.trim())\n return \"Describe the task (e.g. 'design a premium agency hero', 'audit existing settings page').\";\n const results = routeTask(task);\n let out = `# Routing \"${task}\"\\n\\n`;\n for (const r of results) {\n out += `- **skill:** \\`${r.skill}\\`, **section:** \\`${r.section}\\` \\n ${r.why}\\n`;\n if (r.alsoSee?.length) out += ` _Also see:_ ${r.alsoSee.map((s) => `\\`${s}\\``).join(\", \")}\\n`;\n }\n out += `\\nFetch with: \\`get_skill_section skill=\"X\" section=\"Y\"\\``;\n return out;\n}\n\nfunction suggestPrimitive(useCase: string): string {\n const q = useCase.trim().toLowerCase();\n if (!q) return \"Describe your use case.\";\n const suggestions: Array<{ component: string; rationale: string; score: number }> = [];\n const check = (kw: string[], component: string, rationale: string, weight = 2) => {\n if (kw.some((k) => q.includes(k))) suggestions.push({ component, rationale, score: weight });\n };\n check(\n [\"form\", \"submit\", \"validation\", \"register\", \"sign up\"],\n \"Form + FormField\",\n \"RHF + zod composition.\",\n 5,\n );\n check(\n [\"table\", \"rows\", \"columns\"],\n \"DataTable / Table\",\n \"DataTable for chrome (toolbar+pagination+batch). Table for slim primitive.\",\n 5,\n );\n check(\n [\"modal\", \"dialog\", \"confirm\"],\n \"Dialog / AlertDialog\",\n \"Radix Dialog. AlertDialog for destructive.\",\n 4,\n );\n check([\"drawer\", \"side panel\", \"sheet\"], \"Sheet\", \"Side panel for filters/settings.\", 4);\n check([\"toast\", \"notification\"], \"toast / Toaster\", \"Sonner-backed.\", 4);\n check(\n [\"loading\", \"saving\", \"spinner\"],\n \"Spinner / Form loading prop\",\n \"Spinner=active work, Skeleton=init fetch.\",\n 3,\n );\n check([\"alert\", \"banner\"], \"Alert\", \"5 semantic colors × outlined/banner.\", 3);\n check(\n [\"select\", \"dropdown\"],\n \"Select / AutoComplete\",\n \"Select=discrete options, AutoComplete=free-text+suggestions.\",\n 3,\n );\n check([\"filter\"], \"Form layout='inline' + pattern 'filter-bar'\", \"Inline form above table.\", 4);\n check(\n [\"delete\", \"destructive\"],\n \"Pattern 'confirm-destructive'\",\n \"Card accent='destructive' + typed-name confirm.\",\n 4,\n );\n if (!suggestions.length)\n return `No direct match for \"${useCase}\". Try \\`list_primitives\\` or \\`search_components\\`.`;\n suggestions.sort((a, b) => b.score - a.score);\n let out = `# Suggestions for \"${useCase}\"\\n\\n`;\n for (const s of suggestions) out += `- **${s.component}** — ${s.rationale}\\n`;\n return out;\n}\n\nfunction searchComponents(query: string): string {\n const q = query.trim().toLowerCase();\n if (!q) return listPrimitives();\n const matches = COMPONENTS.map((c) => {\n let score = 0;\n if (c.name.toLowerCase().includes(q)) score += 5;\n if (c.tagline.toLowerCase().includes(q)) score += 2;\n if (c.props.some((p) => p.name.toLowerCase().includes(q))) score += 1;\n return { c, score };\n })\n .filter((m) => m.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, 12);\n if (!matches.length) return `No matches for \"${query}\".`;\n let out = `# Search \"${query}\" — ${matches.length} matches\\n\\n`;\n for (const { c, score } of matches)\n out += `- **${c.name}** (${c.group}, ${score}) — ${c.tagline}\\n`;\n return out;\n}\n\nfunction lintJsx(jsx: string): string {\n const issues: string[] = [];\n const check = (regex: RegExp, msg: string) => {\n if (regex.test(jsx)) issues.push(msg);\n };\n // Lowercase HTML tags only — React PascalCase (Button) MUST NOT match.\n check(/<button[\\s>]/, \"Use `<Button>` instead of raw `<button>` (rule 29).\");\n check(/<input[\\s>]/, \"Use `<Input>` instead of raw `<input>` (rule 29).\");\n check(/<select[\\s>]/, \"Use `<Select>` instead of raw `<select>` (rule 29).\");\n check(/<textarea[\\s>]/, \"Use `<Textarea>` instead of raw `<textarea>` (rule 29).\");\n check(\n /bg-(red|blue|green|yellow|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|indigo|violet|purple|fuchsia|pink|rose)-\\d{2,3}\\b/,\n \"Use semantic token utilities (`bg-primary`/`bg-destructive`) not raw color scales (rule 2).\",\n );\n check(\n /<Tag[\\s\\S]*?color=[\"']error[\"']/i,\n 'Tag `color=\"error\"` → `\"destructive\"` (v5.0, PR #60).',\n );\n check(\n /<Badge[\\s\\S]*?variant=[\"']error[\"']/i,\n 'Badge `variant=\"error\"` → `\"destructive\"` (v5.0, PR #63).',\n );\n check(\n /(Flex|Space|Grid|Masonry)[\\s\\S]*?(gap|size)=[\"']middle[\"']/i,\n '`\"middle\"` → `\"default\"` for Flex/Space/Grid/Masonry (v5.0).',\n );\n check(/<IconButton[\\s\\S]*?size=[\"']default[\"']/i, 'IconButton `size=\"default\"` → `\"md\"` (v5.0).');\n check(\n /<SegmentedControl[\\s\\S]*?size=[\"']sm[\"']/i,\n 'SegmentedControl `size=\"sm\"` → `\"small\"` (v5.0).',\n );\n check(\n /<PageContent[\\s\\S]*?padding=[\"'](compact|comfortable)[\"']/i,\n 'PageContent `padding=\"compact\"/\"comfortable\"` → `\"tight\"/\"cozy\"` (v5.0).',\n );\n check(\n /<Pagination[\\s\\S]*?justify=[\"']between[\"']/i,\n 'Pagination `justify=\"between\"` → `\"space-between\"` (v5.0).',\n );\n if (/<IconButton(?![^>]*aria-label)/i.test(jsx) && !/asChild/i.test(jsx)) {\n issues.push(\"`<IconButton>` should have `aria-label` (rule 6 — WCAG).\");\n }\n if (\n /cell:\\s*\\(\\{?\\s*row\\s*\\}?\\)\\s*=>/i.test(jsx) &&\n /export\\s+const\\s+\\w+\\s*:\\s*Story/i.test(jsx)\n ) {\n if (!/parameters[\\s\\S]{0,200}source[\\s\\S]{0,100}code:/i.test(jsx)) {\n issues.push(\n \"Stories with function-valued cell renderers MUST override `parameters.docs.source.code` (rule 34).\",\n );\n }\n }\n // Anti-AI tells\n if (/text-(red|blue|green|yellow)-\\d{2,3}\\b/.test(jsx))\n issues.push(\n \"Hard-coded color scales — use semantic tokens. Tells AI-slop palette (rule 2 + anti-AI-tells.visual.rainbow-chip-wall).\",\n );\n if (/h-\\[?100vh\\]?/.test(jsx))\n issues.push(\n \"`100vh` causes iOS Safari viewport jump — use `min-h-[100dvh]` (redesign.layout / soft.absolute-zero).\",\n );\n if (/className=[\"'][^\"']*(?:shadow-md|shadow-lg|shadow-xl)[\"']/.test(jsx))\n issues.push(\n \"Tailwind heavy shadows are an AI tell — use ultra-diffuse low-opacity (< 0.05) or tinted shadows (soft.absolute-zero, minimalist).\",\n );\n if (/Inter|Roboto|Helvetica|Open\\s*Sans/i.test(jsx))\n issues.push(\n \"Banned default fonts (Inter/Roboto/Helvetica/Open Sans). Use Geist/Clash Display/PP Editorial New (soft.absolute-zero, minimalist.negative-constraints).\",\n );\n if (/Acme|NovaCore|Flowbit|Quantix|VeloPay|John\\s+Doe|Jane\\s+Smith|Lorem\\s+Ipsum/i.test(jsx))\n issues.push(\n \"Generic placeholder content (Acme/NovaCore/John Doe/Lorem Ipsum). Use believable real-sounding names (anti-AI-tells.copy).\",\n );\n if (issues.length === 0) return \"✅ No issues found against the heuristic checks.\";\n let out = `# Lint findings — ${issues.length} issue${issues.length === 1 ? \"\" : \"s\"}\\n\\n`;\n for (const i of issues) out += `- ${i}\\n`;\n out += `\\nNote: heuristic only — not a substitute for the full CI gate.\\n`;\n return out;\n}\n","/**\n * Resource registry — exposes catalogs as MCP resources so agents\n * can discover + browse them without invoking tools.\n *\n * godx-ui://components — full component catalog (JSON)\n * godx-ui://components/{name} — single component (Markdown)\n * godx-ui://prop-vocabulary — full vocab (JSON)\n * godx-ui://tokens — all tokens (JSON)\n * godx-ui://tokens/{category} — tokens in category (JSON)\n * godx-ui://rules — all cardinal rules (Markdown)\n * godx-ui://rules/{number} — single rule (Markdown)\n * godx-ui://patterns — pattern catalog (JSON)\n * godx-ui://patterns/{name} — single pattern (Markdown)\n */\n\nimport { COMPONENTS, findComponent } from \"../data/components.js\";\nimport { PROP_VOCABULARY } from \"../data/prop-vocabulary.js\";\nimport { TOKENS, tokensByCategory, type TokenCategory } from \"../data/tokens.js\";\nimport { CARDINAL_RULES, findRule } from \"../data/rules.js\";\nimport { PATTERNS, findPattern } from \"../data/patterns.js\";\n\nexport const RESOURCE_DEFINITIONS = [\n {\n uri: \"godx-ui://components\",\n name: \"All components\",\n description: \"Full component catalog as JSON — name, group, tagline, props, example, rules.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://prop-vocabulary\",\n name: \"Shared prop vocabulary\",\n description: \"Cross-cutting prop types (SizeProp, StatusProp, ColorProp, LoadingProp, …) as JSON.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://tokens\",\n name: \"All design tokens\",\n description: \"Every CSS variable + role + value + axis as JSON.\",\n mimeType: \"application/json\",\n },\n {\n uri: \"godx-ui://rules\",\n name: \"Cardinal rules (34)\",\n description: \"The 34 binding rules from CLAUDE.md as Markdown.\",\n mimeType: \"text/markdown\",\n },\n {\n uri: \"godx-ui://patterns\",\n name: \"Code patterns\",\n description: \"Canonical pattern catalog (registration-form, settings-page, data-table, …) as JSON.\",\n mimeType: \"application/json\",\n },\n];\n\nexport async function readResource(uri: string): Promise<string> {\n // godx-ui://components\n if (uri === \"godx-ui://components\") {\n return JSON.stringify(COMPONENTS, null, 2);\n }\n // godx-ui://components/{name}\n if (uri.startsWith(\"godx-ui://components/\")) {\n const name = uri.slice(\"godx-ui://components/\".length);\n const c = findComponent(name);\n if (!c) throw new Error(`Component not found: ${name}`);\n return formatComponentMarkdown(c);\n }\n\n if (uri === \"godx-ui://prop-vocabulary\") {\n return JSON.stringify(PROP_VOCABULARY, null, 2);\n }\n\n if (uri === \"godx-ui://tokens\") {\n return JSON.stringify(TOKENS, null, 2);\n }\n if (uri.startsWith(\"godx-ui://tokens/\")) {\n const cat = uri.slice(\"godx-ui://tokens/\".length) as TokenCategory;\n return JSON.stringify(tokensByCategory(cat), null, 2);\n }\n\n if (uri === \"godx-ui://rules\") {\n let out = `# Cardinal rules (${CARDINAL_RULES.length})\\n\\n`;\n for (const r of CARDINAL_RULES) {\n out += `## ${r.number}. ${r.title}\\n\\n${r.body}\\n\\n`;\n }\n return out;\n }\n if (uri.startsWith(\"godx-ui://rules/\")) {\n const num = Number(uri.slice(\"godx-ui://rules/\".length));\n const r = findRule(num);\n if (!r) throw new Error(`Rule not found: ${num}`);\n return `# Rule ${r.number} — ${r.title}\\n\\n${r.body}\\n`;\n }\n\n if (uri === \"godx-ui://patterns\") {\n return JSON.stringify(PATTERNS.map(({ name, tagline, tags }) => ({ name, tagline, tags })), null, 2);\n }\n if (uri.startsWith(\"godx-ui://patterns/\")) {\n const name = uri.slice(\"godx-ui://patterns/\".length);\n const p = findPattern(name);\n if (!p) throw new Error(`Pattern not found: ${name}`);\n return `# ${p.name}\\n\\n${p.tagline}\\n\\n**Tags:** ${p.tags.join(\", \")}\\n\\n\\`\\`\\`tsx\\n${p.code}\\n\\`\\`\\`\\n`;\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n}\n\nfunction formatComponentMarkdown(c: ReturnType<typeof findComponent> & object): string {\n let out = `# ${c.name}\\n\\n**Group:** ${c.group}\\n\\n${c.tagline}\\n\\n`;\n out += `## Props\\n\\n`;\n out += `| Name | Type | Required | Default | Description |\\n|---|---|---|---|---|\\n`;\n for (const p of c.props) {\n out += `| \\`${p.name}\\` | \\`${p.type}\\` | ${p.required ? \"✓\" : \"\"} | ${p.defaultValue ? `\\`${p.defaultValue}\\`` : \"\"} | ${p.description} |\\n`;\n }\n out += `\\n## Example\\n\\n\\`\\`\\`tsx\\n${c.example}\\n\\`\\`\\`\\n`;\n return out;\n}\n"],"mappings":"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","names":["out"]}
|