@godxjp/ui-mcp 0.19.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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","../package.json"],"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\";\nimport pkg from \"../package.json\";\n\nasync function main() {\n const server = new Server(\n {\n name: \"godx-ui-mcp\",\n // Track the package version — never hardcode (see server.test.ts guard).\n version: pkg.version,\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, Flex, ResponsiveGrid, DataTable + ColumnDef, Badge,\n * FormField, Select, Dialog, Toolbar, …) 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 usage: [\n \"DO: Always wrap every page's content in PageContainer — it is the mandatory page shell. Pass `title` (required, rendered as `<h1>`) for every page; omitting it leaves the page without an accessible heading.\",\n \"DO: Use the `extra` prop (not a sibling div, not a wrapper) for action buttons or controls that sit right of the title row — e.g. `extra={<Button>新規作成</Button>}`. Use the `footer` prop for a pinned action bar below the body (e.g. Save/Cancel on a form page); combine with `stickyFooter` to pin it to the viewport bottom on scroll.\",\n \"DO: Use `variant='flush'` when the page body contains a full-bleed component like DataTable. Inside a flush container, wrap any padded strips (Toolbar, intro text) in `<PageContainer.Inset>` to align them with the header. Never add manual `px-*` or `p-*` padding to compensate — use PageContainer.Inset.\",\n \"DO: Pass `breadcrumb` as an ordered array of `{ label, to? }` objects from root to current page. The last item is automatically rendered without a link and receives `aria-current='page'`; earlier items with `to` become router `<Link>` elements. Never hand-roll a breadcrumb nav inside a PageContainer.\",\n \"DON'T: Use `density` to change individual control sizes — it cascades spacing across the entire page subtree. Set it once per page (e.g. `density='compact'` for data-dense list pages) and let all child components inherit it. Do not apply density classes manually.\",\n \"DON'T: Confuse PageContainer's prop names with the old PageHeader's prop names — PageContainer uses `subtitle` (not `description`) and `extra` (not `actions`). If you see those legacy names in old code, migrate them to PageContainer.\",\n ],\n useCases: [\n \"A master list page (e.g. invoices, journal entries, customers) where the header holds the page title, a 'New Invoice' button in `extra`, a breadcrumb trail, and a full-bleed DataTable as the body — use `variant='flush'` + `<PageContainer.Inset>` for the Toolbar above the table.\",\n \"A detail / edit form page where the footer holds Save and Cancel buttons — use `footer={<Flex direction='row'><Button>保存</Button><Button variant='outline'>キャンセル</Button></Flex>}` with `stickyFooter` so the actions remain reachable as the form scrolls.\",\n \"A settings or narrow-form page (e.g. account profile, entity configuration) where `variant='narrow'` constrains content to a readable column width and `stickyFooter` pins the submit bar.\",\n \"A dashboard page with KPI cards and chart sections — use `variant='default'` with `children={<Flex direction='col' gap='lg'>…</Flex>}` to vertically stack multiple Card/StatCard sections beneath the page title.\",\n \"Any deep-nav page in a multi-level admin (e.g. Accounting > Ledger > Journal Entry #42) where a 3-segment breadcrumb trail provides back-navigation without browser history dependence.\",\n \"A high-density data reconciliation page where an analyst needs to see maximum rows — use `density='compact'` to tighten all spacing across the DataTable, Toolbar, and controls in a single prop.\",\n ],\n related: [\n \"PageContainer.Inset — use INSIDE a `variant='flush'` PageContainer to re-introduce horizontal padding for strips like Toolbar or intro text that should align with the page header, while the surrounding DataTable stays full-bleed. Not a standalone page shell.\",\n \"PageContainer — always use PageContainer for new pages; it supports `children`, `footer`, `variant`, `density`, and `stickyFooter`. Legacy code using the old prop names (`description` → `subtitle`, `actions` → `extra`) should be migrated to PageContainer.\",\n \"AppShell — the outer shell that owns the sidebar/topbar layout grid; PageContainer lives inside AppShell's `children` slot. Do not put AppShell inside PageContainer — the nesting order is AppShell → PageContainer.\",\n \"SplitPane — use instead of PageContainer when the page body needs a fixed-width aside panel alongside main content (e.g. a detail drawer next to a list). PageContainer has no aside slot; SplitPane fills that gap and can itself be placed inside PageContainer's children.\",\n ],\n example: `import { PageContainer, Flex } 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 <Flex direction=\"col\" gap=\"lg\">{/* page content */}</Flex>\n </PageContainer>\n );\n}`,\n storyPath: \"layout/PageContainer.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Flex\",\n group: \"layout\",\n tagline:\n \"Token-spaced flex primitive with explicit direction, alignment, justification, and wrapping controls.\",\n props: [\n {\n name: \"direction\",\n type: '\"row\" | \"col\"',\n defaultValue: '\"col\"',\n description: \"Main axis direction. Use row for horizontal runs, col for vertical stacks.\",\n },\n {\n name: \"gap\",\n type: '\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"',\n defaultValue: '\"md\"',\n description: \"Token gap between children, shared with other layout primitives.\",\n },\n {\n name: \"align\",\n type: '\"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\"',\n description: \"Cross-axis alignment, emitted as a data attribute for the layout CSS.\",\n },\n {\n name: \"justify\",\n type: '\"start\" | \"center\" | \"end\" | \"between\" | \"around\" | \"evenly\"',\n description: \"Main-axis distribution, emitted as a data attribute for the layout CSS.\",\n },\n {\n name: \"wrap\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Allows children to wrap onto additional flex lines.\",\n },\n ],\n usage: [\n 'DO import from `@godxjp/ui/layout` and reach for Flex when the axis, alignment, justification, or wrap behavior is part of the component contract: `import { Flex } from \"@godxjp/ui/layout\"`.',\n \"DO keep spacing on the `gap` prop instead of raw `gap-*`, `space-*`, or padding utilities. Flex uses the same token scale as other layout primitives, so spacing remains tied to the design system.\",\n 'DO use `direction=\"row\"` with `wrap` for responsive control rows, chip clusters, and action groups that need more control than simple row composition.',\n 'DO use `direction=\"col\"` for vertical groupings that need explicit `align` or `justify` behavior. For pure vertical stacking without alignment control, `direction=\"col\"` is sufficient.',\n \"DON'T override the axis with `className` after choosing a direction prop. Keep the layout intent in props so catalog guidance and data attributes stay accurate.\",\n \"Flex is a plain div with React.HTMLAttributes<HTMLDivElement>; pass `id`, `role`, `aria-*`, `data-*`, and structural className values as needed, but do not use it as a semantic form or button wrapper.\",\n ],\n useCases: [\n \"Toolbar internals where controls should sit in a row, wrap on narrow widths, and stay vertically centered.\",\n \"Card headers that need title content on the left and actions on the right via `justify='between'` without hand-rolling flex utility classes.\",\n \"Empty-state or loading blocks that center content on both axes using `align='center'` and `justify='center'`.\",\n \"Form sub-sections where a vertical group needs stretched children or centered helper content beyond what a plain column Flex provides.\",\n \"Badge, chip, or tag clusters where wrapping is required but the caller also needs explicit gap control.\",\n \"Low-level layout composition inside custom components where raw flex classes would duplicate the primitive.\",\n ],\n related: [\n \"Flex `direction='col'` — the standard pattern for ordinary vertical block spacing; use explicit `align`, `justify`, or `wrap` props when you need more control.\",\n \"Flex `direction='row'` — the standard pattern for simple horizontal groups; add `wrap` and `align='center'` for the typical row with wrapped centered items.\",\n \"ResponsiveGrid — use for equal-width, multi-column tile layouts. Flex arranges children on one flex axis and does not provide column-count behavior.\",\n \"PageContainer — page scaffold and padding context. Flex is an inner layout primitive used inside page sections, cards, dialogs, and toolbars.\",\n ],\n example: `import { Flex } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Flex direction=\"row\" gap=\"sm\" align=\"center\" justify=\"between\" wrap>\n <SearchSummary />\n <Flex direction=\"row\" gap=\"xs\" align=\"center\" wrap>\n <Button variant=\"outline\">リセット</Button>\n <Button>適用</Button>\n </Flex>\n</Flex>`,\n storyPath: \"layout/Flex.stories.tsx\",\n rules: [2, 40],\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 StatCard.\",\n },\n ],\n usage: [\n \"DO place StatCard tiles directly as immediate children — StatCard IS already a bordered card; never wrap it in an extra <Card><CardContent>. The canonical pattern is <ResponsiveGrid columns={4}><StatCard .../><StatCard .../></ResponsiveGrid>.\",\n \"DO use columns={2|3|4} to declare the target desktop column count — the grid collapses automatically to 1 column on narrow containers (mobile-first via CSS container queries), via 2-column intermediate at ≥640px, then full target count at ≥1024px. There is no 'columns={1}' — omit the grid for single-column flows.\",\n \"DO NOT place a DataTable inside a ResponsiveGrid column beside a card or chart. DataTable must occupy its own full-width row in a Card with CardContent flush. Nesting a multi-column table in a grid column squeezes CJK text to one character per line (see rule 37).\",\n \"DO use ResponsiveGrid for page-level spacing — it applies the correct gap token (--space-stack-md) automatically. Never add raw gap-* / p-* / space-* utilities to the page layout around tiles; compose spacing through this component instead (rule 40).\",\n \"DO render SkeletonStat children in place of StatCard tiles while KPIs are loading — same columns prop, same count as the real tiles. Switch to real StatCard once data resolves.\",\n \"The grid uses CSS container queries, not viewport media queries — it responds to its containing block width, not the window. Ensure the container is not artificially constrained (e.g. inside a narrow SplitPane column) or column expansion will never trigger.\",\n ],\n useCases: [\n \"Dashboard KPI row: rendering 3–4 StatCard tiles (revenue, member count, active invoices, overdue amount) that reflow to a 2-column stacked grid on tablet and a single column on mobile.\",\n \"Summary header above a list page: a 2-column grid of two StatCard totals (e.g. total payable vs total paid) sitting above a Toolbar and DataTable.\",\n \"Accounting period overview: 4 StatCard tiles (opening balance, total debits, total credits, closing balance) that collapse gracefully on narrow viewports without any custom CSS.\",\n \"Loading state for a KPI row: identical <ResponsiveGrid columns={4}> wrapping four <SkeletonStat /> placeholders rendered while async data is in flight, swapped for real StatCard tiles once resolved.\",\n \"Settings or profile summary cards: 2- or 3-column grid of Card+CardContent blocks (not StatCard) showing categorized read-only data groups before a detail form below.\",\n \"Entity comparison panel: a columns={3} grid comparing three legal entities side-by-side with a Card+CardContent per entity, which collapses to 2-up on tablet and stacks on mobile.\",\n ],\n related: [\n \"Flex — use Flex (direction col or row) for sequential blocks of mixed-width content (forms, description lists, button rows). Use ResponsiveGrid only when you want equal-width, auto-reflowing tile columns.\",\n \"SplitPane — use SplitPane for a fixed two-panel side-by-side layout with a defined primary/secondary ratio that does NOT collapse to stacked tiles. Use ResponsiveGrid when you want automatic column count collapse on narrow screens.\",\n \"StatCard — the canonical direct child of ResponsiveGrid for KPI tiles. StatCard is self-contained (draws its own bordered card); never wrap it in Card/CardContent when placing it inside ResponsiveGrid.\",\n \"SkeletonStat — the loading-state sibling of StatCard, used as a drop-in placeholder child of ResponsiveGrid with the same columns count while KPI data is in flight.\",\n ],\n example: `import { ResponsiveGrid } from \"@godxjp/ui/layout\";\nimport { StatCard } from \"@godxjp/ui/data-display\";\n\n<ResponsiveGrid columns={4}>\n <StatCard label=\"総会員数\" value=\"12,400\" />\n <StatCard label=\"公開中クーポン\" value=\"8\" />\n <StatCard label=\"月間利用数\" value=\"3,210\" />\n <StatCard 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 usage: [\n \"DO pass a <Sidebar> node to `sidebar` (required) and page content to `children` (required) — these are the only two required props. Everything else is optional and omitting optional slots simply removes that zone from the rendered DOM.\",\n \"DO use the auto-built topbar rail (logo / topbarLeft / topbarRight) for simple shells. Pass a fully configured <Topbar> to the `topbar` prop only when you need live handlers (entity switcher via productMenu, search, notifications, user avatar) — when `topbar` is provided, logo/topbarLeft/topbarRight are ignored entirely.\",\n \"DO wire a single `sidebarCollapsed` boolean between AppShell's `sidebarCollapsed` prop and Sidebar's `collapsed` prop — AppShell sets `data-collapsed='true'` on the root div (which CSS reads for width transitions) but does NOT own the collapsed state itself; lift the state and pass it down to both.\",\n \"DO place breadcrumb content in AppShell's `breadcrumb` prop (renders in the `app-breadcrumb` div inside `<main>` ABOVE children) — do NOT hand-roll a breadcrumb bar as the first child of children, and do NOT put breadcrumbs inside <Sidebar>.\",\n \"DO NOT nest a second AppShell or AppShell inside AppShell's children — AppShell renders the root `app-root` div; nesting shells breaks the CSS grid layout.\",\n \"DO NOT add padding directly to children expecting it to reach the viewport edge — AppShell's `<main>` is a scroll container; use <PageContainer> (or <PageContainer.Inset> inside a flush PageContainer) inside children to get standard page padding.\",\n ],\n useCases: [\n \"Full admin SPA shell: AppShell wraps a <Sidebar> nav rail and a <Topbar> (with productMenu entity-switcher, onSearchOpen, onNotificationsOpen, user avatar) and every Inertia page renders as children inside a <PageContainer>.\",\n \"Collapsible-sidebar layout: maintain a `collapsed` boolean in a persistent Inertia layout component, pass it to both AppShell's `sidebarCollapsed` and Sidebar's `collapsed`, wire Topbar's `onToggleCollapsed` to flip it — AppShell handles the CSS transition automatically.\",\n \"Multi-tenant accounting app: pass a <Topbar productMenu={<DropdownMenuContent>…</DropdownMenuContent>}> to AppShell's `topbar` slot so the legal-entity chip opens an inline switcher without a modal.\",\n \"App-level footer (e.g. version/build info, compliance notice): pass a <footer> node to AppShell's `footer` prop — it renders outside `<main>` so it stays pinned below the scroll area.\",\n \"Rapid prototype or internal tool where you want a branded shell with minimal topbar: skip the `topbar` prop entirely and use `logo`, `topbarLeft`, `topbarRight` to build the rail declaratively without instantiating <Topbar>.\",\n \"Breadcrumb-aware shell: pass a <Breadcrumb items={…}> node to AppShell's `breadcrumb` prop so the breadcrumb strip appears above all page content without each page having to render it separately.\",\n ],\n related: [\n \"AppShell — opinionated wrapper that composes AppShell + a frozen default Topbar in three props (menu, children, breadcrumb). Use AppShell for quick scaffolding when the default GodX product chip and no-op search/notification handlers are acceptable; switch to AppShell directly the moment you need a custom entity switcher, real onSearchOpen, user slot, or any topbar configuration.\",\n \"Sidebar — the canonical node to pass as AppShell's `sidebar` prop; owns activeId, collapsible submenu groups, collapsed icon-only mode, and section labels. Never hand-roll a nav list inside the sidebar slot.\",\n \"Topbar — the structured topbar component to pass to AppShell's `topbar` prop when you need live product/project chip switchers, search, notifications, sidebar toggle, user avatar, or rightSlot extras. When `topbar` is provided, AppShell's logo/topbarLeft/topbarRight props are ignored.\",\n \"PageContainer — the mandatory direct child inside AppShell's `children` for every page; provides title, subtitle, extra actions, breadcrumb, footer, variant (flush/narrow/ghost), and density. Never render raw content directly as AppShell's child without a PageContainer wrapper.\",\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 }: { content: 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 content: 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 content: [\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 projectSidebar 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 \"AppShell — 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 }: { content: 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: \"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 usage: [\n \"DO: pass all right-panel content via the `aside` prop — it renders inside a semantic `<aside>` element at a fixed rem width (sm=20rem, md=22rem). The `children` prop fills the main `1fr` column. Both accept any ReactNode.\",\n 'DO: choose `asideWidth=\"sm\"` for compact detail panels (filters, quick stats, key-value summaries) and the default `asideWidth=\"md\"` for richer panels (forms, timelines, long metadata lists).',\n \"DO: wrap SplitPane inside `PageContainer` or `PageContainer.Inset` — SplitPane provides no page padding of its own. It is a grid primitive, not a page scaffold.\",\n \"DON'T: expect two columns below 1080px. Below that breakpoint SplitPane stacks to a single column (main on top, aside below). Never use it for layouts that must remain side-by-side on tablet or mobile — use CSS Grid or `ResponsiveGrid` instead.\",\n \"DON'T: add a CSS `overflow: hidden` or fixed height on the SplitPane wrapper; both columns carry `min-width: 0` to handle overflow correctly, and the grid uses `minmax(0, 1fr)` — adding external constraints will break the overflow contract.\",\n \"DON'T: hand-roll a two-column div layout with flexbox or CSS Grid when SplitPane already ships — that duplicates the responsive breakpoint logic and the semantic `<aside>` element.\",\n ],\n useCases: [\n \"Invoice / transaction detail page: list of records in `children` (DataTable), selected-record detail panel in `aside` (Descriptions + Timeline).\",\n 'Accounting ledger drill-down: account list on the left, chart-of-accounts metadata or running balance breakdown on the right using `asideWidth=\"sm\"`.',\n \"Document review workflow: PDF or rich-text viewer in `children`, approval form or annotation panel in `aside`.\",\n \"Settings page with a category list or Steps navigator in `children` and a live preview or summary card in `aside`.\",\n \"Kanban or task board where the main area holds the board columns and the aside shows the focused task detail without navigating away.\",\n ],\n related: [\n \"ResponsiveGrid — use when you need more than two columns, or when both columns must have equal or percentage-based widths rather than a fixed-rem aside. SplitPane always gives main a `1fr` and aside a fixed rem width.\",\n \"PageContainer — use as the outer scaffold that provides page padding and vertical rhythm; nest SplitPane inside PageContainer, not the other way around.\",\n \"Sheet — use when the detail/context panel should slide in as an overlay (drawer) rather than sitting permanently beside the main content. Prefer Sheet on mobile or when the aside content is secondary and on-demand.\",\n \"Flex direction='col' — use when content is purely vertical (single column, sequential sections). SplitPane is the right pick only when a persistent side panel is needed at the same hierarchy level as the main content.\",\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 usage: [\n \"DO import from `@godxjp/ui/layout` (not from a navigation or general sub-path) and pass a single `items` prop — an ordered array of `{ label, to? }` objects. No children, no sub-components, no render-prop API.\",\n 'DO omit `to` on the last (current-page) segment — the component automatically renders it as a `<span aria-current=\"page\">` instead of a router `<Link>`. Passing `to` on the last item does NOT make it a link; drop it intentionally.',\n \"DO pass the Breadcrumb node as a ReactNode to the `breadcrumb` prop of `AppShell` (or `AppShell`) for shell-level breadcrumbs, or to `PageContainer`'s `breadcrumb` prop (which accepts `BreadcrumbItemProp[]` directly — not a ReactNode). When passing to `PageContainer`, pass the raw array; when passing to `AppShell`, wrap it: `breadcrumb={<Breadcrumb items={…} />}`.\",\n 'DON\\'T hand-roll a breadcrumb strip (divs with chevrons, anchors, separators) — Breadcrumb ships the `<nav aria-label=\"Breadcrumb\">` + `<ol>` + `aria-hidden` chevrons. Any custom trail is a violation of the no-hand-roll rule and will fail `npm run ui:audit`.',\n \"DON'T use Breadcrumb for tab-style or step-style navigation (multi-step forms, wizard progress). Those flows belong to `Steps`. Breadcrumb is strictly a spatial location trail, not a process indicator.\",\n \"The component is fully uncontrolled and stateless — it renders whatever `items` you pass. Dynamic breadcrumbs (route-derived, breadcrumb context, etc.) must be assembled in the parent and passed down as a plain array; there is no internal routing awareness.\",\n ],\n useCases: [\n \"Per-page location trail on any admin page deeper than two levels — e.g. Home → Accounting → Invoices → Invoice #1042 — passed to `PageContainer`'s `breadcrumb` prop so it appears above the page `<h1>`.\",\n \"Persistent shell-level breadcrumb in a `AppShell` or `AppShell` layout that updates as the user navigates between Inertia/React Router pages; constructed from route params and passed as a ReactNode to `AppShell`'s `breadcrumb` prop.\",\n \"Master-detail drill-down in an accounting app: the detail page (journal entry, partner, bank account) shows a breadcrumb back to the list and to the domain root, giving the user a one-click escape without using the browser back button.\",\n \"Embedded sub-panel breadcrumb inside a `SplitPane` or `Sheet` where a secondary content area has its own navigable hierarchy and needs a compact location indicator.\",\n \"Audit log or document history page where the entity being reviewed (invoice, payment) is the current segment and the parent module (Accounting, Receivables) is a clickable ancestor.\",\n \"Prefetch pairing: wrap ancestor segments' `to` values with `PrefetchLink` semantics by putting them in `items` — each non-last item with `to` is already rendered as a router `<Link>`, so hovering naturally prefetches if `PrefetchLink` is used elsewhere on the same route.\",\n ],\n related: [\n \"PageContainer — accepts `breadcrumb` as `BreadcrumbItemProp[]` (raw array, not a ReactNode); use this when each page owns its own breadcrumb and you want it co-located with the page title, actions, and body.\",\n \"AppShell — accepts `breadcrumb` as `ReactNode`; pass `<Breadcrumb items={…} />` here when the breadcrumb is a persistent shell-level strip that sits above all page content rather than being owned by individual pages.\",\n \"Steps — use instead of Breadcrumb when showing progress through an ordered multi-step flow (wizard, checkout, onboarding); Steps conveys sequence and completion state, not spatial location.\",\n \"PrefetchLink — if ancestor breadcrumb segments should prefetch their destination query on hover/focus, consider pairing the `to` values with `PrefetchLink` in a custom breadcrumb or pre-warming the cache on mount; Breadcrumb's internal links are plain react-router-dom `<Link>` with no prefetch behaviour.\",\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 usage: [\n \"DO pick the right variant for intent: `default` (primary CTA, one per section), `destructive` (irreversible actions like delete/revoke), `outline` (secondary actions alongside a primary), `secondary` (less prominent actions), `ghost` (toolbar icon-only actions), `link` (inline text-style navigation without an underline by default).\",\n \"DO use icon-only sizes (`icon`, `icon-xs`, `icon-sm`, `icon-lg`) exclusively for buttons that contain only an SVG — these sizes set equal width/height. For text+icon buttons use `default|sm|lg|xs` sizes; icons inside are auto-sized to 1rem via `[&_svg:not([class*='size-'])]:size-4`.\",\n \"DO use `asChild` to render the button as a React Router/Inertia `<Link>` or native `<a>` while keeping all button styling and a11y: `<Button asChild variant=\\\"outline\\\"><Link href={route('invoices.show', id)}>詳細</Link></Button>`. Never wrap a `<button>` around an `<a>` — that is invalid HTML.\",\n \"DON'T use raw `<button>` elements anywhere in the UI — always use this `Button`. The only exception is an `aria-hidden` native control used as an e2e/a11y hook paired with a visible godx-ui control.\",\n 'DO set `type=\"submit\"` explicitly on form submit buttons (the default HTML button type inside `<form>` is already `submit`, but being explicit prevents accidental double-submissions when a `type=\"button\"` sibling exists). For cancel/reset actions set `type=\"button\"` to avoid accidental form submission.',\n \"DON'T apply raw padding, height, or `rounded-*` overrides to `Button` via `className` — the size variants encode the full box model. If a custom size is truly needed, use `buttonVariants` from `@godxjp/ui/general` to compose a new cva class rather than fighting the existing ones.\",\n ],\n useCases: [\n 'Primary form submission in a Dialog or Sheet (e.g. `<Button type=\"submit\" disabled={form.processing}>保存</Button>`) — the `disabled` prop greys it out and blocks pointer events, preventing double-submit during async operations.',\n 'Destructive confirmation inside a Dialog — pair `tone=\"destructive\"` Button as the confirm action and `variant=\"outline\"` as Cancel; never use `variant=\"default\"` for a delete action.',\n 'Icon-only toolbar actions in a DataTable column (edit, delete, copy) using `size=\"icon-sm\"` + `variant=\"ghost\"` + a Lucide icon child — gives equal-width square targets that don\\'t distort the row.',\n \"Navigation links styled as buttons (e.g. 'New Invoice', 'Back to list') using `asChild` + Inertia `<Link>` — preserves SPA navigation while using the button's visual treatment.\",\n \"Async mutation trigger in an accounting workflow (e.g. 'Sync from MF', 'Export CSV') — disable on processing state; pair with `AlertMutationFeedback` for error/retry UI rather than inline `try/catch` alerts.\",\n \"Refetch / retry trigger when NOT using TanStack Query — for manual cache refresh inside a TanStack Query context use `ButtonRefetch` instead, which owns its own `disabled`/`onClick` lifecycle.\",\n ],\n related: [\n \"DropdownMenu — when a button needs to reveal a list of actions (e.g. 'Actions ▾' in a DataTable row), wrap the Button as a `DropdownMenuTrigger` inside a `DropdownMenu` compound; don't open a Sheet/Dialog just to show a list of options.\",\n \"ButtonRefetch — a pre-wired Button variant from `@godxjp/ui/query` that binds directly to a TanStack Query result (shows spinner, auto-disables while fetching, retries on click). Use it instead of a raw Button whenever the action is a query refetch — do not pass `onClick`/`disabled` to it manually.\",\n \"AlertMutationFeedback — for surfacing mutation errors and a retry action; it renders its own retry Button internally. Do not add a separate Button alongside AlertMutationFeedback for the same mutation.\",\n \"PrefetchLink — use when the goal is purely navigation with hover-prefetch (Inertia v3 prefetch); it renders as an `<a>` not a button. Only reach for `Button asChild + Link` when the navigation control must look like a button (primary CTA style).\",\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: { value: 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: \"{ value: 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: { value: 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 { value: \"id\", header: \"Invoice #\", width: \"w-32\" },\n { value: \"customer\", header: \"Customer\" },\n {\n value: \"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 { value: \"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<{ value: 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: \"DataGrid\",\n group: \"data-display\",\n tagline:\n \"Full-feature data grid — the TanStack Table adapter on `@godxjp/ui/data-grid` (NOT the data-display barrel). Adds column sort, global search, column visibility ('set view'), per-page + numbered pagination, row selection + bulk actions, and density over the styled Table* primitives. Defaults to SERVER/manual mode: wire sorting/columnFilters/globalFilter/pagination to your AJAX query (pass rowCount). Use DataTable instead for a lean server-driven list that must NOT pull TanStack. Requires the `@tanstack/react-table` peer dependency.\",\n props: [\n {\n name: \"columns\",\n type: \"ColumnDef<T, unknown>[]\",\n required: true,\n description:\n \"TanStack column definitions ({ accessorKey, header, cell, enableSorting, enableHiding, meta:{label} }). Set enableHiding:false to keep a column out of the ViewOptions menu; meta.label gives a human label there when header is JSX.\",\n },\n {\n name: \"data\",\n type: \"T[]\",\n required: true,\n description: \"Row data. Empty + loading=false renders a built-in EmptyState in the body.\",\n },\n {\n name: \"getRowId\",\n type: \"(row: T) => string\",\n description: \"Stable row id (defaults to row[rowIdKey], rowIdKey defaults to 'id').\",\n },\n {\n name: \"enableRowSelection\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Adds a checkbox column + header select-all; pair with DataGrid.BulkActions.\",\n },\n {\n name: \"sorting / onSortingChange\",\n type: \"SortingState / OnChangeFn<SortingState>\",\n description:\n \"Server sort: pass both and sort in your query (manualSorting defaults true). Omit both for client sort.\",\n },\n {\n name: \"globalFilter / onGlobalFilterChange\",\n type: \"string / OnChangeFn<string>\",\n description:\n \"Global search term, surfaced by DataGrid.Search. Server or client like sorting.\",\n },\n {\n name: \"pagination / onPaginationChange / rowCount\",\n type: \"PaginationState / OnChangeFn / number\",\n description:\n \"Server pagination: pass pagination + onPaginationChange + rowCount (total). Omit for client pagination.\",\n },\n {\n name: \"columnVisibility / onColumnVisibilityChange\",\n type: \"VisibilityState / OnChangeFn<VisibilityState>\",\n description:\n \"Column show/hide state surfaced by DataGrid.ViewOptions ('set view'). Internal if omitted.\",\n },\n {\n name: \"manualSorting / manualFiltering / manualPagination\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Default true (server/AJAX). Set false to let TanStack sort/filter/paginate in-browser.\",\n },\n {\n name: \"loading / density / onRowClick / empty\",\n type: \"boolean / 'compact'|'comfortable' / (row:T)=>void / ReactNode\",\n description: \"Loading row, controlled density, clickable rows, custom empty content.\",\n },\n ],\n usage: [\n \"Import from `@godxjp/ui/data-grid` — it lives on its own subpath because it pulls @tanstack/react-table; it is NOT in the runtime-neutral root or the data-display barrel.\",\n \"Compose the compound parts as children: <DataGrid.Toolbar> (holds <DataGrid.BulkActions>, <DataGrid.Search>, <DataGrid.ViewOptions>, <DataGrid.DensityToggle>), then <DataGrid.Content> (auto-included if omitted) and <DataGrid.Pagination pageSizeOptions=[...]>.\",\n \"Server mode (default): drive sorting/globalFilter/pagination from useQuery and pass rowCount. Client mode: set manualSorting/manualFiltering/manualPagination={false} and the grid handles it on the data array.\",\n ],\n related: [\"DataTable\", \"Table\", \"DataState\", \"Select\", \"DropdownMenu\"],\n example: `import { DataGrid, type ColumnDef } from \"@godxjp/ui/data-grid\";\nimport { Flex } from \"@godxjp/ui/layout\";\n\ntype Row = { id: string; name: string; amount: number };\nconst columns: ColumnDef<Row, unknown>[] = [\n { accessorKey: \"name\", header: \"Name\", meta: { label: \"Name\" } },\n { accessorKey: \"amount\", header: \"Amount\", meta: { label: \"Amount\" } },\n];\n\nexport function Grid({ rows }: { rows: Row[] }) {\n return (\n <DataGrid columns={columns} data={rows} getRowId={(r) => r.id} enableRowSelection manualSorting={false} manualFiltering={false} manualPagination={false}>\n <DataGrid.Toolbar>\n <Flex direction=\"row\" align=\"center\" gap=\"sm\" className=\"ms-auto\">\n <DataGrid.Search />\n <DataGrid.ViewOptions />\n <DataGrid.DensityToggle />\n </Flex>\n </DataGrid.Toolbar>\n <DataGrid.Content />\n <DataGrid.Pagination pageSizeOptions={[10, 20, 50]} />\n </DataGrid>\n );\n}`,\n storyPath: \"data-display/DataGrid.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: '\"md\" | \"compact\"',\n defaultValue: '\"md\"',\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 usage: [\n 'DO always wrap body content in <CardContent> — the bare <Card> div has zero inner padding; content renders flush against card edges without it. Never add className=\"p-4\" directly on <Card> as a substitute.',\n \"DO put titles/descriptions in <CardHeader>/<CardTitle>/<CardDescription>. Use <CardHeader banded> for a visually separated muted-background header band (mirrors <CardFooter separated>). Pair with <CardAction> inside a flex-row CardHeader for header-level action buttons.\",\n \"DO use <CardContent flush> for edge-to-edge children such as DataTable, Table, or a Tabs list — this removes horizontal padding. Combine with <CardContent tight> when there is no visual gap needed after the header, and <CardContent solo> when there is no CardHeader above (top padding matches the card shell).\",\n \"DO use <CardFooter separated> to render a top-bordered action band (Save/Cancel buttons, table summary row). Use <CardFooter flush> for a full-bleed footer bar.\",\n \"DO use <CardCover> as the first child for full-bleed cover media — the header below it uses card-section top spacing, not the card shell.\",\n \"DON'T hand-roll a stat/KPI tile with <Card> + raw divs — use <StatCard> (label, value, hint, delta, layout, inverse props) which is already a Card internally with correct token-driven layout.\",\n ],\n useCases: [\n 'Dashboard KPI summary row: wrap each metric in <StatCard> (or a plain <Card size=\"compact\"> with <CardContent>) to render a uniform grid of labeled value tiles with optional trend deltas.',\n 'Invoice or order detail panel: <Card accent=\"primary\"> with <CardHeader banded><CardTitle>, <CardContent> body rows (use <Descriptions> inside), and <CardFooter separated> holding approve/reject buttons.',\n \"Section container on a settings or form page: a single <Card> wrapping a <CardHeader><CardTitle> plus <CardContent> containing <FormField> groups, with <CardFooter separated> for Save/Cancel.\",\n \"Data table with toolbar: <Card> + <CardHeader> (title + filter controls in <CardAction>) + <CardContent flush> containing <DataTable> — <CardContent flush> removes horizontal padding so the table header spans full width.\",\n 'Featured announcement or alert card: <Card variant=\"featured\"> with an accent stripe (<accent=\"warning\">) to visually elevate a card above sibling cards on the page.',\n \"Media/cover card (e.g. entity profile): <CardCover> first (full-bleed image), then <CardHeader> + <CardContent> below it for structured metadata.\",\n ],\n related: [\n \"StatCard — use instead of a plain Card when rendering a KPI/metric tile (label + value + optional delta/hint). StatCard is a Card internally; do not re-wrap it in another Card.\",\n \"CardContent — mandatory inner wrapper for all body content inside Card. Provides the correct padding and supports flush/tight/solo variants. The only correct way to put padded content inside Card.\",\n \"Descriptions — use inside <CardContent> when body content is a label-value metadata list (e.g. entity details, invoice fields); do not hand-roll a dl/dt/dd grid.\",\n \"DataState / InfiniteQueryState — use instead of Card when the content is a TanStack Query-driven list that needs automatic skeleton, empty, and error states; Card does not manage loading lifecycle.\",\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 Toolbar 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 usage: [\n \"DO: Always wrap body content in <CardContent> — a bare <Card> has no internal padding, so any child placed directly inside it renders flush against the card edges.\",\n \"DO: Use <CardContent flush> for DataTable, Table, or Tabs — the flush prop removes horizontal padding so the content spans edge-to-edge inside the card border. Never add manual p-0 on the Card itself instead.\",\n \"DO: Use <CardContent tight> when placing a flush toolbar or a Tabs list directly below a CardHeader — tight removes the top gap so the header and the body connect without an awkward spacing gap.\",\n \"DO: Use <CardContent solo> when the card has no CardHeader above it — solo gives the top padding that matches the card shell, ensuring visual balance.\",\n \"DON'T: Nest a Toolbar inside <CardContent flush> — flush strips horizontal padding and Toolbar will lose its own padding. Put Toolbar outside the flush CardContent or in a separate non-flush CardContent above it.\",\n \"DON'T: Wrap a StatCard inside <Card><CardContent> — StatCard already renders its own Card border; double-wrapping produces a double border. Render StatCard directly in a ResponsiveGrid.\",\n ],\n useCases: [\n \"Wrapping a form body (Input, Select, Textarea fields) inside a Card that has a CardHeader title — ensures the form fields have correct internal padding.\",\n \"Hosting a DataTable inside a Card edge-to-edge: <CardContent flush><DataTable .../></CardContent> — the table occupies the full card width with the card's border acting as the table container.\",\n \"Dashboard detail panels where the card has no title — <CardContent solo> gives top padding equivalent to the card shell so the content doesn't sit too close to the top border.\",\n \"Placing a Descriptions or Timeline inside a card to display invoice/accounting details — <CardContent> provides the standard 16px (or density-adjusted) padding without needing manual className.\",\n \"Pairing with <CardHeader banded> and <CardFooter separated> in a multi-section layout such as a payment summary card — each section slot (header, content, footer) carries its own semantic spacing tokens.\",\n \"Putting a ScrollArea inside <CardContent> (not flush) to create a scrollable card body with consistent padding, e.g. a chat or log viewer panel.\",\n ],\n related: [\n \"Card — the parent container; CardContent is always a direct child of Card. Card itself has zero internal padding; every visible body padding comes from CardContent (or CardHeader/CardFooter). Never put content directly inside Card.\",\n \"StatCard — a self-contained KPI tile that IS already a Card; do not wrap it in <Card><CardContent>. Use StatCard directly inside a ResponsiveGrid.\",\n \"ScrollArea — place ScrollArea inside CardContent (non-flush) when the card body needs to scroll; do not put ScrollArea outside CardContent or you lose the card's internal padding.\",\n \"SkeletonStat — the loading placeholder for a StatCard tile; swap in SkeletonStat while KPI data is loading. For general Card loading shapes, use SkeletonTable or Skeleton primitives.\",\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: \"StatCard\",\n group: \"data-display\",\n tagline:\n \"KPI tile. ⚠️ StatCard 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 usage: [\n \"DO place StatCard directly as a child of ResponsiveGrid — it renders its own bordered Card shell internally, so no wrapping <Card> or <CardContent> is needed or allowed. Wrapping creates a double border.\",\n \"DO pass `delta` as a sign-prefixed string (e.g. '+12%' or '-3%') to get automatic color tone: '+' renders text-success, '-' renders text-destructive. For metrics where a negative delta is good (e.g. cost reduction, error rate), pass `inverse` so the tone is flipped correctly.\",\n \"DO use `hint` for secondary context (e.g. '先月比 +3%', 'last 30 days'). In the default `stacked` layout hint renders below the value; in `inline` layout it renders beside the label.\",\n \"DO NOT add an `accent` prop — accent is a Card prop and StatCard does not expose it. Passing accent has no effect and creates a false expectation.\",\n \"DO NOT hand-roll a KPI tile using a plain <Card><CardContent>. StatCard is the correct primitive and token-aligns the label/value/hint/delta slots automatically.\",\n \"WHILE data is loading, replace each StatCard with a <SkeletonStat /> at the same grid position — never render an empty value string or a spinner inside StatCard itself.\",\n ],\n useCases: [\n \"Dashboard KPI row: monthly revenue, invoice count, overdue balance, and collection rate displayed side-by-side in a ResponsiveGrid with delta trend vs previous period.\",\n \"Accounting summary header: total debits, total credits, and net balance for a journal entry list page, each with a hint showing the date range in scope.\",\n \"Coupon/membership admin overview: active members, live coupons, monthly redemptions, and total discount amount — the canonical example in the catalog.\",\n \"Inline variant for a narrow sidebar or detail panel where space is constrained: label on the left, large value on the right (layout='inline'), e.g. contract value next to a deal record.\",\n \"Cost or error-rate metrics where a falling number is positive: pass `inverse` so a '-15%' delta shows green, preventing misleading red-for-good UI.\",\n \"Loading state for any KPI grid: render the same ResponsiveGrid columns filled with <SkeletonStat /> components while the query is in-flight, then replace with StatCard tiles once data resolves.\",\n ],\n related: [\n \"ResponsiveGrid — required layout wrapper for StatCard grids; controls column count and responsive breakpoints. Always pair them together.\",\n \"SkeletonStat — exact loading placeholder shaped like a StatCard tile; swap in while KPI data is fetching, then replace with the real StatCard.\",\n \"Descriptions — use instead when displaying multiple label/value metadata pairs on a detail page (not headline KPIs); Descriptions is not card-bordered and does not show delta/hint slots.\",\n \"Card + CardContent — use when you need a general-purpose content container with a header, footer, or arbitrary body; do NOT wrap StatCard inside these.\",\n ],\n example: `import { StatCard } from \"@godxjp/ui/data-display\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n// ✅ StatCard sits directly in the grid — it draws its own card + border.\n<ResponsiveGrid columns={3}>\n <StatCard label=\"総会員数\" value=\"12,450\" hint=\"先月比 +3%\" />\n <StatCard label=\"月次売上\" value=\"¥8,200,000\" delta=\"+12%\" />\n <StatCard label=\"利用率\" value=\"68.4%\" />\n</ResponsiveGrid>\n\n// ❌ Double border — do NOT wrap StatCard in a Card:\n// <Card><CardContent><StatCard label=\"x\" value=\"1\" /></CardContent></Card>`,\n storyPath: \"data-display/StatCard.stories.tsx\",\n rules: [],\n },\n {\n name: \"Badge\",\n group: \"data-display\",\n tagline:\n \"Plain or lifecycle badge. Use `variant` for static chips, or `status` to auto-map lifecycle keys to semantic tone + icon. Labels never wrap.\",\n props: [\n {\n name: \"variant\",\n type: '\"default\" | \"secondary\" | \"outline\" | \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\"',\n defaultValue: '\"default\"',\n description:\n \"Visual variant. Overrides the auto-mapped status tone when status is provided.\",\n },\n {\n name: \"status\",\n type: \"string\",\n description:\n \"Lifecycle key. Known keys auto-map to variant + icon + i18n label; unknown keys fall back to neutral.\",\n },\n {\n name: \"icon\",\n type: \"React.ComponentType<{ className?: string }> | null\",\n description: \"Leading icon override. Pass null to suppress the auto status icon.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n description:\n \"Badge label. When omitted with status, Badge renders the translated lifecycle label or raw status.\",\n },\n ],\n usage: [\n \"DO pick the correct variant semantically: `success` (approved/paid), `warning` (pending/overdue), `destructive` (rejected/error), `secondary` (neutral category), `outline` (subtle label), `default` (primary accent). Never force a colour just for aesthetics — agents and screen readers read the variant as intent.\",\n \"DO use `status` for entity lifecycle statuses (active, draft, pending, cancelled, failed, scheduled, etc.) so the component resolves the correct tone, icon, and i18n label.\",\n \"DO pass `variant` explicitly for localized labels or categorical tiers, and pass `icon={null}` when a lifecycle glyph would be misleading.\",\n \"Badge renders as a `<div>` (HTMLAttributes<HTMLDivElement>). It carries no interactive semantics. If you need a clickable chip, wrap it in a `<button>` or use a Button with a matching variant — never add an `onClick` directly to Badge without an accessible role.\",\n \"Badge is a leaf — pass plain text or a short ReactNode as children. Do NOT nest another Badge, a Button, or interactive controls inside it; that breaks focus order and creates invalid HTML (div-in-inline-context).\",\n \"Use semantic tokens for any className overrides (`text-muted-foreground`, `bg-destructive`) — never raw Tailwind palette classes like `bg-green-500`.\",\n ],\n useCases: [\n 'Category or tier labels on table rows — e.g. plan tier (`<Badge variant=\"secondary\">Pro</Badge>`), document type (`<Badge variant=\"outline\">Invoice</Badge>`), or locale tag (`<Badge variant=\"secondary\">EN</Badge>`).',\n 'Approval or review state in an accounting list where the value is not a lifecycle key in Badge\\'s STATUS_MAP — e.g. a custom approval tier like `<Badge tone=\"success\">承認済</Badge>` or `<Badge tone=\"warning\">要確認</Badge>`.',\n \"Inline count or highlight next to a heading or nav item — e.g. `<Badge variant=\\\"destructive\\\">3</Badge>` beside 'Overdue invoices' to draw attention to a non-zero count.\",\n 'Feature flags or experiment variant labels on admin records — e.g. `<Badge variant=\"outline\">A/B</Badge>` alongside a campaign row to indicate it is in a split test.',\n \"Read-only metadata chips inside a Descriptions.Item or Card header where a lifecycle icon would be visually heavy — e.g. currency code, payment method, or region tag.\",\n ],\n related: [\n \"Button — use instead of Badge when the chip must be interactive (clickable, toggleable). Badge carries no button role or keyboard handler; a naked `onClick` on Badge is inaccessible.\",\n ],\n example: `import { Badge } from \"@godxjp/ui/data-display\";\n\n<Badge variant=\"secondary\">A/B</Badge>\n<Badge status=\"active\">公開中</Badge>\n<Badge status=\"プレミアム\" tone=\"success\" icon={null}>プレミアム</Badge>`,\n storyPath: \"data-display/Badge.stories.tsx\",\n rules: [35],\n },\n {\n name: \"Descriptions\",\n group: \"data-display\",\n tagline:\n \"Responsive definition grid for detail-page metadata. COMPOUND — value goes in Descriptions.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: \"Descriptions.Item elements.\",\n },\n ],\n usage: [\n 'DO use Descriptions.Item as the ONLY direct child — never raw <div>, <dt>/<dd>, or plain text nodes. Every label/value pair must be wrapped in <Descriptions.Item label=\"…\">value</Descriptions.Item>.',\n \"DO pass span={2} or span={3} on an Item when its value is long (e.g. a full address, a memo field, a JSON blob) — span={2} applies sm:col-span-2 and span={3} applies lg:col-span-3, keeping the grid aligned across breakpoints.\",\n \"DO pass mono on Item for machine-readable values: IDs, UUIDs, file paths, currency codes, JSON snippets. This sets font-mono + break-all so long strings wrap rather than overflow.\",\n \"DO embed any ReactNode as the Item child — Badge, Badge, formatDate output, a Tooltip-wrapped value, or a plain string all work. The value slot is not text-only.\",\n \"DON'T use Descriptions as a hand-rolled <dl>/<dt>/<dd> replacement for prose or running text — it is for structured metadata on detail/show pages only. For flowing key→value prose, use a plain <dl>.\",\n \"DON'T add className padding or margin to the root Descriptions to simulate a Card — wrap it in CardContent instead. Descriptions provides only grid layout (gap-x-6 gap-y-3); outer spacing is the Card/CardContent concern.\",\n ],\n useCases: [\n \"Detail/show page header block — displaying entity metadata such as invoice number, status, due date, vendor name, and payment method in a 2- or 3-column grid before the line-item DataTable.\",\n \"Account or member profile panel — showing user ID (mono), plan, registered date, email, and a status Badge in one scannable block instead of a vertical stack of FormField-looking rows.\",\n \"Accounting journal entry detail — date, reference code (mono), debit account, credit account, amount, and memo (span={2}) grouped in a compact grid alongside a Timeline of audit events.\",\n \"Read-only summary step in a multi-step form or wizard — displaying the values the user entered before final submission (Steps + Descriptions), without any input controls.\",\n \"Sidebar or Sheet detail pane — a narrow 1-column Descriptions inside a Sheet presenting the selected row's metadata while the main DataTable stays visible.\",\n \"API / webhook event inspector — showing event ID (mono, span={2}), event type, timestamp, HTTP status, and payload size in a grid, with a Badge for the status code.\",\n ],\n related: [\n \"Card / CardContent — Descriptions provides the internal grid layout; Card/CardContent provides the outer container, padding, and border. Always wrap Descriptions in CardContent (never add p-4 directly on Descriptions). Use Card when you need the visual surface; use Descriptions inside it for the label/value structure.\",\n \"DataTable — use DataTable when you have multiple rows of the same entity type that need sorting, filtering, or pagination. Use Descriptions when you have a single entity's fields laid out as labelled metadata (one row per field, not one row per record).\",\n \"Table — use Table (the lower-level primitive) for tabular data with explicit column headers and multiple data rows. Use Descriptions when the data is inherently label→value (no column headers needed, each field is its own row/cell).\",\n \"Flex — use Flex for arbitrary vertical/horizontal layout of heterogeneous UI elements. Use Descriptions when every item follows the label-on-top / value-below pattern and you want responsive multi-column alignment for free.\",\n ],\n example: `import { Descriptions } from \"@godxjp/ui/data-display\";\n\n<Descriptions columns={2}>\n <Descriptions.Item label=\"会員ID\" mono>{member.id}</Descriptions.Item>\n <Descriptions.Item label=\"プラン\">{member.plan}</Descriptions.Item>\n <Descriptions.Item label=\"メモ\" span={2}>{member.note}</Descriptions.Item>\n</Descriptions>`,\n storyPath: \"data-display/Descriptions.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 usage: [\n \"DO always pass `title` — it is the only required prop and renders an `<h3>`; omitting it causes a blank silent render with no visible error.\",\n \"DO use the `icon` prop (a Lucide icon component, not a JSX element) to give visual context — e.g. `icon={InboxIcon}` for empty inboxes, `icon={SearchIcon}` after a failed search. Pass the component reference, not `<InboxIcon />`.\",\n \"DO use `action` (a `ReactNode`, typically a `<Button>`) for actionable zero-states — e.g. 'Create first invoice' — so users have a clear next step instead of a dead end.\",\n \"DO NOT hand-roll a `data.length === 0 ? <EmptyState /> : <DataTable />` conditional — `DataTable` already embeds an `EmptyState` in its body when `data` is empty. Use the `empty=` prop on `DataTable` to customise it, not a wrapper conditional.\",\n \"DO NOT use EmptyState inside a `DataState` or `InfiniteQueryState` for the loading or error states — those widgets handle skeleton/error themselves; pass `EmptyState` only to their `empty=` prop for the zero-items case.\",\n \"DO NOT add padding directly on `EmptyState` via `className` when placing it inside a `Card` — wrap it in `<CardContent>` first; EmptyState is a self-contained block with its own internal spacing via `ui-empty-state` styles.\",\n ],\n useCases: [\n \"Zero-row admin list pages (invoices, accounts, transactions) that are NOT backed by a `DataTable` — e.g. a card-grid or custom list layout where DataTable's built-in empty state doesn't apply.\",\n \"Post-filter / post-search zero results — show `icon={SearchIcon}` + a `description` explaining what was searched and an `action` to clear filters.\",\n \"First-run onboarding screens where no data has been created yet — e.g. 'No entities added yet' with an action button to create the first legal entity.\",\n \"Passed as the `empty=` prop inside `DataState` or `InfiniteQueryState` to satisfy the TanStack Query lifecycle widget's zero-items slot without hand-rolling markup.\",\n \"Standalone section within a `CardContent` to indicate a sub-section (e.g. attachments, comments, related records) has no entries yet, separate from the page-level list.\",\n \"Error-adjacent zero states where the page loaded successfully but the filtered result set is empty — distinct from an error state handled by `DataState`/`AlertMutationFeedback`.\",\n ],\n related: [\n \"DataTable — already embeds an EmptyState automatically when `data` is empty; customise via the `empty=` prop. Do NOT wrap DataTable in a `data.length === 0` guard that renders EmptyState separately.\",\n \"DataState — TanStack Query lifecycle widget (`@godxjp/ui/query`). Pass `<EmptyState />` to its `empty=` prop for zero-items; DataState itself covers loading/error — do not use EmptyState for those states.\",\n \"InfiniteQueryState — same pattern as DataState but for `useInfiniteQuery`; pass EmptyState to `empty=` when the flattened list is empty.\",\n \"SkeletonTable — use for the loading skeleton before data arrives (pass to DataState's `skeleton=` or DataTable's `loading=`). EmptyState is for after data arrives and is empty, not while loading.\",\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: \"Progress\",\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 usage: [\n 'DO import from `@godxjp/ui/data-display`, not from a generic UI path: `import { Progress } from \"@godxjp/ui/data-display\";`',\n \"DO pass `value` as a 0–100 number — the component clamps it internally via `Math.max(0, Math.min(100, value))`, so out-of-range values are safe but misleading; compute the real percentage before passing it.\",\n 'DO drive `tone` dynamically from business logic — e.g. `variant={pct >= 80 ? \"warning\" : \"success\"}` — to communicate threshold status semantically rather than with raw colour classes.',\n \"DON'T use a `disabled` Slider as a read-only progress bar — Slider is semantically an interactive control even when disabled, which pollutes the a11y tree and exposes the wrong ARIA role (`slider` vs `progressbar`). Progress renders the correct read-only indicator.\",\n \"DON'T pass children or sub-components — Progress is a single self-contained element (track + bar + label). The `label` prop is the only text injection point; don't wrap it in a custom parent div to add a label alongside it.\",\n \"DON'T use Progress for editable numeric input or range selection — it has no callbacks, no interactivity, and no form `name` prop. Use Slider (bounded range input) or Input (free-form number) for data-entry scenarios.\",\n ],\n useCases: [\n 'Budget utilisation in an accounting dashboard — show how much of a monthly budget has been consumed, switching to `tone=\"warning\"` when the figure crosses 80%.',\n 'Invoice payment progress — display the proportion of an invoice total that has been settled (e.g. partial payments), with a label like `\"¥45,000 / ¥60,000 支払済\"` computed before passing `value`.',\n \"Storage or quota indicator in an admin panel — visualise disk usage, API quota, or seat licence consumption against a fixed limit.\",\n \"Sync / import job completion feedback — surface the completion percentage of a long-running background job (polling the server) without giving the user an interactive control.\",\n \"StatCard companion — pair with a `StatCard` metric to add a visual fill below the KPI number, reinforcing how close a target is to being met.\",\n \"Multi-step onboarding or setup checklist — render one Progress per section (e.g. 3/5 steps complete = 60%) to give users a quick scan of overall progress across areas.\",\n ],\n related: [\n \"Slider — use Slider when the user must drag or set a bounded numeric value (volume, priority, price range); use Progress when the value is read-only and must not be interacted with.\",\n \"Steps — use Steps for a discrete, named sequence of phases (onboarding wizard, checkout flow) where each step has a label and a clear current/done/pending state; use Progress for a continuous 0–100 fill.\",\n 'Badge / Badge — use Badge or Badge to communicate a categorical status label (e.g. \"Paid\", \"Overdue\") without a fill metaphor; use Progress when the numeric proportion itself is the information.',\n \"StatCard — use StatCard to headline a single KPI metric with a title; compose Progress inside or alongside StatCard when a visual fill adds meaning to the number.\",\n ],\n example: `import { Progress } from \"@godxjp/ui/data-display\";\n\n<Progress value={pct} label={pct + \"% 使用中\"} variant={pct >= 80 ? \"warning\" : \"success\"} />`,\n storyPath: \"data-display/Progress.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 usage: [\n \"DO pass an array of `TimelineItem` objects to `items` — this is the ONLY prop; there are no sub-components to compose. Each item is `{ title, location?, time?, note?, current? }`. All fields except `title` are optional.\",\n \"DO mark exactly one item with `current: true` to highlight the in-progress event. The component renders a `Plane` icon for the current item and a `CheckCircle2` icon for all past items — do NOT try to pass a custom icon; the icon is determined entirely by the `current` flag.\",\n \"DO pass `ReactNode` to `title`, `location`, `time`, and `note` — you can embed formatted text, `<Badge>`, `<Badge>`, or `<span>` inside those fields. Use `formatDate` to pre-format timestamps before passing them as `time`.\",\n \"DO NOT hand-roll a vertical event list with divs, icons, and connector lines — that is exactly what Timeline ships. Do not apply extra padding or wrapping outside the component; it manages its own rail and spacing internally.\",\n \"DO NOT use Timeline for user-facing wizard progress (steps the user must complete in order) — use `Steps` for that. Timeline is read-only historical/status display; it has no interactive state, no `onClick`, and no concept of 'go to step'.\",\n \"DO wrap Timeline in `<CardContent>` when placing it inside a `Card` — bare `Card` has no inner padding, so the rail will render flush against the card edge without `CardContent`.\",\n ],\n useCases: [\n \"Shipment / delivery tracking — showing a parcel's journey through 'Order placed → Packed → In transit → Delivered' with timestamps and a current-stop indicator.\",\n \"Accounting document audit trail — rendering the lifecycle of an invoice or payment (Draft → Submitted → Approved → Paid) with the current approval stage highlighted.\",\n \"Support ticket / task history — displaying a chronological log of status transitions (Open → Assigned → In Review → Closed) with agent names in the `note` field and timestamps in `time`.\",\n \"MF sync log viewer — listing each sync run event (OAuth refresh, fetch, upsert) with timestamps and record counts so an operator can see what the last sync did.\",\n \"Approval workflow status panel — showing a multi-stage approval chain where completed stages have CheckCircle2 icons and the pending stage has the Plane (in-flight) icon.\",\n \"Order / purchase-order lifecycle in an admin detail page — placed alongside a `Descriptions` summary at the top of a `Card` to give a compact at-a-glance history.\",\n ],\n related: [\n \"Steps — use Steps (navigation group) when the user must actively progress through a wizard (interactive, shows step numbers/status, horizontal layout by default); use Timeline for read-only historical event sequences that have already happened.\",\n \"Descriptions — use Descriptions to display a flat set of label/value metadata fields (e.g., invoice header); use Timeline when events are ordered chronologically and a connector rail communicates sequence and progress.\",\n \"DataTable — use DataTable for multi-row, multi-column tabular event logs where sorting, filtering, and pagination are needed; use Timeline when the sequence/rail visual is the primary communication and there are fewer than ~10 events.\",\n \"Badge — Badge is a single-item inline indicator; Timeline sequences multiple statuses with connectors. Compose Badge inside a Timeline `title` or `note` field for richer per-event context, but do not replace Timeline with a stack of Badges.\",\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 usage: [\n \"DO compose all six sub-parts in order: wrap with `<Table>`, then `<TableHeader>` containing `<TableRow><TableHead>…</TableRow>`, then `<TableBody>` containing one or more `<TableRow><TableCell>…` rows. Skipping any layer (e.g. bare `<th>` inside `<Table>`) bypasses the design tokens and hover/border styles.\",\n 'DO use `TableHead` (not `TableCell`) for header cells — it renders `<th>` with `data-slot=\"table-head\"` and the `--table-row-height` CSS variable for consistent header sizing across the design system. `TableCell` renders `<td>` with `data-slot=\"table-cell\"` and is for body rows only.',\n 'DO apply numeric alignment via `className` on individual `TableHead`/`TableCell` elements (e.g. `className=\"text-right\"`). There are no built-in alignment props — all styling goes through Tailwind class overrides.',\n \"DO NOT hand-roll empty-state handling inside a Table composition. When data can be empty, switch to `DataTable` (which has a built-in empty state) or wrap the `<Table>` with a conditional that renders `<EmptyState>` — never leave a table with only a header and zero rows.\",\n \"DO NOT use Table for lists that need sorting, filtering, pagination, or row selection — those features are only in `DataTable`. Table is intentionally stateless: it owns no TanStack Table instance, no column definitions, and no toolbar.\",\n \"DO place `<Table>` inside a `<CardContent flush>` (or `p-0` card) when embedding in a Card, so the built-in `overflow-auto` wrapper sits flush to the card edges. Wrapping with plain `<CardContent>` adds padding that clips the horizontal scroll shadow.\",\n ],\n useCases: [\n \"Invoice line-item breakdowns — a fixed, read-only list of product/quantity/unit-price/total rows where columns are predefined and will never need sort or filter controls.\",\n \"Summary/comparison tables inside a detail panel or Dialog, such as showing two payment plans side-by-side, where the structure is hand-authored and not driven by a data array.\",\n \"Print or PDF-export views where a minimal, stateless `<table>` element with predictable markup is required and DataTable's JS-driven features would interfere with server-side rendering or CSS print rules.\",\n \"Embedded sub-tables inside a DataTable expanded row (the inner table uses Table primitives because nesting a full DataTable instance inside another is unsupported).\",\n \"Static reference tables in documentation, onboarding, or settings pages — e.g. a permission matrix or feature comparison — where every cell is literal JSX content, not from a data array.\",\n ],\n related: [\n \"DataTable — choose DataTable for any data array that needs sorting, filtering, pagination, row selection, bulk actions, or density toggle. DataTable internally renders Table primitives, so switching up is non-breaking. Default to DataTable for all admin list pages.\",\n \"SkeletonTable — use as a loading placeholder before a Table or DataTable mounts. Drop it in the `skeleton` slot of DataState, or render it directly while data is fetching. Do not show a Table with empty rows as a loading state.\",\n \"Descriptions — choose Descriptions when content is label→value pairs (two columns, no repeated rows of the same type). Table is better when every row shares the same typed columns.\",\n \"DataState — when your Table's data comes from `useQuery`, wrap it in DataState to handle loading/error/empty states declaratively instead of writing conditional logic around the Table yourself.\",\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 usage: [\n \"DO: pass a `UseQueryResult<T>` directly from `useQuery` — DataState reads `isPending`, `isError`, `isFetching`, `data`, and `error` off it; never destructure those fields manually and branch yourself.\",\n \"DO: always provide a `skeleton` — it renders during both the initial pending phase and during a re-fetch after an error; pass `<SkeletonTable />` for tabular data or `<SkeletonStat />` for stat card lists — never `null` or a spinner div.\",\n 'DO: provide `empty` + `isEmpty` together when the data can legitimately return 0 items — e.g. `isEmpty={(d) => d.items.length === 0}` paired with `empty={<EmptyState title=\"…\" />}`. Omitting `empty` means an empty array still falls through to `children`, silently rendering a blank table.',\n \"DON'T: wrap DataState in your own conditional — e.g. `{query.isSuccess && <DataState …>}`. DataState IS the conditional; the outer guard is redundant and breaks the retry/refetch skeleton.\",\n \"DON'T: use DataState for `useInfiniteQuery` results. The `query` prop type is `UseQueryResult<T>`, not `UseInfiniteQueryResult`. Use `InfiniteQueryState` (from `@godxjp/ui/query`) instead, which accepts `flatten` and renders a load-more footer.\",\n \"DO: supply `errorRenderer` only when the default `AlertQueryError` + retry button is not enough — e.g. a full-page error boundary with navigation. Otherwise rely on `showRetry` (default `true`) and the built-in `AlertQueryError`, and override `onRetry` only if `query.refetch()` is not the right action.\",\n ],\n useCases: [\n \"A detail page that loads a single invoice/journal entry via `useQuery` — DataState renders the skeleton row while fetching, an error alert with retry if the API fails, and the `<InvoiceCard>` only when data is confirmed non-null.\",\n \"A list page that shows a `DataTable` of members/partners — wrap the table in DataState so the skeleton matches the column count while loading and `EmptyState` appears when the filtered result set is empty.\",\n \"A sidebar panel that lazily loads related transactions for the selected entity — DataState keeps the panel in skeleton state during the background fetch without any manual `isPending` branching in the parent.\",\n \"A dashboard stat card that calls a summary API — DataState handles the loading/error/empty lifecycle so `<StatCard>` is only rendered with fully resolved numbers, preventing NaN or undefined rendering.\",\n \"Any page using `useQuery` where the empty state and loading state are visually different — DataState enforces the correct visual for each phase without scattered `if` statements across the component tree.\",\n ],\n related: [\n \"InfiniteQueryState — use instead of DataState when the query is `useInfiniteQuery`; it accepts a `flatten` function to reduce pages and adds a load-more footer. DataState cannot accept `UseInfiniteQueryResult`.\",\n \"SkeletonTable / SkeletonStat — pass as the `skeleton` prop of DataState; they are not standalone replacements for DataState, only the loading slot inside it.\",\n \"EmptyState — pass as the `empty` prop of DataState alongside a matching `isEmpty` predicate; do not hand-roll an empty-check outside DataState by inspecting `query.data` yourself.\",\n \"AlertMutationFeedback — sibling widget for mutation (not query) lifecycle; use it below a form submit button to surface `useMutation` errors, not DataState which only handles `useQuery`.\",\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 usage: [\n \"DO: Import from `@godxjp/ui/query` (not `@godxjp/ui`). Use the bundled `flattenItemPages` helper for any API that returns `{ items: T[] }` pages — it handles `undefined` data safely. Custom page shapes require a custom `flatten` function.\",\n \"DO: Always pass `skeleton` (e.g. `<SkeletonTable />` or `<SkeletonStat />`). It shows on initial `isPending`, on refetch-after-error, and whenever `data` is absent. Never show a blank area while loading.\",\n \"DO: Pass `empty` (an `<EmptyState>` node) to handle the zero-results case — without it the children render-prop is called with an empty array and you get a silent blank screen. Provide a custom `isEmpty` only when `TFlat` is not an array.\",\n \"DON'T: Hand-roll a load-more button. The component renders a default centered outline Button when `hasNextPage` is true. Override only via `loadMore` (custom node) or `showLoadMore={false}` (hide entirely). Never call `query.fetchNextPage()` outside the component for pagination.\",\n \"DON'T: Use `InfiniteQueryState` for a `useQuery` result — it expects `UseInfiniteQueryResult` shape (`pages`, `hasNextPage`, `fetchNextPage`, `isFetchingNextPage`). For regular `useQuery` use `DataState` instead.\",\n \"DON'T: Confuse the two generics: `TPage` is the raw page shape from the API, `TFlat` is what `flatten` returns (usually `TItem[]`). The `children` render-prop receives `TFlat`, not `TPage`. Pass `isEmpty` if `TFlat` is not a plain array so empty detection works correctly.\",\n ],\n useCases: [\n \"Activity / audit-log feed that accumulates pages as the user scrolls down or clicks 'Load more' — the default footer button handles `fetchNextPage` automatically.\",\n \"Invoice or transaction list with cursor-based pagination where total count is unknown and pages are appended rather than replaced (replacing pages is DataTable's job).\",\n \"Notification inbox, comment thread, or journal entry list where new items are appended at the bottom and the user never pages backwards.\",\n \"Search results with a 'Show more' button rather than numbered pages — pass `showLoadMore={true}` (default) and hide the button once `hasNextPage` is false without any extra state.\",\n \"Admin dashboard 'recent events' widget backed by `useInfiniteQuery` — use `SkeletonTable` as `skeleton` and `<EmptyState title='No events yet' />` as `empty` so every state is handled.\",\n \"Infinite-scroll implementation: receive the `helpers` argument in `children` (`{ fetchNextPage, hasNextPage, isFetchingNextPage }`) to wire a scroll sentinel (Intersection Observer) instead of the built-in button, while still benefiting from error/skeleton/empty lifecycle handling.\",\n ],\n related: [\n \"DataState — use instead when the query is a plain `useQuery` (not infinite). Identical lifecycle surface (skeleton/empty/error/children) but expects a single page of data, not accumulated pages. Pick DataState for any paginated table where only one page is visible at a time.\",\n \"DataTable — use for tabular data with server-side pagination where pages are swapped, not appended. DataTable manages its own pagination UI (cursor buttons); InfiniteQueryState is for append-only / infinite-scroll patterns.\",\n \"SkeletonTable / SkeletonStat — pass as the `skeleton` prop to InfiniteQueryState; do not render them manually alongside InfiniteQueryState since the component controls when skeleton is visible.\",\n \"ButtonRefetch — companion component for the page header refresh action wired to `query.refetch()`. Use alongside InfiniteQueryState when you want an explicit refresh control in addition to the built-in load-more footer.\",\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 // ─── data-entry ─────────────────────────────────────────────────────────\n {\n name: \"Form\",\n group: \"data-entry\",\n tagline:\n \"Ant-style layout container — renders <form> and pushes layout (vertical/horizontal), labelWidth/controlWidth, label alignment, responsive collapse, and multi-column grid down to every FormField (overridable per field).\",\n props: [\n {\n name: \"layout\",\n type: '\"vertical\" | \"horizontal\" | \"inline\"',\n defaultValue: '\"vertical\"',\n description: \"Label position relative to control; applied to all FormFields.\",\n },\n {\n name: \"labelWidth\",\n type: \"number | string\",\n description: \"Label column width in horizontal layout (number→px). e.g. 120 or '8rem'.\",\n },\n {\n name: \"controlWidth\",\n type: \"number | string\",\n description: \"Cap the control width (number→px). Omit to fill the column.\",\n },\n {\n name: \"labelAlign\",\n type: '\"start\" | \"end\"',\n defaultValue: '\"end\"',\n description: \"Horizontal alignment of the label within its column.\",\n },\n {\n name: \"collapseBelow\",\n type: '\"sm\" | \"md\" | \"lg\" | \"xl\" | false',\n defaultValue: '\"md\"',\n description:\n \"Breakpoint below which horizontal collapses to vertical (mobile-first). false = always horizontal.\",\n },\n {\n name: \"columns\",\n type: \"number | { sm?: number; md?: number; lg?: number }\",\n description: \"Lay fields out in a responsive grid (reuses ResponsiveGrid; 1 col on small).\",\n },\n {\n name: \"density\",\n type: '\"compact\" | \"default\" | \"comfortable\"',\n description: \"Apply a density to controls inside the form.\",\n },\n ],\n usage: [\n \"DO set `layout`, `labelWidth`, `controlWidth` ONCE on `<Form>` — every `<FormField>` inside inherits them. Override a single field by passing the same prop on that `<FormField>` (Form → FormField priority).\",\n \"DO rely on mobile-first collapse: `layout='horizontal'` automatically stacks to vertical below `collapseBelow` (default `md`). Pass `collapseBelow={false}` only when a field MUST stay label-beside-control even on phones.\",\n \"DO use `columns` for multi-field forms (e.g. `columns={2}`) — it reuses ResponsiveGrid (1 column on small screens, more on md/lg). Span a wide field across columns with `<FormField colSpan={2}>`.\",\n \"DON'T hand-roll a `<form>` + Flex stack for spacing — `<Form>` provides the vertical rhythm and the layout context FormField reads. Wire react-hook-form by spreading `onSubmit={handleSubmit(...)}` onto `<Form>`.\",\n ],\n useCases: [\n \"A settings page form where every label sits in a fixed 120px column to the left of its control (horizontal), collapsing to stacked labels on mobile.\",\n \"A two-column entity-edit form (`columns={2}`) where the address field spans both columns (`colSpan={2}`).\",\n \"A compact filter form (`layout='horizontal' density='compact'`) above a DataTable.\",\n ],\n related: [\n \"FormField — the per-field wrapper (label + control + helper/error) that reads Form's layout context; use one per control inside a Form.\",\n \"ResponsiveGrid — Form `columns` reuses it; use ResponsiveGrid directly for non-form card grids.\",\n ],\n example: `import { Form, FormField, Input } from \"@godxjp/ui/data-entry\";\n\n<Form layout=\"horizontal\" labelWidth={120} columns={2} onSubmit={onSubmit}>\n <FormField id=\"first\" label=\"姓\"><Input id=\"first\" /></FormField>\n <FormField id=\"last\" label=\"名\"><Input id=\"last\" /></FormField>\n <FormField id=\"address\" label=\"住所\" colSpan={2}><Input id=\"address\" /></FormField>\n</Form>`,\n storyPath: \"data-entry/Form.stories.tsx\",\n rules: [23, 24],\n },\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. Reads the parent Form's layout (vertical/horizontal) — overridable per field.\",\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: \"layout\",\n type: '\"vertical\" | \"horizontal\" | \"inline\"',\n description: \"Override the parent Form's layout for this field only.\",\n },\n {\n name: \"labelWidth\",\n type: \"number | string\",\n description: \"Override the Form's label width for this field.\",\n },\n {\n name: \"controlWidth\",\n type: \"number | string\",\n description: \"Override the Form's control width for this field.\",\n },\n {\n name: \"colSpan\",\n type: \"number\",\n description: \"Span N columns when inside a `columns` Form grid.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"The single control to render.\",\n },\n ],\n usage: [\n \"DO pass the same string to both `id` on `<FormField>` and `id` on the child control — the component wires `<Label htmlFor={id}>`, and builds `{id}-helper` / `{id}-error` ids for `aria-describedby`. If the ids diverge the label click and screen-reader announcements break.\",\n \"DO pass a SINGLE React element as `children`. FormField calls `React.cloneElement` on it to inject `aria-describedby`, `aria-required`, and `aria-invalid` — if you pass a fragment or multiple nodes, cloneElement silently skips the injection and a11y attributes are lost.\",\n \"DO use the `error` prop (not a hand-rolled `<p>`) for validation messages — it renders with `role='alert'` and `text-destructive` styling and overrides `helper` automatically. Never render an error paragraph alongside FormField.\",\n \"DO use `labelAddon` (a ReactNode rendered inline after the label text) for supplementary controls such as a tooltip trigger or a 'copy' icon button — never insert such controls as siblings outside FormField, which breaks layout.\",\n \"DON'T wrap `Switch` in FormField — use `Field` instead, which already handles the label, hidden `<input name>` for HTML form submission, error, and helper internally.\",\n \"DON'T use FormField for checkbox-beside-label or radio-beside-label patterns — use `Field` (single checkbox/radio with description) or `CheckboxGroup` / `RadioGroup` (multiple options), which have their own integrated labelling.\",\n ],\n useCases: [\n \"Labelling a text `Input` or `Textarea` in an invoice-entry form, showing a red asterisk for required fields and surfacing server validation errors returned from a Laravel FormRequest.\",\n \"Wrapping a `Select` or `DatePicker` inside a multi-field filter panel where each control needs a visible label, helper hint (e.g. 'YYYY/MM/DD'), and inline error state.\",\n \"Adding a `labelAddon` tooltip button next to a 'Tax rate' label in an accounting form to explain when different rates apply, without breaking the label–control association.\",\n \"Enclosing a `DateRangePicker` or `TimePicker` in an admin settings page where the field needs a label, a muted hint ('Inclusive of start and end date'), and conditional error display.\",\n \"Wrapping a `SearchSelect` or `Select` (with `showSearch`) control for vendor/account lookup in a journal-entry form where the `id` must be kept consistent for programmatic focus management.\",\n \"Providing structured error feedback for a `Cascader` or `TreeSelect` in a multi-level category assignment screen, replacing ad-hoc error rendering with the standardised `role='alert'` pattern.\",\n ],\n related: [\n \"Label — the bare Radix label component. Use directly only when you are building a fully custom layout that cannot accept FormField's stack wrapper, and you will manage aria-describedby/aria-invalid yourself. FormField is always preferred for standard form controls.\",\n \"Field — a self-contained field for boolean toggles: it already includes its own label, hidden `<input name>` for HTML form submission, helper, and error. Never wrap a bare `Switch` in FormField.\",\n \"Field — pairs a single checkbox or radio with a label and optional description in a horizontal layout (control beside text). Use Field instead of FormField when the control and its label sit side-by-side rather than stacked.\",\n \"CheckboxGroup / RadioGroup — for groups of options where FormField is not needed per-item; the group component handles its own legend/label and option layout.\",\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} onValueChange={(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 usage: [\n \"DO always wrap Input in FormField when the field needs a label, helper text, or validation error — FormField injects aria-describedby and aria-invalid onto Input automatically; never wire these attributes by hand.\",\n \"DO match the `id` prop on Input to the `id` prop on its parent FormField so that `htmlFor` linkage and the generated helper/error ids are consistent.\",\n \"DO use Input in controlled mode (`value` + `onChange`) for forms driven by Inertia's `useForm` or React state; uncontrolled usage (no `value`) is only acceptable for fire-and-forget inline edits where form state is not needed.\",\n \"DON'T use a raw `<input>` element — Input adds the full token-based styling (border-input, focus ring, disabled/invalid states, file-slot styling) and the `data-slot='input'` marker that FormField relies on to inject aria attributes.\",\n \"DON'T hand-roll an error border or red ring with className — Input reads `aria-invalid` (set by FormField) and applies `border-destructive` + `ring-destructive/20` automatically; adding manual destructive classes will conflict.\",\n \"DON'T use Input for multi-line text — use Textarea; DON'T use it for filtered/debounced search — use SearchInput which fires `onSearch` after a debounce and includes a clear button.\",\n ],\n useCases: [\n \"Single-line text fields in create/edit forms — invoice reference numbers, company names, contact emails, coupon codes, amounts typed as text (pair with `type='number'` for numeric entry).\",\n \"Inline editable cells or quick-edit dialogs where a single short value needs to be changed (e.g. editing a journal entry memo or an account code) and full Select/DatePicker overhead is unnecessary.\",\n \"File upload trigger when wrapped with `type='file'` — the file-slot classes style the native file button consistently without any extra wrapper.\",\n \"Password entry fields (`type='password'`) in auth or settings screens, where the styled focus ring and disabled-state opacity are needed without building a custom control.\",\n \"Numeric/currency input in accounting forms (`type='number'`, `inputMode='decimal'`) for quantities, exchange rates, or tax amounts where a free-form numeric entry is required rather than a slider or stepper.\",\n ],\n related: [\n \"SearchInput — use instead of Input when the value drives a live filter or search query; SearchInput debounces internally, fires `onSearch` (not `onChange`), and provides a built-in clear button. Never put debounce logic on top of a plain Input.\",\n \"Textarea — use instead of Input for multi-line text (notes, descriptions, memo fields). Input is strictly single-line.\",\n \"FormField — always compose Input inside FormField when the field needs a visible label, helper hint, or validation error message; FormField handles all a11y wiring so Input stays a pure unstyled-but-styled primitive.\",\n \"Select — use instead of Input when the value must come from a fixed or async option list; never render a plain Input and parse free text when the set of valid values is enumerable.\",\n ],\n example: `import { Input } from \"@godxjp/ui/data-entry\";\n\n<Input id=\"qty\" type=\"number\" placeholder=\"例: 500\" value={value} onValueChange={(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 usage: [\n \"DO: listen to `onSearch`, not `onChange`. The component debounces internally (default 250 ms) and fires `onSearch(q)` after the delay — never wire your filter logic to `onChange` on SearchInput because it does not expose one.\",\n \"DO: choose controlled vs uncontrolled deliberately. Pass `value` + `onSearch` together for controlled mode (e.g. when search state lives in a URL param or shared parent). For local-only ephemeral search pass only `defaultValue` + `onSearch` — omitting `value` puts the component in uncontrolled mode.\",\n \"DO: supply an `ariaLabel` (or visible `label`) when no adjacent label exists. Without either prop, SearchInput falls back to the i18n key `common.search` rendered as a visually-hidden `<Label>` — still accessible, but providing a context-specific string (e.g. `ariaLabel='請求書を検索'`) is more descriptive for screen readers.\",\n \"DON'T: use SearchInput inside a `<form>` expecting native form submission. The component has no `name` prop and does not emit a form field value — it is a filter-trigger widget. For a form search field, use a plain `Input` inside `FormField`.\",\n \"DON'T: hand-roll a debounced input when you need a search box. SearchInput ships the debounce, clear button (×), search icon, and accessible label — recreating these with a raw `<Input>` adds code and misses the UX contract.\",\n \"DON'T: place SearchInput inside a `ToolbarGroup` wrapper — `ToolbarGroup` is for Select/DatePicker controls with a label chip. SearchInput goes directly as a child of `Toolbar` (or standalone above a table), not wrapped in `ToolbarGroup`.\",\n ],\n useCases: [\n \"List-page filter bar: placed as the first child of `Toolbar` (before any `ToolbarGroup` children) to drive text-based filtering of a `DataTable`. The `onSearch` callback updates a query param or state variable that the table's data fetch reads.\",\n \"Inline client-side search over a small in-memory list (e.g. a sidebar nav list, a transfer panel, a settings category list) where results narrow immediately as the user types without a server round-trip — use uncontrolled mode (`defaultValue`) so no state is needed in the parent.\",\n \"URL-synced search: controlled mode where `value` comes from `useSearchParams()` and `onSearch` pushes to the URL, enabling deep-linkable, bookmarkable filtered views on invoice/transaction/customer index pages.\",\n \"Panel or dialog search: filtering a long dropdown list, a tree, or a multi-item selection panel that does not use the built-in `Command` palette — SearchInput provides the search box while the parent renders the filtered result set.\",\n \"Toolbar search on a data-heavy accounting page (e.g. journal-entry search, partner lookup in a subledger view) where the 250 ms debounce prevents a flood of API calls on every keystroke without requiring the developer to implement debounce logic.\",\n ],\n related: [\n \"Input — use `Input` (inside `FormField`) when the search field is part of a submitted form and needs a `name` attribute, or when you need full `onChange` control without any debounce or clear button. SearchInput is the right pick when the field only triggers filtering, not form submission.\",\n \"Toolbar — SearchInput is almost always placed as a direct child of `Toolbar`, which provides the surrounding strip, clear-all button, and active-filter state. Do not use SearchInput as a standalone header widget when a full filter strip (with selects etc.) already exists — compose them together.\",\n \"Command — use `Command` + `CommandInput` when you need a keyboard-navigable command palette or combobox list with grouped items and keyboard selection. `Command` is only meaningful when paired with `CommandList`; SearchInput is the right pick for a plain filter box with no item-selection behavior.\",\n \"Select (with showSearch) — when users must pick a value from a list AND search to narrow it, use `<Select options={...} showSearch>` (which has its own built-in search input). SearchInput is for filtering an external data set, not for value selection from an option list.\",\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\" | \"md\"',\n defaultValue: '\"md\"',\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 \"Select with showSearch — use Select (with the `showSearch` prop) for typeahead/autocomplete lookup patterns instead of the removed Autocomplete component.\",\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 onValueChange={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 onValueChange={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 onValueChange={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: \"Radix toggle switch (bare). For a labelled row with a hidden form input use Field.\",\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 {\n name: \"size\",\n type: '\"sm\" | \"md\"',\n defaultValue: '\"md\"',\n description: \"Thumb size — 'sm' for dense rows.\",\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 usage: [\n \"DO use Switch (bare) only when you are building a custom inline toggle without a visible label — e.g., a DataTable row action column. Always pair it with a <Label htmlFor={id}> placed adjacent in the DOM; never leave it label-less for screen readers.\",\n \"DO NOT pass a `name` prop to bare Switch expecting HTML form submission — Radix Switch renders no hidden input, so the value is silently dropped on submit. Use Field (which mirrors a hidden `0`/`1` input) for any field that must submit inside an HTML <form>.\",\n \"DO use the `size` prop ('sm' | 'md') to control thumb size. 'sm' is appropriate in dense DataTable rows or filter bars; omit it (defaults to 'md') everywhere else.\",\n \"DO wire controlled state: pass both `checked` (boolean) and `onCheckedChange` together. Passing only one causes a React controlled/uncontrolled warning. For uncontrolled use, pass neither — but bare Switch has no `defaultChecked` state management built in (Field handles that internally).\",\n \"DON'T hand-roll a <div> + <label> wrapper with bare Switch to get a labelled field — that is exactly what Field provides, including aria-describedby, aria-invalid, error/helper text, and the hidden input. Reach for Field instead.\",\n \"DO link the switch to its label via matching `id` on Switch and `htmlFor` on Label. Without this pairing, clicking the label text does not toggle the switch and the a11y association is broken.\",\n ],\n useCases: [\n \"Inline toggle in a DataTable action cell (e.g., 'Active' column) where the label is already provided by the column header and no form submission is involved.\",\n \"Settings panel where a React state boolean is toggled immediately via an optimistic API call — no <form> submit, so Field's hidden input is unnecessary.\",\n \"Custom compound component where you compose Switch + Label yourself and need direct access to the Radix Root props (e.g., adding aria-controls or data-attributes not supported by Field).\",\n \"Filter toolbar toggle (e.g., 'Show archived') rendered inline next to other filter controls, using size='sm' for density parity with adjacent inputs.\",\n \"Preview/demo UI where the switch controls a local display state (dark-mode preview, feature flag preview) with no server persistence.\",\n ],\n related: [\n \"Field — use this instead of bare Switch whenever the toggle needs a visible label, helper text, error message, or must submit its value inside an HTML <form>. Field composes Label + Switch + hidden input automatically.\",\n \"Checkbox — use Checkbox (or CheckboxGroup) when the user is selecting one or more items from a set, or when the binary choice semantically means 'agree/select' rather than 'enable/disable'. Switch implies an immediate, persistent state change; Checkbox implies a form choice.\",\n \"Field — use for a binary or small-set choice rendered as radio-style cards with rich descriptions, when the visual weight of a toggle is insufficient for the decision importance.\",\n \"RadioGroup — use when the user must choose exactly one option from 2–4 mutually exclusive values; Switch is only appropriate for a single on/off boolean.\",\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 usage: [\n \"DO always wrap Textarea in FormField when it appears in a form — FormField clones aria-describedby, aria-required, and aria-invalid onto the child, giving error/helper announcements and screen-reader labelling for free. Pass matching id props to both.\",\n \"DO use the godx-ui Textarea (`import { Textarea } from '@godxjp/ui/data-entry'`) — never a raw `<textarea>`. The component applies the `ui-control-multiline` token class that picks up density, focus-ring, and border tokens from the design system.\",\n \"DO control the value with `value` + `onChange` in React-managed forms (e.g. Inertia `useForm`). Textarea is a plain `forwardRef` over the native element so it accepts all standard `HTMLTextAreaElement` attributes — `rows`, `maxLength`, `disabled`, `name`, `placeholder`, `readOnly` all pass through directly.\",\n \"DO pass `name` when the textarea sits inside an HTML `<form>` for native form submission or when Inertia's `useForm` destructures field values by key — the `name` attribute maps the value into the form data bag.\",\n \"DON'T apply manual height or padding classes directly on Textarea to simulate a taller field — use the `rows` prop instead. The component does not auto-resize; if you need auto-grow behaviour you must wire a custom `onInput` handler that adjusts `style.height` explicitly.\",\n \"DON'T hand-roll label + error markup next to a bare Textarea. Always use FormField: it injects aria-invalid (red ring on the control), renders a `role='alert'` error paragraph, and links them via aria-describedby automatically.\",\n ],\n useCases: [\n \"Free-text memo or note fields on an invoice or transaction detail form — e.g. '備考 / Notes' that can hold multi-line internal comments alongside structured Invoice fields.\",\n \"Rejection reason or approval comment in an admin workflow dialog — a short-to-medium text block a reviewer types before confirming an action in a Dialog or Sheet.\",\n \"Address or multi-line description input on a vendor / partner entity form where a single-line Input would be too restrictive.\",\n \"Email body composer or message template editor in a lightweight CRM or notification settings screen where rich text is not required.\",\n \"Audit log annotation — allowing an accountant to attach a plain-text explanation to a manual journal entry or adjustment record.\",\n ],\n related: [\n \"Input — use Input for single-line values (names, amounts, codes). Use Textarea only when the expected value spans multiple lines or could be longer than ~80 characters.\",\n \"FormField — always the parent wrapper for Textarea in forms; provides label, helper text, error message, and injects all required aria attributes onto the Textarea child automatically.\",\n \"Select — when the user must pick from a finite set of multi-line-looking options (e.g. template choices) use Select, not a Textarea presenting options as free text.\",\n \"Select with showSearch or SearchSelect — if the multi-line field is actually a tag/token input or a constrained lookup, prefer Select (showSearch) or SearchSelect over a Textarea that the user types into freely.\",\n ],\n example: `import { Textarea } from \"@godxjp/ui/data-entry\";\n\n<Textarea id=\"notes\" rows={4} placeholder=\"自由記述\" value={notes} onValueChange={(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 usage: [\n \"DO: always pass `htmlFor` matching the `id` of the associated control — this is the entire purpose of the component. Without it, clicking the label text does NOT focus or toggle the control, breaking a11y and UX.\",\n 'DO: import from `@godxjp/ui/data-entry` (not shadcn or Radix directly). The godx-ui Label extends Radix\\'s LabelPrimitive with `data-slot=\"label\"`, `select-none`, and `group-data-[disabled]` opacity-50 — hand-rolling a `<label>` loses all of these.',\n \"DON'T: use Label as a standalone visible heading or section title. It is a form-control association primitive. For page/section headings use semantic HTML (`<h2>`, etc.) or a typography class instead.\",\n \"DON'T: wrap Label around a control that is already labelled internally. FormField, Field, and CheckboxGroup all render Label internally — adding a second Label creates a duplicate association and redundant screen-reader announcement.\",\n \"DO: pair Label with Checkbox or Switch when NOT using the compound wrapper (Field). In that case generate the shared id with `React.useId()` and pass it to both `id` on the control and `htmlFor` on Label.\",\n \"PREFER FormField over a bare Label + control pair whenever you also need helper text, error messages, or `required` asterisk. FormField injects `aria-describedby` and `aria-invalid` automatically; a bare Label does not.\",\n ],\n useCases: [\n \"Pairing with a standalone Checkbox when Field's two-line layout is unnecessary — e.g. a single 'Remember me' option in a login form.\",\n \"Labelling a bare Switch (not Field) in a settings row where the switch is controlled by parent state and no HTML form name attribute is needed.\",\n \"Adding a visible label to a custom or third-party control that accepts an `id` prop but isn't wrapped by FormField or Field.\",\n \"Labelling a Textarea in a free-text form field when FormField's helper/error slots aren't needed, keeping the markup minimal.\",\n \"Rendering an accessible label inside a table row where a FormField's block layout would break the inline/grid structure.\",\n \"Adding a label to a DatePicker, TimePicker, or ColorPicker inside a simple layout that doesn't need the full FormField wrapper.\",\n ],\n related: [\n \"FormField — prefer this over a bare Label whenever the field needs helper text, an error message, or a required marker; FormField renders Label internally and wires aria-describedby/aria-invalid automatically.\",\n \"Field — use for a Checkbox or Radio.Item that needs a visible label and optional description line; it renders Label internally — do NOT add a second Label around it.\",\n \"Field — use instead of a bare Switch + Label pair when the control must submit a value via an HTML form name; Field owns the Label + hidden input composition.\",\n \"Checkbox — the most common bare-Label partner; pair with Label via shared useId() id/htmlFor when Field's layout is too heavy.\",\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 usage: [\n \"DO pair every standalone Checkbox with a `<Label htmlFor={id}>` — the id prop on Checkbox must match the htmlFor on Label so screen readers announce the label on focus. Without this pairing the control is inaccessible.\",\n \"DO use the controlled pattern (`checked` + `onCheckedChange`) for any form-bound checkbox. `onCheckedChange` receives `boolean | 'indeterminate'` — always coerce with `!!v` or an explicit guard before storing in state.\",\n \"DO use `Checkbox.Group` (alias for CheckboxGroup) with the `options` prop when you have ≥2 choices from an array — it renders each item inside a `Field` (label + optional description), generates stable ids automatically, and manages the `string[]` value array. NEVER hand-roll a loop of bare `<Checkbox>` elements for a multi-select list.\",\n \"DO pass `name` on `Checkbox.Group` (not on individual checkboxes) when the group must submit as form fields — the group propagates the name to each internal checkbox so the browser serialises all checked values under that key.\",\n \"DON'T use `checked='indeterminate'` on `Checkbox.Group` children — indeterminate is only meaningful on a parent 'select-all' control you wire manually; the group itself does not auto-compute it.\",\n \"DON'T wrap a standalone Checkbox in `Field` manually — `Field` is the internal composition primitive that `Checkbox.Group` uses. For a single boolean with a label, use `<div className='flex items-center gap-2'><Checkbox id='x' .../><Label htmlFor='x'>...</Label></div>` as shown in the catalog example; for a full labelled-checkbox with description, use `Field` directly only if you need a one-off item outside a group.\",\n ],\n useCases: [\n \"A 'Select all' / bulk-action row above a DataTable — standalone Checkbox with `checked='indeterminate'` when some (not all) rows are selected, toggling between all-selected and none-selected.\",\n \"A multi-step filter panel (e.g. filter invoices by payment status: Paid, Unpaid, Overdue) — `Checkbox.Group` with `options` prop and `orientation='vertical'`, controlled value wired to Toolbar state.\",\n \"Confirmation or consent acknowledgement before a destructive action in a Dialog — standalone Checkbox with controlled state used to enable/disable the confirm Button.\",\n \"Settings panel where each feature flag is a boolean toggle with a description line — `Checkbox.Group` with options carrying a `description` field so each row renders label + subtext via Field.\",\n \"Bulk-edit form row in an accounting ledger (e.g. 'Apply to all selected entries') — standalone Checkbox with name + value inside a `<form>` for native HTML form submission.\",\n \"Onboarding checklist (e.g. 'I have read the terms', 'I consent to data processing') with multiple distinct items whose values are independent — two separate standalone Checkboxes, each with their own id/state, not a Checkbox.Group (since each item maps to a different boolean field).\",\n ],\n related: [\n \"CheckboxGroup — use instead of bare Checkbox when you have a list of 2+ options from an array; it handles id generation, Field wrapping, value array management, and the `name` prop for form submission. Checkbox is for a single boolean; CheckboxGroup is for multi-select.\",\n \"Switch / Field — use Switch when the action takes immediate effect (enable/disable a feature in settings) rather than selecting an option to be submitted later. Checkbox implies 'will be submitted as part of a form'; Switch implies 'applies now'. Field adds a hidden input for HTML form compatibility.\",\n \"RadioGroup — use when only one option in a group may be selected at a time (mutually exclusive). CheckboxGroup = multiple selections allowed; RadioGroup = single selection only.\",\n \"Field — the internal layout primitive (control slot + Label + description) that Checkbox.Group renders per item. Use it directly only when you need a one-off labelled checkbox or radio item outside of a group, and you want the consistent indent/description layout without the group's value-management overhead.\",\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 usage: [\n \"DO use the `options` prop for the data-driven path: pass `{ label, value, disabled?, description? }[]` and RadioGroup renders every option as a correctly labelled Field automatically — never hand-roll Radio.Item + Label pairs in a loop yourself.\",\n \"DO provide `name` whenever the group lives inside an HTML form: Radix renders a hidden `<input name={name}>` carrying the selected string value, making the field natively form-submittable without a separate hidden input.\",\n \"DO use controlled mode (`value` + `onValueChange`) for any form managed by useForm or a state manager. Use `defaultValue` only for truly uncontrolled UI where you never need to read the value in code.\",\n \"DO NOT reach for children / manual composition unless the options list is dynamic-JSX (e.g. each item needs a custom rendered label with an icon). When you do compose children manually, wrap each Radio.Item in a Field — rendering a bare Radio.Item without Field skips the label and breaks a11y.\",\n \"DO NOT use RadioGroup when the user may select zero or multiple items — that is CheckboxGroup. RadioGroup enforces exactly one selection at all times (or none before first interaction when uncontrolled).\",\n \"A11y: the Radix root emits `role=radiogroup`; each item gets `role=radio` and is keyboard-navigable with arrow keys. Never suppress `name` on the Root when inside a form — without it the hidden input is unnamed and won't submit.\",\n ],\n useCases: [\n \"Selecting a single billing cycle (monthly / quarterly / annual) in an invoice or subscription settings form where all 2-4 options must be visible at once.\",\n \"Choosing a report output format (PDF / CSV / Excel) before triggering an async export job — keeps all options scannable without opening a dropdown.\",\n \"Picking a transaction type (income / expense / transfer) on an accounting entry form where the choice changes which subsequent fields are shown.\",\n \"Selecting a sync trigger mode (first purchase / birthday / manual) in a campaign or automation settings panel — matches the catalog example exactly.\",\n \"Filtering a compact inline control (horizontal orientation) such as date granularity (day / week / month) inside a dashboard filter bar where a full Select dropdown would be over-engineered.\",\n \"Choosing an approval status (pending / approved / rejected) on an admin detail sheet where all states must be visible so reviewers can compare them without interaction.\",\n ],\n related: [\n \"CheckboxGroup — use when the user may select zero or more values simultaneously (multi-select); RadioGroup enforces exactly one selection. Both share the same options array shape and orientation prop.\",\n \"Select — use when there are 5 or more options or the option list is dynamic/searchable; RadioGroup is preferred for 2-4 fixed visible choices where scanning all options at once matters.\",\n \"Field — use when there are exactly two states that map to on/off (boolean); RadioGroup is the right pick when the two-or-more options are semantically distinct named values, not a toggle.\",\n \"Field — the low-level label+description wrapper that RadioGroup uses internally for each item. Use it directly only when manually composing Radio.Item children inside Radio.Group; never hand-roll a label alongside a bare Radio.Item without it.\",\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 onValueChange={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. Rendered with role=dialog.\",\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 usage: [\n \"Use `Dialog` for form-style or wizard-style modal flows that need freeform content and a close action.\",\n \"DO always control open state via `open` + `onOpenChange`. Dialog has no uncontrolled shortcut — omitting `open` means the trigger alone drives state, which is fine for simple trigger-only cases, but any async submission flow must use controlled state so you can hold the dialog open while `pending=true` and close it only on success.\",\n \"DO include `DialogHeader` with `DialogTitle` (and optionally `DialogDescription`) inside every `DialogContent`. Radix requires an accessible title for screen readers; omitting it triggers a console warning and breaks a11y.\",\n \"DO wrap tall/scrolling content in `DialogBody` (the ring-safe scroll slot, max-height ~60vh). It insets the content to match the dialog padding so a full-width control's focus ring never clips against the scroll container — mirror of SheetBody.\",\n ],\n useCases: [\n \"Inline form dialog — create or edit a record (invoice line, supplier, coupon) without navigating away. Place `FormField`/`Input`/`Select` inside `DialogContent`, wire the submit button to your mutation, and hold `open` while `pending` to prevent double-submit.\",\n \"Read-only detail popup — show a full transaction audit trail, attachment preview, or approval history in a modal without leaving the list page. Use `Dialog` with no `DialogFooter` action buttons, just a close trigger.\",\n \"Wizard / multi-step flow — step through entity setup (legal entity → fiscal year → opening balances) using a single Dialog whose `DialogContent` conditionally renders different step panels. Control which step is shown in local state.\",\n ],\n related: [\n \"Sheet — use Sheet instead of Dialog when the content is a slide-in panel (filters, detail sidebar, settings drawer). Sheet uses `side` prop and is better suited for wide filter forms or contextual detail panels that don't demand full focus interruption.\",\n \"Alert — use Alert for inline, non-modal status messages (validation errors, success banners on the page). Dialog is modal and focus-trapping; Alert is inline and never blocks interaction.\",\n \"Popover — use Popover for lightweight non-modal overlays anchored to a trigger (quick-edit a single field, tooltip-style confirmation for low-stakes actions). Dialog is full-modal; Popover stays near its trigger and doesn't dim the page.\",\n \"AlertMutationFeedback — use AlertMutationFeedback for toast/inline feedback after the Dialog closes, not inside it. Putting a success toast inside a Dialog that is about to unmount causes it to disappear immediately; emit the feedback after `onOpenChange(false)` resolves.\",\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: \"AlertDialog\",\n group: \"feedback\",\n tagline:\n 'Canonical modal confirmation flow (destructive / high-stakes decisions). Preserves confirm semantics with `role=\"alertdialog\"` and built-in cancel/confirm handling.',\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: \"title\",\n type: \"string\",\n required: true,\n description: \"Accessible title/announcement for the alertdialog.\",\n },\n { name: \"description\", type: \"string\", description: \"Optional supporting explanatory text.\" },\n {\n name: \"confirmLabel\",\n type: \"string\",\n description: \"Primary action label (defaults to translated continue).\",\n },\n {\n name: \"cancelLabel\",\n type: \"string\",\n description: \"Dismiss action label (defaults to translated cancel).\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"destructive\"',\n defaultValue: '\"default\"',\n description: \"Variant passed through to the confirm button.\",\n },\n {\n name: \"confirmPhrase\",\n type: \"string\",\n description: \"Optional type-to-confirm phrase to prevent accidental confirm.\",\n },\n {\n name: \"onConfirm\",\n type: \"() => Promise<void> | void\",\n description: \"Primary action handler.\",\n },\n {\n name: \"keepOpenOnConfirm\",\n type: \"boolean\",\n description: \"Keep modal open after confirm when true.\",\n },\n {\n name: \"pending\",\n type: \"boolean\",\n description: \"Disable actions while async work is running.\",\n },\n ],\n usage: [\n \"Use `AlertDialog` for destructive/irreversible actions (delete, void, unpublish, archive, etc.).\",\n \"Use `confirmPhrase` for high-friction operations (e.g. requiring `DELETE`) to reduce accidental confirmation.\",\n \"Pass `keepOpenOnConfirm` when the confirm handler advances a multi-step flow and should not close immediately.\",\n ],\n useCases: [\n \"Dangerous delete or irreversible workflow confirmation that should block the background UI.\",\n \"Destructive batch operations that should remain modal and explicit until action is intentionally confirmed.\",\n ],\n related: [\n \"Dialog — use for form-style and non-destructive modal flows, no confirm preset behavior.\",\n ],\n example: `import { AlertDialog } from \"@godxjp/ui/feedback\";\n\n<AlertDialog\n open={open}\n onOpenChange={setOpen}\n title=\"Delete project\"\n description=\"This action cannot be undone.\"\n confirmLabel=\"Delete\"\n cancelLabel=\"Cancel\"\n onConfirm={async () => {\n await deleteProject();\n setOpen(false);\n }}\n variant=\"destructive\"\n/>`,\n storyPath: \"feedback/AlertDialog.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/SheetBody/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 name: \"width\",\n type: \"number | string\",\n description:\n \"On SheetContent (side left/right): desired panel width (number→px). Caps at the viewport — full-width on a small screen (min(width,100%)), NOT a hard fixed width. Default w-3/4 sm:max-w-md.\",\n },\n {\n name: \"title / subtitle / extra / tone\",\n type: \"ReactNode / ReactNode / ReactNode / ToneProp\",\n description:\n \"On SheetHeader (Ant-style): title (→ SheetTitle, accessible name), subtitle (→ SheetDescription), right-aligned extra actions, and a soft semantic `tone` background band. Children still supported.\",\n },\n ],\n usage: [\n \"DO build the panel with SheetHeader (pass `title`/`subtitle`/`extra`/`tone` OR children) > SheetBody (scrollable, ring-safe) > SheetFooter (pinned). SheetTitle is required for a11y — the `title` prop renders it for you. Never skip the title.\",\n \"DO set `width` on SheetContent for a wider/narrower panel (e.g. width={480}); it caps at the viewport so small screens still get a full-width panel.\",\n \"DO use all named sub-parts in order: Sheet (root) > SheetTrigger (opener) > SheetContent (panel) > SheetHeader > SheetTitle (required for a11y — maps to Radix DialogPrimitive.Title, announced as the accessible name) > optional SheetDescription > body content > SheetFooter. Never skip SheetTitle inside an open SheetContent.\",\n \"DO control state explicitly with open + onOpenChange on Sheet root when you need to close programmatically (e.g. after form submit). Uncontrolled (no props) works for simple trigger-only cases but gives you no hook to reset form state on close.\",\n \"DO use SheetTrigger asChild to wrap a Button or other interactive element — this avoids a nested <button> in the DOM. Never render a raw <button> as a direct child of SheetTrigger.\",\n \"DO wrap a long/scrolling body in SheetBody (between SheetHeader and a pinned SheetFooter). It is the ring-safe scroll slot: a hand-rolled <div className='overflow-y-auto'> clips the 3px focus ring of a full-width Input/Select at the scroll edges — SheetBody insets the content so the ring never clips.\",\n \"DO use SheetFooter (renders at the bottom via mt-auto, symmetric 16/24 padding, full-bleed top border) for primary/cancel action Buttons. Never float action Buttons inside the body — they will not stick to the panel bottom.\",\n \"DON'T set showCloseButton={false} on SheetContent unless you provide your own SheetClose element; omitting both leaves users with no keyboard-accessible close path and breaks a11y.\",\n \"DON'T put a Sheet inside a Dialog (nested Radix portals conflict). If you need a slide-over triggered from within a modal, close the Dialog first, then open the Sheet.\",\n ],\n useCases: [\n \"Filter/search panel: slide in from the right with filter FormFields (Select, DateRangePicker, CheckboxGroup) that affect a DataTable — preferred over a Dialog because filters do not require confirmation and benefit from seeing the table behind the overlay.\",\n \"Quick-edit drawer: open an entity's editable fields (e.g. invoice line items, account settings) without navigating away, with Save/Cancel in SheetFooter — use side='right' and keep the main page visible as context.\",\n \"Detail peek panel: show read-only Descriptions / Timeline of a selected record (e.g. a journal entry or invoice) from a DataTable row click, using side='right' with showCloseButton={true}.\",\n \"Mobile-first navigation drawer: side='left' sheet acting as a slide-in nav menu on small viewports when the AppShell Sidebar is hidden — triggered by a hamburger Button.\",\n \"Step-by-step wizard side panel: multi-step form (Steps component inside SheetContent) for onboarding or import flows where full-page navigation would lose list context.\",\n ],\n related: [\n \"Dialog — use Dialog (centered modal) when the action is destructive, requires full user focus, or needs a confirm/alertdialog (mode='confirm'). Use Sheet when the user benefits from seeing the page content behind the slide-over (filters, detail peek, quick-edit).\",\n \"Toolbar/ToolbarGroup — use Toolbar for inline persistent filter controls above a DataTable (no overlay). Use Sheet when the filter set is large (>4 controls) or on mobile where inline controls collapse poorly.\",\n \"Popover — use Popover for lightweight, anchor-positioned context menus or single-control overlays (date picker, color picker). Use Sheet when the panel has a header, multiple fields, or footer actions that need a dedicated panel.\",\n \"SplitPane — use SplitPane for a persistent side-by-side layout where both panes are always visible. Use Sheet when the secondary panel is transient and should overlay the primary content.\",\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 usage: [\n 'DO compose with sub-parts in order: wrap text content in `<Alert.Content>` (or bare `<AlertContent>`), then `<Alert.Title>` + `<Alert.Description>` inside it, then `<Alert.Actions>` for any retry/CTA buttons. Example: `<Alert tone=\"destructive\"><Alert.Content><Alert.Title>Error</Alert.Title><Alert.Description>{msg}</Alert.Description></Alert.Content><Alert.Actions><Button …/></Alert.Actions></Alert>`.',\n \"DO use `Alert.QueryError` (alias `AlertQueryError`) for TanStack Query / API failure surfaces — it already renders humanError(error), an i18n title, and an optional Retry button. Never hand-roll that pattern.\",\n 'DON\\'T pass raw action elements directly as top-level children of `<Alert>` without wrapping them in `<Alert.Actions>` — the layout slot only activates correctly via the `data-slot=\"alert-actions\"` wrapper.',\n 'DON\\'T hand-roll a dismiss ✕ button — pass `onDismiss` to `<Alert>` and the component renders its own accessible dismiss button with `aria-label=\"Dismiss\"`. The `onDismiss` handler may return a Promise.',\n 'DON\\'T suppress the icon with `icon={false}` unless there is a deliberate design reason; the icon is the primary a11y cue for sighted users since the root already carries `role=\"alert\"` for screen readers.',\n \"DO NOT use `Alert` for transient ephemeral feedback (e.g. 'saved successfully'). Use `toast()` from sonner + `<Toaster>` for that. `Alert` is for persistent, page-scoped banners that stay visible until the user acts or dismisses.\",\n ],\n useCases: [\n 'Page-level error banner after a form submission fails server-side validation — `tone=\"destructive\"` with `Alert.Title` summarising the error and `Alert.Description` listing field issues, paired with `onDismiss` so the user can clear it.',\n \"Inline warning at the top of an accounting invoice list when the OAuth token for the MF sync is about to expire — `variant=\\\"warning\\\"` with an `Alert.Actions` containing a 'Reconnect' Button.\",\n 'Success confirmation banner rendered after a bulk-import job completes and the user returns to the list page — `tone=\"success\"` with `Alert.Description` showing the record count imported.',\n \"TanStack Query data-fetch failure inside a Card body — use `<Alert.QueryError error={error} onRetry={refetch} />` instead of writing a custom error state.\",\n \"Informational notice at the top of a settings page when a feature is in beta or requires a plan upgrade — `variant=\\\"default\\\"` (Info icon) with a short description and an `Alert.Actions` 'Learn more' link.\",\n 'Dismissible billing-overdue notice at the top of the dashboard — `tone=\"destructive\"` with `onDismiss` that sets a session flag so it does not reappear until the next login.',\n ],\n related: [\n \"Toaster — use for transient, auto-dismissing feedback ('Record saved', 'Deleted'). Alert is for persistent page-scoped banners; Toaster is for fire-and-forget notifications triggered by toast() from sonner.\",\n \"AlertMutationFeedback — use when you want inline success/error feedback tightly coupled to a form mutation's state (renders inline below the submit button). Alert requires you to manage show/hide state yourself.\",\n \"DataState — use for full query lifecycle (loading skeleton + empty state + error) inside a data-fetching section. Alert.QueryError is the error sub-component DataState uses internally; prefer DataState when you also need the loading/empty states.\",\n \"EmptyState — use for the zero-data case inside a list or table section, not for errors or warnings. Alert is for status messages; EmptyState is for the absence of data.\",\n ],\n example: `import { Alert, AlertTitle, AlertDescription } from \"@godxjp/ui/feedback\";\n\n<Alert tone=\"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 usage: [\n \"DO use SkeletonTable as the pre-mount placeholder — either as a ternary fallback (`{!data ? <SkeletonTable rows={10} columns={6} /> : <DataTable … />}`) for Inertia deferred props, or as the `skeleton` prop of `DataState` (`<DataState query={q} skeleton={<SkeletonTable />} …>`). It is NOT for in-table loading; once DataTable has mounted use its own `loading` prop instead.\",\n \"DO match rows/columns to the final DataTable layout: pass `rows` equal to your expected page size and `columns` equal to your column count so the skeleton doesn't visually jump on hydration. Defaults are rows=8, columns=5.\",\n \"DO NOT use SkeletonTable when data is already present but refetching — use `DataTable loading={isFetching}` for in-table refetch states. SkeletonTable is only for the initial pre-mount gap before DataTable is rendered.\",\n \"DO NOT wrap SkeletonTable in a Card — it renders its own header + body structure matching DataTable's DOM. Placing it inside CardContent adds unwanted padding around the skeleton rail.\",\n 'The root element carries `aria-busy=\"true\"` automatically — do not add a second aria-busy on a wrapper. Screen readers announce the loading state correctly without extra markup.',\n \"Import from `@godxjp/ui/feedback` (not `@godxjp/ui/admin`). Both paths resolve but the canonical export is `feedback`.\",\n ],\n useCases: [\n \"Inertia deferred props: the server streams the page shell immediately and defers the table data; render SkeletonTable until the prop arrives (`{!invoices ? <SkeletonTable rows={20} columns={7} /> : <DataTable data={invoices} columns={columns} />}`).\",\n \"TanStack Query initial load via DataState: pass SkeletonTable as the `skeleton` prop so DataState shows the correct table shape during the query's loading state before switching to the populated DataTable.\",\n \"Filter / search reset that unmounts and remounts DataTable: briefly show SkeletonTable while the new dataset fetches, preventing a flash of the empty state before results arrive.\",\n \"Admin list pages (invoices, journal entries, partners) where the table has a known column count — tune `columns` to match so column widths feel stable and don't reflow on hydration.\",\n \"Page-level Suspense boundaries: use SkeletonTable as the `fallback` of a React Suspense wrapping a lazy-loaded data table component.\",\n \"Route prefetch / navigation transitions: render SkeletonTable in the destination slot while Inertia visits are in-flight, keeping perceived layout stable.\",\n ],\n related: [\n \"DataTable — sibling component that SkeletonTable precedes. Once DataTable mounts, use its `loading` prop (renders an in-table loading row) for subsequent refetches rather than swapping back to SkeletonTable. Pick SkeletonTable only for the pre-mount gap.\",\n \"DataState — query lifecycle widget from `@godxjp/ui/query`; accepts SkeletonTable as its `skeleton` prop and handles loading/empty/error transitions automatically. Prefer DataState + SkeletonTable over a hand-rolled ternary when the data comes from a useQuery hook.\",\n \"SkeletonStat — sibling skeleton shaped like a StatCard tile; use inside a ResponsiveGrid to placeholder KPI dashboard cards, not tabular data.\",\n \"DataTable — when data is already mounted but re-fetching (e.g. pagination, filter change), set `loading={true}` on DataTable directly instead of unmounting it and swapping in SkeletonTable; avoids layout shift and preserves scroll position.\",\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: \"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 usage: [\n \"DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks — there is no provider context, only DOM portals.\",\n 'DO: Import `toast` from `\"sonner\"` directly (not from `@godxjp/ui`) to fire toasts anywhere: `toast.success(…)`, `toast.error(…)`, `toast.warning(…)`, `toast.info(…)`, `toast.loading(…)`, `toast.promise(…)`.',\n \"DON'T: Try to import a `toast` helper from `@godxjp/ui/feedback` — it does not exist. The component re-exports only the `Toaster` mount; the imperative API lives in the `sonner` package.\",\n \"DO: Let the wrapper handle theming — it uses `useDocumentTheme()` to sync with the document `dark` class and `prefers-color-scheme` automatically. Never pass a hardcoded `theme` prop unless you are deliberately overriding.\",\n \"DON'T: Use `Toaster` for persistent errors or blocking confirmations. Toasts auto-dismiss; they are not a substitute for `Alert` (inline persistent warnings) or `Dialog` (decisions requiring user input).\",\n \"DO: Pass `position` to relocate the stack if a persistent sidebar/footer would obscure the default `bottom-right`. The wrapper already sets a safe `mobileOffset`; don't add redundant mobile offsets unless your layout differs.\",\n ],\n useCases: [\n 'After a successful form save (invoice, journal entry, vendor record) — show `toast.success(\"保存しました\")` to confirm without blocking navigation.',\n 'After a background job is enqueued (e.g. bulk sync or export) — show `toast.info(\"エクスポートを開始しました\")` then later update with `toast.promise()` to track completion.',\n \"Mutation error fallback when the error is transient and retrying is the right UX — show `toast.error(message)` instead of replacing page content; reserve `AlertMutationFeedback` for inline, persistent error display inside a form.\",\n 'Soft destructive action confirmation outcome — e.g. \"削除しました\" after an item is removed, paired with an undo action via `toast(\"…\", { action: { label: \\'元に戻す\\', onClick: undo } })`.',\n 'OAuth / session expiry warnings — surface a brief `toast.warning(\"セッションの有効期限が近づいています\")` without interrupting the user\\'s current form state.',\n ],\n related: [\n \"Alert — use for persistent, inline feedback that must stay visible (validation summaries, page-level warnings, destructive notices). Unlike Toaster, Alert does not auto-dismiss and lives in the document flow.\",\n \"AlertMutationFeedback — use when you have a TanStack `useMutation` result and want an inline error + retry UI inside a form or card. Renders nothing on success/idle; pairs naturally with a `toast.success` in `onSuccess`.\",\n \"Dialog — use when the user must make a conscious decision (confirm delete, resolve conflict) before proceeding. Toaster toasts are fire-and-forget; Dialog blocks until the user responds.\",\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 with optional Ant-style `items` API. Pass items for the common full TabsList/TabsContent set, or compose TabsList/TabsTrigger/TabsContent manually when you need per-panel control.\",\n props: [\n {\n name: \"items\",\n type: \"{ value: string; label: React.ReactNode; content: React.ReactNode; disabled?: boolean }[]\",\n description:\n \"Optional data-driven tab list. When provided, Tabs renders all triggers and content panels.\",\n },\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 usage: [\n \"DO pass `items` when all tab content is known up front — each item needs a unique `value`, trigger `label`, and panel `content`.\",\n 'When not using `items`, compose the full four-part tree — `<Tabs>` root, `<TabsList>` trigger bar, one `<TabsTrigger value=\"…\">` per tab, one `<TabsContent value=\"…\">` per matching trigger.',\n \"DO: use `defaultValue` (uncontrolled) for simple local state; use `value` + `onValueChange` together (controlled) when the active tab is driven by URL query params, router state, or parent state. NEVER set both simultaneously.\",\n \"DO use `variant` on Tabs when using `items`; when composing manually, set `variant` on `TabsList`.\",\n 'DO: pass `orientation=\"vertical\"` to `<Tabs>` (not to `TabsList`) for a side-rail layout — the CSS group classes on root and triggers respond automatically, so no extra className gymnastics are needed.',\n \"DON'T: hand-roll the active-indicator underline or selected-state ring — `TabsTrigger` already applies `data-[state=active]` styles including the `after:` line element for the `line` variant. Adding your own underline breaks the design.\",\n ],\n useCases: [\n \"Detail drawers or pages that need full per-panel control — e.g. an accounting journal-entry sheet where one panel has `forceMount` to keep a live chart mounted, requiring custom `TabsContent` props that `Tabs` cannot pass.\",\n \"Controlled tabs driven by URL search params (e.g. `?tab=history`) where the parent reads/writes the active key and passes it to `value` / `onValueChange`.\",\n 'Vertical side-rail navigation inside a `SplitPane` or settings layout where `orientation=\"vertical\"` on the root and `variant=\"line\"` on `TabsList` combine to produce a sidebar-style tab strip.',\n \"Lightweight widget tabs on a dashboard card — e.g. switching a `DataTable` between 'Pending' and 'Paid' invoice views — where an uncontrolled `defaultValue` is sufficient and no URL state is needed.\",\n \"Admin entity profile pages (company, partner, employee) where each `TabsContent` wraps an Inertia deferred prop panel, lazy-loading expensive data only when the tab is first activated.\",\n ],\n related: [\n \"Steps (@godxjp/ui/navigation) — sequential wizard/progress indicator. Use Steps when order and completion state matter (multi-step forms, onboarding flows); use Tabs when panels are non-sequential and any tab can be visited freely.\",\n \"Toolbar / ToolbarGroup (@godxjp/ui/navigation) — horizontal filter chip row. Visually resembles `line`-variant tabs but is semantically different: Toolbar filters a dataset, it does not switch content panels. Never use Tabs as a filter control.\",\n \"DropdownMenu (@godxjp/ui/navigation) — use for space-constrained contexts where showing all tab triggers at once is impractical (e.g. mobile overflow menu). If only 2-3 options exist and screen space is tight, a DropdownSidebar is a lighter alternative to a full tab strip.\",\n ],\n example: `import { Tabs } from \"@godxjp/ui/navigation\";\n\n<Tabs\n defaultValue=\"overview\"\n items={[\n { value: \"overview\", label: \"概要\", content: \"概要コンテンツ\" },\n { value: \"history\", label: \"履歴\", content: \"履歴コンテンツ\" },\n ]}\n/>`,\n storyPath: \"navigation/Tabs.stories.tsx\",\n rules: [],\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: \"value\",\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: \"onValueChange\",\n type: \"(page: number, pageSize: number) => void\",\n description: \"Page / page-size change handler.\",\n },\n ],\n usage: [\n \"DO always control Pagination externally: store `value` (page) and `pageSize` in React state (or URL params), and update both in the `onValueChange(page, pageSize)` callback. Pagination is fully controlled — it has no internal state and will not move unless `value` changes.\",\n \"DO pass `total` as the raw item count (not page count). The component computes `Math.ceil(total / pageSize)` internally; passing a pre-computed page count as `total` will over-paginate.\",\n \"DO use `showSizeChanger` together with `pageSizeOptions` when the user needs density control (default options are [10, 20, 50, 100]). When `showSizeChanger` is omitted the page-size Select is not rendered at all — do NOT hand-roll your own Select beside Pagination.\",\n \"DO use `simple` mode for compact contexts (mobile, sidebars, sheet footers) — it renders Prev / `n / total` / Next with no page-number buttons. Use the full form for primary admin list pages.\",\n \"DO use `showTotal` to surface item counts: pass `true` for the built-in i18n label, or a function `(total, [from, to]) => ReactNode` for a custom range label like '1–10 of 342 invoices'. Never hard-code a total string beside the component.\",\n \"DON'T use Pagination for cursor- or infinite-scroll-based lists. Pagination is strictly offset/page-based (`value` is a page number). For cursor pagination inside a DataTable use `DataTable.Pagination`; for infinite scroll use `InfiniteQueryState`.\",\n ],\n useCases: [\n \"Standalone offset-paginated admin list pages (e.g. invoice list, customer list, transaction history) rendered outside DataTable — place Pagination below the table card, outside the card border, with `showTotal` and optionally `showSizeChanger`.\",\n \"Search results pages where the backend accepts `page` + `per_page` query parameters and returns a total count — wire `value` and `pageSize` to URL search params so the URL is shareable and browser-back works.\",\n \"Reports and filtered data grids where the user needs to export 'all selected pages': `showTotal` with a custom function lets you show '1–50 of 1 200 rows' so the user understands the scope before exporting.\",\n \"Compact modal or sheet footers with a long list (e.g. selecting from a product catalog inside a dialog) — use `simple` mode to save horizontal space while keeping navigation accessible.\",\n \"DataTable instances where the server returns an offset-based total and `DataTable.Pagination` is not being used: attach a standalone Pagination below the card and pass the same `page` / `pageSize` state to both the DataTable `data` prop and the API fetch.\",\n ],\n related: [\n \"DataTable.Pagination — use instead of standalone Pagination when the list is rendered inside a DataTable compound and uses cursor-based navigation (cursor + hasMore + onChange). DataTable.Pagination handles First/Next without page arithmetic; standalone Pagination requires a known total.\",\n \"InfiniteQueryState — use for infinite-scroll / load-more lists driven by useInfiniteQuery. It auto-manages skeleton, empty, and error states; Pagination is inappropriate here because there is no discrete page number.\",\n \"DataTable — when offset pagination is needed inside DataTable, prefer composing DataTable with a standalone Pagination below the card rather than DataTable.Pagination if the API is offset-based and returns a total count. DataTable itself does not paginate; you supply `data` for the current page.\",\n \"SearchInput — often placed in the same toolbar as Pagination. Resetting `value` to page 1 inside the search `onSearchChange` handler is mandatory; forgetting this is the most common bug when combining search and Pagination.\",\n ],\n example: `import { Pagination } from \"@godxjp/ui/navigation\";\n\n<Pagination value={page} total={filtered.length} pageSize={10} showTotal onValueChange={(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 usage: [\n \"DO compose the full sub-part tree: DropdownMenu (root) → DropdownMenuTrigger (with asChild to delegate to your Button/icon) → DropdownMenuContent → DropdownMenuItem / DropdownMenuSeparator / DropdownMenuLabel / DropdownMenuGroup. Omitting any level (e.g. rendering DropdownMenuContent without DropdownMenu as ancestor) breaks Radix context and the menu will not open.\",\n \"DO use DropdownMenuTrigger with asChild and pass a godx-ui Button or icon Button as the child — never render a raw <button> or <div> as the trigger, and never omit asChild when the child is already a button-like element (double-button nesting breaks a11y).\",\n \"DO use variant='destructive' on DropdownMenuItem for irreversible actions (delete, revoke, void) — this applies the semantic destructive colour token automatically without any className override.\",\n \"DO use DropdownMenuSub + DropdownMenuSubTrigger + DropdownMenuSubContent for nested sub-menus (e.g. 'Export' → 'CSV', 'PDF'). The ChevronRight icon is rendered automatically by DropdownMenuSubTrigger — do not add your own.\",\n \"DO use DropdownMenuCheckboxItem (with checked + onCheckedChange) or DropdownMenuRadioGroup + DropdownMenuRadioItem for toggle/selection menus such as column visibility or active view. These items manage their own checked indicator — do not layer a Checkbox or RadioGroup inside a plain DropdownMenuItem.\",\n \"DON'T use DropdownMenu for form submission — items fire onSelect callbacks, not form field values. There is no name prop for native form submission. If a menu selection must feed a form field, lift state into a controlled value and wire a hidden Input or use Select instead.\",\n ],\n useCases: [\n \"Row action menu in a DataTable: a '...' icon Button opens a DropdownMenu with Edit, Duplicate, DropdownMenuSeparator, then Delete (variant='destructive') — keeps the row compact and avoids inline button clutter.\",\n \"Topbar / avatar chip: a user-avatar Button triggers a DropdownMenu with Profile, Settings, DropdownMenuSeparator, Sign out — standard app-shell pattern for account actions.\",\n \"Bulk-action toolbar: after selecting rows, an 'Actions' Button opens a DropdownMenu with Approve, Reject, Export — prevents the toolbar from overflowing with individual buttons.\",\n \"Column visibility toggle in a report table: a 'Columns' Button opens a DropdownMenu whose items are DropdownMenuCheckboxItem entries, letting users show/hide columns without a Dialog.\",\n \"Quick status change on an accounting entry: a Badge-like trigger opens a DropdownMenu with DropdownMenuRadioGroup items (Draft, Posted, Voided) so the user can transition status without navigating away.\",\n \"Context menu for a sidebar nav item: right-click or kebab on a project entry opens a DropdownMenu with Rename, Duplicate, Archive actions scoped to that item.\",\n ],\n related: [\n \"Popover — use Popover when the floating panel needs arbitrary layout (filter forms, date pickers, rich content grids). Use DropdownMenu only for a list of discrete clickable actions or toggle items; DropdownMenu has no layout flexibility beyond label/separator/group.\",\n \"Command — use Command (cmdk) when the list is large, needs fuzzy-search filtering, or acts as a keyboard-driven command palette. DropdownMenu has no built-in search input; once the list exceeds ~8 items or needs filtering, switch to Command (often inside a Popover).\",\n \"Select — use Select when the purpose is choosing a value to submit in a form field (has a name prop for native form submission, renders a hidden select for a11y). Use DropdownMenu when the purpose is triggering actions, not picking a form value.\",\n \"Sidebar — use Sidebar for persistent left-rail navigation. DropdownMenu is transient (opens on click, dismisses on select); Sidebar is always-visible structural navigation.\",\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 tone=\"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: \"value\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Active step index (0-based).\",\n },\n {\n name: \"defaultValue\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Base offset for the first rendered step index.\",\n },\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Layout direction.\",\n },\n ],\n usage: [\n \"DO: Pass all steps via the `items` array (each `{ title, subtitle?, description?, icon?, status?, disabled? }`) — Steps is a single-component API with no child sub-components to compose manually.\",\n \"DO: Control the active step with `value` (0-based index). For async operations, set the top-level `status` prop (`'process'|'error'|'finish'`) to override the current step's icon — e.g. `status='error'` turns the active step red without touching `items`.\",\n \"DO: Use per-item `status` to pin individual steps independently of `value` (e.g. a skipped or already-errored step). Per-item `status` takes precedence over the derived status from `value`.\",\n \"DON'T: Use Steps for navigation that needs URL routing or tab-switching — it has no built-in panel rendering. Pair it with your own conditional panel or a `Tabs`/`Tabs` body; Steps only renders the indicator bar.\",\n \"DON'T: Wire `onValueChange` unless you actually support non-linear navigation. `onValueChange` makes every non-disabled step clickable (rendered as `<button>`); omitting it makes all steps non-interactive (`cursor-default`). Never set `disabled` on an item without also providing `onValueChange`, or the prop is meaningless.\",\n \"A11y: The `<ol>` is given `aria-label='Progress'` automatically. Individual steps render as `<button type='button'>` when `onValueChange` is present — ensure each `item.title` is descriptive enough to serve as the button label; avoid icon-only steps without a visible title.\",\n ],\n useCases: [\n \"Multi-step form wizard (entity onboarding, invoice creation): render Steps above a form, drive `current` from local state, advance on validated submit — use `status='error'` on the current step when server validation fails.\",\n \"Async background job tracker: display steps for a long-running import/export pipeline; poll job status and map job phases to `StepStatusProp` values (`'process'` with spinner for in-flight, `'finish'` for done, `'error'` for failed).\",\n \"Document approval workflow (accounting, contracts): map approval stages (Draft → Review → Approved → Archived) to `items` with per-item `status` reflecting the real state from the server — use `orientation='vertical'` for a sidebar timeline feel.\",\n \"Onboarding checklist sidebar: `orientation='vertical'` + `type='dot'` + `size='sm'` for a compact sidebar progress guide alongside a multi-section settings page.\",\n \"Non-linear step navigation (e.g. revisit a previous step to correct data): provide `onValueChange` and leave only future steps `disabled`; past and current steps become clickable buttons.\",\n ],\n related: [\n \"Timeline — use Timeline (from @godxjp/ui) when you need a chronological event log with timestamps and variable content per entry; use Steps when the number of stages is fixed and forward-progress is the semantic.\",\n \"Tabs / Tabs — use Tabs when each section has its own rendered panel and users switch freely between them; use Steps when stages are ordered and the indicator communicates completion state rather than just selection.\",\n \"Progress — use Progress for a single continuous percentage (file upload, quota fill); use Steps for discrete named stages with individual pass/fail status.\",\n \"Breadcrumb — use Breadcrumb for hierarchical location within a page tree; use Steps for sequential workflow progress where order and completion matter.\",\n ],\n example: `import { Steps } from \"@godxjp/ui/navigation\";\n\n<Steps value={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 usage: [\n \"DO mount AppProvider ONCE at the application root (e.g. in app.tsx or the Inertia layout), wrapping ALL children — every godx-ui picker (LocalePicker, TimezonePicker, DateFormatPicker, TimeFormatPicker), every formatDate call, and the Toaster all rely on the single context it provides. Nesting two AppProviders creates split contexts; inner pickers silently read the wrong one.\",\n \"DO NOT omit AppProvider and then try to use LocalePicker, TimezonePicker, or formatDate standalone — useAppContext() throws 'useAppContext must be used within <AppProvider>' at runtime. The only exception is using those pickers in fully controlled mode (value + onChange) which reads useOptionalAppContext() and returns null safely.\",\n \"DO use the `persist={false}` prop on AppProvider when writing isolated tests or standalone settings forms where localStorage should not be read or written. With the default `persist={true}` the provider reads from localStorage key `godxjp.app` on mount (after first render), so initial state may differ between SSR and client.\",\n \"DO set `defaultTimezone='system'` together with `systemTimezone={serverTimezone}` when your backend knows the legal entity's canonical timezone (e.g. 'Asia/Ho_Chi_Minh'). Use `defaultTimezone='browser'` (the default) only when you want the user's browser clock. Do NOT pass a raw IANA string to `defaultTimezone` if the user may be in a different zone — use the named aliases.\",\n \"DO wire `onLocaleChange`, `onTimezoneChange`, `onTimeFormatChange`, `onDateFormatChange` to persist changes server-side (e.g. patch user profile via Inertia router) in addition to the automatic localStorage write. These callbacks fire after state is set, so the new value is already reflected in context.\",\n \"DO restrict the timezone dropdown by passing `timezoneOptions={APP_TIMEZONE_PRESET}` (an exported constant) to AppProvider — all TimezonePicker instances that omit their own `options` prop will inherit this restricted list automatically from context. Without it, TimezonePicker renders the full IANA list (~600 entries).\",\n ],\n useCases: [\n \"App bootstrap in a multi-locale SaaS admin (ja/en/vi) — mount AppProvider at the root with the tenant's preferred locale and IANA timezone so every DataTable date column, every formatDate call, and every picker renders consistently in the user's locale without any per-component configuration.\",\n \"User settings page — render LocalePicker, TimezonePicker, DateFormatPicker, and TimeFormatPicker as zero-prop children inside the existing AppProvider; each picker reads and writes context automatically. Wire `onLocaleChange` to an Inertia form submit to persist the change to the server profile.\",\n \"Server-rendered Inertia app with SSR hydration — pass `defaultTimezone='system'` and `systemTimezone={sharedProps.timezone}` (injected via HandleInertiaRequests) so the initial render is timezone-deterministic and avoids hydration mismatches caused by browser-timezone detection.\",\n \"Multi-entity accounting dashboard — use `timezoneOptions` to restrict the picker to the legal entity's permissible zones (e.g. Southeast Asian IANA ids only), preventing users from accidentally switching to an out-of-scope timezone that would misrepresent transaction timestamps.\",\n \"Isolated preview / Storybook story — wrap a single component in `<AppProvider persist={false} defaultLocale='en'>` to give it a stable context without polluting localStorage between stories.\",\n \"Test harness — wrap the component under test in `<AppProvider persist={false} defaultLocale='ja' defaultDateFormat='iso'>` to assert locale-sensitive formatting output deterministically, independent of whatever the browser or stored preferences report.\",\n ],\n related: [\n \"LocalePicker — the language-selector control that reads/writes AppProvider locale context automatically when used as a zero-prop child. Prefer LocalePicker over calling setLocale from useAppContext() directly in UI.\",\n \"TimezonePicker — the timezone-selector control; inherits `timezoneOptions` from AppProvider context when its own `options` prop is omitted. Both pickers require AppProvider to be in the tree unless controlled props are passed.\",\n \"formatDate — the MANDATORY date/time formatter that reads locale, timezone, timeFormat, and dateFormat from AppProvider context. Do NOT call date-fns or Intl.DateTimeFormat directly; formatDate is the single source of truth for display.\",\n \"AppShell — the top-level application shell that composes AppProvider, AppShell, Sidebar, and Topbar into a single ready-to-use layout. If your project uses AppShell, AppProvider is already mounted inside it — do not add a second one.\",\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 usage: [\n \"DO import from `@godxjp/ui/datetime` — NOT from `date-fns` or any other datetime utility. `formatDate` is the single mandatory display entry point; calling `date-fns/format` directly bypasses AppProvider locale/timezone/dateFormat/timeFormat context and produces inconsistent output across the app.\",\n \"DO ensure `AppProvider` is mounted at the app root before the first `formatDate` call. The function reads a module-level context synced by `AppProvider` via `syncDatetimeContext`. Without it the fallback locale is `'vi'` / timezone `'Asia/Ho_Chi_Minh'` / `'24h'`, which will silently produce wrong output in Japanese or English apps.\",\n \"DO pass `null` or `undefined` safely — `formatDate` returns an em-dash `'—'` for null/undefined/empty string values. Never guard with a ternary before calling it.\",\n \"DO use `options.kind` when auto-detection is wrong: pass `kind: 'date'` for an ISO datetime string you want displayed as date-only, `kind: 'relative'` for age display (e.g. `'3日前'`), `kind: 'long'` for full PPP format in modals/detail panels. Auto-detection maps plain `yyyy-MM-dd` → `'date'`, `HH:mm` → `'time'`, everything else → `'datetime'`.\",\n \"DO pass `{ calendar: true }` when the `Date` object came from a react-day-picker calendar pick — this prevents timezone shift that would occur if the Date were treated as a UTC instant.\",\n \"DON'T hand-roll per-call locale/timezone resolution with `Intl.DateTimeFormat` or raw `date-fns/format`. The `options.locale` / `options.timezone` overrides exist for one-off per-cell display differences (e.g. showing a partner's local time), not as a substitute for AppProvider context.\",\n ],\n useCases: [\n \"Rendering all date/time columns in a DataTable — invoice due dates (`kind: 'date'`), transaction timestamps (`kind: 'datetime'`), and elapsed time since last sync (`kind: 'relative'`) all go through `formatDate` so the locale/timezone/12h-24h setting from AppProvider is respected everywhere.\",\n \"Displaying a single date/time field in a Descriptions or Card detail panel, e.g. `formatDate(invoice.issuedAt)` for the issued-at row — no extra formatting logic needed, null is handled as `'—'` automatically.\",\n \"Formatting a stored `HH:mm` string (24h canonical storage) for display according to the user's timeFormat preference — pass the raw `'14:30'` string and auto-detection routes it through `formatTimeOfDay`, outputting `'2:30 PM'` or `'14:30'` based on context.\",\n \"Rendering a 'last modified' timestamp with relative wording in an activity feed or audit log row — `formatDate(entry.updatedAt, { kind: 'relative' })` produces locale-correct relative strings like `'3日前'` / `'3 days ago'`.\",\n \"Converting a `Date` selected from `DatePicker` (react-day-picker) back to a display string — pass `{ calendar: true }` to avoid the UTC midnight shift that the default instant path would apply.\",\n ],\n related: [\n \"AppProvider — required peer that seeds locale, timezone, dateFormat, and timeFormat into the module-level context that `formatDate` reads. Must be mounted once at app root; omitting it means `formatDate` silently falls back to Vietnamese/Ho Chi Minh City defaults.\",\n \"DatePicker — the corresponding input control for calendar dates. Use `DatePicker` to capture a date from the user; use `formatDate(value, { calendar: true })` to display the picked `Date` object back as a string.\",\n \"DateFormatPicker / TimeFormatPicker / TimezonePicker — preference pickers that update AppProvider context; their selections are automatically picked up by subsequent `formatDate` calls with no extra wiring needed.\",\n \"TimePicker — the corresponding input control for HH:mm time values. Use `TimePicker` to capture time; use `formatDate(hhmm)` (auto-detects `'time'` kind) to display the stored `HH:mm` string respecting the user's 12h/24h preference.\",\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 onValueChange={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 onValueChange={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: \"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 content: [\n {\n value: \"tokyo\",\n label: \"東京都\",\n content: [\n { value: \"shinjuku\", label: \"新宿区\" },\n { value: \"shibuya\", label: \"渋谷区\" },\n ],\n },\n ],\n },\n {\n value: \"vn\",\n label: \"Việt Nam\",\n content: [\n {\n value: \"hcm\",\n label: \"TP. Hồ Chí Minh\",\n content: [\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 onValueChange={(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 onValueChange={(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\", content: \"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 onValueChange={(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', content: '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 content: [\n { value: \"current-assets\", label: \"Current Assets\", content: [\n { value: \"cash\", label: \"Cash\" },\n { value: \"ar\", label: \"Accounts Receivable\" },\n ],\n },\n { value: \"fixed-assets\", label: \"Fixed Assets\", content: [\n { value: \"equipment\", label: \"Equipment\" },\n ],\n },\n ],\n },\n {\n value: \"liabilities\",\n label: \"Liabilities\",\n content: [\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 onValueChange={(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 onValueChange={(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[]>([]); onValueChange={(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 { value: \"1010\", title: \"Cash\", description: \"Asset\" },\n { value: \"1020\", title: \"Accounts Receivable\", description: \"Asset\" },\n { value: \"2010\", title: \"Accounts Payable\", description: \"Liability\" },\n { value: \"3010\", title: \"Revenue\", description: \"Income\" },\n { value: \"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 onValueChange={(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 onValueChange={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 onValueChange={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/upload\"; // internal — prefer Upload variant=\"avatar-crop\" instead\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/*\" onValueChange={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} onValueChange={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 onValueChange={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} onValueChange={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 \"Progress — use Progress (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: \"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 Field 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 Field (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 Field — 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 / Field — 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 onValueChange={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 Field 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 (+ Field 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 Field 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 Field for custom markup. Every option must be wrapped in Field (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 / Field — 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 Field 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: \"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 \"Descriptions — use Descriptions 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: \"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 \"ButtonRefetch — 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: \"Avatar\",\n group: \"data-display\",\n tagline: \"Radix Avatar wrapper with image and fallback slots for users, teams, and entities.\",\n props: [\n {\n name: \"children\",\n type: \"ReactNode\",\n description: \"Compose AvatarImage and AvatarFallback.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes on the avatar root.\" },\n ],\n usage: [\n \"DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.\",\n \"DON'T use Avatar for decorative thumbnails; use CardCover or an img when the image is content rather than identity.\",\n ],\n useCases: [\"User profile chips\", \"Team member lists\", \"Account owner cells in a DataTable\"],\n related: [\"Badge — use beside Avatar for role/status metadata.\"],\n example: `import { Avatar, AvatarFallback, AvatarImage } from \"@godxjp/ui/data-display\";\n\n<Avatar>\n <AvatarImage src=\"/user.png\" alt=\"User\" />\n <AvatarFallback>UI</AvatarFallback>\n</Avatar>`,\n storyPath: \"data-display/Avatar.stories.tsx\",\n rules: [3, 35],\n },\n {\n name: \"Separator\",\n group: \"layout\",\n tagline: \"Radix Separator wrapper for tokenized horizontal or vertical dividers.\",\n props: [\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Divider direction.\",\n },\n {\n name: \"decorative\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Whether the separator is decorative for assistive tech.\",\n },\n ],\n usage: [\n \"DO use Separator for section dividers instead of raw border divs.\",\n \"DO set orientation='vertical' only when the parent gives it a stable height.\",\n ],\n useCases: [\n \"Separating toolbar groups\",\n \"Dividing stacked page sections\",\n \"Vertical split between metadata groups\",\n ],\n related: [\"Flex direction='col' — use for vertical spacing without a visible rule.\"],\n example: `import { Separator } from \"@godxjp/ui/layout\";\n\n<Separator />`,\n storyPath: \"layout/Separator.stories.tsx\",\n rules: [2, 3],\n },\n {\n name: \"Skeleton\",\n group: \"feedback\",\n tagline: \"Base pulsing skeleton block for custom loading placeholders.\",\n props: [\n { name: \"className\", type: \"string\", description: \"Size and layout classes for the block.\" },\n ],\n usage: [\n \"DO use Skeleton for a custom block when SkeletonRows/Table/Card do not match the final layout.\",\n \"DON'T use a spinner overlay for skeletonable page content.\",\n ],\n useCases: [\n \"Single loading line\",\n \"Custom card media placeholder\",\n \"Inline metadata placeholder\",\n ],\n related: [\"SkeletonRows\", \"SkeletonTable\", \"SkeletonStat\"],\n example: `import { Skeleton } from \"@godxjp/ui/feedback\";\n\n<Skeleton className=\"h-6 w-48\" />`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [3, 31],\n },\n {\n name: \"Toggle\",\n group: \"data-entry\",\n tagline: \"Radix Toggle wrapper with default/outline variants and tokenized sizes.\",\n props: [\n { name: \"pressed\", type: \"boolean\", description: \"Controlled pressed state.\" },\n {\n name: \"onPressedChange\",\n type: \"(pressed: boolean) => void\",\n description: \"Pressed-state callback.\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"outline\"',\n defaultValue: '\"default\"',\n description: \"Visual style.\",\n },\n {\n name: \"size\",\n type: '\"sm\" | \"md\" | \"lg\"',\n defaultValue: '\"md\"',\n description: \"Control size.\",\n },\n ],\n usage: [\n \"DO provide an accessible label when the toggle only contains an icon.\",\n \"DON'T use Toggle for multi-option selection; use ToggleGroup.\",\n ],\n useCases: [\"Bold/italic toolbar buttons\", \"Pinned filter toggles\", \"Compact view mode buttons\"],\n related: [\"ToggleGroup\", \"Button\"],\n example: `import { Toggle } from \"@godxjp/ui/data-entry\";\n\n<Toggle aria-label=\"Bold\">B</Toggle>`,\n storyPath: \"data-entry/Toggle.stories.tsx\",\n rules: [3, 13],\n },\n {\n name: \"ToggleGroup\",\n group: \"data-entry\",\n tagline: \"Radix ToggleGroup wrapper for single or multiple toggle selection.\",\n props: [\n {\n name: \"type\",\n type: '\"single\" | \"multiple\"',\n required: true,\n description: \"Selection mode.\",\n },\n { name: \"value\", type: \"string | string[]\", description: \"Controlled selected value(s).\" },\n {\n name: \"onValueChange\",\n type: \"(value: string | string[]) => void\",\n description: \"Selection callback.\",\n },\n ],\n usage: [\n \"DO choose type='single' for mutually exclusive toolbar modes.\",\n \"DO choose type='multiple' for independent formatting toggles.\",\n ],\n useCases: [\"Text alignment selector\", \"Formatting toolbar\", \"View density switcher\"],\n related: [\"Toggle\", \"RadioGroup\"],\n example: `import { ToggleGroup, ToggleGroupItem } from \"@godxjp/ui/data-entry\";\n\n<ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"left\">Left</ToggleGroupItem>\n</ToggleGroup>`,\n storyPath: \"data-entry/ToggleGroup.stories.tsx\",\n rules: [3, 13],\n },\n {\n name: \"AspectRatio\",\n group: \"layout\",\n tagline: \"Radix AspectRatio wrapper for stable media and preview frames.\",\n props: [\n {\n name: \"ratio\",\n type: \"number\",\n defaultValue: \"16 / 9\",\n description: \"Width divided by height.\",\n },\n { name: \"children\", type: \"ReactNode\", description: \"Content constrained to the ratio.\" },\n ],\n usage: [\n \"DO use AspectRatio for media, maps, charts, or previews that must not jump during load.\",\n \"DON'T use it for unconstrained text content.\",\n ],\n useCases: [\"Video embed frame\", \"Image preview slot\", \"Dashboard chart placeholder\"],\n related: [\"CardCover\", \"Skeleton\"],\n example: `import { AspectRatio } from \"@godxjp/ui/layout\";\n\n<AspectRatio ratio={16 / 9}>...</AspectRatio>`,\n storyPath: \"layout/AspectRatio.stories.tsx\",\n rules: [2, 3],\n },\n {\n name: \"Accordion\",\n group: \"data-display\",\n tagline:\n \"Radix accordion — vertically stacked, collapsible sections. Compose Accordion > AccordionItem > AccordionTrigger + AccordionContent.\",\n props: [\n {\n name: \"type\",\n type: '\"single\" | \"multiple\"',\n required: true,\n description: \"single = one open at a time; multiple = independent.\",\n },\n {\n name: \"collapsible\",\n type: \"boolean\",\n description: \"When type=single, allow closing the open item.\",\n },\n { name: \"value\", type: \"string | string[]\", description: \"Controlled open item(s).\" },\n {\n name: \"defaultValue\",\n type: \"string | string[]\",\n description: \"Uncontrolled initial open item(s).\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string | string[]) => void\",\n description: \"Open-state callback.\",\n },\n ],\n usage: [\n 'DO compose the full set: <Accordion type=\"single\" collapsible><AccordionItem value=\"a\"><AccordionTrigger/><AccordionContent/></AccordionItem></Accordion>.',\n \"DO give each AccordionItem a unique `value`.\",\n \"DON'T use it for primary navigation — that's Sidebar/Tabs. Accordion is for collapsible content/FAQ.\",\n ],\n useCases: [\n \"FAQ lists\",\n \"Grouped settings sections\",\n \"Collapsible detail panels on a record page\",\n \"Filter facet groups in a sidebar\",\n ],\n related: [\n \"Collapsible (single open/close region, no item set)\",\n \"Tabs (mutually-exclusive views, always one visible)\",\n ],\n example: `import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from \"@godxjp/ui/data-display\";\n\n<Accordion type=\"single\" collapsible>\n <AccordionItem value=\"ship\">\n <AccordionTrigger>配送について</AccordionTrigger>\n <AccordionContent>3〜5営業日でお届けします。</AccordionContent>\n </AccordionItem>\n</Accordion>`,\n storyPath: \"data-display/Accordion.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"HoverCard\",\n group: \"data-display\",\n tagline:\n \"Radix hover card — a rich popover shown on hover/focus of a trigger (for sighted-pointer affordances; not a replacement for Tooltip's short text).\",\n props: [\n {\n name: \"openDelay\",\n type: \"number\",\n defaultValue: \"700\",\n description: \"ms before opening on hover.\",\n },\n {\n name: \"closeDelay\",\n type: \"number\",\n defaultValue: \"300\",\n description: \"ms before closing.\",\n },\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state callback.\",\n },\n ],\n usage: [\n \"DO compose HoverCard > HoverCardTrigger > HoverCardContent.\",\n \"DO use for RICH preview content (a card, avatar + bio); for short plain-text hints use Tooltip.\",\n \"DON'T rely on it for essential info — hover isn't available on touch; provide the same content on click/tap elsewhere.\",\n ],\n useCases: [\n \"User/profile preview on @mention hover\",\n \"Entity preview (customer/account) on a table cell\",\n \"Glossary term definitions\",\n \"Commit/PR preview links\",\n ],\n related: [\n \"Tooltip (short text label, not rich content)\",\n \"Popover (click-triggered, interactive content)\",\n ],\n example: `import { HoverCard, HoverCardTrigger, HoverCardContent } from \"@godxjp/ui/data-display\";\n\n<HoverCard>\n <HoverCardTrigger>@yamada</HoverCardTrigger>\n <HoverCardContent>山田太郎 — 経理部</HoverCardContent>\n</HoverCard>`,\n storyPath: \"data-display/HoverCard.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"PasswordInput\",\n group: \"data-entry\",\n tagline:\n \"Input for passwords with a built-in show/hide eye toggle. Accepts all Input props except `type`.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n description: \"Controlled value (or use defaultValue/uncontrolled).\",\n },\n { name: \"name\", type: \"string\", description: \"Form field name for native submission.\" },\n { name: \"placeholder\", type: \"string\", description: \"Placeholder text.\" },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the field + toggle.\" },\n ],\n usage: [\n 'DO use for any password / secret field instead of `<Input type=\"password\">` so users get the show/hide affordance.',\n 'DO pass `name` + `autoComplete=\"current-password\"|\"new-password\"` for correct form/password-manager behavior.',\n \"DON'T add your own eye button — it's built in (and excluded from the tab order).\",\n ],\n useCases: [\n \"Login password field\",\n \"Sign-up / change-password forms (new-password)\",\n \"API key / secret entry in settings\",\n ],\n related: [\n \"Input (the base text field this wraps)\",\n \"FormField (label + error wrapper around it)\",\n ],\n example: `import { PasswordInput } from \"@godxjp/ui/data-entry\";\n\n<PasswordInput name=\"password\" autoComplete=\"current-password\" placeholder=\"パスワード\" />`,\n storyPath: \"data-entry/PasswordInput.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"PasswordStrength\",\n group: \"data-entry\",\n tagline:\n \"Evaluates password quality with a 0-4 score and optional rule checklist. Use with PasswordInput in secure forms.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n required: true,\n description: \"The current password value to evaluate.\",\n },\n {\n name: \"rules\",\n type: \"PasswordRule[]\",\n description: \"`length` | `upper` | `lower` | `number` | `symbol`. Omit to use defaults.\",\n },\n {\n name: \"showChecklist\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Render an optional checklist of rule checks below the bar.\",\n },\n {\n name: \"labels\",\n type: \"{ weak: string; fair: string; strong: string }\",\n description: \"Text labels for the three score buckets.\",\n },\n ],\n usage: [\n \"DO show PasswordStrength immediately below PasswordInput so users understand password quality before submitting.\",\n \"DO keep `rules` stable (default list is recommended for broad UI compatibility).\",\n \"DON'T treat the score as cryptographic strength; use it as a UI hint only.\",\n ],\n useCases: [\n \"Account signup password field\",\n \"Password reset workflow\",\n \"Admin user invite form\",\n ],\n related: [\"PasswordInput\", \"FormField\", \"Input\"],\n example: `import { PasswordInput, PasswordStrength } from \"@godxjp/ui/data-entry\";\n\nconst rules = [\"length\", \"upper\", \"lower\", \"number\", \"symbol\"] as const;\n\nexport default function PasswordBlock() {\n const [value, setValue] = useState(\"\");\n return (\n <div className=\"ui-stack\">\n <PasswordInput value={value} onChange={(event) => setValue(event.target.value)} />\n <PasswordStrength value={value} rules={rules} />\n </div>\n );\n}`,\n storyPath: \"data-entry/PasswordStrength.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"InputOTP\",\n group: \"data-entry\",\n tagline:\n \"One-time-code / 2FA input (input-otp) — N single-character slots that behave as one field. Compose InputOTP > InputOTPGroup > InputOTPSlot.\",\n props: [\n {\n name: \"maxLength\",\n type: \"number\",\n required: true,\n description: \"Number of slots (e.g. 6).\",\n },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n {\n name: \"onChange\",\n type: \"(value: string) => void\",\n description:\n \"Value callback (this is a true text input — onChange is the DOM-style value handler here).\",\n },\n { name: \"pattern\", type: \"string\", description: \"Allowed-char regex (e.g. digits only).\" },\n ],\n usage: [\n \"DO set `maxLength` to the code length and render that many InputOTPSlot with sequential `index`.\",\n \"DO wrap slots in InputOTPGroup; use InputOTPSeparator between groups (e.g. 3 + 3).\",\n \"DON'T build N separate Inputs — this is ONE field with paste, arrow-key, and caret handling built in.\",\n ],\n useCases: [\n \"2FA / OTP verification code\",\n \"Email / SMS confirmation code\",\n \"PIN entry\",\n \"Invite / redemption code\",\n ],\n related: [\"Input (a normal single text field)\", \"PasswordInput (masked secret field)\"],\n example: `import { InputOTP, InputOTPGroup, InputOTPSlot } from \"@godxjp/ui/data-entry\";\n\n<InputOTP maxLength={6}>\n <InputOTPGroup>\n <InputOTPSlot index={0} /><InputOTPSlot index={1} /><InputOTPSlot index={2} />\n <InputOTPSlot index={3} /><InputOTPSlot index={4} /><InputOTPSlot index={5} />\n </InputOTPGroup>\n</InputOTP>`,\n storyPath: \"data-entry/InputOTP.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"Rating\",\n group: \"data-entry\",\n tagline:\n \"Star-rating input (radiogroup) — controlled via value/onValueChange, form-submittable via name, supports readOnly display.\",\n props: [\n { name: \"value\", type: \"number\", description: \"Controlled rating (1..max).\" },\n {\n name: \"defaultValue\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Uncontrolled initial rating.\",\n },\n { name: \"onValueChange\", type: \"(value: number) => void\", description: \"Rating callback.\" },\n { name: \"max\", type: \"number\", defaultValue: \"5\", description: \"Number of stars.\" },\n { name: \"readOnly\", type: \"boolean\", description: \"Display-only (e.g. an average score).\" },\n {\n name: \"name\",\n type: \"string\",\n description: \"Hidden input name for native form submission.\",\n },\n ],\n usage: [\n \"DO use readOnly to DISPLAY a score (e.g. product average); interactive (default) for collecting a rating.\",\n \"DO pass `name` to submit the value in a plain form.\",\n \"DON'T render raw star icons for input — this handles keyboard (radiogroup), hover preview, and a11y.\",\n ],\n useCases: [\n \"Product / vendor review input\",\n \"Display an average score (readOnly)\",\n \"Feedback / CSAT survey\",\n \"Priority or quality scoring in admin\",\n ],\n related: [\"RadioGroup (non-star single choice)\", \"Slider (continuous 0-100 value)\"],\n example: `import { Rating } from \"@godxjp/ui/data-entry\";\n\n<Rating name=\"score\" defaultValue={4} onValueChange={(v) => console.log(v)} />`,\n storyPath: \"data-entry/Rating.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"TagInput\",\n group: \"data-entry\",\n tagline:\n \"Chips/tags input — type + Enter (or comma) to add a tag, Backspace to remove the last; controlled via value/onValueChange (string[]).\",\n props: [\n { name: \"value\", type: \"string[]\", description: \"Controlled tag list.\" },\n { name: \"defaultValue\", type: \"string[]\", description: \"Uncontrolled initial tags.\" },\n {\n name: \"onValueChange\",\n type: \"(tags: string[]) => void\",\n description: \"Tag-list callback.\",\n },\n { name: \"placeholder\", type: \"string\", description: \"Shown when empty.\" },\n {\n name: \"name\",\n type: \"string\",\n description: \"Hidden input (comma-joined) for native form submission.\",\n },\n ],\n usage: [\n \"DO use for free-form multi-value entry (labels, emails, keywords) where options aren't a fixed list.\",\n \"DO note dedupe is built in; Enter/comma commits, Backspace on empty removes the last chip.\",\n \"DON'T use for choosing from a KNOWN set — use Select (multiple) or a multi-Combobox instead.\",\n ],\n useCases: [\n \"Labels / tags on a record\",\n \"Recipient email entry\",\n \"Keyword / skill lists\",\n \"Ad-hoc filter terms\",\n ],\n related: [\n \"Select (multiple) — when the values come from a fixed option set\",\n \"Combobox (multi) — searchable known set\",\n ],\n example: `import { TagInput } from \"@godxjp/ui/data-entry\";\n\n<TagInput name=\"labels\" placeholder=\"ラベルを追加…\" onValueChange={(tags) => setTags(tags)} />`,\n storyPath: \"data-entry/TagInput.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"ContextMenu\",\n group: \"navigation\",\n tagline:\n \"Context menu primitives with keyboard support and compound parts for command-style action surfaces.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state callback.\",\n },\n { name: \"value\", type: \"string\", description: \"Selected value (for controlled patterns).\" },\n ],\n useCases: [\n \"Right-click action menu\",\n \"Contextual menus for rows and cards\",\n \"Nested action rows with shortcuts\",\n ],\n storyPath: \"navigation/ContextMenu.stories.tsx\",\n rules: [3, 6],\n example: `import {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n} from \"@godxjp/ui/navigation\";\n\n<ContextMenu>\n <ContextMenuTrigger>open</ContextMenuTrigger>\n <ContextMenuContent>\n <ContextMenuItem>Edit</ContextMenuItem>\n <ContextMenuItem>Delete</ContextMenuItem>\n </ContextMenuContent>\n</ContextMenu>`,\n },\n {\n name: \"Menubar\",\n group: \"navigation\",\n tagline: \"Application menubar primitives (menus, sub-menus, and check/radio items).\",\n props: [\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial selected value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Selection callback.\",\n },\n ],\n useCases: [\n \"Top-bar application command menus\",\n \"Workspace menus with nested items\",\n \"Desktop-like navigation shells\",\n ],\n storyPath: \"navigation/Menubar.stories.tsx\",\n rules: [3, 6],\n example: `import { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem } from \"@godxjp/ui/navigation\";\n\n<Menubar>\n <MenubarMenu>\n <MenubarTrigger>ファイル</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>新規作成</MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n</Menubar>`,\n },\n {\n name: \"NavigationMenu\",\n group: \"navigation\",\n tagline:\n \"Horizontal navigation menu with trigger/content/link primitives and viewport support.\",\n props: [\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Main-axis arrangement for the nav menu.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial selected value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Selection callback.\",\n },\n ],\n useCases: [\"Primary app navigation\", \"Sectioned marketing navigation\", \"Nested link groups\"],\n storyPath: \"navigation/NavigationMenu.stories.tsx\",\n rules: [3, 6],\n example: `import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger } from \"@godxjp/ui/navigation\";\n\n<NavigationMenu>\n <NavigationMenuList>\n <NavigationMenuItem>\n <NavigationMenuTrigger>ページ</NavigationMenuTrigger>\n </NavigationMenuItem>\n </NavigationMenuList>\n</NavigationMenu>`,\n },\n {\n name: \"ResizablePanel\",\n group: \"layout\",\n tagline: \"Resizable panel group/child/handle primitives from react-resizable-panels.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Panel identifier for persistence.\" },\n { name: \"defaultSize\", type: \"number\", description: \"Initial panel size (percent/units).\" },\n { name: \"minSize\", type: \"number\", description: \"Minimum size constraint.\" },\n { name: \"maxSize\", type: \"number\", description: \"Maximum size constraint.\" },\n ],\n useCases: [\"Split-pane layouts\", \"Resizable sidebars\", \"Code editors with adjustable zones\"],\n storyPath: \"layout/ResizablePanel.stories.tsx\",\n rules: [3, 6],\n example: `import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"@godxjp/ui/layout\";\n\n<ResizablePanelGroup>\n <ResizablePanel>Panel A</ResizablePanel>\n <ResizableHandle />\n <ResizablePanel>Panel B</ResizablePanel>\n</ResizablePanelGroup>`,\n },\n {\n name: \"Carousel\",\n group: \"data-display\",\n tagline:\n \"Embla-backed carousel primitives: previous/next controls, CarouselDots indicators, and a context API.\",\n props: [\n {\n name: \"opts\",\n type: \"Parameters<typeof useEmblaCarousel>[0]\",\n description: \"Embla options.\",\n },\n {\n name: \"plugins\",\n type: \"Parameters<typeof useEmblaCarousel>[1]\",\n description: \"Embla plugins.\",\n },\n {\n name: \"setApi\",\n type: \"(api: CarouselApi) => void\",\n description: \"Receive carousel API for custom logic.\",\n },\n ],\n useCases: [\"Feature cards\", \"Image galleries\", \"Horizontal stepping lists\"],\n storyPath: \"data-display/Carousel.stories.tsx\",\n rules: [3, 6],\n example: `import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, CarouselDots } from \"@godxjp/ui/data-display\";\n\n// CarouselDots reads the Embla api from context — no setApi wiring needed.\n<Carousel opts={{ loop: true }}>\n <CarouselContent>\n <CarouselItem>1</CarouselItem>\n <CarouselItem>2</CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n <CarouselDots />\n</Carousel>`,\n },\n {\n name: \"TimeInput\",\n group: \"data-entry\",\n tagline: \"Masking HH:mm input with validation and optional minute step quantization.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled HH:mm value.\" },\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial HH:mm value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Validated value callback.\",\n },\n { name: \"step\", type: \"number\", defaultValue: \"1\", description: \"Minute step.\" },\n { name: \"name\", type: \"string\", description: \"Form field name.\" },\n ],\n useCases: [\"Time filters\", \"Schedule pickers (calendar-free)\", \"HH:mm-only forms\"],\n storyPath: \"data-entry/TimeInput.stories.tsx\",\n rules: [3, 6],\n example: `import { TimeInput } from \"@godxjp/ui/data-entry\";\n\n<TimeInput value=\"09:00\" step={15} onValueChange={(time) => console.log(time)} />`,\n },\n {\n name: \"AppSettingPicker\",\n group: \"navigation\",\n tagline:\n \"One provider-bound Select for a single AppProvider setting, chosen by `kind` (locale | timezone | dateFormat | timeFormat) — replaces the former Locale/Timezone/Date-format/Time-format pickers. Throws if used without AppProvider AND without controlled value+onValueChange.\",\n props: [\n {\n name: \"kind\",\n type: '\"locale\" | \"timezone\" | \"dateFormat\" | \"timeFormat\"',\n description:\n \"Which AppProvider setting this picker reads and writes. Determines the option list, icon, trigger width, and the context value/setter used.\",\n },\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled value for the chosen kind. When omitted, reads the current value from AppProvider context for that kind.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description:\n \"Controlled change handler. When omitted, calls the matching AppProvider setter (setLocale/setTimezone/setDateFormat/setTimeFormat). Required together with value when no AppProvider is present.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra CSS classes merged onto the SelectTrigger.\",\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: Mount inside <AppProvider> for zero-config use — the picker reads and writes the context value named by kind, no value/onValueChange needed.\",\n \"DO: Use controlled mode (value + onValueChange) when managing state outside AppProvider, e.g. a standalone settings form or a Storybook story. Both are required together in this mode.\",\n \"DO NOT: Render without AppProvider and without both controlled props — it throws 'AppSettingPicker requires <AppProvider> or controlled value + onValueChange'.\",\n \"DO: Render four instances with different kind values to build a full preferences panel; they all share the same AppProvider context and stay in sync.\",\n \"DON'T hand-roll a locale/timezone/format Select — AppSettingPicker already composes Select + the right icon + translated, context-wired options. There is no separate LocalePicker/TimezonePicker/DateFormatPicker/TimeFormatPicker anymore; use kind.\",\n ],\n useCases: [\n 'App-shell top-nav language switcher: <AppSettingPicker kind=\"locale\" /> under AppProvider, persisting to localStorage with no extra state.',\n \"User settings page with all four preferences — render kind=locale, kind=timezone, kind=dateFormat, kind=timeFormat together under one AppProvider.\",\n \"Onboarding step that picks language/timezone before the rest of the app is configured — AppProvider persist={false} + controlled values to keep state local.\",\n 'Storybook/test harness without AppProvider — fully controlled: <AppSettingPicker kind=\"timeFormat\" value=\"24h\" onValueChange={fn} />.',\n ],\n related: [\n \"AppProvider — required peer unless fully controlled. Supplies locale/timezone/dateFormat/timeFormat plus their setters and the i18n context.\",\n \"Select — the data-entry primitive AppSettingPicker is built on; reach for Select directly for any non-AppProvider dropdown.\",\n \"formatDate — reads the same AppProvider date/time context that kind='dateFormat'/'timeFormat' write to.\",\n ],\n example: `{\\`// Uncontrolled — AppProvider manages and persists every setting\nimport { AppProvider } from \"@godxjp/ui/app\";\nimport { AppSettingPicker } from \"@godxjp/ui/navigation\";\n\nexport function SettingsPanel() {\n return (\n <AppProvider defaultLocale=\"ja\" defaultTimezone=\"Asia/Tokyo\">\n <AppSettingPicker kind=\"locale\" />\n <AppSettingPicker kind=\"timezone\" />\n <AppSettingPicker kind=\"dateFormat\" />\n <AppSettingPicker kind=\"timeFormat\" />\n </AppProvider>\n );\n}\n\n// Controlled — no AppProvider required\nimport { useState } from \"react\";\nimport { AppSettingPicker } from \"@godxjp/ui/navigation\";\n\nexport function LocaleField() {\n const [locale, setLocale] = useState(\"en\");\n return <AppSettingPicker kind=\"locale\" value={locale} onValueChange={setLocale} />;\n}\\`}`,\n storyPath: \"navigation/AppSettingPicker.stories.tsx\",\n rules: [3, 5, 6, 23],\n },\n {\n name: \"Field\",\n group: \"data-entry\",\n tagline:\n \"Label + optional description laid out beside a single checkbox/radio/switch control — the inline alternative to FormField's full block layout.\",\n props: [\n {\n name: \"id\",\n type: \"string\",\n description: \"id wired to the control via htmlFor; pass the same id to the child control.\",\n },\n { name: \"label\", type: \"ReactNode\", description: \"The field label, rendered as a <Label>.\" },\n {\n name: \"description\",\n type: \"ReactNode\",\n description: \"Optional helper text rendered under the label.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n description: \"The control (Checkbox/Radio/Switch) placed beside the label.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra CSS classes on the wrapper.\" },\n ],\n usage: [\n \"DO: Use Field to label a single boolean/choice control (Switch, Checkbox, Radio) in a compact two-column row — control beside label + description.\",\n \"DO: Match the child control's id to Field's id so the label is correctly associated.\",\n \"DON'T: Use Field for text inputs needing helper/error/required slots — use FormField (block layout) instead. There is no ChoiceField anymore; Field is the canonical name.\",\n ],\n useCases: [\n \"A settings list of toggle rows (notifications, auto-save) where each Switch has a label + description.\",\n \"A consent checkbox with an explanatory description beside it.\",\n \"A radio option row in a preferences form.\",\n ],\n related: [\n \"FormField — block label/helper/error/required layout for text inputs; use it instead when those slots are needed.\",\n \"Switch / Checkbox / Radio — the controls Field typically wraps.\",\n ],\n example: `{\\`import { Field, Switch } from \"@godxjp/ui/data-entry\";\n\nexport function NotifyRow() {\n return (\n <Field id=\"notify\" label=\"メール通知\" description=\"重要な更新をメールで受け取る\">\n <Switch id=\"notify\" defaultChecked />\n </Field>\n );\n}\\`}`,\n storyPath: \"data-entry/Field.stories.tsx\",\n rules: [23],\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","/** Canonical prop vocabulary taught by the MCP. Mirrors src/props/vocabulary. */\n\nexport interface PropVocabEntry {\n name: string;\n concept: string;\n values: string[];\n usedBy: string[];\n notes?: string;\n}\n\nexport const PROP_VOCABULARY: PropVocabEntry[] = [\n {\n name: \"ValueProp<T = string>\",\n concept: \"Abstract controlled value.\",\n values: [\"generic\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Tabs\", \"SearchSelect\"],\n },\n {\n name: \"DefaultValueProp<T = string>\",\n concept: \"Abstract uncontrolled initial value.\",\n values: [\"generic\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Tabs\"],\n },\n {\n name: \"OnValueChangeProp<T = string>\",\n concept: \"Callback for abstract value changes. DOM events continue to use onChange.\",\n values: [\"(value: T) => void\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Transfer\", \"settings pickers\"],\n },\n {\n name: \"OpenProp / DefaultOpenProp / OnOpenChangeProp\",\n concept: \"Disclosure state.\",\n values: [\"boolean\", \"(open: boolean) => void\"],\n usedBy: [\"Dialog\", \"Sheet\", \"Popover\"],\n },\n {\n name: \"SizeProp\",\n concept: \"Shared public size names.\",\n values: [\"xs\", \"sm\", \"md\", \"lg\"],\n usedBy: [\"Button\", \"Steps\", \"Switch\"],\n notes: \"Component-specific subsets must be documented. Old alias small is sm.\",\n },\n {\n name: \"ToneProp\",\n concept: \"Semantic status/color intent.\",\n values: [\"default\", \"success\", \"warning\", \"destructive\", \"info\", \"muted\", \"neutral\"],\n usedBy: [\"Badge\", \"Alert\"],\n notes: \"Status values belong in tone, not variant.\",\n },\n {\n name: \"GapProp\",\n concept: \"Shared layout gap scale.\",\n values: [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"],\n usedBy: [\"Stack\", \"Inline\"],\n notes: \"Inline uses an Exclude<GapProp, 'xl'> subset.\",\n },\n {\n name: \"TitleProp\",\n concept: \"Primary heading text.\",\n values: [\"React.ReactNode\"],\n usedBy: [\"PageContainer\", \"PageHeader\", \"EmptyState\", \"Dialog\"],\n },\n {\n name: \"DensityProp\",\n concept: \"Page/subtree density.\",\n values: [\"compact\", \"default\", \"comfortable\"],\n usedBy: [\"PageContainer\"],\n },\n];\n\nexport function findVocab(name: string): PropVocabEntry | undefined {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/prop(?:<.*>)?$/i, \"\");\n return PROP_VOCABULARY.find(\n (v) => v.name.toLowerCase().replace(/prop(?:<.*>)?$/i, \"\") === normalized,\n );\n}\n","/** Design token catalog taught by the MCP. Mirrors the 3-tier token model. */\n\nexport type TokenCategory = \"primitive\" | \"semantic\" | \"component\";\n\nexport interface TokenEntry {\n name: string;\n category: TokenCategory;\n role: string;\n tier: \"primitive\" | \"semantic\" | \"component\";\n}\n\nexport const TOKENS: TokenEntry[] = [\n {\n name: \"--wa-*\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Neutral decorative Japanese accent primitives for charts/tags/decoration only.\",\n },\n {\n name: \"--chart-1..6\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Neutral decorative chart primitives; @theme chart colors reference these tokens.\",\n },\n { name: \"--space-0..12\", category: \"primitive\", tier: \"primitive\", role: \"Raw spacing scale.\" },\n {\n name: \"--font-size-*\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Raw typography scale.\",\n },\n { name: \"--primary\", category: \"semantic\", tier: \"semantic\", role: \"Brand/action color role.\" },\n { name: \"--success\", category: \"semantic\", tier: \"semantic\", role: \"Success status role.\" },\n { name: \"--warning\", category: \"semantic\", tier: \"semantic\", role: \"Warning status role.\" },\n {\n name: \"--destructive\",\n category: \"semantic\",\n tier: \"semantic\",\n role: \"Destructive/error status role.\",\n },\n { name: \"--info\", category: \"semantic\", tier: \"semantic\", role: \"Information status role.\" },\n { name: \"--attention\", category: \"semantic\", tier: \"semantic\", role: \"Attention status role.\" },\n { name: \"--badge-space-*\", category: \"component\", tier: \"component\", role: \"Badge spacing.\" },\n {\n name: \"--card-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Card surface, border, spacing, and typography.\",\n },\n {\n name: \"--control-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Shared form control heights, padding, icons, and focus chrome.\",\n },\n { name: \"--table-*\", category: \"component\", tier: \"component\", role: \"Table row/cell sizing.\" },\n {\n name: \"--dialog-* / --alert-* / --skeleton-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Feedback component sizing and spacing.\",\n },\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 {\n number: 1,\n title: \"Storybook is mandatory\",\n body: \"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark.\",\n },\n {\n number: 2,\n title: \"Tokens, not utilities\",\n 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 },\n {\n number: 3,\n title: \"Radix for interactive primitives\",\n body: \"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)\",\n },\n {\n number: 4,\n title: \"shadcn-style ownership\",\n body: \"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)\",\n },\n {\n number: 5,\n title: \"One i18next singleton\",\n body: \"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)\",\n },\n {\n number: 6,\n title: \"WCAG 2.1 AA baseline\",\n 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 },\n {\n number: 7,\n title: \"SemVer 2.0 + Keep a Changelog 1.1\",\n body: \"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR.\",\n },\n {\n number: 8,\n title: \"Inclusive naming\",\n body: \"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced.\",\n },\n {\n number: 9,\n title: \"No marketing speak\",\n body: 'Banned: \"powerful\", \"robust\", \"blazing fast\", \"best-in-class\", \"seamless\", \"enterprise-grade\". State what it does.',\n },\n {\n number: 10,\n title: \"English is canonical for docs\",\n body: \"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness.\",\n },\n {\n number: 11,\n title: \"Submodule discipline\",\n 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 },\n {\n number: 12,\n title: \"Branch + PR workflow\",\n body: \"`feat/<scope>` / `fix/<scope>` → submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden.\",\n },\n {\n number: 13,\n title: \"TypeScript strict\",\n body: \"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link.\",\n },\n {\n number: 14,\n title: \"Every third-party library is shadcn / Radix-recommended\",\n 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 },\n {\n number: 15,\n title: \"No `@apply` re-encoding tokens\",\n 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 },\n {\n number: 16,\n title: \"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`\",\n body: \"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it.\",\n },\n {\n number: 17,\n title: \"`src/stories/` ↔ `src/components/` parity\",\n body: \"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`.\",\n },\n {\n number: 18,\n title: \"`docs/reference/<group>/` ↔ `src/components/<group>/` parity\",\n body: \"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`.\",\n },\n {\n number: 19,\n title: \"No service-specific anything\",\n body: '`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent=\"<palette>\"]`.',\n },\n {\n number: 20,\n title: 'No \"platform-only\" exports',\n body: \"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported.\",\n },\n {\n number: 21,\n title: \"Every component honours every theme axis\",\n 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 },\n {\n number: 22,\n title: \"100% match to the design canon\",\n 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 },\n {\n number: 23,\n title: \"Concept-first prop API\",\n 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 },\n {\n number: 24,\n title: \"Mobile-first\",\n 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 },\n {\n number: 25,\n title: \"Stories are docs; UI is the primitive\",\n 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 },\n {\n number: 26,\n title: \"Library isolation\",\n 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 },\n {\n number: 27,\n title: \"Per-group folder structure\",\n 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 },\n {\n number: 28,\n title: \"`src/` folder taxonomy\",\n 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 },\n {\n number: 29,\n title: \"Stories consume framework primitives only\",\n 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 },\n {\n number: 30,\n title: \"Story `render` returns JSX directly\",\n 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 },\n {\n number: 31,\n title: \"No nested wrapper / convenience primitives\",\n 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 },\n {\n number: 32,\n title: \"No redundant props\",\n 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 },\n {\n number: 33,\n title: \"Stories / source / docs name-synchronized\",\n 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 },\n {\n number: 34,\n title: \"Storybook source panel = real, copy-paste-ready code\",\n body: 'Storybook\\'s react-docgen serializer strips every function value (`cell: ({row}) => <JSX/>`, `render: ({field}) => <Input/>`, `rowClassName`, `renderItem`, …) to `() => {}`. Any story whose `render` passes a function-valued prop, references a module-level helper (`Badge`, `EMPLOYEE_COLUMNS`, etc.), or uses a render-prop pattern MUST override `parameters.docs.source.code` with the literal copy-paste-ready snippet — type aliases, helper functions spelled out, column definitions with cell JSX visible, inline data array. The `render()` callback stays as-is (module-level constants are fine for runtime performance); `source.code` is the marketing surface. Skip ONLY for stories whose JSX is purely static primitives Storybook can serialize verbatim (`<Button variant=\"primary\">Click</Button>`). The exemplar is `Table.Default` in `src/stories/data-display/Table.stories.tsx`.',\n },\n {\n number: 35,\n title: \"Status chips never wrap\",\n body: \"A `Badge` / `Badge` reads as one atomic unit. Its label must never break across lines — pin `white-space: nowrap` on the chip (done in `badge-layout.css`), especially inside narrow `DataTable` cells (スコープ / ステータス columns). If a cell is too tight, widen the column or shorten the label; never let the chip wrap.\",\n },\n {\n number: 36,\n title: \"Badge tone/icon are the colour escape hatch\",\n body: \"`Badge` 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 },\n {\n number: 37,\n title: \"DataTable is full-width — never inside a narrow grid column\",\n 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 },\n {\n number: 38,\n title: \"FilterBar stays OUT of CardContent flush\",\n 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 },\n {\n number: 39,\n title: \"Long text columns get an explicit width\",\n 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 },\n {\n number: 40,\n title: \"Pages are mobile-first\",\n 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 {\n number: 41,\n title: \"Drawer & dialog footer layout\",\n body: \"Sheet/Dialog/AlertDialog footers are a pinned action bar (Ant Design Drawer footer): the footer sticks to the bottom, SheetFooter draws a full-bleed top border, and actions are RIGHT-aligned with the PRIMARY button rightmost (Cancel/secondary to its left). A destructive / clear / reset action goes far-LEFT — give that button `className=\\\"mr-auto\\\"`. NEVER stack footer buttons full-width or center them.\",\n },\n];\n\nexport const VOCABULARY_TOKEN_RULES: CardinalRule[] = [\n {\n number: 1,\n title: \"Prop Registry Entry\",\n body: \"Prop vocabulary: every exported `*Prop` type in `src/props/components/` MUST have exactly one `COMPONENT_PROP_REGISTRY` entry.\",\n },\n {\n number: 2,\n title: \"Public Field Mapping\",\n body: \"Prop vocabulary: every public property in an exported component prop type MUST map to one `VOCABULARY_REGISTRY` entry or to a `local: true` registry record with a non-empty `reason`.\",\n },\n {\n number: 3,\n title: \"Vocabulary Exists\",\n body: \"Prop vocabulary: every vocabulary name referenced by `COMPONENT_PROP_REGISTRY[*].vocabulary` MUST exist in `VOCABULARY_REGISTRY`.\",\n },\n {\n number: 4,\n title: \"Shared Concepts\",\n body: \"Prop vocabulary: the same prop spelling, value kind, and semantic role used by two or more components MUST use one shared vocabulary entry.\",\n },\n {\n number: 5,\n title: \"GapProp\",\n body: \"Prop vocabulary: `gap` MUST use `GapProp`; `StackGapProp` and `InlineGapProp` MUST NOT be canonical registry entries.\",\n },\n {\n number: 6,\n title: \"TitleProp\",\n body: \"Prop vocabulary: primary heading text MUST use `TitleProp`; `PageTitleProp` MUST NOT be a canonical registry entry.\",\n },\n {\n number: 7,\n title: \"Value Props\",\n body: \"Prop vocabulary: abstract controlled values MUST use `value?: ValueProp<T>`, `defaultValue?: DefaultValueProp<T>`, and `onValueChange?: OnValueChangeProp<T>`; `onChange` MAY be used only for DOM event handlers or explicitly local compatibility wrappers.\",\n },\n {\n number: 8,\n title: \"Open Props\",\n body: \"Prop vocabulary: disclosure/open state MUST use `open?: OpenProp`, `defaultOpen?: DefaultOpenProp`, and `onOpenChange?: OnOpenChangeProp`.\",\n },\n {\n number: 9,\n title: \"ToneProp\",\n body: \"Prop vocabulary: semantic color/status intent MUST use `tone` with `ToneProp` or a documented status-specific subtype; `variant` MUST NOT include status-only values such as `success`, `warning`, `info`, or `neutral`.\",\n },\n {\n number: 10,\n title: \"Variant Scope\",\n body: \"Prop vocabulary: `variant` MAY be component-specific only when its registry entry documents the component semantics and allowed values; one global `VariantProp` MUST NOT be used to collapse non-interchangeable value unions.\",\n },\n {\n number: 11,\n title: \"SizeProp\",\n body: \"Prop vocabulary: public `size` values MUST use shared `SizeProp` names or a documented component-specific subset; aliases such as `small` MUST be renamed to the canonical shared value.\",\n },\n {\n number: 12,\n title: \"DensityProp\",\n body: \"Prop vocabulary: public density MUST use `DensityProp` when the component participates in page/subtree density; component-specific density subsets MUST be documented with a registry reason.\",\n },\n {\n number: 13,\n title: \"Named Events\",\n body: \"Prop vocabulary: no new public `HandlerProp` use is allowed for named user events; command callbacks MUST have event-specific names such as `onConfirm`, `onRetry`, `onDismiss`, or `onValueChange`.\",\n },\n {\n number: 14,\n title: \"Token Tiers\",\n body: \"Design tokens: package tokens MUST be organized into primitive, semantic, and component tiers.\",\n },\n {\n number: 15,\n title: \"Tier Roles\",\n body: \"Design tokens: primitive tokens MUST define raw scales or palettes only; semantic tokens MUST alias primitives by UI role; component tokens MUST alias semantic or primitive tokens by component part/state.\",\n },\n {\n number: 16,\n title: \"No Domain Nouns\",\n body: \"Design tokens: package CSS custom properties and Tailwind `@theme` exports MUST NOT contain app, customer, or business-domain nouns.\",\n },\n {\n number: 17,\n title: \"No Tracking Tokens\",\n body: \"Design tokens: `--tracking-*` and `--color-tracking-*` are forbidden in package source.\",\n },\n {\n number: 18,\n title: \"Component Token Names\",\n body: \"Design tokens: component-scoped tokens MUST live in the component tier and use `--{component}-{part}-{property}` or `--{component}-{property}-{state}` naming consistently.\",\n },\n {\n number: 19,\n title: \"Theme References\",\n body: \"Design tokens: Tailwind `@theme` color exports MUST reference package tokens; literal colors are allowed only when first registered as primitive or semantic tokens.\",\n },\n {\n number: 20,\n title: \"Decorative Primitives\",\n body: \"Design tokens: public raw/decorative primitive exports are allowed only under documented neutral namespaces such as `wa-*` or `chart-*`; undocumented raw ramps such as public `gray-*`/`blue-*` exports are forbidden.\",\n },\n {\n number: 21,\n title: \"Dark Semantic Overrides\",\n body: \"Design tokens: dark mode MUST override semantic tokens by role; component-token dark overrides require a documented component contrast reason.\",\n },\n {\n number: 22,\n title: \"Density Aliases\",\n body: \"Design tokens: density CSS MUST select token aliases and MUST NOT introduce new raw component dimensions when a token tier can hold the value.\",\n },\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:\n \"Fix the most common @godxjp/ui consumer mistakes & visual bugs (StatCard double-border, grey Badge, crushed/empty table headers, washed-out sidebar footer, Inertia layout crash, SSR hydration). Before → after.\",\n tags: [\n \"fixes\",\n \"migration\",\n \"bug\",\n \"cardstat\",\n \"statusbadge\",\n \"datatable\",\n \"sidebar\",\n \"gotcha\",\n \"review\",\n ],\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) StatCard shows a DOUBLE border (too thick)\n// Cause: StatCard IS already a bordered Card. Don't wrap it.\n// ❌ <Card><CardContent><StatCard label=\"x\" value=\"1\" /></CardContent></Card>\n// ✅ <ResponsiveGrid columns={4}><StatCard 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}><StatCard .../></ResponsiveGrid></Stack>\n\n// 2) Badge renders grey with a ○ (no colour) for localized/tier labels\n// Cause: it auto-maps only English lifecycle keys. (@godxjp/ui >= 6.1)\n// ❌ <Badge status=\"プレミアム\" />\n// ✅ <Badge status=\"プレミアム\" tone=\"success\" icon={null} /> // tier → pill, no icon\n// ✅ <Badge status=\"active\">公開中</Badge> // 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// ✅ <StatCard label=\"売上\" value=\"¥8.2M\" delta=\"+12%\" /> // + green / - red; inverse flips`,\n },\n\n {\n name: \"signup-form\",\n tagline:\n \"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:\n \"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:\n '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} onValueChange={(e) => setConfirm(e.target.value)} placeholder={slug} />\n </Stack>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>キャンセル</Button>\n <Button tone=\"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:\n \"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:\n \"Inertia + @godxjp/ui list page — PageContainer + FilterBar + DataTable + Badge + 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, StatCard, DataTable, EmptyState, Badge, 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) => <Badge status={c.scope} tone=\"info\" icon={null} /> },\n { key: \"status\", header: \"ステータス\", render: (c) => <Badge 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 <StatCard label=\"公開中\" value={coupons.filter((c) => c.status === \"公開中\").length} />\n <StatCard label=\"総利用数\" value={coupons.reduce((s, c) => s + c.usage, 0).toLocaleString()} />\n <StatCard 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 value={page} total={filtered.length} pageSize={PAGE_SIZE} showTotal onValueChange={(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:\n \"Inertia detail page — receives {id} prop, Descriptions (compound) + StatCard + 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, StatCard, EmptyState, Descriptions, Badge } 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 <StatCard label=\"累計購入額\" value={\\`¥\\${member.total.toLocaleString()}\\`} />\n <StatCard label=\"来店回数\" value={member.visits} />\n <StatCard label=\"ポイント\" value={member.points.toLocaleString()} />\n <StatCard label=\"LTV\" value={\\`¥\\${member.ltv.toLocaleString()}\\`} />\n </ResponsiveGrid>\n <Card>\n <CardContent>\n {/* Descriptions is COMPOUND — value goes in children, not a prop */}\n <Descriptions columns={2}>\n <Descriptions.Item label=\"氏名\">{member.name}</Descriptions.Item>\n <Descriptions.Item label=\"ランク\"><Badge status={member.rank} tone=\"info\" icon={null} /></Descriptions.Item>\n <Descriptions.Item label=\"ステータス\"><Badge status={member.status} /></Descriptions.Item>\n <Descriptions.Item label=\"登録日\">{formatDate(member.registeredAt)}</Descriptions.Item>\n </Descriptions>\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:\n \"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: \"badge-coloring\",\n tagline:\n \"Colour a Badge 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 { Badge } from \"@godxjp/ui/data-display\"\n\n// Badge 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<Badge status=\"active\">公開中</Badge> // green ✓ 公開中\n\n// 2) Unknown label — set tone explicitly (no icon, since the key is unknown):\n<Badge status=\"公開中\" tone=\"success\" />\n\n// 3) Tier / category — coloured pill, drop the misleading glyph with icon={null}:\n<Badge status=\"プレミアム\" tone=\"success\" icon={null} />\n<Badge status=\"ゴールド\" tone=\"warning\" icon={null} />\n<Badge status=\"法人共通\" tone=\"info\" icon={null} />\n\n// tone: \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\" (import type BadgeTone)\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 Badge 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\n/**\n * Who a skill is for:\n * - \"core\" — building/maintaining @godxjp/ui ITSELF (the library, its docs,\n * its MCP catalog). Hidden from the consumer-facing tools.\n * - \"consumer\" — building an APP that imports @godxjp/ui. Surfaced by\n * list_consumer_skills / route_consumer_task / get_consumer_skill.\n * - \"both\" — applies to either audience (e.g. universal taste/output rules).\n * Consumer tools surface audience ∈ {consumer, both}; core-only skills stay hidden\n * from them so an app-dev is never confronted with library-maintenance material.\n */\nexport type SkillAudience = \"core\" | \"consumer\" | \"both\";\n\nexport interface Skill {\n id: string;\n name: string;\n /** Intended audience — drives the consumer-namespace tool filtering. */\n audience: SkillAudience;\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\n/** True if a skill should be visible to the consumer-facing tools. */\nexport function isConsumerSkill(s: Skill): boolean {\n return s.audience !== \"core\";\n}\n\nexport const SKILLS: Skill[] = [\n // ── taste (foundational) ───────────────────────────────────────\n {\n id: \"taste\",\n audience: \"both\",\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: \"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 audience: \"consumer\",\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:\n \"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:\n \"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:\n \"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 audience: \"consumer\",\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:\n \"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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"both\",\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:\n \"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:\n \"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 audience: \"both\",\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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 // ── component discipline (hard contract) ───────────────────────\n {\n id: \"component-discipline\",\n audience: \"core\",\n name: \"Component discipline — international standards (hard contract)\",\n whenToUse:\n \"MANDATORY before creating or changing ANY @godxjp/ui component, recipe, doc, or example. Enforces real primitives only, no duplication, i18n (Intl/CLDR/ISO/IANA/BCP-47), WAI-ARIA APG + WCAG 2.2 AA, RTL, and the controlled-vocabulary API.\",\n source: \"@godxjp/ui .claude/skills/godxjp-ui-component + international-standardization audit\",\n sections: [\n {\n id: \"real-primitives\",\n title: \"Real primitives only — never invent / fake / raw HTML\",\n tagline: \"Compose installable @godxjp/ui only; no hand-rolled wrappers, no raw controls.\",\n body: `NEVER invent/hand-roll a component, fake the design with styled <div>s, or use raw\n<input>/<select>/<button>/<textarea>/<table>. Use Select, Input, Button, Textarea, DataTable,\nCheckbox, RadioGroup, Switch. Compose fully: CardContent for padding; a table = Card +\nCardContent flush + DataTable in a default padded PageContainer (NOT variant=\"flush\").\nMCP-first: get_component before writing; never guess a prop. No duplication — Select\n(showSearch/loadOptions) is the only searchable/async select; there is no Combobox/SearchSelect/\nCountrySelect/Autocomplete; the 4 i18n pickers are one AppSettingPicker kind=…`,\n },\n {\n id: \"i18n-intl\",\n title: \"i18n via t() + Intl/CLDR\",\n tagline: \"Every string + aria-label through t(); format via Intl with the active locale.\",\n body: `Zero hardcoded English/Japanese. Numbers/currency (ISO 4217, minor units from\nresolvedOptions) + bytes via Intl.NumberFormat; dates via the date subsystem (Intl.DateTimeFormat,\nIANA tz, ISO-8601); names via Intl.DisplayNames (countries ISO 3166-1 alpha-2, languages BCP-47);\nplurals via Intl.PluralRules category maps. No emoji flags. No hand-maintained currency/country\nlists.`,\n },\n {\n id: \"a11y-apg\",\n title: \"WAI-ARIA APG + WCAG 2.2 AA\",\n tagline: \"Correct roles/aria/keyboard/focus + a vitest-axe test (0 violations).\",\n body: `Implement the APG pattern: role/landmark, aria-current/expanded/selected/sort/busy +\naria-live/activedescendant, aria-errormessage+aria-invalid. Keyboard: roving tabindex, arrows,\nHome/End, Enter/Space, Esc, visible focus, no positive tabindex. ≥24px targets (2.5.8); never\ncolour-only state (1.4.1 — add sr-only text); icon-only buttons need a name. Add a *.a11y.test.tsx\nwith expectNoA11yViolations. Prefer Radix/cmdk/vaul for ARIA.`,\n },\n {\n id: \"rtl-vocab\",\n title: \"RTL + controlled-vocabulary API\",\n tagline: \"Logical CSS only; value/defaultValue/onValueChange; size md not default.\",\n body: `RTL: logical CSS only (ms/me/ps/pe, start/end, border-s/e, rounded-s/e, text-start/end)\n— never physical ml/mr/pl/pr/left/right. API: controlled triad value/defaultValue/onValueChange\n(open/onOpenChange; checked/onCheckedChange; pressed/onPressedChange); size ∈ xs|sm|md|lg (never\n\"default\"); positive booleans; tone for status; forward ref + ...props + className + id; export\nXProp + XProp as XProps and register in props/registry. Then: add an MCP catalog entry + a\nreal-screen docs page; verify typecheck/lint/audit/check:*/preview:build/test all green.`,\n },\n {\n id: \"report-bug\",\n title: \"Found a library-level defect → file a gh issue (never paper over it)\",\n tagline:\n \"A missing token / wrong vocab / broken a11y in the system is a bug to report, not to work around.\",\n body: `If satisfying this contract is blocked by @godxjp/ui itself — a token tier that\ndoesn't exist, a primitive missing the controlled-vocabulary prop, a Radix wiring with a\nreal a11y bug, a catalog example that's wrong — the contract says STOP and fix the SYSTEM,\nnot the call site. Don't bake a one-off around it. If you can fix the library in this repo,\ndo. If you can't (or you're a consumer agent without write access), open a detailed GitHub\nissue: use the draft_bug_report MCP tool to produce the issue body + a 'gh issue create\n--repo godx-jp/godxjp-ui …' command, linking the component (get_component) and the cardinal\nrule (get_rule) involved, with a minimal repro, expected vs actual, version, and env.`,\n },\n ],\n },\n\n // ── design-to-page (consumer: handoff → real page) ─────────────\n {\n id: \"design-to-page\",\n audience: \"consumer\",\n name: \"Design handoff → real page (consumer build guide)\",\n whenToUse:\n \"You (a consumer agent) received a Claude Design handoff — a bundle/mock/screenshot/HTML prototype or a written brief — and must build it as a REAL page with @godxjp/ui. Read this BEFORE writing any JSX. It teaches: read intent, map every block to a real primitive via this MCP, consume existing tokens, apply the dxs-kintai DNA, treat tables as the centerpiece, resolve gaps by extend-or-ask, and verify.\",\n source:\n \"@godxjp/ui .design/research (chats-intent, tables, atomic-components) + dxs-kintai SKILL/colors_and_type.css\",\n sections: [\n {\n id: \"read-intent\",\n title: \"Read the intent — chats before pixels\",\n tagline: \"A handoff is a prototype, not production code. Build the intent, not the markup.\",\n body: `A Claude Design bundle is HTML/CSS/JS to LOOK AT — never transcribe its DOM.\nIf the bundle has chats/*.md, read them FIRST: they hold what the user actually\nwanted after iterating, the directions rejected, and the explicit rules. The final\nHTML is just the last output; the chat is the intent. Then read the README/SKILL +\ncolors_and_type.css for the DNA. Distil each screen to ONE primary question it\nanswers (one-intent-per-screen) before choosing components. Honesty rules that\nrecur in this DNA: render only VALID actions (no disabled-button noise — a punch\ncard off-state shows Check-In only, never a greyed Check-Out); label = identity\n(never changes), helper row = state (error/help goes BELOW, never recolours the\nlabel); entry-point affordances live in chrome, not floating in content.`,\n },\n {\n id: \"map-to-primitives\",\n title: \"Map every block to a real primitive — MCP-first, never hand-roll\",\n tagline:\n \"For each visual block ask 'which @godxjp/ui component is this?' — list_primitives, then get_component.\",\n body: `NEVER hand-roll a styled <div> that looks like a Card, or use raw\n<input>/<select>/<button>/<table>. Decompose each screen into a shopping list and\nresolve each item through THIS MCP: list_primitives to discover, get_component to\nconfirm the exact prop/union before you write (never guess a prop). Typical map:\npage chrome → AppShell/Sidebar/Topbar/PageContainer; stat row → ResponsiveGrid +\nStatCard; data grid → DataTable; status pill → Badge tone=…; filter row → Form\ninline + Select/Input; org→branch → Cascader/TreeSelect; date/time → DatePicker/\nTimePicker; ⌘K → Command; bulk drawer/detail → Drawer/Sheet/Dialog; split list+\ndetail → SplitPane/Resizable; empty → EmptyState; confirm → AlertDialog; toast →\nSonner. No duplication: Select (showSearch/loadOptions) is the ONLY searchable/\nasync select (no Combobox/Autocomplete); the 4 i18n pickers are one AppSettingPicker\nkind=…. A table = Card + CardContent-flush + DataTable (not PageContainer flush).`,\n },\n {\n id: \"tokens-exist\",\n title: \"Tokens already exist — consume var(--…), never redeclare\",\n tagline: \"The design's colors_and_type.css is already implemented as foundation.css.\",\n body: `The handoff's colors_and_type.css (SmartHR blue, wa-iro, M PLUS 2, the\ndensity scale) is ALREADY shipped as @godxjp/ui's foundation tokens. Never paste a\nhex, never redeclare a token, never invent a neutral. Consume var(--…) and the\nsemantic utilities. Use get_tokens (MCP) to find the right name — if a token seems\nmissing it almost certainly exists under a different name. Soft tints come from\ncolor-mix(in oklch, var(--primary) 15%, transparent), NOT a new pale hex. Control\nheights come from the density scale (xs 24 / sm 28 / default 32 / lg 36 / xl 44),\nnever a literal px. Radii: card 6px, control 4px, inner pill 2px.`,\n },\n {\n id: \"dna\",\n title: \"Apply the dxs-kintai DNA\",\n tagline:\n \"渋み / 間 / 簡素 — fixed color signaling, dense, small headings, 14/1.7, no emoji.\",\n body: `These rules survive when you drop the prototype's divs:\n• 渋み (restraint): primary chroma ≤ 0.18 — --primary is the single most-important\n action + brand surfaces ONLY, never status. No gradients, no pill cards, no\n saturated brand.\n• 間 (breathing): body 14px / 1.7 (NEVER 16/1.5); tabular-nums on every numeric\n column/stat so digits align under 1.7 leading.\n• 簡素 (simplicity): three weights only — 400/500/700 (no 300, no 600). Headings\n stay SMALL: h1 = 20px, h2 = 18 (not 32) — JP enterprise is dense, big headings\n waste 間.\n• Color signaling is FIXED-mapping: success 若竹 · warning 山吹(yellow) · info 群青\n · attention 朱(orange — PREFER over red for non-destructive: 遅刻/lateness) ·\n danger 茜(destructive only). Wa-iro is decorative (charts/tags/tenant) — NEVER\n remap a wa-iro hue to a semantic role.\n• Density up front: compact 28 (heavy tables) · default 32 · comfortable 44 (login/\n mobile, 44px touch floor). Set on the container; don't mix mid-page.\n• Cards: 1px border, NO shadow at rest (shadows only on popover md / dialog xl).\n• Copy quiet & factual — 「承認しました」 not 「承認に成功しました🎉」. Empty state =\n one calm sentence, no illustration. NO emoji in product UI; Lucide 1.5px icons,\n currentColor, sized by context (14 table / 16 nav / 18 button / 20 header).\n• Multi-tenant: tenants override only --primary/--ring/--foreground; semantic\n colors stay shared (a \"rejected\" badge means the same everywhere).`,\n },\n {\n id: \"tables-central\",\n title: \"Tables are the centerpiece — DataTable + the variant catalogue\",\n tagline: \"Enterprise 勤怠/admin lives in tables; showcase the family broadly.\",\n body: `Most of this DNA's real value is in tables — make DataTable the\ncenterpiece. One shell: Card + CardContent-flush wrapping DataTable (1px border,\n6px radius, no shadow). Region order: view tabs · toolbar (search + ⌘K + density +\ncolumns + import/export + primary CTA) · active-filter chip bar · table · footer\ntotals · pagination — every region optional. Build each pattern as its own block:\nassembled CRUD list · bulk-action toolbar (selection REPLACES toolbar; cross-page\n\"select all 1,284\"; destructive isolated last) · column manager · advanced filter\nAND/OR · sort/resize · expandable detail row · inline editable row (row-level\ncommit, dirty dot, \"未保存\" footer) · grouped rows w/ subtotals · tree rows · sticky\ncolumns + horizontal scroll · pagination ×3 (numbered/load-more/cursor) · import/\nexport stepper · empty/loading(Skeleton)/error/no-perm states · footer totals ·\ncompact kintone grid · conditional row/cell formatting. Cells: status → Badge tone;\nidentity → Avatar + two-line; numerics right-aligned tabular-nums with — for null;\nIDs mono. Confirmed (確定済) rows are frozen — no edit, no destructive bulk. Row\nstates change only background via color-mix, never height/padding. get_component\nDataTable + get_vocab ColumnDef/TableDensity/SortState before you build.`,\n },\n {\n id: \"gaps-extend-or-ask\",\n title: \"Gaps → extend or ask — never invent\",\n tagline: \"A block no primitive expresses is a decision, not a hand-roll.\",\n body: `When a block has no clean primitive/prop/variant, do NOT bake a bespoke\none-off into the page. First try to EXTEND: can an existing component take one more\ntone/size/variant/slot, or be composed from existing primitives (e.g. a punch-card\nFSM, a mobile selection-bar, an i18n locale-field are compositions over Button/Card/\nBadge/Tabs/Input, not new primitives)? If it's a genuine gap or you're unsure, STOP\nand ASK the user (or surface it as an ADR/decision) — name the gap, propose\n\"new variant on <X> vs. app-level composition vs. new component\", and converge\nbefore building. Known gaps to expect in this DNA (ask rather than invent): three-\nlevel table density (current is binary), multi-sort priority badges, column resize/\nmanager, numbered/load-more pagination, expandable/editable/grouped/tree/sticky-col\ntable modes, filter chip bar + AND/OR panel, saved-view tabs, week-timeline/staff×\ntime calendar, multilingual-field, no-code builders. Never silently fill a gap.`,\n },\n {\n id: \"verify\",\n title: \"Verify — states complete, a11y, build green\",\n tagline:\n \"Every state shown, WCAG 2.2 AA, typecheck/lint/audit clean, eyeballed at 3 widths.\",\n body: `Before calling it done: every prop × union value × state is exercised\n(default/hover/focus/active/disabled/loading/empty/error) — Skeleton for INIT fetch,\nspinner/loading for active save, EmptyState for no-data, inline error near the field\n(not a disappearing toast). A11y: correct roles/landmarks, keyboard (arrows/Home/End/\nEnter/Esc, visible focus, no positive tabindex), ≥24px targets, never colour-only\nstate (add sr-only text), icon-only buttons have a name; aim for 0 vitest-axe\nviolations. i18n: zero hardcoded strings — every label + aria-label through t(),\nformat numbers/dates via Intl. Then run the build: pnpm typecheck + pnpm lint +\npnpm audit must be green, console clean, and eyeball the page at 390 / 768 / 1280\n(atoms never wrap, containers wrap with row-gap, tabs horizontal-scroll, grids\nminmax(0,1fr), heights never break).`,\n },\n {\n id: \"report-bug\",\n title: \"godx-ui bug / can't-follow-a-rule → file a gh issue (never fake it)\",\n tagline:\n \"If the LIBRARY is wrong, report it — don't hand-roll a workaround that hides the bug.\",\n body: `When you CANNOT satisfy a rule because @godxjp/ui itself is at fault — a\nprimitive doesn't expose the controlled-vocabulary prop you need, a token is\nmissing, a component has a real a11y/behaviour bug, an example in the catalog is\nwrong — the rule is: DO NOT silently hand-roll/fake a replacement to dodge it (that\njust buries a library bug inside every app). Instead:\n• DON'T: copy a primitive's internals into your app, swap in a raw <input>/<div>, or\n redeclare a token to route around the defect.\n• DO: open a detailed GitHub issue against the library, then apply the SMALLEST\n possible local workaround marked // TODO(godxui#<n>: <summary>) so it's grep-able\n and removed once fixed.\n• Use the MCP tool draft_bug_report to generate the issue body + a copy-paste\n 'gh issue create --repo godx-jp/godxjp-ui …' command. Include: the component/rule\n (link via get_component/get_rule), a minimal repro, expected vs actual, the\n installed @godxjp/ui version, and your env. A vague \"X is broken\" issue is not\n enough — the report must let a maintainer reproduce in one paste.`,\n },\n ],\n },\n\n // ── compose-a-screen (consumer: primitives → a finished screen) ──\n {\n id: \"compose-a-screen\",\n audience: \"consumer\",\n name: \"Compose a screen — primitives → a finished app view (consumer)\",\n whenToUse:\n \"You (a consumer agent) are building a NEW screen/page in an app that imports @godxjp/ui — from a written brief or product requirement, not a design handoff. Read this to assemble it from real primitives via this MCP: pick the right components, lay out one-intent-per-screen, wire every state + a11y + i18n, and verify. For a Claude Design handoff bundle/mock specifically, use design-to-page instead.\",\n source:\n \"@godxjp/ui MCP (consumer surface) — taste/one-intent + component-discipline + dxs-kintai DNA\",\n sections: [\n {\n id: \"pick-primitives\",\n title: \"Pick primitives via the MCP — never hand-roll, never guess a prop\",\n tagline:\n \"Decompose the screen into a shopping list; resolve each item with list_primitives → get_component.\",\n body: `Start from the requirement, not the markup. Write a shopping list of every\nblock the screen needs, then resolve each through THIS MCP before writing JSX:\nlist_primitives (discover the group), get_component <Name> (confirm the exact\nprop/union/default — never guess), suggest_primitive / search_components when unsure\nwhich fits. Hard rules: compose ONLY real @godxjp/ui primitives — no styled <div>\nfaking a Card, no raw <input>/<select>/<button>/<textarea>/<table>. No duplication:\nSelect (showSearch/loadOptions) is the ONLY searchable/async select (there is no\nCombobox/Autocomplete/CountrySelect); the 4 i18n pickers are one AppSettingPicker\nkind=…. A table = Card + CardContent-flush + DataTable. If a block has no clean\nprimitive, see gaps handling in design-to-page/gaps-extend-or-ask + report-bug.`,\n },\n {\n id: \"assemble-screen\",\n title: \"Assemble it — one intent per screen, real chrome, fixed signaling\",\n tagline:\n \"One primary question per page; AppShell/PageContainer chrome; --primary once; semantic color is fixed.\",\n body: `Distil the screen to ONE primary question it answers (one-intent-per-screen):\n1–2 hero facts + ONE primary list/form + contextual actions; push tertiary content to\na Sheet/Dialog/next page. An 8-stat-card wall is a red flag. Use real page chrome\n(AppShell/Sidebar/Topbar/PageContainer) — content never touches the viewport edge,\ntwo bordered surfaces never touch (間/breathing via Stack gap). Exactly ONE --primary\naction per view; status uses the FIXED semantic mapping (success/warning/info/\nattention/danger) — never recolor a wa-iro hue into a role, never use --primary for\nstatus. Pick density up front (compact 28 heavy-table / default 32 / comfortable 44\nlogin-mobile) and don't mix it mid-page. Hierarchy from type weight+size+color\n(20/18/14/13 × 400/500/700), not colored background blocks. Mobile-first: default one\ncolumn, add columns only at md:/lg: when each keeps ≥14px body at ≥~280px width.`,\n },\n {\n id: \"state-and-a11y\",\n title: \"Wire every state + a11y + i18n (the part that gets skipped)\",\n tagline:\n \"default/hover/focus/active/disabled/loading/empty/error all handled; APG keyboard; t() everything.\",\n body: `A screen isn't done at the happy path. Handle every state: Skeleton for INIT\nfetch (no data yet), Form loading / Spinner for active save (data present), EmptyState\nfor no-data (one calm sentence, no illustration), inline error near the field via\nFormField (NOT a disappearing toast). Forms: explicit label + help + error always —\nnever placeholder-as-label. A11y (WAI-ARIA APG + WCAG 2.2 AA): correct roles/landmarks,\nkeyboard (arrows/Home/End/Enter/Esc, visible focus, no positive tabindex, return focus\non close), ≥24px targets, never colour-only state (add sr-only text), icon-only buttons\nneed a name. i18n: zero hardcoded strings — every label + aria-label through t();\nnumbers/currency/dates via Intl with the active locale (ISO 4217/8601, IANA tz),\nplurals via Intl.PluralRules. State-truthful affordances: a parent checkbox aggregates\nits children (checked/indeterminate/empty); a held value is visible when a control\nopens; controlled inputs mirror type↔click both ways (a controlled value with no\nsynchronous onValueChange FREEZES the input).`,\n },\n {\n id: \"verify\",\n title: \"Verify — states shown, console clean, build green, 3 widths\",\n tagline:\n \"Drive every interactive control; 0 console errors/warnings; typecheck/lint green; eyeball 390/768/1280.\",\n body: `Before calling the screen done: drive EVERY interactive control to its\nterminal state in a real browser (don't infer behaviour from source) and read the\nDevTools console — a <button>-in-<button>/hydration/act()/404 warning is a FINDING,\nnot noise. Confirm: every prop × union × state is exercised; held values visible on\nopen; multi-step selections (date range, capped multi-select) can be restarted from a\ncomplete state, not trapped; controlled mirrors update both directions. Run the app's\nbuild: typecheck + lint clean, console clean, and eyeball at 390 / 768 / 1280 (atoms\nnever wrap, containers wrap with row-gap, natural-width components stay w-fit, no\ndecorative edge fades, no dead grey panes). If a failure traces to @godxjp/ui itself,\ndo not fake around it — see report-bug.`,\n },\n {\n id: \"report-bug\",\n title: \"godx-ui bug / can't-follow-a-rule → file a gh issue (never fake it)\",\n tagline:\n \"If the LIBRARY is wrong, report it — don't hand-roll a workaround that hides the bug.\",\n body: `Same contract as design-to-page/report-bug: when a rule is impossible because\n@godxjp/ui is at fault (missing token, a primitive without the controlled-vocabulary\nprop, a real a11y/behaviour bug, a wrong catalog example) — DO NOT silently fake a\nreplacement. DON'T copy primitive internals, drop to raw HTML, or redeclare a token to\ndodge it. DO open a detailed GitHub issue (use the draft_bug_report MCP tool to build\nthe body + the 'gh issue create --repo godx-jp/godxjp-ui …' command), then apply the\nsmallest local workaround tagged // TODO(godxui#<n>: <summary>). The issue must carry a\nminimal repro, expected vs actual, the installed version, and env — enough to\nreproduce in one paste.`,\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, opts?: { consumerOnly?: boolean }): 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(\n [\"premium\", \"awwwards\", \"agency\", \"linear\", \"apple\", \"high-end\", \"luxury\"],\n \"soft\",\n \"vibe-archetypes\",\n \"Premium tier — pick a Vibe + Layout archetype + apply Double-Bezel.\",\n [\"soft/double-bezel\", \"soft/magnetic-hover\"],\n );\n\n // Marketing / landing\n route(\n [\"landing page\", \"marketing\", \"hero\", \"long scroll\"],\n \"imagegen-web\",\n \"hero-composition-bias\",\n \"Landing pages benefit from hero composition variety + per-section image generation.\",\n [\"gpt-tasteskill/principles\", \"soft/layout-archetypes\"],\n );\n\n // Mobile app screens\n route(\n [\"mobile app\", \"ios\", \"android\", \"phone screen\", \"onboarding flow\"],\n \"imagegen-mobile\",\n \"principles\",\n \"Mobile app design — generate screens first, avoid phone-shaped-website.\",\n [\"taste/mobile-first\"],\n );\n\n // Workspace / Notion-like\n route(\n [\"workspace\", \"notion\", \"document\", \"editorial\", \"knowledge base\"],\n \"minimalist\",\n \"palette\",\n \"Editorial workspace = warm monochrome + spot pastels + serif headings.\",\n [\"minimalist/typography\", \"minimalist/bento-grids\"],\n );\n\n // Data dashboard\n route(\n [\"dashboard\", \"data heavy\", \"tabular\", \"ops table\"],\n \"brutalist\",\n \"principles\",\n \"Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).\",\n [\"taste/one-intent-per-screen\"],\n );\n\n // Brand work\n route(\n [\"brand\", \"identity\", \"logo\", \"guidelines\"],\n \"brandkit\",\n \"principles\",\n \"Brand identity work — boards before screens.\",\n );\n\n // Existing project upgrade\n route(\n [\"refactor\", \"redesign\", \"upgrade existing\", \"audit\"],\n \"redesign\",\n \"fix-priority\",\n \"Existing project = run audit first, fix in priority order (font → palette → states → ...).\",\n [\"redesign/audit-checklist\"],\n );\n\n // Form work\n route(\n [\"form\", \"validation\", \"submit\", \"sign up\", \"registration\"],\n \"taste\",\n \"form-discipline\",\n \"Form must have explicit label + help + error wired via FormField (rule 34).\",\n );\n\n // Loading / saving\n route(\n [\"loading\", \"saving\", \"skeleton\", \"spinner\"],\n \"taste\",\n \"loading-states\",\n \"Skeleton for INIT fetch, Spinner for active work. Never mix.\",\n );\n\n // Mobile-first concerns\n route(\n [\"mobile first\", \"responsive\", \"breakpoint\"],\n \"taste\",\n \"mobile-first\",\n \"Default styles target xs. Touch targets ≥ 44px. Use useBreakpoint().\",\n );\n\n // Output quality\n route(\n [\"complete code\", \"full implementation\", \"no placeholder\"],\n \"output\",\n \"banned\",\n \"Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code.\",\n );\n\n // GSAP motion\n route(\n [\"gsap\", \"scrolltrigger\", \"scroll choreography\", \"pinning\"],\n \"gpt-tasteskill\",\n \"principles\",\n \"GSAP ScrollTrigger — pinning, stacking, scrubbing.\",\n );\n\n // Image-first / design-first\n route(\n [\"from image\", \"image to code\", \"design first\"],\n \"image-to-code\",\n \"workflow\",\n \"Generate design image first → analyze → implement.\",\n );\n\n // Design handoff → real page (consumer build)\n route(\n [\n \"handoff\",\n \"design bundle\",\n \"claude design\",\n \"prototype\",\n \"build the page\",\n \"implement the design\",\n \"build this screen\",\n \"mockup\",\n ],\n \"design-to-page\",\n \"map-to-primitives\",\n \"Map every block to a real @godxjp/ui primitive (MCP-first), consume existing tokens, apply the dxs-kintai DNA, tables central, gaps → extend-or-ask, verify.\",\n [\"design-to-page/read-intent\", \"design-to-page/dna\", \"design-to-page/tables-central\"],\n );\n\n // Compose a brand-new screen from a written brief (no design handoff)\n route(\n [\n \"compose a screen\",\n \"new screen\",\n \"new page\",\n \"create a page\",\n \"create a screen\",\n \"build a view\",\n \"build a screen\",\n \"from scratch\",\n \"screen from a brief\",\n ],\n \"compose-a-screen\",\n \"pick-primitives\",\n \"Build a new app screen from real @godxjp/ui primitives (MCP-first): one-intent-per-screen, real chrome, every state + a11y + i18n, verify.\",\n [\n \"compose-a-screen/assemble-screen\",\n \"compose-a-screen/state-and-a11y\",\n \"taste/one-intent-per-screen\",\n ],\n );\n\n // Reporting a library bug / un-followable rule\n route(\n [\n \"bug in godx\",\n \"godx-ui bug\",\n \"report a bug\",\n \"file an issue\",\n \"gh issue\",\n \"can't follow the rule\",\n \"library is broken\",\n \"primitive is broken\",\n ],\n \"compose-a-screen\",\n \"report-bug\",\n \"If @godxjp/ui itself is at fault, don't fake a workaround — file a detailed gh issue (use draft_bug_report).\",\n [\"design-to-page/report-bug\"],\n );\n\n // Consumer routing hides core-only skills (e.g. component-discipline) so an\n // app-dev is never pointed at library-maintenance material.\n const filtered = opts?.consumerOnly\n ? matches.filter((m) => {\n const sk = findSkill(m.skill);\n return !sk || sk.audience !== \"core\";\n })\n : matches;\n\n if (filtered.length === 0) {\n if (opts?.consumerOnly) {\n return [\n {\n skill: \"compose-a-screen\",\n section: \"pick-primitives\",\n why: `No keyword match for \"${task}\". Default consumer path: compose the screen from real primitives via the MCP.`,\n alsoSee: [\"design-to-page/map-to-primitives\", \"taste/one-intent-per-screen\"],\n },\n ];\n }\n return [\n {\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\n return filtered;\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 (Sidebar),\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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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 {\n SKILLS,\n findSkill,\n findSection,\n routeTask,\n isConsumerSkill,\n} 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:\n \"Read design tokens, optionally filtered by tier category (primitive / semantic / component).\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: {\n type: \"string\",\n enum: [\"primitive\", \"semantic\", \"component\"],\n },\n },\n },\n },\n\n // ── CONSUMER NAMESPACE (app-dev surface — core-only skills hidden) ─\n {\n name: \"list_consumer_skills\",\n description:\n \"List the design skills relevant to an app-dev BUILDING WITH @godxjp/ui (audience consumer/both). Hides core library-maintenance skills. START HERE if you import @godxjp/ui and want guidance (design-to-page, compose-a-screen, taste, …). Returns id + name + whenToUse + section ids.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"get_consumer_skill\",\n description:\n \"Fetch ONE section of ONE consumer-facing skill. Same as get_skill_section but refuses core-only skills (steers app-devs away from library-maintenance material). Use after list_consumer_skills / route_consumer_task.\",\n inputSchema: {\n type: \"object\",\n properties: {\n skill: {\n type: \"string\",\n description: \"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen').\",\n },\n section: { type: \"string\", description: \"Section id within that skill.\" },\n },\n required: [\"skill\"],\n },\n },\n {\n name: \"route_consumer_task\",\n description:\n \"Natural-language task → consumer skill+section pointer. Like route_task but only points to consumer-facing skills (never core library-maintenance). Use FIRST when you're building an app with @godxjp/ui.\",\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: \"draft_bug_report\",\n description:\n \"When @godxjp/ui ITSELF is at fault (missing token, a primitive lacking the controlled-vocabulary prop, a real a11y/behaviour bug, a wrong catalog example) and you cannot follow a rule — DON'T fake a workaround. This drafts a detailed GitHub issue body + a copy-paste `gh issue create` command so you can report it. Prints the command only; never runs gh.\",\n inputSchema: {\n type: \"object\",\n properties: {\n summary: { type: \"string\", description: \"One-line title of the bug / blocked rule.\" },\n repro: { type: \"string\", description: \"Minimal steps or code to reproduce.\" },\n expected: { type: \"string\", description: \"What SHOULD happen (per the rule/spec).\" },\n actual: { type: \"string\", description: \"What actually happens.\" },\n component: {\n type: \"string\",\n description: \"Affected component name, if any (links to get_component).\",\n },\n rule: {\n type: \"number\",\n description: \"Cardinal rule number that can't be followed, if any.\",\n },\n version: { type: \"string\", description: \"Installed @godxjp/ui version (e.g. '12.1.0').\" },\n env: { type: \"string\", description: \"Environment (browser/OS/framework), if relevant.\" },\n },\n required: [\"summary\"],\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 == null ? undefined : String(args.name));\n case \"get_tokens\":\n return getTokens(args.category as TokenCategory | undefined);\n // Consumer namespace\n case \"list_consumer_skills\":\n return listConsumerSkills();\n case \"get_consumer_skill\":\n return getConsumerSkill(String(args.skill ?? \"\"), String(args.section ?? \"\"));\n case \"route_consumer_task\":\n return routeTaskTool(String(args.task ?? \"\"), { consumerOnly: true });\n case \"draft_bug_report\":\n return draftBugReport(args);\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 += `Each is tagged \\`[audience]\\` — \\`core\\` = building @godxjp/ui itself, \\`consumer\\` = building an app with it, \\`both\\`. App-devs: use \\`list_consumer_skills\\` to hide core material.\\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} \\`[${s.audience}]\\`\\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 listConsumerSkills(): string {\n const list = SKILLS.filter(isConsumerSkill);\n let out = `# Consumer skills (${list.length}) — building an app WITH @godxjp/ui\\n\\n`;\n out += `Core library-maintenance skills are hidden. Drill in with \\`get_consumer_skill skill=\"...\" section=\"...\"\\`, or route a task with \\`route_consumer_task\\`.\\n\\n`;\n for (const s of list) {\n out += `## ${s.id} — ${s.name} \\`[${s.audience}]\\`\\n`;\n out += `**When to use:** ${s.whenToUse}\\n\\n`;\n out += `**Sections:** ${s.sections.map((sec) => `\\`${sec.id}\\``).join(\", \")}\\n\\n`;\n }\n return out;\n}\n\nfunction getConsumerSkill(skillId: string, sectionId: string): string {\n const skill = findSkill(skillId);\n if (skill && !isConsumerSkill(skill)) {\n return `Skill \"${skillId}\" is CORE-only (building @godxjp/ui itself) and isn't served to app-devs. Use \\`list_consumer_skills\\` for consumer-facing guidance${\n skillId === \"component-discipline\"\n ? ` — the standards you need when composing/extending are folded into \\`compose-a-screen/state-and-a11y\\` and \\`design-to-page/verify\\`.`\n : `.`\n }`;\n }\n // Reuse the shared renderer; it also handles not-found + section listing.\n return getSkillSection(skillId, sectionId);\n}\n\nfunction draftBugReport(args: Record<string, unknown>): string {\n const get = (k: string) => {\n const v = args[k];\n return typeof v === \"string\" ? v.trim() : \"\";\n };\n const summary = get(\"summary\");\n if (!summary) {\n return (\n \"Pass at least `summary` (one-line title). For a useful report also pass `repro`, \" +\n \"`expected`, `actual`, and ideally `component` / `rule` / `version` / `env`. \" +\n \"A vague report a maintainer can't reproduce is not enough.\"\n );\n }\n const repro = get(\"repro\");\n const expected = get(\"expected\");\n const actual = get(\"actual\");\n const component = get(\"component\");\n const rule = typeof args.rule === \"number\" ? args.rule : undefined;\n const version = get(\"version\");\n const env = get(\"env\");\n\n const missing: string[] = [];\n if (!repro) missing.push(\"repro\");\n if (!expected) missing.push(\"expected\");\n if (!actual) missing.push(\"actual\");\n\n const ph = (label: string, val: string) =>\n val ? val : `_(TODO: ${label} — required for a reproducible report)_`;\n\n const title = `[bug] ${summary}`;\n let body = `## Summary\\n\\n${summary}\\n\\n`;\n body += `## Affected\\n\\n`;\n body += component\n ? `- Component: \\`${component}\\` (see \\`get_component name=\"${component}\"\\`)\\n`\n : `- Component: _(n/a)_\\n`;\n body += rule !== undefined ? `- Cardinal rule: #${rule} (see \\`get_rule number=${rule}\\`)\\n` : \"\";\n body += `\\n## Reproduction (minimal)\\n\\n${ph(\"repro\", repro)}\\n\\n`;\n body += `## Expected\\n\\n${ph(\"expected\", expected)}\\n\\n`;\n body += `## Actual\\n\\n${ph(\"actual\", actual)}\\n\\n`;\n body += `## Environment\\n\\n`;\n body += `- @godxjp/ui version: ${version || \"_(TODO: e.g. 12.1.0)_\"}\\n`;\n body += `- Env: ${env || \"_(TODO: browser / OS / framework)_\"}\\n\\n`;\n body += `## Proposed fix\\n\\n_(optional — what the library should do instead)_\\n`;\n\n // Shell-safe single-quote escaping for the gh command.\n const q = (s: string) => `'${s.replace(/'/g, `'\\\\''`)}'`;\n const cmd = `gh issue create --repo godx-jp/godxjp-ui --label bug --title ${q(title)} --body ${q(body)}`;\n\n let out = `# Draft bug report\\n\\n`;\n if (missing.length) {\n out += `> ⚠️ Incomplete — fill ${missing.map((m) => `\\`${m}\\``).join(\", \")} before filing (a report a maintainer can't reproduce will bounce).\\n\\n`;\n }\n out += `**Title:** ${title}\\n\\n`;\n out += `## Issue body (Markdown)\\n\\n${body}\\n`;\n out += `## File it (copy-paste — this tool does NOT run gh)\\n\\n\\`\\`\\`sh\\n${cmd}\\n\\`\\`\\`\\n\\n`;\n out += `_Reminder: don't hand-roll a fake workaround to hide the bug — file this, then mark any minimal local workaround with \\`// TODO(godxui#<n>)\\`._\\n`;\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 | Tier |\\n|---|---|---|\\n`;\n for (const t of items) out += `| \\`${t.name}\\` | ${t.role} | ${t.tier} |\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction routeTaskTool(task: string, opts?: { consumerOnly?: boolean }): 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, opts);\n let out = `# Routing \"${task}\"${opts?.consumerOnly ? \" (consumer)\" : \"\"}\\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(/<(table|thead|tbody)[\\s>]/, \"Use `<DataTable>` instead of a hand-rolled `<table>` (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 /\\b(?:ml|mr|pl|pr|left|right)-(?:\\d|\\[|auto|px|full|screen)|\\b(?:rounded-[lr]|border-[lr]|text-(?:left|right))\\b/,\n \"Physical direction class — use logical CSS (`ms-/me-`, `ps-/pe-`, `start-/end-`, `rounded-s/e`, `text-start/end`) so the UI flips correctly under RTL (rule: logical CSS).\",\n );\n check(\n /size=[\"']default[\"']/,\n '`size=\"default\"` is not in the controlled vocabulary — use `size` ∈ xs|sm|md|lg.',\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\nconst RULE_COUNT = CARDINAL_RULES.length;\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:\n \"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 (${RULE_COUNT})`,\n description: `The ${RULE_COUNT} binding rules from CLAUDE.md as Markdown.`,\n mimeType: \"text/markdown\",\n },\n {\n uri: \"godx-ui://patterns\",\n name: \"Code patterns\",\n description:\n \"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(\n PATTERNS.map(({ name, tagline, tags }) => ({ name, tagline, tags })),\n null,\n 2,\n );\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","{\n \"name\": \"@godxjp/ui-mcp\",\n \"version\": \"0.19.0\",\n \"description\": \"Model Context Protocol server for @godxjp/ui — gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 34 cardinal rules, copy-paste-ready patterns, 12 design / taste skills synthesised from Leonxlnx/taste-skill, 20+ anti-AI-tell patterns, and a 50-check redesign audit — token-efficient (list → drill-down).\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"godx-ui-mcp\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/godx-jp/godxjp-ui.git\",\n \"directory\": \"mcp\"\n },\n \"homepage\": \"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme\",\n \"license\": \"Apache-2.0\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"inspect\": \"npx @modelcontextprotocol/inspector node dist/index.js\",\n \"type-check\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.29.0\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.1.6\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"godxjp\",\n \"ui\",\n \"design-system\",\n \"react\",\n \"claude\",\n \"cursor\"\n ]\n}\n"],"mappings":"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;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgDT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE;AAAA,EACrB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmCT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE;AAAA,EACrB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmCT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgCT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmDT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,IAAI,IAAI,EAAE;AAAA,EACvB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAsBT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA+CT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,EAAE;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAsCT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,EAAE;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,aAAa,MAAM,UAAU,aAAa,oCAAoC;AAAA,IACxF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,CAAC,sBAAsB,qBAAqB,oCAAoC;AAAA,IAC1F,SAAS,CAAC,0DAAqD;AAAA,IAC/D,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,EAAE;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,8EAAyE;AAAA,IACnF,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,aAAa,MAAM,UAAU,aAAa,yCAAyC;AAAA,IAC7F;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,gBAAgB,iBAAiB,cAAc;AAAA,IACzD,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,EAAE;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,WAAW,MAAM,WAAW,aAAa,4BAA4B;AAAA,MAC7E;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,CAAC,+BAA+B,yBAAyB,2BAA2B;AAAA,IAC9F,SAAS,CAAC,eAAe,QAAQ;AAAA,IACjC,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,EAAE;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,qBAAqB,aAAa,gCAAgC;AAAA,MACzF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,CAAC,2BAA2B,sBAAsB,uBAAuB;AAAA,IACnF,SAAS,CAAC,UAAU,YAAY;AAAA,IAChC,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,IAKT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,EAAE;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,YAAY,MAAM,aAAa,aAAa,oCAAoC;AAAA,IAC1F;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,CAAC,qBAAqB,sBAAsB,6BAA6B;AAAA,IACnF,SAAS,CAAC,aAAa,UAAU;AAAA,IACjC,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,qBAAqB,aAAa,2BAA2B;AAAA,MACpF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,QAAQ,MAAM,WAAW,aAAa,yBAAyB;AAAA,MACvE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,QAAQ,MAAM,UAAU,aAAa,yCAAyC;AAAA,MACtF,EAAE,MAAM,eAAe,MAAM,UAAU,aAAa,oBAAoB;AAAA,MACxE,EAAE,MAAM,YAAY,MAAM,WAAW,aAAa,+BAA+B;AAAA,IACnF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,iBAAiB,aAAa,OAAO;AAAA,IAC/C,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,UAAU,aAAa,oBAAoB;AAAA,MAClE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,EAAE,MAAM,WAAW,MAAM,UAAU,aAAa,yCAAyC;AAAA,IAC3F;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,sCAAsC,qCAAqC;AAAA,IACrF,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL,EAAE,MAAM,SAAS,MAAM,UAAU,aAAa,8BAA8B;AAAA,MAC5E;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,iBAAiB,MAAM,2BAA2B,aAAa,mBAAmB;AAAA,MAC1F,EAAE,MAAM,OAAO,MAAM,UAAU,cAAc,KAAK,aAAa,mBAAmB;AAAA,MAClF,EAAE,MAAM,YAAY,MAAM,WAAW,aAAa,wCAAwC;AAAA,MAC1F;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,uCAAuC,iCAAiC;AAAA,IAClF,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,EAAE;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL,EAAE,MAAM,SAAS,MAAM,YAAY,aAAa,uBAAuB;AAAA,MACvE,EAAE,MAAM,gBAAgB,MAAM,YAAY,aAAa,6BAA6B;AAAA,MACpF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,eAAe,MAAM,UAAU,aAAa,oBAAoB;AAAA,MACxE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA,IAGT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,EAAE;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL,EAAE,MAAM,QAAQ,MAAM,WAAW,aAAa,yBAAyB;AAAA,MACvE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,UAAU,aAAa,4CAA4C;AAAA,IAC5F;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC,0BAA0B,kCAAkC,oBAAoB;AAAA,IAC3F,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,MAAM,MAAM,UAAU,aAAa,oCAAoC;AAAA,MAC/E,EAAE,MAAM,eAAe,MAAM,UAAU,aAAa,sCAAsC;AAAA,MAC1F,EAAE,MAAM,WAAW,MAAM,UAAU,aAAa,2BAA2B;AAAA,MAC3E,EAAE,MAAM,WAAW,MAAM,UAAU,aAAa,2BAA2B;AAAA,IAC7E;AAAA,IACA,UAAU,CAAC,sBAAsB,sBAAsB,oCAAoC;AAAA,IAC3F,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC,iBAAiB,mBAAmB,2BAA2B;AAAA,IAC1E,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,SAAS,MAAM,UAAU,aAAa,0BAA0B;AAAA,MACxE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,QAAQ,MAAM,UAAU,cAAc,KAAK,aAAa,eAAe;AAAA,MAC/E,EAAE,MAAM,QAAQ,MAAM,UAAU,aAAa,mBAAmB;AAAA,IAClE;AAAA,IACA,UAAU,CAAC,gBAAgB,oCAAoC,kBAAkB;AAAA,IACjF,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,CAAC;AAAA,IACZ,SAAS;AAAA;AAAA;AAAA,EAGX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,YAAY,MAAM,WAAW,aAAa,+BAA+B;AAAA,MACjF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBT,WAAW;AAAA,IACX,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE;AAAA,EACrB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,aAAa,aAAa,0CAA0C;AAAA,MAC3F;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,aAAa,MAAM,UAAU,aAAa,oCAAoC;AAAA,IACxF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAST,WAAW;AAAA,IACX,OAAO,CAAC,EAAE;AAAA,EACZ;AACF;AAEO,SAAS,cAAc,MAA0C;AACtE,QAAM,aAAa,KAAK,KAAK,EAAE,YAAY;AAC3C,SAAO,WAAW,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,UAAU;AACnE;AAEO,SAAS,kBAAkB,OAAyC;AACzE,SAAO,WAAW,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK;AACnD;;;AC7gNO,IAAM,kBAAoC;AAAA,EAC/C;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,SAAS;AAAA,IAClB,QAAQ,CAAC,iBAAiB,UAAU,YAAY,cAAc,QAAQ,cAAc;AAAA,EACtF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,SAAS;AAAA,IAClB,QAAQ,CAAC,iBAAiB,UAAU,YAAY,cAAc,MAAM;AAAA,EACtE;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,oBAAoB;AAAA,IAC7B,QAAQ,CAAC,iBAAiB,UAAU,YAAY,cAAc,YAAY,kBAAkB;AAAA,EAC9F;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,WAAW,yBAAyB;AAAA,IAC7C,QAAQ,CAAC,UAAU,SAAS,SAAS;AAAA,EACvC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,MAAM,MAAM,MAAM,IAAI;AAAA,IAC/B,QAAQ,CAAC,UAAU,SAAS,QAAQ;AAAA,IACpC,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,WAAW,WAAW,WAAW,eAAe,QAAQ,SAAS,SAAS;AAAA,IACnF,QAAQ,CAAC,SAAS,OAAO;AAAA,IACzB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,IACrC,QAAQ,CAAC,SAAS,QAAQ;AAAA,IAC1B,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,QAAQ,CAAC,iBAAiB,cAAc,cAAc,QAAQ;AAAA,EAChE;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,CAAC,WAAW,WAAW,aAAa;AAAA,IAC5C,QAAQ,CAAC,eAAe;AAAA,EAC1B;AACF;AAEO,SAAS,UAAU,MAA0C;AAClE,QAAM,aAAa,KAChB,KAAK,EACL,YAAY,EACZ,QAAQ,mBAAmB,EAAE;AAChC,SAAO,gBAAgB;AAAA,IACrB,CAAC,MAAM,EAAE,KAAK,YAAY,EAAE,QAAQ,mBAAmB,EAAE,MAAM;AAAA,EACjE;AACF;;;ACnEO,IAAM,SAAuB;AAAA,EAClC;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,EAAE,MAAM,iBAAiB,UAAU,aAAa,MAAM,aAAa,MAAM,qBAAqB;AAAA,EAC9F;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,EAAE,MAAM,aAAa,UAAU,YAAY,MAAM,YAAY,MAAM,2BAA2B;AAAA,EAC9F,EAAE,MAAM,aAAa,UAAU,YAAY,MAAM,YAAY,MAAM,uBAAuB;AAAA,EAC1F,EAAE,MAAM,aAAa,UAAU,YAAY,MAAM,YAAY,MAAM,uBAAuB;AAAA,EAC1F;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,EAAE,MAAM,UAAU,UAAU,YAAY,MAAM,YAAY,MAAM,2BAA2B;AAAA,EAC3F,EAAE,MAAM,eAAe,UAAU,YAAY,MAAM,YAAY,MAAM,yBAAyB;AAAA,EAC9F,EAAE,MAAM,mBAAmB,UAAU,aAAa,MAAM,aAAa,MAAM,iBAAiB;AAAA,EAC5F;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,EAAE,MAAM,aAAa,UAAU,aAAa,MAAM,aAAa,MAAM,yBAAyB;AAAA,EAC9F;AAAA,IACE,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACF;AAEO,SAAS,iBAAiB,UAAuC;AACtE,SAAO,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AACrD;;;ACtDO,IAAM,iBAAiC;AAAA,EAC5C;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,Q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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","../package.json"],"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\";\nimport pkg from \"../package.json\";\n\nasync function main() {\n const server = new Server(\n {\n name: \"godx-ui-mcp\",\n // Track the package version — never hardcode (see server.test.ts guard).\n version: pkg.version,\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, Flex, ResponsiveGrid, DataTable + ColumnDef, Badge,\n * FormField, Select, Dialog, Toolbar, …) 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 usage: [\n \"DO: Always wrap every page's content in PageContainer — it is the mandatory page shell. Pass `title` (required, rendered as `<h1>`) for every page; omitting it leaves the page without an accessible heading.\",\n \"DO: Use the `extra` prop (not a sibling div, not a wrapper) for action buttons or controls that sit right of the title row — e.g. `extra={<Button>新規作成</Button>}`. Use the `footer` prop for a pinned action bar below the body (e.g. Save/Cancel on a form page); combine with `stickyFooter` to pin it to the viewport bottom on scroll.\",\n \"DO: Use `variant='flush'` when the page body contains a full-bleed component like DataTable. Inside a flush container, wrap any padded strips (Toolbar, intro text) in `<PageContainer.Inset>` to align them with the header. Never add manual `px-*` or `p-*` padding to compensate — use PageContainer.Inset.\",\n \"DO: Pass `breadcrumb` as an ordered array of `{ label, to? }` objects from root to current page. The last item is automatically rendered without a link and receives `aria-current='page'`; earlier items with `to` become router `<Link>` elements. Never hand-roll a breadcrumb nav inside a PageContainer.\",\n \"DON'T: Use `density` to change individual control sizes — it cascades spacing across the entire page subtree. Set it once per page (e.g. `density='compact'` for data-dense list pages) and let all child components inherit it. Do not apply density classes manually.\",\n \"DON'T: Confuse PageContainer's prop names with the old PageHeader's prop names — PageContainer uses `subtitle` (not `description`) and `extra` (not `actions`). If you see those legacy names in old code, migrate them to PageContainer.\",\n ],\n useCases: [\n \"A master list page (e.g. invoices, journal entries, customers) where the header holds the page title, a 'New Invoice' button in `extra`, a breadcrumb trail, and a full-bleed DataTable as the body — use `variant='flush'` + `<PageContainer.Inset>` for the Toolbar above the table.\",\n \"A detail / edit form page where the footer holds Save and Cancel buttons — use `footer={<Flex direction='row'><Button>保存</Button><Button variant='outline'>キャンセル</Button></Flex>}` with `stickyFooter` so the actions remain reachable as the form scrolls.\",\n \"A settings or narrow-form page (e.g. account profile, entity configuration) where `variant='narrow'` constrains content to a readable column width and `stickyFooter` pins the submit bar.\",\n \"A dashboard page with KPI cards and chart sections — use `variant='default'` with `children={<Flex direction='col' gap='lg'>…</Flex>}` to vertically stack multiple Card/StatCard sections beneath the page title.\",\n \"Any deep-nav page in a multi-level admin (e.g. Accounting > Ledger > Journal Entry #42) where a 3-segment breadcrumb trail provides back-navigation without browser history dependence.\",\n \"A high-density data reconciliation page where an analyst needs to see maximum rows — use `density='compact'` to tighten all spacing across the DataTable, Toolbar, and controls in a single prop.\",\n ],\n related: [\n \"PageContainer.Inset — use INSIDE a `variant='flush'` PageContainer to re-introduce horizontal padding for strips like Toolbar or intro text that should align with the page header, while the surrounding DataTable stays full-bleed. Not a standalone page shell.\",\n \"PageContainer — always use PageContainer for new pages; it supports `children`, `footer`, `variant`, `density`, and `stickyFooter`. Legacy code using the old prop names (`description` → `subtitle`, `actions` → `extra`) should be migrated to PageContainer.\",\n \"AppShell — the outer shell that owns the sidebar/topbar layout grid; PageContainer lives inside AppShell's `children` slot. Do not put AppShell inside PageContainer — the nesting order is AppShell → PageContainer.\",\n \"SplitPane — use instead of PageContainer when the page body needs a fixed-width aside panel alongside main content (e.g. a detail drawer next to a list). PageContainer has no aside slot; SplitPane fills that gap and can itself be placed inside PageContainer's children.\",\n ],\n example: `import { PageContainer, Flex } 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 <Flex direction=\"col\" gap=\"lg\">{/* page content */}</Flex>\n </PageContainer>\n );\n}`,\n storyPath: \"layout/PageContainer.stories.tsx\",\n rules: [23],\n },\n {\n name: \"Flex\",\n group: \"layout\",\n tagline:\n \"Token-spaced flex primitive with explicit direction, alignment, justification, and wrapping controls.\",\n props: [\n {\n name: \"direction\",\n type: '\"row\" | \"col\"',\n defaultValue: '\"col\"',\n description: \"Main axis direction. Use row for horizontal runs, col for vertical stacks.\",\n },\n {\n name: \"gap\",\n type: '\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"',\n defaultValue: '\"md\"',\n description: \"Token gap between children, shared with other layout primitives.\",\n },\n {\n name: \"align\",\n type: '\"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\"',\n description: \"Cross-axis alignment, emitted as a data attribute for the layout CSS.\",\n },\n {\n name: \"justify\",\n type: '\"start\" | \"center\" | \"end\" | \"between\" | \"around\" | \"evenly\"',\n description: \"Main-axis distribution, emitted as a data attribute for the layout CSS.\",\n },\n {\n name: \"wrap\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Allows children to wrap onto additional flex lines.\",\n },\n ],\n usage: [\n 'DO import from `@godxjp/ui/layout` and reach for Flex when the axis, alignment, justification, or wrap behavior is part of the component contract: `import { Flex } from \"@godxjp/ui/layout\"`.',\n \"DO keep spacing on the `gap` prop instead of raw `gap-*`, `space-*`, or padding utilities. Flex uses the same token scale as other layout primitives, so spacing remains tied to the design system.\",\n 'DO use `direction=\"row\"` with `wrap` for responsive control rows, chip clusters, and action groups that need more control than simple row composition.',\n 'DO use `direction=\"col\"` for vertical groupings that need explicit `align` or `justify` behavior. For pure vertical stacking without alignment control, `direction=\"col\"` is sufficient.',\n \"DON'T override the axis with `className` after choosing a direction prop. Keep the layout intent in props so catalog guidance and data attributes stay accurate.\",\n \"Flex is a plain div with React.HTMLAttributes<HTMLDivElement>; pass `id`, `role`, `aria-*`, `data-*`, and structural className values as needed, but do not use it as a semantic form or button wrapper.\",\n ],\n useCases: [\n \"Toolbar internals where controls should sit in a row, wrap on narrow widths, and stay vertically centered.\",\n \"Card headers that need title content on the left and actions on the right via `justify='between'` without hand-rolling flex utility classes.\",\n \"Empty-state or loading blocks that center content on both axes using `align='center'` and `justify='center'`.\",\n \"Form sub-sections where a vertical group needs stretched children or centered helper content beyond what a plain column Flex provides.\",\n \"Badge, chip, or tag clusters where wrapping is required but the caller also needs explicit gap control.\",\n \"Low-level layout composition inside custom components where raw flex classes would duplicate the primitive.\",\n ],\n related: [\n \"Flex `direction='col'` — the standard pattern for ordinary vertical block spacing; use explicit `align`, `justify`, or `wrap` props when you need more control.\",\n \"Flex `direction='row'` — the standard pattern for simple horizontal groups; add `wrap` and `align='center'` for the typical row with wrapped centered items.\",\n \"ResponsiveGrid — use for equal-width, multi-column tile layouts. Flex arranges children on one flex axis and does not provide column-count behavior.\",\n \"PageContainer — page scaffold and padding context. Flex is an inner layout primitive used inside page sections, cards, dialogs, and toolbars.\",\n ],\n example: `import { Flex } from \"@godxjp/ui/layout\";\nimport { Button } from \"@godxjp/ui/general\";\n\n<Flex direction=\"row\" gap=\"sm\" align=\"center\" justify=\"between\" wrap>\n <SearchSummary />\n <Flex direction=\"row\" gap=\"xs\" align=\"center\" wrap>\n <Button variant=\"outline\">リセット</Button>\n <Button>適用</Button>\n </Flex>\n</Flex>`,\n storyPath: \"layout/Flex.stories.tsx\",\n rules: [2, 40],\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 StatCard.\",\n },\n ],\n usage: [\n \"DO place StatCard tiles directly as immediate children — StatCard IS already a bordered card; never wrap it in an extra <Card><CardContent>. The canonical pattern is <ResponsiveGrid columns={4}><StatCard .../><StatCard .../></ResponsiveGrid>.\",\n \"DO use columns={2|3|4} to declare the target desktop column count — the grid collapses automatically to 1 column on narrow containers (mobile-first via CSS container queries), via 2-column intermediate at ≥640px, then full target count at ≥1024px. There is no 'columns={1}' — omit the grid for single-column flows.\",\n \"DO NOT place a DataTable inside a ResponsiveGrid column beside a card or chart. DataTable must occupy its own full-width row in a Card with CardContent flush. Nesting a multi-column table in a grid column squeezes CJK text to one character per line (see rule 37).\",\n \"DO use ResponsiveGrid for page-level spacing — it applies the correct gap token (--space-stack-md) automatically. Never add raw gap-* / p-* / space-* utilities to the page layout around tiles; compose spacing through this component instead (rule 40).\",\n \"DO render SkeletonStat children in place of StatCard tiles while KPIs are loading — same columns prop, same count as the real tiles. Switch to real StatCard once data resolves.\",\n \"The grid uses CSS container queries, not viewport media queries — it responds to its containing block width, not the window. Ensure the container is not artificially constrained (e.g. inside a narrow SplitPane column) or column expansion will never trigger.\",\n ],\n useCases: [\n \"Dashboard KPI row: rendering 3–4 StatCard tiles (revenue, member count, active invoices, overdue amount) that reflow to a 2-column stacked grid on tablet and a single column on mobile.\",\n \"Summary header above a list page: a 2-column grid of two StatCard totals (e.g. total payable vs total paid) sitting above a Toolbar and DataTable.\",\n \"Accounting period overview: 4 StatCard tiles (opening balance, total debits, total credits, closing balance) that collapse gracefully on narrow viewports without any custom CSS.\",\n \"Loading state for a KPI row: identical <ResponsiveGrid columns={4}> wrapping four <SkeletonStat /> placeholders rendered while async data is in flight, swapped for real StatCard tiles once resolved.\",\n \"Settings or profile summary cards: 2- or 3-column grid of Card+CardContent blocks (not StatCard) showing categorized read-only data groups before a detail form below.\",\n \"Entity comparison panel: a columns={3} grid comparing three legal entities side-by-side with a Card+CardContent per entity, which collapses to 2-up on tablet and stacks on mobile.\",\n ],\n related: [\n \"Flex — use Flex (direction col or row) for sequential blocks of mixed-width content (forms, description lists, button rows). Use ResponsiveGrid only when you want equal-width, auto-reflowing tile columns.\",\n \"SplitPane — use SplitPane for a fixed two-panel side-by-side layout with a defined primary/secondary ratio that does NOT collapse to stacked tiles. Use ResponsiveGrid when you want automatic column count collapse on narrow screens.\",\n \"StatCard — the canonical direct child of ResponsiveGrid for KPI tiles. StatCard is self-contained (draws its own bordered card); never wrap it in Card/CardContent when placing it inside ResponsiveGrid.\",\n \"SkeletonStat — the loading-state sibling of StatCard, used as a drop-in placeholder child of ResponsiveGrid with the same columns count while KPI data is in flight.\",\n ],\n example: `import { ResponsiveGrid } from \"@godxjp/ui/layout\";\nimport { StatCard } from \"@godxjp/ui/data-display\";\n\n<ResponsiveGrid columns={4}>\n <StatCard label=\"総会員数\" value=\"12,400\" />\n <StatCard label=\"公開中クーポン\" value=\"8\" />\n <StatCard label=\"月間利用数\" value=\"3,210\" />\n <StatCard 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 usage: [\n \"DO pass a <Sidebar> node to `sidebar` (required) and page content to `children` (required) — these are the only two required props. Everything else is optional and omitting optional slots simply removes that zone from the rendered DOM.\",\n \"DO use the auto-built topbar rail (logo / topbarLeft / topbarRight) for simple shells. Pass a fully configured <Topbar> to the `topbar` prop only when you need live handlers (entity switcher via productMenu, search, notifications, user avatar) — when `topbar` is provided, logo/topbarLeft/topbarRight are ignored entirely.\",\n \"DO wire a single `sidebarCollapsed` boolean between AppShell's `sidebarCollapsed` prop and Sidebar's `collapsed` prop — AppShell sets `data-collapsed='true'` on the root div (which CSS reads for width transitions) but does NOT own the collapsed state itself; lift the state and pass it down to both.\",\n \"DO place breadcrumb content in AppShell's `breadcrumb` prop (renders in the `app-breadcrumb` div inside `<main>` ABOVE children) — do NOT hand-roll a breadcrumb bar as the first child of children, and do NOT put breadcrumbs inside <Sidebar>.\",\n \"DO NOT nest a second AppShell or AppShell inside AppShell's children — AppShell renders the root `app-root` div; nesting shells breaks the CSS grid layout.\",\n \"DO NOT add padding directly to children expecting it to reach the viewport edge — AppShell's `<main>` is a scroll container; use <PageContainer> (or <PageContainer.Inset> inside a flush PageContainer) inside children to get standard page padding.\",\n ],\n useCases: [\n \"Full admin SPA shell: AppShell wraps a <Sidebar> nav rail and a <Topbar> (with productMenu entity-switcher, onSearchOpen, onNotificationsOpen, user avatar) and every Inertia page renders as children inside a <PageContainer>.\",\n \"Collapsible-sidebar layout: maintain a `collapsed` boolean in a persistent Inertia layout component, pass it to both AppShell's `sidebarCollapsed` and Sidebar's `collapsed`, wire Topbar's `onToggleCollapsed` to flip it — AppShell handles the CSS transition automatically.\",\n \"Multi-tenant accounting app: pass a <Topbar productMenu={<DropdownMenuContent>…</DropdownMenuContent>}> to AppShell's `topbar` slot so the legal-entity chip opens an inline switcher without a modal.\",\n \"App-level footer (e.g. version/build info, compliance notice): pass a <footer> node to AppShell's `footer` prop — it renders outside `<main>` so it stays pinned below the scroll area.\",\n \"Rapid prototype or internal tool where you want a branded shell with minimal topbar: skip the `topbar` prop entirely and use `logo`, `topbarLeft`, `topbarRight` to build the rail declaratively without instantiating <Topbar>.\",\n \"Breadcrumb-aware shell: pass a <Breadcrumb items={…}> node to AppShell's `breadcrumb` prop so the breadcrumb strip appears above all page content without each page having to render it separately.\",\n ],\n related: [\n \"AppShell — opinionated wrapper that composes AppShell + a frozen default Topbar in three props (menu, children, breadcrumb). Use AppShell for quick scaffolding when the default GodX product chip and no-op search/notification handlers are acceptable; switch to AppShell directly the moment you need a custom entity switcher, real onSearchOpen, user slot, or any topbar configuration.\",\n \"Sidebar — the canonical node to pass as AppShell's `sidebar` prop; owns activeId, collapsible submenu groups, collapsed icon-only mode, and section labels. Never hand-roll a nav list inside the sidebar slot.\",\n \"Topbar — the structured topbar component to pass to AppShell's `topbar` prop when you need live product/project chip switchers, search, notifications, sidebar toggle, user avatar, or rightSlot extras. When `topbar` is provided, AppShell's logo/topbarLeft/topbarRight props are ignored.\",\n \"PageContainer — the mandatory direct child inside AppShell's `children` for every page; provides title, subtitle, extra actions, breadcrumb, footer, variant (flush/narrow/ghost), and density. Never render raw content directly as AppShell's child without a PageContainer wrapper.\",\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 }: { content: 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 content: 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 content: [\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 projectSidebar 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 \"AppShell — 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 }: { content: 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: \"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 usage: [\n \"DO: pass all right-panel content via the `aside` prop — it renders inside a semantic `<aside>` element at a fixed rem width (sm=20rem, md=22rem). The `children` prop fills the main `1fr` column. Both accept any ReactNode.\",\n 'DO: choose `asideWidth=\"sm\"` for compact detail panels (filters, quick stats, key-value summaries) and the default `asideWidth=\"md\"` for richer panels (forms, timelines, long metadata lists).',\n \"DO: wrap SplitPane inside `PageContainer` or `PageContainer.Inset` — SplitPane provides no page padding of its own. It is a grid primitive, not a page scaffold.\",\n \"DON'T: expect two columns below 1080px. Below that breakpoint SplitPane stacks to a single column (main on top, aside below). Never use it for layouts that must remain side-by-side on tablet or mobile — use CSS Grid or `ResponsiveGrid` instead.\",\n \"DON'T: add a CSS `overflow: hidden` or fixed height on the SplitPane wrapper; both columns carry `min-width: 0` to handle overflow correctly, and the grid uses `minmax(0, 1fr)` — adding external constraints will break the overflow contract.\",\n \"DON'T: hand-roll a two-column div layout with flexbox or CSS Grid when SplitPane already ships — that duplicates the responsive breakpoint logic and the semantic `<aside>` element.\",\n ],\n useCases: [\n \"Invoice / transaction detail page: list of records in `children` (DataTable), selected-record detail panel in `aside` (Descriptions + Timeline).\",\n 'Accounting ledger drill-down: account list on the left, chart-of-accounts metadata or running balance breakdown on the right using `asideWidth=\"sm\"`.',\n \"Document review workflow: PDF or rich-text viewer in `children`, approval form or annotation panel in `aside`.\",\n \"Settings page with a category list or Steps navigator in `children` and a live preview or summary card in `aside`.\",\n \"Kanban or task board where the main area holds the board columns and the aside shows the focused task detail without navigating away.\",\n ],\n related: [\n \"ResponsiveGrid — use when you need more than two columns, or when both columns must have equal or percentage-based widths rather than a fixed-rem aside. SplitPane always gives main a `1fr` and aside a fixed rem width.\",\n \"PageContainer — use as the outer scaffold that provides page padding and vertical rhythm; nest SplitPane inside PageContainer, not the other way around.\",\n \"Sheet — use when the detail/context panel should slide in as an overlay (drawer) rather than sitting permanently beside the main content. Prefer Sheet on mobile or when the aside content is secondary and on-demand.\",\n \"Flex direction='col' — use when content is purely vertical (single column, sequential sections). SplitPane is the right pick only when a persistent side panel is needed at the same hierarchy level as the main content.\",\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 usage: [\n \"DO import from `@godxjp/ui/layout` (not from a navigation or general sub-path) and pass a single `items` prop — an ordered array of `{ label, to? }` objects. No children, no sub-components, no render-prop API.\",\n 'DO omit `to` on the last (current-page) segment — the component automatically renders it as a `<span aria-current=\"page\">` instead of a router `<Link>`. Passing `to` on the last item does NOT make it a link; drop it intentionally.',\n \"DO pass the Breadcrumb node as a ReactNode to the `breadcrumb` prop of `AppShell` (or `AppShell`) for shell-level breadcrumbs, or to `PageContainer`'s `breadcrumb` prop (which accepts `BreadcrumbItemProp[]` directly — not a ReactNode). When passing to `PageContainer`, pass the raw array; when passing to `AppShell`, wrap it: `breadcrumb={<Breadcrumb items={…} />}`.\",\n 'DON\\'T hand-roll a breadcrumb strip (divs with chevrons, anchors, separators) — Breadcrumb ships the `<nav aria-label=\"Breadcrumb\">` + `<ol>` + `aria-hidden` chevrons. Any custom trail is a violation of the no-hand-roll rule and will fail `npm run ui:audit`.',\n \"DON'T use Breadcrumb for tab-style or step-style navigation (multi-step forms, wizard progress). Those flows belong to `Steps`. Breadcrumb is strictly a spatial location trail, not a process indicator.\",\n \"The component is fully uncontrolled and stateless — it renders whatever `items` you pass. Dynamic breadcrumbs (route-derived, breadcrumb context, etc.) must be assembled in the parent and passed down as a plain array; there is no internal routing awareness.\",\n ],\n useCases: [\n \"Per-page location trail on any admin page deeper than two levels — e.g. Home → Accounting → Invoices → Invoice #1042 — passed to `PageContainer`'s `breadcrumb` prop so it appears above the page `<h1>`.\",\n \"Persistent shell-level breadcrumb in a `AppShell` or `AppShell` layout that updates as the user navigates between Inertia/React Router pages; constructed from route params and passed as a ReactNode to `AppShell`'s `breadcrumb` prop.\",\n \"Master-detail drill-down in an accounting app: the detail page (journal entry, partner, bank account) shows a breadcrumb back to the list and to the domain root, giving the user a one-click escape without using the browser back button.\",\n \"Embedded sub-panel breadcrumb inside a `SplitPane` or `Sheet` where a secondary content area has its own navigable hierarchy and needs a compact location indicator.\",\n \"Audit log or document history page where the entity being reviewed (invoice, payment) is the current segment and the parent module (Accounting, Receivables) is a clickable ancestor.\",\n \"Prefetch pairing: wrap ancestor segments' `to` values with `PrefetchLink` semantics by putting them in `items` — each non-last item with `to` is already rendered as a router `<Link>`, so hovering naturally prefetches if `PrefetchLink` is used elsewhere on the same route.\",\n ],\n related: [\n \"PageContainer — accepts `breadcrumb` as `BreadcrumbItemProp[]` (raw array, not a ReactNode); use this when each page owns its own breadcrumb and you want it co-located with the page title, actions, and body.\",\n \"AppShell — accepts `breadcrumb` as `ReactNode`; pass `<Breadcrumb items={…} />` here when the breadcrumb is a persistent shell-level strip that sits above all page content rather than being owned by individual pages.\",\n \"Steps — use instead of Breadcrumb when showing progress through an ordered multi-step flow (wizard, checkout, onboarding); Steps conveys sequence and completion state, not spatial location.\",\n \"PrefetchLink — if ancestor breadcrumb segments should prefetch their destination query on hover/focus, consider pairing the `to` values with `PrefetchLink` in a custom breadcrumb or pre-warming the cache on mount; Breadcrumb's internal links are plain react-router-dom `<Link>` with no prefetch behaviour.\",\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 usage: [\n \"DO pick the right variant for intent: `default` (primary CTA, one per section), `destructive` (irreversible actions like delete/revoke), `outline` (secondary actions alongside a primary), `secondary` (less prominent actions), `ghost` (toolbar icon-only actions), `link` (inline text-style navigation without an underline by default).\",\n \"DO use icon-only sizes (`icon`, `icon-xs`, `icon-sm`, `icon-lg`) exclusively for buttons that contain only an SVG — these sizes set equal width/height. For text+icon buttons use `default|sm|lg|xs` sizes; icons inside are auto-sized to 1rem via `[&_svg:not([class*='size-'])]:size-4`.\",\n \"DO use `asChild` to render the button as a React Router/Inertia `<Link>` or native `<a>` while keeping all button styling and a11y: `<Button asChild variant=\\\"outline\\\"><Link href={route('invoices.show', id)}>詳細</Link></Button>`. Never wrap a `<button>` around an `<a>` — that is invalid HTML.\",\n \"DON'T use raw `<button>` elements anywhere in the UI — always use this `Button`. The only exception is an `aria-hidden` native control used as an e2e/a11y hook paired with a visible godx-ui control.\",\n 'DO set `type=\"submit\"` explicitly on form submit buttons (the default HTML button type inside `<form>` is already `submit`, but being explicit prevents accidental double-submissions when a `type=\"button\"` sibling exists). For cancel/reset actions set `type=\"button\"` to avoid accidental form submission.',\n \"DON'T apply raw padding, height, or `rounded-*` overrides to `Button` via `className` — the size variants encode the full box model. If a custom size is truly needed, use `buttonVariants` from `@godxjp/ui/general` to compose a new cva class rather than fighting the existing ones.\",\n ],\n useCases: [\n 'Primary form submission in a Dialog or Sheet (e.g. `<Button type=\"submit\" disabled={form.processing}>保存</Button>`) — the `disabled` prop greys it out and blocks pointer events, preventing double-submit during async operations.',\n 'Destructive confirmation inside a Dialog — pair `tone=\"destructive\"` Button as the confirm action and `variant=\"outline\"` as Cancel; never use `variant=\"default\"` for a delete action.',\n 'Icon-only toolbar actions in a DataTable column (edit, delete, copy) using `size=\"icon-sm\"` + `variant=\"ghost\"` + a Lucide icon child — gives equal-width square targets that don\\'t distort the row.',\n \"Navigation links styled as buttons (e.g. 'New Invoice', 'Back to list') using `asChild` + Inertia `<Link>` — preserves SPA navigation while using the button's visual treatment.\",\n \"Async mutation trigger in an accounting workflow (e.g. 'Sync from MF', 'Export CSV') — disable on processing state; pair with `AlertMutationFeedback` for error/retry UI rather than inline `try/catch` alerts.\",\n \"Refetch / retry trigger when NOT using TanStack Query — for manual cache refresh inside a TanStack Query context use `ButtonRefetch` instead, which owns its own `disabled`/`onClick` lifecycle.\",\n ],\n related: [\n \"DropdownMenu — when a button needs to reveal a list of actions (e.g. 'Actions ▾' in a DataTable row), wrap the Button as a `DropdownMenuTrigger` inside a `DropdownMenu` compound; don't open a Sheet/Dialog just to show a list of options.\",\n \"ButtonRefetch — a pre-wired Button variant from `@godxjp/ui/query` that binds directly to a TanStack Query result (shows spinner, auto-disables while fetching, retries on click). Use it instead of a raw Button whenever the action is a query refetch — do not pass `onClick`/`disabled` to it manually.\",\n \"AlertMutationFeedback — for surfacing mutation errors and a retry action; it renders its own retry Button internally. Do not add a separate Button alongside AlertMutationFeedback for the same mutation.\",\n \"PrefetchLink — use when the goal is purely navigation with hover-prefetch (Inertia v3 prefetch); it renders as an `<a>` not a button. Only reach for `Button asChild + Link` when the navigation control must look like a button (primary CTA style).\",\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: { value: 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: \"{ value: 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: { value: 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 { value: \"id\", header: \"Invoice #\", width: \"w-32\" },\n { value: \"customer\", header: \"Customer\" },\n {\n value: \"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 { value: \"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<{ value: 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: \"DataGrid\",\n group: \"data-display\",\n tagline:\n \"Full-feature data grid — the TanStack Table adapter on `@godxjp/ui/data-grid` (NOT the data-display barrel). Adds column sort, global search, column visibility ('set view'), per-page + numbered pagination, row selection + bulk actions, and density over the styled Table* primitives. Defaults to SERVER/manual mode: wire sorting/columnFilters/globalFilter/pagination to your AJAX query (pass rowCount). Use DataTable instead for a lean server-driven list that must NOT pull TanStack. Requires the `@tanstack/react-table` peer dependency.\",\n props: [\n {\n name: \"columns\",\n type: \"ColumnDef<T, unknown>[]\",\n required: true,\n description:\n \"TanStack column definitions ({ accessorKey, header, cell, enableSorting, enableHiding, meta:{label} }). Set enableHiding:false to keep a column out of the ViewOptions menu; meta.label gives a human label there when header is JSX.\",\n },\n {\n name: \"data\",\n type: \"T[]\",\n required: true,\n description: \"Row data. Empty + loading=false renders a built-in EmptyState in the body.\",\n },\n {\n name: \"getRowId\",\n type: \"(row: T) => string\",\n description: \"Stable row id (defaults to row[rowIdKey], rowIdKey defaults to 'id').\",\n },\n {\n name: \"enableRowSelection\",\n type: \"boolean\",\n defaultValue: \"false\",\n description: \"Adds a checkbox column + header select-all; pair with DataGrid.BulkActions.\",\n },\n {\n name: \"sorting / onSortingChange\",\n type: \"SortingState / OnChangeFn<SortingState>\",\n description:\n \"Server sort: pass both and sort in your query (manualSorting defaults true). Omit both for client sort.\",\n },\n {\n name: \"globalFilter / onGlobalFilterChange\",\n type: \"string / OnChangeFn<string>\",\n description:\n \"Global search term, surfaced by DataGrid.Search. Server or client like sorting.\",\n },\n {\n name: \"pagination / onPaginationChange / rowCount\",\n type: \"PaginationState / OnChangeFn / number\",\n description:\n \"Server pagination: pass pagination + onPaginationChange + rowCount (total). Omit for client pagination.\",\n },\n {\n name: \"columnVisibility / onColumnVisibilityChange\",\n type: \"VisibilityState / OnChangeFn<VisibilityState>\",\n description:\n \"Column show/hide state surfaced by DataGrid.ViewOptions ('set view'). Internal if omitted.\",\n },\n {\n name: \"manualSorting / manualFiltering / manualPagination\",\n type: \"boolean\",\n defaultValue: \"true\",\n description:\n \"Default true (server/AJAX). Set false to let TanStack sort/filter/paginate in-browser.\",\n },\n {\n name: \"loading / density / onRowClick / empty\",\n type: \"boolean / 'compact'|'comfortable' / (row:T)=>void / ReactNode\",\n description: \"Loading row, controlled density, clickable rows, custom empty content.\",\n },\n ],\n usage: [\n \"Import from `@godxjp/ui/data-grid` — it lives on its own subpath because it pulls @tanstack/react-table; it is NOT in the runtime-neutral root or the data-display barrel.\",\n \"Compose the compound parts as children: <DataGrid.Toolbar> (holds <DataGrid.BulkActions>, <DataGrid.Search>, <DataGrid.ViewOptions>, <DataGrid.DensityToggle>), then <DataGrid.Content> (auto-included if omitted) and <DataGrid.Pagination pageSizeOptions=[...]>.\",\n \"Server mode (default): drive sorting/globalFilter/pagination from useQuery and pass rowCount. Client mode: set manualSorting/manualFiltering/manualPagination={false} and the grid handles it on the data array.\",\n ],\n related: [\"DataTable\", \"Table\", \"DataState\", \"Select\", \"DropdownMenu\"],\n example: `import { DataGrid, type ColumnDef } from \"@godxjp/ui/data-grid\";\nimport { Flex } from \"@godxjp/ui/layout\";\n\ntype Row = { id: string; name: string; amount: number };\nconst columns: ColumnDef<Row, unknown>[] = [\n { accessorKey: \"name\", header: \"Name\", meta: { label: \"Name\" } },\n { accessorKey: \"amount\", header: \"Amount\", meta: { label: \"Amount\" } },\n];\n\nexport function Grid({ rows }: { rows: Row[] }) {\n return (\n <DataGrid columns={columns} data={rows} getRowId={(r) => r.id} enableRowSelection manualSorting={false} manualFiltering={false} manualPagination={false}>\n <DataGrid.Toolbar>\n <Flex direction=\"row\" align=\"center\" gap=\"sm\" className=\"ms-auto\">\n <DataGrid.Search />\n <DataGrid.ViewOptions />\n <DataGrid.DensityToggle />\n </Flex>\n </DataGrid.Toolbar>\n <DataGrid.Content />\n <DataGrid.Pagination pageSizeOptions={[10, 20, 50]} />\n </DataGrid>\n );\n}`,\n storyPath: \"data-display/DataGrid.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: '\"md\" | \"compact\"',\n defaultValue: '\"md\"',\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 usage: [\n 'DO always wrap body content in <CardContent> — the bare <Card> div has zero inner padding; content renders flush against card edges without it. Never add className=\"p-4\" directly on <Card> as a substitute.',\n \"DO put titles/descriptions in <CardHeader>/<CardTitle>/<CardDescription>. Use <CardHeader banded> for a visually separated muted-background header band (mirrors <CardFooter separated>). Pair with <CardAction> inside a flex-row CardHeader for header-level action buttons.\",\n \"DO use <CardContent flush> for edge-to-edge children such as DataTable, Table, or a Tabs list — this removes horizontal padding. Combine with <CardContent tight> when there is no visual gap needed after the header, and <CardContent solo> when there is no CardHeader above (top padding matches the card shell).\",\n \"DO use <CardFooter separated> to render a top-bordered action band (Save/Cancel buttons, table summary row). Use <CardFooter flush> for a full-bleed footer bar.\",\n \"DO use <CardCover> as the first child for full-bleed cover media — the header below it uses card-section top spacing, not the card shell.\",\n \"DON'T hand-roll a stat/KPI tile with <Card> + raw divs — use <StatCard> (label, value, hint, delta, layout, inverse props) which is already a Card internally with correct token-driven layout.\",\n ],\n useCases: [\n 'Dashboard KPI summary row: wrap each metric in <StatCard> (or a plain <Card size=\"compact\"> with <CardContent>) to render a uniform grid of labeled value tiles with optional trend deltas.',\n 'Invoice or order detail panel: <Card accent=\"primary\"> with <CardHeader banded><CardTitle>, <CardContent> body rows (use <Descriptions> inside), and <CardFooter separated> holding approve/reject buttons.',\n \"Section container on a settings or form page: a single <Card> wrapping a <CardHeader><CardTitle> plus <CardContent> containing <FormField> groups, with <CardFooter separated> for Save/Cancel.\",\n \"Data table with toolbar: <Card> + <CardHeader> (title + filter controls in <CardAction>) + <CardContent flush> containing <DataTable> — <CardContent flush> removes horizontal padding so the table header spans full width.\",\n 'Featured announcement or alert card: <Card variant=\"featured\"> with an accent stripe (<accent=\"warning\">) to visually elevate a card above sibling cards on the page.',\n \"Media/cover card (e.g. entity profile): <CardCover> first (full-bleed image), then <CardHeader> + <CardContent> below it for structured metadata.\",\n ],\n related: [\n \"StatCard — use instead of a plain Card when rendering a KPI/metric tile (label + value + optional delta/hint). StatCard is a Card internally; do not re-wrap it in another Card.\",\n \"CardContent — mandatory inner wrapper for all body content inside Card. Provides the correct padding and supports flush/tight/solo variants. The only correct way to put padded content inside Card.\",\n \"Descriptions — use inside <CardContent> when body content is a label-value metadata list (e.g. entity details, invoice fields); do not hand-roll a dl/dt/dd grid.\",\n \"DataState / InfiniteQueryState — use instead of Card when the content is a TanStack Query-driven list that needs automatic skeleton, empty, and error states; Card does not manage loading lifecycle.\",\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 Toolbar 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 usage: [\n \"DO: Always wrap body content in <CardContent> — a bare <Card> has no internal padding, so any child placed directly inside it renders flush against the card edges.\",\n \"DO: Use <CardContent flush> for DataTable, Table, or Tabs — the flush prop removes horizontal padding so the content spans edge-to-edge inside the card border. Never add manual p-0 on the Card itself instead.\",\n \"DO: Use <CardContent tight> when placing a flush toolbar or a Tabs list directly below a CardHeader — tight removes the top gap so the header and the body connect without an awkward spacing gap.\",\n \"DO: Use <CardContent solo> when the card has no CardHeader above it — solo gives the top padding that matches the card shell, ensuring visual balance.\",\n \"DON'T: Nest a Toolbar inside <CardContent flush> — flush strips horizontal padding and Toolbar will lose its own padding. Put Toolbar outside the flush CardContent or in a separate non-flush CardContent above it.\",\n \"DON'T: Wrap a StatCard inside <Card><CardContent> — StatCard already renders its own Card border; double-wrapping produces a double border. Render StatCard directly in a ResponsiveGrid.\",\n ],\n useCases: [\n \"Wrapping a form body (Input, Select, Textarea fields) inside a Card that has a CardHeader title — ensures the form fields have correct internal padding.\",\n \"Hosting a DataTable inside a Card edge-to-edge: <CardContent flush><DataTable .../></CardContent> — the table occupies the full card width with the card's border acting as the table container.\",\n \"Dashboard detail panels where the card has no title — <CardContent solo> gives top padding equivalent to the card shell so the content doesn't sit too close to the top border.\",\n \"Placing a Descriptions or Timeline inside a card to display invoice/accounting details — <CardContent> provides the standard 16px (or density-adjusted) padding without needing manual className.\",\n \"Pairing with <CardHeader banded> and <CardFooter separated> in a multi-section layout such as a payment summary card — each section slot (header, content, footer) carries its own semantic spacing tokens.\",\n \"Putting a ScrollArea inside <CardContent> (not flush) to create a scrollable card body with consistent padding, e.g. a chat or log viewer panel.\",\n ],\n related: [\n \"Card — the parent container; CardContent is always a direct child of Card. Card itself has zero internal padding; every visible body padding comes from CardContent (or CardHeader/CardFooter). Never put content directly inside Card.\",\n \"StatCard — a self-contained KPI tile that IS already a Card; do not wrap it in <Card><CardContent>. Use StatCard directly inside a ResponsiveGrid.\",\n \"ScrollArea — place ScrollArea inside CardContent (non-flush) when the card body needs to scroll; do not put ScrollArea outside CardContent or you lose the card's internal padding.\",\n \"SkeletonStat — the loading placeholder for a StatCard tile; swap in SkeletonStat while KPI data is loading. For general Card loading shapes, use SkeletonTable or Skeleton primitives.\",\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: \"StatCard\",\n group: \"data-display\",\n tagline:\n \"KPI tile. ⚠️ StatCard 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 usage: [\n \"DO place StatCard directly as a child of ResponsiveGrid — it renders its own bordered Card shell internally, so no wrapping <Card> or <CardContent> is needed or allowed. Wrapping creates a double border.\",\n \"DO pass `delta` as a sign-prefixed string (e.g. '+12%' or '-3%') to get automatic color tone: '+' renders text-success, '-' renders text-destructive. For metrics where a negative delta is good (e.g. cost reduction, error rate), pass `inverse` so the tone is flipped correctly.\",\n \"DO use `hint` for secondary context (e.g. '先月比 +3%', 'last 30 days'). In the default `stacked` layout hint renders below the value; in `inline` layout it renders beside the label.\",\n \"DO NOT add an `accent` prop — accent is a Card prop and StatCard does not expose it. Passing accent has no effect and creates a false expectation.\",\n \"DO NOT hand-roll a KPI tile using a plain <Card><CardContent>. StatCard is the correct primitive and token-aligns the label/value/hint/delta slots automatically.\",\n \"WHILE data is loading, replace each StatCard with a <SkeletonStat /> at the same grid position — never render an empty value string or a spinner inside StatCard itself.\",\n ],\n useCases: [\n \"Dashboard KPI row: monthly revenue, invoice count, overdue balance, and collection rate displayed side-by-side in a ResponsiveGrid with delta trend vs previous period.\",\n \"Accounting summary header: total debits, total credits, and net balance for a journal entry list page, each with a hint showing the date range in scope.\",\n \"Coupon/membership admin overview: active members, live coupons, monthly redemptions, and total discount amount — the canonical example in the catalog.\",\n \"Inline variant for a narrow sidebar or detail panel where space is constrained: label on the left, large value on the right (layout='inline'), e.g. contract value next to a deal record.\",\n \"Cost or error-rate metrics where a falling number is positive: pass `inverse` so a '-15%' delta shows green, preventing misleading red-for-good UI.\",\n \"Loading state for any KPI grid: render the same ResponsiveGrid columns filled with <SkeletonStat /> components while the query is in-flight, then replace with StatCard tiles once data resolves.\",\n ],\n related: [\n \"ResponsiveGrid — required layout wrapper for StatCard grids; controls column count and responsive breakpoints. Always pair them together.\",\n \"SkeletonStat — exact loading placeholder shaped like a StatCard tile; swap in while KPI data is fetching, then replace with the real StatCard.\",\n \"Descriptions — use instead when displaying multiple label/value metadata pairs on a detail page (not headline KPIs); Descriptions is not card-bordered and does not show delta/hint slots.\",\n \"Card + CardContent — use when you need a general-purpose content container with a header, footer, or arbitrary body; do NOT wrap StatCard inside these.\",\n ],\n example: `import { StatCard } from \"@godxjp/ui/data-display\";\nimport { ResponsiveGrid } from \"@godxjp/ui/layout\";\n\n// ✅ StatCard sits directly in the grid — it draws its own card + border.\n<ResponsiveGrid columns={3}>\n <StatCard label=\"総会員数\" value=\"12,450\" hint=\"先月比 +3%\" />\n <StatCard label=\"月次売上\" value=\"¥8,200,000\" delta=\"+12%\" />\n <StatCard label=\"利用率\" value=\"68.4%\" />\n</ResponsiveGrid>\n\n// ❌ Double border — do NOT wrap StatCard in a Card:\n// <Card><CardContent><StatCard label=\"x\" value=\"1\" /></CardContent></Card>`,\n storyPath: \"data-display/StatCard.stories.tsx\",\n rules: [],\n },\n {\n name: \"Badge\",\n group: \"data-display\",\n tagline:\n \"Plain or lifecycle badge. Use `variant` for static chips, or `status` to auto-map lifecycle keys to semantic tone + icon. Labels never wrap.\",\n props: [\n {\n name: \"variant\",\n type: '\"default\" | \"secondary\" | \"outline\" | \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\"',\n defaultValue: '\"default\"',\n description:\n \"Visual variant. Overrides the auto-mapped status tone when status is provided.\",\n },\n {\n name: \"status\",\n type: \"string\",\n description:\n \"Lifecycle key. Known keys auto-map to variant + icon + i18n label; unknown keys fall back to neutral.\",\n },\n {\n name: \"icon\",\n type: \"React.ComponentType<{ className?: string }> | null\",\n description: \"Leading icon override. Pass null to suppress the auto status icon.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n description:\n \"Badge label. When omitted with status, Badge renders the translated lifecycle label or raw status.\",\n },\n ],\n usage: [\n \"DO pick the correct variant semantically: `success` (approved/paid), `warning` (pending/overdue), `destructive` (rejected/error), `secondary` (neutral category), `outline` (subtle label), `default` (primary accent). Never force a colour just for aesthetics — agents and screen readers read the variant as intent.\",\n \"DO use `status` for entity lifecycle statuses (active, draft, pending, cancelled, failed, scheduled, etc.) so the component resolves the correct tone, icon, and i18n label.\",\n \"DO pass `variant` explicitly for localized labels or categorical tiers, and pass `icon={null}` when a lifecycle glyph would be misleading.\",\n \"Badge renders as a `<div>` (HTMLAttributes<HTMLDivElement>). It carries no interactive semantics. If you need a clickable chip, wrap it in a `<button>` or use a Button with a matching variant — never add an `onClick` directly to Badge without an accessible role.\",\n \"Badge is a leaf — pass plain text or a short ReactNode as children. Do NOT nest another Badge, a Button, or interactive controls inside it; that breaks focus order and creates invalid HTML (div-in-inline-context).\",\n \"Use semantic tokens for any className overrides (`text-muted-foreground`, `bg-destructive`) — never raw Tailwind palette classes like `bg-green-500`.\",\n ],\n useCases: [\n 'Category or tier labels on table rows — e.g. plan tier (`<Badge variant=\"secondary\">Pro</Badge>`), document type (`<Badge variant=\"outline\">Invoice</Badge>`), or locale tag (`<Badge variant=\"secondary\">EN</Badge>`).',\n 'Approval or review state in an accounting list where the value is not a lifecycle key in Badge\\'s STATUS_MAP — e.g. a custom approval tier like `<Badge tone=\"success\">承認済</Badge>` or `<Badge tone=\"warning\">要確認</Badge>`.',\n \"Inline count or highlight next to a heading or nav item — e.g. `<Badge variant=\\\"destructive\\\">3</Badge>` beside 'Overdue invoices' to draw attention to a non-zero count.\",\n 'Feature flags or experiment variant labels on admin records — e.g. `<Badge variant=\"outline\">A/B</Badge>` alongside a campaign row to indicate it is in a split test.',\n \"Read-only metadata chips inside a Descriptions.Item or Card header where a lifecycle icon would be visually heavy — e.g. currency code, payment method, or region tag.\",\n ],\n related: [\n \"Button — use instead of Badge when the chip must be interactive (clickable, toggleable). Badge carries no button role or keyboard handler; a naked `onClick` on Badge is inaccessible.\",\n ],\n example: `import { Badge } from \"@godxjp/ui/data-display\";\n\n<Badge variant=\"secondary\">A/B</Badge>\n<Badge status=\"active\">公開中</Badge>\n<Badge status=\"プレミアム\" tone=\"success\" icon={null}>プレミアム</Badge>`,\n storyPath: \"data-display/Badge.stories.tsx\",\n rules: [35],\n },\n {\n name: \"Descriptions\",\n group: \"data-display\",\n tagline:\n \"Responsive definition grid for detail-page metadata. COMPOUND — value goes in Descriptions.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: \"Descriptions.Item elements.\",\n },\n ],\n usage: [\n 'DO use Descriptions.Item as the ONLY direct child — never raw <div>, <dt>/<dd>, or plain text nodes. Every label/value pair must be wrapped in <Descriptions.Item label=\"…\">value</Descriptions.Item>.',\n \"DO pass span={2} or span={3} on an Item when its value is long (e.g. a full address, a memo field, a JSON blob) — span={2} applies sm:col-span-2 and span={3} applies lg:col-span-3, keeping the grid aligned across breakpoints.\",\n \"DO pass mono on Item for machine-readable values: IDs, UUIDs, file paths, currency codes, JSON snippets. This sets font-mono + break-all so long strings wrap rather than overflow.\",\n \"DO embed any ReactNode as the Item child — Badge, Badge, formatDate output, a Tooltip-wrapped value, or a plain string all work. The value slot is not text-only.\",\n \"DON'T use Descriptions as a hand-rolled <dl>/<dt>/<dd> replacement for prose or running text — it is for structured metadata on detail/show pages only. For flowing key→value prose, use a plain <dl>.\",\n \"DON'T add className padding or margin to the root Descriptions to simulate a Card — wrap it in CardContent instead. Descriptions provides only grid layout (gap-x-6 gap-y-3); outer spacing is the Card/CardContent concern.\",\n ],\n useCases: [\n \"Detail/show page header block — displaying entity metadata such as invoice number, status, due date, vendor name, and payment method in a 2- or 3-column grid before the line-item DataTable.\",\n \"Account or member profile panel — showing user ID (mono), plan, registered date, email, and a status Badge in one scannable block instead of a vertical stack of FormField-looking rows.\",\n \"Accounting journal entry detail — date, reference code (mono), debit account, credit account, amount, and memo (span={2}) grouped in a compact grid alongside a Timeline of audit events.\",\n \"Read-only summary step in a multi-step form or wizard — displaying the values the user entered before final submission (Steps + Descriptions), without any input controls.\",\n \"Sidebar or Sheet detail pane — a narrow 1-column Descriptions inside a Sheet presenting the selected row's metadata while the main DataTable stays visible.\",\n \"API / webhook event inspector — showing event ID (mono, span={2}), event type, timestamp, HTTP status, and payload size in a grid, with a Badge for the status code.\",\n ],\n related: [\n \"Card / CardContent — Descriptions provides the internal grid layout; Card/CardContent provides the outer container, padding, and border. Always wrap Descriptions in CardContent (never add p-4 directly on Descriptions). Use Card when you need the visual surface; use Descriptions inside it for the label/value structure.\",\n \"DataTable — use DataTable when you have multiple rows of the same entity type that need sorting, filtering, or pagination. Use Descriptions when you have a single entity's fields laid out as labelled metadata (one row per field, not one row per record).\",\n \"Table — use Table (the lower-level primitive) for tabular data with explicit column headers and multiple data rows. Use Descriptions when the data is inherently label→value (no column headers needed, each field is its own row/cell).\",\n \"Flex — use Flex for arbitrary vertical/horizontal layout of heterogeneous UI elements. Use Descriptions when every item follows the label-on-top / value-below pattern and you want responsive multi-column alignment for free.\",\n ],\n example: `import { Descriptions } from \"@godxjp/ui/data-display\";\n\n<Descriptions columns={2}>\n <Descriptions.Item label=\"会員ID\" mono>{member.id}</Descriptions.Item>\n <Descriptions.Item label=\"プラン\">{member.plan}</Descriptions.Item>\n <Descriptions.Item label=\"メモ\" span={2}>{member.note}</Descriptions.Item>\n</Descriptions>`,\n storyPath: \"data-display/Descriptions.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 usage: [\n \"DO always pass `title` — it is the only required prop and renders an `<h3>`; omitting it causes a blank silent render with no visible error.\",\n \"DO use the `icon` prop (a Lucide icon component, not a JSX element) to give visual context — e.g. `icon={InboxIcon}` for empty inboxes, `icon={SearchIcon}` after a failed search. Pass the component reference, not `<InboxIcon />`.\",\n \"DO use `action` (a `ReactNode`, typically a `<Button>`) for actionable zero-states — e.g. 'Create first invoice' — so users have a clear next step instead of a dead end.\",\n \"DO NOT hand-roll a `data.length === 0 ? <EmptyState /> : <DataTable />` conditional — `DataTable` already embeds an `EmptyState` in its body when `data` is empty. Use the `empty=` prop on `DataTable` to customise it, not a wrapper conditional.\",\n \"DO NOT use EmptyState inside a `DataState` or `InfiniteQueryState` for the loading or error states — those widgets handle skeleton/error themselves; pass `EmptyState` only to their `empty=` prop for the zero-items case.\",\n \"DO NOT add padding directly on `EmptyState` via `className` when placing it inside a `Card` — wrap it in `<CardContent>` first; EmptyState is a self-contained block with its own internal spacing via `ui-empty-state` styles.\",\n ],\n useCases: [\n \"Zero-row admin list pages (invoices, accounts, transactions) that are NOT backed by a `DataTable` — e.g. a card-grid or custom list layout where DataTable's built-in empty state doesn't apply.\",\n \"Post-filter / post-search zero results — show `icon={SearchIcon}` + a `description` explaining what was searched and an `action` to clear filters.\",\n \"First-run onboarding screens where no data has been created yet — e.g. 'No entities added yet' with an action button to create the first legal entity.\",\n \"Passed as the `empty=` prop inside `DataState` or `InfiniteQueryState` to satisfy the TanStack Query lifecycle widget's zero-items slot without hand-rolling markup.\",\n \"Standalone section within a `CardContent` to indicate a sub-section (e.g. attachments, comments, related records) has no entries yet, separate from the page-level list.\",\n \"Error-adjacent zero states where the page loaded successfully but the filtered result set is empty — distinct from an error state handled by `DataState`/`AlertMutationFeedback`.\",\n ],\n related: [\n \"DataTable — already embeds an EmptyState automatically when `data` is empty; customise via the `empty=` prop. Do NOT wrap DataTable in a `data.length === 0` guard that renders EmptyState separately.\",\n \"DataState — TanStack Query lifecycle widget (`@godxjp/ui/query`). Pass `<EmptyState />` to its `empty=` prop for zero-items; DataState itself covers loading/error — do not use EmptyState for those states.\",\n \"InfiniteQueryState — same pattern as DataState but for `useInfiniteQuery`; pass EmptyState to `empty=` when the flattened list is empty.\",\n \"SkeletonTable — use for the loading skeleton before data arrives (pass to DataState's `skeleton=` or DataTable's `loading=`). EmptyState is for after data arrives and is empty, not while loading.\",\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: \"Progress\",\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 usage: [\n 'DO import from `@godxjp/ui/data-display`, not from a generic UI path: `import { Progress } from \"@godxjp/ui/data-display\";`',\n \"DO pass `value` as a 0–100 number — the component clamps it internally via `Math.max(0, Math.min(100, value))`, so out-of-range values are safe but misleading; compute the real percentage before passing it.\",\n 'DO drive `tone` dynamically from business logic — e.g. `variant={pct >= 80 ? \"warning\" : \"success\"}` — to communicate threshold status semantically rather than with raw colour classes.',\n \"DON'T use a `disabled` Slider as a read-only progress bar — Slider is semantically an interactive control even when disabled, which pollutes the a11y tree and exposes the wrong ARIA role (`slider` vs `progressbar`). Progress renders the correct read-only indicator.\",\n \"DON'T pass children or sub-components — Progress is a single self-contained element (track + bar + label). The `label` prop is the only text injection point; don't wrap it in a custom parent div to add a label alongside it.\",\n \"DON'T use Progress for editable numeric input or range selection — it has no callbacks, no interactivity, and no form `name` prop. Use Slider (bounded range input) or Input (free-form number) for data-entry scenarios.\",\n ],\n useCases: [\n 'Budget utilisation in an accounting dashboard — show how much of a monthly budget has been consumed, switching to `tone=\"warning\"` when the figure crosses 80%.',\n 'Invoice payment progress — display the proportion of an invoice total that has been settled (e.g. partial payments), with a label like `\"¥45,000 / ¥60,000 支払済\"` computed before passing `value`.',\n \"Storage or quota indicator in an admin panel — visualise disk usage, API quota, or seat licence consumption against a fixed limit.\",\n \"Sync / import job completion feedback — surface the completion percentage of a long-running background job (polling the server) without giving the user an interactive control.\",\n \"StatCard companion — pair with a `StatCard` metric to add a visual fill below the KPI number, reinforcing how close a target is to being met.\",\n \"Multi-step onboarding or setup checklist — render one Progress per section (e.g. 3/5 steps complete = 60%) to give users a quick scan of overall progress across areas.\",\n ],\n related: [\n \"Slider — use Slider when the user must drag or set a bounded numeric value (volume, priority, price range); use Progress when the value is read-only and must not be interacted with.\",\n \"Steps — use Steps for a discrete, named sequence of phases (onboarding wizard, checkout flow) where each step has a label and a clear current/done/pending state; use Progress for a continuous 0–100 fill.\",\n 'Badge / Badge — use Badge or Badge to communicate a categorical status label (e.g. \"Paid\", \"Overdue\") without a fill metaphor; use Progress when the numeric proportion itself is the information.',\n \"StatCard — use StatCard to headline a single KPI metric with a title; compose Progress inside or alongside StatCard when a visual fill adds meaning to the number.\",\n ],\n example: `import { Progress } from \"@godxjp/ui/data-display\";\n\n<Progress value={pct} label={pct + \"% 使用中\"} variant={pct >= 80 ? \"warning\" : \"success\"} />`,\n storyPath: \"data-display/Progress.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 usage: [\n \"DO pass an array of `TimelineItem` objects to `items` — this is the ONLY prop; there are no sub-components to compose. Each item is `{ title, location?, time?, note?, current? }`. All fields except `title` are optional.\",\n \"DO mark exactly one item with `current: true` to highlight the in-progress event. The component renders a `Plane` icon for the current item and a `CheckCircle2` icon for all past items — do NOT try to pass a custom icon; the icon is determined entirely by the `current` flag.\",\n \"DO pass `ReactNode` to `title`, `location`, `time`, and `note` — you can embed formatted text, `<Badge>`, `<Badge>`, or `<span>` inside those fields. Use `formatDate` to pre-format timestamps before passing them as `time`.\",\n \"DO NOT hand-roll a vertical event list with divs, icons, and connector lines — that is exactly what Timeline ships. Do not apply extra padding or wrapping outside the component; it manages its own rail and spacing internally.\",\n \"DO NOT use Timeline for user-facing wizard progress (steps the user must complete in order) — use `Steps` for that. Timeline is read-only historical/status display; it has no interactive state, no `onClick`, and no concept of 'go to step'.\",\n \"DO wrap Timeline in `<CardContent>` when placing it inside a `Card` — bare `Card` has no inner padding, so the rail will render flush against the card edge without `CardContent`.\",\n ],\n useCases: [\n \"Shipment / delivery tracking — showing a parcel's journey through 'Order placed → Packed → In transit → Delivered' with timestamps and a current-stop indicator.\",\n \"Accounting document audit trail — rendering the lifecycle of an invoice or payment (Draft → Submitted → Approved → Paid) with the current approval stage highlighted.\",\n \"Support ticket / task history — displaying a chronological log of status transitions (Open → Assigned → In Review → Closed) with agent names in the `note` field and timestamps in `time`.\",\n \"MF sync log viewer — listing each sync run event (OAuth refresh, fetch, upsert) with timestamps and record counts so an operator can see what the last sync did.\",\n \"Approval workflow status panel — showing a multi-stage approval chain where completed stages have CheckCircle2 icons and the pending stage has the Plane (in-flight) icon.\",\n \"Order / purchase-order lifecycle in an admin detail page — placed alongside a `Descriptions` summary at the top of a `Card` to give a compact at-a-glance history.\",\n ],\n related: [\n \"Steps — use Steps (navigation group) when the user must actively progress through a wizard (interactive, shows step numbers/status, horizontal layout by default); use Timeline for read-only historical event sequences that have already happened.\",\n \"Descriptions — use Descriptions to display a flat set of label/value metadata fields (e.g., invoice header); use Timeline when events are ordered chronologically and a connector rail communicates sequence and progress.\",\n \"DataTable — use DataTable for multi-row, multi-column tabular event logs where sorting, filtering, and pagination are needed; use Timeline when the sequence/rail visual is the primary communication and there are fewer than ~10 events.\",\n \"Badge — Badge is a single-item inline indicator; Timeline sequences multiple statuses with connectors. Compose Badge inside a Timeline `title` or `note` field for richer per-event context, but do not replace Timeline with a stack of Badges.\",\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 usage: [\n \"DO compose all six sub-parts in order: wrap with `<Table>`, then `<TableHeader>` containing `<TableRow><TableHead>…</TableRow>`, then `<TableBody>` containing one or more `<TableRow><TableCell>…` rows. Skipping any layer (e.g. bare `<th>` inside `<Table>`) bypasses the design tokens and hover/border styles.\",\n 'DO use `TableHead` (not `TableCell`) for header cells — it renders `<th>` with `data-slot=\"table-head\"` and the `--table-row-height` CSS variable for consistent header sizing across the design system. `TableCell` renders `<td>` with `data-slot=\"table-cell\"` and is for body rows only.',\n 'DO apply numeric alignment via `className` on individual `TableHead`/`TableCell` elements (e.g. `className=\"text-right\"`). There are no built-in alignment props — all styling goes through Tailwind class overrides.',\n \"DO NOT hand-roll empty-state handling inside a Table composition. When data can be empty, switch to `DataTable` (which has a built-in empty state) or wrap the `<Table>` with a conditional that renders `<EmptyState>` — never leave a table with only a header and zero rows.\",\n \"DO NOT use Table for lists that need sorting, filtering, pagination, or row selection — those features are only in `DataTable`. Table is intentionally stateless: it owns no TanStack Table instance, no column definitions, and no toolbar.\",\n \"DO place `<Table>` inside a `<CardContent flush>` (or `p-0` card) when embedding in a Card, so the built-in `overflow-auto` wrapper sits flush to the card edges. Wrapping with plain `<CardContent>` adds padding that clips the horizontal scroll shadow.\",\n ],\n useCases: [\n \"Invoice line-item breakdowns — a fixed, read-only list of product/quantity/unit-price/total rows where columns are predefined and will never need sort or filter controls.\",\n \"Summary/comparison tables inside a detail panel or Dialog, such as showing two payment plans side-by-side, where the structure is hand-authored and not driven by a data array.\",\n \"Print or PDF-export views where a minimal, stateless `<table>` element with predictable markup is required and DataTable's JS-driven features would interfere with server-side rendering or CSS print rules.\",\n \"Embedded sub-tables inside a DataTable expanded row (the inner table uses Table primitives because nesting a full DataTable instance inside another is unsupported).\",\n \"Static reference tables in documentation, onboarding, or settings pages — e.g. a permission matrix or feature comparison — where every cell is literal JSX content, not from a data array.\",\n ],\n related: [\n \"DataTable — choose DataTable for any data array that needs sorting, filtering, pagination, row selection, bulk actions, or density toggle. DataTable internally renders Table primitives, so switching up is non-breaking. Default to DataTable for all admin list pages.\",\n \"SkeletonTable — use as a loading placeholder before a Table or DataTable mounts. Drop it in the `skeleton` slot of DataState, or render it directly while data is fetching. Do not show a Table with empty rows as a loading state.\",\n \"Descriptions — choose Descriptions when content is label→value pairs (two columns, no repeated rows of the same type). Table is better when every row shares the same typed columns.\",\n \"DataState — when your Table's data comes from `useQuery`, wrap it in DataState to handle loading/error/empty states declaratively instead of writing conditional logic around the Table yourself.\",\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 usage: [\n \"DO: pass a `UseQueryResult<T>` directly from `useQuery` — DataState reads `isPending`, `isError`, `isFetching`, `data`, and `error` off it; never destructure those fields manually and branch yourself.\",\n \"DO: always provide a `skeleton` — it renders during both the initial pending phase and during a re-fetch after an error; pass `<SkeletonTable />` for tabular data or `<SkeletonStat />` for stat card lists — never `null` or a spinner div.\",\n 'DO: provide `empty` + `isEmpty` together when the data can legitimately return 0 items — e.g. `isEmpty={(d) => d.items.length === 0}` paired with `empty={<EmptyState title=\"…\" />}`. Omitting `empty` means an empty array still falls through to `children`, silently rendering a blank table.',\n \"DON'T: wrap DataState in your own conditional — e.g. `{query.isSuccess && <DataState …>}`. DataState IS the conditional; the outer guard is redundant and breaks the retry/refetch skeleton.\",\n \"DON'T: use DataState for `useInfiniteQuery` results. The `query` prop type is `UseQueryResult<T>`, not `UseInfiniteQueryResult`. Use `InfiniteQueryState` (from `@godxjp/ui/query`) instead, which accepts `flatten` and renders a load-more footer.\",\n \"DO: supply `errorRenderer` only when the default `AlertQueryError` + retry button is not enough — e.g. a full-page error boundary with navigation. Otherwise rely on `showRetry` (default `true`) and the built-in `AlertQueryError`, and override `onRetry` only if `query.refetch()` is not the right action.\",\n ],\n useCases: [\n \"A detail page that loads a single invoice/journal entry via `useQuery` — DataState renders the skeleton row while fetching, an error alert with retry if the API fails, and the `<InvoiceCard>` only when data is confirmed non-null.\",\n \"A list page that shows a `DataTable` of members/partners — wrap the table in DataState so the skeleton matches the column count while loading and `EmptyState` appears when the filtered result set is empty.\",\n \"A sidebar panel that lazily loads related transactions for the selected entity — DataState keeps the panel in skeleton state during the background fetch without any manual `isPending` branching in the parent.\",\n \"A dashboard stat card that calls a summary API — DataState handles the loading/error/empty lifecycle so `<StatCard>` is only rendered with fully resolved numbers, preventing NaN or undefined rendering.\",\n \"Any page using `useQuery` where the empty state and loading state are visually different — DataState enforces the correct visual for each phase without scattered `if` statements across the component tree.\",\n ],\n related: [\n \"InfiniteQueryState — use instead of DataState when the query is `useInfiniteQuery`; it accepts a `flatten` function to reduce pages and adds a load-more footer. DataState cannot accept `UseInfiniteQueryResult`.\",\n \"SkeletonTable / SkeletonStat — pass as the `skeleton` prop of DataState; they are not standalone replacements for DataState, only the loading slot inside it.\",\n \"EmptyState — pass as the `empty` prop of DataState alongside a matching `isEmpty` predicate; do not hand-roll an empty-check outside DataState by inspecting `query.data` yourself.\",\n \"AlertMutationFeedback — sibling widget for mutation (not query) lifecycle; use it below a form submit button to surface `useMutation` errors, not DataState which only handles `useQuery`.\",\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 usage: [\n \"DO: Import from `@godxjp/ui/query` (not `@godxjp/ui`). Use the bundled `flattenItemPages` helper for any API that returns `{ items: T[] }` pages — it handles `undefined` data safely. Custom page shapes require a custom `flatten` function.\",\n \"DO: Always pass `skeleton` (e.g. `<SkeletonTable />` or `<SkeletonStat />`). It shows on initial `isPending`, on refetch-after-error, and whenever `data` is absent. Never show a blank area while loading.\",\n \"DO: Pass `empty` (an `<EmptyState>` node) to handle the zero-results case — without it the children render-prop is called with an empty array and you get a silent blank screen. Provide a custom `isEmpty` only when `TFlat` is not an array.\",\n \"DON'T: Hand-roll a load-more button. The component renders a default centered outline Button when `hasNextPage` is true. Override only via `loadMore` (custom node) or `showLoadMore={false}` (hide entirely). Never call `query.fetchNextPage()` outside the component for pagination.\",\n \"DON'T: Use `InfiniteQueryState` for a `useQuery` result — it expects `UseInfiniteQueryResult` shape (`pages`, `hasNextPage`, `fetchNextPage`, `isFetchingNextPage`). For regular `useQuery` use `DataState` instead.\",\n \"DON'T: Confuse the two generics: `TPage` is the raw page shape from the API, `TFlat` is what `flatten` returns (usually `TItem[]`). The `children` render-prop receives `TFlat`, not `TPage`. Pass `isEmpty` if `TFlat` is not a plain array so empty detection works correctly.\",\n ],\n useCases: [\n \"Activity / audit-log feed that accumulates pages as the user scrolls down or clicks 'Load more' — the default footer button handles `fetchNextPage` automatically.\",\n \"Invoice or transaction list with cursor-based pagination where total count is unknown and pages are appended rather than replaced (replacing pages is DataTable's job).\",\n \"Notification inbox, comment thread, or journal entry list where new items are appended at the bottom and the user never pages backwards.\",\n \"Search results with a 'Show more' button rather than numbered pages — pass `showLoadMore={true}` (default) and hide the button once `hasNextPage` is false without any extra state.\",\n \"Admin dashboard 'recent events' widget backed by `useInfiniteQuery` — use `SkeletonTable` as `skeleton` and `<EmptyState title='No events yet' />` as `empty` so every state is handled.\",\n \"Infinite-scroll implementation: receive the `helpers` argument in `children` (`{ fetchNextPage, hasNextPage, isFetchingNextPage }`) to wire a scroll sentinel (Intersection Observer) instead of the built-in button, while still benefiting from error/skeleton/empty lifecycle handling.\",\n ],\n related: [\n \"DataState — use instead when the query is a plain `useQuery` (not infinite). Identical lifecycle surface (skeleton/empty/error/children) but expects a single page of data, not accumulated pages. Pick DataState for any paginated table where only one page is visible at a time.\",\n \"DataTable — use for tabular data with server-side pagination where pages are swapped, not appended. DataTable manages its own pagination UI (cursor buttons); InfiniteQueryState is for append-only / infinite-scroll patterns.\",\n \"SkeletonTable / SkeletonStat — pass as the `skeleton` prop to InfiniteQueryState; do not render them manually alongside InfiniteQueryState since the component controls when skeleton is visible.\",\n \"ButtonRefetch — companion component for the page header refresh action wired to `query.refetch()`. Use alongside InfiniteQueryState when you want an explicit refresh control in addition to the built-in load-more footer.\",\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 // ─── data-entry ─────────────────────────────────────────────────────────\n {\n name: \"Form\",\n group: \"data-entry\",\n tagline:\n \"Ant-style layout container — renders <form> and pushes layout (vertical/horizontal), labelWidth/controlWidth, label alignment, responsive collapse, and multi-column grid down to every FormField (overridable per field).\",\n props: [\n {\n name: \"layout\",\n type: '\"vertical\" | \"horizontal\" | \"inline\"',\n defaultValue: '\"vertical\"',\n description: \"Label position relative to control; applied to all FormFields.\",\n },\n {\n name: \"labelWidth\",\n type: \"number | string\",\n description: \"Label column width in horizontal layout (number→px). e.g. 120 or '8rem'.\",\n },\n {\n name: \"controlWidth\",\n type: \"number | string\",\n description: \"Cap the control width (number→px). Omit to fill the column.\",\n },\n {\n name: \"labelAlign\",\n type: '\"start\" | \"end\"',\n defaultValue: '\"end\"',\n description: \"Horizontal alignment of the label within its column.\",\n },\n {\n name: \"collapseBelow\",\n type: '\"sm\" | \"md\" | \"lg\" | \"xl\" | false',\n defaultValue: '\"md\"',\n description:\n \"Breakpoint below which horizontal collapses to vertical (mobile-first). false = always horizontal.\",\n },\n {\n name: \"columns\",\n type: \"number | { sm?: number; md?: number; lg?: number }\",\n description: \"Lay fields out in a responsive grid (reuses ResponsiveGrid; 1 col on small).\",\n },\n {\n name: \"density\",\n type: '\"compact\" | \"default\" | \"comfortable\"',\n description: \"Apply a density to controls inside the form.\",\n },\n ],\n usage: [\n \"DO set `layout`, `labelWidth`, `controlWidth` ONCE on `<Form>` — every `<FormField>` inside inherits them. Override a single field by passing the same prop on that `<FormField>` (Form → FormField priority).\",\n \"DO rely on mobile-first collapse: `layout='horizontal'` automatically stacks to vertical below `collapseBelow` (default `md`). Pass `collapseBelow={false}` only when a field MUST stay label-beside-control even on phones.\",\n \"DO use `columns` for multi-field forms (e.g. `columns={2}`) — it reuses ResponsiveGrid (1 column on small screens, more on md/lg). Span a wide field across columns with `<FormField colSpan={2}>`.\",\n \"DON'T hand-roll a `<form>` + Flex stack for spacing — `<Form>` provides the vertical rhythm and the layout context FormField reads. Wire react-hook-form by spreading `onSubmit={handleSubmit(...)}` onto `<Form>`.\",\n ],\n useCases: [\n \"A settings page form where every label sits in a fixed 120px column to the left of its control (horizontal), collapsing to stacked labels on mobile.\",\n \"A two-column entity-edit form (`columns={2}`) where the address field spans both columns (`colSpan={2}`).\",\n \"A compact filter form (`layout='horizontal' density='compact'`) above a DataTable.\",\n ],\n related: [\n \"FormField — the per-field wrapper (label + control + helper/error) that reads Form's layout context; use one per control inside a Form.\",\n \"ResponsiveGrid — Form `columns` reuses it; use ResponsiveGrid directly for non-form card grids.\",\n ],\n example: `import { Form, FormField, Input } from \"@godxjp/ui/data-entry\";\n\n<Form layout=\"horizontal\" labelWidth={120} columns={2} onSubmit={onSubmit}>\n <FormField id=\"first\" label=\"姓\"><Input id=\"first\" /></FormField>\n <FormField id=\"last\" label=\"名\"><Input id=\"last\" /></FormField>\n <FormField id=\"address\" label=\"住所\" colSpan={2}><Input id=\"address\" /></FormField>\n</Form>`,\n storyPath: \"data-entry/Form.stories.tsx\",\n rules: [23, 24],\n },\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. Reads the parent Form's layout (vertical/horizontal) — overridable per field.\",\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: \"layout\",\n type: '\"vertical\" | \"horizontal\" | \"inline\"',\n description: \"Override the parent Form's layout for this field only.\",\n },\n {\n name: \"labelWidth\",\n type: \"number | string\",\n description: \"Override the Form's label width for this field.\",\n },\n {\n name: \"controlWidth\",\n type: \"number | string\",\n description: \"Override the Form's control width for this field.\",\n },\n {\n name: \"colSpan\",\n type: \"number\",\n description: \"Span N columns when inside a `columns` Form grid.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n required: true,\n description: \"The single control to render.\",\n },\n ],\n usage: [\n \"DO pass the same string to both `id` on `<FormField>` and `id` on the child control — the component wires `<Label htmlFor={id}>`, and builds `{id}-helper` / `{id}-error` ids for `aria-describedby`. If the ids diverge the label click and screen-reader announcements break.\",\n \"DO pass a SINGLE React element as `children`. FormField calls `React.cloneElement` on it to inject `aria-describedby`, `aria-required`, and `aria-invalid` — if you pass a fragment or multiple nodes, cloneElement silently skips the injection and a11y attributes are lost.\",\n \"DO use the `error` prop (not a hand-rolled `<p>`) for validation messages — it renders with `role='alert'` and `text-destructive` styling and overrides `helper` automatically. Never render an error paragraph alongside FormField.\",\n \"DO use `labelAddon` (a ReactNode rendered inline after the label text) for supplementary controls such as a tooltip trigger or a 'copy' icon button — never insert such controls as siblings outside FormField, which breaks layout.\",\n \"DON'T wrap `Switch` in FormField — use `Field` instead, which already handles the label, hidden `<input name>` for HTML form submission, error, and helper internally.\",\n \"DON'T use FormField for checkbox-beside-label or radio-beside-label patterns — use `Field` (single checkbox/radio with description) or `CheckboxGroup` / `RadioGroup` (multiple options), which have their own integrated labelling.\",\n ],\n useCases: [\n \"Labelling a text `Input` or `Textarea` in an invoice-entry form, showing a red asterisk for required fields and surfacing server validation errors returned from a Laravel FormRequest.\",\n \"Wrapping a `Select` or `DatePicker` inside a multi-field filter panel where each control needs a visible label, helper hint (e.g. 'YYYY/MM/DD'), and inline error state.\",\n \"Adding a `labelAddon` tooltip button next to a 'Tax rate' label in an accounting form to explain when different rates apply, without breaking the label–control association.\",\n \"Enclosing a `DateRangePicker` or `TimePicker` in an admin settings page where the field needs a label, a muted hint ('Inclusive of start and end date'), and conditional error display.\",\n \"Wrapping a `SearchSelect` or `Select` (with `showSearch`) control for vendor/account lookup in a journal-entry form where the `id` must be kept consistent for programmatic focus management.\",\n \"Providing structured error feedback for a `Cascader` or `TreeSelect` in a multi-level category assignment screen, replacing ad-hoc error rendering with the standardised `role='alert'` pattern.\",\n ],\n related: [\n \"Label — the bare Radix label component. Use directly only when you are building a fully custom layout that cannot accept FormField's stack wrapper, and you will manage aria-describedby/aria-invalid yourself. FormField is always preferred for standard form controls.\",\n \"Field — a self-contained field for boolean toggles: it already includes its own label, hidden `<input name>` for HTML form submission, helper, and error. Never wrap a bare `Switch` in FormField.\",\n \"Field — pairs a single checkbox or radio with a label and optional description in a horizontal layout (control beside text). Use Field instead of FormField when the control and its label sit side-by-side rather than stacked.\",\n \"CheckboxGroup / RadioGroup — for groups of options where FormField is not needed per-item; the group component handles its own legend/label and option layout.\",\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} onValueChange={(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 usage: [\n \"DO always wrap Input in FormField when the field needs a label, helper text, or validation error — FormField injects aria-describedby and aria-invalid onto Input automatically; never wire these attributes by hand.\",\n \"DO match the `id` prop on Input to the `id` prop on its parent FormField so that `htmlFor` linkage and the generated helper/error ids are consistent.\",\n \"DO use Input in controlled mode (`value` + `onChange`) for forms driven by Inertia's `useForm` or React state; uncontrolled usage (no `value`) is only acceptable for fire-and-forget inline edits where form state is not needed.\",\n \"DON'T use a raw `<input>` element — Input adds the full token-based styling (border-input, focus ring, disabled/invalid states, file-slot styling) and the `data-slot='input'` marker that FormField relies on to inject aria attributes.\",\n \"DON'T hand-roll an error border or red ring with className — Input reads `aria-invalid` (set by FormField) and applies `border-destructive` + `ring-destructive/20` automatically; adding manual destructive classes will conflict.\",\n \"DON'T use Input for multi-line text — use Textarea; DON'T use it for filtered/debounced search — use SearchInput which fires `onSearch` after a debounce and includes a clear button.\",\n ],\n useCases: [\n \"Single-line text fields in create/edit forms — invoice reference numbers, company names, contact emails, coupon codes, amounts typed as text (pair with `type='number'` for numeric entry).\",\n \"Inline editable cells or quick-edit dialogs where a single short value needs to be changed (e.g. editing a journal entry memo or an account code) and full Select/DatePicker overhead is unnecessary.\",\n \"File upload trigger when wrapped with `type='file'` — the file-slot classes style the native file button consistently without any extra wrapper.\",\n \"Password entry fields (`type='password'`) in auth or settings screens, where the styled focus ring and disabled-state opacity are needed without building a custom control.\",\n \"Numeric/currency input in accounting forms (`type='number'`, `inputMode='decimal'`) for quantities, exchange rates, or tax amounts where a free-form numeric entry is required rather than a slider or stepper.\",\n ],\n related: [\n \"SearchInput — use instead of Input when the value drives a live filter or search query; SearchInput debounces internally, fires `onSearch` (not `onChange`), and provides a built-in clear button. Never put debounce logic on top of a plain Input.\",\n \"Textarea — use instead of Input for multi-line text (notes, descriptions, memo fields). Input is strictly single-line.\",\n \"FormField — always compose Input inside FormField when the field needs a visible label, helper hint, or validation error message; FormField handles all a11y wiring so Input stays a pure unstyled-but-styled primitive.\",\n \"Select — use instead of Input when the value must come from a fixed or async option list; never render a plain Input and parse free text when the set of valid values is enumerable.\",\n ],\n example: `import { Input } from \"@godxjp/ui/data-entry\";\n\n<Input id=\"qty\" type=\"number\" placeholder=\"例: 500\" value={value} onValueChange={(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 usage: [\n \"DO: listen to `onSearch`, not `onChange`. The component debounces internally (default 250 ms) and fires `onSearch(q)` after the delay — never wire your filter logic to `onChange` on SearchInput because it does not expose one.\",\n \"DO: choose controlled vs uncontrolled deliberately. Pass `value` + `onSearch` together for controlled mode (e.g. when search state lives in a URL param or shared parent). For local-only ephemeral search pass only `defaultValue` + `onSearch` — omitting `value` puts the component in uncontrolled mode.\",\n \"DO: supply an `ariaLabel` (or visible `label`) when no adjacent label exists. Without either prop, SearchInput falls back to the i18n key `common.search` rendered as a visually-hidden `<Label>` — still accessible, but providing a context-specific string (e.g. `ariaLabel='請求書を検索'`) is more descriptive for screen readers.\",\n \"DON'T: use SearchInput inside a `<form>` expecting native form submission. The component has no `name` prop and does not emit a form field value — it is a filter-trigger widget. For a form search field, use a plain `Input` inside `FormField`.\",\n \"DON'T: hand-roll a debounced input when you need a search box. SearchInput ships the debounce, clear button (×), search icon, and accessible label — recreating these with a raw `<Input>` adds code and misses the UX contract.\",\n \"DON'T: place SearchInput inside a `ToolbarGroup` wrapper — `ToolbarGroup` is for Select/DatePicker controls with a label chip. SearchInput goes directly as a child of `Toolbar` (or standalone above a table), not wrapped in `ToolbarGroup`.\",\n ],\n useCases: [\n \"List-page filter bar: placed as the first child of `Toolbar` (before any `ToolbarGroup` children) to drive text-based filtering of a `DataTable`. The `onSearch` callback updates a query param or state variable that the table's data fetch reads.\",\n \"Inline client-side search over a small in-memory list (e.g. a sidebar nav list, a transfer panel, a settings category list) where results narrow immediately as the user types without a server round-trip — use uncontrolled mode (`defaultValue`) so no state is needed in the parent.\",\n \"URL-synced search: controlled mode where `value` comes from `useSearchParams()` and `onSearch` pushes to the URL, enabling deep-linkable, bookmarkable filtered views on invoice/transaction/customer index pages.\",\n \"Panel or dialog search: filtering a long dropdown list, a tree, or a multi-item selection panel that does not use the built-in `Command` palette — SearchInput provides the search box while the parent renders the filtered result set.\",\n \"Toolbar search on a data-heavy accounting page (e.g. journal-entry search, partner lookup in a subledger view) where the 250 ms debounce prevents a flood of API calls on every keystroke without requiring the developer to implement debounce logic.\",\n ],\n related: [\n \"Input — use `Input` (inside `FormField`) when the search field is part of a submitted form and needs a `name` attribute, or when you need full `onChange` control without any debounce or clear button. SearchInput is the right pick when the field only triggers filtering, not form submission.\",\n \"Toolbar — SearchInput is almost always placed as a direct child of `Toolbar`, which provides the surrounding strip, clear-all button, and active-filter state. Do not use SearchInput as a standalone header widget when a full filter strip (with selects etc.) already exists — compose them together.\",\n \"Command — use `Command` + `CommandInput` when you need a keyboard-navigable command palette or combobox list with grouped items and keyboard selection. `Command` is only meaningful when paired with `CommandList`; SearchInput is the right pick for a plain filter box with no item-selection behavior.\",\n \"Select (with showSearch) — when users must pick a value from a list AND search to narrow it, use `<Select options={...} showSearch>` (which has its own built-in search input). SearchInput is for filtering an external data set, not for value selection from an option list.\",\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: \"defaultValue\",\n type: \"string\",\n description:\n \"Uncontrolled initial value (data-driven API). The trigger shows the matching option's label at rest — including in searchable (showSearch) mode — so an edit form pre-filled from server data renders the label, not the placeholder. Selected option is marked by a background tint (no check icon).\",\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\" | \"md\"',\n defaultValue: '\"md\"',\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 \"Select with showSearch — use Select (with the `showSearch` prop) for typeahead/autocomplete lookup patterns instead of the removed Autocomplete component.\",\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 onValueChange={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 onValueChange={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 onValueChange={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: \"Radix toggle switch (bare). For a labelled row with a hidden form input use Field.\",\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 {\n name: \"size\",\n type: '\"sm\" | \"md\"',\n defaultValue: '\"md\"',\n description: \"Thumb size — 'sm' for dense rows.\",\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 usage: [\n \"DO use Switch (bare) only when you are building a custom inline toggle without a visible label — e.g., a DataTable row action column. Always pair it with a <Label htmlFor={id}> placed adjacent in the DOM; never leave it label-less for screen readers.\",\n \"DO NOT pass a `name` prop to bare Switch expecting HTML form submission — Radix Switch renders no hidden input, so the value is silently dropped on submit. Use Field (which mirrors a hidden `0`/`1` input) for any field that must submit inside an HTML <form>.\",\n \"DO use the `size` prop ('sm' | 'md') to control thumb size. 'sm' is appropriate in dense DataTable rows or filter bars; omit it (defaults to 'md') everywhere else.\",\n \"DO wire controlled state: pass both `checked` (boolean) and `onCheckedChange` together. Passing only one causes a React controlled/uncontrolled warning. For uncontrolled use, pass neither — but bare Switch has no `defaultChecked` state management built in (Field handles that internally).\",\n \"DON'T hand-roll a <div> + <label> wrapper with bare Switch to get a labelled field — that is exactly what Field provides, including aria-describedby, aria-invalid, error/helper text, and the hidden input. Reach for Field instead.\",\n \"DO link the switch to its label via matching `id` on Switch and `htmlFor` on Label. Without this pairing, clicking the label text does not toggle the switch and the a11y association is broken.\",\n ],\n useCases: [\n \"Inline toggle in a DataTable action cell (e.g., 'Active' column) where the label is already provided by the column header and no form submission is involved.\",\n \"Settings panel where a React state boolean is toggled immediately via an optimistic API call — no <form> submit, so Field's hidden input is unnecessary.\",\n \"Custom compound component where you compose Switch + Label yourself and need direct access to the Radix Root props (e.g., adding aria-controls or data-attributes not supported by Field).\",\n \"Filter toolbar toggle (e.g., 'Show archived') rendered inline next to other filter controls, using size='sm' for density parity with adjacent inputs.\",\n \"Preview/demo UI where the switch controls a local display state (dark-mode preview, feature flag preview) with no server persistence.\",\n ],\n related: [\n \"Field — use this instead of bare Switch whenever the toggle needs a visible label, helper text, error message, or must submit its value inside an HTML <form>. Field composes Label + Switch + hidden input automatically.\",\n \"Checkbox — use Checkbox (or CheckboxGroup) when the user is selecting one or more items from a set, or when the binary choice semantically means 'agree/select' rather than 'enable/disable'. Switch implies an immediate, persistent state change; Checkbox implies a form choice.\",\n \"Field — use for a binary or small-set choice rendered as radio-style cards with rich descriptions, when the visual weight of a toggle is insufficient for the decision importance.\",\n \"RadioGroup — use when the user must choose exactly one option from 2–4 mutually exclusive values; Switch is only appropriate for a single on/off boolean.\",\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 usage: [\n \"DO always wrap Textarea in FormField when it appears in a form — FormField clones aria-describedby, aria-required, and aria-invalid onto the child, giving error/helper announcements and screen-reader labelling for free. Pass matching id props to both.\",\n \"DO use the godx-ui Textarea (`import { Textarea } from '@godxjp/ui/data-entry'`) — never a raw `<textarea>`. The component applies the `ui-control-multiline` token class that picks up density, focus-ring, and border tokens from the design system.\",\n \"DO control the value with `value` + `onChange` in React-managed forms (e.g. Inertia `useForm`). Textarea is a plain `forwardRef` over the native element so it accepts all standard `HTMLTextAreaElement` attributes — `rows`, `maxLength`, `disabled`, `name`, `placeholder`, `readOnly` all pass through directly.\",\n \"DO pass `name` when the textarea sits inside an HTML `<form>` for native form submission or when Inertia's `useForm` destructures field values by key — the `name` attribute maps the value into the form data bag.\",\n \"DON'T apply manual height or padding classes directly on Textarea to simulate a taller field — use the `rows` prop instead. The component does not auto-resize; if you need auto-grow behaviour you must wire a custom `onInput` handler that adjusts `style.height` explicitly.\",\n \"DON'T hand-roll label + error markup next to a bare Textarea. Always use FormField: it injects aria-invalid (red ring on the control), renders a `role='alert'` error paragraph, and links them via aria-describedby automatically.\",\n ],\n useCases: [\n \"Free-text memo or note fields on an invoice or transaction detail form — e.g. '備考 / Notes' that can hold multi-line internal comments alongside structured Invoice fields.\",\n \"Rejection reason or approval comment in an admin workflow dialog — a short-to-medium text block a reviewer types before confirming an action in a Dialog or Sheet.\",\n \"Address or multi-line description input on a vendor / partner entity form where a single-line Input would be too restrictive.\",\n \"Email body composer or message template editor in a lightweight CRM or notification settings screen where rich text is not required.\",\n \"Audit log annotation — allowing an accountant to attach a plain-text explanation to a manual journal entry or adjustment record.\",\n ],\n related: [\n \"Input — use Input for single-line values (names, amounts, codes). Use Textarea only when the expected value spans multiple lines or could be longer than ~80 characters.\",\n \"FormField — always the parent wrapper for Textarea in forms; provides label, helper text, error message, and injects all required aria attributes onto the Textarea child automatically.\",\n \"Select — when the user must pick from a finite set of multi-line-looking options (e.g. template choices) use Select, not a Textarea presenting options as free text.\",\n \"Select with showSearch or SearchSelect — if the multi-line field is actually a tag/token input or a constrained lookup, prefer Select (showSearch) or SearchSelect over a Textarea that the user types into freely.\",\n ],\n example: `import { Textarea } from \"@godxjp/ui/data-entry\";\n\n<Textarea id=\"notes\" rows={4} placeholder=\"自由記述\" value={notes} onValueChange={(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 usage: [\n \"DO: always pass `htmlFor` matching the `id` of the associated control — this is the entire purpose of the component. Without it, clicking the label text does NOT focus or toggle the control, breaking a11y and UX.\",\n 'DO: import from `@godxjp/ui/data-entry` (not shadcn or Radix directly). The godx-ui Label extends Radix\\'s LabelPrimitive with `data-slot=\"label\"`, `select-none`, and `group-data-[disabled]` opacity-50 — hand-rolling a `<label>` loses all of these.',\n \"DON'T: use Label as a standalone visible heading or section title. It is a form-control association primitive. For page/section headings use semantic HTML (`<h2>`, etc.) or a typography class instead.\",\n \"DON'T: wrap Label around a control that is already labelled internally. FormField, Field, and CheckboxGroup all render Label internally — adding a second Label creates a duplicate association and redundant screen-reader announcement.\",\n \"DO: pair Label with Checkbox or Switch when NOT using the compound wrapper (Field). In that case generate the shared id with `React.useId()` and pass it to both `id` on the control and `htmlFor` on Label.\",\n \"PREFER FormField over a bare Label + control pair whenever you also need helper text, error messages, or `required` asterisk. FormField injects `aria-describedby` and `aria-invalid` automatically; a bare Label does not.\",\n ],\n useCases: [\n \"Pairing with a standalone Checkbox when Field's two-line layout is unnecessary — e.g. a single 'Remember me' option in a login form.\",\n \"Labelling a bare Switch (not Field) in a settings row where the switch is controlled by parent state and no HTML form name attribute is needed.\",\n \"Adding a visible label to a custom or third-party control that accepts an `id` prop but isn't wrapped by FormField or Field.\",\n \"Labelling a Textarea in a free-text form field when FormField's helper/error slots aren't needed, keeping the markup minimal.\",\n \"Rendering an accessible label inside a table row where a FormField's block layout would break the inline/grid structure.\",\n \"Adding a label to a DatePicker, TimePicker, or ColorPicker inside a simple layout that doesn't need the full FormField wrapper.\",\n ],\n related: [\n \"FormField — prefer this over a bare Label whenever the field needs helper text, an error message, or a required marker; FormField renders Label internally and wires aria-describedby/aria-invalid automatically.\",\n \"Field — use for a Checkbox or Radio.Item that needs a visible label and optional description line; it renders Label internally — do NOT add a second Label around it.\",\n \"Field — use instead of a bare Switch + Label pair when the control must submit a value via an HTML form name; Field owns the Label + hidden input composition.\",\n \"Checkbox — the most common bare-Label partner; pair with Label via shared useId() id/htmlFor when Field's layout is too heavy.\",\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 usage: [\n \"DO pair every standalone Checkbox with a `<Label htmlFor={id}>` — the id prop on Checkbox must match the htmlFor on Label so screen readers announce the label on focus. Without this pairing the control is inaccessible.\",\n \"DO use the controlled pattern (`checked` + `onCheckedChange`) for any form-bound checkbox. `onCheckedChange` receives `boolean | 'indeterminate'` — always coerce with `!!v` or an explicit guard before storing in state.\",\n \"DO use `Checkbox.Group` (alias for CheckboxGroup) with the `options` prop when you have ≥2 choices from an array — it renders each item inside a `Field` (label + optional description), generates stable ids automatically, and manages the `string[]` value array. NEVER hand-roll a loop of bare `<Checkbox>` elements for a multi-select list.\",\n \"DO pass `name` on `Checkbox.Group` (not on individual checkboxes) when the group must submit as form fields — the group propagates the name to each internal checkbox so the browser serialises all checked values under that key.\",\n \"DON'T use `checked='indeterminate'` on `Checkbox.Group` children — indeterminate is only meaningful on a parent 'select-all' control you wire manually; the group itself does not auto-compute it.\",\n \"DON'T wrap a standalone Checkbox in `Field` manually — `Field` is the internal composition primitive that `Checkbox.Group` uses. For a single boolean with a label, use `<div className='flex items-center gap-2'><Checkbox id='x' .../><Label htmlFor='x'>...</Label></div>` as shown in the catalog example; for a full labelled-checkbox with description, use `Field` directly only if you need a one-off item outside a group.\",\n ],\n useCases: [\n \"A 'Select all' / bulk-action row above a DataTable — standalone Checkbox with `checked='indeterminate'` when some (not all) rows are selected, toggling between all-selected and none-selected.\",\n \"A multi-step filter panel (e.g. filter invoices by payment status: Paid, Unpaid, Overdue) — `Checkbox.Group` with `options` prop and `orientation='vertical'`, controlled value wired to Toolbar state.\",\n \"Confirmation or consent acknowledgement before a destructive action in a Dialog — standalone Checkbox with controlled state used to enable/disable the confirm Button.\",\n \"Settings panel where each feature flag is a boolean toggle with a description line — `Checkbox.Group` with options carrying a `description` field so each row renders label + subtext via Field.\",\n \"Bulk-edit form row in an accounting ledger (e.g. 'Apply to all selected entries') — standalone Checkbox with name + value inside a `<form>` for native HTML form submission.\",\n \"Onboarding checklist (e.g. 'I have read the terms', 'I consent to data processing') with multiple distinct items whose values are independent — two separate standalone Checkboxes, each with their own id/state, not a Checkbox.Group (since each item maps to a different boolean field).\",\n ],\n related: [\n \"CheckboxGroup — use instead of bare Checkbox when you have a list of 2+ options from an array; it handles id generation, Field wrapping, value array management, and the `name` prop for form submission. Checkbox is for a single boolean; CheckboxGroup is for multi-select.\",\n \"Switch / Field — use Switch when the action takes immediate effect (enable/disable a feature in settings) rather than selecting an option to be submitted later. Checkbox implies 'will be submitted as part of a form'; Switch implies 'applies now'. Field adds a hidden input for HTML form compatibility.\",\n \"RadioGroup — use when only one option in a group may be selected at a time (mutually exclusive). CheckboxGroup = multiple selections allowed; RadioGroup = single selection only.\",\n \"Field — the internal layout primitive (control slot + Label + description) that Checkbox.Group renders per item. Use it directly only when you need a one-off labelled checkbox or radio item outside of a group, and you want the consistent indent/description layout without the group's value-management overhead.\",\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 usage: [\n \"DO use the `options` prop for the data-driven path: pass `{ label, value, disabled?, description? }[]` and RadioGroup renders every option as a correctly labelled Field automatically — never hand-roll Radio.Item + Label pairs in a loop yourself.\",\n \"DO provide `name` whenever the group lives inside an HTML form: Radix renders a hidden `<input name={name}>` carrying the selected string value, making the field natively form-submittable without a separate hidden input.\",\n \"DO use controlled mode (`value` + `onValueChange`) for any form managed by useForm or a state manager. Use `defaultValue` only for truly uncontrolled UI where you never need to read the value in code.\",\n \"DO NOT reach for children / manual composition unless the options list is dynamic-JSX (e.g. each item needs a custom rendered label with an icon). When you do compose children manually, wrap each Radio.Item in a Field — rendering a bare Radio.Item without Field skips the label and breaks a11y.\",\n \"DO NOT use RadioGroup when the user may select zero or multiple items — that is CheckboxGroup. RadioGroup enforces exactly one selection at all times (or none before first interaction when uncontrolled).\",\n \"A11y: the Radix root emits `role=radiogroup`; each item gets `role=radio` and is keyboard-navigable with arrow keys. Never suppress `name` on the Root when inside a form — without it the hidden input is unnamed and won't submit.\",\n ],\n useCases: [\n \"Selecting a single billing cycle (monthly / quarterly / annual) in an invoice or subscription settings form where all 2-4 options must be visible at once.\",\n \"Choosing a report output format (PDF / CSV / Excel) before triggering an async export job — keeps all options scannable without opening a dropdown.\",\n \"Picking a transaction type (income / expense / transfer) on an accounting entry form where the choice changes which subsequent fields are shown.\",\n \"Selecting a sync trigger mode (first purchase / birthday / manual) in a campaign or automation settings panel — matches the catalog example exactly.\",\n \"Filtering a compact inline control (horizontal orientation) such as date granularity (day / week / month) inside a dashboard filter bar where a full Select dropdown would be over-engineered.\",\n \"Choosing an approval status (pending / approved / rejected) on an admin detail sheet where all states must be visible so reviewers can compare them without interaction.\",\n ],\n related: [\n \"CheckboxGroup — use when the user may select zero or more values simultaneously (multi-select); RadioGroup enforces exactly one selection. Both share the same options array shape and orientation prop.\",\n \"Select — use when there are 5 or more options or the option list is dynamic/searchable; RadioGroup is preferred for 2-4 fixed visible choices where scanning all options at once matters.\",\n \"Field — use when there are exactly two states that map to on/off (boolean); RadioGroup is the right pick when the two-or-more options are semantically distinct named values, not a toggle.\",\n \"Field — the low-level label+description wrapper that RadioGroup uses internally for each item. Use it directly only when manually composing Radio.Item children inside Radio.Group; never hand-roll a label alongside a bare Radio.Item without it.\",\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 onValueChange={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. Rendered with role=dialog.\",\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 usage: [\n \"Use `Dialog` for form-style or wizard-style modal flows that need freeform content and a close action.\",\n \"DO always control open state via `open` + `onOpenChange`. Dialog has no uncontrolled shortcut — omitting `open` means the trigger alone drives state, which is fine for simple trigger-only cases, but any async submission flow must use controlled state so you can hold the dialog open while `pending=true` and close it only on success.\",\n \"DO include `DialogHeader` with `DialogTitle` (and optionally `DialogDescription`) inside every `DialogContent`. Radix requires an accessible title for screen readers; omitting it triggers a console warning and breaks a11y.\",\n \"DO wrap tall/scrolling content in `DialogBody` (the ring-safe scroll slot, max-height ~60vh). It insets the content to match the dialog padding so a full-width control's focus ring never clips against the scroll container — mirror of SheetBody.\",\n ],\n useCases: [\n \"Inline form dialog — create or edit a record (invoice line, supplier, coupon) without navigating away. Place `FormField`/`Input`/`Select` inside `DialogContent`, wire the submit button to your mutation, and hold `open` while `pending` to prevent double-submit.\",\n \"Read-only detail popup — show a full transaction audit trail, attachment preview, or approval history in a modal without leaving the list page. Use `Dialog` with no `DialogFooter` action buttons, just a close trigger.\",\n \"Wizard / multi-step flow — step through entity setup (legal entity → fiscal year → opening balances) using a single Dialog whose `DialogContent` conditionally renders different step panels. Control which step is shown in local state.\",\n ],\n related: [\n \"Sheet — use Sheet instead of Dialog when the content is a slide-in panel (filters, detail sidebar, settings drawer). Sheet uses `side` prop and is better suited for wide filter forms or contextual detail panels that don't demand full focus interruption.\",\n \"Alert — use Alert for inline, non-modal status messages (validation errors, success banners on the page). Dialog is modal and focus-trapping; Alert is inline and never blocks interaction.\",\n \"Popover — use Popover for lightweight non-modal overlays anchored to a trigger (quick-edit a single field, tooltip-style confirmation for low-stakes actions). Dialog is full-modal; Popover stays near its trigger and doesn't dim the page.\",\n \"AlertMutationFeedback — use AlertMutationFeedback for toast/inline feedback after the Dialog closes, not inside it. Putting a success toast inside a Dialog that is about to unmount causes it to disappear immediately; emit the feedback after `onOpenChange(false)` resolves.\",\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: \"AlertDialog\",\n group: \"feedback\",\n tagline:\n 'Canonical modal confirmation flow (destructive / high-stakes decisions). Preserves confirm semantics with `role=\"alertdialog\"` and built-in cancel/confirm handling.',\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: \"title\",\n type: \"string\",\n required: true,\n description: \"Accessible title/announcement for the alertdialog.\",\n },\n { name: \"description\", type: \"string\", description: \"Optional supporting explanatory text.\" },\n {\n name: \"confirmLabel\",\n type: \"string\",\n description: \"Primary action label (defaults to translated continue).\",\n },\n {\n name: \"cancelLabel\",\n type: \"string\",\n description: \"Dismiss action label (defaults to translated cancel).\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"destructive\"',\n defaultValue: '\"default\"',\n description: \"Variant passed through to the confirm button.\",\n },\n {\n name: \"confirmPhrase\",\n type: \"string\",\n description: \"Optional type-to-confirm phrase to prevent accidental confirm.\",\n },\n {\n name: \"onConfirm\",\n type: \"() => Promise<void> | void\",\n description: \"Primary action handler.\",\n },\n {\n name: \"keepOpenOnConfirm\",\n type: \"boolean\",\n description: \"Keep modal open after confirm when true.\",\n },\n {\n name: \"pending\",\n type: \"boolean\",\n description: \"Disable actions while async work is running.\",\n },\n ],\n usage: [\n \"Use `AlertDialog` for destructive/irreversible actions (delete, void, unpublish, archive, etc.).\",\n \"Use `confirmPhrase` for high-friction operations (e.g. requiring `DELETE`) to reduce accidental confirmation.\",\n \"Pass `keepOpenOnConfirm` when the confirm handler advances a multi-step flow and should not close immediately.\",\n ],\n useCases: [\n \"Dangerous delete or irreversible workflow confirmation that should block the background UI.\",\n \"Destructive batch operations that should remain modal and explicit until action is intentionally confirmed.\",\n ],\n related: [\n \"Dialog — use for form-style and non-destructive modal flows, no confirm preset behavior.\",\n ],\n example: `import { AlertDialog } from \"@godxjp/ui/feedback\";\n\n<AlertDialog\n open={open}\n onOpenChange={setOpen}\n title=\"Delete project\"\n description=\"This action cannot be undone.\"\n confirmLabel=\"Delete\"\n cancelLabel=\"Cancel\"\n onConfirm={async () => {\n await deleteProject();\n setOpen(false);\n }}\n variant=\"destructive\"\n/>`,\n storyPath: \"feedback/AlertDialog.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/SheetBody/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 name: \"width\",\n type: \"number | string\",\n description:\n \"On SheetContent (side left/right): desired panel width (number→px). Caps at the viewport — full-width on a small screen (min(width,100%)), NOT a hard fixed width. Default w-3/4 sm:max-w-md.\",\n },\n {\n name: \"title / subtitle / extra / tone\",\n type: \"ReactNode / ReactNode / ReactNode / ToneProp\",\n description:\n \"On SheetHeader (Ant-style): title (→ SheetTitle, accessible name), subtitle (→ SheetDescription), right-aligned extra actions, and a soft semantic `tone` background band. Children still supported.\",\n },\n ],\n usage: [\n \"DO build the panel with SheetHeader (pass `title`/`subtitle`/`extra`/`tone` OR children) > SheetBody (scrollable, ring-safe) > SheetFooter (pinned). SheetTitle is required for a11y — the `title` prop renders it for you. Never skip the title.\",\n \"DO set `width` on SheetContent for a wider/narrower panel (e.g. width={480}); it caps at the viewport so small screens still get a full-width panel.\",\n \"DO use all named sub-parts in order: Sheet (root) > SheetTrigger (opener) > SheetContent (panel) > SheetHeader > SheetTitle (required for a11y — maps to Radix DialogPrimitive.Title, announced as the accessible name) > optional SheetDescription > body content > SheetFooter. Never skip SheetTitle inside an open SheetContent.\",\n \"DO control state explicitly with open + onOpenChange on Sheet root when you need to close programmatically (e.g. after form submit). Uncontrolled (no props) works for simple trigger-only cases but gives you no hook to reset form state on close.\",\n \"DO use SheetTrigger asChild to wrap a Button or other interactive element — this avoids a nested <button> in the DOM. Never render a raw <button> as a direct child of SheetTrigger.\",\n \"DO wrap a long/scrolling body in SheetBody (between SheetHeader and a pinned SheetFooter). It is the ring-safe scroll slot: a hand-rolled <div className='overflow-y-auto'> clips the 3px focus ring of a full-width Input/Select at the scroll edges — SheetBody insets the content so the ring never clips.\",\n \"DO use SheetFooter (renders at the bottom via mt-auto, symmetric 16/24 padding, full-bleed top border) for primary/cancel action Buttons. Never float action Buttons inside the body — they will not stick to the panel bottom.\",\n \"DON'T set showCloseButton={false} on SheetContent unless you provide your own SheetClose element; omitting both leaves users with no keyboard-accessible close path and breaks a11y.\",\n \"DON'T put a Sheet inside a Dialog (nested Radix portals conflict). If you need a slide-over triggered from within a modal, close the Dialog first, then open the Sheet.\",\n ],\n useCases: [\n \"Filter/search panel: slide in from the right with filter FormFields (Select, DateRangePicker, CheckboxGroup) that affect a DataTable — preferred over a Dialog because filters do not require confirmation and benefit from seeing the table behind the overlay.\",\n \"Quick-edit drawer: open an entity's editable fields (e.g. invoice line items, account settings) without navigating away, with Save/Cancel in SheetFooter — use side='right' and keep the main page visible as context.\",\n \"Detail peek panel: show read-only Descriptions / Timeline of a selected record (e.g. a journal entry or invoice) from a DataTable row click, using side='right' with showCloseButton={true}.\",\n \"Mobile-first navigation drawer: side='left' sheet acting as a slide-in nav menu on small viewports when the AppShell Sidebar is hidden — triggered by a hamburger Button.\",\n \"Step-by-step wizard side panel: multi-step form (Steps component inside SheetContent) for onboarding or import flows where full-page navigation would lose list context.\",\n ],\n related: [\n \"Dialog — use Dialog (centered modal) when the action is destructive, requires full user focus, or needs a confirm/alertdialog (mode='confirm'). Use Sheet when the user benefits from seeing the page content behind the slide-over (filters, detail peek, quick-edit).\",\n \"Toolbar/ToolbarGroup — use Toolbar for inline persistent filter controls above a DataTable (no overlay). Use Sheet when the filter set is large (>4 controls) or on mobile where inline controls collapse poorly.\",\n \"Popover — use Popover for lightweight, anchor-positioned context menus or single-control overlays (date picker, color picker). Use Sheet when the panel has a header, multiple fields, or footer actions that need a dedicated panel.\",\n \"SplitPane — use SplitPane for a persistent side-by-side layout where both panes are always visible. Use Sheet when the secondary panel is transient and should overlay the primary content.\",\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 usage: [\n 'DO compose with sub-parts in order: wrap text content in `<Alert.Content>` (or bare `<AlertContent>`), then `<Alert.Title>` + `<Alert.Description>` inside it, then `<Alert.Actions>` for any retry/CTA buttons. Example: `<Alert tone=\"destructive\"><Alert.Content><Alert.Title>Error</Alert.Title><Alert.Description>{msg}</Alert.Description></Alert.Content><Alert.Actions><Button …/></Alert.Actions></Alert>`.',\n \"DO use `Alert.QueryError` (alias `AlertQueryError`) for TanStack Query / API failure surfaces — it already renders humanError(error), an i18n title, and an optional Retry button. Never hand-roll that pattern.\",\n 'DON\\'T pass raw action elements directly as top-level children of `<Alert>` without wrapping them in `<Alert.Actions>` — the layout slot only activates correctly via the `data-slot=\"alert-actions\"` wrapper.',\n 'DON\\'T hand-roll a dismiss ✕ button — pass `onDismiss` to `<Alert>` and the component renders its own accessible dismiss button with `aria-label=\"Dismiss\"`. The `onDismiss` handler may return a Promise.',\n 'DON\\'T suppress the icon with `icon={false}` unless there is a deliberate design reason; the icon is the primary a11y cue for sighted users since the root already carries `role=\"alert\"` for screen readers.',\n \"DO NOT use `Alert` for transient ephemeral feedback (e.g. 'saved successfully'). Use `toast()` from sonner + `<Toaster>` for that. `Alert` is for persistent, page-scoped banners that stay visible until the user acts or dismisses.\",\n ],\n useCases: [\n 'Page-level error banner after a form submission fails server-side validation — `tone=\"destructive\"` with `Alert.Title` summarising the error and `Alert.Description` listing field issues, paired with `onDismiss` so the user can clear it.',\n \"Inline warning at the top of an accounting invoice list when the OAuth token for the MF sync is about to expire — `variant=\\\"warning\\\"` with an `Alert.Actions` containing a 'Reconnect' Button.\",\n 'Success confirmation banner rendered after a bulk-import job completes and the user returns to the list page — `tone=\"success\"` with `Alert.Description` showing the record count imported.',\n \"TanStack Query data-fetch failure inside a Card body — use `<Alert.QueryError error={error} onRetry={refetch} />` instead of writing a custom error state.\",\n \"Informational notice at the top of a settings page when a feature is in beta or requires a plan upgrade — `variant=\\\"default\\\"` (Info icon) with a short description and an `Alert.Actions` 'Learn more' link.\",\n 'Dismissible billing-overdue notice at the top of the dashboard — `tone=\"destructive\"` with `onDismiss` that sets a session flag so it does not reappear until the next login.',\n ],\n related: [\n \"Toaster — use for transient, auto-dismissing feedback ('Record saved', 'Deleted'). Alert is for persistent page-scoped banners; Toaster is for fire-and-forget notifications triggered by toast() from sonner.\",\n \"AlertMutationFeedback — use when you want inline success/error feedback tightly coupled to a form mutation's state (renders inline below the submit button). Alert requires you to manage show/hide state yourself.\",\n \"DataState — use for full query lifecycle (loading skeleton + empty state + error) inside a data-fetching section. Alert.QueryError is the error sub-component DataState uses internally; prefer DataState when you also need the loading/empty states.\",\n \"EmptyState — use for the zero-data case inside a list or table section, not for errors or warnings. Alert is for status messages; EmptyState is for the absence of data.\",\n ],\n example: `import { Alert, AlertTitle, AlertDescription } from \"@godxjp/ui/feedback\";\n\n<Alert tone=\"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 usage: [\n \"DO use SkeletonTable as the pre-mount placeholder — either as a ternary fallback (`{!data ? <SkeletonTable rows={10} columns={6} /> : <DataTable … />}`) for Inertia deferred props, or as the `skeleton` prop of `DataState` (`<DataState query={q} skeleton={<SkeletonTable />} …>`). It is NOT for in-table loading; once DataTable has mounted use its own `loading` prop instead.\",\n \"DO match rows/columns to the final DataTable layout: pass `rows` equal to your expected page size and `columns` equal to your column count so the skeleton doesn't visually jump on hydration. Defaults are rows=8, columns=5.\",\n \"DO NOT use SkeletonTable when data is already present but refetching — use `DataTable loading={isFetching}` for in-table refetch states. SkeletonTable is only for the initial pre-mount gap before DataTable is rendered.\",\n \"DO NOT wrap SkeletonTable in a Card — it renders its own header + body structure matching DataTable's DOM. Placing it inside CardContent adds unwanted padding around the skeleton rail.\",\n 'The root element carries `aria-busy=\"true\"` automatically — do not add a second aria-busy on a wrapper. Screen readers announce the loading state correctly without extra markup.',\n \"Import from `@godxjp/ui/feedback` (not `@godxjp/ui/admin`). Both paths resolve but the canonical export is `feedback`.\",\n ],\n useCases: [\n \"Inertia deferred props: the server streams the page shell immediately and defers the table data; render SkeletonTable until the prop arrives (`{!invoices ? <SkeletonTable rows={20} columns={7} /> : <DataTable data={invoices} columns={columns} />}`).\",\n \"TanStack Query initial load via DataState: pass SkeletonTable as the `skeleton` prop so DataState shows the correct table shape during the query's loading state before switching to the populated DataTable.\",\n \"Filter / search reset that unmounts and remounts DataTable: briefly show SkeletonTable while the new dataset fetches, preventing a flash of the empty state before results arrive.\",\n \"Admin list pages (invoices, journal entries, partners) where the table has a known column count — tune `columns` to match so column widths feel stable and don't reflow on hydration.\",\n \"Page-level Suspense boundaries: use SkeletonTable as the `fallback` of a React Suspense wrapping a lazy-loaded data table component.\",\n \"Route prefetch / navigation transitions: render SkeletonTable in the destination slot while Inertia visits are in-flight, keeping perceived layout stable.\",\n ],\n related: [\n \"DataTable — sibling component that SkeletonTable precedes. Once DataTable mounts, use its `loading` prop (renders an in-table loading row) for subsequent refetches rather than swapping back to SkeletonTable. Pick SkeletonTable only for the pre-mount gap.\",\n \"DataState — query lifecycle widget from `@godxjp/ui/query`; accepts SkeletonTable as its `skeleton` prop and handles loading/empty/error transitions automatically. Prefer DataState + SkeletonTable over a hand-rolled ternary when the data comes from a useQuery hook.\",\n \"SkeletonStat — sibling skeleton shaped like a StatCard tile; use inside a ResponsiveGrid to placeholder KPI dashboard cards, not tabular data.\",\n \"DataTable — when data is already mounted but re-fetching (e.g. pagination, filter change), set `loading={true}` on DataTable directly instead of unmounting it and swapping in SkeletonTable; avoids layout shift and preserves scroll position.\",\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: \"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 usage: [\n \"DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks — there is no provider context, only DOM portals.\",\n 'DO: Import `toast` from `\"sonner\"` directly (not from `@godxjp/ui`) to fire toasts anywhere: `toast.success(…)`, `toast.error(…)`, `toast.warning(…)`, `toast.info(…)`, `toast.loading(…)`, `toast.promise(…)`.',\n \"DON'T: Try to import a `toast` helper from `@godxjp/ui/feedback` — it does not exist. The component re-exports only the `Toaster` mount; the imperative API lives in the `sonner` package.\",\n \"DO: Let the wrapper handle theming — it uses `useDocumentTheme()` to sync with the document `dark` class and `prefers-color-scheme` automatically. Never pass a hardcoded `theme` prop unless you are deliberately overriding.\",\n \"DON'T: Use `Toaster` for persistent errors or blocking confirmations. Toasts auto-dismiss; they are not a substitute for `Alert` (inline persistent warnings) or `Dialog` (decisions requiring user input).\",\n \"DO: Pass `position` to relocate the stack if a persistent sidebar/footer would obscure the default `bottom-right`. The wrapper already sets a safe `mobileOffset`; don't add redundant mobile offsets unless your layout differs.\",\n ],\n useCases: [\n 'After a successful form save (invoice, journal entry, vendor record) — show `toast.success(\"保存しました\")` to confirm without blocking navigation.',\n 'After a background job is enqueued (e.g. bulk sync or export) — show `toast.info(\"エクスポートを開始しました\")` then later update with `toast.promise()` to track completion.',\n \"Mutation error fallback when the error is transient and retrying is the right UX — show `toast.error(message)` instead of replacing page content; reserve `AlertMutationFeedback` for inline, persistent error display inside a form.\",\n 'Soft destructive action confirmation outcome — e.g. \"削除しました\" after an item is removed, paired with an undo action via `toast(\"…\", { action: { label: \\'元に戻す\\', onClick: undo } })`.',\n 'OAuth / session expiry warnings — surface a brief `toast.warning(\"セッションの有効期限が近づいています\")` without interrupting the user\\'s current form state.',\n ],\n related: [\n \"Alert — use for persistent, inline feedback that must stay visible (validation summaries, page-level warnings, destructive notices). Unlike Toaster, Alert does not auto-dismiss and lives in the document flow.\",\n \"AlertMutationFeedback — use when you have a TanStack `useMutation` result and want an inline error + retry UI inside a form or card. Renders nothing on success/idle; pairs naturally with a `toast.success` in `onSuccess`.\",\n \"Dialog — use when the user must make a conscious decision (confirm delete, resolve conflict) before proceeding. Toaster toasts are fire-and-forget; Dialog blocks until the user responds.\",\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 with optional Ant-style `items` API. Pass items for the common full TabsList/TabsContent set, or compose TabsList/TabsTrigger/TabsContent manually when you need per-panel control.\",\n props: [\n {\n name: \"items\",\n type: \"{ value: string; label: React.ReactNode; content: React.ReactNode; disabled?: boolean }[]\",\n description:\n \"Optional data-driven tab list. When provided, Tabs renders all triggers and content panels.\",\n },\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 usage: [\n \"DO pass `items` when all tab content is known up front — each item needs a unique `value`, trigger `label`, and panel `content`.\",\n 'When not using `items`, compose the full four-part tree — `<Tabs>` root, `<TabsList>` trigger bar, one `<TabsTrigger value=\"…\">` per tab, one `<TabsContent value=\"…\">` per matching trigger.',\n \"DO: use `defaultValue` (uncontrolled) for simple local state; use `value` + `onValueChange` together (controlled) when the active tab is driven by URL query params, router state, or parent state. NEVER set both simultaneously.\",\n \"DO use `variant` on Tabs when using `items`; when composing manually, set `variant` on `TabsList`.\",\n 'DO: pass `orientation=\"vertical\"` to `<Tabs>` (not to `TabsList`) for a side-rail layout — the CSS group classes on root and triggers respond automatically, so no extra className gymnastics are needed.',\n \"DON'T: hand-roll the active-indicator underline or selected-state ring — `TabsTrigger` already applies `data-[state=active]` styles including the `after:` line element for the `line` variant. Adding your own underline breaks the design.\",\n ],\n useCases: [\n \"Detail drawers or pages that need full per-panel control — e.g. an accounting journal-entry sheet where one panel has `forceMount` to keep a live chart mounted, requiring custom `TabsContent` props that `Tabs` cannot pass.\",\n \"Controlled tabs driven by URL search params (e.g. `?tab=history`) where the parent reads/writes the active key and passes it to `value` / `onValueChange`.\",\n 'Vertical side-rail navigation inside a `SplitPane` or settings layout where `orientation=\"vertical\"` on the root and `variant=\"line\"` on `TabsList` combine to produce a sidebar-style tab strip.',\n \"Lightweight widget tabs on a dashboard card — e.g. switching a `DataTable` between 'Pending' and 'Paid' invoice views — where an uncontrolled `defaultValue` is sufficient and no URL state is needed.\",\n \"Admin entity profile pages (company, partner, employee) where each `TabsContent` wraps an Inertia deferred prop panel, lazy-loading expensive data only when the tab is first activated.\",\n ],\n related: [\n \"Steps (@godxjp/ui/navigation) — sequential wizard/progress indicator. Use Steps when order and completion state matter (multi-step forms, onboarding flows); use Tabs when panels are non-sequential and any tab can be visited freely.\",\n \"Toolbar / ToolbarGroup (@godxjp/ui/navigation) — horizontal filter chip row. Visually resembles `line`-variant tabs but is semantically different: Toolbar filters a dataset, it does not switch content panels. Never use Tabs as a filter control.\",\n \"DropdownMenu (@godxjp/ui/navigation) — use for space-constrained contexts where showing all tab triggers at once is impractical (e.g. mobile overflow menu). If only 2-3 options exist and screen space is tight, a DropdownSidebar is a lighter alternative to a full tab strip.\",\n ],\n example: `import { Tabs } from \"@godxjp/ui/navigation\";\n\n<Tabs\n defaultValue=\"overview\"\n items={[\n { value: \"overview\", label: \"概要\", content: \"概要コンテンツ\" },\n { value: \"history\", label: \"履歴\", content: \"履歴コンテンツ\" },\n ]}\n/>`,\n storyPath: \"navigation/Tabs.stories.tsx\",\n rules: [],\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: \"value\",\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: \"onValueChange\",\n type: \"(page: number, pageSize: number) => void\",\n description: \"Page / page-size change handler.\",\n },\n ],\n usage: [\n \"DO always control Pagination externally: store `value` (page) and `pageSize` in React state (or URL params), and update both in the `onValueChange(page, pageSize)` callback. Pagination is fully controlled — it has no internal state and will not move unless `value` changes.\",\n \"DO pass `total` as the raw item count (not page count). The component computes `Math.ceil(total / pageSize)` internally; passing a pre-computed page count as `total` will over-paginate.\",\n \"DO use `showSizeChanger` together with `pageSizeOptions` when the user needs density control (default options are [10, 20, 50, 100]). When `showSizeChanger` is omitted the page-size Select is not rendered at all — do NOT hand-roll your own Select beside Pagination.\",\n \"DO use `simple` mode for compact contexts (mobile, sidebars, sheet footers) — it renders Prev / `n / total` / Next with no page-number buttons. Use the full form for primary admin list pages.\",\n \"DO use `showTotal` to surface item counts: pass `true` for the built-in i18n label, or a function `(total, [from, to]) => ReactNode` for a custom range label like '1–10 of 342 invoices'. Never hard-code a total string beside the component.\",\n \"DON'T use Pagination for cursor- or infinite-scroll-based lists. Pagination is strictly offset/page-based (`value` is a page number). For cursor pagination inside a DataTable use `DataTable.Pagination`; for infinite scroll use `InfiniteQueryState`.\",\n ],\n useCases: [\n \"Standalone offset-paginated admin list pages (e.g. invoice list, customer list, transaction history) rendered outside DataTable — place Pagination below the table card, outside the card border, with `showTotal` and optionally `showSizeChanger`.\",\n \"Search results pages where the backend accepts `page` + `per_page` query parameters and returns a total count — wire `value` and `pageSize` to URL search params so the URL is shareable and browser-back works.\",\n \"Reports and filtered data grids where the user needs to export 'all selected pages': `showTotal` with a custom function lets you show '1–50 of 1 200 rows' so the user understands the scope before exporting.\",\n \"Compact modal or sheet footers with a long list (e.g. selecting from a product catalog inside a dialog) — use `simple` mode to save horizontal space while keeping navigation accessible.\",\n \"DataTable instances where the server returns an offset-based total and `DataTable.Pagination` is not being used: attach a standalone Pagination below the card and pass the same `page` / `pageSize` state to both the DataTable `data` prop and the API fetch.\",\n ],\n related: [\n \"DataTable.Pagination — use instead of standalone Pagination when the list is rendered inside a DataTable compound and uses cursor-based navigation (cursor + hasMore + onChange). DataTable.Pagination handles First/Next without page arithmetic; standalone Pagination requires a known total.\",\n \"InfiniteQueryState — use for infinite-scroll / load-more lists driven by useInfiniteQuery. It auto-manages skeleton, empty, and error states; Pagination is inappropriate here because there is no discrete page number.\",\n \"DataTable — when offset pagination is needed inside DataTable, prefer composing DataTable with a standalone Pagination below the card rather than DataTable.Pagination if the API is offset-based and returns a total count. DataTable itself does not paginate; you supply `data` for the current page.\",\n \"SearchInput — often placed in the same toolbar as Pagination. Resetting `value` to page 1 inside the search `onSearchChange` handler is mandatory; forgetting this is the most common bug when combining search and Pagination.\",\n ],\n example: `import { Pagination } from \"@godxjp/ui/navigation\";\n\n<Pagination value={page} total={filtered.length} pageSize={10} showTotal onValueChange={(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 usage: [\n \"DO compose the full sub-part tree: DropdownMenu (root) → DropdownMenuTrigger (with asChild to delegate to your Button/icon) → DropdownMenuContent → DropdownMenuItem / DropdownMenuSeparator / DropdownMenuLabel / DropdownMenuGroup. Omitting any level (e.g. rendering DropdownMenuContent without DropdownMenu as ancestor) breaks Radix context and the menu will not open.\",\n \"DO use DropdownMenuTrigger with asChild and pass a godx-ui Button or icon Button as the child — never render a raw <button> or <div> as the trigger, and never omit asChild when the child is already a button-like element (double-button nesting breaks a11y).\",\n \"DO use variant='destructive' on DropdownMenuItem for irreversible actions (delete, revoke, void) — this applies the semantic destructive colour token automatically without any className override.\",\n \"DO use DropdownMenuSub + DropdownMenuSubTrigger + DropdownMenuSubContent for nested sub-menus (e.g. 'Export' → 'CSV', 'PDF'). The ChevronRight icon is rendered automatically by DropdownMenuSubTrigger — do not add your own.\",\n \"DO use DropdownMenuCheckboxItem (with checked + onCheckedChange) or DropdownMenuRadioGroup + DropdownMenuRadioItem for toggle/selection menus such as column visibility or active view. These items manage their own checked indicator — do not layer a Checkbox or RadioGroup inside a plain DropdownMenuItem.\",\n \"DON'T use DropdownMenu for form submission — items fire onSelect callbacks, not form field values. There is no name prop for native form submission. If a menu selection must feed a form field, lift state into a controlled value and wire a hidden Input or use Select instead.\",\n ],\n useCases: [\n \"Row action menu in a DataTable: a '...' icon Button opens a DropdownMenu with Edit, Duplicate, DropdownMenuSeparator, then Delete (variant='destructive') — keeps the row compact and avoids inline button clutter.\",\n \"Topbar / avatar chip: a user-avatar Button triggers a DropdownMenu with Profile, Settings, DropdownMenuSeparator, Sign out — standard app-shell pattern for account actions.\",\n \"Bulk-action toolbar: after selecting rows, an 'Actions' Button opens a DropdownMenu with Approve, Reject, Export — prevents the toolbar from overflowing with individual buttons.\",\n \"Column visibility toggle in a report table: a 'Columns' Button opens a DropdownMenu whose items are DropdownMenuCheckboxItem entries, letting users show/hide columns without a Dialog.\",\n \"Quick status change on an accounting entry: a Badge-like trigger opens a DropdownMenu with DropdownMenuRadioGroup items (Draft, Posted, Voided) so the user can transition status without navigating away.\",\n \"Context menu for a sidebar nav item: right-click or kebab on a project entry opens a DropdownMenu with Rename, Duplicate, Archive actions scoped to that item.\",\n ],\n related: [\n \"Popover — use Popover when the floating panel needs arbitrary layout (filter forms, date pickers, rich content grids). Use DropdownMenu only for a list of discrete clickable actions or toggle items; DropdownMenu has no layout flexibility beyond label/separator/group.\",\n \"Command — use Command (cmdk) when the list is large, needs fuzzy-search filtering, or acts as a keyboard-driven command palette. DropdownMenu has no built-in search input; once the list exceeds ~8 items or needs filtering, switch to Command (often inside a Popover).\",\n \"Select — use Select when the purpose is choosing a value to submit in a form field (has a name prop for native form submission, renders a hidden select for a11y). Use DropdownMenu when the purpose is triggering actions, not picking a form value.\",\n \"Sidebar — use Sidebar for persistent left-rail navigation. DropdownMenu is transient (opens on click, dismisses on select); Sidebar is always-visible structural navigation.\",\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 tone=\"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: \"value\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Active step index (0-based).\",\n },\n {\n name: \"defaultValue\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Base offset for the first rendered step index.\",\n },\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Layout direction.\",\n },\n ],\n usage: [\n \"DO: Pass all steps via the `items` array (each `{ title, subtitle?, description?, icon?, status?, disabled? }`) — Steps is a single-component API with no child sub-components to compose manually.\",\n \"DO: Control the active step with `value` (0-based index). For async operations, set the top-level `status` prop (`'process'|'error'|'finish'`) to override the current step's icon — e.g. `status='error'` turns the active step red without touching `items`.\",\n \"DO: Use per-item `status` to pin individual steps independently of `value` (e.g. a skipped or already-errored step). Per-item `status` takes precedence over the derived status from `value`.\",\n \"DON'T: Use Steps for navigation that needs URL routing or tab-switching — it has no built-in panel rendering. Pair it with your own conditional panel or a `Tabs`/`Tabs` body; Steps only renders the indicator bar.\",\n \"DON'T: Wire `onValueChange` unless you actually support non-linear navigation. `onValueChange` makes every non-disabled step clickable (rendered as `<button>`); omitting it makes all steps non-interactive (`cursor-default`). Never set `disabled` on an item without also providing `onValueChange`, or the prop is meaningless.\",\n \"A11y: The `<ol>` is given `aria-label='Progress'` automatically. Individual steps render as `<button type='button'>` when `onValueChange` is present — ensure each `item.title` is descriptive enough to serve as the button label; avoid icon-only steps without a visible title.\",\n ],\n useCases: [\n \"Multi-step form wizard (entity onboarding, invoice creation): render Steps above a form, drive `current` from local state, advance on validated submit — use `status='error'` on the current step when server validation fails.\",\n \"Async background job tracker: display steps for a long-running import/export pipeline; poll job status and map job phases to `StepStatusProp` values (`'process'` with spinner for in-flight, `'finish'` for done, `'error'` for failed).\",\n \"Document approval workflow (accounting, contracts): map approval stages (Draft → Review → Approved → Archived) to `items` with per-item `status` reflecting the real state from the server — use `orientation='vertical'` for a sidebar timeline feel.\",\n \"Onboarding checklist sidebar: `orientation='vertical'` + `type='dot'` + `size='sm'` for a compact sidebar progress guide alongside a multi-section settings page.\",\n \"Non-linear step navigation (e.g. revisit a previous step to correct data): provide `onValueChange` and leave only future steps `disabled`; past and current steps become clickable buttons.\",\n ],\n related: [\n \"Timeline — use Timeline (from @godxjp/ui) when you need a chronological event log with timestamps and variable content per entry; use Steps when the number of stages is fixed and forward-progress is the semantic.\",\n \"Tabs / Tabs — use Tabs when each section has its own rendered panel and users switch freely between them; use Steps when stages are ordered and the indicator communicates completion state rather than just selection.\",\n \"Progress — use Progress for a single continuous percentage (file upload, quota fill); use Steps for discrete named stages with individual pass/fail status.\",\n \"Breadcrumb — use Breadcrumb for hierarchical location within a page tree; use Steps for sequential workflow progress where order and completion matter.\",\n ],\n example: `import { Steps } from \"@godxjp/ui/navigation\";\n\n<Steps value={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 usage: [\n \"DO mount AppProvider ONCE at the application root (e.g. in app.tsx or the Inertia layout), wrapping ALL children — every godx-ui picker (LocalePicker, TimezonePicker, DateFormatPicker, TimeFormatPicker), every formatDate call, and the Toaster all rely on the single context it provides. Nesting two AppProviders creates split contexts; inner pickers silently read the wrong one.\",\n \"DO NOT omit AppProvider and then try to use LocalePicker, TimezonePicker, or formatDate standalone — useAppContext() throws 'useAppContext must be used within <AppProvider>' at runtime. The only exception is using those pickers in fully controlled mode (value + onChange) which reads useOptionalAppContext() and returns null safely.\",\n \"DO use the `persist={false}` prop on AppProvider when writing isolated tests or standalone settings forms where localStorage should not be read or written. With the default `persist={true}` the provider reads from localStorage key `godxjp.app` on mount (after first render), so initial state may differ between SSR and client.\",\n \"DO set `defaultTimezone='system'` together with `systemTimezone={serverTimezone}` when your backend knows the legal entity's canonical timezone (e.g. 'Asia/Ho_Chi_Minh'). Use `defaultTimezone='browser'` (the default) only when you want the user's browser clock. Do NOT pass a raw IANA string to `defaultTimezone` if the user may be in a different zone — use the named aliases.\",\n \"DO wire `onLocaleChange`, `onTimezoneChange`, `onTimeFormatChange`, `onDateFormatChange` to persist changes server-side (e.g. patch user profile via Inertia router) in addition to the automatic localStorage write. These callbacks fire after state is set, so the new value is already reflected in context.\",\n \"DO restrict the timezone dropdown by passing `timezoneOptions={APP_TIMEZONE_PRESET}` (an exported constant) to AppProvider — all TimezonePicker instances that omit their own `options` prop will inherit this restricted list automatically from context. Without it, TimezonePicker renders the full IANA list (~600 entries).\",\n ],\n useCases: [\n \"App bootstrap in a multi-locale SaaS admin (ja/en/vi) — mount AppProvider at the root with the tenant's preferred locale and IANA timezone so every DataTable date column, every formatDate call, and every picker renders consistently in the user's locale without any per-component configuration.\",\n \"User settings page — render LocalePicker, TimezonePicker, DateFormatPicker, and TimeFormatPicker as zero-prop children inside the existing AppProvider; each picker reads and writes context automatically. Wire `onLocaleChange` to an Inertia form submit to persist the change to the server profile.\",\n \"Server-rendered Inertia app with SSR hydration — pass `defaultTimezone='system'` and `systemTimezone={sharedProps.timezone}` (injected via HandleInertiaRequests) so the initial render is timezone-deterministic and avoids hydration mismatches caused by browser-timezone detection.\",\n \"Multi-entity accounting dashboard — use `timezoneOptions` to restrict the picker to the legal entity's permissible zones (e.g. Southeast Asian IANA ids only), preventing users from accidentally switching to an out-of-scope timezone that would misrepresent transaction timestamps.\",\n \"Isolated preview / Storybook story — wrap a single component in `<AppProvider persist={false} defaultLocale='en'>` to give it a stable context without polluting localStorage between stories.\",\n \"Test harness — wrap the component under test in `<AppProvider persist={false} defaultLocale='ja' defaultDateFormat='iso'>` to assert locale-sensitive formatting output deterministically, independent of whatever the browser or stored preferences report.\",\n ],\n related: [\n \"LocalePicker — the language-selector control that reads/writes AppProvider locale context automatically when used as a zero-prop child. Prefer LocalePicker over calling setLocale from useAppContext() directly in UI.\",\n \"TimezonePicker — the timezone-selector control; inherits `timezoneOptions` from AppProvider context when its own `options` prop is omitted. Both pickers require AppProvider to be in the tree unless controlled props are passed.\",\n \"formatDate — the MANDATORY date/time formatter that reads locale, timezone, timeFormat, and dateFormat from AppProvider context. Do NOT call date-fns or Intl.DateTimeFormat directly; formatDate is the single source of truth for display.\",\n \"AppShell — the top-level application shell that composes AppProvider, AppShell, Sidebar, and Topbar into a single ready-to-use layout. If your project uses AppShell, AppProvider is already mounted inside it — do not add a second one.\",\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 usage: [\n \"DO import from `@godxjp/ui/datetime` — NOT from `date-fns` or any other datetime utility. `formatDate` is the single mandatory display entry point; calling `date-fns/format` directly bypasses AppProvider locale/timezone/dateFormat/timeFormat context and produces inconsistent output across the app.\",\n \"DO ensure `AppProvider` is mounted at the app root before the first `formatDate` call. The function reads a module-level context synced by `AppProvider` via `syncDatetimeContext`. Without it the fallback locale is `'vi'` / timezone `'Asia/Ho_Chi_Minh'` / `'24h'`, which will silently produce wrong output in Japanese or English apps.\",\n \"DO pass `null` or `undefined` safely — `formatDate` returns an em-dash `'—'` for null/undefined/empty string values. Never guard with a ternary before calling it.\",\n \"DO use `options.kind` when auto-detection is wrong: pass `kind: 'date'` for an ISO datetime string you want displayed as date-only, `kind: 'relative'` for age display (e.g. `'3日前'`), `kind: 'long'` for full PPP format in modals/detail panels. Auto-detection maps plain `yyyy-MM-dd` → `'date'`, `HH:mm` → `'time'`, everything else → `'datetime'`.\",\n \"DO pass `{ calendar: true }` when the `Date` object came from a react-day-picker calendar pick — this prevents timezone shift that would occur if the Date were treated as a UTC instant.\",\n \"DON'T hand-roll per-call locale/timezone resolution with `Intl.DateTimeFormat` or raw `date-fns/format`. The `options.locale` / `options.timezone` overrides exist for one-off per-cell display differences (e.g. showing a partner's local time), not as a substitute for AppProvider context.\",\n ],\n useCases: [\n \"Rendering all date/time columns in a DataTable — invoice due dates (`kind: 'date'`), transaction timestamps (`kind: 'datetime'`), and elapsed time since last sync (`kind: 'relative'`) all go through `formatDate` so the locale/timezone/12h-24h setting from AppProvider is respected everywhere.\",\n \"Displaying a single date/time field in a Descriptions or Card detail panel, e.g. `formatDate(invoice.issuedAt)` for the issued-at row — no extra formatting logic needed, null is handled as `'—'` automatically.\",\n \"Formatting a stored `HH:mm` string (24h canonical storage) for display according to the user's timeFormat preference — pass the raw `'14:30'` string and auto-detection routes it through `formatTimeOfDay`, outputting `'2:30 PM'` or `'14:30'` based on context.\",\n \"Rendering a 'last modified' timestamp with relative wording in an activity feed or audit log row — `formatDate(entry.updatedAt, { kind: 'relative' })` produces locale-correct relative strings like `'3日前'` / `'3 days ago'`.\",\n \"Converting a `Date` selected from `DatePicker` (react-day-picker) back to a display string — pass `{ calendar: true }` to avoid the UTC midnight shift that the default instant path would apply.\",\n ],\n related: [\n \"AppProvider — required peer that seeds locale, timezone, dateFormat, and timeFormat into the module-level context that `formatDate` reads. Must be mounted once at app root; omitting it means `formatDate` silently falls back to Vietnamese/Ho Chi Minh City defaults.\",\n \"DatePicker — the corresponding input control for calendar dates. Use `DatePicker` to capture a date from the user; use `formatDate(value, { calendar: true })` to display the picked `Date` object back as a string.\",\n \"DateFormatPicker / TimeFormatPicker / TimezonePicker — preference pickers that update AppProvider context; their selections are automatically picked up by subsequent `formatDate` calls with no extra wiring needed.\",\n \"TimePicker — the corresponding input control for HH:mm time values. Use `TimePicker` to capture time; use `formatDate(hhmm)` (auto-detects `'time'` kind) to display the stored `HH:mm` string respecting the user's 12h/24h preference.\",\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 onValueChange={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 onValueChange={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: \"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 content: [\n {\n value: \"tokyo\",\n label: \"東京都\",\n content: [\n { value: \"shinjuku\", label: \"新宿区\" },\n { value: \"shibuya\", label: \"渋谷区\" },\n ],\n },\n ],\n },\n {\n value: \"vn\",\n label: \"Việt Nam\",\n content: [\n {\n value: \"hcm\",\n label: \"TP. Hồ Chí Minh\",\n content: [\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 onValueChange={(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 onValueChange={(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\", content: \"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 onValueChange={(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', content: '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 content: [\n { value: \"current-assets\", label: \"Current Assets\", content: [\n { value: \"cash\", label: \"Cash\" },\n { value: \"ar\", label: \"Accounts Receivable\" },\n ],\n },\n { value: \"fixed-assets\", label: \"Fixed Assets\", content: [\n { value: \"equipment\", label: \"Equipment\" },\n ],\n },\n ],\n },\n {\n value: \"liabilities\",\n label: \"Liabilities\",\n content: [\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 onValueChange={(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 onValueChange={(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[]>([]); onValueChange={(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 { value: \"1010\", title: \"Cash\", description: \"Asset\" },\n { value: \"1020\", title: \"Accounts Receivable\", description: \"Asset\" },\n { value: \"2010\", title: \"Accounts Payable\", description: \"Liability\" },\n { value: \"3010\", title: \"Revenue\", description: \"Income\" },\n { value: \"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 onValueChange={(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 onValueChange={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 onValueChange={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/upload\"; // internal — prefer Upload variant=\"avatar-crop\" instead\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/*\" onValueChange={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} onValueChange={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 onValueChange={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} onValueChange={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 \"Progress — use Progress (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: \"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 Field 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 Field (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 Field — 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 / Field — 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 onValueChange={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 Field 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 (+ Field 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 Field 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 Field for custom markup. Every option must be wrapped in Field (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 / Field — 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 Field 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: \"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 \"Descriptions — use Descriptions 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: \"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 \"ButtonRefetch — 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: \"Avatar\",\n group: \"data-display\",\n tagline: \"Radix Avatar wrapper with image and fallback slots for users, teams, and entities.\",\n props: [\n {\n name: \"children\",\n type: \"ReactNode\",\n description: \"Compose AvatarImage and AvatarFallback.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra classes on the avatar root.\" },\n ],\n usage: [\n \"DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.\",\n \"DON'T use Avatar for decorative thumbnails; use CardCover or an img when the image is content rather than identity.\",\n ],\n useCases: [\"User profile chips\", \"Team member lists\", \"Account owner cells in a DataTable\"],\n related: [\"Badge — use beside Avatar for role/status metadata.\"],\n example: `import { Avatar, AvatarFallback, AvatarImage } from \"@godxjp/ui/data-display\";\n\n<Avatar>\n <AvatarImage src=\"/user.png\" alt=\"User\" />\n <AvatarFallback>UI</AvatarFallback>\n</Avatar>`,\n storyPath: \"data-display/Avatar.stories.tsx\",\n rules: [3, 35],\n },\n {\n name: \"Separator\",\n group: \"layout\",\n tagline: \"Radix Separator wrapper for tokenized horizontal or vertical dividers.\",\n props: [\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Divider direction.\",\n },\n {\n name: \"decorative\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Whether the separator is decorative for assistive tech.\",\n },\n ],\n usage: [\n \"DO use Separator for section dividers instead of raw border divs.\",\n \"DO set orientation='vertical' only when the parent gives it a stable height.\",\n ],\n useCases: [\n \"Separating toolbar groups\",\n \"Dividing stacked page sections\",\n \"Vertical split between metadata groups\",\n ],\n related: [\"Flex direction='col' — use for vertical spacing without a visible rule.\"],\n example: `import { Separator } from \"@godxjp/ui/layout\";\n\n<Separator />`,\n storyPath: \"layout/Separator.stories.tsx\",\n rules: [2, 3],\n },\n {\n name: \"Skeleton\",\n group: \"feedback\",\n tagline: \"Base pulsing skeleton block for custom loading placeholders.\",\n props: [\n { name: \"className\", type: \"string\", description: \"Size and layout classes for the block.\" },\n ],\n usage: [\n \"DO use Skeleton for a custom block when SkeletonRows/Table/Card do not match the final layout.\",\n \"DON'T use a spinner overlay for skeletonable page content.\",\n ],\n useCases: [\n \"Single loading line\",\n \"Custom card media placeholder\",\n \"Inline metadata placeholder\",\n ],\n related: [\"SkeletonRows\", \"SkeletonTable\", \"SkeletonStat\"],\n example: `import { Skeleton } from \"@godxjp/ui/feedback\";\n\n<Skeleton className=\"h-6 w-48\" />`,\n storyPath: \"feedback/Skeleton.stories.tsx\",\n rules: [3, 31],\n },\n {\n name: \"Toggle\",\n group: \"data-entry\",\n tagline: \"Radix Toggle wrapper with default/outline variants and tokenized sizes.\",\n props: [\n { name: \"pressed\", type: \"boolean\", description: \"Controlled pressed state.\" },\n {\n name: \"onPressedChange\",\n type: \"(pressed: boolean) => void\",\n description: \"Pressed-state callback.\",\n },\n {\n name: \"variant\",\n type: '\"default\" | \"outline\"',\n defaultValue: '\"default\"',\n description: \"Visual style.\",\n },\n {\n name: \"size\",\n type: '\"sm\" | \"md\" | \"lg\"',\n defaultValue: '\"md\"',\n description: \"Control size.\",\n },\n ],\n usage: [\n \"DO provide an accessible label when the toggle only contains an icon.\",\n \"DON'T use Toggle for multi-option selection; use ToggleGroup.\",\n ],\n useCases: [\"Bold/italic toolbar buttons\", \"Pinned filter toggles\", \"Compact view mode buttons\"],\n related: [\"ToggleGroup\", \"Button\"],\n example: `import { Toggle } from \"@godxjp/ui/data-entry\";\n\n<Toggle aria-label=\"Bold\">B</Toggle>`,\n storyPath: \"data-entry/Toggle.stories.tsx\",\n rules: [3, 13],\n },\n {\n name: \"ToggleGroup\",\n group: \"data-entry\",\n tagline: \"Radix ToggleGroup wrapper for single or multiple toggle selection.\",\n props: [\n {\n name: \"type\",\n type: '\"single\" | \"multiple\"',\n required: true,\n description: \"Selection mode.\",\n },\n { name: \"value\", type: \"string | string[]\", description: \"Controlled selected value(s).\" },\n {\n name: \"onValueChange\",\n type: \"(value: string | string[]) => void\",\n description: \"Selection callback.\",\n },\n ],\n usage: [\n \"DO choose type='single' for mutually exclusive toolbar modes.\",\n \"DO choose type='multiple' for independent formatting toggles.\",\n ],\n useCases: [\"Text alignment selector\", \"Formatting toolbar\", \"View density switcher\"],\n related: [\"Toggle\", \"RadioGroup\"],\n example: `import { ToggleGroup, ToggleGroupItem } from \"@godxjp/ui/data-entry\";\n\n<ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"left\">Left</ToggleGroupItem>\n</ToggleGroup>`,\n storyPath: \"data-entry/ToggleGroup.stories.tsx\",\n rules: [3, 13],\n },\n {\n name: \"AspectRatio\",\n group: \"layout\",\n tagline: \"Radix AspectRatio wrapper for stable media and preview frames.\",\n props: [\n {\n name: \"ratio\",\n type: \"number\",\n defaultValue: \"16 / 9\",\n description: \"Width divided by height.\",\n },\n { name: \"children\", type: \"ReactNode\", description: \"Content constrained to the ratio.\" },\n ],\n usage: [\n \"DO use AspectRatio for media, maps, charts, or previews that must not jump during load.\",\n \"DON'T use it for unconstrained text content.\",\n ],\n useCases: [\"Video embed frame\", \"Image preview slot\", \"Dashboard chart placeholder\"],\n related: [\"CardCover\", \"Skeleton\"],\n example: `import { AspectRatio } from \"@godxjp/ui/layout\";\n\n<AspectRatio ratio={16 / 9}>...</AspectRatio>`,\n storyPath: \"layout/AspectRatio.stories.tsx\",\n rules: [2, 3],\n },\n {\n name: \"Accordion\",\n group: \"data-display\",\n tagline:\n \"Radix accordion — vertically stacked, collapsible sections. Compose Accordion > AccordionItem > AccordionTrigger + AccordionContent.\",\n props: [\n {\n name: \"type\",\n type: '\"single\" | \"multiple\"',\n required: true,\n description: \"single = one open at a time; multiple = independent.\",\n },\n {\n name: \"collapsible\",\n type: \"boolean\",\n description: \"When type=single, allow closing the open item.\",\n },\n { name: \"value\", type: \"string | string[]\", description: \"Controlled open item(s).\" },\n {\n name: \"defaultValue\",\n type: \"string | string[]\",\n description: \"Uncontrolled initial open item(s).\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string | string[]) => void\",\n description: \"Open-state callback.\",\n },\n ],\n usage: [\n 'DO compose the full set: <Accordion type=\"single\" collapsible><AccordionItem value=\"a\"><AccordionTrigger/><AccordionContent/></AccordionItem></Accordion>.',\n \"DO give each AccordionItem a unique `value`.\",\n \"DON'T use it for primary navigation — that's Sidebar/Tabs. Accordion is for collapsible content/FAQ.\",\n ],\n useCases: [\n \"FAQ lists\",\n \"Grouped settings sections\",\n \"Collapsible detail panels on a record page\",\n \"Filter facet groups in a sidebar\",\n ],\n related: [\n \"Collapsible (single open/close region, no item set)\",\n \"Tabs (mutually-exclusive views, always one visible)\",\n ],\n example: `import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from \"@godxjp/ui/data-display\";\n\n<Accordion type=\"single\" collapsible>\n <AccordionItem value=\"ship\">\n <AccordionTrigger>配送について</AccordionTrigger>\n <AccordionContent>3〜5営業日でお届けします。</AccordionContent>\n </AccordionItem>\n</Accordion>`,\n storyPath: \"data-display/Accordion.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"HoverCard\",\n group: \"data-display\",\n tagline:\n \"Radix hover card — a rich popover shown on hover/focus of a trigger (for sighted-pointer affordances; not a replacement for Tooltip's short text).\",\n props: [\n {\n name: \"openDelay\",\n type: \"number\",\n defaultValue: \"700\",\n description: \"ms before opening on hover.\",\n },\n {\n name: \"closeDelay\",\n type: \"number\",\n defaultValue: \"300\",\n description: \"ms before closing.\",\n },\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state callback.\",\n },\n ],\n usage: [\n \"DO compose HoverCard > HoverCardTrigger > HoverCardContent.\",\n \"DO use for RICH preview content (a card, avatar + bio); for short plain-text hints use Tooltip.\",\n \"DON'T rely on it for essential info — hover isn't available on touch; provide the same content on click/tap elsewhere.\",\n ],\n useCases: [\n \"User/profile preview on @mention hover\",\n \"Entity preview (customer/account) on a table cell\",\n \"Glossary term definitions\",\n \"Commit/PR preview links\",\n ],\n related: [\n \"Tooltip (short text label, not rich content)\",\n \"Popover (click-triggered, interactive content)\",\n ],\n example: `import { HoverCard, HoverCardTrigger, HoverCardContent } from \"@godxjp/ui/data-display\";\n\n<HoverCard>\n <HoverCardTrigger>@yamada</HoverCardTrigger>\n <HoverCardContent>山田太郎 — 経理部</HoverCardContent>\n</HoverCard>`,\n storyPath: \"data-display/HoverCard.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"PasswordInput\",\n group: \"data-entry\",\n tagline:\n \"Input for passwords with a built-in show/hide eye toggle. Accepts all Input props except `type`.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n description: \"Controlled value (or use defaultValue/uncontrolled).\",\n },\n { name: \"name\", type: \"string\", description: \"Form field name for native submission.\" },\n { name: \"placeholder\", type: \"string\", description: \"Placeholder text.\" },\n { name: \"disabled\", type: \"boolean\", description: \"Disables the field + toggle.\" },\n ],\n usage: [\n 'DO use for any password / secret field instead of `<Input type=\"password\">` so users get the show/hide affordance.',\n 'DO pass `name` + `autoComplete=\"current-password\"|\"new-password\"` for correct form/password-manager behavior.',\n \"DON'T add your own eye button — it's built in (and excluded from the tab order).\",\n ],\n useCases: [\n \"Login password field\",\n \"Sign-up / change-password forms (new-password)\",\n \"API key / secret entry in settings\",\n ],\n related: [\n \"Input (the base text field this wraps)\",\n \"FormField (label + error wrapper around it)\",\n ],\n example: `import { PasswordInput } from \"@godxjp/ui/data-entry\";\n\n<PasswordInput name=\"password\" autoComplete=\"current-password\" placeholder=\"パスワード\" />`,\n storyPath: \"data-entry/PasswordInput.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"PasswordStrength\",\n group: \"data-entry\",\n tagline:\n \"Evaluates password quality with a 0-4 score and optional rule checklist. Use with PasswordInput in secure forms.\",\n props: [\n {\n name: \"value\",\n type: \"string\",\n required: true,\n description: \"The current password value to evaluate.\",\n },\n {\n name: \"rules\",\n type: \"PasswordRule[]\",\n description: \"`length` | `upper` | `lower` | `number` | `symbol`. Omit to use defaults.\",\n },\n {\n name: \"showChecklist\",\n type: \"boolean\",\n defaultValue: \"true\",\n description: \"Render an optional checklist of rule checks below the bar.\",\n },\n {\n name: \"labels\",\n type: \"{ weak: string; fair: string; strong: string }\",\n description: \"Text labels for the three score buckets.\",\n },\n ],\n usage: [\n \"DO show PasswordStrength immediately below PasswordInput so users understand password quality before submitting.\",\n \"DO keep `rules` stable (default list is recommended for broad UI compatibility).\",\n \"DON'T treat the score as cryptographic strength; use it as a UI hint only.\",\n ],\n useCases: [\n \"Account signup password field\",\n \"Password reset workflow\",\n \"Admin user invite form\",\n ],\n related: [\"PasswordInput\", \"FormField\", \"Input\"],\n example: `import { PasswordInput, PasswordStrength } from \"@godxjp/ui/data-entry\";\n\nconst rules = [\"length\", \"upper\", \"lower\", \"number\", \"symbol\"] as const;\n\nexport default function PasswordBlock() {\n const [value, setValue] = useState(\"\");\n return (\n <div className=\"ui-stack\">\n <PasswordInput value={value} onChange={(event) => setValue(event.target.value)} />\n <PasswordStrength value={value} rules={rules} />\n </div>\n );\n}`,\n storyPath: \"data-entry/PasswordStrength.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"InputOTP\",\n group: \"data-entry\",\n tagline:\n \"One-time-code / 2FA input (input-otp) — N single-character slots that behave as one field. Compose InputOTP > InputOTPGroup > InputOTPSlot.\",\n props: [\n {\n name: \"maxLength\",\n type: \"number\",\n required: true,\n description: \"Number of slots (e.g. 6).\",\n },\n { name: \"value\", type: \"string\", description: \"Controlled value.\" },\n {\n name: \"onChange\",\n type: \"(value: string) => void\",\n description:\n \"Value callback (this is a true text input — onChange is the DOM-style value handler here).\",\n },\n { name: \"pattern\", type: \"string\", description: \"Allowed-char regex (e.g. digits only).\" },\n ],\n usage: [\n \"DO set `maxLength` to the code length and render that many InputOTPSlot with sequential `index`.\",\n \"DO wrap slots in InputOTPGroup; use InputOTPSeparator between groups (e.g. 3 + 3).\",\n \"DON'T build N separate Inputs — this is ONE field with paste, arrow-key, and caret handling built in.\",\n ],\n useCases: [\n \"2FA / OTP verification code\",\n \"Email / SMS confirmation code\",\n \"PIN entry\",\n \"Invite / redemption code\",\n ],\n related: [\"Input (a normal single text field)\", \"PasswordInput (masked secret field)\"],\n example: `import { InputOTP, InputOTPGroup, InputOTPSlot } from \"@godxjp/ui/data-entry\";\n\n<InputOTP maxLength={6}>\n <InputOTPGroup>\n <InputOTPSlot index={0} /><InputOTPSlot index={1} /><InputOTPSlot index={2} />\n <InputOTPSlot index={3} /><InputOTPSlot index={4} /><InputOTPSlot index={5} />\n </InputOTPGroup>\n</InputOTP>`,\n storyPath: \"data-entry/InputOTP.stories.tsx\",\n rules: [3, 6],\n },\n {\n name: \"Rating\",\n group: \"data-entry\",\n tagline:\n \"Star-rating input (radiogroup) — controlled via value/onValueChange, form-submittable via name, supports readOnly display.\",\n props: [\n { name: \"value\", type: \"number\", description: \"Controlled rating (1..max).\" },\n {\n name: \"defaultValue\",\n type: \"number\",\n defaultValue: \"0\",\n description: \"Uncontrolled initial rating.\",\n },\n { name: \"onValueChange\", type: \"(value: number) => void\", description: \"Rating callback.\" },\n { name: \"max\", type: \"number\", defaultValue: \"5\", description: \"Number of stars.\" },\n { name: \"readOnly\", type: \"boolean\", description: \"Display-only (e.g. an average score).\" },\n {\n name: \"name\",\n type: \"string\",\n description: \"Hidden input name for native form submission.\",\n },\n ],\n usage: [\n \"DO use readOnly to DISPLAY a score (e.g. product average); interactive (default) for collecting a rating.\",\n \"DO pass `name` to submit the value in a plain form.\",\n \"DON'T render raw star icons for input — this handles keyboard (radiogroup), hover preview, and a11y.\",\n ],\n useCases: [\n \"Product / vendor review input\",\n \"Display an average score (readOnly)\",\n \"Feedback / CSAT survey\",\n \"Priority or quality scoring in admin\",\n ],\n related: [\"RadioGroup (non-star single choice)\", \"Slider (continuous 0-100 value)\"],\n example: `import { Rating } from \"@godxjp/ui/data-entry\";\n\n<Rating name=\"score\" defaultValue={4} onValueChange={(v) => console.log(v)} />`,\n storyPath: \"data-entry/Rating.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"TagInput\",\n group: \"data-entry\",\n tagline:\n \"Chips/tags input — type + Enter (or comma) to add a tag, Backspace to remove the last; controlled via value/onValueChange (string[]).\",\n props: [\n { name: \"value\", type: \"string[]\", description: \"Controlled tag list.\" },\n { name: \"defaultValue\", type: \"string[]\", description: \"Uncontrolled initial tags.\" },\n {\n name: \"onValueChange\",\n type: \"(tags: string[]) => void\",\n description: \"Tag-list callback.\",\n },\n { name: \"placeholder\", type: \"string\", description: \"Shown when empty.\" },\n {\n name: \"name\",\n type: \"string\",\n description: \"Hidden input (comma-joined) for native form submission.\",\n },\n ],\n usage: [\n \"DO use for free-form multi-value entry (labels, emails, keywords) where options aren't a fixed list.\",\n \"DO note dedupe is built in; Enter/comma commits, Backspace on empty removes the last chip.\",\n \"DON'T use for choosing from a KNOWN set — use Select (multiple) or a multi-Combobox instead.\",\n ],\n useCases: [\n \"Labels / tags on a record\",\n \"Recipient email entry\",\n \"Keyword / skill lists\",\n \"Ad-hoc filter terms\",\n ],\n related: [\n \"Select (multiple) — when the values come from a fixed option set\",\n \"Combobox (multi) — searchable known set\",\n ],\n example: `import { TagInput } from \"@godxjp/ui/data-entry\";\n\n<TagInput name=\"labels\" placeholder=\"ラベルを追加…\" onValueChange={(tags) => setTags(tags)} />`,\n storyPath: \"data-entry/TagInput.stories.tsx\",\n rules: [3, 6, 23],\n },\n {\n name: \"ContextMenu\",\n group: \"navigation\",\n tagline:\n \"Context menu primitives with keyboard support and compound parts for command-style action surfaces.\",\n props: [\n { name: \"open\", type: \"boolean\", description: \"Controlled open state.\" },\n {\n name: \"onOpenChange\",\n type: \"(open: boolean) => void\",\n description: \"Open-state callback.\",\n },\n { name: \"value\", type: \"string\", description: \"Selected value (for controlled patterns).\" },\n ],\n useCases: [\n \"Right-click action menu\",\n \"Contextual menus for rows and cards\",\n \"Nested action rows with shortcuts\",\n ],\n storyPath: \"navigation/ContextMenu.stories.tsx\",\n rules: [3, 6],\n example: `import {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n} from \"@godxjp/ui/navigation\";\n\n<ContextMenu>\n <ContextMenuTrigger>open</ContextMenuTrigger>\n <ContextMenuContent>\n <ContextMenuItem>Edit</ContextMenuItem>\n <ContextMenuItem>Delete</ContextMenuItem>\n </ContextMenuContent>\n</ContextMenu>`,\n },\n {\n name: \"Menubar\",\n group: \"navigation\",\n tagline: \"Application menubar primitives (menus, sub-menus, and check/radio items).\",\n props: [\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial selected value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Selection callback.\",\n },\n ],\n useCases: [\n \"Top-bar application command menus\",\n \"Workspace menus with nested items\",\n \"Desktop-like navigation shells\",\n ],\n storyPath: \"navigation/Menubar.stories.tsx\",\n rules: [3, 6],\n example: `import { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem } from \"@godxjp/ui/navigation\";\n\n<Menubar>\n <MenubarMenu>\n <MenubarTrigger>ファイル</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>新規作成</MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n</Menubar>`,\n },\n {\n name: \"NavigationMenu\",\n group: \"navigation\",\n tagline:\n \"Horizontal navigation menu with trigger/content/link primitives and viewport support.\",\n props: [\n {\n name: \"orientation\",\n type: '\"horizontal\" | \"vertical\"',\n defaultValue: '\"horizontal\"',\n description: \"Main-axis arrangement for the nav menu.\",\n },\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial selected value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Selection callback.\",\n },\n ],\n useCases: [\"Primary app navigation\", \"Sectioned marketing navigation\", \"Nested link groups\"],\n storyPath: \"navigation/NavigationMenu.stories.tsx\",\n rules: [3, 6],\n example: `import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger } from \"@godxjp/ui/navigation\";\n\n<NavigationMenu>\n <NavigationMenuList>\n <NavigationMenuItem>\n <NavigationMenuTrigger>ページ</NavigationMenuTrigger>\n </NavigationMenuItem>\n </NavigationMenuList>\n</NavigationMenu>`,\n },\n {\n name: \"ResizablePanel\",\n group: \"layout\",\n tagline: \"Resizable panel group/child/handle primitives from react-resizable-panels.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Panel identifier for persistence.\" },\n { name: \"defaultSize\", type: \"number\", description: \"Initial panel size (percent/units).\" },\n { name: \"minSize\", type: \"number\", description: \"Minimum size constraint.\" },\n { name: \"maxSize\", type: \"number\", description: \"Maximum size constraint.\" },\n ],\n useCases: [\"Split-pane layouts\", \"Resizable sidebars\", \"Code editors with adjustable zones\"],\n storyPath: \"layout/ResizablePanel.stories.tsx\",\n rules: [3, 6],\n example: `import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"@godxjp/ui/layout\";\n\n<ResizablePanelGroup>\n <ResizablePanel>Panel A</ResizablePanel>\n <ResizableHandle />\n <ResizablePanel>Panel B</ResizablePanel>\n</ResizablePanelGroup>`,\n },\n {\n name: \"Carousel\",\n group: \"data-display\",\n tagline:\n \"Embla-backed carousel primitives: previous/next controls, CarouselDots indicators, and a context API.\",\n props: [\n {\n name: \"opts\",\n type: \"Parameters<typeof useEmblaCarousel>[0]\",\n description: \"Embla options.\",\n },\n {\n name: \"plugins\",\n type: \"Parameters<typeof useEmblaCarousel>[1]\",\n description: \"Embla plugins.\",\n },\n {\n name: \"setApi\",\n type: \"(api: CarouselApi) => void\",\n description: \"Receive carousel API for custom logic.\",\n },\n ],\n useCases: [\"Feature cards\", \"Image galleries\", \"Horizontal stepping lists\"],\n storyPath: \"data-display/Carousel.stories.tsx\",\n rules: [3, 6],\n example: `import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, CarouselDots } from \"@godxjp/ui/data-display\";\n\n// CarouselDots reads the Embla api from context — no setApi wiring needed.\n<Carousel opts={{ loop: true }}>\n <CarouselContent>\n <CarouselItem>1</CarouselItem>\n <CarouselItem>2</CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n <CarouselDots />\n</Carousel>`,\n },\n {\n name: \"TimeInput\",\n group: \"data-entry\",\n tagline: \"Masking HH:mm input with validation and optional minute step quantization.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Controlled HH:mm value.\" },\n {\n name: \"defaultValue\",\n type: \"string\",\n description: \"Uncontrolled initial HH:mm value.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description: \"Validated value callback.\",\n },\n { name: \"step\", type: \"number\", defaultValue: \"1\", description: \"Minute step.\" },\n { name: \"name\", type: \"string\", description: \"Form field name.\" },\n ],\n useCases: [\"Time filters\", \"Schedule pickers (calendar-free)\", \"HH:mm-only forms\"],\n storyPath: \"data-entry/TimeInput.stories.tsx\",\n rules: [3, 6],\n example: `import { TimeInput } from \"@godxjp/ui/data-entry\";\n\n<TimeInput value=\"09:00\" step={15} onValueChange={(time) => console.log(time)} />`,\n },\n {\n name: \"AppSettingPicker\",\n group: \"navigation\",\n tagline:\n \"One provider-bound Select for a single AppProvider setting, chosen by `kind` (locale | timezone | dateFormat | timeFormat) — replaces the former Locale/Timezone/Date-format/Time-format pickers. Throws if used without AppProvider AND without controlled value+onValueChange.\",\n props: [\n {\n name: \"kind\",\n type: '\"locale\" | \"timezone\" | \"dateFormat\" | \"timeFormat\"',\n description:\n \"Which AppProvider setting this picker reads and writes. Determines the option list, icon, trigger width, and the context value/setter used.\",\n },\n {\n name: \"value\",\n type: \"string\",\n description:\n \"Controlled value for the chosen kind. When omitted, reads the current value from AppProvider context for that kind.\",\n },\n {\n name: \"onValueChange\",\n type: \"(value: string) => void\",\n description:\n \"Controlled change handler. When omitted, calls the matching AppProvider setter (setLocale/setTimezone/setDateFormat/setTimeFormat). Required together with value when no AppProvider is present.\",\n },\n {\n name: \"className\",\n type: \"string\",\n description: \"Extra CSS classes merged onto the SelectTrigger.\",\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: Mount inside <AppProvider> for zero-config use — the picker reads and writes the context value named by kind, no value/onValueChange needed.\",\n \"DO: Use controlled mode (value + onValueChange) when managing state outside AppProvider, e.g. a standalone settings form or a Storybook story. Both are required together in this mode.\",\n \"DO NOT: Render without AppProvider and without both controlled props — it throws 'AppSettingPicker requires <AppProvider> or controlled value + onValueChange'.\",\n \"DO: Render four instances with different kind values to build a full preferences panel; they all share the same AppProvider context and stay in sync.\",\n \"DON'T hand-roll a locale/timezone/format Select — AppSettingPicker already composes Select + the right icon + translated, context-wired options. There is no separate LocalePicker/TimezonePicker/DateFormatPicker/TimeFormatPicker anymore; use kind.\",\n ],\n useCases: [\n 'App-shell top-nav language switcher: <AppSettingPicker kind=\"locale\" /> under AppProvider, persisting to localStorage with no extra state.',\n \"User settings page with all four preferences — render kind=locale, kind=timezone, kind=dateFormat, kind=timeFormat together under one AppProvider.\",\n \"Onboarding step that picks language/timezone before the rest of the app is configured — AppProvider persist={false} + controlled values to keep state local.\",\n 'Storybook/test harness without AppProvider — fully controlled: <AppSettingPicker kind=\"timeFormat\" value=\"24h\" onValueChange={fn} />.',\n ],\n related: [\n \"AppProvider — required peer unless fully controlled. Supplies locale/timezone/dateFormat/timeFormat plus their setters and the i18n context.\",\n \"Select — the data-entry primitive AppSettingPicker is built on; reach for Select directly for any non-AppProvider dropdown.\",\n \"formatDate — reads the same AppProvider date/time context that kind='dateFormat'/'timeFormat' write to.\",\n ],\n example: `{\\`// Uncontrolled — AppProvider manages and persists every setting\nimport { AppProvider } from \"@godxjp/ui/app\";\nimport { AppSettingPicker } from \"@godxjp/ui/navigation\";\n\nexport function SettingsPanel() {\n return (\n <AppProvider defaultLocale=\"ja\" defaultTimezone=\"Asia/Tokyo\">\n <AppSettingPicker kind=\"locale\" />\n <AppSettingPicker kind=\"timezone\" />\n <AppSettingPicker kind=\"dateFormat\" />\n <AppSettingPicker kind=\"timeFormat\" />\n </AppProvider>\n );\n}\n\n// Controlled — no AppProvider required\nimport { useState } from \"react\";\nimport { AppSettingPicker } from \"@godxjp/ui/navigation\";\n\nexport function LocaleField() {\n const [locale, setLocale] = useState(\"en\");\n return <AppSettingPicker kind=\"locale\" value={locale} onValueChange={setLocale} />;\n}\\`}`,\n storyPath: \"navigation/AppSettingPicker.stories.tsx\",\n rules: [3, 5, 6, 23],\n },\n {\n name: \"Field\",\n group: \"data-entry\",\n tagline:\n \"Label + optional description laid out beside a single checkbox/radio/switch control — the inline alternative to FormField's full block layout.\",\n props: [\n {\n name: \"id\",\n type: \"string\",\n description: \"id wired to the control via htmlFor; pass the same id to the child control.\",\n },\n { name: \"label\", type: \"ReactNode\", description: \"The field label, rendered as a <Label>.\" },\n {\n name: \"description\",\n type: \"ReactNode\",\n description: \"Optional helper text rendered under the label.\",\n },\n {\n name: \"children\",\n type: \"ReactNode\",\n description: \"The control (Checkbox/Radio/Switch) placed beside the label.\",\n },\n { name: \"className\", type: \"string\", description: \"Extra CSS classes on the wrapper.\" },\n ],\n usage: [\n \"DO: Use Field to label a single boolean/choice control (Switch, Checkbox, Radio) in a compact two-column row — control beside label + description.\",\n \"DO: Match the child control's id to Field's id so the label is correctly associated.\",\n \"DON'T: Use Field for text inputs needing helper/error/required slots — use FormField (block layout) instead. There is no ChoiceField anymore; Field is the canonical name.\",\n ],\n useCases: [\n \"A settings list of toggle rows (notifications, auto-save) where each Switch has a label + description.\",\n \"A consent checkbox with an explanatory description beside it.\",\n \"A radio option row in a preferences form.\",\n ],\n related: [\n \"FormField — block label/helper/error/required layout for text inputs; use it instead when those slots are needed.\",\n \"Switch / Checkbox / Radio — the controls Field typically wraps.\",\n ],\n example: `{\\`import { Field, Switch } from \"@godxjp/ui/data-entry\";\n\nexport function NotifyRow() {\n return (\n <Field id=\"notify\" label=\"メール通知\" description=\"重要な更新をメールで受け取る\">\n <Switch id=\"notify\" defaultChecked />\n </Field>\n );\n}\\`}`,\n storyPath: \"data-entry/Field.stories.tsx\",\n rules: [23],\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","/** Canonical prop vocabulary taught by the MCP. Mirrors src/props/vocabulary. */\n\nexport interface PropVocabEntry {\n name: string;\n concept: string;\n values: string[];\n usedBy: string[];\n notes?: string;\n}\n\nexport const PROP_VOCABULARY: PropVocabEntry[] = [\n {\n name: \"ValueProp<T = string>\",\n concept: \"Abstract controlled value.\",\n values: [\"generic\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Tabs\", \"SearchSelect\"],\n },\n {\n name: \"DefaultValueProp<T = string>\",\n concept: \"Abstract uncontrolled initial value.\",\n values: [\"generic\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Tabs\"],\n },\n {\n name: \"OnValueChangeProp<T = string>\",\n concept: \"Callback for abstract value changes. DOM events continue to use onChange.\",\n values: [\"(value: T) => void\"],\n usedBy: [\"CheckboxGroup\", \"Upload\", \"Cascader\", \"TreeSelect\", \"Transfer\", \"settings pickers\"],\n },\n {\n name: \"OpenProp / DefaultOpenProp / OnOpenChangeProp\",\n concept: \"Disclosure state.\",\n values: [\"boolean\", \"(open: boolean) => void\"],\n usedBy: [\"Dialog\", \"Sheet\", \"Popover\"],\n },\n {\n name: \"SizeProp\",\n concept: \"Shared public size names.\",\n values: [\"xs\", \"sm\", \"md\", \"lg\"],\n usedBy: [\"Button\", \"Steps\", \"Switch\"],\n notes: \"Component-specific subsets must be documented. Old alias small is sm.\",\n },\n {\n name: \"ToneProp\",\n concept: \"Semantic status/color intent.\",\n values: [\"default\", \"success\", \"warning\", \"destructive\", \"info\", \"muted\", \"neutral\"],\n usedBy: [\"Badge\", \"Alert\"],\n notes: \"Status values belong in tone, not variant.\",\n },\n {\n name: \"GapProp\",\n concept: \"Shared layout gap scale.\",\n values: [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"],\n usedBy: [\"Stack\", \"Inline\"],\n notes: \"Inline uses an Exclude<GapProp, 'xl'> subset.\",\n },\n {\n name: \"TitleProp\",\n concept: \"Primary heading text.\",\n values: [\"React.ReactNode\"],\n usedBy: [\"PageContainer\", \"PageHeader\", \"EmptyState\", \"Dialog\"],\n },\n {\n name: \"DensityProp\",\n concept: \"Page/subtree density.\",\n values: [\"compact\", \"default\", \"comfortable\"],\n usedBy: [\"PageContainer\"],\n },\n];\n\nexport function findVocab(name: string): PropVocabEntry | undefined {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/prop(?:<.*>)?$/i, \"\");\n return PROP_VOCABULARY.find(\n (v) => v.name.toLowerCase().replace(/prop(?:<.*>)?$/i, \"\") === normalized,\n );\n}\n","/** Design token catalog taught by the MCP. Mirrors the 3-tier token model. */\n\nexport type TokenCategory = \"primitive\" | \"semantic\" | \"component\";\n\nexport interface TokenEntry {\n name: string;\n category: TokenCategory;\n role: string;\n tier: \"primitive\" | \"semantic\" | \"component\";\n}\n\nexport const TOKENS: TokenEntry[] = [\n {\n name: \"--wa-*\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Neutral decorative Japanese accent primitives for charts/tags/decoration only.\",\n },\n {\n name: \"--chart-1..6\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Neutral decorative chart primitives; @theme chart colors reference these tokens.\",\n },\n { name: \"--space-0..12\", category: \"primitive\", tier: \"primitive\", role: \"Raw spacing scale.\" },\n {\n name: \"--font-size-*\",\n category: \"primitive\",\n tier: \"primitive\",\n role: \"Raw typography scale.\",\n },\n { name: \"--primary\", category: \"semantic\", tier: \"semantic\", role: \"Brand/action color role.\" },\n { name: \"--success\", category: \"semantic\", tier: \"semantic\", role: \"Success status role.\" },\n { name: \"--warning\", category: \"semantic\", tier: \"semantic\", role: \"Warning status role.\" },\n {\n name: \"--destructive\",\n category: \"semantic\",\n tier: \"semantic\",\n role: \"Destructive/error status role.\",\n },\n { name: \"--info\", category: \"semantic\", tier: \"semantic\", role: \"Information status role.\" },\n { name: \"--attention\", category: \"semantic\", tier: \"semantic\", role: \"Attention status role.\" },\n { name: \"--badge-space-*\", category: \"component\", tier: \"component\", role: \"Badge spacing.\" },\n {\n name: \"--card-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Card surface, border, spacing, and typography.\",\n },\n {\n name: \"--control-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Shared form control heights, padding, icons, and focus chrome.\",\n },\n { name: \"--table-*\", category: \"component\", tier: \"component\", role: \"Table row/cell sizing.\" },\n {\n name: \"--dialog-* / --alert-* / --skeleton-*\",\n category: \"component\",\n tier: \"component\",\n role: \"Feedback component sizing and spacing.\",\n },\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 {\n number: 1,\n title: \"Storybook is mandatory\",\n body: \"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark.\",\n },\n {\n number: 2,\n title: \"Tokens, not utilities\",\n 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 },\n {\n number: 3,\n title: \"Radix for interactive primitives\",\n body: \"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)\",\n },\n {\n number: 4,\n title: \"shadcn-style ownership\",\n body: \"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)\",\n },\n {\n number: 5,\n title: \"One i18next singleton\",\n body: \"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)\",\n },\n {\n number: 6,\n title: \"WCAG 2.1 AA baseline\",\n 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 },\n {\n number: 7,\n title: \"SemVer 2.0 + Keep a Changelog 1.1\",\n body: \"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR.\",\n },\n {\n number: 8,\n title: \"Inclusive naming\",\n body: \"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced.\",\n },\n {\n number: 9,\n title: \"No marketing speak\",\n body: 'Banned: \"powerful\", \"robust\", \"blazing fast\", \"best-in-class\", \"seamless\", \"enterprise-grade\". State what it does.',\n },\n {\n number: 10,\n title: \"English is canonical for docs\",\n body: \"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness.\",\n },\n {\n number: 11,\n title: \"Submodule discipline\",\n 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 },\n {\n number: 12,\n title: \"Branch + PR workflow\",\n body: \"`feat/<scope>` / `fix/<scope>` → submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden.\",\n },\n {\n number: 13,\n title: \"TypeScript strict\",\n body: \"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link.\",\n },\n {\n number: 14,\n title: \"Every third-party library is shadcn / Radix-recommended\",\n 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 },\n {\n number: 15,\n title: \"No `@apply` re-encoding tokens\",\n 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 },\n {\n number: 16,\n title: \"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`\",\n body: \"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it.\",\n },\n {\n number: 17,\n title: \"`src/stories/` ↔ `src/components/` parity\",\n body: \"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`.\",\n },\n {\n number: 18,\n title: \"`docs/reference/<group>/` ↔ `src/components/<group>/` parity\",\n body: \"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`.\",\n },\n {\n number: 19,\n title: \"No service-specific anything\",\n body: '`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent=\"<palette>\"]`.',\n },\n {\n number: 20,\n title: 'No \"platform-only\" exports',\n body: \"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported.\",\n },\n {\n number: 21,\n title: \"Every component honours every theme axis\",\n 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 },\n {\n number: 22,\n title: \"100% match to the design canon\",\n 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 },\n {\n number: 23,\n title: \"Concept-first prop API\",\n 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 },\n {\n number: 24,\n title: \"Mobile-first\",\n 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 },\n {\n number: 25,\n title: \"Stories are docs; UI is the primitive\",\n 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 },\n {\n number: 26,\n title: \"Library isolation\",\n 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 },\n {\n number: 27,\n title: \"Per-group folder structure\",\n 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 },\n {\n number: 28,\n title: \"`src/` folder taxonomy\",\n 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 },\n {\n number: 29,\n title: \"Stories consume framework primitives only\",\n 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 },\n {\n number: 30,\n title: \"Story `render` returns JSX directly\",\n 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 },\n {\n number: 31,\n title: \"No nested wrapper / convenience primitives\",\n 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 },\n {\n number: 32,\n title: \"No redundant props\",\n 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 },\n {\n number: 33,\n title: \"Stories / source / docs name-synchronized\",\n 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 },\n {\n number: 34,\n title: \"Storybook source panel = real, copy-paste-ready code\",\n body: 'Storybook\\'s react-docgen serializer strips every function value (`cell: ({row}) => <JSX/>`, `render: ({field}) => <Input/>`, `rowClassName`, `renderItem`, …) to `() => {}`. Any story whose `render` passes a function-valued prop, references a module-level helper (`Badge`, `EMPLOYEE_COLUMNS`, etc.), or uses a render-prop pattern MUST override `parameters.docs.source.code` with the literal copy-paste-ready snippet — type aliases, helper functions spelled out, column definitions with cell JSX visible, inline data array. The `render()` callback stays as-is (module-level constants are fine for runtime performance); `source.code` is the marketing surface. Skip ONLY for stories whose JSX is purely static primitives Storybook can serialize verbatim (`<Button variant=\"primary\">Click</Button>`). The exemplar is `Table.Default` in `src/stories/data-display/Table.stories.tsx`.',\n },\n {\n number: 35,\n title: \"Status chips never wrap\",\n body: \"A `Badge` / `Badge` reads as one atomic unit. Its label must never break across lines — pin `white-space: nowrap` on the chip (done in `badge-layout.css`), especially inside narrow `DataTable` cells (スコープ / ステータス columns). If a cell is too tight, widen the column or shorten the label; never let the chip wrap.\",\n },\n {\n number: 36,\n title: \"Badge tone/icon are the colour escape hatch\",\n body: \"`Badge` 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 },\n {\n number: 37,\n title: \"DataTable is full-width — never inside a narrow grid column\",\n 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 },\n {\n number: 38,\n title: \"FilterBar stays OUT of CardContent flush\",\n 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 },\n {\n number: 39,\n title: \"Long text columns get an explicit width\",\n 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 },\n {\n number: 40,\n title: \"Pages are mobile-first\",\n 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 {\n number: 41,\n title: \"Drawer & dialog footer layout\",\n body: \"Sheet/Dialog/AlertDialog footers are a pinned action bar (Ant Design Drawer footer): the footer sticks to the bottom, SheetFooter draws a full-bleed top border, and actions are RIGHT-aligned with the PRIMARY button rightmost (Cancel/secondary to its left). A destructive / clear / reset action goes far-LEFT — give that button `className=\\\"mr-auto\\\"`. NEVER stack footer buttons full-width or center them.\",\n },\n];\n\nexport const VOCABULARY_TOKEN_RULES: CardinalRule[] = [\n {\n number: 1,\n title: \"Prop Registry Entry\",\n body: \"Prop vocabulary: every exported `*Prop` type in `src/props/components/` MUST have exactly one `COMPONENT_PROP_REGISTRY` entry.\",\n },\n {\n number: 2,\n title: \"Public Field Mapping\",\n body: \"Prop vocabulary: every public property in an exported component prop type MUST map to one `VOCABULARY_REGISTRY` entry or to a `local: true` registry record with a non-empty `reason`.\",\n },\n {\n number: 3,\n title: \"Vocabulary Exists\",\n body: \"Prop vocabulary: every vocabulary name referenced by `COMPONENT_PROP_REGISTRY[*].vocabulary` MUST exist in `VOCABULARY_REGISTRY`.\",\n },\n {\n number: 4,\n title: \"Shared Concepts\",\n body: \"Prop vocabulary: the same prop spelling, value kind, and semantic role used by two or more components MUST use one shared vocabulary entry.\",\n },\n {\n number: 5,\n title: \"GapProp\",\n body: \"Prop vocabulary: `gap` MUST use `GapProp`; `StackGapProp` and `InlineGapProp` MUST NOT be canonical registry entries.\",\n },\n {\n number: 6,\n title: \"TitleProp\",\n body: \"Prop vocabulary: primary heading text MUST use `TitleProp`; `PageTitleProp` MUST NOT be a canonical registry entry.\",\n },\n {\n number: 7,\n title: \"Value Props\",\n body: \"Prop vocabulary: abstract controlled values MUST use `value?: ValueProp<T>`, `defaultValue?: DefaultValueProp<T>`, and `onValueChange?: OnValueChangeProp<T>`; `onChange` MAY be used only for DOM event handlers or explicitly local compatibility wrappers.\",\n },\n {\n number: 8,\n title: \"Open Props\",\n body: \"Prop vocabulary: disclosure/open state MUST use `open?: OpenProp`, `defaultOpen?: DefaultOpenProp`, and `onOpenChange?: OnOpenChangeProp`.\",\n },\n {\n number: 9,\n title: \"ToneProp\",\n body: \"Prop vocabulary: semantic color/status intent MUST use `tone` with `ToneProp` or a documented status-specific subtype; `variant` MUST NOT include status-only values such as `success`, `warning`, `info`, or `neutral`.\",\n },\n {\n number: 10,\n title: \"Variant Scope\",\n body: \"Prop vocabulary: `variant` MAY be component-specific only when its registry entry documents the component semantics and allowed values; one global `VariantProp` MUST NOT be used to collapse non-interchangeable value unions.\",\n },\n {\n number: 11,\n title: \"SizeProp\",\n body: \"Prop vocabulary: public `size` values MUST use shared `SizeProp` names or a documented component-specific subset; aliases such as `small` MUST be renamed to the canonical shared value.\",\n },\n {\n number: 12,\n title: \"DensityProp\",\n body: \"Prop vocabulary: public density MUST use `DensityProp` when the component participates in page/subtree density; component-specific density subsets MUST be documented with a registry reason.\",\n },\n {\n number: 13,\n title: \"Named Events\",\n body: \"Prop vocabulary: no new public `HandlerProp` use is allowed for named user events; command callbacks MUST have event-specific names such as `onConfirm`, `onRetry`, `onDismiss`, or `onValueChange`.\",\n },\n {\n number: 14,\n title: \"Token Tiers\",\n body: \"Design tokens: package tokens MUST be organized into primitive, semantic, and component tiers.\",\n },\n {\n number: 15,\n title: \"Tier Roles\",\n body: \"Design tokens: primitive tokens MUST define raw scales or palettes only; semantic tokens MUST alias primitives by UI role; component tokens MUST alias semantic or primitive tokens by component part/state.\",\n },\n {\n number: 16,\n title: \"No Domain Nouns\",\n body: \"Design tokens: package CSS custom properties and Tailwind `@theme` exports MUST NOT contain app, customer, or business-domain nouns.\",\n },\n {\n number: 17,\n title: \"No Tracking Tokens\",\n body: \"Design tokens: `--tracking-*` and `--color-tracking-*` are forbidden in package source.\",\n },\n {\n number: 18,\n title: \"Component Token Names\",\n body: \"Design tokens: component-scoped tokens MUST live in the component tier and use `--{component}-{part}-{property}` or `--{component}-{property}-{state}` naming consistently.\",\n },\n {\n number: 19,\n title: \"Theme References\",\n body: \"Design tokens: Tailwind `@theme` color exports MUST reference package tokens; literal colors are allowed only when first registered as primitive or semantic tokens.\",\n },\n {\n number: 20,\n title: \"Decorative Primitives\",\n body: \"Design tokens: public raw/decorative primitive exports are allowed only under documented neutral namespaces such as `wa-*` or `chart-*`; undocumented raw ramps such as public `gray-*`/`blue-*` exports are forbidden.\",\n },\n {\n number: 21,\n title: \"Dark Semantic Overrides\",\n body: \"Design tokens: dark mode MUST override semantic tokens by role; component-token dark overrides require a documented component contrast reason.\",\n },\n {\n number: 22,\n title: \"Density Aliases\",\n body: \"Design tokens: density CSS MUST select token aliases and MUST NOT introduce new raw component dimensions when a token tier can hold the value.\",\n },\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:\n \"Fix the most common @godxjp/ui consumer mistakes & visual bugs (StatCard double-border, grey Badge, crushed/empty table headers, washed-out sidebar footer, Inertia layout crash, SSR hydration). Before → after.\",\n tags: [\n \"fixes\",\n \"migration\",\n \"bug\",\n \"cardstat\",\n \"statusbadge\",\n \"datatable\",\n \"sidebar\",\n \"gotcha\",\n \"review\",\n ],\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) StatCard shows a DOUBLE border (too thick)\n// Cause: StatCard IS already a bordered Card. Don't wrap it.\n// ❌ <Card><CardContent><StatCard label=\"x\" value=\"1\" /></CardContent></Card>\n// ✅ <ResponsiveGrid columns={4}><StatCard 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}><StatCard .../></ResponsiveGrid></Stack>\n\n// 2) Badge renders grey with a ○ (no colour) for localized/tier labels\n// Cause: it auto-maps only English lifecycle keys. (@godxjp/ui >= 6.1)\n// ❌ <Badge status=\"プレミアム\" />\n// ✅ <Badge status=\"プレミアム\" tone=\"success\" icon={null} /> // tier → pill, no icon\n// ✅ <Badge status=\"active\">公開中</Badge> // 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// ✅ <StatCard label=\"売上\" value=\"¥8.2M\" delta=\"+12%\" /> // + green / - red; inverse flips`,\n },\n\n {\n name: \"signup-form\",\n tagline:\n \"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:\n \"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:\n '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} onValueChange={(e) => setConfirm(e.target.value)} placeholder={slug} />\n </Stack>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>キャンセル</Button>\n <Button tone=\"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:\n \"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:\n \"Inertia + @godxjp/ui list page — PageContainer + FilterBar + DataTable + Badge + 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, StatCard, DataTable, EmptyState, Badge, 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) => <Badge status={c.scope} tone=\"info\" icon={null} /> },\n { key: \"status\", header: \"ステータス\", render: (c) => <Badge 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 <StatCard label=\"公開中\" value={coupons.filter((c) => c.status === \"公開中\").length} />\n <StatCard label=\"総利用数\" value={coupons.reduce((s, c) => s + c.usage, 0).toLocaleString()} />\n <StatCard 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 value={page} total={filtered.length} pageSize={PAGE_SIZE} showTotal onValueChange={(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:\n \"Inertia detail page — receives {id} prop, Descriptions (compound) + StatCard + 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, StatCard, EmptyState, Descriptions, Badge } 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 <StatCard label=\"累計購入額\" value={\\`¥\\${member.total.toLocaleString()}\\`} />\n <StatCard label=\"来店回数\" value={member.visits} />\n <StatCard label=\"ポイント\" value={member.points.toLocaleString()} />\n <StatCard label=\"LTV\" value={\\`¥\\${member.ltv.toLocaleString()}\\`} />\n </ResponsiveGrid>\n <Card>\n <CardContent>\n {/* Descriptions is COMPOUND — value goes in children, not a prop */}\n <Descriptions columns={2}>\n <Descriptions.Item label=\"氏名\">{member.name}</Descriptions.Item>\n <Descriptions.Item label=\"ランク\"><Badge status={member.rank} tone=\"info\" icon={null} /></Descriptions.Item>\n <Descriptions.Item label=\"ステータス\"><Badge status={member.status} /></Descriptions.Item>\n <Descriptions.Item label=\"登録日\">{formatDate(member.registeredAt)}</Descriptions.Item>\n </Descriptions>\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:\n \"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: \"badge-coloring\",\n tagline:\n \"Colour a Badge 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 { Badge } from \"@godxjp/ui/data-display\"\n\n// Badge 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<Badge status=\"active\">公開中</Badge> // green ✓ 公開中\n\n// 2) Unknown label — set tone explicitly (no icon, since the key is unknown):\n<Badge status=\"公開中\" tone=\"success\" />\n\n// 3) Tier / category — coloured pill, drop the misleading glyph with icon={null}:\n<Badge status=\"プレミアム\" tone=\"success\" icon={null} />\n<Badge status=\"ゴールド\" tone=\"warning\" icon={null} />\n<Badge status=\"法人共通\" tone=\"info\" icon={null} />\n\n// tone: \"success\" | \"warning\" | \"destructive\" | \"info\" | \"neutral\" (import type BadgeTone)\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 Badge 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\n/**\n * Who a skill is for:\n * - \"core\" — building/maintaining @godxjp/ui ITSELF (the library, its docs,\n * its MCP catalog). Hidden from the consumer-facing tools.\n * - \"consumer\" — building an APP that imports @godxjp/ui. Surfaced by\n * list_consumer_skills / route_consumer_task / get_consumer_skill.\n * - \"both\" — applies to either audience (e.g. universal taste/output rules).\n * Consumer tools surface audience ∈ {consumer, both}; core-only skills stay hidden\n * from them so an app-dev is never confronted with library-maintenance material.\n */\nexport type SkillAudience = \"core\" | \"consumer\" | \"both\";\n\nexport interface Skill {\n id: string;\n name: string;\n /** Intended audience — drives the consumer-namespace tool filtering. */\n audience: SkillAudience;\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\n/** True if a skill should be visible to the consumer-facing tools. */\nexport function isConsumerSkill(s: Skill): boolean {\n return s.audience !== \"core\";\n}\n\nexport const SKILLS: Skill[] = [\n // ── taste (foundational) ───────────────────────────────────────\n {\n id: \"taste\",\n audience: \"both\",\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: \"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 audience: \"consumer\",\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:\n \"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:\n \"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:\n \"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 audience: \"consumer\",\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:\n \"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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"both\",\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:\n \"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:\n \"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 audience: \"both\",\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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 audience: \"consumer\",\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:\n \"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 // ── component discipline (hard contract) ───────────────────────\n {\n id: \"component-discipline\",\n audience: \"core\",\n name: \"Component discipline — international standards (hard contract)\",\n whenToUse:\n \"MANDATORY before creating or changing ANY @godxjp/ui component, recipe, doc, or example. Enforces real primitives only, no duplication, i18n (Intl/CLDR/ISO/IANA/BCP-47), WAI-ARIA APG + WCAG 2.2 AA, RTL, and the controlled-vocabulary API.\",\n source: \"@godxjp/ui .claude/skills/godxjp-ui-component + international-standardization audit\",\n sections: [\n {\n id: \"real-primitives\",\n title: \"Real primitives only — never invent / fake / raw HTML\",\n tagline: \"Compose installable @godxjp/ui only; no hand-rolled wrappers, no raw controls.\",\n body: `NEVER invent/hand-roll a component, fake the design with styled <div>s, or use raw\n<input>/<select>/<button>/<textarea>/<table>. Use Select, Input, Button, Textarea, DataTable,\nCheckbox, RadioGroup, Switch. Compose fully: CardContent for padding; a table = Card +\nCardContent flush + DataTable in a default padded PageContainer (NOT variant=\"flush\").\nMCP-first: get_component before writing; never guess a prop. No duplication — Select\n(showSearch/loadOptions) is the only searchable/async select; there is no Combobox/SearchSelect/\nCountrySelect/Autocomplete; the 4 i18n pickers are one AppSettingPicker kind=…`,\n },\n {\n id: \"i18n-intl\",\n title: \"i18n via t() + Intl/CLDR\",\n tagline: \"Every string + aria-label through t(); format via Intl with the active locale.\",\n body: `Zero hardcoded English/Japanese. Numbers/currency (ISO 4217, minor units from\nresolvedOptions) + bytes via Intl.NumberFormat; dates via the date subsystem (Intl.DateTimeFormat,\nIANA tz, ISO-8601); names via Intl.DisplayNames (countries ISO 3166-1 alpha-2, languages BCP-47);\nplurals via Intl.PluralRules category maps. No emoji flags. No hand-maintained currency/country\nlists.`,\n },\n {\n id: \"a11y-apg\",\n title: \"WAI-ARIA APG + WCAG 2.2 AA\",\n tagline: \"Correct roles/aria/keyboard/focus + a vitest-axe test (0 violations).\",\n body: `Implement the APG pattern: role/landmark, aria-current/expanded/selected/sort/busy +\naria-live/activedescendant, aria-errormessage+aria-invalid. Keyboard: roving tabindex, arrows,\nHome/End, Enter/Space, Esc, visible focus, no positive tabindex. ≥24px targets (2.5.8); never\ncolour-only state (1.4.1 — add sr-only text); icon-only buttons need a name. Add a *.a11y.test.tsx\nwith expectNoA11yViolations. Prefer Radix/cmdk/vaul for ARIA.`,\n },\n {\n id: \"rtl-vocab\",\n title: \"RTL + controlled-vocabulary API\",\n tagline: \"Logical CSS only; value/defaultValue/onValueChange; size md not default.\",\n body: `RTL: logical CSS only (ms/me/ps/pe, start/end, border-s/e, rounded-s/e, text-start/end)\n— never physical ml/mr/pl/pr/left/right. API: controlled triad value/defaultValue/onValueChange\n(open/onOpenChange; checked/onCheckedChange; pressed/onPressedChange); size ∈ xs|sm|md|lg (never\n\"default\"); positive booleans; tone for status; forward ref + ...props + className + id; export\nXProp + XProp as XProps and register in props/registry. Then: add an MCP catalog entry + a\nreal-screen docs page; verify typecheck/lint/audit/check:*/preview:build/test all green.`,\n },\n {\n id: \"report-bug\",\n title: \"Found a library-level defect → file a gh issue (never paper over it)\",\n tagline:\n \"A missing token / wrong vocab / broken a11y in the system is a bug to report, not to work around.\",\n body: `If satisfying this contract is blocked by @godxjp/ui itself — a token tier that\ndoesn't exist, a primitive missing the controlled-vocabulary prop, a Radix wiring with a\nreal a11y bug, a catalog example that's wrong — the contract says STOP and fix the SYSTEM,\nnot the call site. Don't bake a one-off around it. If you can fix the library in this repo,\ndo. If you can't (or you're a consumer agent without write access), open a detailed GitHub\nissue: use the draft_bug_report MCP tool to produce the issue body + a 'gh issue create\n--repo godx-jp/godxjp-ui …' command, linking the component (get_component) and the cardinal\nrule (get_rule) involved, with a minimal repro, expected vs actual, version, and env.`,\n },\n ],\n },\n\n // ── design-to-page (consumer: handoff → real page) ─────────────\n {\n id: \"design-to-page\",\n audience: \"consumer\",\n name: \"Design handoff → real page (consumer build guide)\",\n whenToUse:\n \"You (a consumer agent) received a Claude Design handoff — a bundle/mock/screenshot/HTML prototype or a written brief — and must build it as a REAL page with @godxjp/ui. Read this BEFORE writing any JSX. It teaches: read intent, map every block to a real primitive via this MCP, consume existing tokens, apply the dxs-kintai DNA, treat tables as the centerpiece, resolve gaps by extend-or-ask, and verify.\",\n source:\n \"@godxjp/ui .design/research (chats-intent, tables, atomic-components) + dxs-kintai SKILL/colors_and_type.css\",\n sections: [\n {\n id: \"read-intent\",\n title: \"Read the intent — chats before pixels\",\n tagline: \"A handoff is a prototype, not production code. Build the intent, not the markup.\",\n body: `A Claude Design bundle is HTML/CSS/JS to LOOK AT — never transcribe its DOM.\nIf the bundle has chats/*.md, read them FIRST: they hold what the user actually\nwanted after iterating, the directions rejected, and the explicit rules. The final\nHTML is just the last output; the chat is the intent. Then read the README/SKILL +\ncolors_and_type.css for the DNA. Distil each screen to ONE primary question it\nanswers (one-intent-per-screen) before choosing components. Honesty rules that\nrecur in this DNA: render only VALID actions (no disabled-button noise — a punch\ncard off-state shows Check-In only, never a greyed Check-Out); label = identity\n(never changes), helper row = state (error/help goes BELOW, never recolours the\nlabel); entry-point affordances live in chrome, not floating in content.`,\n },\n {\n id: \"map-to-primitives\",\n title: \"Map every block to a real primitive — MCP-first, never hand-roll\",\n tagline:\n \"For each visual block ask 'which @godxjp/ui component is this?' — list_primitives, then get_component.\",\n body: `NEVER hand-roll a styled <div> that looks like a Card, or use raw\n<input>/<select>/<button>/<table>. Decompose each screen into a shopping list and\nresolve each item through THIS MCP: list_primitives to discover, get_component to\nconfirm the exact prop/union before you write (never guess a prop). Typical map:\npage chrome → AppShell/Sidebar/Topbar/PageContainer; stat row → ResponsiveGrid +\nStatCard; data grid → DataTable; status pill → Badge tone=…; filter row → Form\ninline + Select/Input; org→branch → Cascader/TreeSelect; date/time → DatePicker/\nTimePicker; ⌘K → Command; bulk drawer/detail → Drawer/Sheet/Dialog; split list+\ndetail → SplitPane/Resizable; empty → EmptyState; confirm → AlertDialog; toast →\nSonner. No duplication: Select (showSearch/loadOptions) is the ONLY searchable/\nasync select (no Combobox/Autocomplete); the 4 i18n pickers are one AppSettingPicker\nkind=…. A table = Card + CardContent-flush + DataTable (not PageContainer flush).`,\n },\n {\n id: \"tokens-exist\",\n title: \"Tokens already exist — consume var(--…), never redeclare\",\n tagline: \"The design's colors_and_type.css is already implemented as foundation.css.\",\n body: `The handoff's colors_and_type.css (SmartHR blue, wa-iro, M PLUS 2, the\ndensity scale) is ALREADY shipped as @godxjp/ui's foundation tokens. Never paste a\nhex, never redeclare a token, never invent a neutral. Consume var(--…) and the\nsemantic utilities. Use get_tokens (MCP) to find the right name — if a token seems\nmissing it almost certainly exists under a different name. Soft tints come from\ncolor-mix(in oklch, var(--primary) 15%, transparent), NOT a new pale hex. Control\nheights come from the density scale (xs 24 / sm 28 / default 32 / lg 36 / xl 44),\nnever a literal px. Radii: card 6px, control 4px, inner pill 2px.`,\n },\n {\n id: \"dna\",\n title: \"Apply the dxs-kintai DNA\",\n tagline:\n \"渋み / 間 / 簡素 — fixed color signaling, dense, small headings, 14/1.7, no emoji.\",\n body: `These rules survive when you drop the prototype's divs:\n• 渋み (restraint): primary chroma ≤ 0.18 — --primary is the single most-important\n action + brand surfaces ONLY, never status. No gradients, no pill cards, no\n saturated brand.\n• 間 (breathing): body 14px / 1.7 (NEVER 16/1.5); tabular-nums on every numeric\n column/stat so digits align under 1.7 leading.\n• 簡素 (simplicity): three weights only — 400/500/700 (no 300, no 600). Headings\n stay SMALL: h1 = 20px, h2 = 18 (not 32) — JP enterprise is dense, big headings\n waste 間.\n• Color signaling is FIXED-mapping: success 若竹 · warning 山吹(yellow) · info 群青\n · attention 朱(orange — PREFER over red for non-destructive: 遅刻/lateness) ·\n danger 茜(destructive only). Wa-iro is decorative (charts/tags/tenant) — NEVER\n remap a wa-iro hue to a semantic role.\n• Density up front: compact 28 (heavy tables) · default 32 · comfortable 44 (login/\n mobile, 44px touch floor). Set on the container; don't mix mid-page.\n• Cards: 1px border, NO shadow at rest (shadows only on popover md / dialog xl).\n• Copy quiet & factual — 「承認しました」 not 「承認に成功しました🎉」. Empty state =\n one calm sentence, no illustration. NO emoji in product UI; Lucide 1.5px icons,\n currentColor, sized by context (14 table / 16 nav / 18 button / 20 header).\n• Multi-tenant: tenants override only --primary/--ring/--foreground; semantic\n colors stay shared (a \"rejected\" badge means the same everywhere).`,\n },\n {\n id: \"tables-central\",\n title: \"Tables are the centerpiece — DataTable + the variant catalogue\",\n tagline: \"Enterprise 勤怠/admin lives in tables; showcase the family broadly.\",\n body: `Most of this DNA's real value is in tables — make DataTable the\ncenterpiece. One shell: Card + CardContent-flush wrapping DataTable (1px border,\n6px radius, no shadow). Region order: view tabs · toolbar (search + ⌘K + density +\ncolumns + import/export + primary CTA) · active-filter chip bar · table · footer\ntotals · pagination — every region optional. Build each pattern as its own block:\nassembled CRUD list · bulk-action toolbar (selection REPLACES toolbar; cross-page\n\"select all 1,284\"; destructive isolated last) · column manager · advanced filter\nAND/OR · sort/resize · expandable detail row · inline editable row (row-level\ncommit, dirty dot, \"未保存\" footer) · grouped rows w/ subtotals · tree rows · sticky\ncolumns + horizontal scroll · pagination ×3 (numbered/load-more/cursor) · import/\nexport stepper · empty/loading(Skeleton)/error/no-perm states · footer totals ·\ncompact kintone grid · conditional row/cell formatting. Cells: status → Badge tone;\nidentity → Avatar + two-line; numerics right-aligned tabular-nums with — for null;\nIDs mono. Confirmed (確定済) rows are frozen — no edit, no destructive bulk. Row\nstates change only background via color-mix, never height/padding. get_component\nDataTable + get_vocab ColumnDef/TableDensity/SortState before you build.`,\n },\n {\n id: \"gaps-extend-or-ask\",\n title: \"Gaps → extend or ask — never invent\",\n tagline: \"A block no primitive expresses is a decision, not a hand-roll.\",\n body: `When a block has no clean primitive/prop/variant, do NOT bake a bespoke\none-off into the page. First try to EXTEND: can an existing component take one more\ntone/size/variant/slot, or be composed from existing primitives (e.g. a punch-card\nFSM, a mobile selection-bar, an i18n locale-field are compositions over Button/Card/\nBadge/Tabs/Input, not new primitives)? If it's a genuine gap or you're unsure, STOP\nand ASK the user (or surface it as an ADR/decision) — name the gap, propose\n\"new variant on <X> vs. app-level composition vs. new component\", and converge\nbefore building. Known gaps to expect in this DNA (ask rather than invent): three-\nlevel table density (current is binary), multi-sort priority badges, column resize/\nmanager, numbered/load-more pagination, expandable/editable/grouped/tree/sticky-col\ntable modes, filter chip bar + AND/OR panel, saved-view tabs, week-timeline/staff×\ntime calendar, multilingual-field, no-code builders. Never silently fill a gap.`,\n },\n {\n id: \"verify\",\n title: \"Verify — states complete, a11y, build green\",\n tagline:\n \"Every state shown, WCAG 2.2 AA, typecheck/lint/audit clean, eyeballed at 3 widths.\",\n body: `Before calling it done: every prop × union value × state is exercised\n(default/hover/focus/active/disabled/loading/empty/error) — Skeleton for INIT fetch,\nspinner/loading for active save, EmptyState for no-data, inline error near the field\n(not a disappearing toast). A11y: correct roles/landmarks, keyboard (arrows/Home/End/\nEnter/Esc, visible focus, no positive tabindex), ≥24px targets, never colour-only\nstate (add sr-only text), icon-only buttons have a name; aim for 0 vitest-axe\nviolations. i18n: zero hardcoded strings — every label + aria-label through t(),\nformat numbers/dates via Intl. Then run the build: pnpm typecheck + pnpm lint +\npnpm audit must be green, console clean, and eyeball the page at 390 / 768 / 1280\n(atoms never wrap, containers wrap with row-gap, tabs horizontal-scroll, grids\nminmax(0,1fr), heights never break).`,\n },\n {\n id: \"report-bug\",\n title: \"godx-ui bug / can't-follow-a-rule → file a gh issue (never fake it)\",\n tagline:\n \"If the LIBRARY is wrong, report it — don't hand-roll a workaround that hides the bug.\",\n body: `When you CANNOT satisfy a rule because @godxjp/ui itself is at fault — a\nprimitive doesn't expose the controlled-vocabulary prop you need, a token is\nmissing, a component has a real a11y/behaviour bug, an example in the catalog is\nwrong — the rule is: DO NOT silently hand-roll/fake a replacement to dodge it (that\njust buries a library bug inside every app). Instead:\n• DON'T: copy a primitive's internals into your app, swap in a raw <input>/<div>, or\n redeclare a token to route around the defect.\n• DO: open a detailed GitHub issue against the library, then apply the SMALLEST\n possible local workaround marked // TODO(godxui#<n>: <summary>) so it's grep-able\n and removed once fixed.\n• Use the MCP tool draft_bug_report to generate the issue body + a copy-paste\n 'gh issue create --repo godx-jp/godxjp-ui …' command. Include: the component/rule\n (link via get_component/get_rule), a minimal repro, expected vs actual, the\n installed @godxjp/ui version, and your env. A vague \"X is broken\" issue is not\n enough — the report must let a maintainer reproduce in one paste.`,\n },\n ],\n },\n\n // ── compose-a-screen (consumer: primitives → a finished screen) ──\n {\n id: \"compose-a-screen\",\n audience: \"consumer\",\n name: \"Compose a screen — primitives → a finished app view (consumer)\",\n whenToUse:\n \"You (a consumer agent) are building a NEW screen/page in an app that imports @godxjp/ui — from a written brief or product requirement, not a design handoff. Read this to assemble it from real primitives via this MCP: pick the right components, lay out one-intent-per-screen, wire every state + a11y + i18n, and verify. For a Claude Design handoff bundle/mock specifically, use design-to-page instead.\",\n source:\n \"@godxjp/ui MCP (consumer surface) — taste/one-intent + component-discipline + dxs-kintai DNA\",\n sections: [\n {\n id: \"pick-primitives\",\n title: \"Pick primitives via the MCP — never hand-roll, never guess a prop\",\n tagline:\n \"Decompose the screen into a shopping list; resolve each item with list_primitives → get_component.\",\n body: `Start from the requirement, not the markup. Write a shopping list of every\nblock the screen needs, then resolve each through THIS MCP before writing JSX:\nlist_primitives (discover the group), get_component <Name> (confirm the exact\nprop/union/default — never guess), suggest_primitive / search_components when unsure\nwhich fits. Hard rules: compose ONLY real @godxjp/ui primitives — no styled <div>\nfaking a Card, no raw <input>/<select>/<button>/<textarea>/<table>. No duplication:\nSelect (showSearch/loadOptions) is the ONLY searchable/async select (there is no\nCombobox/Autocomplete/CountrySelect); the 4 i18n pickers are one AppSettingPicker\nkind=…. A table = Card + CardContent-flush + DataTable. If a block has no clean\nprimitive, see gaps handling in design-to-page/gaps-extend-or-ask + report-bug.`,\n },\n {\n id: \"assemble-screen\",\n title: \"Assemble it — one intent per screen, real chrome, fixed signaling\",\n tagline:\n \"One primary question per page; AppShell/PageContainer chrome; --primary once; semantic color is fixed.\",\n body: `Distil the screen to ONE primary question it answers (one-intent-per-screen):\n1–2 hero facts + ONE primary list/form + contextual actions; push tertiary content to\na Sheet/Dialog/next page. An 8-stat-card wall is a red flag. Use real page chrome\n(AppShell/Sidebar/Topbar/PageContainer) — content never touches the viewport edge,\ntwo bordered surfaces never touch (間/breathing via Stack gap). Exactly ONE --primary\naction per view; status uses the FIXED semantic mapping (success/warning/info/\nattention/danger) — never recolor a wa-iro hue into a role, never use --primary for\nstatus. Pick density up front (compact 28 heavy-table / default 32 / comfortable 44\nlogin-mobile) and don't mix it mid-page. Hierarchy from type weight+size+color\n(20/18/14/13 × 400/500/700), not colored background blocks. Mobile-first: default one\ncolumn, add columns only at md:/lg: when each keeps ≥14px body at ≥~280px width.`,\n },\n {\n id: \"state-and-a11y\",\n title: \"Wire every state + a11y + i18n (the part that gets skipped)\",\n tagline:\n \"default/hover/focus/active/disabled/loading/empty/error all handled; APG keyboard; t() everything.\",\n body: `A screen isn't done at the happy path. Handle every state: Skeleton for INIT\nfetch (no data yet), Form loading / Spinner for active save (data present), EmptyState\nfor no-data (one calm sentence, no illustration), inline error near the field via\nFormField (NOT a disappearing toast). Forms: explicit label + help + error always —\nnever placeholder-as-label. A11y (WAI-ARIA APG + WCAG 2.2 AA): correct roles/landmarks,\nkeyboard (arrows/Home/End/Enter/Esc, visible focus, no positive tabindex, return focus\non close), ≥24px targets, never colour-only state (add sr-only text), icon-only buttons\nneed a name. i18n: zero hardcoded strings — every label + aria-label through t();\nnumbers/currency/dates via Intl with the active locale (ISO 4217/8601, IANA tz),\nplurals via Intl.PluralRules. State-truthful affordances: a parent checkbox aggregates\nits children (checked/indeterminate/empty); a held value is visible when a control\nopens; controlled inputs mirror type↔click both ways (a controlled value with no\nsynchronous onValueChange FREEZES the input).`,\n },\n {\n id: \"verify\",\n title: \"Verify — states shown, console clean, build green, 3 widths\",\n tagline:\n \"Drive every interactive control; 0 console errors/warnings; typecheck/lint green; eyeball 390/768/1280.\",\n body: `Before calling the screen done: drive EVERY interactive control to its\nterminal state in a real browser (don't infer behaviour from source) and read the\nDevTools console — a <button>-in-<button>/hydration/act()/404 warning is a FINDING,\nnot noise. Confirm: every prop × union × state is exercised; held values visible on\nopen; multi-step selections (date range, capped multi-select) can be restarted from a\ncomplete state, not trapped; controlled mirrors update both directions. Run the app's\nbuild: typecheck + lint clean, console clean, and eyeball at 390 / 768 / 1280 (atoms\nnever wrap, containers wrap with row-gap, natural-width components stay w-fit, no\ndecorative edge fades, no dead grey panes). If a failure traces to @godxjp/ui itself,\ndo not fake around it — see report-bug.`,\n },\n {\n id: \"report-bug\",\n title: \"godx-ui bug / can't-follow-a-rule → file a gh issue (never fake it)\",\n tagline:\n \"If the LIBRARY is wrong, report it — don't hand-roll a workaround that hides the bug.\",\n body: `Same contract as design-to-page/report-bug: when a rule is impossible because\n@godxjp/ui is at fault (missing token, a primitive without the controlled-vocabulary\nprop, a real a11y/behaviour bug, a wrong catalog example) — DO NOT silently fake a\nreplacement. DON'T copy primitive internals, drop to raw HTML, or redeclare a token to\ndodge it. DO open a detailed GitHub issue (use the draft_bug_report MCP tool to build\nthe body + the 'gh issue create --repo godx-jp/godxjp-ui …' command), then apply the\nsmallest local workaround tagged // TODO(godxui#<n>: <summary>). The issue must carry a\nminimal repro, expected vs actual, the installed version, and env — enough to\nreproduce in one paste.`,\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, opts?: { consumerOnly?: boolean }): 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(\n [\"premium\", \"awwwards\", \"agency\", \"linear\", \"apple\", \"high-end\", \"luxury\"],\n \"soft\",\n \"vibe-archetypes\",\n \"Premium tier — pick a Vibe + Layout archetype + apply Double-Bezel.\",\n [\"soft/double-bezel\", \"soft/magnetic-hover\"],\n );\n\n // Marketing / landing\n route(\n [\"landing page\", \"marketing\", \"hero\", \"long scroll\"],\n \"imagegen-web\",\n \"hero-composition-bias\",\n \"Landing pages benefit from hero composition variety + per-section image generation.\",\n [\"gpt-tasteskill/principles\", \"soft/layout-archetypes\"],\n );\n\n // Mobile app screens\n route(\n [\"mobile app\", \"ios\", \"android\", \"phone screen\", \"onboarding flow\"],\n \"imagegen-mobile\",\n \"principles\",\n \"Mobile app design — generate screens first, avoid phone-shaped-website.\",\n [\"taste/mobile-first\"],\n );\n\n // Workspace / Notion-like\n route(\n [\"workspace\", \"notion\", \"document\", \"editorial\", \"knowledge base\"],\n \"minimalist\",\n \"palette\",\n \"Editorial workspace = warm monochrome + spot pastels + serif headings.\",\n [\"minimalist/typography\", \"minimalist/bento-grids\"],\n );\n\n // Data dashboard\n route(\n [\"dashboard\", \"data heavy\", \"tabular\", \"ops table\"],\n \"brutalist\",\n \"principles\",\n \"Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).\",\n [\"taste/one-intent-per-screen\"],\n );\n\n // Brand work\n route(\n [\"brand\", \"identity\", \"logo\", \"guidelines\"],\n \"brandkit\",\n \"principles\",\n \"Brand identity work — boards before screens.\",\n );\n\n // Existing project upgrade\n route(\n [\"refactor\", \"redesign\", \"upgrade existing\", \"audit\"],\n \"redesign\",\n \"fix-priority\",\n \"Existing project = run audit first, fix in priority order (font → palette → states → ...).\",\n [\"redesign/audit-checklist\"],\n );\n\n // Form work\n route(\n [\"form\", \"validation\", \"submit\", \"sign up\", \"registration\"],\n \"taste\",\n \"form-discipline\",\n \"Form must have explicit label + help + error wired via FormField (rule 34).\",\n );\n\n // Loading / saving\n route(\n [\"loading\", \"saving\", \"skeleton\", \"spinner\"],\n \"taste\",\n \"loading-states\",\n \"Skeleton for INIT fetch, Spinner for active work. Never mix.\",\n );\n\n // Mobile-first concerns\n route(\n [\"mobile first\", \"responsive\", \"breakpoint\"],\n \"taste\",\n \"mobile-first\",\n \"Default styles target xs. Touch targets ≥ 44px. Use useBreakpoint().\",\n );\n\n // Output quality\n route(\n [\"complete code\", \"full implementation\", \"no placeholder\"],\n \"output\",\n \"banned\",\n \"Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code.\",\n );\n\n // GSAP motion\n route(\n [\"gsap\", \"scrolltrigger\", \"scroll choreography\", \"pinning\"],\n \"gpt-tasteskill\",\n \"principles\",\n \"GSAP ScrollTrigger — pinning, stacking, scrubbing.\",\n );\n\n // Image-first / design-first\n route(\n [\"from image\", \"image to code\", \"design first\"],\n \"image-to-code\",\n \"workflow\",\n \"Generate design image first → analyze → implement.\",\n );\n\n // Design handoff → real page (consumer build)\n route(\n [\n \"handoff\",\n \"design bundle\",\n \"claude design\",\n \"prototype\",\n \"build the page\",\n \"implement the design\",\n \"build this screen\",\n \"mockup\",\n ],\n \"design-to-page\",\n \"map-to-primitives\",\n \"Map every block to a real @godxjp/ui primitive (MCP-first), consume existing tokens, apply the dxs-kintai DNA, tables central, gaps → extend-or-ask, verify.\",\n [\"design-to-page/read-intent\", \"design-to-page/dna\", \"design-to-page/tables-central\"],\n );\n\n // Compose a brand-new screen from a written brief (no design handoff)\n route(\n [\n \"compose a screen\",\n \"new screen\",\n \"new page\",\n \"create a page\",\n \"create a screen\",\n \"build a view\",\n \"build a screen\",\n \"from scratch\",\n \"screen from a brief\",\n ],\n \"compose-a-screen\",\n \"pick-primitives\",\n \"Build a new app screen from real @godxjp/ui primitives (MCP-first): one-intent-per-screen, real chrome, every state + a11y + i18n, verify.\",\n [\n \"compose-a-screen/assemble-screen\",\n \"compose-a-screen/state-and-a11y\",\n \"taste/one-intent-per-screen\",\n ],\n );\n\n // Reporting a library bug / un-followable rule\n route(\n [\n \"bug in godx\",\n \"godx-ui bug\",\n \"report a bug\",\n \"file an issue\",\n \"gh issue\",\n \"can't follow the rule\",\n \"library is broken\",\n \"primitive is broken\",\n ],\n \"compose-a-screen\",\n \"report-bug\",\n \"If @godxjp/ui itself is at fault, don't fake a workaround — file a detailed gh issue (use draft_bug_report).\",\n [\"design-to-page/report-bug\"],\n );\n\n // Consumer routing hides core-only skills (e.g. component-discipline) so an\n // app-dev is never pointed at library-maintenance material.\n const filtered = opts?.consumerOnly\n ? matches.filter((m) => {\n const sk = findSkill(m.skill);\n return !sk || sk.audience !== \"core\";\n })\n : matches;\n\n if (filtered.length === 0) {\n if (opts?.consumerOnly) {\n return [\n {\n skill: \"compose-a-screen\",\n section: \"pick-primitives\",\n why: `No keyword match for \"${task}\". Default consumer path: compose the screen from real primitives via the MCP.`,\n alsoSee: [\"design-to-page/map-to-primitives\", \"taste/one-intent-per-screen\"],\n },\n ];\n }\n return [\n {\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\n return filtered;\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 (Sidebar),\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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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:\n \"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 {\n SKILLS,\n findSkill,\n findSection,\n routeTask,\n isConsumerSkill,\n} 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:\n \"Read design tokens, optionally filtered by tier category (primitive / semantic / component).\",\n inputSchema: {\n type: \"object\",\n properties: {\n category: {\n type: \"string\",\n enum: [\"primitive\", \"semantic\", \"component\"],\n },\n },\n },\n },\n\n // ── CONSUMER NAMESPACE (app-dev surface — core-only skills hidden) ─\n {\n name: \"list_consumer_skills\",\n description:\n \"List the design skills relevant to an app-dev BUILDING WITH @godxjp/ui (audience consumer/both). Hides core library-maintenance skills. START HERE if you import @godxjp/ui and want guidance (design-to-page, compose-a-screen, taste, …). Returns id + name + whenToUse + section ids.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"get_consumer_skill\",\n description:\n \"Fetch ONE section of ONE consumer-facing skill. Same as get_skill_section but refuses core-only skills (steers app-devs away from library-maintenance material). Use after list_consumer_skills / route_consumer_task.\",\n inputSchema: {\n type: \"object\",\n properties: {\n skill: {\n type: \"string\",\n description: \"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen').\",\n },\n section: { type: \"string\", description: \"Section id within that skill.\" },\n },\n required: [\"skill\"],\n },\n },\n {\n name: \"route_consumer_task\",\n description:\n \"Natural-language task → consumer skill+section pointer. Like route_task but only points to consumer-facing skills (never core library-maintenance). Use FIRST when you're building an app with @godxjp/ui.\",\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: \"draft_bug_report\",\n description:\n \"When @godxjp/ui ITSELF is at fault (missing token, a primitive lacking the controlled-vocabulary prop, a real a11y/behaviour bug, a wrong catalog example) and you cannot follow a rule — DON'T fake a workaround. This drafts a detailed GitHub issue body + a copy-paste `gh issue create` command so you can report it. Prints the command only; never runs gh.\",\n inputSchema: {\n type: \"object\",\n properties: {\n summary: { type: \"string\", description: \"One-line title of the bug / blocked rule.\" },\n repro: { type: \"string\", description: \"Minimal steps or code to reproduce.\" },\n expected: { type: \"string\", description: \"What SHOULD happen (per the rule/spec).\" },\n actual: { type: \"string\", description: \"What actually happens.\" },\n component: {\n type: \"string\",\n description: \"Affected component name, if any (links to get_component).\",\n },\n rule: {\n type: \"number\",\n description: \"Cardinal rule number that can't be followed, if any.\",\n },\n version: { type: \"string\", description: \"Installed @godxjp/ui version (e.g. '12.1.0').\" },\n env: { type: \"string\", description: \"Environment (browser/OS/framework), if relevant.\" },\n },\n required: [\"summary\"],\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 == null ? undefined : String(args.name));\n case \"get_tokens\":\n return getTokens(args.category as TokenCategory | undefined);\n // Consumer namespace\n case \"list_consumer_skills\":\n return listConsumerSkills();\n case \"get_consumer_skill\":\n return getConsumerSkill(String(args.skill ?? \"\"), String(args.section ?? \"\"));\n case \"route_consumer_task\":\n return routeTaskTool(String(args.task ?? \"\"), { consumerOnly: true });\n case \"draft_bug_report\":\n return draftBugReport(args);\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 += `Each is tagged \\`[audience]\\` — \\`core\\` = building @godxjp/ui itself, \\`consumer\\` = building an app with it, \\`both\\`. App-devs: use \\`list_consumer_skills\\` to hide core material.\\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} \\`[${s.audience}]\\`\\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 listConsumerSkills(): string {\n const list = SKILLS.filter(isConsumerSkill);\n let out = `# Consumer skills (${list.length}) — building an app WITH @godxjp/ui\\n\\n`;\n out += `Core library-maintenance skills are hidden. Drill in with \\`get_consumer_skill skill=\"...\" section=\"...\"\\`, or route a task with \\`route_consumer_task\\`.\\n\\n`;\n for (const s of list) {\n out += `## ${s.id} — ${s.name} \\`[${s.audience}]\\`\\n`;\n out += `**When to use:** ${s.whenToUse}\\n\\n`;\n out += `**Sections:** ${s.sections.map((sec) => `\\`${sec.id}\\``).join(\", \")}\\n\\n`;\n }\n return out;\n}\n\nfunction getConsumerSkill(skillId: string, sectionId: string): string {\n const skill = findSkill(skillId);\n if (skill && !isConsumerSkill(skill)) {\n return `Skill \"${skillId}\" is CORE-only (building @godxjp/ui itself) and isn't served to app-devs. Use \\`list_consumer_skills\\` for consumer-facing guidance${\n skillId === \"component-discipline\"\n ? ` — the standards you need when composing/extending are folded into \\`compose-a-screen/state-and-a11y\\` and \\`design-to-page/verify\\`.`\n : `.`\n }`;\n }\n // Reuse the shared renderer; it also handles not-found + section listing.\n return getSkillSection(skillId, sectionId);\n}\n\nfunction draftBugReport(args: Record<string, unknown>): string {\n const get = (k: string) => {\n const v = args[k];\n return typeof v === \"string\" ? v.trim() : \"\";\n };\n const summary = get(\"summary\");\n if (!summary) {\n return (\n \"Pass at least `summary` (one-line title). For a useful report also pass `repro`, \" +\n \"`expected`, `actual`, and ideally `component` / `rule` / `version` / `env`. \" +\n \"A vague report a maintainer can't reproduce is not enough.\"\n );\n }\n const repro = get(\"repro\");\n const expected = get(\"expected\");\n const actual = get(\"actual\");\n const component = get(\"component\");\n const rule = typeof args.rule === \"number\" ? args.rule : undefined;\n const version = get(\"version\");\n const env = get(\"env\");\n\n const missing: string[] = [];\n if (!repro) missing.push(\"repro\");\n if (!expected) missing.push(\"expected\");\n if (!actual) missing.push(\"actual\");\n\n const ph = (label: string, val: string) =>\n val ? val : `_(TODO: ${label} — required for a reproducible report)_`;\n\n const title = `[bug] ${summary}`;\n let body = `## Summary\\n\\n${summary}\\n\\n`;\n body += `## Affected\\n\\n`;\n body += component\n ? `- Component: \\`${component}\\` (see \\`get_component name=\"${component}\"\\`)\\n`\n : `- Component: _(n/a)_\\n`;\n body += rule !== undefined ? `- Cardinal rule: #${rule} (see \\`get_rule number=${rule}\\`)\\n` : \"\";\n body += `\\n## Reproduction (minimal)\\n\\n${ph(\"repro\", repro)}\\n\\n`;\n body += `## Expected\\n\\n${ph(\"expected\", expected)}\\n\\n`;\n body += `## Actual\\n\\n${ph(\"actual\", actual)}\\n\\n`;\n body += `## Environment\\n\\n`;\n body += `- @godxjp/ui version: ${version || \"_(TODO: e.g. 12.1.0)_\"}\\n`;\n body += `- Env: ${env || \"_(TODO: browser / OS / framework)_\"}\\n\\n`;\n body += `## Proposed fix\\n\\n_(optional — what the library should do instead)_\\n`;\n\n // Shell-safe single-quote escaping for the gh command.\n const q = (s: string) => `'${s.replace(/'/g, `'\\\\''`)}'`;\n const cmd = `gh issue create --repo godx-jp/godxjp-ui --label bug --title ${q(title)} --body ${q(body)}`;\n\n let out = `# Draft bug report\\n\\n`;\n if (missing.length) {\n out += `> ⚠️ Incomplete — fill ${missing.map((m) => `\\`${m}\\``).join(\", \")} before filing (a report a maintainer can't reproduce will bounce).\\n\\n`;\n }\n out += `**Title:** ${title}\\n\\n`;\n out += `## Issue body (Markdown)\\n\\n${body}\\n`;\n out += `## File it (copy-paste — this tool does NOT run gh)\\n\\n\\`\\`\\`sh\\n${cmd}\\n\\`\\`\\`\\n\\n`;\n out += `_Reminder: don't hand-roll a fake workaround to hide the bug — file this, then mark any minimal local workaround with \\`// TODO(godxui#<n>)\\`._\\n`;\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 | Tier |\\n|---|---|---|\\n`;\n for (const t of items) out += `| \\`${t.name}\\` | ${t.role} | ${t.tier} |\\n`;\n out += \"\\n\";\n }\n return out;\n}\n\nfunction routeTaskTool(task: string, opts?: { consumerOnly?: boolean }): 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, opts);\n let out = `# Routing \"${task}\"${opts?.consumerOnly ? \" (consumer)\" : \"\"}\\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(/<(table|thead|tbody)[\\s>]/, \"Use `<DataTable>` instead of a hand-rolled `<table>` (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 /\\b(?:ml|mr|pl|pr|left|right)-(?:\\d|\\[|auto|px|full|screen)|\\b(?:rounded-[lr]|border-[lr]|text-(?:left|right))\\b/,\n \"Physical direction class — use logical CSS (`ms-/me-`, `ps-/pe-`, `start-/end-`, `rounded-s/e`, `text-start/end`) so the UI flips correctly under RTL (rule: logical CSS).\",\n );\n check(\n /size=[\"']default[\"']/,\n '`size=\"default\"` is not in the controlled vocabulary — use `size` ∈ xs|sm|md|lg.',\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\nconst RULE_COUNT = CARDINAL_RULES.length;\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:\n \"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 (${RULE_COUNT})`,\n description: `The ${RULE_COUNT} binding rules from CLAUDE.md as Markdown.`,\n mimeType: \"text/markdown\",\n },\n {\n uri: \"godx-ui://patterns\",\n name: \"Code patterns\",\n description:\n \"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(\n PATTERNS.map(({ name, tagline, tags }) => ({ name, tagline, tags })),\n null,\n 2,\n );\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","{\n \"name\": \"@godxjp/ui-mcp\",\n \"version\": \"0.19.1\",\n \"description\": \"Model Context Protocol server for @godxjp/ui — gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 34 cardinal rules, copy-paste-ready patterns, 12 design / taste skills synthesised from Leonxlnx/taste-skill, 20+ anti-AI-tell patterns, and a 50-check redesign audit — token-efficient (list → drill-down).\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"godx-ui-mcp\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/godx-jp/godxjp-ui.git\",\n \"directory\": \"mcp\"\n },\n \"homepage\": \"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme\",\n \"license\": \"Apache-2.0\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"inspect\": \"npx @modelcontextprotocol/inspector node dist/index.js\",\n \"type-check\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.29.0\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.1.6\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"godxjp\",\n \"ui\",\n \"design-system\",\n \"react\",\n \"claude\",\n \"cursor\"\n ]\n}\n"],"mappings":"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AAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,Q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","names":["out"]}