@godxjp/ui-mcp 18.6.0 → 18.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +203 -25
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{Server as Le}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as Me}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as Fe,ListResourcesRequestSchema as Be,ListToolsRequestSchema as Ve,ReadResourceRequestSchema as qe}from"@modelcontextprotocol/sdk/types.js";var v=[{name:"PageContainer",group:"layout",tagline:"Mandatory page shell \u2014 EVERY page wraps its content in PageContainer (title/subtitle/extra/footer/breadcrumb).",props:[{name:"title",type:"string",required:!0,description:"Page heading rendered as <h1>."},{name:"subtitle",type:"string",description:"Secondary line beneath the title."},{name:"extra",type:"ReactNode",description:"Action buttons / controls rendered right of the title row."},{name:"footer",type:"ReactNode",description:"Content area pinned below the page body."},{name:"breadcrumb",type:"BreadcrumbItemProp[]",description:"Ordered trail of { label, to? } segments above the title."},{name:"breadcrumbAriaLabel",type:"string",description:`Override the breadcrumb nav landmark's accessible name (defaults to a localized "Breadcrumb"). Required when more than one PageContainer (each with its own breadcrumb) renders on the same page/view \u2014 two nav landmarks sharing one name/role fail landmark-unique.`},{name:"variant",type:'"default" | "narrow" | "flush" | "ghost"',defaultValue:'"default"',description:"Page shell layout; flush removes padding for full-bleed content."},{name:"density",type:'"compact" | "default" | "comfortable"',defaultValue:'"default"',description:"Spacing density across the page subtree."},{name:"preset",type:'"default" | "admin-collection"',defaultValue:'"default"',description:'Whole-page semantic composition. "admin-collection" owns header-to-toolbar rhythm, collection search measure, control height and table density for the subtree through themeable tokens.'},{name:"headerLayout",type:'"stack" | "responsive-inline"',defaultValue:'"stack"',description:'How the title band and `extra` share the header row BELOW the 640px step. "stack" (default) drops `extra` onto its own full-width line under the subtitle. "responsive-inline" keeps it beside the title at the token-owned --page-header-extra-measure (11rem) and lets the title/subtitle wrap \u2014 use it for ONE compact control (a search field, a single primary action) that must stay on the title row at 390px. At >=640px the two arrangements are identical.'},{name:"measure",type:'"default" | "narrow" | "medium"',defaultValue:'"default"',description:'Bounded page MEASURE shared by the header AND the body \u2014 a third axis, ORTHOGONAL to `variant` (chrome) and `headerLayout` (arrangement). "default" applies no cap (the historical fluid page). "narrow" (--page-measure-narrow, 42rem outer \u2192 624px visible surface) and "medium" (--page-measure-medium, 48rem outer \u2192 720px visible surface) cap BOTH bands, so a header `extra` action ends flush with the body surface instead of stranded at the page edge \u2014 unlike variant="narrow", which caps only the body. The package-owned page gutters sit INSIDE the cap, and it is a max, so a 390px viewport stays fluid (358px surface at the 16px compact gutter). The footer is intentionally not capped (its border/background is page chrome when `stickyFooter` pins it).'},{name:"stickyFooter",type:"boolean",defaultValue:"false",description:'Pin footer to viewport bottom on scroll \u2014 pairs with variant="narrow".'},{name:"footerReveal",type:'"always" | "onScroll"',defaultValue:'"always"',description:'When the footer is sticky, control WHEN it shows. "always" keeps it pinned the whole time; "onScroll" hides it until the header scrolls out of view then slides it up \u2014 the standard edit/create save bar. Stays mounted (no reflow \u2192 no jitter).'},{name:"fill",type:"boolean",defaultValue:"false",description:"Grow the body to fill the remaining shell height. Default false = top-packed, content-height (short pages leave no stretched void). Enable for a full-height DataTable, SplitPane, or a chat surface."},{name:"linkComponent",type:"React.ElementType",description:"Link component used for breadcrumb / header links (e.g. an Inertia or React Router `Link`). Defaults to a native `<a>`."}],usage:["DO: Always wrap every page's content in PageContainer \u2014 it is the mandatory page shell. Pass `title` (required, rendered as `<h1>`) for every page; omitting it leaves the page without an accessible heading.","DO: Use the `extra` prop (not a sibling div, not a wrapper) for action buttons or controls that sit right of the title row \u2014 e.g. `extra={<Button>\u65B0\u898F\u4F5C\u6210</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.","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 \u2014 use PageContainer.Inset.","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.","DON'T: Use `density` to change individual control sizes \u2014 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.","DO: Use `preset='admin-collection'` for canonical Admin list pages. It owns the toolbar/search/control/table composition once at PageContainer level; do not repeat widths, heights, cell padding or media queries on child fields and rows.","DON'T: Confuse PageContainer's prop names with the old PageHeader's prop names \u2014 PageContainer uses `subtitle` (not `description`) and `extra` (not `actions`). If you see those legacy names in old code, migrate them to PageContainer.","DO: Leave `fill` off (the default) for ordinary pages \u2014 the body is content-height and top-packed, so a short page on a tall viewport leaves no stretched empty void below the content (the page background simply spans the shell). Only set `fill` when the body itself should occupy the full remaining height: a full-height DataTable, a SplitPane, or a chat surface whose message list scrolls and whose composer is pinned to the bottom via `footer` + `stickyFooter`. DON'T add a manual `min-h-screen` / `flex-1` wrapper or a spacer div to fight or fake this.",'DO: Reach for `headerLayout="responsive-inline"` when a SINGLE compact header control (a member search, one primary action) must stay beside the title at 390px instead of wrapping under the subtitle. Its measure is the token `--page-header-extra-measure` (11rem) \u2014 never a consumer `w-[176px]` or a media query in app CSS. Keep the default `stack` when `extra` holds a toolbar of several buttons; squeezing those into the compact measure only makes them wrap in a narrower box.',"DO: Know the header draws NO bottom divider by default \u2014 it is governed by the semantic token `--page-header-divider` (default `none`). A service theme opts in once, globally, with `--page-header-divider: 1px solid hsl(var(--border));` in its theme CSS. Never re-create the divider with a `border-b` utility on the header or a `<Separator>` under the title; `variant='ghost'` stays divider-less regardless of the token.",'DO: Bound a readable/feed page with `measure="medium"` (720px visible surface) or `measure="narrow"` (624px) \u2014 NEVER a page-local `max-w-[720px]`, a wrapper div, or a consumer CSS variable override. `measure` caps the HEADER and the BODY together, which is the whole point: with `variant="narrow"` the header action stays out at the page edge while the body is 624px, so the action and the card do not share an end edge. Retune the presets once in a service theme via `--page-measure-narrow` / `--page-measure-medium`.','DO: Compose the axes \u2014 `variant="ghost" measure="medium" headerLayout="responsive-inline"` is the canonical quiet notification/inbox feed: ghost owns the quiet header rhythm (no divider, no header bottom pad, tighter title\u2192body gap), `measure` owns the shared 720px measure, `headerLayout` keeps one compact control on the title row at 390px. They are independent props precisely so chrome and measure are no longer one variant axis. DON\'T stack `variant="narrow"` on top of `measure` \u2014 the measure rule simply wins on the body (verified in Chromium: variant="narrow" + measure="medium" resolves the body to 768px, not the intersection), so the `variant="narrow"` is dead weight that only misleads the next reader. `variant="narrow"` is the legacy body-only cap; `measure="narrow"` is the same 624px surface with the header included.'],useCases:["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 \u2014 use `variant='flush'` + `<PageContainer.Inset>` for the Toolbar above the table.","A detail / edit form page where the footer holds Save and Cancel buttons \u2014 use `footer={<Flex direction='row' justify='between' className='w-full'><Button variant='outline'>\u524A\u9664</Button><Button>\u4FDD\u5B58</Button></Flex>}` with `stickyFooter` + `footerReveal='onScroll'` so the save bar slides up only once the header (and its actions) scroll out of view \u2014 the canonical edit/create pattern.","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.","A dashboard page with KPI cards and chart sections \u2014 use `variant='default'` with `children={<Flex direction='col' gap='lg'>\u2026</Flex>}` to vertically stack multiple Card/StatCard sections beneath the page title.","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.","A high-density data reconciliation page where an analyst needs to see maximum rows \u2014 use `density='compact'` to tighten all spacing across the DataTable, Toolbar, and controls in a single prop.","A chat / messaging detail page where the message list should scroll inside the page and the composer stays pinned at the bottom \u2014 use `fill` so the body occupies the full shell height, with `footer={<Composer/>}` + `stickyFooter`. Without `fill` the page would top-pack and the composer would float mid-screen on a tall viewport."],related:["PageContainer.Inset \u2014 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.","PageContainer \u2014 always use PageContainer for new pages; it supports `children`, `footer`, `variant`, `density`, `stickyFooter`, and `fill`. Legacy code using the old prop names (`description` \u2192 `subtitle`, `actions` \u2192 `extra`) should be migrated to PageContainer.","AppShell \u2014 the outer shell that owns the sidebar/topbar layout grid; PageContainer lives inside AppShell's `children` slot. Do not put AppShell inside PageContainer \u2014 the nesting order is AppShell \u2192 PageContainer.","SplitPane \u2014 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."],example:`import { PageContainer, Flex } from "@godxjp/ui/layout";
2
+ import{Server as Le}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as Me}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as Fe,ListResourcesRequestSchema as Be,ListToolsRequestSchema as Ve,ReadResourceRequestSchema as qe}from"@modelcontextprotocol/sdk/types.js";var v=[{name:"PageContainer",group:"layout",tagline:"Mandatory page shell \u2014 EVERY page wraps its content in PageContainer (title/subtitle/extra/footer/breadcrumb).",props:[{name:"title",type:"string",required:!0,description:"Page heading rendered as <h1>."},{name:"subtitle",type:"string",description:"Secondary line beneath the title."},{name:"extra",type:"ReactNode",description:"Action buttons / controls rendered right of the title row."},{name:"footer",type:"ReactNode",description:"Content area pinned below the page body."},{name:"breadcrumb",type:"BreadcrumbItemProp[]",description:"Ordered trail of { label, to? } segments above the title."},{name:"breadcrumbAriaLabel",type:"string",description:`Override the breadcrumb nav landmark's accessible name (defaults to a localized "Breadcrumb"). Required when more than one PageContainer (each with its own breadcrumb) renders on the same page/view \u2014 two nav landmarks sharing one name/role fail landmark-unique.`},{name:"variant",type:'"default" | "narrow" | "flush" | "ghost"',defaultValue:'"default"',description:"Page shell layout; flush removes padding for full-bleed content."},{name:"density",type:'"compact" | "default" | "comfortable"',defaultValue:'"default"',description:"Spacing density across the page subtree."},{name:"preset",type:'"default" | "admin-collection"',defaultValue:'"default"',description:'Whole-page semantic composition. "admin-collection" owns header-to-toolbar rhythm, collection search measure, control height and table density for the subtree through themeable tokens.'},{name:"headerLayout",type:'"stack" | "responsive-inline"',defaultValue:'"stack"',description:'How the title band and `extra` share the header row BELOW the 640px step. "stack" (default) drops `extra` onto its own full-width line under the subtitle. "responsive-inline" keeps it beside the title at the token-owned --page-header-extra-measure (11rem) and lets the title/subtitle wrap \u2014 use it for ONE compact control (a search field, a single primary action) that must stay on the title row at 390px. At >=640px the two arrangements are identical.'},{name:"measure",type:'"default" | "narrow" | "medium"',defaultValue:'"default"',description:'Bounded page MEASURE shared by the header AND the body \u2014 a third axis, ORTHOGONAL to `variant` (chrome) and `headerLayout` (arrangement). "default" applies no cap (the historical fluid page). "narrow" (--page-measure-narrow, 42rem outer \u2192 624px visible surface) and "medium" (--page-measure-medium, 48rem outer \u2192 720px visible surface) cap BOTH bands, so a header `extra` action ends flush with the body surface instead of stranded at the page edge \u2014 unlike variant="narrow", which caps only the body. The package-owned page gutters sit INSIDE the cap, and it is a max, so a 390px viewport stays fluid (358px surface at the 16px compact gutter). The footer is intentionally not capped (its border/background is page chrome when `stickyFooter` pins it).'},{name:"stickyFooter",type:"boolean",defaultValue:"false",description:'Pin footer to viewport bottom on scroll \u2014 pairs with variant="narrow".'},{name:"footerReveal",type:'"always" | "onScroll"',defaultValue:'"always"',description:'When the footer is sticky, control WHEN it shows. "always" keeps it pinned the whole time; "onScroll" hides it until the header scrolls out of view then slides it up \u2014 the standard edit/create save bar. Stays mounted (no reflow \u2192 no jitter).'},{name:"fill",type:"boolean",defaultValue:"false",description:"Grow the body to fill the remaining shell height. Default false = top-packed, content-height (short pages leave no stretched void). Enable for a full-height DataTable, SplitPane, or a chat surface."},{name:"meta",type:"ReactNode",description:"Status/meta band rendered INLINE with the <h1> (a Badge tone, a record id, a timestamp). Forwarded verbatim to PageHeader. Omit it and the title band emits its historical bare-<h1> DOM, so no existing page moves."},{name:"headerLoading",type:"boolean",defaultValue:"false",description:"Skeletonise the TITLE BAND only while the page's record resolves (title/subtitle placeholders + aria-busy; the <h1> stays in the outline with an sr-only accessible name). Breadcrumbs and `extra` stay live \u2014 they come from the route, not the record. This is not a page-wide loading flag; use DataState for the body."},{name:"linkComponent",type:"React.ElementType",description:"Link component used for breadcrumb / header links (e.g. an Inertia or React Router `Link`). Defaults to a native `<a>`."}],usage:["DO: Always wrap every page's content in PageContainer \u2014 it is the mandatory page shell. Pass `title` (required, rendered as `<h1>`) for every page; omitting it leaves the page without an accessible heading.","DO: Use the `extra` prop (not a sibling div, not a wrapper) for action buttons or controls that sit right of the title row \u2014 e.g. `extra={<Button>\u65B0\u898F\u4F5C\u6210</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.","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 \u2014 use PageContainer.Inset.","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.","DON'T: Use `density` to change individual control sizes \u2014 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.","DO: Use `preset='admin-collection'` for canonical Admin list pages. It owns the toolbar/search/control/table composition once at PageContainer level; do not repeat widths, heights, cell padding or media queries on child fields and rows.","DO: Use `subtitle` (not `description`) and `extra` (not `actions`) \u2014 those are the names both PageContainer and the standalone PageHeader take. If you see `description` / `actions` in old code, migrate them.","DO: Reach for the standalone `PageHeader` export ONLY when a title band must render outside a page shell (a Sheet detail, a MasterDetail detail pane, a tab body). Inside a page, keep using PageContainer \u2014 it renders that very component internally, so the geometry is identical and a hand-mounted PageHeader inside a PageContainer would produce two `<h1>`s.","DO: Leave `fill` off (the default) for ordinary pages \u2014 the body is content-height and top-packed, so a short page on a tall viewport leaves no stretched empty void below the content (the page background simply spans the shell). Only set `fill` when the body itself should occupy the full remaining height: a full-height DataTable, a SplitPane, or a chat surface whose message list scrolls and whose composer is pinned to the bottom via `footer` + `stickyFooter`. DON'T add a manual `min-h-screen` / `flex-1` wrapper or a spacer div to fight or fake this.",'DO: Reach for `headerLayout="responsive-inline"` when a SINGLE compact header control (a member search, one primary action) must stay beside the title at 390px instead of wrapping under the subtitle. Its measure is the token `--page-header-extra-measure` (11rem) \u2014 never a consumer `w-[176px]` or a media query in app CSS. Keep the default `stack` when `extra` holds a toolbar of several buttons; squeezing those into the compact measure only makes them wrap in a narrower box.',"DO: Know the header draws NO bottom divider by default \u2014 it is governed by the semantic token `--page-header-divider` (default `none`). A service theme opts in once, globally, with `--page-header-divider: 1px solid hsl(var(--border));` in its theme CSS. Never re-create the divider with a `border-b` utility on the header or a `<Separator>` under the title; `variant='ghost'` stays divider-less regardless of the token.",'DO: Bound a readable/feed page with `measure="medium"` (720px visible surface) or `measure="narrow"` (624px) \u2014 NEVER a page-local `max-w-[720px]`, a wrapper div, or a consumer CSS variable override. `measure` caps the HEADER and the BODY together, which is the whole point: with `variant="narrow"` the header action stays out at the page edge while the body is 624px, so the action and the card do not share an end edge. Retune the presets once in a service theme via `--page-measure-narrow` / `--page-measure-medium`.','DO: Compose the axes \u2014 `variant="ghost" measure="medium" headerLayout="responsive-inline"` is the canonical quiet notification/inbox feed: ghost owns the quiet header rhythm (no divider, no header bottom pad, tighter title\u2192body gap), `measure` owns the shared 720px measure, `headerLayout` keeps one compact control on the title row at 390px. They are independent props precisely so chrome and measure are no longer one variant axis. DON\'T stack `variant="narrow"` on top of `measure` \u2014 the measure rule simply wins on the body (verified in Chromium: variant="narrow" + measure="medium" resolves the body to 768px, not the intersection), so the `variant="narrow"` is dead weight that only misleads the next reader. `variant="narrow"` is the legacy body-only cap; `measure="narrow"` is the same 624px surface with the header included.'],useCases:["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 \u2014 use `variant='flush'` + `<PageContainer.Inset>` for the Toolbar above the table.","A detail / edit form page where the footer holds Save and Cancel buttons \u2014 use `footer={<Flex direction='row' justify='between' className='w-full'><Button variant='outline'>\u524A\u9664</Button><Button>\u4FDD\u5B58</Button></Flex>}` with `stickyFooter` + `footerReveal='onScroll'` so the save bar slides up only once the header (and its actions) scroll out of view \u2014 the canonical edit/create pattern.","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.","A dashboard page with KPI cards and chart sections \u2014 use `variant='default'` with `children={<Flex direction='col' gap='lg'>\u2026</Flex>}` to vertically stack multiple Card/StatCard sections beneath the page title.","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.","A high-density data reconciliation page where an analyst needs to see maximum rows \u2014 use `density='compact'` to tighten all spacing across the DataTable, Toolbar, and controls in a single prop.","A chat / messaging detail page where the message list should scroll inside the page and the composer stays pinned at the bottom \u2014 use `fill` so the body occupies the full shell height, with `footer={<Composer/>}` + `stickyFooter`. Without `fill` the page would top-pack and the composer would float mid-screen on a tall viewport."],related:["PageContainer.Inset \u2014 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.","PageContainer \u2014 always use PageContainer for new pages; it supports `children`, `footer`, `variant`, `density`, `stickyFooter`, and `fill`. Legacy code using the old prop names (`description` \u2192 `subtitle`, `actions` \u2192 `extra`) should be migrated to PageContainer.","AppShell \u2014 the outer shell that owns the sidebar/topbar layout grid; PageContainer lives inside AppShell's `children` slot. Do not put AppShell inside PageContainer \u2014 the nesting order is AppShell \u2192 PageContainer.","SplitPane \u2014 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."],example:`import { PageContainer, Flex } from "@godxjp/ui/layout";
3
3
  import { Button } from "@godxjp/ui/general";
4
4
 
5
5
  export default function OrdersPage() {
@@ -13,7 +13,21 @@ export default function OrdersPage() {
13
13
  <Flex direction="col" gap="lg">{/* page content */}</Flex>
14
14
  </PageContainer>
15
15
  );
16
- }`,storyPath:"layout/PageContainer.stories.tsx",rules:[23]},{name:"Flex",group:"layout",tagline:"Token-spaced flex primitive with explicit direction, alignment, justification, and wrapping controls.",props:[{name:"direction",type:'"row" | "col"',defaultValue:'"row"',description:"Main axis direction. Defaults to the CSS platform initial value, row; use col explicitly for vertical stacks."},{name:"gap",type:'"xs" | "sm" | "md" | "lg" | "xl"',defaultValue:'"md"',description:"Token gap between children, shared with other layout primitives."},{name:"align",type:'"start" | "center" | "end" | "stretch" | "baseline"',description:"Cross-axis alignment, emitted as a data attribute for the layout CSS."},{name:"justify",type:'"start" | "center" | "end" | "between" | "around" | "evenly"',description:"Main-axis distribution, emitted as a data attribute for the layout CSS."},{name:"wrap",type:"boolean",defaultValue:"false",description:"Allows children to wrap onto additional flex lines."},{name:"hideBelow",type:'"sm" | "md" | "lg" | "xl"',description:'Drop this region below a canonical breakpoint step (sm 40rem, md 48rem, lg 64rem, xl 80rem). THE public way to make a region responsive without a page-local media query \u2014 a public header hides its anchor navigation with hideBelow="md" (gh#252). Omitted by default, so no attribute is emitted and no rule matches. display:none also removes it from the a11y tree, so keep its destinations reachable elsewhere (a footer nav) at that width.'},{name:"hideFrom",type:'"sm" | "md" | "lg" | "xl"',description:"Inverse of hideBelow \u2014 drop the region FROM that step upwards, i.e. keep it only on the narrow side (a compact-only affordance)."}],usage:['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"`.',"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.",'DO use `direction="row"` with `wrap` for responsive control rows, chip clusters, and action groups that need more control than simple row composition.','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.',"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.","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."],useCases:["Toolbar internals where controls should sit in a row, wrap on narrow widths, and stay vertically centered.","Card headers that need title content on the left and actions on the right via `justify='between'` without hand-rolling flex utility classes.","Empty-state or loading blocks that center content on both axes using `align='center'` and `justify='center'`.","Form sub-sections where a vertical group needs stretched children or centered helper content beyond what a plain column Flex provides.","Badge, chip, or tag clusters where wrapping is required but the caller also needs explicit gap control.","Low-level layout composition inside custom components where raw flex classes would duplicate the primitive."],related:["Flex `direction='col'` \u2014 the standard pattern for ordinary vertical block spacing; use explicit `align`, `justify`, or `wrap` props when you need more control.","Flex `direction='row'` \u2014 the standard pattern for simple horizontal groups; add `wrap` and `align='center'` for the typical row with wrapped centered items.","ResponsiveGrid \u2014 use for equal-width, multi-column tile layouts. Flex arranges children on one flex axis and does not provide column-count behavior.","PageContainer \u2014 page scaffold and padding context. Flex is an inner layout primitive used inside page sections, cards, dialogs, and toolbars."],example:`import { Flex } from "@godxjp/ui/layout";
16
+ }`,storyPath:"layout/PageContainer.stories.tsx",rules:[23]},{name:"PageHeader",group:"layout",tagline:"The canonical page title band (breadcrumb \xB7 h1 \xB7 subtitle \xB7 meta \xB7 actions) \u2014 the SAME component PageContainer renders, exported for use outside a page shell.",props:[{name:"title",type:"ReactNode",required:!0,description:"Heading rendered as the <h1> of the surface."},{name:"subtitle",type:"ReactNode",description:"Secondary line beneath the title."},{name:"meta",type:"ReactNode",description:"Status/meta band rendered INLINE with the <h1> \u2014 a Badge tone, a record id, a timestamp. Wraps below the title at 390px instead of squeezing the title column. Omitted \u2192 no band wrapper is emitted at all."},{name:"extra",type:"ReactNode",description:"Trailing action region \u2014 buttons, a search field, an overflow menu."},{name:"breadcrumb",type:"BreadcrumbItemProp[]",description:"Ordered trail of { label, to? } segments above the title. The last item renders unlinked with aria-current='page'."},{name:"breadcrumbLabel",type:"string",description:'Override the breadcrumb nav landmark\'s accessible name (defaults to a localized "Breadcrumb"). Required when two headers with breadcrumbs render on one view \u2014 two nav landmarks sharing a name/role fail landmark-unique. `breadcrumbAriaLabel` is the kebab/DOM-style alias.'},{name:"layout",type:'"stack" | "responsive-inline"',defaultValue:'"stack"',description:'How the title band and `extra` share the row BELOW the 640px step. "stack" drops `extra` onto its own full-width line; "responsive-inline" keeps it beside the title at the token-owned --page-header-extra-measure. Identical at >=640px. (PageContainer spells this prop `headerLayout`.)'},{name:"loading",type:"boolean",defaultValue:"false",description:"Pending state for the TITLE BAND. Renders the title/subtitle as skeletons and marks the header aria-busy, keeping the <h1> in the heading outline with an sr-only accessible name (an empty heading is an axe violation). Breadcrumbs and `extra` are NOT skeletonised \u2014 they come from the route, not the record."},{name:"linkComponent",type:"React.ElementType",description:"Link component used for breadcrumb links (an Inertia or React Router `Link`). Defaults to a native `<a>`."}],usage:["DON'T: Put a PageHeader inside a PageContainer. PageContainer ALREADY renders this exact component from its own `title`/`subtitle`/`meta`/`extra`/`breadcrumb` props \u2014 nesting one would emit two `<h1>`s on one page. Inside a page, pass the props to PageContainer.","DO: Use the standalone export only where there is no page shell to carry the band: a Sheet/Drawer detail surface, a MasterDetail detail pane, a tab body with its own title, an embedded widget. That is the whole reason it exists \u2014 so those surfaces get the package's header geometry instead of a consumer-local `.page-header` stylesheet.","DO: Pass a status Badge through `meta`, not into `title`. `meta` is a separate inline band, so a long JA/VI title wraps without dragging the badge with it, and the `<h1>` accessible name stays the title alone rather than 'Invoice #4021 Overdue'.","DO: Drive the pending band with `loading` instead of conditionally rendering the header. Unmounting the header removes the page's only level-1 heading mid-load, which breaks the outline screen-reader users navigate by; `loading` keeps the `<h1>` with an sr-only name and marks the band aria-busy.","DON'T: Use `loading` as a page-wide flag. It skeletonises the title band ONLY. The body's loading/empty/error states belong to DataState (@godxjp/ui/query) or Skeleton; a page the user may NOT see belongs to ErrorSurface \u2014 never render a header whose title and breadcrumbs leak a forbidden resource's name.","DON'T: Add a bottom rule with a `border-b` utility. The divider is the semantic token `--page-header-divider` (default `none`); a service theme opts in once globally."],useCases:["A MasterDetail detail pane whose selected record needs its own title, status Badge and action row, while the page-level PageContainer title names the collection.","A Sheet or Drawer detail surface that must present the same title/subtitle/actions rhythm as a full page without being one.","A tab body inside a settings page where each tab carries its own heading and primary action.","A record page whose title arrives asynchronously \u2014 mount the header immediately with `loading` so the heading outline and breadcrumb trail are stable from first paint."],related:["PageContainer \u2014 renders this component internally and adds the page chrome (padding, measure, body rhythm, footer). Use PageContainer for anything that IS a page; use PageHeader only outside a page shell.","ErrorSurface \u2014 the canonical whole-surface contract for permission-denied / error / maintenance states. PageHeader has no `denied` or `error` state on purpose: a title band for a resource the user may not see leaks its name.","Banner \u2014 page-level status strip that sits ABOVE the header (a maintenance notice, a trial-expiry warning), not inside it.","Breadcrumb \u2014 the standalone trail primitive. PageHeader renders its own trail from the `breadcrumb` array; do not nest a Breadcrumb inside it."],example:`import { PageHeader, MasterDetail } from "@godxjp/ui/layout";
17
+ import { Badge } from "@godxjp/ui/data-display";
18
+ import { Button } from "@godxjp/ui/general";
19
+
20
+ export function InvoiceDetail({ invoice, isLoading }) {
21
+ return (
22
+ <PageHeader
23
+ title={invoice?.number}
24
+ subtitle={invoice?.customer}
25
+ meta={<Badge tone="warning">{invoice?.status}</Badge>}
26
+ extra={<Button>\u518D\u9001\u4FE1</Button>}
27
+ loading={isLoading}
28
+ />
29
+ );
30
+ }`,storyPath:"layout/page-header.tsx",rules:[23]},{name:"Flex",group:"layout",tagline:"Token-spaced flex primitive with explicit direction, alignment, justification, and wrapping controls.",props:[{name:"direction",type:'"row" | "col"',defaultValue:'"row"',description:"Main axis direction. Defaults to the CSS platform initial value, row; use col explicitly for vertical stacks."},{name:"gap",type:'"xs" | "sm" | "md" | "lg" | "xl"',defaultValue:'"md"',description:"Token gap between children, shared with other layout primitives."},{name:"align",type:'"start" | "center" | "end" | "stretch" | "baseline"',description:"Cross-axis alignment, emitted as a data attribute for the layout CSS."},{name:"justify",type:'"start" | "center" | "end" | "between" | "around" | "evenly"',description:"Main-axis distribution, emitted as a data attribute for the layout CSS."},{name:"wrap",type:"boolean",defaultValue:"false",description:"Allows children to wrap onto additional flex lines."},{name:"hideBelow",type:'"sm" | "md" | "lg" | "xl"',description:'Drop this region below a canonical breakpoint step (sm 40rem, md 48rem, lg 64rem, xl 80rem). THE public way to make a region responsive without a page-local media query \u2014 a public header hides its anchor navigation with hideBelow="md" (gh#252). Omitted by default, so no attribute is emitted and no rule matches. display:none also removes it from the a11y tree, so keep its destinations reachable elsewhere (a footer nav) at that width.'},{name:"hideFrom",type:'"sm" | "md" | "lg" | "xl"',description:"Inverse of hideBelow \u2014 drop the region FROM that step upwards, i.e. keep it only on the narrow side (a compact-only affordance)."}],usage:['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"`.',"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.",'DO use `direction="row"` with `wrap` for responsive control rows, chip clusters, and action groups that need more control than simple row composition.','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.',"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.","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."],useCases:["Toolbar internals where controls should sit in a row, wrap on narrow widths, and stay vertically centered.","Card headers that need title content on the left and actions on the right via `justify='between'` without hand-rolling flex utility classes.","Empty-state or loading blocks that center content on both axes using `align='center'` and `justify='center'`.","Form sub-sections where a vertical group needs stretched children or centered helper content beyond what a plain column Flex provides.","Badge, chip, or tag clusters where wrapping is required but the caller also needs explicit gap control.","Low-level layout composition inside custom components where raw flex classes would duplicate the primitive."],related:["Flex `direction='col'` \u2014 the standard pattern for ordinary vertical block spacing; use explicit `align`, `justify`, or `wrap` props when you need more control.","Flex `direction='row'` \u2014 the standard pattern for simple horizontal groups; add `wrap` and `align='center'` for the typical row with wrapped centered items.","ResponsiveGrid \u2014 use for equal-width, multi-column tile layouts. Flex arranges children on one flex axis and does not provide column-count behavior.","PageContainer \u2014 page scaffold and padding context. Flex is an inner layout primitive used inside page sections, cards, dialogs, and toolbars."],example:`import { Flex } from "@godxjp/ui/layout";
17
31
  import { Button } from "@godxjp/ui/general";
18
32
 
19
33
  <Flex direction="row" gap="sm" align="center" justify="between" wrap>
@@ -48,7 +62,7 @@ const sidebar = (
48
62
 
49
63
  export function CrmLayout({ children }: { content: React.ReactNode }) {
50
64
  return <AppShell sidebar={sidebar}>{children}</AppShell>;
51
- }`,storyPath:"layout/AppShell.stories.tsx",rules:[23]},{name:"AuthShell",group:"layout",tagline:"Centred auth/login page shell \u2014 brand bar (top) + centred card (main) + footer, over min-h-dvh, at comfortable control density.",props:[{name:"children",type:"ReactNode",required:!0,description:"Centred content \u2014 typically a single auth <Card> holding the form."},{name:"brand",type:"ReactNode",description:"Brand bar slot pinned to the top (e.g. a <Logo> / product mark)."},{name:"footer",type:"ReactNode",description:"Footer slot pinned to the bottom (legal links, locale switch, support)."},{name:"variant",type:'"default" | "canonical"',defaultValue:'"default"',description:'Visual contract for the auth surface. "canonical" applies the shared DXS compact geometry (36px controls, 22.5rem/360px card measure, responsive page insets, tighter field labels) through component tokens. "default" keeps the comfortable 44px shell with the 24rem card.'},{name:"preset",type:'"default" | "login" | "device-authorization" | "context-selection" | "account-recovery"',defaultValue:'"default"',description:'Named flow GEOMETRY \u2014 the package-owned layout contract for a canonical hosted-identity flow. "login" (gh#237) anchors the 360px SCR-001 card at x=540/332/15 and y=363/363/353 for 1440x900, 1024x900 and 390x844; its fixed identity slot absorbs standalone, one-line requester and wrapped two-line requester states without truncating data. "device-authorization" (gh#220) = a 380px card at 1440/1024 with a 5px inline page gutter at 390. "context-selection" (gh#217) = a 25rem card on desktop/tablet, edge-to-edge on mobile, plus tokenized section rhythm. "account-recovery" (gh#233) = the 27rem/432px SCR-008 recovery/MFA panel with a 15px mobile gutter. ORTHOGONAL to `variant`, so `variant="canonical" preset="login"` keeps canonical control chrome while the preset owns layout. Selecting a preset REPLACES consumer-side geometry overrides.'},{name:"density",type:'"comfortable" | "compact"',description:'Vertical density scoped to auth-card descendants. Defaults to "compact" under variant="canonical" and "comfortable" otherwise.'},{name:"className",type:"string",description:"Extra CSS classes merged onto the shell root."}],usage:["DO pass a single <Card> (with the form inside <CardContent>) as `children` \u2014 AuthShell centres it and constrains its width via `--auth-shell-card-max-width`; do NOT hand-roll a `.auth-shell-main` / `.ui-auth-scope` wrapper.",'DO use `variant="canonical" preset="login"` for SCR-001 and pass <AuthIdentity>, <Card>, <AuthFooter> as direct children in that order (an anchor may wrap AuthIdentity). The preset owns the identity slot, card anchor, 20px section rhythm and compact card block inset for standalone and real requester states. Do not wrap the three sections in a consumer Flex/Stack or the semantic grid cannot anchor them.','DO select a `preset` instead of overriding geometry: `preset="login"` for the stable SCR-001 identity/card/footer anchor, `preset="device-authorization"` for the 380px OAuth device-grant measure, `preset="context-selection"` for the 25rem organisation/context picker, `preset="account-recovery"` for the 432px SCR-008 recovery/MFA panel. Page-local width/inset/vertical-offset variables are the exact anti-pattern these presets replace (gh#217/gh#220/gh#233/gh#237).','DO build the password-recovery and sign-in MFA CHALLENGE panels as a COMPOSITION inside `preset="account-recovery"` \u2014 there is NO PasswordRecoveryPanel and NO MfaChallengePanel component (gh#233 Gate 0): Card > CardHeader(CardTitle + CardDescription, INSIDE the bordered surface) > CardContent > AuthStack[ Alert notice \xB7 FormField fields \xB7 Button fullWidth \xB7 Flex justify="between" wrap fallback row ]. Do NOT put AuthIdentity above the panel there (it always renders the hosted mark), and NEVER reuse TwoFactorSetup \u2014 that is the ENROLLMENT dialog, not a sign-in challenge. See the `auth-recovery-panels` pattern.','DO combine `variant` and `preset` \u2014 they are orthogonal: `variant` owns control density + heading size, `preset` owns the page measure. `variant="canonical" preset="device-authorization"` is the canonical device screen.','DO let `preset="context-selection"` space the auth column: it turns the card slot into a flex column with a tokenized `--auth-shell-card-stack-gap`, so an intro (<AuthIdentity>), the choice <Card> and a trailing "remember" row pass as three siblings with NO page-local spacing.',"DO NOT add a page-local width, inset or colour to hit an artboard \u2014 if a measure is missing, it is a library gap: a new preset or token, never consumer CSS (rules #44/#45).","DO put the product/brand mark in `brand` (a <Logo> or an <Avatar>) \u2014 it renders as the top banner landmark; omit it and the banner is not rendered.","DO use `footer` for compliance/legal/support links or a locale switch \u2014 it renders as the contentinfo landmark below the card.","DO wrap the card in <Reveal> for the entrance animation (`<AuthShell><Reveal><Card/></Reveal></AuthShell>`) \u2014 Reveal honours prefers-reduced-motion; AuthShell itself stays layout-only.","DO NOT re-scope control height or heading size in the app \u2014 AuthShell already sets the comfortable control tier (44px, WCAG touch floor) and the larger auth heading via `--auth-shell-control-height` / `--auth-shell-heading-size`; a service retunes those tokens, not a bespoke class.","DO tune the COMPACT auth card through its three independent knobs, never a consumer selector on `[data-slot=\"card-content\"]` (gh#232): `--auth-shell-compact-card-inset` = the inline column, `--auth-shell-card-padding-block-compact` = the card's block (top/bottom) padding \u2014 it is wired to the card's `--card-space-shell-y` and really moves CardContent's block edges \u2014 and `--auth-shell-card-body-gap-compact` = the header\u2194body gap. Each defaults to today's canonical rhythm, so overriding one moves ONLY that axis.","DO NOT nest AuthShell inside AppShell (or vice-versa) \u2014 AuthShell is the ROOT shell for unauthenticated pages (login/mfa/passkey/device/reset); AppShell is for the authenticated app."],useCases:['Canonical Login (SCR-001): <AuthShell variant="canonical" preset="login"> with direct AuthIdentity \xB7 Card \xB7 AuthFooter children; the card remains anchored when requester is absent, one line or wraps to two lines (gh#237).',"Login page: <AuthShell brand={<Logo/>} footer={<AuthFooter/>}> wrapping a <Card> with the email/password form and a primary <Button fullWidth>.","MFA / passkey / device-authorisation step: same shell, a <Card> with the one-time-code <InputOTP> or a passkey prompt.",'OAuth device-grant screen (SCR-004): <AuthShell variant="canonical" preset="device-authorization"> \u2014 a 380px card at 1440/1024 and a 5px inline gutter at 390, with zero page-local CSS (gh#220).','Organisation / context selection (/select-context): <AuthShell variant="canonical" preset="context-selection" brand={<Logo mark="godx" />}> with an <AuthIdentity> intro, a <Card><CardContent flush> list of <ListRow as="li"> organisations, and a trailing "remember this choice" <Checkbox> \u2014 the preset spaces the three sections (gh#217).',"Password reset / forgot-password / accept-invite: the centred single-card flow with a brand bar and a legal footer.",'SSO landing / success confirmation: pair with an <EmptyState tone="success"> inside the card for an approved-device confirmation.'],related:["AppShell \u2014 the shell for AUTHENTICATED app pages (sidebar + topbar + main). AuthShell is its unauthenticated counterpart (brand bar + centred card + footer). Never nest the two.","Reveal \u2014 wrap the auth <Card> in <Reveal> for the entrance animation; AuthShell delegates motion (and prefers-reduced-motion handling) to it rather than baking an animation in.","Card \u2014 the canonical container for the auth form; place the form inside <CardContent>. AuthShell centres and width-constrains it.",'EmptyState \u2014 with `tone="success"` for a confirmation card inside the shell (e.g. device approved).','AuthIdentity / AuthFooter / AuthStack / AuthDivider \u2014 the auth composites that fill the shell: the GoDX identity mark + heading + requesting-client line, the mono legal footer (its `locale` slot takes an <AppSettingPicker kind="locale" appearance="labeled" compact />), the 12px section rhythm, and the labelled "or" rule.','ListRow \u2014 compose the organisation choice list for `preset="context-selection"` as <Card><CardContent flush><ul> of <ListRow as="li">: shared row dividers, no per-row card outline. There is no separate OrganizationChoiceList component \u2014 that is a composition pattern (rule #46), not a framework component.'],example:`import { AuthShell, AuthIdentity, AuthFooter } from "@godxjp/ui/layout";
65
+ }`,storyPath:"layout/AppShell.stories.tsx",rules:[23]},{name:"AuthShell",group:"layout",tagline:"Centred auth/login page shell \u2014 brand bar (top) + centred card (main) + footer, over min-h-dvh, at comfortable control density.",props:[{name:"children",type:"ReactNode",required:!0,description:"Centred content \u2014 typically a single auth <Card> holding the form."},{name:"brand",type:"ReactNode",description:"Brand bar slot pinned to the top (e.g. a <Logo> / product mark)."},{name:"footer",type:"ReactNode",description:"Footer slot pinned to the bottom (legal links, locale switch, support)."},{name:"variant",type:'"default" | "canonical"',defaultValue:'"default"',description:'Visual contract for the auth surface. "canonical" applies the shared DXS compact geometry (36px controls, 22.5rem/360px card measure, responsive page insets, tighter field labels) through component tokens. "default" keeps the comfortable 44px shell with the 24rem card.'},{name:"preset",type:'"default" | "login" | "registration" | "device-authorization" | "context-selection" | "account-recovery"',defaultValue:'"default"',description:'Named flow GEOMETRY \u2014 the package-owned layout contract for a canonical hosted-identity flow. "login" (gh#237) anchors the 360px SCR-001 card at x=540/332/15 and y=363/363/353 for 1440x900, 1024x900 and 390x844; its fixed identity slot absorbs standalone, one-line requester and wrapped two-line requester states without truncating data. "device-authorization" (gh#220) = a 380px card at 1440/1024 with a 5px inline page gutter at 390. "registration" (gh#256) = the 360px sign-up measure with a 15px inline gutter at 390 (the same page rhythm as "login", so sign-in to sign-up never jumps on a phone). It is the ONLY START-aligned preset: a sign-up card is the tallest surface in the set (name/email/password/confirm/strength/consent/submit/providers) and a vertically centred tall card overflows ABOVE the scroll origin on a short viewport, putting its first field out of reach. It is also the only preset with its own footer-clearance knob, so the legal/consent footer never sits flush against the submit button; it carries the full password form AND the pending-email confirmation state with no consumer geometry CSS. "context-selection" (gh#217) = a 25rem card on desktop/tablet, edge-to-edge on mobile, plus tokenized section rhythm. "account-recovery" (gh#233) = the 27rem/432px SCR-008 recovery/MFA panel with a 15px mobile gutter. ORTHOGONAL to `variant`, so `variant="canonical" preset="login"` keeps canonical control chrome while the preset owns layout. Selecting a preset REPLACES consumer-side geometry overrides.'},{name:"density",type:'"comfortable" | "compact"',description:'Vertical density scoped to auth-card descendants. Defaults to "compact" under variant="canonical" and "comfortable" otherwise.'},{name:"className",type:"string",description:"Extra CSS classes merged onto the shell root."}],usage:["DO pass a single <Card> (with the form inside <CardContent>) as `children` \u2014 AuthShell centres it and constrains its width via `--auth-shell-card-max-width`; do NOT hand-roll a `.auth-shell-main` / `.ui-auth-scope` wrapper.",'DO use `variant="canonical" preset="login"` for SCR-001 and pass <AuthIdentity>, <Card>, <AuthFooter> as direct children in that order (an anchor may wrap AuthIdentity). The preset owns the identity slot, card anchor, 20px section rhythm and compact card block inset for standalone and real requester states. Do not wrap the three sections in a consumer Flex/Stack or the semantic grid cannot anchor them.','DO select a `preset` instead of overriding geometry: `preset="login"` for the stable SCR-001 identity/card/footer anchor, `preset="registration"` for the sign-up form and its pending-email state, `preset="device-authorization"` for the 380px OAuth device-grant measure, `preset="context-selection"` for the 25rem organisation/context picker, `preset="account-recovery"` for the 432px SCR-008 recovery/MFA panel. Page-local width/inset/vertical-offset variables are the exact anti-pattern these presets replace (gh#217/gh#220/gh#233/gh#237).','DO build the SOCIAL / PROVIDER ACTION row as a COMPOSITION \u2014 there is NO SocialLinks component (gh#256 Gate 0): `<AuthDivider label="or" />` followed by a `Flex direction="col" gap="sm"` of real `Button variant="outline"` with the provider glyph as an aria-hidden icon. The package deliberately does not own it: which providers a product offers, in what order, and what consent they imply are product decisions, and a component would have to invent them. `disabled` / `loading` are the Button\'s own props \u2014 do not add a provider-specific API.','DO build the ORGANIZATION CHOICE LIST as a COMPOSITION \u2014 there is NO OrganizationChoiceList component (gh#256 Gate 0): `Card` > `CardContent flush` > a `<ul>` of `ListRow as="li"` (leading Avatar, title, description, trailing Button). `CardContent flush` is what gives shared row dividers instead of a card outline per row. Its states are existing exports, never bespoke markup: Skeleton rows for loading, `EmptyState` for no invitations, `Alert tone="destructive"` for a failed fetch and `Alert tone="warning"` for permission-denied. See the auth-shell-context and auth-shell-registration frames.','DO build the password-recovery and sign-in MFA CHALLENGE panels as a COMPOSITION inside `preset="account-recovery"` \u2014 there is NO PasswordRecoveryPanel and NO MfaChallengePanel component (gh#233 Gate 0): Card > CardHeader(CardTitle + CardDescription, INSIDE the bordered surface) > CardContent > AuthStack[ Alert notice \xB7 FormField fields \xB7 Button fullWidth \xB7 Flex justify="between" wrap fallback row ]. Do NOT put AuthIdentity above the panel there (it always renders the hosted mark), and NEVER reuse TwoFactorSetup \u2014 that is the ENROLLMENT dialog, not a sign-in challenge. See the `auth-recovery-panels` pattern.','DO combine `variant` and `preset` \u2014 they are orthogonal: `variant` owns control density + heading size, `preset` owns the page measure. `variant="canonical" preset="device-authorization"` is the canonical device screen.','DO let `preset="context-selection"` space the auth column: it turns the card slot into a flex column with a tokenized `--auth-shell-card-stack-gap`, so an intro (<AuthIdentity>), the choice <Card> and a trailing "remember" row pass as three siblings with NO page-local spacing.',"DO NOT add a page-local width, inset or colour to hit an artboard \u2014 if a measure is missing, it is a library gap: a new preset or token, never consumer CSS (rules #44/#45).","DO put the product/brand mark in `brand` (a <Logo> or an <Avatar>) \u2014 it renders as the top banner landmark; omit it and the banner is not rendered.","DO use `footer` for compliance/legal/support links or a locale switch \u2014 it renders as the contentinfo landmark below the card.","DO wrap the card in <Reveal> for the entrance animation (`<AuthShell><Reveal><Card/></Reveal></AuthShell>`) \u2014 Reveal honours prefers-reduced-motion; AuthShell itself stays layout-only.","DO NOT re-scope control height or heading size in the app \u2014 AuthShell already sets the comfortable control tier (44px, WCAG touch floor) and the larger auth heading via `--auth-shell-control-height` / `--auth-shell-heading-size`; a service retunes those tokens, not a bespoke class.","DO tune the COMPACT auth card through its three independent knobs, never a consumer selector on `[data-slot=\"card-content\"]` (gh#232): `--auth-shell-compact-card-inset` = the inline column, `--auth-shell-card-padding-block-compact` = the card's block (top/bottom) padding \u2014 it is wired to the card's `--card-space-shell-y` and really moves CardContent's block edges \u2014 and `--auth-shell-card-body-gap-compact` = the header\u2194body gap. Each defaults to today's canonical rhythm, so overriding one moves ONLY that axis.","DO NOT nest AuthShell inside AppShell (or vice-versa) \u2014 AuthShell is the ROOT shell for unauthenticated pages (login/mfa/passkey/device/reset); AppShell is for the authenticated app."],useCases:['Canonical Login (SCR-001): <AuthShell variant="canonical" preset="login"> with direct AuthIdentity \xB7 Card \xB7 AuthFooter children; the card remains anchored when requester is absent, one line or wraps to two lines (gh#237).',"Login page: <AuthShell brand={<Logo/>} footer={<AuthFooter/>}> wrapping a <Card> with the email/password form and a primary <Button fullWidth>.","MFA / passkey / device-authorisation step: same shell, a <Card> with the one-time-code <InputOTP> or a passkey prompt.",'OAuth device-grant screen (SCR-004): <AuthShell variant="canonical" preset="device-authorization"> \u2014 a 380px card at 1440/1024 and a 5px inline gutter at 390, with zero page-local CSS (gh#220).','Organisation / context selection (/select-context): <AuthShell variant="canonical" preset="context-selection" brand={<Logo mark="godx" />}> with an <AuthIdentity> intro, a <Card><CardContent flush> list of <ListRow as="li"> organisations, and a trailing "remember this choice" <Checkbox> \u2014 the preset spaces the three sections (gh#217).',"Password reset / forgot-password / accept-invite: the centred single-card flow with a brand bar and a legal footer.",'SSO landing / success confirmation: pair with an <EmptyState tone="success"> inside the card for an approved-device confirmation.'],related:["AppShell \u2014 the shell for AUTHENTICATED app pages (sidebar + topbar + main). AuthShell is its unauthenticated counterpart (brand bar + centred card + footer). Never nest the two.","Reveal \u2014 wrap the auth <Card> in <Reveal> for the entrance animation; AuthShell delegates motion (and prefers-reduced-motion handling) to it rather than baking an animation in.","Card \u2014 the canonical container for the auth form; place the form inside <CardContent>. AuthShell centres and width-constrains it.",'EmptyState \u2014 with `tone="success"` for a confirmation card inside the shell (e.g. device approved).','AuthIdentity / AuthFooter / AuthStack / AuthDivider \u2014 the auth composites that fill the shell: the GoDX identity mark + heading + requesting-client line, the mono legal footer (its `locale` slot takes an <AppSettingPicker kind="locale" appearance="labeled" compact />), the 12px section rhythm, and the labelled "or" rule.','ListRow \u2014 compose the organisation choice list for `preset="context-selection"` as <Card><CardContent flush><ul> of <ListRow as="li">: shared row dividers, no per-row card outline. There is no separate OrganizationChoiceList component \u2014 that is a composition pattern (rule #46), not a framework component.'],example:`import { AuthShell, AuthIdentity, AuthFooter } from "@godxjp/ui/layout";
52
66
  import { Reveal, Logo, Button } from "@godxjp/ui/general";
53
67
  import { Card, CardContent, CardHeader, CardTitle } from "@godxjp/ui/data-display";
54
68
  import { AppSettingPicker } from "@godxjp/ui/navigation";
@@ -867,12 +881,22 @@ import { Button } from "@godxjp/ui/general";
867
881
  <SheetHeader><SheetTitle>\u30D5\u30A3\u30EB\u30BF\u30FC\u8A2D\u5B9A</SheetTitle></SheetHeader>
868
882
  {/* filter fields */}
869
883
  </SheetContent>
870
- </Sheet>`,storyPath:"feedback/Sheet.stories.tsx",rules:[3]},{name:"Alert",group:"feedback",tagline:"Inline alert banner with variant-aware icon + optional dismiss. Parts: Alert/AlertTitle/AlertDescription/AlertActions/AlertQueryError.",props:[{name:"variant",type:'"default" | "destructive" | "warning" | "success"',defaultValue:'"default"',description:"Colour scheme + default icon."},{name:"onDismiss",type:"() => void",description:"Renders an \xD7 dismiss button when provided."},{name:"icon",type:"LucideIcon | false",description:"Override or hide (false) the icon."},{name:"tone",type:'"success" | "warning" | "destructive" | "info" | "neutral"',description:"Semantic tone driving the colour + leading icon."}],usage:["ANATOMY (positions are fixed \u2014 never re-lay-them-out): Alert is ONE horizontal row \u2014 a SINGLE leading tone icon at the inline-start (top-aligned to the first text line, auto-selected by `tone`, never two icons), then the text body (Title/Description), then `<Alert.Actions>` in a trailing-RIGHT column (\u2265sm), and the dismiss \xD7 pinned to the TOP-RIGHT corner (rendered by `onDismiss`). DON'T stack these vertically, DON'T make the action a full-width bar under the text, DON'T center the \xD7 at the bottom, DON'T add a second icon \u2014 that hand-rolled vertical banner is the #1 Alert mistake.",'DO compose text as `<Alert.Title>` + `<Alert.Description>` \u2014 they stack vertically inside the body (the Example below is canonical). When you add `<Alert.Actions>`, the body becomes a two-column grid (text | actions) at \u2265sm; group multi-part text in `<Alert.Content>` so it occupies the text column as one block: `<Alert tone="destructive"><Alert.Content><Alert.Title>Error</Alert.Title><Alert.Description>{msg}</Alert.Description></Alert.Content><Alert.Actions><Button \u2026/></Alert.Actions></Alert>`.',"DO use `Alert.QueryError` (alias `AlertQueryError`) for TanStack Query / API failure surfaces \u2014 it already renders humanError(error), an i18n title, and an optional Retry button. Never hand-roll that pattern.",'DON\'T pass raw action elements directly as top-level children of `<Alert>` without wrapping them in `<Alert.Actions>` \u2014 the layout slot only activates correctly via the `data-slot="alert-actions"` wrapper.','DON\'T hand-roll a dismiss \u2715 button \u2014 pass `onDismiss` to `<Alert>` and the component renders its own accessible dismiss button with `aria-label="Dismiss"`. The `onDismiss` handler may return a Promise.','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.',"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."],useCases:['Page-level error banner after a form submission fails server-side validation \u2014 `tone="destructive"` with `Alert.Title` summarising the error and `Alert.Description` listing field issues, paired with `onDismiss` so the user can clear it.',"Inline warning at the top of an accounting invoice list when the OAuth token for the MF sync is about to expire \u2014 `variant=\"warning\"` with an `Alert.Actions` containing a 'Reconnect' Button.",'Success confirmation banner rendered after a bulk-import job completes and the user returns to the list page \u2014 `tone="success"` with `Alert.Description` showing the record count imported.',"TanStack Query data-fetch failure inside a Card body \u2014 use `<Alert.QueryError error={error} onRetry={refetch} />` instead of writing a custom error state.","Informational notice at the top of a settings page when a feature is in beta or requires a plan upgrade \u2014 `variant=\"default\"` (Info icon) with a short description and an `Alert.Actions` 'Learn more' link.",'Dismissible billing-overdue notice at the top of the dashboard \u2014 `tone="destructive"` with `onDismiss` that sets a session flag so it does not reappear until the next login.'],related:["Toaster \u2014 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.","AlertMutationFeedback \u2014 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.","DataState \u2014 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.","EmptyState \u2014 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."],example:`import { Alert, AlertTitle, AlertDescription } from "@godxjp/ui/feedback";
884
+ </Sheet>`,storyPath:"feedback/Sheet.stories.tsx",rules:[3]},{name:"Alert",group:"feedback",tagline:"Inline alert banner with variant-aware icon + optional dismiss. Parts: Alert/AlertTitle/AlertDescription/AlertActions/AlertQueryError.",props:[{name:"variant",type:'"default" | "banner"',defaultValue:'"default"',description:'Box MEASURE, not colour \u2014 colour is always `tone`. "default" is the inset, rounded, fully-bordered INLINE alert that sits inside a page body. "banner" is the page-level strip: square, edge-to-edge, ruled on the block-end edge only, measured by the --banner-* tokens. Prefer the `Banner` export over writing variant="banner" by hand.'},{name:"onDismiss",type:"() => void",description:"Renders an \xD7 dismiss button when provided."},{name:"icon",type:"LucideIcon | false",description:"Override or hide (false) the icon."},{name:"tone",type:'"success" | "warning" | "destructive" | "info" | "neutral"',description:"Semantic tone driving the colour + leading icon."}],usage:["ANATOMY (positions are fixed \u2014 never re-lay-them-out): Alert is ONE horizontal row \u2014 a SINGLE leading tone icon at the inline-start (top-aligned to the first text line, auto-selected by `tone`, never two icons), then the text body (Title/Description), then `<Alert.Actions>` in a trailing-RIGHT column (\u2265sm), and the dismiss \xD7 pinned to the TOP-RIGHT corner (rendered by `onDismiss`). DON'T stack these vertically, DON'T make the action a full-width bar under the text, DON'T center the \xD7 at the bottom, DON'T add a second icon \u2014 that hand-rolled vertical banner is the #1 Alert mistake.",'DO compose text as `<Alert.Title>` + `<Alert.Description>` \u2014 they stack vertically inside the body (the Example below is canonical). When you add `<Alert.Actions>`, the body becomes a two-column grid (text | actions) at \u2265sm; group multi-part text in `<Alert.Content>` so it occupies the text column as one block: `<Alert tone="destructive"><Alert.Content><Alert.Title>Error</Alert.Title><Alert.Description>{msg}</Alert.Description></Alert.Content><Alert.Actions><Button \u2026/></Alert.Actions></Alert>`.',"DO use `Alert.QueryError` (alias `AlertQueryError`) for TanStack Query / API failure surfaces \u2014 it already renders humanError(error), an i18n title, and an optional Retry button. Never hand-roll that pattern.",'DON\'T pass raw action elements directly as top-level children of `<Alert>` without wrapping them in `<Alert.Actions>` \u2014 the layout slot only activates correctly via the `data-slot="alert-actions"` wrapper.','DON\'T hand-roll a dismiss \u2715 button \u2014 pass `onDismiss` to `<Alert>` and the component renders its own accessible dismiss button with `aria-label="Dismiss"`. The `onDismiss` handler may return a Promise.','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.',"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."],useCases:['Page-level error banner after a form submission fails server-side validation \u2014 `tone="destructive"` with `Alert.Title` summarising the error and `Alert.Description` listing field issues, paired with `onDismiss` so the user can clear it.',"Inline warning at the top of an accounting invoice list when the OAuth token for the MF sync is about to expire \u2014 `tone=\"warning\"` with an `Alert.Actions` containing a 'Reconnect' Button.",'Success confirmation banner rendered after a bulk-import job completes and the user returns to the list page \u2014 `tone="success"` with `Alert.Description` showing the record count imported.',"TanStack Query data-fetch failure inside a Card body \u2014 use `<Alert.QueryError error={error} onRetry={refetch} />` instead of writing a custom error state.","Informational notice at the top of a settings page when a feature is in beta or requires a plan upgrade \u2014 `tone=\"info\"` with a short description and an `Alert.Actions` 'Learn more' link.",'Dismissible billing-overdue notice at the top of the dashboard \u2014 `tone="destructive"` with `onDismiss` that sets a session flag so it does not reappear until the next login.'],related:["Toaster \u2014 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.","AlertMutationFeedback \u2014 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.","DataState \u2014 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.","EmptyState \u2014 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."],example:`import { Alert, AlertTitle, AlertDescription } from "@godxjp/ui/feedback";
871
885
 
872
886
  <Alert tone="warning">
873
887
  <AlertTitle>3 \u4EF6\u306E\u6253\u523B\u6F0F\u308C\u304C\u3042\u308A\u307E\u3059</AlertTitle>
874
888
  <AlertDescription>\u672C\u65E5\u4E2D\u306B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002</AlertDescription>
875
- </Alert>`,storyPath:"feedback/Alert.stories.tsx",rules:[]},{name:"SkeletonTable",group:"feedback",tagline:"Loading placeholder matching the DataTable layout (header + N rows). Drop-in while data loads (deferred props).",props:[{name:"rows",type:"number",defaultValue:"8",description:"Body skeleton rows."},{name:"columns",type:"number",defaultValue:"5",description:"Columns in header + body."}],usage:["DO use SkeletonTable as the pre-mount placeholder \u2014 either as a ternary fallback (`{!data ? <SkeletonTable rows={10} columns={6} /> : <DataTable \u2026 />}`) for Inertia deferred props, or as the `skeleton` prop of `DataState` (`<DataState query={q} skeleton={<SkeletonTable />} \u2026>`). It is NOT for in-table loading; once DataTable has mounted use its own `loading` prop instead.","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.","DO NOT use SkeletonTable when data is already present but refetching \u2014 use `DataTable loading={isFetching}` for in-table refetch states. SkeletonTable is only for the initial pre-mount gap before DataTable is rendered.","DO NOT wrap SkeletonTable in a Card \u2014 it renders its own header + body structure matching DataTable's DOM. Placing it inside CardContent adds unwanted padding around the skeleton rail.",'The root element carries `aria-busy="true"` automatically \u2014 do not add a second aria-busy on a wrapper. Screen readers announce the loading state correctly without extra markup.',"Import from `@godxjp/ui/feedback` (not `@godxjp/ui/admin`). Both paths resolve but the canonical export is `feedback`."],useCases:["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} />}`).","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.","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.","Admin list pages (invoices, journal entries, partners) where the table has a known column count \u2014 tune `columns` to match so column widths feel stable and don't reflow on hydration.","Page-level Suspense boundaries: use SkeletonTable as the `fallback` of a React Suspense wrapping a lazy-loaded data table component.","Route prefetch / navigation transitions: render SkeletonTable in the destination slot while Inertia visits are in-flight, keeping perceived layout stable."],related:["DataTable \u2014 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.","DataState \u2014 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.","SkeletonStat \u2014 sibling skeleton shaped like a StatCard tile; use inside a ResponsiveGrid to placeholder KPI dashboard cards, not tabular data.","DataTable \u2014 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."],example:`import { SkeletonTable } from "@godxjp/ui/feedback";
889
+ </Alert>`,storyPath:"feedback/Alert.stories.tsx",rules:[]},{name:"Banner",group:"feedback",tagline:'Page-level status strip \u2014 Alert locked to variant="banner" (square, edge-to-edge, block-end rule). Same tones, icons, actions and dismiss contract as Alert.',props:[{name:"tone",type:'"default" | "info" | "success" | "warning" | "destructive" | "muted" | "neutral"',defaultValue:'"default"',description:'Semantic tone driving the fill, the leading icon and the live-region politeness (destructive/warning get an assertive role="alert"; everything else role="status").'},{name:"onDismiss",type:"() => void | Promise<void>",description:"Renders the accessible \xD7 dismiss button, pinned to the banner's own (shorter) inset so it stays optically centred on a one-line strip."},{name:"icon",type:"LucideIcon | false",description:"Override or hide (false) the tone's default leading icon."}],usage:['Banner IS Alert \u2014 there is one implementation. It takes every Alert prop except `variant`, which it fixes to "banner". Use `Banner.Title` / `Banner.Description` / `Banner.Actions` (the very same elements as Alert\'s) \u2014 never mix `Alert.Title` inside a `Banner` and vice versa in one strip.',"DO: Reach for Banner when the message is about the PAGE or the whole app \u2014 scheduled maintenance, a trial expiring, a read-only/impersonation mode, a degraded integration. Mount it ABOVE the PageHeader / PageContainer, or in the AppShell so it spans every route. Its inline inset tracks the live page gutter (--banner-space-inline), so its text lines up with the page title.","DON'T: Use Banner for a message about ONE section, card, form or field \u2014 that is an inline `Alert` inside the section it concerns, or `FormField` error text for a field. A page-wide strip for a local problem sends the user hunting.","DON'T: Use Banner for transient 'saved successfully' feedback \u2014 that is `toast()`. Banner is persistent until the user acts or dismisses.","DO: Retheme it with tokens, never a wrapper className. --banner-radius (0), --banner-border-width (0), --banner-border-block-end-width (1px), --banner-space-block / --banner-space-inline, --banner-dismiss-space-offset. An app that keeps rounded card language everywhere sets --banner-radius once in its theme.","DON'T: Stack more than one Banner. Two competing page-level strips halve each other's weight; pick the most severe tone and put the rest in the page body."],useCases:["A scheduled-maintenance notice pinned inside AppShell above every route \u2014 `tone=\"info\"` with a `Banner.Description` carrying the Intl-formatted window and a `Banner.Actions` 'Details' link.","A trial-expiry / billing-overdue strip at the top of an authenticated app \u2014 `tone=\"warning\"` (or `destructive` past due) with an 'Upgrade' action and `onDismiss` stored per session.",'A read-only or impersonation mode indicator that must stay visible for the whole session \u2014 `tone="neutral"`, no `onDismiss`, so the operator cannot lose the context.',"A degraded-integration notice on an accounting workspace (the sync token expired) \u2014 `tone=\"warning\"` with a 'Reconnect' action, spanning the page above the header."],related:["Alert \u2014 the SAME component at the inline measure. Use Alert inside a page body/section; use Banner for page or app chrome. Do not re-create either with a styled div.","PageHeader / PageContainer \u2014 the banner sits ABOVE the title band, never inside it. PageHeader has no banner slot on purpose: an app-wide notice outlives any single page's header.","ErrorSurface \u2014 when the user may not see the page AT ALL (denied / error / maintenance page), replace the whole surface rather than banner-ing a page they should not be reading.","Toaster \u2014 transient, auto-dismissing feedback. Banner is persistent page chrome."],example:`import { Banner } from "@godxjp/ui/feedback";
890
+
891
+ <Banner tone="warning" onDismiss={dismiss}>
892
+ <Banner.Content>
893
+ <Banner.Title>\u304A\u8A66\u3057\u671F\u9593\u306F\u6B8B\u308A3\u65E5\u3067\u3059</Banner.Title>
894
+ <Banner.Description>\u671F\u9650\u307E\u3067\u306B\u30D7\u30E9\u30F3\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002</Banner.Description>
895
+ </Banner.Content>
896
+ <Banner.Actions>
897
+ <Button size="sm">\u30D7\u30E9\u30F3\u3092\u898B\u308B</Button>
898
+ </Banner.Actions>
899
+ </Banner>`,storyPath:"feedback/alert.tsx",rules:[]},{name:"SkeletonTable",group:"feedback",tagline:"Loading placeholder matching the DataTable layout (header + N rows). Drop-in while data loads (deferred props).",props:[{name:"rows",type:"number",defaultValue:"8",description:"Body skeleton rows."},{name:"columns",type:"number",defaultValue:"5",description:"Columns in header + body."}],usage:["DO use SkeletonTable as the pre-mount placeholder \u2014 either as a ternary fallback (`{!data ? <SkeletonTable rows={10} columns={6} /> : <DataTable \u2026 />}`) for Inertia deferred props, or as the `skeleton` prop of `DataState` (`<DataState query={q} skeleton={<SkeletonTable />} \u2026>`). It is NOT for in-table loading; once DataTable has mounted use its own `loading` prop instead.","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.","DO NOT use SkeletonTable when data is already present but refetching \u2014 use `DataTable loading={isFetching}` for in-table refetch states. SkeletonTable is only for the initial pre-mount gap before DataTable is rendered.","DO NOT wrap SkeletonTable in a Card \u2014 it renders its own header + body structure matching DataTable's DOM. Placing it inside CardContent adds unwanted padding around the skeleton rail.",'The root element carries `aria-busy="true"` automatically \u2014 do not add a second aria-busy on a wrapper. Screen readers announce the loading state correctly without extra markup.',"Import from `@godxjp/ui/feedback` (not `@godxjp/ui/admin`). Both paths resolve but the canonical export is `feedback`."],useCases:["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} />}`).","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.","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.","Admin list pages (invoices, journal entries, partners) where the table has a known column count \u2014 tune `columns` to match so column widths feel stable and don't reflow on hydration.","Page-level Suspense boundaries: use SkeletonTable as the `fallback` of a React Suspense wrapping a lazy-loaded data table component.","Route prefetch / navigation transitions: render SkeletonTable in the destination slot while Inertia visits are in-flight, keeping perceived layout stable."],related:["DataTable \u2014 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.","DataState \u2014 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.","SkeletonStat \u2014 sibling skeleton shaped like a StatCard tile; use inside a ResponsiveGrid to placeholder KPI dashboard cards, not tabular data.","DataTable \u2014 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."],example:`import { SkeletonTable } from "@godxjp/ui/feedback";
876
900
 
877
901
  {!coupons ? <SkeletonTable rows={10} columns={6} /> : <DataTable data={coupons} columns={columns} />}`,storyPath:"feedback/Skeleton.stories.tsx",rules:[]},{name:"Toaster",group:"feedback",tagline:'Mount once at app root to enable toasts. IMPORTANT: trigger toasts via `import { toast } from "sonner"` \u2014 NOT from @godxjp/ui.',props:[{name:"position",type:'"top-right" | "top-center" | "bottom-right" | "\u2026"',defaultValue:'"bottom-right"',description:"Toast stack anchor."},{name:"richColors",type:"boolean",description:"Enable Sonner rich variant colours."}],usage:["DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks \u2014 there is no provider context, only DOM portals.",'DO: Import `toast` from `"sonner"` directly (not from `@godxjp/ui`) to fire toasts anywhere: `toast.success(\u2026)`, `toast.error(\u2026)`, `toast.warning(\u2026)`, `toast.info(\u2026)`, `toast.loading(\u2026)`, `toast.promise(\u2026)`.',"DON'T: Try to import a `toast` helper from `@godxjp/ui/feedback` \u2014 it does not exist. The component re-exports only the `Toaster` mount; the imperative API lives in the `sonner` package.","DO: Let the wrapper handle theming \u2014 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.","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).","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."],useCases:['After a successful form save (invoice, journal entry, vendor record) \u2014 show `toast.success("\u4FDD\u5B58\u3057\u307E\u3057\u305F")` to confirm without blocking navigation.','After a background job is enqueued (e.g. bulk sync or export) \u2014 show `toast.info("\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3092\u958B\u59CB\u3057\u307E\u3057\u305F")` then later update with `toast.promise()` to track completion.',"Mutation error fallback when the error is transient and retrying is the right UX \u2014 show `toast.error(message)` instead of replacing page content; reserve `AlertMutationFeedback` for inline, persistent error display inside a form.",'Soft destructive action confirmation outcome \u2014 e.g. "\u524A\u9664\u3057\u307E\u3057\u305F" after an item is removed, paired with an undo action via `toast("\u2026", { action: { label: \'\u5143\u306B\u623B\u3059\', onClick: undo } })`.','OAuth / session expiry warnings \u2014 surface a brief `toast.warning("\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6709\u52B9\u671F\u9650\u304C\u8FD1\u3065\u3044\u3066\u3044\u307E\u3059")` without interrupting the user\'s current form state.'],related:["Alert \u2014 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.","AlertMutationFeedback \u2014 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`.","Dialog \u2014 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."],example:`// app root \u2014 mount once
878
902
  import { Toaster } from "@godxjp/ui/feedback";
@@ -1890,13 +1914,23 @@ import { Badge } from "@godxjp/ui/data-display";
1890
1914
  value={organizationId}
1891
1915
  onValueChange={setOrganizationId}
1892
1916
  labels={labels}
1893
- />`,storyPath:"layout/OrgSwitcher.stories.tsx",rules:[]},{name:"FilterBar",group:"navigation",tagline:"Domain-neutral list-page filter toolbar with optional clear action and labelled groups.",props:[{name:"children",type:"ReactNode",description:"Filter controls and groups."},{name:"onClear",type:"() => void",description:"Consumer-owned clear action."},{name:"hasActiveFilters",type:"boolean",defaultValue:"true",description:"Shows clear only when filters are active."},{name:"sticky",type:"boolean",defaultValue:"false",description:"Uses the token-owned sticky presentation."},{name:"overflow",type:"'wrap' | 'scroll'",defaultValue:"'wrap'",description:"Responsive overflow strategy (gh#216). 'wrap': stacked column below 640px, wrapping rows above. 'scroll': one bounded inline-scrolling row above 640px (still stacked below) with the clear-all action pinned at the inline end. The geometry is entirely token/CSS owned \u2014 never re-implement it in the page."},{name:"className",type:"string",description:"Optional structural class override."}],usage:["Compose real controls as children; filter state and URL synchronization remain consumer-owned.","Give each FilterBarGroup a `controlId` matching its single control's `id` (gh#216) so the visible caption is that control's real <label>; otherwise the control is nameless to a screen reader.","Reach for `overflow='scroll'` on filter-heavy list pages so a long JA/EN/VI label set never grows the strip into multiple rows and pushes the table below the fold."],example:`import { FilterBar, FilterBarGroup } from "@godxjp/ui/navigation";
1917
+ />`,storyPath:"layout/OrgSwitcher.stories.tsx",rules:[]},{name:"FilterBar",group:"navigation",tagline:"Domain-neutral list-page filter toolbar with optional clear action and labelled groups.",props:[{name:"children",type:"ReactNode",description:"Filter controls and groups."},{name:"onClear",type:"() => void",description:"Consumer-owned clear action."},{name:"hasActiveFilters",type:"boolean",defaultValue:"true",description:"Shows clear only when filters are active."},{name:"sticky",type:"boolean",defaultValue:"false",description:"Uses the token-owned sticky presentation."},{name:"overflow",type:"'wrap' | 'scroll'",defaultValue:"'wrap'",description:"Responsive overflow strategy (gh#216). 'wrap': stacked column below 640px, wrapping rows above. 'scroll': one bounded inline-scrolling row above 640px (still stacked below) with the clear-all action pinned at the inline end. The geometry is entirely token/CSS owned \u2014 never re-implement it in the page."},{name:"search",type:"ReactNode",description:"SLOT for the page's search control (gh#258). The bar owns its PLACE (start of the row) and its WIDTH (--filter-bar-search-width, 18rem from the 640px step up, full-width below it); the caller owns the primitive, its value and its debounce. Passing the search control as a plain child instead is what produced inconsistent search widths across list pages."},{name:"chips",type:"readonly { id: string; label: string; onRemove?: () => void }[]",description:"APPLIED filters as removable chips (gh#258) \u2014 the visible record of filters already in effect, NOT the controls that set them. Rendered on their own full-width line inside a labelled group, each with a remove control named after its specific filter. The row disappears entirely when the array is empty (never a reserved empty strip). Omit a chip's `onRemove` for a filter the user may not lift and it renders with NO remove control, rather than a disabled one that is a dead tab stop. The bar holds no state: removal calls back and the caller re-renders the array."},{name:"onChipRemove",type:"(id: string) => void",description:"Called with the chip's id when its remove control is activated. Fires IN ADDITION to that chip's own `onRemove`, so removal can be handled per chip, centrally, or both."},{name:"resultCount",type:"number",description:"Number of records the current filters resolve to (gh#258). Rendered in a POLITE LIVE REGION and formatted with Intl.NumberFormat + CLDR plurals for the active locale. This is the accessibility point of the prop: a sighted user sees the table change, and this is what tells everyone else that filtering happened. Omit while the count is unknown or loading \u2014 do not pass 0 as a placeholder."},{name:"actions",type:"ReactNode",description:"Trailing action region (gh#258) \u2014 export, column settings, a saved-view menu. Rendered AFTER the reset control so `clear filters` never lands at the end of the row next to an unrelated primary action. The bar owns the ordering; the caller owns the controls."},{name:"className",type:"string",description:"Optional structural class override."}],usage:["Compose real controls as children; filter state and URL synchronization remain consumer-owned.","Give each FilterBarGroup a `controlId` matching its single control's `id` (gh#216) so the visible caption is that control's real <label>; otherwise the control is nameless to a screen reader.","Reach for `overflow='scroll'` on filter-heavy list pages so a long JA/EN/VI label set never grows the strip into multiple rows and pushes the table below the fold.","ORDER IS THE CONTRACT (gh#258). DOM order is tab order, and the BAR decides it, not each page: search \u2192 filter groups (children) \u2192 applied chips \u2192 result count \u2192 reset \u2192 actions. Pass each region through its own prop and you get that order for free; hand-placing them as children is what made every list page keyboard-order differently.","DO pass the search control through `search`, NOT as a child. As a child it keeps whatever width the caller's control happened to have; through the prop it gets the one token-owned measure every list page shares.","DO drive applied filters through `chips` rather than rendering Badges yourself. The bar owns the chip lifecycle \u2014 the labelled group, the per-chip remove control named after that specific filter (a row of buttons all called 'Remove' is unusable from a screen-reader's control list), and hiding the row entirely when nothing is applied.","DO pass `resultCount` whenever the filters change a visible count. It is the only part of filtering a non-sighted user is told about; a count rendered as ordinary text beside the bar announces nothing.","DON'T hand-format the count ('12 results'). `resultCount` groups the number with Intl.NumberFormat and selects the noun with CLDR plural rules for the active locale \u2014 a hand-built string produces '1 results' and ignores JA/VI conventions.","DON'T reach for these props to make the bar own filter STATE. It never does: `search` is a slot, `chips` is a rendered array, `resultCount` is a number you computed. The bar owns placement, measure, ordering, keyboard order and announcement \u2014 nothing else."],example:`import { FilterBar, FilterBarGroup } from "@godxjp/ui/navigation";
1918
+ import { SearchInput } from "@godxjp/ui/data-entry";
1919
+ import { Button } from "@godxjp/ui/general";
1894
1920
 
1895
- <FilterBar overflow="scroll" onClear={clearFilters} hasActiveFilters={hasFilters}>
1921
+ <FilterBar
1922
+ overflow="scroll"
1923
+ search={<SearchInput value={q} onSearchChange={setQ} />}
1924
+ chips={applied.map((f) => ({ id: f.id, label: f.label, onRemove: () => lift(f.id) }))}
1925
+ resultCount={rows.length}
1926
+ onClear={clearFilters}
1927
+ hasActiveFilters={applied.length > 0}
1928
+ actions={<Button variant="outline" size="sm">\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8</Button>}
1929
+ >
1896
1930
  <FilterBarGroup label="Status" controlId="f-status">
1897
1931
  <StatusSelect id="f-status" />
1898
1932
  </FilterBarGroup>
1899
- </FilterBar>`,storyPath:"navigation/FilterBar.stories.tsx",rules:[]}];function O(t){let a=t.trim().toLowerCase();return v.find(e=>e.name.toLowerCase()===a)}function F(t){return v.filter(a=>a.group===t)}var k=[{name:"ValueProp<T = string>",concept:"Abstract controlled value.",values:["generic"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Tabs","SearchSelect"]},{name:"DefaultValueProp<T = string>",concept:"Abstract uncontrolled initial value.",values:["generic"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Tabs"]},{name:"OnValueChangeProp<T = string>",concept:"Callback for abstract value changes. DOM events continue to use onChange.",values:["(value: T) => void"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Transfer","settings pickers"]},{name:"OpenProp / DefaultOpenProp / OnOpenChangeProp",concept:"Disclosure state.",values:["boolean","(open: boolean) => void"],usedBy:["Dialog","Sheet","Popover"]},{name:"SizeProp",concept:"Shared public size names.",values:["xs","sm","md","lg"],usedBy:["Button","Steps","Switch"],notes:"Component-specific subsets must be documented. Old alias small is sm."},{name:"ToneProp",concept:"Semantic status/color intent.",values:["default","success","warning","destructive","info","muted","neutral"],usedBy:["Badge","Alert"],notes:"Status values belong in tone, not variant."},{name:"GapProp",concept:"Shared layout gap scale.",values:["xs","sm","md","lg","xl"],usedBy:["Flex"],notes:'The single shared gap scale on Flex \u2014 the one layout primitive (default direction="row"; use direction="col" for vertical rhythm; these replaced the removed Stack/Inline).'},{name:"TitleProp",concept:"Primary heading text.",values:["React.ReactNode"],usedBy:["PageContainer","PageHeader","EmptyState","Dialog"]},{name:"DensityProp",concept:"Page/subtree density.",values:["compact","default","comfortable"],usedBy:["PageContainer"]},{name:"CenteredShellPresetProp",concept:"Named whole-page SHELL contract for CenteredShell \u2014 the page measure, section rhythm, chrome flatness and hero heading tier, all owned by component tokens.",values:["default","public-landing"],usedBy:["CenteredShell"],notes:'public-landing is the PUBLIC marketing/product landing geometry (gh#252): one 67.5rem measure shared by the header bar, the centred column and the footer, the section rhythm, flat elevation-free cards and the hero h1 tier. "default" emits NO data-preset at all, so the existing shell box is untouched. Pair with `Flex hideBelow`/`hideFrom` for header region visibility \u2014 a landing must never own a page-local media query or a max-width wrapper.'},{name:"TablePresetProp",concept:"Named collection contract for a table \u2014 how a dense collection behaves when its container gets narrow.",values:["default","action-collection"],usedBy:["Table","DataTable"],notes:"action-collection (gh#253) swaps the desktop intrinsic column widths for table-layout: fixed + the token-owned column PRIORITY measures below `collapseBelow`, so a five-column approval queue keeps every column \u2014 including row actions \u2014 inside a 390px frame with no page-local CSS, no hidden column and no horizontal scroll. It changes the SIZING model only: no display change, no role rewriting, no card transformation, so table semantics and screen-reader navigation are identical at every width. ONE contract, two entry points: the `Table` primitive (mark `priority` on each TableHead/TableCell yourself) and the TanStack `DataTable` (mark `priority` on the ColumnDef; it stamps both cells for you, and additionally releases the surface's `--table-surface-min-inline-size` floor). Both read the same `--table-action-collection-*` tokens \u2014 there is no parallel DataTable family."},{name:"TableColumnPriorityProp",concept:"Relative importance of a table column, used by the action-collection preset to allocate the narrow-frame measure.",values:["primary","secondary","meta","actions"],usedBy:["Table","DataTable"],notes:"On the raw `Table`, set it on BOTH the TableHead and the TableCell of a column; on `DataTable` set it once on the `ColumnDef` and it is stamped onto the <th> and every <td>. `actions` reserves its measure first so the row-action affordance can never be pushed outside the viewport; a column with no priority takes the remaining space (the free-text column)."},{name:"AuthShellPresetProp",concept:"Named hosted-identity FLOW MEASURE for AuthShell \u2014 the card max-width plus the desktop and mobile page gutters, all owned by component tokens.",values:["default","device-authorization","context-selection"],usedBy:["AuthShell"],notes:'Orthogonal to AuthShell\'s `variant` (which owns control density + heading size) and applied after it, so `variant="canonical" preset="device-authorization"` composes. device-authorization = 380px card / 5px inline gutter at 390 (gh#220); context-selection = 25rem card, edge-to-edge on mobile (gh#217). Selecting a preset REPLACES any consumer-side --auth-shell-card-max-width override \u2014 a page-local width is the anti-pattern these presets exist to remove.'},{name:"AvatarShapeProp",concept:"Avatar geometry \u2014 WHAT the identity mark represents: a person or an entity. Deliberately NOT the control ShapeProp (default|pill|sharp), whose `sharp` is --radius-sharp: 0 and cannot express the rounded rect an entity mark needs.",values:["circle","square"],usedBy:["Avatar"],notes:'circle (default, inert) = the round --radius-pill person avatar on the muted surface; square = the entity-header organization/service mark \u2014 a compact rounded square on the brand surface driven by --avatar-square-{radius,size,background,foreground} (gh#249). Choose by meaning, never by look: a className="rounded-md bg-primary" override on the call site is the anti-pattern this prop removes.'}];function B(t){let a=t.trim().toLowerCase().replace(/prop(?:<.*>)?$/i,"");return k.find(e=>e.name.toLowerCase().replace(/prop(?:<.*>)?$/i,"")===a)}var C=[{name:"--wa-*",category:"primitive",tier:"primitive",role:"Neutral decorative Japanese accent primitives for charts/tags/decoration only."},{name:"--chart-1..6",category:"primitive",tier:"primitive",role:"Neutral decorative chart series palette. The @godxjp/ui/charts components (LineChart/BarChart/AreaChart/PieChart) read these by series index automatically \u2014 a service rethemes every chart at once by overriding --chart-1..6; per-series/per-slice overrides go through the component's series.color / colors props."},{name:"--space-0..12",category:"primitive",tier:"primitive",role:"Raw spacing scale."},{name:"--font-size-*",category:"primitive",tier:"primitive",role:"Raw typography scale."},{name:"--font-sans-base",category:"semantic",tier:"semantic",role:'The default sans face. FONT-AGNOSTIC by default (pure system stack) \u2014 the library ships no hardcoded brand font. Override this for one face everywhere. --font-family-sans defaults to it; --font-family-display / --font-family-body default to --font-family-sans (override those for a dual display+body brand). Consumers supply the actual @font-face (next/font, @fontsource, self-host); the opt-in @godxjp/ui/styles/fonts OVERWRITES this (and --font-sans-vi) with the bundled DXS stack \u2014 "M PLUS 2" primary (incl. the Vietnamese coverage) with "Noto Sans JP" as the CJK fallback. BUNDLE CHANGED IN v18: v16 bundled Noto Sans JP + Montserrat, v18 bundles M PLUS 2 + Noto Sans JP \u2014 if a design spec names the v16 faces, set the tokens explicitly instead of relying on the bundle. IMPORT ORDER IS LOAD-BEARING: styles/fonts must be imported AFTER styles/base, because foundation.css declares this system-stack default on :root at the same specificity (0,1,0) and the later declaration wins (the all-in-one @godxjp/ui/styles entry already orders it correctly \u2014 issue #210).'},{name:"--font-sans-{ja,ko,vi,zh-hans,zh-hant}",category:"semantic",tier:"semantic",role:'Per-language font SLOT tokens. styles/base.css wires each [lang] to read its slot with --font-sans-base as fallback, so a consumer switches a locale\'s face by setting e.g. `--font-sans-ja: "Noto Sans JP", var(--font-sans-base)` \u2014 NO [lang] selectors to write. Empty by default. zh-hans matches lang zh|zh-Hans|zh-CN; zh-hant matches zh-Hant|zh-TW. Deciding which @font-face ships on which locale route is the consumer\'s font pipeline, not the library. The opt-in @godxjp/ui/styles/fonts only fills --font-sans-vi (with the bundled "M PLUS 2", "Noto Sans JP" stack); the other slots stay empty and fall back to --font-sans-base.'},{name:"--duration-{fast,base,slow}",category:"primitive",tier:"primitive",role:"Motion durations (150 / 250 / 500ms). Read these instead of a literal `0.5s` for enter/transition timing (rule #2). the reference design keeps motion short; honour `prefers-reduced-motion` at the call site."},{name:"--ease-{standard,emphasized,decelerate,accelerate}",category:"primitive",tier:"primitive",role:"Motion easing curves. `standard` for most transitions, `emphasized` for entrances/overlays (the vaul drawer curve), `decelerate` for settling in, `accelerate` for exits. Read instead of a literal `cubic-bezier(\u2026)`."},{name:"--reveal-distance",category:"primitive",tier:"primitive",role:"Distance (10px) a revealed element travels on enter (translateY/-X). Read instead of a literal `translateY(10px)` for staggered reveals."},{name:"--reveal-stagger-step",category:"primitive",tier:"primitive",role:"One step (60ms) of the Reveal stagger ladder \u2014 `<Reveal delay={n}>` waits n \xD7 this before entering, so a column of reveals cascades. Read instead of a literal `.04s`/`.09s` per-item delay."},{name:"--shadow-color",category:"primitive",tier:"primitive",role:"RGB channels (space-separated, e.g. `12 26 49`) that tint the WHOLE elevation ramp (--shadow-xs..2xl) at once. Default `0 0 0`. Single-brand :root only \u2014 a scoped override does not re-resolve the ramp (the steps compute at :root); for a scoped/multi-tenant card lift set --card-shadow to a literal value."},{name:"--shadow-glow",category:"primitive",tier:"primitive",role:"Opt-in brand GLOW halo layered on the primary CTA's resting shadow. Default invisible (`0 0 0 0 transparent`, valid inside a comma shadow list). A service sets the whole value, e.g. `--shadow-glow: 0 8px 20px hsl(var(--primary) / .32)` \u2014 works scoped under [data-tenant] because the service declares it inside the scope."},{name:"--focus-ring-color",category:"primitive",tier:"primitive",role:"Themeable hue of EVERY keyboard-focus ring (HSL components, default var(--ring)). A leaf token, so it re-resolves at the element that paints the ring \u2014 override it once, even scoped under [data-tenant], to retint all focus rings. Pair with --focus-ring-width."},{name:"--focus-ring-width",category:"primitive",tier:"primitive",role:"Thickness (2px) of the solid keyboard-focus ring. Leaf token \u2014 :focus-visible rules read it directly as `0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color))`, never via an intermediate composite (which would freeze at :root). Propagates scoped."},{name:"--gradient-{brand,hero,glow}",category:"primitive",tier:"primitive",role:"Opt-in decorative gradient fills, default `none`. --gradient-hero paints the PageContainer header (hero banner); --gradient-glow paints the AppShell .app-main (ambient brand wash); --gradient-brand is a spare. A service sets the full gradient, e.g. `--gradient-glow: radial-gradient(60% 80% at 50% 0%, hsl(var(--primary) / .25), transparent)`."},{name:"--primary",category:"semantic",tier:"semantic",role:"Action color role."},{name:"--brand / --brand-foreground",category:"semantic",tier:"semantic",role:'The IDENTITY role \u2014 the canonical GoDX emerald (light #009766 = oklch(0.595 0.137 162.94); dark lifts lightness only, #00b87c). It is what `<Logo mark="godx">` / `tone="success">` / the godx wordmark / the `@godxjp/ui/email` brand capsule paint, and it is distinct from THREE lookalikes: --primary (the ACTION colour \u2014 re-theme it freely, the mark never moves), --success (\u82E5\u7AF9 #68be8d, the STATUS green for badges/progress/"saved" text \u2014 the mark borrowed this before gh#250 and shipped \u0394E76 \u2248 17.5 off canonical), and --text-brand (the blue brand-NUMERAL text slot behind the Tailwind `text-brand` utility). There is no `bg-brand` utility: `--color-brand` is already taken by --text-brand, so identity surfaces read `hsl(var(--brand))` directly in component CSS. Re-brand a service by overriding --brand once (scoped `[data-tenant]` works \u2014 every logo knob resolves it at the call site).'},{name:"--success",category:"semantic",tier:"semantic",role:'Success STATUS role (\u82E5\u7AF9 wakatake #68be8d) \u2014 badges, alerts, progress fills, timeline done dots, `tone="success"` text. NOT the product identity: the GoDX mark reads --brand (gh#250).'},{name:"--warning",category:"semantic",tier:"semantic",role:"Warning status role."},{name:"--destructive",category:"semantic",tier:"semantic",role:"Destructive/error status role."},{name:"--info",category:"semantic",tier:"semantic",role:"Information status role."},{name:"--attention",category:"semantic",tier:"semantic",role:"Attention status role."},{name:"--page-header-divider",category:"semantic",tier:"semantic",role:"PageContainer header bottom divider. Default none; a service theme opts in with `1px solid hsl(var(--border))`."},{name:"--overlay-background",category:"semantic",tier:"semantic",role:"Modal scrim \u2014 the single backdrop colour shared by every overlay (Dialog, AlertDialog, Sheet, Drawer, AppShell mobile nav). Default `rgb(0 0 0 / 0.5)`. A service tints it once, e.g. a navy `rgb(12 26 49 / .55)`. HOW IT REACHES AN OVERLAY (gh#215 \u2014 until v18 it reached NOTHING; every overlay carried a private literal and this token was dead): each surface declares its own `--*-overlay-background` knob `initial` and resolves a SHARE of this colour at the call site, `color-mix(in srgb, var(--overlay-background) var(--*-overlay-alpha), transparent)`, so the calibrated per-surface depth survives (Sheet/drawer 40% = 0.2, Dialog 60% = 0.3) while ONE override here retints them all. NOTE: portaled overlays render outside a [data-tenant] subtree, so for multi-tenant scoping put the tenant attribute on the portal container too."},{name:"--page-header-pad-bottom",category:"semantic",tier:"semantic",role:"PageContainer header bottom inset. Defaults to page top padding minus the section gap so the title band is vertically balanced."},{name:"--master-detail-rail-{compact,standard}",category:"semantic",tier:"semantic",role:"MasterDetail fixed rail track \u2014 18.75rem (300px) / 20rem (320px). The `railWidth` prop picks the preset; a service theme retunes the presets themselves. Consumers never author a grid track."},{name:"--master-detail-gap",category:"semantic",tier:"semantic",role:"Gap between the MasterDetail master and detail regions (default --space-stack-md), side by side and stacked."},{name:"--master-detail-collapse-below",category:"semantic",tier:"semantic",role:"MasterDetail stacking threshold (default 40rem / the `sm` step), measured against the composition's OWN inline size, not the viewport: wider keeps the split, narrower stacks master above detail. A real knob \u2014 the layout resolves it inside a flex-basis calc(), because a media/container-query CONDITION cannot read a var(). The `collapseBelow` prop overrides it per instance (rule #45)."},{name:"--master-detail-master-viewport-{compact,standard}",category:"semantic",tier:"semantic",role:'Bounded MasterDetail master viewport \u2014 20rem (320px) / 28rem (448px), selected by the semantic `masterViewport` prop. `masterViewport="auto"` (the default) applies NO bound, so existing compositions are unchanged; the presets cap the collection\'s block size and scroll it INSIDE the region, which is what stops a long real collection from pushing the detail below the fold once the layout stacks. Retune the presets in a service theme exactly like --master-detail-rail-*; never author a pixel max-height in consumer CSS.'},{name:"--master-detail-master-viewport-inset",category:"semantic",tier:"semantic",role:"Focus-ring room inside a bounded MasterDetail master region (default --space-1 / 4px), and its scroll-padding. An overflow container clips BOTH axes, so without this inset the focus ring of a row at the region's edge would be cut off; it also keeps a row scrolled into view off the clip edge. Only applies when `masterViewport` is compact/standard."},{name:"--page-header-extra-measure",category:"semantic",tier:"semantic",role:'Inline measure of the PageContainer header `extra` region while `headerLayout="responsive-inline"` and the page is below the 640px step (default 11rem / 176px). The default `headerLayout="stack"` never reads it \u2014 `extra` keeps wrapping onto its own full-width line under the subtitle. At >=640px both arrangements are identical, so this token only governs the compact range.'},{name:"--page-measure-{narrow,medium}",category:"semantic",tier:"semantic",role:'Bounded PageContainer MEASURE presets \u2014 42rem (672px) / 48rem (768px), selected by the semantic `measure` prop. They are OUTER measures: the package-owned page gutters (--space-page-active-x, 24px each side) sit INSIDE the cap, so the VISIBLE surface is 624px / 720px, and at 390px nothing binds (358px surface at the 16px compact gutter). Unlike variant="narrow" \u2014 which caps only .ui-page-body \u2014 the measure caps the page HEADER and the BODY together, so a header `extra` action ends flush with the body surface (gh#245/gh#247). `measure="default"` (the default) reads NEITHER token and matches no rule, so existing pages are unchanged. Retune the presets in a service theme; never author a page-local max-width.'},{name:"--badge-space-*",category:"component",tier:"component",role:"Badge spacing."},{name:"--logo-godx-{size,size-xs|sm|md|lg,color} / --logo-success-{background,foreground} / --logo-identity-foreground",category:"component",tier:"component",role:'The GoDX IDENTITY mark. COLOUR: its default is the --brand IDENTITY role (canonical emerald) \u2014 deliberately independent of --primary, so a re-themed action colour never recolours the brand, AND of --success, the \u82E5\u7AF9 STATUS green it wrongly defaulted to before gh#250 (`tone="success"` names the semantic SLOT, not the status role). Role-mirror knobs: declared `initial` at :root with the role default at the CALL SITE (`hsl(var(--logo-godx-color, var(--brand)))`), so a scoped `.dark`/`[data-tenant]` override of --brand actually reaches the mark. BOX: `--logo-godx-size-{xs,sm,md,lg}` (1.5 / 1.75 / 2 / 2.5rem) is the identity mark\'s own size ramp \u2014 the `size` prop drives it exactly like --logo-size-* drives the boxed glyph, one tier above its glyph sibling because the artwork is a capsule inside a square viewBox. `--logo-godx-size` is the PIN, not the base: `initial` by default (so the tiers apply) and, set once by a service theme, it freezes the mark at that box on EVERY tier. INK: `--logo-identity-foreground` (48 9% 9%, #191815) is the colour the boxed `mark="glyph"` sets its TEXT in on the identity fill \u2014 deliberately NOT --brand-foreground. --brand-foreground is the artwork KNOCKOUT colour (it tracks --background in both themes, because `mark="godx"` punches its inner bar as an evenodd HOLE and the email mark paints that hole solid to match) and as negative space only owes WCAG 2.2 SC 1.4.11\'s 3:1. The boxed glyph renders real TEXT, so SC 1.4.3 applies at 4.5:1 \u2014 14px bold is NOT "large text" (that needs 18.66px bold / 24px) \u2014 and knockout white on the emerald measured only 3.67:1, a straight AA failure. The ink is theme-INVARIANT (it is the same near-black spine the dark theme already resolved to), so dark is unchanged at 6.89:1 and light rises to 4.74:1. It is NOT a role-mirror knob \u2014 its default is a real value, not a role, so there is no role to freeze and it is declared at :root, not `initial`. Re-theming --brand to a DARK fill? Override the public knob --logo-success-foreground to re-invert the ink. Applies to `<Logo mark="godx">` / `tone="success"`.'},{name:"--logo-wordmark-{gap,font-size-xs|sm|md|lg,font-weight,letter-spacing,font-family,color}",category:"component",tier:"component",role:'Wordmark/lockup knobs for `<Logo wordmark="\u2026" />` \u2014 the mark\u2194wordmark gap, the per-size-tier wordmark type ramp, and its face/weight/tracking/colour. The package ships NO wordmark artwork: `--logo-wordmark-font-family` defaults (at the call site) to --font-family-display, so the wordmark is typeset in the design-system face; pass an inline <svg> as `wordmark` when a real logotype exists. `--logo-wordmark-color` is a role-mirror knob (`initial`) whose call-site default is hsl(var(--foreground)), or the --brand IDENTITY role on the godx / tone="success" lockup \u2014 never --primary and never the --success status green (gh#250). Setting it once in a service theme re-colours every lockup with no page CSS (gh#214).'},{name:"--card-*",category:"component",tier:"component",role:"Card surface, border, spacing, and typography."},{name:"--control-*",category:"component",tier:"component",role:"Shared form control heights, padding, icons, and focus chrome."},{name:"--table-*",category:"component",tier:"component",role:"Table row/cell sizing."},{name:"--table-pagination-padding-{y,x}",category:"component",tier:"component",role:"DataTable.Pagination footer inset (gh#236). The footer used to declare `padding-top` ONLY, so in the documented flush container (`<Card><CardContent flush><DataTable/>`) the 'rows per page' label and the page-size Select sat flush against the container edge and its closing border. It now owns `padding-block` + `padding-inline`. Both knobs are declared `initial` with the default at the CALL SITE \u2014 block `var(--space-stack-sm)` (the old padding-top value, now on both block edges), inline `var(--table-cell-space-x)` so the label lands on the same optical axis as the first column's text. `initial` is load-bearing: both defaults are density-scaled and re-declared inside a `.ui-density-*` subtree, and a `:root` binding would freeze the footer at the `:root` density. Consumers no longer need a local `.ui-data-table-pagination` override; a service on another grid retunes either axis."},{name:"--table-surface-min-inline-size",category:"component",tier:"component",role:'DataTable surface narrow-viewport width FLOOR (gh#253). Below the `sm` viewport step a multi-column admin grid whose cells are `white-space: nowrap` would be crushed, so the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. This shipped as a hard-coded `min-w-[640px] sm:min-w-0` utility pair ON the surface element \u2014 the literal that forced the horizontal scroll at 390 \u2014 leaving a service that wants a narrower (or no) floor with no route but forking the component (rule #45). Default `640px`, byte-identical to the old utility, and deliberately px so the floor releases at exactly the same width as the px-based `sm` media query that clears it (a rem value drifts under a non-16px root and re-introduces the scroll between the two thresholds). Set `0` to opt out; `DataTable preset="action-collection"` already does, because there the column-priority measures own the width.'},{name:"--form-label-width",category:"component",tier:"component",role:"Label column width in horizontal Form layout. Default max-content; a service theme sets it once (e.g. 110px) \u2014 the labelWidth prop overrides per form/field."},{name:"--form-label-gap",category:"component",tier:"component",role:"Label\u2194control column gap in horizontal Form layout. Default 16px (--space-4)."},{name:"--dialog-* / --alert-* / --skeleton-*",category:"component",tier:"component",role:"Feedback component sizing and spacing."},{name:"--sheet-responsive-breakpoint-width / --sheet-bottom-max-height",category:"component",tier:"component",role:`The responsive drawer / detail-panel contract (SheetContent responsive="auto"). --sheet-responsive-breakpoint-width (default 48rem = 768px, the library's canonical mobile line) is the viewport width at and below which the desktop side panel becomes a mobile bottom sheet; --sheet-bottom-max-height (default 85dvh) caps THAT bottom presentation only (a plain side="bottom" sheet stays content-sized). Because a CSS @media cannot resolve a custom property, the breakpoint is read off :root at runtime by the exported useSheetResponsiveMode() hook \u2014 which is also what OrgSwitcher responsive="auto" uses, so ONE knob moves the popover\u2192sheet and side\u2192bottom line for every overlay at once. Accepts px/rem/em.`},{name:"--qr-code-*",category:"component",tier:"component",role:"QrCode scanner-safe foreground/background and xs/sm/md/lg natural-size tiers. Keep foreground/background at strong contrast; the defaults remain dark-on-light in dark application themes."},{name:"--chart-trend-plot-height{,-xs,-sm,-md,-lg}",category:"component",tier:"component",role:"CompactBarTrend plot-height tiers (xs 3.5rem = dashboard summary-card density, sm 5rem, md 7.5rem, lg 10rem). The `size` prop picks a step via data-size; a service retunes the whole scale here. This is why a consumer NEVER writes an inline height for a compact trend."},{name:"--chart-trend-bar-{gap,radius,max-width,min-height}",category:"component",tier:"component",role:"CompactBarTrend mark geometry: gap between bars (default --space-2), rounded data-end radius (--radius-sm), the per-mark width ceiling (1.5rem, so a 3-point trend does not render slabs) and the min height floor (2px, so a zero value still reads as a plotted category). All service-tunable (rule #45)."},{name:"--chart-trend-bar-background{,-alpha} / --chart-trend-bar-emphasis-background",category:"component",tier:"component",role:"CompactBarTrend fills \u2014 role-mirror knobs declared `initial` with the role default at the call site. Muted marks default to hsl(var(--muted-foreground) / --chart-trend-bar-background-alpha) (0.75, which clears the 3:1 non-text contrast floor); the emphasized 'current' mark defaults to hsl(var(--primary)). Point them at --chart-N to tint a trend to a series colour."},{name:"--chart-trend-baseline-border",category:"component",tier:"component",role:"CompactBarTrend baseline rule. QUIET by default (rule #44 \u2014 resolves to `none`); a service opts in with `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-{tick-gap,tick-font-size,footer-gap}",category:"component",tier:"component",role:"CompactBarTrend category-tick and activity-footer rhythm \u2014 the plot\u2194tick gap, tick type size (--font-size-xs) and the plot\u2194footer gap."},{name:"--email-shell-{width,padding,page-padding,border-width} / --email-card-{radius,reference-height} / --email-stack-gap{,-sm}",category:"component",tier:"component",role:"Transactional-email shell geometry: the 480px card width, its 32px inset, the 24px viewport gutter, the 1px edge, the 10px radius (mirrors --card-radius) and the block rhythm. The canonical invitation reference measures 480\xD7407 (--email-card-reference-height is a visual-regression target, NEVER a fixed height on the card). Values are LITERAL px \u2014 email clients resolve neither var() nor rem \u2014 and are consumed through the `@godxjp/ui/email` export (EMAIL_SHELL), never by a stylesheet."},{name:"--email-{body,heading}-{font-size,line-height,font-weight} / --email-font-family-{sans,mono}",category:"component",tier:"component",role:`Email type ramp, reconciled with the SCR-302 canonical reference (gh#250). Body 14px/1.9, title 17px/1.7 at weight 500 (a transactional title is CALM, not bold) \u2014 deliberately looser and quieter than the web ramp, because a mail client gives the reader no density control, so do NOT 'fix' it back to --heading-h1/--line-height-body. --email-font-family-sans names the canonical M PLUS 2 face first and degrades Hiragino \u2192 Yu Gothic \u2192 Noto Sans JP \u2192 Meiryo \u2192 system UI \u2192 Arial \u2192 sans-serif; no email client honours @font-face, so the stack is the whole fallback contract. --email-font-family-mono (mirrors --font-family-mono) sets invoice ids, masked card numbers, ISO dates and amounts. Family names export SINGLE-quoted so the value drops into a double-quoted style="\u2026" attribute unescaped (emailInlineStyle throws on a double quote). Exposed as EMAIL_TYPOGRAPHY.`},{name:"--email-mark-{width,height,gap} / --email-wordmark-{font-size,font-weight}",category:"component",tier:"component",role:'Email brand-mark LOCKUP (gh#250). The ARTWORK is byte-identical to <Logo mark="godx" /> (the 32\xD732 capsule + internal glyph, asserted by test); only the rendered box is email-specific \u2014 the canonical header sets a 22px mark, an 8px gap (mirrors --logo-wordmark-gap) and a 13px/700 wordmark (mirrors --logo-wordmark-font-weight). In that pairing the mark is DECORATIVE (render it with label: "") and the wordmark carries the accessible name, so the brand is announced once. Exposed as EMAIL_BRAND_MARK; the svg / dataUri / tableHtml deliveries all derive from this one geometry source.'},{name:"--email-cta-{height,line-height,padding-x,radius,font-size,font-weight} / --email-focus-border-width",category:"component",tier:"component",role:"The single primary email CTA, reconciled with the SCR-302 canonical reference (gh#250): 36px tall (mirrors --control-height-lg) with line-height EQUAL to the height so the label centres without flexbox in Outlook, 16px inline padding (--space-4), the 6px --radius base, 14px/500 label. 36px still clears WCAG 2.2 SC 2.5.8 (24\xD724) and the mobile reflow takes the CTA full-bleed. Fill/label are EMAIL_COLORS.primary / primaryForeground, derived from the --primary role \u2014 never paste a canonical hex, or the email stops tracking a re-theme. --email-focus-border-width mirrors --focus-ring-width for the webmail panes that honour :focus-visible. Exposed as EMAIL_CTA / EMAIL_FOCUS."},{name:"--email-footer-{font-size,line-height,link-gap,padding-top,border-width} / --email-mobile-*",category:"component",tier:"component",role:"Legal-footer typography (11px/1.8 quiet type per the SCR-302 canonical, 12px between adjacent links, 20px above the hairline) and the narrow-viewport reflow (520px breakpoint, fluid card, 20px inset, 12px gutter, 16px heading \u2014 one step under the 17px desktop title, full-bleed CTA). The canonical 390px reference raster is unusable (435px wide and already clipping the card, dxs-platform/platform#496), so the mobile ramp is the library's documented contract rather than a measured value. Exposed as EMAIL_FOOTER / EMAIL_MOBILE; every reflow rule needs an inline fallback because most clients strip <style>."},{name:"--auth-shell-device-{card-max-width,main-padding,main-padding-mobile}",category:"component",tier:"component",role:'AuthShell `preset="device-authorization"` measure (gh#220) \u2014 the canonical OAuth device-grant artboard: a 23.75rem/380px card at 1440/1024 and a 15px-block \xB7 5px-inline page gutter at 390 (so the card renders x=5px, width=380px). LITERAL lengths, not --space-*, because the artboard specifies exact device pixels that must not drift with --scaling. Selecting the preset replaces a consumer-side --auth-shell-card-max-width override or a forked `.auth-shell--wide` class; the canonical 360px/15px default is untouched.'},{name:"--auth-shell-context-{card-max-width,main-padding,main-padding-mobile,card-stack-gap}",category:"component",tier:"component",role:'AuthShell `preset="context-selection"` measure (gh#217) \u2014 the organisation/context picker: a 25rem card on desktop/tablet, edge-to-edge on mobile (0 inline gutter), and a 1rem rhythm between the three direct sections of the auth column (intro \xB7 choice card \xB7 "remember" row).'},{name:"--auth-shell-recovery-{card-max-width,main-padding,main-padding-mobile}",category:"component",tier:"component",role:'AuthShell `preset="account-recovery"` measure (gh#233) \u2014 the SCR-008 27rem/432px panel, shared by the password-recovery panel (request \xB7 sent \xB7 new-password \xB7 expired) AND the sign-in MFA challenge panel (OTP \xB7 recovery-code \xB7 passkey-failure), because both canonical desktop panels measure w=432 at 1440. Mobile gutter = 15px inline at <=30rem, so the panel is x=15, width=360 \u2014 the SAME rhythm as the canonical Login flow, chosen deliberately: the supplied 390 reference is a desktop 2x2 composite that crops horizontally and is NOT a valid source. The canonical 360px Login measure and the 24rem un-preset shell are untouched.'},{name:"--otp-slot-size",category:"component",tier:"component",role:"InputOTP slot box (gh#233). Default `var(--control-height)` \u2014 byte-identical to before and still density-aware \u2014 but its OWN knob, so an auth panel can widen the 6-slot challenge row to fill a wide surface WITHOUT re-scoping --control-height (which would resize the primary button and every other input in the same card). Set it to a NAMED tier (`var(--control-height-lg)`), never an ad-hoc calc offset."},{name:"--tabs-indicator-{background,size,offset}",category:"component",tier:"component",role:"Tabs `line` ACTIVE indicator (gh#248) \u2014 the only selected-state decoration the line variant paints; it never gets a surrounding ring/card border, so the `:focus-visible` keyboard ring stays visible and distinct (WCAG 2.4.7). --tabs-indicator-background is declared `initial` so its hsl(var(--primary)) default re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme. Defaults = primary \xB7 2px \xB7 offset 0 (flush with the trigger edge); raise the offset to park the bar on a thicker strip hairline. The selected ring on the default/card variants is unchanged."},{name:"--avatar-square-{radius,size,background,foreground}",category:"component",tier:"component",role:'Avatar `shape="square"` entity-header mark (gh#249) \u2014 the compact rounded square an organization/service header uses instead of the round person avatar. --avatar-square-background / --avatar-square-foreground are declared `initial` so the hsl(var(--primary)) / hsl(var(--primary-foreground)) defaults re-resolve at the CALL SITE under a scoped theme. Defaults = --radius-lg corners \xB7 --control-height box (swapping shape never reflows the header) \xB7 primary fill at 4.65:1 contrast. `shape="circle"` (the default) is inert and reads --avatar-background / --avatar-tint as before.'},{name:"--steps-inline-{gap,item-gap,font-size,separator-size}",category:"component",tier:"component",role:"Steps type=inline compact auth/device progress rhythm and typography. Consumers select the semantic appearance; services retune the row once without page CSS."},{name:"--auth-account-summary-{min-height,gap,padding,identity-min-width,avatar-size,avatar-glyph-size,email-font-size}",category:"component",tier:"component",role:"AuthAccountSummary compact signed-in identity row: wrapping threshold, avatar, email and action rhythm. The default touch-safe row is package-owned and remains themeable without consumer selectors."},{name:"--auth-shell-{main-align,card-stack-gap}",category:"component",tier:"component",role:"AuthShell column knobs shared by every preset. --auth-shell-main-align is the block alignment of the auth column (default `center`, the vertically-centred card; set `start` for a tall intro+card+footnote stack). --auth-shell-card-stack-gap is the gap between the card slot's direct sections \u2014 default `0px` (quiet, rule #44) so an existing single-card consumer is byte-for-byte unchanged; a preset opts in."},{name:"--card-space-shell-y",category:"component",tier:"component",role:"Card BLOCK-axis shell padding (gh#232) \u2014 a plain header's top, a `solo` body's top and the terminal slot's bottom. Split off --card-space-inset, which is now inline-only, so a theme can make a card SHORTER without narrowing its column. Declared `initial`: the default resolves at the CALL SITE to --card-space-inset, so a card that overrides neither (and `density=\"tight|cozy\"`, which re-declares it `initial` to re-arm the per-instance inset) renders exactly as before."},{name:"--auth-shell-{compact-card-inset,card-padding-block-compact,card-body-gap-compact,card-gap-compact}",category:"component",tier:"component",role:"The compact AuthShell card's four independent knobs (gh#232) \u2014 one per axis, so the canonical Login card is tunable WITHOUT a consumer selector on the card-content slot: `compact-card-inset` = the inline column (\u2192 --card-space-inset); `card-padding-block-compact` = the card's block/top-bottom padding (\u2192 --card-space-shell-y, `initial` so its default mirrors the live inline inset and canonical output is unchanged); `card-body-gap-compact` = the header\u2194body gap (\u2192 --card-space-body-y, 12px, the role the block knob used to be mis-wired to); `card-gap-compact` = the in-slot title\u2195description stack gap (\u2192 --card-space-gap)."},{name:"--app-setting-picker-compact-{control-height,padding-x,gap,font-size}",category:"component",tier:"component",role:'AppSettingPicker `compact` trigger (gh#217) \u2014 the small, content-hugging LABELLED switcher for an auth/legal footer (`kind="locale" appearance="labeled" compact`). The box height reads the official --control-height-sm tier (never a literal or an ad-hoc calc), and padding/gap/type are separate knobs so a service theme retunes the footer switcher without forking CSS.'},{name:"--centered-shell-column-offset-block",category:"component",tier:"component",role:'CenteredShell column block offset (gh#221) \u2014 default `0` (the quiet state, rule #44: the top-aligned flowing/scrolling page). `<CenteredShell align="center">` flips it to `auto`, which centres the column in the 100dvh shell: the package-owned geometry for a SYSTEM-level standalone surface (a 500/503 error page, a maintenance notice) at 1440/1024/390, so a consumer never writes `min-h-dvh` + flex-centring CSS or a className. Auto block offsets collapse to 0 when the content is taller than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--error-surface-*",category:"component",tier:"component",role:'ErrorSurface knobs (gh#221 / gh#251) \u2014 the whole 403/404/500/503 exception surface is themeable without a single consumer class or media query, in BOTH `mode="application"` and `mode="system"`. Geometry: `--error-surface-max-width` (32rem measure of the surface block, so a long JA/VI headline wraps readably even inside a wide PageContainer), `--error-surface-gap` (rhythm between status code \xB7 body \xB7 metadata \xB7 progress), `--error-surface-padding-block` (--space-10, the 1440/1024 steps) and `--error-surface-padding-block-compact` (--space-6, below the narrow step, i.e. the 390 case), `--error-surface-brand-gap` (system-mode Logo slot) and `--error-surface-progress-max-width` (18rem, so the maintenance meter reads as metadata, not as the page\'s primary content). Metadata list: `--error-surface-meta-gap` (row rhythm) \xB7 `--error-surface-meta-row-gap` (label\u2194value gap inside one row) \xB7 `--error-surface-meta-padding-block`. Chrome is QUIET by default (rule #44): `--error-surface-meta-border` is `none`; a service opts in with `1px solid hsl(var(--border))`. The narrow step is a CONTAINER query at 30rem on the SURFACE\'s own width, not a viewport media query, so it compacts correctly whether the squeeze came from a 390px phone or from an application shell with an expanded sidebar; below it, metadata rows stack label-over-value. System-mode viewport centring is delegated to `--centered-shell-column-offset-block` (via CenteredShell align="center"), and the description measure to `--empty-state-description-max-width`.'},{name:"--centered-shell-landing-*",category:"component",tier:"component",role:'CenteredShell public-landing knobs (gh#252) \u2014 the SHELL geometry of a public marketing/product landing, so the landing itself stays a COMPOSITION (Hero/Navbar/Footer fail the Framework-Component Test) with ZERO page-local CSS. Read only under `preset="public-landing"`; the default shell emits no `data-preset`, so none of them can match. Measure: `--centered-shell-landing-max-width` (67.5rem, shared by the header bar, the centred column AND the footer \u2014 the bar/footer inline padding is `max(gutter, (100% - measure) / 2)`, so header content starts on exactly the column edge and no consumer max-width wrapper exists), `--centered-shell-landing-inset-inline` (+ `-compact`, the 390 gutter), `--centered-shell-landing-main-padding-block` (+ `-compact`), `--centered-shell-landing-section-gap` (+ `-compact`, the rhythm BETWEEN plain `<section>` elements \u2014 the consumer never sets a gap) and `--centered-shell-landing-footer-padding-block`. Chrome is QUIET by default (rule #44): `--centered-shell-landing-card-shadow` is `none`, which flattens every Card in the subtree from ONE knob instead of a consumer `.landing .card { box-shadow: none }`. Type: `--centered-shell-landing-heading-size` (+ `-compact`) re-points `--heading-h1`, so a hero title is a real `Heading level={1}` and never a page font-size. `--centered-shell-landing-background` is a ROLE-MIRROR declared `initial` with the role default at the call site (`var(--centered-shell-landing-background, var(--background))`), so a scoped [data-tenant]/.dark override of `--background` still reaches the landing canvas. The compact step is a 40rem media query owned by the package; region visibility (anchor nav below the tablet step, wordmark and the secondary action at mobile) is `Flex hideBelow` / `hideFrom`, never a consumer @media.'},{name:"--table-action-collection-*",category:"component",tier:"component",role:'Table action-collection knobs (gh#253) \u2014 the canonical dense approval/action queue at 1440 \xB7 1024 \xB7 390. Read only under `preset="action-collection"`. Column PRIORITY measures replace the desktop intrinsic widths (a `white-space: nowrap` free-text column is what makes a five-column queue wider than its card and forces the horizontal scroll): `--table-action-collection-primary-width` (18%), `-secondary-width` (22%), `-meta-width` (12%) and `-actions-width` (3.5rem \u2014 an absolute measure because the row-action affordance must never be squeezed below its touch target); an unmarked column takes the remaining space. Below the collapse step the same four re-point to their `-compact` tier (24% / 22% / 20% / 2.75rem) together with `--table-action-collection-font-size-compact`, `-row-height-compact`, `-cell-space-x-compact` and `-cell-padding-y-compact`. The step is a CONTAINER query on the table\'s own width (sm 40rem \xB7 md 48rem \xB7 lg 64rem \xB7 xl 80rem via `collapseBelow`), not a viewport media query, so a table inside a master rail collapses before the page does. Percentages so the ratio holds at any card width; a service retunes the ratio once instead of authoring column widths per screen (rule #45). ONE family serves BOTH entry points \u2014 the `Table` primitive (`priority` on `TableHead`/`TableCell`) and the TanStack `DataTable` (`priority` on the `ColumnDef`, stamped onto both cells for you). There is deliberately no parallel `--data-table-action-collection-*` family: retune these once and every queue follows.'},{name:"--legal-document-*",category:"component",tier:"component",role:"LegalDocumentShell knobs (gh#222) \u2014 the whole legal/policy document surface is themeable without a single consumer `.legal-*` class. Geometry: `--legal-document-measure-max-width` (46rem readable measure, caps header/body/footer), `--legal-document-toc-width` \xB7 `--legal-document-column-gap` \xB7 `--legal-document-toc-inset-block-start` (sticky offset) \xB7 `--legal-document-toc-max-height`, `--legal-document-section-gap` \xB7 `--legal-document-section-title-gap` \xB7 `--legal-document-header-gap` \xB7 `--legal-document-meta-gap` \xB7 `--legal-document-nav-gap` \xB7 `--legal-document-footer-gap`, `--legal-document-meta-font-size`, `--legal-document-body-line-height` (1.8 long-form leading) and `--legal-document-scroll-offset` (the `scroll-margin-block-start` a hash jump leaves above a heading \u2014 this is why no app needs JS offset arithmetic). Contents entries: `--legal-document-toc-font-size` \xB7 `--legal-document-toc-title-font-size` \xB7 `--legal-document-toc-item-padding` \xB7 `--legal-document-toc-item-radius` \xB7 `--legal-document-toc-marker-width`. Chrome is QUIET by default (rule #44): `--legal-document-toc-border` / `--legal-document-header-border` / `--legal-document-footer-border` are all `none`; a service opts in with `1px solid hsl(var(--border))`. The six colour knobs are ROLE-MIRRORS declared `initial` with the role default at the call site \u2014 `--legal-document-toc-foreground` (\u2192 --muted-foreground, also paints the contents caption), `--legal-document-toc-active-foreground` (\u2192 --foreground), `--legal-document-toc-active-background` (\u2192 --accent), `--legal-document-toc-marker-color` (\u2192 --primary), `--legal-document-meta-foreground` (\u2192 --muted-foreground) and `--legal-document-summary-foreground` (\u2192 --muted-foreground) \u2014 so a scoped [data-tenant]/.dark override of the role still reaches them. The one-column \u21C4 two-column split is a CONTAINER query at 56rem on the shell's own width, not a viewport media query."},{name:"--empty-state-description-max-width",category:"component",tier:"component",role:"EmptyState description MEASURE (gh#221) \u2014 default 28rem (~65 Latin characters per line). A service or locale that needs a shorter/longer measure for its own copy (JA/VI error-page descriptions, a narrow system surface) retunes this one knob instead of forking `.ui-empty-state-description` (rule #45)."},{name:"--sidebar-nav-item-{foreground,hover-foreground,disabled-foreground} / --sidebar-nav-icon-{foreground,hover-foreground,active-foreground,disabled-foreground}",category:"component",tier:"component",role:"Sidebar navigation row + icon COLOUR, split so they can differ (gh#228). Previously `.sb-nav-item` set one `color` for the whole row, so the Lucide SVG inherited `--muted-foreground` along with the label and the icons read as 'missing' against a canonical shell that wants darker 16px icons. `--sidebar-nav-item-*` drives the row/label (incl. sub rows), `--sidebar-nav-icon-*` drives `.sb-icon`. All are role-mirror knobs declared `initial` at `:root` with the role default at the call site, so a scoped `[data-tenant]`/`.dark` override reaches them; icon defaults resolve to `currentColor`, i.e. rendering is unchanged until a service opts in (`--sidebar-nav-icon-foreground: hsl(var(--foreground))` is the canonical darker-icon setting). Colour ONLY \u2014 the 16px icon, 32px row height and 10px gap are untouched. The active row keeps `--sidebar-item-active-{background,foreground}`."},{name:"--list-row-compact-{padding-y,padding-x,gap,body-min-width}",category:"component",tier:"component",role:'ListRow `density="compact"` inline-actions geometry (gh#246) \u2014 the compact invitation/history row: a 36px leading Avatar, a shrinkable title+description and one or two small trailing Buttons on ONE line inside the canonical 358px card (326px content). `--list-row-compact-body-min-width` (6rem) is the compact body threshold \u2014 the default 12rem `--list-row-body-min-width` is what forced the actions (and a history Badge + date) onto a second line at 390px; it is consumed as `min(<token>, 100%)` exactly like the default knob, so the #224 wrap contract is intact and a cluster that genuinely cannot fit still wraps instead of widening the page root. `--list-row-compact-{padding-y,padding-x,gap}` are declared `initial` with the density-scaled default at the CALL SITE (`var(--space-2)` block, `var(--list-row-padding-x)` inline, `var(--space-2)` gap) \u2014 a `:root` binding would freeze compact rows at the `:root` density. Measured at 390px: invitation row 62px (was 126px, actions wrapped), history row 41px (was 114px), documentElement scrollWidth === clientWidth.'},{name:"--list-row-{body-min-width,trailing-gap,indicator-size,read-background,unread-background,indicator-color}",category:"component",tier:"component",role:"ListRow shrink + unread state (gh#224, gh#225). `--list-row-body-min-width` (12rem) is consumed as `min(<token>, 100%)` \u2014 the `min()` is load-bearing, a bare length re-inflates the row's intrinsic width and reintroduces page-root overflow. `--list-row-trailing-gap` spaces wrapped trailing actions. The unread trio are role-mirror knobs declared `initial` with the role at the call site: `--list-row-unread-background` defaults to `hsl(var(--muted))` NOT `--accent` \u2014 accent measured 4.23:1 against the xs muted-foreground description line, below WCAG AA; muted is 4.63:1 light / 5.47:1 dark. `--list-row-indicator-color` (\u2192 `--primary`) and `--list-row-indicator-size` drive the unread dot, whose meaning is carried by localized sr-only text, never by colour alone."},{name:"--filter-bar-scroll-padding-y",category:"component",tier:"component",role:'Scrollbar gutter for `<FilterBar overflow="scroll">` (gh#216), default `var(--space-1)`. Only applies at \u2265640px, where a wide filter set becomes a single nowrap strip with a sticky inline-end clear-all; below that the bar still stacks, so the gutter would be dead space. Pair with the existing `--filter-bar-sticky-background` (already an `initial` role-mirror knob) when theming the strip.'},{name:"--app-shell-{sidebar-width,rail-width}",category:"component",tier:"component",role:"AppShell docked navigation rail widths (gh#213) \u2014 `--app-shell-sidebar-width` (default 16rem) is the expanded rail, `--app-shell-rail-width` (default 4rem) the icon-only rail used at `<AppShell sidebarCollapsed>`. These were hard-coded `grid-template-columns` literals; a service on a different design grid (e.g. a 255px rail) now sets ONE token in its theme instead of forking `.app-root`. Below the 900px shell breakpoint both collapse to a single full-width column and the sidebar moves into AppShell's drawer."},{name:"--app-shell-bar-{inset,inset-compact,gap}",category:"component",tier:"component",role:"AppShell top-bar chrome (gh#213) \u2014 `--app-shell-bar-inset` is the bar's inline padding (default --space-4), `--app-shell-bar-inset-compact` the tighter value applied below the 900px breakpoint where the docked rail is gone (default --space-3), `--app-shell-bar-gap` the gap between the bar's direct children (default --space-3). Height stays `--app-shell-bar-height` (3rem), which now holds at EVERY width \u2014 a duplicate 768px rule used to override it with a literal."},{name:"--topbar-{height,inset,gap}",category:"component",tier:"component",role:"Standalone `<Topbar>` box knobs (gh#213). Topbar is a pure slot bar, so the defaults are the QUIET ones and rendering is unchanged from before they existed: `--topbar-height: auto` and `--topbar-inset: 0px` (inside AppShell the `.app-topbar` grid row owns height and inset), `--topbar-gap: var(--space-2)`. A service that mounts Topbar DIRECTLY on a page sizes it from the theme (`--topbar-height: 3.5rem; --topbar-inset: var(--space-4)`) instead of an app-local class. `--topbar-gap` is both the gap BETWEEN the start/center/end clusters and the gap INSIDE each, so one knob re-rhythms the whole bar. None of them touch the gh#226 shrink contract (start clips, center yields first, end stays anchored inline-end)."},{name:"--{dialog,sheet}-overlay-background / --app-shell-mobile-nav-background (+ -alpha)",category:"component",tier:"component",role:"Overlay scrims (gh#215). All three are ROLE-MIRROR knobs declared `initial` at `:root`, with the default resolved at the CALL SITE as a SHARE of the one semantic `--overlay-background` \u2014 `color-mix(in srgb, var(--overlay-background) var(--<x>-overlay-alpha), transparent)`. Previously each carried a private literal, so setting `--overlay-background` had NO effect anywhere. The share knobs (`--dialog-overlay-alpha` 60%, `--sheet-overlay-alpha` 40%, `--app-shell-mobile-nav-alpha` 40%) keep every default byte-identical (0.3 / 0.2 / 0.2 black) while letting one `--overlay-background` override retint the whole system, including scoped `[data-tenant]` / `.dark` themes. Setting a `*-overlay-background` knob directly still wins outright. NOTE: overlays render in a portal, so a multi-tenant scope must also sit on the portal container."}];function I(t){return C.filter(a=>a.category===t)}var V=[{name:"--badge-space-gap",value:"var(--space-inline-xs)",description:"Badge component tokens."},{name:"--badge-space-x",value:"var(--space-2)",description:"Badge component tokens."},{name:"--badge-space-y",value:"var(--space-1)",description:"Badge component tokens."},{name:"--badge-font-size",value:"var(--font-size-xs)",description:"Small-by-design (badge/pill/counter). A knob (rule #45) so a service can * re-tune badge text without touching the global --font-size-xs step."},{name:"--card-space-inset",value:"var(--space-section-active)",description:"Horizontal inset of every slot (header / content / footer) + the resting top/bottom * shell padding. This is the column the title, body and footer all align to."},{name:"--card-space-shell-y",value:"initial",description:'BLOCK-axis (top/bottom) shell padding of the slotted card rhythm \u2014 a plain header\'s top, a * `solo` body\'s top, and the terminal slot\'s bottom (gh#232). Split off --card-space-inset so a * shell (AuthShell compact) can retune the card\'s height WITHOUT moving the inline column. * Declared `initial` \u2014 NOT `var(--card-space-inset)` \u2014 so the default resolves at the CALL SITE: * a :root binding would freeze at the :root inset and `[data-density="tight"|"cozy"]` (which * override --card-space-inset on the card element) would stop reaching it. See docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`" \u2014 the same call-site rule applies to derived knobs.'},{name:"--card-space-header-y",value:"var(--space-stack-sm)",description:"Vertical padding of a BANDED header band (top = bottom). Drives --card-space-divided-y."},{name:"--card-space-body-y",value:"var(--space-section-active)",description:"Gap between the header and the body, and the body's own top padding \u2014 the breathing * room under a title before content begins."},{name:"--card-space-solo-y",value:"initial",description:'Symmetric block padding for a SOLO content slot, so a composed shell can tune block and * inline spacing independently without targeting CardContent. * Declared `initial` for the SAME reason as --card-space-shell-y above: written as * `var(--card-space-inset)` here it would freeze at the :root inset, and a card carrying * [data-density="tight"|"cozy"] (which override --card-space-inset ON THE CARD) would keep the * :root value. The default now resolves at the call site through the chain * solo-y \u2192 shell-y \u2192 inset, so a solo body follows the general block knob when only that is * set, and an explicit solo-y still wins.'},{name:"--card-space-footer-y",value:"var(--space-stack-sm)",description:"Vertical padding of a SEPARATED footer band (top = bottom). Drives --card-space-divided-y."},{name:"--card-space-divided-y",value:"var(--card-space-header-y)",description:"DIVIDED-section vertical padding (rule #44/#45). A header/footer that carries a divider * border (banded header, separated footer) reads as its own band, so it pads SYMMETRICALLY * top+bottom \u2014 distinct from a plain header that flows into the body (top inset, no bottom). * One themeable knob keeps the header- and footer-band rhythm in sync; a service theme tunes * the band density here instead of forking per-slot CSS."},{name:"--card-space-gap",value:"var(--space-stack-xs)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-font-size",value:"var(--font-size-base)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-line-height",value:"var(--line-height-tight)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-font-weight",value:"var(--font-weight-semibold)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-description-font-size",value:"var(--font-size-sm)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-description-line-height",value:"var(--line-height-normal)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-background",value:"initial",description:'Card fill + edge \u2014 opt-in knobs that DEFAULT to the live --card / --border roles. Declared * `initial` (not `var(--card)`) so the default re-resolves at the call site under a scoped theme: * a :root binding to a role var freezes at the :root value and a scoped `[data-tenant]` override of * the role never reaches it (see docs/STANDARDS-vocabulary-tokens.md \xB7 "role-mirror knobs"). A * service still overrides the knob directly (--card-background: \u2026) to win over the role default.'},{name:"--card-border",value:"initial",description:"default = hsl(var(--card))"},{name:"--card-header-background",value:"initial",description:"Banded-header fill \u2014 role-tintable (rule #45): a service points this at any role, * e.g. --card-header-background: var(--primary), and tunes --card-header-background-alpha for * the wash strength. Default = the live --muted role (resolved at the call site)."},{name:"--card-header-background-alpha",value:"0.55",description:"default = hsl(var(--muted))"},{name:"--card-header-border-bottom",value:"initial",description:"Banded-header divider \u2014 tokenised (rule #44) so a service theme can make it * dashed / heavier / none without forking CSS. Pair with * --card-header-background-alpha: 0 for a quiet borderless-band header. * Default = 1px solid hsl(var(--card-border)) (resolved at the call site)."},{name:"--card-radius",value:"var(--radius-xl)",description:"Banded-header divider \u2014 tokenised (rule #44) so a service theme can make it * dashed / heavier / none without forking CSS. Pair with * --card-header-background-alpha: 0 for a quiet borderless-band header. * Default = 1px solid hsl(var(--card-border)) (resolved at the call site)."},{name:"--card-shadow",value:"var(--shadow-sm)",description:"The DXS hi-fi baseline uses a quiet 10px data surface with one shadow-sm * elevation layer. Consumers can still flatten or lift cards through this knob."},{name:"--card-glow",value:"0 0 0 0 transparent",description:"Brand glow layer \u2014 invisible no-op at rest (rule #44). Paired AFTER --card-shadow in the * surface box-shadow so a service can wash every card with the global glow, e.g. * --card-glow: var(--shadow-glow), with no markup change."},{name:"--card-tint",value:"transparent",description:"Fill tint \u2014 subtle role wash over the card background (default transparent = invisible). * Painted as an overlay so a service sets --card-tint: hsl(var(--primary) / 0.04) once."},{name:"--card-accent-rail-width",value:"6px",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-font-size",value:"var(--font-size-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-font-weight",value:"var(--font-weight-medium)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-letter-spacing",value:"0.04em",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-font-size",value:"var(--font-size-2xl)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-line-height",value:"1.1",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-font-weight",value:"var(--font-weight-semibold)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-hint-font-size",value:"var(--font-size-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-gap",value:"var(--space-stack-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-size",value:"2.25rem",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-glyph-size",value:"1.25rem",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-radius",value:"var(--radius-md)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-background",value:"initial",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--stat-card-icon-foreground",value:"initial",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--stat-card-delta-font-size",value:"var(--font-size-xs)",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-space-gap",value:"var(--space-stack-sm)",description:"\u2500\u2500 ServiceLauncherCard (gh#219) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Internal rhythm of a launcher tile: one gap knob drives the vertical stack AND the * icon\u2194title\u2194status row, so a service theme retunes the whole tile density once."},{name:"--card-service-launcher-icon-size",value:"var(--control-height-lg)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-glyph-size",value:"var(--space-5)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-radius",value:"var(--radius-md)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-background",value:"initial",description:"Available-service medallion tint. `initial` (role-mirror rule, docs/TOKENS.md) so the role * defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override reaches them. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-icon-foreground",value:"initial",description:"Available-service medallion tint. `initial` (role-mirror rule, docs/TOKENS.md) so the role * defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override reaches them. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-unavailable-icon-background",value:"initial",description:"Unavailable medallion tint \u2014 applied when the consumer supplies `disabledReason`, so an * un-launchable service never reads as brand-live. `initial` for the same role-mirror reason. * Defaults = hsl(var(--muted)) fill \xB7 hsl(var(--muted-foreground)) glyph."},{name:"--card-service-launcher-unavailable-icon-foreground",value:"initial",description:"Unavailable medallion tint \u2014 applied when the consumer supplies `disabledReason`, so an * un-launchable service never reads as brand-live. `initial` for the same role-mirror reason. * Defaults = hsl(var(--muted)) fill \xB7 hsl(var(--muted-foreground)) glyph."},{name:"--card-service-launcher-description-font-size",value:"var(--font-size-xs)",description:"Description prose \u2014 also drives the disabled-reason line and the catalog-CTA caption."},{name:"--card-service-launcher-description-line-height",value:"var(--line-height-body)",description:"Description prose \u2014 also drives the disabled-reason line and the catalog-CTA caption."},{name:"--card-service-launcher-metadata-font-size",value:"var(--font-size-xs)",description:"Mono metadata line (hostname \xB7 plan) \u2014 tighter leading than prose by design."},{name:"--card-service-launcher-metadata-line-height",value:"var(--line-height-normal)",description:"Mono metadata line (hostname \xB7 plan) \u2014 tighter leading than prose by design."},{name:"--card-service-launcher-cta-min-height",value:"calc(var(--control-height-lg) * 4)",description:"Dashed catalog/add companion tile: kept tall enough to sit level with a populated launcher * tile in the same grid row. Four control tiers \u2248 medallion + title + description + action."},{name:"--card-service-launcher-skeleton-title-width",value:"var(--space-12)",description:"Skeleton bar widths \u2014 shape-matched placeholders for the title and status badge."},{name:"--card-service-launcher-skeleton-status-width",value:"var(--space-10)",description:"Skeleton bar widths \u2014 shape-matched placeholders for the title and status badge."},{name:"--chart-trend-plot-height-xs",value:"3.5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-sm",value:"5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-md",value:"7.5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-lg",value:"10rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height",value:"var(--chart-trend-plot-height-xs)",description:"Active tier \u2014 chart-layout.css re-points this per `data-size`; overriding it directly * pins one height for every trend regardless of `size`."},{name:"--chart-trend-bar-gap",value:"var(--space-2)",description:"\u2500\u2500 Bar marks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Thin marks, a surface gap between neighbours and a rounded data-end anchored to the * baseline (the data-visualization mark spec)."},{name:"--chart-trend-bar-radius",value:"var(--radius-sm)",description:"\u2500\u2500 Bar marks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Thin marks, a surface gap between neighbours and a rounded data-end anchored to the * baseline (the data-visualization mark spec)."},{name:"--chart-trend-bar-max-width",value:"1.5rem",description:"Ceiling on a single mark so a 3-point trend does not render slabs."},{name:"--chart-trend-bar-min-height",value:"2px",description:"Floor so a zero/absent value still reads as a plotted category rather than a hole."},{name:"--chart-trend-bar-background",value:"initial",description:'Muted mark fill \u2014 role-mirror knob, declared `initial` so the role default re-resolves * at the CALL SITE under `.dark` / `[data-tenant]` (docs/TOKENS.md \xB7 "Role-mirror knobs * MUST be `initial`"). Default = hsl(var(--muted-foreground) / 0.75), which clears the * 3:1 non-text contrast floor (WCAG 1.4.11) against the card surface.'},{name:"--chart-trend-bar-background-alpha",value:"0.75",description:"Opacity applied to the muted-fill role default."},{name:"--chart-trend-bar-emphasis-background",value:"initial",description:'Emphasized ("current") mark fill \u2014 role-mirror knob. Default = hsl(var(--primary)).'},{name:"--chart-trend-baseline-border",value:"initial",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-tick-gap",value:"var(--space-1)",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-tick-font-size",value:"var(--font-size-xs)",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-footer-gap",value:"var(--space-2)",description:"Gap between the plot block and the optional activity footer slot."},{name:"--control-height-compact",value:"1.75rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-default",value:"2rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-comfortable",value:"2.75rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-compact",value:"var(--space-2)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-default",value:"var(--space-3)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-comfortable",value:"var(--space-4)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height",value:"calc(var(--control-height-default) * var(--scaling))",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-sm",value:"calc(var(--control-height) - calc(0.25rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-height-lg",value:"calc(var(--control-height) + calc(0.25rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-height-xs",value:"calc(var(--control-height) - calc(0.5rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-padding-x",value:"var(--control-padding-x-default)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-gap",value:"var(--space-inline-sm)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-gap-sm",value:"var(--space-inline-xs)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-radius",value:"var(--radius)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--button-radius",value:"var(--radius-md)",description:"Button corner radius \u2014 defaults to the button's historical `rounded-md` so nothing * changes by default, but is its OWN knob so a service theme can retune the button * radius INDEPENDENTLY of input/control radius (issue #124)."},{name:"--control-font-size",value:"var(--font-size-base)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-border-width",value:"1px",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-shadow",value:"var(--shadow-xs)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-icon-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-icon-size-sm",value:"calc(0.875rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-focus-ring-width",value:"var(--focus-ring-width)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-gap",value:"var(--space-inline-sm)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-group-gap-x",value:"var(--space-6)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-group-gap-y",value:"var(--space-3)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-description-gap",value:"0.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-control-offset",value:"0.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width",value:"calc(2.25rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width-compact",value:"2rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width-comfortable",value:"2.5rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height",value:"calc(1.25rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height-compact",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height-comfortable",value:"1.375rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--slider-track-height",value:"0.375rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--slider-thumb-size",value:"1rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--otp-slot-size",value:"initial",description:'InputOTP slot box (gh#233). Its own knob so an auth surface can widen the 6-slot challenge row * to fill a wide panel WITHOUT re-scoping --control-height (which would resize every other * control in the same card). Declared `initial` \u2014 the tier-mirror form of the role-mirror rule in * docs/TOKENS.md: the default must resolve at the CALL SITE (`var(--otp-slot-size, * var(--control-height))`), because `--otp-slot-size: var(--control-height)` here would FREEZE at * the :root tier (32px) and an OTP row inside `.ui-auth-shell[data-variant="canonical"]`, which * re-scopes --control-height to 36px, would silently shrink. Verified in Chromium: 36px before * and after. A service opts in with a NAMED tier (`var(--control-height-lg)`), never a calc.'},{name:"--checkbox-checked-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--switch-checked-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--toggle-on-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--slider-track-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--slider-range-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--color-picker-input-width",value:"6.5rem",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-list-max-height",value:"min(300px, 50vh)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-input-padding-x",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-group-padding",value:"var(--space-1)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-item-padding-y",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-item-padding-x",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-width",value:"35rem",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-inset-top",value:"calc(var(--space-6) * 4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-viewport-inset",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-padding-y",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-padding-x",value:"var(--space-4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-gap",value:"var(--space-4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-edge-inset",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-start-padding",value:"calc( var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap) )",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-end-padding",value:"calc( var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap) )",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--choice-description-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--color-picker-hex-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-group-heading-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-label-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--tag-input-chip-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--toggle-sm-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--button-sm-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--control-height-compact",value:"2.75rem",description:"Rule #24 \u2014 on touch devices (coarse pointer) interactive controls keep a \u226544px tap target * regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height * resolves through these via var(), so inputs/buttons/selects/table rows all bump together."},{name:"--control-height-default",value:"2.75rem",description:"Rule #24 \u2014 on touch devices (coarse pointer) interactive controls keep a \u226544px tap target * regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height * resolves through these via var(), so inputs/buttons/selects/table rows all bump together."},{name:"--progress-label-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--tree-item-title-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--tree-item-description-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--timeline-note-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--avatar-background",value:"initial",description:"Avatar surface \u2014 `initial` so the --muted default re-resolves at the call site under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override never reaches it). A service re-tints the placeholder fill once (e.g. --avatar-background: hsl(var(--accent))). Default = hsl(var(--muted))."},{name:"--avatar-tint",value:"transparent",description:"Optional role wash over the avatar (default transparent = invisible, rule #44). Painted as an overlay so a service sets --avatar-tint: hsl(var(--primary) / 0.08)."},{name:"--avatar-square-radius",value:"var(--radius-lg)",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-size",value:"var(--control-height)",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-background",value:"initial",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-foreground",value:"initial",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--progress-track-background",value:"initial",description:"Progress track + fill \u2014 `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, fill reads --success; a service re-tones once. Defaults = hsl(var(--secondary)) track \xB7 hsl(var(--success)) fill."},{name:"--progress-fill-background",value:"initial",description:"Progress track + fill \u2014 `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, fill reads --success; a service re-tones once. Defaults = hsl(var(--secondary)) track \xB7 hsl(var(--success)) fill."},{name:"--timeline-dot-done-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--timeline-dot-current-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--timeline-line-completed-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--tree-item-active-border",value:"initial",description:"Tree active item \u2014 border + soft bg tint over the --primary role. `initial` so the default re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border \xB7 0.05 fill."},{name:"--tree-item-active-background",value:"initial",description:"Tree active item \u2014 border + soft bg tint over the --primary role. `initial` so the default re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border \xB7 0.05 fill."},{name:"--qr-code-foreground",value:"0 0% 0%",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-background",value:"0 0% 100%",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-xs",value:"6rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-sm",value:"8rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-md",value:"10rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-lg",value:"12.5rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--password-strength-score-font-size",value:"var(--font-size-xs)",description:"Data-entry component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--password-strength-checklist-font-size",value:"var(--font-size-xs)",description:"Data-entry component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--descriptions-label-width",value:"8rem",description:'Width of the label column when <Descriptions layout="horizontal">. Labels align to this * shared column so the values line up (the horizontal-detail look, mirroring <Form layout>). * A rem value gives a fixed aligned column; set `max-content` to size each label to its text. * (rule #44/#45 \u2014 a service theme tunes it here instead of forking CSS.)'},{name:"--email-shell-width",value:"480px",description:"\u2500\u2500 Shell \u2014 the 480px transactional-email geometry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-shell-padding",value:"32px",description:"canonical transactional card width"},{name:"--email-shell-page-padding",value:"24px",description:"card inset \u2014 mirrors --space-8 (2rem)"},{name:"--email-shell-border-width",value:"1px",description:"gutter between the client viewport and the card (--space-6)"},{name:"--email-card-radius",value:"10px",description:"card edge \u2014 mirrors the 1px --border hairline"},{name:"--email-card-reference-height",value:"407px",description:"mirrors --card-radius (--radius-xl = 6px \xD7 \u03C6 \u2248 10px)"},{name:"--email-stack-gap",value:"24px",description:"canonical invitation reference measures 480\xD7407"},{name:"--email-stack-gap-sm",value:"12px",description:"block rhythm \u2014 mirrors --space-stack-lg (1.5rem)"},{name:"--email-mark-width",value:"22px",description:'The mark ARTWORK is the same 32\xD732 capsule + glyph `<Logo mark="godx" />` paints; only the * RENDERED BOX differs. The canonical SCR-302 header sets it at 22px next to a 13px/700 "GoDX" * wordmark, which is smaller than the web --logo-godx-size (2rem) \u2014 an email header carries the * identity, not the navigation, so the lockup sits quieter (gh#250).'},{name:"--email-mark-height",value:"22px",description:"canonical SCR-302 header lockup mark box"},{name:"--email-mark-gap",value:"8px",description:"canonical SCR-302 header lockup mark box"},{name:"--email-wordmark-font-size",value:"13px",description:"mark \u2194 wordmark \u2014 mirrors --logo-wordmark-gap (--space-2)"},{name:"--email-wordmark-font-weight",value:"700",description:"canonical wordmark size (\u2248 --font-size-xs 12.5px)"},{name:"--email-font-family-sans",value:'"M PLUS 2", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic Medium", YuGothic, "Noto Sans JP", Meiryo, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, Arial, sans-serif',description:'The DXS canonical face is M PLUS 2 (see src/styles/fonts.css). Email clients honour NO * @font-face, so the stack ships the face NAME first and degrades through the platform JP faces * to a generic \u2014 a client with M PLUS 2 installed (or a webmail that already loaded it) renders * the canonical face, everything else lands on Hiragino (macOS/iOS) \u2192 Yu Gothic (Windows) \u2192 * Noto Sans JP \u2192 Meiryo \u2192 the system UI face \u2192 Arial \u2192 sans-serif. Family names are SINGLE-quoted * on export (the generator normalises) because an inline `style="\u2026"` attribute is double-quoted; * only ASCII aliases are listed, since a non-ASCII family name does not survive every transfer * encoding.'},{name:"--email-font-family-mono",value:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",description:"Tabular/reference strings \u2014 invoice ids, masked card numbers, ISO dates, amounts \u2014 are set in * the mono face in the canonical card. Mirrors --font-family-mono."},{name:"--email-body-font-size",value:"14px",description:"Tabular/reference strings \u2014 invoice ids, masked card numbers, ISO dates, amounts \u2014 are set in * the mono face in the canonical card. Mirrors --font-family-mono."},{name:"--email-body-line-height",value:"1.9",description:"1.9, NOT the web --line-height-body (1.7) \u2014 the canonical email card runs its JP body copy * looser than a screen, because a mail client gives the reader no density control."},{name:"--email-body-font-weight",value:"400",description:"1.9, NOT the web --line-height-body (1.7) \u2014 the canonical email card runs its JP body copy * looser than a screen, because a mail client gives the reader no density control."},{name:"--email-heading-font-size",value:"17px",description:"mirrors --font-weight-normal"},{name:"--email-heading-line-height",value:"1.7",description:"canonical card title (\u2248 --heading-h2, base \xD7 \u03C6^\xBC\xB2 \u2248 17.6px)"},{name:"--email-heading-font-weight",value:"500",description:"the title shares the card's body leading, not a tight ramp"},{name:"--email-cta-height",value:"36px",description:"\u2500\u2500 Primary CTA \u2014 the one action button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-cta-line-height",value:"36px",description:"mirrors --control-height-lg (2.25rem) \u2014 the canonical CTA box"},{name:"--email-cta-padding-x",value:"16px",description:"equal to the height: bulletproof vertical centring in Outlook"},{name:"--email-cta-radius",value:"6px",description:"mirrors --space-4"},{name:"--email-cta-font-size",value:"14px",description:"mirrors the --radius base (0.375rem)"},{name:"--email-cta-font-weight",value:"500",description:"mirrors --font-size-base"},{name:"--email-footer-font-size",value:"11px",description:"\u2500\u2500 Legal footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-footer-line-height",value:"1.8",description:"mirrors --font-size-2xs (base \xF7 \u03C6^\xBC\xB2 \u2248 11.1px)"},{name:"--email-footer-link-gap",value:"12px",description:"the legal band runs looser than the web --line-height-normal"},{name:"--email-footer-padding-top",value:"20px",description:"horizontal separation between footer links (--space-3)"},{name:"--email-footer-border-width",value:"1px",description:"space above the legal band"},{name:"--email-focus-border-width",value:"2px",description:"\u2500\u2500 Focus affordance (webmail preview panes that DO honour :focus) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-mobile-max-width",value:"520px",description:"\u2500\u2500 Mobile reflow \u2014 applied under the narrow media query and by inline fallbacks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-mobile-width",value:"100%",description:"the reflow breakpoint (card width + both gutters)"},{name:"--email-mobile-padding",value:"20px",description:"the card goes fluid below the breakpoint"},{name:"--email-mobile-page-padding",value:"12px",description:"reduced card inset \u2014 mirrors --space-5"},{name:"--email-mobile-heading-font-size",value:"16px",description:"One step below the 17px desktop title. The canonical 390px reference raster is unusable (it is * 435px wide and already clips the card \u2014 dxs-platform/platform#496), so this is the library's * documented contract rather than a measured canonical value."},{name:"--email-mobile-cta-width",value:"100%",description:"One step below the 17px desktop title. The canonical 390px reference raster is unusable (it is * 435px wide and already clips the card \u2014 dxs-platform/platform#496), so this is the library's * documented contract rather than a measured canonical value."},{name:"--error-surface-max-width",value:"32rem",description:"Measure of the surface block. Caps the status code + body + metadata column so a long ja/vi * headline wraps at a readable width in BOTH shells, including the application shell where * PageContainer is much wider than the copy wants to be."},{name:"--error-surface-gap",value:"var(--space-3)",description:"Rhythm between the status code, the EmptyState body, the metadata list and the progress meter."},{name:"--error-surface-padding-block",value:"var(--space-10)",description:"Block padding of the surface inside the shell it is placed in. Desktop (1440/1024) default; the * 390 step steps it down so a phone loses no vertical space (see styles/shell-layout.css)."},{name:"--error-surface-padding-block-compact",value:"var(--space-6)",description:"Block padding of the surface inside the shell it is placed in. Desktop (1440/1024) default; the * 390 step steps it down so a phone loses no vertical space (see styles/shell-layout.css)."},{name:"--error-surface-brand-gap",value:"var(--space-2)",description:"Brand slot (a Logo) above the status code, system mode only."},{name:"--error-surface-meta-gap",value:"var(--space-1)",description:"Metadata description list: row rhythm and the label\u2194value gap inside one row."},{name:"--error-surface-meta-row-gap",value:"var(--space-2)",description:"Metadata description list: row rhythm and the label\u2194value gap inside one row."},{name:"--error-surface-meta-border",value:"none",description:"Chrome, default quiet (#44). A service opts in with * `--error-surface-meta-border: 1px solid hsl(var(--border));`."},{name:"--error-surface-meta-padding-block",value:"0",description:"Chrome, default quiet (#44). A service opts in with * `--error-surface-meta-border: 1px solid hsl(var(--border));`."},{name:"--error-surface-progress-max-width",value:"18rem",description:"Width of the maintenance progress meter \u2014 narrower than the measure, so it reads as metadata * rather than as the primary content of the page."},{name:"--sheet-width-default",value:"22.5rem",description:"Feedback primitive tokens: dialog, alert, empty state."},{name:"--sheet-overlay-background",value:"initial",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--sheet-overlay-alpha",value:"40%",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-width-default",value:"32rem",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-viewport-inset",value:"1.5rem",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-overlay-background",value:"initial",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-overlay-alpha",value:"60%",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-space-x",value:"var(--space-chrome-x)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-y",value:"var(--space-chrome-y)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-inset",value:"var(--dialog-space-y) var(--dialog-space-x)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-gap",value:"var(--space-stack-md)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-close-space-offset",value:"var(--space-4)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-space-inset",value:"var(--space-section-active)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-space-gap",value:"var(--space-inline-md)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-inner-space-gap",value:"var(--space-stack-sm)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-dismiss-space-offset",value:"var(--space-3)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-bg-alpha",value:"0.05",description:"Soft (subtle) semantic tint ratios \u2014 themeable so a service can hit its exact spec * (a brand's success-bg/-border are often more present than the faint 5%/30% default)."},{name:"--alert-border-alpha",value:"0.3",description:"Soft (subtle) semantic tint ratios \u2014 themeable so a service can hit its exact spec * (a brand's success-bg/-border are often more present than the faint 5%/30% default)."},{name:"--dialog-content-glow",value:"0 0 0 0 transparent",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-space-y",value:"var(--space-10)",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-space-x",value:"var(--space-6)",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-description-max-width",value:"28rem",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-section-space-y",value:"var(--space-6)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-section-space-x",value:"var(--space-4)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-compact-space-y",value:"var(--space-3)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-compact-space-x",value:"var(--space-2)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-icon-foreground",value:"initial",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--empty-state-icon-tint",value:"initial",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-row-gap",value:"var(--space-stack-sm)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-cell-gap",value:"var(--space-inline-lg)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-card-inset",value:"var(--space-section-active)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-radius",value:"var(--radius)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-background",value:"initial",description:"Skeleton placeholder fill \u2014 `initial` so the --muted default re-resolves at the call site under * a scoped theme (a :root binding to a role var freezes at :root). A service tints the shimmer to * its surface (rule #44) without forking the keyframes. Default = hsl(var(--muted))."},{name:"--form-label-width",value:"max-content",description:"Width of the label column in horizontal/inline layout. A service theme sets * this once (e.g. 110px) to align every form to its design grid; the Form/ * FormField `labelWidth` prop overrides per form/field."},{name:"--form-label-gap",value:"var(--space-4)",description:"Column gap between the label and its control in horizontal/inline layout."},{name:"--legal-document-measure-max-width",value:"46rem",description:"Readable document measure. Caps the header, the section column and the footer so * a 1440px viewport still reads at ~75-90 characters per line."},{name:"--legal-document-column-gap",value:"var(--space-10)",description:"Rail \u2194 document column gutter (two-column mode only)."},{name:"--legal-document-toc-width",value:"15rem",description:"Sticky table-of-contents rail width (two-column mode only)."},{name:"--legal-document-toc-inset-block-start",value:"var(--space-6)",description:"Distance the pinned rail keeps from the top of the scrollport."},{name:"--legal-document-toc-max-height",value:"calc(100dvh - var(--space-12))",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-gap",value:"var(--space-1)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-item-padding",value:"var(--space-1) var(--space-2)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-item-radius",value:"var(--radius)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-title-font-size",value:"var(--font-size-2xs)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-font-size",value:"var(--font-size-xs)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-marker-width",value:"2px",description:"Leading marker on the active contents entry \u2014 a non-colour affordance so the * active state is never colour-only (WCAG 1.4.1)."},{name:"--legal-document-nav-gap",value:"var(--space-4)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-header-gap",value:"var(--space-2)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-meta-gap",value:"var(--space-2)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-meta-font-size",value:"var(--font-size-xs)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-section-gap",value:"var(--space-10)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-section-title-gap",value:"var(--space-3)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-body-line-height",value:"1.8",description:"Long-form leading \u2014 legal prose reads looser than UI text."},{name:"--legal-document-scroll-offset",value:"var(--space-6)",description:"`scroll-margin-block-start` on every section: the offset a hash jump / anchor * activation leaves above the heading so it is not hidden under sticky chrome."},{name:"--legal-document-footer-gap",value:"var(--space-4)",description:"`scroll-margin-block-start` on every section: the offset a hash jump / anchor * activation leaves above the heading so it is not hidden under sticky chrome."},{name:"--legal-document-toc-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-header-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-footer-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-meta-foreground",value:"initial",description:"\u2500\u2500 Role-mirror knobs \u2014 `initial` here, role default at the call site \u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-summary-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-active-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-active-background",value:"initial",description:"default = hsl(var(--foreground))"},{name:"--legal-document-toc-marker-color",value:"initial",description:"default = hsl(var(--accent))"},{name:"--list-row-padding-y",value:"var(--space-3)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-padding-x",value:"var(--space-4)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-gap",value:"var(--space-3)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-border",value:"initial",description:"Row divider \u2014 `initial` so the --border default re-resolves at the call site under a scoped * theme (a :root binding to a role var freezes at :root). Default = 1px solid hsl(var(--border))."},{name:"--list-row-body-min-width",value:"12rem",description:"Inline size the content column keeps before the trailing actions wrap onto their own line * (#45 \u2014 a service retunes the stack threshold to its grid). Clamped with min(\u2026, 100%) at the * call site, so a container narrower than the knob can never force page-root overflow (#224)."},{name:"--list-row-trailing-gap",value:"var(--space-2)",description:"Gap BETWEEN trailing actions \u2014 they also wrap among themselves at narrow widths (#224)."},{name:"--list-row-compact-padding-y",value:"initial",description:'\u2500\u2500 Compact inline-actions geometry (`density="compact"`, #246) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The canonical invitation / history row: a 36px leading avatar, a shrinkable title + * description body and one or two small trailing Buttons, all on ONE line inside the canonical * 358px card (326px content after the row\'s own inline inset) at a 390px viewport. These knobs * only LOWER the geometry \u2014 the #224 wrap contract (row + trailing cluster wrap, body clamped * with min(\u2026, 100%)) is untouched, so a cluster that genuinely cannot fit still wraps instead of * widening the page root. * Declared `initial` so the spacing defaults re-resolve at the CALL SITE \u2014 --space-2 is * density-scaled and re-declared inside a `.ui-density-*` subtree, so a :root binding would * freeze compact rows at the :root density (docs/TOKENS.md \u2014 the :root freeze rule). * Defaults = var(--space-2) block padding \xB7 var(--list-row-padding-x) inline padding \xB7 * var(--space-2) gap.'},{name:"--list-row-compact-padding-x",value:"initial",description:"Inline inset defaults to the default row axis so compact and default rows in the same Card keep * one optical axis; a service retunes it to its own grid (#45)."},{name:"--list-row-compact-gap",value:"initial",description:"Inline inset defaults to the default row axis so compact and default rows in the same Card keep * one optical axis; a service retunes it to its own grid (#45)."},{name:"--list-row-compact-body-min-width",value:"6rem",description:"Compact body threshold \u2014 small enough that avatar + body + two compact Buttons fit the * canonical column (36 + 8 + 96 + 8 + 146 = 294 \u2264 326), and still a readable measure."},{name:"--list-row-read-background",value:"initial",description:"Read (default) row surface \u2014 `initial`, documented default = transparent, i.e. the Card * surface shows through untouched (#44 \u2014 chrome defaults to the quietest state)."},{name:"--list-row-unread-background",value:"initial",description:"Unread emphasis surface (`unread` rows) \u2014 `initial` so the --muted default re-resolves at the * call site under a scoped theme. Documented default = hsl(var(--muted)), the same quiet * emphasis role the table header uses; it keeps the xs muted description line at WCAG AA * (4.63:1 light / 5.47:1 dark), which hsl(var(--accent)) would not (4.23:1 light)."},{name:"--list-row-indicator-color",value:"initial",description:"Unread indicator dot fill \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme. Documented default = hsl(var(--primary))."},{name:"--list-row-indicator-size",value:"var(--space-2)",description:"Diameter of the read/unread indicator dot; the gutter is reserved on read rows too so the * titles of a mixed list stay on one optical axis."},{name:"--logo-radius",value:"var(--radius)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-xs",value:"1.25rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-sm",value:"1.5rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-md",value:"1.75rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-lg",value:"2.25rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-xs",value:"var(--font-size-2xs)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-sm",value:"var(--font-size-xs)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-md",value:"var(--font-size-sm)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-lg",value:"var(--font-size-base)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-success-background",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-success-foreground",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-godx-color",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-identity-foreground",value:"48 9% 9%",description:'Identity-fill INK \u2014 the ink `mark="glyph"` sets its (caller-supplied) TEXT in when it sits on * the --brand identity fill. This is deliberately NOT --brand-foreground. * * --brand-foreground is the identity artwork\'s KNOCKOUT colour, not an ink: it tracks * --background in both themes (light 60 33% 99% = --background; dark 48 9% 9% = --background) * because `<Logo mark="godx">` punches its inner bar as an evenodd HOLE and the email mark has to * paint that hole as a solid fill to match. Negative space only has to clear WCAG 2.2 SC 1.4.11 * (3:1, non-text) \u2014 and at 3.67:1 on the emerald it does. * * The boxed glyph is a different thing: it renders real TEXT, so SC 1.4.3 applies at 4.5:1 (14px * bold is NOT "large text" \u2014 that needs 18.66px bold / 24px), and the knockout white measured * 3.67:1 \u2192 a genuine AA failure. This ink is 48 9% 9% (#191815), the same near-black spine the * DARK theme already inked the glyph with, so it is theme-INVARIANT: dark renders byte-identically * (6.89:1, unchanged) and light rises 3.67 \u2192 4.74:1. A service that re-themes --brand to a dark * fill overrides --logo-success-foreground (the public knob) to re-invert the ink. * * NOT a role-mirror knob: its default is a real value, not a role token, so there is no role to * freeze at :root and the `initial` + call-site rule (docs/TOKENS.md) does not apply to it.'},{name:"--logo-godx-size-xs",value:"1.5rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-sm",value:"1.75rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-md",value:"2rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-lg",value:"2.5rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size",value:"initial",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-wordmark-gap",value:"var(--space-2)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-xs",value:"var(--font-size-xs)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-sm",value:"var(--font-size-sm)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-md",value:"var(--font-size-base)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-lg",value:"var(--font-size-lg)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-weight",value:"700",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-letter-spacing",value:"-0.01em",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-family",value:"initial",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-color",value:"initial",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--pagination-gap",value:"var(--space-inline-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-item-gap",value:"var(--space-inline-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-size-width",value:"5.5rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-total-font-size",value:"var(--font-size-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-bar-gap",value:"var(--space-3)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-bar-padding-y",value:"var(--space-2)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-label-font-size",value:"var(--font-size-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-picker-width-sm",value:"11rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-picker-width-md",value:"14rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-gap",value:"var(--space-2)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-item-gap",value:"var(--space-1)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-font-size",value:"var(--font-size-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-separator-size",value:"var(--control-icon-size-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--app-setting-picker-compact-control-height",value:"var(--control-height-sm)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-padding-x",value:"var(--space-2)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-gap",value:"var(--space-1)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--breadcrumb-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--menubar-shortcut-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-list-max-inline-size",value:"100%",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-list-overflow",value:"auto",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-indicator-background",value:"initial",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--tabs-indicator-size",value:"2px",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--tabs-indicator-offset",value:"0px",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--menubar-item-hover-background",value:"initial",description:"Menu item hover/highlight tint \u2014 `initial` so the --accent default re-resolves at the call site * under a scoped theme (a :root binding to a role var freezes at :root). * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--accent-foreground)) text."},{name:"--menubar-item-hover-foreground",value:"initial",description:"Menu item hover/highlight tint \u2014 `initial` so the --accent default re-resolves at the call site * under a scoped theme (a :root binding to a role var freezes at :root). * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--accent-foreground)) text."},{name:"--filter-bar-sticky-offset",value:"0px",description:"Sticky offset for the pinned filter strip (Toolbar `sticky`, #197). Default 0 (chrome, * rule #44); raise it so the strip parks below a fixed topbar."},{name:"--filter-bar-sticky-background",value:"initial",description:"Fill painted only when the filter strip is pinned. Role-mirror knob (rule #45): `initial` * so --background re-resolves at the call site under a scoped [data-tenant]/.dark theme."},{name:"--filter-bar-scroll-padding-y",value:"var(--space-1)",description:'Scrollbar gutter reserved under a `overflow="scroll"` filter strip (#216) so the inline * scrollbar never overlaps the controls. Rule #45 \u2014 a service theme retunes it to its grid * (0 on an overlay-scrollbar platform).'},{name:"--sheet-responsive-breakpoint-width",value:"48rem",description:'Viewport width at and below which `SheetContent responsive="auto"` renders the mobile bottom * sheet instead of the desktop side panel. Read at runtime by useSheetResponsiveMode() (a CSS * @media cannot resolve a custom property), so a service moves the drawer breakpoint from ONE * knob for every overlay that opts into the responsive contract \u2014 Sheet and OrgSwitcher alike. * 48rem = 768px mirrors the library\'s canonical mobile line (useIsMobile). Accepts px/rem/em.'},{name:"--sheet-bottom-max-height",value:"85dvh",description:'Block size cap for the responsive BOTTOM presentation only (never for a plain * `side="bottom"` sheet, which stays content-sized). Keeps the sheet below the viewport so the * SheetBody scrolls and the page behind it stays visible/dismissable.'},{name:"--sidebar-section-label-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-product-tenant-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-badge-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-user-role-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--org-switcher-meta-foreground",value:"var(--muted-foreground)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-nav-sub-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-flyout-title-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--topbar-chip-icon-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--kbd-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-logo-mark-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-avatar-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-user-name-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-gradient",value:"none",description:"Brand-chrome gradient hooks \u2014 opt-in, invisible by default. A service paints * the sidebar/topbar surface by setting these to a gradient (no-op = none)."},{name:"--topbar-gradient",value:"none",description:"Brand-chrome gradient hooks \u2014 opt-in, invisible by default. A service paints * the sidebar/topbar surface by setting these to a gradient (no-op = none)."},{name:"--app-shell-bar-height",value:"3rem",description:"DXS application-shell geometry. These defaults mirror the checked-in * Admin/Console hi-fi source while remaining themeable by consumers."},{name:"--app-shell-bar-inset",value:"var(--space-4)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-bar-inset-compact",value:"var(--space-3)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-bar-gap",value:"var(--space-3)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-sidebar-width",value:"16rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-rail-width",value:"4rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-page-max-width",value:"80rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-main-background",value:"hsl(var(--muted) / 0.4)",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-mobile-nav-width",value:"22.5rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-mobile-nav-background",value:"initial",description:"Mobile-drawer scrim \u2014 `initial` so the shared --overlay-background default re-resolves at the * CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding freezes at :root). Default = * var(--app-shell-mobile-nav-alpha) of the global scrim, i.e. rgb(0 0 0 / 0.2) out of the box."},{name:"--app-shell-mobile-nav-alpha",value:"40%",description:"Share of the global --overlay-background this drawer's scrim uses. A slide-in drawer washes the * page more lightly than a modal dialog; keeping it a RATIO means a service retints the whole * system with one --overlay-background and every overlay keeps its calibrated depth."},{name:"--app-shell-mobile-nav-inset",value:"var(--space-1)",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-brand-mark-size",value:"1.375rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-height",value:"2rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-font-size",value:"0.8125rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-line-height",value:"1.5",description:"Line box of the nav LABEL, not the row (gh#254): `.sb-label` clips, so its line box is its clip * box, and the row's `line-height: 1` shears descenders and Vietnamese tone marks. Keep >= 1.2."},{name:"--auth-account-summary-email-line-height",value:"1.5",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-start-truncate-line-height",value:"1.5",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-icon-size",value:"1rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-item-gap",value:"0.625rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-item-padding-x",value:"0.625rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-gap",value:"2px",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-scroll-padding",value:"var(--space-3) var(--space-2)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-gap",value:"var(--space-4)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-label-padding-x",value:"var(--space-2)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-label-padding-bottom",value:"var(--space-1)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-search-max-width",value:"26.25rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-height",value:"auto",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-inset",value:"0px",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-gap",value:"var(--space-2)",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-center-compact-display",value:"none",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-trigger-height",value:"2.75rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-trigger-padding-x",value:"var(--space-2)",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-avatar-size",value:"1.75rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-menu-width",value:"16rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-sheet-max-height",value:"75dvh",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-state-min-height",value:"8rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--sidebar-item-active-color",value:"initial",description:"Sidebar active-item tint/marker \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override * never reaches it). A service re-tunes the active sub-item accent without forking CSS. * Defaults = hsl(var(--primary)) marker/tint."},{name:"--sidebar-item-active-tint",value:"initial",description:"Sidebar active-item tint/marker \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override * never reaches it). A service re-tunes the active sub-item accent without forking CSS. * Defaults = hsl(var(--primary)) marker/tint."},{name:"--sidebar-item-active-background",value:"initial",description:"Main nav-item active row \u2014 defaults mirror the hover state (accent bg, foreground text); a * service overrides these to brand the selected row (e.g. a gold tint + gold text on a navy * sidebar). `initial` so the defaults re-resolve under a scoped theme. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--foreground)) text."},{name:"--sidebar-item-active-foreground",value:"initial",description:"Main nav-item active row \u2014 defaults mirror the hover state (accent bg, foreground text); a * service overrides these to brand the selected row (e.g. a gold tint + gold text on a navy * sidebar). `initial` so the defaults re-resolve under a scoped theme. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--foreground)) text."},{name:"--auth-shell-control-height",value:"var(--control-height-comfortable)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-heading-size",value:"var(--font-size-2xl)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-card-max-width",value:"24rem",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-bar-padding",value:"var(--space-5) var(--space-6)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-main-padding",value:"var(--space-6)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-footer-padding",value:"var(--space-3) var(--space-6) var(--space-4)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-canonical-control-height",value:"2.25rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-card-max-width",value:"22.5rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-heading-size",value:"var(--font-size-base)",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-main-padding",value:"1rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-main-padding-mobile",value:"0.9375rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-compact-card-inset",value:"var(--space-6)",description:"INLINE (start/end) inset of the compact auth card \u2014 the column the title, fields and actions * align to. Independent of the block axis below (gh#232)."},{name:"--auth-shell-card-padding-block-compact",value:"initial",description:"BLOCK (top/bottom) padding of the compact auth card \u2014 the knob that tunes canonical Login card * HEIGHT without narrowing the column. Bound to the card's --card-space-shell-y, so it really * reaches CardContent's block edges (before gh#232 it was wired only to --card-space-body-y and * the rendered body kept the inset on both block edges \u2014 the documented token did nothing). * Declared `initial` so the default mirrors the LIVE --auth-shell-compact-card-inset resolved at * the CALL SITE: the canonical card renders exactly as before (24px block = 24px inline), and a * service that re-tunes the inset inside a scoped `[data-tenant]` still drags the block default * with it (a :root binding would freeze at the :root inset \u2014 docs/TOKENS.md)."},{name:"--auth-shell-card-body-gap-compact",value:"var(--space-3)",description:"Header\u2194body gap inside the compact auth card (the breathing room under the title before the * first field). Its own knob since gh#232 \u2014 it used to ride on * --auth-shell-card-padding-block-compact, which conflated the section gap with the card's block * padding and made the block knob un-tunable. Default is the pre-gh#232 12px rhythm."},{name:"--auth-shell-card-gap-compact",value:"var(--space-3)",description:"IN-SLOT stack gap of the compact auth card (title \u2195 description inside the header)."},{name:"--auth-shell-main-align",value:"center",description:"Main-axis alignment of the auth column. Default `center` = today's vertically-centred card; * a flow whose intro + card + footnote stack is tall opts into `start` via this knob."},{name:"--auth-shell-card-stack-gap",value:"0px",description:"Gap between the direct sections of the auth column (intro \xB7 card \xB7 remember row). Default 0 * (quiet, rule #44) so an existing single-card consumer is untouched; presets opt in."},{name:"--auth-shell-login-card-max-width",value:"22.5rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-flow-offset-block",value:"14.4375rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-flow-offset-block-mobile",value:"13.8125rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-inline",value:"1rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-inline-mobile",value:"0.9375rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-block-end",value:"1rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-identity-slot-block-size",value:"7rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-card-stack-gap",value:"1.25rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-card-padding-block-compact",value:"calc( var(--auth-shell-compact-card-inset) + var(--control-border-width) + var(--control-border-width) )",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-device-card-max-width",value:"23.75rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-device-main-padding",value:"1rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-device-main-padding-mobile",value:"0.9375rem 0.3125rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-context-card-max-width",value:"25rem",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-main-padding",value:"var(--space-6)",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-main-padding-mobile",value:"var(--space-6) 0",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-card-stack-gap",value:"1rem",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-recovery-card-max-width",value:"27rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-recovery-main-padding",value:"1rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-recovery-main-padding-mobile",value:"0.9375rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-divider-gap",value:"0.625rem",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-label-font-size",value:"0.6875rem",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-rule-color",value:"var(--border)",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-label-color",value:"var(--muted-foreground)",description:"Labelled auth divider geometry."},{name:"--auth-identity-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-icon-size",value:"1rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-glyph-size",value:"0.625rem",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-min-height",value:"var(--control-height-comfortable)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-gap",value:"var(--space-2)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-padding",value:"var(--space-1) var(--space-2)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-identity-min-width",value:"12rem",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-avatar-size",value:"var(--control-height-sm)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-avatar-glyph-size",value:"var(--control-icon-size-sm)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-email-font-size",value:"var(--font-size-sm)",description:"Labelled auth divider geometry."},{name:"--auth-footer-content-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-footer-text-font-size",value:"0.6875rem",description:"Labelled auth divider geometry."},{name:"--auth-stack-gap",value:"var(--space-3)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-gap",value:"var(--space-1)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-font-size",value:"var(--font-size-xs)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-line-height",value:"1.25",description:"Labelled auth divider geometry."},{name:"--centered-shell-bar-height",value:"var(--app-shell-bar-height)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-bar-padding-x",value:"var(--space-4)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-main-padding",value:"var(--space-6)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-footer-padding",value:"var(--space-3) var(--space-6) var(--space-4)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-column-offset-block",value:"0",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-sm",value:"32rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-md",value:"46rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-lg",value:"64rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-landing-max-width",value:"67.5rem",description:'CenteredShell \xB7 public-landing preset (gh#252) \u2014 the token-owned geometry of a PUBLIC marketing * / product landing page: one content measure shared by header, main column and footer, the * section rhythm between page sections, the flat (chrome-quiet) card presentation and the hero * heading tier. Every value is a service-themeable knob (rule #45): a landing composition is a * COMPOSITION of real primitives (docs/COMPOSITION-VS-COMPONENT.md \u2014 Hero/Navbar/Footer FAIL the * Framework-Component Test), so the consumer must never own geometry or a media query. These * knobs are read ONLY under `.ui-centered-shell[data-preset="public-landing"]`, so the default * shell \u2014 which emits no `data-preset` at all \u2014 is byte-identical to before.'},{name:"--centered-shell-landing-inset-inline",value:"var(--space-6)",description:"1080px \u2014 header/main/footer share ONE measure"},{name:"--centered-shell-landing-inset-inline-compact",value:"var(--space-4)",description:"24px page gutter \u2265 40rem"},{name:"--centered-shell-landing-main-padding-block",value:"var(--space-10)",description:"16px page gutter < 40rem"},{name:"--centered-shell-landing-main-padding-block-compact",value:"var(--space-6)",description:"40px"},{name:"--centered-shell-landing-section-gap",value:"var(--space-10)",description:"24px"},{name:"--centered-shell-landing-section-gap-compact",value:"var(--space-6)",description:"rhythm BETWEEN page sections"},{name:"--centered-shell-landing-footer-padding-block",value:"var(--space-8)",description:"rhythm BETWEEN page sections"},{name:"--centered-shell-landing-card-shadow",value:"none",description:"Chrome is a token, default quiet (rule #44): a landing surface is FLAT \u2014 no card elevation \u2014 * so a service opts back IN with `--centered-shell-landing-card-shadow: var(--card-shadow)`."},{name:"--centered-shell-landing-heading-size",value:"var(--font-size-display)",description:"Hero heading tier. The preset re-points `--heading-h1` (same mechanism as * `.ui-auth-shell` \u2192 `--auth-shell-heading-size`), so a hero title is a real `Heading level={1}` * and never a consumer font-size."},{name:"--centered-shell-landing-heading-size-compact",value:"var(--font-size-3xl)",description:"Hero heading tier. The preset re-points `--heading-h1` (same mechanism as * `.ui-auth-shell` \u2192 `--auth-shell-heading-size`), so a hero title is a real `Heading level={1}` * and never a consumer font-size."},{name:"--centered-shell-landing-background",value:"initial",description:'Role-mirror knob \u2014 MUST stay `initial`, with the role default at the CALL SITE * (`var(--centered-shell-landing-background, var(--background))`), so a scoped * `[data-tenant]` / `.dark` override of `--background` still reaches it (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented default = hsl(var(--background)) \u2014 a public * page is the plain page canvas, not the app\'s `--muted` chrome.'},{name:"--sidebar-nav-item-foreground",value:"initial",description:"Resting nav row + label (also the resting sub-row). Default = hsl(var(--muted-foreground))."},{name:"--sidebar-nav-item-hover-foreground",value:"initial",description:"Hovered nav row + label. Default = hsl(var(--foreground))."},{name:"--sidebar-nav-item-disabled-foreground",value:"initial",description:"`aria-disabled` nav row + label. Default = the resting row colour."},{name:"--sidebar-nav-icon-foreground",value:"initial",description:"Nav ICON (`.sb-icon`, incl. the collapsed rail and group triggers). Default = currentColor, * i.e. the row colour \u2014 the pre-gh#228 look. Set this alone to get canonical dark icons next to * muted labels."},{name:"--sidebar-nav-icon-hover-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--sidebar-nav-icon-active-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--sidebar-nav-icon-disabled-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--table-row-height-compact",value:"1.75rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height-default",value:"2rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height-comfortable",value:"2.75rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height",value:"calc(var(--table-row-height-default) * var(--scaling))",description:"Table component tokens: row height, cell padding."},{name:"--table-cell-padding-y",value:"var(--space-2)",description:"Table component tokens: row height, cell padding."},{name:"--table-cell-space-x",value:"var(--control-padding-x)",description:"Table component tokens: row height, cell padding."},{name:"--table-pagination-padding-y",value:"initial",description:"Pagination footer inset (gh#236). The footer ships as a SELF-CONTAINED slot and is commonly * placed in a flush container (`<Card><CardContent flush><DataTable/>`), where no ancestor * supplies padding \u2014 so it owns its own on BOTH axes instead of declaring block-start only. * Block default = the previous single `padding-top` value, now on both block edges (breathing * room above the footer and before the container's closing border). Inline default = the cell * inline padding, so the \"rows per page\" label sits on the same optical axis as the first * column's text. A service retunes either axis to its own grid (#45). * Both are declared `initial` so the defaults re-resolve at the CALL SITE: --space-stack-sm and * --table-cell-space-x are density-scaled and re-declared inside a `.ui-density-*` subtree, and a * :root binding would freeze the footer at the :root density (docs/TOKENS.md \u2014 the :root freeze * rule). Defaults = var(--space-stack-sm) block \xB7 var(--table-cell-space-x) inline."},{name:"--table-pagination-padding-x",value:"initial",description:"Pagination footer inset (gh#236). The footer ships as a SELF-CONTAINED slot and is commonly * placed in a flush container (`<Card><CardContent flush><DataTable/>`), where no ancestor * supplies padding \u2014 so it owns its own on BOTH axes instead of declaring block-start only. * Block default = the previous single `padding-top` value, now on both block edges (breathing * room above the footer and before the container's closing border). Inline default = the cell * inline padding, so the \"rows per page\" label sits on the same optical axis as the first * column's text. A service retunes either axis to its own grid (#45). * Both are declared `initial` so the defaults re-resolve at the CALL SITE: --space-stack-sm and * --table-cell-space-x are density-scaled and re-declared inside a `.ui-density-*` subtree, and a * :root binding would freeze the footer at the :root density (docs/TOKENS.md \u2014 the :root freeze * rule). Defaults = var(--space-stack-sm) block \xB7 var(--table-cell-space-x) inline."},{name:"--table-surface-min-inline-size",value:"640px",description:'DataTable surface \u2014 narrow-viewport legibility FLOOR (gh#253). Below the `sm` viewport step a * multi-column admin grid whose columns are `white-space: nowrap` would otherwise be crushed, so * the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. * This shipped as a hard-coded `min-w-[640px]` utility on the surface element, which left a * service that wants a narrower (or no) floor with no route but forking the component (#45). * Default = the previous literal, in px so the floor releases at EXACTLY the same width as the * px-based `sm` media query that clears it (a rem value would drift under a non-16px root and * re-introduce the scroll between the two thresholds). Set `0` to opt out entirely \u2014 which is * what `preset="action-collection"` does, because there the priority measures own the width.'},{name:"--table-head-font-size",value:"var(--font-size-xs)",description:'DataTable surface \u2014 narrow-viewport legibility FLOOR (gh#253). Below the `sm` viewport step a * multi-column admin grid whose columns are `white-space: nowrap` would otherwise be crushed, so * the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. * This shipped as a hard-coded `min-w-[640px]` utility on the surface element, which left a * service that wants a narrower (or no) floor with no route but forking the component (#45). * Default = the previous literal, in px so the floor releases at EXACTLY the same width as the * px-based `sm` media query that clears it (a rem value would drift under a non-16px root and * re-introduce the scroll between the two thresholds). Set `0` to opt out entirely \u2014 which is * what `preset="action-collection"` does, because there the priority measures own the width.'},{name:"--table-header-background",value:"initial",description:"Header band \u2014 its OWN bg + fg knobs (decoupled from --secondary). Declared `initial` so the * default re-resolves to the LIVE --muted / --muted-foreground roles at the call site: a :root * binding to a role var freezes at the :root value and a scoped [data-tenant] role override never * reaches it. A brand sets both header tokens together to keep band/text contrast. * Defaults = hsl(var(--muted)) band \xB7 hsl(var(--muted-foreground)) text."},{name:"--table-header-foreground",value:"initial",description:"Header band \u2014 its OWN bg + fg knobs (decoupled from --secondary). Declared `initial` so the * default re-resolves to the LIVE --muted / --muted-foreground roles at the call site: a :root * binding to a role var freezes at the :root value and a scoped [data-tenant] role override never * reaches it. A brand sets both header tokens together to keep band/text contrast. * Defaults = hsl(var(--muted)) band \xB7 hsl(var(--muted-foreground)) text."},{name:"--table-pin-shadow",value:"-6px 0 6px -5px hsl(var(--foreground) / 0.12)",description:"Inline-end shadow that lifts a pinned (sticky) action column off the body it scrolls over."},{name:"--table-row-striped-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-row-hover-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-row-selected-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-action-collection-primary-width",value:"18%",description:'Table \xB7 action-collection preset (gh#253) \u2014 the canonical dense approval / action queue. * Column PRIORITY measures replace the desktop intrinsic widths (a nowrap free-text column is * what makes a five-column queue wider than its card and forces a horizontal scroll). Nothing * here is read unless `preset="action-collection"` is set, so every existing table is untouched. * Percentages so the ratio holds at any card width; the action affordance is an absolute measure * because it must never be squeezed below its touch target.'},{name:"--table-action-collection-secondary-width",value:"22%",description:"requester / subject"},{name:"--table-action-collection-meta-width",value:"12%",description:"target / resource"},{name:"--table-action-collection-actions-width",value:"3.5rem",description:"timestamps, ids \u2014 lowest priority"},{name:"--table-action-collection-primary-width-compact",value:"24%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-secondary-width-compact",value:"22%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-meta-width-compact",value:"20%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-actions-width-compact",value:"2.75rem",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-font-size-compact",value:"var(--font-size-xs)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-cell-space-x-compact",value:"var(--space-2)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-cell-padding-y-compact",value:"var(--space-2)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-row-height-compact",value:"var(--table-row-height-compact)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."}];var p={issue:"https://github.com/godx-jp/godxjp-ui/issues/163",standard:"docs/FRAME-COVERAGE-STANDARD.md",ledger:"preview/frame-coverage.ledger.json",recordedAt:"2026-07-30",warning:"UNTESTED means no executed case demonstrates this dimension. It is NOT a pass. Do not infer support from a happy-path example, a similarly-named frame, or a rendered screenshot.",verdicts:{covered:"An executed case proves this dimension.",untested:"No executed case. NOT a pass \u2014 report it as UNTESTED to the user.","not-applicable":"The dimension cannot exist for this export; the ledger carries the written reason."},requiredViewports:[320,375,390,768,1024,1280,1440,1920],containerWidths:[240,320,480,640,960],totals:{exports:276,dimensionCells:3864,covered:64,untested:2112,notApplicable:1688,exportsWithoutFrame:0},dimensions:[{id:"variants",title:"Variants",axis:"visual"},{id:"tones",title:"Tones",axis:"visual"},{id:"sizes",title:"Sizes",axis:"visual"},{id:"shapes",title:"Shapes",axis:"visual"},{id:"density",title:"Spacing / density",axis:"visual"},{id:"ownership",title:"Controlled / uncontrolled / reset",axis:"ownership"},{id:"states",title:"Disabled / read-only / loading / empty / error / success",axis:"state"},{id:"async",title:"Async: loading / reject / retry / cancel / offline",axis:"async"},{id:"responsive",title:"Responsive viewport matrix",axis:"responsive"},{id:"rtl",title:"RTL / direction",axis:"international"},{id:"contentStress",title:"Long / localized content stress",axis:"contentStress"},{id:"keyboard",title:"Keyboard / focus order / focus return",axis:"accessibility"},{id:"accessibleName",title:"Accessible name / description / error association",axis:"accessibility"},{id:"reducedMotion",title:"Preferences: reduced motion / forced colors / 200% zoom / coarse touch",axis:"preferences"}],knownGaps:[{id:"button-contract-gaps",targets:["Button"],dimensions:["states","contentStress","rtl","keyboard","reducedMotion"],cases:["implicit form `type` inside a form","loading combined with asChild","count / overflowCount / showZero overflow","long Japanese and Vietnamese labels","RTL","coarse touch target"]},{id:"card-contract-gaps",targets:["Card"],dimensions:["variants","density","rtl","accessibleName"],cases:["`variant` \xD7 `accent` \xD7 `size` matrix",'`density="tight"` spacing mode',"nested heading levels","RTL accent rail"]},{id:"card-subcomponent-contract-gaps",targets:["CardBar","CardContent","CardFooter","CardHeader"],dimensions:["rtl","accessibleName","contentStress"],cases:["CardBar `extra` slot","CardContent `tight` / `flush` / `solo`","CardFooter `flush` / `separated`","CardHeader `banded`","RTL"]},{id:"empty-state-contract-gaps",targets:["EmptyState"],dimensions:["variants","contentStress","accessibleName"],cases:["`section` variant","`compact` variant","without icon / description / action","heading level (`titleAs` / `titleLevel`) and live-region semantics"]},{id:"progress-contract-gaps",targets:["Progress"],dimensions:["tones","contentStress"],cases:["destructive tone","`over={true}` (value beyond 100%)"]},{id:"carousel-contract-gaps",targets:["Carousel"],dimensions:["ownership","contentStress","keyboard","reducedMotion","rtl"],cases:["single slide","plugins / setApi","autoplay pause","arrow-key traversal alongside tabs","touch / swipe","RTL"]},{id:"data-table-contract-gaps",targets:["DataTable"],dimensions:["states","async","keyboard","accessibleName","density"],cases:["error / prerequisite / background refresh","server and manual modes (manualPagination / manualSorting / manualFiltering)","zero-page and single-page pagination","accessible table and action-column labels","invalid row ids (getRowId)","keyboard behaviour","virtualization"]},{id:"charts-contract-gaps",targets:["LineChart","BarChart","AreaChart","PieChart"],dimensions:["async","reducedMotion","keyboard","contentStress","responsive","rtl"],cases:["loading / error","reduced motion","keyboard datum navigation","invalid / null / NaN data","mobile axis collision","RTL"]},{id:"locale-stress-gaps",targets:["Timeline","TreeList","PasswordStrength"],dimensions:["contentStress","accessibleName"],cases:["long localized Japanese / Vietnamese content","hard-coded screen-reader strings that never reach `t()`"]}]},z=[{name:"Accordion",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AccordionContent",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AccordionItem",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AccordionTrigger",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Alert",group:"feedback",frame:"docs/feedback/alert.tsx",covered:["tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states"]},{name:"AlertActions",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertContent",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDescription",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialog",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones"]},{name:"AlertDialogAction",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertDialogCancel",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertDialogContent",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogDescription",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogFooter",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogHeader",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"AlertDialogOverlay",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogPortal",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogRoot",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"AlertDialogTitle",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogTrigger",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertMutationFeedback",group:"query",frame:"docs/query/mutation-feedback.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AlertQueryError",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AlertTitle",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AppSettingPicker",group:"navigation",frame:"docs/navigation/app-setting-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AppShell",group:"layout",frame:"docs/layout/app-shell.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AreaChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"AspectRatio",group:"layout",frame:"docs/layout/aspect-ratio.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthAccountSummary",group:"layout",frame:"docs/layout/auth-account-summary.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AuthDivider",group:"layout",frame:"docs/layout/auth-divider.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthFooter",group:"layout",frame:"docs/layout/auth-footer.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthIdentity",group:"layout",frame:"docs/layout/auth-identity.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthShell",group:"layout",frame:"docs/layout/auth-shell.tsx",covered:["density","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones"]},{name:"AuthStack",group:"layout",frame:"docs/layout/auth-stack.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Avatar",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:["shapes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states","tones","variants"]},{name:"AvatarFallback",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AvatarImage",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Badge",group:"data-display",frame:"docs/data-display/badge.tsx",covered:["shapes","tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states"]},{name:"BarChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"Breadcrumb",group:"layout",frame:"docs/navigation/breadcrumb.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Button",group:"general",frame:"docs/general/button/index.tsx",covered:["shapes","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","tones"]},{name:"ButtonRefetch",group:"query",frame:"docs/query/button-refetch.tsx",covered:["shapes","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","tones"]},{name:"Calendar",group:"data-entry",frame:"docs/data-entry/calendar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Card",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:["density","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","states","tones"]},{name:"CardAction",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardBar",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardContent",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardCover",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardDescription",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardFooter",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardHeader",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardTitle",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Carousel",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CarouselContent",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselDots",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselItem",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselNext",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CarouselPrevious",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Cascader",group:"data-entry",frame:"docs/data-entry/cascader.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CenteredShell",group:"layout",frame:"docs/layout/centered-shell.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Checkbox",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CheckboxGroup",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Collapsible",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CollapsibleContent",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CollapsibleTrigger",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ColorPicker",group:"data-entry",frame:"docs/data-entry/color-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Command",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandEmpty",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CommandGroup",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandInput",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandItem",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CommandList",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CommandPalette",group:"data-entry",frame:"docs/data-entry/command-palette.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CompactBarTrend",group:"charts",frame:"docs/charts/compact-bar-trend.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"ContextMenu",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuCheckboxItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ContextMenuContent",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"ContextMenuLabel",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuPortal",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuRadioGroup",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuRadioItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ContextMenuSeparator",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuShortcut",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSub",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSubContent",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSubTrigger",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ContextMenuTrigger",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"CredentialReveal",group:"data-display",frame:"docs/data-display/credential-reveal.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"DataState",group:"query",frame:"docs/query/data-state.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"DataTable",group:"data-display",frame:"docs/data-display/data-table/index.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["shapes","sizes","tones","variants"]},{name:"DatePicker",group:"data-entry",frame:"docs/data-entry/date-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DateRangePicker",group:"data-entry",frame:"docs/data-entry/date-range-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Descriptions",group:"data-display",frame:"docs/data-display/descriptions.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Dialog",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DialogAction",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogBody",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogCancel",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogClose",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogContent",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogDescription",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogFooter",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogHeader",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"DialogOverlay",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogPortal",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogTitle",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogTrigger",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenu",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuCheckboxItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenuContent",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuGroup",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"DropdownMenuLabel",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuPortal",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuRadioGroup",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuRadioItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenuSeparator",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuShortcut",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSub",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSubContent",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSubTrigger",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"DropdownMenuTrigger",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"EmptyState",group:"data-display",frame:"docs/data-display/empty-state.tsx",covered:["tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states"]},{name:"ErrorSurface",group:"layout",frame:"docs/layout/error-surface/index.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"Field",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"FilterBar",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"FilterBarGroup",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Flex",group:"layout",frame:"docs/layout/flex.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Form",group:"data-entry",frame:"docs/data-entry/form.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones","variants"]},{name:"FormField",group:"data-entry",frame:"docs/data-entry/form-field/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Heading",group:"general",frame:"docs/general/typography.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"HoverCard",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"HoverCardContent",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"HoverCardTrigger",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InfiniteQueryState",group:"query",frame:"docs/query/infinite-query-state.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Input",group:"data-entry",frame:"docs/data-entry/input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"InputOTP",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPGroup",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPSeparator",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPSlot",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Label",group:"data-entry",frame:"docs/data-entry/label.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"LegalDocumentShell",group:"layout",frame:"docs/layout/legal-document-shell/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"LineChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"ListRow",group:"data-display",frame:"docs/data-display/list-row.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones","variants"]},{name:"Logo",group:"general",frame:"docs/general/logo.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"MasterDetail",group:"layout",frame:"docs/layout/master-detail.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Menubar",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarCheckboxItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MenubarContent",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"MenubarLabel",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarMenu",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarRadioGroup",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarRadioItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MenubarSeparator",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarShortcut",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarSub",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarSubContent",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarSubTrigger",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"MenubarTrigger",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MonthPicker",group:"data-entry",frame:"docs/data-entry/month-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MonthRangePicker",group:"data-entry",frame:"docs/data-entry/month-range-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"NavigationMenu",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuContent",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuIndicator",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuItem",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuLink",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuList",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuTrigger",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuViewport",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NumberInput",group:"data-entry",frame:"docs/data-entry/number-input.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"OrgSwitcher",group:"layout",frame:"docs/layout/org-switcher.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PageContainer",group:"layout",frame:"docs/layout/page-container.tsx",covered:["density","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones"]},{name:"Pagination",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationContent",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PaginationEllipsis",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PaginationItem",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PaginationLink",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationNext",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationPrevious",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PasswordInput",group:"data-entry",frame:"docs/data-entry/password-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PasswordStrength",group:"data-entry",frame:"docs/data-entry/password-strength.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PieChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"Popover",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PopoverAnchor",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverContent",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverDescription",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverHeader",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverTitle",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverTrigger",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PrefetchLink",group:"query",frame:"docs/query/prefetch-link.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Progress",group:"data-display",frame:"docs/data-display/progress.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","variants"]},{name:"QrCode",group:"data-display",frame:"docs/data-display/qr-code.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"Radio",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioGroup",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioGroupRoot",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioItem",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Rating",group:"data-entry",frame:"docs/data-entry/rating.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ResizableHandle",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResizablePanel",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResizablePanelGroup",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResponsiveGrid",group:"layout",frame:"docs/layout/responsive-grid.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Reveal",group:"general",frame:"docs/general/reveal.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ScrollArea",group:"data-display",frame:"docs/data-display/scroll-area.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ScrollBar",group:"data-display",frame:"docs/data-display/scroll-area.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SearchInput",group:"data-entry",frame:"docs/data-entry/search-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Select",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SelectContent",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectGroup",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectItem",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SelectLabel",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectScrollDownButton",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectScrollUpButton",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectSeparator",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectTrigger",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"SelectValue",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"Separator",group:"layout",frame:"docs/layout/separator.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceCatalogCta",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceLauncherCard",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceLauncherCardSkeleton",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Sheet",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SheetBody",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetClose",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SheetContent",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetDescription",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetFooter",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetHeader",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"SheetOverlay",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetPortal",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetTitle",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetTrigger",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Sidebar",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SidebarHeader",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SidebarItem",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"SidebarSection",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Skeleton",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonDetail",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonRows",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonStat",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonTable",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Slider",group:"data-entry",frame:"docs/data-entry/slider.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SplitPane",group:"layout",frame:"docs/layout/split-pane.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"StatCard",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"StatusBadge",group:"data-display",frame:"docs/data-display/badge.tsx",covered:["shapes","tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states"]},{name:"Steps",group:"navigation",frame:"docs/navigation/steps.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"Switch",group:"data-entry",frame:"docs/data-entry/switch.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"Table",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableBody",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableCell",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableHead",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableHeader",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableRow",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Tabs",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones"]},{name:"TabsContent",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"TabsList",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones"]},{name:"TabsTrigger",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TagInput",group:"data-entry",frame:"docs/data-entry/tag-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Text",group:"general",frame:"docs/general/typography.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"Textarea",group:"data-entry",frame:"docs/data-entry/textarea.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Timeline",group:"data-display",frame:"docs/data-display/timeline.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones"]},{name:"TimePicker",group:"data-entry",frame:"docs/data-entry/time-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Toaster",group:"feedback",frame:"docs/feedback/toast.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Toggle",group:"data-entry",frame:"docs/data-entry/toggle.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones"]},{name:"ToggleGroup",group:"data-entry",frame:"docs/data-entry/toggle-group.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones"]},{name:"ToggleGroupItem",group:"data-entry",frame:"docs/data-entry/toggle-group.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones"]},{name:"Toolbar",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ToolbarGroup",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Tooltip",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"TooltipContent",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TooltipProvider",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TooltipTrigger",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Topbar",group:"layout",frame:"docs/layout/topbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Transfer",group:"data-entry",frame:"docs/data-entry/transfer.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TreeList",group:"data-display",frame:"docs/data-display/tree-list.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TreeSelect",group:"data-entry",frame:"docs/data-entry/tree-select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TwoFactorSetup",group:"feedback",frame:"docs/feedback/two-factor-setup.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Upload",group:"data-entry",frame:"docs/data-entry/upload.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones"]}],le=new Map(z.map(t=>[t.name.toLowerCase(),t]));function L(t){return le.get(String(t??"").trim().toLowerCase())}var u=[{number:1,title:"Storybook is mandatory",body:"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark."},{number:2,title:"Tokens, not utilities",body:"Visual values come from CSS custom properties in `src/tokens/` + `src/styles/theme.css`. Token-named Tailwind utilities (`bg-background`) are fine; raw value utilities (`bg-blue-500`) are forbidden. (ADR-0003)"},{number:3,title:"Radix for interactive primitives",body:"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)"},{number:4,title:"shadcn-style ownership",body:"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)"},{number:5,title:"One i18next singleton",body:"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)"},{number:6,title:"WCAG 2.1 AA baseline",body:"Every interactive primitive passes axe-core (keyboard nav, ARIA, focus-visible, 4.5:1 contrast, `prefers-reduced-motion`). Stories double as a11y test surfaces."},{number:7,title:"SemVer 2.0 + Keep a Changelog 1.1",body:"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR."},{number:8,title:"Inclusive naming",body:"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced."},{number:9,title:"No marketing speak",body:'Banned: "powerful", "robust", "blazing fast", "best-in-class", "seamless", "enterprise-grade". State what it does.'},{number:10,title:"English is canonical for docs",body:"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness."},{number:11,title:"Submodule discipline",body:"Two-PR workflow: (1) submodule PR \u2192 `main`, (2) downstream PR \u2192 bump pin. Never push a pin to a SHA not on the submodule remote."},{number:12,title:"Branch + PR workflow",body:"`feat/<scope>` / `fix/<scope>` \u2192 submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden."},{number:13,title:"TypeScript strict",body:"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link."},{number:14,title:"Every third-party library is shadcn / Radix-recommended",body:"Locked stack: Radix UI, cmdk, sonner, lucide-react, react-aria-components + `@internationalized/date`, i18next + react-i18next, class-variance-authority + clsx + tailwind-merge. New peer \u2192 ADR documenting why it's the canonical choice."},{number:15,title:"No `@apply` re-encoding tokens",body:"Inside a primitive `.tsx`, don't `@apply` a Tailwind utility that re-encodes a token \u2014 reference the canonical CSS class from `tokens.css` instead. Composite token-named utilities remain fine."},{number:16,title:"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`",body:"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it."},{number:17,title:"`src/stories/` \u2194 `src/components/` parity",body:"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`."},{number:18,title:"`docs/reference/<group>/` \u2194 `src/components/<group>/` parity",body:"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`."},{number:19,title:"No service-specific anything",body:'`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent="<palette>"]`.'},{number:20,title:'No "platform-only" exports',body:"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported."},{number:21,title:"Every component honours every theme axis",body:"`data-theme` (light / dark), `data-accent` (6 palettes), `data-density` (compact / default / comfortable), `data-font-size` (sm / base / lg / xl). Read from tokens, never hardcode values. Verify every PR via the Storybook toolbar sweep."},{number:22,title:"100% match to the design canon",body:'Every visual literal comes from `design-handoff/ui-system/<latest-bundle>/`. Token-pin canon literals; never substitute "close enough". If the bundle doesn\'t cover a case \u2014 STOP, ask the user to mock it.'},{number:23,title:"Concept-first prop API",body:"One concept per prop. Reuse shared vocabulary (`size`, `variant`, `color`, `tone`, `accent`, `padding`, `density`, `orientation`, `placement`, `current`, `value` / `defaultValue` / `onValueChange`, `open` / `defaultOpen` / `onOpenChange`, `justify`, `sticky`, `offset`). Before adding a new prop or token: grep for an existing one."},{number:24,title:"Mobile-first",body:"Defaults target `xs` (\u22650px); progressive enhancement via `sm:` / `md:` / `lg:` / `xl:` / `2xl:`. Touch targets \u2265 44 \xD7 44 px (`--touch-target-min`, does NOT scale with density). Runtime viewport via `useBreakpoint`, never `window.innerWidth`. Stories render at narrow viewport first."},{number:25,title:"Stories are docs; UI is the primitive",body:"When a story looks wrong, fix the primitive / CSS / token. Never paper over with a story tweak. Story-only diff without a paired primitive / CSS / token diff is rejected."},{number:26,title:"Library isolation",body:"`dist/` ships only the consumer surface. Storybook, tests, scripts, design-handoff, `dev-probe/` stay out of npm. Every `dependencies` entry is `external` in `tsup`. Verification via `pnpm pack` + grep of `dist/`."},{number:27,title:"Per-group folder structure",body:"Primitives at `src/components/<group>/<Name>.tsx`; six canonical groups (general, layout, data-display, data-entry, feedback, navigation). Barrel = `src/components/primitives.ts` (single file). Stories + reference docs mirror the same group hierarchy."},{number:28,title:"`src/` folder taxonomy",body:"Three classes: consumer surface (matched by `tsup` entry + `package.json::exports`), Storybook-only (`src/stories/`), build-input-only (`cn.ts`, per-group sources consumed via the barrel). No `src/lib/`, `src/utils/`, `src/internal/`, `src/clients/`, `src/screens/`. Service clients live with the composite that uses them."},{number:29,title:"Stories consume framework primitives only",body:"No raw `<button>` / `<input>` / hand-rolled chips when a primitive exists. HTML semantics (`<section>`, `<article>`, \u2026) for structure are fine. Inline `style={{}}` limited to layout / positioning; no colour / radius / typography overrides."},{number:30,title:"Story `render` returns JSX directly",body:"No opaque `<XyzDemo />` wrapper components, no zero-arg `Demo` helpers. Use `render: function StoryName() { \u2026 }` so Storybook's source panel shows runnable JSX, not `<XyzDemo />`."},{number:31,title:"No nested wrapper / convenience primitives",body:"One Radix base = one framework primitive. `<SimpleX>` over `<X>` is forbidden; add a prop to `<X>` instead. Composites under `src/components/composites/` that combine multiple primitives are NOT wrappers."},{number:32,title:"No redundant props",body:"Before adding a prop / item field / variant, grep the existing surface; if a field already covers the concept, use it. Top-level prop that re-expresses an item field (Timeline `pending` \u2194 `items[i].animate`) is rejected."},{number:33,title:"Stories / source / docs name-synchronized",body:"No two names for the same export across the framework surface; no legacy aliases in stories / docs (source may keep an alias for a deprecation cycle, but the marketing surfaces use the canonical name only). Rename PR runs `grep -rn '<oldName>' src docs` and clears it."},{number:34,title:"Storybook source panel = real, copy-paste-ready code",body:'Storybook\'s react-docgen serializer strips every function value (`cell: ({row}) => <JSX/>`, `render: ({field}) => <Input/>`, `rowClassName`, `renderItem`, \u2026) 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 \u2014 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`.'},{number:35,title:"Status chips never wrap",body:"A `Badge` / `Badge` reads as one atomic unit. Its label must never break across lines \u2014 pin `white-space: nowrap` on the chip (done in `badge-layout.css`), especially inside narrow `DataTable` cells (\u30B9\u30B3\u30FC\u30D7 / \u30B9\u30C6\u30FC\u30BF\u30B9 columns). If a cell is too tight, widen the column or shorten the label; never let the chip wrap."},{number:36,title:"Badge tone/icon are the colour escape hatch",body:"`Badge` auto-maps a fixed set of English lifecycle keys (active, draft, pending, scheduled, cancelled, failed, \u2026) to tone + icon. For ANY other value \u2014 localized labels (\u516C\u958B\u4E2D, \u30A2\u30AF\u30C6\u30A3\u30D6) or categorical tiers (\u4F1A\u54E1\u30E9\u30F3\u30AF, \u5951\u7D04\u30D7\u30E9\u30F3) \u2014 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 + \u25CB. Map domain\u2192tone in the CONSUMER layer; the framework only provides the props."},{number:37,title:"DataTable is full-width \u2014 never inside a narrow grid column",body:"A multi-column `DataTable` occupies its OWN row at the page's full width: `<Card><CardContent flush><DataTable \u2026/></CardContent></Card>`. Never nest it in a `lg:col-span-2` of a `ResponsiveGrid columns={3}` beside a chart \u2014 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.)"},{number:38,title:"FilterBar stays OUT of CardContent flush",body:"`CardContent flush` strips horizontal padding for edge-to-edge tables. A `FilterBar` placed inside it loses all padding and sticks to the card edge. Render `FilterBar` as a STANDALONE block above the table card; wrap ONLY the `DataTable` / `EmptyState` in the `Card` + `CardContent flush`. Order on a list page: KPIs \u2192 FilterBar \u2192 table card."},{number:39,title:"Long text columns get an explicit width",body:"For columns whose value can be long (name / title / segment / address), set `col.width` to a Tailwind width class (e.g. `w-64`, `w-48`) so the column reserves space instead of shrinking and wrapping to many lines; leave numeric / status columns auto. Table cells default to `white-space: nowrap`, so an over-tight table scrolls horizontally rather than crushing \u2014 give the important columns real widths so the default layout reads well before any scroll."},{number:40,title:"Pages are mobile-first",body:'Author and verify every page at 320\u2013390px FIRST. Spacing comes only from `Flex` `gap` (vertical rhythm = `Flex direction="col"`, control rows = the default `direction="row"`) + `ResponsiveGrid columns={2|3|4}` (which collapse to a single column on narrow screens) \u2014 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 \u2265 44\xD744px.'},{number:41,title:"Drawer & dialog footer layout",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 \u2014 give that button `className="mr-auto"`. NEVER stack footer buttons full-width or center them.'},{number:42,title:"Props & Tokens Before Customization",body:"Before reaching for a Tailwind class, inline `style`, or extra CSS, you MUST first check whether the component already supports the need via a PROP, a design TOKEN, or a layout/typography PRIMITIVE. godx-ui is meant to be enough on its own (Ant-Design-style): `className` is for genuine one-offs only \u2014 never to redo what an API already does. Specifically: (1) NEVER hand-roll typography \u2014 no `text-[13px]`/`text-[11px]` arbitrary px (bypasses the golden type scale), no `font-medium`/`font-semibold`/`text-muted-foreground` on a raw `<span>`; use `<Text size tone weight tabular mono>` / `<Heading level>`. (2) NEVER hand-roll a trivial flex/grid wrapper; use `<Flex>` / `<ResponsiveGrid>` / `<PageContainer>`. (3) NEVER set a control's radius/height/colour with a utility when a `shape`/`size`/`tone`/token exists. If a real need has NO prop/token/primitive, that is a library GAP \u2014 file it (draft_bug_report), don't paper over it with ad-hoc Tailwind."},{number:43,title:"Every form control goes through FormField",body:"Consumers MUST wrap every labelled form control (Input, Select, DatePicker, DateRangePicker, NumberInput, Radio.Group, Checkbox groups, range pairs, ...) in FormField \u2014 it owns the label (aria-labelledby, never a dangling <label for>), auto-generates/injects the control id, and wires aria-describedby/aria-errormessage/aria-invalid. Bare controls are the rare exception (e.g. a toolbar quick-filter with its own aria-label) and must carry id/name + aria-label themselves. Never hand-roll a label+control stack with Text/Label."},{number:44,title:"Chrome is a token, default quiet",body:"Any decorative chrome a component draws \u2014 dividers, separator borders, and the padding that exists only to space that chrome \u2014 MUST read a token; never hard-code it in `src/styles/*.css` (a hard-coded `border-bottom: 1px solid hsl(var(--border))` leaves consumers no off-switch short of a variant fork). The DEFAULT is the quietest state (`none` / balanced rhythm); a service theme opts IN, e.g. `--page-header-divider: 1px solid hsl(var(--border))`. Born from real consumption: PageContainer's header divider was undisableable until tokenised."},{number:45,title:"Every service-tunable constant gets a knob",body:'When component CSS encodes a geometry choice that a service plausibly re-tunes to match its design handoff \u2014 form label column width, label\u2194control gap, header insets \u2014 it MUST be a documented component token (current value as the default). The theme sets it ONCE globally; props (`labelWidth`) override per instance; Form\u2192FormField priority stays intact. The test: "would a service theme.css want to change this to match its design grid?" If yes and the only route is forking CSS, that is a library gap \u2014 fix the library, don\'t patch the app. Born from real consumption: `--form-label-width` / `--form-label-gap` (design spec said 110px/8px; the values were prop-only and hard-coded `--space-4`).'},{number:46,title:"Typography is tokens, default is base",body:"A UI framework gives consumers knobs: every font-size in `src/styles/*.css` MUST reference a token \u2014 the global modular scale `var(--font-size-{2xs|xs|sm|base|lg|xl|2xl})` or a per-component `var(--{component}-\u2026-font-size)` knob (rule #45) \u2014 never a hard-coded literal (`font-size: 12px` can't be re-themed). The DEFAULT body size is `--font-size-base`; components render body/UI text at `base`, not at the `sm` alias. Smaller-by-design text (badge, section label, caption) is a component token defaulting to a small step (`--badge-font-size: var(--font-size-xs)`), so a service re-tunes that part without moving the global scale. The `sm`/`xs` tokens stay for the explicit `<Text size>` API. Every component token is surfaced in the MCP `get_component` output (check:mcp-token-sync). Enforced by `check:typography`."}];function T(t){return u.find(a=>a.number===t)}var b=[{name:"common-fixes",tagline:"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 \u2192 after.",tags:["fixes","migration","bug","cardstat","statusbadge","datatable","sidebar","gotcha","review"],code:`// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1933
+ </FilterBar>`,storyPath:"navigation/FilterBar.stories.tsx",rules:[]}];function N(t){let a=t.trim().toLowerCase();return v.find(e=>e.name.toLowerCase()===a)}function F(t){return v.filter(a=>a.group===t)}var k=[{name:"ValueProp<T = string>",concept:"Abstract controlled value.",values:["generic"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Tabs","SearchSelect"]},{name:"DefaultValueProp<T = string>",concept:"Abstract uncontrolled initial value.",values:["generic"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Tabs"]},{name:"OnValueChangeProp<T = string>",concept:"Callback for abstract value changes. DOM events continue to use onChange.",values:["(value: T) => void"],usedBy:["CheckboxGroup","Upload","Cascader","TreeSelect","Transfer","settings pickers"]},{name:"OpenProp / DefaultOpenProp / OnOpenChangeProp",concept:"Disclosure state.",values:["boolean","(open: boolean) => void"],usedBy:["Dialog","Sheet","Popover"]},{name:"SizeProp",concept:"Shared public size names.",values:["xs","sm","md","lg"],usedBy:["Button","Steps","Switch"],notes:"Component-specific subsets must be documented. Old alias small is sm."},{name:"ToneProp",concept:"Semantic status/color intent.",values:["default","success","warning","destructive","info","muted","neutral"],usedBy:["Badge","Alert"],notes:"Status values belong in tone, not variant."},{name:"GapProp",concept:"Shared layout gap scale.",values:["xs","sm","md","lg","xl"],usedBy:["Flex"],notes:'The single shared gap scale on Flex \u2014 the one layout primitive (default direction="row"; use direction="col" for vertical rhythm; these replaced the removed Stack/Inline).'},{name:"TitleProp",concept:"Primary heading text.",values:["React.ReactNode"],usedBy:["PageContainer","PageHeader","EmptyState","Dialog"]},{name:"DensityProp",concept:"Page/subtree density.",values:["compact","default","comfortable"],usedBy:["PageContainer"]},{name:"CenteredShellPresetProp",concept:"Named whole-page SHELL contract for CenteredShell \u2014 the page measure, section rhythm, chrome flatness and hero heading tier, all owned by component tokens.",values:["default","public-landing"],usedBy:["CenteredShell"],notes:'public-landing is the PUBLIC marketing/product landing geometry (gh#252): one 67.5rem measure shared by the header bar, the centred column and the footer, the section rhythm, flat elevation-free cards and the hero h1 tier. "default" emits NO data-preset at all, so the existing shell box is untouched. Pair with `Flex hideBelow`/`hideFrom` for header region visibility \u2014 a landing must never own a page-local media query or a max-width wrapper.'},{name:"TablePresetProp",concept:"Named collection contract for a table \u2014 how a dense collection behaves when its container gets narrow.",values:["default","action-collection"],usedBy:["Table","DataTable"],notes:"action-collection (gh#253) swaps the desktop intrinsic column widths for table-layout: fixed + the token-owned column PRIORITY measures below `collapseBelow`, so a five-column approval queue keeps every column \u2014 including row actions \u2014 inside a 390px frame with no page-local CSS, no hidden column and no horizontal scroll. It changes the SIZING model only: no display change, no role rewriting, no card transformation, so table semantics and screen-reader navigation are identical at every width. ONE contract, two entry points: the `Table` primitive (mark `priority` on each TableHead/TableCell yourself) and the TanStack `DataTable` (mark `priority` on the ColumnDef; it stamps both cells for you, and additionally releases the surface's `--table-surface-min-inline-size` floor). Both read the same `--table-action-collection-*` tokens \u2014 there is no parallel DataTable family."},{name:"TableColumnPriorityProp",concept:"Relative importance of a table column, used by the action-collection preset to allocate the narrow-frame measure.",values:["primary","secondary","meta","actions"],usedBy:["Table","DataTable"],notes:"On the raw `Table`, set it on BOTH the TableHead and the TableCell of a column; on `DataTable` set it once on the `ColumnDef` and it is stamped onto the <th> and every <td>. `actions` reserves its measure first so the row-action affordance can never be pushed outside the viewport; a column with no priority takes the remaining space (the free-text column)."},{name:"AuthShellPresetProp",concept:"Named hosted-identity FLOW MEASURE for AuthShell \u2014 the card max-width plus the desktop and mobile page gutters, all owned by component tokens.",values:["default","device-authorization","context-selection"],usedBy:["AuthShell"],notes:'Orthogonal to AuthShell\'s `variant` (which owns control density + heading size) and applied after it, so `variant="canonical" preset="device-authorization"` composes. device-authorization = 380px card / 5px inline gutter at 390 (gh#220); context-selection = 25rem card, edge-to-edge on mobile (gh#217). Selecting a preset REPLACES any consumer-side --auth-shell-card-max-width override \u2014 a page-local width is the anti-pattern these presets exist to remove.'},{name:"AvatarShapeProp",concept:"Avatar geometry \u2014 WHAT the identity mark represents: a person or an entity. Deliberately NOT the control ShapeProp (default|pill|sharp), whose `sharp` is --radius-sharp: 0 and cannot express the rounded rect an entity mark needs.",values:["circle","square"],usedBy:["Avatar"],notes:'circle (default, inert) = the round --radius-pill person avatar on the muted surface; square = the entity-header organization/service mark \u2014 a compact rounded square on the brand surface driven by --avatar-square-{radius,size,background,foreground} (gh#249). Choose by meaning, never by look: a className="rounded-md bg-primary" override on the call site is the anti-pattern this prop removes.'}];function B(t){let a=t.trim().toLowerCase().replace(/prop(?:<.*>)?$/i,"");return k.find(e=>e.name.toLowerCase().replace(/prop(?:<.*>)?$/i,"")===a)}var C=[{name:"--wa-*",category:"primitive",tier:"primitive",role:"Neutral decorative Japanese accent primitives for charts/tags/decoration only."},{name:"--chart-1..6",category:"primitive",tier:"primitive",role:"Neutral decorative chart series palette. The @godxjp/ui/charts components (LineChart/BarChart/AreaChart/PieChart) read these by series index automatically \u2014 a service rethemes every chart at once by overriding --chart-1..6; per-series/per-slice overrides go through the component's series.color / colors props."},{name:"--space-0..12",category:"primitive",tier:"primitive",role:"Raw spacing scale."},{name:"--font-size-*",category:"primitive",tier:"primitive",role:"Raw typography scale."},{name:"--font-sans-base",category:"semantic",tier:"semantic",role:'The default sans face. FONT-AGNOSTIC by default (pure system stack) \u2014 the library ships no hardcoded brand font. Override this for one face everywhere. --font-family-sans defaults to it; --font-family-display / --font-family-body default to --font-family-sans (override those for a dual display+body brand). Consumers supply the actual @font-face (next/font, @fontsource, self-host); the opt-in @godxjp/ui/styles/fonts OVERWRITES this (and --font-sans-vi) with the bundled DXS stack \u2014 "M PLUS 2" primary (incl. the Vietnamese coverage) with "Noto Sans JP" as the CJK fallback. BUNDLE CHANGED IN v18: v16 bundled Noto Sans JP + Montserrat, v18 bundles M PLUS 2 + Noto Sans JP \u2014 if a design spec names the v16 faces, set the tokens explicitly instead of relying on the bundle. IMPORT ORDER IS LOAD-BEARING: styles/fonts must be imported AFTER styles/base, because foundation.css declares this system-stack default on :root at the same specificity (0,1,0) and the later declaration wins (the all-in-one @godxjp/ui/styles entry already orders it correctly \u2014 issue #210).'},{name:"--font-sans-{ja,ko,vi,zh-hans,zh-hant}",category:"semantic",tier:"semantic",role:'Per-language font SLOT tokens. styles/base.css wires each [lang] to read its slot with --font-sans-base as fallback, so a consumer switches a locale\'s face by setting e.g. `--font-sans-ja: "Noto Sans JP", var(--font-sans-base)` \u2014 NO [lang] selectors to write. Empty by default. zh-hans matches lang zh|zh-Hans|zh-CN; zh-hant matches zh-Hant|zh-TW. Deciding which @font-face ships on which locale route is the consumer\'s font pipeline, not the library. The opt-in @godxjp/ui/styles/fonts only fills --font-sans-vi (with the bundled "M PLUS 2", "Noto Sans JP" stack); the other slots stay empty and fall back to --font-sans-base.'},{name:"--duration-{fast,base,slow}",category:"primitive",tier:"primitive",role:"Motion durations (150 / 250 / 500ms). Read these instead of a literal `0.5s` for enter/transition timing (rule #2). the reference design keeps motion short; honour `prefers-reduced-motion` at the call site."},{name:"--ease-{standard,emphasized,decelerate,accelerate}",category:"primitive",tier:"primitive",role:"Motion easing curves. `standard` for most transitions, `emphasized` for entrances/overlays (the vaul drawer curve), `decelerate` for settling in, `accelerate` for exits. Read instead of a literal `cubic-bezier(\u2026)`."},{name:"--reveal-distance",category:"primitive",tier:"primitive",role:"Distance (10px) a revealed element travels on enter (translateY/-X). Read instead of a literal `translateY(10px)` for staggered reveals."},{name:"--reveal-stagger-step",category:"primitive",tier:"primitive",role:"One step (60ms) of the Reveal stagger ladder \u2014 `<Reveal delay={n}>` waits n \xD7 this before entering, so a column of reveals cascades. Read instead of a literal `.04s`/`.09s` per-item delay."},{name:"--shadow-color",category:"primitive",tier:"primitive",role:"RGB channels (space-separated, e.g. `12 26 49`) that tint the WHOLE elevation ramp (--shadow-xs..2xl) at once. Default `0 0 0`. Single-brand :root only \u2014 a scoped override does not re-resolve the ramp (the steps compute at :root); for a scoped/multi-tenant card lift set --card-shadow to a literal value."},{name:"--shadow-glow",category:"primitive",tier:"primitive",role:"Opt-in brand GLOW halo layered on the primary CTA's resting shadow. Default invisible (`0 0 0 0 transparent`, valid inside a comma shadow list). A service sets the whole value, e.g. `--shadow-glow: 0 8px 20px hsl(var(--primary) / .32)` \u2014 works scoped under [data-tenant] because the service declares it inside the scope."},{name:"--focus-ring-color",category:"primitive",tier:"primitive",role:"Themeable hue of EVERY keyboard-focus ring (HSL components, default var(--ring)). A leaf token, so it re-resolves at the element that paints the ring \u2014 override it once, even scoped under [data-tenant], to retint all focus rings. Pair with --focus-ring-width."},{name:"--focus-ring-width",category:"primitive",tier:"primitive",role:"Thickness (2px) of the solid keyboard-focus ring. Leaf token \u2014 :focus-visible rules read it directly as `0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color))`, never via an intermediate composite (which would freeze at :root). Propagates scoped."},{name:"--gradient-{brand,hero,glow}",category:"primitive",tier:"primitive",role:"Opt-in decorative gradient fills, default `none`. --gradient-hero paints the PageContainer header (hero banner); --gradient-glow paints the AppShell .app-main (ambient brand wash); --gradient-brand is a spare. A service sets the full gradient, e.g. `--gradient-glow: radial-gradient(60% 80% at 50% 0%, hsl(var(--primary) / .25), transparent)`."},{name:"--primary",category:"semantic",tier:"semantic",role:"Action color role."},{name:"--brand / --brand-foreground",category:"semantic",tier:"semantic",role:'The IDENTITY role \u2014 the canonical GoDX emerald (light #009766 = oklch(0.595 0.137 162.94); dark lifts lightness only, #00b87c). It is what `<Logo mark="godx">` / `tone="success">` / the godx wordmark / the `@godxjp/ui/email` brand capsule paint, and it is distinct from THREE lookalikes: --primary (the ACTION colour \u2014 re-theme it freely, the mark never moves), --success (\u82E5\u7AF9 #68be8d, the STATUS green for badges/progress/"saved" text \u2014 the mark borrowed this before gh#250 and shipped \u0394E76 \u2248 17.5 off canonical), and --text-brand (the blue brand-NUMERAL text slot behind the Tailwind `text-brand` utility). There is no `bg-brand` utility: `--color-brand` is already taken by --text-brand, so identity surfaces read `hsl(var(--brand))` directly in component CSS. Re-brand a service by overriding --brand once (scoped `[data-tenant]` works \u2014 every logo knob resolves it at the call site).'},{name:"--success",category:"semantic",tier:"semantic",role:'Success STATUS role (\u82E5\u7AF9 wakatake #68be8d) \u2014 badges, alerts, progress fills, timeline done dots, `tone="success"` text. NOT the product identity: the GoDX mark reads --brand (gh#250).'},{name:"--warning",category:"semantic",tier:"semantic",role:"Warning status role."},{name:"--destructive",category:"semantic",tier:"semantic",role:"Destructive/error status role."},{name:"--info",category:"semantic",tier:"semantic",role:"Information status role."},{name:"--attention",category:"semantic",tier:"semantic",role:"Attention status role."},{name:"--page-header-divider",category:"semantic",tier:"semantic",role:"PageContainer header bottom divider. Default none; a service theme opts in with `1px solid hsl(var(--border))`."},{name:"--overlay-background",category:"semantic",tier:"semantic",role:"Modal scrim \u2014 the single backdrop colour shared by every overlay (Dialog, AlertDialog, Sheet, Drawer, AppShell mobile nav). Default `rgb(0 0 0 / 0.5)`. A service tints it once, e.g. a navy `rgb(12 26 49 / .55)`. HOW IT REACHES AN OVERLAY (gh#215 \u2014 until v18 it reached NOTHING; every overlay carried a private literal and this token was dead): each surface declares its own `--*-overlay-background` knob `initial` and resolves a SHARE of this colour at the call site, `color-mix(in srgb, var(--overlay-background) var(--*-overlay-alpha), transparent)`, so the calibrated per-surface depth survives (Sheet/drawer 40% = 0.2, Dialog 60% = 0.3) while ONE override here retints them all. NOTE: portaled overlays render outside a [data-tenant] subtree, so for multi-tenant scoping put the tenant attribute on the portal container too."},{name:"--page-header-pad-bottom",category:"semantic",tier:"semantic",role:"PageContainer header bottom inset. Defaults to page top padding minus the section gap so the title band is vertically balanced."},{name:"--master-detail-rail-{compact,standard}",category:"semantic",tier:"semantic",role:"MasterDetail fixed rail track \u2014 18.75rem (300px) / 20rem (320px). The `railWidth` prop picks the preset; a service theme retunes the presets themselves. Consumers never author a grid track."},{name:"--master-detail-gap",category:"semantic",tier:"semantic",role:"Gap between the MasterDetail master and detail regions (default --space-stack-md), side by side and stacked."},{name:"--master-detail-collapse-below",category:"semantic",tier:"semantic",role:"MasterDetail stacking threshold (default 40rem / the `sm` step), measured against the composition's OWN inline size, not the viewport: wider keeps the split, narrower stacks master above detail. A real knob \u2014 the layout resolves it inside a flex-basis calc(), because a media/container-query CONDITION cannot read a var(). The `collapseBelow` prop overrides it per instance (rule #45)."},{name:"--master-detail-master-viewport-{compact,standard}",category:"semantic",tier:"semantic",role:'Bounded MasterDetail master viewport \u2014 20rem (320px) / 28rem (448px), selected by the semantic `masterViewport` prop. `masterViewport="auto"` (the default) applies NO bound, so existing compositions are unchanged; the presets cap the collection\'s block size and scroll it INSIDE the region, which is what stops a long real collection from pushing the detail below the fold once the layout stacks. Retune the presets in a service theme exactly like --master-detail-rail-*; never author a pixel max-height in consumer CSS.'},{name:"--master-detail-master-viewport-inset",category:"semantic",tier:"semantic",role:"Focus-ring room inside a bounded MasterDetail master region (default --space-1 / 4px), and its scroll-padding. An overflow container clips BOTH axes, so without this inset the focus ring of a row at the region's edge would be cut off; it also keeps a row scrolled into view off the clip edge. Only applies when `masterViewport` is compact/standard."},{name:"--page-header-extra-measure",category:"semantic",tier:"semantic",role:'Inline measure of the PageContainer header `extra` region while `headerLayout="responsive-inline"` and the page is below the 640px step (default 11rem / 176px). The default `headerLayout="stack"` never reads it \u2014 `extra` keeps wrapping onto its own full-width line under the subtitle. At >=640px both arrangements are identical, so this token only governs the compact range.'},{name:"--page-measure-{narrow,medium}",category:"semantic",tier:"semantic",role:'Bounded PageContainer MEASURE presets \u2014 42rem (672px) / 48rem (768px), selected by the semantic `measure` prop. They are OUTER measures: the package-owned page gutters (--space-page-active-x, 24px each side) sit INSIDE the cap, so the VISIBLE surface is 624px / 720px, and at 390px nothing binds (358px surface at the 16px compact gutter). Unlike variant="narrow" \u2014 which caps only .ui-page-body \u2014 the measure caps the page HEADER and the BODY together, so a header `extra` action ends flush with the body surface (gh#245/gh#247). `measure="default"` (the default) reads NEITHER token and matches no rule, so existing pages are unchanged. Retune the presets in a service theme; never author a page-local max-width.'},{name:"--badge-space-*",category:"component",tier:"component",role:"Badge spacing."},{name:"--logo-godx-{size,size-xs|sm|md|lg,color} / --logo-success-{background,foreground} / --logo-identity-foreground",category:"component",tier:"component",role:'The GoDX IDENTITY mark. COLOUR: its default is the --brand IDENTITY role (canonical emerald) \u2014 deliberately independent of --primary, so a re-themed action colour never recolours the brand, AND of --success, the \u82E5\u7AF9 STATUS green it wrongly defaulted to before gh#250 (`tone="success"` names the semantic SLOT, not the status role). Role-mirror knobs: declared `initial` at :root with the role default at the CALL SITE (`hsl(var(--logo-godx-color, var(--brand)))`), so a scoped `.dark`/`[data-tenant]` override of --brand actually reaches the mark. BOX: `--logo-godx-size-{xs,sm,md,lg}` (1.5 / 1.75 / 2 / 2.5rem) is the identity mark\'s own size ramp \u2014 the `size` prop drives it exactly like --logo-size-* drives the boxed glyph, one tier above its glyph sibling because the artwork is a capsule inside a square viewBox. `--logo-godx-size` is the PIN, not the base: `initial` by default (so the tiers apply) and, set once by a service theme, it freezes the mark at that box on EVERY tier. INK: `--logo-identity-foreground` (48 9% 9%, #191815) is the colour the boxed `mark="glyph"` sets its TEXT in on the identity fill \u2014 deliberately NOT --brand-foreground. --brand-foreground is the artwork KNOCKOUT colour (it tracks --background in both themes, because `mark="godx"` punches its inner bar as an evenodd HOLE and the email mark paints that hole solid to match) and as negative space only owes WCAG 2.2 SC 1.4.11\'s 3:1. The boxed glyph renders real TEXT, so SC 1.4.3 applies at 4.5:1 \u2014 14px bold is NOT "large text" (that needs 18.66px bold / 24px) \u2014 and knockout white on the emerald measured only 3.67:1, a straight AA failure. The ink is theme-INVARIANT (it is the same near-black spine the dark theme already resolved to), so dark is unchanged at 6.89:1 and light rises to 4.74:1. It is NOT a role-mirror knob \u2014 its default is a real value, not a role, so there is no role to freeze and it is declared at :root, not `initial`. Re-theming --brand to a DARK fill? Override the public knob --logo-success-foreground to re-invert the ink. Applies to `<Logo mark="godx">` / `tone="success"`.'},{name:"--logo-wordmark-{gap,font-size-xs|sm|md|lg,font-weight,letter-spacing,font-family,color}",category:"component",tier:"component",role:'Wordmark/lockup knobs for `<Logo wordmark="\u2026" />` \u2014 the mark\u2194wordmark gap, the per-size-tier wordmark type ramp, and its face/weight/tracking/colour. The package ships NO wordmark artwork: `--logo-wordmark-font-family` defaults (at the call site) to --font-family-display, so the wordmark is typeset in the design-system face; pass an inline <svg> as `wordmark` when a real logotype exists. `--logo-wordmark-color` is a role-mirror knob (`initial`) whose call-site default is hsl(var(--foreground)), or the --brand IDENTITY role on the godx / tone="success" lockup \u2014 never --primary and never the --success status green (gh#250). Setting it once in a service theme re-colours every lockup with no page CSS (gh#214).'},{name:"--card-*",category:"component",tier:"component",role:"Card surface, border, spacing, and typography."},{name:"--control-*",category:"component",tier:"component",role:"Shared form control heights, padding, icons, and focus chrome."},{name:"--table-*",category:"component",tier:"component",role:"Table row/cell sizing."},{name:"--table-pagination-padding-{y,x}",category:"component",tier:"component",role:"DataTable.Pagination footer inset (gh#236). The footer used to declare `padding-top` ONLY, so in the documented flush container (`<Card><CardContent flush><DataTable/>`) the 'rows per page' label and the page-size Select sat flush against the container edge and its closing border. It now owns `padding-block` + `padding-inline`. Both knobs are declared `initial` with the default at the CALL SITE \u2014 block `var(--space-stack-sm)` (the old padding-top value, now on both block edges), inline `var(--table-cell-space-x)` so the label lands on the same optical axis as the first column's text. `initial` is load-bearing: both defaults are density-scaled and re-declared inside a `.ui-density-*` subtree, and a `:root` binding would freeze the footer at the `:root` density. Consumers no longer need a local `.ui-data-table-pagination` override; a service on another grid retunes either axis."},{name:"--table-surface-min-inline-size",category:"component",tier:"component",role:'DataTable surface narrow-viewport width FLOOR (gh#253). Below the `sm` viewport step a multi-column admin grid whose cells are `white-space: nowrap` would be crushed, so the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. This shipped as a hard-coded `min-w-[640px] sm:min-w-0` utility pair ON the surface element \u2014 the literal that forced the horizontal scroll at 390 \u2014 leaving a service that wants a narrower (or no) floor with no route but forking the component (rule #45). Default `640px`, byte-identical to the old utility, and deliberately px so the floor releases at exactly the same width as the px-based `sm` media query that clears it (a rem value drifts under a non-16px root and re-introduces the scroll between the two thresholds). Set `0` to opt out; `DataTable preset="action-collection"` already does, because there the column-priority measures own the width.'},{name:"--form-label-width",category:"component",tier:"component",role:"Label column width in horizontal Form layout. Default max-content; a service theme sets it once (e.g. 110px) \u2014 the labelWidth prop overrides per form/field."},{name:"--form-label-gap",category:"component",tier:"component",role:"Label\u2194control column gap in horizontal Form layout. Default 16px (--space-4)."},{name:"--dialog-* / --alert-* / --skeleton-*",category:"component",tier:"component",role:"Feedback component sizing and spacing."},{name:"--sheet-responsive-breakpoint-width / --sheet-bottom-max-height",category:"component",tier:"component",role:`The responsive drawer / detail-panel contract (SheetContent responsive="auto"). --sheet-responsive-breakpoint-width (default 48rem = 768px, the library's canonical mobile line) is the viewport width at and below which the desktop side panel becomes a mobile bottom sheet; --sheet-bottom-max-height (default 85dvh) caps THAT bottom presentation only (a plain side="bottom" sheet stays content-sized). Because a CSS @media cannot resolve a custom property, the breakpoint is read off :root at runtime by the exported useSheetResponsiveMode() hook \u2014 which is also what OrgSwitcher responsive="auto" uses, so ONE knob moves the popover\u2192sheet and side\u2192bottom line for every overlay at once. Accepts px/rem/em.`},{name:"--qr-code-*",category:"component",tier:"component",role:"QrCode scanner-safe foreground/background and xs/sm/md/lg natural-size tiers. Keep foreground/background at strong contrast; the defaults remain dark-on-light in dark application themes."},{name:"--chart-trend-plot-height{,-xs,-sm,-md,-lg}",category:"component",tier:"component",role:"CompactBarTrend plot-height tiers (xs 3.5rem = dashboard summary-card density, sm 5rem, md 7.5rem, lg 10rem). The `size` prop picks a step via data-size; a service retunes the whole scale here. This is why a consumer NEVER writes an inline height for a compact trend."},{name:"--chart-trend-bar-{gap,radius,max-width,min-height}",category:"component",tier:"component",role:"CompactBarTrend mark geometry: gap between bars (default --space-2), rounded data-end radius (--radius-sm), the per-mark width ceiling (1.5rem, so a 3-point trend does not render slabs) and the min height floor (2px, so a zero value still reads as a plotted category). All service-tunable (rule #45)."},{name:"--chart-trend-bar-background{,-alpha} / --chart-trend-bar-emphasis-background",category:"component",tier:"component",role:"CompactBarTrend fills \u2014 role-mirror knobs declared `initial` with the role default at the call site. Muted marks default to hsl(var(--muted-foreground) / --chart-trend-bar-background-alpha) (0.75, which clears the 3:1 non-text contrast floor); the emphasized 'current' mark defaults to hsl(var(--primary)). Point them at --chart-N to tint a trend to a series colour."},{name:"--chart-trend-baseline-border",category:"component",tier:"component",role:"CompactBarTrend baseline rule. QUIET by default (rule #44 \u2014 resolves to `none`); a service opts in with `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-{tick-gap,tick-font-size,footer-gap}",category:"component",tier:"component",role:"CompactBarTrend category-tick and activity-footer rhythm \u2014 the plot\u2194tick gap, tick type size (--font-size-xs) and the plot\u2194footer gap."},{name:"--email-shell-{width,padding,page-padding,border-width} / --email-card-{radius,reference-height} / --email-stack-gap{,-sm}",category:"component",tier:"component",role:"Transactional-email shell geometry: the 480px card width, its 32px inset, the 24px viewport gutter, the 1px edge, the 10px radius (mirrors --card-radius) and the block rhythm. The canonical invitation reference measures 480\xD7407 (--email-card-reference-height is a visual-regression target, NEVER a fixed height on the card). Values are LITERAL px \u2014 email clients resolve neither var() nor rem \u2014 and are consumed through the `@godxjp/ui/email` export (EMAIL_SHELL), never by a stylesheet."},{name:"--email-{body,heading}-{font-size,line-height,font-weight} / --email-font-family-{sans,mono}",category:"component",tier:"component",role:`Email type ramp, reconciled with the SCR-302 canonical reference (gh#250). Body 14px/1.9, title 17px/1.7 at weight 500 (a transactional title is CALM, not bold) \u2014 deliberately looser and quieter than the web ramp, because a mail client gives the reader no density control, so do NOT 'fix' it back to --heading-h1/--line-height-body. --email-font-family-sans names the canonical M PLUS 2 face first and degrades Hiragino \u2192 Yu Gothic \u2192 Noto Sans JP \u2192 Meiryo \u2192 system UI \u2192 Arial \u2192 sans-serif; no email client honours @font-face, so the stack is the whole fallback contract. --email-font-family-mono (mirrors --font-family-mono) sets invoice ids, masked card numbers, ISO dates and amounts. Family names export SINGLE-quoted so the value drops into a double-quoted style="\u2026" attribute unescaped (emailInlineStyle throws on a double quote). Exposed as EMAIL_TYPOGRAPHY.`},{name:"--email-mark-{width,height,gap} / --email-wordmark-{font-size,font-weight}",category:"component",tier:"component",role:'Email brand-mark LOCKUP (gh#250). The ARTWORK is byte-identical to <Logo mark="godx" /> (the 32\xD732 capsule + internal glyph, asserted by test); only the rendered box is email-specific \u2014 the canonical header sets a 22px mark, an 8px gap (mirrors --logo-wordmark-gap) and a 13px/700 wordmark (mirrors --logo-wordmark-font-weight). In that pairing the mark is DECORATIVE (render it with label: "") and the wordmark carries the accessible name, so the brand is announced once. Exposed as EMAIL_BRAND_MARK; the svg / dataUri / tableHtml deliveries all derive from this one geometry source.'},{name:"--email-cta-{height,line-height,padding-x,radius,font-size,font-weight} / --email-focus-border-width",category:"component",tier:"component",role:"The single primary email CTA, reconciled with the SCR-302 canonical reference (gh#250): 36px tall (mirrors --control-height-lg) with line-height EQUAL to the height so the label centres without flexbox in Outlook, 16px inline padding (--space-4), the 6px --radius base, 14px/500 label. 36px still clears WCAG 2.2 SC 2.5.8 (24\xD724) and the mobile reflow takes the CTA full-bleed. Fill/label are EMAIL_COLORS.primary / primaryForeground, derived from the --primary role \u2014 never paste a canonical hex, or the email stops tracking a re-theme. --email-focus-border-width mirrors --focus-ring-width for the webmail panes that honour :focus-visible. Exposed as EMAIL_CTA / EMAIL_FOCUS."},{name:"--email-footer-{font-size,line-height,link-gap,padding-top,border-width} / --email-mobile-*",category:"component",tier:"component",role:"Legal-footer typography (11px/1.8 quiet type per the SCR-302 canonical, 12px between adjacent links, 20px above the hairline) and the narrow-viewport reflow (520px breakpoint, fluid card, 20px inset, 12px gutter, 16px heading \u2014 one step under the 17px desktop title, full-bleed CTA). The canonical 390px reference raster is unusable (435px wide and already clipping the card, dxs-platform/platform#496), so the mobile ramp is the library's documented contract rather than a measured value. Exposed as EMAIL_FOOTER / EMAIL_MOBILE; every reflow rule needs an inline fallback because most clients strip <style>."},{name:"--auth-shell-device-{card-max-width,main-padding,main-padding-mobile}",category:"component",tier:"component",role:'AuthShell `preset="device-authorization"` measure (gh#220) \u2014 the canonical OAuth device-grant artboard: a 23.75rem/380px card at 1440/1024 and a 15px-block \xB7 5px-inline page gutter at 390 (so the card renders x=5px, width=380px). LITERAL lengths, not --space-*, because the artboard specifies exact device pixels that must not drift with --scaling. Selecting the preset replaces a consumer-side --auth-shell-card-max-width override or a forked `.auth-shell--wide` class; the canonical 360px/15px default is untouched.'},{name:"--auth-shell-context-{card-max-width,main-padding,main-padding-mobile,card-stack-gap}",category:"component",tier:"component",role:'AuthShell `preset="context-selection"` measure (gh#217) \u2014 the organisation/context picker: a 25rem card on desktop/tablet, edge-to-edge on mobile (0 inline gutter), and a 1rem rhythm between the three direct sections of the auth column (intro \xB7 choice card \xB7 "remember" row).'},{name:"--auth-shell-recovery-{card-max-width,main-padding,main-padding-mobile}",category:"component",tier:"component",role:'AuthShell `preset="account-recovery"` measure (gh#233) \u2014 the SCR-008 27rem/432px panel, shared by the password-recovery panel (request \xB7 sent \xB7 new-password \xB7 expired) AND the sign-in MFA challenge panel (OTP \xB7 recovery-code \xB7 passkey-failure), because both canonical desktop panels measure w=432 at 1440. Mobile gutter = 15px inline at <=30rem, so the panel is x=15, width=360 \u2014 the SAME rhythm as the canonical Login flow, chosen deliberately: the supplied 390 reference is a desktop 2x2 composite that crops horizontally and is NOT a valid source. The canonical 360px Login measure and the 24rem un-preset shell are untouched.'},{name:"--otp-slot-size",category:"component",tier:"component",role:"InputOTP slot box (gh#233). Default `var(--control-height)` \u2014 byte-identical to before and still density-aware \u2014 but its OWN knob, so an auth panel can widen the 6-slot challenge row to fill a wide surface WITHOUT re-scoping --control-height (which would resize the primary button and every other input in the same card). Set it to a NAMED tier (`var(--control-height-lg)`), never an ad-hoc calc offset."},{name:"--tabs-indicator-{background,size,offset}",category:"component",tier:"component",role:"Tabs `line` ACTIVE indicator (gh#248) \u2014 the only selected-state decoration the line variant paints; it never gets a surrounding ring/card border, so the `:focus-visible` keyboard ring stays visible and distinct (WCAG 2.4.7). --tabs-indicator-background is declared `initial` so its hsl(var(--primary)) default re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme. Defaults = primary \xB7 2px \xB7 offset 0 (flush with the trigger edge); raise the offset to park the bar on a thicker strip hairline. The selected ring on the default/card variants is unchanged."},{name:"--avatar-square-{radius,size,background,foreground}",category:"component",tier:"component",role:'Avatar `shape="square"` entity-header mark (gh#249) \u2014 the compact rounded square an organization/service header uses instead of the round person avatar. --avatar-square-background / --avatar-square-foreground are declared `initial` so the hsl(var(--primary)) / hsl(var(--primary-foreground)) defaults re-resolve at the CALL SITE under a scoped theme. Defaults = --radius-lg corners \xB7 --control-height box (swapping shape never reflows the header) \xB7 primary fill at 4.65:1 contrast. `shape="circle"` (the default) is inert and reads --avatar-background / --avatar-tint as before.'},{name:"--steps-inline-{gap,item-gap,font-size,separator-size}",category:"component",tier:"component",role:"Steps type=inline compact auth/device progress rhythm and typography. Consumers select the semantic appearance; services retune the row once without page CSS."},{name:"--auth-account-summary-{min-height,gap,padding,identity-min-width,avatar-size,avatar-glyph-size,email-font-size}",category:"component",tier:"component",role:"AuthAccountSummary compact signed-in identity row: wrapping threshold, avatar, email and action rhythm. The default touch-safe row is package-owned and remains themeable without consumer selectors."},{name:"--auth-shell-{main-align,card-stack-gap}",category:"component",tier:"component",role:"AuthShell column knobs shared by every preset. --auth-shell-main-align is the block alignment of the auth column (default `center`, the vertically-centred card; set `start` for a tall intro+card+footnote stack). --auth-shell-card-stack-gap is the gap between the card slot's direct sections \u2014 default `0px` (quiet, rule #44) so an existing single-card consumer is byte-for-byte unchanged; a preset opts in."},{name:"--card-space-shell-y",category:"component",tier:"component",role:"Card BLOCK-axis shell padding (gh#232) \u2014 a plain header's top, a `solo` body's top and the terminal slot's bottom. Split off --card-space-inset, which is now inline-only, so a theme can make a card SHORTER without narrowing its column. Declared `initial`: the default resolves at the CALL SITE to --card-space-inset, so a card that overrides neither (and `density=\"tight|cozy\"`, which re-declares it `initial` to re-arm the per-instance inset) renders exactly as before."},{name:"--auth-shell-{compact-card-inset,card-padding-block-compact,card-body-gap-compact,card-gap-compact}",category:"component",tier:"component",role:"The compact AuthShell card's four independent knobs (gh#232) \u2014 one per axis, so the canonical Login card is tunable WITHOUT a consumer selector on the card-content slot: `compact-card-inset` = the inline column (\u2192 --card-space-inset); `card-padding-block-compact` = the card's block/top-bottom padding (\u2192 --card-space-shell-y, `initial` so its default mirrors the live inline inset and canonical output is unchanged); `card-body-gap-compact` = the header\u2194body gap (\u2192 --card-space-body-y, 12px, the role the block knob used to be mis-wired to); `card-gap-compact` = the in-slot title\u2195description stack gap (\u2192 --card-space-gap)."},{name:"--app-setting-picker-compact-{control-height,padding-x,gap,font-size}",category:"component",tier:"component",role:'AppSettingPicker `compact` trigger (gh#217) \u2014 the small, content-hugging LABELLED switcher for an auth/legal footer (`kind="locale" appearance="labeled" compact`). The box height reads the official --control-height-sm tier (never a literal or an ad-hoc calc), and padding/gap/type are separate knobs so a service theme retunes the footer switcher without forking CSS.'},{name:"--centered-shell-column-offset-block",category:"component",tier:"component",role:'CenteredShell column block offset (gh#221) \u2014 default `0` (the quiet state, rule #44: the top-aligned flowing/scrolling page). `<CenteredShell align="center">` flips it to `auto`, which centres the column in the 100dvh shell: the package-owned geometry for a SYSTEM-level standalone surface (a 500/503 error page, a maintenance notice) at 1440/1024/390, so a consumer never writes `min-h-dvh` + flex-centring CSS or a className. Auto block offsets collapse to 0 when the content is taller than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--error-surface-*",category:"component",tier:"component",role:'ErrorSurface knobs (gh#221 / gh#251) \u2014 the whole 403/404/500/503 exception surface is themeable without a single consumer class or media query, in BOTH `mode="application"` and `mode="system"`. Geometry: `--error-surface-max-width` (32rem measure of the surface block, so a long JA/VI headline wraps readably even inside a wide PageContainer), `--error-surface-gap` (rhythm between status code \xB7 body \xB7 metadata \xB7 progress), `--error-surface-padding-block` (--space-10, the 1440/1024 steps) and `--error-surface-padding-block-compact` (--space-6, below the narrow step, i.e. the 390 case), `--error-surface-brand-gap` (system-mode Logo slot) and `--error-surface-progress-max-width` (18rem, so the maintenance meter reads as metadata, not as the page\'s primary content). Metadata list: `--error-surface-meta-gap` (row rhythm) \xB7 `--error-surface-meta-row-gap` (label\u2194value gap inside one row) \xB7 `--error-surface-meta-padding-block`. Chrome is QUIET by default (rule #44): `--error-surface-meta-border` is `none`; a service opts in with `1px solid hsl(var(--border))`. The narrow step is a CONTAINER query at 30rem on the SURFACE\'s own width, not a viewport media query, so it compacts correctly whether the squeeze came from a 390px phone or from an application shell with an expanded sidebar; below it, metadata rows stack label-over-value. System-mode viewport centring is delegated to `--centered-shell-column-offset-block` (via CenteredShell align="center"), and the description measure to `--empty-state-description-max-width`.'},{name:"--centered-shell-landing-*",category:"component",tier:"component",role:'CenteredShell public-landing knobs (gh#252) \u2014 the SHELL geometry of a public marketing/product landing, so the landing itself stays a COMPOSITION (Hero/Navbar/Footer fail the Framework-Component Test) with ZERO page-local CSS. Read only under `preset="public-landing"`; the default shell emits no `data-preset`, so none of them can match. Measure: `--centered-shell-landing-max-width` (67.5rem, shared by the header bar, the centred column AND the footer \u2014 the bar/footer inline padding is `max(gutter, (100% - measure) / 2)`, so header content starts on exactly the column edge and no consumer max-width wrapper exists), `--centered-shell-landing-inset-inline` (+ `-compact`, the 390 gutter), `--centered-shell-landing-main-padding-block` (+ `-compact`), `--centered-shell-landing-section-gap` (+ `-compact`, the rhythm BETWEEN plain `<section>` elements \u2014 the consumer never sets a gap) and `--centered-shell-landing-footer-padding-block`. Chrome is QUIET by default (rule #44): `--centered-shell-landing-card-shadow` is `none`, which flattens every Card in the subtree from ONE knob instead of a consumer `.landing .card { box-shadow: none }`. Type: `--centered-shell-landing-heading-size` (+ `-compact`) re-points `--heading-h1`, so a hero title is a real `Heading level={1}` and never a page font-size. `--centered-shell-landing-background` is a ROLE-MIRROR declared `initial` with the role default at the call site (`var(--centered-shell-landing-background, var(--background))`), so a scoped [data-tenant]/.dark override of `--background` still reaches the landing canvas. The compact step is a 40rem media query owned by the package; region visibility (anchor nav below the tablet step, wordmark and the secondary action at mobile) is `Flex hideBelow` / `hideFrom`, never a consumer @media.'},{name:"--table-action-collection-*",category:"component",tier:"component",role:'Table action-collection knobs (gh#253) \u2014 the canonical dense approval/action queue at 1440 \xB7 1024 \xB7 390. Read only under `preset="action-collection"`. Column PRIORITY measures replace the desktop intrinsic widths (a `white-space: nowrap` free-text column is what makes a five-column queue wider than its card and forces the horizontal scroll): `--table-action-collection-primary-width` (18%), `-secondary-width` (22%), `-meta-width` (12%) and `-actions-width` (3.5rem \u2014 an absolute measure because the row-action affordance must never be squeezed below its touch target); an unmarked column takes the remaining space. Below the collapse step the same four re-point to their `-compact` tier (24% / 22% / 20% / 2.75rem) together with `--table-action-collection-font-size-compact`, `-row-height-compact`, `-cell-space-x-compact` and `-cell-padding-y-compact`. The step is a CONTAINER query on the table\'s own width (sm 40rem \xB7 md 48rem \xB7 lg 64rem \xB7 xl 80rem via `collapseBelow`), not a viewport media query, so a table inside a master rail collapses before the page does. Percentages so the ratio holds at any card width; a service retunes the ratio once instead of authoring column widths per screen (rule #45). ONE family serves BOTH entry points \u2014 the `Table` primitive (`priority` on `TableHead`/`TableCell`) and the TanStack `DataTable` (`priority` on the `ColumnDef`, stamped onto both cells for you). There is deliberately no parallel `--data-table-action-collection-*` family: retune these once and every queue follows.'},{name:"--legal-document-*",category:"component",tier:"component",role:"LegalDocumentShell knobs (gh#222) \u2014 the whole legal/policy document surface is themeable without a single consumer `.legal-*` class. Geometry: `--legal-document-measure-max-width` (46rem readable measure, caps header/body/footer), `--legal-document-toc-width` \xB7 `--legal-document-column-gap` \xB7 `--legal-document-toc-inset-block-start` (sticky offset) \xB7 `--legal-document-toc-max-height`, `--legal-document-section-gap` \xB7 `--legal-document-section-title-gap` \xB7 `--legal-document-header-gap` \xB7 `--legal-document-meta-gap` \xB7 `--legal-document-nav-gap` \xB7 `--legal-document-footer-gap`, `--legal-document-meta-font-size`, `--legal-document-body-line-height` (1.8 long-form leading) and `--legal-document-scroll-offset` (the `scroll-margin-block-start` a hash jump leaves above a heading \u2014 this is why no app needs JS offset arithmetic). Contents entries: `--legal-document-toc-font-size` \xB7 `--legal-document-toc-title-font-size` \xB7 `--legal-document-toc-item-padding` \xB7 `--legal-document-toc-item-radius` \xB7 `--legal-document-toc-marker-width`. Chrome is QUIET by default (rule #44): `--legal-document-toc-border` / `--legal-document-header-border` / `--legal-document-footer-border` are all `none`; a service opts in with `1px solid hsl(var(--border))`. The six colour knobs are ROLE-MIRRORS declared `initial` with the role default at the call site \u2014 `--legal-document-toc-foreground` (\u2192 --muted-foreground, also paints the contents caption), `--legal-document-toc-active-foreground` (\u2192 --foreground), `--legal-document-toc-active-background` (\u2192 --accent), `--legal-document-toc-marker-color` (\u2192 --primary), `--legal-document-meta-foreground` (\u2192 --muted-foreground) and `--legal-document-summary-foreground` (\u2192 --muted-foreground) \u2014 so a scoped [data-tenant]/.dark override of the role still reaches them. The one-column \u21C4 two-column split is a CONTAINER query at 56rem on the shell's own width, not a viewport media query."},{name:"--empty-state-description-max-width",category:"component",tier:"component",role:"EmptyState description MEASURE (gh#221) \u2014 default 28rem (~65 Latin characters per line). A service or locale that needs a shorter/longer measure for its own copy (JA/VI error-page descriptions, a narrow system surface) retunes this one knob instead of forking `.ui-empty-state-description` (rule #45)."},{name:"--sidebar-nav-item-{foreground,hover-foreground,disabled-foreground} / --sidebar-nav-icon-{foreground,hover-foreground,active-foreground,disabled-foreground}",category:"component",tier:"component",role:"Sidebar navigation row + icon COLOUR, split so they can differ (gh#228). Previously `.sb-nav-item` set one `color` for the whole row, so the Lucide SVG inherited `--muted-foreground` along with the label and the icons read as 'missing' against a canonical shell that wants darker 16px icons. `--sidebar-nav-item-*` drives the row/label (incl. sub rows), `--sidebar-nav-icon-*` drives `.sb-icon`. All are role-mirror knobs declared `initial` at `:root` with the role default at the call site, so a scoped `[data-tenant]`/`.dark` override reaches them; icon defaults resolve to `currentColor`, i.e. rendering is unchanged until a service opts in (`--sidebar-nav-icon-foreground: hsl(var(--foreground))` is the canonical darker-icon setting). Colour ONLY \u2014 the 16px icon, 32px row height and 10px gap are untouched. The active row keeps `--sidebar-item-active-{background,foreground}`."},{name:"--list-row-compact-{padding-y,padding-x,gap,body-min-width}",category:"component",tier:"component",role:'ListRow `density="compact"` inline-actions geometry (gh#246) \u2014 the compact invitation/history row: a 36px leading Avatar, a shrinkable title+description and one or two small trailing Buttons on ONE line inside the canonical 358px card (326px content). `--list-row-compact-body-min-width` (6rem) is the compact body threshold \u2014 the default 12rem `--list-row-body-min-width` is what forced the actions (and a history Badge + date) onto a second line at 390px; it is consumed as `min(<token>, 100%)` exactly like the default knob, so the #224 wrap contract is intact and a cluster that genuinely cannot fit still wraps instead of widening the page root. `--list-row-compact-{padding-y,padding-x,gap}` are declared `initial` with the density-scaled default at the CALL SITE (`var(--space-2)` block, `var(--list-row-padding-x)` inline, `var(--space-2)` gap) \u2014 a `:root` binding would freeze compact rows at the `:root` density. Measured at 390px: invitation row 62px (was 126px, actions wrapped), history row 41px (was 114px), documentElement scrollWidth === clientWidth.'},{name:"--list-row-{body-min-width,trailing-gap,indicator-size,read-background,unread-background,indicator-color}",category:"component",tier:"component",role:"ListRow shrink + unread state (gh#224, gh#225). `--list-row-body-min-width` (12rem) is consumed as `min(<token>, 100%)` \u2014 the `min()` is load-bearing, a bare length re-inflates the row's intrinsic width and reintroduces page-root overflow. `--list-row-trailing-gap` spaces wrapped trailing actions. The unread trio are role-mirror knobs declared `initial` with the role at the call site: `--list-row-unread-background` defaults to `hsl(var(--muted))` NOT `--accent` \u2014 accent measured 4.23:1 against the xs muted-foreground description line, below WCAG AA; muted is 4.63:1 light / 5.47:1 dark. `--list-row-indicator-color` (\u2192 `--primary`) and `--list-row-indicator-size` drive the unread dot, whose meaning is carried by localized sr-only text, never by colour alone."},{name:"--filter-bar-scroll-padding-y",category:"component",tier:"component",role:'Scrollbar gutter for `<FilterBar overflow="scroll">` (gh#216), default `var(--space-1)`. Only applies at \u2265640px, where a wide filter set becomes a single nowrap strip with a sticky inline-end clear-all; below that the bar still stacks, so the gutter would be dead space. Pair with the existing `--filter-bar-sticky-background` (already an `initial` role-mirror knob) when theming the strip.'},{name:"--app-shell-{sidebar-width,rail-width}",category:"component",tier:"component",role:"AppShell docked navigation rail widths (gh#213) \u2014 `--app-shell-sidebar-width` (default 16rem) is the expanded rail, `--app-shell-rail-width` (default 4rem) the icon-only rail used at `<AppShell sidebarCollapsed>`. These were hard-coded `grid-template-columns` literals; a service on a different design grid (e.g. a 255px rail) now sets ONE token in its theme instead of forking `.app-root`. Below the 900px shell breakpoint both collapse to a single full-width column and the sidebar moves into AppShell's drawer."},{name:"--app-shell-bar-{inset,inset-compact,gap}",category:"component",tier:"component",role:"AppShell top-bar chrome (gh#213) \u2014 `--app-shell-bar-inset` is the bar's inline padding (default --space-4), `--app-shell-bar-inset-compact` the tighter value applied below the 900px breakpoint where the docked rail is gone (default --space-3), `--app-shell-bar-gap` the gap between the bar's direct children (default --space-3). Height stays `--app-shell-bar-height` (3rem), which now holds at EVERY width \u2014 a duplicate 768px rule used to override it with a literal."},{name:"--topbar-{height,inset,gap}",category:"component",tier:"component",role:"Standalone `<Topbar>` box knobs (gh#213). Topbar is a pure slot bar, so the defaults are the QUIET ones and rendering is unchanged from before they existed: `--topbar-height: auto` and `--topbar-inset: 0px` (inside AppShell the `.app-topbar` grid row owns height and inset), `--topbar-gap: var(--space-2)`. A service that mounts Topbar DIRECTLY on a page sizes it from the theme (`--topbar-height: 3.5rem; --topbar-inset: var(--space-4)`) instead of an app-local class. `--topbar-gap` is both the gap BETWEEN the start/center/end clusters and the gap INSIDE each, so one knob re-rhythms the whole bar. None of them touch the gh#226 shrink contract (start clips, center yields first, end stays anchored inline-end)."},{name:"--{dialog,sheet}-overlay-background / --app-shell-mobile-nav-background (+ -alpha)",category:"component",tier:"component",role:"Overlay scrims (gh#215). All three are ROLE-MIRROR knobs declared `initial` at `:root`, with the default resolved at the CALL SITE as a SHARE of the one semantic `--overlay-background` \u2014 `color-mix(in srgb, var(--overlay-background) var(--<x>-overlay-alpha), transparent)`. Previously each carried a private literal, so setting `--overlay-background` had NO effect anywhere. The share knobs (`--dialog-overlay-alpha` 60%, `--sheet-overlay-alpha` 40%, `--app-shell-mobile-nav-alpha` 40%) keep every default byte-identical (0.3 / 0.2 / 0.2 black) while letting one `--overlay-background` override retint the whole system, including scoped `[data-tenant]` / `.dark` themes. Setting a `*-overlay-background` knob directly still wins outright. NOTE: overlays render in a portal, so a multi-tenant scope must also sit on the portal container."}];function I(t){return C.filter(a=>a.category===t)}var V=[{name:"--badge-space-gap",value:"var(--space-inline-xs)",description:"Badge component tokens."},{name:"--badge-space-x",value:"var(--space-2)",description:"Badge component tokens."},{name:"--badge-space-y",value:"var(--space-1)",description:"Badge component tokens."},{name:"--badge-font-size",value:"var(--font-size-xs)",description:"Small-by-design (badge/pill/counter). A knob (rule #45) so a service can * re-tune badge text without touching the global --font-size-xs step."},{name:"--card-space-inset",value:"var(--space-section-active)",description:"Horizontal inset of every slot (header / content / footer) + the resting top/bottom * shell padding. This is the column the title, body and footer all align to."},{name:"--card-space-shell-y",value:"initial",description:'BLOCK-axis (top/bottom) shell padding of the slotted card rhythm \u2014 a plain header\'s top, a * `solo` body\'s top, and the terminal slot\'s bottom (gh#232). Split off --card-space-inset so a * shell (AuthShell compact) can retune the card\'s height WITHOUT moving the inline column. * Declared `initial` \u2014 NOT `var(--card-space-inset)` \u2014 so the default resolves at the CALL SITE: * a :root binding would freeze at the :root inset and `[data-density="tight"|"cozy"]` (which * override --card-space-inset on the card element) would stop reaching it. See docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`" \u2014 the same call-site rule applies to derived knobs.'},{name:"--card-space-header-y",value:"var(--space-stack-sm)",description:"Vertical padding of a BANDED header band (top = bottom). Drives --card-space-divided-y."},{name:"--card-space-body-y",value:"var(--space-section-active)",description:"Gap between the header and the body, and the body's own top padding \u2014 the breathing * room under a title before content begins."},{name:"--card-space-solo-y",value:"initial",description:'Symmetric block padding for a SOLO content slot, so a composed shell can tune block and * inline spacing independently without targeting CardContent. * Declared `initial` for the SAME reason as --card-space-shell-y above: written as * `var(--card-space-inset)` here it would freeze at the :root inset, and a card carrying * [data-density="tight"|"cozy"] (which override --card-space-inset ON THE CARD) would keep the * :root value. The default now resolves at the call site through the chain * solo-y \u2192 shell-y \u2192 inset, so a solo body follows the general block knob when only that is * set, and an explicit solo-y still wins.'},{name:"--card-space-footer-y",value:"var(--space-stack-sm)",description:"Vertical padding of a SEPARATED footer band (top = bottom). Drives --card-space-divided-y."},{name:"--card-space-divided-y",value:"var(--card-space-header-y)",description:"DIVIDED-section vertical padding (rule #44/#45). A header/footer that carries a divider * border (banded header, separated footer) reads as its own band, so it pads SYMMETRICALLY * top+bottom \u2014 distinct from a plain header that flows into the body (top inset, no bottom). * One themeable knob keeps the header- and footer-band rhythm in sync; a service theme tunes * the band density here instead of forking per-slot CSS."},{name:"--card-space-gap",value:"var(--space-stack-xs)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-font-size",value:"var(--font-size-base)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-line-height",value:"var(--line-height-tight)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-title-font-weight",value:"var(--font-weight-semibold)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-description-font-size",value:"var(--font-size-sm)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-description-line-height",value:"var(--line-height-normal)",description:"Vertical gap between stacked items WITHIN a slot (e.g. title \u2195 description in the header)."},{name:"--card-background",value:"initial",description:'Card fill + edge \u2014 opt-in knobs that DEFAULT to the live --card / --border roles. Declared * `initial` (not `var(--card)`) so the default re-resolves at the call site under a scoped theme: * a :root binding to a role var freezes at the :root value and a scoped `[data-tenant]` override of * the role never reaches it (see docs/STANDARDS-vocabulary-tokens.md \xB7 "role-mirror knobs"). A * service still overrides the knob directly (--card-background: \u2026) to win over the role default.'},{name:"--card-border",value:"initial",description:"default = hsl(var(--card))"},{name:"--card-header-background",value:"initial",description:"Banded-header fill \u2014 role-tintable (rule #45): a service points this at any role, * e.g. --card-header-background: var(--primary), and tunes --card-header-background-alpha for * the wash strength. Default = the live --muted role (resolved at the call site)."},{name:"--card-header-background-alpha",value:"0.55",description:"default = hsl(var(--muted))"},{name:"--card-header-border-bottom",value:"initial",description:"Banded-header divider \u2014 tokenised (rule #44) so a service theme can make it * dashed / heavier / none without forking CSS. Pair with * --card-header-background-alpha: 0 for a quiet borderless-band header. * Default = 1px solid hsl(var(--card-border)) (resolved at the call site)."},{name:"--card-radius",value:"var(--radius-xl)",description:"Banded-header divider \u2014 tokenised (rule #44) so a service theme can make it * dashed / heavier / none without forking CSS. Pair with * --card-header-background-alpha: 0 for a quiet borderless-band header. * Default = 1px solid hsl(var(--card-border)) (resolved at the call site)."},{name:"--card-shadow",value:"var(--shadow-sm)",description:"The DXS hi-fi baseline uses a quiet 10px data surface with one shadow-sm * elevation layer. Consumers can still flatten or lift cards through this knob."},{name:"--card-glow",value:"0 0 0 0 transparent",description:"Brand glow layer \u2014 invisible no-op at rest (rule #44). Paired AFTER --card-shadow in the * surface box-shadow so a service can wash every card with the global glow, e.g. * --card-glow: var(--shadow-glow), with no markup change."},{name:"--card-tint",value:"transparent",description:"Fill tint \u2014 subtle role wash over the card background (default transparent = invisible). * Painted as an overlay so a service sets --card-tint: hsl(var(--primary) / 0.04) once."},{name:"--card-accent-rail-width",value:"6px",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-font-size",value:"var(--font-size-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-font-weight",value:"var(--font-weight-medium)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-label-letter-spacing",value:"0.04em",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-font-size",value:"var(--font-size-2xl)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-line-height",value:"1.1",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-value-font-weight",value:"var(--font-weight-semibold)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-hint-font-size",value:"var(--font-size-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-gap",value:"var(--space-stack-xs)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-size",value:"2.25rem",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-glyph-size",value:"1.25rem",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-radius",value:"var(--radius-md)",description:"Accent edge \u2014 width of the semantic leading-edge stripe (data-accent). * Tokenised (rule #44) so a service theme can re-tune it without forking CSS. * The slot padding compensation in card-layout.css subtracts the same token, * so content stays aligned on the shell whatever the rail width."},{name:"--stat-card-icon-background",value:"initial",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--stat-card-icon-foreground",value:"initial",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--stat-card-delta-font-size",value:"var(--font-size-xs)",description:"Medallion tint \u2014 soft brand wash + brand glyph by default; a service retints by overriding * --primary or these tokens directly (rule #44/#45). `initial` so the --primary default * re-resolves at the call site under a scoped theme (no :root freeze). * Defaults = hsl(var(--primary) / 0.1) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-space-gap",value:"var(--space-stack-sm)",description:"\u2500\u2500 ServiceLauncherCard (gh#219) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Internal rhythm of a launcher tile: one gap knob drives the vertical stack AND the * icon\u2194title\u2194status row, so a service theme retunes the whole tile density once."},{name:"--card-service-launcher-icon-size",value:"var(--control-height-lg)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-glyph-size",value:"var(--space-5)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-radius",value:"var(--radius-md)",description:"Semantic icon surface. `--control-height-lg` is the 36px control tier the hi-fi calls for \u2014 * a tier token, never a literal, so the medallion tracks --scaling with its sibling controls."},{name:"--card-service-launcher-icon-background",value:"initial",description:"Available-service medallion tint. `initial` (role-mirror rule, docs/TOKENS.md) so the role * defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override reaches them. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-icon-foreground",value:"initial",description:"Available-service medallion tint. `initial` (role-mirror rule, docs/TOKENS.md) so the role * defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override reaches them. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--primary)) glyph."},{name:"--card-service-launcher-unavailable-icon-background",value:"initial",description:"Unavailable medallion tint \u2014 applied when the consumer supplies `disabledReason`, so an * un-launchable service never reads as brand-live. `initial` for the same role-mirror reason. * Defaults = hsl(var(--muted)) fill \xB7 hsl(var(--muted-foreground)) glyph."},{name:"--card-service-launcher-unavailable-icon-foreground",value:"initial",description:"Unavailable medallion tint \u2014 applied when the consumer supplies `disabledReason`, so an * un-launchable service never reads as brand-live. `initial` for the same role-mirror reason. * Defaults = hsl(var(--muted)) fill \xB7 hsl(var(--muted-foreground)) glyph."},{name:"--card-service-launcher-description-font-size",value:"var(--font-size-xs)",description:"Description prose \u2014 also drives the disabled-reason line and the catalog-CTA caption."},{name:"--card-service-launcher-description-line-height",value:"var(--line-height-body)",description:"Description prose \u2014 also drives the disabled-reason line and the catalog-CTA caption."},{name:"--card-service-launcher-metadata-font-size",value:"var(--font-size-xs)",description:"Mono metadata line (hostname \xB7 plan) \u2014 tighter leading than prose by design."},{name:"--card-service-launcher-metadata-line-height",value:"var(--line-height-normal)",description:"Mono metadata line (hostname \xB7 plan) \u2014 tighter leading than prose by design."},{name:"--card-service-launcher-cta-min-height",value:"calc(var(--control-height-lg) * 4)",description:"Dashed catalog/add companion tile: kept tall enough to sit level with a populated launcher * tile in the same grid row. Four control tiers \u2248 medallion + title + description + action."},{name:"--card-service-launcher-skeleton-title-width",value:"var(--space-12)",description:"Skeleton bar widths \u2014 shape-matched placeholders for the title and status badge."},{name:"--card-service-launcher-skeleton-status-width",value:"var(--space-10)",description:"Skeleton bar widths \u2014 shape-matched placeholders for the title and status badge."},{name:"--chart-trend-plot-height-xs",value:"3.5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-sm",value:"5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-md",value:"7.5rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height-lg",value:"10rem",description:"\u2500\u2500 Plot height tiers (size = xs|sm|md|lg) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * `xs` is the canonical dashboard-summary-card density: a seven-day trend that sits under * a KPI headline without stealing its vertical rhythm. A service retunes the whole scale * here; a screen picks a step with the `size` prop."},{name:"--chart-trend-plot-height",value:"var(--chart-trend-plot-height-xs)",description:"Active tier \u2014 chart-layout.css re-points this per `data-size`; overriding it directly * pins one height for every trend regardless of `size`."},{name:"--chart-trend-bar-gap",value:"var(--space-2)",description:"\u2500\u2500 Bar marks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Thin marks, a surface gap between neighbours and a rounded data-end anchored to the * baseline (the data-visualization mark spec)."},{name:"--chart-trend-bar-radius",value:"var(--radius-sm)",description:"\u2500\u2500 Bar marks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Thin marks, a surface gap between neighbours and a rounded data-end anchored to the * baseline (the data-visualization mark spec)."},{name:"--chart-trend-bar-max-width",value:"1.5rem",description:"Ceiling on a single mark so a 3-point trend does not render slabs."},{name:"--chart-trend-bar-min-height",value:"2px",description:"Floor so a zero/absent value still reads as a plotted category rather than a hole."},{name:"--chart-trend-bar-background",value:"initial",description:'Muted mark fill \u2014 role-mirror knob, declared `initial` so the role default re-resolves * at the CALL SITE under `.dark` / `[data-tenant]` (docs/TOKENS.md \xB7 "Role-mirror knobs * MUST be `initial`"). Default = hsl(var(--muted-foreground) / 0.75), which clears the * 3:1 non-text contrast floor (WCAG 1.4.11) against the card surface.'},{name:"--chart-trend-bar-background-alpha",value:"0.75",description:"Opacity applied to the muted-fill role default."},{name:"--chart-trend-bar-emphasis-background",value:"initial",description:'Emphasized ("current") mark fill \u2014 role-mirror knob. Default = hsl(var(--primary)).'},{name:"--chart-trend-baseline-border",value:"initial",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-tick-gap",value:"var(--space-1)",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-tick-font-size",value:"var(--font-size-xs)",description:"\u2500\u2500 Baseline + category ticks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * Chrome defaults QUIET (rule #44): no baseline rule at rest. A service opts in with * `--chart-trend-baseline-border: 1px solid hsl(var(--border));`."},{name:"--chart-trend-footer-gap",value:"var(--space-2)",description:"Gap between the plot block and the optional activity footer slot."},{name:"--control-height-compact",value:"1.75rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-default",value:"2rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-comfortable",value:"2.75rem",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-compact",value:"var(--space-2)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-default",value:"var(--space-3)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-padding-x-comfortable",value:"var(--space-4)",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height",value:"calc(var(--control-height-default) * var(--scaling))",description:"Control primitive tokens: heights, horizontal padding, adjacent control sizes."},{name:"--control-height-sm",value:"calc(var(--control-height) - calc(0.25rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-height-lg",value:"calc(var(--control-height) + calc(0.25rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-height-xs",value:"calc(var(--control-height) - calc(0.5rem * var(--scaling)))",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-padding-x",value:"var(--control-padding-x-default)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-gap",value:"var(--space-inline-sm)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-gap-sm",value:"var(--space-inline-xs)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--control-radius",value:"var(--radius)",description:"Adjacent control sizes, derived from the active --control-height. The \xB1step * is scaled too so the whole control ladder stays proportional under --scaling."},{name:"--button-radius",value:"var(--radius-md)",description:"Button corner radius \u2014 defaults to the button's historical `rounded-md` so nothing * changes by default, but is its OWN knob so a service theme can retune the button * radius INDEPENDENTLY of input/control radius (issue #124)."},{name:"--control-font-size",value:"var(--font-size-base)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-border-width",value:"1px",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-shadow",value:"var(--shadow-xs)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-icon-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-icon-size-sm",value:"calc(0.875rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--control-focus-ring-width",value:"var(--focus-ring-width)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--checkbox-size-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-gap",value:"var(--space-inline-sm)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-group-gap-x",value:"var(--space-6)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-group-gap-y",value:"var(--space-3)",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-description-gap",value:"0.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--choice-control-offset",value:"0.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width",value:"calc(2.25rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width-compact",value:"2rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-width-comfortable",value:"2.5rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height",value:"calc(1.25rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height-compact",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-height-comfortable",value:"1.375rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-size-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate",value:"calc(1rem * var(--scaling))",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate-compact",value:"0.875rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--switch-thumb-translate-comfortable",value:"1.125rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--slider-track-height",value:"0.375rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--slider-thumb-size",value:"1rem",description:"Control surface knobs \u2014 font-size, border width and resting shadow of every * `.ui-control` (input / picker trigger). Tokenised so a service theme tunes them * once instead of each component hard-coding Tailwind utilities. Defaults preserve * the historical look (font-size-base, 1px border, shadow-xs)."},{name:"--otp-slot-size",value:"initial",description:'InputOTP slot box (gh#233). Its own knob so an auth surface can widen the 6-slot challenge row * to fill a wide panel WITHOUT re-scoping --control-height (which would resize every other * control in the same card). Declared `initial` \u2014 the tier-mirror form of the role-mirror rule in * docs/TOKENS.md: the default must resolve at the CALL SITE (`var(--otp-slot-size, * var(--control-height))`), because `--otp-slot-size: var(--control-height)` here would FREEZE at * the :root tier (32px) and an OTP row inside `.ui-auth-shell[data-variant="canonical"]`, which * re-scopes --control-height to 36px, would silently shrink. Verified in Chromium: 36px before * and after. A service opts in with a NAMED tier (`var(--control-height-lg)`), never a calc.'},{name:"--checkbox-checked-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--switch-checked-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--toggle-on-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--slider-track-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--slider-range-background",value:"initial",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--color-picker-input-width",value:"6.5rem",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-list-max-height",value:"min(300px, 50vh)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-input-padding-x",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-group-padding",value:"var(--space-1)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-item-padding-y",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-item-padding-x",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-width",value:"35rem",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-inset-top",value:"calc(var(--space-6) * 4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-viewport-inset",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-padding-y",value:"var(--space-2)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-padding-x",value:"var(--space-4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-palette-hint-gap",value:"var(--space-4)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-edge-inset",value:"var(--space-3)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-start-padding",value:"calc( var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap) )",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-end-padding",value:"calc( var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap) )",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--choice-description-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--color-picker-hex-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--command-group-heading-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--search-input-label-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--tag-input-chip-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--toggle-sm-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--button-sm-font-size",value:"var(--font-size-xs)",description:'Checked/on/active fills \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme (a :root binding to var(--primary) freezes at the :root value and a scoped * [data-tenant] override of --primary never reaches it). A service retints the "selected" state * by overriding these directly. Defaults = hsl(var(--primary)) \xB7 slider track 0.2\u03B1.'},{name:"--control-height-compact",value:"2.75rem",description:"Rule #24 \u2014 on touch devices (coarse pointer) interactive controls keep a \u226544px tap target * regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height * resolves through these via var(), so inputs/buttons/selects/table rows all bump together."},{name:"--control-height-default",value:"2.75rem",description:"Rule #24 \u2014 on touch devices (coarse pointer) interactive controls keep a \u226544px tap target * regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height * resolves through these via var(), so inputs/buttons/selects/table rows all bump together."},{name:"--progress-label-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--tree-item-title-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--tree-item-description-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--timeline-note-font-size",value:"var(--font-size-xs)",description:"Data-display component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--avatar-background",value:"initial",description:"Avatar surface \u2014 `initial` so the --muted default re-resolves at the call site under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override never reaches it). A service re-tints the placeholder fill once (e.g. --avatar-background: hsl(var(--accent))). Default = hsl(var(--muted))."},{name:"--avatar-tint",value:"transparent",description:"Optional role wash over the avatar (default transparent = invisible, rule #44). Painted as an overlay so a service sets --avatar-tint: hsl(var(--primary) / 0.08)."},{name:"--avatar-square-radius",value:"var(--radius-lg)",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-size",value:"var(--control-height)",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-background",value:"initial",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--avatar-square-foreground",value:"initial",description:'Entity-header mark \u2014 `<Avatar shape="square">` (gh#249): the compact rounded SQUARE an organization/service header uses, as opposed to the round person avatar. Every value is a knob (rule #45) so a service matches the mark to its own grid without a className override. --avatar-square-background / --avatar-square-foreground are role-mirror knobs: `initial` so the --primary / --primary-foreground defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to a role var would freeze at the :root value). Defaults = --radius-lg corners \xB7 --control-height box (same as the circle avatar, so swapping shape never reflows a header) \xB7 hsl(var(--primary)) fill \xB7 hsl(var(--primary-foreground)) glyph.'},{name:"--progress-track-background",value:"initial",description:"Progress track + fill \u2014 `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, fill reads --success; a service re-tones once. Defaults = hsl(var(--secondary)) track \xB7 hsl(var(--success)) fill."},{name:"--progress-fill-background",value:"initial",description:"Progress track + fill \u2014 `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, fill reads --success; a service re-tones once. Defaults = hsl(var(--secondary)) track \xB7 hsl(var(--success)) fill."},{name:"--timeline-dot-done-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--timeline-dot-current-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--timeline-line-completed-background",value:"initial",description:"Timeline accents \u2014 `initial` so the dot/line role defaults re-resolve under a scoped theme. Defaults = hsl(var(--success)) done \xB7 hsl(var(--primary)) current/line."},{name:"--tree-item-active-border",value:"initial",description:"Tree active item \u2014 border + soft bg tint over the --primary role. `initial` so the default re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border \xB7 0.05 fill."},{name:"--tree-item-active-background",value:"initial",description:"Tree active item \u2014 border + soft bg tint over the --primary role. `initial` so the default re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border \xB7 0.05 fill."},{name:"--qr-code-foreground",value:"0 0% 0%",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-background",value:"0 0% 100%",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-xs",value:"6rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-sm",value:"8rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-md",value:"10rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--qr-code-size-lg",value:"12.5rem",description:"QR codes stay scanner-safe in light and dark application themes. Consumers may override these component tokens only when the resulting pair retains strong contrast."},{name:"--password-strength-score-font-size",value:"var(--font-size-xs)",description:"Data-entry component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--password-strength-checklist-font-size",value:"var(--font-size-xs)",description:"Data-entry component tokens \u2014 small-by-design text knobs (rule #45/#46)."},{name:"--descriptions-label-width",value:"8rem",description:'Width of the label column when <Descriptions layout="horizontal">. Labels align to this * shared column so the values line up (the horizontal-detail look, mirroring <Form layout>). * A rem value gives a fixed aligned column; set `max-content` to size each label to its text. * (rule #44/#45 \u2014 a service theme tunes it here instead of forking CSS.)'},{name:"--email-shell-width",value:"480px",description:"\u2500\u2500 Shell \u2014 the 480px transactional-email geometry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-shell-padding",value:"32px",description:"canonical transactional card width"},{name:"--email-shell-page-padding",value:"24px",description:"card inset \u2014 mirrors --space-8 (2rem)"},{name:"--email-shell-border-width",value:"1px",description:"gutter between the client viewport and the card (--space-6)"},{name:"--email-card-radius",value:"10px",description:"card edge \u2014 mirrors the 1px --border hairline"},{name:"--email-card-reference-height",value:"407px",description:"mirrors --card-radius (--radius-xl = 6px \xD7 \u03C6 \u2248 10px)"},{name:"--email-stack-gap",value:"24px",description:"canonical invitation reference measures 480\xD7407"},{name:"--email-stack-gap-sm",value:"12px",description:"block rhythm \u2014 mirrors --space-stack-lg (1.5rem)"},{name:"--email-mark-width",value:"22px",description:'The mark ARTWORK is the same 32\xD732 capsule + glyph `<Logo mark="godx" />` paints; only the * RENDERED BOX differs. The canonical SCR-302 header sets it at 22px next to a 13px/700 "GoDX" * wordmark, which is smaller than the web --logo-godx-size (2rem) \u2014 an email header carries the * identity, not the navigation, so the lockup sits quieter (gh#250).'},{name:"--email-mark-height",value:"22px",description:"canonical SCR-302 header lockup mark box"},{name:"--email-mark-gap",value:"8px",description:"canonical SCR-302 header lockup mark box"},{name:"--email-wordmark-font-size",value:"13px",description:"mark \u2194 wordmark \u2014 mirrors --logo-wordmark-gap (--space-2)"},{name:"--email-wordmark-font-weight",value:"700",description:"canonical wordmark size (\u2248 --font-size-xs 12.5px)"},{name:"--email-font-family-sans",value:'"M PLUS 2", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic Medium", YuGothic, "Noto Sans JP", Meiryo, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, Arial, sans-serif',description:'The DXS canonical face is M PLUS 2 (see src/styles/fonts.css). Email clients honour NO * @font-face, so the stack ships the face NAME first and degrades through the platform JP faces * to a generic \u2014 a client with M PLUS 2 installed (or a webmail that already loaded it) renders * the canonical face, everything else lands on Hiragino (macOS/iOS) \u2192 Yu Gothic (Windows) \u2192 * Noto Sans JP \u2192 Meiryo \u2192 the system UI face \u2192 Arial \u2192 sans-serif. Family names are SINGLE-quoted * on export (the generator normalises) because an inline `style="\u2026"` attribute is double-quoted; * only ASCII aliases are listed, since a non-ASCII family name does not survive every transfer * encoding.'},{name:"--email-font-family-mono",value:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",description:"Tabular/reference strings \u2014 invoice ids, masked card numbers, ISO dates, amounts \u2014 are set in * the mono face in the canonical card. Mirrors --font-family-mono."},{name:"--email-body-font-size",value:"14px",description:"Tabular/reference strings \u2014 invoice ids, masked card numbers, ISO dates, amounts \u2014 are set in * the mono face in the canonical card. Mirrors --font-family-mono."},{name:"--email-body-line-height",value:"1.9",description:"1.9, NOT the web --line-height-body (1.7) \u2014 the canonical email card runs its JP body copy * looser than a screen, because a mail client gives the reader no density control."},{name:"--email-body-font-weight",value:"400",description:"1.9, NOT the web --line-height-body (1.7) \u2014 the canonical email card runs its JP body copy * looser than a screen, because a mail client gives the reader no density control."},{name:"--email-heading-font-size",value:"17px",description:"mirrors --font-weight-normal"},{name:"--email-heading-line-height",value:"1.7",description:"canonical card title (\u2248 --heading-h2, base \xD7 \u03C6^\xBC\xB2 \u2248 17.6px)"},{name:"--email-heading-font-weight",value:"500",description:"the title shares the card's body leading, not a tight ramp"},{name:"--email-cta-height",value:"36px",description:"\u2500\u2500 Primary CTA \u2014 the one action button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-cta-line-height",value:"36px",description:"mirrors --control-height-lg (2.25rem) \u2014 the canonical CTA box"},{name:"--email-cta-padding-x",value:"16px",description:"equal to the height: bulletproof vertical centring in Outlook"},{name:"--email-cta-radius",value:"6px",description:"mirrors --space-4"},{name:"--email-cta-font-size",value:"14px",description:"mirrors the --radius base (0.375rem)"},{name:"--email-cta-font-weight",value:"500",description:"mirrors --font-size-base"},{name:"--email-footer-font-size",value:"11px",description:"\u2500\u2500 Legal footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-footer-line-height",value:"1.8",description:"mirrors --font-size-2xs (base \xF7 \u03C6^\xBC\xB2 \u2248 11.1px)"},{name:"--email-footer-link-gap",value:"12px",description:"the legal band runs looser than the web --line-height-normal"},{name:"--email-footer-padding-top",value:"20px",description:"horizontal separation between footer links (--space-3)"},{name:"--email-footer-border-width",value:"1px",description:"space above the legal band"},{name:"--email-focus-border-width",value:"2px",description:"\u2500\u2500 Focus affordance (webmail preview panes that DO honour :focus) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-mobile-max-width",value:"520px",description:"\u2500\u2500 Mobile reflow \u2014 applied under the narrow media query and by inline fallbacks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--email-mobile-width",value:"100%",description:"the reflow breakpoint (card width + both gutters)"},{name:"--email-mobile-padding",value:"20px",description:"the card goes fluid below the breakpoint"},{name:"--email-mobile-page-padding",value:"12px",description:"reduced card inset \u2014 mirrors --space-5"},{name:"--email-mobile-heading-font-size",value:"16px",description:"One step below the 17px desktop title. The canonical 390px reference raster is unusable (it is * 435px wide and already clips the card \u2014 dxs-platform/platform#496), so this is the library's * documented contract rather than a measured canonical value."},{name:"--email-mobile-cta-width",value:"100%",description:"One step below the 17px desktop title. The canonical 390px reference raster is unusable (it is * 435px wide and already clips the card \u2014 dxs-platform/platform#496), so this is the library's * documented contract rather than a measured canonical value."},{name:"--error-surface-max-width",value:"32rem",description:"Measure of the surface block. Caps the status code + body + metadata column so a long ja/vi * headline wraps at a readable width in BOTH shells, including the application shell where * PageContainer is much wider than the copy wants to be."},{name:"--error-surface-gap",value:"var(--space-3)",description:"Rhythm between the status code, the EmptyState body, the metadata list and the progress meter."},{name:"--error-surface-padding-block",value:"var(--space-10)",description:"Block padding of the surface inside the shell it is placed in. Desktop (1440/1024) default; the * 390 step steps it down so a phone loses no vertical space (see styles/shell-layout.css)."},{name:"--error-surface-padding-block-compact",value:"var(--space-6)",description:"Block padding of the surface inside the shell it is placed in. Desktop (1440/1024) default; the * 390 step steps it down so a phone loses no vertical space (see styles/shell-layout.css)."},{name:"--error-surface-brand-gap",value:"var(--space-2)",description:"Brand slot (a Logo) above the status code, system mode only."},{name:"--error-surface-meta-gap",value:"var(--space-1)",description:"Metadata description list: row rhythm and the label\u2194value gap inside one row."},{name:"--error-surface-meta-row-gap",value:"var(--space-2)",description:"Metadata description list: row rhythm and the label\u2194value gap inside one row."},{name:"--error-surface-meta-border",value:"none",description:"Chrome, default quiet (#44). A service opts in with * `--error-surface-meta-border: 1px solid hsl(var(--border));`."},{name:"--error-surface-meta-padding-block",value:"0",description:"Chrome, default quiet (#44). A service opts in with * `--error-surface-meta-border: 1px solid hsl(var(--border));`."},{name:"--error-surface-progress-max-width",value:"18rem",description:"Width of the maintenance progress meter \u2014 narrower than the measure, so it reads as metadata * rather than as the primary content of the page."},{name:"--sheet-width-default",value:"22.5rem",description:"Feedback primitive tokens: dialog, alert, empty state."},{name:"--sheet-overlay-background",value:"initial",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--sheet-overlay-alpha",value:"40%",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-width-default",value:"32rem",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-viewport-inset",value:"1.5rem",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-overlay-background",value:"initial",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-overlay-alpha",value:"60%",description:"Overlay scrims \u2014 `initial` so the shared semantic --overlay-background re-resolves at the CALL * SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a * scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather * than a private literal, so a service retints every backdrop with one --overlay-background while * the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a * modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog)."},{name:"--dialog-space-x",value:"var(--space-chrome-x)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-y",value:"var(--space-chrome-y)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-inset",value:"var(--dialog-space-y) var(--dialog-space-x)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-space-gap",value:"var(--space-stack-md)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--dialog-close-space-offset",value:"var(--space-4)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-space-inset",value:"var(--space-section-active)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-space-gap",value:"var(--space-inline-md)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-inner-space-gap",value:"var(--space-stack-sm)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-dismiss-space-offset",value:"var(--space-3)",description:"Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the * whole system, or --dialog-space-x/-y for dialogs only)."},{name:"--alert-bg-alpha",value:"0.05",description:"Soft (subtle) semantic tint ratios \u2014 themeable so a service can hit its exact spec * (a brand's success-bg/-border are often more present than the faint 5%/30% default)."},{name:"--alert-border-alpha",value:"0.3",description:"Soft (subtle) semantic tint ratios \u2014 themeable so a service can hit its exact spec * (a brand's success-bg/-border are often more present than the faint 5%/30% default)."},{name:"--banner-radius",value:"0",description:"BANNER \u2014 the page-level Alert treatment (gh#255). Every constant a service would want to * match to its page grid is a knob (rule #45): a banner that must keep the app's rounded card * language sets --banner-radius, one that rules its top edge too sets --banner-border-width. * The inline inset tracks the live page gutter, so a banner mounted above a PageContainer lines * its text up with the page title instead of sitting at a second, unrelated margin."},{name:"--banner-border-width",value:"0",description:"BANNER \u2014 the page-level Alert treatment (gh#255). Every constant a service would want to * match to its page grid is a knob (rule #45): a banner that must keep the app's rounded card * language sets --banner-radius, one that rules its top edge too sets --banner-border-width. * The inline inset tracks the live page gutter, so a banner mounted above a PageContainer lines * its text up with the page title instead of sitting at a second, unrelated margin."},{name:"--banner-border-block-end-width",value:"1px",description:"BANNER \u2014 the page-level Alert treatment (gh#255). Every constant a service would want to * match to its page grid is a knob (rule #45): a banner that must keep the app's rounded card * language sets --banner-radius, one that rules its top edge too sets --banner-border-width. * The inline inset tracks the live page gutter, so a banner mounted above a PageContainer lines * its text up with the page title instead of sitting at a second, unrelated margin."},{name:"--banner-space-block",value:"var(--space-3)",description:"BANNER \u2014 the page-level Alert treatment (gh#255). Every constant a service would want to * match to its page grid is a knob (rule #45): a banner that must keep the app's rounded card * language sets --banner-radius, one that rules its top edge too sets --banner-border-width. * The inline inset tracks the live page gutter, so a banner mounted above a PageContainer lines * its text up with the page title instead of sitting at a second, unrelated margin."},{name:"--banner-space-inline",value:"var(--space-page-active-x)",description:"Inline inset tracks the page gutter so a banner's text lines up with the page title. * `--space-page-active-x` steps down to the compact gutter on `.ui-page-container` only, and * custom properties inherit \u2014 so a banner rendered INSIDE the container picks the compact value * up for free, while the normal case (a banner mounted ABOVE the container, or in AppShell) would * keep the desktop gutter and sit 8px out at 390px. The compact step below is what actually keeps * the two aligned; retune it rather than hard-coding a mobile inset at the call site."},{name:"--banner-space-inline-compact",value:"var(--space-page-compact-x)",description:"Inline inset tracks the page gutter so a banner's text lines up with the page title. * `--space-page-active-x` steps down to the compact gutter on `.ui-page-container` only, and * custom properties inherit \u2014 so a banner rendered INSIDE the container picks the compact value * up for free, while the normal case (a banner mounted ABOVE the container, or in AppShell) would * keep the desktop gutter and sit 8px out at 390px. The compact step below is what actually keeps * the two aligned; retune it rather than hard-coding a mobile inset at the call site."},{name:"--banner-dismiss-space-offset",value:"var(--space-2)",description:"Dismiss offset is measured from the banner's own (shorter) block inset, so the \u2715 stays * optically centred on a one-line strip instead of floating at the inline-alert offset."},{name:"--dialog-content-glow",value:"0 0 0 0 transparent",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-space-y",value:"var(--space-10)",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-space-x",value:"var(--space-6)",description:"Brand glow layer for the raised dialog/sheet panel \u2014 invisible no-op at rest (rule #44). * Paired AFTER --shadow-lg in the surface box-shadow so a service can wash the overlay with the * global glow, e.g. --dialog-content-glow: var(--shadow-glow), with no markup change."},{name:"--empty-state-description-max-width",value:"28rem",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-section-space-y",value:"var(--space-6)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-section-space-x",value:"var(--space-4)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-compact-space-y",value:"var(--space-3)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-compact-space-x",value:"var(--space-2)",description:"Measure of the description paragraph (rule #45 \u2014 a service-tunable constant gets a knob). * 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer * measure for its own copy retunes this once instead of forking `.ui-empty-state-description`."},{name:"--empty-state-icon-foreground",value:"initial",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--empty-state-icon-tint",value:"initial",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-row-gap",value:"var(--space-stack-sm)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-cell-gap",value:"var(--space-inline-lg)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-card-inset",value:"var(--space-section-active)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-radius",value:"var(--radius)",description:"EmptyState icon medallion colour \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground) * or washes the medallion fill (--empty-state-icon-tint) without forking. * Defaults = hsl(var(--muted-foreground)) glyph \xB7 hsl(var(--muted)) fill."},{name:"--skeleton-background",value:"initial",description:"Skeleton placeholder fill \u2014 `initial` so the --muted default re-resolves at the call site under * a scoped theme (a :root binding to a role var freezes at :root). A service tints the shimmer to * its surface (rule #44) without forking the keyframes. Default = hsl(var(--muted))."},{name:"--form-label-width",value:"max-content",description:"Width of the label column in horizontal/inline layout. A service theme sets * this once (e.g. 110px) to align every form to its design grid; the Form/ * FormField `labelWidth` prop overrides per form/field."},{name:"--form-label-gap",value:"var(--space-4)",description:"Column gap between the label and its control in horizontal/inline layout."},{name:"--legal-document-measure-max-width",value:"46rem",description:"Readable document measure. Caps the header, the section column and the footer so * a 1440px viewport still reads at ~75-90 characters per line."},{name:"--legal-document-column-gap",value:"var(--space-10)",description:"Rail \u2194 document column gutter (two-column mode only)."},{name:"--legal-document-toc-width",value:"15rem",description:"Sticky table-of-contents rail width (two-column mode only)."},{name:"--legal-document-toc-inset-block-start",value:"var(--space-6)",description:"Distance the pinned rail keeps from the top of the scrollport."},{name:"--legal-document-toc-max-height",value:"calc(100dvh - var(--space-12))",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-gap",value:"var(--space-1)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-item-padding",value:"var(--space-1) var(--space-2)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-item-radius",value:"var(--radius)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-title-font-size",value:"var(--font-size-2xs)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-font-size",value:"var(--font-size-xs)",description:"Cap for a long contents list so the rail never outgrows the viewport."},{name:"--legal-document-toc-marker-width",value:"2px",description:"Leading marker on the active contents entry \u2014 a non-colour affordance so the * active state is never colour-only (WCAG 1.4.1)."},{name:"--legal-document-nav-gap",value:"var(--space-4)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-header-gap",value:"var(--space-2)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-meta-gap",value:"var(--space-2)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-meta-font-size",value:"var(--font-size-xs)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-section-gap",value:"var(--space-10)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-section-title-gap",value:"var(--space-3)",description:"Gap between the `documentNavigation` slot and the contents list inside the rail."},{name:"--legal-document-body-line-height",value:"1.8",description:"Long-form leading \u2014 legal prose reads looser than UI text."},{name:"--legal-document-scroll-offset",value:"var(--space-6)",description:"`scroll-margin-block-start` on every section: the offset a hash jump / anchor * activation leaves above the heading so it is not hidden under sticky chrome."},{name:"--legal-document-footer-gap",value:"var(--space-4)",description:"`scroll-margin-block-start` on every section: the offset a hash jump / anchor * activation leaves above the heading so it is not hidden under sticky chrome."},{name:"--legal-document-toc-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-header-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-footer-border",value:"none",description:"\u2500\u2500 Chrome \u2014 quiet by default (rule #44) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-meta-foreground",value:"initial",description:"\u2500\u2500 Role-mirror knobs \u2014 `initial` here, role default at the call site \u2500\u2500\u2500\u2500\u2500\u2500\u2500"},{name:"--legal-document-summary-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-active-foreground",value:"initial",description:"default = hsl(var(--muted-foreground))"},{name:"--legal-document-toc-active-background",value:"initial",description:"default = hsl(var(--foreground))"},{name:"--legal-document-toc-marker-color",value:"initial",description:"default = hsl(var(--accent))"},{name:"--list-row-padding-y",value:"var(--space-3)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-padding-x",value:"var(--space-4)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-gap",value:"var(--space-3)",description:"ListRow component tokens \u2014 a single-line entity row for short lists inside a Card * (sessions / API tokens / linked accounts / passkeys / notifications \u2026). Sits in a flush * CardContent; rows separate with a quiet divider (#44 \u2014 chrome defaults to the calm * semantic border)."},{name:"--list-row-border",value:"initial",description:"Row divider \u2014 `initial` so the --border default re-resolves at the call site under a scoped * theme (a :root binding to a role var freezes at :root). Default = 1px solid hsl(var(--border))."},{name:"--list-row-body-min-width",value:"12rem",description:"Inline size the content column keeps before the trailing actions wrap onto their own line * (#45 \u2014 a service retunes the stack threshold to its grid). Clamped with min(\u2026, 100%) at the * call site, so a container narrower than the knob can never force page-root overflow (#224)."},{name:"--list-row-trailing-gap",value:"var(--space-2)",description:"Gap BETWEEN trailing actions \u2014 they also wrap among themselves at narrow widths (#224)."},{name:"--list-row-compact-padding-y",value:"initial",description:'\u2500\u2500 Compact inline-actions geometry (`density="compact"`, #246) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The canonical invitation / history row: a 36px leading avatar, a shrinkable title + * description body and one or two small trailing Buttons, all on ONE line inside the canonical * 358px card (326px content after the row\'s own inline inset) at a 390px viewport. These knobs * only LOWER the geometry \u2014 the #224 wrap contract (row + trailing cluster wrap, body clamped * with min(\u2026, 100%)) is untouched, so a cluster that genuinely cannot fit still wraps instead of * widening the page root. * Declared `initial` so the spacing defaults re-resolve at the CALL SITE \u2014 --space-2 is * density-scaled and re-declared inside a `.ui-density-*` subtree, so a :root binding would * freeze compact rows at the :root density (docs/TOKENS.md \u2014 the :root freeze rule). * Defaults = var(--space-2) block padding \xB7 var(--list-row-padding-x) inline padding \xB7 * var(--space-2) gap.'},{name:"--list-row-compact-padding-x",value:"initial",description:"Inline inset defaults to the default row axis so compact and default rows in the same Card keep * one optical axis; a service retunes it to its own grid (#45)."},{name:"--list-row-compact-gap",value:"initial",description:"Inline inset defaults to the default row axis so compact and default rows in the same Card keep * one optical axis; a service retunes it to its own grid (#45)."},{name:"--list-row-compact-body-min-width",value:"6rem",description:"Compact body threshold \u2014 small enough that avatar + body + two compact Buttons fit the * canonical column (36 + 8 + 96 + 8 + 146 = 294 \u2264 326), and still a readable measure."},{name:"--list-row-read-background",value:"initial",description:"Read (default) row surface \u2014 `initial`, documented default = transparent, i.e. the Card * surface shows through untouched (#44 \u2014 chrome defaults to the quietest state)."},{name:"--list-row-unread-background",value:"initial",description:"Unread emphasis surface (`unread` rows) \u2014 `initial` so the --muted default re-resolves at the * call site under a scoped theme. Documented default = hsl(var(--muted)), the same quiet * emphasis role the table header uses; it keeps the xs muted description line at WCAG AA * (4.63:1 light / 5.47:1 dark), which hsl(var(--accent)) would not (4.23:1 light)."},{name:"--list-row-indicator-color",value:"initial",description:"Unread indicator dot fill \u2014 `initial` so the --primary default re-resolves at the call site * under a scoped theme. Documented default = hsl(var(--primary))."},{name:"--list-row-indicator-size",value:"var(--space-2)",description:"Diameter of the read/unread indicator dot; the gutter is reserved on read rows too so the * titles of a mixed list stay on one optical axis."},{name:"--logo-radius",value:"var(--radius)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-xs",value:"1.25rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-sm",value:"1.5rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-md",value:"1.75rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-size-lg",value:"2.25rem",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-xs",value:"var(--font-size-2xs)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-sm",value:"var(--font-size-xs)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-md",value:"var(--font-size-sm)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-font-size-lg",value:"var(--font-size-base)",description:"Logo component tokens \u2014 the product brand-mark box (a glyph on the primary fill), used in the * app shell header, auth screens, and topbars. Size + radius + per-tier font-size are knobs so a * service theme retunes the mark without forking CSS (rules #44/#45). Colours read the primary * role tokens directly, so a re-themed --primary re-tints the mark automatically."},{name:"--logo-success-background",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-success-foreground",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-godx-color",value:"initial",description:'Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed * action colour never recolours the mark) AND of --success (the \u82E5\u7AF9 STATUS green stays on * badges/progress/"saved" text \u2014 the mark used to borrow it and rendered \u0394E76 \u2248 17.5 off the * canonical emerald, gh#250). Services retune the role once for every Logo. * ROLE-MIRROR KNOBS \u2014 declared `initial` here with the role default at the CALL SITE * (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually * reaches the mark instead of freezing at the :root value (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented defaults: * --logo-success-background = hsl(var(--brand)) * --logo-success-foreground = hsl(var(--logo-identity-foreground)) * --logo-godx-color = hsl(var(--brand))'},{name:"--logo-identity-foreground",value:"48 9% 9%",description:'Identity-fill INK \u2014 the ink `mark="glyph"` sets its (caller-supplied) TEXT in when it sits on * the --brand identity fill. This is deliberately NOT --brand-foreground. * * --brand-foreground is the identity artwork\'s KNOCKOUT colour, not an ink: it tracks * --background in both themes (light 60 33% 99% = --background; dark 48 9% 9% = --background) * because `<Logo mark="godx">` punches its inner bar as an evenodd HOLE and the email mark has to * paint that hole as a solid fill to match. Negative space only has to clear WCAG 2.2 SC 1.4.11 * (3:1, non-text) \u2014 and at 3.67:1 on the emerald it does. * * The boxed glyph is a different thing: it renders real TEXT, so SC 1.4.3 applies at 4.5:1 (14px * bold is NOT "large text" \u2014 that needs 18.66px bold / 24px), and the knockout white measured * 3.67:1 \u2192 a genuine AA failure. This ink is 48 9% 9% (#191815), the same near-black spine the * DARK theme already inked the glyph with, so it is theme-INVARIANT: dark renders byte-identically * (6.89:1, unchanged) and light rises 3.67 \u2192 4.74:1. A service that re-themes --brand to a dark * fill overrides --logo-success-foreground (the public knob) to re-invert the ink. * * NOT a role-mirror knob: its default is a real value, not a role token, so there is no role to * freeze at :root and the `initial` + call-site rule (docs/TOKENS.md) does not apply to it.'},{name:"--logo-godx-size-xs",value:"1.5rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-sm",value:"1.75rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-md",value:"2rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size-lg",value:"2.5rem",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-godx-size",value:"initial",description:'\u2500\u2500 Identity-mark box (`<Logo mark="godx" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The `size` prop drives the identity mark exactly like it drives the boxed glyph \u2014 a public * prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already * scaled its wordmark per tier, so a fixed mark broke the mark\u2194wordmark proportion at * `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square * viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits * +0.25rem above its --logo-size-* sibling. `md` is 2rem \u2014 the historical fixed value \u2014 so * every existing default-size identity surface renders byte-identically. * * --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier * default at the CALL SITE (logo-layout.css), so it is inert by default and a service that * sets it once freezes the mark at that box on EVERY tier \u2014 the same call-site pattern the * role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*. * Documented default: --logo-godx-size = unset (tiers apply).'},{name:"--logo-wordmark-gap",value:"var(--space-2)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-xs",value:"var(--font-size-xs)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-sm",value:"var(--font-size-sm)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-md",value:"var(--font-size-base)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-size-lg",value:"var(--font-size-lg)",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-weight",value:"700",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-letter-spacing",value:"-0.01em",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-font-family",value:"initial",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--logo-wordmark-color",value:"initial",description:'\u2500\u2500 Wordmark / lockup (`<Logo wordmark="GoDX" />`) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 * The readable product name set beside the mark. The package ships NO wordmark artwork: the * wordmark is typeset in the design-system display face, so a service retunes face, weight, * tracking, size and the mark\u2194wordmark gap here instead of writing page CSS. The colour is a * role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the * --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and * every other lockup reads --foreground. * Documented defaults: --logo-wordmark-font-family = var(--font-family-display); * --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the * godx / tone="success" lockup.'},{name:"--pagination-gap",value:"var(--space-inline-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-item-gap",value:"var(--space-inline-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-size-width",value:"5.5rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--pagination-total-font-size",value:"var(--font-size-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-bar-gap",value:"var(--space-3)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-bar-padding-y",value:"var(--space-2)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-label-font-size",value:"var(--font-size-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-picker-width-sm",value:"11rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--filter-picker-width-md",value:"14rem",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-gap",value:"var(--space-2)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-item-gap",value:"var(--space-1)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-font-size",value:"var(--font-size-xs)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--steps-inline-separator-size",value:"var(--control-icon-size-sm)",description:"Navigation primitive tokens: pagination, filters, compact pickers."},{name:"--app-setting-picker-compact-control-height",value:"var(--control-height-sm)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-padding-x",value:"var(--space-2)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-gap",value:"var(--space-1)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--app-setting-picker-compact-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--breadcrumb-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--menubar-shortcut-font-size",value:"var(--font-size-xs)",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-list-max-inline-size",value:"100%",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-list-overflow",value:"auto",description:"AppSettingPicker `compact` (gh#217) \u2014 the small, content-hugging labelled trigger used in an * auth/legal footer, where the square icon-only default reads as a stray button and the full * labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never * a literal / ad-hoc calc), and every other knob is themeable (rule #45)."},{name:"--tabs-indicator-background",value:"initial",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--tabs-indicator-size",value:"2px",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--tabs-indicator-offset",value:"0px",description:"Tabs `line` active indicator (gh#248) \u2014 the ONLY selected-state decoration the line variant * paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible` * keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a * role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped * [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root). * Default = hsl(var(--primary)) \xB7 2px thick \xB7 flush with the trigger edge (offset 0 = quietest, * rule #44); a service raises the offset to park the bar on a thicker strip hairline."},{name:"--menubar-item-hover-background",value:"initial",description:"Menu item hover/highlight tint \u2014 `initial` so the --accent default re-resolves at the call site * under a scoped theme (a :root binding to a role var freezes at :root). * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--accent-foreground)) text."},{name:"--menubar-item-hover-foreground",value:"initial",description:"Menu item hover/highlight tint \u2014 `initial` so the --accent default re-resolves at the call site * under a scoped theme (a :root binding to a role var freezes at :root). * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--accent-foreground)) text."},{name:"--filter-bar-sticky-offset",value:"0px",description:"Sticky offset for the pinned filter strip (Toolbar `sticky`, #197). Default 0 (chrome, * rule #44); raise it so the strip parks below a fixed topbar."},{name:"--filter-bar-sticky-background",value:"initial",description:"Fill painted only when the filter strip is pinned. Role-mirror knob (rule #45): `initial` * so --background re-resolves at the call site under a scoped [data-tenant]/.dark theme."},{name:"--filter-bar-scroll-padding-y",value:"var(--space-1)",description:'Scrollbar gutter reserved under a `overflow="scroll"` filter strip (#216) so the inline * scrollbar never overlaps the controls. Rule #45 \u2014 a service theme retunes it to its grid * (0 on an overlay-scrollbar platform).'},{name:"--filter-bar-search-width",value:"18rem",description:"FilterBar typed model (#258) \u2014 the search / chip / result-count regions the bar now OWNS, so a * list page never re-decides them. Every constant is a knob (rule #45): a service matches its own * grid by retuning these once instead of per page. * * Search MEASURE \u2014 the whole point of the `search` slot. Below the 640px step the control is * full-width (a bounded search box on a 390px screen wastes the row), so this binds only at and * above it. 18rem = 288px: comfortable for a JA/VI query without crowding the filter groups."},{name:"--filter-bar-chip-gap",value:"var(--space-inline-xs)",description:"Applied-filter chips."},{name:"--filter-bar-chip-row-gap",value:"var(--space-inline-xs)",description:"Applied-filter chips."},{name:"--filter-bar-chip-padding-inline",value:"var(--space-2)",description:"Applied-filter chips."},{name:"--filter-bar-chip-padding-block",value:"var(--space-1)",description:"Applied-filter chips."},{name:"--filter-bar-chip-radius",value:"var(--radius-sm)",description:"Applied-filter chips."},{name:"--filter-bar-chip-font-size",value:"var(--font-size-xs)",description:"Applied-filter chips."},{name:"--filter-bar-chip-background",value:"initial",description:"Role-mirror knobs (docs/TOKENS.md) \u2014 `initial` at :root so --muted / --muted-foreground * re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme. Binding a role var here * would freeze the chip at the :root palette and a tenant override would never reach it."},{name:"--filter-bar-chip-foreground",value:"initial",description:"Role-mirror knobs (docs/TOKENS.md) \u2014 `initial` at :root so --muted / --muted-foreground * re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme. Binding a role var here * would freeze the chip at the :root palette and a tenant override would never reach it."},{name:"--filter-bar-count-font-size",value:"var(--font-size-xs)",description:"Result-count live region."},{name:"--filter-bar-count-foreground",value:"initial",description:"Result-count live region."},{name:"--sheet-responsive-breakpoint-width",value:"48rem",description:'Viewport width at and below which `SheetContent responsive="auto"` renders the mobile bottom * sheet instead of the desktop side panel. Read at runtime by useSheetResponsiveMode() (a CSS * @media cannot resolve a custom property), so a service moves the drawer breakpoint from ONE * knob for every overlay that opts into the responsive contract \u2014 Sheet and OrgSwitcher alike. * 48rem = 768px mirrors the library\'s canonical mobile line (useIsMobile). Accepts px/rem/em.'},{name:"--sheet-bottom-max-height",value:"85dvh",description:'Block size cap for the responsive BOTTOM presentation only (never for a plain * `side="bottom"` sheet, which stays content-sized). Keeps the sheet below the viewport so the * SheetBody scrolls and the page behind it stays visible/dismissable.'},{name:"--sidebar-section-label-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-product-tenant-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-badge-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-user-role-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--org-switcher-meta-foreground",value:"var(--muted-foreground)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-nav-sub-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-flyout-title-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--topbar-chip-icon-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--kbd-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-logo-mark-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-avatar-font-size",value:"var(--font-size-2xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-user-name-font-size",value:"var(--font-size-xs)",description:"Shell (sidebar / topbar / kbd) component tokens \u2014 small-by-design text * knobs (rule #45/#46). A service re-tunes chrome text without moving the * global scale."},{name:"--sidebar-gradient",value:"none",description:"Brand-chrome gradient hooks \u2014 opt-in, invisible by default. A service paints * the sidebar/topbar surface by setting these to a gradient (no-op = none)."},{name:"--topbar-gradient",value:"none",description:"Brand-chrome gradient hooks \u2014 opt-in, invisible by default. A service paints * the sidebar/topbar surface by setting these to a gradient (no-op = none)."},{name:"--app-shell-bar-height",value:"3rem",description:"DXS application-shell geometry. These defaults mirror the checked-in * Admin/Console hi-fi source while remaining themeable by consumers."},{name:"--app-shell-bar-inset",value:"var(--space-4)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-bar-inset-compact",value:"var(--space-3)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-bar-gap",value:"var(--space-3)",description:"Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell * breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge)."},{name:"--app-shell-sidebar-width",value:"16rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-rail-width",value:"4rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-page-max-width",value:"80rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-main-background",value:"hsl(var(--muted) / 0.4)",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-mobile-nav-width",value:"22.5rem",description:"Docked navigation rail widths \u2014 the SINGLE most-retuned shell constant (rule #45). A service * that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once * instead of forking `.app-root`. `-rail-` is the icon-only width used at * `<AppShell sidebarCollapsed>`."},{name:"--app-shell-mobile-nav-background",value:"initial",description:"Mobile-drawer scrim \u2014 `initial` so the shared --overlay-background default re-resolves at the * CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding freezes at :root). Default = * var(--app-shell-mobile-nav-alpha) of the global scrim, i.e. rgb(0 0 0 / 0.2) out of the box."},{name:"--app-shell-mobile-nav-alpha",value:"40%",description:"Share of the global --overlay-background this drawer's scrim uses. A slide-in drawer washes the * page more lightly than a modal dialog; keeping it a RATIO means a service retints the whole * system with one --overlay-background and every overlay keeps its calibrated depth."},{name:"--app-shell-mobile-nav-inset",value:"var(--space-1)",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-brand-mark-size",value:"1.375rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-height",value:"2rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-font-size",value:"0.8125rem",description:"Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav * (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the * generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for * a custom mobileNav node that wants the full sheet chrome inset."},{name:"--sidebar-nav-item-line-height",value:"1.5",description:"Line box of the nav LABEL, not the row (gh#254): `.sb-label` clips, so its line box is its clip * box, and the row's `line-height: 1` shears descenders and Vietnamese tone marks. Keep >= 1.2."},{name:"--auth-account-summary-email-line-height",value:"1.5",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-start-truncate-line-height",value:"1.5",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-icon-size",value:"1rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-item-gap",value:"0.625rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-item-padding-x",value:"0.625rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-gap",value:"2px",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-nav-scroll-padding",value:"var(--space-3) var(--space-2)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-gap",value:"var(--space-4)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-label-padding-x",value:"var(--space-2)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--sidebar-section-label-padding-bottom",value:"var(--space-1)",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-search-max-width",value:"26.25rem",description:"Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last * child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`), * so their line box IS their clip box \u2014 inheriting a tight value shears descenders and Vietnamese * tone marks exactly as the sidebar label did. Keep >= 1.2."},{name:"--topbar-height",value:"auto",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-inset",value:"0px",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-gap",value:"var(--space-2)",description:"Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally * QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs * existed \u2014 inside AppShell the `.app-topbar` grid row still owns the height. A service that * places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)` * once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end * clusters and INSIDE each of them, so one knob re-rhythms the whole bar."},{name:"--topbar-center-compact-display",value:"none",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-trigger-height",value:"2.75rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-trigger-padding-x",value:"var(--space-2)",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-avatar-size",value:"1.75rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-menu-width",value:"16rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-sheet-max-height",value:"75dvh",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--org-switcher-state-min-height",value:"8rem",description:"At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters. The package hides the optional center slot before it can cover * the breadcrumb/title or end utilities. Consumers may opt back into another display strategy * (for example `flex`) once their center content has its own compact presentation."},{name:"--sidebar-item-active-color",value:"initial",description:"Sidebar active-item tint/marker \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override * never reaches it). A service re-tunes the active sub-item accent without forking CSS. * Defaults = hsl(var(--primary)) marker/tint."},{name:"--sidebar-item-active-tint",value:"initial",description:"Sidebar active-item tint/marker \u2014 `initial` so the role defaults re-resolve at the call site * under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override * never reaches it). A service re-tunes the active sub-item accent without forking CSS. * Defaults = hsl(var(--primary)) marker/tint."},{name:"--sidebar-item-active-background",value:"initial",description:"Main nav-item active row \u2014 defaults mirror the hover state (accent bg, foreground text); a * service overrides these to brand the selected row (e.g. a gold tint + gold text on a navy * sidebar). `initial` so the defaults re-resolve under a scoped theme. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--foreground)) text."},{name:"--sidebar-item-active-foreground",value:"initial",description:"Main nav-item active row \u2014 defaults mirror the hover state (accent bg, foreground text); a * service overrides these to brand the selected row (e.g. a gold tint + gold text on a navy * sidebar). `initial` so the defaults re-resolve under a scoped theme. * Defaults = hsl(var(--accent)) fill \xB7 hsl(var(--foreground)) text."},{name:"--auth-shell-control-height",value:"var(--control-height-comfortable)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-heading-size",value:"var(--font-size-2xl)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-card-max-width",value:"24rem",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-bar-padding",value:"var(--space-5) var(--space-6)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-main-padding",value:"var(--space-6)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-footer-padding",value:"var(--space-3) var(--space-6) var(--space-4)",description:"AuthShell \u2014 centred auth/login page shell. Comfortable control density (44px, WCAG touch floor) * + a larger auth heading, scoped to the shell; a service re-tunes the auth card width, insets * and heading size without forking."},{name:"--auth-shell-canonical-control-height",value:"2.25rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-card-max-width",value:"22.5rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-heading-size",value:"var(--font-size-base)",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-main-padding",value:"1rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-canonical-main-padding-mobile",value:"0.9375rem",description:"Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on * AuthShell and may retune the product theme here rather than overriding individual fields."},{name:"--auth-shell-compact-card-inset",value:"var(--space-6)",description:"INLINE (start/end) inset of the compact auth card \u2014 the column the title, fields and actions * align to. Independent of the block axis below (gh#232)."},{name:"--auth-shell-card-padding-block-compact",value:"initial",description:"BLOCK (top/bottom) padding of the compact auth card \u2014 the knob that tunes canonical Login card * HEIGHT without narrowing the column. Bound to the card's --card-space-shell-y, so it really * reaches CardContent's block edges (before gh#232 it was wired only to --card-space-body-y and * the rendered body kept the inset on both block edges \u2014 the documented token did nothing). * Declared `initial` so the default mirrors the LIVE --auth-shell-compact-card-inset resolved at * the CALL SITE: the canonical card renders exactly as before (24px block = 24px inline), and a * service that re-tunes the inset inside a scoped `[data-tenant]` still drags the block default * with it (a :root binding would freeze at the :root inset \u2014 docs/TOKENS.md)."},{name:"--auth-shell-card-body-gap-compact",value:"var(--space-3)",description:"Header\u2194body gap inside the compact auth card (the breathing room under the title before the * first field). Its own knob since gh#232 \u2014 it used to ride on * --auth-shell-card-padding-block-compact, which conflated the section gap with the card's block * padding and made the block knob un-tunable. Default is the pre-gh#232 12px rhythm."},{name:"--auth-shell-card-gap-compact",value:"var(--space-3)",description:"IN-SLOT stack gap of the compact auth card (title \u2195 description inside the header)."},{name:"--auth-shell-main-align",value:"center",description:"Main-axis alignment of the auth column. Default `center` = today's vertically-centred card; * a flow whose intro + card + footnote stack is tall opts into `start` via this knob."},{name:"--auth-shell-card-stack-gap",value:"0px",description:"Gap between the direct sections of the auth column (intro \xB7 card \xB7 remember row). Default 0 * (quiet, rule #44) so an existing single-card consumer is untouched; presets opt in."},{name:"--auth-shell-login-card-max-width",value:"22.5rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-flow-offset-block",value:"14.4375rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-flow-offset-block-mobile",value:"13.8125rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-inline",value:"1rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-inline-mobile",value:"0.9375rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-main-padding-block-end",value:"1rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-identity-slot-block-size",value:"7rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-card-stack-gap",value:"1.25rem",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-login-card-padding-block-compact",value:"calc( var(--auth-shell-compact-card-inset) + var(--control-border-width) + var(--control-border-width) )",description:"Login preset (gh#237) \u2014 canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844. * The 112px identity slot is deliberately taller than a two-line real requester. Identity * content aligns to the slot end, so missing/one-line/two-line requester data changes only the * empty space above it, never the card or footer position. The flow starts at y=231 desktop and * y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here, * not in a consumer selector, and do not drift with --scaling."},{name:"--auth-shell-device-card-max-width",value:"23.75rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-device-main-padding",value:"1rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-device-main-padding-mobile",value:"0.9375rem 0.3125rem",description:"Device-authorization preset \u2014 380px card measure, 15px block \xB7 5px inline mobile gutter * (at a 390px viewport the card is x=5px, width=380px)."},{name:"--auth-shell-context-card-max-width",value:"25rem",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-main-padding",value:"var(--space-6)",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-main-padding-mobile",value:"var(--space-6) 0",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-context-card-stack-gap",value:"1rem",description:"Context-selection preset \u2014 25rem card measure on desktop/tablet, edge-to-edge on mobile * (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row."},{name:"--auth-shell-recovery-card-max-width",value:"27rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-recovery-main-padding",value:"1rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-recovery-main-padding-mobile",value:"0.9375rem",description:"Account-recovery preset (gh#233) \u2014 the SCR-008 measure shared by the password-recovery panel * (request \xB7 sent \xB7 new-password \xB7 expired) and the sign-in MFA challenge panel (OTP \xB7 * recovery-code \xB7 passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE * preset owns them; the 360px canonical Login measure is untouched. * The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a * desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 \u21D2 the * panel is x=15, width=360 \u2014 the same page rhythm as the canonical Login flow, so a user moving * from Login to Recovery on a phone never sees the surface jump."},{name:"--auth-shell-registration-card-max-width",value:"22.5rem",description:"Registration preset (gh#256) \u2014 the canonical sign-up measure. Two things make it structurally * different from every preset above, and both are the reason it could not be expressed by * re-using `login`: * * 1. LONG-FORM SCROLLING. A registration card is the tallest surface in the hosted-identity set * (name \xB7 email \xB7 password \xB7 confirm \xB7 strength meter \xB7 consent \xB7 submit \xB7 provider row), and * a vertically CENTRED tall card clips its own top on a short viewport \u2014 the top overflows * above the scroll origin and becomes unreachable. So the column is start-aligned and the * block-start inset becomes ordinary page padding the user can scroll past. * 2. FOOTER CLEARANCE. The legal/consent footer must never be flush against the submit button * at the end of a long scroll, so the block-end inset is a knob of its own rather than * mirroring the block-start one. * * The 360px form measure and the 15px mobile inline gutter match the canonical Login flow exactly * (22.5rem card, x=15 at 390 \u21D2 width=360), so a user moving sign-in \u2192 sign-up on a phone never * sees the surface jump."},{name:"--auth-shell-registration-main-padding-block-start",value:"9.5rem",description:"Block-start offsets are DERIVED from the canonical SCR-002 artboard, not chosen: the card * anchors at y=284 (1440x900) and y=274 (390x844), and the column is * card y = padding-block-start + identity slot + stack gap * so 284 - 112 - 20 = 152px (9.5rem) and 274 - 112 - 20 = 142px (8.875rem). Like every canonical * screen in this family the page passes NO brand bar (the mark lives INSIDE the column as * AuthIdentity), so `main` starts at the viewport top and the offset is the whole anchor."},{name:"--auth-shell-registration-main-padding-block-start-mobile",value:"8.875rem",description:"Block-start offsets are DERIVED from the canonical SCR-002 artboard, not chosen: the card * anchors at y=284 (1440x900) and y=274 (390x844), and the column is * card y = padding-block-start + identity slot + stack gap * so 284 - 112 - 20 = 152px (9.5rem) and 274 - 112 - 20 = 142px (8.875rem). Like every canonical * screen in this family the page passes NO brand bar (the mark lives INSIDE the column as * AuthIdentity), so `main` starts at the viewport top and the offset is the whole anchor."},{name:"--auth-shell-registration-main-padding-inline",value:"1rem",description:"Block-start offsets are DERIVED from the canonical SCR-002 artboard, not chosen: the card * anchors at y=284 (1440x900) and y=274 (390x844), and the column is * card y = padding-block-start + identity slot + stack gap * so 284 - 112 - 20 = 152px (9.5rem) and 274 - 112 - 20 = 142px (8.875rem). Like every canonical * screen in this family the page passes NO brand bar (the mark lives INSIDE the column as * AuthIdentity), so `main` starts at the viewport top and the offset is the whole anchor."},{name:"--auth-shell-registration-main-padding-inline-mobile",value:"0.9375rem",description:"Block-start offsets are DERIVED from the canonical SCR-002 artboard, not chosen: the card * anchors at y=284 (1440x900) and y=274 (390x844), and the column is * card y = padding-block-start + identity slot + stack gap * so 284 - 112 - 20 = 152px (9.5rem) and 274 - 112 - 20 = 142px (8.875rem). Like every canonical * screen in this family the page passes NO brand bar (the mark lives INSIDE the column as * AuthIdentity), so `main` starts at the viewport top and the offset is the whole anchor."},{name:"--auth-shell-registration-main-padding-block-end",value:"3rem",description:"Footer clearance \u2014 the gap the legal footer keeps below the end of a long form."},{name:"--auth-shell-registration-main-padding-block-end-mobile",value:"2rem",description:"Footer clearance \u2014 the gap the legal footer keeps below the end of a long form."},{name:"--auth-shell-registration-card-stack-gap",value:"1.25rem",description:"Footer clearance \u2014 the gap the legal footer keeps below the end of a long form."},{name:"--auth-shell-registration-identity-slot-block-size",value:"7rem",description:"Fixed identity track, the same 112px `login` proved (gh#237). Without it the card anchor moves * with the title/requester line count \u2014 measured here at 82.69px for one wrapped requester \u2014 so * the canonical y above would hold for exactly one copy length and drift for every other. The * slot absorbs absent / one-line / two-line identity content instead."},{name:"--auth-shell-divider-gap",value:"0.625rem",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-label-font-size",value:"0.6875rem",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-rule-color",value:"var(--border)",description:"Labelled auth divider geometry."},{name:"--auth-shell-divider-label-color",value:"var(--muted-foreground)",description:"Labelled auth divider geometry."},{name:"--auth-identity-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-icon-size",value:"1rem",description:"Labelled auth divider geometry."},{name:"--auth-requester-glyph-size",value:"0.625rem",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-min-height",value:"var(--control-height-comfortable)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-gap",value:"var(--space-2)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-padding",value:"var(--space-1) var(--space-2)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-identity-min-width",value:"12rem",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-avatar-size",value:"var(--control-height-sm)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-avatar-glyph-size",value:"var(--control-icon-size-sm)",description:"Labelled auth divider geometry."},{name:"--auth-account-summary-email-font-size",value:"var(--font-size-sm)",description:"Labelled auth divider geometry."},{name:"--auth-footer-content-gap",value:"0.375rem",description:"Labelled auth divider geometry."},{name:"--auth-footer-text-font-size",value:"0.6875rem",description:"Labelled auth divider geometry."},{name:"--auth-stack-gap",value:"var(--space-3)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-gap",value:"var(--space-1)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-font-size",value:"var(--font-size-xs)",description:"Labelled auth divider geometry."},{name:"--auth-shell-field-label-line-height",value:"1.25",description:"Labelled auth divider geometry."},{name:"--centered-shell-bar-height",value:"var(--app-shell-bar-height)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-bar-padding-x",value:"var(--space-4)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-main-padding",value:"var(--space-6)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-footer-padding",value:"var(--space-3) var(--space-6) var(--space-4)",description:'CenteredShell \u2014 authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page", * account, standalone settings). The bar mirrors AppShell\'s `.app-topbar` chrome (fixed height + * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A * service retunes the bar inset, block padding and each width tier without forking CSS.'},{name:"--centered-shell-column-offset-block",value:"0",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-sm",value:"32rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-md",value:"46rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-width-lg",value:"64rem",description:'Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state \u2014 * rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which * is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503 * error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller * than the viewport, so a long localized message scrolls from the top instead of clipping.'},{name:"--centered-shell-landing-max-width",value:"67.5rem",description:'CenteredShell \xB7 public-landing preset (gh#252) \u2014 the token-owned geometry of a PUBLIC marketing * / product landing page: one content measure shared by header, main column and footer, the * section rhythm between page sections, the flat (chrome-quiet) card presentation and the hero * heading tier. Every value is a service-themeable knob (rule #45): a landing composition is a * COMPOSITION of real primitives (docs/COMPOSITION-VS-COMPONENT.md \u2014 Hero/Navbar/Footer FAIL the * Framework-Component Test), so the consumer must never own geometry or a media query. These * knobs are read ONLY under `.ui-centered-shell[data-preset="public-landing"]`, so the default * shell \u2014 which emits no `data-preset` at all \u2014 is byte-identical to before.'},{name:"--centered-shell-landing-inset-inline",value:"var(--space-6)",description:"1080px \u2014 header/main/footer share ONE measure"},{name:"--centered-shell-landing-inset-inline-compact",value:"var(--space-4)",description:"24px page gutter \u2265 40rem"},{name:"--centered-shell-landing-main-padding-block",value:"var(--space-10)",description:"16px page gutter < 40rem"},{name:"--centered-shell-landing-main-padding-block-compact",value:"var(--space-6)",description:"40px"},{name:"--centered-shell-landing-section-gap",value:"var(--space-10)",description:"24px"},{name:"--centered-shell-landing-section-gap-compact",value:"var(--space-6)",description:"rhythm BETWEEN page sections"},{name:"--centered-shell-landing-footer-padding-block",value:"var(--space-8)",description:"rhythm BETWEEN page sections"},{name:"--centered-shell-landing-card-shadow",value:"none",description:"Chrome is a token, default quiet (rule #44): a landing surface is FLAT \u2014 no card elevation \u2014 * so a service opts back IN with `--centered-shell-landing-card-shadow: var(--card-shadow)`."},{name:"--centered-shell-landing-heading-size",value:"var(--font-size-display)",description:"Hero heading tier. The preset re-points `--heading-h1` (same mechanism as * `.ui-auth-shell` \u2192 `--auth-shell-heading-size`), so a hero title is a real `Heading level={1}` * and never a consumer font-size."},{name:"--centered-shell-landing-heading-size-compact",value:"var(--font-size-3xl)",description:"Hero heading tier. The preset re-points `--heading-h1` (same mechanism as * `.ui-auth-shell` \u2192 `--auth-shell-heading-size`), so a hero title is a real `Heading level={1}` * and never a consumer font-size."},{name:"--centered-shell-landing-background",value:"initial",description:'Role-mirror knob \u2014 MUST stay `initial`, with the role default at the CALL SITE * (`var(--centered-shell-landing-background, var(--background))`), so a scoped * `[data-tenant]` / `.dark` override of `--background` still reaches it (docs/TOKENS.md \xB7 * "Role-mirror knobs MUST be `initial`"). Documented default = hsl(var(--background)) \u2014 a public * page is the plain page canvas, not the app\'s `--muted` chrome.'},{name:"--sidebar-nav-item-foreground",value:"initial",description:"Resting nav row + label (also the resting sub-row). Default = hsl(var(--muted-foreground))."},{name:"--sidebar-nav-item-hover-foreground",value:"initial",description:"Hovered nav row + label. Default = hsl(var(--foreground))."},{name:"--sidebar-nav-item-disabled-foreground",value:"initial",description:"`aria-disabled` nav row + label. Default = the resting row colour."},{name:"--sidebar-nav-icon-foreground",value:"initial",description:"Nav ICON (`.sb-icon`, incl. the collapsed rail and group triggers). Default = currentColor, * i.e. the row colour \u2014 the pre-gh#228 look. Set this alone to get canonical dark icons next to * muted labels."},{name:"--sidebar-nav-icon-hover-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--sidebar-nav-icon-active-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--sidebar-nav-icon-disabled-foreground",value:"initial",description:"Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground, * then to currentColor, so setting the base icon knob alone themes every state."},{name:"--table-row-height-compact",value:"1.75rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height-default",value:"2rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height-comfortable",value:"2.75rem",description:"Table component tokens: row height, cell padding."},{name:"--table-row-height",value:"calc(var(--table-row-height-default) * var(--scaling))",description:"Table component tokens: row height, cell padding."},{name:"--table-cell-padding-y",value:"var(--space-2)",description:"Table component tokens: row height, cell padding."},{name:"--table-cell-space-x",value:"var(--control-padding-x)",description:"Table component tokens: row height, cell padding."},{name:"--table-pagination-padding-y",value:"initial",description:"Pagination footer inset (gh#236). The footer ships as a SELF-CONTAINED slot and is commonly * placed in a flush container (`<Card><CardContent flush><DataTable/>`), where no ancestor * supplies padding \u2014 so it owns its own on BOTH axes instead of declaring block-start only. * Block default = the previous single `padding-top` value, now on both block edges (breathing * room above the footer and before the container's closing border). Inline default = the cell * inline padding, so the \"rows per page\" label sits on the same optical axis as the first * column's text. A service retunes either axis to its own grid (#45). * Both are declared `initial` so the defaults re-resolve at the CALL SITE: --space-stack-sm and * --table-cell-space-x are density-scaled and re-declared inside a `.ui-density-*` subtree, and a * :root binding would freeze the footer at the :root density (docs/TOKENS.md \u2014 the :root freeze * rule). Defaults = var(--space-stack-sm) block \xB7 var(--table-cell-space-x) inline."},{name:"--table-pagination-padding-x",value:"initial",description:"Pagination footer inset (gh#236). The footer ships as a SELF-CONTAINED slot and is commonly * placed in a flush container (`<Card><CardContent flush><DataTable/>`), where no ancestor * supplies padding \u2014 so it owns its own on BOTH axes instead of declaring block-start only. * Block default = the previous single `padding-top` value, now on both block edges (breathing * room above the footer and before the container's closing border). Inline default = the cell * inline padding, so the \"rows per page\" label sits on the same optical axis as the first * column's text. A service retunes either axis to its own grid (#45). * Both are declared `initial` so the defaults re-resolve at the CALL SITE: --space-stack-sm and * --table-cell-space-x are density-scaled and re-declared inside a `.ui-density-*` subtree, and a * :root binding would freeze the footer at the :root density (docs/TOKENS.md \u2014 the :root freeze * rule). Defaults = var(--space-stack-sm) block \xB7 var(--table-cell-space-x) inline."},{name:"--table-surface-min-inline-size",value:"640px",description:'DataTable surface \u2014 narrow-viewport legibility FLOOR (gh#253). Below the `sm` viewport step a * multi-column admin grid whose columns are `white-space: nowrap` would otherwise be crushed, so * the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. * This shipped as a hard-coded `min-w-[640px]` utility on the surface element, which left a * service that wants a narrower (or no) floor with no route but forking the component (#45). * Default = the previous literal, in px so the floor releases at EXACTLY the same width as the * px-based `sm` media query that clears it (a rem value would drift under a non-16px root and * re-introduce the scroll between the two thresholds). Set `0` to opt out entirely \u2014 which is * what `preset="action-collection"` does, because there the priority measures own the width.'},{name:"--table-head-font-size",value:"var(--font-size-xs)",description:'DataTable surface \u2014 narrow-viewport legibility FLOOR (gh#253). Below the `sm` viewport step a * multi-column admin grid whose columns are `white-space: nowrap` would otherwise be crushed, so * the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead. * This shipped as a hard-coded `min-w-[640px]` utility on the surface element, which left a * service that wants a narrower (or no) floor with no route but forking the component (#45). * Default = the previous literal, in px so the floor releases at EXACTLY the same width as the * px-based `sm` media query that clears it (a rem value would drift under a non-16px root and * re-introduce the scroll between the two thresholds). Set `0` to opt out entirely \u2014 which is * what `preset="action-collection"` does, because there the priority measures own the width.'},{name:"--table-header-background",value:"initial",description:"Header band \u2014 its OWN bg + fg knobs (decoupled from --secondary). Declared `initial` so the * default re-resolves to the LIVE --muted / --muted-foreground roles at the call site: a :root * binding to a role var freezes at the :root value and a scoped [data-tenant] role override never * reaches it. A brand sets both header tokens together to keep band/text contrast. * Defaults = hsl(var(--muted)) band \xB7 hsl(var(--muted-foreground)) text."},{name:"--table-header-foreground",value:"initial",description:"Header band \u2014 its OWN bg + fg knobs (decoupled from --secondary). Declared `initial` so the * default re-resolves to the LIVE --muted / --muted-foreground roles at the call site: a :root * binding to a role var freezes at the :root value and a scoped [data-tenant] role override never * reaches it. A brand sets both header tokens together to keep band/text contrast. * Defaults = hsl(var(--muted)) band \xB7 hsl(var(--muted-foreground)) text."},{name:"--table-pin-shadow",value:"-6px 0 6px -5px hsl(var(--foreground) / 0.12)",description:"Inline-end shadow that lifts a pinned (sticky) action column off the body it scrolls over."},{name:"--table-row-striped-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-row-hover-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-row-selected-background",value:"initial",description:"Row-state tint washes \u2014 translucent muted over the opaque base. `initial` so the --muted * default re-resolves under a scoped theme; a service retints by reading another role (e.g. * --primary). Defaults = hsl(var(--muted) / 0.4 striped \xB7 0.5 hover \xB7 0.3 selected)."},{name:"--table-action-collection-primary-width",value:"18%",description:'Table \xB7 action-collection preset (gh#253) \u2014 the canonical dense approval / action queue. * Column PRIORITY measures replace the desktop intrinsic widths (a nowrap free-text column is * what makes a five-column queue wider than its card and forces a horizontal scroll). Nothing * here is read unless `preset="action-collection"` is set, so every existing table is untouched. * Percentages so the ratio holds at any card width; the action affordance is an absolute measure * because it must never be squeezed below its touch target.'},{name:"--table-action-collection-secondary-width",value:"22%",description:"requester / subject"},{name:"--table-action-collection-meta-width",value:"12%",description:"target / resource"},{name:"--table-action-collection-actions-width",value:"3.5rem",description:"timestamps, ids \u2014 lowest priority"},{name:"--table-action-collection-primary-width-compact",value:"24%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-secondary-width-compact",value:"22%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-meta-width-compact",value:"20%",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-actions-width-compact",value:"2.75rem",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-font-size-compact",value:"var(--font-size-xs)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-cell-space-x-compact",value:"var(--space-2)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-cell-padding-y-compact",value:"var(--space-2)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."},{name:"--table-action-collection-row-height-compact",value:"var(--table-row-height-compact)",description:"Compact tier, applied below the collapse step (the 390px acceptance frame)."}];var p={issue:"https://github.com/godx-jp/godxjp-ui/issues/163",standard:"docs/FRAME-COVERAGE-STANDARD.md",ledger:"preview/frame-coverage.ledger.json",recordedAt:"2026-07-30",warning:"UNTESTED means no executed case demonstrates this dimension. It is NOT a pass. Do not infer support from a happy-path example, a similarly-named frame, or a rendered screenshot.",verdicts:{covered:"An executed case proves this dimension.",untested:"No executed case. NOT a pass \u2014 report it as UNTESTED to the user.","not-applicable":"The dimension cannot exist for this export; the ledger carries the written reason."},requiredViewports:[320,375,390,768,1024,1280,1440,1920],containerWidths:[240,320,480,640,960],totals:{exports:278,dimensionCells:3892,covered:64,untested:2128,notApplicable:1700,exportsWithoutFrame:0},dimensions:[{id:"variants",title:"Variants",axis:"visual"},{id:"tones",title:"Tones",axis:"visual"},{id:"sizes",title:"Sizes",axis:"visual"},{id:"shapes",title:"Shapes",axis:"visual"},{id:"density",title:"Spacing / density",axis:"visual"},{id:"ownership",title:"Controlled / uncontrolled / reset",axis:"ownership"},{id:"states",title:"Disabled / read-only / loading / empty / error / success",axis:"state"},{id:"async",title:"Async: loading / reject / retry / cancel / offline",axis:"async"},{id:"responsive",title:"Responsive viewport matrix",axis:"responsive"},{id:"rtl",title:"RTL / direction",axis:"international"},{id:"contentStress",title:"Long / localized content stress",axis:"contentStress"},{id:"keyboard",title:"Keyboard / focus order / focus return",axis:"accessibility"},{id:"accessibleName",title:"Accessible name / description / error association",axis:"accessibility"},{id:"reducedMotion",title:"Preferences: reduced motion / forced colors / 200% zoom / coarse touch",axis:"preferences"}],knownGaps:[{id:"button-contract-gaps",targets:["Button"],dimensions:["states","contentStress","rtl","keyboard","reducedMotion"],cases:["implicit form `type` inside a form","loading combined with asChild","count / overflowCount / showZero overflow","long Japanese and Vietnamese labels","RTL","coarse touch target"]},{id:"card-contract-gaps",targets:["Card"],dimensions:["variants","density","rtl","accessibleName"],cases:["`variant` \xD7 `accent` \xD7 `size` matrix",'`density="tight"` spacing mode',"nested heading levels","RTL accent rail"]},{id:"card-subcomponent-contract-gaps",targets:["CardBar","CardContent","CardFooter","CardHeader"],dimensions:["rtl","accessibleName","contentStress"],cases:["CardBar `extra` slot","CardContent `tight` / `flush` / `solo`","CardFooter `flush` / `separated`","CardHeader `banded`","RTL"]},{id:"empty-state-contract-gaps",targets:["EmptyState"],dimensions:["variants","contentStress","accessibleName"],cases:["`section` variant","`compact` variant","without icon / description / action","heading level (`titleAs` / `titleLevel`) and live-region semantics"]},{id:"progress-contract-gaps",targets:["Progress"],dimensions:["tones","contentStress"],cases:["destructive tone","`over={true}` (value beyond 100%)"]},{id:"carousel-contract-gaps",targets:["Carousel"],dimensions:["ownership","contentStress","keyboard","reducedMotion","rtl"],cases:["single slide","plugins / setApi","autoplay pause","arrow-key traversal alongside tabs","touch / swipe","RTL"]},{id:"data-table-contract-gaps",targets:["DataTable"],dimensions:["states","async","keyboard","accessibleName","density"],cases:["error / prerequisite / background refresh","server and manual modes (manualPagination / manualSorting / manualFiltering)","zero-page and single-page pagination","accessible table and action-column labels","invalid row ids (getRowId)","keyboard behaviour","virtualization"]},{id:"charts-contract-gaps",targets:["LineChart","BarChart","AreaChart","PieChart"],dimensions:["async","reducedMotion","keyboard","contentStress","responsive","rtl"],cases:["loading / error","reduced motion","keyboard datum navigation","invalid / null / NaN data","mobile axis collision","RTL"]},{id:"locale-stress-gaps",targets:["Timeline","TreeList","PasswordStrength"],dimensions:["contentStress","accessibleName"],cases:["long localized Japanese / Vietnamese content","hard-coded screen-reader strings that never reach `t()`"]}]},z=[{name:"Accordion",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AccordionContent",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AccordionItem",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AccordionTrigger",group:"data-display",frame:"docs/data-display/accordion.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Alert",group:"feedback",frame:"docs/feedback/alert.tsx",covered:["tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states"]},{name:"AlertActions",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertContent",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDescription",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialog",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones"]},{name:"AlertDialogAction",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertDialogCancel",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertDialogContent",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogDescription",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogFooter",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogHeader",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"AlertDialogOverlay",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogPortal",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogRoot",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"AlertDialogTitle",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AlertDialogTrigger",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AlertMutationFeedback",group:"query",frame:"docs/query/mutation-feedback.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AlertQueryError",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AlertTitle",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AppSettingPicker",group:"navigation",frame:"docs/navigation/app-setting-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"AppShell",group:"layout",frame:"docs/layout/app-shell.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AreaChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"AspectRatio",group:"layout",frame:"docs/layout/aspect-ratio.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthAccountSummary",group:"layout",frame:"docs/layout/auth-account-summary.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"AuthDivider",group:"layout",frame:"docs/layout/auth-divider.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthFooter",group:"layout",frame:"docs/layout/auth-footer.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthIdentity",group:"layout",frame:"docs/layout/auth-identity.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AuthShell",group:"layout",frame:"docs/layout/auth-shell.tsx",covered:["density","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones"]},{name:"AuthStack",group:"layout",frame:"docs/layout/auth-stack.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Avatar",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:["shapes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states","tones","variants"]},{name:"AvatarFallback",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"AvatarImage",group:"data-display",frame:"docs/data-display/avatar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Badge",group:"data-display",frame:"docs/data-display/badge.tsx",covered:["shapes","tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states"]},{name:"Banner",group:"feedback",frame:"docs/feedback/alert.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","tones"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"BarChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"Breadcrumb",group:"layout",frame:"docs/navigation/breadcrumb.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Button",group:"general",frame:"docs/general/button/index.tsx",covered:["shapes","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","tones"]},{name:"ButtonRefetch",group:"query",frame:"docs/query/button-refetch.tsx",covered:["shapes","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","tones"]},{name:"Calendar",group:"data-entry",frame:"docs/data-entry/calendar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Card",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:["density","sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","states","tones"]},{name:"CardAction",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardBar",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardContent",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardCover",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardDescription",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardFooter",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardHeader",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CardTitle",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Carousel",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CarouselContent",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselDots",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselItem",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CarouselNext",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CarouselPrevious",group:"data-display",frame:"docs/data-display/carousel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Cascader",group:"data-entry",frame:"docs/data-entry/cascader.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CenteredShell",group:"layout",frame:"docs/layout/centered-shell.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Checkbox",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CheckboxGroup",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Collapsible",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CollapsibleContent",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CollapsibleTrigger",group:"data-display",frame:"docs/data-display/collapsible.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ColorPicker",group:"data-entry",frame:"docs/data-entry/color-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Command",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandEmpty",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CommandGroup",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandInput",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"CommandItem",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CommandList",group:"data-entry",frame:"docs/data-entry/command.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"CommandPalette",group:"data-entry",frame:"docs/data-entry/command-palette.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"CompactBarTrend",group:"charts",frame:"docs/charts/compact-bar-trend.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"ContextMenu",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuCheckboxItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ContextMenuContent",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"ContextMenuLabel",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuPortal",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuRadioGroup",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuRadioItem",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ContextMenuSeparator",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuShortcut",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSub",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSubContent",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ContextMenuSubTrigger",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ContextMenuTrigger",group:"navigation",frame:"docs/navigation/context-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"CredentialReveal",group:"data-display",frame:"docs/data-display/credential-reveal.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"DataState",group:"query",frame:"docs/query/data-state.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"DataTable",group:"data-display",frame:"docs/data-display/data-table/index.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["shapes","sizes","tones","variants"]},{name:"DatePicker",group:"data-entry",frame:"docs/data-entry/date-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DateRangePicker",group:"data-entry",frame:"docs/data-entry/date-range-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Descriptions",group:"data-display",frame:"docs/data-display/descriptions.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Dialog",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DialogAction",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogBody",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogCancel",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogClose",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DialogContent",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogDescription",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogFooter",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogHeader",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"DialogOverlay",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogPortal",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogTitle",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DialogTrigger",group:"feedback",frame:"docs/feedback/dialog.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenu",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuCheckboxItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenuContent",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuGroup",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"DropdownMenuLabel",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuPortal",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuRadioGroup",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuRadioItem",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"DropdownMenuSeparator",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuShortcut",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSub",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSubContent",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"DropdownMenuSubTrigger",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"DropdownMenuTrigger",group:"navigation",frame:"docs/navigation/dropdown-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"EmptyState",group:"data-display",frame:"docs/data-display/empty-state.tsx",covered:["tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states"]},{name:"ErrorSurface",group:"layout",frame:"docs/layout/error-surface/index.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"Field",group:"data-entry",frame:"docs/data-entry/checkbox.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"FilterBar",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"FilterBarGroup",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Flex",group:"layout",frame:"docs/layout/flex.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Form",group:"data-entry",frame:"docs/data-entry/form.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones","variants"]},{name:"FormField",group:"data-entry",frame:"docs/data-entry/form-field/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Heading",group:"general",frame:"docs/general/typography.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"HoverCard",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"HoverCardContent",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"HoverCardTrigger",group:"data-display",frame:"docs/data-display/hover-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InfiniteQueryState",group:"query",frame:"docs/query/infinite-query-state.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Input",group:"data-entry",frame:"docs/data-entry/input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"InputOTP",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPGroup",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPSeparator",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"InputOTPSlot",group:"data-entry",frame:"docs/data-entry/input-otp.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Label",group:"data-entry",frame:"docs/data-entry/label.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"LegalDocumentShell",group:"layout",frame:"docs/layout/legal-document-shell/index.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"LineChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"ListRow",group:"data-display",frame:"docs/data-display/list-row.tsx",covered:["density"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones","variants"]},{name:"Logo",group:"general",frame:"docs/general/logo.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"MasterDetail",group:"layout",frame:"docs/layout/master-detail.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Menubar",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarCheckboxItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MenubarContent",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones"]},{name:"MenubarLabel",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarMenu",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarRadioGroup",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarRadioItem",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MenubarSeparator",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarShortcut",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarSub",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"MenubarSubContent",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MenubarSubTrigger",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"MenubarTrigger",group:"navigation",frame:"docs/navigation/menubar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"MonthPicker",group:"data-entry",frame:"docs/data-entry/month-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"MonthRangePicker",group:"data-entry",frame:"docs/data-entry/month-range-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"NavigationMenu",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuContent",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuIndicator",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuItem",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuLink",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuList",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuTrigger",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NavigationMenuViewport",group:"navigation",frame:"docs/navigation/navigation-menu.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"NumberInput",group:"data-entry",frame:"docs/data-entry/number-input.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"OrgSwitcher",group:"layout",frame:"docs/layout/org-switcher.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PageContainer",group:"layout",frame:"docs/layout/page-container.tsx",covered:["density","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["ownership","shapes","sizes","states","tones"]},{name:"PageHeader",group:"layout",frame:"docs/layout/page-header.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"Pagination",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationContent",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PaginationEllipsis",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PaginationItem",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PaginationLink",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationNext",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PaginationPrevious",group:"navigation",frame:"docs/navigation/pagination.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"PasswordInput",group:"data-entry",frame:"docs/data-entry/password-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PasswordStrength",group:"data-entry",frame:"docs/data-entry/password-strength.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PieChart",group:"charts",frame:"docs/data-display/charts.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones","variants"]},{name:"Popover",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"PopoverAnchor",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverContent",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverDescription",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverHeader",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverTitle",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PopoverTrigger",group:"data-display",frame:"docs/data-display/popover.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"PrefetchLink",group:"query",frame:"docs/query/prefetch-link.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Progress",group:"data-display",frame:"docs/data-display/progress.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","variants"]},{name:"QrCode",group:"data-display",frame:"docs/data-display/qr-code.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"Radio",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioGroup",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioGroupRoot",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"RadioItem",group:"data-entry",frame:"docs/data-entry/radio-group.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Rating",group:"data-entry",frame:"docs/data-entry/rating.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"ResizableHandle",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResizablePanel",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResizablePanelGroup",group:"layout",frame:"docs/layout/resizable-panel.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"ResponsiveGrid",group:"layout",frame:"docs/layout/responsive-grid.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Reveal",group:"general",frame:"docs/general/reveal.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ScrollArea",group:"data-display",frame:"docs/data-display/scroll-area.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ScrollBar",group:"data-display",frame:"docs/data-display/scroll-area.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SearchInput",group:"data-entry",frame:"docs/data-entry/search-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Select",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SelectContent",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectGroup",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectItem",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SelectLabel",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectScrollDownButton",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectScrollUpButton",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectSeparator",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SelectTrigger",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"SelectValue",group:"data-entry",frame:"docs/data-entry/select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"Separator",group:"layout",frame:"docs/layout/separator.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceCatalogCta",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceLauncherCard",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ServiceLauncherCardSkeleton",group:"data-display",frame:"docs/data-display/service-launcher-card.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Sheet",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"SheetBody",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetClose",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SheetContent",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetDescription",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetFooter",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetHeader",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","variants"]},{name:"SheetOverlay",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetPortal",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetTitle",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SheetTrigger",group:"feedback",frame:"docs/feedback/sheet.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Sidebar",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SidebarHeader",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SidebarItem",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl","states"],notApplicable:["density","ownership","shapes","sizes","tones","variants"]},{name:"SidebarSection",group:"layout",frame:"docs/layout/sidebar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Skeleton",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonDetail",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonRows",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonStat",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"SkeletonTable",group:"feedback",frame:"docs/feedback/skeleton.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Slider",group:"data-entry",frame:"docs/data-entry/slider.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"SplitPane",group:"layout",frame:"docs/layout/split-pane.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"StatCard",group:"data-display",frame:"docs/data-display/card/index.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"StatusBadge",group:"data-display",frame:"docs/data-display/badge.tsx",covered:["shapes","tones","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","sizes","states"]},{name:"Steps",group:"navigation",frame:"docs/navigation/steps.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones","variants"]},{name:"Switch",group:"data-entry",frame:"docs/data-entry/switch.tsx",covered:["sizes"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones","variants"]},{name:"Table",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableBody",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableCell",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableHead",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableHeader",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TableRow",group:"data-display",frame:"docs/data-display/table.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Tabs",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones"]},{name:"TabsContent",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"TabsList",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones"]},{name:"TabsTrigger",group:"navigation",frame:"docs/navigation/tabs.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TagInput",group:"data-entry",frame:"docs/data-entry/tag-input.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Text",group:"general",frame:"docs/general/typography.tsx",covered:["sizes","tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","variants"]},{name:"Textarea",group:"data-entry",frame:"docs/data-entry/textarea.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Timeline",group:"data-display",frame:"docs/data-display/timeline.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones"]},{name:"TimePicker",group:"data-entry",frame:"docs/data-entry/time-picker.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Toaster",group:"feedback",frame:"docs/feedback/toast.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Toggle",group:"data-entry",frame:"docs/data-entry/toggle.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","states","tones"]},{name:"ToggleGroup",group:"data-entry",frame:"docs/data-entry/toggle-group.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","tones"]},{name:"ToggleGroupItem",group:"data-entry",frame:"docs/data-entry/toggle-group.tsx",covered:["sizes","variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","states","tones"]},{name:"Toolbar",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"ToolbarGroup",group:"navigation",frame:"docs/navigation/toolbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Tooltip",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl"],notApplicable:["density","shapes","sizes","states","tones","variants"]},{name:"TooltipContent",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TooltipProvider",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TooltipTrigger",group:"feedback",frame:"docs/feedback/tooltip.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Topbar",group:"layout",frame:"docs/layout/topbar.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"Transfer",group:"data-entry",frame:"docs/data-entry/transfer.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TreeList",group:"data-display",frame:"docs/data-display/tree-list.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],notApplicable:["density","ownership","shapes","sizes","states","tones","variants"]},{name:"TreeSelect",group:"data-entry",frame:"docs/data-entry/tree-select.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"TwoFactorSetup",group:"feedback",frame:"docs/feedback/two-factor-setup.tsx",covered:[],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones","variants"]},{name:"Upload",group:"data-entry",frame:"docs/data-entry/upload.tsx",covered:["variants"],untested:["accessibleName","async","contentStress","keyboard","ownership","reducedMotion","responsive","rtl","states"],notApplicable:["density","shapes","sizes","tones"]}],le=new Map(z.map(t=>[t.name.toLowerCase(),t]));function L(t){return le.get(String(t??"").trim().toLowerCase())}var u=[{number:1,title:"Storybook is mandatory",body:"Every primitive / shell / composite has a paired story under `src/stories/<group>/<Name>.stories.tsx` covering every variant + state on light + dark."},{number:2,title:"Tokens, not utilities",body:"Visual values come from CSS custom properties in `src/tokens/` + `src/styles/theme.css`. Token-named Tailwind utilities (`bg-background`) are fine; raw value utilities (`bg-blue-500`) are forbidden. (ADR-0003)"},{number:3,title:"Radix for interactive primitives",body:"Anything with keyboard / ARIA / portal wraps the relevant Radix primitive. (ADR-0001)"},{number:4,title:"shadcn-style ownership",body:"Primitives are thin wrappers; consumers can fork the source in place. (ADR-0002)"},{number:5,title:"One i18next singleton",body:"`initI18n()` in `src/i18n/index.ts` is THE instance; consumers extend via `addResourceBundle`. (ADR-0004)"},{number:6,title:"WCAG 2.1 AA baseline",body:"Every interactive primitive passes axe-core (keyboard nav, ARIA, focus-visible, 4.5:1 contrast, `prefers-reduced-motion`). Stories double as a11y test surfaces."},{number:7,title:"SemVer 2.0 + Keep a Changelog 1.1",body:"Every release-worthy change updates `CHANGELOG.md` under `## Unreleased` in the same PR."},{number:8,title:"Inclusive naming",body:"`allowlist` / `denylist`, `main` / `primary` / `replica` / `secondary`, `they/them`. Never `whitelist` / `blacklist` / `master` / `slave`. Lint-enforced."},{number:9,title:"No marketing speak",body:'Banned: "powerful", "robust", "blazing fast", "best-in-class", "seamless", "enterprise-grade". State what it does.'},{number:10,title:"English is canonical for docs",body:"Localised docs at `docs/i18n/<bcp47>/`; front-matter tracks staleness."},{number:11,title:"Submodule discipline",body:"Two-PR workflow: (1) submodule PR \u2192 `main`, (2) downstream PR \u2192 bump pin. Never push a pin to a SHA not on the submodule remote."},{number:12,title:"Branch + PR workflow",body:"`feat/<scope>` / `fix/<scope>` \u2192 submodule `main`. CI green + squash-merge. No direct push to `main`. `--no-verify` forbidden."},{number:13,title:"TypeScript strict",body:"Explicit types on every export. `forwardRef` for components; `ComponentPropsWithoutRef` for extension. No `any`. No `@ts-ignore` without comment + issue link."},{number:14,title:"Every third-party library is shadcn / Radix-recommended",body:"Locked stack: Radix UI, cmdk, sonner, lucide-react, react-aria-components + `@internationalized/date`, i18next + react-i18next, class-variance-authority + clsx + tailwind-merge. New peer \u2192 ADR documenting why it's the canonical choice."},{number:15,title:"No `@apply` re-encoding tokens",body:"Inside a primitive `.tsx`, don't `@apply` a Tailwind utility that re-encodes a token \u2014 reference the canonical CSS class from `tokens.css` instead. Composite token-named utilities remain fine."},{number:16,title:"CSS source-of-truth is `src/tokens/` + `src/styles/theme.css`",body:"A primitive that needs a new color / spacing / radius adds it there FIRST, then references it."},{number:17,title:"`src/stories/` \u2194 `src/components/` parity",body:"Story set matches primitive set under each group. CI-checked via `scripts/check-stories-parity.mjs`."},{number:18,title:"`docs/reference/<group>/` \u2194 `src/components/<group>/` parity",body:"Every primitive has a reference page; every page maps to a primitive. CI-checked via `scripts/check-docs-parity.mjs`."},{number:19,title:"No service-specific anything",body:'`me-service`, `forge-service`, `admin-service` never appear in source / comments / prop names. Per-deployment brand color lives at `[data-accent="<palette>"]`.'},{number:20,title:'No "platform-only" exports',body:"Every primitive ships via `package.json::exports`. Internal-only helpers stay un-exported."},{number:21,title:"Every component honours every theme axis",body:"`data-theme` (light / dark), `data-accent` (6 palettes), `data-density` (compact / default / comfortable), `data-font-size` (sm / base / lg / xl). Read from tokens, never hardcode values. Verify every PR via the Storybook toolbar sweep."},{number:22,title:"100% match to the design canon",body:'Every visual literal comes from `design-handoff/ui-system/<latest-bundle>/`. Token-pin canon literals; never substitute "close enough". If the bundle doesn\'t cover a case \u2014 STOP, ask the user to mock it.'},{number:23,title:"Concept-first prop API",body:"One concept per prop. Reuse shared vocabulary (`size`, `variant`, `color`, `tone`, `accent`, `padding`, `density`, `orientation`, `placement`, `current`, `value` / `defaultValue` / `onValueChange`, `open` / `defaultOpen` / `onOpenChange`, `justify`, `sticky`, `offset`). Before adding a new prop or token: grep for an existing one."},{number:24,title:"Mobile-first",body:"Defaults target `xs` (\u22650px); progressive enhancement via `sm:` / `md:` / `lg:` / `xl:` / `2xl:`. Touch targets \u2265 44 \xD7 44 px (`--touch-target-min`, does NOT scale with density). Runtime viewport via `useBreakpoint`, never `window.innerWidth`. Stories render at narrow viewport first."},{number:25,title:"Stories are docs; UI is the primitive",body:"When a story looks wrong, fix the primitive / CSS / token. Never paper over with a story tweak. Story-only diff without a paired primitive / CSS / token diff is rejected."},{number:26,title:"Library isolation",body:"`dist/` ships only the consumer surface. Storybook, tests, scripts, design-handoff, `dev-probe/` stay out of npm. Every `dependencies` entry is `external` in `tsup`. Verification via `pnpm pack` + grep of `dist/`."},{number:27,title:"Per-group folder structure",body:"Primitives at `src/components/<group>/<Name>.tsx`; six canonical groups (general, layout, data-display, data-entry, feedback, navigation). Barrel = `src/components/primitives.ts` (single file). Stories + reference docs mirror the same group hierarchy."},{number:28,title:"`src/` folder taxonomy",body:"Three classes: consumer surface (matched by `tsup` entry + `package.json::exports`), Storybook-only (`src/stories/`), build-input-only (`cn.ts`, per-group sources consumed via the barrel). No `src/lib/`, `src/utils/`, `src/internal/`, `src/clients/`, `src/screens/`. Service clients live with the composite that uses them."},{number:29,title:"Stories consume framework primitives only",body:"No raw `<button>` / `<input>` / hand-rolled chips when a primitive exists. HTML semantics (`<section>`, `<article>`, \u2026) for structure are fine. Inline `style={{}}` limited to layout / positioning; no colour / radius / typography overrides."},{number:30,title:"Story `render` returns JSX directly",body:"No opaque `<XyzDemo />` wrapper components, no zero-arg `Demo` helpers. Use `render: function StoryName() { \u2026 }` so Storybook's source panel shows runnable JSX, not `<XyzDemo />`."},{number:31,title:"No nested wrapper / convenience primitives",body:"One Radix base = one framework primitive. `<SimpleX>` over `<X>` is forbidden; add a prop to `<X>` instead. Composites under `src/components/composites/` that combine multiple primitives are NOT wrappers."},{number:32,title:"No redundant props",body:"Before adding a prop / item field / variant, grep the existing surface; if a field already covers the concept, use it. Top-level prop that re-expresses an item field (Timeline `pending` \u2194 `items[i].animate`) is rejected."},{number:33,title:"Stories / source / docs name-synchronized",body:"No two names for the same export across the framework surface; no legacy aliases in stories / docs (source may keep an alias for a deprecation cycle, but the marketing surfaces use the canonical name only). Rename PR runs `grep -rn '<oldName>' src docs` and clears it."},{number:34,title:"Storybook source panel = real, copy-paste-ready code",body:'Storybook\'s react-docgen serializer strips every function value (`cell: ({row}) => <JSX/>`, `render: ({field}) => <Input/>`, `rowClassName`, `renderItem`, \u2026) 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 \u2014 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`.'},{number:35,title:"Status chips never wrap",body:"A `Badge` / `Badge` reads as one atomic unit. Its label must never break across lines \u2014 pin `white-space: nowrap` on the chip (done in `badge-layout.css`), especially inside narrow `DataTable` cells (\u30B9\u30B3\u30FC\u30D7 / \u30B9\u30C6\u30FC\u30BF\u30B9 columns). If a cell is too tight, widen the column or shorten the label; never let the chip wrap."},{number:36,title:"Badge tone/icon are the colour escape hatch",body:"`Badge` auto-maps a fixed set of English lifecycle keys (active, draft, pending, scheduled, cancelled, failed, \u2026) to tone + icon. For ANY other value \u2014 localized labels (\u516C\u958B\u4E2D, \u30A2\u30AF\u30C6\u30A3\u30D6) or categorical tiers (\u4F1A\u54E1\u30E9\u30F3\u30AF, \u5951\u7D04\u30D7\u30E9\u30F3) \u2014 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 + \u25CB. Map domain\u2192tone in the CONSUMER layer; the framework only provides the props."},{number:37,title:"DataTable is full-width \u2014 never inside a narrow grid column",body:"A multi-column `DataTable` occupies its OWN row at the page's full width: `<Card><CardContent flush><DataTable \u2026/></CardContent></Card>`. Never nest it in a `lg:col-span-2` of a `ResponsiveGrid columns={3}` beside a chart \u2014 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.)"},{number:38,title:"FilterBar stays OUT of CardContent flush",body:"`CardContent flush` strips horizontal padding for edge-to-edge tables. A `FilterBar` placed inside it loses all padding and sticks to the card edge. Render `FilterBar` as a STANDALONE block above the table card; wrap ONLY the `DataTable` / `EmptyState` in the `Card` + `CardContent flush`. Order on a list page: KPIs \u2192 FilterBar \u2192 table card."},{number:39,title:"Long text columns get an explicit width",body:"For columns whose value can be long (name / title / segment / address), set `col.width` to a Tailwind width class (e.g. `w-64`, `w-48`) so the column reserves space instead of shrinking and wrapping to many lines; leave numeric / status columns auto. Table cells default to `white-space: nowrap`, so an over-tight table scrolls horizontally rather than crushing \u2014 give the important columns real widths so the default layout reads well before any scroll."},{number:40,title:"Pages are mobile-first",body:'Author and verify every page at 320\u2013390px FIRST. Spacing comes only from `Flex` `gap` (vertical rhythm = `Flex direction="col"`, control rows = the default `direction="row"`) + `ResponsiveGrid columns={2|3|4}` (which collapse to a single column on narrow screens) \u2014 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 \u2265 44\xD744px.'},{number:41,title:"Drawer & dialog footer layout",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 \u2014 give that button `className="mr-auto"`. NEVER stack footer buttons full-width or center them.'},{number:42,title:"Props & Tokens Before Customization",body:"Before reaching for a Tailwind class, inline `style`, or extra CSS, you MUST first check whether the component already supports the need via a PROP, a design TOKEN, or a layout/typography PRIMITIVE. godx-ui is meant to be enough on its own (Ant-Design-style): `className` is for genuine one-offs only \u2014 never to redo what an API already does. Specifically: (1) NEVER hand-roll typography \u2014 no `text-[13px]`/`text-[11px]` arbitrary px (bypasses the golden type scale), no `font-medium`/`font-semibold`/`text-muted-foreground` on a raw `<span>`; use `<Text size tone weight tabular mono>` / `<Heading level>`. (2) NEVER hand-roll a trivial flex/grid wrapper; use `<Flex>` / `<ResponsiveGrid>` / `<PageContainer>`. (3) NEVER set a control's radius/height/colour with a utility when a `shape`/`size`/`tone`/token exists. If a real need has NO prop/token/primitive, that is a library GAP \u2014 file it (draft_bug_report), don't paper over it with ad-hoc Tailwind."},{number:43,title:"Every form control goes through FormField",body:"Consumers MUST wrap every labelled form control (Input, Select, DatePicker, DateRangePicker, NumberInput, Radio.Group, Checkbox groups, range pairs, ...) in FormField \u2014 it owns the label (aria-labelledby, never a dangling <label for>), auto-generates/injects the control id, and wires aria-describedby/aria-errormessage/aria-invalid. Bare controls are the rare exception (e.g. a toolbar quick-filter with its own aria-label) and must carry id/name + aria-label themselves. Never hand-roll a label+control stack with Text/Label."},{number:44,title:"Chrome is a token, default quiet",body:"Any decorative chrome a component draws \u2014 dividers, separator borders, and the padding that exists only to space that chrome \u2014 MUST read a token; never hard-code it in `src/styles/*.css` (a hard-coded `border-bottom: 1px solid hsl(var(--border))` leaves consumers no off-switch short of a variant fork). The DEFAULT is the quietest state (`none` / balanced rhythm); a service theme opts IN, e.g. `--page-header-divider: 1px solid hsl(var(--border))`. Born from real consumption: PageContainer's header divider was undisableable until tokenised."},{number:45,title:"Every service-tunable constant gets a knob",body:'When component CSS encodes a geometry choice that a service plausibly re-tunes to match its design handoff \u2014 form label column width, label\u2194control gap, header insets \u2014 it MUST be a documented component token (current value as the default). The theme sets it ONCE globally; props (`labelWidth`) override per instance; Form\u2192FormField priority stays intact. The test: "would a service theme.css want to change this to match its design grid?" If yes and the only route is forking CSS, that is a library gap \u2014 fix the library, don\'t patch the app. Born from real consumption: `--form-label-width` / `--form-label-gap` (design spec said 110px/8px; the values were prop-only and hard-coded `--space-4`).'},{number:46,title:"Typography is tokens, default is base",body:"A UI framework gives consumers knobs: every font-size in `src/styles/*.css` MUST reference a token \u2014 the global modular scale `var(--font-size-{2xs|xs|sm|base|lg|xl|2xl})` or a per-component `var(--{component}-\u2026-font-size)` knob (rule #45) \u2014 never a hard-coded literal (`font-size: 12px` can't be re-themed). The DEFAULT body size is `--font-size-base`; components render body/UI text at `base`, not at the `sm` alias. Smaller-by-design text (badge, section label, caption) is a component token defaulting to a small step (`--badge-font-size: var(--font-size-xs)`), so a service re-tunes that part without moving the global scale. The `sm`/`xs` tokens stay for the explicit `<Text size>` API. Every component token is surfaced in the MCP `get_component` output (check:mcp-token-sync). Enforced by `check:typography`."}];function T(t){return u.find(a=>a.number===t)}var b=[{name:"common-fixes",tagline:"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 \u2192 after.",tags:["fixes","migration","bug","cardstat","statusbadge","datatable","sidebar","gotcha","review"],code:`// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1900
1934
  // 0) \u2605 MOST COMMON: <Card> body has NO padding (content is flush against the edges)
1901
1935
  // Cause: the bare <Card> has ZERO inner padding \u2014 it MUST contain <CardContent>.
1902
1936
  // Don't hand-roll padding with className="p-4" on the Card either.
@@ -2767,7 +2801,151 @@ export function OrganizationMemberships({
2767
2801
  );
2768
2802
  }
2769
2803
  // DON'T: passive rows with no action \xB7 identical decorative icons \xB7 unlabeled timestamps
2770
- // (label them: "2024\u5E74\u306B\u53C2\u52A0") \xB7 a large empty invitation Card shown permanently.`},{name:"auth-recovery-panels",aliases:["password-recovery","forgot-password","reset-password","mfa-challenge","two-factor-challenge","2fa-challenge","otp-challenge","passkey-failure","scr-008"],tagline:'Signed-OUT password recovery + sign-in MFA challenge panels (SCR-008). There is NO PasswordRecoveryPanel and NO MfaChallengePanel \u2014 compose Card + AuthStack + FormField/InputOTP + Button inside AuthShell preset="account-recovery" (the 432px token-owned measure).',tags:["auth","authshell","recovery","password","mfa","2fa","otp","inputotp","passkey","layout","presentation"],code:`// \u26A0\uFE0F There is NO <PasswordRecoveryPanel state=\u2026/> and NO <MfaChallengePanel state=\u2026/> in
2804
+ // (label them: "2024\u5E74\u306B\u53C2\u52A0") \xB7 a large empty invitation Card shown permanently.`},{name:"rbac-service-roles",aliases:["service-role-panel","servicerolepanel","branch-scope-picker","branchscopepicker","permission-matrix","permissionmatrix","role-editor","rbac","scr-203","scr-111b"],tagline:"Service roles, branch scope and the permission matrix. There is NO ServiceRolePanel, NO BranchScopePicker and NO PermissionMatrix component \u2014 all three FAIL the Framework-Component Test and are canonical COMPOSITIONS of existing primitives, with the only genuinely reusable part (the grant/diff data logic) shipped as @godxjp/ui/lib/permission-grid.",tags:["rbac","permissions","roles","admin","table","treeselect","listrow","masterdetail","presentation"],code:`// \u26A0\uFE0F There is NO <ServiceRolePanel/>, NO <BranchScopePicker/> and NO <PermissionMatrix/> in
2805
+ // @godxjp/ui, and none is planned (gh#257). Each fails the Framework-Component Test
2806
+ // (docs/COMPOSITION-VS-COMPONENT.md): they own no reusable BEHAVIOR beyond what Table / TreeSelect
2807
+ // / ListRow already give (C2), they are expressible today from primitives + tokens (C3), and they
2808
+ // are RBAC-admin-niche rather than universal (C7). What the package DOES own is the part every
2809
+ // consumer would otherwise re-derive: the grant/diff logic, as pure framework-neutral helpers.
2810
+ //
2811
+ // The three canonical compositions, and the ONE import you actually need:
2812
+
2813
+ import {
2814
+ countDifferences,
2815
+ grantKey,
2816
+ hasGrant,
2817
+ rolesDifferOnPermission,
2818
+ visibleRows,
2819
+ } from "@godxjp/ui/lib/permission-grid";
2820
+ import {
2821
+ Badge,
2822
+ Card,
2823
+ CardContent,
2824
+ CardDescription,
2825
+ CardHeader,
2826
+ CardTitle,
2827
+ EmptyState,
2828
+ ListRow,
2829
+ Table,
2830
+ TableBody,
2831
+ TableCell,
2832
+ TableHead,
2833
+ TableHeader,
2834
+ TableRow,
2835
+ } from "@godxjp/ui/data-display";
2836
+ import { FormField, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SHOW_PARENT, Switch, TreeSelect } from "@godxjp/ui/data-entry";
2837
+ import { Alert, AlertDescription, AlertDialog, AlertTitle, Skeleton } from "@godxjp/ui/feedback";
2838
+ import { Button } from "@godxjp/ui/general";
2839
+ import { Flex, MasterDetail, PageContainer } from "@godxjp/ui/layout";
2840
+
2841
+ // \u2500\u2500 1. SERVICE ROLE PANEL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2842
+ // "which role does this member hold on each service" = a labelled list of rows, each with a role
2843
+ // Select. Card + CardContent flush + <ul> of ListRow as="li" gives shared row dividers instead of
2844
+ // a card outline per service. READ-ONLY / LOCKED is a Badge, NOT a disabled Select: a disabled
2845
+ // control is a dead tab stop that says "you may change this later", which is not what locked means.
2846
+ <Card>
2847
+ <CardHeader>
2848
+ <CardTitle level={2}>\u30B5\u30FC\u30D3\u30B9\u6A29\u9650</CardTitle>
2849
+ <CardDescription>\u30B5\u30FC\u30D3\u30B9\u3054\u3068\u306B\u4ED8\u4E0E\u3059\u308B\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u307E\u3059\u3002</CardDescription>
2850
+ </CardHeader>
2851
+ <CardContent flush>
2852
+ <ul>
2853
+ {services.map((service) => (
2854
+ <ListRow
2855
+ as="li"
2856
+ key={service.id}
2857
+ title={service.name}
2858
+ description={service.description}
2859
+ trailing={
2860
+ service.locked ? (
2861
+ <Badge tone="neutral">{service.roleLabel}\uFF08\u5909\u66F4\u4E0D\u53EF\uFF09</Badge>
2862
+ ) : (
2863
+ <Select value={service.roleId} onValueChange={(next) => assign(service.id, next)}>
2864
+ <SelectTrigger aria-label={\`\${service.name} \u306E\u30ED\u30FC\u30EB\`}>
2865
+ <SelectValue />
2866
+ </SelectTrigger>
2867
+ <SelectContent>
2868
+ {roles.map((role) => (
2869
+ <SelectItem key={role.id} value={role.id}>{role.name}</SelectItem>
2870
+ ))}
2871
+ </SelectContent>
2872
+ </Select>
2873
+ )
2874
+ }
2875
+ />
2876
+ ))}
2877
+ </ul>
2878
+ </CardContent>
2879
+ </Card>
2880
+
2881
+ // \u2500\u2500 2. BRANCH SCOPE PICKER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2882
+ // A branch scope is a HIERARCHICAL multi-select with parent/child aggregation \u2014 which is exactly
2883
+ // TreeSelect. Do NOT hand-roll a checkbox tree, and do NOT add a BranchScopePicker: that would
2884
+ // duplicate a primitive (the cardinal no-duplication rule). SHOW_PARENT collapses a fully selected
2885
+ // subtree to its parent, which is what makes "\u5168\u793E" read as one chip instead of 42.
2886
+ <FormField
2887
+ label="\u9069\u7528\u7BC4\u56F2\uFF08\u652F\u5E97\uFF09"
2888
+ required
2889
+ helper="\u9078\u629E\u3057\u305F\u652F\u5E97\u3068\u305D\u306E\u914D\u4E0B\u306B\u306E\u307F\u6A29\u9650\u304C\u9069\u7528\u3055\u308C\u307E\u3059\u3002"
2890
+ error={scope.length === 0 ? "\u5C11\u306A\u304F\u3068\u30821\u3064\u306E\u652F\u5E97\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : undefined}
2891
+ >
2892
+ <TreeSelect
2893
+ multiple
2894
+ treeCheckable
2895
+ showSearch
2896
+ showCheckedStrategy={SHOW_PARENT}
2897
+ treeData={branches}
2898
+ value={scope}
2899
+ onValueChange={setScope}
2900
+ disabled={readOnly}
2901
+ />
2902
+ </FormField>
2903
+
2904
+ // \u2500\u2500 3. PERMISSION MATRIX \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2905
+ // role \xD7 permission grid with a sticky first column, a two-role COMPARE mode and a
2906
+ // differences-only filter. Built from the Table family + Badge; the DATA logic is the library
2907
+ // helper, so every consumer shares one source of truth for grant lookup and diffing.
2908
+ // State is shape-encoded (Check vs Minus icon) plus sr-only text \u2014 never colour alone (WCAG 1.4.1).
2909
+ <Table>
2910
+ <TableHeader>
2911
+ <TableRow>
2912
+ <TableHead className="sticky start-0">\u6A29\u9650</TableHead>
2913
+ {roles.map((role) => <TableHead key={role.id}>{role.name}</TableHead>)}
2914
+ </TableRow>
2915
+ </TableHeader>
2916
+ <TableBody>
2917
+ {visibleRows(permissions, grants, { compare, diffOnly }).map((permission) => (
2918
+ <TableRow key={permission.id} data-diff={compare && rolesDifferOnPermission(grants, compare, permission.id)}>
2919
+ <TableCell className="sticky start-0">{permission.name}</TableCell>
2920
+ {roles.map((role) => (
2921
+ <TableCell key={grantKey(role.id, permission.id)}>
2922
+ {hasGrant(grants, role.id, permission.id)
2923
+ ? <><Check aria-hidden="true" /><span className="sr-only">\u8A31\u53EF</span></>
2924
+ : <><Minus aria-hidden="true" /><span className="sr-only">\u4E0D\u8A31\u53EF</span></>}
2925
+ </TableCell>
2926
+ ))}
2927
+ </TableRow>
2928
+ ))}
2929
+ </TableBody>
2930
+ </Table>
2931
+
2932
+ // \u2500\u2500 THE STATES, all from existing exports \u2014 never bespoke markup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2933
+ // loading \u2192 <Skeleton/> rows (match the settled row height so nothing jumps)
2934
+ // empty \u2192 <EmptyState title=\u2026 description=\u2026/>
2935
+ // validation \u2192 FormField \`error\` (announced via aria-errormessage, not colour)
2936
+ // error \u2192 <Alert tone="destructive"> with a retry action
2937
+ // permission-denied \u2192 <Alert tone="warning"> for a SECTION; <ErrorSurface mode="denied"> when
2938
+ // the whole page is forbidden (never render a page header that leaks the
2939
+ // resource's name)
2940
+ // read-only / locked \u2192 a Badge stating the fact, NOT a disabled control
2941
+ // destructive \u2192 <AlertDialog variant="destructive" title=\u2026 onConfirm=\u2026> (revoking a
2942
+ // role is not undoable from the UI; add \`challenge\` for type-to-confirm)
2943
+ //
2944
+ // LAYOUT: put the role list and the editor side by side with <MasterDetail> \u2014 it owns the tracks,
2945
+ // the gap and the stacking threshold as tokens, so there is no grid-template-columns and no media
2946
+ // query in your page at 1440 / 1024 / 390.
2947
+ //
2948
+ // Full worked screen: docs/showcase/permission-matrix.tsx and docs/showcase/service-role-scope.tsx`},{name:"auth-recovery-panels",aliases:["password-recovery","forgot-password","reset-password","mfa-challenge","two-factor-challenge","2fa-challenge","otp-challenge","passkey-failure","scr-008"],tagline:'Signed-OUT password recovery + sign-in MFA challenge panels (SCR-008). There is NO PasswordRecoveryPanel and NO MfaChallengePanel \u2014 compose Card + AuthStack + FormField/InputOTP + Button inside AuthShell preset="account-recovery" (the 432px token-owned measure).',tags:["auth","authshell","recovery","password","mfa","2fa","otp","inputotp","passkey","layout","presentation"],code:`// \u26A0\uFE0F There is NO <PasswordRecoveryPanel state=\u2026/> and NO <MfaChallengePanel state=\u2026/> in
2771
2949
  // @godxjp/ui (gh#233 \u2014 both fail the Framework-Component Test: they own no behaviour, and a
2772
2950
  // \`state\` prop that swaps five incompatible bodies is the screen-shaped grab-bag anti-pattern,
2773
2951
  // the same call as ErrorSurface's \`mode\`). What the package owns is the MEASURE:
@@ -3580,7 +3758,7 @@ Only after sign-off do you move to code. A wireframe skipped = a redesign reliti
3580
3758
  6. Hand-rolled UI instead of @godxjp/ui primitives (raw nav buttons, styled-div "Card", raw table).
3581
3759
  Every run of this skill produces, in order: (1) a stakeholder-confirmed concept/entity artifact \u2192
3582
3760
  (2) a layered IA doc \u2192 (3) an approved wireframe Artifact \u2192 (4) a per-route implementation checklist.
3583
- Do not advance a step until the prior artifact is signed off.`}]}];function A(t){return x.find(a=>a.id===t)}function U(t,a){return A(t)?.sections.find(e=>e.id===a)}function j(t,a){let e=t.toLowerCase(),o=[],r=(n,s,g,h,d)=>{n.some(y=>e.includes(y))&&o.push({skill:s,section:g,why:h,alsoSee:d})};r(["premium","awwwards","agency","linear","apple","high-end","luxury"],"soft","vibe-archetypes","Premium tier \u2014 pick a Vibe + Layout archetype + apply Double-Bezel.",["soft/double-bezel","soft/magnetic-hover"]),r(["landing page","marketing","hero","long scroll"],"imagegen-web","hero-composition-bias","Landing pages benefit from hero composition variety + per-section image generation.",["gpt-tasteskill/principles","soft/layout-archetypes"]),r(["mobile app","ios","android","phone screen","onboarding flow"],"imagegen-mobile","principles","Mobile app design \u2014 generate screens first, avoid phone-shaped-website.",["taste/mobile-first"]),r(["workspace","notion","document","editorial","knowledge base"],"minimalist","palette","Editorial workspace = warm monochrome + spot pastels + serif headings.",["minimalist/typography","minimalist/bento-grids"]),r(["dashboard","data heavy","tabular","ops table"],"brutalist","principles","Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).",["taste/one-intent-per-screen"]),r(["brand","identity","logo","guidelines"],"brandkit","principles","Brand identity work \u2014 boards before screens."),r(["refactor","redesign","upgrade existing","audit"],"redesign","fix-priority","Existing project = run audit first, fix in priority order (font \u2192 palette \u2192 states \u2192 ...).",["redesign/audit-checklist"]),r(["form","validation","submit","sign up","registration"],"taste","form-discipline","Form must have explicit label + help + error wired via FormField (rule 34)."),r(["loading","saving","skeleton","spinner"],"taste","loading-states","Skeleton for INIT fetch, Spinner for active work. Never mix."),r(["mobile first","responsive","breakpoint"],"taste","mobile-first","Default styles target xs. Touch targets \u2265 44px. Use useBreakpoint()."),r(["complete code","full implementation","no placeholder"],"output","banned","Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code."),r(["gsap","scrolltrigger","scroll choreography","pinning"],"gpt-tasteskill","principles","GSAP ScrollTrigger \u2014 pinning, stacking, scrubbing."),r(["from image","image to code","design first"],"image-to-code","workflow","Generate design image first \u2192 analyze \u2192 implement."),r(["handoff","design bundle","claude design","prototype","build the page","implement the design","build this screen","mockup"],"design-to-page","map-to-primitives","Map every block to a real @godxjp/ui primitive (MCP-first), consume existing tokens, apply the reference-design DNA, tables central, gaps \u2192 extend-or-ask, verify.",["design-to-page/read-intent","design-to-page/dna","design-to-page/tables-central"]),r(["compose a screen","new screen","new page","create a page","create a screen","build a view","build a screen","from scratch","screen from a brief"],"compose-a-screen","pick-primitives","Build a new app screen from real @godxjp/ui primitives (MCP-first): one-intent-per-screen, real chrome, every state + a11y + i18n, verify.",["compose-a-screen/assemble-screen","compose-a-screen/state-and-a11y","taste/one-intent-per-screen"]),r(["bug in godx","godx-ui bug","report a bug","file an issue","gh issue","can't follow the rule","library is broken","primitive is broken"],"compose-a-screen","report-bug","If @godxjp/ui itself is at fault, don't fake a workaround \u2014 file a detailed gh issue (use draft_bug_report).",["design-to-page/report-bug"]),r(["slow","performance","perf","violation","long task","lag","janky","re-render","rerender","bundle size","code splitting","tree-shak","ch\u1EADm","l\u1ED7i hi\u1EC7u n\u0103ng","\u91CD\u3044"],"app-performance","measure-first","Measure FIRST (longtask + temporary Profiler), then apply the matching proven fix \u2014 page architecture, not the library, is almost always the culprit.",["app-performance/filter-pane-memo","app-performance/heavy-panels","app-performance/bundle-budget"]),r(["admin console","admin panel","control panel","back-office","back office","management console","management ui","multi-tenant","multi tenant","platform admin","workspace admin","console qu\u1EA3n tr\u1ECB","layered ia","information architecture"],"design-complex-admin","entity-model-first","A complex multi-tier admin console: lock the entity model \u2192 study exemplars \u2192 design a LAYERED IA \u2192 wireframe (Artifact) \u2192 validate \u2192 build route-by-route. Kills the flat-console anti-pattern.",["design-complex-admin/layered-ia","design-complex-admin/wireframe-first","compose-a-screen/pick-primitives"]);let i=a?.consumerOnly?o.filter(n=>{let s=A(n.skill);return!s||s.audience!=="core"}):o;return i.length===0?a?.consumerOnly?[{skill:"compose-a-screen",section:"pick-primitives",why:`No keyword match for "${t}". Default consumer path: compose the screen from real primitives via the MCP.`,alsoSee:["design-to-page/map-to-primitives","taste/one-intent-per-screen"]}]:[{skill:"taste",section:"<see whenToUse>",why:`No keyword match for "${t}". Default to the "taste" baseline \u2014 see whenToUse for sections.`}]:i}var D=[{category:"visual",name:"Purple-blue gradient hero",body:`The default LLM color palette \u2014 purple \u2192 blue \u2192 cyan radial /
3761
+ Do not advance a step until the prior artifact is signed off.`}]}];function A(t){return x.find(a=>a.id===t)}function U(t,a){return A(t)?.sections.find(e=>e.id===a)}function j(t,a){let e=t.toLowerCase(),o=[],r=(n,s,g,h,d)=>{n.some(f=>e.includes(f))&&o.push({skill:s,section:g,why:h,alsoSee:d})};r(["premium","awwwards","agency","linear","apple","high-end","luxury"],"soft","vibe-archetypes","Premium tier \u2014 pick a Vibe + Layout archetype + apply Double-Bezel.",["soft/double-bezel","soft/magnetic-hover"]),r(["landing page","marketing","hero","long scroll"],"imagegen-web","hero-composition-bias","Landing pages benefit from hero composition variety + per-section image generation.",["gpt-tasteskill/principles","soft/layout-archetypes"]),r(["mobile app","ios","android","phone screen","onboarding flow"],"imagegen-mobile","principles","Mobile app design \u2014 generate screens first, avoid phone-shaped-website.",["taste/mobile-first"]),r(["workspace","notion","document","editorial","knowledge base"],"minimalist","palette","Editorial workspace = warm monochrome + spot pastels + serif headings.",["minimalist/typography","minimalist/bento-grids"]),r(["dashboard","data heavy","tabular","ops table"],"brutalist","principles","Data-heavy dashboards work with Brutalist (rigid grids, utilitarian color).",["taste/one-intent-per-screen"]),r(["brand","identity","logo","guidelines"],"brandkit","principles","Brand identity work \u2014 boards before screens."),r(["refactor","redesign","upgrade existing","audit"],"redesign","fix-priority","Existing project = run audit first, fix in priority order (font \u2192 palette \u2192 states \u2192 ...).",["redesign/audit-checklist"]),r(["form","validation","submit","sign up","registration"],"taste","form-discipline","Form must have explicit label + help + error wired via FormField (rule 34)."),r(["loading","saving","skeleton","spinner"],"taste","loading-states","Skeleton for INIT fetch, Spinner for active work. Never mix."),r(["mobile first","responsive","breakpoint"],"taste","mobile-first","Default styles target xs. Touch targets \u2265 44px. Use useBreakpoint()."),r(["complete code","full implementation","no placeholder"],"output","banned","Banned: // ..., // TODO, 'for brevity'. Ship complete runnable code."),r(["gsap","scrolltrigger","scroll choreography","pinning"],"gpt-tasteskill","principles","GSAP ScrollTrigger \u2014 pinning, stacking, scrubbing."),r(["from image","image to code","design first"],"image-to-code","workflow","Generate design image first \u2192 analyze \u2192 implement."),r(["handoff","design bundle","claude design","prototype","build the page","implement the design","build this screen","mockup"],"design-to-page","map-to-primitives","Map every block to a real @godxjp/ui primitive (MCP-first), consume existing tokens, apply the reference-design DNA, tables central, gaps \u2192 extend-or-ask, verify.",["design-to-page/read-intent","design-to-page/dna","design-to-page/tables-central"]),r(["compose a screen","new screen","new page","create a page","create a screen","build a view","build a screen","from scratch","screen from a brief"],"compose-a-screen","pick-primitives","Build a new app screen from real @godxjp/ui primitives (MCP-first): one-intent-per-screen, real chrome, every state + a11y + i18n, verify.",["compose-a-screen/assemble-screen","compose-a-screen/state-and-a11y","taste/one-intent-per-screen"]),r(["bug in godx","godx-ui bug","report a bug","file an issue","gh issue","can't follow the rule","library is broken","primitive is broken"],"compose-a-screen","report-bug","If @godxjp/ui itself is at fault, don't fake a workaround \u2014 file a detailed gh issue (use draft_bug_report).",["design-to-page/report-bug"]),r(["slow","performance","perf","violation","long task","lag","janky","re-render","rerender","bundle size","code splitting","tree-shak","ch\u1EADm","l\u1ED7i hi\u1EC7u n\u0103ng","\u91CD\u3044"],"app-performance","measure-first","Measure FIRST (longtask + temporary Profiler), then apply the matching proven fix \u2014 page architecture, not the library, is almost always the culprit.",["app-performance/filter-pane-memo","app-performance/heavy-panels","app-performance/bundle-budget"]),r(["admin console","admin panel","control panel","back-office","back office","management console","management ui","multi-tenant","multi tenant","platform admin","workspace admin","console qu\u1EA3n tr\u1ECB","layered ia","information architecture"],"design-complex-admin","entity-model-first","A complex multi-tier admin console: lock the entity model \u2192 study exemplars \u2192 design a LAYERED IA \u2192 wireframe (Artifact) \u2192 validate \u2192 build route-by-route. Kills the flat-console anti-pattern.",["design-complex-admin/layered-ia","design-complex-admin/wireframe-first","compose-a-screen/pick-primitives"]);let i=a?.consumerOnly?o.filter(n=>{let s=A(n.skill);return!s||s.audience!=="core"}):o;return i.length===0?a?.consumerOnly?[{skill:"compose-a-screen",section:"pick-primitives",why:`No keyword match for "${t}". Default consumer path: compose the screen from real primitives via the MCP.`,alsoSee:["design-to-page/map-to-primitives","taste/one-intent-per-screen"]}]:[{skill:"taste",section:"<see whenToUse>",why:`No keyword match for "${t}". Default to the "taste" baseline \u2014 see whenToUse for sections.`}]:i}var D=[{category:"visual",name:"Purple-blue gradient hero",body:`The default LLM color palette \u2014 purple \u2192 blue \u2192 cyan radial /
3584
3762
  linear gradient as hero background. Looks like every AI-generated
3585
3763
  SaaS landing page from 2023.`,fix:`Use the framework's accent palette (\`data-accent="blue"\` /
3586
3764
  "violet" / "cyan" / "green" / "orange" / "rose"). Solid surface
@@ -3688,7 +3866,7 @@ arrives.`,fix:`Use Skeleton placeholders matching the eventual content shape.
3688
3866
  The framework's \`<Form loading={{ kind: "skeleton" }}>\` cascades
3689
3867
  to every field; \`<Skeleton className="h-9 w-full rounded-md" />\`
3690
3868
  for individual blocks. Layout stays stable, perceived speed
3691
- improves.`}];function H(t){return D.filter(a=>a.category===t)}var R=[{category:"typography",symptom:"Inter / Roboto / Open Sans everywhere \u2014 the AI default.",fix:"Pick a font with character: Geist, Outfit, Cabinet Grotesk, Satoshi for sans. For editorial / creative \u2014 pair a serif heading (Newsreader, Lyon, Playfair) with a sans body.",uiNote:"Override --font-sans + --font-serif at the consumer's root CSS. Framework reads from these tokens."},{category:"typography",symptom:"Headlines lack presence \u2014 small + thin + default tracking.",fix:"Increase display size, tighten letter-spacing (-0.02em to -0.04em), reduce line-height (1.1). Headlines should feel HEAVY and INTENTIONAL.",uiNote:"Typography.Title size={1} for hero; override fontFamily + letterSpacing inline."},{category:"typography",symptom:"Body paragraphs full-width \u2014 hard to read.",fix:"Limit paragraph max-width to ~65ch. Increase line-height to 1.6+.",uiNote:"Wrap Typography.Paragraph in `<div style={{ maxWidth: '65ch' }}>`."},{category:"typography",symptom:"Only Regular (400) + Bold (700) weights \u2014 flat hierarchy.",fix:"Introduce Medium (500) + SemiBold (600) for subtle weight contrasts."},{category:"typography",symptom:"Numbers in proportional font \u2014 columns jitter in tables.",fix:"`font-variant-numeric: tabular-nums` for data, or a monospace font like Geist Mono.",uiNote:"Table primitive already uses `tabular-nums` on `.num` cells. For ad-hoc numeric labels, add the CSS prop manually."},{category:"typography",symptom:"Orphaned words \u2014 single word on the last line of a heading.",fix:"`text-wrap: balance` (h1/h2/h3) or `text-wrap: pretty` (body)."},{category:"typography",symptom:"Title Case On Every Header.",fix:"Use sentence case instead. More modern, easier to read."},{category:"color-surface",symptom:"Pure #000000 background.",fix:"Replace with off-black (#0A0A0A) / dark charcoal (#121212) / tinted dark (deep navy).",uiNote:"Framework dark theme already uses tinted dark values \u2014 verify the consumer's override didn't force pure black."},{category:"color-surface",symptom:"Oversaturated accent colors.",fix:"Keep saturation below 80%. Desaturate so accents BLEND with neutrals rather than scream."},{category:"color-surface",symptom:"More than one accent color competing.",fix:"Pick ONE. Remove the rest. Consistency beats variety in palette.",uiNote:"Set ONE `data-accent` at `<html>` root. Use semantic colors (success / warning / destructive) only for genuinely semantic content."},{category:"color-surface",symptom:"Purple/blue 'AI gradient' aesthetic \u2014 most common AI fingerprint.",fix:"Replace with neutral base + ONE considered accent. Drop the gradient entirely if it has no narrative purpose."},{category:"color-surface",symptom:"Generic black `box-shadow` everywhere.",fix:"Tint shadow to match background hue (e.g. cool gray bg \u2192 cool gray shadow). Colored shadows over pure black."},{category:"color-surface",symptom:"Random dark section breaking an otherwise light page.",fix:"Either commit to full dark mode OR keep light consistently. If contrast needed, use a SLIGHTLY darker shade of the same palette \u2014 not a sudden jump to #111."},{category:"color-surface",symptom:"Empty flat sections with no visual depth.",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."},{category:"layout",symptom:"Everything centered + symmetric.",fix:"Break symmetry: offset margins, mixed aspect ratios, left-aligned header over centered body."},{category:"layout",symptom:"Three equal card columns as feature row \u2014 the most generic AI layout.",fix:"Replace with 2-column zig-zag, asymmetric grid, horizontal scroll, or masonry. The 3-equal-cols pattern is RED FLAG #1.",uiNote:"Use Bento Grid (custom CSS grid with `gridColumn: 'span N'`) instead of `<Grid cols={3}>` for hero sections."},{category:"layout",symptom:"`height: 100vh` causing iOS Safari jump.",fix:"Use `min-height: 100dvh` (dynamic viewport) instead."},{category:"layout",symptom:"No max-width container \u2014 content stretches edge-to-edge.",fix:"Add a container constraint (1200-1440px) with `margin: auto`. Or use `max-w-4xl / max-w-5xl` for content-heavy pages.",uiNote:"Framework's PageContent constrains via `var(--container-max-width)`. Consumer may override."},{category:"layout",symptom:"Cards forced to same height by flexbox.",fix:"Allow variable heights or use masonry when content varies.",uiNote:"Use Masonry primitive \u2014 handles variable heights without flexbox stretch."},{category:"layout",symptom:"Buttons at random vertical positions in card rows.",fix:"Pin CTAs to card bottom \u2014 same Y-position across the row regardless of content above.",uiNote:"Card's `actions` footer slot bottom-aligns automatically."},{category:"layout",symptom:"Feature lists starting at different vertical positions in pricing tables.",fix:"Fixed-height title/price block + consistent spacing above the feature list. Cards align across columns."},{category:"layout",symptom:"Dashboard ALWAYS has a left sidebar.",fix:"Consider top navigation, floating command menu, or collapsible panel. Sidebar isn't the only chrome.",uiNote:"Framework supports both \u2014 AppShell with sidebar slot is optional; can use Topbar-only for some flows."},{category:"interactivity",symptom:"No hover states on buttons.",fix:"Background shift, scale, or translate on hover \u2014 150-200ms ease.",uiNote:"Framework Button has built-in hover. If overridden \u2014 restore."},{category:"interactivity",symptom:"No active/pressed feedback.",fix:"`scale(0.98)` or `translateY(1px)` on `:active`. Simulates a physical click."},{category:"interactivity",symptom:"No focus ring (`outline: none`).",fix:"Restore visible `:focus-visible` ring. Accessibility requirement, not optional."},{category:"interactivity",symptom:"Generic circular spinner for page-level loading.",fix:"Replace with Skeleton placeholders matching the eventual content shape.",uiNote:"Framework Skeleton + Form `loading={{ kind: 'skeleton' }}` handles cascading initial-fetch state."},{category:"interactivity",symptom:"No empty states \u2014 empty dashboard shows nothing.",fix:"Design a composed 'getting started' view: Empty primitive with title + description + next-action button."},{category:"interactivity",symptom:"`window.alert()` for errors.",fix:"Inline error in the relevant Field, OR toast for non-form errors, OR Dialog for blocking errors."},{category:"interactivity",symptom:"Dead links (`href='#'`).",fix:"Either link to real destinations or visually disable the button."},{category:"interactivity",symptom:"No indication of current page in navigation.",fix:"Style the active nav link distinctly.",uiNote:"Sidebar handles via `activeId` \u2014 pass it."},{category:"content",symptom:"Generic names \u2014 'John Doe', 'Jane Smith'.",fix:"Diverse, realistic names. For Japanese apps: \u7530\u4E2D \u592A\u90CE, \u4F50\u85E4 \u7F8E\u54B2, Nguy\u1EC5n Lan, Maria Cruz."},{category:"content",symptom:"Fake round numbers \u2014 '99.99%', '50%', '$100.00'.",fix:"Organic data: '47.2%', '$99.00', '+1 (312) 847-1928'."},{category:"content",symptom:"Placeholder brand names \u2014 Acme, Nexus, SmartFlow.",fix:"Invent contextual believable brands or use the consumer's real brand."},{category:"content",symptom:"AI copy clich\xE9s \u2014 'elevate', 'seamless', 'unleash', 'next-gen', 'game-changer', 'delve', 'tapestry', 'in the world of'.",fix:"Plain specific language. Numbers, nouns, verbs.",uiNote:"Framework's cardinal rule 9 bans this in framework docs; same discipline applies to consumer copy."},{category:"content",symptom:"Exclamation marks in success messages.",fix:"Remove. Be confident, not loud."},{category:"content",symptom:"'Oops!' or apologetic error messages.",fix:"Direct + specific: 'Connection failed. Please try again.' / '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306E\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093'."},{category:"content",symptom:"Lorem Ipsum.",fix:"Real draft copy. Even rough placeholder beats Latin."},{category:"components",symptom:"Generic card look (border + shadow + white).",fix:"Remove border OR shadow OR background \u2014 keep ONE. Cards exist only when elevation communicates hierarchy."},{category:"components",symptom:"Always one filled + one ghost button.",fix:"Add text links / tertiary styles for variety.",uiNote:"Button has `variant='link'` for tertiary actions."},{category:"components",symptom:"3-card carousel testimonials with dots.",fix:"Replace with masonry wall of quotes, embedded social posts, or single rotating quote."},{category:"components",symptom:"Pricing table with 3 equal towers.",fix:"Highlight recommended tier with COLOR and emphasis, not just extra height."},{category:"components",symptom:"Modals for everything.",fix:"Use inline editing, Sheet (slide-over), or expandable Collapse for simple actions. Reserve Dialog for true blocking decisions."},{category:"components",symptom:"Footer link farm with 4 columns.",fix:"Simplify. Main nav paths + legally required links. No marketing kitchen sink."},{category:"iconography",symptom:"Lucide or Feather icons exclusively.",fix:"Use Phosphor (Bold / Fill), Heroicons, or a custom set. AI default tell.",uiNote:"Framework ships with lucide as locked dependency (rule 14). For editorial differentiation, layer Phosphor on top."},{category:"iconography",symptom:"Cliche icon metaphors \u2014 rocketship 'launch', shield 'security'.",fix:"Less obvious: bolt, fingerprint, spark, vault, gem."},{category:"iconography",symptom:"Stock 'diverse team in office' photo.",fix:"Real team photos, candid shots, or a consistent illustration style. Avatar initials fallback > generic stock person."},{category:"code-quality",symptom:"Div soup \u2014 no semantic HTML.",fix:"`<nav>`, `<main>`, `<article>`, `<aside>`, `<section>` for landmarks.",uiNote:"AppShell renders the canonical landmark structure automatically."},{category:"code-quality",symptom:"Inline styles mixed with CSS classes haphazardly.",fix:"Move styling into the project's system. Inline `style={{}}` only for layout / positioning (rule 29)."},{category:"code-quality",symptom:"Missing alt text on images.",fix:"Describe content for SR. Never leave `alt=''` or `alt='image'` on meaningful images."},{category:"code-quality",symptom:"Arbitrary z-index values like `9999`.",fix:"Establish a clean z-index scale in CSS variables."},{category:"omissions",symptom:"No legal links in footer.",fix:"Add Privacy Policy + Terms of Service."},{category:"omissions",symptom:"Dead ends in user flows \u2014 no 'back'.",fix:"Every page has a way back. Breadcrumb, back button, OR clear nav state."},{category:"omissions",symptom:"No custom 404 page.",fix:"Design a helpful branded 404 with a way home and search."},{category:"omissions",symptom:"No form validation.",fix:"Client-side validation via zod schema. Framework's Form + FormField handle field-level errors automatically."},{category:"omissions",symptom:"No 'skip to content' link.",fix:"Hidden skip-link, first focusable element. Essential for keyboard users.",uiNote:"AppShell renders one automatically."}],G=["1. Font swap \u2014 biggest instant improvement, lowest risk","2. Color palette cleanup \u2014 remove clashing / oversaturated colors","3. Hover + active states \u2014 makes the interface feel alive","4. Layout + spacing \u2014 proper grid, max-width, consistent padding","5. Replace generic components \u2014 swap cliche patterns for modern alternatives","6. Add loading, empty, error states \u2014 makes it feel finished","7. Polish typography scale + spacing \u2014 the premium final touch"],W=["Work with the existing tech stack. Do NOT migrate frameworks or styling libraries.","Do NOT break existing functionality. Test after every change.","Before importing any new library, check `package.json` first.","Keep changes reviewable + focused. Small targeted improvements over big rewrites.","Run the audit before fixing \u2014 listing issues first prevents accidental scope creep."];function _(t){return R.filter(a=>a.category===t)}var K="node node_modules/@godxjp/ui/scripts/ui-audit.mjs (add --format json for machine output, --rules to print this catalog)",$=[{id:"no-raw-palette-color",severity:"error",category:"tokens",standard:null,fix:"Use semantic tokens (bg-primary, text-muted-foreground), never raw palette (bg-blue-500)."},{id:"no-arbitrary-hex",severity:"error",category:"tokens",standard:null,fix:"No hardcoded hex in className; read design-system color tokens."},{id:"no-arbitrary-spacing",severity:"error",category:"tokens",standard:null,fix:"No p-[13px]/gap-[7px]; use the token scale / <Flex gap> / <PageContainer>."},{id:"no-arbitrary-size",severity:"error",category:"tokens",standard:null,fix:"No w-[37px]/h-[260px]; use token sizes or a sizing prop (min-w-[\u2026] allowed)."},{id:"no-arbitrary-typography",severity:"error",category:"tokens",standard:null,fix:"No text-[20px]/leading-[1.7]; use the golden-ratio type-scale tokens."},{id:"no-arbitrary-radius",severity:"error",category:"tokens",standard:null,fix:"No rounded-[6px]; use rounded-sm/md/lg radius tokens."},{id:"no-dark-color-override",severity:"warn",category:"tokens",standard:null,fix:"Drop dark: color overrides \u2014 semantic tokens already adapt."},{id:"raw-white-black",severity:"warn",category:"tokens",standard:null,fix:"Prefer semantic tokens (text-primary-foreground, bg-background) over raw white/black."},{id:"no-domain-tracking-token",severity:"error",category:"tokens",standard:null,fix:"No package-tracking/domain tokens; use semantic tokens or app theme overrides."},{id:"no-space-xy",severity:"error",category:"tokens",standard:null,fix:"Use <Flex gap> instead of space-x/y-*."},{id:"no-raw-select",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Select> from @godxjp/ui, not a raw <select>."},{id:"no-raw-table",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use the <Table>/<DataTable> family, not a raw <table>."},{id:"no-raw-input",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Input> from @godxjp/ui, not a raw <input>."},{id:"no-raw-textarea",severity:"warn",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Textarea> from @godxjp/ui, not a raw <textarea>."},{id:"no-raw-button",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Button> from @godxjp/ui, not a raw <button>."},{id:"card-manual-padding",severity:"error",category:"composition",standard:null,fix:"Wrap the body in <CardContent>; don't hand-roll padding on <Card>."},{id:"card-needs-content",severity:"error",category:"composition",standard:null,fix:"<Card> body must be in <CardContent> (no padding otherwise); flush only for a full-bleed table."},{id:"bare-control-needs-formfield",severity:"warn",category:"composition",standard:"WCAG 2.2 SC 1.3.1 \xB7 3.3.2 \xB7 @godxjp/ui FormField (cardinal rule 227)",fix:"Wrap a labelled control in <FormField label=\u2026> \u2014 it owns label\u2194control id wiring, aria/error, AND the field rhythm; never pair a bare <Label> with an <Input>."},{id:"manual-field-error",severity:"warn",category:"composition",standard:"WCAG 2.2 SC 3.3.1",fix:"Use <FormField error=\u2026>, not a hand-rolled <p class='text-destructive'>."},{id:"manual-field-helper",severity:"warn",category:"composition",standard:null,fix:"Use <FormField helper=\u2026>, not a hand-rolled helper <p>."},{id:"status-tone-not-variant",severity:"error",category:"api",standard:null,fix:"Badge/Tag/StatCard status uses tone, not variant (variant is structural)."},{id:"value-callback-on-value-change",severity:"error",category:"api",standard:null,fix:"Abstract value components use onValueChange, not onChange."},{id:"icon-button-needs-name",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 4.1.2 \xB7 1.1.1 \xB7 WAI-ARIA 1.2",fix:"Add aria-label={t('\u2026')} to <Button size='icon'>; the glyph is aria-hidden."},{id:"img-needs-alt",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 1.1.1 \xB7 HTML Living Standard",fix:"Add alt to every <img> (alt='' if decorative); prefer <Avatar>/<AspectRatio>."},{id:"no-positive-tabindex",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 2.4.3 \xB7 WAI-ARIA APG",fix:"Use tabIndex 0 or -1 only; never positive \u2014 it breaks focus order."},{id:"hand-rolled-close-glyph",severity:"warn",category:"a11y",standard:"WAI-ARIA 1.2 (dialog) \xB7 WCAG 2.2 SC 4.1.2",fix:"Pass onDismiss to <Alert>, or use <Dialog>/<Sheet>'s built-in labelled close \u2014 not a bare \u2715."},{id:"no-emoji-in-ui",severity:"warn",category:"i18n",standard:"Unicode UTS #51 \xB7 WCAG 2.2 SC 1.1.1",fix:"No emoji in product UI; quiet i18n copy + Lucide icon + Badge tone."},{id:"no-emoji-flag",severity:"warn",category:"i18n",standard:"ISO 3166-1 \xB7 ECMA-402 Intl.DisplayNames \xB7 Unicode UTS #51",fix:"Derive country names from Intl.DisplayNames; no emoji flags."},{id:"hardcoded-currency",severity:"warn",category:"i18n",standard:"ISO 4217 \xB7 ECMA-402 Intl.NumberFormat",fix:"Format money with Intl.NumberFormat({ style: 'currency', currency }), not \xA5{amount}."},{id:"raw-intl-date",severity:"warn",category:"i18n",standard:"ISO 8601 \xB7 IANA tz \xB7 ECMA-402 Intl.DateTimeFormat",fix:"Use formatDate from @godxjp/ui/datetime, not hand-built or locale-default dates."},{id:"no-physical-direction",severity:"warn",category:"rtl",standard:"W3C CSS Logical Properties L1 \xB7 WCAG 2.2 (1.3.2)",fix:"Use logical utilities (ms-/me-/ps-/pe-, start-/end-, text-start/end, border-s/e, rounded-s/e)."},{id:"no-em-dash-in-copy",severity:"warn",category:"copy",standard:"@godxjp/ui reference-design typography",fix:"No em-dash (\u2014) in copy; use a middot \xB7 or two calm sentences."}];function Y(t){return t?$.filter(a=>a.category===t):$}var X="node node_modules/@godxjp/ui/scripts/visual-audit.mjs <baseUrl> [route \u2026] (optional peers, TESTED range: playwright >=1.55 <2 [1.61.1] + @axe-core/playwright >=4.10 <5 [4.12.1] + axe-core >=4.10 <5 [4.12.1] + a chromium via `playwright install chromium`; --strict for a CI gate, --format json ALWAYS emits valid JSON with a status of ok|partial|error separating infra errors[] from product findings[], --rules to print this catalog)",Q=[{id:"axe-violations",severity:"warn",category:"a11y",standard:"WCAG 2.2 A/AA \xB7 WAI-ARIA 1.2 (axe-core engine)",fix:"Fix each axe node \u2014 contrast (1.4.3), name/role/value (4.1.2), ARIA, landmarks. Runs on the REAL DOM, catching what static analysis cannot."},{id:"target-size-min",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 2.5.8 (24\xD724 AA) \xB7 2.5.5 (44\xD744 AAA)",fix:"Interactive targets must be \u226524\xD724 CSS px; size from the --control-height tier."},{id:"oversaturated-accent",severity:"warn",category:"color",standard:"@godxjp/ui reference-design \u6E0B\u307F (OKLCH chroma \u2264 0.18)",fix:"Desaturate brand/primary surfaces (OKLCH chroma \u2264 0.18); read --primary tokens, no raw vivid bars."},{id:"emoji-rendered",severity:"warn",category:"i18n",standard:"Unicode UTS #51 \xB7 WCAG 2.2 SC 1.1.1",fix:"Remove emoji from rendered product text; quiet i18n copy + Lucide icon + Badge tone."},{id:"alert-controls-misplaced",severity:"warn",category:"layout",standard:"@godxjp/ui Alert anatomy \xB7 WAI-ARIA 1.2 \xB7 WCAG 2.2 SC 4.1.2",fix:"Use <Alert>: one leading tone icon, <Alert.Actions> trailing-right normal width, onDismiss \xD7 top-right, one horizontal row."}];function J(t){return t?Q.filter(a=>a.category===t):Q}var m={name:"@godxjp/ui-mcp",version:"18.6.0",godxUiCompatibility:"18.6.x",description:"Model Context Protocol server for @godxjp/ui \u2014 gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 45 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 \u2014 token-efficient (list \u2192 drill-down).",type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",bin:{"godx-ui-mcp":"./dist/index.js"},files:["dist","README.md"],publishConfig:{registry:"https://registry.npmjs.org/",access:"public"},repository:{type:"git",url:"git+https://github.com/godx-jp/godxjp-ui.git",directory:"mcp"},homepage:"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme",license:"Apache-2.0",scripts:{build:"tsup",dev:"tsup --watch",start:"node dist/index.js",inspect:"npx @modelcontextprotocol/inspector node dist/index.js","type-check":"tsc --noEmit",test:"vitest run",prepublishOnly:"npm run build"},dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",zod:"^4.4.3"},devDependencies:{"@types/node":"^22.10.0",tsup:"^8.5.1",typescript:"^6.0.3",vitest:"^4.1.6"},keywords:["mcp","model-context-protocol","godxjp","ui","design-system","react","claude","cursor"]};var ee=[{name:"list_skills",description:"List every design/taste skill bundled by this MCP (id + name + whenToUse + section ids). Use FIRST to discover skills; then `get_skill_section` to drill in.",inputSchema:{type:"object",properties:{}}},{name:"list_primitives",description:"List every @godxjp/ui primitive/composite/shell (group + tagline per entry). Optionally filter by group. Then `get_component` for one's full API.",inputSchema:{type:"object",properties:{group:{type:"string",enum:["general","layout","data-display","data-entry","feedback","navigation","composites","shell","providers"]}}}},{name:"list_patterns",description:"List every canonical copy-paste code pattern (signup-form, settings-page, data-table-page, async-data-state, confirm-destructive, \u2026); common aliases resolve too. Use before `get_pattern`.",inputSchema:{type:"object",properties:{}}},{name:"list_anti_ai_tells",description:"List every AI-tell pattern to AVOID (optionally by category). Use to self-audit a design before shipping; then `get_anti_ai_tell` for the fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["visual","layout","copy","interaction","imagery","structure"]}}}},{name:"list_redesign_checks",description:"List the redesign audit checklist (50+ checks; optionally by category). Use when auditing an existing project; then `get_redesign_check` for a symptom's fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["typography","color-surface","layout","interactivity","content","components","iconography","code-quality","omissions"]}}}},{name:"list_audit_rules",description:"List the LOCAL static ui-audit rules (scripts/ui-audit.mjs) to run BEFORE any visual review \u2014 each cites the standard it enforces (WCAG/WAI-ARIA/Intl/ISO/IANA/CSS-Logical) + a fix + the run command. Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["tokens","composition","api","a11y","i18n","rtl","copy"]}}}},{name:"list_visual_checks",description:"List the RUNTIME visual-audit checks (scripts/visual-audit.mjs \u2014 Playwright + axe-core) to run against the RUNNING app: contrast/ARIA (axe), target size, rendered-accent chroma, DOM emoji, banner layout. Needs a browser (vs list_audit_rules, static). Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["a11y","color","i18n","layout"]}}}},{name:"get_anti_ai_tell",description:"Fetch ONE anti-AI-tell \u2014 full body + concrete fix. Use after `list_anti_ai_tells`.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Exact tell name from list_anti_ai_tells."}},required:["name"]}},{name:"get_redesign_check",description:"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.",inputSchema:{type:"object",properties:{symptom:{type:"string",description:"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh')."}},required:["symptom"]}},{name:"get_skill_section",description:"Fetch ONE section of ONE skill \u2014 token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Skill id (e.g. 'soft', 'minimalist', 'taste')."},section:{type:"string",description:"Section id within that skill."}},required:["skill","section"]}},{name:"get_component",description:"Full guide for one @godxjp/ui component \u2014 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. Design-token knobs are listed compactly (name+default); pass `verbose:true` for what each token controls.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Component name (e.g. 'Button', 'DataTable')."},verbose:{type:"boolean",description:"Include the full design-token table with a 'what it controls' description per token. Default false (compact token+default only) to save context."}},required:["name"]}},{name:"get_pattern",description:"Full code snippet for one canonical pattern \u2014 copy-paste-ready.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Pattern slug (use list_patterns first)."}},required:["name"]}},{name:"get_rule",description:"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Rule number (1-N)."}}}},{name:"get_vocab",description:"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Vocab type name."}}}},{name:"get_tokens",description:"Read design tokens, optionally filtered by tier category (primitive / semantic / component).",inputSchema:{type:"object",properties:{category:{type:"string",enum:["primitive","semantic","component"]}}}},{name:"list_consumer_skills",description:"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, \u2026). Returns id + name + whenToUse + section ids.",inputSchema:{type:"object",properties:{}}},{name:"get_consumer_skill",description:"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.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen')."},section:{type:"string",description:"Section id within that skill."}},required:["skill"]}},{name:"route_consumer_task",description:"Natural-language task \u2192 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.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"draft_bug_report",description:"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 \u2014 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.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"One-line title of the bug / blocked rule."},repro:{type:"string",description:"Minimal steps or code to reproduce."},expected:{type:"string",description:"What SHOULD happen (per the rule/spec)."},actual:{type:"string",description:"What actually happens."},component:{type:"string",description:"Affected component name, if any (links to get_component)."},rule:{type:"number",description:"Cardinal rule number that can't be followed, if any."},version:{type:"string",description:"Installed @godxjp/ui version (e.g. '12.1.0')."},env:{type:"string",description:"Environment (browser/OS/framework), if relevant."}},required:["summary"]}},{name:"check_compatibility",description:"Report whether the @godxjp/ui version installed in the target project matches THIS catalog (which describes one release train). A mismatched minor means the props/tokens/patterns may describe a build they never installed (#140). Pass the installed version (`npm ls @godxjp/ui`); call it at the START of a consumer session.",inputSchema:{type:"object",properties:{version:{type:"string",description:"Installed @godxjp/ui version in the target project, e.g. '16.10.0'. Omit to just read the catalog's own version + compatible range."}}}},{name:"route_task",description:"Natural-language task \u2192 skill+section pointer (e.g. 'design a premium agency hero' \u2192 soft/vibe-archetypes). Use FIRST when you don't know which skill applies.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"suggest_primitive",description:"Use case \u2192 primitive recommendation. E.g. 'confirm a destructive delete' \u2192 DangerZone pattern + Dialog suggestion.",inputSchema:{type:"object",properties:{use_case:{type:"string"}},required:["use_case"]}},{name:"search_components",description:"Fuzzy-search primitives by name / tagline / prop. Returns ranked matches.",inputSchema:{type:"object",properties:{query:{type:"string"}},required:["query"]}},{name:"get_frame_coverage",description:"Verified preview-contract coverage for a component (issue #163). Answers 'is this state actually PROVEN?' \u2014 returns, per contract dimension (variants, tones, sizes, shapes, density, controlled/uncontrolled ownership, disabled/read-only/loading/empty/error/success, async retry/cancel/offline, responsive viewport matrix, RTL, long/localized content, keyboard/focus, accessible name/description/error, reduced motion / coarse touch), whether an EXECUTED case proves it (covered), whether nothing proves it (UNTESTED), or whether it cannot exist (not-applicable, with a reason). UNTESTED IS NOT A PASS: never infer that a component supports a state because an example renders. Call this before telling a user a component 'supports' anything. Omit `name` for the repo-wide summary and the tracked known gaps.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Public export name (e.g. 'Button', 'DataTable', 'CardFooter'). Omit for the repo-wide coverage summary."}}}},{name:"lint_jsx",description:"Heuristic check of a JSX snippet for common violations \u2014 raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.",inputSchema:{type:"object",properties:{jsx:{type:"string"}},required:["jsx"]}}];async function te(t,a){switch(t){case"list_skills":return ce();case"list_primitives":return ae(a.group);case"list_patterns":return ge();case"list_anti_ai_tells":return fe(a.category);case"list_redesign_checks":return we(a.category);case"list_audit_rules":return ye(a.category);case"list_visual_checks":return be(a.category);case"get_anti_ai_tell":return ve(String(a.name??""));case"get_redesign_check":return ke(String(a.symptom??""));case"get_skill_section":return oe(String(a.skill??""),String(a.section??""));case"get_component":return Ce(String(a.name??""),a.verbose===!0);case"get_pattern":return De(String(a.name??""));case"get_rule":return Ne(typeof a.number=="number"?a.number:void 0);case"get_vocab":return Oe(a.name==null?void 0:String(a.name));case"get_tokens":return Ie(a.category);case"list_consumer_skills":return pe();case"get_consumer_skill":return he(String(a.skill??""),String(a.section??""));case"route_consumer_task":return Z(String(a.task??""),{consumerOnly:!0});case"draft_bug_report":return ue(a);case"check_compatibility":return me(a.version==null?void 0:String(a.version));case"route_task":return Z(String(a.task??""));case"suggest_primitive":return Pe(String(a.use_case??""));case"search_components":return Re(String(a.query??""));case"get_frame_coverage":return Ae(a.name===void 0?void 0:String(a.name));case"lint_jsx":return Ee(String(a.jsx??""));default:return`Unknown tool: ${t}`}}function ce(){let t=`# Available skills (${x.length})
3869
+ improves.`}];function H(t){return D.filter(a=>a.category===t)}var R=[{category:"typography",symptom:"Inter / Roboto / Open Sans everywhere \u2014 the AI default.",fix:"Pick a font with character: Geist, Outfit, Cabinet Grotesk, Satoshi for sans. For editorial / creative \u2014 pair a serif heading (Newsreader, Lyon, Playfair) with a sans body.",uiNote:"Override --font-sans + --font-serif at the consumer's root CSS. Framework reads from these tokens."},{category:"typography",symptom:"Headlines lack presence \u2014 small + thin + default tracking.",fix:"Increase display size, tighten letter-spacing (-0.02em to -0.04em), reduce line-height (1.1). Headlines should feel HEAVY and INTENTIONAL.",uiNote:"Typography.Title size={1} for hero; override fontFamily + letterSpacing inline."},{category:"typography",symptom:"Body paragraphs full-width \u2014 hard to read.",fix:"Limit paragraph max-width to ~65ch. Increase line-height to 1.6+.",uiNote:"Wrap Typography.Paragraph in `<div style={{ maxWidth: '65ch' }}>`."},{category:"typography",symptom:"Only Regular (400) + Bold (700) weights \u2014 flat hierarchy.",fix:"Introduce Medium (500) + SemiBold (600) for subtle weight contrasts."},{category:"typography",symptom:"Numbers in proportional font \u2014 columns jitter in tables.",fix:"`font-variant-numeric: tabular-nums` for data, or a monospace font like Geist Mono.",uiNote:"Table primitive already uses `tabular-nums` on `.num` cells. For ad-hoc numeric labels, add the CSS prop manually."},{category:"typography",symptom:"Orphaned words \u2014 single word on the last line of a heading.",fix:"`text-wrap: balance` (h1/h2/h3) or `text-wrap: pretty` (body)."},{category:"typography",symptom:"Title Case On Every Header.",fix:"Use sentence case instead. More modern, easier to read."},{category:"color-surface",symptom:"Pure #000000 background.",fix:"Replace with off-black (#0A0A0A) / dark charcoal (#121212) / tinted dark (deep navy).",uiNote:"Framework dark theme already uses tinted dark values \u2014 verify the consumer's override didn't force pure black."},{category:"color-surface",symptom:"Oversaturated accent colors.",fix:"Keep saturation below 80%. Desaturate so accents BLEND with neutrals rather than scream."},{category:"color-surface",symptom:"More than one accent color competing.",fix:"Pick ONE. Remove the rest. Consistency beats variety in palette.",uiNote:"Set ONE `data-accent` at `<html>` root. Use semantic colors (success / warning / destructive) only for genuinely semantic content."},{category:"color-surface",symptom:"Purple/blue 'AI gradient' aesthetic \u2014 most common AI fingerprint.",fix:"Replace with neutral base + ONE considered accent. Drop the gradient entirely if it has no narrative purpose."},{category:"color-surface",symptom:"Generic black `box-shadow` everywhere.",fix:"Tint shadow to match background hue (e.g. cool gray bg \u2192 cool gray shadow). Colored shadows over pure black."},{category:"color-surface",symptom:"Random dark section breaking an otherwise light page.",fix:"Either commit to full dark mode OR keep light consistently. If contrast needed, use a SLIGHTLY darker shade of the same palette \u2014 not a sudden jump to #111."},{category:"color-surface",symptom:"Empty flat sections with no visual depth.",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."},{category:"layout",symptom:"Everything centered + symmetric.",fix:"Break symmetry: offset margins, mixed aspect ratios, left-aligned header over centered body."},{category:"layout",symptom:"Three equal card columns as feature row \u2014 the most generic AI layout.",fix:"Replace with 2-column zig-zag, asymmetric grid, horizontal scroll, or masonry. The 3-equal-cols pattern is RED FLAG #1.",uiNote:"Use Bento Grid (custom CSS grid with `gridColumn: 'span N'`) instead of `<Grid cols={3}>` for hero sections."},{category:"layout",symptom:"`height: 100vh` causing iOS Safari jump.",fix:"Use `min-height: 100dvh` (dynamic viewport) instead."},{category:"layout",symptom:"No max-width container \u2014 content stretches edge-to-edge.",fix:"Add a container constraint (1200-1440px) with `margin: auto`. Or use `max-w-4xl / max-w-5xl` for content-heavy pages.",uiNote:"Framework's PageContent constrains via `var(--container-max-width)`. Consumer may override."},{category:"layout",symptom:"Cards forced to same height by flexbox.",fix:"Allow variable heights or use masonry when content varies.",uiNote:"Use Masonry primitive \u2014 handles variable heights without flexbox stretch."},{category:"layout",symptom:"Buttons at random vertical positions in card rows.",fix:"Pin CTAs to card bottom \u2014 same Y-position across the row regardless of content above.",uiNote:"Card's `actions` footer slot bottom-aligns automatically."},{category:"layout",symptom:"Feature lists starting at different vertical positions in pricing tables.",fix:"Fixed-height title/price block + consistent spacing above the feature list. Cards align across columns."},{category:"layout",symptom:"Dashboard ALWAYS has a left sidebar.",fix:"Consider top navigation, floating command menu, or collapsible panel. Sidebar isn't the only chrome.",uiNote:"Framework supports both \u2014 AppShell with sidebar slot is optional; can use Topbar-only for some flows."},{category:"interactivity",symptom:"No hover states on buttons.",fix:"Background shift, scale, or translate on hover \u2014 150-200ms ease.",uiNote:"Framework Button has built-in hover. If overridden \u2014 restore."},{category:"interactivity",symptom:"No active/pressed feedback.",fix:"`scale(0.98)` or `translateY(1px)` on `:active`. Simulates a physical click."},{category:"interactivity",symptom:"No focus ring (`outline: none`).",fix:"Restore visible `:focus-visible` ring. Accessibility requirement, not optional."},{category:"interactivity",symptom:"Generic circular spinner for page-level loading.",fix:"Replace with Skeleton placeholders matching the eventual content shape.",uiNote:"Framework Skeleton + Form `loading={{ kind: 'skeleton' }}` handles cascading initial-fetch state."},{category:"interactivity",symptom:"No empty states \u2014 empty dashboard shows nothing.",fix:"Design a composed 'getting started' view: Empty primitive with title + description + next-action button."},{category:"interactivity",symptom:"`window.alert()` for errors.",fix:"Inline error in the relevant Field, OR toast for non-form errors, OR Dialog for blocking errors."},{category:"interactivity",symptom:"Dead links (`href='#'`).",fix:"Either link to real destinations or visually disable the button."},{category:"interactivity",symptom:"No indication of current page in navigation.",fix:"Style the active nav link distinctly.",uiNote:"Sidebar handles via `activeId` \u2014 pass it."},{category:"content",symptom:"Generic names \u2014 'John Doe', 'Jane Smith'.",fix:"Diverse, realistic names. For Japanese apps: \u7530\u4E2D \u592A\u90CE, \u4F50\u85E4 \u7F8E\u54B2, Nguy\u1EC5n Lan, Maria Cruz."},{category:"content",symptom:"Fake round numbers \u2014 '99.99%', '50%', '$100.00'.",fix:"Organic data: '47.2%', '$99.00', '+1 (312) 847-1928'."},{category:"content",symptom:"Placeholder brand names \u2014 Acme, Nexus, SmartFlow.",fix:"Invent contextual believable brands or use the consumer's real brand."},{category:"content",symptom:"AI copy clich\xE9s \u2014 'elevate', 'seamless', 'unleash', 'next-gen', 'game-changer', 'delve', 'tapestry', 'in the world of'.",fix:"Plain specific language. Numbers, nouns, verbs.",uiNote:"Framework's cardinal rule 9 bans this in framework docs; same discipline applies to consumer copy."},{category:"content",symptom:"Exclamation marks in success messages.",fix:"Remove. Be confident, not loud."},{category:"content",symptom:"'Oops!' or apologetic error messages.",fix:"Direct + specific: 'Connection failed. Please try again.' / '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306E\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093'."},{category:"content",symptom:"Lorem Ipsum.",fix:"Real draft copy. Even rough placeholder beats Latin."},{category:"components",symptom:"Generic card look (border + shadow + white).",fix:"Remove border OR shadow OR background \u2014 keep ONE. Cards exist only when elevation communicates hierarchy."},{category:"components",symptom:"Always one filled + one ghost button.",fix:"Add text links / tertiary styles for variety.",uiNote:"Button has `variant='link'` for tertiary actions."},{category:"components",symptom:"3-card carousel testimonials with dots.",fix:"Replace with masonry wall of quotes, embedded social posts, or single rotating quote."},{category:"components",symptom:"Pricing table with 3 equal towers.",fix:"Highlight recommended tier with COLOR and emphasis, not just extra height."},{category:"components",symptom:"Modals for everything.",fix:"Use inline editing, Sheet (slide-over), or expandable Collapse for simple actions. Reserve Dialog for true blocking decisions."},{category:"components",symptom:"Footer link farm with 4 columns.",fix:"Simplify. Main nav paths + legally required links. No marketing kitchen sink."},{category:"iconography",symptom:"Lucide or Feather icons exclusively.",fix:"Use Phosphor (Bold / Fill), Heroicons, or a custom set. AI default tell.",uiNote:"Framework ships with lucide as locked dependency (rule 14). For editorial differentiation, layer Phosphor on top."},{category:"iconography",symptom:"Cliche icon metaphors \u2014 rocketship 'launch', shield 'security'.",fix:"Less obvious: bolt, fingerprint, spark, vault, gem."},{category:"iconography",symptom:"Stock 'diverse team in office' photo.",fix:"Real team photos, candid shots, or a consistent illustration style. Avatar initials fallback > generic stock person."},{category:"code-quality",symptom:"Div soup \u2014 no semantic HTML.",fix:"`<nav>`, `<main>`, `<article>`, `<aside>`, `<section>` for landmarks.",uiNote:"AppShell renders the canonical landmark structure automatically."},{category:"code-quality",symptom:"Inline styles mixed with CSS classes haphazardly.",fix:"Move styling into the project's system. Inline `style={{}}` only for layout / positioning (rule 29)."},{category:"code-quality",symptom:"Missing alt text on images.",fix:"Describe content for SR. Never leave `alt=''` or `alt='image'` on meaningful images."},{category:"code-quality",symptom:"Arbitrary z-index values like `9999`.",fix:"Establish a clean z-index scale in CSS variables."},{category:"omissions",symptom:"No legal links in footer.",fix:"Add Privacy Policy + Terms of Service."},{category:"omissions",symptom:"Dead ends in user flows \u2014 no 'back'.",fix:"Every page has a way back. Breadcrumb, back button, OR clear nav state."},{category:"omissions",symptom:"No custom 404 page.",fix:"Design a helpful branded 404 with a way home and search."},{category:"omissions",symptom:"No form validation.",fix:"Client-side validation via zod schema. Framework's Form + FormField handle field-level errors automatically."},{category:"omissions",symptom:"No 'skip to content' link.",fix:"Hidden skip-link, first focusable element. Essential for keyboard users.",uiNote:"AppShell renders one automatically."}],G=["1. Font swap \u2014 biggest instant improvement, lowest risk","2. Color palette cleanup \u2014 remove clashing / oversaturated colors","3. Hover + active states \u2014 makes the interface feel alive","4. Layout + spacing \u2014 proper grid, max-width, consistent padding","5. Replace generic components \u2014 swap cliche patterns for modern alternatives","6. Add loading, empty, error states \u2014 makes it feel finished","7. Polish typography scale + spacing \u2014 the premium final touch"],W=["Work with the existing tech stack. Do NOT migrate frameworks or styling libraries.","Do NOT break existing functionality. Test after every change.","Before importing any new library, check `package.json` first.","Keep changes reviewable + focused. Small targeted improvements over big rewrites.","Run the audit before fixing \u2014 listing issues first prevents accidental scope creep."];function _(t){return R.filter(a=>a.category===t)}var K="node node_modules/@godxjp/ui/scripts/ui-audit.mjs (add --format json for machine output, --rules to print this catalog)",$=[{id:"no-raw-palette-color",severity:"error",category:"tokens",standard:null,fix:"Use semantic tokens (bg-primary, text-muted-foreground), never raw palette (bg-blue-500)."},{id:"no-arbitrary-hex",severity:"error",category:"tokens",standard:null,fix:"No hardcoded hex in className; read design-system color tokens."},{id:"no-arbitrary-spacing",severity:"error",category:"tokens",standard:null,fix:"No p-[13px]/gap-[7px]; use the token scale / <Flex gap> / <PageContainer>."},{id:"no-arbitrary-size",severity:"error",category:"tokens",standard:null,fix:"No w-[37px]/h-[260px]; use token sizes or a sizing prop (min-w-[\u2026] allowed)."},{id:"no-arbitrary-typography",severity:"error",category:"tokens",standard:null,fix:"No text-[20px]/leading-[1.7]; use the golden-ratio type-scale tokens."},{id:"no-arbitrary-radius",severity:"error",category:"tokens",standard:null,fix:"No rounded-[6px]; use rounded-sm/md/lg radius tokens."},{id:"no-dark-color-override",severity:"warn",category:"tokens",standard:null,fix:"Drop dark: color overrides \u2014 semantic tokens already adapt."},{id:"raw-white-black",severity:"warn",category:"tokens",standard:null,fix:"Prefer semantic tokens (text-primary-foreground, bg-background) over raw white/black."},{id:"no-domain-tracking-token",severity:"error",category:"tokens",standard:null,fix:"No package-tracking/domain tokens; use semantic tokens or app theme overrides."},{id:"no-space-xy",severity:"error",category:"tokens",standard:null,fix:"Use <Flex gap> instead of space-x/y-*."},{id:"no-raw-select",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Select> from @godxjp/ui, not a raw <select>."},{id:"no-raw-table",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use the <Table>/<DataTable> family, not a raw <table>."},{id:"no-raw-input",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Input> from @godxjp/ui, not a raw <input>."},{id:"no-raw-textarea",severity:"warn",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Textarea> from @godxjp/ui, not a raw <textarea>."},{id:"no-raw-button",severity:"error",category:"composition",standard:"HTML Living Standard (WHATWG)",fix:"Use <Button> from @godxjp/ui, not a raw <button>."},{id:"card-manual-padding",severity:"error",category:"composition",standard:null,fix:"Wrap the body in <CardContent>; don't hand-roll padding on <Card>."},{id:"card-needs-content",severity:"error",category:"composition",standard:null,fix:"<Card> body must be in <CardContent> (no padding otherwise); flush only for a full-bleed table."},{id:"bare-control-needs-formfield",severity:"warn",category:"composition",standard:"WCAG 2.2 SC 1.3.1 \xB7 3.3.2 \xB7 @godxjp/ui FormField (cardinal rule 227)",fix:"Wrap a labelled control in <FormField label=\u2026> \u2014 it owns label\u2194control id wiring, aria/error, AND the field rhythm; never pair a bare <Label> with an <Input>."},{id:"manual-field-error",severity:"warn",category:"composition",standard:"WCAG 2.2 SC 3.3.1",fix:"Use <FormField error=\u2026>, not a hand-rolled <p class='text-destructive'>."},{id:"manual-field-helper",severity:"warn",category:"composition",standard:null,fix:"Use <FormField helper=\u2026>, not a hand-rolled helper <p>."},{id:"status-tone-not-variant",severity:"error",category:"api",standard:null,fix:"Badge/Tag/StatCard status uses tone, not variant (variant is structural)."},{id:"value-callback-on-value-change",severity:"error",category:"api",standard:null,fix:"Abstract value components use onValueChange, not onChange."},{id:"icon-button-needs-name",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 4.1.2 \xB7 1.1.1 \xB7 WAI-ARIA 1.2",fix:"Add aria-label={t('\u2026')} to <Button size='icon'>; the glyph is aria-hidden."},{id:"img-needs-alt",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 1.1.1 \xB7 HTML Living Standard",fix:"Add alt to every <img> (alt='' if decorative); prefer <Avatar>/<AspectRatio>."},{id:"no-positive-tabindex",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 2.4.3 \xB7 WAI-ARIA APG",fix:"Use tabIndex 0 or -1 only; never positive \u2014 it breaks focus order."},{id:"hand-rolled-close-glyph",severity:"warn",category:"a11y",standard:"WAI-ARIA 1.2 (dialog) \xB7 WCAG 2.2 SC 4.1.2",fix:"Pass onDismiss to <Alert>, or use <Dialog>/<Sheet>'s built-in labelled close \u2014 not a bare \u2715."},{id:"no-emoji-in-ui",severity:"warn",category:"i18n",standard:"Unicode UTS #51 \xB7 WCAG 2.2 SC 1.1.1",fix:"No emoji in product UI; quiet i18n copy + Lucide icon + Badge tone."},{id:"no-emoji-flag",severity:"warn",category:"i18n",standard:"ISO 3166-1 \xB7 ECMA-402 Intl.DisplayNames \xB7 Unicode UTS #51",fix:"Derive country names from Intl.DisplayNames; no emoji flags."},{id:"hardcoded-currency",severity:"warn",category:"i18n",standard:"ISO 4217 \xB7 ECMA-402 Intl.NumberFormat",fix:"Format money with Intl.NumberFormat({ style: 'currency', currency }), not \xA5{amount}."},{id:"raw-intl-date",severity:"warn",category:"i18n",standard:"ISO 8601 \xB7 IANA tz \xB7 ECMA-402 Intl.DateTimeFormat",fix:"Use formatDate from @godxjp/ui/datetime, not hand-built or locale-default dates."},{id:"no-physical-direction",severity:"warn",category:"rtl",standard:"W3C CSS Logical Properties L1 \xB7 WCAG 2.2 (1.3.2)",fix:"Use logical utilities (ms-/me-/ps-/pe-, start-/end-, text-start/end, border-s/e, rounded-s/e)."},{id:"no-em-dash-in-copy",severity:"warn",category:"copy",standard:"@godxjp/ui reference-design typography",fix:"No em-dash (\u2014) in copy; use a middot \xB7 or two calm sentences."}];function Y(t){return t?$.filter(a=>a.category===t):$}var X="node node_modules/@godxjp/ui/scripts/visual-audit.mjs <baseUrl> [route \u2026] (optional peers, TESTED range: playwright >=1.55 <2 [1.61.1] + @axe-core/playwright >=4.10 <5 [4.12.1] + axe-core >=4.10 <5 [4.12.1] + a chromium via `playwright install chromium`; --strict for a CI gate, --format json ALWAYS emits valid JSON with a status of ok|partial|error separating infra errors[] from product findings[], --rules to print this catalog)",Q=[{id:"axe-violations",severity:"warn",category:"a11y",standard:"WCAG 2.2 A/AA \xB7 WAI-ARIA 1.2 (axe-core engine)",fix:"Fix each axe node \u2014 contrast (1.4.3), name/role/value (4.1.2), ARIA, landmarks. Runs on the REAL DOM, catching what static analysis cannot."},{id:"target-size-min",severity:"warn",category:"a11y",standard:"WCAG 2.2 SC 2.5.8 (24\xD724 AA) \xB7 2.5.5 (44\xD744 AAA)",fix:"Interactive targets must be \u226524\xD724 CSS px; size from the --control-height tier."},{id:"oversaturated-accent",severity:"warn",category:"color",standard:"@godxjp/ui reference-design \u6E0B\u307F (OKLCH chroma \u2264 0.18)",fix:"Desaturate brand/primary surfaces (OKLCH chroma \u2264 0.18); read --primary tokens, no raw vivid bars."},{id:"emoji-rendered",severity:"warn",category:"i18n",standard:"Unicode UTS #51 \xB7 WCAG 2.2 SC 1.1.1",fix:"Remove emoji from rendered product text; quiet i18n copy + Lucide icon + Badge tone."},{id:"alert-controls-misplaced",severity:"warn",category:"layout",standard:"@godxjp/ui Alert anatomy \xB7 WAI-ARIA 1.2 \xB7 WCAG 2.2 SC 4.1.2",fix:"Use <Alert>: one leading tone icon, <Alert.Actions> trailing-right normal width, onDismiss \xD7 top-right, one horizontal row."}];function J(t){return t?Q.filter(a=>a.category===t):Q}var m={name:"@godxjp/ui-mcp",version:"18.7.0",godxUiCompatibility:"18.7.x",description:"Model Context Protocol server for @godxjp/ui \u2014 gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 45 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 \u2014 token-efficient (list \u2192 drill-down).",type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",bin:{"godx-ui-mcp":"./dist/index.js"},files:["dist","README.md"],publishConfig:{registry:"https://registry.npmjs.org/",access:"public"},repository:{type:"git",url:"git+https://github.com/godx-jp/godxjp-ui.git",directory:"mcp"},homepage:"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme",license:"Apache-2.0",scripts:{build:"tsup",dev:"tsup --watch",start:"node dist/index.js",inspect:"npx @modelcontextprotocol/inspector node dist/index.js","type-check":"tsc --noEmit",test:"vitest run",prepublishOnly:"npm run build"},dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",zod:"^4.4.3"},devDependencies:{"@types/node":"^22.10.0",tsup:"^8.5.1",typescript:"^6.0.3",vitest:"^4.1.6"},keywords:["mcp","model-context-protocol","godxjp","ui","design-system","react","claude","cursor"]};var ee=[{name:"list_skills",description:"List every design/taste skill bundled by this MCP (id + name + whenToUse + section ids). Use FIRST to discover skills; then `get_skill_section` to drill in.",inputSchema:{type:"object",properties:{}}},{name:"list_primitives",description:"List every @godxjp/ui primitive/composite/shell (group + tagline per entry). Optionally filter by group. Then `get_component` for one's full API.",inputSchema:{type:"object",properties:{group:{type:"string",enum:["general","layout","data-display","data-entry","feedback","navigation","composites","shell","providers"]}}}},{name:"list_patterns",description:"List every canonical copy-paste code pattern (signup-form, settings-page, data-table-page, async-data-state, confirm-destructive, \u2026); common aliases resolve too. Use before `get_pattern`.",inputSchema:{type:"object",properties:{}}},{name:"list_anti_ai_tells",description:"List every AI-tell pattern to AVOID (optionally by category). Use to self-audit a design before shipping; then `get_anti_ai_tell` for the fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["visual","layout","copy","interaction","imagery","structure"]}}}},{name:"list_redesign_checks",description:"List the redesign audit checklist (50+ checks; optionally by category). Use when auditing an existing project; then `get_redesign_check` for a symptom's fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["typography","color-surface","layout","interactivity","content","components","iconography","code-quality","omissions"]}}}},{name:"list_audit_rules",description:"List the LOCAL static ui-audit rules (scripts/ui-audit.mjs) to run BEFORE any visual review \u2014 each cites the standard it enforces (WCAG/WAI-ARIA/Intl/ISO/IANA/CSS-Logical) + a fix + the run command. Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["tokens","composition","api","a11y","i18n","rtl","copy"]}}}},{name:"list_visual_checks",description:"List the RUNTIME visual-audit checks (scripts/visual-audit.mjs \u2014 Playwright + axe-core) to run against the RUNNING app: contrast/ARIA (axe), target size, rendered-accent chroma, DOM emoji, banner layout. Needs a browser (vs list_audit_rules, static). Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["a11y","color","i18n","layout"]}}}},{name:"get_anti_ai_tell",description:"Fetch ONE anti-AI-tell \u2014 full body + concrete fix. Use after `list_anti_ai_tells`.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Exact tell name from list_anti_ai_tells."}},required:["name"]}},{name:"get_redesign_check",description:"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.",inputSchema:{type:"object",properties:{symptom:{type:"string",description:"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh')."}},required:["symptom"]}},{name:"get_skill_section",description:"Fetch ONE section of ONE skill \u2014 token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Skill id (e.g. 'soft', 'minimalist', 'taste')."},section:{type:"string",description:"Section id within that skill."}},required:["skill","section"]}},{name:"get_component",description:"Full guide for one @godxjp/ui component \u2014 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. Design-token knobs are listed compactly (name+default); pass `verbose:true` for what each token controls.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Component name (e.g. 'Button', 'DataTable')."},verbose:{type:"boolean",description:"Include the full design-token table with a 'what it controls' description per token. Default false (compact token+default only) to save context."}},required:["name"]}},{name:"get_pattern",description:"Full code snippet for one canonical pattern \u2014 copy-paste-ready.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Pattern slug (use list_patterns first)."}},required:["name"]}},{name:"get_rule",description:"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Rule number (1-N)."}}}},{name:"get_vocab",description:"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Vocab type name."}}}},{name:"get_tokens",description:"Read design tokens, optionally filtered by tier category (primitive / semantic / component).",inputSchema:{type:"object",properties:{category:{type:"string",enum:["primitive","semantic","component"]}}}},{name:"list_consumer_skills",description:"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, \u2026). Returns id + name + whenToUse + section ids.",inputSchema:{type:"object",properties:{}}},{name:"get_consumer_skill",description:"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.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen')."},section:{type:"string",description:"Section id within that skill."}},required:["skill"]}},{name:"route_consumer_task",description:"Natural-language task \u2192 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.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"draft_bug_report",description:"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 \u2014 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.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"One-line title of the bug / blocked rule."},repro:{type:"string",description:"Minimal steps or code to reproduce."},expected:{type:"string",description:"What SHOULD happen (per the rule/spec)."},actual:{type:"string",description:"What actually happens."},component:{type:"string",description:"Affected component name, if any (links to get_component)."},rule:{type:"number",description:"Cardinal rule number that can't be followed, if any."},version:{type:"string",description:"Installed @godxjp/ui version (e.g. '12.1.0')."},env:{type:"string",description:"Environment (browser/OS/framework), if relevant."}},required:["summary"]}},{name:"check_compatibility",description:"Report whether the @godxjp/ui version installed in the target project matches THIS catalog (which describes one release train). A mismatched minor means the props/tokens/patterns may describe a build they never installed (#140). Pass the installed version (`npm ls @godxjp/ui`); call it at the START of a consumer session.",inputSchema:{type:"object",properties:{version:{type:"string",description:"Installed @godxjp/ui version in the target project, e.g. '16.10.0'. Omit to just read the catalog's own version + compatible range."}}}},{name:"route_task",description:"Natural-language task \u2192 skill+section pointer (e.g. 'design a premium agency hero' \u2192 soft/vibe-archetypes). Use FIRST when you don't know which skill applies.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"suggest_primitive",description:"Use case \u2192 primitive recommendation. E.g. 'confirm a destructive delete' \u2192 DangerZone pattern + Dialog suggestion.",inputSchema:{type:"object",properties:{use_case:{type:"string"}},required:["use_case"]}},{name:"search_components",description:"Fuzzy-search primitives by name / tagline / prop. Returns ranked matches.",inputSchema:{type:"object",properties:{query:{type:"string"}},required:["query"]}},{name:"get_frame_coverage",description:"Verified preview-contract coverage for a component (issue #163). Answers 'is this state actually PROVEN?' \u2014 returns, per contract dimension (variants, tones, sizes, shapes, density, controlled/uncontrolled ownership, disabled/read-only/loading/empty/error/success, async retry/cancel/offline, responsive viewport matrix, RTL, long/localized content, keyboard/focus, accessible name/description/error, reduced motion / coarse touch), whether an EXECUTED case proves it (covered), whether nothing proves it (UNTESTED), or whether it cannot exist (not-applicable, with a reason). UNTESTED IS NOT A PASS: never infer that a component supports a state because an example renders. Call this before telling a user a component 'supports' anything. Omit `name` for the repo-wide summary and the tracked known gaps.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Public export name (e.g. 'Button', 'DataTable', 'CardFooter'). Omit for the repo-wide coverage summary."}}}},{name:"lint_jsx",description:"Heuristic check of a JSX snippet for common violations \u2014 raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.",inputSchema:{type:"object",properties:{jsx:{type:"string"}},required:["jsx"]}}];async function te(t,a){switch(t){case"list_skills":return ce();case"list_primitives":return ae(a.group);case"list_patterns":return ge();case"list_anti_ai_tells":return ye(a.category);case"list_redesign_checks":return we(a.category);case"list_audit_rules":return fe(a.category);case"list_visual_checks":return be(a.category);case"get_anti_ai_tell":return ve(String(a.name??""));case"get_redesign_check":return ke(String(a.symptom??""));case"get_skill_section":return oe(String(a.skill??""),String(a.section??""));case"get_component":return Ce(String(a.name??""),a.verbose===!0);case"get_pattern":return De(String(a.name??""));case"get_rule":return Oe(typeof a.number=="number"?a.number:void 0);case"get_vocab":return Ne(a.name==null?void 0:String(a.name));case"get_tokens":return Ie(a.category);case"list_consumer_skills":return pe();case"get_consumer_skill":return he(String(a.skill??""),String(a.section??""));case"route_consumer_task":return Z(String(a.task??""),{consumerOnly:!0});case"draft_bug_report":return ue(a);case"check_compatibility":return me(a.version==null?void 0:String(a.version));case"route_task":return Z(String(a.task??""));case"suggest_primitive":return Pe(String(a.use_case??""));case"search_components":return Re(String(a.query??""));case"get_frame_coverage":return Ae(a.name===void 0?void 0:String(a.name));case"lint_jsx":return Ee(String(a.jsx??""));default:return`Unknown tool: ${t}`}}function ce(){let t=`# Available skills (${x.length})
3692
3870
 
3693
3871
  `;t+="Each is tagged `[audience]` \u2014 `core` = building @godxjp/ui itself, `consumer` = building an app with it, `both`. App-devs: use `list_consumer_skills` to hide core material.\n\n",t+='Use `get_skill_section skill="..." section="..."` to drill in.\n\n';for(let a of x)t+=`## ${a.id} \u2014 ${a.name} \`[${a.audience}]\`
3694
3872
  `,t+=`**When to use:** ${a.whenToUse}
@@ -3703,7 +3881,7 @@ _Source: ${x.map(a=>a.source).filter((a,e,o)=>o.indexOf(a)===e).slice(0,3).join(
3703
3881
 
3704
3882
  `,a+=`**Sections:** ${e.sections.map(o=>`\`${o.id}\``).join(", ")}
3705
3883
 
3706
- `;return a}function he(t,a){let e=A(t);return e&&!M(e)?`Skill "${t}" is CORE-only (building @godxjp/ui itself) and isn't served to app-devs. Use \`list_consumer_skills\` for consumer-facing guidance${t==="component-discipline"?" \u2014 the standards you need when composing/extending are folded into `compose-a-screen/state-and-a11y` and `design-to-page/verify`.":"."}`:oe(t,a)}function ue(t){let a=f=>{let S=t[f];return typeof S=="string"?S.trim():""},e=a("summary");if(!e)return"Pass at least `summary` (one-line title). For a useful report also pass `repro`, `expected`, `actual`, and ideally `component` / `rule` / `version` / `env`. A vague report a maintainer can't reproduce is not enough.";let o=a("repro"),r=a("expected"),i=a("actual"),n=a("component"),s=typeof t.rule=="number"?t.rule:void 0,g=a("version"),h=a("env"),d=[];o||d.push("repro"),r||d.push("expected"),i||d.push("actual");let y=(f,S)=>S||`_(TODO: ${f} \u2014 required for a reproducible report)_`,N=`[bug] ${e}`,l=`## Summary
3884
+ `;return a}function he(t,a){let e=A(t);return e&&!M(e)?`Skill "${t}" is CORE-only (building @godxjp/ui itself) and isn't served to app-devs. Use \`list_consumer_skills\` for consumer-facing guidance${t==="component-discipline"?" \u2014 the standards you need when composing/extending are folded into `compose-a-screen/state-and-a11y` and `design-to-page/verify`.":"."}`:oe(t,a)}function ue(t){let a=y=>{let S=t[y];return typeof S=="string"?S.trim():""},e=a("summary");if(!e)return"Pass at least `summary` (one-line title). For a useful report also pass `repro`, `expected`, `actual`, and ideally `component` / `rule` / `version` / `env`. A vague report a maintainer can't reproduce is not enough.";let o=a("repro"),r=a("expected"),i=a("actual"),n=a("component"),s=typeof t.rule=="number"?t.rule:void 0,g=a("version"),h=a("env"),d=[];o||d.push("repro"),r||d.push("expected"),i||d.push("actual");let f=(y,S)=>S||`_(TODO: ${y} \u2014 required for a reproducible report)_`,O=`[bug] ${e}`,l=`## Summary
3707
3885
 
3708
3886
  ${e}
3709
3887
 
@@ -3715,15 +3893,15 @@ ${e}
3715
3893
  `:"",l+=`
3716
3894
  ## Reproduction (minimal)
3717
3895
 
3718
- ${y("repro",o)}
3896
+ ${f("repro",o)}
3719
3897
 
3720
3898
  `,l+=`## Expected
3721
3899
 
3722
- ${y("expected",r)}
3900
+ ${f("expected",r)}
3723
3901
 
3724
3902
  `,l+=`## Actual
3725
3903
 
3726
- ${y("actual",i)}
3904
+ ${f("actual",i)}
3727
3905
 
3728
3906
  `,l+=`## Environment
3729
3907
 
@@ -3733,11 +3911,11 @@ ${y("actual",i)}
3733
3911
  `,l+=`## Proposed fix
3734
3912
 
3735
3913
  _(optional \u2014 what the library should do instead)_
3736
- `;let c=f=>`'${f.replace(/'/g,"'\\''")}'`,E=`gh issue create --repo godx-jp/godxjp-ui --label bug --title ${c(N)} --body ${c(l)}`,w=`# Draft bug report
3914
+ `;let c=y=>`'${y.replace(/'/g,"'\\''")}'`,E=`gh issue create --repo godx-jp/godxjp-ui --label bug --title ${c(O)} --body ${c(l)}`,w=`# Draft bug report
3737
3915
 
3738
- `;return d.length&&(w+=`> \u26A0\uFE0F Incomplete \u2014 fill ${d.map(f=>`\`${f}\``).join(", ")} before filing (a report a maintainer can't reproduce will bounce).
3916
+ `;return d.length&&(w+=`> \u26A0\uFE0F Incomplete \u2014 fill ${d.map(y=>`\`${y}\``).join(", ")} before filing (a report a maintainer can't reproduce will bounce).
3739
3917
 
3740
- `),w+=`**Title:** ${N}
3918
+ `),w+=`**Title:** ${O}
3741
3919
 
3742
3920
  `,w+=`## Issue body (Markdown)
3743
3921
 
@@ -3781,7 +3959,7 @@ ${X}
3781
3959
 
3782
3960
  `,e+="_Static `list_audit_rules` first (cheap, every save) \u2192 THIS (before review) \u2192 human eyes for taste._\n\n";for(let o of a)e+=`- **${o.id}** (${o.severity}, ${o.category}) \u2014 _${o.standard}_
3783
3961
  ${o.fix}
3784
- `;return e}function ye(t){let a=Y(t),e=`# Local UI-audit rules${t?` \u2014 ${t}`:""} (${a.length})
3962
+ `;return e}function fe(t){let a=Y(t),e=`# Local UI-audit rules${t?` \u2014 ${t}`:""} (${a.length})
3785
3963
 
3786
3964
  `;e+=`_Run BEFORE any visual review (warnings are agent guidance, non-blocking):_
3787
3965
  `,e+=`\`\`\`
@@ -3792,7 +3970,7 @@ ${K}
3792
3970
  `;for(let n of i)e+=`- **${n.id}** (${n.severity})${n.standard?` \u2014 _${n.standard}_`:""}
3793
3971
  ${n.fix}
3794
3972
  `;e+=`
3795
- `}return e}function fe(t){let a=t?H(t):D,e=`# AI tells to AVOID${t?` \u2014 ${t}`:""} (${a.length})
3973
+ `}return e}function ye(t){let a=t?H(t):D,e=`# AI tells to AVOID${t?` \u2014 ${t}`:""} (${a.length})
3796
3974
 
3797
3975
  `;e+='_Compact list. Use `get_anti_ai_tell name="<name>"` for the full body + fix._\n\n';let o=a.reduce((r,i)=>((r[i.category]??=[]).push(i),r),{});for(let[r,i]of Object.entries(o)){e+=`## ${r}
3798
3976
  `;for(let n of i)e+=`- ${n.name}
@@ -3848,7 +4026,7 @@ ${o.tagline}
3848
4026
 
3849
4027
  ${o.body}
3850
4028
 
3851
- _Source: ${e.source}_`}var xe={Badge:["badge"],Button:["button"],Toggle:["toggle"],TagInput:["tag-input"],Card:["card"],StatCard:["stat-card"],Table:["table"],DataTable:["table"],Dialog:["dialog"],AlertDialog:["dialog"],Sheet:["dialog"],Drawer:["dialog"],Alert:["alert"],EmptyState:["empty-state"],Skeleton:["skeleton"],Pagination:["pagination"],Toolbar:["filter"],Breadcrumb:["breadcrumb"],Menubar:["menubar"],Progress:["progress"],TreeSelect:["tree"],Timeline:["timeline"],PasswordStrength:["password-strength"],PasswordInput:["password-strength"],Checkbox:["checkbox"],Switch:["switch"],Slider:["slider"],ColorPicker:["color-picker"],Command:["command"],Radio:["choice"],RadioGroup:["choice"],Field:["choice"],AppShell:["app-shell","sidebar","topbar"],Sidebar:["sidebar"],Topbar:["topbar"],Form:["form"],FormField:["form"],Input:["control"],Textarea:["control"],NumberInput:["control"],Select:["control","search-input"],Cascader:["control"],DatePicker:["control"],TimePicker:["control"],InputOTP:["control"]};function Se(t){let a=xe[t]??[t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()];return V.filter(e=>a.some(o=>e.name.startsWith(`--${o}-`)))}function Ce(t,a=!1){let e=O(t);if(!e)return`Component "${t}" not found. Use \`list_primitives\` to discover.`;let o=`# ${e.name}
4029
+ _Source: ${e.source}_`}var xe={Badge:["badge"],Button:["button"],Toggle:["toggle"],TagInput:["tag-input"],Card:["card"],StatCard:["stat-card"],Table:["table"],DataTable:["table"],Dialog:["dialog"],AlertDialog:["dialog"],Sheet:["dialog"],Drawer:["dialog"],Alert:["alert"],EmptyState:["empty-state"],Skeleton:["skeleton"],Pagination:["pagination"],Toolbar:["filter"],Breadcrumb:["breadcrumb"],Menubar:["menubar"],Progress:["progress"],TreeSelect:["tree"],Timeline:["timeline"],PasswordStrength:["password-strength"],PasswordInput:["password-strength"],Checkbox:["checkbox"],Switch:["switch"],Slider:["slider"],ColorPicker:["color-picker"],Command:["command"],Radio:["choice"],RadioGroup:["choice"],Field:["choice"],AppShell:["app-shell","sidebar","topbar"],Sidebar:["sidebar"],Topbar:["topbar"],Form:["form"],FormField:["form"],Input:["control"],Textarea:["control"],NumberInput:["control"],Select:["control","search-input"],Cascader:["control"],DatePicker:["control"],TimePicker:["control"],InputOTP:["control"]};function Se(t){let a=xe[t]??[t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()];return V.filter(e=>a.some(o=>e.name.startsWith(`--${o}-`)))}function Ce(t,a=!1){let e=N(t);if(!e)return`Component "${t}" not found. Use \`list_primitives\` to discover.`;let o=`# ${e.name}
3852
4030
 
3853
4031
  **Group:** ${e.group}`,r=e.importPath??`@godxjp/ui/${e.group==="providers"?"app":e.group}`;o+=` \xB7 **Import:** \`import { ${e.name} } from "${r}"\`
3854
4032
 
@@ -3950,7 +4128,7 @@ ${a.tagline}
3950
4128
  \`\`\`tsx
3951
4129
  ${a.code}
3952
4130
  \`\`\`
3953
- `}function Ne(t){if(t!==void 0){let e=T(t);return e?`# Rule ${e.number} \u2014 ${e.title}
4131
+ `}function Oe(t){if(t!==void 0){let e=T(t);return e?`# Rule ${e.number} \u2014 ${e.title}
3954
4132
 
3955
4133
  ${e.body}
3956
4134
  `:`Rule ${t} not found. Valid: 1-${u.length}.`}let a=`# Cardinal rules (${u.length})
@@ -3959,7 +4137,7 @@ ${e.body}
3959
4137
 
3960
4138
  ${e.body}
3961
4139
 
3962
- `;return a}function Oe(t){if(t){let e=B(t);if(!e)return`Vocab "${t}" not found.`;let o=`# ${e.name}
4140
+ `;return a}function Ne(t){if(t){let e=B(t);if(!e)return`Vocab "${t}" not found.`;let o=`# ${e.name}
3963
4141
 
3964
4142
  ${e.concept}
3965
4143
 
@@ -3993,7 +4171,7 @@ Values: ${e.values.map(o=>`\`${o}\``).join(" | ")}
3993
4171
  `);return o+='\nFetch with: `get_skill_section skill="X" section="Y"`',o}function Pe(t){let a=t.trim().toLowerCase();if(!a)return"Describe your use case.";let e=[],o=(i,n,s,g=2)=>{i.some(h=>a.includes(h))&&e.push({component:n,rationale:s,score:g})};if(o(["form","submit","validation","register","sign up"],"Form + FormField","RHF + zod composition.",5),o(["table","rows","columns"],"DataTable / Table","DataTable for chrome (toolbar+pagination+batch). Table for slim primitive.",5),o(["modal","dialog","confirm"],"Dialog / AlertDialog","Radix Dialog. AlertDialog for destructive.",4),o(["drawer","side panel","sheet"],"Sheet","Side panel for filters/settings.",4),o(["toast","notification"],"toast / Toaster","Sonner-backed.",4),o(["loading","saving","spinner"],"Spinner / Form loading prop","Spinner=active work, Skeleton=init fetch.",3),o(["alert","banner"],"Alert","5 semantic colors \xD7 outlined/banner.",3),o(["select","dropdown"],"Select / AutoComplete","Select=discrete options, AutoComplete=free-text+suggestions.",3),o(["filter"],"Toolbar/ToolbarGroup + pattern 'filter-bar' (\u2192 data-table-page)","Standalone Toolbar filter bar above a table; see the data-table-page pattern.",4),o(["delete","destructive"],"Pattern 'confirm-destructive'","Card accent='destructive' + typed-name confirm.",4),!e.length)return`No direct match for "${t}". Try \`list_primitives\` or \`search_components\`.`;e.sort((i,n)=>n.score-i.score);let r=`# Suggestions for "${t}"
3994
4172
 
3995
4173
  `;for(let i of e)r+=`- **${i.component}** \u2014 ${i.rationale}
3996
- `;return r}function Re(t){let a=t.trim().toLowerCase();if(!a)return ae();let e=a.split(/\s+/).filter(n=>n.length>=2),o=e.length?e:[a],r=v.map(n=>{let s=n.name.toLowerCase(),g=n.tagline.toLowerCase(),h=(n.useCases??[]).join(" ").toLowerCase(),d=(n.usage??[]).join(" ").toLowerCase(),y=(n.related??[]).join(" ").toLowerCase(),N=n.props.map(c=>c.name.toLowerCase()),l=0;s===a&&(l+=100);for(let c of o)s.includes(c)&&(l+=5),g.includes(c)&&(l+=3),h.includes(c)&&(l+=2),d.includes(c)&&(l+=1),y.includes(c)&&(l+=1),n.group.includes(c)&&(l+=1),N.some(E=>E.includes(c))&&(l+=1);return{c:n,score:l}}).filter(n=>n.score>0).sort((n,s)=>s.score-n.score).slice(0,12);if(!r.length)return`No matches for "${t}". Try \`list_primitives\` or a broader term (e.g. a use-case word like "date", "select", "confirm").`;let i=`# Search "${t}" \u2014 ${r.length} match${r.length>1?"es":""}
4174
+ `;return r}function Re(t){let a=t.trim().toLowerCase();if(!a)return ae();let e=a.split(/\s+/).filter(n=>n.length>=2),o=e.length?e:[a],r=v.map(n=>{let s=n.name.toLowerCase(),g=n.tagline.toLowerCase(),h=(n.useCases??[]).join(" ").toLowerCase(),d=(n.usage??[]).join(" ").toLowerCase(),f=(n.related??[]).join(" ").toLowerCase(),O=n.props.map(c=>c.name.toLowerCase()),l=0;s===a&&(l+=100);for(let c of o)s.includes(c)&&(l+=5),g.includes(c)&&(l+=3),h.includes(c)&&(l+=2),d.includes(c)&&(l+=1),f.includes(c)&&(l+=1),n.group.includes(c)&&(l+=1),O.some(E=>E.includes(c))&&(l+=1);return{c:n,score:l}}).filter(n=>n.score>0).sort((n,s)=>s.score-n.score).slice(0,12);if(!r.length)return`No matches for "${t}". Try \`list_primitives\` or a broader term (e.g. a use-case word like "date", "select", "confirm").`;let i=`# Search "${t}" \u2014 ${r.length} match${r.length>1?"es":""}
3997
4175
 
3998
4176
  `;for(let{c:n,score:s}of r)i+=`- **${n.name}** (${n.group}, ${s}) \u2014 ${n.tagline}
3999
4177
  `;return i}function Ee(t){let a=[],e=(r,i)=>{r.test(t)&&a.push(i)};if(e(/<button[\s>]/,"Use `<Button>` instead of raw `<button>` (rule 29)."),e(/<input[\s>]/,"Use `<Input>` instead of raw `<input>` (rule 29)."),e(/<select[\s>]/,"Use `<Select>` instead of raw `<select>` (rule 29)."),e(/<textarea[\s>]/,"Use `<Textarea>` instead of raw `<textarea>` (rule 29)."),e(/<(table|thead|tbody)[\s>]/,"Use `<DataTable>` instead of a hand-rolled `<table>` (rule 29)."),e(/bg-(red|blue|green|yellow|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|indigo|violet|purple|fuchsia|pink|rose)-\d{2,3}\b/,"Use semantic token utilities (`bg-primary`/`bg-destructive`) not raw color scales (rule 2)."),e(/\b(?:ml|mr|pl|pr|left|right)-(?:\d|\[|auto|px|full|screen)|\b(?:rounded-[lr]|border-[lr]|text-(?:left|right))\b/,"Physical direction class \u2014 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)."),e(/size=["']default["']/,'`size="default"` is not in the controlled vocabulary \u2014 use `size` \u2208 xs|sm|md|lg.'),e(/\btext-\[[0-9.]+px\]/,"Arbitrary text size `text-[Npx]` bypasses the golden type scale \u2014 use `<Text size>` / `<Heading level>` (rule 42)."),e(/<Tag[\s\S]*?color=["']error["']/i,'Tag `color="error"` \u2192 `"destructive"` (v5.0, PR #60).'),e(/<Badge[\s\S]*?variant=["']error["']/i,'Badge `variant="error"` \u2192 `"destructive"` (v5.0, PR #63).'),e(/(Flex|Space|Grid|Masonry)[\s\S]*?(gap|size)=["']middle["']/i,'`"middle"` \u2192 `"default"` for Flex/Space/Grid/Masonry (v5.0).'),e(/<IconButton[\s\S]*?size=["']default["']/i,'IconButton `size="default"` \u2192 `"md"` (v5.0).'),e(/<SegmentedControl[\s\S]*?size=["']sm["']/i,'SegmentedControl `size="sm"` \u2192 `"small"` (v5.0).'),e(/<PageContent[\s\S]*?padding=["'](compact|comfortable)["']/i,'PageContent `padding="compact"/"comfortable"` \u2192 `"tight"/"cozy"` (v5.0).'),e(/<Pagination[\s\S]*?justify=["']between["']/i,'Pagination `justify="between"` \u2192 `"space-between"` (v5.0).'),/<IconButton(?![^>]*aria-label)/i.test(t)&&!/asChild/i.test(t)&&a.push("`<IconButton>` should have `aria-label` (rule 6 \u2014 WCAG)."),/cell:\s*\(\{?\s*row\s*\}?\)\s*=>/i.test(t)&&/export\s+const\s+\w+\s*:\s*Story/i.test(t)&&(/parameters[\s\S]{0,200}source[\s\S]{0,100}code:/i.test(t)||a.push("Stories with function-valued cell renderers MUST override `parameters.docs.source.code` (rule 34).")),/text-(red|blue|green|yellow)-\d{2,3}\b/.test(t)&&a.push("Hard-coded color scales \u2014 use semantic tokens. Tells AI-slop palette (rule 2 + anti-AI-tells.visual.rainbow-chip-wall)."),/h-\[?100vh\]?/.test(t)&&a.push("`100vh` causes iOS Safari viewport jump \u2014 use `min-h-[100dvh]` (redesign.layout / soft.absolute-zero)."),/className=["'][^"']*(?:shadow-md|shadow-lg|shadow-xl)["']/.test(t)&&a.push("Tailwind heavy shadows are an AI tell \u2014 use ultra-diffuse low-opacity (< 0.05) or tinted shadows (soft.absolute-zero, minimalist)."),/\b(?:Inter|Roboto|Helvetica|Open\s+Sans)\b/i.test(t)&&a.push("Banned default fonts (Inter/Roboto/Helvetica/Open Sans). Use Geist/Clash Display/PP Editorial New (soft.absolute-zero, minimalist.negative-constraints)."),/Acme|NovaCore|Flowbit|Quantix|VeloPay|John\s+Doe|Jane\s+Smith|Lorem\s+Ipsum/i.test(t)&&a.push("Generic placeholder content (Acme/NovaCore/John Doe/Lorem Ipsum). Use believable real-sounding names (anti-AI-tells.copy)."),a.length===0)return"\u2705 No issues found against the heuristic checks.";let o=`# Lint findings \u2014 ${a.length} issue${a.length===1?"":"s"}
@@ -4001,7 +4179,7 @@ Values: ${e.values.map(o=>`\`${o}\``).join(" | ")}
4001
4179
  `;for(let r of a)o+=`- ${r}
4002
4180
  `;return o+=`
4003
4181
  Note: heuristic only \u2014 not a substitute for the full CI gate.
4004
- `,o}var ne=u.length,ie=[{uri:"godx-ui://compatibility",name:"Package compatibility",description:"MCP package/server version and the compatible @godxjp/ui release range.",mimeType:"application/json"},{uri:"godx-ui://components",name:"All components",description:"Full component catalog as JSON \u2014 name, group, tagline, props, example, rules.",mimeType:"application/json"},{uri:"godx-ui://prop-vocabulary",name:"Shared prop vocabulary",description:"Cross-cutting prop types (SizeProp, StatusProp, ColorProp, LoadingProp, \u2026) as JSON.",mimeType:"application/json"},{uri:"godx-ui://tokens",name:"All design tokens",description:"Every CSS variable + role + value + axis as JSON.",mimeType:"application/json"},{uri:"godx-ui://rules",name:`Cardinal rules (${ne})`,description:`The ${ne} binding rules from CLAUDE.md as Markdown.`,mimeType:"text/markdown"},{uri:"godx-ui://patterns",name:"Code patterns",description:"Canonical pattern catalog (registration-form, settings-page, data-table, \u2026) as JSON.",mimeType:"application/json"}];async function se(t){if(t==="godx-ui://compatibility")return JSON.stringify({mcpVersion:m.version,serverVersion:m.version,compatibleUi:m.godxUiCompatibility,policy:"UI and MCP are released from the same source commit and minor release train."},null,2);if(t==="godx-ui://components")return JSON.stringify(v,null,2);if(t.startsWith("godx-ui://components/")){let a=t.slice(21),e=O(a);if(!e)throw new Error(`Component not found: ${a}`);return ze(e)}if(t==="godx-ui://prop-vocabulary")return JSON.stringify(k,null,2);if(t==="godx-ui://tokens")return JSON.stringify(C,null,2);if(t.startsWith("godx-ui://tokens/")){let a=t.slice(17);return JSON.stringify(I(a),null,2)}if(t==="godx-ui://rules"){let a=`# Cardinal rules (${u.length})
4182
+ `,o}var ne=u.length,ie=[{uri:"godx-ui://compatibility",name:"Package compatibility",description:"MCP package/server version and the compatible @godxjp/ui release range.",mimeType:"application/json"},{uri:"godx-ui://components",name:"All components",description:"Full component catalog as JSON \u2014 name, group, tagline, props, example, rules.",mimeType:"application/json"},{uri:"godx-ui://prop-vocabulary",name:"Shared prop vocabulary",description:"Cross-cutting prop types (SizeProp, StatusProp, ColorProp, LoadingProp, \u2026) as JSON.",mimeType:"application/json"},{uri:"godx-ui://tokens",name:"All design tokens",description:"Every CSS variable + role + value + axis as JSON.",mimeType:"application/json"},{uri:"godx-ui://rules",name:`Cardinal rules (${ne})`,description:`The ${ne} binding rules from CLAUDE.md as Markdown.`,mimeType:"text/markdown"},{uri:"godx-ui://patterns",name:"Code patterns",description:"Canonical pattern catalog (registration-form, settings-page, data-table, \u2026) as JSON.",mimeType:"application/json"}];async function se(t){if(t==="godx-ui://compatibility")return JSON.stringify({mcpVersion:m.version,serverVersion:m.version,compatibleUi:m.godxUiCompatibility,policy:"UI and MCP are released from the same source commit and minor release train."},null,2);if(t==="godx-ui://components")return JSON.stringify(v,null,2);if(t.startsWith("godx-ui://components/")){let a=t.slice(21),e=N(a);if(!e)throw new Error(`Component not found: ${a}`);return ze(e)}if(t==="godx-ui://prop-vocabulary")return JSON.stringify(k,null,2);if(t==="godx-ui://tokens")return JSON.stringify(C,null,2);if(t.startsWith("godx-ui://tokens/")){let a=t.slice(17);return JSON.stringify(I(a),null,2)}if(t==="godx-ui://rules"){let a=`# Cardinal rules (${u.length})
4005
4183
 
4006
4184
  `;for(let e of u)a+=`## ${e.number}. ${e.title}
4007
4185