@unpunnyfuns/swatchbook-blocks 0.65.0 → 0.66.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["snapshot","listeners","subscribed","ensureSubscribed","subscribe","getSnapshot","getServerSnapshot","sampleStyle","formatDimension","formatDimension","CopyButton","CopyButton","styles","formatFontFamily","formatPrimitive","formatDimension","StrokeStylePreview","CopyButton","CopyButton","CopyButton"],"sources":["../src/internal/styles.tsx","../src/internal/channel-globals.ts","../src/contexts.ts","../src/internal/channel-tokens.ts","../src/internal/use-project.ts","../src/border-preview/BorderSample.tsx","../src/internal/composite-sample-format.ts","../src/internal/data-attr.ts","../src/internal/sort-tokens.ts","../src/BorderPreview.tsx","../src/ColorPalette.tsx","../src/internal/CopyButton.tsx","../src/internal/persistent-state.ts","../src/ColorTable.tsx","../src/Diagnostics.tsx","../src/dimension-scale/dimension-px.ts","../src/dimension-scale/DimensionBar.tsx","../src/internal/format-token-value.ts","../src/DimensionScale.tsx","../src/FontFamilyPreview.tsx","../src/internal/css-var-style.ts","../src/FontWeightScale.tsx","../src/GradientPalette.tsx","../src/internal/prefers-reduced-motion.ts","../src/motion-preview/MotionSample.tsx","../src/MotionPreview.tsx","../src/OpacityScale.tsx","../src/provider.tsx","../src/shadow-preview/ShadowSample.tsx","../src/ShadowPreview.tsx","../src/StrokeStylePreview.tsx","../src/token-detail/internal.ts","../src/token-detail/AliasChain.tsx","../src/token-detail/AliasedBy.tsx","../src/token-detail/AxisVariance.tsx","../src/token-detail/CompositeBreakdown.tsx","../src/token-detail/transition-duration.ts","../src/token-detail/CompositePreview.tsx","../src/token-detail/ConsumerOutput.tsx","../src/token-detail/TokenHeader.tsx","../src/token-detail/TokenUsageSnippet.tsx","../src/TokenDetail.tsx","../src/internal/DetailOverlay.tsx","../src/token-navigator/navigate.ts","../src/indicators/resolve.ts","../src/indicators/RowIndicators.tsx","../src/TokenNavigator.tsx","../src/TokenTable.tsx","../src/TypographyScale.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from 'react';\n\n/**\n * Chrome-style primitives shared across every block. Kept as JS exports\n * for the inline-style sites that still compose them into per-block style\n * objects (e.g. TokenNavigator's `typePill` that builds on the shared\n * pill base). The pure direct-reference chrome — surface wrapper, caption,\n * empty-state — lives in `styles.css` and is applied via class names.\n */\n\nexport const TEXT_MUTED = 'var(--swatchbook-text-muted, CanvasText)';\n\nexport const SURFACE_RAISED = 'var(--swatchbook-surface-raised, Canvas)';\nexport const SURFACE_MUTED = 'var(--swatchbook-surface-muted, rgba(128,128,128,0.15))';\n\nexport const BORDER_FAINT = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.15))`;\nexport const BORDER_STRONG = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.3))`;\n\n/**\n * Inner content for a block's \"nothing to render\" state. Call sites wrap\n * it in their own block wrapper (which already carries `blockWrapperAttrs`), so\n * the message itself just needs the muted type.\n */\nexport function EmptyState({ children }: { children: ReactNode }): ReactElement {\n return <div className=\"sb-block__empty\">{children}</div>;\n}\n","import { useSyncExternalStore } from 'react';\nimport { addons } from 'storybook/preview-api';\nimport { COLOR_FORMATS } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Shared subscription to Storybook's globals channel, lifted out of React\n * component state so the values survive docs-mode remounts.\n *\n * On MDX docs pages, Storybook force-rerenders the docs container on every\n * `updateGlobals` (see `preview/runtime.js` → `onUpdateGlobals`), which\n * unmounts and remounts any embedded blocks. A `useState(null)` initializer\n * inside the block would reset to null on each remount — the symptom is a\n * one-frame flicker to the correct value, then revert to the defaults.\n * Module-level state persists; React reads it through `useSyncExternalStore`\n * and stays concurrent-safe.\n */\n\nexport interface ChannelGlobals {\n axes: Record<string, string> | null;\n format: ColorFormat | null;\n}\n\nconst AXES_GLOBAL_KEY = 'swatchbookAxes';\nconst COLOR_FORMAT_GLOBAL_KEY = 'swatchbookColorFormat';\n\nlet snapshot: ChannelGlobals = { axes: null, format: null };\nconst listeners = new Set<() => void>();\nlet subscribed = false;\n\nfunction isColorFormat(value: unknown): value is ColorFormat {\n return typeof value === 'string' && (COLOR_FORMATS as readonly string[]).includes(value);\n}\n\ninterface SwatchbookGlobalsPayload {\n swatchbookAxes?: Record<string, string>;\n swatchbookColorFormat?: ColorFormat;\n [key: string]: unknown;\n}\n\nfunction ensureSubscribed(): void {\n if (subscribed || typeof window === 'undefined') return;\n subscribed = true;\n const channel = addons.getChannel();\n // Storybook fires `globalsUpdated`, `setGlobals`, and `updateGlobals`\n // for the same logical change (preview init + every toolbar tick).\n // Subscribing to all three is intentional — `setGlobals` carries the\n // initial URL-persisted globals; `updateGlobals` is the toolbar\n // signal; `globalsUpdated` is the cross-frame echo. The handler runs\n // for each but content-deduplicates: we only update the shared\n // snapshot when axes or format actually shifted, so the three events\n // per tick don't each trigger a re-render.\n let lastFingerprint = '';\n const onGlobals = (payload: { globals?: SwatchbookGlobalsPayload }): void => {\n const globals = payload.globals;\n if (!globals) return;\n const incomingAxes = globals[AXES_GLOBAL_KEY];\n const incomingFormat = globals[COLOR_FORMAT_GLOBAL_KEY];\n const nextAxes =\n incomingAxes && typeof incomingAxes === 'object' ? incomingAxes : snapshot.axes;\n const nextFormat = isColorFormat(incomingFormat) ? incomingFormat : snapshot.format;\n const fingerprint = `${nextFormat ?? ''}|${nextAxes ? JSON.stringify(nextAxes) : ''}`;\n if (fingerprint === lastFingerprint) return;\n lastFingerprint = fingerprint;\n snapshot = { axes: nextAxes, format: nextFormat };\n for (const cb of listeners) cb();\n };\n channel.on('globalsUpdated', onGlobals);\n channel.on('updateGlobals', onGlobals);\n channel.on('setGlobals', onGlobals);\n}\n\n// Subscribe at module load so the `SET_GLOBALS` emission from preview init\n// lands in our snapshot before any block renders. Running `useSyncExternalStore`'s\n// `subscribe` lazily on first hook call would miss the event in most cases.\nensureSubscribed();\n\nfunction subscribe(cb: () => void): () => void {\n ensureSubscribed();\n listeners.add(cb);\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): ChannelGlobals {\n return snapshot;\n}\n\nfunction getServerSnapshot(): ChannelGlobals {\n return snapshot;\n}\n\nexport function useChannelGlobals(): ChannelGlobals {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import type { Axis, Diagnostic, Preset } from '@unpunnyfuns/swatchbook-core';\nimport type { TokenGraph } from '@unpunnyfuns/swatchbook-core/graph';\nimport type { SlimListedToken } from '@unpunnyfuns/swatchbook-core/snapshot-for-wire';\nimport { createContext, useContext } from 'react';\nimport { useChannelGlobals } from '#/internal/channel-globals.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Typed shape of the addon's `virtual:swatchbook/tokens` module.\n *\n * The axis / permutation / diagnostic / preset entries are deliberate\n * type-aliases of core's authoritative shapes — the virtual module\n * publishes those shapes verbatim, so single-sourcing the types prevents\n * silent drift the moment core grows a field the plugin doesn't\n * serialise.\n *\n * Token / listing shapes stay as narrowed interfaces because blocks\n * only read a subset of Terrazzo's full token / listing structure; the\n * narrower shape documents what's actually relied on.\n *\n * The ambient `declare module 'virtual:swatchbook/tokens'` declarations\n * in `packages/addon/src/virtual.d.ts` describe the same payload.\n */\nexport type VirtualAxisShape = Axis;\n\nexport type VirtualDiagnosticShape = Diagnostic;\n\nexport interface VirtualTokenShape {\n $type?: string | undefined;\n $value?: unknown;\n $description?: string | undefined;\n /**\n * DTCG `$deprecated` — `true` or a message string. Mirrors core's\n * `SwatchbookToken.$deprecated`; reaches blocks via the resolved token\n * map reconstructed from the wire `tokenGraph`.\n */\n $deprecated?: string | boolean | undefined;\n aliasOf?: string | undefined;\n aliasChain?: readonly string[] | undefined;\n aliasedBy?: readonly string[] | undefined;\n /**\n * Per-sub-field alias map for composite tokens whose value blends\n * primitives with aliased fragments — Terrazzo populates this when\n * one or more component fields of a composite ($type: 'border',\n * 'shadow', 'typography', 'gradient', 'transition') resolve through\n * an alias. The `CompositeBreakdown` block reads it to render the\n * source path beside each component value. Typed as `unknown` because\n * the shape varies per composite type (color carries a\n * `{components: (string | undefined)[]}` sub-shape; typography/border\n * carry a flat `Record<string, string | undefined>`); the block\n * narrows it at the consumer.\n */\n partialAliasOf?: unknown;\n}\n\n/**\n * Subset of `@terrazzo/plugin-token-listing`'s `ListedToken` that the\n * snapshot carries. Blocks read `names.css` for the authoritative CSS\n * variable name and `previewValue` for the display-ready CSS string.\n * `source.loc` enables \"jump to authoring source\" affordances.\n *\n * Aliases `SlimListedToken` from core's `/snapshot-for-wire` subpath —\n * the single canonical wire shape; both the addon's plugin (server-side\n * emit) and blocks (consumer-side read) reference the same definition.\n */\nexport type VirtualTokenListingShape = SlimListedToken;\n\nexport type VirtualPresetShape = Preset;\n\n/**\n * Wire shape of the token graph — aliased from core's authoritative\n * `TokenGraph` so both the virtual module declaration and the React\n * context stay aligned with the same definition.\n */\nexport type VirtualTokenGraph = TokenGraph;\n\n/**\n * Full project data read by blocks. Populated by the addon's preview\n * decorator (from the virtual module) or constructed by hand in\n * non-Storybook consumers.\n */\nexport interface ProjectSnapshot {\n axes: readonly VirtualAxisShape[];\n activeTheme: string;\n activeAxes: Readonly<Record<string, string>>;\n cssVarPrefix: string;\n diagnostics: readonly VirtualDiagnosticShape[];\n css: string;\n /**\n * Path-indexed Token Listing data produced by\n * `@terrazzo/plugin-token-listing`. Blocks prefer reading authoritative\n * CSS var names and preview values from here; empty for non-resolver\n * projects. Treat as enrichment — fall back gracefully when a path is\n * absent.\n */\n listing?: Readonly<Record<string, VirtualTokenListingShape>>;\n /**\n * Pre-built token graph for the project. JSON-serializable; nodes\n * carry per-axis writes plus alias edges. The blocks hook backs\n * `resolveAt` and variance from this graph.\n */\n tokenGraph?: VirtualTokenGraph;\n /** The default tuple — `{ axis: axis.default }` for every axis. */\n defaultTuple: Record<string, string>;\n /**\n * Pre-built `resolveAt(tuple)` accessor. The addon's preview decorator\n * instantiates this once per iframe lifetime. When present, use-project\n * prefers it over building its own from `tokenGraph`, so it MUST preserve\n * alias provenance — back it with `resolveAllWithProvenanceAt`, not the raw\n * leaf `resolveAllAt`, or axis-varying aliases silently lose their chain /\n * reverse refs / description at non-default tuples. Hand-built snapshots\n * (tests, MDX) can omit this; blocks then fall back to a provenance-aware\n * graph-backed resolver built from `tokenGraph`.\n */\n resolveAt?: (tuple: Record<string, string>) => Record<string, VirtualTokenShape>;\n}\n\n/**\n * Context carrying the full {@link ProjectSnapshot}. `null` sentinel lets\n * `useSwatchbookData()` tell \"provider present\" from \"fall back to the\n * virtual module\".\n */\nexport const SwatchbookContext = createContext<ProjectSnapshot | null>(null);\n\nexport function useOptionalSwatchbookData(): ProjectSnapshot | null {\n return useContext(SwatchbookContext);\n}\n\n/**\n * Active swatchbook theme for the current story/docs render. Populated by\n * the addon's preview decorator and consumed by `useToken` + any future\n * consumer hooks.\n *\n * This runs through plain React context rather than Storybook's\n * `useGlobals` so the same hook works in autodocs / MDX renders where the\n * preview-hooks context isn't available.\n */\nexport const ThemeContext = createContext<string>('');\n\nexport function useActiveTheme(): string {\n return useContext(ThemeContext);\n}\n\n/**\n * Active axis tuple for the current story/docs render — `Record<axisName,\n * contextName>`. Derived from the same input as {@link ThemeContext}; split\n * out so consumers needing per-axis info (toolbar, panel, tuple-aware\n * blocks) don't have to reparse the composed theme name.\n */\nexport const AxesContext = createContext<Readonly<Record<string, string>>>({});\n\nexport function useActiveAxes(): Readonly<Record<string, string>> {\n return useContext(AxesContext);\n}\n\n/**\n * Active color-display format for the current story/docs render. Populated\n * by the addon's preview decorator from the `swatchbookColorFormat` global\n * (per-story `globals` or toolbar dropdown) and consumed by blocks that\n * render color-token values. Emitted CSS is unaffected.\n *\n * Runs through plain React context rather than Storybook's `useGlobals` so\n * per-story seeded globals flow through on first render and the same hook\n * is safe to call from MDX doc blocks (where the preview-hooks context\n * isn't available).\n */\nexport const ColorFormatContext = createContext<ColorFormat | null>(null);\n\nexport function useColorFormat(): ColorFormat {\n const contextValue = useContext(ColorFormatContext);\n const channelGlobals = useChannelGlobals();\n return contextValue ?? channelGlobals.format ?? 'hex';\n}\n","import { useSyncExternalStore } from 'react';\nimport { addons } from 'storybook/preview-api';\nimport type { VirtualTokenGraph, VirtualTokenListingShape } from '#/contexts.ts';\nimport type { VirtualAxis, VirtualDiagnostic } from '#/types.ts';\n\n/**\n * Live token snapshot backed by the addon's preview dev-time HMR event.\n *\n * The initial snapshot is *injected* by the addon preview via\n * {@link registerTokenSource} rather than imported from the addon's\n * `virtual:swatchbook/tokens` build artifact — so blocks carries no\n * dependency on that module and imports cleanly standalone (outside\n * Storybook, in unit tests, in the docs site). Until something registers\n * a source, blocks render from empty defaults.\n *\n * For dev-time updates this module subscribes to `TOKENS_UPDATED_EVENT`\n * on Storybook's channel (which the addon preview re-broadcasts from its\n * own HMR listener) and exposes the latest snapshot via\n * `useSyncExternalStore`, so hooks re-render in place on each token save.\n */\n\n// The dev-time HMR wire event. Single source of truth: the addon preview\n// emits it, this module listens — exported so the two can't drift.\nexport const TOKENS_UPDATED_EVENT = 'swatchbook/tokens-updated';\n\nexport interface TokenSnapshot {\n readonly axes: readonly VirtualAxis[];\n readonly presets: readonly {\n name: string;\n axes: Partial<Record<string, string>>;\n description?: string;\n }[];\n readonly diagnostics: readonly VirtualDiagnostic[];\n readonly css: string;\n readonly cssVarPrefix: string;\n readonly listing: Readonly<Record<string, VirtualTokenListingShape>>;\n readonly tokenGraph: VirtualTokenGraph;\n readonly defaultTuple: Record<string, string>;\n /** Monotonic counter, bumped on each update. Useful as a React key. */\n readonly version: number;\n}\n\nconst EMPTY_TOKEN_GRAPH: VirtualTokenGraph = {\n nodes: {},\n axes: [],\n axisDefaults: {},\n axisContexts: {},\n};\n\nconst EMPTY_SNAPSHOT: TokenSnapshot = {\n axes: [],\n presets: [],\n diagnostics: [],\n css: '',\n cssVarPrefix: '',\n listing: {},\n tokenGraph: EMPTY_TOKEN_GRAPH,\n defaultTuple: {},\n version: 0,\n};\n\nlet snapshot: TokenSnapshot = EMPTY_SNAPSHOT;\n\nconst listeners = new Set<() => void>();\nlet subscribed = false;\n\n// Merge a partial payload over the current snapshot, keeping prior values\n// for omitted fields and bumping the version. Shared by the injected\n// initial source and the dev-time channel updates.\nfunction applyPatch(patch: Partial<TokenSnapshot>): void {\n snapshot = {\n axes: patch.axes ?? snapshot.axes,\n presets: patch.presets ?? snapshot.presets,\n diagnostics: patch.diagnostics ?? snapshot.diagnostics,\n css: patch.css ?? snapshot.css,\n cssVarPrefix: patch.cssVarPrefix ?? snapshot.cssVarPrefix,\n listing: patch.listing ?? snapshot.listing,\n tokenGraph: patch.tokenGraph ?? snapshot.tokenGraph,\n defaultTuple: patch.defaultTuple ?? snapshot.defaultTuple,\n version: snapshot.version + 1,\n };\n for (const cb of listeners) cb();\n}\n\n/**\n * Seed the initial token snapshot. The addon preview calls this once at\n * init with the build-time `virtual:swatchbook/tokens` data. Keeping the\n * virtual-module read on the addon side (the package that owns it) lets\n * blocks import cleanly without it. No-op fields fall back to the current\n * snapshot, so a partial source is safe.\n */\nexport function registerTokenSource(source: Partial<TokenSnapshot>): void {\n applyPatch(source);\n}\n\nfunction ensureSubscribed(): void {\n if (subscribed || typeof window === 'undefined') return;\n subscribed = true;\n const channel = addons.getChannel();\n channel.on(TOKENS_UPDATED_EVENT, (payload: Partial<TokenSnapshot>) => {\n applyPatch(payload);\n });\n}\n\nensureSubscribed();\n\nfunction subscribe(cb: () => void): () => void {\n ensureSubscribed();\n listeners.add(cb);\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): TokenSnapshot {\n return snapshot;\n}\n\nfunction getServerSnapshot(): TokenSnapshot {\n return snapshot;\n}\n\nexport function useTokenSnapshot(): TokenSnapshot {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import {\n resolveAllWithProvenanceAt,\n getVariance,\n listPaths,\n} from '@unpunnyfuns/swatchbook-core/graph';\nimport { makeCssVar } from '@unpunnyfuns/swatchbook-core/css-var';\nimport {\n ensureStyleElement,\n SWATCHBOOK_STYLE_ELEMENT_ID,\n} from '@unpunnyfuns/swatchbook-core/style-element';\nimport { tupleToName } from '@unpunnyfuns/swatchbook-core/themes';\nimport type { AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { useEffect, useMemo } from 'react';\nimport type { VirtualTokenGraph, VirtualTokenListingShape } from '#/contexts.ts';\n\ntype VirtualVarianceByPathShape = Record<string, AxisVarianceResult>;\n\n// Pre-compute variance for every path in the graph. `getVariance` is cheap\n// (O(paths × axes)); callers wrap this in `useMemo` keyed on the graph so it\n// recomputes only on an HMR refresh. Shared by the provider and fallback paths.\nfunction computeVarianceByPath(graph: VirtualTokenGraph | undefined): VirtualVarianceByPathShape {\n if (!graph) return {};\n const out: VirtualVarianceByPathShape = {};\n for (const path of listPaths(graph)) {\n out[path] = getVariance(graph, path);\n }\n return out;\n}\nimport { useActiveAxes, useActiveTheme, useOptionalSwatchbookData } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat, FormatColorResult } from '#/format-color.ts';\nimport { useChannelGlobals } from '#/internal/channel-globals.ts';\nimport { useTokenSnapshot } from '#/internal/channel-tokens.ts';\nimport type { ProjectSnapshot, VirtualAxis, VirtualDiagnostic, VirtualToken } from '#/types.ts';\n\ntype ResolvedTokens = Record<string, VirtualToken>;\n\nexport interface ProjectData {\n activeTheme: string;\n activeAxes: Record<string, string>;\n axes: readonly VirtualAxis[];\n resolved: ResolvedTokens;\n diagnostics: readonly VirtualDiagnostic[];\n cssVarPrefix: string;\n /**\n * Path-indexed Token Listing data. Empty when absent (non-resolver\n * projects, hand-built snapshots that don't populate it). Blocks read\n * authoritative CSS var names from `listing[path].names.css` and\n * preview strings from `listing[path].previewValue`.\n */\n listing: Readonly<Record<string, VirtualTokenListingShape>>;\n /**\n * Cached per-path `AxisVarianceResult` — blocks use this for O(1)\n * variance lookup instead of re-running the analysis on every\n * render.\n */\n varianceByPath: VirtualVarianceByPathShape;\n /**\n * Compose the resolved `TokenMap` for any tuple of axis selections.\n * Backed browser-side by `resolveAllWithProvenanceAt` over the `tokenGraph`.\n */\n resolveAt: (tuple: Record<string, string>) => ResolvedTokens;\n}\n\nfunction ensureStylesheet(css: string): void {\n ensureStyleElement(SWATCHBOOK_STYLE_ELEMENT_ID, css);\n}\n\nfunction defaultTuple(axes: readonly VirtualAxis[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n return out;\n}\n\n// Build a `resolveAt` accessor backed by the token graph. Returns an\n// empty resolver when no graph is present (test stubs, partial\n// snapshots). Stable identity when memoized on `tokenGraph` — the\n// graph is a module-level virtual-module export so its reference stays\n// constant for the lifetime of the iframe.\nfunction makeResolveAt(\n graph: VirtualTokenGraph | undefined,\n): (tuple: Record<string, string>) => ResolvedTokens {\n if (!graph) return () => ({});\n return (tuple) => resolveAllWithProvenanceAt(graph, tuple) as unknown as ResolvedTokens;\n}\n\n// Build the `resolveAt` accessor for a snapshot. Prefers the\n// snapshot's own `resolveAt` (the addon's preview decorator\n// pre-builds one at module load — see `previewResolveAt` in\n// `packages/addon/src/preview.tsx`), otherwise builds one from\n// `tokenGraph`. Hand-built snapshots can omit `resolveAt`;\n// the graph-backed fallback covers them.\nfunction snapshotResolveAt(\n snapshot: ProjectSnapshot,\n): (tuple: Record<string, string>) => ResolvedTokens {\n if (snapshot.resolveAt)\n return snapshot.resolveAt as (tuple: Record<string, string>) => ResolvedTokens;\n return makeResolveAt(snapshot.tokenGraph);\n}\n\n/**\n * Reads project data either from a mounted {@link SwatchbookProvider}\n * (preferred — the addon's preview decorator installs one around every\n * story) or, when no provider is present, from the virtual module plus\n * Storybook globals directly.\n *\n * The provider-less path is what makes the hook safe to call from MDX\n * doc blocks and autodocs renders where no story is active. It\n * self-mounts the virtual module's per-theme CSS and tracks the active\n * tuple via the `globalsUpdated` channel event; {@link useGlobals} from\n * `storybook/preview-api` would throw outside a story render.\n */\nexport function useProject(): ProjectData {\n const snapshot = useOptionalSwatchbookData();\n // Memoize against the stable underlying fields, NOT the snapshot\n // wrapper. Storybook rebuilds `context.globals` identity on every\n // render → the preview's `tuple` useMemo invalidates → the\n // provider's snapshot useMemo rebuilds. Keying off `snapshot`\n // would mean `makeResolveAt` runs on every render, producing a\n // fresh closure with a fresh internal memo, so `resolved` would\n // have a new identity each render. Downstream block\n // `useMemo([resolved, …])` calls would recompute forever; the\n // `TokenNavigator`'s focus-repair `useEffect` (deps include the\n // recomputed `flatVisible`) would `setState` in an infinite loop.\n // The underlying `tokenGraph` reference is a stable module-level\n // virtual-module export, so depending on it directly keeps `resolveAt`\n // (and the resolved map it returns) referentially stable across renders.\n const axes = snapshot?.axes;\n const activeAxes = snapshot?.activeAxes;\n const activeTheme = snapshot?.activeTheme;\n const diagnostics = snapshot?.diagnostics;\n const cssVarPrefix = snapshot?.cssVarPrefix;\n const listing = snapshot?.listing;\n const tokenGraph = snapshot?.tokenGraph;\n const resolveAt = useMemo(() => {\n if (!snapshot) return null;\n return snapshotResolveAt(snapshot);\n // The deps below are deliberately the stable inner fields rather\n // than `snapshot` itself; see the long block comment above.\n // `tokenGraph` is a stable module-level virtual-module export, so\n // depending on it directly keeps `resolveAt` (and the resolved map\n // it returns) referentially stable across renders.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tokenGraph, activeTheme]);\n const derivedVarianceByPath = useMemo(() => computeVarianceByPath(tokenGraph), [tokenGraph]);\n // Memoize the returned ProjectData against the same stable inner\n // fields — without this, blocks `useMemo([project, …])` calls\n // invalidate every render (the function returns a fresh object\n // identity), defeating the per-block memoization that\n // `TokenNavigator` / `TokenTable` / `ColorPalette` rely on.\n const providerData = useMemo<ProjectData | null>(() => {\n if (!snapshot || !resolveAt || !axes || !activeAxes) return null;\n return {\n activeTheme: activeTheme ?? '',\n activeAxes: activeAxes as Record<string, string>,\n axes,\n resolved: resolveAt(activeAxes as Record<string, string>),\n diagnostics: diagnostics ?? [],\n cssVarPrefix: cssVarPrefix ?? '',\n listing: listing ?? {},\n varianceByPath: derivedVarianceByPath,\n resolveAt,\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n snapshot,\n resolveAt,\n axes,\n activeTheme,\n activeAxes,\n diagnostics,\n cssVarPrefix,\n listing,\n derivedVarianceByPath,\n tokenGraph,\n ]);\n const fallback = useVirtualModuleFallback(snapshot === null);\n return providerData ?? fallback;\n}\n\nfunction useVirtualModuleFallback(enabled: boolean): ProjectData {\n const contextThemeName = useActiveTheme();\n const contextAxes = useActiveAxes();\n const channelGlobals = useChannelGlobals();\n // Subscribe to the live token snapshot rather than reading the virtual\n // module's module-level exports directly. Initial values come from\n // `virtual:swatchbook/tokens` at load time; subsequent dev-time edits\n // flow through the addon's HMR channel and update this snapshot in\n // place so blocks re-render without a full preview reload.\n const tokens = useTokenSnapshot();\n\n useEffect(() => {\n if (!enabled) return;\n ensureStylesheet(tokens.css);\n }, [enabled, tokens.css]);\n\n // Memoize against the stable identities — `contextAxes` is a\n // useContext value that's stable across renders unless the\n // provider mutates; `channelGlobals.axes` updates on channel\n // events; `tokens.axes` is a stable virtual-module export.\n // Without this memo `activeAxes` would have fresh identity per\n // render and defeat downstream `useMemo([project, …])` calls.\n const activeAxes = useMemo<Record<string, string>>(() => {\n const hasContextAxes = Object.keys(contextAxes).length > 0;\n return hasContextAxes ? { ...contextAxes } : (channelGlobals.axes ?? defaultTuple(tokens.axes));\n }, [contextAxes, channelGlobals.axes, tokens.axes]);\n\n const activeTheme = contextThemeName || tupleToName(tokens.axes, activeAxes);\n\n // `resolveAllWithProvenanceAt` is a pure function over the graph; the only memo\n // we need is for the outer closure so React's reference equality\n // stays stable between renders. `tokens.tokenGraph` is the stable\n // module-level virtual-module export — changes only on HMR refresh.\n const resolveAt = useMemo(() => makeResolveAt(tokens.tokenGraph), [tokens.tokenGraph]);\n\n const fallbackVarianceByPath = useMemo(\n () => computeVarianceByPath(tokens.tokenGraph),\n [tokens.tokenGraph],\n );\n\n // Memoize the returned ProjectData against the stable inner fields\n // for the same reason the provider path does — fresh object identity\n // per render would defeat `useMemo([project, …])` in every block.\n return useMemo<ProjectData>(\n () => ({\n activeTheme,\n activeAxes,\n axes: tokens.axes,\n resolved: resolveAt(activeAxes),\n diagnostics: tokens.diagnostics,\n cssVarPrefix: tokens.cssVarPrefix,\n listing: tokens.listing,\n varianceByPath: fallbackVarianceByPath,\n resolveAt,\n }),\n [\n activeTheme,\n activeAxes,\n tokens.axes,\n tokens.diagnostics,\n tokens.cssVarPrefix,\n tokens.listing,\n fallbackVarianceByPath,\n resolveAt,\n ],\n );\n}\n\n/**\n * Resolve a token's CSS var reference, preferring the authoritative name\n * emitted by `@terrazzo/plugin-css` (as recorded by\n * `@terrazzo/plugin-token-listing` in the snapshot's `listing` field).\n * Falls back to `makeCssVar` when the listing lacks an entry for this\n * path — covers non-resolver projects, hand-built snapshots, and any\n * listing-plugin miss.\n */\nexport function resolveCssVar(\n path: string,\n project: Pick<ProjectData, 'listing' | 'cssVarPrefix'>,\n): string {\n const listed = project.listing[path]?.names?.['css'];\n if (listed) return `var(${listed})`;\n return makeCssVar(path, project.cssVarPrefix);\n}\n\n/**\n * Resolve a color value's display string + gamut flag, preferring the\n * listing's `previewValue` when the user's active color-format matches\n * plugin-css's output (hex). For any other format we fall back to\n * `formatColor` so the toolbar's inspection modes (rgb / hsl / oklch /\n * raw) keep working — the listing has only one canonical format.\n *\n * Pass `path === undefined` when resolving a sub-color inside a composite\n * (shadow / border / gradient stop): composites' `previewValue` covers\n * the whole token's rendering, not the individual channel, so there's no\n * listing entry to key against.\n */\nexport function resolveColorValue(\n path: string | undefined,\n raw: unknown,\n colorFormat: ColorFormat,\n project: Pick<ProjectData, 'listing'>,\n): FormatColorResult {\n if (path !== undefined && colorFormat === 'hex') {\n const listed = project.listing[path]?.previewValue;\n if (typeof listed === 'string') {\n return { value: listed, outOfGamut: false };\n }\n }\n return formatColor(raw, colorFormat);\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { SURFACE_RAISED } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport interface BorderSampleProps {\n /** Full dot-path of the border token to preview. */\n path: string;\n}\n\nconst sampleStyle: CSSProperties = {\n width: 120,\n height: 56,\n background: SURFACE_RAISED,\n borderRadius: 6,\n};\n\nexport function BorderSample({ path }: BorderSampleProps): ReactElement {\n const project = useProject();\n const cssVar = resolveCssVar(path, project);\n return <div style={{ ...sampleStyle, border: cssVar }} aria-hidden />;\n}\n","import { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Display a composite sub-field dimension (shadow offset / blur / spread,\n * border width, …) in the preview tables. Renders `—` for a missing\n * sub-field and falls back to JSON for shapes it doesn't recognize.\n *\n * Distinct from `format-token-value`'s internal `formatDimension`, which\n * formats a token's top-level value and has no `—` placeholder — these are\n * the per-layer sample formatters shared by `ShadowPreview` + `BorderPreview`.\n */\nexport function formatDimension(raw: unknown): string {\n if (raw == null) return '—';\n if (typeof raw === 'number') return String(raw);\n if (typeof raw === 'string') return raw;\n if (typeof raw === 'object') {\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value === 'number' && typeof v.unit === 'string') {\n return `${v.value}${v.unit}`;\n }\n }\n return JSON.stringify(raw);\n}\n\n/** Display a composite sub-field color via the active format; `—` when absent. */\nexport function formatSubColor(raw: unknown, format: ColorFormat): string {\n if (raw == null) return '—';\n return formatColor(raw, format).value;\n}\n","import { dataAttr } from '@unpunnyfuns/swatchbook-core/data-attr';\n\n/**\n * Marker attribute set on every block wrapper. Retained as a stable hook\n * for consumer-side selectors (e.g. when a host app wants to target or\n * override block chrome without relying on hashed class names).\n */\nexport const BLOCK_ATTR = 'data-swatchbook-block';\n\n// Opt-out class that Storybook's `.sbdocs` stylesheet uses to self-exclude\n// on MDX docs pages — every `.sbdocs` house rule is wrapped in\n// `:not(.sb-unstyled, .sb-unstyled *)`, so any descendant of a `.sb-unstyled`\n// container is left alone. Stamped onto every block wrapper so blocks\n// render identically in MDX docs and regular stories without fighting\n// cascade specificity.\nconst WRAPPER_CLASSES = 'sb-unstyled sb-block';\n\n/**\n * Spread helper for the common block wrapper. Returns:\n * - One `data-<prefix>-<axisName>=\"<contextName>\"` per axis in the tuple.\n * These are what the smart CSS emitter actually targets — single-axis\n * cell selectors (`[data-<prefix>-mode=\"Dark\"]`) and joint compounds\n * (`[data-<prefix>-mode=\"Dark\"][data-<prefix>-brand=\"Brand A\"]`).\n * Wrapping a block subtree in these attrs lets the cascade resolve\n * per-tuple values inside the block independently of the document\n * root — `AxisVariance`'s grid uses this to render real per-cell\n * swatches.\n * - `data-swatchbook-block` — stable consumer hook for targeting block\n * chrome from outside.\n * - `className=\"sb-unstyled sb-block\"` — Storybook's opt-out class so\n * MDX docs house styles self-exclude the subtree, plus `sb-block`\n * which carries the shared chrome from `internal/styles.css`.\n */\nexport function blockWrapperAttrs(\n prefix: string,\n tuple: Readonly<Record<string, string>>,\n): Record<string, string> {\n return {\n ...perAxisAttrs(prefix, tuple),\n [BLOCK_ATTR]: '',\n className: WRAPPER_CLASSES,\n };\n}\n\n/**\n * Spread helper for any element that wants per-axis cell semantics\n * without the block-wrapper chrome — `AxisVariance`'s grid uses this\n * on each swatch so the swatch's CSS vars resolve at the cell's own\n * tuple, not the document root's active tuple.\n */\nexport function perAxisAttrs(\n prefix: string,\n tuple: Readonly<Record<string, string>>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [axisName, contextName] of Object.entries(tuple)) {\n out[dataAttr(prefix, axisName)] = contextName;\n }\n return out;\n}\n","import { parseColor } from '@unpunnyfuns/swatchbook-core/format-color';\nimport type { VirtualToken } from '#/types.ts';\n\nexport type SortBy = 'path' | 'value' | 'none';\nexport type SortDir = 'asc' | 'desc';\n\nexport interface SortOptions {\n by?: SortBy;\n dir?: SortDir;\n}\n\ntype Entry = readonly [string, VirtualToken];\n\n// Stable sort for a filtered `[path, token][]` list.\n//\n// `sortBy: 'path'` — lexicographic on the dot-path (locale-aware, numeric).\n// `sortBy: 'value'` — per-`$type` ordering:\n// - `dimension` / `duration` → numeric pixels / ms (via `toMagnitude`).\n// - `fontWeight` / `opacity` / `number` / `lineHeight` → numeric.\n// - `color` → perceptual by oklch L → C → H.\n// - `fontFamily` / `strokeStyle` (string form) → lexicographic.\n// - Composites (`typography`, `shadow`, `border`, `gradient`, `transition`) →\n// fall back to path-alpha. No useful single-axis order.\n// `sortBy: 'none'` — preserve input order (still respects `sortDir: 'desc'`\n// as a reverse).\n\n// Pre-computed per-token sort key — one of three shapes depending on\n// `$type`. The comparator looks the key up by token-reference once\n// per pair instead of recomputing on every comparison (Schwartzian\n// transform).\n//\n// For N tokens, sort does O(N log N) comparisons; per-call cost for\n// colors is an Oklch conversion (a `new Color()` + `to('oklch')`)\n// which dominates wall time on real fixtures. Pre-computing brings\n// that down to O(N) keys + O(N log N) cheap lookups.\ntype SortKey =\n | { kind: 'numeric'; value: number; valid: boolean }\n | { kind: 'color'; key: { l: number; c: number; h: number } | null }\n | { kind: 'string'; value: string }\n | { kind: 'none' };\n\nconst NUMERIC_TYPES = new Set([\n 'dimension',\n 'duration',\n 'fontWeight',\n 'opacity',\n 'number',\n 'lineHeight',\n]);\n\nconst STRING_TYPES = new Set(['fontFamily', 'strokeStyle']);\n\nfunction computeSortKey(token: VirtualToken): SortKey {\n const type = token.$type;\n if (!type) return { kind: 'none' };\n if (NUMERIC_TYPES.has(type)) {\n const value = toMagnitude(token.$value);\n return { kind: 'numeric', value, valid: Number.isFinite(value) };\n }\n if (type === 'color') {\n return { kind: 'color', key: colorKey(token.$value) };\n }\n if (STRING_TYPES.has(type)) {\n return { kind: 'string', value: toDisplayable(token.$value) };\n }\n // Composite types ($type: 'typography', 'shadow', 'border', …) have\n // no useful one-dimensional ordering — fall back to no-op.\n return { kind: 'none' };\n}\n\nexport function sortTokens(entries: readonly Entry[], options: SortOptions = {}): Entry[] {\n const by = options.by ?? 'path';\n const dir = options.dir ?? 'asc';\n const sign = dir === 'desc' ? -1 : 1;\n\n if (by === 'none') {\n return dir === 'desc' ? [...entries].toReversed() : [...entries];\n }\n\n if (by === 'path') {\n return [...entries].toSorted(\n ([a], [b]) => sign * a.localeCompare(b, undefined, { numeric: true }),\n );\n }\n\n // by === 'value' — pre-compute per-token sort keys once.\n const keys = new Map<VirtualToken, SortKey>();\n for (const [, token] of entries) {\n keys.set(token, computeSortKey(token));\n }\n\n return [...entries].toSorted(([aPath, aTok], [bPath, bTok]) => {\n const cmp = compareValue(aTok, bTok, keys);\n if (cmp !== 0) return sign * cmp;\n // Stable tiebreak on path so the order is deterministic when values equal.\n return sign * aPath.localeCompare(bPath, undefined, { numeric: true });\n });\n}\n\nfunction compareValue(\n a: VirtualToken,\n b: VirtualToken,\n keys: ReadonlyMap<VirtualToken, SortKey>,\n): number {\n // When the two tokens differ in $type, fall back to type-alpha so at\n // least the mixed list clusters by type.\n if (a.$type !== b.$type) return String(a.$type ?? '').localeCompare(String(b.$type ?? ''));\n\n const ak = keys.get(a);\n const bk = keys.get(b);\n if (!ak || !bk) return 0;\n // Matches the `a.$type === b.$type` check above.\n if (ak.kind !== bk.kind) return 0;\n\n if (ak.kind === 'numeric' && bk.kind === 'numeric') {\n if (ak.valid && bk.valid) return ak.value - bk.value;\n if (ak.valid) return -1;\n if (bk.valid) return 1;\n return 0;\n }\n\n if (ak.kind === 'color' && bk.kind === 'color') {\n const a3 = ak.key;\n const b3 = bk.key;\n if (!a3 && !b3) return 0;\n if (!a3) return 1;\n if (!b3) return -1;\n if (a3.l !== b3.l) return a3.l - b3.l;\n if (a3.c !== b3.c) return a3.c - b3.c;\n return a3.h - b3.h;\n }\n\n if (ak.kind === 'string' && bk.kind === 'string') {\n return ak.value.localeCompare(bk.value, undefined, { numeric: true });\n }\n\n return 0;\n}\n\nfunction toMagnitude(v: unknown): number {\n if (typeof v === 'number') return v;\n if (v && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value !== 'number') return Number.NaN;\n if (typeof d.unit !== 'string') return d.value;\n switch (d.unit) {\n case 'px':\n case 'ms':\n return d.value;\n case 's':\n return d.value * 1000;\n case 'rem':\n case 'em':\n return d.value * 16;\n default:\n return d.value;\n }\n }\n return Number.NaN;\n}\n\n// Coerce a possibly-null/undefined number to 0 — `coords` returns\n// `(number | null)[]` and `noUncheckedIndexedAccess` adds `undefined`\n// on top. `typeof` narrows the union for the comparator below.\nfunction safeNumber(v: number | null | undefined): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : 0;\n}\n\nfunction colorKey(v: unknown): { l: number; c: number; h: number } | null {\n // parseColor applies the colorjs space-alias map, so wide-gamut spaces\n // (display-p3, a98-rgb, prophoto-rgb) yield a perceptual key instead of\n // throwing and sinking the token to the end of a value sort.\n const color = parseColor(v);\n if (!color) return null;\n try {\n const [l, chroma, h] = color.to('oklch').coords;\n return { l: safeNumber(l), c: safeNumber(chroma), h: safeNumber(h) };\n } catch {\n return null;\n }\n}\n\nfunction toDisplayable(v: unknown): string {\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n if (v && typeof v === 'object') return JSON.stringify(v);\n return String(v ?? '');\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './BorderPreview.css';\nimport { BorderSample } from '#/border-preview/BorderSample.tsx';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatDimension, formatSubColor } from '#/internal/composite-sample-format.ts';\nimport type { BorderValue } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface BorderPreviewProps {\n /**\n * Token-path filter. Defaults to every `border` token. Use e.g.\n * `\"border.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (borders don't have a\n * single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n value: BorderValue;\n}\n\nexport function BorderPreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: BorderPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'border') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n value: (token.$value ?? {}) as BorderValue,\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} border${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No border tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-border-preview__row\">\n <div className=\"sb-border-preview__meta\">\n <span className=\"sb-border-preview__path\">{row.path}</span>\n <span className=\"sb-border-preview__css-var\">{row.cssVar}</span>\n </div>\n <div className=\"sb-border-preview__sample-cell\">\n <BorderSample path={row.path} />\n </div>\n <div className=\"sb-border-preview__breakdown\">\n <span className=\"sb-border-preview__breakdown-key\">width</span>\n <span>{formatDimension(row.value.width)}</span>\n <span className=\"sb-border-preview__breakdown-key\">style</span>\n <span>{row.value.style != null ? String(row.value.style) : '—'}</span>\n <span className=\"sb-border-preview__breakdown-key\">color</span>\n <span>{formatSubColor(row.value.color, colorFormat)}</span>\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './ColorPalette.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface ColorPaletteProps {\n /**\n * Token-path filter. Defaults to every `color` token. Use e.g.\n * `\"color.*\"` to scope to the semantic layer, or `\"color.palette.blue.*\"`\n * for a single ref ramp.\n */\n filter?: string;\n /**\n * Grouping depth. Tokens are grouped by the first `groupBy` dot-segments\n * of their path. `1` yields a single `color` group; `2` yields\n * `color.surface`, `color.text`, `color.blue`, etc.\n *\n * If omitted, groupBy is derived from the filter: one level below the\n * filter's fixed prefix (segments before the first `*`), clamped so each\n * swatch still carries a leaf label. `\"color.*\"` → groups at\n * `color.<family>`; `\"color.palette.blue.*\"` collapses all shades into\n * one `color.blue` group because the tokens have no deeper level.\n */\n groupBy?: number;\n /** Override the section caption. */\n caption?: string;\n /**\n * Sort order within each group.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — perceptual ordering: oklch L → C → H (ramps read\n * light→dark, then warm→cool within each lightness band).\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Swatch {\n path: string;\n leaf: string;\n cssVar: string;\n value: string;\n outOfGamut: boolean;\n}\n\n// Count segments in the filter before the first glob (`*` / `**`).\n// `color.*` → 2; `color.surface.*` → 3; `color` → 1; undefined → 0.\nfunction fixedPrefixLength(filter: string | undefined): number {\n if (!filter) return 0;\n const segments = filter.split('.');\n let fixed = 0;\n for (const seg of segments) {\n if (seg === '*' || seg === '**') break;\n fixed += 1;\n }\n return fixed;\n}\n\nexport function ColorPalette({\n filter,\n groupBy,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: ColorPaletteProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = project;\n const colorFormat = useColorFormat();\n\n const groups = useMemo(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'color') return false;\n return matchPath(path, filter);\n });\n const entries = sortTokens(filtered, { by: sortBy, dir: sortDir });\n\n const maxDepth = entries.reduce((m, [p]) => Math.max(m, p.split('.').length), 0);\n const effectiveGroupBy =\n groupBy ?? Math.min(fixedPrefixLength(filter) + 1, Math.max(maxDepth - 1, 1));\n\n const bucket = new Map<string, Swatch[]>();\n for (const [path, token] of entries) {\n const segments = path.split('.');\n const groupKey = segments.slice(0, effectiveGroupBy).join('.');\n const leaf = segments.slice(effectiveGroupBy).join('.') || segments.at(-1) || path;\n const list = bucket.get(groupKey) ?? [];\n const formatted = resolveColorValue(path, token.$value, colorFormat, projectFields);\n list.push({\n path,\n leaf,\n cssVar: resolveCssVar(path, projectFields),\n value: formatted.value,\n outOfGamut: formatted.outOfGamut,\n });\n bucket.set(groupKey, list);\n }\n\n return [...bucket.entries()].toSorted(([a], [b]) =>\n a.localeCompare(b, undefined, { numeric: true }),\n );\n }, [resolved, listing, cssVarPrefix, filter, groupBy, colorFormat, sortBy, sortDir]);\n\n const totalCount = groups.reduce((acc, [, swatches]) => acc + swatches.length, 0);\n const captionText =\n caption ??\n `${totalCount} color${totalCount === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (totalCount === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No color tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {groups.map(([group, swatches]) => (\n <section key={group} className=\"sb-color-palette__group\">\n <div className=\"sb-color-palette__group-header\">{group}</div>\n <div className=\"sb-color-palette__grid\">\n {swatches.map((swatch) => (\n <div key={swatch.path} className=\"sb-color-palette__card\">\n <div\n className=\"sb-color-palette__swatch\"\n style={{ background: swatch.cssVar }}\n aria-hidden\n />\n <div className=\"sb-color-palette__meta\">\n <span className=\"sb-color-palette__leaf\">{swatch.leaf}</span>\n <span className=\"sb-color-palette__value\">\n {swatch.value}\n {swatch.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-color-palette__gamut-warn\"\n >\n {' '}\n ⚠\n </span>\n )}\n </span>\n </div>\n </div>\n ))}\n </div>\n </section>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport './CopyButton.css';\n\nexport interface CopyButtonProps {\n /** Text written to the clipboard when clicked. */\n value: string;\n /**\n * Accessible label. Defaults to `Copy <value>`; override for long values\n * (hex + description + etc.) where the full label would be too chatty.\n */\n label?: string;\n /** `'icon'` (default) — 16 px glyph button; `'text'` — `Copy` pill. */\n variant?: 'icon' | 'text';\n /** Extra class to merge onto the button root. */\n className?: string;\n}\n\n/**\n * Copy the given string to the clipboard and briefly surface a \"Copied!\"\n * state. Falls back silently on unsupported clipboard APIs (older Safari,\n * insecure origins) — the click still happens, the user just won't see the\n * tick. No custom permission prompt: relies on the browser's native user-\n * activation gate.\n */\nexport function CopyButton({\n value,\n label,\n variant = 'icon',\n className,\n}: CopyButtonProps): ReactElement {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n };\n }, []);\n\n const handleClick = useCallback((): void => {\n // `writeText` is async and rejects on unfocused documents,\n // insecure origins, missing permissions, etc. Swallow the\n // rejection — the \"Copied!\" affordance is a nicety, not a\n // correctness requirement; an unhandled rejection in prod would\n // surface in DevTools and (under vitest browser-mode) fail the\n // suite from an unrelated test.\n navigator.clipboard?.writeText(value).catch(() => {});\n setCopied(true);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 1500);\n }, [value]);\n\n const ariaLabel = label ?? `Copy ${value}`;\n const classes = ['sb-copy-button', `sb-copy-button--${variant}`];\n if (copied) classes.push('sb-copy-button--copied');\n if (className) classes.push(className);\n\n return (\n <>\n <button\n type=\"button\"\n className={classes.join(' ')}\n onClick={handleClick}\n aria-label={ariaLabel}\n title={ariaLabel}\n data-copied={copied ? 'true' : undefined}\n >\n {variant === 'text' ? (\n <span className=\"sb-copy-button__text\">{copied ? 'Copied' : 'Copy'}</span>\n ) : (\n <span className=\"sb-copy-button__glyph\" aria-hidden>\n {copied ? '✓' : '⧉'}\n </span>\n )}\n </button>\n {/* Polite live region announces the transition to SR users — the\n icon variant's \"✓ Copied\" cue is otherwise visual-only. */}\n <span role=\"status\" aria-live=\"polite\" className=\"sb-copy-button__sr-status\">\n {copied ? 'Copied' : ''}\n </span>\n </>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\n/**\n * Block UI state that survives a docs-mode remount.\n *\n * In MDX docs mode Storybook re-renders the docs container on every\n * `updateGlobals` (axis flip), which unmounts and remounts the embedded\n * blocks — destroying any plain `useState` (expand/collapse, selection,\n * search). This is the same problem `channel-globals` solves for the\n * globals: lift the value out of React into module state so it persists\n * across the remount, and re-seed component state from it on mount.\n *\n * `usePersistedState` is a drop-in `useState` whose value is mirrored to a\n * module-level store under a caller-supplied key, and read back from it on\n * (re)mount. `useBlockKey` builds a stable key scoped to the current docs\n * page + block identity so two pages (or two distinct blocks) don't share\n * an entry.\n */\n\nconst store = new Map<string, unknown>();\n\n/**\n * Drop all persisted block state. The store is module-global and intentionally\n * outlives React's tree (that's the whole point), so tests must clear it\n * between cases to stay isolated — wired via the browser project's setupFiles.\n */\nexport function clearPersistedState(): void {\n store.clear();\n}\n\n// The current docs/story id, so persisted state is scoped per page. Docs\n// navigation is an SPA swap inside the preview iframe (no reload), so without\n// this scope a `<TokenNavigator root=\"color\">` on page A would inherit page\n// B's expand/selection state. Falls back to the pathname, then empty (SSR).\nfunction pageScope(): string {\n if (typeof window === 'undefined') return '';\n try {\n return new URLSearchParams(window.location.search).get('id') ?? window.location.pathname;\n } catch {\n return '';\n }\n}\n\nconst SEP = '\u0001';\n\n/**\n * Build a stable persistence key for a block's UI state: docs page + block\n * type + the props that distinguish one instance from another (and an\n * optional explicit `id` for identical-prop siblings on the same page).\n */\nexport function useBlockKey(\n blockType: string,\n parts: readonly (string | number | boolean | undefined)[],\n): string {\n const partsKey = parts.map((p) => (p === undefined ? '' : String(p))).join(SEP);\n // pageScope() is read once per (re)mount via the memo; a docs page swap\n // remounts the block, so the scope is current for the new page.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => `${pageScope()}${SEP}${blockType}${SEP}${partsKey}`, [blockType, partsKey]);\n}\n\n/**\n * `useState`, but the value persists across remounts under `key`. `initial`\n * may be a value or a lazy initializer (used only on the first mount when the\n * store has no entry yet — never an actual `T` that's a function here).\n */\nexport function usePersistedState<T>(\n key: string,\n initial: T | (() => T),\n): readonly [T, Dispatch<SetStateAction<T>>] {\n const [value, setValue] = useState<T>(() => {\n if (store.has(key)) return store.get(key) as T;\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n });\n useEffect(() => {\n store.set(key, value);\n }, [key, value]);\n return [value, setValue] as const;\n}\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { memo, useCallback, useDeferredValue, useMemo } from 'react';\nimport './ColorTable.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat, NormalizedColor } from '#/format-color.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nconst BASE_LABEL = 'base';\nconst COLUMN_COUNT = 6;\n\nexport interface ColorTableProps {\n /**\n * Token-path filter. Defaults to every `$type: color` token. `\"color.*\"`\n * scopes to the semantic layer; `\"color.palette.blue.*\"` to a single ramp.\n */\n filter?: string;\n /** Override the table caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — perceptual (oklch L → C → H). Ramps read light→dark, then\n * warm→cool within each lightness band.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n /**\n * Render a fuzzy-search input above the table. Defaults to `true`.\n */\n searchable?: boolean;\n /**\n * Called with the *currently-selected* variant's dot-path on row click.\n * When set, the built-in expand-in-place behavior is suppressed — the\n * consumer owns follow-up UI.\n */\n onSelect?(path: string): void;\n /**\n * Map from a display label to a suffix matched against each token's\n * trailing path segment. Tokens whose leaves match a suffix are grouped\n * under a shared \"base\" path (the path with the suffix stripped), and\n * the group renders as a single row with a pill selector — clicking a\n * pill swaps the displayed values to that variant. Sibling tokens\n * without a suffix that share the group's base path are labeled `base`.\n *\n * Matches both DTCG-idiomatic and Backmarket-style conventions:\n * - **Dot segment** (`color.bg.hi.disabled`): last dot-segment equals\n * the suffix (`disabled`). Base path = drop the last segment.\n * - **Hyphen tail** (`color.bg.hi-d`): last dot-segment ends in\n * `-<suffix>` (`d`). Base path = trim the `-<suffix>` from the leaf.\n *\n * Longest-suffix-wins. Hyphen-tail form requires an actual hyphen\n * boundary — suffix `0` does not match `neutral-900`.\n *\n * Single-member groups render as plain rows (no pill selector). Empty\n * map (default) disables grouping entirely; each token renders as its\n * own row.\n */\n variants?: Record<string, string>;\n /** Disambiguates persisted UI state for two identical-prop tables on a page. */\n id?: string;\n}\n\ninterface Variant {\n label: string;\n path: string;\n cssVar: string;\n // The display value in the currently-active color format.\n value: string;\n outOfGamut: boolean;\n // Hex / HSL / OKLCH breakdown — retained for the expanded sub-table.\n hex: string;\n hsl: string;\n oklch: string;\n description?: string;\n aliasOf?: string;\n aliasChain?: readonly string[];\n}\n\ninterface Group {\n base: string;\n variants: Variant[];\n searchText: string;\n}\n\nexport function ColorTable({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n searchable = true,\n onSelect,\n variants,\n id,\n}: ColorTableProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = project;\n const colorFormat = useColorFormat();\n // Persist search + variant selection + expansion across docs-mode remounts.\n const blockKey = useBlockKey('ColorTable', [filter, caption, id]);\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n const [selectedByBase, setSelectedByBase] = usePersistedState<Record<string, string>>(\n `${blockKey}::selected`,\n {},\n );\n const [expandedByBase, setExpandedByBase] = usePersistedState<ReadonlySet<string>>(\n `${blockKey}::expanded`,\n () => new Set(),\n );\n\n const defs = useMemo(() => buildVariantDefs(variants), [variants]);\n\n const groups = useMemo<Group[]>(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'color') return false;\n return matchPath(path, filter);\n });\n const sorted = sortTokens(filtered, { by: sortBy, dir: sortDir });\n\n const groupMap = new Map<string, { base: string; variants: Variant[] }>();\n for (const [path, token] of sorted) {\n const raw = token.$value as NormalizedColor;\n const hex = resolveColorValue(path, raw, 'hex', projectFields);\n const hsl = formatColor(raw, 'hsl');\n const oklch = formatColor(raw, 'oklch');\n const active = pickActiveFormat(raw, colorFormat, hex, hsl, oklch);\n const match = matchVariant(path, defs.matchOrder);\n const variant: Variant = {\n label: match?.label ?? BASE_LABEL,\n path,\n cssVar: resolveCssVar(path, projectFields),\n value: active.value,\n outOfGamut: active.outOfGamut,\n hex: hex.value,\n hsl: hsl.value,\n oklch: oklch.value,\n ...(token.$description !== undefined && { description: token.$description }),\n ...(token.aliasOf !== undefined && { aliasOf: token.aliasOf }),\n ...(token.aliasChain !== undefined && { aliasChain: token.aliasChain }),\n };\n const basePath = match?.basePath ?? path;\n const existing = groupMap.get(basePath);\n if (existing) existing.variants.push(variant);\n else groupMap.set(basePath, { base: basePath, variants: [variant] });\n }\n\n const out: Group[] = [];\n for (const { base, variants: vs } of groupMap.values()) {\n vs.sort((a, b) => orderIndex(a.label, defs) - orderIndex(b.label, defs));\n const searchText = vs.map((v) => `${v.path} ${v.value}`).join(' ');\n out.push({ base, variants: vs, searchText });\n }\n return out;\n }, [resolved, listing, cssVarPrefix, filter, sortBy, sortDir, defs, colorFormat]);\n\n const visibleGroups = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') return groups;\n return fuzzyFilter(groups, deferredQuery, (g) => g.searchText);\n }, [groups, deferredQuery, searchable]);\n\n const totalTokens = useMemo(() => groups.reduce((n, g) => n + g.variants.length, 0), [groups]);\n\n const toggleExpand = useCallback(\n (base: string) => {\n setExpandedByBase((prev) => {\n const next = new Set(prev);\n if (next.has(base)) next.delete(base);\n else next.add(base);\n return next;\n });\n },\n [setExpandedByBase],\n );\n\n const selectVariant = useCallback(\n (base: string, label: string) => {\n setSelectedByBase((prev) => ({ ...prev, [base]: label }));\n },\n [setSelectedByBase],\n );\n\n const matchSuffix =\n searchable && query.trim() !== ''\n ? ` · ${visibleGroups.length} matching \"${query.trim()}\"`\n : '';\n const captionText =\n caption ??\n `${totalTokens} color${totalTokens === 1 ? '' : 's'} across ${groups.length} group${\n groups.length === 1 ? '' : 's'\n }${filter ? ` matching \\`${filter}\\`` : ''}${matchSuffix} · ${activeTheme}`;\n\n if (groups.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No color tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-color-table__search\">\n <input\n type=\"search\"\n className=\"sb-color-table__search-input\"\n placeholder=\"Search colors…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Fuzzy-search colors by path or value\"\n data-testid=\"color-table-search\"\n />\n </div>\n )}\n <div className=\"sb-color-table__scroll\">\n <table className=\"sb-color-table__table\">\n <caption className=\"sb-color-table__caption\">{captionText}</caption>\n <thead>\n <tr>\n <th className=\"sb-color-table__th sb-color-table__th--swatch\">\n <span className=\"sb-color-table__sr-only\">Swatch</span>\n </th>\n <th className=\"sb-color-table__th sb-color-table__th--path\">Name</th>\n <th className=\"sb-color-table__th\">Value</th>\n <th className=\"sb-color-table__th\">CSS var</th>\n <th className=\"sb-color-table__th\">Alias</th>\n <th className=\"sb-color-table__th sb-color-table__th--expand\">\n <span className=\"sb-color-table__sr-only\">Expand</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {visibleGroups.length === 0 && (\n <tr>\n <td colSpan={COLUMN_COUNT} className=\"sb-color-table__td sb-color-table__empty-row\">\n No colors match \"{query.trim()}\".\n </td>\n </tr>\n )}\n {visibleGroups.map((group) => (\n <GroupRow\n key={group.base}\n group={group}\n selectedLabel={selectedByBase[group.base]}\n expanded={expandedByBase.has(group.base)}\n onToggleExpand={toggleExpand}\n onSelectVariant={selectVariant}\n {...(onSelect !== undefined && { onSelect })}\n />\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\ninterface GroupRowProps {\n group: Group;\n selectedLabel: string | undefined;\n expanded: boolean;\n onToggleExpand(base: string): void;\n onSelectVariant(base: string, label: string): void;\n onSelect?(path: string): void;\n}\n\nconst GroupRow = memo(function GroupRow({\n group,\n selectedLabel,\n expanded,\n onToggleExpand,\n onSelectVariant,\n onSelect,\n}: GroupRowProps): ReactElement {\n const multi = group.variants.length > 1;\n const active =\n group.variants.find((v) => v.label === selectedLabel) ?? (group.variants[0] as Variant);\n const nameText = multi ? group.base : active.path;\n\n const handleRowActivate = (): void => {\n if (onSelect) onSelect(active.path);\n else onToggleExpand(group.base);\n };\n\n return (\n <>\n <tr\n className={cx('sb-color-table__row', {\n 'sb-color-table__row--expanded': expanded,\n })}\n onClick={handleRowActivate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleRowActivate();\n }\n }}\n tabIndex={0}\n aria-label={\n onSelect\n ? `Inspect ${active.path}`\n : expanded\n ? `Collapse ${group.base}`\n : `Expand ${group.base}`\n }\n {...(onSelect ? { 'aria-haspopup': 'dialog' as const } : {})}\n data-testid=\"color-table-row\"\n data-path={active.path}\n data-base={group.base}\n >\n <td className=\"sb-color-table__td sb-color-table__swatch-cell\">\n <span\n className=\"sb-color-table__swatch\"\n style={{ background: active.cssVar }}\n aria-hidden\n />\n </td>\n <td className={cx('sb-color-table__td', 'sb-color-table__path')}>\n <span className=\"sb-color-table__path-text\">{nameText}</span>\n {multi && (\n <span\n className=\"sb-color-table__variant-pills\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n {group.variants.map((v) => (\n <button\n key={v.label}\n type=\"button\"\n className={cx('sb-color-table__variant-pill', {\n 'sb-color-table__variant-pill--active': v.label === active.label,\n })}\n onClick={() => onSelectVariant(group.base, v.label)}\n aria-pressed={v.label === active.label}\n data-testid=\"color-table-variant\"\n data-variant={v.label}\n >\n {v.label}\n </button>\n ))}\n </span>\n )}\n </td>\n <ValueCell value={active.value} label={`Copy value ${active.value}`}>\n {active.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-color-table__gamut-warn\"\n >\n ⚠\n </span>\n )}\n </ValueCell>\n <ValueCell value={active.cssVar} label={`Copy CSS var ${active.cssVar}`} />\n <td className=\"sb-color-table__td sb-color-table__alias\">\n {active.aliasOf ? (\n <span className=\"sb-color-table__alias-text\">{active.aliasOf}</span>\n ) : (\n <span className=\"sb-color-table__alias-empty\" aria-hidden>\n —\n </span>\n )}\n </td>\n <td className=\"sb-color-table__td sb-color-table__expand-cell\">\n {!onSelect && (\n <span\n className={cx('sb-color-table__chevron', {\n 'sb-color-table__chevron--expanded': expanded,\n })}\n aria-hidden\n >\n ▸\n </span>\n )}\n </td>\n </tr>\n {expanded && !onSelect && (\n <tr className=\"sb-color-table__detail-row\" data-testid=\"color-table-detail\">\n <td colSpan={COLUMN_COUNT} className=\"sb-color-table__td sb-color-table__detail-cell\">\n <ExpandedDetail group={group} active={active} />\n </td>\n </tr>\n )}\n </>\n );\n});\n\nfunction ExpandedDetail({ group, active }: { group: Group; active: Variant }): ReactElement {\n const hasDescription = active.description !== undefined && active.description.length > 0;\n const chain = active.aliasChain && active.aliasChain.length > 0 ? active.aliasChain : undefined;\n const multi = group.variants.length > 1;\n\n return (\n <div className=\"sb-color-table__detail\">\n {hasDescription && <p className=\"sb-color-table__description\">{active.description}</p>}\n {chain && (\n <p className=\"sb-color-table__chain\">\n <span className=\"sb-color-table__detail-label\">Alias chain:</span> {chain.join(' → ')}\n </p>\n )}\n {multi && (\n <div className=\"sb-color-table__variant-grid\">\n <div className=\"sb-color-table__variant-grid-header\">All variants</div>\n <table className=\"sb-color-table__subtable\">\n <thead>\n <tr>\n <th className=\"sb-color-table__subth\">Variant</th>\n <th className=\"sb-color-table__subth\">Path</th>\n <th className=\"sb-color-table__subth\">HEX</th>\n <th className=\"sb-color-table__subth\">HSL</th>\n <th className=\"sb-color-table__subth\">OKLCH</th>\n </tr>\n </thead>\n <tbody>\n {group.variants.map((v) => (\n <tr\n key={v.label}\n className={cx({\n 'sb-color-table__subrow--active': v.label === active.label,\n })}\n >\n <td className=\"sb-color-table__subtd\">{v.label}</td>\n <td className=\"sb-color-table__subtd sb-color-table__subtd--path\">{v.path}</td>\n <td className=\"sb-color-table__subtd\">{v.hex}</td>\n <td className=\"sb-color-table__subtd\">{v.hsl}</td>\n <td className=\"sb-color-table__subtd\">{v.oklch}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n {!hasDescription && !chain && !multi && (\n <p className=\"sb-color-table__detail-empty\">\n No description or alias chain authored for this token.\n </p>\n )}\n </div>\n );\n}\n\nfunction ValueCell({\n value,\n label,\n children,\n}: {\n value: string;\n label: string;\n children?: ReactElement | false;\n}): ReactElement {\n return (\n <td className=\"sb-color-table__td sb-color-table__value-cell\">\n <span className=\"sb-color-table__value-text\" title={value}>\n {value}\n </span>\n {children}\n <span\n className=\"sb-color-table__copy-wrap\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n <CopyButton value={value} label={label} className=\"sb-color-table__copy\" />\n </span>\n </td>\n );\n}\n\ntype FormatColorResult = ReturnType<typeof formatColor>;\n\n// Pick the value + gamut flag to display in the single Value column based\n// on the active color-format context. We pre-compute hex/hsl/oklch for the\n// expanded sub-table regardless; the extras (`rgb`, `raw`) take a fresh\n// `formatColor` pass. Keeps the hot path fast while staying honest about\n// out-of-gamut warnings per-format.\nfunction pickActiveFormat(\n raw: NormalizedColor,\n colorFormat: ColorFormat,\n hex: FormatColorResult,\n hsl: FormatColorResult,\n oklch: FormatColorResult,\n): { value: string; outOfGamut: boolean } {\n switch (colorFormat) {\n case 'hex':\n return { value: hex.value, outOfGamut: hex.outOfGamut };\n case 'hsl':\n return { value: hsl.value, outOfGamut: hsl.outOfGamut };\n case 'oklch':\n return { value: oklch.value, outOfGamut: oklch.outOfGamut };\n default: {\n const extra = formatColor(raw, colorFormat);\n return { value: extra.value, outOfGamut: extra.outOfGamut };\n }\n }\n}\n\ninterface VariantEntry {\n label: string;\n suffix: string;\n}\n\ninterface VariantDefs {\n // Match iteration order — longest suffix first.\n matchOrder: readonly VariantEntry[];\n // Display iteration order — preserves the caller's declared order.\n displayOrder: readonly string[];\n}\n\nfunction buildVariantDefs(variants: Record<string, string> | undefined): VariantDefs {\n if (!variants) return { matchOrder: [], displayOrder: [] };\n const entries: VariantEntry[] = [];\n const displayOrder: string[] = [];\n for (const [label, suffix] of Object.entries(variants)) {\n if (suffix.length === 0) continue;\n entries.push({ label, suffix });\n displayOrder.push(label);\n }\n const matchOrder = entries.toSorted((a, b) => b.suffix.length - a.suffix.length);\n return { matchOrder, displayOrder };\n}\n\n// Position of a label within a group — the `base` entry always sorts first,\n// then declared labels in the order the caller wrote them in the `variants`\n// prop. Unknown labels (shouldn't happen in practice) fall to the end.\nfunction orderIndex(label: string, defs: VariantDefs): number {\n if (label === BASE_LABEL) return -1;\n const idx = defs.displayOrder.indexOf(label);\n return idx >= 0 ? idx : Number.POSITIVE_INFINITY;\n}\n\n// Resolve the variant label + base path for a token, if any. The leaf\n// (last dot-segment) must either equal the suffix outright (dot-segment\n// form: `hi.disabled` matches suffix `disabled`) or end in `-<suffix>`\n// (hyphen-tail form: `hi-d` matches `d`). The leading hyphen is required\n// for the tail form so suffix `0` can't hit `neutral-900` by character.\n//\n// Returned `basePath` is what gets used as the grouping key:\n// - Dot-segment match → parent path (drop the last dot-segment)\n// - Hyphen-tail match → same dot-depth, leaf with `-<suffix>` stripped\n//\n// Entries in `matchOrder` are pre-sorted longest-first, so `h-dark` wins\n// over `dark` for a path ending in `-h-dark`.\nfunction matchVariant(\n path: string,\n matchOrder: readonly VariantEntry[],\n): { label: string; basePath: string } | undefined {\n if (matchOrder.length === 0) return undefined;\n const segments = path.split('.');\n const leaf = segments.at(-1) ?? path;\n for (const entry of matchOrder) {\n if (leaf === entry.suffix) {\n const parent = segments.slice(0, -1).join('.');\n if (parent.length === 0) continue;\n return { label: entry.label, basePath: parent };\n }\n const tailMarker = `-${entry.suffix}`;\n if (leaf.endsWith(tailMarker)) {\n const trimmed = leaf.slice(0, -tailMarker.length);\n if (trimmed.length === 0) continue;\n const copy = segments.slice(0, -1);\n copy.push(trimmed);\n return { label: entry.label, basePath: copy.join('.') };\n }\n }\n return undefined;\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './Diagnostics.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport type { VirtualDiagnostic } from '#/types.ts';\n\nexport interface DiagnosticsProps {\n /** Override the section caption. Defaults to a severity summary. */\n caption?: string;\n}\n\ntype DiagnosticSeverity = VirtualDiagnostic['severity'];\n\nconst severityLabel: Record<DiagnosticSeverity, string> = {\n error: 'ERROR',\n warn: 'WARN',\n info: 'INFO',\n};\n\ninterface DiagnosticsSummary {\n text: string;\n variant: 'ok' | 'error' | 'warn' | null;\n hasErrorsOrWarnings: boolean;\n}\n\nfunction summarize(diagnostics: readonly VirtualDiagnostic[]): DiagnosticsSummary {\n if (diagnostics.length === 0) {\n return { text: '✔ OK · no diagnostics', variant: 'ok', hasErrorsOrWarnings: false };\n }\n let errors = 0;\n let warnings = 0;\n let infos = 0;\n for (const d of diagnostics) {\n if (d.severity === 'error') errors += 1;\n else if (d.severity === 'warn') warnings += 1;\n else infos += 1;\n }\n const parts: string[] = [];\n if (errors > 0) parts.push(`✖ ${errors} error${errors === 1 ? '' : 's'}`);\n if (warnings > 0) parts.push(`⚠ ${warnings} warning${warnings === 1 ? '' : 's'}`);\n if (infos > 0) parts.push(`${infos} info`);\n const variant = errors > 0 ? 'error' : warnings > 0 ? 'warn' : null;\n return {\n text: parts.join(' · '),\n variant,\n hasErrorsOrWarnings: errors > 0 || warnings > 0,\n };\n}\n\nfunction diagnosticKey(d: VirtualDiagnostic, i: number): string {\n return `${d.severity}:${d.group}:${d.filename ?? ''}:${d.line ?? ''}:${d.message}:${i}`;\n}\n\n/**\n * Render the project's load diagnostics — parser errors, resolver warnings,\n * disabled-axes validation issues, etc. — as a collapsible list. Auto-opens\n * when the project carries errors or warnings; stays collapsed for clean\n * loads and info-only loads.\n *\n * Replaces the diagnostics section from the addon's (now-retired) Design\n * Tokens panel. Consumers compose it alongside TokenNavigator / TokenTable\n * on their own MDX pages.\n */\nexport function Diagnostics({ caption }: DiagnosticsProps = {}): ReactElement {\n const { activeAxes, cssVarPrefix, diagnostics } = useProject();\n const summary = useMemo(() => summarize(diagnostics), [diagnostics]);\n const headingText = caption ?? `Diagnostics · ${summary.text}`;\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)} data-testid=\"diagnostics\">\n <details open={summary.hasErrorsOrWarnings}>\n <summary\n className={cx(\n 'sb-diagnostics__summary',\n summary.variant && `sb-diagnostics__summary--${summary.variant}`,\n )}\n >\n {headingText}\n </summary>\n {diagnostics.length > 0 && (\n <ul role=\"list\" className=\"sb-diagnostics__list\">\n {diagnostics.map((d, i) => (\n <li\n key={diagnosticKey(d, i)}\n className=\"sb-diagnostics__row\"\n aria-label={`${severityLabel[d.severity]}: ${d.message}`}\n >\n <span\n className={cx('sb-diagnostics__label', {\n [`sb-diagnostics__label--${d.severity}`]: d.severity !== 'info',\n })}\n aria-hidden\n >\n {severityLabel[d.severity]}\n </span>\n <div>\n <div>{d.message}</div>\n {(d.group || d.filename) && (\n <div className=\"sb-diagnostics__meta\">\n {[d.group, d.filename, d.line ? `:${d.line}` : '']\n .filter(Boolean)\n .join(' · ')}\n </div>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </details>\n </div>\n );\n}\n","/** Max rendered pixel size for a dimension bar/sample before it's capped. */\nexport const MAX_RENDER_PX = 480;\n\n/**\n * Convert a DTCG dimension `$value` (`{ value, unit }`) to pixels for the\n * purpose of deciding whether to cap the rendered size. Returns `NaN` for\n * units we can't reasonably approximate (ex / ch / %), which the caller\n * treats as \"render at cssVar but don't cap\".\n */\nexport function toPixels(raw: unknown): number {\n if (raw == null || typeof raw !== 'object') return Number.NaN;\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value !== 'number' || typeof v.unit !== 'string') return Number.NaN;\n switch (v.unit) {\n case 'px':\n return v.value;\n case 'rem':\n case 'em':\n return v.value * 16;\n default:\n return Number.NaN;\n }\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { MAX_RENDER_PX, toPixels } from '#/dimension-scale/dimension-px.ts';\nimport { BORDER_STRONG } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport type DimensionVisual = 'length' | 'radius' | 'size';\n\nexport interface DimensionBarProps {\n /** Full dot-path of the dimension token to preview. */\n path: string;\n /**\n * Visualization kind:\n * - `'length'` (default): horizontal bar whose width equals the token's dimension.\n * - `'radius'`: 56×56 square with the token applied as `border-radius`.\n * - `'size'`: a square sized to the token's dimension.\n */\n visual?: DimensionVisual;\n}\n\nconst styles = {\n bar: {\n height: 14,\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n borderRadius: 2,\n minWidth: 1,\n } satisfies CSSProperties,\n radiusSample: {\n width: 56,\n height: 56,\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n border: BORDER_STRONG,\n } satisfies CSSProperties,\n sizeSample: {\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n border: BORDER_STRONG,\n minWidth: 1,\n minHeight: 1,\n } satisfies CSSProperties,\n};\n\nexport function DimensionBar({ path, visual = 'length' }: DimensionBarProps): ReactElement {\n const project = useProject();\n const { resolved } = project;\n const cssVar = resolveCssVar(path, project);\n const token = resolved[path];\n const pxValue = toPixels(token?.$value);\n const capped = Number.isFinite(pxValue) && pxValue > MAX_RENDER_PX;\n const cappedValue = capped ? `${MAX_RENDER_PX}px` : cssVar;\n\n switch (visual) {\n case 'radius':\n return <div style={{ ...styles.radiusSample, borderRadius: cssVar }} aria-hidden />;\n case 'size':\n return (\n <div\n style={{ ...styles.sizeSample, width: cappedValue, height: cappedValue }}\n aria-hidden\n />\n );\n case 'length':\n default:\n return <div style={{ ...styles.bar, width: cappedValue }} aria-hidden />;\n }\n}\n","import type { VirtualTokenListingShape } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport type {\n BorderValue,\n DashedStrokeStyleValue,\n ShadowLayer,\n} from '#/internal/composite-types.ts';\n\n/**\n * Single-line display string for any DTCG token `$value`. Prefers\n * plugin-css's `previewValue` from the Token Listing; for color\n * tokens only when the toolbar format is hex (other formats route\n * through local colorjs.io).\n */\nexport function formatTokenValue(\n value: unknown,\n $type: string | undefined,\n colorFormat: ColorFormat,\n listingEntry?: VirtualTokenListingShape,\n): string {\n if (value == null) return '';\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n\n const preview = listingEntry?.previewValue;\n if (preview !== undefined) {\n const previewStr = typeof preview === 'string' ? cleanFloatNoise(preview) : String(preview);\n if ($type !== 'color') return previewStr;\n if (colorFormat === 'hex') return previewStr;\n }\n\n switch ($type) {\n case 'color':\n return formatColor(value, colorFormat).value;\n case 'dimension':\n case 'duration':\n return formatDimension(value);\n case 'fontFamily':\n return formatFontFamily(value);\n case 'fontWeight':\n case 'lineHeight':\n case 'letterSpacing':\n case 'opacity':\n case 'number':\n return formatPrimitive(value);\n case 'cubicBezier':\n return formatCubicBezier(value);\n case 'strokeStyle':\n return formatStrokeStyle(value);\n case 'shadow':\n return formatShadow(value, colorFormat);\n case 'border':\n return formatBorder(value, colorFormat);\n default:\n return formatUnknown(value);\n }\n}\n\nfunction formatDimension(v: unknown): string {\n if (typeof v === 'string' || typeof v === 'number') return String(v);\n if (v && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number' && typeof d.unit === 'string') return `${d.value}${d.unit}`;\n }\n return formatUnknown(v);\n}\n\nfunction cleanFloatNoise(s: string): string {\n return s.replace(/-?\\d+\\.\\d{8,}/g, (m) => `${+Number(m).toFixed(3)}`);\n}\n\nfunction formatFontFamily(v: unknown): string {\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n return formatUnknown(v);\n}\n\nfunction formatPrimitive(v: unknown): string {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n return formatUnknown(v);\n}\n\nfunction formatCubicBezier(v: unknown): string {\n if (Array.isArray(v) && v.length === 4) {\n return `cubic-bezier(${v.map((n) => (typeof n === 'number' ? n : 0)).join(', ')})`;\n }\n return formatUnknown(v);\n}\n\nfunction formatStrokeStyle(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v && typeof v === 'object') {\n const s = v as DashedStrokeStyleValue;\n const parts: string[] = ['dashed'];\n if (Array.isArray(s.dashArray)) {\n parts.push(s.dashArray.map((n) => formatDimension(n)).join(' '));\n }\n if (typeof s.lineCap === 'string') parts.push(s.lineCap);\n return parts.join(' · ');\n }\n return formatUnknown(v);\n}\n\nfunction formatShadow(v: unknown, colorFormat: ColorFormat): string {\n const layers = Array.isArray(v) ? v : [v];\n const parts = layers.map((layer) => {\n if (!layer || typeof layer !== 'object') return formatUnknown(layer);\n const s = layer as ShadowLayer;\n const pieces = [\n formatDimension(s.offsetX),\n formatDimension(s.offsetY),\n formatDimension(s.blur),\n formatDimension(s.spread),\n formatColor(s.color, colorFormat).value,\n ].filter((p) => p !== '');\n if (s.inset) pieces.push('inset');\n return pieces.join(' ');\n });\n return parts.join(', ');\n}\n\nfunction formatBorder(v: unknown, colorFormat: ColorFormat): string {\n if (!v || typeof v !== 'object') return formatUnknown(v);\n const b = v as BorderValue;\n const width = formatDimension(b.width);\n const style = formatPrimitive(b.style);\n const color = formatColor(b.color, colorFormat).value;\n return [width, style, color].filter((p) => p !== '').join(' ');\n}\n\nfunction formatUnknown(v: unknown): string {\n if (v == null) return '';\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n try {\n return JSON.stringify(v).slice(0, 120);\n } catch {\n return String(v);\n }\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './DimensionScale.css';\nimport { DimensionBar } from '#/dimension-scale/DimensionBar.tsx';\nimport type { DimensionVisual } from '#/dimension-scale/DimensionBar.tsx';\nimport { MAX_RENDER_PX, toPixels } from '#/dimension-scale/dimension-px.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport type { DimensionVisual };\n\nexport interface DimensionScaleProps {\n /**\n * Token-path filter. Defaults to every `dimension` token. Use e.g.\n * `\"space.*\"` to scope to the spacing scale.\n */\n filter?: string;\n /**\n * Visualization kind:\n * - `'length'` (default): horizontal bar whose width equals the token's dimension.\n * - `'radius'`: 56×56 square with the token applied as `border-radius`.\n * - `'size'`: a square sized to the token's dimension.\n */\n visual?: DimensionVisual;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — numeric by rendered pixel size (`px` / `rem` / `em`).\n * Non-convertible units (ex/ch/%) land after the convertible ones.\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n displayValue: string;\n pxValue: number;\n capped: boolean;\n}\n\nexport function DimensionScale({\n filter,\n visual = 'length',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: DimensionScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'dimension') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const pxValue = toPixels(token.$value);\n return {\n path,\n cssVar: resolveCssVar(path, project),\n displayValue: formatTokenValue(token.$value, token.$type, 'raw', project.listing[path]),\n pxValue,\n capped: Number.isFinite(pxValue) && pxValue > MAX_RENDER_PX,\n };\n });\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} dimension${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No dimension tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-dimension-scale__row\">\n <div className=\"sb-dimension-scale__meta\">\n <span className=\"sb-dimension-scale__path\">{row.path}</span>\n <span className=\"sb-dimension-scale__specs\">{row.displayValue}</span>\n </div>\n <div className=\"sb-dimension-scale__visual-cell\">\n <DimensionBar path={row.path} visual={visual} />\n {row.capped && (\n <span className=\"sb-dimension-scale__cap\">capped at {MAX_RENDER_PX}px</span>\n )}\n </div>\n <span className=\"sb-dimension-scale__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './FontFamilyPreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\nexport interface FontFamilyPreviewProps {\n /**\n * Token-path filter. Defaults to every `fontFamily` token. Use e.g.\n * `\"font.family.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n stack: string;\n}\n\nfunction stackString(raw: unknown): string {\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.map(String).join(', ');\n return '';\n}\n\nexport function FontFamilyPreview({\n filter,\n sample = 'The quick brown fox jumps over the lazy dog.',\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: FontFamilyPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'fontFamily') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n stack: stackString(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} fontFamily token${rows.length === 1 ? '' : 's'}${filter && filter !== 'fontFamily' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No fontFamily tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-font-family-sample__row\">\n <div className=\"sb-font-family-sample__meta\">\n <span className=\"sb-font-family-sample__path\">{row.path}</span>\n <span className=\"sb-font-family-sample__stack\">{row.stack}</span>\n </div>\n <div className=\"sb-font-family-sample__sample\" style={{ fontFamily: row.cssVar }}>\n {sample}\n </div>\n <span className=\"sb-font-family-sample__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","/**\n * Coerce a CSS `var(--…)` reference into the numeric slot of a React\n * inline-style property.\n *\n * React's `CSSProperties` types unitless properties (`fontWeight`,\n * `lineHeight`, `zIndex`, …) as `number`. The DOM accepts a string at\n * runtime — the rendered stylesheet just receives whatever React passes —\n * so a `var(--font-weight)` reference works functionally. TypeScript still\n * complains. Centralising the type assertion in one named helper keeps\n * the gap visible (and greppable) instead of scattering casts across\n * block components that want CSS-var-driven typography or layout values.\n */\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error — React's CSSProperties slot is `number`; the DOM tolerates a CSS var string.\nexport const cssVarAsNumber = (varRef: string): number => varRef;\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './FontWeightScale.css';\nimport { cssVarAsNumber } from '#/internal/css-var-style.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface FontWeightScaleProps {\n /**\n * Token-path filter. Defaults to every `fontWeight` token. Use e.g.\n * `\"font.weight.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — ascending numeric by weight (100 → 900).\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n display: string;\n weight: number;\n}\n\nfunction toWeight(raw: unknown): number {\n if (typeof raw === 'number') return raw;\n if (typeof raw === 'string') {\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) ? n : Number.NaN;\n }\n return Number.NaN;\n}\n\nexport function FontWeightScale({\n filter,\n sample = 'Aa',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: FontWeightScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'fontWeight') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n display: token.$value == null ? '' : String(token.$value),\n weight: toWeight(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} fontWeight token${rows.length === 1 ? '' : 's'}${filter && filter !== 'fontWeight' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No fontWeight tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-font-weight-scale__row\">\n <div className=\"sb-font-weight-scale__meta\">\n <span className=\"sb-font-weight-scale__path\">{row.path}</span>\n <span className=\"sb-font-weight-scale__value\">{row.display}</span>\n </div>\n <div\n className=\"sb-font-weight-scale__sample\"\n style={{ fontWeight: cssVarAsNumber(row.cssVar) }}\n >\n {sample}\n </div>\n <span className=\"sb-font-weight-scale__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './GradientPalette.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport { parseColor } from '@unpunnyfuns/swatchbook-core/format-color';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface GradientPaletteProps {\n /**\n * Token-path filter. Defaults to every `gradient` token. Use e.g.\n * `\"gradient.*\"` or `\"gradient.accent\"` to scope.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (gradients don't have\n * a single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface GradientStop {\n color?: {\n colorSpace?: string;\n components?: readonly number[];\n alpha?: number;\n };\n position?: number;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n stops: GradientStop[];\n}\n\nfunction asStops(raw: unknown): GradientStop[] {\n if (!Array.isArray(raw)) return [];\n return raw as GradientStop[];\n}\n\nfunction stopCssColor(stop: GradientStop): string {\n // parseColor respects the stop's colorSpace (via the colorjs space-alias\n // map) and emits a gamut-correct CSS string — e.g. `color(display-p3 …)`\n // for a P3 stop — rather than the old code's raw sRGB-percentage rendering\n // that mislabeled every non-sRGB stop.\n const color = parseColor(stop.color);\n if (!color) return 'transparent';\n return color.toString();\n}\n\nfunction stopKey(path: string, stop: GradientStop, fallback: number): string {\n return `${path}|${stop.position ?? fallback}|${stopCssColor(stop)}`;\n}\n\nexport function GradientPalette({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: GradientPaletteProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'gradient') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, projectFields),\n stops: asStops(token.$value),\n }));\n }, [resolved, listing, cssVarPrefix, filter, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} gradient${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No gradient tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-gradient-palette__row\">\n <div className=\"sb-gradient-palette__meta\">\n <span className=\"sb-gradient-palette__path\">{row.path}</span>\n <span className=\"sb-gradient-palette__css-var\">{row.cssVar}</span>\n </div>\n <div\n className=\"sb-gradient-palette__sample\"\n style={{ background: `linear-gradient(to right, ${row.cssVar})` }}\n aria-hidden\n />\n <div className=\"sb-gradient-palette__stops\">\n {row.stops.map((stop, i) => (\n <div key={stopKey(row.path, stop, i)} className=\"sb-gradient-palette__stop-row\">\n <span\n className=\"sb-gradient-palette__stop-swatch\"\n style={{ background: stopCssColor(stop) }}\n aria-hidden\n />\n <span>{formatColor(stop.color, colorFormat).value}</span>\n <span className=\"sb-gradient-palette__stop-position\">\n @ {((stop.position ?? 0) * 100).toFixed(0)}%\n </span>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\n\n// True when rendering inside Chromatic's snapshot runner. Chromatic's\n// browser ships a recognisable user-agent string; checked here so\n// motion-looping components can fall back to their static state for\n// deterministic snapshots. Per-component detection rather than the\n// global `chromatic.prefersReducedMotion: true` parameter — that\n// parameter is incompatible with Chromatic's verification parser.\nfunction isChromatic(): boolean {\n if (typeof navigator === 'undefined') return false;\n return navigator.userAgent.includes('Chromatic');\n}\n\n/**\n * Reactive `prefers-reduced-motion: reduce` detector. Returns the current\n * match and updates if the user toggles the OS-level preference. Also\n * returns `true` under Chromatic to keep animated samples deterministic\n * during visual regression capture.\n */\nexport function usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (isChromatic()) {\n setReduced(true);\n return;\n }\n const query = window.matchMedia('(prefers-reduced-motion: reduce)');\n setReduced(query.matches);\n const onChange = (e: MediaQueryListEvent): void => setReduced(e.matches);\n query.addEventListener('change', onChange);\n return () => query.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { SURFACE_MUTED, TEXT_MUTED } from '#/internal/styles.tsx';\nimport { useEffect, useMemo, useState } from 'react';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { useProject } from '#/internal/use-project.ts';\n\nexport type MotionSpeed = 0.25 | 0.5 | 1 | 2;\n\nexport interface MotionSampleProps {\n /** Full dot-path of the motion token (`transition`, `duration`, or `cubicBezier`). */\n path: string;\n /** Playback speed multiplier. Defaults to `1`. */\n speed?: MotionSpeed;\n /**\n * Change this value to force the animation to restart. Useful when an\n * outer block exposes a \"replay\" button that should re-trigger every\n * sample at once.\n */\n runKey?: number;\n}\n\nconst DEFAULT_DURATION_MS = 300;\nconst DEFAULT_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst styles = {\n track: {\n position: 'relative',\n height: 36,\n background: SURFACE_MUTED,\n borderRadius: 18,\n overflow: 'hidden',\n } satisfies CSSProperties,\n ball: {\n position: 'absolute',\n top: '50%',\n width: 28,\n height: 28,\n marginTop: -14,\n borderRadius: '50%',\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n } satisfies CSSProperties,\n reducedMotion: {\n fontSize: 11,\n color: TEXT_MUTED,\n fontStyle: 'italic',\n } satisfies CSSProperties,\n};\n\ninterface Spec {\n durationMs: number;\n easing: string;\n}\n\nfunction extractDurationMs(raw: unknown): number {\n if (raw == null) return Number.NaN;\n if (typeof raw === 'object') {\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value === 'number' && typeof v.unit === 'string') {\n if (v.unit === 'ms') return v.value;\n if (v.unit === 's') return v.value * 1000;\n }\n }\n return Number.NaN;\n}\n\nfunction extractCubicBezier(raw: unknown): string | null {\n if (Array.isArray(raw) && raw.length === 4 && raw.every((n) => typeof n === 'number')) {\n return `cubic-bezier(${raw.map((n) => Number(n).toFixed(3)).join(', ')})`;\n }\n return null;\n}\n\nfunction asDuration(\n raw: unknown,\n themeTokens: Record<string, { $value?: unknown }>,\n fallback: number,\n): number {\n const direct = extractDurationMs(raw);\n if (Number.isFinite(direct)) return direct;\n if (typeof raw === 'string') {\n const match = raw.match(/^\\{([^}]+)\\}$/);\n if (match && match[1]) {\n const referenced = themeTokens[match[1]];\n const resolved = extractDurationMs(referenced?.$value);\n if (Number.isFinite(resolved)) return resolved;\n }\n }\n return fallback;\n}\n\nfunction asEasing(\n raw: unknown,\n themeTokens: Record<string, { $value?: unknown }>,\n fallback: string,\n): string {\n const direct = extractCubicBezier(raw);\n if (direct) return direct;\n if (typeof raw === 'string') {\n const match = raw.match(/^\\{([^}]+)\\}$/);\n if (match && match[1]) {\n const referenced = themeTokens[match[1]];\n const resolved = extractCubicBezier(referenced?.$value);\n if (resolved) return resolved;\n }\n }\n return fallback;\n}\n\nexport function resolveMotionSpec(\n token: { $type?: string | undefined; $value?: unknown } | undefined,\n themeTokens: Record<string, { $value?: unknown }>,\n): Spec | null {\n if (!token) return null;\n const type = token.$type;\n if (type === 'transition') {\n const v = (token.$value ?? {}) as {\n duration?: unknown;\n timingFunction?: unknown;\n };\n return {\n durationMs: asDuration(v.duration, themeTokens, DEFAULT_DURATION_MS),\n easing: asEasing(v.timingFunction, themeTokens, DEFAULT_EASING),\n };\n }\n if (type === 'duration') {\n const durationMs = extractDurationMs(token.$value);\n if (!Number.isFinite(durationMs)) return null;\n return { durationMs, easing: DEFAULT_EASING };\n }\n if (type === 'cubicBezier') {\n const easing = extractCubicBezier(token.$value);\n if (!easing) return null;\n return { durationMs: DEFAULT_DURATION_MS, easing };\n }\n return null;\n}\n\nexport function MotionSample({ path, speed = 1, runKey = 0 }: MotionSampleProps): ReactElement {\n const { resolved } = useProject();\n const reducedMotion = usePrefersReducedMotion();\n\n const spec = useMemo(() => resolveMotionSpec(resolved[path], resolved), [resolved, path]);\n\n const durationMs = spec?.durationMs ?? DEFAULT_DURATION_MS;\n const easing = spec?.easing ?? DEFAULT_EASING;\n const scaledDuration = Math.max(1, durationMs / speed);\n\n const [phase, setPhase] = useState<0 | 1>(0);\n\n useEffect(() => {\n if (reducedMotion) return;\n setPhase(0);\n const id = requestAnimationFrame(() => setPhase(1));\n const loop = window.setInterval(() => {\n setPhase((p) => (p === 0 ? 1 : 0));\n }, scaledDuration * 2);\n return () => {\n cancelAnimationFrame(id);\n window.clearInterval(loop);\n };\n }, [scaledDuration, runKey, reducedMotion]);\n\n if (reducedMotion) {\n return (\n <div style={styles.reducedMotion}>\n Animation suppressed by <code>prefers-reduced-motion: reduce</code>.\n </div>\n );\n }\n\n return (\n <div style={styles.track}>\n <div\n style={{\n ...styles.ball,\n left: phase === 1 ? 'calc(100% - 32px)' : '4px',\n transition: `left ${scaledDuration}ms ${easing}`,\n }}\n aria-hidden\n />\n </div>\n );\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo, useState } from 'react';\nimport './MotionPreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { MotionSample, resolveMotionSpec } from '#/motion-preview/MotionSample.tsx';\nimport type { MotionSpeed } from '#/motion-preview/MotionSample.tsx';\n\nexport type { MotionSpeed };\n\nexport interface MotionPreviewProps {\n /**\n * Token-path filter. Defaults to transition + duration + cubicBezier\n * tokens. Use e.g. `\"transition.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n}\n\nconst SPEEDS: MotionSpeed[] = [0.25, 0.5, 1, 2];\n\ninterface Row {\n path: string;\n cssVar: string;\n durationMs: number;\n easing: string;\n kind: 'transition' | 'duration' | 'cubicBezier';\n}\n\nfunction formatSpec(row: Row): string {\n switch (row.kind) {\n case 'transition':\n return `transition · ${Math.round(row.durationMs)}ms · ${row.easing}`;\n case 'duration':\n return `duration · ${Math.round(row.durationMs)}ms`;\n case 'cubicBezier':\n return `cubicBezier · ${row.easing}`;\n }\n}\n\nexport function MotionPreview({ filter, caption }: MotionPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const [speed, setSpeed] = useState<MotionSpeed>(1);\n const [run, setRun] = useState(0);\n const reducedMotion = usePrefersReducedMotion();\n\n const rows = useMemo(() => {\n const collected: Row[] = [];\n for (const [path, token] of Object.entries(resolved)) {\n if (filter && !matchPath(path, filter)) continue;\n if (!filter && !['transition', 'duration', 'cubicBezier'].includes(token.$type ?? '')) {\n continue;\n }\n const kind = token.$type as Row['kind'] | undefined;\n if (!kind) continue;\n const spec = resolveMotionSpec(token, resolved);\n if (!spec) continue;\n collected.push({\n path,\n cssVar: resolveCssVar(path, project),\n durationMs: spec.durationMs,\n easing: spec.easing,\n kind,\n });\n }\n collected.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);\n return a.path.localeCompare(b.path, undefined, { numeric: true });\n });\n return collected;\n }, [resolved, filter, project]);\n\n const captionText =\n caption ??\n `${rows.length} motion token${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No motion tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n <div className=\"sb-motion-preview__controls\">\n <span className=\"sb-motion-preview__control-label\">Speed</span>\n {SPEEDS.map((s) => (\n <button\n key={s}\n type=\"button\"\n className={cx('sb-motion-preview__speed-btn', {\n 'sb-motion-preview__speed-btn--active': s === speed,\n })}\n onClick={() => setSpeed(s)}\n >\n {s}×\n </button>\n ))}\n <button\n type=\"button\"\n className=\"sb-motion-preview__replay-btn\"\n onClick={() => setRun((n) => n + 1)}\n disabled={reducedMotion}\n title={reducedMotion ? 'Disabled by prefers-reduced-motion' : 'Replay all'}\n >\n ↻ Replay\n </button>\n </div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-motion-preview__row\">\n <div className=\"sb-motion-preview__meta\">\n <span className=\"sb-motion-preview__path\">{row.path}</span>\n <span className=\"sb-motion-preview__specs\">{formatSpec(row)}</span>\n </div>\n <MotionSample path={row.path} speed={speed} runKey={run} />\n <span className=\"sb-motion-preview__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './OpacityScale.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface OpacityScaleProps {\n /**\n * Token-path filter. Use `\"number.opacity.*\"` or `\"opacity.*\"` depending\n * on your layout. Omit to match every `$type: 'number'` token whose\n * value is in `[0, 1]` — the value-range check (applied alongside\n * the glob) keeps line-heights / z-indexes out.\n */\n filter?: string;\n /**\n * DTCG `$type` filter. `opacity` tokens where DTCG ships them as a\n * dedicated type; otherwise `number` (the common placement pre-spec).\n * Accepts either.\n */\n type?: 'number' | 'opacity';\n /**\n * Sample token rendered at each opacity. Defaults to `color.accent.bg`\n * — swap to whatever colour your system uses to demonstrate scrim /\n * overlay behaviour.\n */\n sampleColor?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — numeric, low opacity first.\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n opacity: number;\n displayValue: string;\n}\n\nfunction toOpacity(raw: unknown): number {\n if (typeof raw === 'number') return raw;\n return Number.NaN;\n}\n\n/**\n * Render each opacity token as a colored sample at that opacity over a\n * checkerboard backdrop, so the transparency is visually readable. The\n * number by itself (`0.4`) doesn't convey what the token looks like\n * applied to a surface; the sample does.\n *\n * Only tokens whose `$value` is a finite number between 0 and 1\n * inclusive are rendered — non-opacity `number` siblings (`line-height`,\n * `z-index`) fall out naturally.\n */\nexport function OpacityScale({\n filter,\n type = 'number',\n sampleColor = 'color.accent.bg',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: OpacityScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== type) return false;\n const v = toOpacity(token.$value);\n if (!Number.isFinite(v) || v < 0 || v > 1) return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const opacity = toOpacity(token.$value);\n return {\n path,\n cssVar: resolveCssVar(path, project),\n opacity,\n displayValue: String(opacity),\n };\n });\n }, [resolved, filter, type, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} opacity token${rows.length === 1 ? '' : 's'}${\n filter ? ` matching \\`${filter}\\`` : ''\n } · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No opacity tokens match this filter.</div>\n </div>\n );\n }\n\n const sampleColorVar = resolveCssVar(sampleColor, project);\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n <div className=\"sb-opacity-scale__grid\">\n {rows.map((row) => (\n <div key={row.path} className=\"sb-opacity-scale__card\">\n <div\n className=\"sb-opacity-scale__swatch\"\n style={\n {\n '--sb-opacity-scale-color': sampleColorVar,\n '--sb-opacity-scale-alpha': String(row.opacity),\n } as CSSProperties\n }\n aria-hidden\n />\n <div className=\"sb-opacity-scale__meta\">\n <span className=\"sb-opacity-scale__path\">{row.path}</span>\n <span className=\"sb-opacity-scale__value\">{row.displayValue}</span>\n <span className=\"sb-opacity-scale__css-var\">{row.cssVar}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import type { ReactElement, ReactNode } from 'react';\nimport { SwatchbookContext, useOptionalSwatchbookData } from '#/contexts.ts';\nimport type { ProjectSnapshot } from '#/contexts.ts';\n\nexport type { ProjectSnapshot };\n\nexport interface SwatchbookProviderProps {\n value: ProjectSnapshot;\n children: ReactNode;\n}\n\n/**\n * Wraps a tree of blocks with the token data they need to render.\n *\n * The Storybook addon's preview decorator mounts this automatically, so\n * story/MDX authors typically never see it. Outside Storybook — unit\n * tests, custom React apps, non-Storybook doc sites — consumers construct\n * a {@link ProjectSnapshot} (often imported from a JSON file) and wrap\n * their blocks in this provider.\n */\nexport function SwatchbookProvider({ value, children }: SwatchbookProviderProps): ReactElement {\n return <SwatchbookContext.Provider value={value}>{children}</SwatchbookContext.Provider>;\n}\n\n/**\n * Read the current {@link ProjectSnapshot}. Throws if called outside a\n * {@link SwatchbookProvider}; blocks that need to fall back to the\n * virtual module go through the internal `useProject()` hook instead.\n */\nexport function useSwatchbookData(): ProjectSnapshot {\n const value = useOptionalSwatchbookData();\n if (!value) {\n throw new Error(\n '[swatchbook-blocks] useSwatchbookData() called outside <SwatchbookProvider>. ' +\n 'Wrap your tree in <SwatchbookProvider value={snapshot}> or render inside a Storybook story.',\n );\n }\n return value;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { BORDER_FAINT, SURFACE_RAISED } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport interface ShadowSampleProps {\n /** Full dot-path of the shadow token to preview. */\n path: string;\n}\n\nconst sampleStyle: CSSProperties = {\n width: 120,\n height: 56,\n background: SURFACE_RAISED,\n border: BORDER_FAINT,\n borderRadius: 6,\n};\n\nexport function ShadowSample({ path }: ShadowSampleProps): ReactElement {\n const project = useProject();\n const cssVar = resolveCssVar(path, project);\n return <div style={{ ...sampleStyle, boxShadow: cssVar }} aria-hidden />;\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './ShadowPreview.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { formatDimension, formatSubColor } from '#/internal/composite-sample-format.ts';\nimport type { ShadowLayer } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { ShadowSample } from '#/shadow-preview/ShadowSample.tsx';\n\nexport interface ShadowPreviewProps {\n /**\n * Token-path filter. Defaults to every `shadow` token. Use e.g.\n * `\"shadow.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (shadows don't have a\n * single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n layers: ShadowLayer[];\n}\n\nfunction asLayers(raw: unknown): ShadowLayer[] {\n if (Array.isArray(raw)) return raw as ShadowLayer[];\n if (raw && typeof raw === 'object') return [raw as ShadowLayer];\n return [];\n}\n\nfunction layerKey(path: string, layer: ShadowLayer, fallback: number): string {\n const off = `${formatDimension(layer.offsetX)},${formatDimension(layer.offsetY)}`;\n const blur = formatDimension(layer.blur);\n const spread = formatDimension(layer.spread);\n return `${path}|${off}|${blur}|${spread}|${fallback}`;\n}\n\nexport function ShadowPreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: ShadowPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'shadow') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n layers: asLayers(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} shadow${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No shadow tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-shadow-preview__row\">\n <div className=\"sb-shadow-preview__meta\">\n <span className=\"sb-shadow-preview__path\">{row.path}</span>\n <span className=\"sb-shadow-preview__css-var\">{row.cssVar}</span>\n </div>\n <div className=\"sb-shadow-preview__sample-cell\">\n <ShadowSample path={row.path} />\n </div>\n <div className=\"sb-shadow-preview__breakdown\">\n {row.layers.length === 1\n ? renderLayer(row.layers[0], colorFormat)\n : row.layers.map((layer, i) => (\n <Layer\n key={layerKey(row.path, layer, i)}\n layer={layer}\n index={i}\n total={row.layers.length}\n colorFormat={colorFormat}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction renderLayer(layer: ShadowLayer | undefined, format: ColorFormat): ReactElement[] {\n if (!layer) return [];\n const entries: [string, string][] = [\n ['offset', `${formatDimension(layer.offsetX)} ${formatDimension(layer.offsetY)}`],\n ['blur', formatDimension(layer.blur)],\n ['spread', formatDimension(layer.spread)],\n ['color', formatSubColor(layer.color, format)],\n ];\n if (layer.inset) entries.push(['inset', String(layer.inset)]);\n return entries.flatMap(([k, v]) => [\n <span key={`k-${k}`} className=\"sb-shadow-preview__breakdown-key\">\n {k}\n </span>,\n <span key={`v-${k}`}>{v}</span>,\n ]);\n}\n\nfunction Layer({\n layer,\n index,\n total,\n colorFormat,\n}: {\n layer: ShadowLayer;\n index: number;\n total: number;\n colorFormat: ColorFormat;\n}): ReactElement {\n return (\n <div className=\"sb-shadow-preview__layer\">\n <div className=\"sb-shadow-preview__layer-header\">\n layer {index + 1} of {total}\n </div>\n <div className={cx('sb-shadow-preview__breakdown', 'sb-shadow-preview__layer-breakdown')}>\n {renderLayer(layer, colorFormat)}\n </div>\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './StrokeStylePreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\nexport interface StrokeStylePreviewProps {\n /**\n * Token-path filter. Defaults to every `strokeStyle` token. Use e.g.\n * `\"stroke.style.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\nconst STRING_STYLES = new Set([\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n 'inset',\n]);\n\ninterface Row {\n path: string;\n cssVar: string;\n displayValue: string;\n cssStyle: string | null;\n}\n\nfunction extractCssStyle(value: unknown): string | null {\n if (typeof value === 'string' && STRING_STYLES.has(value)) return value;\n return null;\n}\n\nexport function StrokeStylePreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: StrokeStylePreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'strokeStyle') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n displayValue: formatTokenValue(token.$value, token.$type, 'raw', project.listing[path]),\n cssStyle: extractCssStyle(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} strokeStyle token${rows.length === 1 ? '' : 's'}${filter && filter !== 'strokeStyle' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No strokeStyle tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-stroke-style-sample__row\">\n <div className=\"sb-stroke-style-sample__meta\">\n <span className=\"sb-stroke-style-sample__path\">{row.path}</span>\n <span className=\"sb-stroke-style-sample__value\">{row.displayValue}</span>\n </div>\n {row.cssStyle ? (\n <div\n className=\"sb-stroke-style-sample__line\"\n style={{\n borderTopStyle: row.cssStyle as CSSProperties['borderTopStyle'],\n }}\n aria-hidden\n />\n ) : (\n <span className=\"sb-stroke-style-sample__object-fallback\">\n Object-form (dashArray + lineCap) — no pure CSS `border-style` equivalent.\n </span>\n )}\n <span className=\"sb-stroke-style-sample__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { Axis, AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\ntype VirtualVarianceByPathShape = Record<string, AxisVarianceResult>;\n\nexport interface DetailToken {\n $type?: string;\n $value?: unknown;\n $description?: string;\n $deprecated?: string | boolean;\n aliasOf?: string;\n aliasChain?: readonly string[];\n aliasedBy?: readonly string[];\n /**\n * Terrazzo-populated sub-value alias map for composite tokens. Shape\n * varies by $type: object-valued composites (`border`, `typography`,\n * `transition`) use `Record<string, string | undefined>` keyed by\n * sub-key; array-valued composites (`shadow`, `gradient`) use an array\n * of such records indexed per layer / stop. Carried through `unknown`\n * here so each consumer narrows at use-site.\n */\n partialAliasOf?: unknown;\n}\n\nexport interface TokenDetailData {\n token: DetailToken | undefined;\n cssVar: string;\n activeTheme: string;\n activeAxes: Record<string, string>;\n axes: readonly Axis[];\n resolved: Record<string, DetailToken>;\n cssVarPrefix: string;\n varianceByPath: VirtualVarianceByPathShape;\n /**\n * Pure-function accessor that composes the resolved tokens for any\n * tuple of axis selections — used by the `AxisVariance` grid to\n * read per-cell values without indexing `permutationsResolved` by\n * a derived tuple name.\n */\n resolveAt: (tuple: Record<string, string>) => Record<string, DetailToken>;\n}\n\nexport function useTokenDetailData(path: string): TokenDetailData {\n const project = useProject();\n const { activeTheme, activeAxes, axes, resolved, cssVarPrefix, varianceByPath, resolveAt } =\n project;\n const typedResolved = resolved as Record<string, DetailToken>;\n return {\n token: typedResolved[path],\n cssVar: resolveCssVar(path, project),\n activeTheme,\n activeAxes,\n axes,\n resolved: typedResolved,\n cssVarPrefix,\n varianceByPath,\n resolveAt: resolveAt as (tuple: Record<string, string>) => Record<string, DetailToken>,\n };\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface AliasChainProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function AliasChain({ path }: AliasChainProps): ReactElement | null {\n const { token } = useTokenDetailData(path);\n\n const chain = useMemo<string[]>(() => {\n if (!token) return [];\n if (Array.isArray(token.aliasChain) && token.aliasChain.length > 0) {\n return [path, ...token.aliasChain];\n }\n if (typeof token.aliasOf === 'string') return [path, token.aliasOf];\n return [path];\n }, [token, path]);\n\n if (chain.length <= 1) return null;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Alias chain</div>\n <div className=\"sb-token-detail__chain\">\n {chain.map((step, i) => (\n <span key={step} className=\"sb-token-detail__chain\">\n <span className=\"sb-token-detail__chain-node\">{step}</span>\n {i < chain.length - 1 && <span className=\"sb-token-detail__arrow\">→</span>}\n </span>\n ))}\n </div>\n </>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface AliasedByProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nconst ALIASED_BY_DEPTH_CAP = 6;\n\ninterface AliasedByNode {\n path: string;\n children: AliasedByNode[];\n truncated?: boolean;\n}\n\nconst GROUP_RANK: Record<string, number> = { ref: 0, sys: 1 };\n\nexport function AliasedBy({ path }: AliasedByProps): ReactElement | null {\n const { resolved } = useTokenDetailData(path);\n const tree = useMemo<AliasedByNode[]>(() => buildAliasedByTree(path, resolved), [path, resolved]);\n const truncated = useMemo(() => treeHasTruncation(tree), [tree]);\n\n if (tree.length === 0) return null;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Aliased by</div>\n <ul className=\"sb-token-detail__aliased-by-list\">\n {tree.map((node) => (\n <AliasedByRow key={node.path} node={node} depth={0} />\n ))}\n </ul>\n {truncated && (\n <div className=\"sb-token-detail__aliased-by-truncated\">\n Further descendants truncated at depth {ALIASED_BY_DEPTH_CAP}.\n </div>\n )}\n </>\n );\n}\n\nfunction AliasedByRow({ node, depth }: { node: AliasedByNode; depth: number }): ReactElement {\n return (\n <li>\n <div className=\"sb-token-detail__aliased-by-row\" style={{ paddingLeft: depth * 16 }}>\n <span className=\"sb-token-detail__chain-node\">{node.path}</span>\n </div>\n {node.children.length > 0 && (\n <ul className=\"sb-token-detail__aliased-by-list\">\n {node.children.map((child) => (\n <AliasedByRow key={child.path} node={child} depth={depth + 1} />\n ))}\n </ul>\n )}\n </li>\n );\n}\n\nexport function buildAliasedByTree(\n rootPath: string,\n resolved: Record<string, DetailToken>,\n): AliasedByNode[] {\n const root = resolved[rootPath];\n const direct = root?.aliasedBy;\n if (!direct || direct.length === 0) return [];\n return sortPaths(direct).map((p) => walk(p, resolved, new Set<string>([rootPath]), 1));\n}\n\n// `ancestors` is the current root-to-here path only (copied per descent),\n// not a tree-wide visited set: that guards genuine cycles without hiding a\n// node that legitimately appears under two sibling branches of a diamond\n// alias graph (a shared set let the first branch claim the node and\n// truncate every later one).\nfunction walk(\n path: string,\n resolved: Record<string, DetailToken>,\n ancestors: ReadonlySet<string>,\n depth: number,\n): AliasedByNode {\n if (ancestors.has(path)) return { path, children: [] };\n const token = resolved[path];\n const parents = token?.aliasedBy;\n if (!parents || parents.length === 0) return { path, children: [] };\n if (depth >= ALIASED_BY_DEPTH_CAP) {\n return { path, children: [], truncated: true };\n }\n const childAncestors = new Set(ancestors).add(path);\n const children = sortPaths(parents).map((p) => walk(p, resolved, childAncestors, depth + 1));\n return { path, children };\n}\n\nfunction sortPaths(paths: readonly string[]): string[] {\n return paths.toSorted((a, b) => {\n const ra = GROUP_RANK[a.split('.')[0] ?? ''] ?? 2;\n const rb = GROUP_RANK[b.split('.')[0] ?? ''] ?? 2;\n return ra !== rb ? ra - rb : a.localeCompare(b, undefined, { numeric: true });\n });\n}\n\nfunction treeHasTruncation(nodes: AliasedByNode[]): boolean {\n for (const n of nodes) {\n if (n.truncated) return true;\n if (treeHasTruncation(n.children)) return true;\n }\n return false;\n}\n","import type { Axis } from '@unpunnyfuns/swatchbook-core';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { perAxisAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface AxisVarianceProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\ntype Variance =\n | { kind: 'constant' }\n | { kind: 'one-axis'; axis: string; varyingAxes: readonly [string] }\n | { kind: 'multi-axis'; varyingAxes: readonly [string, string, ...string[]] };\n\nexport function AxisVariance({ path }: AxisVarianceProps): ReactElement {\n const { token, cssVar, axes, activeAxes, cssVarPrefix, varianceByPath, resolveAt } =\n useTokenDetailData(path);\n const colorFormat = useColorFormat();\n const tokenType = token?.$type;\n const isColor = tokenType === 'color';\n const formatFn = (t: DetailToken | undefined): string => valueFor(t, tokenType, colorFormat);\n\n const variance = useMemo<Variance>(() => {\n // Read the pre-computed per-path variance from the snapshot. The\n // server side runs the bucket analysis once at load and ships the\n // map over the wire — O(1) lookup per render instead of an O(paths\n // × permutations) re-derivation here.\n const result = varianceByPath[path];\n if (!result) return { kind: 'constant' };\n switch (result.kind) {\n case 'constant':\n return { kind: 'constant' };\n case 'single':\n return { kind: 'one-axis', axis: result.axis, varyingAxes: result.varyingAxes };\n case 'multi':\n return { kind: 'multi-axis', varyingAxes: result.varyingAxes };\n default: {\n const exhaustive: never = result;\n throw new Error(`unhandled AxisVarianceResult kind: ${JSON.stringify(exhaustive)}`);\n }\n }\n }, [path, varianceByPath]);\n\n if (axes.length === 0) {\n return <></>;\n }\n\n if (variance.kind === 'constant') {\n const value = formatFn(resolveAt(activeAxes)[path] as DetailToken | undefined);\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Values across axes</div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <tbody>\n <tr className=\"sb-token-detail__theme-row\">\n <td className=\"sb-token-detail__theme-cell\" data-testid=\"token-detail-constant\">\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n aria-hidden\n />\n )}\n {value}\n <span style={{ opacity: 0.6, marginLeft: 8 }}>same across every axis</span>\n </td>\n </tr>\n </tbody>\n </table>\n </>\n );\n }\n\n if (variance.kind === 'one-axis') {\n const axisName = variance.axis;\n const axis = axes.find((a) => a.name === axisName);\n if (!axis) return <></>;\n const contextValues = axis.contexts.map((ctx) => {\n const target = { ...activeAxes, [axisName]: ctx };\n return {\n ctx,\n target,\n value: formatFn(resolveAt(target)[path] as DetailToken | undefined),\n };\n });\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Varies with {axisName}</div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <tbody>\n {contextValues.map((row) => (\n <tr\n key={row.ctx}\n className=\"sb-token-detail__theme-row\"\n data-axis={axisName}\n data-context={row.ctx}\n >\n <td className=\"sb-token-detail__theme-cell\" style={{ width: '30%' }}>\n {row.ctx}\n </td>\n <td className=\"sb-token-detail__theme-cell\">\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n {...perAxisAttrs(cssVarPrefix, row.target)}\n aria-hidden\n />\n )}\n {row.value}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </>\n );\n }\n\n const varying = variance.varyingAxes\n .map((name) => axes.find((a) => a.name === name))\n .filter((a): a is Axis => Boolean(a))\n .toSorted((a, b) => b.contexts.length - a.contexts.length);\n const [rowAxis, colAxis, ...extra] = varying;\n if (!rowAxis || !colAxis) return <></>;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">\n Varies with {variance.varyingAxes.join(' × ')}\n </div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <thead>\n <tr className=\"sb-token-detail__theme-row\">\n <th className=\"sb-token-detail__theme-cell\" style={{ textAlign: 'left', opacity: 0.7 }}>\n {rowAxis.name} \\ {colAxis.name}\n </th>\n {colAxis.contexts.map((col) => (\n <th\n key={col}\n className=\"sb-token-detail__theme-cell\"\n style={{ textAlign: 'left', opacity: 0.7 }}\n >\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rowAxis.contexts.map((row) => (\n <tr key={row} className=\"sb-token-detail__theme-row\">\n <td className=\"sb-token-detail__theme-cell\">{row}</td>\n {colAxis.contexts.map((col) => {\n const target: Record<string, string> = {\n ...activeAxes,\n [rowAxis.name]: row,\n [colAxis.name]: col,\n };\n const value = formatFn(resolveAt(target)[path] as DetailToken | undefined);\n return (\n <td\n key={col}\n className=\"sb-token-detail__theme-cell\"\n data-row={row}\n data-col={col}\n >\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n {...perAxisAttrs(cssVarPrefix, target)}\n aria-hidden\n />\n )}\n {value}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {extra.length > 0 && (\n <div className=\"sb-token-detail__aliased-by-truncated\" style={{ marginTop: 6 }}>\n Values also vary with {extra.map((a) => a.name).join(', ')}; matrix shows the slice for\n the active selection.\n </div>\n )}\n </>\n );\n}\n\nfunction valueFor(\n token: DetailToken | undefined,\n $type: string | undefined,\n format: ColorFormat,\n): string {\n if (!token) return '—';\n return formatTokenValue(token.$value, $type, format);\n}\n","import type { ReactElement } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport type {\n BorderValue,\n GradientStop,\n ShadowLayer,\n TransitionValue,\n TypographyValue,\n} from '#/internal/composite-types.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface CompositeBreakdownProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function CompositeBreakdown({ path }: CompositeBreakdownProps): ReactElement | null {\n const { token, resolved } = useTokenDetailData(path);\n const colorFormat = useColorFormat();\n if (!token) return null;\n return (\n <CompositeBreakdownContent\n type={token.$type}\n rawValue={token.$value}\n partialAliasOf={token.partialAliasOf}\n resolved={resolved}\n colorFormat={colorFormat}\n />\n );\n}\n\nexport function CompositeBreakdownContent({\n type,\n rawValue,\n partialAliasOf,\n resolved,\n colorFormat,\n}: {\n type: string | undefined;\n rawValue: unknown;\n partialAliasOf?: unknown;\n resolved?: Record<string, DetailToken>;\n colorFormat: ColorFormat;\n}): ReactElement | null {\n if (!rawValue || typeof rawValue !== 'object') return null;\n\n const objectAliases = pickObjectAliases(partialAliasOf);\n const arrayAliases = pickArrayAliases(partialAliasOf);\n const aliasFor = (key: string): readonly string[] | undefined =>\n subValueChain(objectAliases?.[key], resolved);\n\n if (type === 'typography') {\n const v = rawValue as TypographyValue;\n return renderKeyValueList([\n ['fontFamily', formatFontFamily(v.fontFamily), aliasFor('fontFamily')],\n ['fontSize', formatDimensionValue(v.fontSize), aliasFor('fontSize')],\n ['fontWeight', formatPrimitive(v.fontWeight), aliasFor('fontWeight')],\n ['lineHeight', formatPrimitive(v.lineHeight), aliasFor('lineHeight')],\n ['letterSpacing', formatDimensionValue(v.letterSpacing), aliasFor('letterSpacing')],\n ]);\n }\n\n if (type === 'border') {\n const v = rawValue as BorderValue;\n return renderKeyValueList([\n ['color', formatColorSubValue(v.color, colorFormat), aliasFor('color')],\n ['width', formatDimensionValue(v.width), aliasFor('width')],\n ['style', formatPrimitive(v.style), aliasFor('style')],\n ]);\n }\n\n if (type === 'transition') {\n const v = rawValue as TransitionValue;\n return renderKeyValueList([\n ['duration', formatDimensionValue(v.duration), aliasFor('duration')],\n ['timingFunction', formatPrimitive(v.timingFunction), aliasFor('timingFunction')],\n ['delay', formatDimensionValue(v.delay), aliasFor('delay')],\n ]);\n }\n\n if (type === 'shadow') {\n const layers = Array.isArray(rawValue) ? rawValue : [rawValue];\n const multi = layers.length > 1;\n const layerAliasFor = (i: number, key: string): readonly string[] | undefined =>\n subValueChain(arrayAliases?.[i]?.[key], resolved);\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {layers.map((layer, i) => {\n const v = layer as ShadowLayer;\n return (\n <div key={shadowLayerKey(v, i)} style={{ display: 'contents' }}>\n {multi && (\n <div className=\"sb-token-detail__breakdown-layer-header\">Layer {i + 1}</div>\n )}\n <KeyValueRow\n label=\"color\"\n value={formatColorSubValue(v.color, colorFormat)}\n alias={layerAliasFor(i, 'color')}\n />\n <KeyValueRow\n label=\"offsetX\"\n value={formatDimensionValue(v.offsetX)}\n alias={layerAliasFor(i, 'offsetX')}\n />\n <KeyValueRow\n label=\"offsetY\"\n value={formatDimensionValue(v.offsetY)}\n alias={layerAliasFor(i, 'offsetY')}\n />\n <KeyValueRow\n label=\"blur\"\n value={formatDimensionValue(v.blur)}\n alias={layerAliasFor(i, 'blur')}\n />\n <KeyValueRow\n label=\"spread\"\n value={formatDimensionValue(v.spread)}\n alias={layerAliasFor(i, 'spread')}\n />\n {v.inset !== undefined && (\n <KeyValueRow label=\"inset\" value={formatPrimitive(v.inset)} alias={undefined} />\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n if (type === 'gradient') {\n const stops = Array.isArray(rawValue) ? rawValue : [];\n if (stops.length === 0) return null;\n const stopAliasFor = (i: number): readonly string[] | undefined =>\n subValueChain(arrayAliases?.[i]?.['color'], resolved);\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {stops.map((stop, i) => {\n const v = stop as GradientStop;\n const position = typeof v.position === 'number' ? v.position : 0;\n return (\n <KeyValueRow\n key={gradientStopKey(v, i)}\n label={`${(position * 100).toFixed(0)}%`}\n value={formatColorSubValue(v.color, colorFormat)}\n alias={stopAliasFor(i)}\n />\n );\n })}\n </div>\n );\n }\n\n return null;\n}\n\nfunction renderKeyValueList(\n rows: [string, string | null, readonly string[] | undefined][],\n): ReactElement {\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {rows\n .filter(([, v, alias]) => v !== null || (alias && alias.length > 0))\n .map(([k, v, alias]) => (\n <KeyValueRow key={k} label={k} value={v ?? ''} alias={alias} />\n ))}\n </div>\n );\n}\n\nfunction KeyValueRow({\n label,\n value,\n alias,\n}: {\n label: string;\n value: string | null;\n alias: readonly string[] | undefined;\n}): ReactElement {\n const hasAlias = alias && alias.length > 0;\n return (\n <>\n <span className=\"sb-token-detail__breakdown-key\">{label}</span>\n <span className=\"sb-token-detail__breakdown-value\">\n <span>{value ?? '—'}</span>\n {hasAlias && (\n <span className=\"sb-token-detail__breakdown-alias\" data-testid=\"breakdown-alias\">\n {alias.map((p, i) => (\n <span key={p} className=\"sb-token-detail__breakdown-alias-step\">\n {i > 0 && <span className=\"sb-token-detail__arrow\">→</span>}\n <span className=\"sb-token-detail__chain-node\">{p}</span>\n </span>\n ))}\n </span>\n )}\n </span>\n </>\n );\n}\n\nfunction formatPrimitive(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n return JSON.stringify(v);\n}\n\nfunction formatFontFamily(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n return JSON.stringify(v);\n}\n\nfunction formatDimensionValue(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string' || typeof v === 'number') return String(v);\n if (typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number' && typeof d.unit === 'string') return `${d.value}${d.unit}`;\n }\n return JSON.stringify(v);\n}\n\n// Route sub-value colors through `formatColor` so they honor the active\n// color-format dropdown, just like the standalone `<ColorPalette />` and\n// `<TokenDetail />` top-line do. Returns `null` for a missing field so\n// the key/value row drops out entirely.\nfunction formatColorSubValue(v: unknown, format: ColorFormat): string | null {\n if (v == null) return null;\n return formatColor(v, format).value;\n}\n\nfunction pickObjectAliases(v: unknown): Record<string, string | undefined> | undefined {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return undefined;\n return v as Record<string, string | undefined>;\n}\n\nfunction pickArrayAliases(v: unknown): Record<string, string | undefined>[] | undefined {\n if (!Array.isArray(v)) return undefined;\n return v as Record<string, string | undefined>[];\n}\n\n// Walk the alias chain starting from an immediate sub-value alias target.\n// `aliasTarget` is the path the sub-value directly references; the target\n// token's own `aliasChain` continues the walk to the primitive.\nfunction subValueChain(\n aliasTarget: string | undefined,\n resolved: Record<string, DetailToken> | undefined,\n): readonly string[] | undefined {\n if (!aliasTarget) return undefined;\n const tok = resolved?.[aliasTarget];\n const tail = tok?.aliasChain;\n return tail && tail.length > 0 ? [aliasTarget, ...tail] : [aliasTarget];\n}\n\nfunction shadowLayerKey(layer: ShadowLayer, fallback: number): string {\n const parts = [\n layer.color,\n layer.offsetX,\n layer.offsetY,\n layer.blur,\n layer.spread,\n layer.inset,\n ].map((p) => (p === undefined ? '' : JSON.stringify(p)));\n return `shadow|${parts.join('|')}|${fallback}`;\n}\n\nfunction gradientStopKey(stop: GradientStop, fallback: number): string {\n return `stop|${stop.position ?? fallback}|${JSON.stringify(stop.color)}`;\n}\n","/**\n * Numeric duration (ms) the motion preview should animate over for a given\n * token type, read from its resolved `$value`. Lets the sample's toggle loop\n * match the token's real duration instead of a fixed cadence — a long token\n * (say 2s) otherwise reverses mid-move under the old hardcoded interval.\n * Returns `undefined` for types that carry no duration, so the caller can\n * fall back to its default.\n */\nexport function transitionDurationMs(\n type: string | undefined,\n rawValue: unknown,\n): number | undefined {\n // The cubicBezier sample animates `left 800ms <bezier>`, so its loop is fixed.\n if (type === 'cubicBezier') return 800;\n if (type === 'duration') return parseDurationMs(rawValue);\n if (type === 'transition' && rawValue !== null && typeof rawValue === 'object') {\n return parseDurationMs((rawValue as { duration?: unknown }).duration);\n }\n return undefined;\n}\n\n// Parse a DTCG duration (`{ value, unit }`), a CSS string (`300ms` / `1.5s`),\n// or a bare number (treated as ms) into milliseconds.\nfunction parseDurationMs(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') {\n const m = /^([\\d.]+)(ms|s)?$/.exec(v.trim());\n if (!m?.[1]) return undefined;\n const n = Number(m[1]);\n if (Number.isNaN(n)) return undefined;\n return m[2] === 's' ? n * 1000 : n;\n }\n if (v !== null && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number') return d.unit === 's' ? d.value * 1000 : d.value;\n }\n return undefined;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useEffect, useState } from 'react';\nimport { cssVarAsNumber } from '#/internal/css-var-style.ts';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport { transitionDurationMs } from '#/token-detail/transition-duration.ts';\n\nexport interface CompositePreviewProps {\n /** Full dot-path of the token to preview. */\n path: string;\n}\n\nconst PANGRAM = 'Sphinx of black quartz, judge my vow.';\n\nconst STROKE_STYLE_STRINGS = new Set([\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n 'inset',\n]);\n\nexport function CompositePreview({ path }: CompositePreviewProps): ReactElement | null {\n const { token, cssVar } = useTokenDetailData(path);\n if (!token) return null;\n return <CompositePreviewContent type={token.$type} cssVar={cssVar} rawValue={token.$value} />;\n}\n\nexport function CompositePreviewContent({\n type,\n cssVar,\n rawValue,\n}: {\n type: string | undefined;\n cssVar: string;\n rawValue: unknown;\n}): ReactElement | null {\n if (type === 'typography') {\n const base = cssVar.replace(/^var\\(/, '').replace(/\\)$/, '');\n return (\n <div\n className=\"sb-token-detail__typography-sample\"\n style={{\n fontFamily: `var(${base}-font-family)`,\n fontSize: `var(${base}-font-size)`,\n fontWeight: cssVarAsNumber(`var(${base}-font-weight)`),\n lineHeight: cssVarAsNumber(`var(${base}-line-height)`),\n letterSpacing: `var(${base}-letter-spacing)`,\n }}\n >\n {PANGRAM}\n </div>\n );\n }\n if (type === 'shadow') {\n return (\n <div className=\"sb-token-detail__shadow-sample\" style={{ boxShadow: cssVar }} aria-hidden />\n );\n }\n if (type === 'border') {\n return (\n <div className=\"sb-token-detail__border-sample\" style={{ border: cssVar }} aria-hidden />\n );\n }\n if (type === 'transition') {\n return (\n <TransitionSample transition={cssVar} durationMs={transitionDurationMs(type, rawValue)} />\n );\n }\n if (type === 'dimension') {\n return (\n <div className=\"sb-token-detail__dimension-track\">\n <div className=\"sb-token-detail__dimension-bar\" style={{ width: cssVar }} aria-hidden />\n </div>\n );\n }\n if (type === 'duration') {\n return (\n <TransitionSample\n transition={`left ${cssVar} ease`}\n durationMs={transitionDurationMs(type, rawValue)}\n />\n );\n }\n if (type === 'fontFamily') {\n return (\n <div className=\"sb-token-detail__font-family-sample\" style={{ fontFamily: cssVar }}>\n {PANGRAM}\n </div>\n );\n }\n if (type === 'fontWeight') {\n return (\n <div\n className=\"sb-token-detail__font-weight-sample\"\n style={{ fontWeight: cssVarAsNumber(cssVar) }}\n >\n Aa\n </div>\n );\n }\n if (type === 'cubicBezier') {\n return (\n <TransitionSample\n transition={`left 800ms ${cssVar}`}\n durationMs={transitionDurationMs(type, rawValue)}\n />\n );\n }\n if (type === 'gradient') {\n return (\n <div\n className=\"sb-token-detail__gradient-sample\"\n style={{ background: `linear-gradient(to right, ${cssVar})` }}\n aria-hidden\n />\n );\n }\n if (type === 'strokeStyle') {\n return <StrokeStylePreview value={rawValue} />;\n }\n if (type === 'color') {\n return (\n <div className=\"sb-token-detail__color-swatch-row\" aria-hidden>\n <div className=\"sb-token-detail__color-swatch-light\" style={{ background: cssVar }} />\n <div className=\"sb-token-detail__color-swatch-dark\" style={{ background: cssVar }} />\n </div>\n );\n }\n return null;\n}\n\nfunction StrokeStylePreview({ value }: { value: unknown }): ReactElement {\n if (typeof value === 'string' && STROKE_STYLE_STRINGS.has(value)) {\n return (\n <div\n className=\"sb-token-detail__stroke-style-line\"\n style={{ borderTopStyle: value as CSSProperties['borderTopStyle'] }}\n aria-hidden\n />\n );\n }\n if (value && typeof value === 'object' && 'dashArray' in value) {\n const v = value as {\n dashArray?: unknown;\n lineCap?: unknown;\n };\n const lengths = asDashLengths(v.dashArray);\n if (lengths.length === 0) {\n return (\n <div className=\"sb-token-detail__stroke-style-fallback\">\n Object-form strokeStyle with no resolvable dashArray.\n </div>\n );\n }\n const cap = typeof v.lineCap === 'string' ? v.lineCap : 'butt';\n return (\n <svg\n className=\"sb-token-detail__stroke-style-svg\"\n viewBox=\"0 0 220 24\"\n preserveAspectRatio=\"none\"\n aria-hidden\n >\n <line\n x1=\"4\"\n y1=\"12\"\n x2=\"216\"\n y2=\"12\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeDasharray={lengths.join(' ')}\n strokeLinecap={cap as 'butt' | 'round' | 'square'}\n />\n </svg>\n );\n }\n return (\n <div className=\"sb-token-detail__stroke-style-fallback\">\n strokeStyle value could not be previewed.\n </div>\n );\n}\n\nfunction asDashLengths(raw: unknown): number[] {\n if (!Array.isArray(raw)) return [];\n const out: number[] = [];\n for (const entry of raw) {\n if (typeof entry === 'number') {\n out.push(entry);\n continue;\n }\n if (entry && typeof entry === 'object') {\n const e = entry as { value?: unknown };\n if (typeof e.value === 'number') out.push(e.value);\n }\n }\n return out;\n}\n\n// Toggle cadence when the token carries no readable duration.\nconst DEFAULT_LOOP_MS = 1200;\n// Rest at each end so the eye registers the position before the ball returns;\n// added on top of the move duration so each leg fully completes first.\nconst MOTION_HOLD_MS = 400;\n\nfunction TransitionSample({\n transition,\n durationMs,\n}: {\n transition: string;\n durationMs?: number | undefined;\n}): ReactElement {\n const reduced = usePrefersReducedMotion();\n const [phase, setPhase] = useState<0 | 1>(0);\n\n useEffect(() => {\n if (reduced) return;\n // Match the loop to the token's real duration; a long token otherwise\n // reversed mid-move under the old fixed 1200ms interval.\n const loopMs = durationMs === undefined ? DEFAULT_LOOP_MS : durationMs + MOTION_HOLD_MS;\n const id = requestAnimationFrame(() => setPhase(1));\n const loop = window.setInterval(() => {\n setPhase((p) => (p === 0 ? 1 : 0));\n }, loopMs);\n return () => {\n cancelAnimationFrame(id);\n window.clearInterval(loop);\n };\n }, [reduced, durationMs]);\n\n if (reduced) {\n return (\n <div className=\"sb-token-detail__reduced-motion\">\n Animation suppressed by `prefers-reduced-motion: reduce`.\n </div>\n );\n }\n\n return (\n <div className=\"sb-token-detail__motion-track\">\n <div\n className=\"sb-token-detail__motion-ball\"\n style={{\n left: phase === 1 ? 'calc(100% - 28px)' : '4px',\n transition,\n }}\n aria-hidden\n />\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { useProject } from '#/internal/use-project.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface ConsumerOutputProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function ConsumerOutput({ path }: ConsumerOutputProps): ReactElement | null {\n const { token, cssVar, activeAxes } = useTokenDetailData(path);\n const { listing } = useProject();\n\n if (!token) return null;\n\n const tupleLabel = Object.entries(activeAxes)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n\n // Platforms beyond `css`. Populated only when the consumer has loaded\n // extra plugins (`@terrazzo/plugin-swift`, `-android`, `-sass`, …) via\n // `config.terrazzoPlugins` + `config.listingOptions.platforms`. Always\n // empty otherwise — the row set falls back to Path + CSS.\n const names = listing[path]?.names ?? {};\n const extraPlatforms = Object.keys(names)\n .filter((platform) => platform !== 'css' && names[platform])\n .toSorted();\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Consumer output</div>\n {tupleLabel && (\n <div className=\"sb-token-detail__tuple-indicator\">\n Active tuple: <strong>{tupleLabel}</strong>\n </div>\n )}\n <OutputRow label=\"Path\" value={path} testId=\"consumer-output-path\" />\n <OutputRow label=\"CSS\" value={cssVar} testId=\"consumer-output-css\" />\n {extraPlatforms.map((platform) => (\n <OutputRow\n key={platform}\n label={formatPlatformLabel(platform)}\n value={names[platform]!}\n testId={`consumer-output-${platform}`}\n />\n ))}\n </>\n );\n}\n\nfunction formatPlatformLabel(platform: string): string {\n if (platform.length === 0) return platform;\n return platform[0]!.toUpperCase() + platform.slice(1);\n}\n\ninterface OutputRowProps {\n label: string;\n value: string;\n testId: string;\n}\n\nfunction OutputRow({ label, value, testId }: OutputRowProps): ReactElement {\n return (\n <div className=\"sb-token-detail__consumer-row\">\n <span className=\"sb-token-detail__consumer-row-label\">{label}</span>\n <code className=\"sb-token-detail__consumer-row-value\" data-testid={testId}>\n {value}\n </code>\n <CopyButton text={value} testId={`${testId}-copy`} />\n </div>\n );\n}\n\nfunction CopyButton({ text, testId }: { text: string; testId: string }): ReactElement {\n const [copied, setCopied] = useState(false);\n return (\n <button\n type=\"button\"\n className=\"sb-token-detail__consumer-row-copy\"\n data-testid={testId}\n onClick={() => {\n void copyToClipboard(text).then((ok) => {\n if (!ok) return;\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1200);\n });\n }}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n );\n}\n\nasync function copyToClipboard(text: string): Promise<boolean> {\n if (typeof navigator === 'undefined' || !navigator.clipboard) return false;\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n","import type { ReactElement } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface TokenHeaderProps {\n /** Full dot-path of the token. */\n path: string;\n /** Override the heading. Defaults to the path. */\n heading?: string;\n}\n\nexport function TokenHeader({ path, heading }: TokenHeaderProps): ReactElement {\n const { token, cssVar, activeTheme } = useTokenDetailData(path);\n\n if (!token) {\n return (\n <div className=\"sb-token-detail__missing\">\n Token <code>{path}</code> not found in theme <strong>{activeTheme}</strong>.\n </div>\n );\n }\n\n return (\n <>\n <h3 className=\"sb-token-detail__heading\">{heading ?? path}</h3>\n <div className=\"sb-token-detail__subline\">\n {token.$type && <span className=\"sb-token-detail__type-pill\">{token.$type}</span>}\n <span>{cssVar}</span>\n </div>\n {token.$description && <p className=\"sb-token-detail__description\">{token.$description}</p>}\n </>\n );\n}\n","import type { ReactElement } from 'react';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface TokenUsageSnippetProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\n// DTCG `$type`s with a single canonical CSS property. Types whose value is\n// applied across many properties (`dimension`, `number`, `strokeStyle`,\n// `typography`) are intentionally absent — they fall back to a commented hint.\nconst CSS_PROPERTY_BY_TYPE: Record<string, string> = {\n color: 'color',\n shadow: 'box-shadow',\n border: 'border',\n fontFamily: 'font-family',\n fontWeight: 'font-weight',\n duration: 'transition-duration',\n cubicBezier: 'transition-timing-function',\n gradient: 'background',\n transition: 'transition',\n};\n\nfunction usageSnippet(cssVar: string, type: string | undefined): string {\n const property = type ? CSS_PROPERTY_BY_TYPE[type] : undefined;\n if (property) return `${property}: ${cssVar};`;\n if (type) return `/* ${type} */ ${cssVar};`;\n return `${cssVar};`;\n}\n\nexport function TokenUsageSnippet({ path }: TokenUsageSnippetProps): ReactElement | null {\n const { token, cssVar } = useTokenDetailData(path);\n if (!token) return null;\n const snippet = usageSnippet(cssVar, token.$type);\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Usage</div>\n <div className=\"sb-token-detail__snippet-row\">\n <code className=\"sb-token-detail__snippet\">{snippet}</code>\n <CopyButton value={snippet} label={`Copy usage snippet ${snippet}`} />\n </div>\n </>\n );\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport { AliasChain } from '#/token-detail/AliasChain.tsx';\nimport { AliasedBy } from '#/token-detail/AliasedBy.tsx';\nimport { AxisVariance } from '#/token-detail/AxisVariance.tsx';\nimport { CompositeBreakdown } from '#/token-detail/CompositeBreakdown.tsx';\nimport { CompositePreview } from '#/token-detail/CompositePreview.tsx';\nimport { ConsumerOutput } from '#/token-detail/ConsumerOutput.tsx';\nimport { TokenHeader } from '#/token-detail/TokenHeader.tsx';\nimport { TokenUsageSnippet } from '#/token-detail/TokenUsageSnippet.tsx';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport '#/token-detail/styles.css';\n\nexport interface TokenDetailProps {\n /** Full dot-path of the token to inspect. */\n path: string;\n /** Override the heading. Defaults to the path. */\n heading?: string;\n}\n\nexport function TokenDetail({ path, heading }: TokenDetailProps): ReactElement {\n const { token, cssVar, activeTheme, activeAxes, cssVarPrefix } = useTokenDetailData(path);\n const colorFormat = useColorFormat();\n const { listing } = useProject();\n const wrapperAttrs = blockWrapperAttrs(cssVarPrefix, activeAxes);\n\n if (!token) {\n return (\n <div {...wrapperAttrs} className={cx(wrapperAttrs['className'], 'sb-token-detail')}>\n <div className=\"sb-token-detail__missing\">\n Token <code>{path}</code> not found in theme <strong>{activeTheme}</strong>.\n </div>\n </div>\n );\n }\n\n const isColor = token.$type === 'color';\n const gamut = isColor ? formatColor(token.$value, colorFormat) : null;\n const value = formatTokenValue(token.$value, token.$type, colorFormat, listing[path]);\n const outOfGamut = gamut?.outOfGamut ?? false;\n const dep = token.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n\n return (\n <div {...wrapperAttrs} className={cx(wrapperAttrs['className'], 'sb-token-detail')}>\n <TokenHeader path={path} {...(heading !== undefined && { heading })} />\n {isDeprecated && (\n <div\n className=\"sb-token-detail__deprecated\"\n data-testid=\"token-detail-deprecated\"\n role=\"note\"\n >\n <span aria-hidden>⚠ </span>\n Deprecated{typeof dep === 'string' ? `: ${dep}` : ''}\n </div>\n )}\n\n <div className=\"sb-token-detail__section-header\">Resolved value · {activeTheme}</div>\n <CompositePreview path={path} />\n <CompositeBreakdown path={path} />\n <div className=\"sb-token-detail__chain\">\n {isColor && (\n <span className=\"sb-token-detail__swatch\" style={{ background: cssVar }} aria-hidden />\n )}\n <span>{value}</span>\n {outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n style={{ marginLeft: 6 }}\n >\n ⚠\n </span>\n )}\n <CopyButton value={value} label={`Copy value ${value}`} />\n </div>\n\n <AliasChain path={path} />\n <AliasedBy path={path} />\n <TokenUsageSnippet path={path} />\n <ConsumerOutput path={path} />\n <AxisVariance path={path} />\n </div>\n );\n}\n","import type { KeyboardEvent as ReactKeyboardEvent, ReactElement } from 'react';\nimport { useEffect, useRef } from 'react';\nimport './DetailOverlay.css';\nimport { TokenDetail } from '#/TokenDetail.tsx';\n\n/**\n * Slide-over that wraps `<TokenDetail>`. Shared between `<TokenNavigator />`\n * and `<TokenTable />` so both land on the same opener and the same styling.\n *\n * Dismisses on backdrop click, Escape, and the close button. Implements the\n * WAI-ARIA dialog pattern's focus management: on mount, focus moves into the\n * panel; Tab is trapped so it cycles through the panel's interactive\n * descendants only; on unmount, focus restores to whatever opened the\n * overlay (typically the row / treeitem the user clicked).\n */\n\nexport interface DetailOverlayProps {\n path: string;\n onClose(): void;\n testId?: string;\n}\n\n// Selector for elements the trap considers focus stops. Mirrors the\n// \"tabbable\" set most focus-trap libraries use; the `:not(...)` clauses\n// skip the panel wrapper itself (we focus it manually on mount via its\n// own ref) and any explicitly-detabbed descendants.\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ');\n\nexport function DetailOverlay({\n path,\n onClose,\n testId = 'swatchbook-overlay',\n}: DetailOverlayProps): ReactElement {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const openerRef = useRef<HTMLElement | null>(null);\n\n // Set up focus management + sibling inerting in one effect so the\n // teardown ordering is explicit: un-inert siblings BEFORE restoring\n // focus to the opener (`.focus()` is a no-op on an inert element).\n //\n // `aria-modal=\"true\"` alone is widely known to be insufficient —\n // VoiceOver + NVDA virtual cursor + swipe gestures still pierce the\n // dialog and read sibling content behind the backdrop. Marking every\n // other top-level body branch `inert` while the overlay is mounted\n // closes that gap.\n useEffect(() => {\n const panel = panelRef.current;\n if (!panel) return;\n openerRef.current =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n panel.focus();\n const overlayBranch = findBodyChildContaining(panel);\n const restorers: (() => void)[] = [];\n if (overlayBranch) {\n for (const sibling of Array.from(document.body.children)) {\n if (sibling === overlayBranch) continue;\n if (!(sibling instanceof HTMLElement)) continue;\n const hadInert = sibling.inert;\n sibling.inert = true;\n restorers.push(() => {\n sibling.inert = hadInert;\n });\n }\n }\n return () => {\n // Un-inert first — focusing an inert element is a no-op.\n for (const restore of restorers) restore();\n openerRef.current?.focus();\n };\n }, []);\n\n // Window-level Escape handler: works whether or not focus is currently\n // inside the panel (e.g. user clicked the backdrop, focus moved away).\n useEffect(() => {\n const onKey = (e: globalThis.KeyboardEvent): void => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Wrap Tab inside the panel: from the last focusable, jump to the first;\n // from the first (or from the panel itself), Shift+Tab jumps to the last.\n // Defers to the browser otherwise.\n const onPanelKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n if (e.key !== 'Tab') return;\n const panel = panelRef.current;\n if (!panel) return;\n const focusables = panel.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);\n if (focusables.length === 0) {\n e.preventDefault();\n return;\n }\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement;\n if (!first || !last) return;\n if (e.shiftKey) {\n if (active === first || active === panel) {\n e.preventDefault();\n last.focus();\n }\n } else if (active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n return (\n <div\n className=\"sb-detail-overlay__backdrop\"\n onClick={onClose}\n role=\"presentation\"\n data-testid={testId}\n >\n <div\n ref={panelRef}\n className=\"sb-detail-overlay__panel\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={onPanelKeyDown}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Token detail for ${path}`}\n tabIndex={-1}\n >\n <button\n type=\"button\"\n className=\"sb-detail-overlay__close\"\n onClick={onClose}\n aria-label=\"Close\"\n data-testid={`${testId}-close`}\n >\n ×\n </button>\n <TokenDetail path={path} />\n </div>\n </div>\n );\n}\n\n// Walk up from `node` to the direct child of `<body>` that contains it.\n// Returns `null` when the node isn't attached to the document (mid-mount,\n// post-unmount). Used to identify which top-level branch to *not* mark\n// inert when the overlay opens.\nfunction findBodyChildContaining(node: HTMLElement): HTMLElement | null {\n let cursor: HTMLElement | null = node;\n while (cursor && cursor.parentElement !== document.body) {\n cursor = cursor.parentElement;\n }\n return cursor;\n}\n","import type { VirtualTokenShape } from '#/contexts.ts';\n\n/**\n * The group paths to expand so `path` becomes visible in the tree — the\n * cumulative dotted prefixes of `path`, excluding `path` itself and any\n * prefix at or above `root` (the navigator's implicit root container is not\n * a group node). Matches `buildTree`'s full-dotted group-path scheme.\n */\nexport function ancestorGroupPaths(path: string, root: string | undefined): string[] {\n const segments = path.split('.');\n const out: string[] = [];\n for (let i = 1; i < segments.length; i += 1) {\n const prefix = segments.slice(0, i).join('.');\n if (root && !prefix.startsWith(`${root}.`)) continue;\n out.push(prefix);\n }\n return out;\n}\n\n/** Context a navigation target is tested against — the active structural filters. */\nexport interface InViewContext {\n resolved: Record<string, VirtualTokenShape>;\n root?: string | undefined;\n typeFilter?: ReadonlySet<string> | undefined;\n}\n\n/**\n * Whether `path` survives the navigator's structural (`root` / `type`)\n * filters and exists in the resolved map — i.e. it can be selected in the\n * current tree. Transient search is NOT considered here: a target hidden\n * only by an active query is still \"in view\" once the query is cleared,\n * which the caller handles.\n */\nexport function isInView(path: string, ctx: InViewContext): boolean {\n const token = ctx.resolved[path];\n if (!token) return false;\n if (ctx.root && !(path === ctx.root || path.startsWith(`${ctx.root}.`))) return false;\n if (ctx.typeFilter && !(token.$type !== undefined && ctx.typeFilter.has(token.$type))) {\n return false;\n }\n return true;\n}\n","/** The individually-toggleable indicators in the row strip. `alias` covers the whole alias unit (forward chain + reverse count). */\nexport type IndicatorName = 'alias' | 'variance' | 'gamut' | 'deprecation' | 'description';\n\n/**\n * Consumer-facing indicator config for the strip-hosting blocks:\n * - `true` — every indicator on (including the opt-in `description`)\n * - `false` — every indicator off\n * - object — per-key override layered over the defaults\n * - omitted — the defaults\n */\nexport type IndicatorsProp = boolean | Partial<Record<IndicatorName, boolean>>;\n\n/** Established-on set; `description` is opt-in. */\nconst DEFAULT_INDICATORS: Record<IndicatorName, boolean> = {\n alias: true,\n variance: true,\n gamut: true,\n deprecation: true,\n description: false,\n};\n\n/** Normalize an `IndicatorsProp` into a full enabled-map by layering over the defaults. */\nexport function resolveIndicators(prop?: IndicatorsProp): Record<IndicatorName, boolean> {\n if (prop === undefined) return { ...DEFAULT_INDICATORS };\n if (prop === true) {\n return { alias: true, variance: true, gamut: true, deprecation: true, description: true };\n }\n if (prop === false) {\n return { alias: false, variance: false, gamut: false, deprecation: false, description: false };\n }\n return { ...DEFAULT_INDICATORS, ...prop };\n}\n","import type { AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactElement } from 'react';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { VirtualTokenShape } from '#/contexts.ts';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorName } from '#/indicators/resolve.ts';\nimport './indicators.css';\n\nexport interface RowIndicatorsProps {\n path: string;\n token: VirtualTokenShape;\n /** Active navigator root prefix, for relative chain-node labels. */\n root: string | undefined;\n /** Per-path variance result for the variance badge. */\n variance: AxisVarianceResult | undefined;\n /** Active color format, for the gamut check (color rows only). */\n colorFormat: ColorFormat;\n /** True when a referenced path can be acted on. */\n canReference: (path: string) => boolean;\n /** Act on a referenced path — the host decides what that means: the navigator moves the tree, the table opens detail. */\n onReferenceClick: (path: string) => void;\n /** Resolved enabled-map (from `resolveIndicators`). Defaults to the established four-on set. */\n enabled?: Record<IndicatorName, boolean>;\n}\n\n// Strip the navigator's `root` prefix from a path for a compact chain label.\nfunction relativeLabel(path: string, root: string | undefined): string {\n if (root && path.startsWith(`${root}.`)) return path.slice(root.length + 1);\n return path;\n}\n\ninterface ForwardChainProps {\n chain: readonly string[];\n root: string | undefined;\n canReference: (path: string) => boolean;\n onReferenceClick: (path: string) => void;\n}\n\n/**\n * The forward alias chain for one row. Full chain in `aria-label`; visually\n * capped to first … last beyond two hops (no width measurement). Each shown\n * node navigates when in view, else renders as plain text.\n */\nfunction ForwardChain({\n chain,\n root,\n canReference,\n onReferenceClick,\n}: ForwardChainProps): ReactElement {\n const full = chain.map((p) => relativeLabel(p, root)).join(' → ');\n const capped = chain.length > 2;\n const shown = capped ? [chain[0] as string, chain[chain.length - 1] as string] : [...chain];\n\n return (\n <span\n className=\"sb-indicator__alias-forward\"\n data-testid=\"row-indicator-alias-forward\"\n aria-label={`aliases ${full}`}\n >\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n →\n </span>\n {shown.map((target, i) => {\n const label = relativeLabel(target, root);\n const node = canReference(target) ? (\n <button\n type=\"button\"\n className=\"sb-indicator__alias-node\"\n data-testid=\"alias-node\"\n aria-label={target}\n onClick={(e) => {\n e.stopPropagation();\n onReferenceClick(target);\n }}\n >\n {label}\n </button>\n ) : (\n <span\n className=\"sb-indicator__alias-node sb-indicator__alias-node--offview\"\n data-testid=\"alias-node\"\n title=\"outside current view\"\n >\n {label}\n </span>\n );\n const sep =\n capped && i === 0 ? (\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n {' '}\n → … →{' '}\n </span>\n ) : i < shown.length - 1 ? (\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n {' '}\n →{' '}\n </span>\n ) : null;\n return (\n <span key={target}>\n {node}\n {sep}\n </span>\n );\n })}\n </span>\n );\n}\n\ninterface DeprecatedBadgeProps {\n deprecated: string | boolean;\n}\n\nfunction DeprecatedBadge({ deprecated }: DeprecatedBadgeProps): ReactElement {\n const label = typeof deprecated === 'string' ? `deprecated: ${deprecated}` : 'deprecated';\n return (\n <span\n className=\"sb-indicator__deprecated\"\n data-testid=\"row-indicator-deprecated\"\n title={label}\n aria-label={label}\n >\n deprecated\n </span>\n );\n}\n\ninterface VarianceBadgeProps {\n variance: AxisVarianceResult;\n}\n\nfunction VarianceBadge({ variance }: VarianceBadgeProps): ReactElement | null {\n if (variance.kind === 'constant') return null;\n const axes = variance.varyingAxes;\n const label = variance.kind === 'single' ? variance.axis : `${axes.length} axes`;\n return (\n <span\n className=\"sb-indicator__variance\"\n data-testid=\"row-indicator-variance\"\n aria-label={`varies by ${axes.join(', ')}`}\n >\n <span className=\"sb-indicator__variance-glyph\" aria-hidden>\n ⊹\n </span>\n {label}\n </span>\n );\n}\n\ninterface ReverseCountProps {\n referents: readonly string[];\n canReference: (path: string) => boolean;\n onReferenceClick: (path: string) => void;\n}\n\nfunction ReverseCount({\n referents,\n canReference,\n onReferenceClick,\n}: ReverseCountProps): ReactElement {\n const [open, setOpen] = useState(false);\n const wrapRef = useRef<HTMLSpanElement>(null);\n const count = referents.length;\n const single = count === 1;\n\n // Move focus to the first enabled menu item on open; close on outside pointerdown.\n useEffect(() => {\n if (single || !open) return;\n const first = wrapRef.current?.querySelector<HTMLElement>(\n 'button[role=\"menuitem\"]:not(:disabled)',\n );\n first?.focus();\n\n const handlePointerDown = (e: PointerEvent) => {\n if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener('pointerdown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n };\n }, [open, single]);\n\n return (\n <span\n ref={wrapRef}\n className=\"sb-indicator__reverse-wrap\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(false);\n }}\n >\n <button\n type=\"button\"\n className=\"sb-indicator__alias-reverse\"\n data-testid=\"row-indicator-alias-reverse\"\n aria-label={`referenced by ${count} ${count === 1 ? 'token' : 'tokens'}`}\n aria-haspopup={single ? undefined : 'menu'}\n aria-expanded={single ? undefined : open}\n onClick={(e) => {\n e.stopPropagation();\n if (single) onReferenceClick(referents[0] as string);\n else setOpen((v) => !v);\n }}\n >\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n ←\n </span>\n {count}\n </button>\n {!single && open && (\n <ul className=\"sb-indicator__reverse-menu\" role=\"menu\">\n {referents.map((ref) => (\n <li key={ref} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"sb-indicator__reverse-item\"\n disabled={!canReference(ref)}\n title={canReference(ref) ? undefined : 'outside current view'}\n onClick={(e) => {\n e.stopPropagation();\n setOpen(false);\n onReferenceClick(ref);\n }}\n >\n {ref}\n </button>\n </li>\n ))}\n </ul>\n )}\n </span>\n );\n}\n\n/** Per-row indicator strip: alias references, variance, gamut, deprecation. */\nexport function RowIndicators(props: RowIndicatorsProps): ReactElement | null {\n const { token, root, variance, colorFormat, canReference, onReferenceClick } = props;\n const en = props.enabled ?? resolveIndicators(undefined);\n\n const aliasChain =\n Array.isArray(token.aliasChain) && token.aliasChain.length > 0 ? token.aliasChain : undefined;\n const reverseCount =\n Array.isArray(token.aliasedBy) && token.aliasedBy.length > 0 ? token.aliasedBy.length : 0;\n const isVarying = variance !== undefined && variance.kind !== 'constant';\n const outOfGamut =\n token.$type === 'color' && (formatColor(token.$value, colorFormat)?.outOfGamut ?? false);\n const deprecated = token.$deprecated;\n const isDeprecated =\n deprecated === true || (typeof deprecated === 'string' && deprecated.length > 0);\n const description =\n typeof token.$description === 'string' && token.$description.length > 0\n ? token.$description\n : undefined;\n\n const showDeprecated = en.deprecation && isDeprecated;\n const showForward = en.alias && aliasChain !== undefined;\n const showReverse = en.alias && reverseCount > 0;\n const showVariance = en.variance && isVarying;\n const showGamut = en.gamut && outOfGamut;\n const showDescription = en.description && description !== undefined;\n\n if (\n !showDeprecated &&\n !showForward &&\n !showReverse &&\n !showVariance &&\n !showGamut &&\n !showDescription\n ) {\n return null;\n }\n\n return (\n <span className=\"sb-indicator__indicators\">\n {showDeprecated && deprecated !== undefined && <DeprecatedBadge deprecated={deprecated} />}\n {showForward && aliasChain && (\n <ForwardChain\n chain={aliasChain}\n root={root}\n canReference={canReference}\n onReferenceClick={onReferenceClick}\n />\n )}\n {showReverse && token.aliasedBy && (\n <ReverseCount\n referents={token.aliasedBy}\n canReference={canReference}\n onReferenceClick={onReferenceClick}\n />\n )}\n {showVariance && variance && <VarianceBadge variance={variance} />}\n {showGamut && (\n <span\n className=\"sb-indicator__gamut\"\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n >\n ⚠\n </span>\n )}\n {showDescription && description !== undefined && (\n <span\n className=\"sb-indicator__description\"\n data-testid=\"row-indicator-description\"\n title={description}\n aria-label={`description: ${description}`}\n >\n ⓘ\n </span>\n )}\n </span>\n );\n}\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport type { KeyboardEvent, ReactElement } from 'react';\nimport { memo, useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';\nimport './TokenNavigator.css';\nimport { BorderSample } from '#/border-preview/BorderSample.tsx';\nimport { useColorFormat } from '#/contexts.ts';\nimport { DimensionBar } from '#/dimension-scale/DimensionBar.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { DetailOverlay } from '#/internal/DetailOverlay.tsx';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { EmptyState } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { MotionSample } from '#/motion-preview/MotionSample.tsx';\nimport { ShadowSample } from '#/shadow-preview/ShadowSample.tsx';\nimport { ancestorGroupPaths, isInView } from '#/token-navigator/navigate.ts';\nimport { RowIndicators } from '#/indicators/RowIndicators.tsx';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorName, IndicatorsProp } from '#/indicators/resolve.ts';\nimport type { VirtualToken } from '#/types.ts';\n\nexport interface TokenNavigatorProps {\n /** If provided, mount at this dot-path subtree and hide everything outside it. */\n root?: string;\n /**\n * Restrict the tree to tokens with the given DTCG `$type`(s). Pass a single\n * string to scope to one type (`type=\"color\"`), or an array for a narrow\n * small-multiples view (`type={['duration', 'cubicBezier', 'transition']}`).\n * Composes with `root` — both constraints must hold. Group nodes that end\n * up with no surviving leaves collapse out.\n */\n type?: string | readonly string[];\n /**\n * Depth (from the mounted root) that is expanded on first render.\n * `0` = everything collapsed, `1` = top-level groups open (default),\n * `2` = one level deeper, etc.\n */\n initiallyExpanded?: number;\n /**\n * Render a runtime search input above the tree. Matches are fuzzy\n * (case-insensitive, out-of-order terms, single-character typo\n * tolerance) against a leaf's token path; groups that contain no\n * matching leaves collapse out, and every group on the path to a\n * match auto-expands so hits are visible without clicking. Defaults\n * to `true`.\n */\n searchable?: boolean;\n /**\n * Called with a leaf's full dot-path when it is clicked. When set, the\n * inline `<TokenDetail>` slide-over is suppressed — the consumer owns\n * the follow-up UI.\n */\n onSelect?(path: string): void;\n /**\n * Disambiguates persisted UI state (expand/collapse, selection, search)\n * when two navigators with otherwise-identical props sit on the same docs\n * page. Only needed in that case; the state key is derived from the other\n * props otherwise.\n */\n id?: string;\n /** Configure the per-row indicator strip. See `IndicatorsProp`. */\n indicators?: IndicatorsProp;\n}\n\ninterface LeafNode {\n kind: 'leaf';\n segment: string;\n path: string;\n token: VirtualToken;\n}\n\ninterface GroupNode {\n kind: 'group';\n segment: string;\n path: string;\n children: TreeNode[];\n}\n\ntype TreeNode = LeafNode | GroupNode;\n\nfunction buildTree(\n resolved: Record<string, VirtualToken>,\n root: string | undefined,\n typeFilter: ReadonlySet<string> | undefined,\n): TreeNode[] {\n const rootPrefix = root && root.length > 0 ? `${root}.` : '';\n const rootSegments = root ? root.split('.') : [];\n\n const entries = Object.entries(resolved).filter(([path, token]) => {\n if (root && !(path === root || path.startsWith(rootPrefix))) return false;\n if (typeFilter && !(token.$type && typeFilter.has(token.$type))) return false;\n return true;\n });\n\n const rootNode: GroupNode = { kind: 'group', segment: '', path: '', children: [] };\n\n for (const [path, token] of entries) {\n const remainder = root ? (path === root ? '' : path.slice(rootPrefix.length)) : path;\n const segments = remainder.length > 0 ? remainder.split('.') : [];\n\n let node: GroupNode = rootNode;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const seg = segments[i];\n if (seg === undefined) continue;\n const prefix = [...rootSegments, ...segments.slice(0, i + 1)].join('.');\n let child = node.children.find(\n (c): c is GroupNode => c.kind === 'group' && c.segment === seg,\n );\n if (!child) {\n child = { kind: 'group', segment: seg, path: prefix, children: [] };\n node.children.push(child);\n }\n node = child;\n }\n\n const leafSegment = segments[segments.length - 1];\n if (leafSegment === undefined) {\n node.children.push({\n kind: 'leaf',\n segment: root ? (rootSegments[rootSegments.length - 1] ?? path) : path,\n path,\n token,\n });\n } else {\n node.children.push({ kind: 'leaf', segment: leafSegment, path, token });\n }\n }\n\n sortTree(rootNode);\n\n return rootNode.children;\n}\n\nfunction sortTree(node: GroupNode): void {\n node.children.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'group' ? -1 : 1;\n return a.segment.localeCompare(b.segment, undefined, { numeric: true });\n });\n for (const c of node.children) {\n if (c.kind === 'group') sortTree(c);\n }\n}\n\nfunction collectInitialExpanded(nodes: TreeNode[], remainingDepth: number, out: Set<string>): void {\n if (remainingDepth <= 0) return;\n for (const node of nodes) {\n if (node.kind !== 'group') continue;\n out.add(node.path);\n collectInitialExpanded(node.children, remainingDepth - 1, out);\n }\n}\n\nfunction countLeaves(node: TreeNode): number {\n if (node.kind === 'leaf') return 1;\n let n = 0;\n for (const c of node.children) n += countLeaves(c);\n return n;\n}\n\nfunction collectLeafPaths(nodes: TreeNode[], out: string[]): void {\n for (const node of nodes) {\n if (node.kind === 'leaf') out.push(node.path);\n else collectLeafPaths(node.children, out);\n }\n}\n\n// Flatten the currently-visible treeitems into the order screen-reader\n// users + arrow-key users navigate them: depth-first, only descending\n// into expanded groups. Each entry carries enough metadata for the\n// keyboard handler to compute parent / first-child / next / prev.\ninterface FlatTreeItem {\n path: string;\n kind: 'group' | 'leaf';\n // Dot-path of the parent group, or `null` for top-level entries.\n parentPath: string | null;\n}\n\nfunction flattenVisible(\n nodes: TreeNode[],\n expanded: Set<string>,\n parentPath: string | null,\n out: FlatTreeItem[],\n): void {\n for (const node of nodes) {\n out.push({ path: node.path, kind: node.kind, parentPath });\n if (node.kind === 'group' && expanded.has(node.path)) {\n flattenVisible(node.children, expanded, node.path, out);\n }\n }\n}\n\n// Return a pruned copy of the tree keeping only leaves whose path is in\n// `matches`, plus the groups on the way to them. Every surviving group's\n// path is added to `expandOut` so callers can force those groups open.\nfunction pruneTreeForMatches(\n nodes: TreeNode[],\n matches: ReadonlySet<string>,\n expandOut: Set<string>,\n): TreeNode[] {\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (node.kind === 'leaf') {\n if (matches.has(node.path)) out.push(node);\n } else {\n const children = pruneTreeForMatches(node.children, matches, expandOut);\n if (children.length > 0) {\n expandOut.add(node.path);\n out.push({ ...node, children });\n }\n }\n }\n return out;\n}\n\nexport function TokenNavigator({\n root,\n type,\n initiallyExpanded = 1,\n searchable = true,\n onSelect,\n id,\n indicators,\n}: TokenNavigatorProps): ReactElement {\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = useProject();\n\n // Persist UI state (expand/collapse, selection, search) across docs-mode\n // remounts. Keyed on the props that distinguish one navigator from another\n // (plus the optional `id`); excludes `initiallyExpanded`/`searchable`, whose\n // changes are handled by the re-seed effect below rather than a fresh key.\n const typeKey = type === undefined ? '' : typeof type === 'string' ? type : type.join(',');\n const blockKey = useBlockKey('TokenNavigator', [root, typeKey, id]);\n\n const typeFilter = useMemo<ReadonlySet<string> | undefined>(() => {\n if (type === undefined) return undefined;\n return new Set(Array.isArray(type) ? type : [type]);\n }, [type]);\n\n const enabledIndicators = useMemo(() => resolveIndicators(indicators), [indicators]);\n\n const tree = useMemo(() => buildTree(resolved, root, typeFilter), [resolved, root, typeFilter]);\n\n const initialExpanded = useMemo(() => {\n const out = new Set<string>();\n collectInitialExpanded(tree, initiallyExpanded, out);\n return out;\n }, [tree, initiallyExpanded]);\n\n const [expanded, setExpanded] = usePersistedState<Set<string>>(\n `${blockKey}::expanded`,\n initialExpanded,\n );\n const initiallyExpandedRef = useRef(initiallyExpanded);\n useEffect(() => {\n // Re-seed the expand/collapse state ONLY when the `initiallyExpanded`\n // prop itself changes — not when `initialExpanded` merely gets a fresh\n // identity because `resolved`/`tree` churned on an axis flip. `resolved`\n // is recomputed per active tuple, so without this guard every mode switch\n // would snap the user's expand/collapse state back to the default.\n if (initiallyExpandedRef.current === initiallyExpanded) return;\n initiallyExpandedRef.current = initiallyExpanded;\n setExpanded(initialExpanded);\n }, [initiallyExpanded, initialExpanded, setExpanded]);\n\n const [selectedPath, setSelectedPath] = usePersistedState<string | null>(\n `${blockKey}::selected`,\n null,\n );\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n\n const { visibleTree, searchExpanded } = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') {\n return { visibleTree: tree, searchExpanded: null as Set<string> | null };\n }\n const leafPaths: string[] = [];\n collectLeafPaths(tree, leafPaths);\n const matches = new Set(fuzzyFilter(leafPaths, deferredQuery, (p) => p));\n const expandOut = new Set<string>();\n const pruned = matches.size === 0 ? [] : pruneTreeForMatches(tree, matches, expandOut);\n return { visibleTree: pruned, searchExpanded: expandOut };\n }, [tree, deferredQuery, searchable]);\n\n const effectiveExpanded = useMemo(() => {\n if (!searchExpanded) return expanded;\n const merged = new Set(expanded);\n for (const p of searchExpanded) merged.add(p);\n return merged;\n }, [expanded, searchExpanded]);\n\n const toggle = useCallback(\n (path: string): void => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n },\n [setExpanded],\n );\n\n const handleLeafClick = useCallback(\n (path: string) => {\n if (onSelect) onSelect(path);\n else setSelectedPath(path);\n },\n [onSelect, setSelectedPath],\n );\n\n // WAI-ARIA tree pattern's roving tabindex — exactly one treeitem at a\n // time has tabIndex={0}; the rest are -1. Tab into / out of the tree\n // hits that one item; arrow keys move focus between items inside.\n // `storedFocus` is the user-driven state; the derived `focusedPath`\n // below repairs the focus to the first visible item when storedFocus\n // points at a now-hidden row (e.g. after a search narrows the tree).\n const [storedFocus, setStoredFocus] = useState<string | null>(null);\n const treeItemRefs = useRef<Map<string, HTMLLIElement>>(new Map());\n\n const resolveInView = useCallback(\n (path: string): boolean => isInView(path, { resolved, root, typeFilter }),\n [resolved, root, typeFilter],\n );\n\n const navigateTo = useCallback(\n (target: string): void => {\n setQuery('');\n setExpanded((prev) => {\n const next = new Set(prev);\n for (const p of ancestorGroupPaths(target, root)) next.add(p);\n return next;\n });\n if (onSelect) onSelect(target);\n else setSelectedPath(target);\n setStoredFocus(target);\n requestAnimationFrame(() => {\n const el = treeItemRefs.current.get(target);\n el?.scrollIntoView({ block: 'nearest' });\n el?.focus();\n });\n },\n [root, onSelect, setQuery, setExpanded, setSelectedPath],\n );\n const registerTreeItem = useCallback(\n (path: string) =>\n (el: HTMLLIElement | null): void => {\n if (el) treeItemRefs.current.set(path, el);\n else treeItemRefs.current.delete(path);\n },\n [],\n );\n\n const flatVisible = useMemo<FlatTreeItem[]>(() => {\n const out: FlatTreeItem[] = [];\n flattenVisible(visibleTree, effectiveExpanded, null, out);\n return out;\n }, [visibleTree, effectiveExpanded]);\n\n const focusedPath = useMemo<string | null>(() => {\n if (flatVisible.length === 0) return null;\n if (storedFocus && flatVisible.some((entry) => entry.path === storedFocus)) {\n return storedFocus;\n }\n return flatVisible[0]?.path ?? null;\n }, [flatVisible, storedFocus]);\n\n const focusByPath = useCallback((path: string): void => {\n const node = treeItemRefs.current.get(path);\n // If the ref isn't mounted yet (e.g. after expanding a group via\n // Right-arrow, before the new children render), flag the path so\n // the DOM-sync effect below can move focus once the node mounts.\n if (node) node.focus();\n setStoredFocus(path);\n }, []);\n\n // After expanding a group via Right-arrow, the new children mount on\n // the following render. If a path was queued via `setStoredFocus`\n // but the corresponding ref didn't exist at the time, repair focus\n // now that the children are live.\n useEffect(() => {\n if (focusedPath === null) return;\n const node = treeItemRefs.current.get(focusedPath);\n if (node && document.activeElement !== node) {\n const active = document.activeElement;\n // Move focus to the repaired row in two cases:\n // 1. Focus sits on a different treeitem inside our tree (e.g. after\n // Right-arrow expands a group and the queued child mounts).\n // 2. The previously-focused row was removed (a toolbar axis flip\n // dropped a token, a search narrowed the tree, a live edit) and\n // the browser orphaned focus onto <body>. `focusedPath` has\n // repaired to the first visible row but `storedFocus` still names\n // the gone row — restore the live focus to match.\n // Don't yank focus from the search input or anything else still\n // legitimately focused, and don't grab it on mount (storedFocus null).\n const insideTree = active instanceof HTMLElement && active.closest('[role=\"tree\"]');\n const orphaned = active === document.body || active === null;\n const focusedRowRemoved = storedFocus !== null && storedFocus !== focusedPath;\n if (insideTree || (orphaned && focusedRowRemoved)) node.focus();\n }\n // Deps are intentionally just `focusedPath`. The repair fires when the\n // focused row changes — including when a removed row forces the fall back\n // to the first visible row — NOT on every `storedFocus` change (that would\n // re-run while DOM focus sits on a descendant leaf and steal it to the\n // group). Reading `storedFocus` from the triggering render is correct: on\n // removal it still names the now-gone row, so `focusedRowRemoved` holds.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [focusedPath]);\n\n const handleTreeKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>): void => {\n // Derive the active treeitem from `document.activeElement` rather\n // than the `focusedPath` state. State updates from `onFocus` may\n // not have flushed by the time a subsequent keydown fires (e.g.\n // tests that programmatically `.focus()` then immediately dispatch\n // keys), and the handler must always operate on the row the user\n // is currently on.\n if (flatVisible.length === 0) return;\n const active = document.activeElement;\n if (!(active instanceof HTMLLIElement)) return;\n const activePath = active.getAttribute('data-path');\n if (activePath === null) return;\n const currentIndex = flatVisible.findIndex((entry) => entry.path === activePath);\n if (currentIndex < 0) return;\n const current = flatVisible[currentIndex];\n if (!current) return;\n\n switch (e.key) {\n case 'ArrowDown': {\n const next = flatVisible[currentIndex + 1];\n if (next) {\n e.preventDefault();\n focusByPath(next.path);\n }\n return;\n }\n case 'ArrowUp': {\n const prev = flatVisible[currentIndex - 1];\n if (prev) {\n e.preventDefault();\n focusByPath(prev.path);\n }\n return;\n }\n case 'Home': {\n const first = flatVisible[0];\n if (first) {\n e.preventDefault();\n focusByPath(first.path);\n }\n return;\n }\n case 'End': {\n const last = flatVisible[flatVisible.length - 1];\n if (last) {\n e.preventDefault();\n focusByPath(last.path);\n }\n return;\n }\n case 'ArrowRight': {\n if (current.kind === 'group') {\n if (!effectiveExpanded.has(current.path)) {\n e.preventDefault();\n toggle(current.path);\n // Focus stays on the group — user can press Right again\n // to step into the first child on the next render.\n return;\n }\n // Already expanded: step into first child (which is the\n // next entry in the flattened list).\n const firstChild = flatVisible[currentIndex + 1];\n if (firstChild && firstChild.parentPath === current.path) {\n e.preventDefault();\n focusByPath(firstChild.path);\n }\n }\n return;\n }\n case 'ArrowLeft': {\n if (current.kind === 'group' && effectiveExpanded.has(current.path)) {\n e.preventDefault();\n toggle(current.path);\n return;\n }\n // Collapsed group or leaf: step to parent.\n if (current.parentPath !== null) {\n e.preventDefault();\n focusByPath(current.parentPath);\n }\n return;\n }\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (current.kind === 'group') toggle(current.path);\n else handleLeafClick(current.path);\n return;\n }\n default:\n return;\n }\n },\n [flatVisible, effectiveExpanded, toggle, focusByPath, handleLeafClick],\n );\n\n const typeLabel = typeFilter ? ` · ${[...typeFilter].map((t) => `$type=${t}`).join(', ')}` : '';\n const trimmedQuery = query.trim();\n // Must run every render — React's rules of hooks forbid the earlier empty-state\n // early return from skipping it, or the next non-empty render throws\n // \"Rendered fewer hooks than expected\".\n const matchCount = useMemo(() => {\n if (!searchExpanded) return 0;\n let n = 0;\n for (const node of visibleTree) n += countLeaves(node);\n return n;\n }, [visibleTree, searchExpanded]);\n\n if (tree.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <EmptyState>\n {root\n ? `No tokens under \"${root}\"${typeFilter ? ` matching ${typeLabel.slice(3)}` : ''}.`\n : typeFilter\n ? `No tokens matching ${typeLabel.slice(3)} in the active theme.`\n : 'No tokens in the active theme.'}\n </EmptyState>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-token-navigator__search\">\n <input\n type=\"search\"\n className=\"sb-token-navigator__search-input\"\n placeholder=\"Search tokens…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Search tokens by path\"\n data-testid=\"token-navigator-search\"\n />\n </div>\n )}\n <div className=\"sb-token-navigator__caption\">\n {root ? `Tokens under ${root}` : 'Token graph'}\n {typeLabel}\n {trimmedQuery !== '' ? ` · ${matchCount} matching \"${trimmedQuery}\"` : ''} · {activeTheme}\n </div>\n {searchable && (\n <span role=\"status\" aria-live=\"polite\" className=\"sb-token-navigator__sr-status\">\n {trimmedQuery !== '' ? `${matchCount} tokens matching \"${trimmedQuery}\"` : ''}\n </span>\n )}\n {visibleTree.length === 0 ? (\n <div className=\"sb-block__empty\">No tokens match \"{trimmedQuery}\".</div>\n ) : (\n <ul\n className=\"sb-token-navigator__tree\"\n role=\"tree\"\n aria-label=\"Token graph\"\n onKeyDown={handleTreeKeyDown}\n >\n {visibleTree.map((node, i) => (\n <TreeNodeRow\n key={node.path || node.segment}\n node={node}\n expanded={effectiveExpanded}\n focusedPath={focusedPath}\n registerTreeItem={registerTreeItem}\n onToggle={toggle}\n onFocusPath={setStoredFocus}\n onLeafClick={handleLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={navigateTo}\n enabled={enabledIndicators}\n level={1}\n setsize={visibleTree.length}\n posinset={i + 1}\n />\n ))}\n </ul>\n )}\n\n {selectedPath !== null && (\n <DetailOverlay\n path={selectedPath}\n onClose={() => setSelectedPath(null)}\n testId=\"token-navigator-overlay\"\n />\n )}\n </div>\n );\n}\n\ninterface TreeNodeRowProps {\n node: TreeNode;\n expanded: Set<string>;\n focusedPath: string | null;\n registerTreeItem(path: string): (el: HTMLLIElement | null) => void;\n onToggle(path: string): void;\n onFocusPath(path: string): void;\n onLeafClick(path: string): void;\n root: string | undefined;\n resolveInView(path: string): boolean;\n onNavigate(path: string): void;\n enabled: Record<IndicatorName, boolean>;\n // 1-indexed depth in the tree (top-level = 1).\n level: number;\n // Number of siblings at this level (including self).\n setsize: number;\n // 1-indexed position among siblings.\n posinset: number;\n}\n\nfunction TreeNodeRow({\n node,\n expanded,\n focusedPath,\n registerTreeItem,\n onToggle,\n onFocusPath,\n onLeafClick,\n root,\n resolveInView,\n onNavigate,\n enabled,\n level,\n setsize,\n posinset,\n}: TreeNodeRowProps): ReactElement {\n if (node.kind === 'leaf') {\n return (\n <LeafRow\n node={node}\n isFocused={focusedPath === node.path}\n registerTreeItem={registerTreeItem}\n onFocusPath={onFocusPath}\n onLeafClick={onLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={onNavigate}\n enabled={enabled}\n level={level}\n setsize={setsize}\n posinset={posinset}\n />\n );\n }\n const isOpen = expanded.has(node.path);\n const isFocused = focusedPath === node.path;\n return (\n <li\n ref={registerTreeItem(node.path)}\n role=\"treeitem\"\n aria-expanded={isOpen}\n aria-level={level}\n aria-setsize={setsize}\n aria-posinset={posinset}\n tabIndex={isFocused ? 0 : -1}\n onFocus={() => onFocusPath(node.path)}\n data-path={node.path}\n data-testid=\"token-navigator-group\"\n >\n {/*\n Click handler on the inner row div, not the <li>. Nested\n treeitems are DOM descendants of their parent <li>, so a\n click on a child row would bubble through each ancestor\n <li>'s onClick. The row div is a SIBLING of the nested\n <ul>, so child rows never bubble through it.\n */}\n <div\n className=\"sb-token-navigator__group-row\"\n data-testid=\"token-navigator-group-row\"\n onClick={() => {\n onFocusPath(node.path);\n onToggle(node.path);\n }}\n >\n <span className=\"sb-token-navigator__caret\" aria-hidden>\n {isOpen ? '▾' : '▸'}\n </span>\n <span>{node.segment}</span>\n <span className=\"sb-token-navigator__count\">{countLeaves(node)}</span>\n </div>\n {isOpen && (\n <ul className=\"sb-token-navigator__nested\" role=\"group\">\n {node.children.map((c, i) => (\n <TreeNodeRow\n key={c.path || c.segment}\n node={c}\n expanded={expanded}\n focusedPath={focusedPath}\n registerTreeItem={registerTreeItem}\n onToggle={onToggle}\n onFocusPath={onFocusPath}\n onLeafClick={onLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={onNavigate}\n enabled={enabled}\n level={level + 1}\n setsize={node.children.length}\n posinset={i + 1}\n />\n ))}\n </ul>\n )}\n </li>\n );\n}\n\ninterface LeafRowProps {\n node: LeafNode;\n isFocused: boolean;\n registerTreeItem(path: string): (el: HTMLLIElement | null) => void;\n onFocusPath(path: string): void;\n onLeafClick(path: string): void;\n root: string | undefined;\n resolveInView(path: string): boolean;\n onNavigate(path: string): void;\n enabled: Record<IndicatorName, boolean>;\n // 1-indexed depth in the tree (top-level = 1).\n level: number;\n // Number of siblings at this level (including self).\n setsize: number;\n // 1-indexed position among siblings.\n posinset: number;\n}\n\nconst LeafRow = memo(function LeafRow({\n node,\n isFocused,\n registerTreeItem,\n onFocusPath,\n onLeafClick,\n root,\n resolveInView,\n onNavigate,\n enabled,\n level,\n setsize,\n posinset,\n}: LeafRowProps): ReactElement {\n const type = node.token.$type ?? '';\n const project = useProject();\n const colorFormat = useColorFormat();\n const variance = project.varianceByPath[node.path];\n const dep = node.token.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n return (\n <li\n ref={registerTreeItem(node.path)}\n role=\"treeitem\"\n aria-level={level}\n aria-setsize={setsize}\n aria-posinset={posinset}\n tabIndex={isFocused ? 0 : -1}\n onFocus={() => onFocusPath(node.path)}\n data-path={node.path}\n data-testid=\"token-navigator-leaf\"\n >\n {/* Click handler on the inner row div for the same reason as\n group rows — see TreeNodeRow. */}\n <div\n className=\"sb-token-navigator__leaf-row\"\n data-testid=\"token-navigator-leaf-row\"\n data-deprecated={enabled.deprecation && isDeprecated ? 'true' : undefined}\n onClick={() => {\n onFocusPath(node.path);\n onLeafClick(node.path);\n }}\n >\n <span className=\"sb-token-navigator__caret\" aria-hidden>\n •\n </span>\n <span className=\"sb-token-navigator__tail\">{node.segment}</span>\n {type && <span className=\"sb-token-navigator__type-pill\">{type}</span>}\n <RowIndicators\n path={node.path}\n token={node.token}\n root={root}\n variance={variance}\n colorFormat={colorFormat}\n canReference={resolveInView}\n onReferenceClick={onNavigate}\n enabled={enabled}\n />\n <LeafPreview path={node.path} token={node.token} />\n </div>\n </li>\n );\n});\n\ninterface LeafPreviewProps {\n path: string;\n token: VirtualToken;\n}\n\nconst LeafPreview = memo(function LeafPreview({ path, token }: LeafPreviewProps): ReactElement {\n const project = useProject();\n const colorFormat = useColorFormat();\n const type = token.$type;\n\n if (type === 'color') {\n const cssVar = resolveCssVar(path, project);\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n <span\n className=\"sb-token-navigator__color-swatch\"\n style={{ background: cssVar }}\n aria-hidden\n />\n </span>\n );\n }\n if (type === 'dimension') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n <span className=\"sb-token-navigator__preview-dimension\">\n <DimensionBar path={path} visual=\"length\" />\n </span>\n </span>\n );\n }\n if (type === 'shadow') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-scaled\">\n <ShadowSample path={path} />\n </span>\n </span>\n );\n }\n if (type === 'border') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-scaled\">\n <BorderSample path={path} />\n </span>\n </span>\n );\n }\n if (type === 'transition' || type === 'duration' || type === 'cubicBezier') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-motion\">\n <MotionSample path={path} />\n </span>\n </span>\n );\n }\n\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n </span>\n );\n});\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useCallback, useDeferredValue, useMemo } from 'react';\nimport './TokenTable.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { DetailOverlay } from '#/internal/DetailOverlay.tsx';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { RowIndicators } from '#/indicators/RowIndicators.tsx';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorsProp } from '#/indicators/resolve.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface TokenTableProps {\n /**\n * Token-path filter. `\"color.*\"` matches every `color.…` token;\n * omit to include everything. Combines with `type` (both must match).\n */\n filter?: string;\n /** Restrict to one DTCG `$type`. */\n type?: string;\n /** Override the table caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — per-`$type`: numeric for `dimension` / `duration` /\n * `fontWeight`; perceptual (oklch L → C → H) for `color`; lexicographic\n * for `fontFamily` / `strokeStyle`. Composite types fall through to\n * path order.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n /**\n * Render a runtime search input above the table that narrows rows by\n * fuzzy match (case-insensitive, out-of-order terms, single-character\n * typo tolerance) against the token path, type, or value. Defaults to\n * `true` because browsing a multi-hundred-token reference without\n * search is painful. Pass `false` to hide the input (the `filter` /\n * `type` props still apply at authoring time).\n */\n searchable?: boolean;\n /**\n * Called with the clicked row's dot-path. When set, the built-in\n * `<TokenDetail>` slide-over is suppressed — the consumer owns the\n * follow-up UI (inline panel, drill-down route, …).\n */\n onSelect?(path: string): void;\n /** Disambiguates persisted UI state for two identical-prop tables on a page. */\n id?: string;\n /** Configure the per-row indicator strip. See `IndicatorsProp`. */\n indicators?: IndicatorsProp;\n}\n\nexport function TokenTable({\n filter,\n type,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n searchable = true,\n onSelect,\n id,\n indicators,\n}: TokenTableProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = project;\n const colorFormat = useColorFormat();\n // Persist selection + search across docs-mode remounts (see persistent-state).\n const blockKey = useBlockKey('TokenTable', [filter, type, caption, id]);\n const enabledIndicators = useMemo(() => resolveIndicators(indicators), [indicators]);\n const [selectedPath, setSelectedPath] = usePersistedState<string | null>(\n `${blockKey}::selected`,\n null,\n );\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n\n const rows = useMemo(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (!matchPath(path, filter)) return false;\n if (type && token.$type !== type) return false;\n return true;\n });\n const entries = sortTokens(filtered, { by: sortBy, dir: sortDir });\n return entries.map(([path, token]) => {\n const isColor = token.$type === 'color';\n const color = isColor\n ? resolveColorValue(path, token.$value, colorFormat, projectFields)\n : null;\n return {\n path,\n type: token.$type ?? '',\n value: formatTokenValue(token.$value, token.$type, colorFormat, listing[path]),\n outOfGamut: color?.outOfGamut ?? false,\n cssVar: resolveCssVar(path, projectFields),\n isColor,\n };\n });\n }, [resolved, listing, cssVarPrefix, filter, type, colorFormat, sortBy, sortDir]);\n\n const visibleRows = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') return rows;\n return fuzzyFilter(rows, deferredQuery, (row) => `${row.path} ${row.type} ${row.value}`);\n }, [rows, deferredQuery, searchable]);\n\n const handleRowClick = useCallback(\n (path: string) => {\n if (onSelect) onSelect(path);\n else setSelectedPath(path);\n },\n [onSelect, setSelectedPath],\n );\n\n const matchSuffix =\n searchable && query.trim() !== '' ? ` · ${visibleRows.length} matching \"${query.trim()}\"` : '';\n const captionText =\n caption ??\n `${rows.length} token${rows.length === 1 ? '' : 's'}${\n filter ? ` matching \\`${filter}\\`` : ''\n }${type ? ` · $type=${type}` : ''}${matchSuffix} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-token-table__search\">\n <input\n type=\"search\"\n className=\"sb-token-table__search-input\"\n placeholder=\"Search tokens…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Fuzzy-search tokens by path, type, or value\"\n data-testid=\"token-table-search\"\n />\n </div>\n )}\n {searchable && (\n <span role=\"status\" aria-live=\"polite\" className=\"sb-token-table__sr-status\">\n {query.trim() !== ''\n ? `${visibleRows.length} of ${rows.length} tokens match \"${query.trim()}\"`\n : ''}\n </span>\n )}\n <table className=\"sb-token-table__table\">\n <caption className=\"sb-token-table__caption\">{captionText}</caption>\n <thead>\n <tr>\n <th className={cx('sb-token-table__th', 'sb-token-table__th--path')}>Path</th>\n <th className={cx('sb-token-table__th', 'sb-token-table__th--value')}>Value</th>\n <th className=\"sb-token-table__th sb-token-table__th--refs\">\n <span className=\"sb-token-table__sr-status\">References and status</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {visibleRows.length === 0 && (\n <tr>\n <td colSpan={3} className=\"sb-token-table__td sb-token-table__empty-row\">\n No tokens match \"{query.trim()}\".\n </td>\n </tr>\n )}\n {visibleRows.map((row) => {\n const token = resolved[row.path];\n const dep = token?.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n return (\n <tr\n key={row.path}\n className=\"sb-token-table__row\"\n onClick={() => handleRowClick(row.path)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleRowClick(row.path);\n }\n }}\n tabIndex={0}\n aria-haspopup=\"dialog\"\n aria-label={`Inspect ${row.path}`}\n data-testid=\"token-table-row\"\n data-path={row.path}\n >\n <td\n className={cx('sb-token-table__td', 'sb-token-table__path')}\n data-deprecated={\n enabledIndicators.deprecation && isDeprecated ? 'true' : undefined\n }\n >\n {row.path}\n </td>\n <td className=\"sb-token-table__td\">\n <span className=\"sb-token-table__value-cell\">\n {row.type && <span className=\"sb-token-table__type-pill\">{row.type}</span>}\n {row.isColor && (\n <span\n className=\"sb-token-table__swatch\"\n style={{ background: row.cssVar }}\n aria-hidden\n />\n )}\n <span\n className=\"sb-token-table__value-text\"\n title={row.value}\n data-testid=\"token-table-value\"\n >\n {row.value}\n </span>\n {row.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-token-table__gamut-warn\"\n >\n ⚠\n </span>\n )}\n <span\n className=\"sb-token-table__copy-wrap\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n <CopyButton\n value={row.value}\n label={`Copy value ${row.value}`}\n className=\"sb-token-table__copy\"\n />\n </span>\n </span>\n </td>\n <td className=\"sb-token-table__td sb-token-table__refs\">\n {token && (\n <RowIndicators\n path={row.path}\n token={token}\n root={undefined}\n variance={varianceByPath[row.path]}\n colorFormat={colorFormat}\n canReference={(p) => p in resolved}\n onReferenceClick={(p) => setSelectedPath(p)}\n enabled={enabledIndicators}\n />\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n {selectedPath !== null && (\n <DetailOverlay\n path={selectedPath}\n onClose={() => setSelectedPath(null)}\n testId=\"token-table-overlay\"\n />\n )}\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './TypographyScale.css';\nimport type { TypographyValue } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\n// Dimension sub-values in DTCG 2025.10 use a `{ value, unit }` envelope\n// — narrow once here so the local `asDimension` helper doesn't need\n// to re-validate keys at every read.\ninterface DimensionLike {\n value?: unknown;\n unit?: unknown;\n}\n\nexport interface TypographyScaleProps {\n /**\n * Token-path filter. Defaults to every `typography` token. Use e.g.\n * `\"typography.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n sampleStyle: CSSProperties;\n specs: string;\n}\n\nfunction asDimension(raw: unknown): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'string' || typeof raw === 'number') return String(raw);\n if (typeof raw === 'object') {\n const v = raw as DimensionLike;\n if (v.value !== undefined && v.unit !== undefined) return `${String(v.value)}${String(v.unit)}`;\n }\n return undefined;\n}\n\nfunction asFontFamily(raw: unknown): string | undefined {\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.map(String).join(', ');\n return undefined;\n}\n\nfunction buildRow(path: string, composite: TypographyValue): Row {\n const fontFamily = asFontFamily(composite.fontFamily);\n const fontSize = asDimension(composite.fontSize);\n const fontWeight = composite.fontWeight == null ? undefined : String(composite.fontWeight);\n const lineHeight = composite.lineHeight == null ? undefined : String(composite.lineHeight);\n const letterSpacing = asDimension(composite.letterSpacing);\n\n const sampleStyle: CSSProperties = {};\n if (fontFamily) sampleStyle.fontFamily = fontFamily;\n if (fontSize) sampleStyle.fontSize = fontSize;\n if (fontWeight) sampleStyle.fontWeight = fontWeight as CSSProperties['fontWeight'];\n if (lineHeight) sampleStyle.lineHeight = lineHeight;\n if (letterSpacing) sampleStyle.letterSpacing = letterSpacing;\n\n const parts = [\n fontSize,\n fontWeight ? `w${fontWeight}` : undefined,\n lineHeight ? `lh ${lineHeight}` : undefined,\n ]\n .filter(Boolean)\n .join(' · ');\n\n return { path, sampleStyle, specs: parts };\n}\n\nexport function TypographyScale({\n filter,\n sample = 'The quick brown fox jumps over the lazy dog.',\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: TypographyScaleProps): ReactElement {\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = useProject();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'typography') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const value = token.$value;\n if (!value || typeof value !== 'object') {\n return { path, sampleStyle: {}, specs: '' };\n }\n return buildRow(path, value as TypographyValue);\n });\n }, [resolved, filter, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} typography token${rows.length === 1 ? '' : 's'}${filter && filter !== 'typography' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No typography tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-typography-scale__row\">\n <div className=\"sb-typography-scale__meta\">\n <span className=\"sb-typography-scale__path\">{row.path}</span>\n {row.specs && <span className=\"sb-typography-scale__specs\">{row.specs}</span>}\n </div>\n <div style={row.sampleStyle}>{sample}</div>\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["snapshot","listeners","subscribed","ensureSubscribed","subscribe","getSnapshot","getServerSnapshot","sampleStyle","formatDimension","formatDimension","CopyButton","CopyButton","styles","formatFontFamily","formatPrimitive","formatDimension","StrokeStylePreview","CopyButton","CopyButton","CopyButton"],"sources":["../src/internal/styles.tsx","../src/internal/channel-globals.ts","../src/contexts.ts","../src/internal/channel-tokens.ts","../src/internal/use-project.ts","../src/border-preview/BorderSample.tsx","../src/internal/composite-sample-format.ts","../src/internal/data-attr.ts","../src/internal/sort-tokens.ts","../src/BorderPreview.tsx","../src/ColorPalette.tsx","../src/indicators/resolve.ts","../src/indicators/RowIndicators.tsx","../src/internal/CopyButton.tsx","../src/internal/persistent-state.ts","../src/ColorTable.tsx","../src/Diagnostics.tsx","../src/dimension-scale/dimension-px.ts","../src/dimension-scale/DimensionBar.tsx","../src/internal/format-token-value.ts","../src/DimensionScale.tsx","../src/FontFamilyPreview.tsx","../src/internal/css-var-style.ts","../src/FontWeightScale.tsx","../src/GradientPalette.tsx","../src/internal/prefers-reduced-motion.ts","../src/motion-preview/MotionSample.tsx","../src/MotionPreview.tsx","../src/OpacityScale.tsx","../src/provider.tsx","../src/shadow-preview/ShadowSample.tsx","../src/ShadowPreview.tsx","../src/StrokeStylePreview.tsx","../src/token-detail/internal.ts","../src/token-detail/AliasChain.tsx","../src/token-detail/AliasedBy.tsx","../src/token-detail/AxisVariance.tsx","../src/token-detail/CompositeBreakdown.tsx","../src/token-detail/transition-duration.ts","../src/token-detail/CompositePreview.tsx","../src/token-detail/ConsumerOutput.tsx","../src/token-detail/TokenHeader.tsx","../src/token-detail/TokenUsageSnippet.tsx","../src/TokenDetail.tsx","../src/internal/DetailOverlay.tsx","../src/token-navigator/navigate.ts","../src/TokenNavigator.tsx","../src/TokenTable.tsx","../src/TypographyScale.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from 'react';\n\n/**\n * Chrome-style primitives shared across every block. Kept as JS exports\n * for the inline-style sites that still compose them into per-block style\n * objects (e.g. TokenNavigator's `typePill` that builds on the shared\n * pill base). The pure direct-reference chrome — surface wrapper, caption,\n * empty-state — lives in `styles.css` and is applied via class names.\n */\n\nexport const TEXT_MUTED = 'var(--swatchbook-text-muted, CanvasText)';\n\nexport const SURFACE_RAISED = 'var(--swatchbook-surface-raised, Canvas)';\nexport const SURFACE_MUTED = 'var(--swatchbook-surface-muted, rgba(128,128,128,0.15))';\n\nexport const BORDER_FAINT = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.15))`;\nexport const BORDER_STRONG = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.3))`;\n\n/**\n * Inner content for a block's \"nothing to render\" state. Call sites wrap\n * it in their own block wrapper (which already carries `blockWrapperAttrs`), so\n * the message itself just needs the muted type.\n */\nexport function EmptyState({ children }: { children: ReactNode }): ReactElement {\n return <div className=\"sb-block__empty\">{children}</div>;\n}\n","import { useSyncExternalStore } from 'react';\nimport { addons } from 'storybook/preview-api';\nimport { COLOR_FORMATS } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Shared subscription to Storybook's globals channel, lifted out of React\n * component state so the values survive docs-mode remounts.\n *\n * On MDX docs pages, Storybook force-rerenders the docs container on every\n * `updateGlobals` (see `preview/runtime.js` → `onUpdateGlobals`), which\n * unmounts and remounts any embedded blocks. A `useState(null)` initializer\n * inside the block would reset to null on each remount — the symptom is a\n * one-frame flicker to the correct value, then revert to the defaults.\n * Module-level state persists; React reads it through `useSyncExternalStore`\n * and stays concurrent-safe.\n */\n\nexport interface ChannelGlobals {\n axes: Record<string, string> | null;\n format: ColorFormat | null;\n}\n\nconst AXES_GLOBAL_KEY = 'swatchbookAxes';\nconst COLOR_FORMAT_GLOBAL_KEY = 'swatchbookColorFormat';\n\nlet snapshot: ChannelGlobals = { axes: null, format: null };\nconst listeners = new Set<() => void>();\nlet subscribed = false;\n\nfunction isColorFormat(value: unknown): value is ColorFormat {\n return typeof value === 'string' && (COLOR_FORMATS as readonly string[]).includes(value);\n}\n\ninterface SwatchbookGlobalsPayload {\n swatchbookAxes?: Record<string, string>;\n swatchbookColorFormat?: ColorFormat;\n [key: string]: unknown;\n}\n\nfunction ensureSubscribed(): void {\n if (subscribed || typeof window === 'undefined') return;\n subscribed = true;\n const channel = addons.getChannel();\n // Storybook fires `globalsUpdated`, `setGlobals`, and `updateGlobals`\n // for the same logical change (preview init + every toolbar tick).\n // Subscribing to all three is intentional — `setGlobals` carries the\n // initial URL-persisted globals; `updateGlobals` is the toolbar\n // signal; `globalsUpdated` is the cross-frame echo. The handler runs\n // for each but content-deduplicates: we only update the shared\n // snapshot when axes or format actually shifted, so the three events\n // per tick don't each trigger a re-render.\n let lastFingerprint = '';\n const onGlobals = (payload: { globals?: SwatchbookGlobalsPayload }): void => {\n const globals = payload.globals;\n if (!globals) return;\n const incomingAxes = globals[AXES_GLOBAL_KEY];\n const incomingFormat = globals[COLOR_FORMAT_GLOBAL_KEY];\n const nextAxes =\n incomingAxes && typeof incomingAxes === 'object' ? incomingAxes : snapshot.axes;\n const nextFormat = isColorFormat(incomingFormat) ? incomingFormat : snapshot.format;\n const fingerprint = `${nextFormat ?? ''}|${nextAxes ? JSON.stringify(nextAxes) : ''}`;\n if (fingerprint === lastFingerprint) return;\n lastFingerprint = fingerprint;\n snapshot = { axes: nextAxes, format: nextFormat };\n for (const cb of listeners) cb();\n };\n channel.on('globalsUpdated', onGlobals);\n channel.on('updateGlobals', onGlobals);\n channel.on('setGlobals', onGlobals);\n}\n\n// Subscribe at module load so the `SET_GLOBALS` emission from preview init\n// lands in our snapshot before any block renders. Running `useSyncExternalStore`'s\n// `subscribe` lazily on first hook call would miss the event in most cases.\nensureSubscribed();\n\nfunction subscribe(cb: () => void): () => void {\n ensureSubscribed();\n listeners.add(cb);\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): ChannelGlobals {\n return snapshot;\n}\n\nfunction getServerSnapshot(): ChannelGlobals {\n return snapshot;\n}\n\nexport function useChannelGlobals(): ChannelGlobals {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import type { Axis, Diagnostic, Preset } from '@unpunnyfuns/swatchbook-core';\nimport type { TokenGraph } from '@unpunnyfuns/swatchbook-core/graph';\nimport type { SlimListedToken } from '@unpunnyfuns/swatchbook-core/snapshot-for-wire';\nimport { createContext, useContext } from 'react';\nimport { useChannelGlobals } from '#/internal/channel-globals.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Typed shape of the addon's `virtual:swatchbook/tokens` module.\n *\n * The axis / permutation / diagnostic / preset entries are deliberate\n * type-aliases of core's authoritative shapes — the virtual module\n * publishes those shapes verbatim, so single-sourcing the types prevents\n * silent drift the moment core grows a field the plugin doesn't\n * serialise.\n *\n * Token / listing shapes stay as narrowed interfaces because blocks\n * only read a subset of Terrazzo's full token / listing structure; the\n * narrower shape documents what's actually relied on.\n *\n * The ambient `declare module 'virtual:swatchbook/tokens'` declarations\n * in `packages/addon/src/virtual.d.ts` describe the same payload.\n */\nexport type VirtualAxisShape = Axis;\n\nexport type VirtualDiagnosticShape = Diagnostic;\n\nexport interface VirtualTokenShape {\n $type?: string | undefined;\n $value?: unknown;\n $description?: string | undefined;\n /**\n * DTCG `$deprecated` — `true` or a message string. Mirrors core's\n * `SwatchbookToken.$deprecated`; reaches blocks via the resolved token\n * map reconstructed from the wire `tokenGraph`.\n */\n $deprecated?: string | boolean | undefined;\n aliasOf?: string | undefined;\n aliasChain?: readonly string[] | undefined;\n aliasedBy?: readonly string[] | undefined;\n /**\n * Per-sub-field alias map for composite tokens whose value blends\n * primitives with aliased fragments — Terrazzo populates this when\n * one or more component fields of a composite ($type: 'border',\n * 'shadow', 'typography', 'gradient', 'transition') resolve through\n * an alias. The `CompositeBreakdown` block reads it to render the\n * source path beside each component value. Typed as `unknown` because\n * the shape varies per composite type (color carries a\n * `{components: (string | undefined)[]}` sub-shape; typography/border\n * carry a flat `Record<string, string | undefined>`); the block\n * narrows it at the consumer.\n */\n partialAliasOf?: unknown;\n}\n\n/**\n * Subset of `@terrazzo/plugin-token-listing`'s `ListedToken` that the\n * snapshot carries. Blocks read `names.css` for the authoritative CSS\n * variable name and `previewValue` for the display-ready CSS string.\n * `source.loc` enables \"jump to authoring source\" affordances.\n *\n * Aliases `SlimListedToken` from core's `/snapshot-for-wire` subpath —\n * the single canonical wire shape; both the addon's plugin (server-side\n * emit) and blocks (consumer-side read) reference the same definition.\n */\nexport type VirtualTokenListingShape = SlimListedToken;\n\nexport type VirtualPresetShape = Preset;\n\n/**\n * Wire shape of the token graph — aliased from core's authoritative\n * `TokenGraph` so both the virtual module declaration and the React\n * context stay aligned with the same definition.\n */\nexport type VirtualTokenGraph = TokenGraph;\n\n/**\n * Full project data read by blocks. Populated by the addon's preview\n * decorator (from the virtual module) or constructed by hand in\n * non-Storybook consumers.\n */\nexport interface ProjectSnapshot {\n axes: readonly VirtualAxisShape[];\n activeTheme: string;\n activeAxes: Readonly<Record<string, string>>;\n cssVarPrefix: string;\n /**\n * Project-wide baseline for the row-indicator strip from\n * `config.indicators`. Sits between the hard-coded indicator defaults\n * and a block's `indicators` prop. Optional — hand-built snapshots\n * (tests, MDX) omit it and blocks fall back to the bare defaults.\n */\n indicators?: Readonly<Record<string, boolean>>;\n diagnostics: readonly VirtualDiagnosticShape[];\n css: string;\n /**\n * Path-indexed Token Listing data produced by\n * `@terrazzo/plugin-token-listing`. Blocks prefer reading authoritative\n * CSS var names and preview values from here; empty for non-resolver\n * projects. Treat as enrichment — fall back gracefully when a path is\n * absent.\n */\n listing?: Readonly<Record<string, VirtualTokenListingShape>>;\n /**\n * Pre-built token graph for the project. JSON-serializable; nodes\n * carry per-axis writes plus alias edges. The blocks hook backs\n * `resolveAt` and variance from this graph.\n */\n tokenGraph?: VirtualTokenGraph;\n /** The default tuple — `{ axis: axis.default }` for every axis. */\n defaultTuple: Record<string, string>;\n /**\n * Pre-built `resolveAt(tuple)` accessor. The addon's preview decorator\n * instantiates this once per iframe lifetime. When present, use-project\n * prefers it over building its own from `tokenGraph`, so it MUST preserve\n * alias provenance — back it with `resolveAllWithProvenanceAt`, not the raw\n * leaf `resolveAllAt`, or axis-varying aliases silently lose their chain /\n * reverse refs / description at non-default tuples. Hand-built snapshots\n * (tests, MDX) can omit this; blocks then fall back to a provenance-aware\n * graph-backed resolver built from `tokenGraph`.\n */\n resolveAt?: (tuple: Record<string, string>) => Record<string, VirtualTokenShape>;\n}\n\n/**\n * Context carrying the full {@link ProjectSnapshot}. `null` sentinel lets\n * `useSwatchbookData()` tell \"provider present\" from \"fall back to the\n * virtual module\".\n */\nexport const SwatchbookContext = createContext<ProjectSnapshot | null>(null);\n\nexport function useOptionalSwatchbookData(): ProjectSnapshot | null {\n return useContext(SwatchbookContext);\n}\n\n/**\n * Active swatchbook theme for the current story/docs render. Populated by\n * the addon's preview decorator and consumed by `useToken` + any future\n * consumer hooks.\n *\n * This runs through plain React context rather than Storybook's\n * `useGlobals` so the same hook works in autodocs / MDX renders where the\n * preview-hooks context isn't available.\n */\nexport const ThemeContext = createContext<string>('');\n\nexport function useActiveTheme(): string {\n return useContext(ThemeContext);\n}\n\n/**\n * Active axis tuple for the current story/docs render — `Record<axisName,\n * contextName>`. Derived from the same input as {@link ThemeContext}; split\n * out so consumers needing per-axis info (toolbar, panel, tuple-aware\n * blocks) don't have to reparse the composed theme name.\n */\nexport const AxesContext = createContext<Readonly<Record<string, string>>>({});\n\nexport function useActiveAxes(): Readonly<Record<string, string>> {\n return useContext(AxesContext);\n}\n\n/**\n * Active color-display format for the current story/docs render. Populated\n * by the addon's preview decorator from the `swatchbookColorFormat` global\n * (per-story `globals` or toolbar dropdown) and consumed by blocks that\n * render color-token values. Emitted CSS is unaffected.\n *\n * Runs through plain React context rather than Storybook's `useGlobals` so\n * per-story seeded globals flow through on first render and the same hook\n * is safe to call from MDX doc blocks (where the preview-hooks context\n * isn't available).\n */\nexport const ColorFormatContext = createContext<ColorFormat | null>(null);\n\nexport function useColorFormat(): ColorFormat {\n const contextValue = useContext(ColorFormatContext);\n const channelGlobals = useChannelGlobals();\n return contextValue ?? channelGlobals.format ?? 'hex';\n}\n","import { useSyncExternalStore } from 'react';\nimport { addons } from 'storybook/preview-api';\nimport type { VirtualTokenGraph, VirtualTokenListingShape } from '#/contexts.ts';\nimport type { VirtualAxis, VirtualDiagnostic } from '#/types.ts';\n\n/**\n * Live token snapshot backed by the addon's preview dev-time HMR event.\n *\n * The initial snapshot is *injected* by the addon preview via\n * {@link registerTokenSource} rather than imported from the addon's\n * `virtual:swatchbook/tokens` build artifact — so blocks carries no\n * dependency on that module and imports cleanly standalone (outside\n * Storybook, in unit tests, in the docs site). Until something registers\n * a source, blocks render from empty defaults.\n *\n * For dev-time updates this module subscribes to `TOKENS_UPDATED_EVENT`\n * on Storybook's channel (which the addon preview re-broadcasts from its\n * own HMR listener) and exposes the latest snapshot via\n * `useSyncExternalStore`, so hooks re-render in place on each token save.\n */\n\n// The dev-time HMR wire event. Single source of truth: the addon preview\n// emits it, this module listens — exported so the two can't drift.\nexport const TOKENS_UPDATED_EVENT = 'swatchbook/tokens-updated';\n\nexport interface TokenSnapshot {\n readonly axes: readonly VirtualAxis[];\n readonly presets: readonly {\n name: string;\n axes: Partial<Record<string, string>>;\n description?: string;\n }[];\n readonly diagnostics: readonly VirtualDiagnostic[];\n readonly css: string;\n readonly cssVarPrefix: string;\n /** Project-wide baseline for the row-indicator strip from `config.indicators`. */\n readonly indicators: Readonly<Record<string, boolean>>;\n readonly listing: Readonly<Record<string, VirtualTokenListingShape>>;\n readonly tokenGraph: VirtualTokenGraph;\n readonly defaultTuple: Record<string, string>;\n /** Monotonic counter, bumped on each update. Useful as a React key. */\n readonly version: number;\n}\n\nconst EMPTY_TOKEN_GRAPH: VirtualTokenGraph = {\n nodes: {},\n axes: [],\n axisDefaults: {},\n axisContexts: {},\n};\n\nconst EMPTY_SNAPSHOT: TokenSnapshot = {\n axes: [],\n presets: [],\n diagnostics: [],\n css: '',\n cssVarPrefix: '',\n indicators: {},\n listing: {},\n tokenGraph: EMPTY_TOKEN_GRAPH,\n defaultTuple: {},\n version: 0,\n};\n\nlet snapshot: TokenSnapshot = EMPTY_SNAPSHOT;\n\nconst listeners = new Set<() => void>();\nlet subscribed = false;\n\n// Merge a partial payload over the current snapshot, keeping prior values\n// for omitted fields and bumping the version. Shared by the injected\n// initial source and the dev-time channel updates.\nfunction applyPatch(patch: Partial<TokenSnapshot>): void {\n snapshot = {\n axes: patch.axes ?? snapshot.axes,\n presets: patch.presets ?? snapshot.presets,\n diagnostics: patch.diagnostics ?? snapshot.diagnostics,\n css: patch.css ?? snapshot.css,\n cssVarPrefix: patch.cssVarPrefix ?? snapshot.cssVarPrefix,\n indicators: patch.indicators ?? snapshot.indicators,\n listing: patch.listing ?? snapshot.listing,\n tokenGraph: patch.tokenGraph ?? snapshot.tokenGraph,\n defaultTuple: patch.defaultTuple ?? snapshot.defaultTuple,\n version: snapshot.version + 1,\n };\n for (const cb of listeners) cb();\n}\n\n/**\n * Seed the initial token snapshot. The addon preview calls this once at\n * init with the build-time `virtual:swatchbook/tokens` data. Keeping the\n * virtual-module read on the addon side (the package that owns it) lets\n * blocks import cleanly without it. No-op fields fall back to the current\n * snapshot, so a partial source is safe.\n */\nexport function registerTokenSource(source: Partial<TokenSnapshot>): void {\n applyPatch(source);\n}\n\nfunction ensureSubscribed(): void {\n if (subscribed || typeof window === 'undefined') return;\n subscribed = true;\n const channel = addons.getChannel();\n channel.on(TOKENS_UPDATED_EVENT, (payload: Partial<TokenSnapshot>) => {\n applyPatch(payload);\n });\n}\n\nensureSubscribed();\n\nfunction subscribe(cb: () => void): () => void {\n ensureSubscribed();\n listeners.add(cb);\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): TokenSnapshot {\n return snapshot;\n}\n\nfunction getServerSnapshot(): TokenSnapshot {\n return snapshot;\n}\n\nexport function useTokenSnapshot(): TokenSnapshot {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import {\n resolveAllWithProvenanceAt,\n getVariance,\n listPaths,\n} from '@unpunnyfuns/swatchbook-core/graph';\nimport { makeCssVar } from '@unpunnyfuns/swatchbook-core/css-var';\nimport {\n ensureStyleElement,\n SWATCHBOOK_STYLE_ELEMENT_ID,\n} from '@unpunnyfuns/swatchbook-core/style-element';\nimport { tupleToName } from '@unpunnyfuns/swatchbook-core/themes';\nimport type { AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { useEffect, useMemo } from 'react';\nimport type { VirtualTokenGraph, VirtualTokenListingShape } from '#/contexts.ts';\n\ntype VirtualVarianceByPathShape = Record<string, AxisVarianceResult>;\n\n// Pre-compute variance for every path in the graph. `getVariance` is cheap\n// (O(paths × axes)); callers wrap this in `useMemo` keyed on the graph so it\n// recomputes only on an HMR refresh. Shared by the provider and fallback paths.\nfunction computeVarianceByPath(graph: VirtualTokenGraph | undefined): VirtualVarianceByPathShape {\n if (!graph) return {};\n const out: VirtualVarianceByPathShape = {};\n for (const path of listPaths(graph)) {\n out[path] = getVariance(graph, path);\n }\n return out;\n}\nimport { useActiveAxes, useActiveTheme, useOptionalSwatchbookData } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat, FormatColorResult } from '#/format-color.ts';\nimport { useChannelGlobals } from '#/internal/channel-globals.ts';\nimport { useTokenSnapshot } from '#/internal/channel-tokens.ts';\nimport type { ProjectSnapshot, VirtualAxis, VirtualDiagnostic, VirtualToken } from '#/types.ts';\n\ntype ResolvedTokens = Record<string, VirtualToken>;\n\nexport interface ProjectData {\n activeTheme: string;\n activeAxes: Record<string, string>;\n axes: readonly VirtualAxis[];\n resolved: ResolvedTokens;\n diagnostics: readonly VirtualDiagnostic[];\n cssVarPrefix: string;\n /**\n * Project-wide baseline for the row-indicator strip from\n * `config.indicators`. `{}` when absent. Strip-hosting blocks pass it as\n * the baseline arg to `resolveIndicators` so a per-block `indicators`\n * prop overrides it.\n */\n indicators: Readonly<Record<string, boolean>>;\n /**\n * Path-indexed Token Listing data. Empty when absent (non-resolver\n * projects, hand-built snapshots that don't populate it). Blocks read\n * authoritative CSS var names from `listing[path].names.css` and\n * preview strings from `listing[path].previewValue`.\n */\n listing: Readonly<Record<string, VirtualTokenListingShape>>;\n /**\n * Cached per-path `AxisVarianceResult` — blocks use this for O(1)\n * variance lookup instead of re-running the analysis on every\n * render.\n */\n varianceByPath: VirtualVarianceByPathShape;\n /**\n * Compose the resolved `TokenMap` for any tuple of axis selections.\n * Backed browser-side by `resolveAllWithProvenanceAt` over the `tokenGraph`.\n */\n resolveAt: (tuple: Record<string, string>) => ResolvedTokens;\n}\n\nfunction ensureStylesheet(css: string): void {\n ensureStyleElement(SWATCHBOOK_STYLE_ELEMENT_ID, css);\n}\n\nfunction defaultTuple(axes: readonly VirtualAxis[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (const axis of axes) out[axis.name] = axis.default;\n return out;\n}\n\n// Build a `resolveAt` accessor backed by the token graph. Returns an\n// empty resolver when no graph is present (test stubs, partial\n// snapshots). Stable identity when memoized on `tokenGraph` — the\n// graph is a module-level virtual-module export so its reference stays\n// constant for the lifetime of the iframe.\nfunction makeResolveAt(\n graph: VirtualTokenGraph | undefined,\n): (tuple: Record<string, string>) => ResolvedTokens {\n if (!graph) return () => ({});\n return (tuple) => resolveAllWithProvenanceAt(graph, tuple) as unknown as ResolvedTokens;\n}\n\n// Build the `resolveAt` accessor for a snapshot. Prefers the\n// snapshot's own `resolveAt` (the addon's preview decorator\n// pre-builds one at module load — see `previewResolveAt` in\n// `packages/addon/src/preview.tsx`), otherwise builds one from\n// `tokenGraph`. Hand-built snapshots can omit `resolveAt`;\n// the graph-backed fallback covers them.\nfunction snapshotResolveAt(\n snapshot: ProjectSnapshot,\n): (tuple: Record<string, string>) => ResolvedTokens {\n if (snapshot.resolveAt)\n return snapshot.resolveAt as (tuple: Record<string, string>) => ResolvedTokens;\n return makeResolveAt(snapshot.tokenGraph);\n}\n\n/**\n * Reads project data either from a mounted {@link SwatchbookProvider}\n * (preferred — the addon's preview decorator installs one around every\n * story) or, when no provider is present, from the virtual module plus\n * Storybook globals directly.\n *\n * The provider-less path is what makes the hook safe to call from MDX\n * doc blocks and autodocs renders where no story is active. It\n * self-mounts the virtual module's per-theme CSS and tracks the active\n * tuple via the `globalsUpdated` channel event; {@link useGlobals} from\n * `storybook/preview-api` would throw outside a story render.\n */\nexport function useProject(): ProjectData {\n const snapshot = useOptionalSwatchbookData();\n // Memoize against the stable underlying fields, NOT the snapshot\n // wrapper. Storybook rebuilds `context.globals` identity on every\n // render → the preview's `tuple` useMemo invalidates → the\n // provider's snapshot useMemo rebuilds. Keying off `snapshot`\n // would mean `makeResolveAt` runs on every render, producing a\n // fresh closure with a fresh internal memo, so `resolved` would\n // have a new identity each render. Downstream block\n // `useMemo([resolved, …])` calls would recompute forever; the\n // `TokenNavigator`'s focus-repair `useEffect` (deps include the\n // recomputed `flatVisible`) would `setState` in an infinite loop.\n // The underlying `tokenGraph` reference is a stable module-level\n // virtual-module export, so depending on it directly keeps `resolveAt`\n // (and the resolved map it returns) referentially stable across renders.\n const axes = snapshot?.axes;\n const activeAxes = snapshot?.activeAxes;\n const activeTheme = snapshot?.activeTheme;\n const diagnostics = snapshot?.diagnostics;\n const cssVarPrefix = snapshot?.cssVarPrefix;\n const indicators = snapshot?.indicators;\n const listing = snapshot?.listing;\n const tokenGraph = snapshot?.tokenGraph;\n const resolveAt = useMemo(() => {\n if (!snapshot) return null;\n return snapshotResolveAt(snapshot);\n // The deps below are deliberately the stable inner fields rather\n // than `snapshot` itself; see the long block comment above.\n // `tokenGraph` is a stable module-level virtual-module export, so\n // depending on it directly keeps `resolveAt` (and the resolved map\n // it returns) referentially stable across renders.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tokenGraph, activeTheme]);\n const derivedVarianceByPath = useMemo(() => computeVarianceByPath(tokenGraph), [tokenGraph]);\n // Memoize the returned ProjectData against the same stable inner\n // fields — without this, blocks `useMemo([project, …])` calls\n // invalidate every render (the function returns a fresh object\n // identity), defeating the per-block memoization that\n // `TokenNavigator` / `TokenTable` / `ColorPalette` rely on.\n const providerData = useMemo<ProjectData | null>(() => {\n if (!snapshot || !resolveAt || !axes || !activeAxes) return null;\n return {\n activeTheme: activeTheme ?? '',\n activeAxes: activeAxes as Record<string, string>,\n axes,\n resolved: resolveAt(activeAxes as Record<string, string>),\n diagnostics: diagnostics ?? [],\n cssVarPrefix: cssVarPrefix ?? '',\n indicators: indicators ?? {},\n listing: listing ?? {},\n varianceByPath: derivedVarianceByPath,\n resolveAt,\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n snapshot,\n resolveAt,\n axes,\n activeTheme,\n activeAxes,\n diagnostics,\n cssVarPrefix,\n indicators,\n listing,\n derivedVarianceByPath,\n tokenGraph,\n ]);\n const fallback = useVirtualModuleFallback(snapshot === null);\n return providerData ?? fallback;\n}\n\nfunction useVirtualModuleFallback(enabled: boolean): ProjectData {\n const contextThemeName = useActiveTheme();\n const contextAxes = useActiveAxes();\n const channelGlobals = useChannelGlobals();\n // Subscribe to the live token snapshot rather than reading the virtual\n // module's module-level exports directly. Initial values come from\n // `virtual:swatchbook/tokens` at load time; subsequent dev-time edits\n // flow through the addon's HMR channel and update this snapshot in\n // place so blocks re-render without a full preview reload.\n const tokens = useTokenSnapshot();\n\n useEffect(() => {\n if (!enabled) return;\n ensureStylesheet(tokens.css);\n }, [enabled, tokens.css]);\n\n // Memoize against the stable identities — `contextAxes` is a\n // useContext value that's stable across renders unless the\n // provider mutates; `channelGlobals.axes` updates on channel\n // events; `tokens.axes` is a stable virtual-module export.\n // Without this memo `activeAxes` would have fresh identity per\n // render and defeat downstream `useMemo([project, …])` calls.\n const activeAxes = useMemo<Record<string, string>>(() => {\n const hasContextAxes = Object.keys(contextAxes).length > 0;\n return hasContextAxes ? { ...contextAxes } : (channelGlobals.axes ?? defaultTuple(tokens.axes));\n }, [contextAxes, channelGlobals.axes, tokens.axes]);\n\n const activeTheme = contextThemeName || tupleToName(tokens.axes, activeAxes);\n\n // `resolveAllWithProvenanceAt` is a pure function over the graph; the only memo\n // we need is for the outer closure so React's reference equality\n // stays stable between renders. `tokens.tokenGraph` is the stable\n // module-level virtual-module export — changes only on HMR refresh.\n const resolveAt = useMemo(() => makeResolveAt(tokens.tokenGraph), [tokens.tokenGraph]);\n\n const fallbackVarianceByPath = useMemo(\n () => computeVarianceByPath(tokens.tokenGraph),\n [tokens.tokenGraph],\n );\n\n // Memoize the returned ProjectData against the stable inner fields\n // for the same reason the provider path does — fresh object identity\n // per render would defeat `useMemo([project, …])` in every block.\n return useMemo<ProjectData>(\n () => ({\n activeTheme,\n activeAxes,\n axes: tokens.axes,\n resolved: resolveAt(activeAxes),\n diagnostics: tokens.diagnostics,\n cssVarPrefix: tokens.cssVarPrefix,\n indicators: tokens.indicators,\n listing: tokens.listing,\n varianceByPath: fallbackVarianceByPath,\n resolveAt,\n }),\n [\n activeTheme,\n activeAxes,\n tokens.axes,\n tokens.diagnostics,\n tokens.cssVarPrefix,\n tokens.indicators,\n tokens.listing,\n fallbackVarianceByPath,\n resolveAt,\n ],\n );\n}\n\n/**\n * Resolve a token's CSS var reference, preferring the authoritative name\n * emitted by `@terrazzo/plugin-css` (as recorded by\n * `@terrazzo/plugin-token-listing` in the snapshot's `listing` field).\n * Falls back to `makeCssVar` when the listing lacks an entry for this\n * path — covers non-resolver projects, hand-built snapshots, and any\n * listing-plugin miss.\n */\nexport function resolveCssVar(\n path: string,\n project: Pick<ProjectData, 'listing' | 'cssVarPrefix'>,\n): string {\n const listed = project.listing[path]?.names?.['css'];\n if (listed) return `var(${listed})`;\n return makeCssVar(path, project.cssVarPrefix);\n}\n\n/**\n * Resolve a color value's display string + gamut flag, preferring the\n * listing's `previewValue` when the user's active color-format matches\n * plugin-css's output (hex). For any other format we fall back to\n * `formatColor` so the toolbar's inspection modes (rgb / hsl / oklch /\n * raw) keep working — the listing has only one canonical format.\n *\n * Pass `path === undefined` when resolving a sub-color inside a composite\n * (shadow / border / gradient stop): composites' `previewValue` covers\n * the whole token's rendering, not the individual channel, so there's no\n * listing entry to key against.\n */\nexport function resolveColorValue(\n path: string | undefined,\n raw: unknown,\n colorFormat: ColorFormat,\n project: Pick<ProjectData, 'listing'>,\n): FormatColorResult {\n if (path !== undefined && colorFormat === 'hex') {\n const listed = project.listing[path]?.previewValue;\n if (typeof listed === 'string') {\n return { value: listed, outOfGamut: false };\n }\n }\n return formatColor(raw, colorFormat);\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { SURFACE_RAISED } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport interface BorderSampleProps {\n /** Full dot-path of the border token to preview. */\n path: string;\n}\n\nconst sampleStyle: CSSProperties = {\n width: 120,\n height: 56,\n background: SURFACE_RAISED,\n borderRadius: 6,\n};\n\nexport function BorderSample({ path }: BorderSampleProps): ReactElement {\n const project = useProject();\n const cssVar = resolveCssVar(path, project);\n return <div style={{ ...sampleStyle, border: cssVar }} aria-hidden />;\n}\n","import { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\n\n/**\n * Display a composite sub-field dimension (shadow offset / blur / spread,\n * border width, …) in the preview tables. Renders `—` for a missing\n * sub-field and falls back to JSON for shapes it doesn't recognize.\n *\n * Distinct from `format-token-value`'s internal `formatDimension`, which\n * formats a token's top-level value and has no `—` placeholder — these are\n * the per-layer sample formatters shared by `ShadowPreview` + `BorderPreview`.\n */\nexport function formatDimension(raw: unknown): string {\n if (raw == null) return '—';\n if (typeof raw === 'number') return String(raw);\n if (typeof raw === 'string') return raw;\n if (typeof raw === 'object') {\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value === 'number' && typeof v.unit === 'string') {\n return `${v.value}${v.unit}`;\n }\n }\n return JSON.stringify(raw);\n}\n\n/** Display a composite sub-field color via the active format; `—` when absent. */\nexport function formatSubColor(raw: unknown, format: ColorFormat): string {\n if (raw == null) return '—';\n return formatColor(raw, format).value;\n}\n","import { dataAttr } from '@unpunnyfuns/swatchbook-core/data-attr';\n\n/**\n * Marker attribute set on every block wrapper. Retained as a stable hook\n * for consumer-side selectors (e.g. when a host app wants to target or\n * override block chrome without relying on hashed class names).\n */\nexport const BLOCK_ATTR = 'data-swatchbook-block';\n\n// Opt-out class that Storybook's `.sbdocs` stylesheet uses to self-exclude\n// on MDX docs pages — every `.sbdocs` house rule is wrapped in\n// `:not(.sb-unstyled, .sb-unstyled *)`, so any descendant of a `.sb-unstyled`\n// container is left alone. Stamped onto every block wrapper so blocks\n// render identically in MDX docs and regular stories without fighting\n// cascade specificity.\nconst WRAPPER_CLASSES = 'sb-unstyled sb-block';\n\n/**\n * Spread helper for the common block wrapper. Returns:\n * - One `data-<prefix>-<axisName>=\"<contextName>\"` per axis in the tuple.\n * These are what the smart CSS emitter actually targets — single-axis\n * cell selectors (`[data-<prefix>-mode=\"Dark\"]`) and joint compounds\n * (`[data-<prefix>-mode=\"Dark\"][data-<prefix>-brand=\"Brand A\"]`).\n * Wrapping a block subtree in these attrs lets the cascade resolve\n * per-tuple values inside the block independently of the document\n * root — `AxisVariance`'s grid uses this to render real per-cell\n * swatches.\n * - `data-swatchbook-block` — stable consumer hook for targeting block\n * chrome from outside.\n * - `className=\"sb-unstyled sb-block\"` — Storybook's opt-out class so\n * MDX docs house styles self-exclude the subtree, plus `sb-block`\n * which carries the shared chrome from `internal/styles.css`.\n */\nexport function blockWrapperAttrs(\n prefix: string,\n tuple: Readonly<Record<string, string>>,\n): Record<string, string> {\n return {\n ...perAxisAttrs(prefix, tuple),\n [BLOCK_ATTR]: '',\n className: WRAPPER_CLASSES,\n };\n}\n\n/**\n * Spread helper for any element that wants per-axis cell semantics\n * without the block-wrapper chrome — `AxisVariance`'s grid uses this\n * on each swatch so the swatch's CSS vars resolve at the cell's own\n * tuple, not the document root's active tuple.\n */\nexport function perAxisAttrs(\n prefix: string,\n tuple: Readonly<Record<string, string>>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [axisName, contextName] of Object.entries(tuple)) {\n out[dataAttr(prefix, axisName)] = contextName;\n }\n return out;\n}\n","import { parseColor } from '@unpunnyfuns/swatchbook-core/format-color';\nimport type { VirtualToken } from '#/types.ts';\n\nexport type SortBy = 'path' | 'value' | 'none';\nexport type SortDir = 'asc' | 'desc';\n\nexport interface SortOptions {\n by?: SortBy;\n dir?: SortDir;\n}\n\ntype Entry = readonly [string, VirtualToken];\n\n// Stable sort for a filtered `[path, token][]` list.\n//\n// `sortBy: 'path'` — lexicographic on the dot-path (locale-aware, numeric).\n// `sortBy: 'value'` — per-`$type` ordering:\n// - `dimension` / `duration` → numeric pixels / ms (via `toMagnitude`).\n// - `fontWeight` / `opacity` / `number` / `lineHeight` → numeric.\n// - `color` → perceptual by oklch L → C → H.\n// - `fontFamily` / `strokeStyle` (string form) → lexicographic.\n// - Composites (`typography`, `shadow`, `border`, `gradient`, `transition`) →\n// fall back to path-alpha. No useful single-axis order.\n// `sortBy: 'none'` — preserve input order (still respects `sortDir: 'desc'`\n// as a reverse).\n\n// Pre-computed per-token sort key — one of three shapes depending on\n// `$type`. The comparator looks the key up by token-reference once\n// per pair instead of recomputing on every comparison (Schwartzian\n// transform).\n//\n// For N tokens, sort does O(N log N) comparisons; per-call cost for\n// colors is an Oklch conversion (a `new Color()` + `to('oklch')`)\n// which dominates wall time on real fixtures. Pre-computing brings\n// that down to O(N) keys + O(N log N) cheap lookups.\ntype SortKey =\n | { kind: 'numeric'; value: number; valid: boolean }\n | { kind: 'color'; key: { l: number; c: number; h: number } | null }\n | { kind: 'string'; value: string }\n | { kind: 'none' };\n\nconst NUMERIC_TYPES = new Set([\n 'dimension',\n 'duration',\n 'fontWeight',\n 'opacity',\n 'number',\n 'lineHeight',\n]);\n\nconst STRING_TYPES = new Set(['fontFamily', 'strokeStyle']);\n\nfunction computeSortKey(token: VirtualToken): SortKey {\n const type = token.$type;\n if (!type) return { kind: 'none' };\n if (NUMERIC_TYPES.has(type)) {\n const value = toMagnitude(token.$value);\n return { kind: 'numeric', value, valid: Number.isFinite(value) };\n }\n if (type === 'color') {\n return { kind: 'color', key: colorKey(token.$value) };\n }\n if (STRING_TYPES.has(type)) {\n return { kind: 'string', value: toDisplayable(token.$value) };\n }\n // Composite types ($type: 'typography', 'shadow', 'border', …) have\n // no useful one-dimensional ordering — fall back to no-op.\n return { kind: 'none' };\n}\n\nexport function sortTokens(entries: readonly Entry[], options: SortOptions = {}): Entry[] {\n const by = options.by ?? 'path';\n const dir = options.dir ?? 'asc';\n const sign = dir === 'desc' ? -1 : 1;\n\n if (by === 'none') {\n return dir === 'desc' ? [...entries].toReversed() : [...entries];\n }\n\n if (by === 'path') {\n return [...entries].toSorted(\n ([a], [b]) => sign * a.localeCompare(b, undefined, { numeric: true }),\n );\n }\n\n // by === 'value' — pre-compute per-token sort keys once.\n const keys = new Map<VirtualToken, SortKey>();\n for (const [, token] of entries) {\n keys.set(token, computeSortKey(token));\n }\n\n return [...entries].toSorted(([aPath, aTok], [bPath, bTok]) => {\n const cmp = compareValue(aTok, bTok, keys);\n if (cmp !== 0) return sign * cmp;\n // Stable tiebreak on path so the order is deterministic when values equal.\n return sign * aPath.localeCompare(bPath, undefined, { numeric: true });\n });\n}\n\nfunction compareValue(\n a: VirtualToken,\n b: VirtualToken,\n keys: ReadonlyMap<VirtualToken, SortKey>,\n): number {\n // When the two tokens differ in $type, fall back to type-alpha so at\n // least the mixed list clusters by type.\n if (a.$type !== b.$type) return String(a.$type ?? '').localeCompare(String(b.$type ?? ''));\n\n const ak = keys.get(a);\n const bk = keys.get(b);\n if (!ak || !bk) return 0;\n // Matches the `a.$type === b.$type` check above.\n if (ak.kind !== bk.kind) return 0;\n\n if (ak.kind === 'numeric' && bk.kind === 'numeric') {\n if (ak.valid && bk.valid) return ak.value - bk.value;\n if (ak.valid) return -1;\n if (bk.valid) return 1;\n return 0;\n }\n\n if (ak.kind === 'color' && bk.kind === 'color') {\n const a3 = ak.key;\n const b3 = bk.key;\n if (!a3 && !b3) return 0;\n if (!a3) return 1;\n if (!b3) return -1;\n if (a3.l !== b3.l) return a3.l - b3.l;\n if (a3.c !== b3.c) return a3.c - b3.c;\n return a3.h - b3.h;\n }\n\n if (ak.kind === 'string' && bk.kind === 'string') {\n return ak.value.localeCompare(bk.value, undefined, { numeric: true });\n }\n\n return 0;\n}\n\nfunction toMagnitude(v: unknown): number {\n if (typeof v === 'number') return v;\n if (v && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value !== 'number') return Number.NaN;\n if (typeof d.unit !== 'string') return d.value;\n switch (d.unit) {\n case 'px':\n case 'ms':\n return d.value;\n case 's':\n return d.value * 1000;\n case 'rem':\n case 'em':\n return d.value * 16;\n default:\n return d.value;\n }\n }\n return Number.NaN;\n}\n\n// Coerce a possibly-null/undefined number to 0 — `coords` returns\n// `(number | null)[]` and `noUncheckedIndexedAccess` adds `undefined`\n// on top. `typeof` narrows the union for the comparator below.\nfunction safeNumber(v: number | null | undefined): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : 0;\n}\n\nfunction colorKey(v: unknown): { l: number; c: number; h: number } | null {\n // parseColor applies the colorjs space-alias map, so wide-gamut spaces\n // (display-p3, a98-rgb, prophoto-rgb) yield a perceptual key instead of\n // throwing and sinking the token to the end of a value sort.\n const color = parseColor(v);\n if (!color) return null;\n try {\n const [l, chroma, h] = color.to('oklch').coords;\n return { l: safeNumber(l), c: safeNumber(chroma), h: safeNumber(h) };\n } catch {\n return null;\n }\n}\n\nfunction toDisplayable(v: unknown): string {\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n if (v && typeof v === 'object') return JSON.stringify(v);\n return String(v ?? '');\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './BorderPreview.css';\nimport { BorderSample } from '#/border-preview/BorderSample.tsx';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatDimension, formatSubColor } from '#/internal/composite-sample-format.ts';\nimport type { BorderValue } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface BorderPreviewProps {\n /**\n * Token-path filter. Defaults to every `border` token. Use e.g.\n * `\"border.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (borders don't have a\n * single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n value: BorderValue;\n}\n\nexport function BorderPreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: BorderPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'border') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n value: (token.$value ?? {}) as BorderValue,\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} border${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No border tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-border-preview__row\">\n <div className=\"sb-border-preview__meta\">\n <span className=\"sb-border-preview__path\">{row.path}</span>\n <span className=\"sb-border-preview__css-var\">{row.cssVar}</span>\n </div>\n <div className=\"sb-border-preview__sample-cell\">\n <BorderSample path={row.path} />\n </div>\n <div className=\"sb-border-preview__breakdown\">\n <span className=\"sb-border-preview__breakdown-key\">width</span>\n <span>{formatDimension(row.value.width)}</span>\n <span className=\"sb-border-preview__breakdown-key\">style</span>\n <span>{row.value.style != null ? String(row.value.style) : '—'}</span>\n <span className=\"sb-border-preview__breakdown-key\">color</span>\n <span>{formatSubColor(row.value.color, colorFormat)}</span>\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './ColorPalette.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface ColorPaletteProps {\n /**\n * Token-path filter. Defaults to every `color` token. Use e.g.\n * `\"color.*\"` to scope to the semantic layer, or `\"color.palette.blue.*\"`\n * for a single ref ramp.\n */\n filter?: string;\n /**\n * Grouping depth. Tokens are grouped by the first `groupBy` dot-segments\n * of their path. `1` yields a single `color` group; `2` yields\n * `color.surface`, `color.text`, `color.blue`, etc.\n *\n * If omitted, groupBy is derived from the filter: one level below the\n * filter's fixed prefix (segments before the first `*`), clamped so each\n * swatch still carries a leaf label. `\"color.*\"` → groups at\n * `color.<family>`; `\"color.palette.blue.*\"` collapses all shades into\n * one `color.blue` group because the tokens have no deeper level.\n */\n groupBy?: number;\n /** Override the section caption. */\n caption?: string;\n /**\n * Sort order within each group.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — perceptual ordering: oklch L → C → H (ramps read\n * light→dark, then warm→cool within each lightness band).\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Swatch {\n path: string;\n leaf: string;\n cssVar: string;\n value: string;\n outOfGamut: boolean;\n}\n\n// Count segments in the filter before the first glob (`*` / `**`).\n// `color.*` → 2; `color.surface.*` → 3; `color` → 1; undefined → 0.\nfunction fixedPrefixLength(filter: string | undefined): number {\n if (!filter) return 0;\n const segments = filter.split('.');\n let fixed = 0;\n for (const seg of segments) {\n if (seg === '*' || seg === '**') break;\n fixed += 1;\n }\n return fixed;\n}\n\nexport function ColorPalette({\n filter,\n groupBy,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: ColorPaletteProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = project;\n const colorFormat = useColorFormat();\n\n const groups = useMemo(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'color') return false;\n return matchPath(path, filter);\n });\n const entries = sortTokens(filtered, { by: sortBy, dir: sortDir });\n\n const maxDepth = entries.reduce((m, [p]) => Math.max(m, p.split('.').length), 0);\n const effectiveGroupBy =\n groupBy ?? Math.min(fixedPrefixLength(filter) + 1, Math.max(maxDepth - 1, 1));\n\n const bucket = new Map<string, Swatch[]>();\n for (const [path, token] of entries) {\n const segments = path.split('.');\n const groupKey = segments.slice(0, effectiveGroupBy).join('.');\n const leaf = segments.slice(effectiveGroupBy).join('.') || segments.at(-1) || path;\n const list = bucket.get(groupKey) ?? [];\n const formatted = resolveColorValue(path, token.$value, colorFormat, projectFields);\n list.push({\n path,\n leaf,\n cssVar: resolveCssVar(path, projectFields),\n value: formatted.value,\n outOfGamut: formatted.outOfGamut,\n });\n bucket.set(groupKey, list);\n }\n\n return [...bucket.entries()].toSorted(([a], [b]) =>\n a.localeCompare(b, undefined, { numeric: true }),\n );\n }, [resolved, listing, cssVarPrefix, filter, groupBy, colorFormat, sortBy, sortDir]);\n\n const totalCount = groups.reduce((acc, [, swatches]) => acc + swatches.length, 0);\n const captionText =\n caption ??\n `${totalCount} color${totalCount === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (totalCount === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No color tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {groups.map(([group, swatches]) => (\n <section key={group} className=\"sb-color-palette__group\">\n <div className=\"sb-color-palette__group-header\">{group}</div>\n <div className=\"sb-color-palette__grid\">\n {swatches.map((swatch) => (\n <div key={swatch.path} className=\"sb-color-palette__card\">\n <div\n className=\"sb-color-palette__swatch\"\n style={{ background: swatch.cssVar }}\n aria-hidden\n />\n <div className=\"sb-color-palette__meta\">\n <span className=\"sb-color-palette__leaf\">{swatch.leaf}</span>\n <span className=\"sb-color-palette__value\">\n {swatch.value}\n {swatch.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-color-palette__gamut-warn\"\n >\n {' '}\n ⚠\n </span>\n )}\n </span>\n </div>\n </div>\n ))}\n </div>\n </section>\n ))}\n </div>\n );\n}\n","/** The individually-toggleable indicators in the row strip. `alias` covers the whole alias unit (forward chain + reverse count). */\nexport type IndicatorName =\n | 'alias'\n | 'variance'\n | 'gamut'\n | 'deprecation'\n | 'description'\n | 'composes';\n\n/**\n * Consumer-facing indicator config for the strip-hosting blocks:\n * - `true` — every indicator on (including the opt-in `description`)\n * - `false` — every indicator off\n * - object — per-key override layered over the defaults\n * - omitted — the defaults\n */\nexport type IndicatorsProp = boolean | Partial<Record<IndicatorName, boolean>>;\n\n/** Established-on set; `description` and `composes` are opt-in. */\nconst DEFAULT_INDICATORS: Record<IndicatorName, boolean> = {\n alias: true,\n variance: true,\n gamut: true,\n deprecation: true,\n description: false,\n composes: false,\n};\n\n/**\n * Normalize an `IndicatorsProp` into a full enabled-map. Precedence\n * (lowest→highest): `DEFAULT_INDICATORS` → `baseline` (the project-wide\n * `config.indicators` default) → per-block `prop`. An explicit boolean\n * `prop` (`true`/`false`) forces every key on/off and wins over the\n * baseline; an object `prop` overlays on top of defaults+baseline; an\n * absent `prop` leaves the result at defaults overlaid with baseline.\n */\nexport function resolveIndicators(\n prop?: IndicatorsProp,\n baseline?: Partial<Record<IndicatorName, boolean>>,\n): Record<IndicatorName, boolean> {\n if (prop === true) {\n return {\n alias: true,\n variance: true,\n gamut: true,\n deprecation: true,\n description: true,\n composes: true,\n };\n }\n if (prop === false) {\n return {\n alias: false,\n variance: false,\n gamut: false,\n deprecation: false,\n description: false,\n composes: false,\n };\n }\n return { ...DEFAULT_INDICATORS, ...baseline, ...prop };\n}\n","import type { AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactElement } from 'react';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { VirtualTokenShape } from '#/contexts.ts';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorName } from '#/indicators/resolve.ts';\nimport './indicators.css';\n\nexport interface RowIndicatorsProps {\n path: string;\n token: VirtualTokenShape;\n /** Active navigator root prefix, for relative chain-node labels. */\n root: string | undefined;\n /** Per-path variance result for the variance badge. */\n variance: AxisVarianceResult | undefined;\n /** Active color format, for the gamut check (color rows only). */\n colorFormat: ColorFormat;\n /** True when a referenced path can be acted on. */\n canReference: (path: string) => boolean;\n /** Act on a referenced path — the host decides what that means: the navigator moves the tree, the table opens detail. */\n onReferenceClick: (path: string) => void;\n /** Resolved enabled-map (from `resolveIndicators`). Defaults to the established four-on set. */\n enabled?: Record<IndicatorName, boolean>;\n}\n\n// Strip the navigator's `root` prefix from a path for a compact chain label.\nfunction relativeLabel(path: string, root: string | undefined): string {\n if (root && path.startsWith(`${root}.`)) return path.slice(root.length + 1);\n return path;\n}\n\n// DTCG composite `$type`s — the same set core's token-graph build keys on\n// (build.ts COMPOSITE_TYPES). Only these carry a meaningful sub-part count;\n// other object-valued tokens (a 2025-spec color, say) must not be badged.\nconst COMPOSITE_TYPES = new Set(['border', 'typography', 'transition', 'gradient', 'shadow']);\n\n// Number of constituent parts a composite token bundles: object fields for\n// typography / border / transition / object-form shadow, stops/layers for an\n// array-form gradient or shadow. `undefined` for non-composites and for an\n// aliased composite (string `$value`), which compose nothing locally.\nfunction compositeFieldCount(token: VirtualTokenShape): number | undefined {\n if (!token.$type || !COMPOSITE_TYPES.has(token.$type)) return undefined;\n const v = token.$value;\n if (Array.isArray(v)) return v.length > 0 ? v.length : undefined;\n if (v !== null && typeof v === 'object') {\n const n = Object.keys(v).length;\n return n > 0 ? n : undefined;\n }\n return undefined;\n}\n\ninterface ForwardChainProps {\n chain: readonly string[];\n root: string | undefined;\n canReference: (path: string) => boolean;\n onReferenceClick: (path: string) => void;\n}\n\n/**\n * The forward alias chain for one row. Full chain in `aria-label`; visually\n * capped to first … last beyond two hops (no width measurement). Each shown\n * node navigates when in view, else renders as plain text.\n */\nfunction ForwardChain({\n chain,\n root,\n canReference,\n onReferenceClick,\n}: ForwardChainProps): ReactElement {\n const full = chain.map((p) => relativeLabel(p, root)).join(' → ');\n const capped = chain.length > 2;\n const shown = capped ? [chain[0] as string, chain[chain.length - 1] as string] : [...chain];\n\n return (\n <span\n className=\"sb-indicator__alias-forward\"\n data-testid=\"row-indicator-alias-forward\"\n aria-label={`aliases ${full}`}\n >\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n →\n </span>\n {shown.map((target, i) => {\n const label = relativeLabel(target, root);\n const node = canReference(target) ? (\n <button\n type=\"button\"\n className=\"sb-indicator__alias-node\"\n data-testid=\"alias-node\"\n aria-label={target}\n onClick={(e) => {\n e.stopPropagation();\n onReferenceClick(target);\n }}\n >\n {label}\n </button>\n ) : (\n <span\n className=\"sb-indicator__alias-node sb-indicator__alias-node--offview\"\n data-testid=\"alias-node\"\n title=\"outside current view\"\n >\n {label}\n </span>\n );\n const sep =\n capped && i === 0 ? (\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n {' '}\n → … →{' '}\n </span>\n ) : i < shown.length - 1 ? (\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n {' '}\n →{' '}\n </span>\n ) : null;\n return (\n <span key={target}>\n {node}\n {sep}\n </span>\n );\n })}\n </span>\n );\n}\n\ninterface DeprecatedBadgeProps {\n deprecated: string | boolean;\n}\n\nfunction DeprecatedBadge({ deprecated }: DeprecatedBadgeProps): ReactElement {\n const label = typeof deprecated === 'string' ? `deprecated: ${deprecated}` : 'deprecated';\n return (\n <span\n className=\"sb-indicator__deprecated\"\n data-testid=\"row-indicator-deprecated\"\n title={label}\n aria-label={label}\n >\n deprecated\n </span>\n );\n}\n\ninterface VarianceBadgeProps {\n variance: AxisVarianceResult;\n}\n\nfunction VarianceBadge({ variance }: VarianceBadgeProps): ReactElement | null {\n if (variance.kind === 'constant') return null;\n const axes = variance.varyingAxes;\n const label = variance.kind === 'single' ? variance.axis : `${axes.length} axes`;\n return (\n <span\n className=\"sb-indicator__variance\"\n data-testid=\"row-indicator-variance\"\n aria-label={`varies by ${axes.join(', ')}`}\n >\n <span className=\"sb-indicator__variance-glyph\" aria-hidden>\n ⊹\n </span>\n {label}\n </span>\n );\n}\n\ninterface ReverseCountProps {\n referents: readonly string[];\n canReference: (path: string) => boolean;\n onReferenceClick: (path: string) => void;\n}\n\nfunction ReverseCount({\n referents,\n canReference,\n onReferenceClick,\n}: ReverseCountProps): ReactElement {\n const [open, setOpen] = useState(false);\n const wrapRef = useRef<HTMLSpanElement>(null);\n const count = referents.length;\n const single = count === 1;\n\n // Move focus to the first enabled menu item on open; close on outside pointerdown.\n useEffect(() => {\n if (single || !open) return;\n const first = wrapRef.current?.querySelector<HTMLElement>(\n 'button[role=\"menuitem\"]:not(:disabled)',\n );\n first?.focus();\n\n const handlePointerDown = (e: PointerEvent) => {\n if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener('pointerdown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n };\n }, [open, single]);\n\n return (\n <span\n ref={wrapRef}\n className=\"sb-indicator__reverse-wrap\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(false);\n }}\n >\n <button\n type=\"button\"\n className=\"sb-indicator__alias-reverse\"\n data-testid=\"row-indicator-alias-reverse\"\n aria-label={`referenced by ${count} ${count === 1 ? 'token' : 'tokens'}`}\n aria-haspopup={single ? undefined : 'menu'}\n aria-expanded={single ? undefined : open}\n onClick={(e) => {\n e.stopPropagation();\n if (single) onReferenceClick(referents[0] as string);\n else setOpen((v) => !v);\n }}\n >\n <span className=\"sb-indicator__alias-arrow\" aria-hidden>\n ←\n </span>\n {count}\n </button>\n {!single && open && (\n <ul className=\"sb-indicator__reverse-menu\" role=\"menu\">\n {referents.map((ref) => (\n <li key={ref} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"sb-indicator__reverse-item\"\n disabled={!canReference(ref)}\n title={canReference(ref) ? undefined : 'outside current view'}\n onClick={(e) => {\n e.stopPropagation();\n setOpen(false);\n onReferenceClick(ref);\n }}\n >\n {ref}\n </button>\n </li>\n ))}\n </ul>\n )}\n </span>\n );\n}\n\n/** Per-row indicator strip: alias references, variance, gamut, deprecation. */\nexport function RowIndicators(props: RowIndicatorsProps): ReactElement | null {\n const { token, root, variance, colorFormat, canReference, onReferenceClick } = props;\n const en = props.enabled ?? resolveIndicators(undefined);\n\n const aliasChain =\n Array.isArray(token.aliasChain) && token.aliasChain.length > 0 ? token.aliasChain : undefined;\n const reverseCount =\n Array.isArray(token.aliasedBy) && token.aliasedBy.length > 0 ? token.aliasedBy.length : 0;\n const isVarying = variance !== undefined && variance.kind !== 'constant';\n const outOfGamut =\n token.$type === 'color' && (formatColor(token.$value, colorFormat)?.outOfGamut ?? false);\n const deprecated = token.$deprecated;\n const isDeprecated =\n deprecated === true || (typeof deprecated === 'string' && deprecated.length > 0);\n const description =\n typeof token.$description === 'string' && token.$description.length > 0\n ? token.$description\n : undefined;\n const composesCount = en.composes ? compositeFieldCount(token) : undefined;\n\n const showDeprecated = en.deprecation && isDeprecated;\n const showForward = en.alias && aliasChain !== undefined;\n const showReverse = en.alias && reverseCount > 0;\n const showVariance = en.variance && isVarying;\n const showGamut = en.gamut && outOfGamut;\n const showDescription = en.description && description !== undefined;\n const showComposes = composesCount !== undefined;\n\n if (\n !showDeprecated &&\n !showForward &&\n !showReverse &&\n !showVariance &&\n !showGamut &&\n !showDescription &&\n !showComposes\n ) {\n return null;\n }\n\n return (\n <span className=\"sb-indicator__indicators\">\n {showDeprecated && deprecated !== undefined && <DeprecatedBadge deprecated={deprecated} />}\n {showForward && aliasChain && (\n <ForwardChain\n chain={aliasChain}\n root={root}\n canReference={canReference}\n onReferenceClick={onReferenceClick}\n />\n )}\n {showReverse && token.aliasedBy && (\n <ReverseCount\n referents={token.aliasedBy}\n canReference={canReference}\n onReferenceClick={onReferenceClick}\n />\n )}\n {showComposes && composesCount !== undefined && (\n <span\n className=\"sb-indicator__composes\"\n data-testid=\"row-indicator-composes\"\n title={`composes ${composesCount} parts`}\n aria-label={`composes ${composesCount} parts`}\n >\n <span className=\"sb-indicator__composes-glyph\" aria-hidden>\n ⊞\n </span>\n {composesCount}\n </span>\n )}\n {showVariance && variance && <VarianceBadge variance={variance} />}\n {showGamut && (\n <span\n className=\"sb-indicator__gamut\"\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n >\n ⚠\n </span>\n )}\n {showDescription && description !== undefined && (\n <span\n className=\"sb-indicator__description\"\n data-testid=\"row-indicator-description\"\n title={description}\n aria-label={`description: ${description}`}\n >\n ⓘ\n </span>\n )}\n </span>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport './CopyButton.css';\n\nexport interface CopyButtonProps {\n /** Text written to the clipboard when clicked. */\n value: string;\n /**\n * Accessible label. Defaults to `Copy <value>`; override for long values\n * (hex + description + etc.) where the full label would be too chatty.\n */\n label?: string;\n /** `'icon'` (default) — 16 px glyph button; `'text'` — `Copy` pill. */\n variant?: 'icon' | 'text';\n /** Extra class to merge onto the button root. */\n className?: string;\n}\n\n/**\n * Copy the given string to the clipboard and briefly surface a \"Copied!\"\n * state. Falls back silently on unsupported clipboard APIs (older Safari,\n * insecure origins) — the click still happens, the user just won't see the\n * tick. No custom permission prompt: relies on the browser's native user-\n * activation gate.\n */\nexport function CopyButton({\n value,\n label,\n variant = 'icon',\n className,\n}: CopyButtonProps): ReactElement {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n };\n }, []);\n\n const handleClick = useCallback((): void => {\n // `writeText` is async and rejects on unfocused documents,\n // insecure origins, missing permissions, etc. Swallow the\n // rejection — the \"Copied!\" affordance is a nicety, not a\n // correctness requirement; an unhandled rejection in prod would\n // surface in DevTools and (under vitest browser-mode) fail the\n // suite from an unrelated test.\n navigator.clipboard?.writeText(value).catch(() => {});\n setCopied(true);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 1500);\n }, [value]);\n\n const ariaLabel = label ?? `Copy ${value}`;\n const classes = ['sb-copy-button', `sb-copy-button--${variant}`];\n if (copied) classes.push('sb-copy-button--copied');\n if (className) classes.push(className);\n\n return (\n <>\n <button\n type=\"button\"\n className={classes.join(' ')}\n onClick={handleClick}\n aria-label={ariaLabel}\n title={ariaLabel}\n data-copied={copied ? 'true' : undefined}\n >\n {variant === 'text' ? (\n <span className=\"sb-copy-button__text\">{copied ? 'Copied' : 'Copy'}</span>\n ) : (\n <span className=\"sb-copy-button__glyph\" aria-hidden>\n {copied ? '✓' : '⧉'}\n </span>\n )}\n </button>\n {/* Polite live region announces the transition to SR users — the\n icon variant's \"✓ Copied\" cue is otherwise visual-only. */}\n <span role=\"status\" aria-live=\"polite\" className=\"sb-copy-button__sr-status\">\n {copied ? 'Copied' : ''}\n </span>\n </>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\n/**\n * Block UI state that survives a docs-mode remount.\n *\n * In MDX docs mode Storybook re-renders the docs container on every\n * `updateGlobals` (axis flip), which unmounts and remounts the embedded\n * blocks — destroying any plain `useState` (expand/collapse, selection,\n * search). This is the same problem `channel-globals` solves for the\n * globals: lift the value out of React into module state so it persists\n * across the remount, and re-seed component state from it on mount.\n *\n * `usePersistedState` is a drop-in `useState` whose value is mirrored to a\n * module-level store under a caller-supplied key, and read back from it on\n * (re)mount. `useBlockKey` builds a stable key scoped to the current docs\n * page + block identity so two pages (or two distinct blocks) don't share\n * an entry.\n */\n\nconst store = new Map<string, unknown>();\n\n/**\n * Drop all persisted block state. The store is module-global and intentionally\n * outlives React's tree (that's the whole point), so tests must clear it\n * between cases to stay isolated — wired via the browser project's setupFiles.\n */\nexport function clearPersistedState(): void {\n store.clear();\n}\n\n// The current docs/story id, so persisted state is scoped per page. Docs\n// navigation is an SPA swap inside the preview iframe (no reload), so without\n// this scope a `<TokenNavigator root=\"color\">` on page A would inherit page\n// B's expand/selection state. Falls back to the pathname, then empty (SSR).\nfunction pageScope(): string {\n if (typeof window === 'undefined') return '';\n try {\n return new URLSearchParams(window.location.search).get('id') ?? window.location.pathname;\n } catch {\n return '';\n }\n}\n\nconst SEP = '\u0001';\n\n/**\n * Build a stable persistence key for a block's UI state: docs page + block\n * type + the props that distinguish one instance from another (and an\n * optional explicit `id` for identical-prop siblings on the same page).\n */\nexport function useBlockKey(\n blockType: string,\n parts: readonly (string | number | boolean | undefined)[],\n): string {\n const partsKey = parts.map((p) => (p === undefined ? '' : String(p))).join(SEP);\n // pageScope() is read once per (re)mount via the memo; a docs page swap\n // remounts the block, so the scope is current for the new page.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => `${pageScope()}${SEP}${blockType}${SEP}${partsKey}`, [blockType, partsKey]);\n}\n\n/**\n * `useState`, but the value persists across remounts under `key`. `initial`\n * may be a value or a lazy initializer (used only on the first mount when the\n * store has no entry yet — never an actual `T` that's a function here).\n */\nexport function usePersistedState<T>(\n key: string,\n initial: T | (() => T),\n): readonly [T, Dispatch<SetStateAction<T>>] {\n const [value, setValue] = useState<T>(() => {\n if (store.has(key)) return store.get(key) as T;\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n });\n useEffect(() => {\n store.set(key, value);\n }, [key, value]);\n return [value, setValue] as const;\n}\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport type { AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { memo, useCallback, useDeferredValue, useMemo } from 'react';\nimport './ColorTable.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport type { VirtualTokenShape } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat, NormalizedColor } from '#/format-color.ts';\nimport { RowIndicators } from '#/indicators/RowIndicators.tsx';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorName, IndicatorsProp } from '#/indicators/resolve.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nconst NOOP_REFERENCE = (): void => {};\n\nconst BASE_LABEL = 'base';\nconst COLUMN_COUNT = 6;\n\nexport interface ColorTableProps {\n /**\n * Token-path filter. Defaults to every `$type: color` token. `\"color.*\"`\n * scopes to the semantic layer; `\"color.palette.blue.*\"` to a single ramp.\n */\n filter?: string;\n /** Override the table caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — perceptual (oklch L → C → H). Ramps read light→dark, then\n * warm→cool within each lightness band.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n /**\n * Render a fuzzy-search input above the table. Defaults to `true`.\n */\n searchable?: boolean;\n /**\n * Called with the *currently-selected* variant's dot-path on row click.\n * When set, the built-in expand-in-place behavior is suppressed — the\n * consumer owns follow-up UI.\n */\n onSelect?(path: string): void;\n /**\n * Map from a display label to a suffix matched against each token's\n * trailing path segment. Tokens whose leaves match a suffix are grouped\n * under a shared \"base\" path (the path with the suffix stripped), and\n * the group renders as a single row with a pill selector — clicking a\n * pill swaps the displayed values to that variant. Sibling tokens\n * without a suffix that share the group's base path are labeled `base`.\n *\n * Matches both DTCG-idiomatic and Backmarket-style conventions:\n * - **Dot segment** (`color.bg.hi.disabled`): last dot-segment equals\n * the suffix (`disabled`). Base path = drop the last segment.\n * - **Hyphen tail** (`color.bg.hi-d`): last dot-segment ends in\n * `-<suffix>` (`d`). Base path = trim the `-<suffix>` from the leaf.\n *\n * Longest-suffix-wins. Hyphen-tail form requires an actual hyphen\n * boundary — suffix `0` does not match `neutral-900`.\n *\n * Single-member groups render as plain rows (no pill selector). Empty\n * map (default) disables grouping entirely; each token renders as its\n * own row.\n */\n variants?: Record<string, string>;\n /** Disambiguates persisted UI state for two identical-prop tables on a page. */\n id?: string;\n /** Configure the per-row indicator strip. See `IndicatorsProp`. Gamut stays in the Value cell, so it is not part of this strip. */\n indicators?: IndicatorsProp;\n}\n\ninterface Variant {\n label: string;\n path: string;\n cssVar: string;\n token: VirtualTokenShape;\n variance: AxisVarianceResult | undefined;\n // The display value in the currently-active color format.\n value: string;\n outOfGamut: boolean;\n // Hex / HSL / OKLCH breakdown — retained for the expanded sub-table.\n hex: string;\n hsl: string;\n oklch: string;\n description?: string;\n aliasOf?: string;\n aliasChain?: readonly string[];\n}\n\ninterface Group {\n base: string;\n variants: Variant[];\n searchText: string;\n}\n\nexport function ColorTable({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n searchable = true,\n onSelect,\n variants,\n id,\n indicators,\n}: ColorTableProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = project;\n const colorFormat = useColorFormat();\n const enabledIndicators = useMemo(\n () => ({ ...resolveIndicators(indicators), gamut: false }),\n [indicators],\n );\n // Persist search + variant selection + expansion across docs-mode remounts.\n const blockKey = useBlockKey('ColorTable', [filter, caption, id]);\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n const [selectedByBase, setSelectedByBase] = usePersistedState<Record<string, string>>(\n `${blockKey}::selected`,\n {},\n );\n const [expandedByBase, setExpandedByBase] = usePersistedState<ReadonlySet<string>>(\n `${blockKey}::expanded`,\n () => new Set(),\n );\n\n const defs = useMemo(() => buildVariantDefs(variants), [variants]);\n\n const groups = useMemo<Group[]>(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'color') return false;\n return matchPath(path, filter);\n });\n const sorted = sortTokens(filtered, { by: sortBy, dir: sortDir });\n\n const groupMap = new Map<string, { base: string; variants: Variant[] }>();\n for (const [path, token] of sorted) {\n const raw = token.$value as NormalizedColor;\n const hex = resolveColorValue(path, raw, 'hex', projectFields);\n const hsl = formatColor(raw, 'hsl');\n const oklch = formatColor(raw, 'oklch');\n const active = pickActiveFormat(raw, colorFormat, hex, hsl, oklch);\n const match = matchVariant(path, defs.matchOrder);\n const variant: Variant = {\n label: match?.label ?? BASE_LABEL,\n path,\n token,\n variance: varianceByPath[path],\n cssVar: resolveCssVar(path, projectFields),\n value: active.value,\n outOfGamut: active.outOfGamut,\n hex: hex.value,\n hsl: hsl.value,\n oklch: oklch.value,\n ...(token.$description !== undefined && { description: token.$description }),\n ...(token.aliasOf !== undefined && { aliasOf: token.aliasOf }),\n ...(token.aliasChain !== undefined && { aliasChain: token.aliasChain }),\n };\n const basePath = match?.basePath ?? path;\n const existing = groupMap.get(basePath);\n if (existing) existing.variants.push(variant);\n else groupMap.set(basePath, { base: basePath, variants: [variant] });\n }\n\n const out: Group[] = [];\n for (const { base, variants: vs } of groupMap.values()) {\n vs.sort((a, b) => orderIndex(a.label, defs) - orderIndex(b.label, defs));\n const searchText = vs.map((v) => `${v.path} ${v.value}`).join(' ');\n out.push({ base, variants: vs, searchText });\n }\n return out;\n }, [resolved, listing, cssVarPrefix, varianceByPath, filter, sortBy, sortDir, defs, colorFormat]);\n\n const visibleGroups = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') return groups;\n return fuzzyFilter(groups, deferredQuery, (g) => g.searchText);\n }, [groups, deferredQuery, searchable]);\n\n const totalTokens = useMemo(() => groups.reduce((n, g) => n + g.variants.length, 0), [groups]);\n\n const toggleExpand = useCallback(\n (base: string) => {\n setExpandedByBase((prev) => {\n const next = new Set(prev);\n if (next.has(base)) next.delete(base);\n else next.add(base);\n return next;\n });\n },\n [setExpandedByBase],\n );\n\n const selectVariant = useCallback(\n (base: string, label: string) => {\n setSelectedByBase((prev) => ({ ...prev, [base]: label }));\n },\n [setSelectedByBase],\n );\n\n const matchSuffix =\n searchable && query.trim() !== ''\n ? ` · ${visibleGroups.length} matching \"${query.trim()}\"`\n : '';\n const captionText =\n caption ??\n `${totalTokens} color${totalTokens === 1 ? '' : 's'} across ${groups.length} group${\n groups.length === 1 ? '' : 's'\n }${filter ? ` matching \\`${filter}\\`` : ''}${matchSuffix} · ${activeTheme}`;\n\n if (groups.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No color tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-color-table__search\">\n <input\n type=\"search\"\n className=\"sb-color-table__search-input\"\n placeholder=\"Search colors…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Fuzzy-search colors by path or value\"\n data-testid=\"color-table-search\"\n />\n </div>\n )}\n <div className=\"sb-color-table__scroll\">\n <table className=\"sb-color-table__table\">\n <caption className=\"sb-color-table__caption\">{captionText}</caption>\n <thead>\n <tr>\n <th className=\"sb-color-table__th sb-color-table__th--swatch\">\n <span className=\"sb-color-table__sr-only\">Swatch</span>\n </th>\n <th className=\"sb-color-table__th sb-color-table__th--path\">Name</th>\n <th className=\"sb-color-table__th\">Value</th>\n <th className=\"sb-color-table__th\">CSS var</th>\n <th className=\"sb-color-table__th sb-color-table__th--refs\">\n <span className=\"sb-color-table__sr-only\">References and status</span>\n </th>\n <th className=\"sb-color-table__th sb-color-table__th--expand\">\n <span className=\"sb-color-table__sr-only\">Expand</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {visibleGroups.length === 0 && (\n <tr>\n <td colSpan={COLUMN_COUNT} className=\"sb-color-table__td sb-color-table__empty-row\">\n No colors match \"{query.trim()}\".\n </td>\n </tr>\n )}\n {visibleGroups.map((group) => (\n <GroupRow\n key={group.base}\n group={group}\n selectedLabel={selectedByBase[group.base]}\n expanded={expandedByBase.has(group.base)}\n onToggleExpand={toggleExpand}\n onSelectVariant={selectVariant}\n enabled={enabledIndicators}\n colorFormat={colorFormat}\n {...(onSelect !== undefined && { onSelect })}\n />\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\ninterface GroupRowProps {\n group: Group;\n selectedLabel: string | undefined;\n expanded: boolean;\n onToggleExpand(base: string): void;\n onSelectVariant(base: string, label: string): void;\n onSelect?(path: string): void;\n enabled: Record<IndicatorName, boolean>;\n colorFormat: ColorFormat;\n}\n\nconst GroupRow = memo(function GroupRow({\n group,\n selectedLabel,\n expanded,\n onToggleExpand,\n onSelectVariant,\n onSelect,\n enabled,\n colorFormat,\n}: GroupRowProps): ReactElement {\n const multi = group.variants.length > 1;\n const active =\n group.variants.find((v) => v.label === selectedLabel) ?? (group.variants[0] as Variant);\n const nameText = multi ? group.base : active.path;\n\n const dep = active.token.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n\n const handleRowActivate = (): void => {\n if (onSelect) onSelect(active.path);\n else onToggleExpand(group.base);\n };\n\n return (\n <>\n <tr\n className={cx('sb-color-table__row', {\n 'sb-color-table__row--expanded': expanded,\n })}\n onClick={handleRowActivate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleRowActivate();\n }\n }}\n tabIndex={0}\n aria-label={\n onSelect\n ? `Inspect ${active.path}`\n : expanded\n ? `Collapse ${group.base}`\n : `Expand ${group.base}`\n }\n {...(onSelect ? { 'aria-haspopup': 'dialog' as const } : {})}\n data-testid=\"color-table-row\"\n data-path={active.path}\n data-base={group.base}\n >\n <td className=\"sb-color-table__td sb-color-table__swatch-cell\">\n <span\n className=\"sb-color-table__swatch\"\n style={{ background: active.cssVar }}\n aria-hidden\n />\n </td>\n <td\n className={cx('sb-color-table__td', 'sb-color-table__path')}\n data-deprecated={enabled.deprecation && isDeprecated ? 'true' : undefined}\n >\n <span className=\"sb-color-table__path-text\">{nameText}</span>\n {multi && (\n <span\n className=\"sb-color-table__variant-pills\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n {group.variants.map((v) => (\n <button\n key={v.label}\n type=\"button\"\n className={cx('sb-color-table__variant-pill', {\n 'sb-color-table__variant-pill--active': v.label === active.label,\n })}\n onClick={() => onSelectVariant(group.base, v.label)}\n aria-pressed={v.label === active.label}\n data-testid=\"color-table-variant\"\n data-variant={v.label}\n >\n {v.label}\n </button>\n ))}\n </span>\n )}\n </td>\n <ValueCell value={active.value} label={`Copy value ${active.value}`}>\n {active.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-color-table__gamut-warn\"\n >\n ⚠\n </span>\n )}\n </ValueCell>\n <ValueCell value={active.cssVar} label={`Copy CSS var ${active.cssVar}`} />\n <td className=\"sb-color-table__td sb-color-table__refs\">\n <RowIndicators\n path={active.path}\n token={active.token}\n root={undefined}\n variance={active.variance}\n colorFormat={colorFormat}\n canReference={() => false}\n onReferenceClick={NOOP_REFERENCE}\n enabled={enabled}\n />\n </td>\n <td className=\"sb-color-table__td sb-color-table__expand-cell\">\n {!onSelect && (\n <span\n className={cx('sb-color-table__chevron', {\n 'sb-color-table__chevron--expanded': expanded,\n })}\n aria-hidden\n >\n ▸\n </span>\n )}\n </td>\n </tr>\n {expanded && !onSelect && (\n <tr className=\"sb-color-table__detail-row\" data-testid=\"color-table-detail\">\n <td colSpan={COLUMN_COUNT} className=\"sb-color-table__td sb-color-table__detail-cell\">\n <ExpandedDetail group={group} active={active} />\n </td>\n </tr>\n )}\n </>\n );\n});\n\nfunction ExpandedDetail({ group, active }: { group: Group; active: Variant }): ReactElement {\n const hasDescription = active.description !== undefined && active.description.length > 0;\n const chain = active.aliasChain && active.aliasChain.length > 0 ? active.aliasChain : undefined;\n const multi = group.variants.length > 1;\n\n return (\n <div className=\"sb-color-table__detail\">\n {hasDescription && <p className=\"sb-color-table__description\">{active.description}</p>}\n {chain && (\n <p className=\"sb-color-table__chain\">\n <span className=\"sb-color-table__detail-label\">Alias chain:</span> {chain.join(' → ')}\n </p>\n )}\n {multi && (\n <div className=\"sb-color-table__variant-grid\">\n <div className=\"sb-color-table__variant-grid-header\">All variants</div>\n <table className=\"sb-color-table__subtable\">\n <thead>\n <tr>\n <th className=\"sb-color-table__subth\">Variant</th>\n <th className=\"sb-color-table__subth\">Path</th>\n <th className=\"sb-color-table__subth\">HEX</th>\n <th className=\"sb-color-table__subth\">HSL</th>\n <th className=\"sb-color-table__subth\">OKLCH</th>\n </tr>\n </thead>\n <tbody>\n {group.variants.map((v) => (\n <tr\n key={v.label}\n className={cx({\n 'sb-color-table__subrow--active': v.label === active.label,\n })}\n >\n <td className=\"sb-color-table__subtd\">{v.label}</td>\n <td className=\"sb-color-table__subtd sb-color-table__subtd--path\">{v.path}</td>\n <td className=\"sb-color-table__subtd\">{v.hex}</td>\n <td className=\"sb-color-table__subtd\">{v.hsl}</td>\n <td className=\"sb-color-table__subtd\">{v.oklch}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n {!hasDescription && !chain && !multi && (\n <p className=\"sb-color-table__detail-empty\">\n No description or alias chain authored for this token.\n </p>\n )}\n </div>\n );\n}\n\nfunction ValueCell({\n value,\n label,\n children,\n}: {\n value: string;\n label: string;\n children?: ReactElement | false;\n}): ReactElement {\n return (\n <td className=\"sb-color-table__td sb-color-table__value-cell\">\n <span className=\"sb-color-table__value-text\" title={value}>\n {value}\n </span>\n {children}\n <span\n className=\"sb-color-table__copy-wrap\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n <CopyButton value={value} label={label} className=\"sb-color-table__copy\" />\n </span>\n </td>\n );\n}\n\ntype FormatColorResult = ReturnType<typeof formatColor>;\n\n// Pick the value + gamut flag to display in the single Value column based\n// on the active color-format context. We pre-compute hex/hsl/oklch for the\n// expanded sub-table regardless; the extras (`rgb`, `raw`) take a fresh\n// `formatColor` pass. Keeps the hot path fast while staying honest about\n// out-of-gamut warnings per-format.\nfunction pickActiveFormat(\n raw: NormalizedColor,\n colorFormat: ColorFormat,\n hex: FormatColorResult,\n hsl: FormatColorResult,\n oklch: FormatColorResult,\n): { value: string; outOfGamut: boolean } {\n switch (colorFormat) {\n case 'hex':\n return { value: hex.value, outOfGamut: hex.outOfGamut };\n case 'hsl':\n return { value: hsl.value, outOfGamut: hsl.outOfGamut };\n case 'oklch':\n return { value: oklch.value, outOfGamut: oklch.outOfGamut };\n default: {\n const extra = formatColor(raw, colorFormat);\n return { value: extra.value, outOfGamut: extra.outOfGamut };\n }\n }\n}\n\ninterface VariantEntry {\n label: string;\n suffix: string;\n}\n\ninterface VariantDefs {\n // Match iteration order — longest suffix first.\n matchOrder: readonly VariantEntry[];\n // Display iteration order — preserves the caller's declared order.\n displayOrder: readonly string[];\n}\n\nfunction buildVariantDefs(variants: Record<string, string> | undefined): VariantDefs {\n if (!variants) return { matchOrder: [], displayOrder: [] };\n const entries: VariantEntry[] = [];\n const displayOrder: string[] = [];\n for (const [label, suffix] of Object.entries(variants)) {\n if (suffix.length === 0) continue;\n entries.push({ label, suffix });\n displayOrder.push(label);\n }\n const matchOrder = entries.toSorted((a, b) => b.suffix.length - a.suffix.length);\n return { matchOrder, displayOrder };\n}\n\n// Position of a label within a group — the `base` entry always sorts first,\n// then declared labels in the order the caller wrote them in the `variants`\n// prop. Unknown labels (shouldn't happen in practice) fall to the end.\nfunction orderIndex(label: string, defs: VariantDefs): number {\n if (label === BASE_LABEL) return -1;\n const idx = defs.displayOrder.indexOf(label);\n return idx >= 0 ? idx : Number.POSITIVE_INFINITY;\n}\n\n// Resolve the variant label + base path for a token, if any. The leaf\n// (last dot-segment) must either equal the suffix outright (dot-segment\n// form: `hi.disabled` matches suffix `disabled`) or end in `-<suffix>`\n// (hyphen-tail form: `hi-d` matches `d`). The leading hyphen is required\n// for the tail form so suffix `0` can't hit `neutral-900` by character.\n//\n// Returned `basePath` is what gets used as the grouping key:\n// - Dot-segment match → parent path (drop the last dot-segment)\n// - Hyphen-tail match → same dot-depth, leaf with `-<suffix>` stripped\n//\n// Entries in `matchOrder` are pre-sorted longest-first, so `h-dark` wins\n// over `dark` for a path ending in `-h-dark`.\nfunction matchVariant(\n path: string,\n matchOrder: readonly VariantEntry[],\n): { label: string; basePath: string } | undefined {\n if (matchOrder.length === 0) return undefined;\n const segments = path.split('.');\n const leaf = segments.at(-1) ?? path;\n for (const entry of matchOrder) {\n if (leaf === entry.suffix) {\n const parent = segments.slice(0, -1).join('.');\n if (parent.length === 0) continue;\n return { label: entry.label, basePath: parent };\n }\n const tailMarker = `-${entry.suffix}`;\n if (leaf.endsWith(tailMarker)) {\n const trimmed = leaf.slice(0, -tailMarker.length);\n if (trimmed.length === 0) continue;\n const copy = segments.slice(0, -1);\n copy.push(trimmed);\n return { label: entry.label, basePath: copy.join('.') };\n }\n }\n return undefined;\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './Diagnostics.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport type { VirtualDiagnostic } from '#/types.ts';\n\nexport interface DiagnosticsProps {\n /** Override the section caption. Defaults to a severity summary. */\n caption?: string;\n}\n\ntype DiagnosticSeverity = VirtualDiagnostic['severity'];\n\nconst severityLabel: Record<DiagnosticSeverity, string> = {\n error: 'ERROR',\n warn: 'WARN',\n info: 'INFO',\n};\n\ninterface DiagnosticsSummary {\n text: string;\n variant: 'ok' | 'error' | 'warn' | null;\n hasErrorsOrWarnings: boolean;\n}\n\nfunction summarize(diagnostics: readonly VirtualDiagnostic[]): DiagnosticsSummary {\n if (diagnostics.length === 0) {\n return { text: '✔ OK · no diagnostics', variant: 'ok', hasErrorsOrWarnings: false };\n }\n let errors = 0;\n let warnings = 0;\n let infos = 0;\n for (const d of diagnostics) {\n if (d.severity === 'error') errors += 1;\n else if (d.severity === 'warn') warnings += 1;\n else infos += 1;\n }\n const parts: string[] = [];\n if (errors > 0) parts.push(`✖ ${errors} error${errors === 1 ? '' : 's'}`);\n if (warnings > 0) parts.push(`⚠ ${warnings} warning${warnings === 1 ? '' : 's'}`);\n if (infos > 0) parts.push(`${infos} info`);\n const variant = errors > 0 ? 'error' : warnings > 0 ? 'warn' : null;\n return {\n text: parts.join(' · '),\n variant,\n hasErrorsOrWarnings: errors > 0 || warnings > 0,\n };\n}\n\nfunction diagnosticKey(d: VirtualDiagnostic, i: number): string {\n return `${d.severity}:${d.group}:${d.filename ?? ''}:${d.line ?? ''}:${d.message}:${i}`;\n}\n\n/**\n * Render the project's load diagnostics — parser errors, resolver warnings,\n * disabled-axes validation issues, etc. — as a collapsible list. Auto-opens\n * when the project carries errors or warnings; stays collapsed for clean\n * loads and info-only loads.\n *\n * Replaces the diagnostics section from the addon's (now-retired) Design\n * Tokens panel. Consumers compose it alongside TokenNavigator / TokenTable\n * on their own MDX pages.\n */\nexport function Diagnostics({ caption }: DiagnosticsProps = {}): ReactElement {\n const { activeAxes, cssVarPrefix, diagnostics } = useProject();\n const summary = useMemo(() => summarize(diagnostics), [diagnostics]);\n const headingText = caption ?? `Diagnostics · ${summary.text}`;\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)} data-testid=\"diagnostics\">\n <details open={summary.hasErrorsOrWarnings}>\n <summary\n className={cx(\n 'sb-diagnostics__summary',\n summary.variant && `sb-diagnostics__summary--${summary.variant}`,\n )}\n >\n {headingText}\n </summary>\n {diagnostics.length > 0 && (\n <ul role=\"list\" className=\"sb-diagnostics__list\">\n {diagnostics.map((d, i) => (\n <li\n key={diagnosticKey(d, i)}\n className=\"sb-diagnostics__row\"\n aria-label={`${severityLabel[d.severity]}: ${d.message}`}\n >\n <span\n className={cx('sb-diagnostics__label', {\n [`sb-diagnostics__label--${d.severity}`]: d.severity !== 'info',\n })}\n aria-hidden\n >\n {severityLabel[d.severity]}\n </span>\n <div>\n <div>{d.message}</div>\n {(d.group || d.filename) && (\n <div className=\"sb-diagnostics__meta\">\n {[d.group, d.filename, d.line ? `:${d.line}` : '']\n .filter(Boolean)\n .join(' · ')}\n </div>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </details>\n </div>\n );\n}\n","/** Max rendered pixel size for a dimension bar/sample before it's capped. */\nexport const MAX_RENDER_PX = 480;\n\n/**\n * Convert a DTCG dimension `$value` (`{ value, unit }`) to pixels for the\n * purpose of deciding whether to cap the rendered size. Returns `NaN` for\n * units we can't reasonably approximate (ex / ch / %), which the caller\n * treats as \"render at cssVar but don't cap\".\n */\nexport function toPixels(raw: unknown): number {\n if (raw == null || typeof raw !== 'object') return Number.NaN;\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value !== 'number' || typeof v.unit !== 'string') return Number.NaN;\n switch (v.unit) {\n case 'px':\n return v.value;\n case 'rem':\n case 'em':\n return v.value * 16;\n default:\n return Number.NaN;\n }\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { MAX_RENDER_PX, toPixels } from '#/dimension-scale/dimension-px.ts';\nimport { BORDER_STRONG } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport type DimensionVisual = 'length' | 'radius' | 'size';\n\nexport interface DimensionBarProps {\n /** Full dot-path of the dimension token to preview. */\n path: string;\n /**\n * Visualization kind:\n * - `'length'` (default): horizontal bar whose width equals the token's dimension.\n * - `'radius'`: 56×56 square with the token applied as `border-radius`.\n * - `'size'`: a square sized to the token's dimension.\n */\n visual?: DimensionVisual;\n}\n\nconst styles = {\n bar: {\n height: 14,\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n borderRadius: 2,\n minWidth: 1,\n } satisfies CSSProperties,\n radiusSample: {\n width: 56,\n height: 56,\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n border: BORDER_STRONG,\n } satisfies CSSProperties,\n sizeSample: {\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n border: BORDER_STRONG,\n minWidth: 1,\n minHeight: 1,\n } satisfies CSSProperties,\n};\n\nexport function DimensionBar({ path, visual = 'length' }: DimensionBarProps): ReactElement {\n const project = useProject();\n const { resolved } = project;\n const cssVar = resolveCssVar(path, project);\n const token = resolved[path];\n const pxValue = toPixels(token?.$value);\n const capped = Number.isFinite(pxValue) && pxValue > MAX_RENDER_PX;\n const cappedValue = capped ? `${MAX_RENDER_PX}px` : cssVar;\n\n switch (visual) {\n case 'radius':\n return <div style={{ ...styles.radiusSample, borderRadius: cssVar }} aria-hidden />;\n case 'size':\n return (\n <div\n style={{ ...styles.sizeSample, width: cappedValue, height: cappedValue }}\n aria-hidden\n />\n );\n case 'length':\n default:\n return <div style={{ ...styles.bar, width: cappedValue }} aria-hidden />;\n }\n}\n","import type { VirtualTokenListingShape } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport type {\n BorderValue,\n DashedStrokeStyleValue,\n ShadowLayer,\n} from '#/internal/composite-types.ts';\n\n/**\n * Single-line display string for any DTCG token `$value`. Prefers\n * plugin-css's `previewValue` from the Token Listing; for color\n * tokens only when the toolbar format is hex (other formats route\n * through local colorjs.io).\n */\nexport function formatTokenValue(\n value: unknown,\n $type: string | undefined,\n colorFormat: ColorFormat,\n listingEntry?: VirtualTokenListingShape,\n): string {\n if (value == null) return '';\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n\n const preview = listingEntry?.previewValue;\n if (preview !== undefined) {\n const previewStr = typeof preview === 'string' ? cleanFloatNoise(preview) : String(preview);\n if ($type !== 'color') return previewStr;\n if (colorFormat === 'hex') return previewStr;\n }\n\n switch ($type) {\n case 'color':\n return formatColor(value, colorFormat).value;\n case 'dimension':\n case 'duration':\n return formatDimension(value);\n case 'fontFamily':\n return formatFontFamily(value);\n case 'fontWeight':\n case 'lineHeight':\n case 'letterSpacing':\n case 'opacity':\n case 'number':\n return formatPrimitive(value);\n case 'cubicBezier':\n return formatCubicBezier(value);\n case 'strokeStyle':\n return formatStrokeStyle(value);\n case 'shadow':\n return formatShadow(value, colorFormat);\n case 'border':\n return formatBorder(value, colorFormat);\n default:\n return formatUnknown(value);\n }\n}\n\nfunction formatDimension(v: unknown): string {\n if (typeof v === 'string' || typeof v === 'number') return String(v);\n if (v && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number' && typeof d.unit === 'string') return `${d.value}${d.unit}`;\n }\n return formatUnknown(v);\n}\n\nfunction cleanFloatNoise(s: string): string {\n return s.replace(/-?\\d+\\.\\d{8,}/g, (m) => `${+Number(m).toFixed(3)}`);\n}\n\nfunction formatFontFamily(v: unknown): string {\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n return formatUnknown(v);\n}\n\nfunction formatPrimitive(v: unknown): string {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n return formatUnknown(v);\n}\n\nfunction formatCubicBezier(v: unknown): string {\n if (Array.isArray(v) && v.length === 4) {\n return `cubic-bezier(${v.map((n) => (typeof n === 'number' ? n : 0)).join(', ')})`;\n }\n return formatUnknown(v);\n}\n\nfunction formatStrokeStyle(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v && typeof v === 'object') {\n const s = v as DashedStrokeStyleValue;\n const parts: string[] = ['dashed'];\n if (Array.isArray(s.dashArray)) {\n parts.push(s.dashArray.map((n) => formatDimension(n)).join(' '));\n }\n if (typeof s.lineCap === 'string') parts.push(s.lineCap);\n return parts.join(' · ');\n }\n return formatUnknown(v);\n}\n\nfunction formatShadow(v: unknown, colorFormat: ColorFormat): string {\n const layers = Array.isArray(v) ? v : [v];\n const parts = layers.map((layer) => {\n if (!layer || typeof layer !== 'object') return formatUnknown(layer);\n const s = layer as ShadowLayer;\n const pieces = [\n formatDimension(s.offsetX),\n formatDimension(s.offsetY),\n formatDimension(s.blur),\n formatDimension(s.spread),\n formatColor(s.color, colorFormat).value,\n ].filter((p) => p !== '');\n if (s.inset) pieces.push('inset');\n return pieces.join(' ');\n });\n return parts.join(', ');\n}\n\nfunction formatBorder(v: unknown, colorFormat: ColorFormat): string {\n if (!v || typeof v !== 'object') return formatUnknown(v);\n const b = v as BorderValue;\n const width = formatDimension(b.width);\n const style = formatPrimitive(b.style);\n const color = formatColor(b.color, colorFormat).value;\n return [width, style, color].filter((p) => p !== '').join(' ');\n}\n\nfunction formatUnknown(v: unknown): string {\n if (v == null) return '';\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n try {\n return JSON.stringify(v).slice(0, 120);\n } catch {\n return String(v);\n }\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './DimensionScale.css';\nimport { DimensionBar } from '#/dimension-scale/DimensionBar.tsx';\nimport type { DimensionVisual } from '#/dimension-scale/DimensionBar.tsx';\nimport { MAX_RENDER_PX, toPixels } from '#/dimension-scale/dimension-px.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport type { DimensionVisual };\n\nexport interface DimensionScaleProps {\n /**\n * Token-path filter. Defaults to every `dimension` token. Use e.g.\n * `\"space.*\"` to scope to the spacing scale.\n */\n filter?: string;\n /**\n * Visualization kind:\n * - `'length'` (default): horizontal bar whose width equals the token's dimension.\n * - `'radius'`: 56×56 square with the token applied as `border-radius`.\n * - `'size'`: a square sized to the token's dimension.\n */\n visual?: DimensionVisual;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — numeric by rendered pixel size (`px` / `rem` / `em`).\n * Non-convertible units (ex/ch/%) land after the convertible ones.\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n displayValue: string;\n pxValue: number;\n capped: boolean;\n}\n\nexport function DimensionScale({\n filter,\n visual = 'length',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: DimensionScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'dimension') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const pxValue = toPixels(token.$value);\n return {\n path,\n cssVar: resolveCssVar(path, project),\n displayValue: formatTokenValue(token.$value, token.$type, 'raw', project.listing[path]),\n pxValue,\n capped: Number.isFinite(pxValue) && pxValue > MAX_RENDER_PX,\n };\n });\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} dimension${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No dimension tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-dimension-scale__row\">\n <div className=\"sb-dimension-scale__meta\">\n <span className=\"sb-dimension-scale__path\">{row.path}</span>\n <span className=\"sb-dimension-scale__specs\">{row.displayValue}</span>\n </div>\n <div className=\"sb-dimension-scale__visual-cell\">\n <DimensionBar path={row.path} visual={visual} />\n {row.capped && (\n <span className=\"sb-dimension-scale__cap\">capped at {MAX_RENDER_PX}px</span>\n )}\n </div>\n <span className=\"sb-dimension-scale__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './FontFamilyPreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\nexport interface FontFamilyPreviewProps {\n /**\n * Token-path filter. Defaults to every `fontFamily` token. Use e.g.\n * `\"font.family.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n stack: string;\n}\n\nfunction stackString(raw: unknown): string {\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.map(String).join(', ');\n return '';\n}\n\nexport function FontFamilyPreview({\n filter,\n sample = 'The quick brown fox jumps over the lazy dog.',\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: FontFamilyPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'fontFamily') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n stack: stackString(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} fontFamily token${rows.length === 1 ? '' : 's'}${filter && filter !== 'fontFamily' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No fontFamily tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-font-family-sample__row\">\n <div className=\"sb-font-family-sample__meta\">\n <span className=\"sb-font-family-sample__path\">{row.path}</span>\n <span className=\"sb-font-family-sample__stack\">{row.stack}</span>\n </div>\n <div className=\"sb-font-family-sample__sample\" style={{ fontFamily: row.cssVar }}>\n {sample}\n </div>\n <span className=\"sb-font-family-sample__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","/**\n * Coerce a CSS `var(--…)` reference into the numeric slot of a React\n * inline-style property.\n *\n * React's `CSSProperties` types unitless properties (`fontWeight`,\n * `lineHeight`, `zIndex`, …) as `number`. The DOM accepts a string at\n * runtime — the rendered stylesheet just receives whatever React passes —\n * so a `var(--font-weight)` reference works functionally. TypeScript still\n * complains. Centralising the type assertion in one named helper keeps\n * the gap visible (and greppable) instead of scattering casts across\n * block components that want CSS-var-driven typography or layout values.\n */\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error — React's CSSProperties slot is `number`; the DOM tolerates a CSS var string.\nexport const cssVarAsNumber = (varRef: string): number => varRef;\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './FontWeightScale.css';\nimport { cssVarAsNumber } from '#/internal/css-var-style.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface FontWeightScaleProps {\n /**\n * Token-path filter. Defaults to every `fontWeight` token. Use e.g.\n * `\"font.weight.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — ascending numeric by weight (100 → 900).\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n display: string;\n weight: number;\n}\n\nfunction toWeight(raw: unknown): number {\n if (typeof raw === 'number') return raw;\n if (typeof raw === 'string') {\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) ? n : Number.NaN;\n }\n return Number.NaN;\n}\n\nexport function FontWeightScale({\n filter,\n sample = 'Aa',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: FontWeightScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'fontWeight') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n display: token.$value == null ? '' : String(token.$value),\n weight: toWeight(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} fontWeight token${rows.length === 1 ? '' : 's'}${filter && filter !== 'fontWeight' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No fontWeight tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-font-weight-scale__row\">\n <div className=\"sb-font-weight-scale__meta\">\n <span className=\"sb-font-weight-scale__path\">{row.path}</span>\n <span className=\"sb-font-weight-scale__value\">{row.display}</span>\n </div>\n <div\n className=\"sb-font-weight-scale__sample\"\n style={{ fontWeight: cssVarAsNumber(row.cssVar) }}\n >\n {sample}\n </div>\n <span className=\"sb-font-weight-scale__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './GradientPalette.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport { parseColor } from '@unpunnyfuns/swatchbook-core/format-color';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface GradientPaletteProps {\n /**\n * Token-path filter. Defaults to every `gradient` token. Use e.g.\n * `\"gradient.*\"` or `\"gradient.accent\"` to scope.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (gradients don't have\n * a single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface GradientStop {\n color?: {\n colorSpace?: string;\n components?: readonly number[];\n alpha?: number;\n };\n position?: number;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n stops: GradientStop[];\n}\n\nfunction asStops(raw: unknown): GradientStop[] {\n if (!Array.isArray(raw)) return [];\n return raw as GradientStop[];\n}\n\nfunction stopCssColor(stop: GradientStop): string {\n // parseColor respects the stop's colorSpace (via the colorjs space-alias\n // map) and emits a gamut-correct CSS string — e.g. `color(display-p3 …)`\n // for a P3 stop — rather than the old code's raw sRGB-percentage rendering\n // that mislabeled every non-sRGB stop.\n const color = parseColor(stop.color);\n if (!color) return 'transparent';\n return color.toString();\n}\n\nfunction stopKey(path: string, stop: GradientStop, fallback: number): string {\n return `${path}|${stop.position ?? fallback}|${stopCssColor(stop)}`;\n}\n\nexport function GradientPalette({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: GradientPaletteProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'gradient') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, projectFields),\n stops: asStops(token.$value),\n }));\n }, [resolved, listing, cssVarPrefix, filter, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} gradient${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No gradient tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-gradient-palette__row\">\n <div className=\"sb-gradient-palette__meta\">\n <span className=\"sb-gradient-palette__path\">{row.path}</span>\n <span className=\"sb-gradient-palette__css-var\">{row.cssVar}</span>\n </div>\n <div\n className=\"sb-gradient-palette__sample\"\n style={{ background: `linear-gradient(to right, ${row.cssVar})` }}\n aria-hidden\n />\n <div className=\"sb-gradient-palette__stops\">\n {row.stops.map((stop, i) => (\n <div key={stopKey(row.path, stop, i)} className=\"sb-gradient-palette__stop-row\">\n <span\n className=\"sb-gradient-palette__stop-swatch\"\n style={{ background: stopCssColor(stop) }}\n aria-hidden\n />\n <span>{formatColor(stop.color, colorFormat).value}</span>\n <span className=\"sb-gradient-palette__stop-position\">\n @ {((stop.position ?? 0) * 100).toFixed(0)}%\n </span>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\n\n// True when rendering inside Chromatic's snapshot runner. Chromatic's\n// browser ships a recognisable user-agent string; checked here so\n// motion-looping components can fall back to their static state for\n// deterministic snapshots. Per-component detection rather than the\n// global `chromatic.prefersReducedMotion: true` parameter — that\n// parameter is incompatible with Chromatic's verification parser.\nfunction isChromatic(): boolean {\n if (typeof navigator === 'undefined') return false;\n return navigator.userAgent.includes('Chromatic');\n}\n\n/**\n * Reactive `prefers-reduced-motion: reduce` detector. Returns the current\n * match and updates if the user toggles the OS-level preference. Also\n * returns `true` under Chromatic to keep animated samples deterministic\n * during visual regression capture.\n */\nexport function usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (isChromatic()) {\n setReduced(true);\n return;\n }\n const query = window.matchMedia('(prefers-reduced-motion: reduce)');\n setReduced(query.matches);\n const onChange = (e: MediaQueryListEvent): void => setReduced(e.matches);\n query.addEventListener('change', onChange);\n return () => query.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { SURFACE_MUTED, TEXT_MUTED } from '#/internal/styles.tsx';\nimport { useEffect, useMemo, useState } from 'react';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { useProject } from '#/internal/use-project.ts';\n\nexport type MotionSpeed = 0.25 | 0.5 | 1 | 2;\n\nexport interface MotionSampleProps {\n /** Full dot-path of the motion token (`transition`, `duration`, or `cubicBezier`). */\n path: string;\n /** Playback speed multiplier. Defaults to `1`. */\n speed?: MotionSpeed;\n /**\n * Change this value to force the animation to restart. Useful when an\n * outer block exposes a \"replay\" button that should re-trigger every\n * sample at once.\n */\n runKey?: number;\n}\n\nconst DEFAULT_DURATION_MS = 300;\nconst DEFAULT_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst styles = {\n track: {\n position: 'relative',\n height: 36,\n background: SURFACE_MUTED,\n borderRadius: 18,\n overflow: 'hidden',\n } satisfies CSSProperties,\n ball: {\n position: 'absolute',\n top: '50%',\n width: 28,\n height: 28,\n marginTop: -14,\n borderRadius: '50%',\n background: 'var(--swatchbook-accent-bg, #3b82f6)',\n } satisfies CSSProperties,\n reducedMotion: {\n fontSize: 11,\n color: TEXT_MUTED,\n fontStyle: 'italic',\n } satisfies CSSProperties,\n};\n\ninterface Spec {\n durationMs: number;\n easing: string;\n}\n\nfunction extractDurationMs(raw: unknown): number {\n if (raw == null) return Number.NaN;\n if (typeof raw === 'object') {\n const v = raw as { value?: unknown; unit?: unknown };\n if (typeof v.value === 'number' && typeof v.unit === 'string') {\n if (v.unit === 'ms') return v.value;\n if (v.unit === 's') return v.value * 1000;\n }\n }\n return Number.NaN;\n}\n\nfunction extractCubicBezier(raw: unknown): string | null {\n if (Array.isArray(raw) && raw.length === 4 && raw.every((n) => typeof n === 'number')) {\n return `cubic-bezier(${raw.map((n) => Number(n).toFixed(3)).join(', ')})`;\n }\n return null;\n}\n\nfunction asDuration(\n raw: unknown,\n themeTokens: Record<string, { $value?: unknown }>,\n fallback: number,\n): number {\n const direct = extractDurationMs(raw);\n if (Number.isFinite(direct)) return direct;\n if (typeof raw === 'string') {\n const match = raw.match(/^\\{([^}]+)\\}$/);\n if (match && match[1]) {\n const referenced = themeTokens[match[1]];\n const resolved = extractDurationMs(referenced?.$value);\n if (Number.isFinite(resolved)) return resolved;\n }\n }\n return fallback;\n}\n\nfunction asEasing(\n raw: unknown,\n themeTokens: Record<string, { $value?: unknown }>,\n fallback: string,\n): string {\n const direct = extractCubicBezier(raw);\n if (direct) return direct;\n if (typeof raw === 'string') {\n const match = raw.match(/^\\{([^}]+)\\}$/);\n if (match && match[1]) {\n const referenced = themeTokens[match[1]];\n const resolved = extractCubicBezier(referenced?.$value);\n if (resolved) return resolved;\n }\n }\n return fallback;\n}\n\nexport function resolveMotionSpec(\n token: { $type?: string | undefined; $value?: unknown } | undefined,\n themeTokens: Record<string, { $value?: unknown }>,\n): Spec | null {\n if (!token) return null;\n const type = token.$type;\n if (type === 'transition') {\n const v = (token.$value ?? {}) as {\n duration?: unknown;\n timingFunction?: unknown;\n };\n return {\n durationMs: asDuration(v.duration, themeTokens, DEFAULT_DURATION_MS),\n easing: asEasing(v.timingFunction, themeTokens, DEFAULT_EASING),\n };\n }\n if (type === 'duration') {\n const durationMs = extractDurationMs(token.$value);\n if (!Number.isFinite(durationMs)) return null;\n return { durationMs, easing: DEFAULT_EASING };\n }\n if (type === 'cubicBezier') {\n const easing = extractCubicBezier(token.$value);\n if (!easing) return null;\n return { durationMs: DEFAULT_DURATION_MS, easing };\n }\n return null;\n}\n\nexport function MotionSample({ path, speed = 1, runKey = 0 }: MotionSampleProps): ReactElement {\n const { resolved } = useProject();\n const reducedMotion = usePrefersReducedMotion();\n\n const spec = useMemo(() => resolveMotionSpec(resolved[path], resolved), [resolved, path]);\n\n const durationMs = spec?.durationMs ?? DEFAULT_DURATION_MS;\n const easing = spec?.easing ?? DEFAULT_EASING;\n const scaledDuration = Math.max(1, durationMs / speed);\n\n const [phase, setPhase] = useState<0 | 1>(0);\n\n useEffect(() => {\n if (reducedMotion) return;\n setPhase(0);\n const id = requestAnimationFrame(() => setPhase(1));\n const loop = window.setInterval(() => {\n setPhase((p) => (p === 0 ? 1 : 0));\n }, scaledDuration * 2);\n return () => {\n cancelAnimationFrame(id);\n window.clearInterval(loop);\n };\n }, [scaledDuration, runKey, reducedMotion]);\n\n if (reducedMotion) {\n return (\n <div style={styles.reducedMotion}>\n Animation suppressed by <code>prefers-reduced-motion: reduce</code>.\n </div>\n );\n }\n\n return (\n <div style={styles.track}>\n <div\n style={{\n ...styles.ball,\n left: phase === 1 ? 'calc(100% - 32px)' : '4px',\n transition: `left ${scaledDuration}ms ${easing}`,\n }}\n aria-hidden\n />\n </div>\n );\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo, useState } from 'react';\nimport './MotionPreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { MotionSample, resolveMotionSpec } from '#/motion-preview/MotionSample.tsx';\nimport type { MotionSpeed } from '#/motion-preview/MotionSample.tsx';\n\nexport type { MotionSpeed };\n\nexport interface MotionPreviewProps {\n /**\n * Token-path filter. Defaults to transition + duration + cubicBezier\n * tokens. Use e.g. `\"transition.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n}\n\nconst SPEEDS: MotionSpeed[] = [0.25, 0.5, 1, 2];\n\ninterface Row {\n path: string;\n cssVar: string;\n durationMs: number;\n easing: string;\n kind: 'transition' | 'duration' | 'cubicBezier';\n}\n\nfunction formatSpec(row: Row): string {\n switch (row.kind) {\n case 'transition':\n return `transition · ${Math.round(row.durationMs)}ms · ${row.easing}`;\n case 'duration':\n return `duration · ${Math.round(row.durationMs)}ms`;\n case 'cubicBezier':\n return `cubicBezier · ${row.easing}`;\n }\n}\n\nexport function MotionPreview({ filter, caption }: MotionPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const [speed, setSpeed] = useState<MotionSpeed>(1);\n const [run, setRun] = useState(0);\n const reducedMotion = usePrefersReducedMotion();\n\n const rows = useMemo(() => {\n const collected: Row[] = [];\n for (const [path, token] of Object.entries(resolved)) {\n if (filter && !matchPath(path, filter)) continue;\n if (!filter && !['transition', 'duration', 'cubicBezier'].includes(token.$type ?? '')) {\n continue;\n }\n const kind = token.$type as Row['kind'] | undefined;\n if (!kind) continue;\n const spec = resolveMotionSpec(token, resolved);\n if (!spec) continue;\n collected.push({\n path,\n cssVar: resolveCssVar(path, project),\n durationMs: spec.durationMs,\n easing: spec.easing,\n kind,\n });\n }\n collected.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);\n return a.path.localeCompare(b.path, undefined, { numeric: true });\n });\n return collected;\n }, [resolved, filter, project]);\n\n const captionText =\n caption ??\n `${rows.length} motion token${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No motion tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n <div className=\"sb-motion-preview__controls\">\n <span className=\"sb-motion-preview__control-label\">Speed</span>\n {SPEEDS.map((s) => (\n <button\n key={s}\n type=\"button\"\n className={cx('sb-motion-preview__speed-btn', {\n 'sb-motion-preview__speed-btn--active': s === speed,\n })}\n onClick={() => setSpeed(s)}\n >\n {s}×\n </button>\n ))}\n <button\n type=\"button\"\n className=\"sb-motion-preview__replay-btn\"\n onClick={() => setRun((n) => n + 1)}\n disabled={reducedMotion}\n title={reducedMotion ? 'Disabled by prefers-reduced-motion' : 'Replay all'}\n >\n ↻ Replay\n </button>\n </div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-motion-preview__row\">\n <div className=\"sb-motion-preview__meta\">\n <span className=\"sb-motion-preview__path\">{row.path}</span>\n <span className=\"sb-motion-preview__specs\">{formatSpec(row)}</span>\n </div>\n <MotionSample path={row.path} speed={speed} runKey={run} />\n <span className=\"sb-motion-preview__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './OpacityScale.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface OpacityScaleProps {\n /**\n * Token-path filter. Use `\"number.opacity.*\"` or `\"opacity.*\"` depending\n * on your layout. Omit to match every `$type: 'number'` token whose\n * value is in `[0, 1]` — the value-range check (applied alongside\n * the glob) keeps line-heights / z-indexes out.\n */\n filter?: string;\n /**\n * DTCG `$type` filter. `opacity` tokens where DTCG ships them as a\n * dedicated type; otherwise `number` (the common placement pre-spec).\n * Accepts either.\n */\n type?: 'number' | 'opacity';\n /**\n * Sample token rendered at each opacity. Defaults to `color.accent.bg`\n * — swap to whatever colour your system uses to demonstrate scrim /\n * overlay behaviour.\n */\n sampleColor?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'value'` (default) — numeric, low opacity first.\n * - `'path'` — lexicographic on the dot-path.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n opacity: number;\n displayValue: string;\n}\n\nfunction toOpacity(raw: unknown): number {\n if (typeof raw === 'number') return raw;\n return Number.NaN;\n}\n\n/**\n * Render each opacity token as a colored sample at that opacity over a\n * checkerboard backdrop, so the transparency is visually readable. The\n * number by itself (`0.4`) doesn't convey what the token looks like\n * applied to a surface; the sample does.\n *\n * Only tokens whose `$value` is a finite number between 0 and 1\n * inclusive are rendered — non-opacity `number` siblings (`line-height`,\n * `z-index`) fall out naturally.\n */\nexport function OpacityScale({\n filter,\n type = 'number',\n sampleColor = 'color.accent.bg',\n caption,\n sortBy = 'value',\n sortDir = 'asc',\n}: OpacityScaleProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== type) return false;\n const v = toOpacity(token.$value);\n if (!Number.isFinite(v) || v < 0 || v > 1) return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const opacity = toOpacity(token.$value);\n return {\n path,\n cssVar: resolveCssVar(path, project),\n opacity,\n displayValue: String(opacity),\n };\n });\n }, [resolved, filter, type, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} opacity token${rows.length === 1 ? '' : 's'}${\n filter ? ` matching \\`${filter}\\`` : ''\n } · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No opacity tokens match this filter.</div>\n </div>\n );\n }\n\n const sampleColorVar = resolveCssVar(sampleColor, project);\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n <div className=\"sb-opacity-scale__grid\">\n {rows.map((row) => (\n <div key={row.path} className=\"sb-opacity-scale__card\">\n <div\n className=\"sb-opacity-scale__swatch\"\n style={\n {\n '--sb-opacity-scale-color': sampleColorVar,\n '--sb-opacity-scale-alpha': String(row.opacity),\n } as CSSProperties\n }\n aria-hidden\n />\n <div className=\"sb-opacity-scale__meta\">\n <span className=\"sb-opacity-scale__path\">{row.path}</span>\n <span className=\"sb-opacity-scale__value\">{row.displayValue}</span>\n <span className=\"sb-opacity-scale__css-var\">{row.cssVar}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import type { ReactElement, ReactNode } from 'react';\nimport { SwatchbookContext, useOptionalSwatchbookData } from '#/contexts.ts';\nimport type { ProjectSnapshot } from '#/contexts.ts';\n\nexport type { ProjectSnapshot };\n\nexport interface SwatchbookProviderProps {\n value: ProjectSnapshot;\n children: ReactNode;\n}\n\n/**\n * Wraps a tree of blocks with the token data they need to render.\n *\n * The Storybook addon's preview decorator mounts this automatically, so\n * story/MDX authors typically never see it. Outside Storybook — unit\n * tests, custom React apps, non-Storybook doc sites — consumers construct\n * a {@link ProjectSnapshot} (often imported from a JSON file) and wrap\n * their blocks in this provider.\n */\nexport function SwatchbookProvider({ value, children }: SwatchbookProviderProps): ReactElement {\n return <SwatchbookContext.Provider value={value}>{children}</SwatchbookContext.Provider>;\n}\n\n/**\n * Read the current {@link ProjectSnapshot}. Throws if called outside a\n * {@link SwatchbookProvider}; blocks that need to fall back to the\n * virtual module go through the internal `useProject()` hook instead.\n */\nexport function useSwatchbookData(): ProjectSnapshot {\n const value = useOptionalSwatchbookData();\n if (!value) {\n throw new Error(\n '[swatchbook-blocks] useSwatchbookData() called outside <SwatchbookProvider>. ' +\n 'Wrap your tree in <SwatchbookProvider value={snapshot}> or render inside a Storybook story.',\n );\n }\n return value;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { BORDER_FAINT, SURFACE_RAISED } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\nexport interface ShadowSampleProps {\n /** Full dot-path of the shadow token to preview. */\n path: string;\n}\n\nconst sampleStyle: CSSProperties = {\n width: 120,\n height: 56,\n background: SURFACE_RAISED,\n border: BORDER_FAINT,\n borderRadius: 6,\n};\n\nexport function ShadowSample({ path }: ShadowSampleProps): ReactElement {\n const project = useProject();\n const cssVar = resolveCssVar(path, project);\n return <div style={{ ...sampleStyle, boxShadow: cssVar }} aria-hidden />;\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './ShadowPreview.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { formatDimension, formatSubColor } from '#/internal/composite-sample-format.ts';\nimport type { ShadowLayer } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { ShadowSample } from '#/shadow-preview/ShadowSample.tsx';\n\nexport interface ShadowPreviewProps {\n /**\n * Token-path filter. Defaults to every `shadow` token. Use e.g.\n * `\"shadow.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` falls through to path (shadows don't have a\n * single-axis ordering); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n cssVar: string;\n layers: ShadowLayer[];\n}\n\nfunction asLayers(raw: unknown): ShadowLayer[] {\n if (Array.isArray(raw)) return raw as ShadowLayer[];\n if (raw && typeof raw === 'object') return [raw as ShadowLayer];\n return [];\n}\n\nfunction layerKey(path: string, layer: ShadowLayer, fallback: number): string {\n const off = `${formatDimension(layer.offsetX)},${formatDimension(layer.offsetY)}`;\n const blur = formatDimension(layer.blur);\n const spread = formatDimension(layer.spread);\n return `${path}|${off}|${blur}|${spread}|${fallback}`;\n}\n\nexport function ShadowPreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: ShadowPreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n const colorFormat = useColorFormat();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'shadow') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n layers: asLayers(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} shadow${rows.length === 1 ? '' : 's'}${filter ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No shadow tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-shadow-preview__row\">\n <div className=\"sb-shadow-preview__meta\">\n <span className=\"sb-shadow-preview__path\">{row.path}</span>\n <span className=\"sb-shadow-preview__css-var\">{row.cssVar}</span>\n </div>\n <div className=\"sb-shadow-preview__sample-cell\">\n <ShadowSample path={row.path} />\n </div>\n <div className=\"sb-shadow-preview__breakdown\">\n {row.layers.length === 1\n ? renderLayer(row.layers[0], colorFormat)\n : row.layers.map((layer, i) => (\n <Layer\n key={layerKey(row.path, layer, i)}\n layer={layer}\n index={i}\n total={row.layers.length}\n colorFormat={colorFormat}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction renderLayer(layer: ShadowLayer | undefined, format: ColorFormat): ReactElement[] {\n if (!layer) return [];\n const entries: [string, string][] = [\n ['offset', `${formatDimension(layer.offsetX)} ${formatDimension(layer.offsetY)}`],\n ['blur', formatDimension(layer.blur)],\n ['spread', formatDimension(layer.spread)],\n ['color', formatSubColor(layer.color, format)],\n ];\n if (layer.inset) entries.push(['inset', String(layer.inset)]);\n return entries.flatMap(([k, v]) => [\n <span key={`k-${k}`} className=\"sb-shadow-preview__breakdown-key\">\n {k}\n </span>,\n <span key={`v-${k}`}>{v}</span>,\n ]);\n}\n\nfunction Layer({\n layer,\n index,\n total,\n colorFormat,\n}: {\n layer: ShadowLayer;\n index: number;\n total: number;\n colorFormat: ColorFormat;\n}): ReactElement {\n return (\n <div className=\"sb-shadow-preview__layer\">\n <div className=\"sb-shadow-preview__layer-header\">\n layer {index + 1} of {total}\n </div>\n <div className={cx('sb-shadow-preview__breakdown', 'sb-shadow-preview__layer-breakdown')}>\n {renderLayer(layer, colorFormat)}\n </div>\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './StrokeStylePreview.css';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\nexport interface StrokeStylePreviewProps {\n /**\n * Token-path filter. Defaults to every `strokeStyle` token. Use e.g.\n * `\"stroke.style.*\"` to scope to the ref layer.\n */\n filter?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\nconst STRING_STYLES = new Set([\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n 'inset',\n]);\n\ninterface Row {\n path: string;\n cssVar: string;\n displayValue: string;\n cssStyle: string | null;\n}\n\nfunction extractCssStyle(value: unknown): string | null {\n if (typeof value === 'string' && STRING_STYLES.has(value)) return value;\n return null;\n}\n\nexport function StrokeStylePreview({\n filter,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: StrokeStylePreviewProps): ReactElement {\n const project = useProject();\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'strokeStyle') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => ({\n path,\n cssVar: resolveCssVar(path, project),\n displayValue: formatTokenValue(token.$value, token.$type, 'raw', project.listing[path]),\n cssStyle: extractCssStyle(token.$value),\n }));\n }, [resolved, filter, project, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} strokeStyle token${rows.length === 1 ? '' : 's'}${filter && filter !== 'strokeStyle' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No strokeStyle tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-stroke-style-sample__row\">\n <div className=\"sb-stroke-style-sample__meta\">\n <span className=\"sb-stroke-style-sample__path\">{row.path}</span>\n <span className=\"sb-stroke-style-sample__value\">{row.displayValue}</span>\n </div>\n {row.cssStyle ? (\n <div\n className=\"sb-stroke-style-sample__line\"\n style={{\n borderTopStyle: row.cssStyle as CSSProperties['borderTopStyle'],\n }}\n aria-hidden\n />\n ) : (\n <span className=\"sb-stroke-style-sample__object-fallback\">\n Object-form (dashArray + lineCap) — no pure CSS `border-style` equivalent.\n </span>\n )}\n <span className=\"sb-stroke-style-sample__css-var\">{row.cssVar}</span>\n </div>\n ))}\n </div>\n );\n}\n","import type { Axis, AxisVarianceResult } from '@unpunnyfuns/swatchbook-core';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\n\ntype VirtualVarianceByPathShape = Record<string, AxisVarianceResult>;\n\nexport interface DetailToken {\n $type?: string;\n $value?: unknown;\n $description?: string;\n $deprecated?: string | boolean;\n aliasOf?: string;\n aliasChain?: readonly string[];\n aliasedBy?: readonly string[];\n /**\n * Terrazzo-populated sub-value alias map for composite tokens. Shape\n * varies by $type: object-valued composites (`border`, `typography`,\n * `transition`) use `Record<string, string | undefined>` keyed by\n * sub-key; array-valued composites (`shadow`, `gradient`) use an array\n * of such records indexed per layer / stop. Carried through `unknown`\n * here so each consumer narrows at use-site.\n */\n partialAliasOf?: unknown;\n}\n\nexport interface TokenDetailData {\n token: DetailToken | undefined;\n cssVar: string;\n activeTheme: string;\n activeAxes: Record<string, string>;\n axes: readonly Axis[];\n resolved: Record<string, DetailToken>;\n cssVarPrefix: string;\n varianceByPath: VirtualVarianceByPathShape;\n /**\n * Pure-function accessor that composes the resolved tokens for any\n * tuple of axis selections — used by the `AxisVariance` grid to\n * read per-cell values without indexing `permutationsResolved` by\n * a derived tuple name.\n */\n resolveAt: (tuple: Record<string, string>) => Record<string, DetailToken>;\n}\n\nexport function useTokenDetailData(path: string): TokenDetailData {\n const project = useProject();\n const { activeTheme, activeAxes, axes, resolved, cssVarPrefix, varianceByPath, resolveAt } =\n project;\n const typedResolved = resolved as Record<string, DetailToken>;\n return {\n token: typedResolved[path],\n cssVar: resolveCssVar(path, project),\n activeTheme,\n activeAxes,\n axes,\n resolved: typedResolved,\n cssVarPrefix,\n varianceByPath,\n resolveAt: resolveAt as (tuple: Record<string, string>) => Record<string, DetailToken>,\n };\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface AliasChainProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function AliasChain({ path }: AliasChainProps): ReactElement | null {\n const { token } = useTokenDetailData(path);\n\n const chain = useMemo<string[]>(() => {\n if (!token) return [];\n if (Array.isArray(token.aliasChain) && token.aliasChain.length > 0) {\n return [path, ...token.aliasChain];\n }\n if (typeof token.aliasOf === 'string') return [path, token.aliasOf];\n return [path];\n }, [token, path]);\n\n if (chain.length <= 1) return null;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Alias chain</div>\n <div className=\"sb-token-detail__chain\">\n {chain.map((step, i) => (\n <span key={step} className=\"sb-token-detail__chain\">\n <span className=\"sb-token-detail__chain-node\">{step}</span>\n {i < chain.length - 1 && <span className=\"sb-token-detail__arrow\">→</span>}\n </span>\n ))}\n </div>\n </>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface AliasedByProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nconst ALIASED_BY_DEPTH_CAP = 6;\n\ninterface AliasedByNode {\n path: string;\n children: AliasedByNode[];\n truncated?: boolean;\n}\n\nconst GROUP_RANK: Record<string, number> = { ref: 0, sys: 1 };\n\nexport function AliasedBy({ path }: AliasedByProps): ReactElement | null {\n const { resolved } = useTokenDetailData(path);\n const tree = useMemo<AliasedByNode[]>(() => buildAliasedByTree(path, resolved), [path, resolved]);\n const truncated = useMemo(() => treeHasTruncation(tree), [tree]);\n\n if (tree.length === 0) return null;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Aliased by</div>\n <ul className=\"sb-token-detail__aliased-by-list\">\n {tree.map((node) => (\n <AliasedByRow key={node.path} node={node} depth={0} />\n ))}\n </ul>\n {truncated && (\n <div className=\"sb-token-detail__aliased-by-truncated\">\n Further descendants truncated at depth {ALIASED_BY_DEPTH_CAP}.\n </div>\n )}\n </>\n );\n}\n\nfunction AliasedByRow({ node, depth }: { node: AliasedByNode; depth: number }): ReactElement {\n return (\n <li>\n <div className=\"sb-token-detail__aliased-by-row\" style={{ paddingLeft: depth * 16 }}>\n <span className=\"sb-token-detail__chain-node\">{node.path}</span>\n </div>\n {node.children.length > 0 && (\n <ul className=\"sb-token-detail__aliased-by-list\">\n {node.children.map((child) => (\n <AliasedByRow key={child.path} node={child} depth={depth + 1} />\n ))}\n </ul>\n )}\n </li>\n );\n}\n\nexport function buildAliasedByTree(\n rootPath: string,\n resolved: Record<string, DetailToken>,\n): AliasedByNode[] {\n const root = resolved[rootPath];\n const direct = root?.aliasedBy;\n if (!direct || direct.length === 0) return [];\n return sortPaths(direct).map((p) => walk(p, resolved, new Set<string>([rootPath]), 1));\n}\n\n// `ancestors` is the current root-to-here path only (copied per descent),\n// not a tree-wide visited set: that guards genuine cycles without hiding a\n// node that legitimately appears under two sibling branches of a diamond\n// alias graph (a shared set let the first branch claim the node and\n// truncate every later one).\nfunction walk(\n path: string,\n resolved: Record<string, DetailToken>,\n ancestors: ReadonlySet<string>,\n depth: number,\n): AliasedByNode {\n if (ancestors.has(path)) return { path, children: [] };\n const token = resolved[path];\n const parents = token?.aliasedBy;\n if (!parents || parents.length === 0) return { path, children: [] };\n if (depth >= ALIASED_BY_DEPTH_CAP) {\n return { path, children: [], truncated: true };\n }\n const childAncestors = new Set(ancestors).add(path);\n const children = sortPaths(parents).map((p) => walk(p, resolved, childAncestors, depth + 1));\n return { path, children };\n}\n\nfunction sortPaths(paths: readonly string[]): string[] {\n return paths.toSorted((a, b) => {\n const ra = GROUP_RANK[a.split('.')[0] ?? ''] ?? 2;\n const rb = GROUP_RANK[b.split('.')[0] ?? ''] ?? 2;\n return ra !== rb ? ra - rb : a.localeCompare(b, undefined, { numeric: true });\n });\n}\n\nfunction treeHasTruncation(nodes: AliasedByNode[]): boolean {\n for (const n of nodes) {\n if (n.truncated) return true;\n if (treeHasTruncation(n.children)) return true;\n }\n return false;\n}\n","import type { Axis } from '@unpunnyfuns/swatchbook-core';\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport { perAxisAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface AxisVarianceProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\ntype Variance =\n | { kind: 'constant' }\n | { kind: 'one-axis'; axis: string; varyingAxes: readonly [string] }\n | { kind: 'multi-axis'; varyingAxes: readonly [string, string, ...string[]] };\n\nexport function AxisVariance({ path }: AxisVarianceProps): ReactElement {\n const { token, cssVar, axes, activeAxes, cssVarPrefix, varianceByPath, resolveAt } =\n useTokenDetailData(path);\n const colorFormat = useColorFormat();\n const tokenType = token?.$type;\n const isColor = tokenType === 'color';\n const formatFn = (t: DetailToken | undefined): string => valueFor(t, tokenType, colorFormat);\n\n const variance = useMemo<Variance>(() => {\n // Read the pre-computed per-path variance from the snapshot. The\n // server side runs the bucket analysis once at load and ships the\n // map over the wire — O(1) lookup per render instead of an O(paths\n // × permutations) re-derivation here.\n const result = varianceByPath[path];\n if (!result) return { kind: 'constant' };\n switch (result.kind) {\n case 'constant':\n return { kind: 'constant' };\n case 'single':\n return { kind: 'one-axis', axis: result.axis, varyingAxes: result.varyingAxes };\n case 'multi':\n return { kind: 'multi-axis', varyingAxes: result.varyingAxes };\n default: {\n const exhaustive: never = result;\n throw new Error(`unhandled AxisVarianceResult kind: ${JSON.stringify(exhaustive)}`);\n }\n }\n }, [path, varianceByPath]);\n\n if (axes.length === 0) {\n return <></>;\n }\n\n if (variance.kind === 'constant') {\n const value = formatFn(resolveAt(activeAxes)[path] as DetailToken | undefined);\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Values across axes</div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <tbody>\n <tr className=\"sb-token-detail__theme-row\">\n <td className=\"sb-token-detail__theme-cell\" data-testid=\"token-detail-constant\">\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n aria-hidden\n />\n )}\n {value}\n <span style={{ opacity: 0.6, marginLeft: 8 }}>same across every axis</span>\n </td>\n </tr>\n </tbody>\n </table>\n </>\n );\n }\n\n if (variance.kind === 'one-axis') {\n const axisName = variance.axis;\n const axis = axes.find((a) => a.name === axisName);\n if (!axis) return <></>;\n const contextValues = axis.contexts.map((ctx) => {\n const target = { ...activeAxes, [axisName]: ctx };\n return {\n ctx,\n target,\n value: formatFn(resolveAt(target)[path] as DetailToken | undefined),\n };\n });\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Varies with {axisName}</div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <tbody>\n {contextValues.map((row) => (\n <tr\n key={row.ctx}\n className=\"sb-token-detail__theme-row\"\n data-axis={axisName}\n data-context={row.ctx}\n >\n <td className=\"sb-token-detail__theme-cell\" style={{ width: '30%' }}>\n {row.ctx}\n </td>\n <td className=\"sb-token-detail__theme-cell\">\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n {...perAxisAttrs(cssVarPrefix, row.target)}\n aria-hidden\n />\n )}\n {row.value}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </>\n );\n }\n\n const varying = variance.varyingAxes\n .map((name) => axes.find((a) => a.name === name))\n .filter((a): a is Axis => Boolean(a))\n .toSorted((a, b) => b.contexts.length - a.contexts.length);\n const [rowAxis, colAxis, ...extra] = varying;\n if (!rowAxis || !colAxis) return <></>;\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">\n Varies with {variance.varyingAxes.join(' × ')}\n </div>\n <table className=\"sb-token-detail__theme-table\" data-testid=\"token-detail-values\">\n <thead>\n <tr className=\"sb-token-detail__theme-row\">\n <th className=\"sb-token-detail__theme-cell\" style={{ textAlign: 'left', opacity: 0.7 }}>\n {rowAxis.name} \\ {colAxis.name}\n </th>\n {colAxis.contexts.map((col) => (\n <th\n key={col}\n className=\"sb-token-detail__theme-cell\"\n style={{ textAlign: 'left', opacity: 0.7 }}\n >\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rowAxis.contexts.map((row) => (\n <tr key={row} className=\"sb-token-detail__theme-row\">\n <td className=\"sb-token-detail__theme-cell\">{row}</td>\n {colAxis.contexts.map((col) => {\n const target: Record<string, string> = {\n ...activeAxes,\n [rowAxis.name]: row,\n [colAxis.name]: col,\n };\n const value = formatFn(resolveAt(target)[path] as DetailToken | undefined);\n return (\n <td\n key={col}\n className=\"sb-token-detail__theme-cell\"\n data-row={row}\n data-col={col}\n >\n {isColor && (\n <span\n className=\"sb-token-detail__swatch\"\n style={{ background: cssVar }}\n {...perAxisAttrs(cssVarPrefix, target)}\n aria-hidden\n />\n )}\n {value}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {extra.length > 0 && (\n <div className=\"sb-token-detail__aliased-by-truncated\" style={{ marginTop: 6 }}>\n Values also vary with {extra.map((a) => a.name).join(', ')}; matrix shows the slice for\n the active selection.\n </div>\n )}\n </>\n );\n}\n\nfunction valueFor(\n token: DetailToken | undefined,\n $type: string | undefined,\n format: ColorFormat,\n): string {\n if (!token) return '—';\n return formatTokenValue(token.$value, $type, format);\n}\n","import type { ReactElement } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport type { ColorFormat } from '#/format-color.ts';\nimport type {\n BorderValue,\n GradientStop,\n ShadowLayer,\n TransitionValue,\n TypographyValue,\n} from '#/internal/composite-types.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport type { DetailToken } from '#/token-detail/internal.ts';\n\nexport interface CompositeBreakdownProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function CompositeBreakdown({ path }: CompositeBreakdownProps): ReactElement | null {\n const { token, resolved } = useTokenDetailData(path);\n const colorFormat = useColorFormat();\n if (!token) return null;\n return (\n <CompositeBreakdownContent\n type={token.$type}\n rawValue={token.$value}\n partialAliasOf={token.partialAliasOf}\n resolved={resolved}\n colorFormat={colorFormat}\n />\n );\n}\n\nexport function CompositeBreakdownContent({\n type,\n rawValue,\n partialAliasOf,\n resolved,\n colorFormat,\n}: {\n type: string | undefined;\n rawValue: unknown;\n partialAliasOf?: unknown;\n resolved?: Record<string, DetailToken>;\n colorFormat: ColorFormat;\n}): ReactElement | null {\n if (!rawValue || typeof rawValue !== 'object') return null;\n\n const objectAliases = pickObjectAliases(partialAliasOf);\n const arrayAliases = pickArrayAliases(partialAliasOf);\n const aliasFor = (key: string): readonly string[] | undefined =>\n subValueChain(objectAliases?.[key], resolved);\n\n if (type === 'typography') {\n const v = rawValue as TypographyValue;\n return renderKeyValueList([\n ['fontFamily', formatFontFamily(v.fontFamily), aliasFor('fontFamily')],\n ['fontSize', formatDimensionValue(v.fontSize), aliasFor('fontSize')],\n ['fontWeight', formatPrimitive(v.fontWeight), aliasFor('fontWeight')],\n ['lineHeight', formatPrimitive(v.lineHeight), aliasFor('lineHeight')],\n ['letterSpacing', formatDimensionValue(v.letterSpacing), aliasFor('letterSpacing')],\n ]);\n }\n\n if (type === 'border') {\n const v = rawValue as BorderValue;\n return renderKeyValueList([\n ['color', formatColorSubValue(v.color, colorFormat), aliasFor('color')],\n ['width', formatDimensionValue(v.width), aliasFor('width')],\n ['style', formatPrimitive(v.style), aliasFor('style')],\n ]);\n }\n\n if (type === 'transition') {\n const v = rawValue as TransitionValue;\n return renderKeyValueList([\n ['duration', formatDimensionValue(v.duration), aliasFor('duration')],\n ['timingFunction', formatPrimitive(v.timingFunction), aliasFor('timingFunction')],\n ['delay', formatDimensionValue(v.delay), aliasFor('delay')],\n ]);\n }\n\n if (type === 'shadow') {\n const layers = Array.isArray(rawValue) ? rawValue : [rawValue];\n const multi = layers.length > 1;\n const layerAliasFor = (i: number, key: string): readonly string[] | undefined =>\n subValueChain(arrayAliases?.[i]?.[key], resolved);\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {layers.map((layer, i) => {\n const v = layer as ShadowLayer;\n return (\n <div key={shadowLayerKey(v, i)} style={{ display: 'contents' }}>\n {multi && (\n <div className=\"sb-token-detail__breakdown-layer-header\">Layer {i + 1}</div>\n )}\n <KeyValueRow\n label=\"color\"\n value={formatColorSubValue(v.color, colorFormat)}\n alias={layerAliasFor(i, 'color')}\n />\n <KeyValueRow\n label=\"offsetX\"\n value={formatDimensionValue(v.offsetX)}\n alias={layerAliasFor(i, 'offsetX')}\n />\n <KeyValueRow\n label=\"offsetY\"\n value={formatDimensionValue(v.offsetY)}\n alias={layerAliasFor(i, 'offsetY')}\n />\n <KeyValueRow\n label=\"blur\"\n value={formatDimensionValue(v.blur)}\n alias={layerAliasFor(i, 'blur')}\n />\n <KeyValueRow\n label=\"spread\"\n value={formatDimensionValue(v.spread)}\n alias={layerAliasFor(i, 'spread')}\n />\n {v.inset !== undefined && (\n <KeyValueRow label=\"inset\" value={formatPrimitive(v.inset)} alias={undefined} />\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n if (type === 'gradient') {\n const stops = Array.isArray(rawValue) ? rawValue : [];\n if (stops.length === 0) return null;\n const stopAliasFor = (i: number): readonly string[] | undefined =>\n subValueChain(arrayAliases?.[i]?.['color'], resolved);\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {stops.map((stop, i) => {\n const v = stop as GradientStop;\n const position = typeof v.position === 'number' ? v.position : 0;\n return (\n <KeyValueRow\n key={gradientStopKey(v, i)}\n label={`${(position * 100).toFixed(0)}%`}\n value={formatColorSubValue(v.color, colorFormat)}\n alias={stopAliasFor(i)}\n />\n );\n })}\n </div>\n );\n }\n\n return null;\n}\n\nfunction renderKeyValueList(\n rows: [string, string | null, readonly string[] | undefined][],\n): ReactElement {\n return (\n <div className=\"sb-token-detail__breakdown-section\">\n {rows\n .filter(([, v, alias]) => v !== null || (alias && alias.length > 0))\n .map(([k, v, alias]) => (\n <KeyValueRow key={k} label={k} value={v ?? ''} alias={alias} />\n ))}\n </div>\n );\n}\n\nfunction KeyValueRow({\n label,\n value,\n alias,\n}: {\n label: string;\n value: string | null;\n alias: readonly string[] | undefined;\n}): ReactElement {\n const hasAlias = alias && alias.length > 0;\n return (\n <>\n <span className=\"sb-token-detail__breakdown-key\">{label}</span>\n <span className=\"sb-token-detail__breakdown-value\">\n <span>{value ?? '—'}</span>\n {hasAlias && (\n <span className=\"sb-token-detail__breakdown-alias\" data-testid=\"breakdown-alias\">\n {alias.map((p, i) => (\n <span key={p} className=\"sb-token-detail__breakdown-alias-step\">\n {i > 0 && <span className=\"sb-token-detail__arrow\">→</span>}\n <span className=\"sb-token-detail__chain-node\">{p}</span>\n </span>\n ))}\n </span>\n )}\n </span>\n </>\n );\n}\n\nfunction formatPrimitive(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);\n return JSON.stringify(v);\n}\n\nfunction formatFontFamily(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string') return v;\n if (Array.isArray(v)) return v.map(String).join(', ');\n return JSON.stringify(v);\n}\n\nfunction formatDimensionValue(v: unknown): string | null {\n if (v == null) return null;\n if (typeof v === 'string' || typeof v === 'number') return String(v);\n if (typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number' && typeof d.unit === 'string') return `${d.value}${d.unit}`;\n }\n return JSON.stringify(v);\n}\n\n// Route sub-value colors through `formatColor` so they honor the active\n// color-format dropdown, just like the standalone `<ColorPalette />` and\n// `<TokenDetail />` top-line do. Returns `null` for a missing field so\n// the key/value row drops out entirely.\nfunction formatColorSubValue(v: unknown, format: ColorFormat): string | null {\n if (v == null) return null;\n return formatColor(v, format).value;\n}\n\nfunction pickObjectAliases(v: unknown): Record<string, string | undefined> | undefined {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return undefined;\n return v as Record<string, string | undefined>;\n}\n\nfunction pickArrayAliases(v: unknown): Record<string, string | undefined>[] | undefined {\n if (!Array.isArray(v)) return undefined;\n return v as Record<string, string | undefined>[];\n}\n\n// Walk the alias chain starting from an immediate sub-value alias target.\n// `aliasTarget` is the path the sub-value directly references; the target\n// token's own `aliasChain` continues the walk to the primitive.\nfunction subValueChain(\n aliasTarget: string | undefined,\n resolved: Record<string, DetailToken> | undefined,\n): readonly string[] | undefined {\n if (!aliasTarget) return undefined;\n const tok = resolved?.[aliasTarget];\n const tail = tok?.aliasChain;\n return tail && tail.length > 0 ? [aliasTarget, ...tail] : [aliasTarget];\n}\n\nfunction shadowLayerKey(layer: ShadowLayer, fallback: number): string {\n const parts = [\n layer.color,\n layer.offsetX,\n layer.offsetY,\n layer.blur,\n layer.spread,\n layer.inset,\n ].map((p) => (p === undefined ? '' : JSON.stringify(p)));\n return `shadow|${parts.join('|')}|${fallback}`;\n}\n\nfunction gradientStopKey(stop: GradientStop, fallback: number): string {\n return `stop|${stop.position ?? fallback}|${JSON.stringify(stop.color)}`;\n}\n","/**\n * Numeric duration (ms) the motion preview should animate over for a given\n * token type, read from its resolved `$value`. Lets the sample's toggle loop\n * match the token's real duration instead of a fixed cadence — a long token\n * (say 2s) otherwise reverses mid-move under the old hardcoded interval.\n * Returns `undefined` for types that carry no duration, so the caller can\n * fall back to its default.\n */\nexport function transitionDurationMs(\n type: string | undefined,\n rawValue: unknown,\n): number | undefined {\n // The cubicBezier sample animates `left 800ms <bezier>`, so its loop is fixed.\n if (type === 'cubicBezier') return 800;\n if (type === 'duration') return parseDurationMs(rawValue);\n if (type === 'transition' && rawValue !== null && typeof rawValue === 'object') {\n return parseDurationMs((rawValue as { duration?: unknown }).duration);\n }\n return undefined;\n}\n\n// Parse a DTCG duration (`{ value, unit }`), a CSS string (`300ms` / `1.5s`),\n// or a bare number (treated as ms) into milliseconds.\nfunction parseDurationMs(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') {\n const m = /^([\\d.]+)(ms|s)?$/.exec(v.trim());\n if (!m?.[1]) return undefined;\n const n = Number(m[1]);\n if (Number.isNaN(n)) return undefined;\n return m[2] === 's' ? n * 1000 : n;\n }\n if (v !== null && typeof v === 'object') {\n const d = v as { value?: unknown; unit?: unknown };\n if (typeof d.value === 'number') return d.unit === 's' ? d.value * 1000 : d.value;\n }\n return undefined;\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useEffect, useState } from 'react';\nimport { cssVarAsNumber } from '#/internal/css-var-style.ts';\nimport { usePrefersReducedMotion } from '#/internal/prefers-reduced-motion.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport { transitionDurationMs } from '#/token-detail/transition-duration.ts';\n\nexport interface CompositePreviewProps {\n /** Full dot-path of the token to preview. */\n path: string;\n}\n\nconst PANGRAM = 'Sphinx of black quartz, judge my vow.';\n\nconst STROKE_STYLE_STRINGS = new Set([\n 'solid',\n 'dashed',\n 'dotted',\n 'double',\n 'groove',\n 'ridge',\n 'outset',\n 'inset',\n]);\n\nexport function CompositePreview({ path }: CompositePreviewProps): ReactElement | null {\n const { token, cssVar } = useTokenDetailData(path);\n if (!token) return null;\n return <CompositePreviewContent type={token.$type} cssVar={cssVar} rawValue={token.$value} />;\n}\n\nexport function CompositePreviewContent({\n type,\n cssVar,\n rawValue,\n}: {\n type: string | undefined;\n cssVar: string;\n rawValue: unknown;\n}): ReactElement | null {\n if (type === 'typography') {\n const base = cssVar.replace(/^var\\(/, '').replace(/\\)$/, '');\n return (\n <div\n className=\"sb-token-detail__typography-sample\"\n style={{\n fontFamily: `var(${base}-font-family)`,\n fontSize: `var(${base}-font-size)`,\n fontWeight: cssVarAsNumber(`var(${base}-font-weight)`),\n lineHeight: cssVarAsNumber(`var(${base}-line-height)`),\n letterSpacing: `var(${base}-letter-spacing)`,\n }}\n >\n {PANGRAM}\n </div>\n );\n }\n if (type === 'shadow') {\n return (\n <div className=\"sb-token-detail__shadow-sample\" style={{ boxShadow: cssVar }} aria-hidden />\n );\n }\n if (type === 'border') {\n return (\n <div className=\"sb-token-detail__border-sample\" style={{ border: cssVar }} aria-hidden />\n );\n }\n if (type === 'transition') {\n return (\n <TransitionSample transition={cssVar} durationMs={transitionDurationMs(type, rawValue)} />\n );\n }\n if (type === 'dimension') {\n return (\n <div className=\"sb-token-detail__dimension-track\">\n <div className=\"sb-token-detail__dimension-bar\" style={{ width: cssVar }} aria-hidden />\n </div>\n );\n }\n if (type === 'duration') {\n return (\n <TransitionSample\n transition={`left ${cssVar} ease`}\n durationMs={transitionDurationMs(type, rawValue)}\n />\n );\n }\n if (type === 'fontFamily') {\n return (\n <div className=\"sb-token-detail__font-family-sample\" style={{ fontFamily: cssVar }}>\n {PANGRAM}\n </div>\n );\n }\n if (type === 'fontWeight') {\n return (\n <div\n className=\"sb-token-detail__font-weight-sample\"\n style={{ fontWeight: cssVarAsNumber(cssVar) }}\n >\n Aa\n </div>\n );\n }\n if (type === 'cubicBezier') {\n return (\n <TransitionSample\n transition={`left 800ms ${cssVar}`}\n durationMs={transitionDurationMs(type, rawValue)}\n />\n );\n }\n if (type === 'gradient') {\n return (\n <div\n className=\"sb-token-detail__gradient-sample\"\n style={{ background: `linear-gradient(to right, ${cssVar})` }}\n aria-hidden\n />\n );\n }\n if (type === 'strokeStyle') {\n return <StrokeStylePreview value={rawValue} />;\n }\n if (type === 'color') {\n return (\n <div className=\"sb-token-detail__color-swatch-row\" aria-hidden>\n <div className=\"sb-token-detail__color-swatch-light\" style={{ background: cssVar }} />\n <div className=\"sb-token-detail__color-swatch-dark\" style={{ background: cssVar }} />\n </div>\n );\n }\n return null;\n}\n\nfunction StrokeStylePreview({ value }: { value: unknown }): ReactElement {\n if (typeof value === 'string' && STROKE_STYLE_STRINGS.has(value)) {\n return (\n <div\n className=\"sb-token-detail__stroke-style-line\"\n style={{ borderTopStyle: value as CSSProperties['borderTopStyle'] }}\n aria-hidden\n />\n );\n }\n if (value && typeof value === 'object' && 'dashArray' in value) {\n const v = value as {\n dashArray?: unknown;\n lineCap?: unknown;\n };\n const lengths = asDashLengths(v.dashArray);\n if (lengths.length === 0) {\n return (\n <div className=\"sb-token-detail__stroke-style-fallback\">\n Object-form strokeStyle with no resolvable dashArray.\n </div>\n );\n }\n const cap = typeof v.lineCap === 'string' ? v.lineCap : 'butt';\n return (\n <svg\n className=\"sb-token-detail__stroke-style-svg\"\n viewBox=\"0 0 220 24\"\n preserveAspectRatio=\"none\"\n aria-hidden\n >\n <line\n x1=\"4\"\n y1=\"12\"\n x2=\"216\"\n y2=\"12\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeDasharray={lengths.join(' ')}\n strokeLinecap={cap as 'butt' | 'round' | 'square'}\n />\n </svg>\n );\n }\n return (\n <div className=\"sb-token-detail__stroke-style-fallback\">\n strokeStyle value could not be previewed.\n </div>\n );\n}\n\nfunction asDashLengths(raw: unknown): number[] {\n if (!Array.isArray(raw)) return [];\n const out: number[] = [];\n for (const entry of raw) {\n if (typeof entry === 'number') {\n out.push(entry);\n continue;\n }\n if (entry && typeof entry === 'object') {\n const e = entry as { value?: unknown };\n if (typeof e.value === 'number') out.push(e.value);\n }\n }\n return out;\n}\n\n// Toggle cadence when the token carries no readable duration.\nconst DEFAULT_LOOP_MS = 1200;\n// Rest at each end so the eye registers the position before the ball returns;\n// added on top of the move duration so each leg fully completes first.\nconst MOTION_HOLD_MS = 400;\n\nfunction TransitionSample({\n transition,\n durationMs,\n}: {\n transition: string;\n durationMs?: number | undefined;\n}): ReactElement {\n const reduced = usePrefersReducedMotion();\n const [phase, setPhase] = useState<0 | 1>(0);\n\n useEffect(() => {\n if (reduced) return;\n // Match the loop to the token's real duration; a long token otherwise\n // reversed mid-move under the old fixed 1200ms interval.\n const loopMs = durationMs === undefined ? DEFAULT_LOOP_MS : durationMs + MOTION_HOLD_MS;\n const id = requestAnimationFrame(() => setPhase(1));\n const loop = window.setInterval(() => {\n setPhase((p) => (p === 0 ? 1 : 0));\n }, loopMs);\n return () => {\n cancelAnimationFrame(id);\n window.clearInterval(loop);\n };\n }, [reduced, durationMs]);\n\n if (reduced) {\n return (\n <div className=\"sb-token-detail__reduced-motion\">\n Animation suppressed by `prefers-reduced-motion: reduce`.\n </div>\n );\n }\n\n return (\n <div className=\"sb-token-detail__motion-track\">\n <div\n className=\"sb-token-detail__motion-ball\"\n style={{\n left: phase === 1 ? 'calc(100% - 28px)' : '4px',\n transition,\n }}\n aria-hidden\n />\n </div>\n );\n}\n","import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { useProject } from '#/internal/use-project.ts';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface ConsumerOutputProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\nexport function ConsumerOutput({ path }: ConsumerOutputProps): ReactElement | null {\n const { token, cssVar, activeAxes } = useTokenDetailData(path);\n const { listing } = useProject();\n\n if (!token) return null;\n\n const tupleLabel = Object.entries(activeAxes)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n\n // Platforms beyond `css`. Populated only when the consumer has loaded\n // extra plugins (`@terrazzo/plugin-swift`, `-android`, `-sass`, …) via\n // `config.terrazzoPlugins` + `config.listingOptions.platforms`. Always\n // empty otherwise — the row set falls back to Path + CSS.\n const names = listing[path]?.names ?? {};\n const extraPlatforms = Object.keys(names)\n .filter((platform) => platform !== 'css' && names[platform])\n .toSorted();\n\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Consumer output</div>\n {tupleLabel && (\n <div className=\"sb-token-detail__tuple-indicator\">\n Active tuple: <strong>{tupleLabel}</strong>\n </div>\n )}\n <OutputRow label=\"Path\" value={path} testId=\"consumer-output-path\" />\n <OutputRow label=\"CSS\" value={cssVar} testId=\"consumer-output-css\" />\n {extraPlatforms.map((platform) => (\n <OutputRow\n key={platform}\n label={formatPlatformLabel(platform)}\n value={names[platform]!}\n testId={`consumer-output-${platform}`}\n />\n ))}\n </>\n );\n}\n\nfunction formatPlatformLabel(platform: string): string {\n if (platform.length === 0) return platform;\n return platform[0]!.toUpperCase() + platform.slice(1);\n}\n\ninterface OutputRowProps {\n label: string;\n value: string;\n testId: string;\n}\n\nfunction OutputRow({ label, value, testId }: OutputRowProps): ReactElement {\n return (\n <div className=\"sb-token-detail__consumer-row\">\n <span className=\"sb-token-detail__consumer-row-label\">{label}</span>\n <code className=\"sb-token-detail__consumer-row-value\" data-testid={testId}>\n {value}\n </code>\n <CopyButton text={value} testId={`${testId}-copy`} />\n </div>\n );\n}\n\nfunction CopyButton({ text, testId }: { text: string; testId: string }): ReactElement {\n const [copied, setCopied] = useState(false);\n return (\n <button\n type=\"button\"\n className=\"sb-token-detail__consumer-row-copy\"\n data-testid={testId}\n onClick={() => {\n void copyToClipboard(text).then((ok) => {\n if (!ok) return;\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1200);\n });\n }}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n );\n}\n\nasync function copyToClipboard(text: string): Promise<boolean> {\n if (typeof navigator === 'undefined' || !navigator.clipboard) return false;\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n","import type { ReactElement } from 'react';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface TokenHeaderProps {\n /** Full dot-path of the token. */\n path: string;\n /** Override the heading. Defaults to the path. */\n heading?: string;\n}\n\nexport function TokenHeader({ path, heading }: TokenHeaderProps): ReactElement {\n const { token, cssVar, activeTheme } = useTokenDetailData(path);\n\n if (!token) {\n return (\n <div className=\"sb-token-detail__missing\">\n Token <code>{path}</code> not found in theme <strong>{activeTheme}</strong>.\n </div>\n );\n }\n\n return (\n <>\n <h3 className=\"sb-token-detail__heading\">{heading ?? path}</h3>\n <div className=\"sb-token-detail__subline\">\n {token.$type && <span className=\"sb-token-detail__type-pill\">{token.$type}</span>}\n <span>{cssVar}</span>\n </div>\n {token.$description && <p className=\"sb-token-detail__description\">{token.$description}</p>}\n </>\n );\n}\n","import type { ReactElement } from 'react';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\n\nexport interface TokenUsageSnippetProps {\n /** Full dot-path of the token. */\n path: string;\n}\n\n// DTCG `$type`s with a single canonical CSS property. Types whose value is\n// applied across many properties (`dimension`, `number`, `strokeStyle`,\n// `typography`) are intentionally absent — they fall back to a commented hint.\nconst CSS_PROPERTY_BY_TYPE: Record<string, string> = {\n color: 'color',\n shadow: 'box-shadow',\n border: 'border',\n fontFamily: 'font-family',\n fontWeight: 'font-weight',\n duration: 'transition-duration',\n cubicBezier: 'transition-timing-function',\n gradient: 'background',\n transition: 'transition',\n};\n\nfunction usageSnippet(cssVar: string, type: string | undefined): string {\n const property = type ? CSS_PROPERTY_BY_TYPE[type] : undefined;\n if (property) return `${property}: ${cssVar};`;\n if (type) return `/* ${type} */ ${cssVar};`;\n return `${cssVar};`;\n}\n\nexport function TokenUsageSnippet({ path }: TokenUsageSnippetProps): ReactElement | null {\n const { token, cssVar } = useTokenDetailData(path);\n if (!token) return null;\n const snippet = usageSnippet(cssVar, token.$type);\n return (\n <>\n <div className=\"sb-token-detail__section-header\">Usage</div>\n <div className=\"sb-token-detail__snippet-row\">\n <code className=\"sb-token-detail__snippet\">{snippet}</code>\n <CopyButton value={snippet} label={`Copy usage snippet ${snippet}`} />\n </div>\n </>\n );\n}\n","import cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useColorFormat } from '#/contexts.ts';\nimport { formatColor } from '#/format-color.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport { AliasChain } from '#/token-detail/AliasChain.tsx';\nimport { AliasedBy } from '#/token-detail/AliasedBy.tsx';\nimport { AxisVariance } from '#/token-detail/AxisVariance.tsx';\nimport { CompositeBreakdown } from '#/token-detail/CompositeBreakdown.tsx';\nimport { CompositePreview } from '#/token-detail/CompositePreview.tsx';\nimport { ConsumerOutput } from '#/token-detail/ConsumerOutput.tsx';\nimport { TokenHeader } from '#/token-detail/TokenHeader.tsx';\nimport { TokenUsageSnippet } from '#/token-detail/TokenUsageSnippet.tsx';\nimport { useTokenDetailData } from '#/token-detail/internal.ts';\nimport '#/token-detail/styles.css';\n\nexport interface TokenDetailProps {\n /** Full dot-path of the token to inspect. */\n path: string;\n /** Override the heading. Defaults to the path. */\n heading?: string;\n}\n\nexport function TokenDetail({ path, heading }: TokenDetailProps): ReactElement {\n const { token, cssVar, activeTheme, activeAxes, cssVarPrefix } = useTokenDetailData(path);\n const colorFormat = useColorFormat();\n const { listing } = useProject();\n const wrapperAttrs = blockWrapperAttrs(cssVarPrefix, activeAxes);\n\n if (!token) {\n return (\n <div {...wrapperAttrs} className={cx(wrapperAttrs['className'], 'sb-token-detail')}>\n <div className=\"sb-token-detail__missing\">\n Token <code>{path}</code> not found in theme <strong>{activeTheme}</strong>.\n </div>\n </div>\n );\n }\n\n const isColor = token.$type === 'color';\n const gamut = isColor ? formatColor(token.$value, colorFormat) : null;\n const value = formatTokenValue(token.$value, token.$type, colorFormat, listing[path]);\n const outOfGamut = gamut?.outOfGamut ?? false;\n const dep = token.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n\n return (\n <div {...wrapperAttrs} className={cx(wrapperAttrs['className'], 'sb-token-detail')}>\n <TokenHeader path={path} {...(heading !== undefined && { heading })} />\n {isDeprecated && (\n <div\n className=\"sb-token-detail__deprecated\"\n data-testid=\"token-detail-deprecated\"\n role=\"note\"\n >\n <span aria-hidden>⚠ </span>\n Deprecated{typeof dep === 'string' ? `: ${dep}` : ''}\n </div>\n )}\n\n <div className=\"sb-token-detail__section-header\">Resolved value · {activeTheme}</div>\n <CompositePreview path={path} />\n <CompositeBreakdown path={path} />\n <div className=\"sb-token-detail__chain\">\n {isColor && (\n <span className=\"sb-token-detail__swatch\" style={{ background: cssVar }} aria-hidden />\n )}\n <span>{value}</span>\n {outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n style={{ marginLeft: 6 }}\n >\n ⚠\n </span>\n )}\n <CopyButton value={value} label={`Copy value ${value}`} />\n </div>\n\n <AliasChain path={path} />\n <AliasedBy path={path} />\n <TokenUsageSnippet path={path} />\n <ConsumerOutput path={path} />\n <AxisVariance path={path} />\n </div>\n );\n}\n","import type { KeyboardEvent as ReactKeyboardEvent, ReactElement } from 'react';\nimport { useEffect, useRef } from 'react';\nimport './DetailOverlay.css';\nimport { TokenDetail } from '#/TokenDetail.tsx';\n\n/**\n * Slide-over that wraps `<TokenDetail>`. Shared between `<TokenNavigator />`\n * and `<TokenTable />` so both land on the same opener and the same styling.\n *\n * Dismisses on backdrop click, Escape, and the close button. Implements the\n * WAI-ARIA dialog pattern's focus management: on mount, focus moves into the\n * panel; Tab is trapped so it cycles through the panel's interactive\n * descendants only; on unmount, focus restores to whatever opened the\n * overlay (typically the row / treeitem the user clicked).\n */\n\nexport interface DetailOverlayProps {\n path: string;\n onClose(): void;\n testId?: string;\n}\n\n// Selector for elements the trap considers focus stops. Mirrors the\n// \"tabbable\" set most focus-trap libraries use; the `:not(...)` clauses\n// skip the panel wrapper itself (we focus it manually on mount via its\n// own ref) and any explicitly-detabbed descendants.\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ');\n\nexport function DetailOverlay({\n path,\n onClose,\n testId = 'swatchbook-overlay',\n}: DetailOverlayProps): ReactElement {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const openerRef = useRef<HTMLElement | null>(null);\n\n // Set up focus management + sibling inerting in one effect so the\n // teardown ordering is explicit: un-inert siblings BEFORE restoring\n // focus to the opener (`.focus()` is a no-op on an inert element).\n //\n // `aria-modal=\"true\"` alone is widely known to be insufficient —\n // VoiceOver + NVDA virtual cursor + swipe gestures still pierce the\n // dialog and read sibling content behind the backdrop. Marking every\n // other top-level body branch `inert` while the overlay is mounted\n // closes that gap.\n useEffect(() => {\n const panel = panelRef.current;\n if (!panel) return;\n openerRef.current =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n panel.focus();\n const overlayBranch = findBodyChildContaining(panel);\n const restorers: (() => void)[] = [];\n if (overlayBranch) {\n for (const sibling of Array.from(document.body.children)) {\n if (sibling === overlayBranch) continue;\n if (!(sibling instanceof HTMLElement)) continue;\n const hadInert = sibling.inert;\n sibling.inert = true;\n restorers.push(() => {\n sibling.inert = hadInert;\n });\n }\n }\n return () => {\n // Un-inert first — focusing an inert element is a no-op.\n for (const restore of restorers) restore();\n openerRef.current?.focus();\n };\n }, []);\n\n // Window-level Escape handler: works whether or not focus is currently\n // inside the panel (e.g. user clicked the backdrop, focus moved away).\n useEffect(() => {\n const onKey = (e: globalThis.KeyboardEvent): void => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Wrap Tab inside the panel: from the last focusable, jump to the first;\n // from the first (or from the panel itself), Shift+Tab jumps to the last.\n // Defers to the browser otherwise.\n const onPanelKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n if (e.key !== 'Tab') return;\n const panel = panelRef.current;\n if (!panel) return;\n const focusables = panel.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);\n if (focusables.length === 0) {\n e.preventDefault();\n return;\n }\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement;\n if (!first || !last) return;\n if (e.shiftKey) {\n if (active === first || active === panel) {\n e.preventDefault();\n last.focus();\n }\n } else if (active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n return (\n <div\n className=\"sb-detail-overlay__backdrop\"\n onClick={onClose}\n role=\"presentation\"\n data-testid={testId}\n >\n <div\n ref={panelRef}\n className=\"sb-detail-overlay__panel\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={onPanelKeyDown}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Token detail for ${path}`}\n tabIndex={-1}\n >\n <button\n type=\"button\"\n className=\"sb-detail-overlay__close\"\n onClick={onClose}\n aria-label=\"Close\"\n data-testid={`${testId}-close`}\n >\n ×\n </button>\n <TokenDetail path={path} />\n </div>\n </div>\n );\n}\n\n// Walk up from `node` to the direct child of `<body>` that contains it.\n// Returns `null` when the node isn't attached to the document (mid-mount,\n// post-unmount). Used to identify which top-level branch to *not* mark\n// inert when the overlay opens.\nfunction findBodyChildContaining(node: HTMLElement): HTMLElement | null {\n let cursor: HTMLElement | null = node;\n while (cursor && cursor.parentElement !== document.body) {\n cursor = cursor.parentElement;\n }\n return cursor;\n}\n","import type { VirtualTokenShape } from '#/contexts.ts';\n\n/**\n * The group paths to expand so `path` becomes visible in the tree — the\n * cumulative dotted prefixes of `path`, excluding `path` itself and any\n * prefix at or above `root` (the navigator's implicit root container is not\n * a group node). Matches `buildTree`'s full-dotted group-path scheme.\n */\nexport function ancestorGroupPaths(path: string, root: string | undefined): string[] {\n const segments = path.split('.');\n const out: string[] = [];\n for (let i = 1; i < segments.length; i += 1) {\n const prefix = segments.slice(0, i).join('.');\n if (root && !prefix.startsWith(`${root}.`)) continue;\n out.push(prefix);\n }\n return out;\n}\n\n/** Context a navigation target is tested against — the active structural filters. */\nexport interface InViewContext {\n resolved: Record<string, VirtualTokenShape>;\n root?: string | undefined;\n typeFilter?: ReadonlySet<string> | undefined;\n}\n\n/**\n * Whether `path` survives the navigator's structural (`root` / `type`)\n * filters and exists in the resolved map — i.e. it can be selected in the\n * current tree. Transient search is NOT considered here: a target hidden\n * only by an active query is still \"in view\" once the query is cleared,\n * which the caller handles.\n */\nexport function isInView(path: string, ctx: InViewContext): boolean {\n const token = ctx.resolved[path];\n if (!token) return false;\n if (ctx.root && !(path === ctx.root || path.startsWith(`${ctx.root}.`))) return false;\n if (ctx.typeFilter && !(token.$type !== undefined && ctx.typeFilter.has(token.$type))) {\n return false;\n }\n return true;\n}\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport type { KeyboardEvent, ReactElement } from 'react';\nimport { memo, useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';\nimport './TokenNavigator.css';\nimport { BorderSample } from '#/border-preview/BorderSample.tsx';\nimport { useColorFormat } from '#/contexts.ts';\nimport { DimensionBar } from '#/dimension-scale/DimensionBar.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { DetailOverlay } from '#/internal/DetailOverlay.tsx';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { EmptyState } from '#/internal/styles.tsx';\nimport { resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { MotionSample } from '#/motion-preview/MotionSample.tsx';\nimport { ShadowSample } from '#/shadow-preview/ShadowSample.tsx';\nimport { ancestorGroupPaths, isInView } from '#/token-navigator/navigate.ts';\nimport { RowIndicators } from '#/indicators/RowIndicators.tsx';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorName, IndicatorsProp } from '#/indicators/resolve.ts';\nimport type { VirtualToken } from '#/types.ts';\n\nexport interface TokenNavigatorProps {\n /** If provided, mount at this dot-path subtree and hide everything outside it. */\n root?: string;\n /**\n * Restrict the tree to tokens with the given DTCG `$type`(s). Pass a single\n * string to scope to one type (`type=\"color\"`), or an array for a narrow\n * small-multiples view (`type={['duration', 'cubicBezier', 'transition']}`).\n * Composes with `root` — both constraints must hold. Group nodes that end\n * up with no surviving leaves collapse out.\n */\n type?: string | readonly string[];\n /**\n * Depth (from the mounted root) that is expanded on first render.\n * `0` = everything collapsed, `1` = top-level groups open (default),\n * `2` = one level deeper, etc.\n */\n initiallyExpanded?: number;\n /**\n * Render a runtime search input above the tree. Matches are fuzzy\n * (case-insensitive, out-of-order terms, single-character typo\n * tolerance) against a leaf's token path; groups that contain no\n * matching leaves collapse out, and every group on the path to a\n * match auto-expands so hits are visible without clicking. Defaults\n * to `true`.\n */\n searchable?: boolean;\n /**\n * Called with a leaf's full dot-path when it is clicked. When set, the\n * inline `<TokenDetail>` slide-over is suppressed — the consumer owns\n * the follow-up UI.\n */\n onSelect?(path: string): void;\n /**\n * Disambiguates persisted UI state (expand/collapse, selection, search)\n * when two navigators with otherwise-identical props sit on the same docs\n * page. Only needed in that case; the state key is derived from the other\n * props otherwise.\n */\n id?: string;\n /** Configure the per-row indicator strip. See `IndicatorsProp`. */\n indicators?: IndicatorsProp;\n}\n\ninterface LeafNode {\n kind: 'leaf';\n segment: string;\n path: string;\n token: VirtualToken;\n}\n\ninterface GroupNode {\n kind: 'group';\n segment: string;\n path: string;\n children: TreeNode[];\n}\n\ntype TreeNode = LeafNode | GroupNode;\n\nfunction buildTree(\n resolved: Record<string, VirtualToken>,\n root: string | undefined,\n typeFilter: ReadonlySet<string> | undefined,\n): TreeNode[] {\n const rootPrefix = root && root.length > 0 ? `${root}.` : '';\n const rootSegments = root ? root.split('.') : [];\n\n const entries = Object.entries(resolved).filter(([path, token]) => {\n if (root && !(path === root || path.startsWith(rootPrefix))) return false;\n if (typeFilter && !(token.$type && typeFilter.has(token.$type))) return false;\n return true;\n });\n\n const rootNode: GroupNode = { kind: 'group', segment: '', path: '', children: [] };\n\n for (const [path, token] of entries) {\n const remainder = root ? (path === root ? '' : path.slice(rootPrefix.length)) : path;\n const segments = remainder.length > 0 ? remainder.split('.') : [];\n\n let node: GroupNode = rootNode;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const seg = segments[i];\n if (seg === undefined) continue;\n const prefix = [...rootSegments, ...segments.slice(0, i + 1)].join('.');\n let child = node.children.find(\n (c): c is GroupNode => c.kind === 'group' && c.segment === seg,\n );\n if (!child) {\n child = { kind: 'group', segment: seg, path: prefix, children: [] };\n node.children.push(child);\n }\n node = child;\n }\n\n const leafSegment = segments[segments.length - 1];\n if (leafSegment === undefined) {\n node.children.push({\n kind: 'leaf',\n segment: root ? (rootSegments[rootSegments.length - 1] ?? path) : path,\n path,\n token,\n });\n } else {\n node.children.push({ kind: 'leaf', segment: leafSegment, path, token });\n }\n }\n\n sortTree(rootNode);\n\n return rootNode.children;\n}\n\nfunction sortTree(node: GroupNode): void {\n node.children.sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'group' ? -1 : 1;\n return a.segment.localeCompare(b.segment, undefined, { numeric: true });\n });\n for (const c of node.children) {\n if (c.kind === 'group') sortTree(c);\n }\n}\n\nfunction collectInitialExpanded(nodes: TreeNode[], remainingDepth: number, out: Set<string>): void {\n if (remainingDepth <= 0) return;\n for (const node of nodes) {\n if (node.kind !== 'group') continue;\n out.add(node.path);\n collectInitialExpanded(node.children, remainingDepth - 1, out);\n }\n}\n\nfunction countLeaves(node: TreeNode): number {\n if (node.kind === 'leaf') return 1;\n let n = 0;\n for (const c of node.children) n += countLeaves(c);\n return n;\n}\n\nfunction collectLeafPaths(nodes: TreeNode[], out: string[]): void {\n for (const node of nodes) {\n if (node.kind === 'leaf') out.push(node.path);\n else collectLeafPaths(node.children, out);\n }\n}\n\n// Flatten the currently-visible treeitems into the order screen-reader\n// users + arrow-key users navigate them: depth-first, only descending\n// into expanded groups. Each entry carries enough metadata for the\n// keyboard handler to compute parent / first-child / next / prev.\ninterface FlatTreeItem {\n path: string;\n kind: 'group' | 'leaf';\n // Dot-path of the parent group, or `null` for top-level entries.\n parentPath: string | null;\n}\n\nfunction flattenVisible(\n nodes: TreeNode[],\n expanded: Set<string>,\n parentPath: string | null,\n out: FlatTreeItem[],\n): void {\n for (const node of nodes) {\n out.push({ path: node.path, kind: node.kind, parentPath });\n if (node.kind === 'group' && expanded.has(node.path)) {\n flattenVisible(node.children, expanded, node.path, out);\n }\n }\n}\n\n// Return a pruned copy of the tree keeping only leaves whose path is in\n// `matches`, plus the groups on the way to them. Every surviving group's\n// path is added to `expandOut` so callers can force those groups open.\nfunction pruneTreeForMatches(\n nodes: TreeNode[],\n matches: ReadonlySet<string>,\n expandOut: Set<string>,\n): TreeNode[] {\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (node.kind === 'leaf') {\n if (matches.has(node.path)) out.push(node);\n } else {\n const children = pruneTreeForMatches(node.children, matches, expandOut);\n if (children.length > 0) {\n expandOut.add(node.path);\n out.push({ ...node, children });\n }\n }\n }\n return out;\n}\n\nexport function TokenNavigator({\n root,\n type,\n initiallyExpanded = 1,\n searchable = true,\n onSelect,\n id,\n indicators,\n}: TokenNavigatorProps): ReactElement {\n const {\n resolved,\n activeTheme,\n activeAxes,\n cssVarPrefix,\n indicators: indicatorBaseline,\n } = useProject();\n\n // Persist UI state (expand/collapse, selection, search) across docs-mode\n // remounts. Keyed on the props that distinguish one navigator from another\n // (plus the optional `id`); excludes `initiallyExpanded`/`searchable`, whose\n // changes are handled by the re-seed effect below rather than a fresh key.\n const typeKey = type === undefined ? '' : typeof type === 'string' ? type : type.join(',');\n const blockKey = useBlockKey('TokenNavigator', [root, typeKey, id]);\n\n const typeFilter = useMemo<ReadonlySet<string> | undefined>(() => {\n if (type === undefined) return undefined;\n return new Set(Array.isArray(type) ? type : [type]);\n }, [type]);\n\n const enabledIndicators = useMemo(\n () => resolveIndicators(indicators, indicatorBaseline),\n [indicators, indicatorBaseline],\n );\n\n const tree = useMemo(() => buildTree(resolved, root, typeFilter), [resolved, root, typeFilter]);\n\n const initialExpanded = useMemo(() => {\n const out = new Set<string>();\n collectInitialExpanded(tree, initiallyExpanded, out);\n return out;\n }, [tree, initiallyExpanded]);\n\n const [expanded, setExpanded] = usePersistedState<Set<string>>(\n `${blockKey}::expanded`,\n initialExpanded,\n );\n const initiallyExpandedRef = useRef(initiallyExpanded);\n useEffect(() => {\n // Re-seed the expand/collapse state ONLY when the `initiallyExpanded`\n // prop itself changes — not when `initialExpanded` merely gets a fresh\n // identity because `resolved`/`tree` churned on an axis flip. `resolved`\n // is recomputed per active tuple, so without this guard every mode switch\n // would snap the user's expand/collapse state back to the default.\n if (initiallyExpandedRef.current === initiallyExpanded) return;\n initiallyExpandedRef.current = initiallyExpanded;\n setExpanded(initialExpanded);\n }, [initiallyExpanded, initialExpanded, setExpanded]);\n\n const [selectedPath, setSelectedPath] = usePersistedState<string | null>(\n `${blockKey}::selected`,\n null,\n );\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n\n const { visibleTree, searchExpanded } = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') {\n return { visibleTree: tree, searchExpanded: null as Set<string> | null };\n }\n const leafPaths: string[] = [];\n collectLeafPaths(tree, leafPaths);\n const matches = new Set(fuzzyFilter(leafPaths, deferredQuery, (p) => p));\n const expandOut = new Set<string>();\n const pruned = matches.size === 0 ? [] : pruneTreeForMatches(tree, matches, expandOut);\n return { visibleTree: pruned, searchExpanded: expandOut };\n }, [tree, deferredQuery, searchable]);\n\n const effectiveExpanded = useMemo(() => {\n if (!searchExpanded) return expanded;\n const merged = new Set(expanded);\n for (const p of searchExpanded) merged.add(p);\n return merged;\n }, [expanded, searchExpanded]);\n\n const toggle = useCallback(\n (path: string): void => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n },\n [setExpanded],\n );\n\n const handleLeafClick = useCallback(\n (path: string) => {\n if (onSelect) onSelect(path);\n else setSelectedPath(path);\n },\n [onSelect, setSelectedPath],\n );\n\n // WAI-ARIA tree pattern's roving tabindex — exactly one treeitem at a\n // time has tabIndex={0}; the rest are -1. Tab into / out of the tree\n // hits that one item; arrow keys move focus between items inside.\n // `storedFocus` is the user-driven state; the derived `focusedPath`\n // below repairs the focus to the first visible item when storedFocus\n // points at a now-hidden row (e.g. after a search narrows the tree).\n const [storedFocus, setStoredFocus] = useState<string | null>(null);\n const treeItemRefs = useRef<Map<string, HTMLLIElement>>(new Map());\n\n const resolveInView = useCallback(\n (path: string): boolean => isInView(path, { resolved, root, typeFilter }),\n [resolved, root, typeFilter],\n );\n\n const navigateTo = useCallback(\n (target: string): void => {\n setQuery('');\n setExpanded((prev) => {\n const next = new Set(prev);\n for (const p of ancestorGroupPaths(target, root)) next.add(p);\n return next;\n });\n if (onSelect) onSelect(target);\n else setSelectedPath(target);\n setStoredFocus(target);\n requestAnimationFrame(() => {\n const el = treeItemRefs.current.get(target);\n el?.scrollIntoView({ block: 'nearest' });\n el?.focus();\n });\n },\n [root, onSelect, setQuery, setExpanded, setSelectedPath],\n );\n const registerTreeItem = useCallback(\n (path: string) =>\n (el: HTMLLIElement | null): void => {\n if (el) treeItemRefs.current.set(path, el);\n else treeItemRefs.current.delete(path);\n },\n [],\n );\n\n const flatVisible = useMemo<FlatTreeItem[]>(() => {\n const out: FlatTreeItem[] = [];\n flattenVisible(visibleTree, effectiveExpanded, null, out);\n return out;\n }, [visibleTree, effectiveExpanded]);\n\n const focusedPath = useMemo<string | null>(() => {\n if (flatVisible.length === 0) return null;\n if (storedFocus && flatVisible.some((entry) => entry.path === storedFocus)) {\n return storedFocus;\n }\n return flatVisible[0]?.path ?? null;\n }, [flatVisible, storedFocus]);\n\n const focusByPath = useCallback((path: string): void => {\n const node = treeItemRefs.current.get(path);\n // If the ref isn't mounted yet (e.g. after expanding a group via\n // Right-arrow, before the new children render), flag the path so\n // the DOM-sync effect below can move focus once the node mounts.\n if (node) node.focus();\n setStoredFocus(path);\n }, []);\n\n // After expanding a group via Right-arrow, the new children mount on\n // the following render. If a path was queued via `setStoredFocus`\n // but the corresponding ref didn't exist at the time, repair focus\n // now that the children are live.\n useEffect(() => {\n if (focusedPath === null) return;\n const node = treeItemRefs.current.get(focusedPath);\n if (node && document.activeElement !== node) {\n const active = document.activeElement;\n // Move focus to the repaired row in two cases:\n // 1. Focus sits on a different treeitem inside our tree (e.g. after\n // Right-arrow expands a group and the queued child mounts).\n // 2. The previously-focused row was removed (a toolbar axis flip\n // dropped a token, a search narrowed the tree, a live edit) and\n // the browser orphaned focus onto <body>. `focusedPath` has\n // repaired to the first visible row but `storedFocus` still names\n // the gone row — restore the live focus to match.\n // Don't yank focus from the search input or anything else still\n // legitimately focused, and don't grab it on mount (storedFocus null).\n const insideTree = active instanceof HTMLElement && active.closest('[role=\"tree\"]');\n const orphaned = active === document.body || active === null;\n const focusedRowRemoved = storedFocus !== null && storedFocus !== focusedPath;\n if (insideTree || (orphaned && focusedRowRemoved)) node.focus();\n }\n // Deps are intentionally just `focusedPath`. The repair fires when the\n // focused row changes — including when a removed row forces the fall back\n // to the first visible row — NOT on every `storedFocus` change (that would\n // re-run while DOM focus sits on a descendant leaf and steal it to the\n // group). Reading `storedFocus` from the triggering render is correct: on\n // removal it still names the now-gone row, so `focusedRowRemoved` holds.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [focusedPath]);\n\n const handleTreeKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>): void => {\n // Derive the active treeitem from `document.activeElement` rather\n // than the `focusedPath` state. State updates from `onFocus` may\n // not have flushed by the time a subsequent keydown fires (e.g.\n // tests that programmatically `.focus()` then immediately dispatch\n // keys), and the handler must always operate on the row the user\n // is currently on.\n if (flatVisible.length === 0) return;\n const active = document.activeElement;\n if (!(active instanceof HTMLLIElement)) return;\n const activePath = active.getAttribute('data-path');\n if (activePath === null) return;\n const currentIndex = flatVisible.findIndex((entry) => entry.path === activePath);\n if (currentIndex < 0) return;\n const current = flatVisible[currentIndex];\n if (!current) return;\n\n switch (e.key) {\n case 'ArrowDown': {\n const next = flatVisible[currentIndex + 1];\n if (next) {\n e.preventDefault();\n focusByPath(next.path);\n }\n return;\n }\n case 'ArrowUp': {\n const prev = flatVisible[currentIndex - 1];\n if (prev) {\n e.preventDefault();\n focusByPath(prev.path);\n }\n return;\n }\n case 'Home': {\n const first = flatVisible[0];\n if (first) {\n e.preventDefault();\n focusByPath(first.path);\n }\n return;\n }\n case 'End': {\n const last = flatVisible[flatVisible.length - 1];\n if (last) {\n e.preventDefault();\n focusByPath(last.path);\n }\n return;\n }\n case 'ArrowRight': {\n if (current.kind === 'group') {\n if (!effectiveExpanded.has(current.path)) {\n e.preventDefault();\n toggle(current.path);\n // Focus stays on the group — user can press Right again\n // to step into the first child on the next render.\n return;\n }\n // Already expanded: step into first child (which is the\n // next entry in the flattened list).\n const firstChild = flatVisible[currentIndex + 1];\n if (firstChild && firstChild.parentPath === current.path) {\n e.preventDefault();\n focusByPath(firstChild.path);\n }\n }\n return;\n }\n case 'ArrowLeft': {\n if (current.kind === 'group' && effectiveExpanded.has(current.path)) {\n e.preventDefault();\n toggle(current.path);\n return;\n }\n // Collapsed group or leaf: step to parent.\n if (current.parentPath !== null) {\n e.preventDefault();\n focusByPath(current.parentPath);\n }\n return;\n }\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (current.kind === 'group') toggle(current.path);\n else handleLeafClick(current.path);\n return;\n }\n default:\n return;\n }\n },\n [flatVisible, effectiveExpanded, toggle, focusByPath, handleLeafClick],\n );\n\n const typeLabel = typeFilter ? ` · ${[...typeFilter].map((t) => `$type=${t}`).join(', ')}` : '';\n const trimmedQuery = query.trim();\n // Must run every render — React's rules of hooks forbid the earlier empty-state\n // early return from skipping it, or the next non-empty render throws\n // \"Rendered fewer hooks than expected\".\n const matchCount = useMemo(() => {\n if (!searchExpanded) return 0;\n let n = 0;\n for (const node of visibleTree) n += countLeaves(node);\n return n;\n }, [visibleTree, searchExpanded]);\n\n if (tree.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <EmptyState>\n {root\n ? `No tokens under \"${root}\"${typeFilter ? ` matching ${typeLabel.slice(3)}` : ''}.`\n : typeFilter\n ? `No tokens matching ${typeLabel.slice(3)} in the active theme.`\n : 'No tokens in the active theme.'}\n </EmptyState>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-token-navigator__search\">\n <input\n type=\"search\"\n className=\"sb-token-navigator__search-input\"\n placeholder=\"Search tokens…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Search tokens by path\"\n data-testid=\"token-navigator-search\"\n />\n </div>\n )}\n <div className=\"sb-token-navigator__caption\">\n {root ? `Tokens under ${root}` : 'Token graph'}\n {typeLabel}\n {trimmedQuery !== '' ? ` · ${matchCount} matching \"${trimmedQuery}\"` : ''} · {activeTheme}\n </div>\n {searchable && (\n <span role=\"status\" aria-live=\"polite\" className=\"sb-token-navigator__sr-status\">\n {trimmedQuery !== '' ? `${matchCount} tokens matching \"${trimmedQuery}\"` : ''}\n </span>\n )}\n {visibleTree.length === 0 ? (\n <div className=\"sb-block__empty\">No tokens match \"{trimmedQuery}\".</div>\n ) : (\n <ul\n className=\"sb-token-navigator__tree\"\n role=\"tree\"\n aria-label=\"Token graph\"\n onKeyDown={handleTreeKeyDown}\n >\n {visibleTree.map((node, i) => (\n <TreeNodeRow\n key={node.path || node.segment}\n node={node}\n expanded={effectiveExpanded}\n focusedPath={focusedPath}\n registerTreeItem={registerTreeItem}\n onToggle={toggle}\n onFocusPath={setStoredFocus}\n onLeafClick={handleLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={navigateTo}\n enabled={enabledIndicators}\n level={1}\n setsize={visibleTree.length}\n posinset={i + 1}\n />\n ))}\n </ul>\n )}\n\n {selectedPath !== null && (\n <DetailOverlay\n path={selectedPath}\n onClose={() => setSelectedPath(null)}\n testId=\"token-navigator-overlay\"\n />\n )}\n </div>\n );\n}\n\ninterface TreeNodeRowProps {\n node: TreeNode;\n expanded: Set<string>;\n focusedPath: string | null;\n registerTreeItem(path: string): (el: HTMLLIElement | null) => void;\n onToggle(path: string): void;\n onFocusPath(path: string): void;\n onLeafClick(path: string): void;\n root: string | undefined;\n resolveInView(path: string): boolean;\n onNavigate(path: string): void;\n enabled: Record<IndicatorName, boolean>;\n // 1-indexed depth in the tree (top-level = 1).\n level: number;\n // Number of siblings at this level (including self).\n setsize: number;\n // 1-indexed position among siblings.\n posinset: number;\n}\n\nfunction TreeNodeRow({\n node,\n expanded,\n focusedPath,\n registerTreeItem,\n onToggle,\n onFocusPath,\n onLeafClick,\n root,\n resolveInView,\n onNavigate,\n enabled,\n level,\n setsize,\n posinset,\n}: TreeNodeRowProps): ReactElement {\n if (node.kind === 'leaf') {\n return (\n <LeafRow\n node={node}\n isFocused={focusedPath === node.path}\n registerTreeItem={registerTreeItem}\n onFocusPath={onFocusPath}\n onLeafClick={onLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={onNavigate}\n enabled={enabled}\n level={level}\n setsize={setsize}\n posinset={posinset}\n />\n );\n }\n const isOpen = expanded.has(node.path);\n const isFocused = focusedPath === node.path;\n return (\n <li\n ref={registerTreeItem(node.path)}\n role=\"treeitem\"\n aria-expanded={isOpen}\n aria-level={level}\n aria-setsize={setsize}\n aria-posinset={posinset}\n tabIndex={isFocused ? 0 : -1}\n onFocus={() => onFocusPath(node.path)}\n data-path={node.path}\n data-testid=\"token-navigator-group\"\n >\n {/*\n Click handler on the inner row div, not the <li>. Nested\n treeitems are DOM descendants of their parent <li>, so a\n click on a child row would bubble through each ancestor\n <li>'s onClick. The row div is a SIBLING of the nested\n <ul>, so child rows never bubble through it.\n */}\n <div\n className=\"sb-token-navigator__group-row\"\n data-testid=\"token-navigator-group-row\"\n onClick={() => {\n onFocusPath(node.path);\n onToggle(node.path);\n }}\n >\n <span className=\"sb-token-navigator__caret\" aria-hidden>\n {isOpen ? '▾' : '▸'}\n </span>\n <span>{node.segment}</span>\n <span className=\"sb-token-navigator__count\">{countLeaves(node)}</span>\n </div>\n {isOpen && (\n <ul className=\"sb-token-navigator__nested\" role=\"group\">\n {node.children.map((c, i) => (\n <TreeNodeRow\n key={c.path || c.segment}\n node={c}\n expanded={expanded}\n focusedPath={focusedPath}\n registerTreeItem={registerTreeItem}\n onToggle={onToggle}\n onFocusPath={onFocusPath}\n onLeafClick={onLeafClick}\n root={root}\n resolveInView={resolveInView}\n onNavigate={onNavigate}\n enabled={enabled}\n level={level + 1}\n setsize={node.children.length}\n posinset={i + 1}\n />\n ))}\n </ul>\n )}\n </li>\n );\n}\n\ninterface LeafRowProps {\n node: LeafNode;\n isFocused: boolean;\n registerTreeItem(path: string): (el: HTMLLIElement | null) => void;\n onFocusPath(path: string): void;\n onLeafClick(path: string): void;\n root: string | undefined;\n resolveInView(path: string): boolean;\n onNavigate(path: string): void;\n enabled: Record<IndicatorName, boolean>;\n // 1-indexed depth in the tree (top-level = 1).\n level: number;\n // Number of siblings at this level (including self).\n setsize: number;\n // 1-indexed position among siblings.\n posinset: number;\n}\n\nconst LeafRow = memo(function LeafRow({\n node,\n isFocused,\n registerTreeItem,\n onFocusPath,\n onLeafClick,\n root,\n resolveInView,\n onNavigate,\n enabled,\n level,\n setsize,\n posinset,\n}: LeafRowProps): ReactElement {\n const type = node.token.$type ?? '';\n const project = useProject();\n const colorFormat = useColorFormat();\n const variance = project.varianceByPath[node.path];\n const dep = node.token.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n return (\n <li\n ref={registerTreeItem(node.path)}\n role=\"treeitem\"\n aria-level={level}\n aria-setsize={setsize}\n aria-posinset={posinset}\n tabIndex={isFocused ? 0 : -1}\n onFocus={() => onFocusPath(node.path)}\n data-path={node.path}\n data-testid=\"token-navigator-leaf\"\n >\n {/* Click handler on the inner row div for the same reason as\n group rows — see TreeNodeRow. */}\n <div\n className=\"sb-token-navigator__leaf-row\"\n data-testid=\"token-navigator-leaf-row\"\n data-deprecated={enabled.deprecation && isDeprecated ? 'true' : undefined}\n onClick={() => {\n onFocusPath(node.path);\n onLeafClick(node.path);\n }}\n >\n <span className=\"sb-token-navigator__caret\" aria-hidden>\n •\n </span>\n <span className=\"sb-token-navigator__tail\">{node.segment}</span>\n {type && <span className=\"sb-token-navigator__type-pill\">{type}</span>}\n <RowIndicators\n path={node.path}\n token={node.token}\n root={root}\n variance={variance}\n colorFormat={colorFormat}\n canReference={resolveInView}\n onReferenceClick={onNavigate}\n enabled={enabled}\n />\n <LeafPreview path={node.path} token={node.token} />\n </div>\n </li>\n );\n});\n\ninterface LeafPreviewProps {\n path: string;\n token: VirtualToken;\n}\n\nconst LeafPreview = memo(function LeafPreview({ path, token }: LeafPreviewProps): ReactElement {\n const project = useProject();\n const colorFormat = useColorFormat();\n const type = token.$type;\n\n if (type === 'color') {\n const cssVar = resolveCssVar(path, project);\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n <span\n className=\"sb-token-navigator__color-swatch\"\n style={{ background: cssVar }}\n aria-hidden\n />\n </span>\n );\n }\n if (type === 'dimension') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n <span className=\"sb-token-navigator__preview-dimension\">\n <DimensionBar path={path} visual=\"length\" />\n </span>\n </span>\n );\n }\n if (type === 'shadow') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-scaled\">\n <ShadowSample path={path} />\n </span>\n </span>\n );\n }\n if (type === 'border') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-scaled\">\n <BorderSample path={path} />\n </span>\n </span>\n );\n }\n if (type === 'transition' || type === 'duration' || type === 'cubicBezier') {\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__preview-motion\">\n <MotionSample path={path} />\n </span>\n </span>\n );\n }\n\n return (\n <span className=\"sb-token-navigator__preview-box\">\n <span className=\"sb-token-navigator__value\">\n {formatTokenValue(token.$value, type, colorFormat, project.listing[path])}\n </span>\n </span>\n );\n});\n","import { fuzzyFilter } from '@unpunnyfuns/swatchbook-core/fuzzy';\nimport cx from 'clsx';\nimport type { ReactElement } from 'react';\nimport { useCallback, useDeferredValue, useMemo } from 'react';\nimport './TokenTable.css';\nimport { useColorFormat } from '#/contexts.ts';\nimport { CopyButton } from '#/internal/CopyButton.tsx';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { DetailOverlay } from '#/internal/DetailOverlay.tsx';\nimport { formatTokenValue } from '#/internal/format-token-value.ts';\nimport { useBlockKey, usePersistedState } from '#/internal/persistent-state.ts';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\nimport { resolveColorValue, resolveCssVar, useProject } from '#/internal/use-project.ts';\nimport { RowIndicators } from '#/indicators/RowIndicators.tsx';\nimport { resolveIndicators } from '#/indicators/resolve.ts';\nimport type { IndicatorsProp } from '#/indicators/resolve.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\n\nexport interface TokenTableProps {\n /**\n * Token-path filter. `\"color.*\"` matches every `color.…` token;\n * omit to include everything. Combines with `type` (both must match).\n */\n filter?: string;\n /** Restrict to one DTCG `$type`. */\n type?: string;\n /** Override the table caption. */\n caption?: string;\n /**\n * Sort order.\n * - `'path'` (default) — lexicographic on the dot-path.\n * - `'value'` — per-`$type`: numeric for `dimension` / `duration` /\n * `fontWeight`; perceptual (oklch L → C → H) for `color`; lexicographic\n * for `fontFamily` / `strokeStyle`. Composite types fall through to\n * path order.\n * - `'none'` — preserve project iteration order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n /**\n * Render a runtime search input above the table that narrows rows by\n * fuzzy match (case-insensitive, out-of-order terms, single-character\n * typo tolerance) against the token path, type, or value. Defaults to\n * `true` because browsing a multi-hundred-token reference without\n * search is painful. Pass `false` to hide the input (the `filter` /\n * `type` props still apply at authoring time).\n */\n searchable?: boolean;\n /**\n * Called with the clicked row's dot-path. When set, the built-in\n * `<TokenDetail>` slide-over is suppressed — the consumer owns the\n * follow-up UI (inline panel, drill-down route, …).\n */\n onSelect?(path: string): void;\n /** Disambiguates persisted UI state for two identical-prop tables on a page. */\n id?: string;\n /** Configure the per-row indicator strip. See `IndicatorsProp`. */\n indicators?: IndicatorsProp;\n}\n\nexport function TokenTable({\n filter,\n type,\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n searchable = true,\n onSelect,\n id,\n indicators,\n}: TokenTableProps): ReactElement {\n const project = useProject();\n const {\n resolved,\n activeTheme,\n activeAxes,\n cssVarPrefix,\n listing,\n varianceByPath,\n indicators: indicatorBaseline,\n } = project;\n const colorFormat = useColorFormat();\n // Persist selection + search across docs-mode remounts (see persistent-state).\n const blockKey = useBlockKey('TokenTable', [filter, type, caption, id]);\n const enabledIndicators = useMemo(\n () => resolveIndicators(indicators, indicatorBaseline),\n [indicators, indicatorBaseline],\n );\n const [selectedPath, setSelectedPath] = usePersistedState<string | null>(\n `${blockKey}::selected`,\n null,\n );\n const [query, setQuery] = usePersistedState(`${blockKey}::query`, '');\n const deferredQuery = useDeferredValue(query);\n\n const rows = useMemo(() => {\n const projectFields = { listing, cssVarPrefix };\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (!matchPath(path, filter)) return false;\n if (type && token.$type !== type) return false;\n return true;\n });\n const entries = sortTokens(filtered, { by: sortBy, dir: sortDir });\n return entries.map(([path, token]) => {\n const isColor = token.$type === 'color';\n const color = isColor\n ? resolveColorValue(path, token.$value, colorFormat, projectFields)\n : null;\n return {\n path,\n type: token.$type ?? '',\n value: formatTokenValue(token.$value, token.$type, colorFormat, listing[path]),\n outOfGamut: color?.outOfGamut ?? false,\n cssVar: resolveCssVar(path, projectFields),\n isColor,\n };\n });\n }, [resolved, listing, cssVarPrefix, filter, type, colorFormat, sortBy, sortDir]);\n\n const visibleRows = useMemo(() => {\n if (!searchable || deferredQuery.trim() === '') return rows;\n return fuzzyFilter(rows, deferredQuery, (row) => `${row.path} ${row.type} ${row.value}`);\n }, [rows, deferredQuery, searchable]);\n\n const handleRowClick = useCallback(\n (path: string) => {\n if (onSelect) onSelect(path);\n else setSelectedPath(path);\n },\n [onSelect, setSelectedPath],\n );\n\n const matchSuffix =\n searchable && query.trim() !== '' ? ` · ${visibleRows.length} matching \"${query.trim()}\"` : '';\n const captionText =\n caption ??\n `${rows.length} token${rows.length === 1 ? '' : 's'}${\n filter ? ` matching \\`${filter}\\`` : ''\n }${type ? ` · $type=${type}` : ''}${matchSuffix} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n {searchable && (\n <div className=\"sb-token-table__search\">\n <input\n type=\"search\"\n className=\"sb-token-table__search-input\"\n placeholder=\"Search tokens…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n aria-label=\"Fuzzy-search tokens by path, type, or value\"\n data-testid=\"token-table-search\"\n />\n </div>\n )}\n {searchable && (\n <span role=\"status\" aria-live=\"polite\" className=\"sb-token-table__sr-status\">\n {query.trim() !== ''\n ? `${visibleRows.length} of ${rows.length} tokens match \"${query.trim()}\"`\n : ''}\n </span>\n )}\n <table className=\"sb-token-table__table\">\n <caption className=\"sb-token-table__caption\">{captionText}</caption>\n <thead>\n <tr>\n <th className={cx('sb-token-table__th', 'sb-token-table__th--path')}>Path</th>\n <th className={cx('sb-token-table__th', 'sb-token-table__th--value')}>Value</th>\n <th className=\"sb-token-table__th sb-token-table__th--refs\">\n <span className=\"sb-token-table__sr-status\">References and status</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {visibleRows.length === 0 && (\n <tr>\n <td colSpan={3} className=\"sb-token-table__td sb-token-table__empty-row\">\n No tokens match \"{query.trim()}\".\n </td>\n </tr>\n )}\n {visibleRows.map((row) => {\n const token = resolved[row.path];\n const dep = token?.$deprecated;\n const isDeprecated = dep === true || (typeof dep === 'string' && dep.length > 0);\n return (\n <tr\n key={row.path}\n className=\"sb-token-table__row\"\n onClick={() => handleRowClick(row.path)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleRowClick(row.path);\n }\n }}\n tabIndex={0}\n aria-haspopup=\"dialog\"\n aria-label={`Inspect ${row.path}`}\n data-testid=\"token-table-row\"\n data-path={row.path}\n >\n <td\n className={cx('sb-token-table__td', 'sb-token-table__path')}\n data-deprecated={\n enabledIndicators.deprecation && isDeprecated ? 'true' : undefined\n }\n >\n {row.path}\n </td>\n <td className=\"sb-token-table__td\">\n <span className=\"sb-token-table__value-cell\">\n {row.type && <span className=\"sb-token-table__type-pill\">{row.type}</span>}\n {row.isColor && (\n <span\n className=\"sb-token-table__swatch\"\n style={{ background: row.cssVar }}\n aria-hidden\n />\n )}\n <span\n className=\"sb-token-table__value-text\"\n title={row.value}\n data-testid=\"token-table-value\"\n >\n {row.value}\n </span>\n {row.outOfGamut && (\n <span\n title=\"Out of sRGB gamut for this format\"\n aria-label=\"out of gamut\"\n className=\"sb-token-table__gamut-warn\"\n >\n ⚠\n </span>\n )}\n <span\n className=\"sb-token-table__copy-wrap\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n role=\"presentation\"\n >\n <CopyButton\n value={row.value}\n label={`Copy value ${row.value}`}\n className=\"sb-token-table__copy\"\n />\n </span>\n </span>\n </td>\n <td className=\"sb-token-table__td sb-token-table__refs\">\n {token && (\n <RowIndicators\n path={row.path}\n token={token}\n root={undefined}\n variance={varianceByPath[row.path]}\n colorFormat={colorFormat}\n canReference={(p) => p in resolved}\n onReferenceClick={(p) => setSelectedPath(p)}\n enabled={enabledIndicators}\n />\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n\n {selectedPath !== null && (\n <DetailOverlay\n path={selectedPath}\n onClose={() => setSelectedPath(null)}\n testId=\"token-table-overlay\"\n />\n )}\n </div>\n );\n}\n","import type { CSSProperties, ReactElement } from 'react';\nimport { useMemo } from 'react';\nimport './TypographyScale.css';\nimport type { TypographyValue } from '#/internal/composite-types.ts';\nimport { blockWrapperAttrs } from '#/internal/data-attr.ts';\nimport { useProject } from '#/internal/use-project.ts';\nimport { matchPath } from '@unpunnyfuns/swatchbook-core/match-path';\nimport { sortTokens } from '#/internal/sort-tokens.ts';\nimport type { SortBy, SortDir } from '#/internal/sort-tokens.ts';\n\n// Dimension sub-values in DTCG 2025.10 use a `{ value, unit }` envelope\n// — narrow once here so the local `asDimension` helper doesn't need\n// to re-validate keys at every read.\ninterface DimensionLike {\n value?: unknown;\n unit?: unknown;\n}\n\nexport interface TypographyScaleProps {\n /**\n * Token-path filter. Defaults to every `typography` token. Use e.g.\n * `\"typography.*\"` to scope to the semantic layer.\n */\n filter?: string;\n /** Override the sample text rendered for each token. */\n sample?: string;\n /** Override the caption. */\n caption?: string;\n /**\n * Sort order. `'path'` (default) sorts lexicographically on the\n * dot-path; `'value'` ordering falls through to path for this block's\n * type (composite / non-numeric); `'none'` preserves project order.\n */\n sortBy?: SortBy;\n /** `'asc'` (default) or `'desc'`. */\n sortDir?: SortDir;\n}\n\ninterface Row {\n path: string;\n sampleStyle: CSSProperties;\n specs: string;\n}\n\nfunction asDimension(raw: unknown): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'string' || typeof raw === 'number') return String(raw);\n if (typeof raw === 'object') {\n const v = raw as DimensionLike;\n if (v.value !== undefined && v.unit !== undefined) return `${String(v.value)}${String(v.unit)}`;\n }\n return undefined;\n}\n\nfunction asFontFamily(raw: unknown): string | undefined {\n if (typeof raw === 'string') return raw;\n if (Array.isArray(raw)) return raw.map(String).join(', ');\n return undefined;\n}\n\nfunction buildRow(path: string, composite: TypographyValue): Row {\n const fontFamily = asFontFamily(composite.fontFamily);\n const fontSize = asDimension(composite.fontSize);\n const fontWeight = composite.fontWeight == null ? undefined : String(composite.fontWeight);\n const lineHeight = composite.lineHeight == null ? undefined : String(composite.lineHeight);\n const letterSpacing = asDimension(composite.letterSpacing);\n\n const sampleStyle: CSSProperties = {};\n if (fontFamily) sampleStyle.fontFamily = fontFamily;\n if (fontSize) sampleStyle.fontSize = fontSize;\n if (fontWeight) sampleStyle.fontWeight = fontWeight as CSSProperties['fontWeight'];\n if (lineHeight) sampleStyle.lineHeight = lineHeight;\n if (letterSpacing) sampleStyle.letterSpacing = letterSpacing;\n\n const parts = [\n fontSize,\n fontWeight ? `w${fontWeight}` : undefined,\n lineHeight ? `lh ${lineHeight}` : undefined,\n ]\n .filter(Boolean)\n .join(' · ');\n\n return { path, sampleStyle, specs: parts };\n}\n\nexport function TypographyScale({\n filter,\n sample = 'The quick brown fox jumps over the lazy dog.',\n caption,\n sortBy = 'path',\n sortDir = 'asc',\n}: TypographyScaleProps): ReactElement {\n const { resolved, activeTheme, activeAxes, cssVarPrefix } = useProject();\n\n const rows = useMemo<Row[]>(() => {\n const filtered = Object.entries(resolved).filter(([path, token]) => {\n if (token.$type !== 'typography') return false;\n return matchPath(path, filter);\n });\n return sortTokens(filtered, { by: sortBy, dir: sortDir }).map(([path, token]) => {\n const value = token.$value;\n if (!value || typeof value !== 'object') {\n return { path, sampleStyle: {}, specs: '' };\n }\n return buildRow(path, value as TypographyValue);\n });\n }, [resolved, filter, sortBy, sortDir]);\n\n const captionText =\n caption ??\n `${rows.length} typography token${rows.length === 1 ? '' : 's'}${filter && filter !== 'typography' ? ` matching \\`${filter}\\`` : ''} · ${activeTheme}`;\n\n if (rows.length === 0) {\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__empty\">No typography tokens match this filter.</div>\n </div>\n );\n }\n\n return (\n <div {...blockWrapperAttrs(cssVarPrefix, activeAxes)}>\n <div className=\"sb-block__caption\">{captionText}</div>\n {rows.map((row) => (\n <div key={row.path} className=\"sb-typography-scale__row\">\n <div className=\"sb-typography-scale__meta\">\n <span className=\"sb-typography-scale__path\">{row.path}</span>\n {row.specs && <span className=\"sb-typography-scale__specs\">{row.specs}</span>}\n </div>\n <div style={row.sampleStyle}>{sample}</div>\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}