@marktiderman/genesis-ui 2.12.1 → 2.13.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,"sources":["../src/option-storage.ts","../src/components/layout/PageHeader.tsx","../src/components/layout/sub-nav.tsx","../src/components/layout/AppShell.tsx"],"names":["readStoredOptions","useEffect","jsx","jsxs","Fragment","useState","useCallback","useMemo","useId","OPTION_DEFAULTS","useIsoLayoutEffect","useLayoutEffect","useRef","SlidersHorizontal"],"mappings":"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","file":"chunk-6N6MUN3T.js","sourcesContent":["/**\n * Generic localStorage-backed persistence for \"customize chrome\" option\n * objects (AppShell, PageHeader, …). SSR-safe (no-ops without `window`) and\n * swallows quota / private-mode errors so a storage failure never breaks\n * rendering.\n *\n * Callers own their own shape validation — this module only handles the\n * JSON <-> localStorage plumbing shared across chrome components.\n */\nexport function readStoredOptions<T extends object>(key: string): Partial<T> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as Partial<T>;\n } catch {\n return {};\n }\n}\n\nexport function writeStoredOptions<T extends object>(\n key: string,\n value: Partial<T>,\n): void {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota / private mode\n }\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useState, type ReactNode } from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { ListFilter, MoreHorizontal, SlidersHorizontal } from \"lucide-react\";\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Switch } from \"../ui/switch\";\nimport { Label } from \"../ui/label\";\nimport { ViewToggle, type ViewMode } from \"../patterns/view-toggle\";\nimport { ViewSettings } from \"../patterns/view-settings\";\nimport type { Density } from \"../../hooks/use-view-settings\";\nimport { cn } from \"../../utils\";\nimport {\n readStoredOptions as readStoredOptionsRaw,\n writeStoredOptions,\n} from \"../../option-storage\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\n\n/**\n * Declarative chrome for PageHeader — developer defaults + optional\n * in-header user toggles (Notion/Linear “customize view” pattern).\n *\n * @stability Beta\n */\nexport interface PageHeaderOptions {\n /**\n * The icon, title and subtitle block. Turn it off where the surrounding\n * page already names the content (a list inside a tab), keeping only the\n * actions row: count, view toggle, filters, create. Default true. A\n * developer setting, not offered in the user's Header options.\n */\n showTitle?: boolean;\n showIcon?: boolean;\n showSubtitle?: boolean;\n showCount?: boolean;\n showViewToggle?: boolean;\n showViewSettings?: boolean;\n showCreate?: boolean;\n /**\n * Stat cards row under the title block. Off by default — a header that\n * receives `stats` still hides them until the developer or the user turns\n * this on, so an existing page gains no new chrome by upgrading.\n */\n showStats?: boolean;\n /** Ghost ListFilter control in the actions cluster */\n showDetailsToggle?: boolean;\n /** Quiet hint beside actions while details are collapsed */\n showDetailsHint?: boolean;\n /** Move subtitle into the details panel (default true when details exist) */\n subtitleInDetails?: boolean;\n defaultDetailsOpen?: boolean;\n detailsLabel?: string;\n /**\n * Show the in-header Header options popover so users can customize chrome.\n * Default true when the header has more than one chrome affordance.\n */\n configurable?: boolean;\n}\n\n/** @stability Beta */\nexport type PageHeaderOptionKey = keyof PageHeaderOptions;\n\n/** Naive English pluralization for the count badge — singular at exactly 1. */\nfunction pluralizeEntity(entity: string, count: number): string {\n if (count === 1) return entity;\n return entity.endsWith(\"s\") ? entity : `${entity}s`;\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\">\n> &\n Pick<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\"> = {\n showTitle: true,\n showIcon: true,\n showSubtitle: true,\n showCount: true,\n showViewToggle: true,\n showViewSettings: true,\n showCreate: true,\n showStats: false,\n showDetailsToggle: true,\n showDetailsHint: true,\n subtitleInDetails: undefined,\n defaultDetailsOpen: false,\n detailsLabel: \"Details\",\n configurable: undefined,\n};\n\n// `showTitle` is left out on purpose: it is a developer setting, so a stored\n// user override must never hide the title.\nconst BOOLEAN_OPTION_KEYS: PageHeaderOptionKey[] = [\n \"showIcon\",\n \"showSubtitle\",\n \"showCount\",\n \"showViewToggle\",\n \"showViewSettings\",\n \"showCreate\",\n \"showStats\",\n \"showDetailsToggle\",\n \"showDetailsHint\",\n \"subtitleInDetails\",\n \"defaultDetailsOpen\",\n \"configurable\",\n];\nconst STRING_OPTION_KEYS: PageHeaderOptionKey[] = [\"detailsLabel\"];\n\n/**\n * Reads persisted options and keeps only known keys whose stored value has\n * the expected primitive type — a malformed or hand-edited localStorage\n * value can't smuggle in an unexpected key or wrong-typed override.\n */\nfunction readStoredOptions(key: string): Partial<PageHeaderOptions> {\n const raw = readStoredOptionsRaw<PageHeaderOptions>(key);\n const sanitized: Partial<PageHeaderOptions> = {};\n for (const optKey of BOOLEAN_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"boolean\") {\n (sanitized as Record<string, boolean>)[optKey] = value;\n }\n }\n for (const optKey of STRING_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"string\") {\n (sanitized as Record<string, string>)[optKey] = value;\n }\n }\n return sanitized;\n}\n\n/** One entry in {@link PageHeaderProps.secondaryActions}. */\nexport interface PageHeaderAction {\n label: string;\n onClick: () => void;\n icon?: LucideIcon;\n /** `data-testid` on the menu item, so e2e can drive it. */\n testId?: string;\n disabled?: boolean;\n /** Omits the action entirely — for one gated on data. */\n hidden?: boolean;\n}\n\nexport interface PageHeaderProps {\n title: string;\n subtitle?: string;\n icon?: LucideIcon;\n /**\n * Header chrome config (developer defaults). Merged under user picks from\n * the in-header options menu when `options.configurable` / storage is on.\n */\n options?: PageHeaderOptions;\n /** Persist user header-option overrides (localStorage) */\n optionsStorageKey?: string;\n /** Extra trailing actions (after create); prefer first-class slots below */\n actions?: ReactNode;\n /**\n * Stat cards row, full width, directly under the title block and above\n * `details`. Layout-only: pass `<StatCard>`s (or anything else) and the\n * header positions them. Rendered only when `options.showStats` resolves\n * true — see {@link PageHeaderOptions.showStats}.\n */\n stats?: ReactNode;\n /** Collapsible details region below the title row */\n details?: ReactNode;\n detailsOpen?: boolean;\n onDetailsOpenChange?: (open: boolean) => void;\n detailsActive?: boolean;\n detailsHint?: ReactNode;\n /** Count badge */\n count?: number;\n totalCount?: number;\n /** Singular entity for “N rows” copy when unfiltered */\n entityName?: string;\n countActive?: boolean;\n viewMode?: ViewMode;\n onViewModeChange?: (mode: ViewMode) => void;\n pageSize?: number;\n onPageSizeChange?: (size: number) => void;\n density?: Density;\n onDensityChange?: (density: Density) => void;\n createAction?: ReactNode;\n /**\n * Additional actions, rendered in ONE overflow menu — never as more\n * side-by-side buttons.\n *\n * The budget is the point. A header with three top-level buttons squeezes\n * its own title to an ellipsis at real viewport widths, so a surface that\n * genuinely has four actions needs somewhere to put the other three. Before\n * this existed the only place was a fork of the header, which is exactly\n * what one consumer did.\n *\n * Pass `ReactNode` via `actions` instead when you need arbitrary chrome;\n * this prop is for the ordinary case, and it keeps the budget for you.\n */\n secondaryActions?: PageHeaderAction[];\n}\n\ntype ToggleDef = {\n key: keyof PageHeaderOptions;\n label: string;\n available: boolean;\n};\n\nexport function PageHeader({\n title,\n subtitle,\n icon: Icon,\n options: optionsProp,\n optionsStorageKey,\n actions,\n stats,\n details,\n detailsOpen,\n onDetailsOpenChange,\n detailsActive = false,\n detailsHint,\n count,\n totalCount,\n entityName,\n countActive = false,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n createAction,\n secondaryActions,\n}: PageHeaderProps) {\n const detailsRegionId = useId();\n const hasDetails = details != null;\n const hasStats = stats != null;\n const hasCount = count !== undefined && totalCount !== undefined;\n const hasViewToggle = Boolean(viewMode && onViewModeChange);\n const hasViewSettings = Boolean(onPageSizeChange && onDensityChange);\n const hasCreate = createAction != null;\n // `hidden` is filtered here rather than at the call site: an action gated on\n // data (\"Review drafts\", only when drafts exist) is the common case, and a\n // conditional array at every call site is what makes those call sites drift.\n const visibleSecondary = (secondaryActions ?? []).filter((a) => !a.hidden);\n\n const [userOverrides, setUserOverrides] = useState<Partial<PageHeaderOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change (routing between pages with distinct keys while this header\n // stays mounted) can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const resolved = useMemo(() => {\n const merged: PageHeaderOptions = {\n ...OPTION_DEFAULTS,\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.subtitleInDetails === undefined) {\n merged.subtitleInDetails = hasDetails;\n }\n if (merged.configurable === undefined) {\n merged.configurable =\n hasDetails || hasStats || hasCount || hasViewSettings || hasViewToggle;\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n hasDetails,\n hasStats,\n hasCount,\n hasViewSettings,\n hasViewToggle,\n ]);\n\n const patchOption = useCallback((key: keyof PageHeaderOptions, value: boolean) => {\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n const moveSubtitle = Boolean(resolved.subtitleInDetails) && hasDetails;\n const showTitleSubtitle =\n Boolean(subtitle) &&\n Boolean(resolved.showSubtitle) &&\n !moveSubtitle;\n\n const [uncontrolledOpen, setUncontrolledOpen] = useState(\n () => optionsProp?.defaultDetailsOpen ?? OPTION_DEFAULTS.defaultDetailsOpen!,\n );\n const isControlled = detailsOpen !== undefined;\n const open = isControlled ? detailsOpen! : uncontrolledOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onDetailsOpenChange?.(next);\n };\n\n const detailsLabel = resolved.detailsLabel ?? \"Details\";\n const entity = entityName || \"item\";\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showIcon\", label: \"Icon\", available: Boolean(Icon) },\n {\n key: \"showSubtitle\",\n label: \"Subtitle\",\n available: Boolean(subtitle) && !moveSubtitle,\n },\n { key: \"showCount\", label: \"Count\", available: hasCount },\n { key: \"showViewToggle\", label: \"View toggle\", available: hasViewToggle },\n {\n key: \"showViewSettings\",\n label: \"Display settings\",\n available: hasViewSettings,\n },\n { key: \"showCreate\", label: \"Create action\", available: hasCreate },\n { key: \"showStats\", label: \"Stat cards\", available: hasStats },\n {\n key: \"showDetailsToggle\",\n label: \"Filters / details\",\n available: hasDetails,\n },\n {\n key: \"showDetailsHint\",\n label: \"Collapsed hint\",\n available: hasDetails && detailsHint != null,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available);\n\n const showDetailsToggle =\n hasDetails && Boolean(resolved.showDetailsToggle);\n const showStats = hasStats && Boolean(resolved.showStats);\n const showHint =\n hasDetails &&\n !open &&\n Boolean(resolved.showDetailsHint) &&\n detailsHint != null;\n\n const actionsCluster = (\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {showHint ? (\n <span className=\"hidden max-w-[14rem] truncate text-xs text-muted-foreground sm:inline\">\n {detailsHint}\n </span>\n ) : null}\n\n {hasCount && resolved.showCount !== false ? (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {countActive\n ? `${count} of ${totalCount}`\n : `${totalCount} ${pluralizeEntity(entity, totalCount!)}`}\n </Badge>\n ) : null}\n\n {hasViewToggle && resolved.showViewToggle !== false ? (\n <ViewToggle viewMode={viewMode!} onViewModeChange={onViewModeChange!} />\n ) : null}\n\n {showDetailsToggle ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n \"relative h-8 w-8\",\n (open || detailsActive) && \"bg-accent text-accent-foreground\",\n )}\n onClick={() => setOpen(!open)}\n data-testid=\"page-header-details-toggle\"\n title={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-label={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-expanded={open}\n aria-controls={detailsRegionId}\n testID=\"page-header-details-toggle\"\n >\n <ListFilter className=\"h-4 w-4\" />\n {detailsActive ? (\n <span\n className=\"absolute right-1.5 top-1.5 size-1.5 rounded-full bg-primary\"\n aria-hidden\n />\n ) : null}\n </Button>\n ) : null}\n\n {hasViewSettings && resolved.showViewSettings !== false ? (\n <ViewSettings\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange!}\n density={density ?? \"comfortable\"}\n onDensityChange={onDensityChange!}\n />\n ) : null}\n\n {hasCreate && resolved.showCreate !== false ? createAction : null}\n\n {visibleSecondary.length > 0 ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"More actions\"\n data-testid=\"page-header-more-actions\"\n >\n <MoreHorizontal className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {visibleSecondary.map((action) => {\n const ActionIcon = action.icon;\n return (\n <DropdownMenuItem\n key={action.label}\n onSelect={action.onClick}\n disabled={action.disabled}\n data-testid={action.testId}\n >\n {ActionIcon ? (\n <ActionIcon className=\"mr-2 h-4 w-4\" aria-hidden=\"true\" />\n ) : null}\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n\n {actions}\n\n {resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Header options\"\n aria-label=\"Header options\"\n data-testid=\"page-header-options\"\n testID=\"page-header-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Header options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this page header. Saved on this device when a storage\n key is set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`page-header-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`page-header-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey && Object.keys(userOverrides).length > 0 ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => setUserOverrides({})}\n data-testid=\"page-header-options-reset\"\n aria-label=\"Reset header options\"\n testID=\"page-header-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null}\n </div>\n );\n\n const titleRow = resolved.showTitle === false ? (\n <div\n data-testid=\"page-header-toolbar\"\n className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\"\n >\n {actionsCluster}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3 min-w-0\">\n {Icon && resolved.showIcon !== false ? (\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-primary/10\">\n <Icon className=\"h-5 w-5 text-primary\" />\n </div>\n ) : null}\n <div className=\"min-w-0\">\n <h1\n data-testid=\"page-title\"\n className=\"truncate font-display text-xl font-bold tracking-tight sm:text-2xl\"\n >\n {title}\n </h1>\n {showTitleSubtitle ? (\n <p className=\"truncate text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n </div>\n {actionsCluster}\n </div>\n );\n\n const statsRow = showStats ? (\n <div\n data-testid=\"page-header-stats\"\n className=\"mt-3 grid gap-3 sm:grid-cols-2 lg:grid-cols-4\"\n >\n {stats}\n </div>\n ) : null;\n\n if (!hasDetails) {\n return (\n <>\n {titleRow}\n {statsRow}\n </>\n );\n }\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n {titleRow}\n {statsRow}\n <CollapsibleContent id={detailsRegionId} className=\"mt-3\">\n <div className=\"flex flex-col gap-3 rounded-lg border border-border bg-card/40 p-3 sm:p-4\">\n {moveSubtitle && subtitle && resolved.showSubtitle !== false ? (\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n {details}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n","\"use client\";\n\n/**\n * Shell sub-navigation: the child items of the page you are on (a form's\n * Questions / Logic and endings / Responses / Settings), shown by AppShell\n * as a tab row, nested in the sidebar, or not at all (`SubNavMode`), and in\n * the mobile bottom bar whatever the mode.\n *\n * Children come from two places:\n * - statically, the current `NavigationNode`'s `items` (with `$param`s filled\n * from the URL), the same contextual items AppShell has always derived;\n * - dynamically, from the page: `useAppShellSubNav(items)` replaces them\n * while the page is mounted, so badges can carry live counts.\n *\n * Role gating works as for every other `NavItem`: filter the list before\n * handing it over (the tree's `items` or the hook's argument).\n */\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { LucideIcon } from \"lucide-react\";\n\nimport { cn } from \"../../utils\";\nimport { isPathActive, type LinkComponent } from \"../../navigation\";\nimport type { NavItem } from \"./AppShell\";\n\n/**\n * How AppShell shows the current page's child items. Sub-navigation is\n * opt-in: the default, `section`, is the shell as it always was.\n * - `section` (default): a labelled section below the global sidebar\n * items; on phones the children replace the bottom bar (no back item).\n * - `tabs`: one row of tabs across the top of the page content.\n * - `sidebar`: nested under the active item in the sidebar; a flyout from\n * that item on the collapsed rail.\n * - `off`: nothing, on desktop or phones; the app draws its own\n * (`SubNavTabs` is exported for it).\n *\n * With `tabs` or `sidebar`, phones switch the bottom bar to a back item to\n * the logical parent plus the children, with their badges.\n *\n * @stability Beta\n */\nexport type SubNavMode = \"section\" | \"tabs\" | \"sidebar\" | \"off\";\n\n/**\n * A sub-navigation item: a `NavItem` whose `icon` is optional (the tab row,\n * the phone bar and the rail show the label's first letter without one).\n * Every `NavItem` is a `SubNavItem`; `NavItem` itself keeps `icon` required.\n *\n * @stability Beta\n */\nexport interface SubNavItem extends Omit<NavItem, \"icon\" | \"children\"> {\n icon?: LucideIcon;\n children?: SubNavItem[];\n}\n\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** @internal Active-state rule shared by the sidebar, tabs and bottom bar. */\nexport function itemIsActive(\n item: SubNavItem,\n activePath: string | undefined,\n isActive: (to: string, activePath?: string) => boolean,\n): boolean {\n // `end` is exact on the path but ignores an incidental query/hash, so an\n // `end` item stays active on `/dashboard?page=2`.\n if (item.end) {\n return isPathActive(item.to, activePath, { end: true });\n }\n if (isActive(item.to, activePath)) return true;\n return Boolean(\n item.children?.some((child) => itemIsActive(child, activePath, isActive)),\n );\n}\n\n/**\n * Of several matching items, the one whose path matches most specifically,\n * so `/forms/f1/edit/logic` doesn't also light up an `/forms/f1/edit`\n * Questions tab that isn't marked `end`.\n *\n * @internal\n */\nexport function mostSpecificActive(\n items: SubNavItem[],\n activePath: string | undefined,\n isActive: (to: string, activePath?: string) => boolean,\n): SubNavItem | undefined {\n let best: SubNavItem | undefined;\n for (const item of items) {\n if (!itemIsActive(item, activePath, isActive)) continue;\n if (!best || item.to.length > best.to.length) best = item;\n }\n return best;\n}\n\nfunction BadgeChip({ badge, active }: { badge: string | number; active?: boolean }) {\n return (\n <span\n className={cn(\n \"inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-medium tabular-nums\",\n active ? \"bg-primary/10 text-primary\" : \"bg-muted text-muted-foreground\",\n )}\n >\n {badge}\n </span>\n );\n}\n\n/**\n * Props for {@link SubNavTabs}.\n *\n * @stability Beta\n */\nexport interface SubNavTabsProps {\n items: SubNavItem[];\n /** Current location (`pathname + search + hash`); drives the active tab. */\n activePath?: string;\n linkComponent: LinkComponent;\n isActive?: (to: string, activePath?: string) => boolean;\n /** Right-aligned slot in the row, e.g. a \"Ready to publish\" chip. */\n end?: ReactNode;\n /** Accessible name of the `<nav>` (default \"Page sections\"). */\n label?: string;\n className?: string;\n}\n\n/**\n * A row of navigation tabs: real links (deep links and middle-click work),\n * `aria-current=\"page\"` on the active one, badges as chips, the active tab\n * underlined in the brand colour. AppShell renders it in `tabs` mode; an app\n * using `subNav: \"off\"` can place it itself.\n *\n * @stability Beta\n */\nexport function SubNavTabs({\n items,\n activePath,\n linkComponent: LinkComp,\n isActive = isPathActive,\n end,\n label = \"Page sections\",\n className,\n}: SubNavTabsProps) {\n const current = mostSpecificActive(items, activePath, isActive);\n return (\n <div\n className={cn(\"flex min-w-0 items-end gap-4 border-b\", className)}\n data-testid=\"app-shell-sub-nav\"\n >\n <nav aria-label={label} className=\"-mb-px min-w-0 flex-1 overflow-x-auto\">\n <ul className=\"flex items-end gap-6\">\n {items.map((item) => {\n const active = item === current;\n const Icon = item.icon;\n const body = (\n <>\n {Icon ? <Icon className=\"h-4 w-4 shrink-0\" aria-hidden /> : null}\n <span className=\"whitespace-nowrap\">{item.label}</span>\n {item.badge != null ? <BadgeChip badge={item.badge} active={active} /> : null}\n </>\n );\n const cls = cn(\n \"flex items-center gap-1.5 border-b-2 pb-2.5 pt-2 text-sm transition-colors motion-reduce:transition-none\",\n active\n ? \"border-primary font-semibold text-foreground\"\n : \"border-transparent text-muted-foreground hover:text-foreground\",\n );\n return (\n <li key={item.to + item.label} className=\"shrink-0\">\n {item.disabled ? (\n <span className={cn(cls, \"opacity-40\")} role=\"link\" aria-disabled=\"true\">\n {body}\n </span>\n ) : (\n <LinkComp\n href={item.to}\n aria-current={active ? \"page\" : undefined}\n className={cn(\n cls,\n \"rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n )}\n testID={`app-shell-sub-nav-${item.label}`}\n >\n {body}\n </LinkComp>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n {end != null ? <div className=\"flex shrink-0 items-center pb-2\">{end}</div> : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Page → shell channel\n// ---------------------------------------------------------------------------\n\ninterface PageSubNav {\n /** Absent: this registrant only sets a mode; items come from elsewhere. */\n items?: SubNavItem[];\n mode?: SubNavMode;\n}\n\ninterface Registration extends PageSubNav {\n id: string;\n /**\n * Render order of the registering component, taken at its first render.\n * React renders top-down, so a page inside a layout always gets a higher\n * number than that layout, and a page mounted later (a route change under\n * a mounted layout) does too: the highest number is the innermost caller.\n */\n order: number;\n}\n\n/** Portal slots the shell exposes to pages. */\ntype SlotName = \"header\" | \"end\";\n\n/** @internal What AppShell provides to pages. */\nexport interface SubNavChannel {\n register(id: string, order: number, value: PageSubNav): void;\n unregister(id: string): void;\n /** Claim a portal slot; the innermost claimant (highest order) renders. */\n claimSlot(slot: SlotName, id: string, order: number): void;\n releaseSlot(slot: SlotName, id: string): void;\n /** The mounted slot elements, and which claimant owns each. */\n slots: Record<SlotName, { el: HTMLElement | null; owner: string | undefined }>;\n}\n\n/** @internal */\nexport const SubNavContext = createContext<SubNavChannel | null>(null);\n\ntype Claims = Record<SlotName, Array<{ id: string; order: number }>>;\n\nfunction innermost(claims: Array<{ id: string; order: number }>): string | undefined {\n let best: { id: string; order: number } | undefined;\n for (const c of claims) if (!best || c.order > best.order) best = c;\n return best?.id;\n}\n\n/**\n * @internal Shell side: holds the page registrations and slot claims.\n * Registration runs in a layout effect, so the page's items are in place\n * before first paint.\n */\nexport function useSubNavChannel(): {\n page: PageSubNav | undefined;\n channel: SubNavChannel;\n setEndSlot: (el: HTMLElement | null) => void;\n setHeaderSlot: (el: HTMLElement | null) => void;\n /** A page header has been claimed (render the header region). */\n hasHeader: boolean;\n /** An end-slot chip has been claimed (render the row's end region). */\n hasEnd: boolean;\n} {\n const [entries, setEntries] = useState<Registration[]>([]);\n const [endSlot, setEndSlot] = useState<HTMLElement | null>(null);\n const [headerSlot, setHeaderSlot] = useState<HTMLElement | null>(null);\n const [claims, setClaims] = useState<Claims>({ header: [], end: [] });\n\n // Updated in place, so a badge change never reorders registrants.\n const register = useCallback((id: string, order: number, value: PageSubNav) => {\n setEntries((prev) =>\n prev.some((e) => e.id === id)\n ? prev.map((e) => (e.id === id ? { ...value, id, order } : e))\n : [...prev, { ...value, id, order }],\n );\n }, []);\n const unregister = useCallback((id: string) => {\n setEntries((prev) => prev.filter((e) => e.id !== id));\n }, []);\n const claimSlot = useCallback((slot: SlotName, id: string, order: number) => {\n setClaims((prev) =>\n prev[slot].some((c) => c.id === id)\n ? prev\n : { ...prev, [slot]: [...prev[slot], { id, order }] },\n );\n }, []);\n const releaseSlot = useCallback((slot: SlotName, id: string) => {\n setClaims((prev) =>\n prev[slot].some((c) => c.id === id)\n ? { ...prev, [slot]: prev[slot].filter((c) => c.id !== id) }\n : prev,\n );\n }, []);\n\n const headerOwner = innermost(claims.header);\n const endOwner = innermost(claims.end);\n const channel = useMemo<SubNavChannel>(\n () => ({\n register,\n unregister,\n claimSlot,\n releaseSlot,\n slots: {\n header: { el: headerSlot, owner: headerOwner },\n end: { el: endSlot, owner: endOwner },\n },\n }),\n [register, unregister, claimSlot, releaseSlot, headerSlot, headerOwner, endSlot, endOwner],\n );\n\n // Innermost registrant wins, separately for items and for mode, so a page\n // that only sets a mode keeps a layout's items (and vice versa).\n const byDepth = [...entries].sort((a, b) => b.order - a.order);\n const items = byDepth.find((e) => e.items)?.items;\n const mode = byDepth.find((e) => e.mode)?.mode;\n return {\n page: items || mode ? { items, mode } : undefined,\n channel,\n setEndSlot,\n setHeaderSlot,\n hasHeader: headerOwner !== undefined,\n hasEnd: endOwner !== undefined,\n };\n}\n\nlet nextOrder = 0;\n\nconst iconIds = new WeakMap<object, number>();\nlet nextIconId = 1;\nfunction iconKey(icon: unknown): number {\n if (!icon || (typeof icon !== \"object\" && typeof icon !== \"function\")) return 0;\n let id = iconIds.get(icon as object);\n if (id == null) {\n id = nextIconId++;\n iconIds.set(icon as object, id);\n }\n return id;\n}\n\nfunction itemsKey(items: SubNavItem[]): string {\n return JSON.stringify(\n items.map((i) => [\n i.to,\n i.label,\n i.badge ?? null,\n Boolean(i.disabled),\n Boolean(i.end),\n iconKey(i.icon),\n i.children ? itemsKey(i.children) : null,\n ]),\n );\n}\n\n/**\n * Options for {@link useAppShellSubNav}.\n *\n * @stability Beta\n */\nexport interface UseAppShellSubNavOptions {\n /** This page's `subNav` mode; wins over the shell's and the node's. */\n mode?: SubNavMode;\n}\n\n/**\n * Give the shell this page's child items (sub-navigation) while the page is\n * mounted. They replace the current `NavigationNode`'s `items`; pass\n * `null` / `undefined` to fall back to them (a `mode` still applies). When\n * several components call it (a layout and its page), the innermost wins,\n * for items and for mode separately. Use it when children depend on\n * page data, such as live badge counts. A fresh array each render is fine:\n * the shell only updates when a `to`, label, badge, icon or flag changes.\n *\n * ```tsx\n * useAppShellSubNav([\n * { to: `/forms/${id}/edit`, label: \"Questions\", icon: ListChecks, badge: questions.length, end: true },\n * { to: `/forms/${id}/edit/logic`, label: \"Logic and endings\", icon: GitBranch, badge: rules.length },\n * { to: `/forms/${id}/edit/responses`, label: \"Responses\", icon: Inbox, badge: responses },\n * { to: `/forms/${id}/edit/settings`, label: \"Settings\", icon: Settings },\n * ]);\n * ```\n *\n * Does nothing outside an `AppShell`.\n *\n * @stability Beta\n */\nexport function useAppShellSubNav(\n items: SubNavItem[] | null | undefined,\n options?: UseAppShellSubNavOptions,\n): void {\n const channel = useContext(SubNavContext);\n const id = useId();\n const [order] = useState(() => ++nextOrder);\n const latest = useRef(items);\n latest.current = items;\n const key = items ? itemsKey(items) : \"\";\n const mode = options?.mode;\n const register = channel?.register;\n const unregister = channel?.unregister;\n\n useIsoLayoutEffect(() => {\n if (!register || !unregister) return;\n const value = latest.current ?? undefined;\n // `null` items with a mode still register: the mode applies, and the\n // items fall back to an outer registrant or the node's.\n if (value || mode) register(id, order, { items: value, mode });\n else unregister(id);\n }, [register, unregister, id, order, key, mode]);\n\n useIsoLayoutEffect(() => {\n if (!unregister) return;\n return () => unregister(id);\n }, [unregister, id]);\n}\n\nfunction useSlotPortal(slot: SlotName, children: ReactNode): ReactNode {\n const channel = useContext(SubNavContext);\n const id = useId();\n const [order] = useState(() => ++nextOrder);\n const claimSlot = channel?.claimSlot;\n const releaseSlot = channel?.releaseSlot;\n useIsoLayoutEffect(() => {\n if (!claimSlot || !releaseSlot) return;\n claimSlot(slot, id, order);\n return () => releaseSlot(slot, id);\n }, [claimSlot, releaseSlot, slot, id, order]);\n const target = channel?.slots[slot];\n if (!target?.el || target.owner !== id) return null;\n return createPortal(children, target.el);\n}\n\n/**\n * Render `children` in the right-hand slot of the shell's sub-navigation\n * tab row, e.g. a \"Ready to publish\" status chip. Rendered through a\n * portal, so it keeps the page's context and state. Renders nothing when\n * the shell shows no tab row (other modes, phones, no children). When\n * several are mounted (a layout's and a page's), the innermost renders.\n *\n * @stability Beta\n */\nexport function AppShellSubNavEnd({ children }: { children: ReactNode }) {\n return useSlotPortal(\"end\", children);\n}\n\n/**\n * Render the page's resource header (breadcrumb, title, status, actions) at\n * the top of the shell's content, ABOVE the sub-navigation tab row, where\n * the design puts it. A portal like `AppShellSubNavEnd`, so it keeps the\n * page's state; the innermost mounted one renders. On phones it stays at\n * the top of the content while the bottom bar carries the children. With\n * no tab row (the default `\"section\"` mode, or a page without children) it\n * simply sits at the top of the content. Mount none and the layout is\n * unchanged.\n *\n * @stability Beta\n */\nexport function AppShellPageHeader({ children }: { children: ReactNode }) {\n return useSlotPortal(\"header\", children);\n}\n","\"use client\";\n\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n Menu,\n X,\n Sun,\n Moon,\n SlidersHorizontal,\n PanelLeftClose,\n PanelLeft,\n ChevronDown,\n ChevronRight,\n ArrowLeft,\n} from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { Badge } from \"../ui/badge\";\nimport { Label } from \"../ui/label\";\nimport { Switch } from \"../ui/switch\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport { Tooltip } from \"../ui/tooltip\";\nimport {\n itemIsActive,\n mostSpecificActive,\n SubNavContext,\n SubNavTabs,\n useSubNavChannel,\n type SubNavItem,\n type SubNavMode,\n} from \"./sub-nav\";\nimport { cn } from \"../../utils\";\nimport { readStoredOptions, writeStoredOptions } from \"../../option-storage\";\nimport {\n DefaultLink,\n isPathActive,\n resolveNavigation,\n type LinkComponent,\n type NavigationNode,\n} from \"../../navigation\";\n\nexport interface NavItem {\n /** Route, optionally with `?search` / `#hash` (see `isPathActive`). */\n to: string;\n icon: LucideIcon;\n label: string;\n /** Nested items — rendered as a collapsible group when the rail is expanded */\n children?: NavItem[];\n /**\n * A count (`3`) or a short status (`\"New\"`), shown as a chip: in the\n * sidebar, the sub-navigation tabs and the mobile bar; as a dot on the\n * collapsed rail. It is part of the item's accessible name where the label\n * is hidden.\n */\n badge?: string | number;\n disabled?: boolean;\n /**\n * Exact-match active state (e.g. overview `/`). Exact on the path only, so\n * an `activePath` carrying `?search#hash` still matches.\n */\n end?: boolean;\n}\n\n/**\n * The \"up\" link AppShell renders above page content: a real link to the\n * logical parent, never `history.back()`.\n *\n * @stability Beta\n */\nexport interface ParentNavigation {\n href: string;\n label: string;\n}\n\n/**\n * Declarative chrome for AppShell — developer defaults + optional\n * in-sidebar user toggles (Notion/Linear “customize chrome” pattern).\n *\n * @stability Beta\n */\nexport interface AppShellOptions {\n showLogo?: boolean;\n showAppName?: boolean;\n showThemeToggle?: boolean;\n /** Desktop rail collapse control */\n showCollapse?: boolean;\n showUserSlot?: boolean;\n showFooter?: boolean;\n showSecondaryNav?: boolean;\n /** Mobile fixed bottom tab bar */\n showMobileBottomNav?: boolean;\n /**\n * Open the desktop sidebar collapsed (an icon rail, `collapsedRailWidth` wide) when the user hasn't\n * chosen. The app-wide default; a page asks for its own through\n * `AppShellProps.defaultCollapsed` or `NavigationNode.defaultCollapsed`.\n */\n defaultCollapsed?: boolean;\n /**\n * Opt-in key that toggles the desktop sidebar, e.g. `\"[\"` as in Linear and\n * Notion. Off (`false`) by default. It never fires while typing in a field,\n * while a listbox, combobox or menu has focus (Select typeahead), while a\n * dialog is open, with Ctrl/Cmd/Alt held, or when `showCollapse` is off.\n */\n collapseShortcut?: string | false;\n /**\n * Width of the collapsed icon rail in px: `56` (default, as before) or\n * `64` (the Breakthrough design).\n */\n collapsedRailWidth?: 56 | 64;\n /**\n * Shell sub-navigation, opt-in. `\"section\"` (default) renders a page's\n * children exactly as AppShell always has; `\"tabs\"` or `\"sidebar\"` turn\n * sub-navigation on (see `SubNavMode`), and `\"off\"` hides them. A\n * navigation node, the `subNav` prop or the page\n * (`useAppShellSubNav(items, { mode })`) can override it.\n */\n subNav?: SubNavMode;\n /**\n * Show the in-sidebar Sidebar options popover so users can customize chrome.\n * Default true when collapse / secondary / theme / slots are available.\n */\n configurable?: boolean;\n /**\n * Toggle keys the developer has decided on and users may not override —\n * e.g. hiding `showThemeToggle` for a brand that manages theme elsewhere.\n * Locked keys are dropped from the options popover and any stored user\n * override for them is ignored on resolve.\n */\n lockedOptions?: (keyof AppShellOptions)[];\n /** Comfortable (default) vs compact row padding */\n density?: \"comfortable\" | \"compact\";\n /** Expanded rail width in rem-ish tokens: narrow ≈ 13rem, wide ≈ 16rem */\n railWidth?: \"narrow\" | \"wide\";\n /**\n * Where page content scrolls.\n * - `container` (default): main panel scrolls — classic app-shell chrome.\n * - `window`: document/window scrolls with a sticky rail so React Router\n * `ScrollRestoration` keeps working (dashboard dogfood).\n */\n scrollRoot?: \"container\" | \"window\";\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<\n AppShellOptions,\n | \"configurable\"\n | \"defaultCollapsed\"\n | \"lockedOptions\"\n | \"collapseShortcut\"\n | \"subNav\"\n | \"collapsedRailWidth\"\n >\n> &\n Pick<\n AppShellOptions,\n | \"configurable\"\n | \"defaultCollapsed\"\n | \"lockedOptions\"\n | \"collapseShortcut\"\n | \"subNav\"\n | \"collapsedRailWidth\"\n > = {\n showLogo: true,\n showAppName: true,\n showThemeToggle: true,\n showCollapse: true,\n showUserSlot: true,\n showFooter: true,\n showSecondaryNav: true,\n showMobileBottomNav: true,\n defaultCollapsed: false,\n collapseShortcut: false,\n collapsedRailWidth: 56,\n subNav: \"section\",\n configurable: undefined,\n density: \"comfortable\",\n railWidth: \"narrow\",\n scrollRoot: \"container\",\n};\n\n// The user's collapse choice lives at `${optionsStorageKey}:collapsed` as\n// \"1\" / \"0\"; no entry means they haven't chosen. It is read through\n// `useSyncExternalStore`, so a client-only mount reads it during the first\n// render (no expanded-then-collapsed flash), hydration uses the server\n// snapshot (no mismatch), and every shell on the page, and other tabs via the\n// `storage` event, stays in step.\nconst collapsedListeners = new Set<() => void>();\n\nfunction subscribeCollapsed(listener: () => void): () => void {\n collapsedListeners.add(listener);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"storage\", listener);\n }\n return () => {\n collapsedListeners.delete(listener);\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"storage\", listener);\n }\n };\n}\n\nfunction readStoredCollapsed(key: string): boolean | undefined {\n if (typeof window === \"undefined\") return undefined;\n try {\n const raw = localStorage.getItem(`${key}:collapsed`);\n if (raw === \"1\") return true;\n if (raw === \"0\") return false;\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStoredCollapsed(key: string, collapsed: boolean | undefined) {\n if (typeof window === \"undefined\") return;\n try {\n if (collapsed === undefined) localStorage.removeItem(`${key}:collapsed`);\n else localStorage.setItem(`${key}:collapsed`, collapsed ? \"1\" : \"0\");\n } catch {\n // quota / private mode\n }\n collapsedListeners.forEach((listener) => listener());\n}\n\nfunction useStoredCollapsed(key: string | undefined): boolean | undefined {\n return useSyncExternalStore(\n subscribeCollapsed,\n () => (key ? readStoredCollapsed(key) : undefined),\n () => undefined,\n );\n}\n\nfunction isTypingTarget(el: EventTarget | null): boolean {\n if (!el || typeof (el as HTMLElement).tagName !== \"string\") return false;\n const node = el as HTMLElement;\n const tag = node.tagName;\n return (\n tag === \"INPUT\" ||\n tag === \"TEXTAREA\" ||\n tag === \"SELECT\" ||\n node.isContentEditable === true ||\n node.closest?.('[contenteditable=\"\"], [contenteditable=\"true\"]') != null\n );\n}\n\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** Focus is in a widget that uses printable keys itself (typeahead). */\nfunction ownsKeys(el: EventTarget | null): boolean {\n const node = el as HTMLElement | null;\n return Boolean(\n node?.closest?.(\n '[role=\"listbox\"], [role=\"combobox\"], [role=\"menu\"], [role=\"menubar\"], [role=\"menuitem\"], [role=\"option\"], [role=\"tree\"], [role=\"grid\"]',\n ),\n );\n}\n\n/** A modal or Radix dialog is open somewhere on the page. */\nfunction dialogOpen(): boolean {\n if (typeof document === \"undefined\") return false;\n return (\n document.querySelector('[role=\"dialog\"][data-state=\"open\"], [role=\"alertdialog\"][data-state=\"open\"], [aria-modal=\"true\"]') !=\n null\n );\n}\n\n/** md breakpoint: the desktop sidebar only exists at this width and up. */\nconst DESKTOP_QUERY = \"(min-width: 768px)\";\n\n/**\n * @stability Beta\n */\nexport interface AppShellProps {\n /** App name shown in sidebar header */\n appName: string;\n /** App logo letter or short text (ignored when `logo` is set) */\n appLogo?: string;\n /** Custom logo node — preferred over `appLogo` letter tile */\n logo?: ReactNode;\n /**\n * Primary navigation items. Optional when `navigation` is set: the tree\n * root's `items` are the global nav then.\n */\n navItems?: NavItem[];\n /**\n * The app's logical navigation hierarchy. AppShell resolves it against\n * `activePath` (see `resolveNavigation`) and derives:\n * - the sidebar's global items from the root's `items` (unless `navItems`),\n * - a contextual section from the current node's `items`, labelled with\n * the node's `label` (`$param` segments in `to` filled from the URL),\n * - the mobile tab bar: the contextual items when there are any, else the\n * global top-level items (unless `mobileNavItems`),\n * - a back link to the current node's logical parent (unless\n * `parentNavigation`).\n *\n * @stability Beta\n */\n navigation?: NavigationNode<NavItem>;\n /**\n * Back-to-parent link rendered in the content header, above `children`, on\n * mobile and desktop. Derived from `navigation` when omitted; `null` hides\n * it. Use this instead of placing a back row inside page content.\n *\n * @stability Beta\n */\n parentNavigation?: ParentNavigation | null;\n /** Secondary nav (e.g. “More”) — rendered below a divider when shown */\n secondaryNavItems?: NavItem[];\n /** Label above secondary nav (default “More”) */\n secondaryNavLabel?: string;\n /**\n * Items for the mobile bottom tab bar. Defaults to top-level `navItems`\n * (no children). Pass a short list for apps with large sidebars; pass `[]`\n * and set `options.showMobileBottomNav: false` to hide.\n */\n mobileNavItems?: NavItem[];\n /** Slot below the logo row (product switcher, workspace picker, …) */\n headerSlot?: ReactNode;\n /**\n * Compact slot shown in the **collapsed** desktop rail, where `headerSlot`\n * is hidden for space. Use it to keep a core affordance reachable without\n * expanding — e.g. an icon-only product switcher. Omit to hide the header\n * region entirely while collapsed.\n */\n collapsedHeaderSlot?: ReactNode;\n /** Footer region above the user slot (version, links) */\n footer?: ReactNode;\n /**\n * User / account block at the bottom of the sidebar. When the rail is\n * collapsed, AppShell hides any descendant carrying the\n * `data-shell-user-detail` attribute (e.g. name/email text) so only a\n * compact element (avatar, initial) remains — tag the detail wrapper you\n * want hidden in the collapsed rail with that attribute.\n */\n userSlot?: ReactNode;\n /** Page content */\n children: ReactNode;\n /**\n * @deprecated Prefer `options.showThemeToggle`. Kept for sample-app\n * back-compat; merges into resolved options when `options` omits it.\n */\n showThemeToggle?: boolean;\n /** Chrome config (developer defaults + optional in-sidebar menu) */\n options?: AppShellOptions;\n /** Persist user sidebar-option overrides + collapse state (localStorage) */\n optionsStorageKey?: string;\n /**\n * Controlled collapse (desktop rail). Overrides the stored user choice and\n * every default.\n */\n collapsed?: boolean;\n /** Called with the new state whenever the user toggles the sidebar. */\n onCollapsedChange?: (collapsed: boolean) => void;\n /**\n * This page's default: open the desktop sidebar collapsed (`true`) or\n * expanded (`false`) until the user toggles it. Reactive, so a layout can\n * pass it per route. Wins over `navigation`'s `defaultCollapsed` and\n * `options.defaultCollapsed`; the user's own choice (persisted under\n * `optionsStorageKey`) wins over all of them.\n *\n * @stability Beta\n */\n defaultCollapsed?: boolean;\n /**\n * This page's sub-navigation mode (see `AppShellOptions.subNav`). Wins\n * over `navigation`'s `subNav` and `options.subNav`; the page's own\n * `useAppShellSubNav(items, { mode })` wins over it.\n *\n * @stability Beta\n */\n subNav?: SubNavMode;\n /**\n * Accessible name of the sub-navigation tab row. Defaults to the current\n * navigation node's label, else \"Page sections\".\n */\n subNavLabel?: string;\n /**\n * Injectable link component. Defaults to a plain `<a>` (no router). Pass a\n * router adapter — e.g. React Router `({ href, ...p }) => <Link to={href} {...p} />`\n * or Next.js `next/link` — to get client-side navigation.\n */\n linkComponent?: LinkComponent;\n /**\n * Current location used to highlight the active nav item. Pass the full\n * location, `pathname + search + hash` (React Router: `useLocation()`), so\n * items whose `to` names a query or hash (`/admin?tab=users`) can become\n * active. A pathname alone still works for path-only items, `end` included.\n * Omit to disable active highlighting.\n */\n activePath?: string;\n /**\n * Optional custom active-state matcher. Defaults to a prefix match (with `/`\n * treated as exact), mirroring React Router `NavLink`.\n */\n isActive?: (to: string, activePath?: string) => boolean;\n}\n\nconst PARAM = /^\\$(.+)$/;\n\n/**\n * Fill `$name` path segments from `params`; `undefined` if one is missing. A\n * `?query` / `#hash` on `to` is kept as is.\n */\nfunction fillParams(to: string, params: Record<string, string>): string | undefined {\n const cut = to.search(/[?#]/);\n const path = cut === -1 ? to : to.slice(0, cut);\n const suffix = cut === -1 ? \"\" : to.slice(cut);\n let missing = false;\n const filled = path\n .split(\"/\")\n .map((part) => {\n const name = PARAM.exec(part)?.[1];\n if (name == null) return part;\n const value = params[name];\n if (value == null) missing = true;\n return value == null ? part : encodeURIComponent(value);\n })\n .join(\"/\");\n return missing ? undefined : filled + suffix;\n}\n\n/** Interpolate items (and children); drop any whose path the URL can't fill. */\nfunction fillItems(items: NavItem[], params: Record<string, string>): NavItem[] {\n return items.flatMap((item) => {\n const to = fillParams(item.to, params);\n if (to == null) return [];\n return [\n {\n ...item,\n to,\n children: item.children ? fillItems(item.children, params) : undefined,\n },\n ];\n });\n}\n\nfunction ThemeToggle({ testId }: { testId: string }) {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n const stored = localStorage.getItem(\"theme\");\n const prefersDark = window.matchMedia(\n \"(prefers-color-scheme: dark)\",\n ).matches;\n const isDark = stored === \"dark\" || (!stored && prefersDark);\n setDark(isDark);\n document.documentElement.classList.toggle(\"dark\", isDark);\n }, []);\n\n function toggle() {\n const next = !dark;\n setDark(next);\n document.documentElement.classList.toggle(\"dark\", next);\n localStorage.setItem(\"theme\", next ? \"dark\" : \"light\");\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggle}\n className=\"h-8 w-8\"\n title=\"Toggle theme\"\n aria-label=\"Toggle theme\"\n data-testid={testId}\n testID={testId}\n >\n {dark ? <Sun className=\"h-4 w-4\" /> : <Moon className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\n/** The item's icon, or its label's first letter when it has none. */\nfunction NavIcon({ item, className }: { item: SubNavItem; className?: string }) {\n if (item.icon) {\n const Icon = item.icon;\n return <Icon className={className} />;\n }\n return (\n <span\n className={cn(\n className,\n \"inline-flex items-center justify-center rounded text-[11px] font-semibold uppercase leading-none\",\n )}\n aria-hidden\n >\n {item.label.trim().charAt(0)}\n </span>\n );\n}\n\n/**\n * Name tooltip for an icon-rail entry, on hover and on keyboard focus. The\n * trigger is a wrapper span rather than the link itself, so it works with any\n * injected `linkComponent` (Radix needs a ref and event props on its\n * trigger; a router adapter need not forward either). Focus and blur bubble\n * up to the span, so tabbing onto the link still opens it.\n */\nfunction RailTooltip({ label, children }: { label: string; children: ReactNode }) {\n return (\n <Tooltip content={label} side=\"right\" className=\"flex w-full\">\n <span className=\"flex w-full\">{children}</span>\n </Tooltip>\n );\n}\n\nfunction NavLinkRow({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent: LinkComp,\n activePath,\n isActive,\n notCurrent = false,\n active: activeOverride,\n}: {\n item: SubNavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n /** Decided by the caller (most specific of siblings) instead of by `isActive`. */\n active?: boolean;\n}) {\n const active = activeOverride ?? itemIsActive(item, activePath, isActive);\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n\n if (item.disabled) {\n if (!collapsed) {\n return (\n <span\n title={item.label}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium opacity-40\",\n pad,\n )}\n aria-disabled\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate\">{item.label}</span>\n </span>\n );\n }\n // Rail: a disabled link, named so screen readers announce it (a bare\n // span's aria-label is not reliably read).\n return (\n <RailTooltip label={item.label}>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-label={item.label}\n className=\"flex h-10 w-full items-center justify-center rounded-lg text-sm font-medium opacity-40\"\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n </span>\n </RailTooltip>\n );\n }\n\n const link = (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n aria-label={\n collapsed\n ? item.badge != null\n ? `${item.label} (${item.badge})`\n : item.label\n : undefined\n }\n aria-current={active && !notCurrent ? \"page\" : undefined}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n collapsed && \"relative h-10 w-full justify-center px-0 py-0 motion-reduce:transition-none\",\n active\n ? \"bg-sidebar-accent text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n )}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n {!collapsed ? (\n <>\n <span className=\"min-w-0 flex-1 truncate\">{item.label}</span>\n {item.badge != null ? (\n <Badge variant=\"secondary\" className=\"h-5 shrink-0 px-1.5 text-[10px]\">\n {item.badge}\n </Badge>\n ) : null}\n </>\n ) : item.badge != null ? (\n // The rail has no room for the count: a dot shows there is one, and\n // the accessible name carries the number.\n <span\n className=\"absolute right-1.5 top-1.5 h-2 w-2 rounded-full bg-sidebar-primary\"\n aria-hidden\n />\n ) : null}\n </LinkComp>\n );\n return collapsed ? <RailTooltip label={item.label}>{link}</RailTooltip> : link;\n}\n\n/**\n * A nested group on the collapsed rail: one icon button that opens a popover\n * listing the group's own page (when it has one) and its children. Radix\n * Popover moves focus into the list, closes on Escape / outside click and\n * hands focus back to the button.\n */\nfunction RailGroup({\n item,\n density,\n linkComponent,\n activePath,\n isActive,\n notCurrent,\n}: {\n item: SubNavItem;\n density: \"comfortable\" | \"compact\";\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n notCurrent: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const children = item.children ?? [];\n const active = itemIsActive(item, activePath, isActive);\n const entries: SubNavItem[] = item.to\n ? [{ ...item, children: undefined, end: true }, ...children]\n : children;\n const current = mostSpecificActive(entries, activePath, isActive);\n\n // Close when navigation lands, whichever link (or the URL) caused it.\n useEffect(() => {\n setOpen(false);\n }, [activePath]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <RailTooltip label={item.label}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={item.label}\n disabled={item.disabled}\n data-testid={`nav-rail-group-${item.label}`}\n className={cn(\n \"relative flex h-10 w-full items-center justify-center rounded-lg transition-colors motion-reduce:transition-none\",\n active\n ? \"bg-sidebar-accent text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n item.disabled && \"pointer-events-none opacity-40\",\n )}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <ChevronRight\n className=\"absolute right-0.5 h-3 w-3 opacity-50\"\n aria-hidden\n />\n </button>\n </PopoverTrigger>\n </RailTooltip>\n <PopoverContent\n side=\"right\"\n align=\"start\"\n sideOffset={8}\n className=\"w-56 p-1.5 motion-reduce:animate-none\"\n aria-label={item.label}\n data-testid={`nav-rail-popover-${item.label}`}\n >\n <p className=\"truncate px-2.5 pb-1 pt-1.5 text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {item.label}\n </p>\n <nav aria-label={item.label} className=\"space-y-0.5\">\n {entries.map((entry) => (\n <NavLinkRow\n key={entry.to + entry.label}\n item={entry}\n collapsed={false}\n density={density}\n onNavClick={() => setOpen(false)}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n active={entry === current}\n />\n ))}\n </nav>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction NavGroup({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n notCurrent = false,\n}: {\n item: SubNavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n}) {\n const children = item.children ?? [];\n const childActive = children.some((c) =>\n itemIsActive(c, activePath, isActive),\n );\n const [open, setOpen] = useState(childActive);\n\n useEffect(() => {\n if (childActive) setOpen(true);\n }, [childActive]);\n\n if (children.length === 0) {\n return (\n <NavLinkRow\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Collapsed rail: the group becomes one icon that opens its items in a popover.\n if (collapsed) {\n return (\n <RailGroup\n item={item}\n density={density}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Parent may be its own route (`item.to`) — keep a real link and a separate\n // expand control so groups under an existing page stay navigable + highlightable.\n // Visual highlight may use prefix match; aria-current is exact-only so a child\n // route does not leave two \"page\" currents in the tree (CMT-322-008). Exact\n // means the same path; a query/hash on `activePath` alone doesn't break it.\n const selfExact = Boolean(\n item.to && isPathActive(item.to, activePath, { end: true }),\n );\n const selfActive = item.to\n ? item.end\n ? selfExact\n : isActive(item.to, activePath)\n : false;\n const groupHighlight = selfActive || childActive;\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n const LinkComp = linkComponent;\n const parentClass = cn(\n \"flex min-w-0 flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n groupHighlight\n ? \"bg-sidebar-accent/60 text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n );\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center gap-0.5\" data-testid={`nav-group-${item.label}`}>\n {item.to && !item.disabled ? (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n aria-current={selfExact && !notCurrent ? \"page\" : undefined}\n className={parentClass}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </LinkComp>\n ) : (\n <button\n type=\"button\"\n className={parentClass}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </button>\n )}\n <button\n type=\"button\"\n className={cn(\n \"shrink-0 rounded-lg p-1.5 text-sidebar-foreground transition-colors hover:bg-sidebar-accent\",\n groupHighlight && \"text-sidebar-primary\",\n item.disabled && \"pointer-events-none opacity-40\",\n )}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-label={open ? `Collapse ${item.label}` : `Expand ${item.label}`}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n data-testid={`nav-group-toggle-${item.label}`}\n >\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform\",\n open && \"rotate-180\",\n )}\n />\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-3 space-y-0.5 border-l border-sidebar-border pl-2\">\n {children.map((child) => (\n <NavLinkRow\n key={child.to + child.label}\n item={child}\n collapsed={false}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n ))}\n </div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n\nfunction SidebarNav({\n navItems,\n contextualNavItems,\n contextualNavLabel,\n secondaryNavItems,\n secondaryNavLabel,\n showSecondary,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n subActive = false,\n nest = false,\n}: {\n navItems: SubNavItem[];\n /** The page's children, in `subNav: \"sidebar\"` mode only. */\n contextualNavItems?: SubNavItem[];\n contextualNavLabel?: string;\n /** A sub-navigation item (wherever it renders) is the current page. */\n subActive?: boolean;\n /**\n * `subNav: \"sidebar\"`: nest the children under the active item (a flyout on\n * the rail), and mark only the most specific one current. Off, they keep\n * the legacy section below the global items.\n */\n nest?: boolean;\n secondaryNavItems?: SubNavItem[];\n secondaryNavLabel: string;\n showSecondary: boolean;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n}) {\n const contextualLabelId = useId();\n // While a contextual item is the current page, global items keep their\n // highlight (the section you are in) but leave `aria-current` to it, so\n // \"Showcase\" and \"Overview\" are never both the current page.\n const contextualActive =\n subActive ||\n Boolean(\n contextualNavItems?.some((item) => itemIsActive(item, activePath, isActive)),\n );\n const contextual = contextualNavItems ?? [];\n // Children nest under the active global item (\"Forms\" for a form's tabs).\n // With none active they get their own section below the global items.\n const host =\n nest && contextual.length > 0\n ? mostSpecificActive(navItems, activePath, isActive)\n : undefined;\n // Only the most specific sibling is current: `/forms/f1/edit/logic` must\n // not also light up a Questions item at `/forms/f1/edit`.\n const contextualCurrent = mostSpecificActive(contextual, activePath, isActive);\n\n const contextualGroup = (nested: boolean) => (\n <div\n className={cn(\n nested\n ? \"ml-3 space-y-0.5 border-l border-sidebar-border pl-2\"\n : \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n !nested && collapsed && \"mt-2 pt-2\",\n )}\n data-testid=\"app-shell-contextual-nav\"\n role=\"group\"\n aria-labelledby={!collapsed && !nested && contextualNavLabel ? contextualLabelId : undefined}\n aria-label={collapsed || nested ? contextualNavLabel : undefined}\n >\n {!collapsed && !nested && contextualNavLabel ? (\n <p\n id={contextualLabelId}\n className=\"mb-2 truncate px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\"\n >\n {contextualNavLabel}\n </p>\n ) : null}\n {contextual.map((item) =>\n item.children?.length ? (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ) : (\n <NavLinkRow\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n active={nest ? item === contextualCurrent : undefined}\n />\n ),\n )}\n </div>\n );\n\n return (\n <nav\n className={cn(\n \"flex-1 space-y-1 overflow-y-auto\",\n collapsed ? \"p-2\" : \"p-3\",\n )}\n aria-label=\"Main\"\n >\n {navItems.map((item) => {\n if (item === host && collapsed) {\n // Rail: the active item opens a flyout with its children.\n return (\n <RailGroup\n key={item.to + item.label}\n item={{ ...item, children: [...(item.children ?? []), ...contextual] }}\n density={density}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={false}\n />\n );\n }\n const row = (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={contextualActive}\n />\n );\n if (item !== host) return row;\n return (\n <div key={item.to + item.label} className=\"space-y-0.5\">\n {row}\n {contextualGroup(true)}\n </div>\n );\n })}\n\n {contextual.length > 0 && !host ? contextualGroup(false) : null}\n\n {showSecondary && secondaryNavItems && secondaryNavItems.length > 0 ? (\n <div\n className={cn(\n \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n collapsed && \"mt-2 pt-2\",\n )}\n >\n {!collapsed ? (\n <p className=\"mb-2 px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\">\n {secondaryNavLabel}\n </p>\n ) : null}\n {secondaryNavItems.map((item) => (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ))}\n </div>\n ) : null}\n </nav>\n );\n}\n\nfunction SidebarBrand({\n appName,\n appLogo,\n logo,\n showLogo,\n showAppName,\n collapsed,\n}: {\n appName: string;\n appLogo?: string;\n logo?: ReactNode;\n showLogo: boolean;\n showAppName: boolean;\n collapsed: boolean;\n}) {\n if (!showLogo && !showAppName) return null;\n\n return (\n <div\n className={cn(\n \"flex min-w-0 items-center gap-2\",\n collapsed && \"justify-center\",\n )}\n >\n {showLogo ? (\n logo ? (\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden\">\n {logo}\n </div>\n ) : appLogo || collapsed ? (\n // Collapsed with no logo at all: the app name's first letter keeps\n // a mark at the top of the rail.\n <div\n className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary\"\n aria-hidden={!appLogo || undefined}\n >\n <span className=\"text-sm font-bold text-primary-foreground\">\n {appLogo || appName.trim().charAt(0).toUpperCase()}\n </span>\n </div>\n ) : null\n ) : null}\n {showAppName && !collapsed ? (\n <span className=\"truncate font-semibold text-sidebar-foreground\">\n {appName}\n </span>\n ) : null}\n </div>\n );\n}\n\ntype ToggleDef = {\n key: keyof AppShellOptions;\n label: string;\n available: boolean;\n};\n\nexport function AppShell({\n appName,\n appLogo,\n logo,\n navItems: navItemsProp,\n navigation,\n parentNavigation: parentNavigationProp,\n secondaryNavItems,\n secondaryNavLabel = \"More\",\n mobileNavItems,\n headerSlot,\n collapsedHeaderSlot,\n footer,\n userSlot,\n children,\n showThemeToggle: showThemeToggleProp,\n options: optionsProp,\n optionsStorageKey,\n collapsed: collapsedProp,\n onCollapsedChange,\n defaultCollapsed: defaultCollapsedProp,\n subNav: subNavProp,\n subNavLabel,\n linkComponent = DefaultLink,\n activePath,\n isActive = isPathActive,\n}: AppShellProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n\n // Hierarchical nav: resolve the tree against the current location once.\n const derived = useMemo(() => {\n if (!navigation) return undefined;\n const nav = resolveNavigation(navigation, activePath ?? \"/\");\n const atRoot = nav.trail.length === 1;\n const globalItems = fillItems(navigation.items, nav.params);\n const contextualItems = atRoot ? [] : fillItems(nav.items, nav.params);\n // No link up to the root from a top-level page (it is where the global\n // nav already goes), and none whose path the URL couldn't fill.\n const parent =\n nav.parent &&\n nav.trail.length > 2 &&\n !nav.parent.path.split(\"/\").some((p) => PARAM.test(p))\n ? { href: nav.parent.path, label: nav.parent.label }\n : undefined;\n // Nearest node in the trail that states a sidebar default.\n const navDefaultCollapsed = [...nav.trail]\n .reverse()\n .find((node) => node.defaultCollapsed !== undefined)?.defaultCollapsed;\n const navSubNav = [...nav.trail]\n .reverse()\n .find((node) => node.subNav !== undefined)?.subNav;\n // The mobile bar's back item: the logical parent, the root included.\n const navParentPath = nav.parent ? fillParams(nav.parent.path, nav.params) : undefined;\n const backItem =\n nav.parent && navParentPath ? { href: navParentPath, label: nav.parent.label } : undefined;\n return {\n current: nav.current,\n globalItems,\n contextualItems,\n parent,\n navDefaultCollapsed,\n navSubNav,\n backItem,\n };\n }, [navigation, activePath]);\n\n const navItems = navItemsProp ?? derived?.globalItems ?? [];\n const subNavChannel = useSubNavChannel();\n const pageSubNav = subNavChannel.page;\n const hasPageHeader = subNavChannel.hasHeader;\n // The current page's children: the page's own (hook) over the node's items.\n const contextualNavItems = pageSubNav?.items ?? derived?.contextualItems ?? [];\n const parentNavigation =\n parentNavigationProp === undefined ? derived?.parent : parentNavigationProp ?? undefined;\n\n const [userOverrides, setUserOverrides] = useState<Partial<AppShellOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n // Close the drawer on any path change (product switcher, deep links, …).\n useEffect(() => {\n setMobileOpen(false);\n }, [activePath]);\n\n const hasSecondary = Boolean(secondaryNavItems && secondaryNavItems.length);\n const hasUser = userSlot != null;\n const hasFooter = footer != null;\n const hasLogo = Boolean(logo || appLogo);\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions<AppShellOptions>(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions<AppShellOptions>(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const lockedOptions = optionsProp?.lockedOptions;\n\n const resolved = useMemo(() => {\n const merged: AppShellOptions = {\n ...OPTION_DEFAULTS,\n ...(showThemeToggleProp !== undefined\n ? { showThemeToggle: showThemeToggleProp }\n : {}),\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.configurable === undefined) {\n merged.configurable =\n hasSecondary ||\n hasUser ||\n hasFooter ||\n Boolean(merged.showCollapse) ||\n Boolean(merged.showThemeToggle);\n }\n // Locked keys always resolve to the developer default, never a stored\n // or in-session user override.\n if (lockedOptions?.length) {\n const defaults = OPTION_DEFAULTS as Record<string, unknown>;\n const devOptions = optionsProp as Record<string, unknown> | undefined;\n const target = merged as Record<string, unknown>;\n for (const key of lockedOptions) {\n target[key] = devOptions?.[key] ?? defaults[key];\n }\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n showThemeToggleProp,\n hasSecondary,\n hasUser,\n hasFooter,\n lockedOptions,\n ]);\n\n const patchOption = useCallback(\n (key: keyof AppShellOptions, value: boolean) => {\n if (lockedOptions?.includes(key)) return;\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n },\n [lockedOptions],\n );\n\n // Collapse precedence: controlled prop > the user's own choice (stored, or\n // this session's when there is no storage key) > this page's default\n // (prop, then the navigation trail) > the app default > expanded.\n const storedCollapsed = useStoredCollapsed(optionsStorageKey);\n const [sessionCollapsed, setSessionCollapsed] = useState<boolean | undefined>(\n undefined,\n );\n const userCollapsed = optionsStorageKey ? storedCollapsed : sessionCollapsed;\n const pageDefaultCollapsed =\n defaultCollapsedProp ??\n derived?.navDefaultCollapsed ??\n optionsProp?.defaultCollapsed ??\n OPTION_DEFAULTS.defaultCollapsed!;\n\n const isCollapseControlled = collapsedProp !== undefined;\n const collapsed = isCollapseControlled\n ? collapsedProp!\n : (userCollapsed ?? pageDefaultCollapsed);\n\n const setCollapsed = useCallback(\n (next: boolean) => {\n if (!isCollapseControlled) {\n if (optionsStorageKey) writeStoredCollapsed(optionsStorageKey, next);\n else setSessionCollapsed(next);\n }\n onCollapsedChange?.(next);\n },\n [isCollapseControlled, optionsStorageKey, onCollapsedChange],\n );\n\n const sidebarRef = useRef<HTMLElement>(null);\n\n // Collapsing re-renders the sidebar's insides: the toggle moves from the\n // header to the rail's foot, and rail links gain a tooltip wrapper. Both\n // remount, which would drop keyboard focus on <body>. So note what had\n // focus (the toggle, or a link by its href) and put focus back on the\n // matching element once the new layout has committed.\n const pendingFocus = useRef<{ toggle: true } | { href: string } | null>(null);\n const toggleCollapsed = useCallback(\n (fromToggle: boolean) => {\n const aside = sidebarRef.current;\n const focused = typeof document === \"undefined\" ? null : document.activeElement;\n if (fromToggle) {\n pendingFocus.current = { toggle: true };\n } else if (aside && focused instanceof HTMLElement && aside.contains(focused)) {\n const href = focused.getAttribute(\"href\");\n pendingFocus.current = href ? { href } : { toggle: true };\n }\n setCollapsed(!collapsed);\n },\n [collapsed, setCollapsed],\n );\n // A collapse that no toggle asked for (a route's `defaultCollapsed`, a\n // controlled prop): capture what had focus during the render that changes\n // it, before the commit remounts the sidebar's insides.\n const renderedCollapsed = useRef(collapsed);\n if (renderedCollapsed.current !== collapsed && !pendingFocus.current) {\n const aside = sidebarRef.current;\n const focused = typeof document === \"undefined\" ? null : document.activeElement;\n if (aside && focused instanceof HTMLElement && aside.contains(focused)) {\n const href = focused.getAttribute(\"href\");\n pendingFocus.current = href ? { href } : { toggle: true };\n }\n }\n // Runs on every commit, so a request is always consumed in the commit that\n // follows it: a controlled parent that keeps `collapsed` as it was, or a\n // discarded render, can't leave a stale request for a later collapse.\n useIsoLayoutEffect(() => {\n const changed = renderedCollapsed.current !== collapsed;\n renderedCollapsed.current = collapsed;\n const want = pendingFocus.current;\n pendingFocus.current = null;\n const aside = sidebarRef.current;\n if (!changed || !want || !aside) return;\n const toggleEl = aside.querySelector<HTMLElement>('[data-testid=\"app-shell-collapse\"]');\n let target: HTMLElement | null = null;\n if (\"href\" in want) {\n target =\n Array.from(aside.querySelectorAll<HTMLElement>(\"a[href]\")).find(\n (a) => a.getAttribute(\"href\") === want.href,\n ) ?? null;\n }\n (target ?? toggleEl)?.focus();\n });\n const showCollapseCtrl = resolved.showCollapse !== false;\n const collapseShortcut =\n optionsProp?.collapseShortcut ?? OPTION_DEFAULTS.collapseShortcut!;\n\n // Opt-in shortcut (e.g. `[`) toggles the desktop sidebar. Skipped while\n // typing, in a listbox/combobox/menu (typeahead), while a dialog is open,\n // with a modifier held (those chords belong to the app or browser), when\n // another handler already took the key, below the md breakpoint (no\n // desktop sidebar there), and when the collapse control is hidden.\n useEffect(() => {\n if (!collapseShortcut || !showCollapseCtrl) return;\n if (typeof window === \"undefined\") return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== collapseShortcut || e.repeat || e.defaultPrevented) return;\n if (e.ctrlKey || e.metaKey || e.altKey) return;\n if (isTypingTarget(e.target)) return;\n if (ownsKeys(e.target)) return;\n if (dialogOpen()) return;\n if (window.matchMedia && !window.matchMedia(DESKTOP_QUERY).matches) return;\n e.preventDefault();\n toggleCollapsed(false);\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [collapseShortcut, showCollapseCtrl, toggleCollapsed]);\n\n const ParentLink = linkComponent;\n const LinkComp = linkComponent;\n const density = resolved.density ?? \"comfortable\";\n const scrollWindow = resolved.scrollRoot === \"window\";\n const railExpanded =\n resolved.railWidth === \"wide\" ? \"md:w-64\" : \"md:w-52\";\n // Collapsed icon rail: 56px as before, or 64px when asked for.\n const railCollapsed =\n (optionsProp?.collapsedRailWidth ?? OPTION_DEFAULTS.collapsedRailWidth) === 64\n ? \"md:w-16\"\n : \"md:w-14\";\n const railClass = collapsed ? railCollapsed : railExpanded;\n\n // Sub-navigation mode: page (hook) > prop > nearest node > app option.\n const subNavMode: SubNavMode =\n pageSubNav?.mode ??\n subNavProp ??\n derived?.navSubNav ??\n resolved.subNav ??\n OPTION_DEFAULTS.subNav!;\n const subActive = contextualNavItems.some((i) => itemIsActive(i, activePath, isActive));\n\n // \"tabs\" and \"sidebar\" turn sub-navigation on; \"section\" (the default) is\n // the shell as it always was; \"off\" hides the children entirely.\n const subNavOn = subNavMode === \"tabs\" || subNavMode === \"sidebar\";\n\n const leaves = (items: SubNavItem[]) =>\n items.filter((i) => !i.children || i.children.length === 0);\n // Phones. On: a page with children swaps the bar to them, led by a back\n // item to the logical parent. \"section\": the children replace the bar\n // as before, with no back item. \"off\": the app's main bar. An explicit\n // `mobileNavItems` always wins.\n const contextualLeaves = subNavMode === \"off\" ? [] : leaves(contextualNavItems);\n // With sub-navigation on, a page's children win over an app-wide\n // `mobileNavItems` on that page; elsewhere `mobileNavItems` applies.\n const subBottom = subNavOn && contextualLeaves.length > 0;\n const legacyBottom = !subNavOn && !mobileNavItems && contextualLeaves.length > 0;\n const backTarget = subBottom\n ? (parentNavigation ?? derived?.backItem ?? (() => {\n const hostItem = mostSpecificActive(navItems, activePath, isActive);\n return hostItem ? { href: hostItem.to, label: hostItem.label } : undefined;\n })())\n : undefined;\n const bottomItems = (\n subBottom\n ? contextualLeaves\n : (mobileNavItems ?? (legacyBottom ? contextualLeaves : leaves(navItems)))\n ).filter((i) => !i.disabled);\n // Global tabs keep their highlight, but leave `aria-current` to the sub\n // item that is the current page (see SidebarNav).\n const bottomNotCurrent =\n !mobileNavItems && !subBottom && !legacyBottom && subActive;\n const bottomCurrent = subBottom\n ? mostSpecificActive(bottomItems, activePath, isActive)\n : undefined;\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showLogo\", label: \"Logo\", available: hasLogo },\n { key: \"showAppName\", label: \"App name\", available: true },\n {\n key: \"showThemeToggle\",\n label: \"Theme toggle\",\n available: true,\n },\n { key: \"showCollapse\", label: \"Collapse control\", available: true },\n {\n key: \"showSecondaryNav\",\n label: \"Secondary nav\",\n available: hasSecondary,\n },\n { key: \"showFooter\", label: \"Footer\", available: hasFooter },\n { key: \"showUserSlot\", label: \"User block\", available: hasUser },\n {\n key: \"showMobileBottomNav\",\n label: \"Mobile bottom nav\",\n available: bottomItems.length > 0,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available && !lockedOptions?.includes(t.key));\n\n const showTheme = resolved.showThemeToggle !== false;\n const showSecondary = hasSecondary && resolved.showSecondaryNav !== false;\n const showFooterSlot = hasFooter && resolved.showFooter !== false;\n const showUser = hasUser && resolved.showUserSlot !== false;\n const showMobileBottom =\n bottomItems.length > 0 && resolved.showMobileBottomNav !== false;\n const showTabs = subNavMode === \"tabs\" && contextualNavItems.length > 0;\n\n const optionsControl =\n resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Sidebar options\"\n aria-label=\"Sidebar options\"\n data-testid=\"app-shell-options\"\n testID=\"app-shell-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"top\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Sidebar options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this sidebar. Saved on this device when a storage key is\n set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`app-shell-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`app-shell-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey &&\n (Object.keys(userOverrides).length > 0 ||\n storedCollapsed !== undefined) ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => {\n setUserOverrides({});\n // Hand the sidebar back to the page defaults too.\n writeStoredCollapsed(optionsStorageKey, undefined);\n }}\n data-testid=\"app-shell-options-reset\"\n aria-label=\"Reset sidebar options\"\n testID=\"app-shell-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null;\n\n const collapseLabel = collapsed ? \"Expand sidebar\" : \"Collapse sidebar\";\n // Same markup as before this feature (title + aria-pressed); only its\n // place changes on the collapsed rail (the foot instead of the header).\n const collapseToggle = showCollapseCtrl ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => toggleCollapsed(true)}\n title={collapseShortcut ? `${collapseLabel} (${collapseShortcut})` : collapseLabel}\n aria-label={collapseLabel}\n aria-pressed={collapsed}\n aria-keyshortcuts={collapseShortcut || undefined}\n data-testid=\"app-shell-collapse\"\n testID=\"app-shell-collapse\"\n >\n {collapsed ? (\n <PanelLeft className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </Button>\n ) : null;\n\n const sidebarChrome = (opts: { mobile?: boolean }) => (\n <>\n <div\n className={cn(\n \"flex h-14 shrink-0 items-center gap-2 border-b border-sidebar-border\",\n collapsed && !opts.mobile ? \"justify-center px-2\" : \"px-3\",\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <SidebarBrand\n appName={appName}\n appLogo={appLogo}\n logo={logo}\n showLogo={resolved.showLogo !== false}\n showAppName={resolved.showAppName !== false}\n collapsed={collapsed && !opts.mobile}\n />\n </div>\n {opts.mobile ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(false)}\n aria-label=\"Close navigation\"\n data-testid=\"app-shell-mobile-close\"\n testID=\"app-shell-mobile-close\"\n >\n <X className=\"h-5 w-5\" />\n </Button>\n ) : (\n // Expanded: collapse sits beside the logo. Collapsed: the rail's\n // header is the logo mark alone; expand moves to the rail's foot.\n !collapsed ? (\n <div className=\"flex shrink-0 items-center gap-0.5\">\n {collapseToggle}\n {optionsControl}\n </div>\n ) : null\n )}\n </div>\n\n {collapsed && !opts.mobile ? (\n collapsedHeaderSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border p-2\">\n {collapsedHeaderSlot}\n </div>\n ) : null\n ) : headerSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border\">\n {headerSlot}\n </div>\n ) : null}\n\n <SidebarNav\n navItems={navItems}\n contextualNavItems={\n (\n opts.mobile\n ? subNavMode !== \"off\"\n : subNavMode === \"sidebar\" || subNavMode === \"section\"\n )\n ? contextualNavItems\n : undefined\n }\n nest={subNavMode === \"sidebar\" || (opts.mobile && subNavOn)}\n contextualNavLabel={derived?.current.label}\n subActive={subActive}\n secondaryNavItems={secondaryNavItems}\n secondaryNavLabel={secondaryNavLabel}\n showSecondary={showSecondary}\n collapsed={collapsed && !opts.mobile}\n density={density}\n onNavClick={opts.mobile ? () => setMobileOpen(false) : undefined}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n\n {(showFooterSlot ||\n showUser ||\n showTheme ||\n (collapsed && (optionsControl || collapseToggle))) &&\n !opts.mobile ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-2\">\n {showFooterSlot && !collapsed ? footer : null}\n {showUser ? (\n <div\n className={cn(\n collapsed &&\n \"flex justify-center [&_[data-shell-user-detail]]:hidden\",\n )}\n >\n {userSlot}\n </div>\n ) : null}\n <div\n className={cn(\n \"flex items-center gap-1\",\n collapsed ? \"flex-col\" : \"justify-end\",\n )}\n >\n {collapsed ? optionsControl : null}\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-desktop\" />\n ) : null}\n {collapsed ? collapseToggle : null}\n </div>\n </div>\n ) : null}\n\n {opts.mobile && (showFooterSlot || showUser || showTheme) ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-3\">\n {showFooterSlot ? footer : null}\n {showUser ? userSlot : null}\n {showTheme ? (\n <div className=\"flex justify-end\">\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-drawer\" />\n </div>\n ) : null}\n </div>\n ) : null}\n </>\n );\n\n return (\n <div\n className={cn(\n \"flex\",\n scrollWindow ? \"min-h-screen\" : \"h-screen overflow-hidden\",\n )}\n >\n {/* Desktop sidebar */}\n <aside\n className={cn(\n \"hidden flex-col border-r border-sidebar-border bg-sidebar transition-[width] duration-200 motion-reduce:transition-none md:flex\",\n scrollWindow && \"sticky top-0 h-screen\",\n railClass,\n )}\n ref={sidebarRef}\n data-collapsed={collapsed || undefined}\n data-testid=\"app-shell-sidebar\"\n >\n {sidebarChrome({})}\n </aside>\n\n {/* Mobile overlay */}\n {mobileOpen ? (\n <div\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\n onClick={() => setMobileOpen(false)}\n aria-hidden\n />\n ) : null}\n\n {/* Mobile sidebar — inert when closed so off-screen links leave tab order */}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r border-sidebar-border bg-sidebar transition-transform md:hidden\",\n mobileOpen ? \"translate-x-0\" : \"-translate-x-full pointer-events-none\",\n )}\n id=\"app-shell-mobile-nav\"\n aria-hidden={!mobileOpen}\n inert={!mobileOpen || undefined}\n >\n {sidebarChrome({ mobile: true })}\n </aside>\n\n {/* Main content */}\n <div\n className={cn(\n \"flex min-w-0 flex-1 flex-col\",\n !scrollWindow && \"overflow-hidden\",\n )}\n >\n <header\n className={cn(\n \"flex h-14 items-center gap-3 border-b px-4 md:hidden\",\n scrollWindow && \"sticky top-0 z-20 bg-background\",\n )}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(true)}\n aria-label=\"Open navigation\"\n aria-expanded={mobileOpen}\n aria-controls=\"app-shell-mobile-nav\"\n data-testid=\"app-shell-mobile-open\"\n testID=\"app-shell-mobile-open\"\n >\n <Menu className=\"h-5 w-5\" />\n </Button>\n <span className=\"flex-1 truncate font-semibold\">{appName}</span>\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-header\" />\n ) : null}\n </header>\n\n <main\n className={cn(\n \"flex-1\",\n !scrollWindow && \"overflow-y-auto\",\n showMobileBottom ? \"pb-16 md:pb-0\" : \"pb-0\",\n )}\n >\n {parentNavigation ? (\n <div\n className=\"flex min-w-0 items-center px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8\"\n data-testid=\"app-shell-parent-nav\"\n >\n {/* -ml-3 lines the arrow up with the content's left edge. */}\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"-ml-3 min-w-0 max-w-full\"\n testID=\"app-shell-parent-link\"\n >\n <ParentLink\n href={parentNavigation.href}\n aria-label={`Back to ${parentNavigation.label}`}\n >\n <ArrowLeft aria-hidden />\n <span className=\"truncate\">{parentNavigation.label}</span>\n </ParentLink>\n </Button>\n </div>\n ) : null}\n {/* Page header slot (<AppShellPageHeader>): above the tab row, on\n phones too. Empty and unstyled until a page mounts one. */}\n {hasPageHeader ? (\n <div\n ref={subNavChannel.setHeaderSlot}\n className={cn(\n \"min-w-0 px-4 sm:px-6 lg:px-8\",\n parentNavigation ? \"pt-2 sm:pt-3 lg:pt-4\" : \"pt-4 sm:pt-6 lg:pt-8\",\n )}\n data-testid=\"app-shell-page-header\"\n />\n ) : null}\n {showTabs ? (\n <div\n className={cn(\n \"px-4 sm:px-6 lg:px-8\",\n // Phones use the bottom bar, unless the app turned it off.\n showMobileBottom && \"hidden md:block\",\n (!parentNavigation || hasPageHeader) && \"pt-2 sm:pt-3 lg:pt-4\",\n )}\n >\n <SubNavTabs\n items={contextualNavItems}\n activePath={activePath}\n isActive={isActive}\n linkComponent={linkComponent}\n label={subNavLabel ?? derived?.current.label ?? \"Page sections\"}\n end={\n subNavChannel.hasEnd ? (\n <div ref={subNavChannel.setEndSlot} className=\"flex items-center\" />\n ) : undefined\n }\n />\n </div>\n ) : null}\n <div\n className={cn(\n \"min-w-0 p-4 sm:p-6 lg:p-8\",\n (parentNavigation || hasPageHeader) && !showTabs && \"pt-2 sm:pt-3 lg:pt-4\",\n )}\n >\n <SubNavContext.Provider value={subNavChannel.channel}>\n {children}\n </SubNavContext.Provider>\n </div>\n </main>\n\n {showMobileBottom ? (\n <nav\n className=\"fixed bottom-0 left-0 right-0 z-30 flex border-t bg-background md:hidden\"\n aria-label=\"Primary\"\n >\n {backTarget ? (\n <LinkComp\n href={backTarget.href}\n aria-label={`Back to ${backTarget.label}`}\n className=\"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium text-muted-foreground transition-colors\"\n testID=\"app-shell-mobile-back\"\n >\n <ArrowLeft className=\"h-5 w-5\" aria-hidden />\n <span className=\"max-w-full truncate px-0.5\">{backTarget.label}</span>\n </LinkComp>\n ) : null}\n {bottomItems.map((item) => {\n const active = bottomCurrent\n ? item === bottomCurrent\n : itemIsActive(item, activePath, isActive);\n return (\n <LinkComp\n key={item.to + item.label}\n href={item.to}\n title={item.label}\n aria-label={\n subNavOn && item.badge != null\n ? `${item.label} (${item.badge})`\n : item.label\n }\n aria-current={active && !bottomNotCurrent ? \"page\" : undefined}\n className={cn(\n \"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium transition-colors\",\n active ? \"text-primary\" : \"text-muted-foreground\",\n )}\n >\n {subNavOn && item.badge != null ? (\n <span className=\"relative\">\n <NavIcon item={item} className=\"h-5 w-5\" />\n {/* Anchored to the icon's right edge and growing right,\n so a word badge (\"New\") never covers the icon. */}\n <span\n className=\"absolute -top-1.5 left-full -ml-1 inline-flex h-4 min-w-4 items-center justify-center whitespace-nowrap rounded-full bg-primary px-1 text-[10px] font-semibold leading-none text-primary-foreground ring-2 ring-background\"\n aria-hidden\n >\n {item.badge}\n </span>\n </span>\n ) : (\n <NavIcon item={item} className=\"h-5 w-5\" />\n )}\n <span className=\"max-w-full truncate px-0.5\">\n {item.label}\n </span>\n </LinkComp>\n );\n })}\n </nav>\n ) : null}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/option-storage.ts","../src/components/layout/PageHeader.tsx","../src/components/layout/sub-nav.tsx","../src/components/layout/AppShell.tsx"],"names":["readStoredOptions","useEffect","jsx","jsxs","Fragment","useState","useCallback","useMemo","useId","OPTION_DEFAULTS","useIsoLayoutEffect","useLayoutEffect","useRef","SlidersHorizontal"],"mappings":"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","file":"chunk-5OFA2CQR.js","sourcesContent":["/**\n * Generic localStorage-backed persistence for \"customize chrome\" option\n * objects (AppShell, PageHeader, …). SSR-safe (no-ops without `window`) and\n * swallows quota / private-mode errors so a storage failure never breaks\n * rendering.\n *\n * Callers own their own shape validation — this module only handles the\n * JSON <-> localStorage plumbing shared across chrome components.\n */\nexport function readStoredOptions<T extends object>(key: string): Partial<T> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as Partial<T>;\n } catch {\n return {};\n }\n}\n\nexport function writeStoredOptions<T extends object>(\n key: string,\n value: Partial<T>,\n): void {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota / private mode\n }\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useState, type ReactNode } from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { ListFilter, MoreHorizontal, SlidersHorizontal } from \"lucide-react\";\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Switch } from \"../ui/switch\";\nimport { Label } from \"../ui/label\";\nimport { ViewToggle, type ViewMode } from \"../patterns/view-toggle\";\nimport { ViewSettings } from \"../patterns/view-settings\";\nimport type { Density } from \"../../hooks/use-view-settings\";\nimport { cn } from \"../../utils\";\nimport {\n readStoredOptions as readStoredOptionsRaw,\n writeStoredOptions,\n} from \"../../option-storage\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\n\n/**\n * Declarative chrome for PageHeader — developer defaults + optional\n * in-header user toggles (Notion/Linear “customize view” pattern).\n *\n * @stability Beta\n */\nexport interface PageHeaderOptions {\n /**\n * The icon, title and subtitle block. Turn it off where the surrounding\n * page already names the content (a list inside a tab), keeping only the\n * actions row: count, view toggle, filters, create. Default true. A\n * developer setting, not offered in the user's Header options.\n */\n showTitle?: boolean;\n showIcon?: boolean;\n showSubtitle?: boolean;\n showCount?: boolean;\n showViewToggle?: boolean;\n showViewSettings?: boolean;\n showCreate?: boolean;\n /**\n * Stat cards row under the title block. Off by default — a header that\n * receives `stats` still hides them until the developer or the user turns\n * this on, so an existing page gains no new chrome by upgrading.\n */\n showStats?: boolean;\n /** Ghost ListFilter control in the actions cluster */\n showDetailsToggle?: boolean;\n /** Quiet hint beside actions while details are collapsed */\n showDetailsHint?: boolean;\n /** Move subtitle into the details panel (default true when details exist) */\n subtitleInDetails?: boolean;\n defaultDetailsOpen?: boolean;\n detailsLabel?: string;\n /**\n * Show the in-header Header options popover so users can customize chrome.\n * Default true when the header has more than one chrome affordance.\n */\n configurable?: boolean;\n}\n\n/** @stability Beta */\nexport type PageHeaderOptionKey = keyof PageHeaderOptions;\n\n/** Naive English pluralization for the count badge — singular at exactly 1. */\nfunction pluralizeEntity(entity: string, count: number): string {\n if (count === 1) return entity;\n return entity.endsWith(\"s\") ? entity : `${entity}s`;\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\">\n> &\n Pick<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\"> = {\n showTitle: true,\n showIcon: true,\n showSubtitle: true,\n showCount: true,\n showViewToggle: true,\n showViewSettings: true,\n showCreate: true,\n showStats: false,\n showDetailsToggle: true,\n showDetailsHint: true,\n subtitleInDetails: undefined,\n defaultDetailsOpen: false,\n detailsLabel: \"Details\",\n configurable: undefined,\n};\n\n// `showTitle` is left out on purpose: it is a developer setting, so a stored\n// user override must never hide the title.\nconst BOOLEAN_OPTION_KEYS: PageHeaderOptionKey[] = [\n \"showIcon\",\n \"showSubtitle\",\n \"showCount\",\n \"showViewToggle\",\n \"showViewSettings\",\n \"showCreate\",\n \"showStats\",\n \"showDetailsToggle\",\n \"showDetailsHint\",\n \"subtitleInDetails\",\n \"defaultDetailsOpen\",\n \"configurable\",\n];\nconst STRING_OPTION_KEYS: PageHeaderOptionKey[] = [\"detailsLabel\"];\n\n/**\n * Reads persisted options and keeps only known keys whose stored value has\n * the expected primitive type — a malformed or hand-edited localStorage\n * value can't smuggle in an unexpected key or wrong-typed override.\n */\nfunction readStoredOptions(key: string): Partial<PageHeaderOptions> {\n const raw = readStoredOptionsRaw<PageHeaderOptions>(key);\n const sanitized: Partial<PageHeaderOptions> = {};\n for (const optKey of BOOLEAN_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"boolean\") {\n (sanitized as Record<string, boolean>)[optKey] = value;\n }\n }\n for (const optKey of STRING_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"string\") {\n (sanitized as Record<string, string>)[optKey] = value;\n }\n }\n return sanitized;\n}\n\n/** One entry in {@link PageHeaderProps.secondaryActions}. */\nexport interface PageHeaderAction {\n label: string;\n onClick: () => void;\n icon?: LucideIcon;\n /** `data-testid` on the menu item, so e2e can drive it. */\n testId?: string;\n disabled?: boolean;\n /** Omits the action entirely — for one gated on data. */\n hidden?: boolean;\n}\n\nexport interface PageHeaderProps {\n title: string;\n subtitle?: string;\n icon?: LucideIcon;\n /**\n * Header chrome config (developer defaults). Merged under user picks from\n * the in-header options menu when `options.configurable` / storage is on.\n */\n options?: PageHeaderOptions;\n /** Persist user header-option overrides (localStorage) */\n optionsStorageKey?: string;\n /** Extra trailing actions (after create); prefer first-class slots below */\n actions?: ReactNode;\n /**\n * Stat cards row, full width, directly under the title block and above\n * `details`. Layout-only: pass `<StatCard>`s (or anything else) and the\n * header positions them. Rendered only when `options.showStats` resolves\n * true — see {@link PageHeaderOptions.showStats}.\n */\n stats?: ReactNode;\n /** Collapsible details region below the title row */\n details?: ReactNode;\n detailsOpen?: boolean;\n onDetailsOpenChange?: (open: boolean) => void;\n detailsActive?: boolean;\n detailsHint?: ReactNode;\n /** Count badge */\n count?: number;\n totalCount?: number;\n /** Singular entity for “N rows” copy when unfiltered */\n entityName?: string;\n countActive?: boolean;\n viewMode?: ViewMode;\n onViewModeChange?: (mode: ViewMode) => void;\n pageSize?: number;\n onPageSizeChange?: (size: number) => void;\n density?: Density;\n onDensityChange?: (density: Density) => void;\n createAction?: ReactNode;\n /**\n * Additional actions, rendered in ONE overflow menu — never as more\n * side-by-side buttons.\n *\n * The budget is the point. A header with three top-level buttons squeezes\n * its own title to an ellipsis at real viewport widths, so a surface that\n * genuinely has four actions needs somewhere to put the other three. Before\n * this existed the only place was a fork of the header, which is exactly\n * what one consumer did.\n *\n * Pass `ReactNode` via `actions` instead when you need arbitrary chrome;\n * this prop is for the ordinary case, and it keeps the budget for you.\n */\n secondaryActions?: PageHeaderAction[];\n}\n\ntype ToggleDef = {\n key: keyof PageHeaderOptions;\n label: string;\n available: boolean;\n};\n\nexport function PageHeader({\n title,\n subtitle,\n icon: Icon,\n options: optionsProp,\n optionsStorageKey,\n actions,\n stats,\n details,\n detailsOpen,\n onDetailsOpenChange,\n detailsActive = false,\n detailsHint,\n count,\n totalCount,\n entityName,\n countActive = false,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n createAction,\n secondaryActions,\n}: PageHeaderProps) {\n const detailsRegionId = useId();\n const hasDetails = details != null;\n const hasStats = stats != null;\n const hasCount = count !== undefined && totalCount !== undefined;\n const hasViewToggle = Boolean(viewMode && onViewModeChange);\n const hasViewSettings = Boolean(onPageSizeChange && onDensityChange);\n const hasCreate = createAction != null;\n // `hidden` is filtered here rather than at the call site: an action gated on\n // data (\"Review drafts\", only when drafts exist) is the common case, and a\n // conditional array at every call site is what makes those call sites drift.\n const visibleSecondary = (secondaryActions ?? []).filter((a) => !a.hidden);\n\n const [userOverrides, setUserOverrides] = useState<Partial<PageHeaderOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change (routing between pages with distinct keys while this header\n // stays mounted) can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const resolved = useMemo(() => {\n const merged: PageHeaderOptions = {\n ...OPTION_DEFAULTS,\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.subtitleInDetails === undefined) {\n merged.subtitleInDetails = hasDetails;\n }\n if (merged.configurable === undefined) {\n merged.configurable =\n hasDetails || hasStats || hasCount || hasViewSettings || hasViewToggle;\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n hasDetails,\n hasStats,\n hasCount,\n hasViewSettings,\n hasViewToggle,\n ]);\n\n const patchOption = useCallback((key: keyof PageHeaderOptions, value: boolean) => {\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n const moveSubtitle = Boolean(resolved.subtitleInDetails) && hasDetails;\n const showTitleSubtitle =\n Boolean(subtitle) &&\n Boolean(resolved.showSubtitle) &&\n !moveSubtitle;\n\n const [uncontrolledOpen, setUncontrolledOpen] = useState(\n () => optionsProp?.defaultDetailsOpen ?? OPTION_DEFAULTS.defaultDetailsOpen!,\n );\n const isControlled = detailsOpen !== undefined;\n const open = isControlled ? detailsOpen! : uncontrolledOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onDetailsOpenChange?.(next);\n };\n\n const detailsLabel = resolved.detailsLabel ?? \"Details\";\n const entity = entityName || \"item\";\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showIcon\", label: \"Icon\", available: Boolean(Icon) },\n {\n key: \"showSubtitle\",\n label: \"Subtitle\",\n available: Boolean(subtitle) && !moveSubtitle,\n },\n { key: \"showCount\", label: \"Count\", available: hasCount },\n { key: \"showViewToggle\", label: \"View toggle\", available: hasViewToggle },\n {\n key: \"showViewSettings\",\n label: \"Display settings\",\n available: hasViewSettings,\n },\n { key: \"showCreate\", label: \"Create action\", available: hasCreate },\n { key: \"showStats\", label: \"Stat cards\", available: hasStats },\n {\n key: \"showDetailsToggle\",\n label: \"Filters / details\",\n available: hasDetails,\n },\n {\n key: \"showDetailsHint\",\n label: \"Collapsed hint\",\n available: hasDetails && detailsHint != null,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available);\n\n const showDetailsToggle =\n hasDetails && Boolean(resolved.showDetailsToggle);\n const showStats = hasStats && Boolean(resolved.showStats);\n const showHint =\n hasDetails &&\n !open &&\n Boolean(resolved.showDetailsHint) &&\n detailsHint != null;\n\n const actionsCluster = (\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {showHint ? (\n <span className=\"hidden max-w-[14rem] truncate text-xs text-muted-foreground sm:inline\">\n {detailsHint}\n </span>\n ) : null}\n\n {hasCount && resolved.showCount !== false ? (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {countActive\n ? `${count} of ${totalCount}`\n : `${totalCount} ${pluralizeEntity(entity, totalCount!)}`}\n </Badge>\n ) : null}\n\n {hasViewToggle && resolved.showViewToggle !== false ? (\n <ViewToggle viewMode={viewMode!} onViewModeChange={onViewModeChange!} />\n ) : null}\n\n {showDetailsToggle ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n \"relative h-8 w-8\",\n (open || detailsActive) && \"bg-accent text-accent-foreground\",\n )}\n onClick={() => setOpen(!open)}\n data-testid=\"page-header-details-toggle\"\n title={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-label={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-expanded={open}\n aria-controls={detailsRegionId}\n testID=\"page-header-details-toggle\"\n >\n <ListFilter className=\"h-4 w-4\" />\n {detailsActive ? (\n <span\n className=\"absolute right-1.5 top-1.5 size-1.5 rounded-full bg-primary\"\n aria-hidden\n />\n ) : null}\n </Button>\n ) : null}\n\n {hasViewSettings && resolved.showViewSettings !== false ? (\n <ViewSettings\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange!}\n density={density ?? \"comfortable\"}\n onDensityChange={onDensityChange!}\n />\n ) : null}\n\n {hasCreate && resolved.showCreate !== false ? createAction : null}\n\n {visibleSecondary.length > 0 ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"More actions\"\n data-testid=\"page-header-more-actions\"\n >\n <MoreHorizontal className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {visibleSecondary.map((action) => {\n const ActionIcon = action.icon;\n return (\n <DropdownMenuItem\n key={action.label}\n onSelect={action.onClick}\n disabled={action.disabled}\n data-testid={action.testId}\n >\n {ActionIcon ? (\n <ActionIcon className=\"mr-2 h-4 w-4\" aria-hidden=\"true\" />\n ) : null}\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n\n {actions}\n\n {resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Header options\"\n aria-label=\"Header options\"\n data-testid=\"page-header-options\"\n testID=\"page-header-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Header options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this page header. Saved on this device when a storage\n key is set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`page-header-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`page-header-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey && Object.keys(userOverrides).length > 0 ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => setUserOverrides({})}\n data-testid=\"page-header-options-reset\"\n aria-label=\"Reset header options\"\n testID=\"page-header-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null}\n </div>\n );\n\n const titleRow = resolved.showTitle === false ? (\n <div\n data-testid=\"page-header-toolbar\"\n className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\"\n >\n {actionsCluster}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3 min-w-0\">\n {Icon && resolved.showIcon !== false ? (\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-primary/10\">\n <Icon className=\"h-5 w-5 text-primary\" />\n </div>\n ) : null}\n <div className=\"min-w-0\">\n <h1\n data-testid=\"page-title\"\n className=\"truncate font-display text-xl font-bold tracking-tight sm:text-2xl\"\n >\n {title}\n </h1>\n {showTitleSubtitle ? (\n <p className=\"truncate text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n </div>\n {actionsCluster}\n </div>\n );\n\n const statsRow = showStats ? (\n <div\n data-testid=\"page-header-stats\"\n className=\"mt-3 grid gap-3 sm:grid-cols-2 lg:grid-cols-4\"\n >\n {stats}\n </div>\n ) : null;\n\n if (!hasDetails) {\n return (\n <>\n {titleRow}\n {statsRow}\n </>\n );\n }\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n {titleRow}\n {statsRow}\n <CollapsibleContent id={detailsRegionId} className=\"mt-3\">\n <div className=\"flex flex-col gap-3 rounded-lg border border-border bg-card/40 p-3 sm:p-4\">\n {moveSubtitle && subtitle && resolved.showSubtitle !== false ? (\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n {details}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n","\"use client\";\n\n/**\n * Shell sub-navigation: the child items of the page you are on (a form's\n * Questions / Logic and endings / Responses / Settings), shown by AppShell\n * as a tab row, nested in the sidebar, or not at all (`SubNavMode`), and in\n * the mobile bottom bar whatever the mode.\n *\n * Children come from two places:\n * - statically, the current `NavigationNode`'s `items` (with `$param`s filled\n * from the URL), the same contextual items AppShell has always derived;\n * - dynamically, from the page: `useAppShellSubNav(items)` replaces them\n * while the page is mounted, so badges can carry live counts.\n *\n * Role gating works as for every other `NavItem`: filter the list before\n * handing it over (the tree's `items` or the hook's argument).\n */\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { LucideIcon } from \"lucide-react\";\n\nimport { cn } from \"../../utils\";\nimport { isPathActive, type LinkComponent } from \"../../navigation\";\nimport type { NavItem } from \"./AppShell\";\n\n/**\n * How AppShell shows the current page's child items. Sub-navigation is\n * opt-in: the default, `section`, is the shell as it always was.\n * - `section` (default): a labelled section below the global sidebar\n * items; on phones the children replace the bottom bar (no back item).\n * - `tabs`: one row of tabs across the top of the page content.\n * - `sidebar`: nested under the active item in the sidebar; a flyout from\n * that item on the collapsed rail.\n * - `off`: nothing, on desktop or phones; the app draws its own\n * (`SubNavTabs` is exported for it).\n *\n * With `tabs` or `sidebar`, phones switch the bottom bar to a back item to\n * the logical parent plus the children, with their badges.\n *\n * @stability Beta\n */\nexport type SubNavMode = \"section\" | \"tabs\" | \"sidebar\" | \"off\";\n\n/**\n * A sub-navigation item: a `NavItem` whose `icon` is optional (the tab row,\n * the phone bar and the rail show the label's first letter without one).\n * Every `NavItem` is a `SubNavItem`; `NavItem` itself keeps `icon` required.\n *\n * @stability Beta\n */\nexport interface SubNavItem extends Omit<NavItem, \"icon\" | \"children\"> {\n icon?: LucideIcon;\n children?: SubNavItem[];\n}\n\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** @internal Active-state rule shared by the sidebar, tabs and bottom bar. */\nexport function itemIsActive(\n item: SubNavItem,\n activePath: string | undefined,\n isActive: (to: string, activePath?: string) => boolean,\n): boolean {\n // `end` is exact on the path but ignores an incidental query/hash, so an\n // `end` item stays active on `/dashboard?page=2`.\n if (item.end) {\n return isPathActive(item.to, activePath, { end: true });\n }\n if (isActive(item.to, activePath)) return true;\n return Boolean(\n item.children?.some((child) => itemIsActive(child, activePath, isActive)),\n );\n}\n\n/**\n * Of several matching items, the one whose path matches most specifically,\n * so `/forms/f1/edit/logic` doesn't also light up an `/forms/f1/edit`\n * Questions tab that isn't marked `end`.\n *\n * @internal\n */\nexport function mostSpecificActive(\n items: SubNavItem[],\n activePath: string | undefined,\n isActive: (to: string, activePath?: string) => boolean,\n): SubNavItem | undefined {\n let best: SubNavItem | undefined;\n for (const item of items) {\n if (!itemIsActive(item, activePath, isActive)) continue;\n if (!best || item.to.length > best.to.length) best = item;\n }\n return best;\n}\n\nfunction BadgeChip({ badge, active }: { badge: string | number; active?: boolean }) {\n return (\n <span\n className={cn(\n \"inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-medium tabular-nums\",\n active ? \"bg-primary/10 text-primary\" : \"bg-muted text-muted-foreground\",\n )}\n >\n {badge}\n </span>\n );\n}\n\n/**\n * Props for {@link SubNavTabs}.\n *\n * @stability Beta\n */\nexport interface SubNavTabsProps {\n items: SubNavItem[];\n /** Current location (`pathname + search + hash`); drives the active tab. */\n activePath?: string;\n linkComponent: LinkComponent;\n isActive?: (to: string, activePath?: string) => boolean;\n /** Right-aligned slot in the row, e.g. a \"Ready to publish\" chip. */\n end?: ReactNode;\n /** Accessible name of the `<nav>` (default \"Page sections\"). */\n label?: string;\n className?: string;\n}\n\n/**\n * A row of navigation tabs: real links (deep links and middle-click work),\n * `aria-current=\"page\"` on the active one, badges as chips, the active tab\n * underlined in the brand colour. AppShell renders it in `tabs` mode; an app\n * using `subNav: \"off\"` can place it itself.\n *\n * @stability Beta\n */\nexport function SubNavTabs({\n items,\n activePath,\n linkComponent: LinkComp,\n isActive = isPathActive,\n end,\n label = \"Page sections\",\n className,\n}: SubNavTabsProps) {\n const current = mostSpecificActive(items, activePath, isActive);\n return (\n <div\n className={cn(\"flex min-w-0 items-end gap-4 border-b\", className)}\n data-testid=\"app-shell-sub-nav\"\n >\n <nav aria-label={label} className=\"-mb-px min-w-0 flex-1 overflow-x-auto\">\n <ul className=\"flex items-end gap-6\">\n {items.map((item) => {\n const active = item === current;\n const Icon = item.icon;\n const body = (\n <>\n {Icon ? <Icon className=\"h-4 w-4 shrink-0\" aria-hidden /> : null}\n <span className=\"whitespace-nowrap\">{item.label}</span>\n {item.badge != null ? <BadgeChip badge={item.badge} active={active} /> : null}\n </>\n );\n const cls = cn(\n \"flex items-center gap-1.5 border-b-2 pb-2.5 pt-2 text-sm transition-colors motion-reduce:transition-none\",\n active\n ? \"border-primary font-semibold text-foreground\"\n : \"border-transparent text-muted-foreground hover:text-foreground\",\n );\n return (\n <li key={item.to + item.label} className=\"shrink-0\">\n {item.disabled ? (\n <span className={cn(cls, \"opacity-40\")} role=\"link\" aria-disabled=\"true\">\n {body}\n </span>\n ) : (\n <LinkComp\n href={item.to}\n aria-current={active ? \"page\" : undefined}\n className={cn(\n cls,\n \"rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n )}\n testID={`app-shell-sub-nav-${item.label}`}\n >\n {body}\n </LinkComp>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n {end != null ? <div className=\"flex shrink-0 items-center pb-2\">{end}</div> : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Page → shell channel\n// ---------------------------------------------------------------------------\n\ninterface PageSubNav {\n /** Absent: this registrant only sets a mode; items come from elsewhere. */\n items?: SubNavItem[];\n mode?: SubNavMode;\n}\n\ninterface Registration extends PageSubNav {\n id: string;\n /**\n * Render order of the registering component, taken at its first render.\n * React renders top-down, so a page inside a layout always gets a higher\n * number than that layout, and a page mounted later (a route change under\n * a mounted layout) does too: the highest number is the innermost caller.\n */\n order: number;\n}\n\n/** Portal slots the shell exposes to pages. */\ntype SlotName = \"header\" | \"end\";\n\n/** @internal What AppShell provides to pages. */\nexport interface SubNavChannel {\n register(id: string, order: number, value: PageSubNav): void;\n unregister(id: string): void;\n /** Claim a portal slot; the innermost claimant (highest order) renders. */\n claimSlot(slot: SlotName, id: string, order: number): void;\n releaseSlot(slot: SlotName, id: string): void;\n /** The mounted slot elements, and which claimant owns each. */\n slots: Record<SlotName, { el: HTMLElement | null; owner: string | undefined }>;\n}\n\n/** @internal */\nexport const SubNavContext = createContext<SubNavChannel | null>(null);\n\ntype Claims = Record<SlotName, Array<{ id: string; order: number }>>;\n\nfunction innermost(claims: Array<{ id: string; order: number }>): string | undefined {\n let best: { id: string; order: number } | undefined;\n for (const c of claims) if (!best || c.order > best.order) best = c;\n return best?.id;\n}\n\n/**\n * @internal Shell side: holds the page registrations and slot claims.\n * Registration runs in a layout effect, so the page's items are in place\n * before first paint.\n */\nexport function useSubNavChannel(): {\n page: PageSubNav | undefined;\n channel: SubNavChannel;\n setEndSlot: (el: HTMLElement | null) => void;\n setHeaderSlot: (el: HTMLElement | null) => void;\n /** A page header has been claimed (render the header region). */\n hasHeader: boolean;\n /** An end-slot chip has been claimed (render the row's end region). */\n hasEnd: boolean;\n} {\n const [entries, setEntries] = useState<Registration[]>([]);\n const [endSlot, setEndSlot] = useState<HTMLElement | null>(null);\n const [headerSlot, setHeaderSlot] = useState<HTMLElement | null>(null);\n const [claims, setClaims] = useState<Claims>({ header: [], end: [] });\n\n // Updated in place, so a badge change never reorders registrants.\n const register = useCallback((id: string, order: number, value: PageSubNav) => {\n setEntries((prev) =>\n prev.some((e) => e.id === id)\n ? prev.map((e) => (e.id === id ? { ...value, id, order } : e))\n : [...prev, { ...value, id, order }],\n );\n }, []);\n const unregister = useCallback((id: string) => {\n setEntries((prev) => prev.filter((e) => e.id !== id));\n }, []);\n const claimSlot = useCallback((slot: SlotName, id: string, order: number) => {\n setClaims((prev) =>\n prev[slot].some((c) => c.id === id)\n ? prev\n : { ...prev, [slot]: [...prev[slot], { id, order }] },\n );\n }, []);\n const releaseSlot = useCallback((slot: SlotName, id: string) => {\n setClaims((prev) =>\n prev[slot].some((c) => c.id === id)\n ? { ...prev, [slot]: prev[slot].filter((c) => c.id !== id) }\n : prev,\n );\n }, []);\n\n const headerOwner = innermost(claims.header);\n const endOwner = innermost(claims.end);\n const channel = useMemo<SubNavChannel>(\n () => ({\n register,\n unregister,\n claimSlot,\n releaseSlot,\n slots: {\n header: { el: headerSlot, owner: headerOwner },\n end: { el: endSlot, owner: endOwner },\n },\n }),\n [register, unregister, claimSlot, releaseSlot, headerSlot, headerOwner, endSlot, endOwner],\n );\n\n // Innermost registrant wins, separately for items and for mode, so a page\n // that only sets a mode keeps a layout's items (and vice versa).\n const byDepth = [...entries].sort((a, b) => b.order - a.order);\n const items = byDepth.find((e) => e.items)?.items;\n const mode = byDepth.find((e) => e.mode)?.mode;\n return {\n page: items || mode ? { items, mode } : undefined,\n channel,\n setEndSlot,\n setHeaderSlot,\n hasHeader: headerOwner !== undefined,\n hasEnd: endOwner !== undefined,\n };\n}\n\nlet nextOrder = 0;\n\nconst iconIds = new WeakMap<object, number>();\nlet nextIconId = 1;\nfunction iconKey(icon: unknown): number {\n if (!icon || (typeof icon !== \"object\" && typeof icon !== \"function\")) return 0;\n let id = iconIds.get(icon as object);\n if (id == null) {\n id = nextIconId++;\n iconIds.set(icon as object, id);\n }\n return id;\n}\n\nfunction itemsKey(items: SubNavItem[]): string {\n return JSON.stringify(\n items.map((i) => [\n i.to,\n i.label,\n i.badge ?? null,\n Boolean(i.disabled),\n Boolean(i.end),\n iconKey(i.icon),\n i.children ? itemsKey(i.children) : null,\n ]),\n );\n}\n\n/**\n * Options for {@link useAppShellSubNav}.\n *\n * @stability Beta\n */\nexport interface UseAppShellSubNavOptions {\n /** This page's `subNav` mode; wins over the shell's and the node's. */\n mode?: SubNavMode;\n}\n\n/**\n * Give the shell this page's child items (sub-navigation) while the page is\n * mounted. They replace the current `NavigationNode`'s `items`; pass\n * `null` / `undefined` to fall back to them (a `mode` still applies). When\n * several components call it (a layout and its page), the innermost wins,\n * for items and for mode separately. Use it when children depend on\n * page data, such as live badge counts. A fresh array each render is fine:\n * the shell only updates when a `to`, label, badge, icon or flag changes.\n *\n * ```tsx\n * useAppShellSubNav([\n * { to: `/forms/${id}/edit`, label: \"Questions\", icon: ListChecks, badge: questions.length, end: true },\n * { to: `/forms/${id}/edit/logic`, label: \"Logic and endings\", icon: GitBranch, badge: rules.length },\n * { to: `/forms/${id}/edit/responses`, label: \"Responses\", icon: Inbox, badge: responses },\n * { to: `/forms/${id}/edit/settings`, label: \"Settings\", icon: Settings },\n * ]);\n * ```\n *\n * Does nothing outside an `AppShell`.\n *\n * @stability Beta\n */\nexport function useAppShellSubNav(\n items: SubNavItem[] | null | undefined,\n options?: UseAppShellSubNavOptions,\n): void {\n const channel = useContext(SubNavContext);\n const id = useId();\n const [order] = useState(() => ++nextOrder);\n const latest = useRef(items);\n latest.current = items;\n const key = items ? itemsKey(items) : \"\";\n const mode = options?.mode;\n const register = channel?.register;\n const unregister = channel?.unregister;\n\n useIsoLayoutEffect(() => {\n if (!register || !unregister) return;\n const value = latest.current ?? undefined;\n // `null` items with a mode still register: the mode applies, and the\n // items fall back to an outer registrant or the node's.\n if (value || mode) register(id, order, { items: value, mode });\n else unregister(id);\n }, [register, unregister, id, order, key, mode]);\n\n useIsoLayoutEffect(() => {\n if (!unregister) return;\n return () => unregister(id);\n }, [unregister, id]);\n}\n\nfunction useSlotPortal(slot: SlotName, children: ReactNode): ReactNode {\n const channel = useContext(SubNavContext);\n const id = useId();\n const [order] = useState(() => ++nextOrder);\n const claimSlot = channel?.claimSlot;\n const releaseSlot = channel?.releaseSlot;\n useIsoLayoutEffect(() => {\n if (!claimSlot || !releaseSlot) return;\n claimSlot(slot, id, order);\n return () => releaseSlot(slot, id);\n }, [claimSlot, releaseSlot, slot, id, order]);\n const target = channel?.slots[slot];\n if (!target?.el || target.owner !== id) return null;\n return createPortal(children, target.el);\n}\n\n/**\n * Render `children` in the right-hand slot of the shell's sub-navigation\n * tab row, e.g. a \"Ready to publish\" status chip. Rendered through a\n * portal, so it keeps the page's context and state. Renders nothing when\n * the shell shows no tab row (other modes, phones, no children). When\n * several are mounted (a layout's and a page's), the innermost renders.\n *\n * @stability Beta\n */\nexport function AppShellSubNavEnd({ children }: { children: ReactNode }) {\n return useSlotPortal(\"end\", children);\n}\n\n/**\n * Render the page's resource header (breadcrumb, title, status, actions) at\n * the top of the shell's content, ABOVE the sub-navigation tab row, where\n * the design puts it. A portal like `AppShellSubNavEnd`, so it keeps the\n * page's state; the innermost mounted one renders. On phones it stays at\n * the top of the content while the bottom bar carries the children. With\n * no tab row (the default `\"section\"` mode, or a page without children) it\n * simply sits at the top of the content. Mount none and the layout is\n * unchanged.\n *\n * @stability Beta\n */\nexport function AppShellPageHeader({ children }: { children: ReactNode }) {\n return useSlotPortal(\"header\", children);\n}\n","\"use client\";\n\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n Menu,\n X,\n Sun,\n Moon,\n SlidersHorizontal,\n PanelLeftClose,\n PanelLeft,\n ChevronDown,\n ChevronRight,\n ArrowLeft,\n} from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { Badge } from \"../ui/badge\";\nimport { Label } from \"../ui/label\";\nimport { Switch } from \"../ui/switch\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport { Tooltip } from \"../ui/tooltip\";\nimport {\n itemIsActive,\n mostSpecificActive,\n SubNavContext,\n SubNavTabs,\n useSubNavChannel,\n type SubNavItem,\n type SubNavMode,\n} from \"./sub-nav\";\nimport { cn } from \"../../utils\";\nimport { readStoredOptions, writeStoredOptions } from \"../../option-storage\";\nimport {\n DefaultLink,\n isPathActive,\n resolveNavigation,\n type LinkComponent,\n type NavigationNode,\n} from \"../../navigation\";\n\nexport interface NavItem {\n /** Route, optionally with `?search` / `#hash` (see `isPathActive`). */\n to: string;\n icon: LucideIcon;\n label: string;\n /** Nested items — rendered as a collapsible group when the rail is expanded */\n children?: NavItem[];\n /**\n * A count (`3`) or a short status (`\"New\"`), shown as a chip: in the\n * sidebar, the sub-navigation tabs and the mobile bar; as a dot on the\n * collapsed rail. It is part of the item's accessible name where the label\n * is hidden.\n */\n badge?: string | number;\n disabled?: boolean;\n /**\n * Exact-match active state (e.g. overview `/`). Exact on the path only, so\n * an `activePath` carrying `?search#hash` still matches.\n */\n end?: boolean;\n}\n\n/**\n * The \"up\" link AppShell renders above page content: a real link to the\n * logical parent, never `history.back()`.\n *\n * @stability Beta\n */\nexport interface ParentNavigation {\n href: string;\n label: string;\n}\n\n/**\n * Declarative chrome for AppShell — developer defaults + optional\n * in-sidebar user toggles (Notion/Linear “customize chrome” pattern).\n *\n * @stability Beta\n */\nexport interface AppShellOptions {\n showLogo?: boolean;\n showAppName?: boolean;\n showThemeToggle?: boolean;\n /** Desktop rail collapse control */\n showCollapse?: boolean;\n showUserSlot?: boolean;\n showFooter?: boolean;\n showSecondaryNav?: boolean;\n /** Mobile fixed bottom tab bar */\n showMobileBottomNav?: boolean;\n /**\n * Open the desktop sidebar collapsed (an icon rail, `collapsedRailWidth` wide) when the user hasn't\n * chosen. The app-wide default; a page asks for its own through\n * `AppShellProps.defaultCollapsed` or `NavigationNode.defaultCollapsed`.\n */\n defaultCollapsed?: boolean;\n /**\n * Opt-in key that toggles the desktop sidebar, e.g. `\"[\"` as in Linear and\n * Notion. Off (`false`) by default. It never fires while typing in a field,\n * while a listbox, combobox or menu has focus (Select typeahead), while a\n * dialog is open, with Ctrl/Cmd/Alt held, or when `showCollapse` is off.\n */\n collapseShortcut?: string | false;\n /**\n * Width of the collapsed icon rail in px: `56` (default, as before) or\n * `64` (a wider rail some apps use).\n */\n collapsedRailWidth?: 56 | 64;\n /**\n * Shell sub-navigation, opt-in. `\"section\"` (default) renders a page's\n * children exactly as AppShell always has; `\"tabs\"` or `\"sidebar\"` turn\n * sub-navigation on (see `SubNavMode`), and `\"off\"` hides them. A\n * navigation node, the `subNav` prop or the page\n * (`useAppShellSubNav(items, { mode })`) can override it.\n */\n subNav?: SubNavMode;\n /**\n * Show the in-sidebar Sidebar options popover so users can customize chrome.\n * Default true when collapse / secondary / theme / slots are available.\n */\n configurable?: boolean;\n /**\n * Toggle keys the developer has decided on and users may not override —\n * e.g. hiding `showThemeToggle` for a brand that manages theme elsewhere.\n * Locked keys are dropped from the options popover and any stored user\n * override for them is ignored on resolve.\n */\n lockedOptions?: (keyof AppShellOptions)[];\n /** Comfortable (default) vs compact row padding */\n density?: \"comfortable\" | \"compact\";\n /** Expanded rail width in rem-ish tokens: narrow ≈ 13rem, wide ≈ 16rem */\n railWidth?: \"narrow\" | \"wide\";\n /**\n * Where page content scrolls.\n * - `container` (default): main panel scrolls — classic app-shell chrome.\n * - `window`: document/window scrolls with a sticky rail so React Router\n * `ScrollRestoration` keeps working (dashboard dogfood).\n */\n scrollRoot?: \"container\" | \"window\";\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<\n AppShellOptions,\n | \"configurable\"\n | \"defaultCollapsed\"\n | \"lockedOptions\"\n | \"collapseShortcut\"\n | \"subNav\"\n | \"collapsedRailWidth\"\n >\n> &\n Pick<\n AppShellOptions,\n | \"configurable\"\n | \"defaultCollapsed\"\n | \"lockedOptions\"\n | \"collapseShortcut\"\n | \"subNav\"\n | \"collapsedRailWidth\"\n > = {\n showLogo: true,\n showAppName: true,\n showThemeToggle: true,\n showCollapse: true,\n showUserSlot: true,\n showFooter: true,\n showSecondaryNav: true,\n showMobileBottomNav: true,\n defaultCollapsed: false,\n collapseShortcut: false,\n collapsedRailWidth: 56,\n subNav: \"section\",\n configurable: undefined,\n density: \"comfortable\",\n railWidth: \"narrow\",\n scrollRoot: \"container\",\n};\n\n// The user's collapse choice lives at `${optionsStorageKey}:collapsed` as\n// \"1\" / \"0\"; no entry means they haven't chosen. It is read through\n// `useSyncExternalStore`, so a client-only mount reads it during the first\n// render (no expanded-then-collapsed flash), hydration uses the server\n// snapshot (no mismatch), and every shell on the page, and other tabs via the\n// `storage` event, stays in step.\nconst collapsedListeners = new Set<() => void>();\n\nfunction subscribeCollapsed(listener: () => void): () => void {\n collapsedListeners.add(listener);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"storage\", listener);\n }\n return () => {\n collapsedListeners.delete(listener);\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"storage\", listener);\n }\n };\n}\n\nfunction readStoredCollapsed(key: string): boolean | undefined {\n if (typeof window === \"undefined\") return undefined;\n try {\n const raw = localStorage.getItem(`${key}:collapsed`);\n if (raw === \"1\") return true;\n if (raw === \"0\") return false;\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStoredCollapsed(key: string, collapsed: boolean | undefined) {\n if (typeof window === \"undefined\") return;\n try {\n if (collapsed === undefined) localStorage.removeItem(`${key}:collapsed`);\n else localStorage.setItem(`${key}:collapsed`, collapsed ? \"1\" : \"0\");\n } catch {\n // quota / private mode\n }\n collapsedListeners.forEach((listener) => listener());\n}\n\nfunction useStoredCollapsed(key: string | undefined): boolean | undefined {\n return useSyncExternalStore(\n subscribeCollapsed,\n () => (key ? readStoredCollapsed(key) : undefined),\n () => undefined,\n );\n}\n\nfunction isTypingTarget(el: EventTarget | null): boolean {\n if (!el || typeof (el as HTMLElement).tagName !== \"string\") return false;\n const node = el as HTMLElement;\n const tag = node.tagName;\n return (\n tag === \"INPUT\" ||\n tag === \"TEXTAREA\" ||\n tag === \"SELECT\" ||\n node.isContentEditable === true ||\n node.closest?.('[contenteditable=\"\"], [contenteditable=\"true\"]') != null\n );\n}\n\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** Focus is in a widget that uses printable keys itself (typeahead). */\nfunction ownsKeys(el: EventTarget | null): boolean {\n const node = el as HTMLElement | null;\n return Boolean(\n node?.closest?.(\n '[role=\"listbox\"], [role=\"combobox\"], [role=\"menu\"], [role=\"menubar\"], [role=\"menuitem\"], [role=\"option\"], [role=\"tree\"], [role=\"grid\"]',\n ),\n );\n}\n\n/** A modal or Radix dialog is open somewhere on the page. */\nfunction dialogOpen(): boolean {\n if (typeof document === \"undefined\") return false;\n return (\n document.querySelector('[role=\"dialog\"][data-state=\"open\"], [role=\"alertdialog\"][data-state=\"open\"], [aria-modal=\"true\"]') !=\n null\n );\n}\n\n/** md breakpoint: the desktop sidebar only exists at this width and up. */\nconst DESKTOP_QUERY = \"(min-width: 768px)\";\n\n/**\n * @stability Beta\n */\nexport interface AppShellProps {\n /** App name shown in sidebar header */\n appName: string;\n /** App logo letter or short text (ignored when `logo` is set) */\n appLogo?: string;\n /** Custom logo node — preferred over `appLogo` letter tile */\n logo?: ReactNode;\n /**\n * Primary navigation items. Optional when `navigation` is set: the tree\n * root's `items` are the global nav then.\n */\n navItems?: NavItem[];\n /**\n * The app's logical navigation hierarchy. AppShell resolves it against\n * `activePath` (see `resolveNavigation`) and derives:\n * - the sidebar's global items from the root's `items` (unless `navItems`),\n * - a contextual section from the current node's `items`, labelled with\n * the node's `label` (`$param` segments in `to` filled from the URL),\n * - the mobile tab bar: the contextual items when there are any, else the\n * global top-level items (unless `mobileNavItems`),\n * - a back link to the current node's logical parent (unless\n * `parentNavigation`).\n *\n * @stability Beta\n */\n navigation?: NavigationNode<NavItem>;\n /**\n * Back-to-parent link rendered in the content header, above `children`, on\n * mobile and desktop. Derived from `navigation` when omitted; `null` hides\n * it. Use this instead of placing a back row inside page content.\n *\n * @stability Beta\n */\n parentNavigation?: ParentNavigation | null;\n /** Secondary nav (e.g. “More”) — rendered below a divider when shown */\n secondaryNavItems?: NavItem[];\n /** Label above secondary nav (default “More”) */\n secondaryNavLabel?: string;\n /**\n * Items for the mobile bottom tab bar. Defaults to top-level `navItems`\n * (no children). Pass a short list for apps with large sidebars; pass `[]`\n * and set `options.showMobileBottomNav: false` to hide.\n */\n mobileNavItems?: NavItem[];\n /** Slot below the logo row (product switcher, workspace picker, …) */\n headerSlot?: ReactNode;\n /**\n * Compact slot shown in the **collapsed** desktop rail, where `headerSlot`\n * is hidden for space. Use it to keep a core affordance reachable without\n * expanding — e.g. an icon-only product switcher. Omit to hide the header\n * region entirely while collapsed.\n */\n collapsedHeaderSlot?: ReactNode;\n /** Footer region above the user slot (version, links) */\n footer?: ReactNode;\n /**\n * User / account block at the bottom of the sidebar. When the rail is\n * collapsed, AppShell hides any descendant carrying the\n * `data-shell-user-detail` attribute (e.g. name/email text) so only a\n * compact element (avatar, initial) remains — tag the detail wrapper you\n * want hidden in the collapsed rail with that attribute.\n */\n userSlot?: ReactNode;\n /** Page content */\n children: ReactNode;\n /**\n * @deprecated Prefer `options.showThemeToggle`. Kept for sample-app\n * back-compat; merges into resolved options when `options` omits it.\n */\n showThemeToggle?: boolean;\n /** Chrome config (developer defaults + optional in-sidebar menu) */\n options?: AppShellOptions;\n /** Persist user sidebar-option overrides + collapse state (localStorage) */\n optionsStorageKey?: string;\n /**\n * Controlled collapse (desktop rail). Overrides the stored user choice and\n * every default.\n */\n collapsed?: boolean;\n /** Called with the new state whenever the user toggles the sidebar. */\n onCollapsedChange?: (collapsed: boolean) => void;\n /**\n * This page's default: open the desktop sidebar collapsed (`true`) or\n * expanded (`false`) until the user toggles it. Reactive, so a layout can\n * pass it per route. Wins over `navigation`'s `defaultCollapsed` and\n * `options.defaultCollapsed`; the user's own choice (persisted under\n * `optionsStorageKey`) wins over all of them.\n *\n * @stability Beta\n */\n defaultCollapsed?: boolean;\n /**\n * This page's sub-navigation mode (see `AppShellOptions.subNav`). Wins\n * over `navigation`'s `subNav` and `options.subNav`; the page's own\n * `useAppShellSubNav(items, { mode })` wins over it.\n *\n * @stability Beta\n */\n subNav?: SubNavMode;\n /**\n * Accessible name of the sub-navigation tab row. Defaults to the current\n * navigation node's label, else \"Page sections\".\n */\n subNavLabel?: string;\n /**\n * Injectable link component. Defaults to a plain `<a>` (no router). Pass a\n * router adapter — e.g. React Router `({ href, ...p }) => <Link to={href} {...p} />`\n * or Next.js `next/link` — to get client-side navigation.\n */\n linkComponent?: LinkComponent;\n /**\n * Current location used to highlight the active nav item. Pass the full\n * location, `pathname + search + hash` (React Router: `useLocation()`), so\n * items whose `to` names a query or hash (`/admin?tab=users`) can become\n * active. A pathname alone still works for path-only items, `end` included.\n * Omit to disable active highlighting.\n */\n activePath?: string;\n /**\n * Optional custom active-state matcher. Defaults to a prefix match (with `/`\n * treated as exact), mirroring React Router `NavLink`.\n */\n isActive?: (to: string, activePath?: string) => boolean;\n}\n\nconst PARAM = /^\\$(.+)$/;\n\n/**\n * Fill `$name` path segments from `params`; `undefined` if one is missing. A\n * `?query` / `#hash` on `to` is kept as is.\n */\nfunction fillParams(to: string, params: Record<string, string>): string | undefined {\n const cut = to.search(/[?#]/);\n const path = cut === -1 ? to : to.slice(0, cut);\n const suffix = cut === -1 ? \"\" : to.slice(cut);\n let missing = false;\n const filled = path\n .split(\"/\")\n .map((part) => {\n const name = PARAM.exec(part)?.[1];\n if (name == null) return part;\n const value = params[name];\n if (value == null) missing = true;\n return value == null ? part : encodeURIComponent(value);\n })\n .join(\"/\");\n return missing ? undefined : filled + suffix;\n}\n\n/** Interpolate items (and children); drop any whose path the URL can't fill. */\nfunction fillItems(items: NavItem[], params: Record<string, string>): NavItem[] {\n return items.flatMap((item) => {\n const to = fillParams(item.to, params);\n if (to == null) return [];\n return [\n {\n ...item,\n to,\n children: item.children ? fillItems(item.children, params) : undefined,\n },\n ];\n });\n}\n\nfunction ThemeToggle({ testId }: { testId: string }) {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n const stored = localStorage.getItem(\"theme\");\n const prefersDark = window.matchMedia(\n \"(prefers-color-scheme: dark)\",\n ).matches;\n const isDark = stored === \"dark\" || (!stored && prefersDark);\n setDark(isDark);\n document.documentElement.classList.toggle(\"dark\", isDark);\n }, []);\n\n function toggle() {\n const next = !dark;\n setDark(next);\n document.documentElement.classList.toggle(\"dark\", next);\n localStorage.setItem(\"theme\", next ? \"dark\" : \"light\");\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggle}\n className=\"h-8 w-8\"\n title=\"Toggle theme\"\n aria-label=\"Toggle theme\"\n data-testid={testId}\n testID={testId}\n >\n {dark ? <Sun className=\"h-4 w-4\" /> : <Moon className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\n/** The item's icon, or its label's first letter when it has none. */\nfunction NavIcon({ item, className }: { item: SubNavItem; className?: string }) {\n if (item.icon) {\n const Icon = item.icon;\n return <Icon className={className} />;\n }\n return (\n <span\n className={cn(\n className,\n \"inline-flex items-center justify-center rounded text-[11px] font-semibold uppercase leading-none\",\n )}\n aria-hidden\n >\n {item.label.trim().charAt(0)}\n </span>\n );\n}\n\n/**\n * Name tooltip for an icon-rail entry, on hover and on keyboard focus. The\n * trigger is a wrapper span rather than the link itself, so it works with any\n * injected `linkComponent` (Radix needs a ref and event props on its\n * trigger; a router adapter need not forward either). Focus and blur bubble\n * up to the span, so tabbing onto the link still opens it.\n */\nfunction RailTooltip({ label, children }: { label: string; children: ReactNode }) {\n return (\n <Tooltip content={label} side=\"right\" className=\"flex w-full\">\n <span className=\"flex w-full\">{children}</span>\n </Tooltip>\n );\n}\n\nfunction NavLinkRow({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent: LinkComp,\n activePath,\n isActive,\n notCurrent = false,\n active: activeOverride,\n}: {\n item: SubNavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n /** Decided by the caller (most specific of siblings) instead of by `isActive`. */\n active?: boolean;\n}) {\n const active = activeOverride ?? itemIsActive(item, activePath, isActive);\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n\n if (item.disabled) {\n if (!collapsed) {\n return (\n <span\n title={item.label}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium opacity-40\",\n pad,\n )}\n aria-disabled\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate\">{item.label}</span>\n </span>\n );\n }\n // Rail: a disabled link, named so screen readers announce it (a bare\n // span's aria-label is not reliably read).\n return (\n <RailTooltip label={item.label}>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-label={item.label}\n className=\"flex h-10 w-full items-center justify-center rounded-lg text-sm font-medium opacity-40\"\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n </span>\n </RailTooltip>\n );\n }\n\n const link = (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n aria-label={\n collapsed\n ? item.badge != null\n ? `${item.label} (${item.badge})`\n : item.label\n : undefined\n }\n aria-current={active && !notCurrent ? \"page\" : undefined}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n collapsed && \"relative h-10 w-full justify-center px-0 py-0 motion-reduce:transition-none\",\n active\n ? \"bg-sidebar-accent text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n )}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n {!collapsed ? (\n <>\n <span className=\"min-w-0 flex-1 truncate\">{item.label}</span>\n {item.badge != null ? (\n <Badge variant=\"secondary\" className=\"h-5 shrink-0 px-1.5 text-[10px]\">\n {item.badge}\n </Badge>\n ) : null}\n </>\n ) : item.badge != null ? (\n // The rail has no room for the count: a dot shows there is one, and\n // the accessible name carries the number.\n <span\n className=\"absolute right-1.5 top-1.5 h-2 w-2 rounded-full bg-sidebar-primary\"\n aria-hidden\n />\n ) : null}\n </LinkComp>\n );\n return collapsed ? <RailTooltip label={item.label}>{link}</RailTooltip> : link;\n}\n\n/**\n * A nested group on the collapsed rail: one icon button that opens a popover\n * listing the group's own page (when it has one) and its children. Radix\n * Popover moves focus into the list, closes on Escape / outside click and\n * hands focus back to the button.\n */\nfunction RailGroup({\n item,\n density,\n linkComponent,\n activePath,\n isActive,\n notCurrent,\n}: {\n item: SubNavItem;\n density: \"comfortable\" | \"compact\";\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n notCurrent: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const children = item.children ?? [];\n const active = itemIsActive(item, activePath, isActive);\n const entries: SubNavItem[] = item.to\n ? [{ ...item, children: undefined, end: true }, ...children]\n : children;\n const current = mostSpecificActive(entries, activePath, isActive);\n\n // Close when navigation lands, whichever link (or the URL) caused it.\n useEffect(() => {\n setOpen(false);\n }, [activePath]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <RailTooltip label={item.label}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={item.label}\n disabled={item.disabled}\n data-testid={`nav-rail-group-${item.label}`}\n className={cn(\n \"relative flex h-10 w-full items-center justify-center rounded-lg transition-colors motion-reduce:transition-none\",\n active\n ? \"bg-sidebar-accent text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n item.disabled && \"pointer-events-none opacity-40\",\n )}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <ChevronRight\n className=\"absolute right-0.5 h-3 w-3 opacity-50\"\n aria-hidden\n />\n </button>\n </PopoverTrigger>\n </RailTooltip>\n <PopoverContent\n side=\"right\"\n align=\"start\"\n sideOffset={8}\n className=\"w-56 p-1.5 motion-reduce:animate-none\"\n aria-label={item.label}\n data-testid={`nav-rail-popover-${item.label}`}\n >\n <p className=\"truncate px-2.5 pb-1 pt-1.5 text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {item.label}\n </p>\n <nav aria-label={item.label} className=\"space-y-0.5\">\n {entries.map((entry) => (\n <NavLinkRow\n key={entry.to + entry.label}\n item={entry}\n collapsed={false}\n density={density}\n onNavClick={() => setOpen(false)}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n active={entry === current}\n />\n ))}\n </nav>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction NavGroup({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n notCurrent = false,\n}: {\n item: SubNavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n}) {\n const children = item.children ?? [];\n const childActive = children.some((c) =>\n itemIsActive(c, activePath, isActive),\n );\n const [open, setOpen] = useState(childActive);\n\n useEffect(() => {\n if (childActive) setOpen(true);\n }, [childActive]);\n\n if (children.length === 0) {\n return (\n <NavLinkRow\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Collapsed rail: the group becomes one icon that opens its items in a popover.\n if (collapsed) {\n return (\n <RailGroup\n item={item}\n density={density}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Parent may be its own route (`item.to`) — keep a real link and a separate\n // expand control so groups under an existing page stay navigable + highlightable.\n // Visual highlight may use prefix match; aria-current is exact-only so a child\n // route does not leave two \"page\" currents in the tree (CMT-322-008). Exact\n // means the same path; a query/hash on `activePath` alone doesn't break it.\n const selfExact = Boolean(\n item.to && isPathActive(item.to, activePath, { end: true }),\n );\n const selfActive = item.to\n ? item.end\n ? selfExact\n : isActive(item.to, activePath)\n : false;\n const groupHighlight = selfActive || childActive;\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n const LinkComp = linkComponent;\n const parentClass = cn(\n \"flex min-w-0 flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n groupHighlight\n ? \"bg-sidebar-accent/60 text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n );\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center gap-0.5\" data-testid={`nav-group-${item.label}`}>\n {item.to && !item.disabled ? (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n aria-current={selfExact && !notCurrent ? \"page\" : undefined}\n className={parentClass}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </LinkComp>\n ) : (\n <button\n type=\"button\"\n className={parentClass}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n >\n <NavIcon item={item} className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </button>\n )}\n <button\n type=\"button\"\n className={cn(\n \"shrink-0 rounded-lg p-1.5 text-sidebar-foreground transition-colors hover:bg-sidebar-accent\",\n groupHighlight && \"text-sidebar-primary\",\n item.disabled && \"pointer-events-none opacity-40\",\n )}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-label={open ? `Collapse ${item.label}` : `Expand ${item.label}`}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n data-testid={`nav-group-toggle-${item.label}`}\n >\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform\",\n open && \"rotate-180\",\n )}\n />\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-3 space-y-0.5 border-l border-sidebar-border pl-2\">\n {children.map((child) => (\n <NavLinkRow\n key={child.to + child.label}\n item={child}\n collapsed={false}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n ))}\n </div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n\nfunction SidebarNav({\n navItems,\n contextualNavItems,\n contextualNavLabel,\n secondaryNavItems,\n secondaryNavLabel,\n showSecondary,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n subActive = false,\n nest = false,\n}: {\n navItems: SubNavItem[];\n /** The page's children, in `subNav: \"sidebar\"` mode only. */\n contextualNavItems?: SubNavItem[];\n contextualNavLabel?: string;\n /** A sub-navigation item (wherever it renders) is the current page. */\n subActive?: boolean;\n /**\n * `subNav: \"sidebar\"`: nest the children under the active item (a flyout on\n * the rail), and mark only the most specific one current. Off, they keep\n * the legacy section below the global items.\n */\n nest?: boolean;\n secondaryNavItems?: SubNavItem[];\n secondaryNavLabel: string;\n showSecondary: boolean;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n}) {\n const contextualLabelId = useId();\n // While a contextual item is the current page, global items keep their\n // highlight (the section you are in) but leave `aria-current` to it, so\n // \"Showcase\" and \"Overview\" are never both the current page.\n const contextualActive =\n subActive ||\n Boolean(\n contextualNavItems?.some((item) => itemIsActive(item, activePath, isActive)),\n );\n const contextual = contextualNavItems ?? [];\n // Children nest under the active global item (\"Forms\" for a form's tabs).\n // With none active they get their own section below the global items.\n const host =\n nest && contextual.length > 0\n ? mostSpecificActive(navItems, activePath, isActive)\n : undefined;\n // Only the most specific sibling is current: `/forms/f1/edit/logic` must\n // not also light up a Questions item at `/forms/f1/edit`.\n const contextualCurrent = mostSpecificActive(contextual, activePath, isActive);\n\n const contextualGroup = (nested: boolean) => (\n <div\n className={cn(\n nested\n ? \"ml-3 space-y-0.5 border-l border-sidebar-border pl-2\"\n : \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n !nested && collapsed && \"mt-2 pt-2\",\n )}\n data-testid=\"app-shell-contextual-nav\"\n role=\"group\"\n aria-labelledby={!collapsed && !nested && contextualNavLabel ? contextualLabelId : undefined}\n aria-label={collapsed || nested ? contextualNavLabel : undefined}\n >\n {!collapsed && !nested && contextualNavLabel ? (\n <p\n id={contextualLabelId}\n className=\"mb-2 truncate px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\"\n >\n {contextualNavLabel}\n </p>\n ) : null}\n {contextual.map((item) =>\n item.children?.length ? (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ) : (\n <NavLinkRow\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n active={nest ? item === contextualCurrent : undefined}\n />\n ),\n )}\n </div>\n );\n\n return (\n <nav\n className={cn(\n \"flex-1 space-y-1 overflow-y-auto\",\n collapsed ? \"p-2\" : \"p-3\",\n )}\n aria-label=\"Main\"\n >\n {navItems.map((item) => {\n if (item === host && collapsed) {\n // Rail: the active item opens a flyout with its children.\n return (\n <RailGroup\n key={item.to + item.label}\n item={{ ...item, children: [...(item.children ?? []), ...contextual] }}\n density={density}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={false}\n />\n );\n }\n const row = (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={contextualActive}\n />\n );\n if (item !== host) return row;\n return (\n <div key={item.to + item.label} className=\"space-y-0.5\">\n {row}\n {contextualGroup(true)}\n </div>\n );\n })}\n\n {contextual.length > 0 && !host ? contextualGroup(false) : null}\n\n {showSecondary && secondaryNavItems && secondaryNavItems.length > 0 ? (\n <div\n className={cn(\n \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n collapsed && \"mt-2 pt-2\",\n )}\n >\n {!collapsed ? (\n <p className=\"mb-2 px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\">\n {secondaryNavLabel}\n </p>\n ) : null}\n {secondaryNavItems.map((item) => (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ))}\n </div>\n ) : null}\n </nav>\n );\n}\n\nfunction SidebarBrand({\n appName,\n appLogo,\n logo,\n showLogo,\n showAppName,\n collapsed,\n}: {\n appName: string;\n appLogo?: string;\n logo?: ReactNode;\n showLogo: boolean;\n showAppName: boolean;\n collapsed: boolean;\n}) {\n if (!showLogo && !showAppName) return null;\n\n return (\n <div\n className={cn(\n \"flex min-w-0 items-center gap-2\",\n collapsed && \"justify-center\",\n )}\n >\n {showLogo ? (\n logo ? (\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden\">\n {logo}\n </div>\n ) : appLogo || collapsed ? (\n // Collapsed with no logo at all: the app name's first letter keeps\n // a mark at the top of the rail.\n <div\n className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary\"\n aria-hidden={!appLogo || undefined}\n >\n <span className=\"text-sm font-bold text-primary-foreground\">\n {appLogo || appName.trim().charAt(0).toUpperCase()}\n </span>\n </div>\n ) : null\n ) : null}\n {showAppName && !collapsed ? (\n <span className=\"truncate font-semibold text-sidebar-foreground\">\n {appName}\n </span>\n ) : null}\n </div>\n );\n}\n\ntype ToggleDef = {\n key: keyof AppShellOptions;\n label: string;\n available: boolean;\n};\n\nexport function AppShell({\n appName,\n appLogo,\n logo,\n navItems: navItemsProp,\n navigation,\n parentNavigation: parentNavigationProp,\n secondaryNavItems,\n secondaryNavLabel = \"More\",\n mobileNavItems,\n headerSlot,\n collapsedHeaderSlot,\n footer,\n userSlot,\n children,\n showThemeToggle: showThemeToggleProp,\n options: optionsProp,\n optionsStorageKey,\n collapsed: collapsedProp,\n onCollapsedChange,\n defaultCollapsed: defaultCollapsedProp,\n subNav: subNavProp,\n subNavLabel,\n linkComponent = DefaultLink,\n activePath,\n isActive = isPathActive,\n}: AppShellProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n\n // Hierarchical nav: resolve the tree against the current location once.\n const derived = useMemo(() => {\n if (!navigation) return undefined;\n const nav = resolveNavigation(navigation, activePath ?? \"/\");\n const atRoot = nav.trail.length === 1;\n const globalItems = fillItems(navigation.items, nav.params);\n const contextualItems = atRoot ? [] : fillItems(nav.items, nav.params);\n // No link up to the root from a top-level page (it is where the global\n // nav already goes), and none whose path the URL couldn't fill.\n const parent =\n nav.parent &&\n nav.trail.length > 2 &&\n !nav.parent.path.split(\"/\").some((p) => PARAM.test(p))\n ? { href: nav.parent.path, label: nav.parent.label }\n : undefined;\n // Nearest node in the trail that states a sidebar default.\n const navDefaultCollapsed = [...nav.trail]\n .reverse()\n .find((node) => node.defaultCollapsed !== undefined)?.defaultCollapsed;\n const navSubNav = [...nav.trail]\n .reverse()\n .find((node) => node.subNav !== undefined)?.subNav;\n // The mobile bar's back item: the logical parent, the root included.\n const navParentPath = nav.parent ? fillParams(nav.parent.path, nav.params) : undefined;\n const backItem =\n nav.parent && navParentPath ? { href: navParentPath, label: nav.parent.label } : undefined;\n return {\n current: nav.current,\n globalItems,\n contextualItems,\n parent,\n navDefaultCollapsed,\n navSubNav,\n backItem,\n };\n }, [navigation, activePath]);\n\n const navItems = navItemsProp ?? derived?.globalItems ?? [];\n const subNavChannel = useSubNavChannel();\n const pageSubNav = subNavChannel.page;\n const hasPageHeader = subNavChannel.hasHeader;\n // The current page's children: the page's own (hook) over the node's items.\n const contextualNavItems = pageSubNav?.items ?? derived?.contextualItems ?? [];\n const parentNavigation =\n parentNavigationProp === undefined ? derived?.parent : parentNavigationProp ?? undefined;\n\n const [userOverrides, setUserOverrides] = useState<Partial<AppShellOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n // Close the drawer on any path change (product switcher, deep links, …).\n useEffect(() => {\n setMobileOpen(false);\n }, [activePath]);\n\n const hasSecondary = Boolean(secondaryNavItems && secondaryNavItems.length);\n const hasUser = userSlot != null;\n const hasFooter = footer != null;\n const hasLogo = Boolean(logo || appLogo);\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions<AppShellOptions>(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions<AppShellOptions>(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const lockedOptions = optionsProp?.lockedOptions;\n\n const resolved = useMemo(() => {\n const merged: AppShellOptions = {\n ...OPTION_DEFAULTS,\n ...(showThemeToggleProp !== undefined\n ? { showThemeToggle: showThemeToggleProp }\n : {}),\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.configurable === undefined) {\n merged.configurable =\n hasSecondary ||\n hasUser ||\n hasFooter ||\n Boolean(merged.showCollapse) ||\n Boolean(merged.showThemeToggle);\n }\n // Locked keys always resolve to the developer default, never a stored\n // or in-session user override.\n if (lockedOptions?.length) {\n const defaults = OPTION_DEFAULTS as Record<string, unknown>;\n const devOptions = optionsProp as Record<string, unknown> | undefined;\n const target = merged as Record<string, unknown>;\n for (const key of lockedOptions) {\n target[key] = devOptions?.[key] ?? defaults[key];\n }\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n showThemeToggleProp,\n hasSecondary,\n hasUser,\n hasFooter,\n lockedOptions,\n ]);\n\n const patchOption = useCallback(\n (key: keyof AppShellOptions, value: boolean) => {\n if (lockedOptions?.includes(key)) return;\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n },\n [lockedOptions],\n );\n\n // Collapse precedence: controlled prop > the user's own choice (stored, or\n // this session's when there is no storage key) > this page's default\n // (prop, then the navigation trail) > the app default > expanded.\n const storedCollapsed = useStoredCollapsed(optionsStorageKey);\n const [sessionCollapsed, setSessionCollapsed] = useState<boolean | undefined>(\n undefined,\n );\n const userCollapsed = optionsStorageKey ? storedCollapsed : sessionCollapsed;\n const pageDefaultCollapsed =\n defaultCollapsedProp ??\n derived?.navDefaultCollapsed ??\n optionsProp?.defaultCollapsed ??\n OPTION_DEFAULTS.defaultCollapsed!;\n\n const isCollapseControlled = collapsedProp !== undefined;\n const collapsed = isCollapseControlled\n ? collapsedProp!\n : (userCollapsed ?? pageDefaultCollapsed);\n\n const setCollapsed = useCallback(\n (next: boolean) => {\n if (!isCollapseControlled) {\n if (optionsStorageKey) writeStoredCollapsed(optionsStorageKey, next);\n else setSessionCollapsed(next);\n }\n onCollapsedChange?.(next);\n },\n [isCollapseControlled, optionsStorageKey, onCollapsedChange],\n );\n\n const sidebarRef = useRef<HTMLElement>(null);\n\n // Collapsing re-renders the sidebar's insides: the toggle moves from the\n // header to the rail's foot, and rail links gain a tooltip wrapper. Both\n // remount, which would drop keyboard focus on <body>. So note what had\n // focus (the toggle, or a link by its href) and put focus back on the\n // matching element once the new layout has committed.\n const pendingFocus = useRef<{ toggle: true } | { href: string } | null>(null);\n const toggleCollapsed = useCallback(\n (fromToggle: boolean) => {\n const aside = sidebarRef.current;\n const focused = typeof document === \"undefined\" ? null : document.activeElement;\n if (fromToggle) {\n pendingFocus.current = { toggle: true };\n } else if (aside && focused instanceof HTMLElement && aside.contains(focused)) {\n const href = focused.getAttribute(\"href\");\n pendingFocus.current = href ? { href } : { toggle: true };\n }\n setCollapsed(!collapsed);\n },\n [collapsed, setCollapsed],\n );\n // A collapse that no toggle asked for (a route's `defaultCollapsed`, a\n // controlled prop): capture what had focus during the render that changes\n // it, before the commit remounts the sidebar's insides.\n const renderedCollapsed = useRef(collapsed);\n if (renderedCollapsed.current !== collapsed && !pendingFocus.current) {\n const aside = sidebarRef.current;\n const focused = typeof document === \"undefined\" ? null : document.activeElement;\n if (aside && focused instanceof HTMLElement && aside.contains(focused)) {\n const href = focused.getAttribute(\"href\");\n pendingFocus.current = href ? { href } : { toggle: true };\n }\n }\n // Runs on every commit, so a request is always consumed in the commit that\n // follows it: a controlled parent that keeps `collapsed` as it was, or a\n // discarded render, can't leave a stale request for a later collapse.\n useIsoLayoutEffect(() => {\n const changed = renderedCollapsed.current !== collapsed;\n renderedCollapsed.current = collapsed;\n const want = pendingFocus.current;\n pendingFocus.current = null;\n const aside = sidebarRef.current;\n if (!changed || !want || !aside) return;\n const toggleEl = aside.querySelector<HTMLElement>('[data-testid=\"app-shell-collapse\"]');\n let target: HTMLElement | null = null;\n if (\"href\" in want) {\n target =\n Array.from(aside.querySelectorAll<HTMLElement>(\"a[href]\")).find(\n (a) => a.getAttribute(\"href\") === want.href,\n ) ?? null;\n }\n (target ?? toggleEl)?.focus();\n });\n const showCollapseCtrl = resolved.showCollapse !== false;\n const collapseShortcut =\n optionsProp?.collapseShortcut ?? OPTION_DEFAULTS.collapseShortcut!;\n\n // Opt-in shortcut (e.g. `[`) toggles the desktop sidebar. Skipped while\n // typing, in a listbox/combobox/menu (typeahead), while a dialog is open,\n // with a modifier held (those chords belong to the app or browser), when\n // another handler already took the key, below the md breakpoint (no\n // desktop sidebar there), and when the collapse control is hidden.\n useEffect(() => {\n if (!collapseShortcut || !showCollapseCtrl) return;\n if (typeof window === \"undefined\") return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== collapseShortcut || e.repeat || e.defaultPrevented) return;\n if (e.ctrlKey || e.metaKey || e.altKey) return;\n if (isTypingTarget(e.target)) return;\n if (ownsKeys(e.target)) return;\n if (dialogOpen()) return;\n if (window.matchMedia && !window.matchMedia(DESKTOP_QUERY).matches) return;\n e.preventDefault();\n toggleCollapsed(false);\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [collapseShortcut, showCollapseCtrl, toggleCollapsed]);\n\n const ParentLink = linkComponent;\n const LinkComp = linkComponent;\n const density = resolved.density ?? \"comfortable\";\n const scrollWindow = resolved.scrollRoot === \"window\";\n const railExpanded =\n resolved.railWidth === \"wide\" ? \"md:w-64\" : \"md:w-52\";\n // Collapsed icon rail: 56px as before, or 64px when asked for.\n const railCollapsed =\n (optionsProp?.collapsedRailWidth ?? OPTION_DEFAULTS.collapsedRailWidth) === 64\n ? \"md:w-16\"\n : \"md:w-14\";\n const railClass = collapsed ? railCollapsed : railExpanded;\n\n // Sub-navigation mode: page (hook) > prop > nearest node > app option.\n const subNavMode: SubNavMode =\n pageSubNav?.mode ??\n subNavProp ??\n derived?.navSubNav ??\n resolved.subNav ??\n OPTION_DEFAULTS.subNav!;\n const subActive = contextualNavItems.some((i) => itemIsActive(i, activePath, isActive));\n\n // \"tabs\" and \"sidebar\" turn sub-navigation on; \"section\" (the default) is\n // the shell as it always was; \"off\" hides the children entirely.\n const subNavOn = subNavMode === \"tabs\" || subNavMode === \"sidebar\";\n\n const leaves = (items: SubNavItem[]) =>\n items.filter((i) => !i.children || i.children.length === 0);\n // Phones. On: a page with children swaps the bar to them, led by a back\n // item to the logical parent. \"section\": the children replace the bar\n // as before, with no back item. \"off\": the app's main bar. An explicit\n // `mobileNavItems` always wins.\n const contextualLeaves = subNavMode === \"off\" ? [] : leaves(contextualNavItems);\n // With sub-navigation on, a page's children win over an app-wide\n // `mobileNavItems` on that page; elsewhere `mobileNavItems` applies.\n const subBottom = subNavOn && contextualLeaves.length > 0;\n const legacyBottom = !subNavOn && !mobileNavItems && contextualLeaves.length > 0;\n const backTarget = subBottom\n ? (parentNavigation ?? derived?.backItem ?? (() => {\n const hostItem = mostSpecificActive(navItems, activePath, isActive);\n return hostItem ? { href: hostItem.to, label: hostItem.label } : undefined;\n })())\n : undefined;\n const bottomItems = (\n subBottom\n ? contextualLeaves\n : (mobileNavItems ?? (legacyBottom ? contextualLeaves : leaves(navItems)))\n ).filter((i) => !i.disabled);\n // Global tabs keep their highlight, but leave `aria-current` to the sub\n // item that is the current page (see SidebarNav).\n const bottomNotCurrent =\n !mobileNavItems && !subBottom && !legacyBottom && subActive;\n const bottomCurrent = subBottom\n ? mostSpecificActive(bottomItems, activePath, isActive)\n : undefined;\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showLogo\", label: \"Logo\", available: hasLogo },\n { key: \"showAppName\", label: \"App name\", available: true },\n {\n key: \"showThemeToggle\",\n label: \"Theme toggle\",\n available: true,\n },\n { key: \"showCollapse\", label: \"Collapse control\", available: true },\n {\n key: \"showSecondaryNav\",\n label: \"Secondary nav\",\n available: hasSecondary,\n },\n { key: \"showFooter\", label: \"Footer\", available: hasFooter },\n { key: \"showUserSlot\", label: \"User block\", available: hasUser },\n {\n key: \"showMobileBottomNav\",\n label: \"Mobile bottom nav\",\n available: bottomItems.length > 0,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available && !lockedOptions?.includes(t.key));\n\n const showTheme = resolved.showThemeToggle !== false;\n const showSecondary = hasSecondary && resolved.showSecondaryNav !== false;\n const showFooterSlot = hasFooter && resolved.showFooter !== false;\n const showUser = hasUser && resolved.showUserSlot !== false;\n const showMobileBottom =\n bottomItems.length > 0 && resolved.showMobileBottomNav !== false;\n const showTabs = subNavMode === \"tabs\" && contextualNavItems.length > 0;\n\n const optionsControl =\n resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Sidebar options\"\n aria-label=\"Sidebar options\"\n data-testid=\"app-shell-options\"\n testID=\"app-shell-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"top\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Sidebar options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this sidebar. Saved on this device when a storage key is\n set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`app-shell-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`app-shell-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey &&\n (Object.keys(userOverrides).length > 0 ||\n storedCollapsed !== undefined) ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => {\n setUserOverrides({});\n // Hand the sidebar back to the page defaults too.\n writeStoredCollapsed(optionsStorageKey, undefined);\n }}\n data-testid=\"app-shell-options-reset\"\n aria-label=\"Reset sidebar options\"\n testID=\"app-shell-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null;\n\n const collapseLabel = collapsed ? \"Expand sidebar\" : \"Collapse sidebar\";\n // Same markup as before this feature (title + aria-pressed); only its\n // place changes on the collapsed rail (the foot instead of the header).\n const collapseToggle = showCollapseCtrl ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => toggleCollapsed(true)}\n title={collapseShortcut ? `${collapseLabel} (${collapseShortcut})` : collapseLabel}\n aria-label={collapseLabel}\n aria-pressed={collapsed}\n aria-keyshortcuts={collapseShortcut || undefined}\n data-testid=\"app-shell-collapse\"\n testID=\"app-shell-collapse\"\n >\n {collapsed ? (\n <PanelLeft className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </Button>\n ) : null;\n\n const sidebarChrome = (opts: { mobile?: boolean }) => (\n <>\n <div\n className={cn(\n \"flex h-14 shrink-0 items-center gap-2 border-b border-sidebar-border\",\n collapsed && !opts.mobile ? \"justify-center px-2\" : \"px-3\",\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <SidebarBrand\n appName={appName}\n appLogo={appLogo}\n logo={logo}\n showLogo={resolved.showLogo !== false}\n showAppName={resolved.showAppName !== false}\n collapsed={collapsed && !opts.mobile}\n />\n </div>\n {opts.mobile ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(false)}\n aria-label=\"Close navigation\"\n data-testid=\"app-shell-mobile-close\"\n testID=\"app-shell-mobile-close\"\n >\n <X className=\"h-5 w-5\" />\n </Button>\n ) : (\n // Expanded: collapse sits beside the logo. Collapsed: the rail's\n // header is the logo mark alone; expand moves to the rail's foot.\n !collapsed ? (\n <div className=\"flex shrink-0 items-center gap-0.5\">\n {collapseToggle}\n {optionsControl}\n </div>\n ) : null\n )}\n </div>\n\n {collapsed && !opts.mobile ? (\n collapsedHeaderSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border p-2\">\n {collapsedHeaderSlot}\n </div>\n ) : null\n ) : headerSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border\">\n {headerSlot}\n </div>\n ) : null}\n\n <SidebarNav\n navItems={navItems}\n contextualNavItems={\n (\n opts.mobile\n ? subNavMode !== \"off\"\n : subNavMode === \"sidebar\" || subNavMode === \"section\"\n )\n ? contextualNavItems\n : undefined\n }\n nest={subNavMode === \"sidebar\" || (opts.mobile && subNavOn)}\n contextualNavLabel={derived?.current.label}\n subActive={subActive}\n secondaryNavItems={secondaryNavItems}\n secondaryNavLabel={secondaryNavLabel}\n showSecondary={showSecondary}\n collapsed={collapsed && !opts.mobile}\n density={density}\n onNavClick={opts.mobile ? () => setMobileOpen(false) : undefined}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n\n {(showFooterSlot ||\n showUser ||\n showTheme ||\n (collapsed && (optionsControl || collapseToggle))) &&\n !opts.mobile ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-2\">\n {showFooterSlot && !collapsed ? footer : null}\n {showUser ? (\n <div\n className={cn(\n collapsed &&\n \"flex justify-center [&_[data-shell-user-detail]]:hidden\",\n )}\n >\n {userSlot}\n </div>\n ) : null}\n <div\n className={cn(\n \"flex items-center gap-1\",\n collapsed ? \"flex-col\" : \"justify-end\",\n )}\n >\n {collapsed ? optionsControl : null}\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-desktop\" />\n ) : null}\n {collapsed ? collapseToggle : null}\n </div>\n </div>\n ) : null}\n\n {opts.mobile && (showFooterSlot || showUser || showTheme) ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-3\">\n {showFooterSlot ? footer : null}\n {showUser ? userSlot : null}\n {showTheme ? (\n <div className=\"flex justify-end\">\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-drawer\" />\n </div>\n ) : null}\n </div>\n ) : null}\n </>\n );\n\n return (\n <div\n className={cn(\n \"flex\",\n scrollWindow ? \"min-h-screen\" : \"h-screen overflow-hidden\",\n )}\n >\n {/* Desktop sidebar */}\n <aside\n className={cn(\n \"hidden flex-col border-r border-sidebar-border bg-sidebar transition-[width] duration-200 motion-reduce:transition-none md:flex\",\n scrollWindow && \"sticky top-0 h-screen\",\n railClass,\n )}\n ref={sidebarRef}\n data-collapsed={collapsed || undefined}\n data-testid=\"app-shell-sidebar\"\n >\n {sidebarChrome({})}\n </aside>\n\n {/* Mobile overlay */}\n {mobileOpen ? (\n <div\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\n onClick={() => setMobileOpen(false)}\n aria-hidden\n />\n ) : null}\n\n {/* Mobile sidebar — inert when closed so off-screen links leave tab order */}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r border-sidebar-border bg-sidebar transition-transform md:hidden\",\n mobileOpen ? \"translate-x-0\" : \"-translate-x-full pointer-events-none\",\n )}\n id=\"app-shell-mobile-nav\"\n aria-hidden={!mobileOpen}\n inert={!mobileOpen || undefined}\n >\n {sidebarChrome({ mobile: true })}\n </aside>\n\n {/* Main content */}\n <div\n className={cn(\n \"flex min-w-0 flex-1 flex-col\",\n !scrollWindow && \"overflow-hidden\",\n )}\n >\n <header\n className={cn(\n \"flex h-14 items-center gap-3 border-b px-4 md:hidden\",\n scrollWindow && \"sticky top-0 z-20 bg-background\",\n )}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(true)}\n aria-label=\"Open navigation\"\n aria-expanded={mobileOpen}\n aria-controls=\"app-shell-mobile-nav\"\n data-testid=\"app-shell-mobile-open\"\n testID=\"app-shell-mobile-open\"\n >\n <Menu className=\"h-5 w-5\" />\n </Button>\n <span className=\"flex-1 truncate font-semibold\">{appName}</span>\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-header\" />\n ) : null}\n </header>\n\n <main\n className={cn(\n \"flex-1\",\n !scrollWindow && \"overflow-y-auto\",\n showMobileBottom ? \"pb-16 md:pb-0\" : \"pb-0\",\n )}\n >\n {parentNavigation ? (\n <div\n className=\"flex min-w-0 items-center px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8\"\n data-testid=\"app-shell-parent-nav\"\n >\n {/* -ml-3 lines the arrow up with the content's left edge. */}\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"-ml-3 min-w-0 max-w-full\"\n testID=\"app-shell-parent-link\"\n >\n <ParentLink\n href={parentNavigation.href}\n aria-label={`Back to ${parentNavigation.label}`}\n >\n <ArrowLeft aria-hidden />\n <span className=\"truncate\">{parentNavigation.label}</span>\n </ParentLink>\n </Button>\n </div>\n ) : null}\n {/* Page header slot (<AppShellPageHeader>): above the tab row, on\n phones too. Empty and unstyled until a page mounts one. */}\n {hasPageHeader ? (\n <div\n ref={subNavChannel.setHeaderSlot}\n className={cn(\n \"min-w-0 px-4 sm:px-6 lg:px-8\",\n parentNavigation ? \"pt-2 sm:pt-3 lg:pt-4\" : \"pt-4 sm:pt-6 lg:pt-8\",\n )}\n data-testid=\"app-shell-page-header\"\n />\n ) : null}\n {showTabs ? (\n <div\n className={cn(\n \"px-4 sm:px-6 lg:px-8\",\n // Phones use the bottom bar, unless the app turned it off.\n showMobileBottom && \"hidden md:block\",\n (!parentNavigation || hasPageHeader) && \"pt-2 sm:pt-3 lg:pt-4\",\n )}\n >\n <SubNavTabs\n items={contextualNavItems}\n activePath={activePath}\n isActive={isActive}\n linkComponent={linkComponent}\n label={subNavLabel ?? derived?.current.label ?? \"Page sections\"}\n end={\n subNavChannel.hasEnd ? (\n <div ref={subNavChannel.setEndSlot} className=\"flex items-center\" />\n ) : undefined\n }\n />\n </div>\n ) : null}\n <div\n className={cn(\n \"min-w-0 p-4 sm:p-6 lg:p-8\",\n (parentNavigation || hasPageHeader) && !showTabs && \"pt-2 sm:pt-3 lg:pt-4\",\n )}\n >\n <SubNavContext.Provider value={subNavChannel.channel}>\n {children}\n </SubNavContext.Provider>\n </div>\n </main>\n\n {showMobileBottom ? (\n <nav\n className=\"fixed bottom-0 left-0 right-0 z-30 flex border-t bg-background md:hidden\"\n aria-label=\"Primary\"\n >\n {backTarget ? (\n <LinkComp\n href={backTarget.href}\n aria-label={`Back to ${backTarget.label}`}\n className=\"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium text-muted-foreground transition-colors\"\n testID=\"app-shell-mobile-back\"\n >\n <ArrowLeft className=\"h-5 w-5\" aria-hidden />\n <span className=\"max-w-full truncate px-0.5\">{backTarget.label}</span>\n </LinkComp>\n ) : null}\n {bottomItems.map((item) => {\n const active = bottomCurrent\n ? item === bottomCurrent\n : itemIsActive(item, activePath, isActive);\n return (\n <LinkComp\n key={item.to + item.label}\n href={item.to}\n title={item.label}\n aria-label={\n subNavOn && item.badge != null\n ? `${item.label} (${item.badge})`\n : item.label\n }\n aria-current={active && !bottomNotCurrent ? \"page\" : undefined}\n className={cn(\n \"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium transition-colors\",\n active ? \"text-primary\" : \"text-muted-foreground\",\n )}\n >\n {subNavOn && item.badge != null ? (\n <span className=\"relative\">\n <NavIcon item={item} className=\"h-5 w-5\" />\n {/* Anchored to the icon's right edge and growing right,\n so a word badge (\"New\") never covers the icon. */}\n <span\n className=\"absolute -top-1.5 left-full -ml-1 inline-flex h-4 min-w-4 items-center justify-center whitespace-nowrap rounded-full bg-primary px-1 text-[10px] font-semibold leading-none text-primary-foreground ring-2 ring-background\"\n aria-hidden\n >\n {item.badge}\n </span>\n </span>\n ) : (\n <NavIcon item={item} className=\"h-5 w-5\" />\n )}\n <span className=\"max-w-full truncate px-0.5\">\n {item.label}\n </span>\n </LinkComp>\n );\n })}\n </nav>\n ) : null}\n </div>\n </div>\n );\n}\n"]}