@godxjp/ui-mcp 18.7.0 → 18.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +10 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -44,7 +44,7 @@ import { StatCard } from "@godxjp/ui/data-display";
|
|
|
44
44
|
<StatCard label="\u516C\u958B\u4E2D\u30AF\u30FC\u30DD\u30F3" value="8" />
|
|
45
45
|
<StatCard label="\u6708\u9593\u5229\u7528\u6570" value="3,210" />
|
|
46
46
|
<StatCard label="\u5272\u5F15\u7DCF\u984D" value="\xA5480,000" />
|
|
47
|
-
</ResponsiveGrid>`,storyPath:"layout/ResponsiveGrid.stories.tsx",rules:[24,40]},{name:"AppShell",group:"layout",tagline:"Root application shell \u2014 composes sidebar, topbar rail, main content area, and optional footer.",props:[{name:"sidebar",type:"ReactNode",required:!0,description:"Sidebar node \u2014 typically a <Sidebar>."},{name:"children",type:"ReactNode",required:!0,description:"Main page content rendered in <main>."},{name:"topbar",type:"ReactNode",description:"Full topbar override; else a rail is built from topbarLeft/topbarRight/logo."},{name:"topbarRight",type:"ReactNode",description:"Right slot of the auto-built topbar rail (user menu, switcher)."},{name:"topbarLeft",type:"ReactNode",description:"Left slot of the auto-built topbar rail."},{name:"logo",type:"ReactNode",description:"Brand mark at the far-left of the auto-built topbar rail (e.g. an Avatar)."},{name:"sidebarCollapsed",type:"boolean",defaultValue:"false",description:"Collapse the sidebar to icon-only mode."},{name:"responsiveNavigation",type:'"drawer" | "docked"',defaultValue:'"drawer"',description:"Navigation strategy below the canonical 900px breakpoint. drawer exposes the accessible mobile Sheet; docked retains the token-sized sidebar grid track and suppresses the redundant drawer trigger."},{name:"footer",type:"ReactNode",description:"App-level footer outside the main content area."},{name:"breadcrumb",type:"BreadcrumbProp",description:"Breadcrumb trail rendered in the topbar header for back-navigation."},{name:"mobileNav",type:"ReactNode",description:"Navigation shown in the AppShell-owned mobile drawer below
|
|
47
|
+
</ResponsiveGrid>`,storyPath:"layout/ResponsiveGrid.stories.tsx",rules:[24,40]},{name:"AppShell",group:"layout",tagline:"Root application shell \u2014 composes sidebar, topbar rail, main content area, and optional footer.",props:[{name:"sidebar",type:"ReactNode",required:!0,description:"Sidebar node \u2014 typically a <Sidebar>."},{name:"children",type:"ReactNode",required:!0,description:"Main page content rendered in <main>."},{name:"topbar",type:"ReactNode",description:"Full topbar override; else a rail is built from topbarLeft/topbarRight/logo."},{name:"topbarRight",type:"ReactNode",description:"Right slot of the auto-built topbar rail (user menu, switcher)."},{name:"topbarLeft",type:"ReactNode",description:"Left slot of the auto-built topbar rail."},{name:"logo",type:"ReactNode",description:"Brand mark at the far-left of the auto-built topbar rail (e.g. an Avatar)."},{name:"sidebarCollapsed",type:"boolean",defaultValue:"false",description:"Collapse the sidebar to icon-only mode."},{name:"responsiveNavigation",type:'"drawer" | "docked"',defaultValue:'"drawer"',description:"Navigation strategy below the canonical 900px breakpoint. drawer exposes the accessible mobile Sheet; docked retains the token-sized sidebar grid track and suppresses the redundant drawer trigger."},{name:"footer",type:"ReactNode",description:"App-level footer outside the main content area."},{name:"breadcrumb",type:"BreadcrumbProp",description:"Breadcrumb trail rendered in the topbar header for back-navigation."},{name:"mobileNav",type:"ReactNode",description:"Navigation shown in the AppShell-owned mobile drawer at 900px and below \u2014 THE ONE AppShell breakpoint, where the docked sidebar is hidden. It is NOT Tailwind's `lg` (1024px): the shipped `@media (width <= 56.25rem)` rule and the hamburger's `max-[900px]:inline-flex` both fire at 900, and this catalog said `lg` for six minors (gh#259). Defaults to the `sidebar` node; pass a tailored menu, or null to opt out."},{name:"mobileNavLabel",type:"string",description:"Accessible title for the mobile navigation drawer. Defaults to localized 'Menu'."},{name:"mobileNavOpen",type:"boolean",description:"Controlled open state of the mobile drawer. Omit for AppShell-owned state."},{name:"onMobileNavOpenChange",type:"(open: boolean) => void",description:"Change handler for the mobile drawer open state."}],usage:["DO pass a <Sidebar> node to `sidebar` (required) and page content to `children` (required) \u2014 these are the only two required props. Everything else is optional and omitting optional slots simply removes that zone from the rendered DOM.","DO rely on AppShell's OWNED mobile drawer at 900px and below (56.25rem \u2014 the ONE AppShell breakpoint, not Tailwind's `lg`/1024px): it renders a hamburger trigger in the topbar and a focus-trapped Sheet (Esc + overlay close, focus returns to the trigger). `mobileNav` defaults to the `sidebar` node, so the same nav is reachable on mobile with no wiring \u2014 never hide the sidebar without providing this. Pass a tailored `mobileNav`, or `mobileNav={null}` only when navigation lives elsewhere (e.g. a bottom bar).",'DO set `responsiveNavigation="docked"` only when the approved product contract retains its sidebar below 900px. AppShell keeps the same sidebar/footer/active navigation in a token-sized grid track and removes the redundant drawer trigger; never reproduce this with consumer media queries.',"DO let the drawer nav own its own inset: AppShell renders `mobileNav` in a Sheet body whose inline padding is the `--app-shell-mobile-nav-inset` token (near-zero by default) instead of the generic 24px sheet chrome inset, so a <Sidebar> in the drawer is not double-padded (its own --sidebar-nav-scroll-padding already insets each row). If a custom `mobileNav` node needs the full chrome inset, set `--app-shell-mobile-nav-inset: var(--space-6)` in the service theme \u2014 never patch the drawer with a `[data-slot='sheet-body']` selector in app CSS.","DO use the auto-built topbar rail (logo / topbarLeft / topbarRight) for simple shells. Pass a fully configured <Topbar> to the `topbar` prop only when you need live handlers (entity switcher via productMenu, search, notifications, user avatar) \u2014 when `topbar` is provided, logo/topbarLeft/topbarRight are ignored entirely.","DO wire a single `sidebarCollapsed` boolean between AppShell's `sidebarCollapsed` prop and Sidebar's `collapsed` prop \u2014 AppShell sets `data-collapsed='true'` on the root div (which CSS reads for width transitions) but does NOT own the collapsed state itself; lift the state and pass it down to both.","DO place breadcrumb content in AppShell's `breadcrumb` prop (renders in the `app-breadcrumb` div inside `<main>` ABOVE children) \u2014 do NOT hand-roll a breadcrumb bar as the first child of children, and do NOT put breadcrumbs inside <Sidebar>.","DO NOT nest a second AppShell or AppShell inside AppShell's children \u2014 AppShell renders the root `app-root` div; nesting shells breaks the CSS grid layout.","DO NOT add padding directly to children expecting it to reach the viewport edge \u2014 AppShell's `<main>` is a scroll container; use <PageContainer> (or <PageContainer.Inset> inside a flush PageContainer) inside children to get standard page padding."],useCases:["Full admin SPA shell: AppShell wraps a <Sidebar> nav rail and a <Topbar> (with productMenu entity-switcher, onSearchOpen, onNotificationsOpen, user avatar) and every Inertia page renders as children inside a <PageContainer>.","Collapsible-sidebar layout: maintain a `collapsed` boolean in a persistent Inertia layout component, pass it to both AppShell's `sidebarCollapsed` and Sidebar's `collapsed`, wire Topbar's `onToggleCollapsed` to flip it \u2014 AppShell handles the CSS transition automatically.","Multi-tenant accounting app: pass a <Topbar productMenu={<DropdownMenuContent>\u2026</DropdownMenuContent>}> to AppShell's `topbar` slot so the legal-entity chip opens an inline switcher without a modal.","App-level footer (e.g. version/build info, compliance notice): pass a <footer> node to AppShell's `footer` prop \u2014 it renders outside `<main>` so it stays pinned below the scroll area.","Rapid prototype or internal tool where you want a branded shell with minimal topbar: skip the `topbar` prop entirely and use `logo`, `topbarLeft`, `topbarRight` to build the rail declaratively without instantiating <Topbar>.","Breadcrumb-aware shell: pass a <Breadcrumb items={\u2026}> node to AppShell's `breadcrumb` prop so the breadcrumb strip appears above all page content without each page having to render it separately."],related:["AppShell \u2014 opinionated wrapper that composes AppShell + a frozen default Topbar in three props (menu, children, breadcrumb). Use AppShell for quick scaffolding when the default GodX product chip and no-op search/notification handlers are acceptable; switch to AppShell directly the moment you need a custom entity switcher, real onSearchOpen, user slot, or any topbar configuration.","Sidebar \u2014 the canonical node to pass as AppShell's `sidebar` prop; owns activeId, collapsible submenu groups, collapsed icon-only mode, and section labels. Never hand-roll a nav list inside the sidebar slot.","Topbar \u2014 the structured topbar component to pass to AppShell's `topbar` prop when you need live product/project chip switchers, search, notifications, sidebar toggle, user avatar, or rightSlot extras. When `topbar` is provided, AppShell's logo/topbarLeft/topbarRight props are ignored.","PageContainer \u2014 the mandatory direct child inside AppShell's `children` for every page; provides title, subtitle, extra actions, breadcrumb, footer, variant (flush/narrow/ghost), and density. Never render raw content directly as AppShell's child without a PageContainer wrapper."],example:`import { AppShell, Sidebar } from "@godxjp/ui/layout";
|
|
48
48
|
import { LayoutDashboard, Users } from "lucide-react";
|
|
49
49
|
import { router } from "@inertiajs/react";
|
|
50
50
|
|
|
@@ -62,7 +62,7 @@ const sidebar = (
|
|
|
62
62
|
|
|
63
63
|
export function CrmLayout({ children }: { content: React.ReactNode }) {
|
|
64
64
|
return <AppShell sidebar={sidebar}>{children}</AppShell>;
|
|
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";
|
|
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, gh#12) = a 380px card at 1440/1024 with a 5px inline page gutter at 390, AND the code field itself: the preset hands --otp-slot-{inline,block}-size the canonical 27.5x52 device-grant slot, so two 4-slot grouped boxes measure 112x54 instead of the 146x38 the square --control-height tier produced. "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";
|
|
66
66
|
import { Reveal, Logo, Button } from "@godxjp/ui/general";
|
|
67
67
|
import { Card, CardContent, CardHeader, CardTitle } from "@godxjp/ui/data-display";
|
|
68
68
|
import { AppSettingPicker } from "@godxjp/ui/navigation";
|
|
@@ -206,7 +206,7 @@ export default function Shell() {
|
|
|
206
206
|
</AppShell>
|
|
207
207
|
);
|
|
208
208
|
}\`}
|
|
209
|
-
`,storyPath:"layout/Sidebar.preview.tsx",rules:[3,6,23,31]},{name:"Topbar",group:"layout",tagline:"A PURE SLOT bar for the app shell \u2014 positions three clusters (start / center / end) and owns ONLY the bar layout. It bakes NO chrome: no product switcher, no search box, no notification bell, no language picker. The CONSUMER composes those from real primitives and drops them into a slot; whether a control is icon-only / labelled / bordered is that control's own config, never the shell's.",props:[{name:"start",type:"ReactNode",defaultValue:"undefined",description:"Inline-start cluster \u2014 typically the sidebar toggle (a `Button` with a `PanelLeftClose` icon), the brand mark (an `Avatar`), and primary nav."},{name:"center",type:"ReactNode",defaultValue:"undefined",description:"Center cluster (grows + centers) \u2014 optional. e.g. a search trigger (`Button` + `Search` icon opening your command palette) or a page/entity switcher (`DropdownMenu`)."},{name:"end",type:"ReactNode",defaultValue:"undefined",description:'Inline-end cluster \u2014 settings pickers (`AppSettingPicker kind="locale"|"theme"`), a notifications `Button`, the user-menu `DropdownMenu`.'},{name:"children",type:"ReactNode",defaultValue:"undefined",description:"Escape hatch \u2014 render fully custom bar content instead of the three slots. When set, `start`/`center`/`end` are ignored."},{name:"className",type:"string",description:"Merged onto the bar element; arbitrary props (aria-*, etc.) are forwarded."}],usage:["DO compose the bar yourself: a brand mark (an `Avatar`) + sidebar toggle in `start`, a search trigger in `center`, settings pickers + notifications + user menu in `end`. The shell only positions; it never decides WHICH controls exist.",'DO build the sidebar toggle as a `Button variant="ghost" size="icon-sm"` with a `PanelLeftClose`/`PanelLeftOpen` icon and your own `t()` aria-label, wired to AppShell\'s `sidebarCollapsed`. There is no baked toggle.',"DO put a locale/theme switcher in `end` using `AppSettingPicker` (or your own control) \u2014 icon-only vs labelled, bordered vs not, is THAT component's prop, not Topbar's. Topbar does not ship or force a language picker.","DON'T look for `product`/`project`/`onSearchOpen`/`onNotificationsOpen`/`collapsed` props \u2014 they were removed. A chrome control only exists if YOU put it in a slot, so there is never a dead dropdown / empty search with nothing behind it.","DO render Topbar inside `AppShell`'s `topbar` slot (or any `<header>`). For a non-three-cluster layout, pass `children` and lay it out yourself.","DO rely on the built-in shrink contract instead of hand-tuning widths: the bar never exceeds its shell allocation, `start` shrinks first and `center` yields its whole box, each cluster CLIPS its own overflow (so a long tenant/brand string can never spill over a sibling or leak a horizontal document scroll), and `end` keeps its natural width anchored inline-end \u2014 the locale picker and user menu stay visible at 1024px with a 16rem sidebar. If a label must degrade gracefully rather than be cut, give THAT element `truncate`/`text-overflow` yourself; don't add `overflow`/`flex` overrides to the slots."],useCases:["Admin shell: `start` = sidebar toggle + brand mark (`Avatar`) + an entity switcher (`DropdownMenu` around a `Button`); `center` = a `Button` search trigger; `end` = `AppSettingPicker` (locale) + a notifications `Button` + a user `DropdownMenu`.","Minimal shell (no search, no notifications): pass only `start` (brand mark) and `end` (user menu). Nothing else renders \u2014 no empty chrome.","Marketing / docs header: pass `children` with a fully custom flex layout when the three-cluster model doesn't fit."],related:["AppShell \u2014 place Topbar in its `topbar` slot. AppShell also exposes its own `logo`/`topbarLeft`/`topbarRight` slots if you don't want a separate Topbar at all.",'Avatar \u2014 the brand mark for the `start` slot (use `className="rounded-md"` for a square-ish product glyph).',"AppSettingPicker \u2014 locale/theme/timezone/currency picker; the consumer drops it into `end`. Its appearance (icon-only, labelled, bordered) is configured on IT, not on Topbar.","DropdownMenu \u2014 wrap a `Button` to build an entity switcher or user menu yourself, then place it in a slot."],example:`import { Topbar, AppShell } from "@godxjp/ui/layout";
|
|
209
|
+
`,storyPath:"layout/Sidebar.preview.tsx",rules:[3,6,23,31]},{name:"Topbar",group:"layout",tagline:"A PURE SLOT bar for the app shell \u2014 positions three clusters (start / center / end) and owns ONLY the bar layout. It bakes NO chrome: no product switcher, no search box, no notification bell, no language picker. The CONSUMER composes those from real primitives and drops them into a slot; whether a control is icon-only / labelled / bordered is that control's own config, never the shell's.",props:[{name:"start",type:"ReactNode",defaultValue:"undefined",description:"Inline-start cluster \u2014 typically the sidebar toggle (a `Button` with a `PanelLeftClose` icon), the brand mark (an `Avatar`), and primary nav."},{name:"center",type:"ReactNode",defaultValue:"undefined",description:"Center cluster (grows + centers) \u2014 optional. e.g. a search trigger (`Button` + `Search` icon opening your command palette) or a page/entity switcher (`DropdownMenu`). \u26A0 HIDDEN AT 1100px AND BELOW by default: the slot follows `--topbar-center-compact-display` (default `none`) so it cannot cover the start breadcrumb/title or the end utilities when a 16rem sidebar is docked (gh#244). A global search placed here is therefore invisible on tablets and every phone until you set `--topbar-center-compact-display: flex`."},{name:"end",type:"ReactNode",defaultValue:"undefined",description:'Inline-end cluster \u2014 settings pickers (`AppSettingPicker kind="locale"|"theme"`), a notifications `Button`, the user-menu `DropdownMenu`.'},{name:"children",type:"ReactNode",defaultValue:"undefined",description:"Escape hatch \u2014 render fully custom bar content instead of the three slots. When set, `start`/`center`/`end` are ignored."},{name:"className",type:"string",description:"Merged onto the bar element; arbitrary props (aria-*, etc.) are forwarded."}],usage:["DO compose the bar yourself: a brand mark (an `Avatar`) + sidebar toggle in `start`, a search trigger in `center`, settings pickers + notifications + user menu in `end`. The shell only positions; it never decides WHICH controls exist.",'DO build the sidebar toggle as a `Button variant="ghost" size="icon-sm"` with a `PanelLeftClose`/`PanelLeftOpen` icon and your own `t()` aria-label, wired to AppShell\'s `sidebarCollapsed`. There is no baked toggle.',"DO put a locale/theme switcher in `end` using `AppSettingPicker` (or your own control) \u2014 icon-only vs labelled, bordered vs not, is THAT component's prop, not Topbar's. Topbar does not ship or force a language picker.","DON'T look for `product`/`project`/`onSearchOpen`/`onNotificationsOpen`/`collapsed` props \u2014 they were removed. A chrome control only exists if YOU put it in a slot, so there is never a dead dropdown / empty search with nothing behind it.","DO render Topbar inside `AppShell`'s `topbar` slot (or any `<header>`). For a non-three-cluster layout, pass `children` and lay it out yourself.","DO decide, explicitly, what happens to the `center` slot at 1100px and below. It is REMOVED there by default (`--topbar-center-compact-display: none`, gh#244) so it cannot cover the start or end clusters when a 16rem sidebar is docked \u2014 which also means a global search trigger in `center` is gone on tablets AND phones. This default arrived in 18.6.0 and changed behaviour for consumers who touched nothing but their lockfile. If your center content already has a compact presentation (an icon-only search trigger), opt back in globally with `:root { --topbar-center-compact-display: flex; }`; if it does not, move the trigger into `end` for compact widths. Never re-create either behaviour with a page-local media query.","DO rely on the built-in shrink contract instead of hand-tuning widths: the bar never exceeds its shell allocation, `start` shrinks first and `center` yields its whole box, each cluster CLIPS its own overflow (so a long tenant/brand string can never spill over a sibling or leak a horizontal document scroll), and `end` keeps its natural width anchored inline-end \u2014 the locale picker and user menu stay visible at 1024px with a 16rem sidebar. If a label must degrade gracefully rather than be cut, give THAT element `truncate`/`text-overflow` yourself; don't add `overflow`/`flex` overrides to the slots."],useCases:["Admin shell: `start` = sidebar toggle + brand mark (`Avatar`) + an entity switcher (`DropdownMenu` around a `Button`); `center` = a `Button` search trigger; `end` = `AppSettingPicker` (locale) + a notifications `Button` + a user `DropdownMenu`.","Minimal shell (no search, no notifications): pass only `start` (brand mark) and `end` (user menu). Nothing else renders \u2014 no empty chrome.","Marketing / docs header: pass `children` with a fully custom flex layout when the three-cluster model doesn't fit."],related:["AppShell \u2014 place Topbar in its `topbar` slot. AppShell also exposes its own `logo`/`topbarLeft`/`topbarRight` slots if you don't want a separate Topbar at all.",'Avatar \u2014 the brand mark for the `start` slot (use `className="rounded-md"` for a square-ish product glyph).',"AppSettingPicker \u2014 locale/theme/timezone/currency picker; the consumer drops it into `end`. Its appearance (icon-only, labelled, bordered) is configured on IT, not on Topbar.","DropdownMenu \u2014 wrap a `Button` to build an entity switcher or user menu yourself, then place it in a slot."],example:`import { Topbar, AppShell } from "@godxjp/ui/layout";
|
|
210
210
|
import { Button } from "@godxjp/ui/general";
|
|
211
211
|
import { Avatar, AvatarFallback } from "@godxjp/ui/data-display";
|
|
212
212
|
import { AppSettingPicker } from "@godxjp/ui/navigation";
|
|
@@ -451,7 +451,7 @@ export default function InvoiceList({
|
|
|
451
451
|
</DataTable.Toolbar>
|
|
452
452
|
</DataTable>
|
|
453
453
|
);
|
|
454
|
-
}`,storyPath:"data-display/DataTable.stories.tsx",rules:[24,31,35,37]},{name:"Card",group:"data-display",tagline:'Surface container with optional accent stripe, variant fill, size, and density. \u26A0\uFE0F The bare <Card> has NO inner padding \u2014 body content MUST be wrapped in <CardContent> (titles in <CardHeader>), or it sits FLUSH against the card edges. Never hand-roll padding with className="p-4"; use <CardContent>. Compose with CardHeader/CardTitle/CardContent/CardFooter. For a tab/toolbar/filter strip (view tabs, list controls) use <CardBar extra={\u2026}> \u2014 a positionable bar that auto-draws its separator from its position (top\u2192bottom border, bottom\u2192top border, middle\u2192both) and pins `extra` content to the inline-end edge; place it as first/last child of the Card. Never hand-roll a bordered div for this.',props:[{name:"accent",type:'"primary" | "success" | "warning" | "info" | "attention" | "destructive"',description:"
|
|
454
|
+
}`,storyPath:"data-display/DataTable.stories.tsx",rules:[24,31,35,37]},{name:"Card",group:"data-display",tagline:'Surface container with optional accent stripe, variant fill, size, and density. \u26A0\uFE0F The bare <Card> has NO inner padding \u2014 body content MUST be wrapped in <CardContent> (titles in <CardHeader>), or it sits FLUSH against the card edges. Never hand-roll padding with className="p-4"; use <CardContent>. Compose with CardHeader/CardTitle/CardContent/CardFooter. For a tab/toolbar/filter strip (view tabs, list controls) use <CardBar extra={\u2026}> \u2014 a positionable bar that auto-draws its separator from its position (top\u2192bottom border, bottom\u2192top border, middle\u2192both) and pins `extra` content to the inline-end edge; place it as first/last child of the Card. Never hand-roll a bordered div for this.',props:[{name:"accent",type:'"primary" | "success" | "warning" | "info" | "attention" | "destructive"',description:"Semantic accent TONE. Where it is drawn is `accentPlacement`'s job \u2014 by default a leading-edge stripe on `border-inline-start` at the `--card-accent-rail-width` measure (6px)."},{name:"accentPlacement",type:'"edge" | "perimeter"',defaultValue:'"edge"',description:'Where `accent` is drawn. "edge" is the classic leading rail. "perimeter" is the FULL attention border \u2014 the whole edge in the accent tone, at the same optical weight as `variant="featured"` but tone-owned, so a card can read as "action required" (accent="attention") or "failed" (accent="destructive") without borrowing the brand colour. Inert without `accent`. Switching placement never shifts the body text: the rail\'s slot-padding compensation is undone with it.'},{name:"variant",type:'"default" | "muted" | "outline" | "featured"',defaultValue:'"default"',description:'Surface fill style. `featured` is the BRAND perimeter; its colour is now the `--card-featured-border-color` knob rather than a hard-coded `--primary`. For a perimeter in a semantic tone use `accent` + `accentPlacement="perimeter"` instead.'},{name:"size",type:'"md" | "compact"',defaultValue:'"md"',description:"Card size preset."},{name:"density",type:'"tight" | "cozy"',description:"Internal padding density (base 16 / tight 12 / cozy 20)."}],usage:['DO always wrap body content in <CardContent> \u2014 the bare <Card> div has zero inner padding; content renders flush against card edges without it. Never add className="p-4" directly on <Card> as a substitute.',"DO put titles/descriptions in <CardHeader>/<CardTitle>/<CardDescription>. Use <CardHeader banded> for a visually separated muted-background header band (mirrors <CardFooter separated>). Pair with <CardAction> inside a flex-row CardHeader for header-level action buttons.",'DO set <CardTitle level={n}> to keep a valid document outline (h1 \u2192 h2 \u2192 h3, no skipped levels): CardTitle renders <h3> by default, so a section card directly under a page <h1> needs level={2}. Pick the level by OUTLINE position, NEVER for visual size \u2014 the title size is fixed by tokens and does not change with level. When the card title is a styled label rather than a section heading, use <CardTitle as="p"> so it is not announced as a heading.',"DO use <CardContent flush> for edge-to-edge children such as DataTable, Table, or a Tabs list \u2014 this removes horizontal padding. Combine with <CardContent tight> when there is no visual gap needed after the header, and <CardContent solo> when there is no CardHeader above (top padding matches the card shell).","DO use <CardFooter separated> to render a top-bordered action band (Save/Cancel buttons, table summary row). Use <CardFooter flush> for a full-bleed footer bar.","DO use <CardCover> as the first child for full-bleed cover media \u2014 the header below it uses card-section top spacing, not the card shell.",'DO reach for `accentPlacement="perimeter"` when the whole card needs attention, not one edge: `<Card accent="attention" accentPlacement="perimeter">` is the semantic-tone equivalent of `variant="featured"` (which is brand-toned by definition). Never hand-roll it with `className="border-2 border-[--attention]"` or a page-local `.card--attention` rule \u2014 the placement owns the border weight, the outer ring AND the slot-padding compensation, so text stays on the same column as an unaccented sibling.',"DON'T hand-roll a stat/KPI tile with <Card> + raw divs \u2014 use <StatCard> (label, value, hint, delta, layout, inverse props) which is already a Card internally with correct token-driven layout.","SPACING IS BORDER-AWARE & token-driven (theme via src/tokens/components/card.css, never hard-code padding on slots): `--card-space-inset` is the shared horizontal column every slot (header/content/footer) aligns to. A DIVIDED section \u2014 a `banded` header or a `separated` footer, i.e. one carrying a divider border \u2014 pads SYMMETRICALLY top+bottom from `--card-space-divided-y` (a band reads as its own region). A PLAIN header flows into the body instead: top `--card-space-shell-y`, no bottom, and the body supplies the gap via `--card-space-body-y`. THE TWO AXES ARE INDEPENDENT (gh#232): `--card-space-inset` is inline-only, while `--card-space-shell-y` owns the BLOCK shell edges (plain-header top, `solo` body top, terminal slot bottom) and defaults to the inset \u2014 so a shell/theme can make a card SHORTER without narrowing its column by overriding `--card-space-shell-y` alone (this is how AuthShell's `--auth-shell-card-padding-block-compact` reaches CardContent). Never bridge it with a consumer selector on the card-content slot. Special case: a header above `<CardContent flush>` with a <Table> gets its own `--card-space-body-y` bottom gap (the flush table zeroes its top), so the title never butts the table. `--card-space-gap` is the in-slot stack gap (title\u2195description). Tune the band rhythm once at `--card-space-divided-y`; tune the accent stripe width at `--card-accent-rail-width` (default 6px)."],useCases:['Dashboard KPI summary row: wrap each metric in <StatCard> (or a plain <Card size="compact"> with <CardContent>) to render a uniform grid of labeled value tiles with optional trend deltas.','Invoice or order detail panel: <Card accent="primary"> with <CardHeader banded><CardTitle>, <CardContent> body rows (use <Descriptions> inside), and <CardFooter separated> holding approve/reject buttons.',"Section container on a settings or form page: a single <Card> wrapping a <CardHeader><CardTitle> plus <CardContent> containing <FormField> groups, with <CardFooter separated> for Save/Cancel.","Data table with toolbar: <Card> + <CardHeader> (title + filter controls in <CardAction>) + <CardContent flush> containing <DataTable> \u2014 <CardContent flush> removes horizontal padding so the table header spans full width.",'Featured announcement or alert card: <Card variant="featured"> with an accent stripe (<accent="warning">) to visually elevate a card above sibling cards on the page.',"Media/cover card (e.g. entity profile): <CardCover> first (full-bleed image), then <CardHeader> + <CardContent> below it for structured metadata."],related:["StatCard \u2014 use instead of a plain Card when rendering a KPI/metric tile (label + value + optional delta/hint). StatCard is a Card internally; do not re-wrap it in another Card.","CardContent \u2014 mandatory inner wrapper for all body content inside Card. Provides the correct padding and supports flush/tight/solo variants. The only correct way to put padded content inside Card.","Descriptions \u2014 use inside <CardContent> when body content is a label-value metadata list (e.g. entity details, invoice fields); do not hand-roll a dl/dt/dd grid.","DataState / InfiniteQueryState \u2014 use instead of Card when the content is a TanStack Query-driven list that needs automatic skeleton, empty, and error states; Card does not manage loading lifecycle."],example:`import { Card, CardHeader, CardTitle, CardContent } from "@godxjp/ui/data-display";
|
|
455
455
|
|
|
456
456
|
<Card accent="success">
|
|
457
457
|
<CardHeader><CardTitle>\u6CE8\u6587\u30B5\u30DE\u30EA\u30FC</CardTitle></CardHeader>
|
|
@@ -925,7 +925,7 @@ import { Button } from "@godxjp/ui/general";
|
|
|
925
925
|
<DropdownMenuSeparator />
|
|
926
926
|
<DropdownMenuItem tone="destructive">\u524A\u9664</DropdownMenuItem>
|
|
927
927
|
</DropdownMenuContent>
|
|
928
|
-
</DropdownMenu>`,storyPath:"navigation/DropdownMenu.stories.tsx",rules:[]},{name:"Steps",group:"navigation",tagline:"Multi-step progress indicator \u2014 horizontal or vertical, default or dot style.",props:[{name:"items",type:"StepItemProp[]",description:"Array of { title, subtitle?, description?, icon?, status? }."},{name:"value",type:"number",defaultValue:"0",description:"Active step index (0-based)."},{name:"defaultValue",type:"number",defaultValue:"0",description:"Base offset for the first rendered step index."},{name:"orientation",type:'"horizontal" | "vertical"',defaultValue:'"horizontal"',description:"Layout direction."},{name:"status",type:'"wait" | "process" | "finish" | "error"',description:"Status of the CURRENT step (drives the active step colour)."},{name:"type",type:'"default" | "dot" | "inline"',description:"Render full markers, compact dots, or a numbered inline auth progress row."},{name:"size",type:'"md" | "sm"',description:"Step size."},{name:"titlePlacement",type:'"horizontal" | "vertical"',description:"Lay step titles beside or below the step icons."},{name:"onValueChange",type:"(value: number) => void",description:"Fires with the clicked step index (0-based)."}],usage:["DO: Pass all steps via the `items` array (each `{ title, subtitle?, description?, icon?, status?, disabled? }`) \u2014 Steps is a single-component API with no child sub-components to compose manually.","DO: Control the active step with `value` (0-based index). For async operations, set the top-level `status` prop (`'process'|'error'|'finish'`) to override the current step's icon \u2014 e.g. `status='error'` turns the active step red without touching `items`.","DO: Use per-item `status` to pin individual steps independently of `value` (e.g. a skipped or already-errored step). Per-item `status` takes precedence over the derived status from `value`.","DO: Use type='inline' for compact hosted-auth/device progress. It retains process/finish/error/wait and aria-current semantics without the tall icon rail; never rebuild the row from Text and arrows in a consumer.","DON'T: Use Steps for navigation that needs URL routing or tab-switching \u2014 it has no built-in panel rendering. Pair it with your own conditional panel or a `Tabs`/`Tabs` body; Steps only renders the indicator bar.","DON'T: Wire `onValueChange` unless you actually support non-linear navigation. `onValueChange` makes every non-disabled step clickable (rendered as `<button>`); omitting it makes all steps non-interactive (`cursor-default`). Never set `disabled` on an item without also providing `onValueChange`, or the prop is meaningless.","A11y: The `<ol>` is given `aria-label='Progress'` automatically. Individual steps render as `<button type='button'>` when `onValueChange` is present \u2014 ensure each `item.title` is descriptive enough to serve as the button label; avoid icon-only steps without a visible title."],useCases:["Multi-step form wizard (entity onboarding, invoice creation): render Steps above a form, drive `current` from local state, advance on validated submit \u2014 use `status='error'` on the current step when server validation fails.","Async background job tracker: display steps for a long-running import/export pipeline; poll job status and map job phases to `StepStatusProp` values (`'process'` with spinner for in-flight, `'finish'` for done, `'error'` for failed).","Document approval workflow (accounting, contracts): map approval stages (Draft \u2192 Review \u2192 Approved \u2192 Archived) to `items` with per-item `status` reflecting the real state from the server \u2014 use `orientation='vertical'` for a sidebar timeline feel.","Onboarding checklist sidebar: `orientation='vertical'` + `type='dot'` + `size='sm'` for a compact sidebar progress guide alongside a multi-section settings page.","Non-linear step navigation (e.g. revisit a previous step to correct data): provide `onValueChange` and leave only future steps `disabled`; past and current steps become clickable buttons."],related:["Timeline \u2014 use Timeline (from @godxjp/ui) when you need a chronological event log with timestamps and variable content per entry; use Steps when the number of stages is fixed and forward-progress is the semantic.","Tabs / Tabs \u2014 use Tabs when each section has its own rendered panel and users switch freely between them; use Steps when stages are ordered and the indicator communicates completion state rather than just selection.","Progress \u2014 use Progress for a single continuous percentage (file upload, quota fill); use Steps for discrete named stages with individual pass/fail status.","Breadcrumb \u2014 use Breadcrumb for hierarchical location within a page tree; use Steps for sequential workflow progress where order and completion matter."],example:`import { Steps } from "@godxjp/ui/navigation";
|
|
928
|
+
</DropdownMenu>`,storyPath:"navigation/DropdownMenu.stories.tsx",rules:[]},{name:"Steps",group:"navigation",tagline:"Multi-step progress indicator \u2014 horizontal or vertical, default or dot style.",props:[{name:"items",type:"StepItemProp[]",description:"Array of { title, subtitle?, description?, icon?, status? }."},{name:"value",type:"number",defaultValue:"0",description:"Active step index (0-based)."},{name:"defaultValue",type:"number",defaultValue:"0",description:"Base offset for the first rendered step index."},{name:"orientation",type:'"horizontal" | "vertical"',defaultValue:'"horizontal"',description:"Layout direction."},{name:"status",type:'"wait" | "process" | "finish" | "error"',description:"Status of the CURRENT step (drives the active step colour)."},{name:"type",type:'"default" | "dot" | "inline"',description:"Render full markers, compact dots, or a numbered inline auth progress row."},{name:"size",type:'"md" | "sm"',description:"Step size."},{name:"titlePlacement",type:'"horizontal" | "vertical"',description:"Lay step titles beside or below the step icons."},{name:"separator",type:'"chevron" | "arrow"',defaultValue:'"chevron"',description:'The glyph between INLINE steps (`type="inline"` only; gh#12). `chevron` (\u203A) is the breadcrumb-flavoured original; `arrow` (\u2192) is the canonical hosted-identity progression marker \u2014 a chevron reads "drill into", an arrow reads "then", which is what a step row means. Both flip under dir="rtl". Ignored by every other `type`.'},{name:"onValueChange",type:"(value: number) => void",description:"Fires with the clicked step index (0-based)."}],usage:["DO: Pass all steps via the `items` array (each `{ title, subtitle?, description?, icon?, status?, disabled? }`) \u2014 Steps is a single-component API with no child sub-components to compose manually.","DO: Control the active step with `value` (0-based index). For async operations, set the top-level `status` prop (`'process'|'error'|'finish'`) to override the current step's icon \u2014 e.g. `status='error'` turns the active step red without touching `items`.","DO: Use per-item `status` to pin individual steps independently of `value` (e.g. a skipped or already-errored step). Per-item `status` takes precedence over the derived status from `value`.","DO: Use type='inline' for compact hosted-auth/device progress. It retains process/finish/error/wait and aria-current semantics without the tall icon rail; never rebuild the row from Text and arrows in a consumer.",'DO: Pick the inline progression marker with `separator` (`"arrow"` for the canonical hosted-identity row, `"chevron"` for the default), and express the step-number emphasis through `--steps-inline-index-{color,font-weight}` + `--steps-inline-separator-color` in the service theme. The canonical treatment is an accent TINT at normal weight; the library default is bold at the inherited colour. Both are one token away \u2014 never fork `.ui-steps-inline-index` in app CSS.',"DON'T: Use Steps for navigation that needs URL routing or tab-switching \u2014 it has no built-in panel rendering. Pair it with your own conditional panel or a `Tabs`/`Tabs` body; Steps only renders the indicator bar.","DON'T: Wire `onValueChange` unless you actually support non-linear navigation. `onValueChange` makes every non-disabled step clickable (rendered as `<button>`); omitting it makes all steps non-interactive (`cursor-default`). Never set `disabled` on an item without also providing `onValueChange`, or the prop is meaningless.","A11y: The `<ol>` is given `aria-label='Progress'` automatically. Individual steps render as `<button type='button'>` when `onValueChange` is present \u2014 ensure each `item.title` is descriptive enough to serve as the button label; avoid icon-only steps without a visible title."],useCases:["Multi-step form wizard (entity onboarding, invoice creation): render Steps above a form, drive `current` from local state, advance on validated submit \u2014 use `status='error'` on the current step when server validation fails.","Async background job tracker: display steps for a long-running import/export pipeline; poll job status and map job phases to `StepStatusProp` values (`'process'` with spinner for in-flight, `'finish'` for done, `'error'` for failed).","Document approval workflow (accounting, contracts): map approval stages (Draft \u2192 Review \u2192 Approved \u2192 Archived) to `items` with per-item `status` reflecting the real state from the server \u2014 use `orientation='vertical'` for a sidebar timeline feel.","Onboarding checklist sidebar: `orientation='vertical'` + `type='dot'` + `size='sm'` for a compact sidebar progress guide alongside a multi-section settings page.","Non-linear step navigation (e.g. revisit a previous step to correct data): provide `onValueChange` and leave only future steps `disabled`; past and current steps become clickable buttons."],related:["Timeline \u2014 use Timeline (from @godxjp/ui) when you need a chronological event log with timestamps and variable content per entry; use Steps when the number of stages is fixed and forward-progress is the semantic.","Tabs / Tabs \u2014 use Tabs when each section has its own rendered panel and users switch freely between them; use Steps when stages are ordered and the indicator communicates completion state rather than just selection.","Progress \u2014 use Progress for a single continuous percentage (file upload, quota fill); use Steps for discrete named stages with individual pass/fail status.","Breadcrumb \u2014 use Breadcrumb for hierarchical location within a page tree; use Steps for sequential workflow progress where order and completion matter."],example:`import { Steps } from "@godxjp/ui/navigation";
|
|
929
929
|
|
|
930
930
|
<Steps value={1} items={[{ title: "\u7533\u8ACB" }, { title: "\u5BE9\u67FB\u4E2D" }, { title: "\u5B8C\u4E86" }]} />`,storyPath:"navigation/Steps.stories.tsx",rules:[]},{name:"Toolbar",group:"navigation",tagline:"List-page filter strip (the framework FilterBar) \u2014 SearchInput + labelled ToolbarGroup filter slots + a clear-all affordance, optionally sticky.",props:[{name:"children",type:"ReactNode",required:!0,description:"Filter controls. Place SearchInput directly; wrap each labelled Select/DatePicker in a ToolbarGroup."},{name:"onClear",type:"() => void",description:"Clear-all handler. When provided AND hasActiveFilters is true, Toolbar renders the trailing 'Clear filters' button."},{name:"hasActiveFilters",type:"boolean",defaultValue:"true",description:"Whether any filter is applied \u2014 gates the clear-all button visibility."},{name:"sticky",type:"boolean",defaultValue:"false",description:"Pin the strip to the top of its scroll container while the list scrolls beneath it (#197). Opt-in; tune offset/fill via the --filter-bar-sticky-offset / --filter-bar-sticky-background theme knobs."},{name:"overflow",type:"'wrap' | 'scroll'",defaultValue:"'wrap'",description:"Responsive overflow strategy (gh#216). 'wrap' stacks the groups into one column below 640px, then wraps onto extra rows. 'scroll' keeps ONE bounded row at >=640px that scrolls inline (groups never shrink; the clear-all button stays sticky at the inline end) \u2014 use it when many filters with long JA/EN/VI labels would otherwise push the table below the fold. Below 640px 'scroll' still stacks, so a 390px viewport never hides a filter behind an invisible horizontal scroll. Gutter knob: --filter-bar-scroll-padding-y."},{name:"className",type:"string",description:"Extra classes on the role='toolbar' element."}],usage:["DO place Toolbar ABOVE the table Card, never inside a `CardContent flush`. Put SearchInput as a direct child (it self-labels) and wrap every other control in a ToolbarGroup with a `label`.","DO drive the clear-all button with `hasActiveFilters` + `onClear` \u2014 it only renders when both are truthy. The strip collapses to a single stacked column below 640px automatically.","DO set `sticky` for long list pages so the filters stay reachable while scrolling; if a topbar sits above the list, raise `--filter-bar-sticky-offset` so the strip parks below it.","DO pass `controlId` on a ToolbarGroup that wraps ONE control (gh#216) and give that control the same `id` \u2014 the visible caption then becomes the control's real `<label htmlFor>` (WCAG 2.5.3 label-in-name). Without it the caption only names the group wrapper and the control itself is NAMELESS (axe: select-name / button-name), so you must fall back to an `aria-label` that repeats the caption.","DO switch to `overflow='scroll'` when a list page carries more filters than fit one row (gh#216) \u2014 one bounded row that scrolls inline keeps the table above the fold, where the default `wrap` would grow a 3-row strip with long JA/EN/VI labels. Never re-implement the geometry in the page: no page-local flex/grid/width rules on a filter strip.","DON'T build active-filter chips by nesting a Button inside a Badge (invalid markup + broken focus). Render each chip as a Badge label with a SIBLING icon Button (`aria-label` = 'clear <filter>'); a ghost `size='sm'` Button clears all.","DON'T hand-roll a debounced search box or a raw `<select>` \u2014 compose SearchInput and Select. Toolbar is layout + clear-all only; the controls own their own state and a11y."],useCases:["Master list screens (members, organizations, subscriptions, invoices) that need free-text search plus a few dropdown filters above a DataTable.","Sticky filter strip over a tall list where the filters must remain visible as the user scrolls the results.","Filtered views that surface applied conditions as removable chips (clear-one via each chip's \xD7 Button, clear-all via `onClear`)."],related:["ToolbarGroup \u2014 the labelled wrapper for each individual filter control inside a Toolbar (SearchInput is placed directly, without a group).","DataTable.Toolbar \u2014 the in-table strip for column/density/bulk-action controls; Toolbar (this) is the page-level filter strip that sits ABOVE the table.","SearchInput \u2014 the debounced free-text control placed as the first child of Toolbar.","Badge \u2014 compose Badge + a sibling icon Button to render each active-filter chip; Badge itself is a non-interactive leaf."],example:`import { Toolbar, ToolbarGroup } from "@godxjp/ui/navigation";
|
|
931
931
|
import { SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@godxjp/ui/data-entry";
|
|
@@ -1673,7 +1673,7 @@ import { fetchInvoice } from "@/api/invoices";
|
|
|
1673
1673
|
prefetchOn="none"
|
|
1674
1674
|
>
|
|
1675
1675
|
{invoice.number}
|
|
1676
|
-
</PrefetchLink>`,storyPath:"data-display/PrefetchLink.stories.tsx",rules:[2,3,31]},{name:"Avatar",group:"data-display",tagline:"Radix Avatar wrapper with image and fallback slots for users, teams, and entities.",props:[{name:"shape",type:'"circle" | "square"',defaultValue:'"circle"',description:'Identity geometry. `circle` (default, inert) is the PERSON avatar \u2014 the round --radius-pill mark on the muted surface. `square` is the ENTITY-HEADER organization/service mark (gh#249): a compact rounded square on the brand surface, whose radius, box size, fill and glyph colour are all --avatar-square-{radius,size,background,foreground} tokens. Pick the shape by WHAT the mark represents; never hand-roll it with className="rounded-md bg-primary".'},{name:"children",type:"ReactNode",description:"Compose AvatarImage and AvatarFallback."},{name:"className",type:"string",description:"Extra classes on the avatar root."}],usage:["DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.",'DO use `shape="square"` for an organization / service / tenant mark in an entity header, and keep the default `shape="circle"` for people. The square appearance already carries the brand surface and an AA-contrast glyph colour \u2014 a className/colour override on the call site is never needed (and is forbidden by the API-first redesign policy).',"DON'T retune the entity mark per call site: set --avatar-square-{radius,size,background,foreground} ONCE in the service theme (e.g. --avatar-square-background: hsl(var(--muted)) for a neutral mark).","DON'T use Avatar for decorative thumbnails; use CardCover or an img when the image is content rather than identity."],useCases:["User profile chips","Team member lists","Account owner cells in a DataTable",'Organization / service entity headers (shape="square" beside the entity name and code)'],related:["Badge \u2014 use beside Avatar for role/status metadata."],example:`import { Avatar, AvatarFallback, AvatarImage } from "@godxjp/ui/data-display";
|
|
1676
|
+
</PrefetchLink>`,storyPath:"data-display/PrefetchLink.stories.tsx",rules:[2,3,31]},{name:"Avatar",group:"data-display",tagline:"Radix Avatar wrapper with image and fallback slots for users, teams, and entities.",props:[{name:"shape",type:'"circle" | "square"',defaultValue:'"circle"',description:'Identity geometry. `circle` (default, inert) is the PERSON avatar \u2014 the round --radius-pill mark on the muted surface. `square` is the ENTITY-HEADER organization/service mark (gh#249): a compact rounded square on the brand surface, whose radius, box size, fill and glyph colour are all --avatar-square-{radius,size,background,foreground} tokens. Pick the shape by WHAT the mark represents; never hand-roll it with className="rounded-md bg-primary".'},{name:"appearance",type:'"default" | "tinted"',defaultValue:'"default"',description:'Fill treatment, ORTHOGONAL to `shape`. `default` (inert) is the identity fill \u2014 --muted for a person, the solid brand mark for `shape="square"`. `tinted` is the CAPABILITY MEDALLION (gh#12): a soft role wash behind a role-coloured glyph, with the glyph sized by the component. `shape="square" appearance="tinted"` is the canonical rounded-square medallion a feature/capability icon sits on. Retune with --avatar-tinted-{background,foreground,glyph-size}.'},{name:"children",type:"ReactNode",description:"Compose AvatarImage and AvatarFallback."},{name:"className",type:"string",description:"Extra classes on the avatar root."}],usage:["DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.",'DO render a capability / feature icon as `<Avatar shape="square" appearance="tinted"><AvatarFallback><Sparkles aria-hidden /></AvatarFallback></Avatar>` \u2014 the medallion is a COMPOSITION (Avatar + a Lucide glyph, per docs/COMPOSITION-VS-COMPONENT.md), and `appearance="tinted"` is the token-owned tint that composition needs. A BARE glyph beside a card title, or a hand-derived `hsl(var(--primary) / 0.1)` plate in page CSS, are both the anti-pattern this replaces. Left-aligned capability card: `<Card><CardHeader className="flex flex-row items-center gap-3"><Avatar shape="square" appearance="tinted">\u2026</Avatar><CardTitle>\u2026</CardTitle></CardHeader>\u2026`.','DO use `shape="square"` for an organization / service / tenant mark in an entity header, and keep the default `shape="circle"` for people. The square appearance already carries the brand surface and an AA-contrast glyph colour \u2014 a className/colour override on the call site is never needed (and is forbidden by the API-first redesign policy).',"DON'T retune the entity mark per call site: set --avatar-square-{radius,size,background,foreground} ONCE in the service theme (e.g. --avatar-square-background: hsl(var(--muted)) for a neutral mark).","DON'T use Avatar for decorative thumbnails; use CardCover or an img when the image is content rather than identity."],useCases:["User profile chips","Team member lists","Account owner cells in a DataTable",'Organization / service entity headers (shape="square" beside the entity name and code)'],related:["Badge \u2014 use beside Avatar for role/status metadata."],example:`import { Avatar, AvatarFallback, AvatarImage } from "@godxjp/ui/data-display";
|
|
1677
1677
|
|
|
1678
1678
|
<Avatar>
|
|
1679
1679
|
<AvatarImage src="/user.png" alt="User" />
|
|
@@ -1723,7 +1723,7 @@ export default function PasswordBlock() {
|
|
|
1723
1723
|
<PasswordStrength value={value} rules={rules} />
|
|
1724
1724
|
</div>
|
|
1725
1725
|
);
|
|
1726
|
-
}`,storyPath:"data-entry/PasswordStrength.stories.tsx",rules:[3,6]},{name:"InputOTP",group:"data-entry",tagline:"One-time-code / 2FA input (input-otp) \u2014 N single-character slots that behave as one field. Compose InputOTP > InputOTPGroup > InputOTPSlot.",props:[{name:"maxLength",type:"number",required:!0,description:"Number of slots (e.g. 6)."},{name:"value",type:"string",description:"Controlled value."},{name:"onChange",type:"(value: string) => void",description:"Value callback (this is a true text input \u2014 onChange is the DOM-style value handler here)."},{name:"pattern",type:"string",description:"Allowed-char regex (e.g. digits only)."}],usage:["DO set `maxLength` to the code length and render that many InputOTPSlot with sequential `index`.","DO wrap slots in InputOTPGroup; use InputOTPSeparator between groups (e.g. 3 + 3).","For device codes, set `appearance='grouped'` on each InputOTPGroup to render one outline per group while preserving the single hidden input, paste, caret, keyboard and screen-reader behavior.","DON'T build N separate Inputs \u2014 this is ONE field with paste, arrow-key, and caret handling built in.","DO widen the slots with `--otp-slot-size` (gh#233) when a challenge row must fill a wide auth panel \u2014 it defaults to the live `--control-height` tier, so re-scoping `--control-height` on the card instead would also resize the submit button and every other input in it. Set a NAMED tier (`var(--control-height-lg)`), never an ad-hoc calc offset.","DO drive the sign-in MFA challenge from FormField: `error` wires aria-invalid + aria-errormessage + a role=alert message onto the single field, and the slot borders turn destructive. State is never colour-only."],useCases:["2FA / OTP verification code","Email / SMS confirmation code","PIN entry","Invite / redemption code"],related:["Input (a normal single text field)","PasswordInput (masked secret field)"],example:`import { InputOTP, InputOTPGroup, InputOTPSlot } from "@godxjp/ui/data-entry";
|
|
1726
|
+
}`,storyPath:"data-entry/PasswordStrength.stories.tsx",rules:[3,6]},{name:"InputOTP",group:"data-entry",tagline:"One-time-code / 2FA input (input-otp) \u2014 N single-character slots that behave as one field. Compose InputOTP > InputOTPGroup > InputOTPSlot.",props:[{name:"maxLength",type:"number",required:!0,description:"Number of slots (e.g. 6)."},{name:"value",type:"string",description:"Controlled value."},{name:"onChange",type:"(value: string) => void",description:"Value callback (this is a true text input \u2014 onChange is the DOM-style value handler here)."},{name:"pattern",type:"string",description:"Allowed-char regex (e.g. digits only)."},{name:"align",type:'"start" | "center" | "end"',defaultValue:'"start"',description:"Main-axis alignment of the whole code row (groups + separators) inside the field (gh#12). `center` is the canonical auth challenge. Before this existed, every consumer wrapped the OTP in their own flex-centring div \u2014 do not. A service that wants all code fields centred sets `--otp-container-align` once instead."}],usage:["DO set `maxLength` to the code length and render that many InputOTPSlot with sequential `index`.",'DO centre a challenge with `align="center"` on InputOTP \u2014 never with a wrapper `<div className="flex justify-center">`. The container is owned by input-otp, so a wrapper is the only thing a consumer CAN reach, which is exactly why the prop exists.',"DO wrap slots in InputOTPGroup; use InputOTPSeparator between groups (e.g. 3 + 3).","For device codes, set `appearance='grouped'` on each InputOTPGroup to render one outline per group while preserving the single hidden input, paste, caret, keyboard and screen-reader behavior.","DON'T build N separate Inputs \u2014 this is ONE field with paste, arrow-key, and caret handling built in.","DO widen the slots with `--otp-slot-size` (gh#233) when a challenge row must fill a wide auth panel \u2014 it defaults to the live `--control-height` tier, so re-scoping `--control-height` on the card instead would also resize the submit button and every other input in it. Set a NAMED tier (`var(--control-height-lg)`), never an ad-hoc calc offset.",'DO use `--otp-slot-inline-size` / `--otp-slot-block-size` (gh#12) when the code field is NOT square \u2014 a device-grant slot is taller than it is wide. They win over the `--otp-slot-size` shorthand and fall back to it, so setting neither keeps the square control tier. You rarely set them by hand inside `AuthShell preset="device-authorization"`: that preset already owns its code-field measure.',"DO drive the sign-in MFA challenge from FormField: `error` wires aria-invalid + aria-errormessage + a role=alert message onto the single field, and the slot borders turn destructive. State is never colour-only."],useCases:["2FA / OTP verification code","Email / SMS confirmation code","PIN entry","Invite / redemption code"],related:["Input (a normal single text field)","PasswordInput (masked secret field)"],example:`import { InputOTP, InputOTPGroup, InputOTPSlot } from "@godxjp/ui/data-entry";
|
|
1727
1727
|
|
|
1728
1728
|
<InputOTP maxLength={6}>
|
|
1729
1729
|
<InputOTPGroup>
|
|
@@ -1930,7 +1930,7 @@ import { Button } from "@godxjp/ui/general";
|
|
|
1930
1930
|
<FilterBarGroup label="Status" controlId="f-status">
|
|
1931
1931
|
<StatusSelect id="f-status" />
|
|
1932
1932
|
</FilterBarGroup>
|
|
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
|
|
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): 44px tall 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. The height is a TOUCH TARGET and is deliberately DECOUPLED from --control-height-lg (36px), which it mirrored until 18.8.0 \u2014 do not restore the mirror. Email is touch-only: no hover, no precise pointer, no dependable zoom, so the web AA floor (SC 2.5.8, 24\xD724, which 36px clears) is the wrong bar. 44px is SC 2.5.5 Target Size (Enhanced, AAA, 44\xD744) plus the Apple HIG 44pt / Material 48dp convention, and the mobile reflow still 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,otp-slot-inline-size,otp-slot-block-size}",category:"component",tier:"component",role:'AuthShell `preset="device-authorization"` measure (gh#220, gh#12) \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), PLUS the code field the flow is actually about. The preset now owns its OTP slot box and hands it to --otp-slot-{inline,block}-size: 27.5x52 per slot, i.e. a 4-slot `appearance="grouped"` box of 112x54 with its 1px group border. Without it the field fell back to the square --control-height tier and rendered 146x38 against that artboard \u2014 the preset owned the page but not its subject. 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:"--otp-slot-{inline-size,block-size}",category:"component",tier:"component",role:'Per-AXIS InputOTP slot box (gh#12). --otp-slot-size stays the SQUARE shorthand; these two win over it and fall back to it, so a code field that is taller than it is wide \u2014 the canonical device-grant slot, 27.5x52 \u2014 is finally expressible from a token. Declared `initial` so the whole chain (axis \u2192 square \u2192 --control-height) resolves at the CALL SITE and a shell that re-scopes --control-height still reaches a field that sets neither axis. `AuthShell preset="device-authorization"` sets both for you.'},{name:"--otp-container-align",category:"component",tier:"component",role:'Main-axis alignment of the whole InputOTP row (gh#12). Default `flex-start` = the historical layout, so nothing moves. It exists because a centred code challenge is the common auth case and the container element belongs to `input-otp` \u2014 the only thing a consumer could reach was a wrapper div, and every one of them wrote it. Per instance use `align="center"` on InputOTP, which outranks this token.'},{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:"--avatar-tinted-{background,foreground,glyph-size}",category:"component",tier:"component",role:'Avatar `appearance="tinted"` \u2014 the CAPABILITY MEDALLION (gh#12): the tinted plate a feature/capability glyph sits on, as opposed to the solid entity mark above. Orthogonal to `shape`, so `shape="square" appearance="tinted"` is the canonical rounded square. --avatar-tinted-background / --avatar-tinted-foreground are declared `initial` so the hsl(var(--primary) / 0.1) / hsl(var(--primary)) defaults re-resolve at the CALL SITE under a scoped [data-tenant]/.dark theme \u2014 which is the whole point: consumers were writing that 0.1 alpha literal into page CSS, or giving up and rendering a bare glyph, because the medallion is a composition (Avatar + a Lucide glyph) whose tint had no token. Defaults = 10% primary wash \xB7 primary glyph \xB7 --control-icon-size glyph box.'},{name:"--steps-inline-{gap,item-gap,font-size,separator-size,index-font-weight,index-color,separator-color}",category:"component",tier:"component",role:"Steps type=inline compact auth/device progress rhythm, typography and EMPHASIS (gh#12). Consumers select the semantic appearance; services retune the row once without page CSS. The step number's emphasis is two knobs \u2014 --steps-inline-index-font-weight (default bold) and --steps-inline-index-color (role-mirror `initial`, default the inherited step colour) \u2014 because the canonical hosted-identity row marks the step with an accent TINT at normal weight while the library default marks it with bold. --steps-inline-separator-color (role-mirror `initial`, default --muted-foreground) tints the glyph the `separator` prop picks."},{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-{accent-rail-width,accent-perimeter-width,accent-perimeter-ring-width,featured-border-color,featured-ring-width}",category:"component",tier:"component",role:'Card ACCENT geometry, one set per placement (gh#12). `accentPlacement="edge"` (the default) draws the leading rail at --card-accent-rail-width (6px). `accentPlacement="perimeter"` draws the FULL attention border, measured by --card-accent-perimeter-width + --card-accent-perimeter-ring-width (1px + 1px, the optical weight of `variant="featured"`) in the card\'s own semantic accent tone. `variant="featured"` is the brand-toned member of the same family and no longer hard-codes --primary: its edge is the --card-featured-border-color role-mirror knob (`initial`, so the --primary default resolves at the CALL SITE and a scoped [data-tenant]/.dark override reaches it) at --card-featured-ring-width. The accent COLOUR itself is not a knob \u2014 it is resolved from `data-accent` on the card, so retint the ROLE (--attention, --success \u2026).'},{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:"--card-accent-perimeter-width",value:"1px",description:'Accent placement `perimeter` (gh#12) \u2014 the FULL attention border. Two knobs so a service can * tune the edge weight and the outer ring independently; the defaults reproduce the optical * weight of `variant="featured"` (1px border + 1px ring) in the card\'s own semantic accent tone * instead of --primary. Structural 1px literals, like the base card hairline.'},{name:"--card-accent-perimeter-ring-width",value:"1px",description:'Accent placement `perimeter` (gh#12) \u2014 the FULL attention border. Two knobs so a service can * tune the edge weight and the outer ring independently; the defaults reproduce the optical * weight of `variant="featured"` (1px border + 1px ring) in the card\'s own semantic accent tone * instead of --primary. Structural 1px literals, like the base card hairline.'},{name:"--card-featured-border-color",value:"initial",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--card-featured-ring-width",value:"1px",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-label-font-size",value:"var(--font-size-xs)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-label-font-weight",value:"var(--font-weight-medium)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-label-letter-spacing",value:"0.04em",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-value-font-size",value:"var(--font-size-2xl)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-value-line-height",value:"1.1",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-value-font-weight",value:"var(--font-weight-semibold)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-hint-font-size",value:"var(--font-size-xs)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-gap",value:"var(--space-stack-xs)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-icon-size",value:"2.25rem",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-icon-glyph-size",value:"1.25rem",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{name:"--stat-card-icon-radius",value:"var(--radius-md)",description:'`variant="featured"` edge \u2014 role-mirror knob (docs/TOKENS.md). `initial` so the --primary * default resolves at the CALL SITE and a scoped [data-tenant]/.dark override of --primary * reaches it; a service points it anywhere (e.g. var(--attention)) to retint every featured card * at once. Default = hsl(var(--primary)).'},{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:"--otp-slot-inline-size",value:"initial",description:'Per-AXIS overrides of the slot box (gh#12). --otp-slot-size stays the square shorthand; these * two win over it when set, so a code field can be WIDER-than-tall or TALLER-than-wide without * abandoning the token. A canonical device-grant code field is 27.5x52 per slot (a 4-slot * `appearance="grouped"` box of 112x54 with its 1px group border) \u2014 not expressible with one * square knob, which is why grouped OTP measured 146x38 against that artboard. `initial` for the * same tier-mirror reason as --otp-slot-size: the whole fallback chain * (axis \u2192 square \u2192 --control-height) must resolve at the CALL SITE so a shell that re-scopes * --control-height still reaches an OTP row that sets neither axis.'},{name:"--otp-slot-block-size",value:"initial",description:"default = var(--otp-slot-size, var(--control-height))"},{name:"--otp-container-align",value:"flex-start",description:'Main-axis alignment of the whole OTP row (rule #44/#45 \u2014 chrome is a token, default quiet). * `flex-start` is the historical behaviour, so an existing field is byte-identical; a centred * code field is `align="center"` on InputOTP (which wins over this knob) or this token set once * in a service theme. It exists because EVERY consumer was wrapping .ui-otp-container in a * flex-centring div to get a centred challenge.'},{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:"--avatar-tinted-background",value:"initial",description:'Capability medallion \u2014 `<Avatar appearance="tinted">` (gh#12): the tinted plate a capability / feature glyph sits on, as opposed to the SOLID entity mark above. Pair it with shape="square" for the canonical rounded square. --avatar-tinted-background / --avatar-tinted-foreground are role-mirror knobs (`initial`, docs/TOKENS.md) so the --primary defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override of --primary reaches them \u2014 the exact reason this is a token and not the `hsl(var(--primary) / 0.1)` literal consumers were writing in page CSS. Defaults = hsl(var(--primary) / 0.1) wash \xB7 hsl(var(--primary)) glyph \xB7 --control-icon-size glyph box.'},{name:"--avatar-tinted-foreground",value:"initial",description:'Capability medallion \u2014 `<Avatar appearance="tinted">` (gh#12): the tinted plate a capability / feature glyph sits on, as opposed to the SOLID entity mark above. Pair it with shape="square" for the canonical rounded square. --avatar-tinted-background / --avatar-tinted-foreground are role-mirror knobs (`initial`, docs/TOKENS.md) so the --primary defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override of --primary reaches them \u2014 the exact reason this is a token and not the `hsl(var(--primary) / 0.1)` literal consumers were writing in page CSS. Defaults = hsl(var(--primary) / 0.1) wash \xB7 hsl(var(--primary)) glyph \xB7 --control-icon-size glyph box.'},{name:"--avatar-tinted-glyph-size",value:"var(--control-icon-size)",description:'Capability medallion \u2014 `<Avatar appearance="tinted">` (gh#12): the tinted plate a capability / feature glyph sits on, as opposed to the SOLID entity mark above. Pair it with shape="square" for the canonical rounded square. --avatar-tinted-background / --avatar-tinted-foreground are role-mirror knobs (`initial`, docs/TOKENS.md) so the --primary defaults resolve at the CALL SITE and a scoped [data-tenant]/.dark override of --primary reaches them \u2014 the exact reason this is a token and not the `hsl(var(--primary) / 0.1)` literal consumers were writing in page CSS. Defaults = hsl(var(--primary) / 0.1) wash \xB7 hsl(var(--primary)) glyph \xB7 --control-icon-size glyph box.'},{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:"44px",description:`TOUCH TARGET, deliberately DECOUPLED from --control-height-lg (36px). Do not "restore" the * mirror: email is a mobile-first, touch-only medium. There is no hover state, no precise * pointer, and mail clients do not reliably offer zoom or a focus affordance \u2014 so the web's AA * floor (SC 2.5.8, 24x24, which 36px clears) is the wrong bar here. 44px is the AAA target size * (SC 2.5.5, 44x44) and the Apple HIG 44pt / Material 48dp convention. A service that must keep * the old box sets --email-cta-height + --email-cta-line-height in its own theme.`},{name:"--email-cta-line-height",value:"44px",description:`TOUCH TARGET, deliberately DECOUPLED from --control-height-lg (36px). Do not "restore" the * mirror: email is a mobile-first, touch-only medium. There is no hover state, no precise * pointer, and mail clients do not reliably offer zoom or a focus affordance \u2014 so the web's AA * floor (SC 2.5.8, 24x24, which 36px clears) is the wrong bar here. 44px is the AAA target size * (SC 2.5.5, 44x44) and the Apple HIG 44pt / Material 48dp convention. A service that must keep * the old box sets --email-cta-height + --email-cta-line-height in its own theme.`},{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:"--steps-inline-index-font-weight",value:"var(--font-weight-bold)",description:"Inline-step emphasis (gh#12). The step number's weight and tint are separate knobs so a * service can express progression the canonical way \u2014 an accent TINT at normal weight \u2014 instead * of the original bold. --steps-inline-index-color / --steps-inline-separator-color are * role-mirror knobs (docs/TOKENS.md): `initial` so their defaults (the inherited step colour and * the --muted-foreground role) resolve at the CALL SITE and a scoped [data-tenant]/.dark * override still reaches them. Defaults reproduce today's row byte for byte."},{name:"--steps-inline-index-color",value:"initial",description:"Inline-step emphasis (gh#12). The step number's weight and tint are separate knobs so a * service can express progression the canonical way \u2014 an accent TINT at normal weight \u2014 instead * of the original bold. --steps-inline-index-color / --steps-inline-separator-color are * role-mirror knobs (docs/TOKENS.md): `initial` so their defaults (the inherited step colour and * the --muted-foreground role) resolve at the CALL SITE and a scoped [data-tenant]/.dark * override still reaches them. Defaults reproduce today's row byte for byte."},{name:"--steps-inline-separator-color",value:"initial",description:"default = currentColor at the call site"},{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:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-trigger-height",value:"2.75rem",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-trigger-padding-x",value:"var(--space-2)",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-avatar-size",value:"1.75rem",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-menu-width",value:"16rem",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-sheet-max-height",value:"75dvh",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{name:"--org-switcher-state-min-height",value:"8rem",description:"\u26A0 THIS KNOB DELETES CONTENT AT 1100px AND BELOW \u2014 read before you ship a center slot. * At compact desktop/tablet widths the docked sidebar leaves too little inline room for three * intrinsically-sized clusters, so the package hides the optional center slot before it can * cover the breadcrumb/title or end utilities (gh#244). The default is `none`, which means a * global search trigger placed in `center` is INVISIBLE from 1100px down \u2014 including on every * phone \u2014 unless the consumer opts back in. That default arrived in 18.6.0 and removed the slot * for consumers who never changed a line of their own code (gh#12); it stays because the * overlap it prevents is a real defect and flipping a shipped default twice is worse than * documenting it once, but it is a DECISION, not an accident: * * :root { --topbar-center-compact-display: flex; } \u2190 restore the slot at every width * * Opt back in only once the center content has a compact presentation of its own (an icon-only * search trigger, a collapsing field). A page-local media query is the anti-pattern this knob * replaces."},{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-device-otp-slot-inline-size",value:"1.71875rem",description:'CODE FIELD measure \u2014 the preset owns it (gh#12). A device grant is the one canonical flow whose * PRIMARY control is the code field, so leaving it on the generic square --otp-slot-size made the * preset own the page but not its own subject: two 4-slot `appearance="grouped"` boxes rendered * 146x38 (4 x the canonical 36px control tier + the 1px group border) against a 112x54 artboard. * These are the per-slot boxes that ADD UP to that artboard group: * inline 27.5px x 4 + 2 x 1px group border = 112px * block 52px + 2 x 1px group border = 54px * Literal artboard lengths, like every other preset measure here \u2014 they must not drift with * --scaling. A service that groups its code differently overrides --otp-slot-inline-size / * --otp-slot-block-size on its own field; the generic square knob is untouched everywhere else.'},{name:"--auth-shell-device-otp-slot-block-size",value:"3.25rem",description:'CODE FIELD measure \u2014 the preset owns it (gh#12). A device grant is the one canonical flow whose * PRIMARY control is the code field, so leaving it on the generic square --otp-slot-size made the * preset own the page but not its own subject: two 4-slot `appearance="grouped"` boxes rendered * 146x38 (4 x the canonical 36px control tier + the 1px group border) against a 112x54 artboard. * These are the per-slot boxes that ADD UP to that artboard group: * inline 27.5px x 4 + 2 x 1px group border = 112px * block 52px + 2 x 1px group border = 54px * Literal artboard lengths, like every other preset measure here \u2014 they must not drift with * --scaling. A service that groups its code differently overrides --otp-slot-inline-size / * --otp-slot-block-size on its own field; the generic square knob is untouched everywhere else.'},{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:65,untested:2128,notApplicable:1699,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:["tones"],untested:["accessibleName","async","contentStress","keyboard","reducedMotion","responsive","rtl"],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","states"],notApplicable:["density","ownership","shapes","sizes","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
|
|
1934
1934
|
// 0) \u2605 MOST COMMON: <Card> body has NO padding (content is flush against the edges)
|
|
1935
1935
|
// Cause: the bare <Card> has ZERO inner padding \u2014 it MUST contain <CardContent>.
|
|
1936
1936
|
// Don't hand-roll padding with className="p-4" on the Card either.
|
|
@@ -3172,7 +3172,7 @@ const mark = emailBrandMarkSvg({ label: "" });
|
|
|
3172
3172
|
|
|
3173
3173
|
// 3) THE CTA \u2014 line-height EQUALS height, so the label centres with no flexbox.
|
|
3174
3174
|
const ctaCell = emailInlineStyle({
|
|
3175
|
-
height: EMAIL_CTA.height, //
|
|
3175
|
+
height: EMAIL_CTA.height, // 44px \u2014 the SC 2.5.5 / HIG 44pt touch target
|
|
3176
3176
|
borderRadius: EMAIL_CTA.radius,
|
|
3177
3177
|
backgroundColor: c.primary,
|
|
3178
3178
|
});
|
|
@@ -3866,7 +3866,7 @@ arrives.`,fix:`Use Skeleton placeholders matching the eventual content shape.
|
|
|
3866
3866
|
The framework's \`<Form loading={{ kind: "skeleton" }}>\` cascades
|
|
3867
3867
|
to every field; \`<Skeleton className="h-9 w-full rounded-md" />\`
|
|
3868
3868
|
for individual blocks. Layout stays stable, perceived speed
|
|
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})
|
|
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.8.0",godxUiCompatibility:"18.8.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})
|
|
3870
3870
|
|
|
3871
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}]\`
|
|
3872
3872
|
`,t+=`**When to use:** ${a.whenToUse}
|