efficient-shell 4.126.2 → 4.126.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -30
- package/dist/{Browser-DBRSIQ4J.js → Browser-IIVSJJIO.js} +4 -4
- package/dist/{Browser-DBRSIQ4J.js.map → Browser-IIVSJJIO.js.map} +1 -1
- package/dist/{Documents-5MD5SKPB.js → Documents-MIU3AWGL.js} +4 -4
- package/dist/{Documents-5MD5SKPB.js.map → Documents-MIU3AWGL.js.map} +1 -1
- package/dist/{Files-KY35DPWB.js → Files-N2P2LJ5R.js} +4 -4
- package/dist/{Files-KY35DPWB.js.map → Files-N2P2LJ5R.js.map} +1 -1
- package/dist/{Notepad-2BO5VEUG.js → Notepad-L775LQBJ.js} +4 -4
- package/dist/{Notepad-2BO5VEUG.js.map → Notepad-L775LQBJ.js.map} +1 -1
- package/dist/{Preview-N4UYYXG6.js → Preview-G56SXZU4.js} +4 -4
- package/dist/{Preview-N4UYYXG6.js.map → Preview-G56SXZU4.js.map} +1 -1
- package/dist/{Spreadsheet-5EWZGMXN.js → Spreadsheet-ZP5KSNLJ.js} +4 -4
- package/dist/{Spreadsheet-5EWZGMXN.js.map → Spreadsheet-ZP5KSNLJ.js.map} +1 -1
- package/dist/apps/index.js +8 -8
- package/dist/chunk-K6ZT6MWE.js +7 -0
- package/dist/{chunk-YMGXZABY.js.map → chunk-K6ZT6MWE.js.map} +1 -1
- package/dist/{chunk-C3NELUTX.js → chunk-N2CMEDSH.js} +3 -3
- package/dist/{chunk-C3NELUTX.js.map → chunk-N2CMEDSH.js.map} +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/ui/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-YMGXZABY.js +0 -7
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/windowRegistry/createWindowRegistry.ts","../src/shell/windowTarget.ts","../src/shell/ShortcutHelp.tsx","../src/shell/ShellContextMenu.tsx","../src/shell/NotificationBell.tsx","../src/utils/env.ts","../src/shell/DevIndicator.tsx","../src/shell/WidgetManager.tsx","../src/shell/perfVerdict.ts","../src/shell/perfLog.ts","../src/shell/perfEnvironment.ts","../src/shell/PerfStats.tsx","../src/changelog.ts","../src/shell/Desktop.tsx","../src/shell/StartupAnimation.tsx","../src/shell/LogoutAnimation.tsx","../src/shell/SessionRestore.tsx","../src/shell/StartMenu.tsx","../src/shell/MobileAppLanding.tsx","../src/shell/Layout.tsx","../src/settings/Customization.tsx","../src/settings/BehaviorPanel.tsx","../src/settings/SoundsPanel.tsx","../src/settings/SystemPreferences.tsx","../src/data/useTableNav.ts","../src/data/useDefaultColumnConfig.ts","../src/data/useColumnConfig.ts","../src/data/ResizableTable.tsx","../src/data/EntityList.tsx","../src/data/useInfiniteScroll.ts","../src/data/useSort.ts","../src/shell/FilterBar.tsx","../src/shell/perfDescribe.ts","../src/utils/mergeBulkItems.ts","../src/shell/BulkImportGrid.tsx","../src/shell/ServerStatusIndicator.tsx","../src/shell/ChangePasswordForm.tsx","../src/shell/withTimeout.ts","../src/shell/PdfActionButton.tsx","../src/shell/ShellEntityFetcher.tsx","../src/hooks/useNewHotkey.ts","../src/hooks/useEditHotkey.ts","../src/shell/modalEventScope.ts","../src/hooks/useModalSave.ts","../src/hooks/useModalDuplicate.ts"],"names":["Dialog","useState","useEffect","selected","close","sections","jsxs","jsx","Fragment","fps","useRef","useCallback","useQueryClient","e","dx","dy","move","useLayoutEffect","navSections","navIcons","sectionIcons","isValidElement","cloneElement","visibleChildren","useSyncExternalStore","toISODate","useMemo","group","isCustom","Row","useContext","useQuery","LoadingSpinner","timeAgo","createPortal","createContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * createWindowRegistry — composes a window registry from one or more partial\n * registry maps. Used at the consumer's App layer to merge package-bundled\n * apps with the consumer's own entity windows.\n *\n * const windows = createWindowRegistry(\n * bundledApps, // utility + document + web apps from the package\n * entityWindows, // consumer-defined entity windows (e.g. Sales Order, Invoice)\n * );\n *\n * Later partials override earlier ones on the same key — handy when a\n * consumer wants to swap a built-in app for their own variant.\n */\nimport type { WindowRegistry } from './types';\n\nexport function createWindowRegistry(...partials: WindowRegistry[]): WindowRegistry {\n return Object.assign({}, ...partials);\n}\n","/**\n * Staging channels for app-mounted windows.\n *\n * ## The pattern this exists for\n *\n * Most windows are opened through `WindowManager` (`openEntity` / `openPage`),\n * which knows how to reuse one that is already open and bring it forward. But\n * some windows aren't opened at all — they are mounted once, for the life of the\n * session, and merely RETARGETED: one form builder that every \"Edit form\" entry\n * point points at, one media picker every slot borrows, one Edit Coupon window\n * per list. The host stays mounted and swaps what it is showing.\n *\n * That third kind used to have a hole in it. The window rose when it was first\n * created, because creating it is a mount and `Modal` raises a fresh mount. It\n * did NOT rise when it was asked for again, because asking again only changed\n * some content — and no amount of content changing is distinguishable, from\n * inside the shell, from a re-render. So a window that was already open but\n * buried under another one stayed buried, and the button that opened it read as\n * dead.\n *\n * ## Why the fix lives here and not at the call sites\n *\n * The shell could have exported \"raise this window\" and asked every button to\n * remember to call it. The four hand-written copies of this channel that this\n * module replaces are the argument against that: each carried a comment saying\n * it mirrored the others so they could not drift apart, and they had drifted\n * anyway — only one of the four had thought to make a repeat staging of the\n * SAME target observable. A rule that four call sites must remember is a rule\n * three of them will forget.\n *\n * So the ask is built into the channel. `set()` is the only way to show one of\n * these windows, and `set()` brings it forward.\n *\n * ## The two halves, and why they cannot be confused\n *\n * A window must come forward when it is asked for, and must NEVER come forward\n * on its own. Those pull against each other, and the separation here is\n * structural rather than a matter of care:\n *\n * - The raise is emitted from exactly one place — `set()`, an imperative\n * \"show this\" call. There is no path from rendering to raising. A window\n * that refetches, re-renders, receives a socket push or resolves a query\n * has no way to reach that line, so it cannot leap in front of somebody\n * typing in another window. Somebody has to ask.\n * - `set(null)` is a close, and closes never raise.\n *\n * Note what this deliberately does NOT do: gate the raise on a browser user\n * gesture. That reads like a stronger guarantee and is in fact a worse one —\n * a real user-initiated open can arrive without a gesture attached (an embedded\n * editor asking its host for a window relays the click through `postMessage`,\n * which lands in a plain listener with no activation), and the window would then\n * silently fail to rise for the one entry point that is hardest to test. The\n * contract is `set()` means the user asked; a caller staging a target for any\n * other reason says so with `{ raise: false }`.\n */\nimport { useSyncExternalStore } from 'react';\n\nimport { cancelWindowFront, requestWindowFront } from './Modal';\n\n/**\n * A target as the window receives it: what was asked for, plus the stamp that\n * makes THIS staging distinct from the last one.\n *\n * The stamp is not decoration. Without it, staging is only observable when the\n * target's contents change — so asking for the window that is already showing\n * exactly what you asked for would be a no-op, and \"New form\" on top of an open\n * blank form would neither reset it nor (before this module) raise it. Callers\n * never set `nav`; staging does.\n */\nexport type StagedTarget<T> = T & { readonly nav: number };\n\nexport interface WindowTargetOptions {\n /**\n * Whether staging this target should also bring the window forward.\n * Defaults to `true`, because staging a target is how the product says\n * \"the user asked to see this\".\n *\n * Pass `false` for the rare staging that is not a request to be looked at —\n * restoring a session's window state on load, say, where several windows are\n * re-staged at once and none of them was just asked for.\n */\n raise?: boolean;\n}\n\nexport interface WindowTarget<T> {\n /** The stable key the window's `Modal` must be given, so the shell can find\n * it to raise. Read it straight off the channel:\n * `<Modal windowKey={myTarget.windowKey}>`. */\n readonly windowKey: string;\n /** Point the window at something — or `null` to close it. A non-null target\n * also brings the window forward, whether it was closed, open and buried, or\n * already showing this very thing. */\n set(target: T | null, options?: WindowTargetOptions): void;\n /** What is staged right now (`null` if nothing) — for readers outside React. */\n get(): StagedTarget<T> | null;\n /** Watch for stagings. Returns its own unsubscribe. */\n subscribe(listener: () => void): () => void;\n}\n\n/**\n * Create the staging channel for one app-mounted window.\n *\n * `windowKey` identifies the window to the shell and must match the `windowKey`\n * given to that window's `Modal`. Use a stable, namespaced string — it also\n * becomes the key the window's position and stacking order are remembered\n * under, so it outlives a page refresh.\n */\nexport function createWindowTarget<T extends object>(windowKey: string): WindowTarget<T> {\n let current: StagedTarget<T> | null = null;\n let nav = 0;\n const listeners = new Set<() => void>();\n\n const emit = () => { listeners.forEach((fn) => fn()); };\n\n return {\n windowKey,\n set(target, options) {\n if (target === null) {\n current = null;\n // Withdraw an ask that nothing ever mounted to honour. Staging and\n // then immediately clearing (an editor request cancelled before the\n // window rendered) would otherwise leave the request in the shell to\n // be claimed by the next, unrelated open.\n cancelWindowFront(windowKey);\n emit();\n return;\n }\n current = { ...target, nav: ++nav };\n emit();\n if (options?.raise !== false) requestWindowFront(windowKey);\n },\n get() { return current; },\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n };\n}\n\n/**\n * Read the staged target inside the window's host component, re-rendering\n * whenever a new one is staged — including a fresh staging of an identical\n * target, which `nav` makes a distinct value.\n *\n * Replaces the `useState` + `useEffect(subscribe)` pair every hand-written\n * version of this channel used to carry, and closes that pair's own gap: it\n * reads the currently-staged target during render rather than after mount, so a\n * host mounted while something is already staged shows it on its first frame.\n */\nexport function useWindowTarget<T extends object>(target: WindowTarget<T>): StagedTarget<T> | null {\n return useSyncExternalStore(target.subscribe, target.get, target.get);\n}\n","import { useState, useEffect } from 'react';\nimport { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react';\nimport { CMD_ENTER, CMD_S, CMD_K, CMD_DOT, CMD_A, CMD_Z, CMD_SHIFT_Z, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, MOD, SHIFT, ENTER } from './Kbd';\nimport { useDismissPopupsOnOpen } from './useDismissPopupsOnOpen';\nimport { Z_LAYERS } from './zLayers';\n\nconst sections = [\n {\n title: 'Global',\n shortcuts: [\n { keys: CMD_K, description: 'Search' },\n { keys: CMD_DOT, description: 'Toggle sidebar' },\n { keys: 'Ctrl F11', description: 'Toggle fullscreen' },\n { keys: 'ESC', description: 'Exit fullscreen (when no windows open)' },\n { keys: '?', description: 'Show keyboard shortcuts' },\n ],\n },\n {\n // The title bar is a tab stop; these act on the focused window's bar.\n title: 'Windows (title bar focused)',\n shortcuts: [\n { keys: '←↑→↓', description: 'Move window' },\n { keys: `${SHIFT} Arrows`, description: 'Resize window' },\n { keys: `${MOD} ←/→`, description: 'Snap to left / right half' },\n { keys: `${MOD} ↑`, description: 'Maximize' },\n { keys: `${MOD} ↓`, description: 'Restore / minimize' },\n { keys: ENTER, description: 'Toggle maximize' },\n ],\n },\n {\n title: 'Lists',\n shortcuts: [\n { keys: 'J / \\u2193', description: 'Next row' },\n { keys: 'K / \\u2191', description: 'Previous row' },\n { keys: '\\u23CE', description: 'Open selected row' },\n { keys: '\\u21E7J / \\u21E7K', description: 'Move and select' },\n { keys: '\\u21E7 Click', description: 'Range select' },\n { keys: 'Space', description: 'Toggle row checkbox' },\n { keys: CMD_A, description: 'Select / deselect all' },\n { keys: ALT_SHIFT_N, description: 'Create new item' },\n { keys: ALT_SHIFT_E, description: 'Edit selected item' },\n ],\n },\n {\n title: 'Modals / Forms',\n shortcuts: [\n { keys: CMD_ENTER, description: 'Submit' },\n { keys: CMD_S, description: 'Save' },\n { keys: ALT_SHIFT_D, description: 'Save as new (duplicate)' },\n { keys: CMD_Z, description: 'Undo the last change to the form' },\n { keys: CMD_SHIFT_Z, description: 'Redo it' },\n { keys: 'ESC', description: 'Close modal' },\n ],\n },\n];\n\nexport default function ShortcutHelp() {\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n const toggle = () => setOpen(prev => !prev);\n document.addEventListener('toggle-shortcut-help', toggle);\n return () => document.removeEventListener('toggle-shortcut-help', toggle);\n }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === '?' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if ((e.target as HTMLElement)?.isContentEditable) return;\n e.preventDefault();\n setOpen(prev => !prev);\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, []);\n\n // An overlay like the palette and Dialog: opening it closes the popups that\n // would otherwise float above its backdrop (see `overlayEvents.ts`). The\n // `?` key never fires from a text field, but a menu or the server-status\n // card can be open, and `toggle-shortcut-help` arrives from anywhere.\n useDismissPopupsOnOpen(open);\n\n return (\n <Dialog open={open} onClose={() => setOpen(false)} className=\"relative\" style={{ zIndex: Z_LAYERS.overlay }}>\n <DialogBackdrop className=\"fixed inset-0 bg-black/30 transition-opacity\" />\n <div className=\"fixed inset-0 flex items-center justify-center p-6\">\n <DialogPanel className=\"w-full max-w-md rounded-lg bg-white shadow-xl\">\n <div className=\"flex items-center justify-between px-5 pt-5 pb-3 border-b border-gray-200\">\n <h2 className=\"text-base font-semibold text-gray-900\">Keyboard Shortcuts</h2>\n <button onClick={() => setOpen(false)} className=\"text-gray-400 hover:text-gray-500 text-sm\">\n ESC\n </button>\n </div>\n <div className=\"px-5 py-4 space-y-5 max-h-[60vh] overflow-y-auto\">\n {sections.map(section => (\n <div key={section.title}>\n <h3 className=\"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2\">{section.title}</h3>\n <div className=\"space-y-1.5\">\n {section.shortcuts.map(s => (\n <div key={s.keys + s.description} className=\"flex items-center justify-between\">\n <span className=\"text-sm text-gray-700\">{s.description}</span>\n <kbd className=\"inline-flex items-center rounded border border-gray-300 bg-gray-50 px-2 py-0.5 text-xs font-medium text-gray-600 font-mono\">\n {s.keys}\n </kbd>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n <div className=\"px-5 py-3 border-t border-gray-100 text-center\">\n <span className=\"text-xs text-gray-400\">Press <kbd className=\"rounded border border-gray-300 bg-gray-50 px-1.5 py-0.5 text-[10px] font-medium text-gray-500\">?</kbd> to toggle</span>\n </div>\n </DialogPanel>\n </div>\n </Dialog>\n );\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, MenuIcon } from './PopupMenu';\nimport { copyToClipboard, selectionAt, type SelectedText } from './clipboard';\nimport {\n describeContextTarget,\n keepsNativeMenu,\n type ShellContextTarget,\n} from './contextMenuTarget';\n\n/**\n * One context menu for the whole shell.\n *\n * Right-click used to be a patchwork: fourteen surfaces in this package drew\n * their own menu, and everywhere else the browser's native menu appeared,\n * which reads as a hole in a desktop OS. This component closes the hole with a\n * single `contextmenu` listener on the document, and does it without touching\n * any of those handlers:\n *\n * - Every existing handler calls `preventDefault()`, so by the time the\n * event bubbles to the document it is already spoken for. The listener\n * checks `defaultPrevented` and stands down — the specific menu wins,\n * exactly as it does today. `PopupMenu` claims right-clicks on itself the\n * same way, so a menu never opens on top of another one.\n * - Whatever the browser's own menu does better keeps it (`keepsNativeMenu`):\n * text fields, for spellcheck and \"Add to dictionary\"; images, canvases and\n * media, for Save / Copy image and the playback controls.\n * - A touch long-press keeps it too. It fires `contextmenu`, and taking it\n * would cancel the browser's touch text selection.\n * - Shift+right-click anywhere reaches the browser's real menu, so \"Inspect\"\n * is still one gesture away for developers.\n *\n * Mounted by `Layout` (`contextMenu={false}` turns it off), so a consumer gets\n * it without wiring anything. It is exported too, for a screen that renders\n * outside the shell layout.\n */\n\nconst ICONS = {\n copy: 'M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m0 0H5.625',\n open: 'M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25',\n back: 'M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18',\n forward: 'M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3',\n reload: 'M16.023 9.348h4.992V4.356m-4.993 4.992l3.181-3.183a8.25 8.25 0 00-13.803 3.7M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7',\n link: 'M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244',\n} as const;\n\nfunction openInNewTab(url: string) {\n window.open(url, '_blank', 'noopener,noreferrer');\n}\n\nexport interface ShellContextMenuProps {\n /** Turn this instance off — every right-click falls through to the browser.\n * Under `Layout`, pass `contextMenu={false}` to `Layout` instead: it mounts\n * its own instance. */\n disabled?: boolean;\n}\n\ninterface OpenMenu {\n x: number;\n y: number;\n target: ShellContextTarget;\n selected: SelectedText | null;\n}\n\nexport default function ShellContextMenu({ disabled }: ShellContextMenuProps = {}) {\n const [menu, setMenu] = useState<OpenMenu | null>(null);\n\n useEffect(() => {\n if (disabled) return;\n const onContextMenu = (e: MouseEvent) => {\n // A surface with its own menu has already called preventDefault().\n if (e.defaultPrevented) return;\n // Developer escape hatch — the browser's real menu, with Inspect on it.\n if (e.shiftKey) return;\n // Browsers dispatch `contextmenu` as a PointerEvent. A touch long-press\n // is how text gets selected by touch; taking it would cancel that.\n if ((e as PointerEvent).pointerType === 'touch') return;\n // The element actually clicked. A document listener sees `e.target`\n // retargeted to the host when the click lands inside a shadow root.\n const target = (typeof e.composedPath === 'function' ? e.composedPath()[0] : undefined) ?? e.target;\n if (keepsNativeMenu(target)) return;\n\n e.preventDefault();\n const selected = selectionAt(target);\n setMenu({\n x: e.clientX,\n y: e.clientY,\n target: describeContextTarget(target, selected?.text),\n selected,\n });\n };\n document.addEventListener('contextmenu', onContextMenu);\n return () => { document.removeEventListener('contextmenu', onContextMenu); };\n }, [disabled]);\n\n // A window that scrolls or resizes under an open menu leaves it anchored to\n // nothing; close rather than follow. Scroll is captured, so a scroll inside\n // a window's own scroll area counts, not only the page's.\n useEffect(() => {\n if (!menu) return;\n const close = () => setMenu(null);\n window.addEventListener('resize', close);\n window.addEventListener('blur', close);\n window.addEventListener('scroll', close, true);\n return () => {\n window.removeEventListener('resize', close);\n window.removeEventListener('blur', close);\n window.removeEventListener('scroll', close, true);\n };\n }, [menu]);\n\n if (!menu) return null;\n\n const { linkUrl } = menu.target;\n const { selected } = menu;\n const close = () => setMenu(null);\n const run = (fn: () => void) => () => { fn(); close(); };\n\n const sections: ReactNode[][] = [];\n\n if (selected) {\n sections.push([\n <PopupMenuItem key=\"copy\" onClick={run(() => void copyToClipboard('Text', selected.text, selected.html))}>\n <MenuIcon d={ICONS.copy} />Copy\n </PopupMenuItem>,\n ]);\n }\n\n if (linkUrl) {\n sections.push([\n <PopupMenuItem key=\"open-link\" onClick={run(() => openInNewTab(linkUrl))}>\n <MenuIcon d={ICONS.open} />Open link in new tab\n </PopupMenuItem>,\n <PopupMenuItem key=\"copy-link\" onClick={run(() => void copyToClipboard('Link address', linkUrl))}>\n <MenuIcon d={ICONS.link} />Copy link address\n </PopupMenuItem>,\n ]);\n }\n\n // The default section is always drawn, so the menu is never empty and the\n // same four page actions sit in the same place whatever was clicked. Reload\n // and Back leave the page, which a dirty window (`useWindowDirty`) holds with\n // the browser's own \"Leave site?\" prompt.\n sections.push([\n <PopupMenuItem key=\"back\" onClick={run(() => window.history.back())}>\n <MenuIcon d={ICONS.back} />Back\n </PopupMenuItem>,\n <PopupMenuItem key=\"forward\" onClick={run(() => window.history.forward())}>\n <MenuIcon d={ICONS.forward} />Forward\n </PopupMenuItem>,\n <PopupMenuItem key=\"reload\" onClick={run(() => window.location.reload())}>\n <MenuIcon d={ICONS.reload} />Reload\n </PopupMenuItem>,\n <PopupMenuItem key=\"copy-page\" onClick={run(() => void copyToClipboard('Page address', window.location.href))}>\n <MenuIcon d={ICONS.link} />Copy page address\n </PopupMenuItem>,\n ]);\n\n return (\n <PopupMenu\n portal\n minWidth={200}\n style={{ left: menu.x, top: menu.y }}\n onClose={close}\n className=\"shell-context-menu\"\n >\n <div data-shell-context-menu={menu.target.kind}>\n {sections.map((items, i) => (\n <div key={i}>\n {i > 0 && <PopupMenuDivider />}\n {items}\n </div>\n ))}\n </div>\n </PopupMenu>\n );\n}\n","import { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { formatDate } from '../utils/date';\nimport { playNotification } from '../utils/sounds';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from './PopupMenu';\nimport { useShellPrefs } from './ShellPrefs';\nimport { useShellStrings } from './strings';\n\n/** Generic notification shape consumed by the shell. Consumer-specific\n * fields live on `extra` (or just on additional properties — TS structural\n * typing is permissive). */\nexport interface ShellNotification {\n id: string;\n title: string;\n message?: string;\n entity_type?: string;\n entity_id?: string;\n entity_label?: string;\n is_read: boolean;\n actor_name?: string;\n created_at: string;\n}\n\n/** Config bundle for the notification system. Supplied by the consumer;\n * the shell never calls a hardcoded URL. */\nexport interface NotificationsConfig {\n /** Hook called inside <NotificationBell> on every render. Return the\n * current unread count for the signed-in user. */\n useUnreadCount: () => number;\n /** Fetcher for the dropdown list (most recent first). */\n list: (params?: { page_size?: number }) => Promise<{ results: ShellNotification[] }>;\n /** Mark a single notification as read. */\n markRead: (id: string) => Promise<unknown>;\n /** Mark every unread notification as read. */\n markAllRead: () => Promise<unknown>;\n /** Click handler for a notification item. */\n onItemClick: (notif: ShellNotification) => void;\n /** Click handler for \"View all notifications\". When omitted, the link is hidden. */\n onViewAll?: () => void;\n}\n\nfunction timeAgo(dateStr: string): string {\n const diff = Date.now() - new Date(dateStr).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n if (days < 7) return `${days}d ago`;\n return formatDate(dateStr);\n}\n\n/** How long the pop-up card stays up. It used to be a flat 5s, which was\n * fine while the card clipped everything to one line — now that it shows\n * the whole message, a five-line notification needs longer than five\n * seconds or it vanishes mid-sentence. ~15 chars/sec ≈ 200 wpm, floored at\n * the old 5s so short notifications behave exactly as before, and capped so\n * a long one never parks on screen. */\nexport function readingTimeMs(notif: ShellNotification): number {\n const chars = (notif.title?.length ?? 0) + (notif.message?.length ?? 0);\n return Math.min(12000, Math.max(5000, Math.round(chars / 15) * 1000));\n}\n\ninterface NotificationBellProps extends NotificationsConfig {\n popDirection?: 'left' | 'right';\n}\n\nexport default function NotificationBell({\n useUnreadCount, list, markRead, markAllRead, onItemClick, onViewAll, popDirection,\n}: NotificationBellProps) {\n const [open, setOpen] = useState(false);\n const strings = useShellStrings().notifications;\n // Do Not Disturb: the badge keeps counting, the interruptions stop — no\n // pop-up card, no browser Notification, no sound. Persisted per user.\n const { prefs, save: savePrefs } = useShellPrefs();\n const dnd = prefs.notifications_dnd === true;\n const toggleDnd = () => savePrefs({ notifications_dnd: !dnd });\n const dropdownRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const queryClient = useQueryClient();\n\n const unreadCount = useUnreadCount();\n\n useEffect(() => {\n if ('Notification' in window && Notification.permission === 'default') Notification.requestPermission();\n }, []);\n\n // Extracted click flow shared by the bell popup, the toast, and the\n // browser-Notification fallback. Optimistic mark-read + invoke consumer\n // `onItemClick` to open the entity.\n const handleClick = useCallback((notif: ShellNotification) => {\n if (!notif.is_read) {\n queryClient.setQueryData(['notification-unread-count'], (old: any) => old ? { ...old, count: Math.max(0, (old.count || 0) - 1) } : old);\n queryClient.setQueryData(['notifications-dropdown'], (old: any) => {\n if (!old?.results) return old;\n return { ...old, results: old.results.map((n: any) => n.id === notif.id ? { ...n, is_read: true } : n) };\n });\n markRead(notif.id).catch(() => {\n queryClient.invalidateQueries({ queryKey: ['notification-unread-count'] });\n queryClient.invalidateQueries({ queryKey: ['notifications-dropdown'] });\n });\n }\n setOpen(false);\n onItemClick(notif);\n }, [queryClient, markRead, onItemClick]);\n\n // The actionable in-page notification — top-right, click anywhere on the\n // card to open the entity (same behavior as clicking the same item in the\n // bell popup), X to dismiss only. Lives as React state (not via toast.info)\n // so the click target is a first-class part of the notification system.\n const [inlineNotif, setInlineNotif] = useState<ShellNotification | null>(null);\n const inlineTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const dismissInline = useCallback(() => {\n if (inlineTimerRef.current) { clearTimeout(inlineTimerRef.current); inlineTimerRef.current = null; }\n setInlineNotif(null);\n }, []);\n const showInlineNotif = useCallback((notif: ShellNotification, durationMs = readingTimeMs(notif)) => {\n setInlineNotif(notif);\n playNotification();\n if (inlineTimerRef.current) clearTimeout(inlineTimerRef.current);\n inlineTimerRef.current = setTimeout(() => setInlineNotif(null), durationMs);\n }, []);\n useEffect(() => () => { if (inlineTimerRef.current) clearTimeout(inlineTimerRef.current); }, []);\n\n const prevCountRef = useRef<number | null>(null);\n useEffect(() => {\n if (prevCountRef.current === null) { prevCountRef.current = unreadCount; return; }\n // DND suppresses the interruptions but not the counter: prevCountRef still\n // advances below, so turning DND off later does not replay a backlog.\n if (unreadCount > prevCountRef.current && !dnd) {\n list({ page_size: 1 }).then(data => {\n const latest = data?.results?.[0];\n if (!latest) return;\n const title = latest.title || 'New Notification';\n const body = latest.message || latest.entity_label || '';\n if (document.hidden) {\n if ('Notification' in window && Notification.permission === 'granted') {\n const n = new Notification(title, { body, icon: '/favicon.svg', tag: `notif-${latest.id}` });\n n.onclick = () => { window.focus(); handleClick(latest); n.close(); };\n }\n } else {\n showInlineNotif(latest);\n }\n }).catch(() => {});\n }\n prevCountRef.current = unreadCount;\n }, [unreadCount, list, showInlineNotif, dnd]);\n\n // Always run on mount + every 30s so the dropdown is always populated\n // with cached data before the first click — no loading-state flash.\n const { data: notifData } = useQuery({\n queryKey: ['notifications-dropdown'],\n queryFn: () => list({ page_size: 30 }),\n staleTime: 30_000,\n refetchInterval: 30_000,\n });\n const notifications: ShellNotification[] = notifData?.results ?? [];\n\n // Outside-click is handled by PopupMenu's own onClose listener. Since the\n // popup is portaled into document.body it doesn't sit inside dropdownRef,\n // so any handler scoped to dropdownRef would fire pointerdown on items\n // inside the popup and close it before their onClick runs — see #issue.\n\n const handleMarkAllRead = () => {\n queryClient.setQueryData(['notification-unread-count'], (old: any) => old ? { ...old, count: 0 } : old);\n queryClient.setQueryData(['notifications-dropdown'], (old: any) => {\n if (!old?.results) return old;\n return { ...old, results: old.results.map((n: any) => ({ ...n, is_read: true })) };\n });\n markAllRead().then(() => {\n queryClient.invalidateQueries({ queryKey: ['notification-unread-count'] });\n queryClient.invalidateQueries({ queryKey: ['notifications-dropdown'] });\n });\n };\n\n const [dropdownPos, setDropdownPos] = useState<Record<string, number | string>>({});\n const calcPos = useCallback(() => {\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 56;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const verticalReserve = (taskbarPos === 'top' || taskbarPos === 'bottom') ? taskbarH + 16 : 16;\n const maxHeight = `calc(100vh - ${verticalReserve}px)`;\n if (popDirection === 'right') setDropdownPos({ left: taskbarW + 8, bottom: 8, maxHeight });\n else if (popDirection === 'left') setDropdownPos({ right: taskbarW + 8, bottom: 8, maxHeight });\n else if (taskbarPos === 'top') setDropdownPos({ right: 8, top: taskbarH + 8, maxHeight });\n else setDropdownPos({ right: 8, bottom: taskbarH + 8, maxHeight });\n }, [popDirection]);\n // Run synchronously before paint so the dropdown renders at the right\n // position on first open (otherwise it briefly flashes at viewport origin).\n useLayoutEffect(() => {\n if (!open) return;\n calcPos();\n }, [open, calcPos]);\n useEffect(() => {\n if (!open) return;\n window.addEventListener('resize', calcPos);\n return () => window.removeEventListener('resize', calcPos);\n }, [open, calcPos]);\n\n return (\n <div ref={dropdownRef} className=\"relative\">\n <button ref={buttonRef} data-menu-toggle\n onMouseEnter={() => queryClient.prefetchQuery({ queryKey: ['notifications-dropdown'], queryFn: () => list({ page_size: 30 }) })}\n onClick={() => setOpen(prev => !prev)}\n title={dnd ? strings.dndOn : strings.title}\n className=\"relative shrink-0 rounded-md p-2 text-gray-900 hover:text-black hover:bg-white/20 transition-colors\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n {unreadCount > 0 && (\n <span className=\"absolute top-0.5 right-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n {dnd && (\n /* A quiet moon on the bell: DND is on. Decorative — the button's\n title and the popover toggle carry the state for AT. */\n <span aria-hidden=\"true\" className=\"absolute bottom-0.5 right-0.5 flex h-3 w-3 items-center justify-center rounded-full bg-indigo-500 text-white\">\n <svg className=\"h-2 w-2\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z\"/></svg>\n </span>\n )}\n </button>\n\n {open && createPortal(\n <PopupMenu minWidth={320} className=\"w-80 flex flex-col overflow-hidden\" style={{ ...dropdownPos }} onClose={() => setOpen(false)}>\n <PopupMenuLabel>\n <span className=\"flex items-center justify-between w-full gap-2\">\n <span>{strings.title}</span>\n <span className=\"flex items-center gap-2\">\n {unreadCount > 0 && (\n <button onClick={handleMarkAllRead} className=\"text-[10px] text-blue-600 hover:text-blue-700 font-medium normal-case tracking-normal\">\n {strings.markAllRead}\n </button>\n )}\n <button\n onClick={toggleDnd}\n aria-pressed={dnd}\n title={strings.dnd}\n className={`rounded p-0.5 transition-colors ${dnd ? 'text-indigo-600 bg-indigo-50' : 'text-gray-400 hover:text-gray-600'}`}\n >\n <svg className=\"h-3.5 w-3.5\" fill={dnd ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z\" />\n </svg>\n </button>\n </span>\n </span>\n </PopupMenuLabel>\n <PopupMenuDivider />\n {/* Both axes are named on purpose. `overflow-y: auto` on its own makes\n the other axis compute to `auto` as well, so a fraction of a pixel\n of horizontal overflow — a rounding error on the item's\n `calc(100% - 8px)`, a title with no break opportunity in it — hangs\n a horizontal scrollbar under a dropdown of fixed width that has\n nothing to scroll sideways to. */}\n <div className=\"overflow-y-auto overflow-x-hidden\" style={{ flex: '1 1 auto', minHeight: 0 }}>\n {notifications.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\n <svg className=\"h-8 w-8 text-gray-300 mb-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n <p className=\"text-sm text-gray-600 font-medium\">{strings.caughtUp}</p>\n <p className=\"text-xs text-gray-400 mt-0.5\">{strings.empty}</p>\n </div>\n ) : (\n notifications.map(notif => (\n <PopupMenuItem key={notif.id} onClick={() => handleClick(notif)}>\n <div className=\"pt-0.5 shrink-0\">\n {!notif.is_read ? <div className=\"h-2 w-2 rounded-full bg-blue-500\" /> : <div className=\"h-2 w-2\" />}\n </div>\n <div className=\"min-w-0 flex-1\">\n {/* The message truncates, but the title wraps — `break-words` so a\n long unbroken token (a container or reference number) wraps\n instead of running out under the hidden axis above. */}\n <p className={`text-sm leading-tight break-words ${!notif.is_read ? 'font-medium' : ''}`}>{notif.title}</p>\n {notif.message && <p className=\"text-xs text-gray-500 mt-0.5 truncate\">{notif.message}</p>}\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-[10px] text-gray-400\">{timeAgo(notif.created_at)}</span>\n {notif.actor_name && <span className=\"text-[10px] text-gray-400\">by {notif.actor_name}</span>}\n </div>\n </div>\n </PopupMenuItem>\n ))\n )}\n </div>\n {onViewAll && (\n <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setOpen(false); onViewAll(); }}>\n <span className=\"w-full text-center text-xs text-blue-600 font-medium\">{strings.viewAll}</span>\n </PopupMenuItem>\n </>\n )}\n </PopupMenu>,\n document.body\n )}\n\n {inlineNotif && createPortal(\n <>\n <style>{`@keyframes notif-in { from { opacity: 0; transform: translateX(30px) scale(0.95); } to { opacity: 1; transform: translateX(0) scale(1); } }`}</style>\n <div\n onClick={() => { handleClick(inlineNotif); dismissInline(); }}\n className=\"fixed top-4 right-4 z-[9999] w-[320px] max-w-[calc(100vw-2rem)] cursor-pointer rounded-2xl bg-white/85 backdrop-blur-md border border-white/40 shadow-2xl flex items-start gap-3 px-4 py-3\"\n style={{ animation: 'notif-in 300ms cubic-bezier(0.4,0,0.2,1)' }}\n >\n <div className=\"h-9 w-9 shrink-0 rounded-lg bg-blue-500/15 flex items-center justify-center\">\n <svg className=\"h-5 w-5 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n </div>\n {/* Title and message wrap to as many lines as they need — the card\n grows instead of clipping, so the notification is readable\n without opening it. max-h is only a runaway guard (a very long\n message can't push the dismiss X off-screen); normal ones never\n reach it. break-words keeps an unbroken token (URL, long ref)\n from overflowing the 320px card. */}\n <div className=\"flex-1 min-w-0 max-h-[60vh] overflow-y-auto\">\n <div className=\"text-[11px] font-semibold uppercase tracking-wide text-blue-600 mb-0.5\">{strings.cardLabel}</div>\n <div className=\"text-sm font-medium text-gray-800 leading-snug break-words\">{inlineNotif.title}</div>\n {inlineNotif.message && (\n <div className=\"text-xs text-gray-500 leading-snug break-words mt-0.5\">{inlineNotif.message}</div>\n )}\n </div>\n <button\n onClick={(e) => { e.stopPropagation(); dismissInline(); }}\n className=\"shrink-0 p-1 -mr-1 -mt-1 text-gray-400 hover:text-gray-600 transition-colors\"\n aria-label={strings.dismiss}\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </>,\n document.body\n )}\n </div>\n );\n}\n","/**\n * Dev-environment detection + browser chrome.\n *\n * A deployed bundle is byte-identical across hosts (CI builds once and promotes\n * the same image between environments), so build-time signals like\n * `import.meta.env.MODE` can't tell a developer's machine from a deployed site —\n * only the runtime hostname can. `isDevEnv()` is therefore gated on\n * `localhost`/`127.0.0.1`, and everything dev-only (the <DevIndicator/> tray\n * badge, the `[DEV]` tab-title prefix) keys off it so it never leaks onto a\n * deployed host.\n */\n\n/** Tooltip/banner copy for the dev indicator. */\nexport const DEV_BANNER_TEXT =\n 'LOCAL DEV ENVIRONMENT — running against your local backend; not connected to the live system';\n\n/**\n * True only when served from a developer's own machine.\n *\n * Gated on `localhost`/`127.0.0.1` only (not `*.local` mDNS names), so a\n * teammate reaching a dev server over the LAN doesn't get the dev chrome.\n */\nexport function isDevEnv(): boolean {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n}\n\n/**\n * Apply local-dev browser chrome: prefix the tab title with `[DEV]` and,\n * optionally, swap the favicon. No-op outside localhost. Idempotent — safe to\n * call at startup and again whenever a route overwrites `document.title`.\n *\n * Call before React mounts (e.g. in `main.tsx`) so the title is correct on the\n * first paint. Pass `faviconHref` only if the host actually ships that asset.\n */\nexport function applyDevTitle(opts?: { faviconHref?: string }): void {\n if (!isDevEnv()) return;\n\n if (!document.title.startsWith('[DEV]')) {\n document.title = `[DEV] ${document.title}`;\n }\n\n if (opts?.faviconHref) {\n const icon = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]');\n if (icon) icon.href = opts.faviconHref;\n }\n}\n","import { isDevEnv, DEV_BANNER_TEXT } from '../utils/env';\n\n/**\n * System-tray badge shown only when the app is served from a developer's own\n * machine (localhost / 127.0.0.1). Drop it into the host's `taskbarTrayLeft`\n * slot — it renders nothing off-localhost, so it's safe to leave wired on every\n * build. Visibility is gated on the runtime hostname; see utils/env.ts.\n */\nexport default function DevIndicator() {\n if (!isDevEnv()) return null;\n\n return (\n <div\n className=\"shrink-0 inline-flex items-center gap-1 rounded-md bg-blue-600 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-blue-50 select-none\"\n title={DEV_BANNER_TEXT}\n >\n <svg className=\"h-3 w-3 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4\" />\n </svg>\n <span>Dev</span>\n </div>\n );\n}\n","import { useMemo, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { setWindowPosition } from './Modal';\nimport { useWindowManager } from './WindowManager';\nimport { WINDOW_REGISTRY, isPageEntry, type PageRegistryEntry } from '../windowRegistry/types';\nimport { navIcons } from '../shell-config/nav';\n\ninterface AvailableWidget {\n route: string;\n label: string;\n entry: PageRegistryEntry;\n}\n\n/** Generic fallback glyph for widgets the consumer hasn't given a navIcon. */\nfunction FallbackIcon() {\n return (\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n </svg>\n );\n}\n\nfunction widgetIcon(entry: PageRegistryEntry, route: string) {\n const icon = navIcons[entry.icon ?? route];\n if (icon && isValidElement(icon)) {\n return cloneElement(icon as ReactElement, { className: 'h-5 w-5' });\n }\n return <FallbackIcon />;\n}\n\n/**\n * Widget gallery — the \"manage widgets on the desktop\" surface.\n *\n * Enumerates every widget-flagged page in the live window registry (so it\n * automatically lists whatever the consumer registered, not just the bundled\n * five) and cross-references the window manager's `openWindows` to know which\n * are currently sitting on the desktop. Adding a widget calls `openPage`\n * (which drops the chrome-less panel onto the desktop and persists it via the\n * normal open-windows session store); removing one calls `closeEntity` on the\n * live window. No new persistence layer — it drives the same plumbing the\n * Start Menu already uses.\n *\n * Surfaced from the desktop right-click menu (\"Manage Widgets…\") and exported\n * so a consumer can also register it as a window or wire it to a tray button.\n */\nexport default function WidgetManager({ open, onClose }: { open: boolean; onClose: () => void }) {\n const { openWindows, openPage, closeEntity } = useWindowManager();\n\n // Widget-flagged page entries from the live registry, alphabetised.\n const widgets = useMemo<AvailableWidget[]>(() => {\n if (!open) return [];\n return Object.entries(WINDOW_REGISTRY)\n .filter(([, e]) => isPageEntry(e) && (e as PageRegistryEntry).widget)\n .map(([route, e]) => ({ route, label: (e as PageRegistryEntry).label, entry: e as PageRegistryEntry }))\n .sort((a, b) => a.label.localeCompare(b.label));\n }, [open]);\n\n if (!open) return null;\n\n // route → the live open-window item (widgets aren't multi-instance, so at\n // most one per route).\n const activeByRoute = new Map(openWindows.filter(w => w.route).map(w => [w.route!, w]));\n const isActive = (route: string) => activeByRoute.has(route);\n\n // ── Placement ────────────────────────────────────────────────────────────\n // Newly-added widgets drop into the top-left corner and stack downward so\n // they never cover an existing widget. We read the live on-screen rects of\n // any widgets already on the desktop and place the new one below the lowest\n // one in the left column, wrapping to a new column when the column fills.\n const PAD = 20, GAP = 16;\n type Rect = { x: number; y: number; w: number; h: number };\n\n const workArea = () => {\n const cs = getComputedStyle(document.documentElement);\n const tbH = parseInt(cs.getPropertyValue('--taskbar-height')) || 0;\n const tbW = parseInt(cs.getPropertyValue('--taskbar-width')) || 0;\n const tbPos = cs.getPropertyValue('--taskbar-position').trim() || 'bottom';\n const sidebarW = parseInt(cs.getPropertyValue('--sidebar-width')) || 0;\n return {\n leftOffset: (tbPos === 'left' ? tbW : 0) + sidebarW + PAD,\n topOffset: (tbPos === 'top' ? tbH : 0) + PAD,\n maxBottom: window.innerHeight - (tbPos === 'bottom' ? tbH : 0) - PAD,\n };\n };\n\n const liveWidgetRects = (): Rect[] =>\n [...document.querySelectorAll<HTMLElement>('[data-modal-panel][data-widget]')]\n .map(el => { const r = el.getBoundingClientRect(); return { x: r.left, y: r.top, w: r.width, h: r.height }; })\n .filter(r => r.w > 0 && r.h > 0);\n\n const computeSlot = (occupied: Rect[], w: number, h: number) => {\n const { leftOffset, topOffset, maxBottom } = workArea();\n const rightLimit = window.innerWidth - PAD;\n const lowestInColumn = (colX: number) => {\n const ov = occupied.filter(r => r.x < colX + w && r.x + r.w > colX);\n return ov.length ? Math.max(...ov.map(r => r.y + r.h)) + GAP : topOffset;\n };\n let x = leftOffset, y = lowestInColumn(x), guard = 0;\n // Move to a fresh column when this one is full — but never push a widget\n // off the right edge: only wrap if the next column still fits on-screen.\n while (y + h > maxBottom && x + (w + GAP) + w <= rightLimit && guard < 12) {\n x += w + GAP; y = lowestInColumn(x); guard++;\n }\n return { x, y };\n };\n\n const dimsFor = (route: string) => {\n const e = WINDOW_REGISTRY[route] as PageRegistryEntry;\n return { w: e?.dimensions?.[0] ?? 320, h: e?.dimensions?.[1] ?? 240, auto: !!e?.autoHeight };\n };\n\n // Place a widget into a free top-left slot, then open it. We choose the slot\n // from the *live* rects of widgets already on the desktop, so the new one\n // stacks below their real (content-aware) heights. `autoHeight` widgets\n // shrink to their content, so we only reserve a small slice of height for\n // them when picking a column — otherwise their full dimension height would\n // push later widgets into needless extra columns. The seeded `h` is just a\n // first-paint placeholder; autoHeight widgets re-measure on open.\n const placeAndOpen = (route: string) => {\n const { w, h, auto } = dimsFor(route);\n const selfH = auto ? Math.min(h, 160) : h;\n const { x, y } = computeSlot(liveWidgetRects(), w, selfH);\n setWindowPosition(`page:${route}`, { x, y, w, h });\n openPage(route);\n };\n\n // Resolve once the just-opened widget has rendered with a real height, so the\n // next placement in a batch can read its actual rect (capped so a slow lazy\n // chunk never hangs the loop).\n const waitForWidget = (route: string) => new Promise<void>(resolve => {\n const sel = `[data-modal-panel][data-window-key=\"page:${route}\"]`;\n let n = 0;\n const tick = () => {\n const el = document.querySelector(sel) as HTMLElement | null;\n if ((el && el.getBoundingClientRect().height > 40) || n++ > 30) resolve();\n else setTimeout(tick, 30);\n };\n setTimeout(tick, 30);\n });\n\n const add = (route: string) => { if (!isActive(route)) placeAndOpen(route); };\n const remove = (route: string) => { const w = activeByRoute.get(route); if (w) closeEntity(w.id); };\n const toggle = (route: string) => { isActive(route) ? remove(route) : add(route); };\n\n const activeCount = widgets.reduce((n, w) => n + (isActive(w.route) ? 1 : 0), 0);\n const allActive = widgets.length > 0 && activeCount === widgets.length;\n const addAll = async () => {\n for (const w of widgets) {\n if (isActive(w.route)) continue;\n placeAndOpen(w.route);\n await waitForWidget(w.route);\n }\n };\n const removeAll = () => widgets.forEach(w => remove(w.route));\n\n const widgetGlyph = (\n <svg className=\"h-5 w-5 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n </svg>\n );\n\n return (\n <Modal open={open} onClose={onClose} title=\"Widgets\" icon={widgetGlyph} size=\"md\" compact dimensions={[480, 560]}>\n <div className=\"flex flex-col h-full\">\n {/* Summary + bulk actions */}\n <div className=\"flex items-center justify-between gap-2 px-1 pb-3\">\n <p className=\"text-xs text-gray-500\">\n {widgets.length === 0\n ? 'No widgets available'\n : <><span className=\"font-semibold text-gray-700\">{activeCount}</span> of {widgets.length} on your desktop</>}\n </p>\n {widgets.length > 0 && (\n <button\n onClick={allActive ? removeAll : addAll}\n className=\"text-xs font-medium text-blue-600 hover:text-blue-700 hover:underline\">\n {allActive ? 'Remove all' : 'Add all'}\n </button>\n )}\n </div>\n\n {/* Gallery */}\n <div className=\"flex-1 overflow-y-auto -mx-1 px-1\">\n {widgets.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center text-center py-12 text-gray-400\">\n <div className=\"opacity-60 mb-2\">{widgetGlyph}</div>\n <p className=\"text-sm\">No widgets are registered.</p>\n <p className=\"text-xs mt-1\">Widgets like Weather, Currency, and the Pomodoro timer appear here once available.</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n {widgets.map(({ route, label, entry }) => {\n const active = isActive(route);\n return (\n <button\n key={route}\n onClick={() => toggle(route)}\n title={active ? `Remove ${label} from desktop` : `Add ${label} to desktop`}\n className={`group relative flex items-center gap-3 rounded-xl border p-3 text-left transition-colors ${\n active\n ? 'border-blue-300 bg-blue-50/70 hover:bg-blue-50'\n : 'border-gray-200 bg-white/60 hover:border-gray-300 hover:bg-gray-50'\n }`}>\n <span className={`shrink-0 flex items-center justify-center h-10 w-10 rounded-lg ${\n active ? 'bg-blue-100 text-blue-600' : 'bg-gray-100 text-gray-500'\n }`}>\n {widgetIcon(entry, route)}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-medium text-gray-900 truncate\">{label}</span>\n <span className={`block text-[11px] ${active ? 'text-blue-600' : 'text-gray-400'}`}>\n {active ? 'On desktop' : 'Available'}\n </span>\n </span>\n {/* Toggle affordance */}\n <span className={`shrink-0 inline-flex items-center justify-center h-6 w-6 rounded-full border transition-colors ${\n active\n ? 'border-blue-500 bg-blue-500 text-white group-hover:border-red-400 group-hover:bg-red-400'\n : 'border-gray-300 text-gray-400 group-hover:border-blue-400 group-hover:text-blue-500'\n }`}>\n {active ? (\n <>\n {/* check by default, swap to × on hover to signal removal */}\n <svg className=\"h-3.5 w-3.5 group-hover:hidden\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>\n <svg className=\"h-3.5 w-3.5 hidden group-hover:block\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </>\n ) : (\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n )}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* Hint */}\n <p className=\"shrink-0 pt-3 mt-1 border-t border-gray-100 text-[11px] text-gray-400 leading-relaxed\">\n Drag a widget anywhere on the desktop to reposition it. Right-click a widget for its appearance settings.\n </p>\n </div>\n </Modal>\n );\n}\n","/**\n * Frame-timing maths + bottleneck attribution for the desktop perf HUD.\n *\n * Split out from `PerfStats.tsx` because the interesting part is the\n * *attribution*, and attribution is pure: given a frame rate and how much of\n * the wall clock the main thread spent blocked, decide whether a janky UI is\n * the GPU's fault or JavaScript's. That decision is what the HUD exists for —\n * \"the UI feels laggy\" is not actionable, \"you are GPU-bound\" is — so it lives\n * where a test can pin it.\n *\n * The discriminator: frames are landing late, but the main thread is idle.\n * If JS were the problem the main thread would be busy, so late frames plus an\n * idle thread means the cost is downstream of script — compositing, paint,\n * backdrop-filter. The shell leans hard on frosted glass (`utils/glass.ts`\n * blurs at a 40px radius), which is exactly the kind of work that shows up\n * here and nowhere in a JS profile.\n */\n\n/** Frame rate at or above which we call the UI smooth. Below 60 because\n * rAF sampling is noisy and a display may be capped at 60Hz anyway — a\n * steady 55 is not a complaint anyone would file. */\nexport const SMOOTH_FPS = 50;\n\n/** Share of wall-clock time in long tasks that makes JS the prime suspect.\n * `longtask` entries are >50ms by definition, so even 20% means the thread\n * is stalling several times a second — visible as jank on its own. */\nexport const BLOCKED_PCT_CPU = 20;\n\nexport type BottleneckKind = 'smooth' | 'gpu' | 'cpu' | 'unknown';\n\nexport interface PerfReading {\n /** Frames per second across the sample window. */\n fps: number;\n /** Mean frame interval, ms. */\n frameMs: number;\n /** Slowest single frame in the window, ms — where the jank actually lives. */\n worstMs: number;\n /** Percentage of wall-clock time the main thread spent inside long tasks\n * (0–100), or null when the browser exposes no `longtask` observer.\n * Null is load-bearing: without it we cannot separate GPU from CPU, and\n * guessing would defeat the point of the HUD. */\n blockedPct: number | null;\n}\n\nexport interface Verdict {\n kind: BottleneckKind;\n /** Headline, for the HUD's verdict row. */\n label: string;\n /** One line of what to do about it. */\n detail: string;\n}\n\n/** Reached from two directions — frames arriving late, and frames not arriving\n * at all because the thread is too busy to deliver them — so it lives in one\n * place rather than being spelled out twice. */\nconst CPU_BOUND: Verdict = {\n kind: 'cpu',\n label: 'CPU-bound (JavaScript)',\n detail: 'The main thread is blocked. Rendering settings will not help — this is script or data work.',\n};\n\n/** Turn a window of rAF timestamps into a frame-rate reading.\n * Needs two timestamps to describe one interval; anything less is not yet a\n * measurement and reports zeroes rather than a fabricated 0 fps. */\nexport function summariseFrames(timestamps: number[]): Pick<PerfReading, 'fps' | 'frameMs' | 'worstMs'> {\n if (timestamps.length < 2) return { fps: 0, frameMs: 0, worstMs: 0 };\n\n let worstMs = 0;\n for (let i = 1; i < timestamps.length; i++) {\n const delta = timestamps[i] - timestamps[i - 1];\n if (delta > worstMs) worstMs = delta;\n }\n\n const spanMs = timestamps[timestamps.length - 1] - timestamps[0];\n // A window where every timestamp collapsed to the same instant is not a\n // 0-second span we can divide by — treat it as no reading.\n if (spanMs <= 0) return { fps: 0, frameMs: 0, worstMs: 0 };\n\n const intervals = timestamps.length - 1;\n return {\n fps: (intervals / spanMs) * 1000,\n frameMs: spanMs / intervals,\n worstMs,\n };\n}\n\n/**\n * Attribute a reading to a bottleneck.\n *\n * Order matters: smooth wins outright (nobody cares what a healthy frame rate\n * is *not* bound by), and an unknown block share can only ever downgrade to\n * `unknown` — never to `gpu`. Blaming the GPU because the browser withheld\n * long-task timing would be a confident wrong answer, which is worse than no\n * answer when someone is about to go change settings on the strength of it.\n */\nexport function classify(reading: PerfReading): Verdict {\n const { fps, blockedPct } = reading;\n const threadBlocked = blockedPct !== null && blockedPct >= BLOCKED_PCT_CPU;\n\n if (!Number.isFinite(fps) || fps <= 0) {\n // No readable frame rate — but if the main thread is also blocked, the\n // blocking is *why* there are no frames: a starved thread never gets to\n // service `requestAnimationFrame`, so the samples dry up. That is the most\n // severe CPU-bound case there is, and it must not be reported as an\n // absence of data — \"Measuring…\" would leave the HUD at its least useful\n // exactly when the machine is at its worst.\n if (threadBlocked) return CPU_BOUND;\n return { kind: 'unknown', label: 'Measuring…', detail: 'Collecting frame timings.' };\n }\n\n if (fps >= SMOOTH_FPS) {\n return {\n kind: 'smooth',\n label: 'Smooth',\n detail: 'Frames are landing on time. No rendering bottleneck here.',\n };\n }\n\n if (blockedPct === null) {\n return {\n kind: 'unknown',\n label: 'Janky — cause unknown',\n detail: 'This browser reports no long-task timing, so GPU and JS cannot be told apart. Try Chrome or Edge.',\n };\n }\n\n if (threadBlocked) return CPU_BOUND;\n\n return {\n kind: 'gpu',\n label: 'GPU-bound (compositing)',\n detail: 'Frames are late while the main thread sits idle. Try Preferences → Customization → Reduce transparency.',\n };\n}\n","/**\n * Session log for the desktop perf HUD — and the analysis that turns it into\n * a conclusion.\n *\n * A live frame rate tells you the UI is slow *now*. It does not tell you what\n * made it slow, and the person watching it is usually the last person able to\n * say. So while the HUD is on, every reading is stamped with what was\n * happening around it: how many windows were open, which one was on top,\n * whether the user was clicking, typing, scrolling or dragging. The log is\n * exportable, so a laggy machine somewhere else can produce evidence rather\n * than an adjective.\n *\n * The maths here is deliberately non-clever. Median rather than mean, because\n * one 400ms stall would drag a mean somewhere no frame ever was. Buckets\n * rather than a fitted curve, because \"6 windows open halves the frame rate\"\n * is a sentence someone can act on and a correlation coefficient is not.\n */\nimport type { BottleneckKind } from './perfVerdict';\n\n/** One flush interval's worth of measurement plus its context. Keys are short\n * because thousands of these get JSON-serialised into localStorage and into\n * whatever the user sends afterwards. */\nexport interface PerfLogRecord {\n /** Milliseconds since logging began. */\n t: number;\n fps: number;\n frameMs: number;\n worstMs: number;\n blockedPct: number | null;\n heapMB: number | null;\n verdict: BottleneckKind;\n /** Open shell windows at the moment of the reading. */\n windows: number;\n /** Identity of the topmost window, when there is one — so a summary can name\n * the screen that was slow rather than just the count. */\n active: string | null;\n clicks: number;\n keys: number;\n scrolls: number;\n /** Milliseconds spent with the pointer down and moving. Dragging is the\n * single most compositing-heavy thing a user does in a window shell, so it\n * gets its own axis rather than being lumped in with clicks. Covers any\n * drag — a window gesture, a desktop icon, a text selection; `moveMs` and\n * `resizeMs` below are the window subset of it. */\n dragMs: number;\n /** Start-menu opens (`perfEvents`). */\n menus: number;\n /** Flyout opens — 2nd- and 3rd-level menus. Hover-opened flyouts fire no\n * click and no keypress, so before this axis existed the frame a submenu\n * painted on was filed as *idle*, which is where the jank people actually\n * report was going missing. */\n submenus: number;\n /** Last menu or flyout opened in the interval, so one can be named. */\n menuKey: string | null;\n /** Milliseconds spent dragging a window by its title bar. */\n moveMs: number;\n /** Milliseconds spent dragging a window's resize handle. */\n resizeMs: number;\n}\n\nexport interface FpsGroup {\n samples: number;\n /** Median across the group's *measurable* samples — see `summariseLog`. Zero\n * when every sample in the group stalled. */\n medianFps: number;\n /** Slowest single frame anywhere in the group. For a group of brief\n * interactions this is the number that matters: a flyout that costs one\n * 300ms frame barely moves a median but is exactly what the user saw. */\n worstMs: number;\n /** Samples too blocked to report a frame rate at all. Kept beside the median\n * rather than folded into it, so a group that is entirely stalls reads as\n * the emergency it is instead of as a 0 fps reading. */\n stalls: number;\n}\n\n/**\n * What the user was doing during a sample, reduced to one label.\n *\n * A single interval routinely carries several axes at once — opening a flyout\n * involves a click, a pointer move and a menu mark — so the ranking below\n * decides which one the sample is filed under. It runs most-specific first:\n * the deliberate, expensive gesture beats the incidental click that came with\n * it, because filing a janky submenu open under \"click\" is how you end up\n * optimising the wrong thing.\n */\nexport type ActivityKind = 'submenu' | 'menu' | 'resize' | 'move' | 'scroll' | 'type' | 'click' | 'idle';\n\nconst ACTIVITY_ORDER: { kind: ActivityKind; test: (r: PerfLogRecord) => boolean }[] = [\n { kind: 'submenu', test: r => r.submenus > 0 },\n { kind: 'menu', test: r => r.menus > 0 },\n { kind: 'resize', test: r => r.resizeMs > 0 },\n { kind: 'move', test: r => r.moveMs > 0 },\n { kind: 'scroll', test: r => r.scrolls > 0 },\n { kind: 'type', test: r => r.keys > 0 },\n { kind: 'click', test: r => r.clicks > 0 || r.dragMs > 0 },\n];\n\n/** File a sample under the one thing most likely to have cost it. */\nexport function classifyActivity(r: PerfLogRecord): ActivityKind {\n return ACTIVITY_ORDER.find(entry => entry.test(r))?.kind ?? 'idle';\n}\n\nexport interface LogSummary {\n samples: number;\n durationMs: number;\n medianFps: number;\n worstFrameMs: number;\n /** Fraction of samples in each verdict, 0–1. */\n verdictShare: Record<BottleneckKind, number>;\n /** Split by whether the user was doing anything. The gap between these two\n * is the headline: a desktop that is smooth at rest and janky in use has a\n * rendering cost that only shows up under interaction. */\n interacting: FpsGroup | null;\n idle: FpsGroup | null;\n /** Frame rate per kind of interaction, worst-first — the answer to \"which\n * gesture is slow\", which is the question a report is usually filed to\n * ask. */\n byActivity: (FpsGroup & { kind: ActivityKind })[];\n /** Frame rate against how many windows were open. */\n byWindowCount: (FpsGroup & { windows: number })[];\n /** Windows ranked worst-first, so the slowest screen names itself. */\n worstWindows: (FpsGroup & { key: string })[];\n /** Menus and flyouts ranked worst-first, same idea one layer up. */\n worstMenus: (FpsGroup & { key: string })[];\n}\n\n/** Records kept in memory before the oldest are dropped. At one record per\n * 500ms this is about 20 minutes — long enough to catch an intermittent\n * stall, small enough to serialise without thinking about it. */\nexport const LOG_CAP = 2400;\n\n/** Minimum samples before a group is reported. One unlucky reading is not a\n * finding, and a summary that names a window off a single sample invites\n * someone to go optimise the wrong screen. */\nexport const MIN_GROUP_SAMPLES = 4;\n\n/** The floor for menu and gesture groups. Lower because these events are rare\n * by construction — a flyout opens inside a single 500ms interval, not across\n * twenty of them, so holding them to the window floor would suppress exactly\n * the findings the axes were added for. Two still rules out a one-off, and\n * every group carries its own `samples` for whoever reads it. */\nexport const MIN_EVENT_SAMPLES = 2;\n\n/** Append with a cap, oldest dropped first. Returns a new array — callers hold\n * this in React state, where mutation would not re-render. */\nexport function appendRecord(log: PerfLogRecord[], record: PerfLogRecord, cap = LOG_CAP): PerfLogRecord[] {\n const next = log.length >= cap ? log.slice(log.length - cap + 1) : log.slice();\n next.push(record);\n return next;\n}\n\n/** True when the user was doing something during the interval. */\nexport function isInteracting(r: PerfLogRecord): boolean {\n return classifyActivity(r) !== 'idle';\n}\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = values.slice().sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\n/**\n * Reduce a bucket of samples to a group.\n *\n * A reading taken while the main thread was too blocked to deliver frames\n * carries fps 0. Letting those into a median would report a frame rate the\n * display never showed, so the median is taken over the measurable samples\n * only — but the stall is not thrown away, because a stall is the worst thing\n * in the log. It survives as `stalls`, and its frame time still sets\n * `worstMs`.\n */\nfunction group(records: PerfLogRecord[]): FpsGroup {\n const measured = records.filter(r => r.fps > 0);\n return {\n samples: records.length,\n medianFps: median(measured.map(r => r.fps)),\n worstMs: records.reduce((worst, r) => (r.worstMs > worst ? r.worstMs : worst), 0),\n stalls: records.length - measured.length,\n };\n}\n\n/** Bucket by a key, dropping records that have none. */\nfunction bucket<K>(records: PerfLogRecord[], keyOf: (r: PerfLogRecord) => K | null): Map<K, PerfLogRecord[]> {\n const map = new Map<K, PerfLogRecord[]>();\n for (const r of records) {\n const key = keyOf(r);\n if (key === null) continue;\n const existing = map.get(key);\n if (existing) existing.push(r); else map.set(key, [r]);\n }\n return map;\n}\n\n/** Groups worst-first. A group that stalled outright sorts above one that\n * merely ran slowly — `medianFps` is 0 there, which is already the bottom of\n * the order, and that is the correct place for it. */\nfunction rankWorstFirst<T extends FpsGroup>(groups: T[]): T[] {\n return groups.sort((a, b) => a.medianFps - b.medianFps);\n}\n\n/** Reduce a log to the handful of statements worth acting on. */\nexport function summariseLog(log: PerfLogRecord[]): LogSummary {\n const empty: LogSummary = {\n samples: 0,\n durationMs: 0,\n medianFps: 0,\n worstFrameMs: 0,\n verdictShare: { smooth: 0, gpu: 0, cpu: 0, unknown: 0 },\n interacting: null,\n idle: null,\n byActivity: [],\n byWindowCount: [],\n worstWindows: [],\n worstMenus: [],\n };\n if (!log.length) return empty;\n\n const verdictShare = { ...empty.verdictShare };\n for (const r of log) verdictShare[r.verdict] += 1 / log.length;\n\n const interacting = log.filter(isInteracting);\n const idle = log.filter(r => !isInteracting(r));\n\n return {\n samples: log.length,\n durationMs: log[log.length - 1].t - log[0].t,\n medianFps: median(log.filter(r => r.fps > 0).map(r => r.fps)),\n worstFrameMs: log.reduce((worst, r) => (r.worstMs > worst ? r.worstMs : worst), 0),\n verdictShare,\n interacting: interacting.length >= MIN_GROUP_SAMPLES ? group(interacting) : null,\n idle: idle.length >= MIN_GROUP_SAMPLES ? group(idle) : null,\n byActivity: rankWorstFirst(\n [...bucket(log, classifyActivity).entries()]\n .filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES)\n .map(([kind, rs]) => ({ kind, ...group(rs) })),\n ),\n byWindowCount: [...bucket(log, r => r.windows).entries()]\n .filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES)\n .map(([windows, rs]) => ({ windows, ...group(rs) }))\n .sort((a, b) => a.windows - b.windows),\n worstWindows: rankWorstFirst(\n [...bucket(log, r => r.active).entries()]\n .filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES)\n .map(([key, rs]) => ({ key, ...group(rs) })),\n ),\n worstMenus: rankWorstFirst(\n [...bucket(log, r => r.menuKey).entries()]\n .filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES)\n .map(([key, rs]) => ({ key, ...group(rs) })),\n ),\n };\n}\n\nconst CSV_COLUMNS: (keyof PerfLogRecord)[] = [\n 't', 'fps', 'frameMs', 'worstMs', 'blockedPct', 'heapMB',\n 'verdict', 'windows', 'active', 'clicks', 'keys', 'scrolls', 'dragMs',\n 'menus', 'submenus', 'menuKey', 'moveMs', 'resizeMs',\n];\n\n/** Flat CSV, for opening in a spreadsheet without writing any code. */\nexport function toCsv(log: PerfLogRecord[]): string {\n const cell = (value: unknown): string => {\n if (value === null || value === undefined) return '';\n const text = typeof value === 'number' ? String(Math.round(value * 10) / 10) : String(value);\n // Window and menu keys are app-supplied text and can contain a comma or a\n // quote — a section label is literally whatever the nav config says.\n return /[\",\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n };\n return [\n CSV_COLUMNS.join(','),\n ...log.map(r => CSV_COLUMNS.map(c => cell(r[c])).join(',')),\n ].join('\\n');\n}\n","/**\n * What machine the readings came off.\n *\n * A frame rate without a machine attached is half a report. \"GPU-bound\n * (compositing)\" means something very different on an Intel UHD 620 driving a\n * 4K panel than on an M3 Max, and the first question anyone triaging a\n * slowdown asks is which one they are looking at — a question the reporter is\n * usually the worst-placed person to answer, and often simply cannot.\n *\n * The user agent alone does not settle it. Chromium freezes its UA string, so\n * Windows 11 reports itself as Windows 10 and an ARM machine looks like an x86\n * one; and no UA string has ever named the GPU, which is the part that matters\n * most here. So this reads the specifics directly, from four sources:\n *\n * - **Synchronous navigator and screen fields** — cores, memory, panel,\n * network, display settings. Cheap, and occasionally withheld.\n * - **A WebGL context**, purely to ask the driver its own name. Created and\n * destroyed inside one call, at report time and never during measurement,\n * because a live context is exactly the sort of thing that would show up in\n * the numbers it is meant to explain.\n * - **Client hints and the battery**, both async, both unchanging, so both\n * are resolved once when the HUD mounts rather than while a report is being\n * assembled.\n * - **Media queries**, for the settings that change how much compositing the\n * browser is being asked to do in the first place.\n *\n * Everything is best-effort and every field degrades to null. Firefox and\n * Safari withhold `deviceMemory`; Safari has no client hints; a blocklisted\n * driver refuses WebGL. A report missing one line is a far smaller loss than a\n * report that failed to send, so nothing here is allowed to throw.\n */\n\n/** Async platform detail from `navigator.userAgentData`. */\nexport interface PlatformHints {\n /** 'macOS', 'Windows', 'Linux', … */\n platform: string | null;\n /** The real OS version, which the frozen UA string no longer carries. */\n platformVersion: string | null;\n /** 'arm' | 'x86' — an Intel Mac and an Apple Silicon Mac are not the same\n * machine and do not have the same compositing story. */\n architecture: string | null;\n /** Device model, on mobile. */\n model: string | null;\n /** Browser name and full version, e.g. 'Chrome 141.0.7390.55'. */\n browser: string | null;\n}\n\n/** Power state. A laptop in Low Power Mode is capped at 30 fps by the OS, which\n * is the single most common cause of \"it halved this afternoon\". */\nexport interface BatteryInfo {\n charging: boolean;\n /** 0–1. */\n level: number;\n}\n\n/** The parts that cannot be read synchronously, resolved once on mount. */\nexport interface AsyncEnvironment {\n hints: PlatformHints | null;\n battery: BatteryInfo | null;\n}\n\nexport interface PerfEnvironment {\n userAgent: string;\n /** Browser name and version from client hints; null outside Chromium, where\n * `userAgent` above is the fallback. */\n browser: string | null;\n platform: string | null;\n platformVersion: string | null;\n architecture: string | null;\n model: string | null;\n /** Logical cores. The shell is single-threaded, so this mostly says how much\n * else the machine can be doing at once. */\n cpuCores: number | null;\n /** Approximate RAM in GB. Deliberately coarse — the spec has browsers round\n * to a power of two and permits clamping to 8 to blunt fingerprinting, so\n * treat it as a floor (\"this much or more\"), not a measurement. Chromium\n * only; Firefox and Safari publish nothing. */\n deviceMemoryGB: number | null;\n /** The driver's own name for itself, e.g. 'Apple M3 Max' or\n * 'ANGLE (Intel, Intel(R) UHD Graphics 620 …)'. */\n gpu: string | null;\n gpuVendor: string | null;\n /** False when the browser fell back to software rendering — which explains a\n * GPU-bound verdict outright. */\n webglAvailable: boolean;\n screen: { width: number; height: number; dpr: number; colorDepth: number | null };\n /** The window, which is what actually gets composited — a maximised window on\n * a 4K panel and a small one are different amounts of work. */\n viewport: { width: number; height: number };\n /** Heap ceiling this tab was given, MB. Chromium only. */\n heapLimitMB: number | null;\n /** Effective connection class, downlink Mb/s and round-trip ms. Separates a\n * UI that is slow from a UI that is waiting. */\n network: { effectiveType: string | null; downlinkMbps: number | null; rttMs: number | null; saveData: boolean } | null;\n battery: BatteryInfo | null;\n /** Settings that change how much work the browser is being asked to do. */\n prefersReducedMotion: boolean;\n forcedColors: boolean;\n /** The shell's own \"reduce transparency\" — the first thing to suggest, and\n * the first thing to check has not already been tried. */\n reducedTransparency: boolean;\n /** Screens can be scaled; a report from a 4K panel at 200% is not the same as\n * one at 100%. */\n touchPoints: number | null;\n}\n\ninterface UADataLike {\n platform?: string;\n brands?: { brand: string; version: string }[];\n getHighEntropyValues?: (hints: string[]) => Promise<Record<string, unknown>>;\n}\n\ninterface ChromeMemoryLike {\n jsHeapSizeLimit: number;\n}\n\ninterface ConnectionLike {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n}\n\ninterface BatteryManagerLike {\n charging: boolean;\n level: number;\n}\n\n/** Chromium reports itself under several brands, most of them decoys (\"Not;A\n * Brand\") planted to break naive UA sniffing. Pick the real one. */\nfunction pickBrand(brands: { brand: string; version: string }[] | undefined): string | null {\n if (!brands?.length) return null;\n const real = brands.filter(b => !/not[^a-z]*a[^a-z]*brand/i.test(b.brand));\n // Chromium itself is the generic engine brand; the specific product (Chrome,\n // Edge, Opera) is what someone reproducing the report needs to install.\n const named = real.find(b => b.brand !== 'Chromium') ?? real[0];\n return named ? `${named.brand} ${named.version}` : null;\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === 'string' && value ? value : null;\n}\n\n/**\n * Resolve everything that needs a promise. Call once, keep the result — the\n * values cannot change for the life of the page, and the prompt some browsers\n * attach to high-entropy hints must not fire while someone is filing a report.\n *\n * Never rejects. A browser with no client hints and no battery API is the\n * normal case outside Chromium, not an error worth handling at the call site.\n */\nexport async function requestAsyncEnvironment(): Promise<AsyncEnvironment> {\n return { hints: await readHints(), battery: await readBattery() };\n}\n\nasync function readHints(): Promise<PlatformHints | null> {\n const uaData = (navigator as Navigator & { userAgentData?: UADataLike }).userAgentData;\n if (!uaData) return null;\n const base: PlatformHints = {\n platform: uaData.platform ?? null,\n platformVersion: null,\n architecture: null,\n model: null,\n browser: pickBrand(uaData.brands),\n };\n if (!uaData.getHighEntropyValues) return base;\n try {\n const high = await uaData.getHighEntropyValues([\n 'platform',\n 'platformVersion',\n 'architecture',\n 'model',\n 'fullVersionList',\n ]);\n const full = high.fullVersionList as { brand: string; version: string }[] | undefined;\n return {\n platform: asString(high.platform) ?? base.platform,\n platformVersion: asString(high.platformVersion),\n architecture: asString(high.architecture),\n model: asString(high.model),\n // The full list carries the build number; the low-entropy brands only\n // carry the major, which is not enough to match against a known bug.\n browser: pickBrand(full) ?? base.browser,\n };\n } catch {\n // The browser may decline the high-entropy set outright.\n return base;\n }\n}\n\nasync function readBattery(): Promise<BatteryInfo | null> {\n const getBattery = (navigator as Navigator & { getBattery?: () => Promise<BatteryManagerLike> }).getBattery;\n if (!getBattery) return null;\n try {\n const battery = await getBattery.call(navigator);\n return { charging: battery.charging, level: battery.level };\n } catch {\n return null;\n }\n}\n\n/**\n * Ask the GPU its name, then throw the context away.\n *\n * `WEBGL_debug_renderer_info` is the extension that returns the unmasked\n * string; without it `RENDERER` reports a generic sanitised name, which is\n * still worth having. The context is explicitly lost afterwards because\n * browsers cap how many may exist at once, and a diagnostic must not be the\n * thing that exhausts them.\n */\nexport function readGpu(): { renderer: string | null; vendor: string | null; available: boolean } {\n if (typeof document === 'undefined') return { renderer: null, vendor: null, available: false };\n try {\n const gl = document.createElement('canvas').getContext('webgl');\n if (!gl) return { renderer: null, vendor: null, available: false };\n const debug = gl.getExtension('WEBGL_debug_renderer_info');\n const renderer = debug ? gl.getParameter(debug.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER);\n const vendor = debug ? gl.getParameter(debug.UNMASKED_VENDOR_WEBGL) : gl.getParameter(gl.VENDOR);\n gl.getExtension('WEBGL_lose_context')?.loseContext();\n return { renderer: asString(renderer), vendor: asString(vendor), available: true };\n } catch {\n // A blocklisted driver, a headless browser, or WebGL disabled outright —\n // all of which are themselves an answer to \"why is compositing slow\".\n return { renderer: null, vendor: null, available: false };\n }\n}\n\nfunction matches(query: string): boolean {\n try {\n return window.matchMedia(query).matches;\n } catch {\n return false;\n }\n}\n\n/** Snapshot the machine. Synchronous — pass what `requestAsyncEnvironment`\n * resolved earlier, or null if it never arrived. */\nexport function readEnvironment(async_: AsyncEnvironment | null): PerfEnvironment {\n const nav = navigator as Navigator & { deviceMemory?: number; connection?: ConnectionLike };\n const memory = (performance as Performance & { memory?: ChromeMemoryLike }).memory;\n const hints = async_?.hints ?? null;\n const gpu = readGpu();\n const conn = nav.connection;\n return {\n userAgent: nav.userAgent,\n browser: hints?.browser ?? null,\n platform: hints?.platform ?? null,\n platformVersion: hints?.platformVersion ?? null,\n architecture: hints?.architecture ?? null,\n model: hints?.model ?? null,\n cpuCores: typeof nav.hardwareConcurrency === 'number' ? nav.hardwareConcurrency : null,\n deviceMemoryGB: typeof nav.deviceMemory === 'number' ? nav.deviceMemory : null,\n gpu: gpu.renderer,\n gpuVendor: gpu.vendor,\n webglAvailable: gpu.available,\n screen: {\n width: screen.width,\n height: screen.height,\n dpr: window.devicePixelRatio,\n colorDepth: typeof screen.colorDepth === 'number' ? screen.colorDepth : null,\n },\n viewport: { width: window.innerWidth, height: window.innerHeight },\n heapLimitMB: memory ? Math.round(memory.jsHeapSizeLimit / 1048576) : null,\n network: conn\n ? {\n effectiveType: asString(conn.effectiveType),\n downlinkMbps: typeof conn.downlink === 'number' ? conn.downlink : null,\n rttMs: typeof conn.rtt === 'number' ? conn.rtt : null,\n saveData: conn.saveData === true,\n }\n : null,\n battery: async_?.battery ?? null,\n prefersReducedMotion: matches('(prefers-reduced-motion: reduce)'),\n forcedColors: matches('(forced-colors: active)'),\n reducedTransparency: document.documentElement.classList.contains('rosh-reduce-transparency'),\n touchPoints: typeof nav.maxTouchPoints === 'number' ? nav.maxTouchPoints : null,\n };\n}\n\n/**\n * One line naming the machine, for a report title or a bug-tracker\n * description — the place where a reader decides whether this report is about\n * a slow machine or a slow application. The full record is in the attachment;\n * this is the digest.\n *\n * Omits what it does not know rather than printing \"unknown\": a line of\n * absences reads as a broken probe, when in truth Firefox simply does not\n * publish RAM.\n */\nexport function describeMachine(env: PerfEnvironment): string {\n const parts: string[] = [];\n if (env.browser) parts.push(env.browser);\n const os = [env.platform, env.platformVersion].filter(Boolean).join(' ');\n if (os) parts.push(env.architecture ? `${os} (${env.architecture})` : os);\n if (env.gpu) parts.push(env.gpu);\n else if (!env.webglAvailable) parts.push('no WebGL (software rendering)');\n if (env.cpuCores) parts.push(`${env.cpuCores} cores`);\n if (env.deviceMemoryGB) parts.push(`${env.deviceMemoryGB}GB+ RAM`);\n parts.push(`${env.screen.width}×${env.screen.height} @${env.screen.dpr}x`);\n // Flags only when they are true — each one is a live explanation for a low\n // frame rate, and a list of \"off\" states is noise.\n if (env.battery && !env.battery.charging) parts.push(`on battery ${Math.round(env.battery.level * 100)}%`);\n if (env.reducedTransparency) parts.push('reduce transparency on');\n if (env.prefersReducedMotion) parts.push('reduced motion');\n return parts.join(' · ');\n}\n","/**\n * Desktop performance HUD — an opt-in overlay that measures where the UI is\n * actually spending its time, so \"it feels laggy\" can become a number someone\n * can act on, and a report someone can file.\n *\n * Filing is the end of the story, not an export: the person who can see the\n * jank is rarely the person who can fix it, and a downloaded JSON that has to\n * be found, attached and explained mostly does not get sent. One button\n * freezes the log, asks the one question a log cannot answer — what were you\n * doing? — and hands both to the host's feedback channel.\n *\n * Two rules shape the implementation, both about not corrupting the reading:\n *\n * 1. **The HUD must be nearly free to render.** The rAF loop and the activity\n * counters write to refs and never set state; a 500ms interval is the only\n * thing that re-renders, and the session log lives in a ref too — only its\n * size is state, because only its size is on screen. A HUD that\n * re-rendered per frame would be measuring itself.\n * 2. **No frosted glass on the panel.** Every other surface in the shell\n * uses `glassStyle()`, but a perf overlay that costs a 40px backdrop blur\n * would add exactly the GPU load it is trying to attribute. Solid\n * background, deliberately.\n *\n * Caveat worth knowing when reading the numbers: a running rAF loop keeps the\n * browser rendering continuously, so an idle desktop with the HUD open is\n * doing more work than an idle desktop without it. Read the numbers while\n * actually using the UI — scrolling, dragging a window, opening a menu — which\n * is when the interesting jank happens anyway.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { classify, summariseFrames, type PerfReading, type Verdict } from './perfVerdict';\nimport { appendRecord, summariseLog, type LogSummary, type PerfLogRecord } from './perfLog';\nimport { drainPerfEvents, setPerfCollecting } from './perfEvents';\nimport {\n readEnvironment,\n requestAsyncEnvironment,\n type AsyncEnvironment,\n type PerfEnvironment,\n} from './perfEnvironment';\n\n/** How often the accumulated frame data is turned into a render and a log record. */\nconst FLUSH_MS = 500;\n/** Rolling window of frames each reading is computed from. */\nconst WINDOW_MS = 1000;\n/** Sparkline width, in flush samples — 40 × 500ms ≈ 20s of history, enough to\n * catch intermittent hitches (a periodic refetch, a GC pause) that a single\n * instantaneous number hides. */\nconst HISTORY = 40;\n/** The log is mirrored to localStorage this often, so a reload or a crash does\n * not throw away a session someone spent ten minutes reproducing. Throttled\n * rather than per-flush because serialising thousands of records twice a\n * second would itself become main-thread work the HUD would then report. */\nconst PERSIST_EVERY_MS = 10_000;\nconst LOG_STORAGE_KEY = 'react-os-shell:perf-log';\n/** Longest gap between two pointer moves still counted as drag time. Far above\n * one frame even on a machine in trouble, so a real drag is never clipped; a\n * gap beyond it means the pointer stopped. */\nconst MAX_DRAG_GAP_MS = 100;\n\n/** Chrome exposes heap numbers off `performance`; nothing else does, and it is\n * not in any spec — hence the local shape rather than a lib type. */\ninterface ChromeMemory {\n usedJSHeapSize: number;\n jsHeapSizeLimit: number;\n}\n\nconst VERDICT_STYLES: Record<Verdict['kind'], { dot: string; text: string }> = {\n smooth: { dot: 'bg-emerald-400', text: 'text-emerald-300' },\n gpu: { dot: 'bg-amber-400', text: 'text-amber-300' },\n cpu: { dot: 'bg-sky-400', text: 'text-sky-300' },\n unknown: { dot: 'bg-gray-400', text: 'text-gray-300' },\n};\n\n/** Count the open shell windows and identify the topmost one. Read from the\n * DOM rather than threaded through context because that is how the shell\n * already counts its own windows (Layout, WindowManager), and a diagnostic\n * should observe what is really on screen rather than trust a mirror of it. */\nfunction readWindows(): { windows: number; active: string | null } {\n if (typeof document === 'undefined') return { windows: 0, active: null };\n const panels = document.querySelectorAll<HTMLElement>('[data-modal-panel]');\n let active: string | null = null;\n let topZ = -Infinity;\n panels.forEach(panel => {\n const z = parseInt(window.getComputedStyle(panel).zIndex, 10);\n // `auto` parses to NaN; fall back to DOM order, which is paint order.\n const rank = Number.isFinite(z) ? z : 0;\n if (rank >= topZ) {\n topZ = rank;\n active = panel.dataset.windowKey ?? panel.dataset.modalId ?? null;\n }\n });\n return { windows: panels.length, active };\n}\n\n/** A finished report, handed to the host to file. The JSON is pre-serialised\n * because the host's job is to attach it, not to re-derive it; `summary` and\n * `verdict` come along so a host can title or route the report without\n * parsing the attachment back apart. */\nexport interface PerfReport {\n /** What the user typed about what they were doing. May be empty. */\n message: string;\n /** Suggested attachment filename, stamped with the local time. */\n filename: string;\n /** The whole report — environment, summary and every raw record. */\n json: string;\n summary: LogSummary;\n /** The HUD's current headline, e.g. \"GPU-bound (compositing)\". */\n verdict: string;\n /** The machine the readings came off — GPU, cores, memory, OS, screen. A\n * verdict of \"GPU-bound\" is not actionable until you know which GPU. */\n environment: PerfEnvironment;\n}\n\nexport interface PerfStatsProps {\n /** Dismiss handler — the shell wires this to turn the pref back off, so the\n * HUD can be closed from itself rather than only from Preferences. */\n onClose?: () => void;\n /** File the report through the host's own feedback channel — the whole point\n * of the HUD, since a log that reaches nobody fixes nothing. Rejecting\n * surfaces the error and keeps the composer open with the text intact.\n * Without it the button downloads the same JSON instead, so the shell stays\n * usable standalone. */\n onSubmit?: (report: PerfReport) => void | Promise<void>;\n className?: string;\n}\n\nexport default function PerfStats({ onClose, onSubmit, className = '' }: PerfStatsProps) {\n const framesRef = useRef<number[]>([]);\n const blockedMsRef = useRef(0);\n const activityRef = useRef({ clicks: 0, keys: 0, scrolls: 0, dragMs: 0 });\n const dragRef = useRef({ down: false, since: 0 });\n const logRef = useRef<PerfLogRecord[]>([]);\n const startedAtRef = useRef(0);\n const persistedAtRef = useRef(0);\n\n /** The log as it stood when the composer opened. Frozen there so the twenty\n * seconds someone spends typing \"the second-level menu stutters\" do not\n * become twenty samples of typing at the end of the very report that\n * sentence is about. */\n const snapshotRef = useRef<PerfLogRecord[] | null>(null);\n /** Client hints and battery state are async and unchanging, so they are\n * fetched once here and read synchronously when a report is built. */\n const envRef = useRef<AsyncEnvironment | null>(null);\n\n const [longTaskSupported, setLongTaskSupported] = useState(false);\n const [reading, setReading] = useState<PerfReading>({ fps: 0, frameMs: 0, worstMs: 0, blockedPct: null });\n const [history, setHistory] = useState<number[]>([]);\n const [heap, setHeap] = useState<{ usedMB: number; limitMB: number } | null>(null);\n const [logSize, setLogSize] = useState(0);\n const [composing, setComposing] = useState(false);\n const [message, setMessage] = useState('');\n const [sending, setSending] = useState(false);\n const [sendError, setSendError] = useState<string | null>(null);\n\n // ── Interaction marks: menus and window gestures only accumulate while the\n // HUD is up. See perfEvents for why a counter left running would lie.\n useEffect(() => {\n setPerfCollecting(true);\n return () => setPerfCollecting(false);\n }, []);\n\n // ── Machine detail. Resolved on mount rather than at report time: the values\n // cannot change, and some browsers gate high-entropy hints behind a\n // prompt that must not fire while someone is filing a report.\n useEffect(() => {\n let live = true;\n requestAsyncEnvironment().then(env => { if (live) envRef.current = env; });\n return () => { live = false; };\n }, []);\n\n // ── Frame sampling: refs only, so this never triggers a render ──\n useEffect(() => {\n let raf = 0;\n const tick = (now: number) => {\n const frames = framesRef.current;\n frames.push(now);\n const cutoff = now - WINDOW_MS;\n while (frames.length && frames[0] < cutoff) frames.shift();\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, []);\n\n // ── Long tasks: the signal that separates a busy main thread from a busy GPU ──\n useEffect(() => {\n if (typeof PerformanceObserver === 'undefined') return;\n let observer: PerformanceObserver | undefined;\n try {\n observer = new PerformanceObserver(list => {\n for (const entry of list.getEntries()) blockedMsRef.current += entry.duration;\n });\n observer.observe({ entryTypes: ['longtask'] });\n setLongTaskSupported(true);\n } catch {\n // Safari has no `longtask` entry type. Leaving `longTaskSupported`\n // false makes the verdict report \"cause unknown\" rather than silently\n // attributing every dropped frame to the GPU.\n return;\n }\n return () => observer?.disconnect();\n }, []);\n\n // ── Activity: what the user was doing while the frames were being measured ──\n useEffect(() => {\n // Every handler reads `activityRef.current` at call time rather than\n // closing over the object. The flush zeroes these counters in place for\n // the same reason: an earlier version swapped in a fresh object each\n // flush, which silently orphaned the one these listeners were still\n // incrementing — the log kept recording zero activity forever after the\n // first interval, while looking perfectly healthy.\n const onPointerDown = () => {\n activityRef.current.clicks++;\n dragRef.current = { down: true, since: performance.now() };\n };\n const onPointerMove = () => {\n if (!dragRef.current.down) return;\n const now = performance.now();\n const gap = now - dragRef.current.since;\n dragRef.current.since = now;\n // Only time the pointer actually spent moving. Without the cap, a press\n // held still for five seconds and then nudged credits all five to the\n // move it ended on — which is how a 500ms interval came to report 5,004ms\n // of dragging, a number that cannot be true and quietly discredits the\n // column beside it. A gap this long is a stationary press, not a drag.\n if (gap <= MAX_DRAG_GAP_MS) activityRef.current.dragMs += gap;\n };\n const onPointerUp = () => { dragRef.current.down = false; };\n const onKeyDown = () => { activityRef.current.keys++; };\n const onWheel = () => { activityRef.current.scrolls++; };\n\n // Capture phase, so a handler that stops propagation cannot hide activity\n // from the log; passive, so the HUD never delays the very input it times.\n const opts = { capture: true, passive: true } as const;\n window.addEventListener('pointerdown', onPointerDown, opts);\n window.addEventListener('pointermove', onPointerMove, opts);\n window.addEventListener('pointerup', onPointerUp, opts);\n window.addEventListener('pointercancel', onPointerUp, opts);\n window.addEventListener('keydown', onKeyDown, opts);\n window.addEventListener('wheel', onWheel, opts);\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, opts);\n window.removeEventListener('pointermove', onPointerMove, opts);\n window.removeEventListener('pointerup', onPointerUp, opts);\n window.removeEventListener('pointercancel', onPointerUp, opts);\n window.removeEventListener('keydown', onKeyDown, opts);\n window.removeEventListener('wheel', onWheel, opts);\n };\n }, []);\n\n const persist = useCallback(() => {\n try {\n localStorage.setItem(LOG_STORAGE_KEY, JSON.stringify(logRef.current));\n } catch {\n // A full or disabled localStorage must never take the HUD down — the\n // in-memory log and the exports still work without it.\n }\n }, []);\n\n // ── Durability: the throttle above can leave up to PERSIST_EVERY_MS of\n // unsaved tail, and the tail is exactly the part someone was watching\n // when they gave up and closed the tab. Flush on the way out. `pagehide`\n // rather than `beforeunload` because it also fires when a tab is frozen\n // or restored from the back/forward cache, which `beforeunload` misses.\n useEffect(() => {\n const onHide = () => persist();\n window.addEventListener('pagehide', onHide);\n document.addEventListener('visibilitychange', onHide);\n return () => {\n window.removeEventListener('pagehide', onHide);\n document.removeEventListener('visibilitychange', onHide);\n persist();\n };\n }, [persist]);\n\n // ── Flush: the only thing here that renders ──\n useEffect(() => {\n const id = setInterval(() => {\n const now = performance.now();\n if (!startedAtRef.current) startedAtRef.current = now;\n\n const frames = summariseFrames(framesRef.current);\n const blockedPct = longTaskSupported\n ? Math.min(100, (blockedMsRef.current / FLUSH_MS) * 100)\n : null;\n blockedMsRef.current = 0;\n\n const memory = (performance as Performance & { memory?: ChromeMemory }).memory;\n const heapMB = memory ? memory.usedJSHeapSize / 1048576 : null;\n const nextReading: PerfReading = { ...frames, blockedPct };\n\n const activity = activityRef.current;\n const events = drainPerfEvents();\n const { windows, active } = readWindows();\n logRef.current = appendRecord(logRef.current, {\n t: Math.round(now - startedAtRef.current),\n ...frames,\n blockedPct,\n heapMB,\n verdict: classify(nextReading).kind,\n windows,\n active,\n clicks: activity.clicks,\n keys: activity.keys,\n scrolls: activity.scrolls,\n dragMs: Math.round(activity.dragMs),\n menus: events.menus,\n submenus: events.submenus,\n menuKey: events.menuKey,\n moveMs: Math.round(events.moveMs),\n resizeMs: Math.round(events.resizeMs),\n });\n // Zero in place — never reassign. See the listener effect above.\n activity.clicks = 0;\n activity.keys = 0;\n activity.scrolls = 0;\n activity.dragMs = 0;\n\n // Zero means \"never written\", so the first flush always persists. Timing\n // the throttle off `performance.now()` alone would measure from page\n // load, not from when logging started — opening the HUD on a fresh page\n // would then leave the log unsaved for the first ten seconds, while\n // opening it on a long-lived tab would save on the very first flush.\n if (!persistedAtRef.current || now - persistedAtRef.current >= PERSIST_EVERY_MS) {\n persistedAtRef.current = now;\n persist();\n }\n\n setReading(nextReading);\n setHistory(prev => [...prev, frames.fps].slice(-HISTORY));\n setHeap(memory ? { usedMB: memory.usedJSHeapSize / 1048576, limitMB: memory.jsHeapSizeLimit / 1048576 } : null);\n setLogSize(logRef.current.length);\n }, FLUSH_MS);\n return () => clearInterval(id);\n }, [longTaskSupported, persist]);\n\n /** Freeze the log and open the composer. */\n const beginReport = useCallback(() => {\n snapshotRef.current = logRef.current.slice();\n setSendError(null);\n setComposing(true);\n }, []);\n\n const verdict = classify(reading);\n\n /** Build the report from the frozen snapshot. The summary rides alongside the\n * raw records so whoever opens the file gets the conclusion without having\n * to run the analysis themselves, and the user's own sentence goes in the\n * file too — the attachment has to stand alone once it is detached from the\n * message that carried it. */\n const buildReport = useCallback((): PerfReport => {\n const records = snapshotRef.current ?? logRef.current;\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n const summary = summariseLog(records);\n const environment = readEnvironment(envRef.current);\n return {\n message,\n filename: `perf-log-${stamp}.json`,\n summary,\n environment,\n verdict: verdict.label,\n json: JSON.stringify(\n {\n generatedAt: new Date().toISOString(),\n message,\n verdict: verdict.label,\n environment,\n summary,\n records,\n },\n null,\n 2,\n ),\n };\n }, [message, verdict.label]);\n\n /** Fallback when no host channel is wired: the same JSON, to disk. */\n const downloadReport = useCallback((report: PerfReport) => {\n const url = URL.createObjectURL(new Blob([report.json], { type: 'application/json' }));\n const link = document.createElement('a');\n link.href = url;\n link.download = report.filename;\n link.click();\n URL.revokeObjectURL(url);\n }, []);\n\n const send = useCallback(async () => {\n const report = buildReport();\n setSending(true);\n setSendError(null);\n try {\n if (onSubmit) await onSubmit(report);\n else downloadReport(report);\n snapshotRef.current = null;\n setMessage('');\n setComposing(false);\n } catch (err) {\n // Keep the composer open with the text intact — retyping a description\n // of something that has already stopped happening is how a report stops\n // getting filed at all.\n setSendError(err instanceof Error && err.message ? err.message : 'Could not send. Try again.');\n } finally {\n setSending(false);\n }\n }, [buildReport, downloadReport, onSubmit]);\n\n const styles = VERDICT_STYLES[verdict.kind];\n const peak = Math.max(60, ...history);\n const loggedSeconds = Math.round((logSize * FLUSH_MS) / 1000);\n const sendLabel = onSubmit ? 'Send' : 'Download';\n const reportSamples = snapshotRef.current?.length ?? logSize;\n\n return (\n <div\n className={`w-56 rounded-lg border border-white/15 bg-[#11111b]/95 px-3 py-2 font-mono text-[10px] text-white/80 shadow-lg select-none ${className}`}\n /* No backdrop-filter here on purpose — see the module docstring. */\n role=\"status\"\n aria-live=\"off\"\n aria-label=\"Performance statistics\"\n >\n <div className=\"mb-1.5 flex items-center justify-between\">\n <span className=\"text-[9px] uppercase tracking-wider text-white/40\">Performance</span>\n {onClose && (\n <button\n onClick={onClose}\n className=\"-mr-1 px-1 leading-none text-white/40 transition-colors hover:text-white/90\"\n aria-label=\"Hide performance statistics\"\n >\n ×\n </button>\n )}\n </div>\n\n <div className=\"flex items-baseline justify-between\">\n <span className={`text-base font-semibold tabular-nums ${styles.text}`}>\n {reading.fps ? reading.fps.toFixed(0) : '—'}\n <span className=\"ml-1 text-[10px] font-normal text-white/40\">fps</span>\n </span>\n <span className=\"tabular-nums text-white/50\">\n {reading.frameMs ? `${reading.frameMs.toFixed(1)} ms` : '—'}\n </span>\n </div>\n\n {/* Frame-rate history. Plain divs: cheap to lay out, and a shape is far\n quicker to read than a column of numbers when hunting a periodic hitch. */}\n <div className=\"mt-1.5 flex h-5 items-end gap-px\" aria-hidden=\"true\">\n {Array.from({ length: HISTORY }, (_, i) => {\n const value = history[history.length - HISTORY + i];\n return (\n <div\n key={i}\n className={`flex-1 rounded-sm ${value === undefined ? 'bg-white/5' : styles.dot}`}\n style={{ height: value === undefined ? '2px' : `${Math.max(6, (value / peak) * 100)}%` }}\n />\n );\n })}\n </div>\n\n <dl className=\"mt-2 space-y-0.5\">\n <Row label=\"worst frame\" value={reading.worstMs ? `${reading.worstMs.toFixed(0)} ms` : '—'} />\n <Row\n label=\"main thread\"\n value={reading.blockedPct === null ? 'n/a' : `${reading.blockedPct.toFixed(0)}% blocked`}\n />\n <Row\n label=\"JS heap\"\n value={heap ? `${heap.usedMB.toFixed(0)} / ${heap.limitMB.toFixed(0)} MB` : 'n/a'}\n />\n </dl>\n\n <div className=\"mt-2 border-t border-white/10 pt-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <span className={`h-1.5 w-1.5 shrink-0 rounded-full ${styles.dot}`} aria-hidden=\"true\" />\n <span className={`font-semibold ${styles.text}`}>{verdict.label}</span>\n </div>\n <p className=\"mt-0.5 leading-snug text-white/45\">{verdict.detail}</p>\n </div>\n\n <div className=\"mt-2 border-t border-white/10 pt-1.5\">\n {composing ? (\n /* Composer. `select-text` because the panel as a whole is\n `select-none` — without it the user cannot correct their own\n sentence. */\n <div className=\"select-text space-y-1.5\">\n <label className=\"block text-white/40\" htmlFor=\"perf-report-message\">\n What were you doing?\n </label>\n <textarea\n id=\"perf-report-message\"\n value={message}\n onChange={e => setMessage(e.target.value)}\n rows={3}\n autoFocus\n placeholder=\"e.g. opening the second-level menu stutters\"\n className=\"w-full resize-none rounded border border-white/15 bg-black/40 px-1.5 py-1 font-mono text-[10px] text-white/90 placeholder:text-white/25 focus:border-white/40 focus:outline-none\"\n />\n {sendError && <p className=\"leading-snug text-rose-300\">{sendError}</p>}\n <div className=\"flex items-center justify-between\">\n {/* Just the count — \"samples attached\" wraps to a second line in\n the panel's 224px and shoves the buttons down. */}\n <span className=\"text-white/35\">{reportSamples} samples</span>\n <span className=\"flex gap-1\">\n <button\n onClick={() => { setComposing(false); snapshotRef.current = null; setSendError(null); }}\n disabled={sending}\n className=\"rounded border border-white/15 px-1.5 py-0.5 text-white/50 transition-colors hover:border-white/30 hover:text-white disabled:opacity-40\"\n >\n Cancel\n </button>\n <button\n onClick={send}\n disabled={sending}\n className=\"rounded border border-white/30 bg-white/10 px-1.5 py-0.5 text-white/90 transition-colors hover:bg-white/20 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {sending ? 'Sending…' : sendLabel}\n </button>\n </span>\n </div>\n </div>\n ) : (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-white/35\">\n log {logSize} · {loggedSeconds < 60 ? `${loggedSeconds}s` : `${Math.round(loggedSeconds / 60)}m`}\n </span>\n <button\n onClick={beginReport}\n disabled={!logSize}\n className=\"rounded border border-white/15 px-1.5 py-0.5 text-white/60 transition-colors hover:border-white/30 hover:text-white disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {onSubmit ? 'Report this' : 'Save report'}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-baseline justify-between gap-2\">\n <dt className=\"text-white/40\">{label}</dt>\n <dd className=\"tabular-nums text-white/70\">{value}</dd>\n </div>\n );\n}\n","/**\n * INTERNAL stub — Desktop's What's New modal references the consumer-side\n * changelog. The package ships no built-in changelog; the consumer wires\n * their own through `DesktopHostConfig.productChangelog` (the What's New\n * dialog reads it first, and this empty default keeps the import compiling\n * when they don't). Layout's `branding` prop carries the rest of the visual\n * identity — name, logo, tagline.\n */\nexport interface ChangelogEntry {\n version: string;\n date: string;\n changes: string[];\n}\nconst changelog: ChangelogEntry[] = [];\nexport default changelog;\n","import { useState, useRef, useEffect, useCallback, createContext, useContext, type ReactNode } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useWindowManager } from './WindowManager';\nimport { useShellStrings } from './strings';\nimport { useShellPrefs } from './ShellPrefs';\nimport Modal from './Modal';\nimport MarkdownLite from './Markdown';\nimport WidgetManager from './WidgetManager';\nimport PerfStats, { type PerfReport } from './PerfStats';\nimport { APP_VERSION } from '../version';\nimport changelog, { type ChangelogEntry } from '../changelog';\nimport toast from './toast';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport { formatDate } from '../utils/date';\nimport {\n openPreviewFile,\n PREVIEW_OPENED_EVENT,\n type PreviewFileKind,\n type PreviewOpenedDetail,\n} from '../utils/openPreviewFile';\n\n// Icon tiles, entity-icon config and the Files-app bridge live in\n// desktopIcons.tsx so Files can share them without importing Desktop.\nimport {\n FileIconTile,\n FolderGlyph,\n publishDesktopFolders,\n requestFilesDesktopFolderView,\n requestFilesTrashView,\n type DesktopItem,\n} from './desktopIcons';\n\nconst DOCUMENTS_FOLDER_ID = 'documents';\nconst DOCUMENTS_FOLDER_NAME = 'Recent Documents';\n\ninterface DesktopFolder {\n id: string;\n name: string;\n x?: number;\n y?: number;\n}\n\nconst GRID = 90; // snap grid size\n\nfunction snapToGrid(x: number, y: number) {\n return { x: Math.round(x / GRID) * GRID, y: Math.round(y / GRID) * GRID };\n}\n\n// ── Consumer-supplied desktop config ────────────────────────────────────────\n//\n// Desktop talks to two consumer-specific things:\n// 1. A sticky-note ref resolver — turns `PREFIX#NUMBER` into an entity\n// window-registry key + id. Implementations look up numbering configs\n// and search the consumer's REST API.\n// 2. Persistence callbacks — where to save the user's reordered shortcuts,\n// created folders, snap toggle, etc. The shell hands the new array; the\n// consumer commits it (server profile, localStorage, whatever).\n//\n// Both default to no-ops, so the desktop renders as a static surface when no\n// provider is mounted.\n\nexport interface StickyEntityRef {\n /** Window-registry key used by `openEntity`. */\n entityType: string;\n entityId: string;\n /** Optional human-readable label (defaults to `${prefix}#${number}`). */\n label?: string;\n /** Optional pre-fetched entity payload passed to openEntity as snapshot. */\n snapshot?: unknown;\n}\n\nexport type StickyResolver = (prefix: string, number: string) => Promise<StickyEntityRef | null>;\n\n/** Optional items in the desktop right-click menu that a consumer can hide via\n * {@link DesktopHostConfig.hiddenContextMenuItems} — e.g. when they're surfaced\n * under Preferences instead. `'customization'` is the Preferences/Customization\n * shortcut, `'favorites'` the Favorites shortcut, `'about'` the About item,\n * `'perf-stats'` the performance-overlay toggle. */\nexport type DesktopContextMenuItem = 'customization' | 'favorites' | 'about' | 'perf-stats';\n\nexport interface DesktopHostConfig {\n /** Product name shown in the About dialog and desktop context menu. */\n productName?: string;\n /** Tagline shown under the product name in the About dialog. */\n productTagline?: string;\n /** Icon URL shown in the About dialog. Defaults to `/favicon.svg`. */\n productIcon?: string;\n /** Version string shown on the desktop watermark and About dialog. Falls\n * back to the react-os-shell package version if omitted. */\n productVersion?: string;\n /** Changelog rendered in the \"What's New\" dialog. Hidden when omitted. */\n productChangelog?: ChangelogEntry[];\n /** Copyright line in the About dialog footer. Hidden when omitted. */\n productCopyright?: string;\n /** Website URL in the About dialog footer. Hidden when omitted. */\n productWebsite?: string;\n /** Wallpaper picker options for the Customization settings page. */\n wallpapers?: { src: string; label: string }[];\n /** Resolves sticky-note refs (e.g. \"SO#27150\") to window-registry coords. */\n stickyResolver?: StickyResolver;\n /** Persists the user's desktop shortcut list. */\n saveShortcuts?: (items: DesktopItem[]) => void | Promise<void>;\n /** Persists the user's folder list. */\n saveFolders?: (folders: DesktopFolder[]) => void | Promise<void>;\n /** Persists the snap-to-grid preference. */\n saveSnap?: (snap: boolean) => void | Promise<void>;\n /** Persists the user's notepad / sticky-note content. */\n saveNotes?: (notes: unknown[]) => void | Promise<void>;\n /** Desktop right-click menu items to hide (all shown by default). Pass keys\n * here when the consumer surfaces them elsewhere — e.g. under Preferences. */\n hiddenContextMenuItems?: DesktopContextMenuItem[];\n /** Open the consumer's own \"report a bug / suggestion\" UI. When set, the\n * desktop and taskbar right-click menus show a \"Suggestion or Bug\" item that\n * calls this. Lets a consumer that files feedback natively (the shell itself\n * dropped bug reporting in v3.0.0) surface the familiar right-click entry. */\n onReportBug?: () => void;\n /** File a performance report from the desktop perf HUD through the same\n * feedback channel, with the session log attached. Unset, the HUD's button\n * downloads the report instead — which is a strictly worse outcome, because\n * a file on someone's Downloads folder is not a bug report. Rejecting shows\n * the error in the HUD and keeps what the user typed. */\n onSubmitPerfReport?: (report: PerfReport) => void | Promise<void>;\n}\n\nconst DesktopHostContext = createContext<DesktopHostConfig>({});\n\nexport function DesktopHostProvider({ value, children }: { value: DesktopHostConfig; children: ReactNode }) {\n return <DesktopHostContext.Provider value={value}>{children}</DesktopHostContext.Provider>;\n}\n\nexport function useDesktopHost(): DesktopHostConfig {\n return useContext(DesktopHostContext);\n}\n\n/**\n * The taskbar's EFFECTIVE position and thickness, for the desktop furniture\n * anchored to whichever corner it leaves free — the Trash tile below, and the\n * version watermark.\n *\n * Read from the custom properties `Layout` publishes on `<html>`, not from\n * `prefs.taskbar_position`, for two reasons: those carry the EFFECTIVE values\n * (sidebar mode forces the taskbar horizontal whatever the preference says),\n * and a `<Desktop>` mounted without a `<Layout>` — which is an exported,\n * supported shape — has no taskbar at all and no preference that says so.\n *\n * They are written in an effect, so the first render of a fresh mount reads\n * zero and the corner settles on the next one. That is the behaviour the Trash\n * has always had; the watermark now shares it rather than the two disagreeing.\n */\nfunction taskbarMetrics() {\n const cs = typeof document !== 'undefined' ? getComputedStyle(document.documentElement) : null;\n const position = (cs?.getPropertyValue('--taskbar-position') || 'bottom').trim();\n const vertical = position === 'left' || position === 'right';\n const height = parseInt(cs?.getPropertyValue('--taskbar-height') || '0') || 0;\n const width = parseInt(cs?.getPropertyValue('--taskbar-width') || '0') || 0;\n return { position, vertical, height, width };\n}\n\nexport default function Desktop({ profile }: { profile: any }) {\n const shellStrings = useShellStrings();\n const queryClient = useQueryClient();\n const { openEntity, openPage } = useWindowManager();\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Read desktop preferences from the consumer prefs adapter so they stay\n // in sync with what apps like Notepad write. Some legacy code paths\n // also expect them under profile.preferences — fall back to that for\n // consumers who haven't migrated.\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs = { ...(profile?.preferences || {}), ...shellPrefs };\n const favDocs: DesktopItem[] = prefs.favorite_documents || [];\n // \"Recent Documents\" is a system folder: like the Trash it is always on the\n // desktop and cannot be deleted or renamed. Injected at render rather than\n // persisted so it exists from first load even on an empty profile; a stored\n // copy (when present) contributes its position while the canonical name\n // wins — which also migrates pre-2.6 desktops whose stored copy is still\n // called \"Documents\".\n const storedFolders: DesktopFolder[] = prefs.desktop_folders || [];\n const folders: DesktopFolder[] = storedFolders.some(f => f.id === DOCUMENTS_FOLDER_ID)\n ? storedFolders.map(f => f.id === DOCUMENTS_FOLDER_ID ? { ...f, name: DOCUMENTS_FOLDER_NAME } : f)\n : [...storedFolders, { id: DOCUMENTS_FOLDER_ID, name: DOCUMENTS_FOLDER_NAME }];\n const snapEnabled: boolean = prefs.desktop_snap ?? false;\n\n // Sticky notes from notepad\n interface StickyNote { id: string; title: string; content: string; color: string; sticky: boolean; sticky_x?: number; sticky_y?: number; sticky_w?: number; sticky_h?: number; sticky_on_top?: boolean; sticky_anchor?: 'left' | 'right'; updated_at: string; }\n const allNotes: StickyNote[] = prefs.notepad_notes || [];\n const stickyNotes = allNotes.filter(n => n.sticky);\n\n // ── Entity reference support for sticky notes ──\n // The PREFIX#NUMBER → entity lookup is consumer-supplied; the shell only\n // calls the resolver and hands the result to openEntity().\n const host = useDesktopHost();\n const hiddenMenuItems = host.hiddenContextMenuItems ?? [];\n const openStickyRef = async (prefix: string, number: string) => {\n const refNum = `${prefix}#${number}`;\n if (!host.stickyResolver) { toast.error(`Unknown reference: ${refNum}`); return; }\n try {\n const result = await host.stickyResolver(prefix, number);\n if (result) openEntity(result.entityType, result.entityId, result.snapshot, result.label ?? refNum);\n else toast.error(`${refNum} not found`);\n } catch {\n toast.error(`Failed to open ${refNum}`);\n }\n };\n\n const toggleStickyCheckbox = (noteId: string, charIndex: number) => {\n const note = allNotes.find(n => n.id === noteId);\n if (!note) return;\n const content = note.content;\n const match = content.slice(charIndex).match(/^\\[([ xX]?)\\]/);\n if (!match) return;\n const isChecked = match[1] === 'x' || match[1] === 'X';\n const replacement = isChecked ? '[ ]' : '[x]';\n const updated = content.slice(0, charIndex) + replacement + content.slice(charIndex + match[0].length);\n saveNotes(allNotes.map(n => n.id === noteId ? { ...n, content: updated, updated_at: new Date().toISOString() } : n));\n };\n\n const renderStickyContent = (noteId: string, text: string): ReactNode[] => {\n if (!text) return [];\n const lines = text.split('\\n');\n let charOffset = 0;\n return lines.map((line, li) => {\n const lineStart = charOffset;\n charOffset += line.length + 1;\n const tokens: { idx: number; len: number; render: () => ReactNode }[] = [];\n\n // Entity references — rendered as clickable when a resolver is configured;\n // if the resolver returns null at click-time the user sees a \"not found\" toast.\n const refRegex = /([A-Z]{2,4})#(\\d{4,6})/g;\n let m: RegExpExecArray | null;\n while ((m = refRegex.exec(line)) !== null) {\n if (host.stickyResolver) {\n const prefix = m[1], num = m[2], startIdx = m.index, matchText = m[0];\n tokens.push({ idx: startIdx, len: matchText.length, render: () => (\n <button key={`r-${li}-${startIdx}`} onClick={e => { e.stopPropagation(); openStickyRef(prefix, num); }}\n className=\"text-blue-700 hover:underline font-medium cursor-pointer\">{matchText}</button>\n )});\n }\n }\n\n // Checkboxes\n const cbRegex = /\\[([ xX]?)\\]/g;\n while ((m = cbRegex.exec(line)) !== null) {\n const isChecked = m[1] === 'x' || m[1] === 'X';\n const startIdx = m.index;\n const contentCharIdx = lineStart + startIdx;\n tokens.push({ idx: startIdx, len: m[0].length, render: () => (\n <button key={`c-${li}-${startIdx}`} onClick={e => { e.stopPropagation(); toggleStickyCheckbox(noteId, contentCharIdx); }}\n className={`inline-flex items-center justify-center w-3.5 h-3.5 rounded border ${isChecked ? 'bg-blue-500 border-blue-500 text-white' : 'border-gray-500 bg-white/50 hover:border-blue-400'} cursor-pointer align-text-bottom mr-0.5`}>\n {isChecked && <svg className=\"w-2.5 h-2.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>}\n </button>\n )});\n }\n\n tokens.sort((a, b) => a.idx - b.idx);\n const parts: ReactNode[] = [];\n let lastIdx = 0;\n for (const t of tokens) {\n if (t.idx > lastIdx) parts.push(<span key={`t-${li}-${lastIdx}`}>{line.slice(lastIdx, t.idx)}</span>);\n parts.push(t.render());\n lastIdx = t.idx + t.len;\n }\n if (lastIdx < line.length) parts.push(<span key={`t-${li}-${lastIdx}`}>{line.slice(lastIdx)}</span>);\n if (parts.length === 0) parts.push(<span key={`e-${li}`}>{'\\u200B'}</span>);\n\n const lineHasChecked = /^\\[x\\]/i.test(line.trimStart());\n return <div key={li} className={lineHasChecked ? 'line-through opacity-50' : ''}>{parts}</div>;\n });\n };\n\n // State\n const [dragging, setDragging] = useState<{ type: 'item' | 'folder' | 'trash'; idx: number; startX: number; startY: number; origX: number; origY: number } | null>(null);\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number; itemIdx?: number; folderIdx?: number } | null>(null);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [rubberBand, setRubberBand] = useState<{ startX: number; startY: number; endX: number; endY: number } | null>(null);\n const [aboutOpen, setAboutOpen] = useState(false);\n const [whatsNewOpen, setWhatsNewOpen] = useState(false);\n const [widgetsOpen, setWidgetsOpen] = useState(false);\n const [renamingFolder, setRenamingFolder] = useState<string | null>(null);\n const [renameValue, setRenameValue] = useState('');\n const [editingStickyId, setEditingStickyId] = useState<string | null>(null);\n const [stickyDrag, setStickyDrag] = useState<{ id: string; startX: number; startY: number; origX: number; origY: number } | null>(null);\n const [stickyResize, setStickyResize] = useState<{ id: string; startX: number; startY: number; origW: number; origH: number } | null>(null);\n // Index of the folder the user is currently hovering while dragging an\n // icon — drives the lift / glow animation and the on-drop fold-in.\n const [hoverFolderIdx, setHoverFolderIdx] = useState<number | null>(null);\n const hoverFolderIdxRef = useRef<number | null>(null);\n\n // Save helpers — delegate persistence to the consumer-supplied callbacks\n // when wired, otherwise write through the prefs adapter so backend-less\n // demos still survive a reload.\n const saveDocs = useCallback((docs: DesktopItem[]) => {\n if (host.saveShortcuts) host.saveShortcuts(docs);\n else saveShellPrefs({ favorite_documents: docs });\n }, [host, saveShellPrefs]);\n\n const saveFolders = useCallback((f: DesktopFolder[]) => {\n if (host.saveFolders) host.saveFolders(f);\n else saveShellPrefs({ desktop_folders: f });\n }, [host, saveShellPrefs]);\n\n const saveSnap = useCallback((v: boolean) => {\n if (host.saveSnap) host.saveSnap(v);\n else saveShellPrefs({ desktop_snap: v });\n }, [host, saveShellPrefs]);\n\n // Latest-state refs so handlers registered once (the preview-opened event\n // listener, the Files-app bridge callbacks) always read the current\n // folders / favDocs instead of stale closure values from initial mount.\n const liveStateRef = useRef({ folders, favDocs, saveFolders, saveDocs });\n liveStateRef.current = { folders, favDocs, saveFolders, saveDocs };\n\n // When the user previews a file (via Files app or a Recent Documents\n // shortcut), drop a dedup'd shortcut into the \"Recent Documents\" system\n // folder. The folder always exists, so there is nothing to create here.\n useEffect(() => {\n const handler = (e: Event) => {\n const detail = (e as CustomEvent<PreviewOpenedDetail>).detail;\n if (!detail?.filePath) return;\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const deduped = docs.filter(d =>\n !(d.entityType === 'preview-file' && d.filePath === detail.filePath),\n );\n const next: DesktopItem = {\n entityType: 'preview-file',\n entityId: detail.filePath,\n label: detail.filename,\n filePath: detail.filePath,\n fileKind: detail.kind,\n folderId: DOCUMENTS_FOLDER_ID,\n };\n sd([next, ...deduped]);\n };\n window.addEventListener(PREVIEW_OPENED_EVENT, handler);\n return () => window.removeEventListener(PREVIEW_OPENED_EVENT, handler);\n }, []);\n\n // Positions stored as { right, top } — distance from right/top edges\n // This keeps icons anchored to the top-right regardless of window size\n const getDefaultPos = (idx: number) => {\n const col = Math.floor(idx / 8);\n const row = idx % 8;\n return { right: 20 + col * GRID, top: 20 + row * GRID };\n };\n\n const getItemPos = (item: DesktopItem, idx: number) => {\n if (item.x != null && item.y != null) return { right: item.x, top: item.y };\n return getDefaultPos(idx);\n };\n\n const getFolderPos = (folder: DesktopFolder, idx: number) => {\n if (folder.x != null && folder.y != null) return { right: folder.x, top: folder.y };\n return getDefaultPos(favDocs.filter(d => !d.folderId).length + idx);\n };\n\n // Items not in any folder\n const desktopItems = favDocs.filter(d => !d.folderId);\n const folderItems = (folderId: string) => favDocs.filter(d => d.folderId === folderId);\n\n // Open a shortcut — shared by icon double-click and the context menu.\n const openItem = (item: DesktopItem) => {\n if (item.entityType === 'preview-file' && item.filePath && item.fileKind) {\n openPreviewFile({\n filePath: item.filePath,\n filename: item.label,\n kind: item.fileKind,\n onStaged: route => openPage(route),\n });\n } else if (item.entityType === 'page') {\n openPage(item.entityId);\n } else {\n openEntity(item.entityType, item.entityId, null, item.label);\n }\n };\n\n // Desktop folders open in the Files app (same side-channel the Trash icon\n // uses): flag + event for an already-open instance, then route to /files.\n const openDesktopFolder = (folderId: string) => {\n requestFilesDesktopFolderView(folderId);\n openPage('/files');\n };\n\n // ── Files-app bridge ──\n // Publish the live folder list (and mutation callbacks) so the Files app\n // can list desktop folders in its sidebar and render their contents.\n const bridgeMoveToDesktop = useCallback((toMove: DesktopItem[]) => {\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const ids = new Set(toMove.map(t => `${t.entityType}|${t.entityId}`));\n sd(docs.map(d =>\n d.folderId && ids.has(`${d.entityType}|${d.entityId}`)\n ? { ...d, folderId: undefined, folderX: undefined, folderY: undefined }\n : d,\n ));\n }, []);\n\n const bridgeRemoveShortcuts = useCallback((toRemove: DesktopItem[]) => {\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const ids = new Set(toRemove.map(t => `${t.entityType}|${t.entityId}`));\n sd(docs.filter(d => !(d.folderId && ids.has(`${d.entityType}|${d.entityId}`))));\n }, []);\n\n // ── Drag logic ──\n // Local position overrides — applied immediately on drop, before API responds\n const [localPositions, setLocalPositions] = useState<Record<string, { right: number; top: number }>>({});\n // When the drag starts on a selected icon, all selected icons move together.\n // dragEntriesRef holds one entry per moving icon: its element, type, index,\n // and origin position (relative to the desktop). The Trash rides along too\n // when it's part of the selection — its entry stores the BOTTOM offset in\n // `origY` (the icon is bottom-anchored), every other type stores the top.\n type DragEntry = { key: string; type: 'item' | 'folder' | 'trash'; idx: number; origX: number; origY: number; el: HTMLElement | null };\n const dragEntriesRef = useRef<DragEntry[]>([]);\n\n const startDrag = (type: 'item' | 'folder' | 'trash', idx: number, e: React.PointerEvent) => {\n if (e.button !== 0) return;\n const primaryKey = type === 'trash' ? 'trash' : `${type}-${idx}`;\n // If the icon being grabbed is in the current selection, every selected\n // icon comes along. Otherwise it's a single-icon drag and we replace\n // the selection with just this one.\n const draggingMulti = selected.has(primaryKey) && selected.size > 1;\n const keys = draggingMulti ? Array.from(selected) : [primaryKey];\n\n const entries: DragEntry[] = [];\n for (const key of keys) {\n if (key.startsWith('item-')) {\n const i = parseInt(key.slice(5), 10);\n const itm = desktopItems[i];\n if (!itm) continue;\n const pos = getItemPos(itm, i);\n const el = document.querySelector(`[data-desktop-icon=\"${key}\"]`) as HTMLElement | null;\n entries.push({ key, type: 'item', idx: i, origX: pos.right, origY: pos.top, el });\n } else if (key.startsWith('folder-')) {\n const i = parseInt(key.slice(7), 10);\n const f = folders[i];\n if (!f) continue;\n const pos = getFolderPos(f, i);\n const el = document.querySelector(`[data-desktop-icon=\"${key}\"]`) as HTMLElement | null;\n entries.push({ key, type: 'folder', idx: i, origX: pos.right, origY: pos.top, el });\n } else if (key === 'trash') {\n const el = document.querySelector('[data-desktop-icon=\"trash\"]') as HTMLElement | null;\n if (!el) continue;\n // Read the live inline offsets React set (right/bottom anchoring).\n const right = parseFloat(el.style.right || '0') || 0;\n const bottom = parseFloat(el.style.bottom || '0') || 0;\n entries.push({ key, type: 'trash', idx: 0, origX: right, origY: bottom, el });\n }\n }\n dragEntriesRef.current = entries;\n const primaryEntry = entries.find(e => e.key === primaryKey) ?? entries[0];\n if (!primaryEntry) return;\n setDragging({ type, idx, startX: e.clientX, startY: e.clientY, origX: primaryEntry.origX, origY: primaryEntry.origY });\n e.preventDefault();\n };\n\n useEffect(() => {\n if (!dragging) return;\n const entries = dragEntriesRef.current;\n // Single-icon drags can fold into a folder; track which folder the\n // cursor is currently hovering over so the folder element can react\n // (scale + glow) and so we can short-circuit the right-overlap test\n // on drop.\n const isSingleItemDrag = entries.length === 1 && entries[0].type === 'item';\n\n // Drag-to-pin helpers: a single page shortcut dropped onto the taskbar\n // pins it to the taskbar strip (prefs.favorite_pages — see Layout.tsx,\n // which tags the bar with data-taskbar-dropzone). Returns the route to pin,\n // or null when the drag isn't a lone page shortcut.\n const draggedPageRoute = (): string | null => {\n if (!isSingleItemDrag) return null;\n const itm = desktopItems[entries[0].idx];\n return itm?.entityType === 'page' ? itm.entityId : null;\n };\n const taskbarEl = (): HTMLElement | null =>\n document.querySelector('[data-taskbar-dropzone]') as HTMLElement | null;\n const pointOverTaskbar = (x: number, y: number): boolean => {\n const tb = taskbarEl();\n if (!tb) return false;\n const r = tb.getBoundingClientRect();\n return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;\n };\n const setTaskbarDropHint = (on: boolean) => {\n const tb = taskbarEl();\n if (!tb) return;\n tb.style.outline = on ? '2px solid var(--accent-600, #7c3aed)' : '';\n tb.style.outlineOffset = on ? '-2px' : '';\n };\n\n const move = (e: PointerEvent) => {\n const dx = e.clientX - dragging.startX;\n const dy = e.clientY - dragging.startY;\n // Apply delta to every dragged icon.\n for (const entry of entries) {\n if (!entry.el) continue;\n // Moving right → decrease right offset; moving down → increase top\n // offset — except the Trash, whose origY is a BOTTOM offset, so\n // moving down decreases it.\n entry.el.style.right = `${entry.origX - dx}px`;\n if (entry.type === 'trash') {\n entry.el.style.bottom = `${entry.origY - dy}px`;\n } else {\n entry.el.style.top = `${entry.origY + dy}px`;\n entry.el.style.left = 'auto';\n }\n entry.el.style.zIndex = '100';\n entry.el.style.opacity = '0.7';\n }\n // Detect hover-over-folder for drop-into-folder UX.\n if (isSingleItemDrag) {\n const elsBelow = document.elementsFromPoint(e.clientX, e.clientY);\n let nextHover: number | null = null;\n for (const el of elsBelow) {\n const fk = (el as HTMLElement).closest?.('[data-desktop-icon^=\"folder-\"]');\n if (fk) {\n const key = (fk as HTMLElement).getAttribute('data-desktop-icon');\n if (key) nextHover = parseInt(key.slice(7), 10);\n break;\n }\n }\n hoverFolderIdxRef.current = nextHover;\n setHoverFolderIdx(prev => (prev === nextHover ? prev : nextHover));\n // Light the taskbar when a page shortcut is dragged over it.\n setTaskbarDropHint(draggedPageRoute() != null && pointOverTaskbar(e.clientX, e.clientY));\n }\n };\n const up = (e: PointerEvent) => {\n const dx = e.clientX - dragging.startX;\n const dy = e.clientY - dragging.startY;\n // Reset visual transform overrides on every dragged icon.\n for (const entry of entries) {\n if (!entry.el) continue;\n entry.el.style.zIndex = '';\n entry.el.style.opacity = '';\n }\n\n // Drag-to-pin: a lone page shortcut released over the taskbar gets pinned\n // to the taskbar strip (prefs.favorite_pages) instead of being moved.\n const pinRoute = draggedPageRoute();\n if (pinRoute && pointOverTaskbar(e.clientX, e.clientY)) {\n setTaskbarDropHint(false);\n // Snap the icon back to where it started — no position change persisted.\n for (const entry of entries) {\n if (!entry.el) continue;\n entry.el.style.left = 'auto';\n entry.el.style.right = `${entry.origX}px`;\n entry.el.style.top = `${entry.origY}px`;\n }\n const pages: string[] = Array.isArray(shellPrefs.favorite_pages) ? shellPrefs.favorite_pages : [];\n if (!pages.includes(pinRoute)) saveShellPrefs({ favorite_pages: [...pages, pinRoute] } as any);\n hoverFolderIdxRef.current = null;\n setHoverFolderIdx(null);\n setDragging(null);\n dragEntriesRef.current = [];\n return;\n }\n setTaskbarDropHint(false);\n\n const liveHoverIdx = hoverFolderIdxRef.current;\n const hoveredFolder = liveHoverIdx != null ? folders[liveHoverIdx] : null;\n hoverFolderIdxRef.current = null;\n setHoverFolderIdx(null);\n\n // Compute final positions for each dragged entry. The Trash is\n // bottom-anchored and never snaps — handled separately below.\n const computedPositions = entries.filter(en => en.type !== 'trash').map(entry => {\n let finalRight = entry.origX - dx;\n let finalTop = Math.max(0, entry.origY + dy);\n if (snapEnabled) { const s = snapToGrid(finalRight, finalTop); finalRight = s.x; finalTop = s.y; }\n finalRight = Math.max(0, finalRight);\n return { entry, finalRight, finalTop };\n });\n\n // Persist the trash's new corner offsets when it rode along.\n const trashEntry = entries.find(en => en.type === 'trash');\n if (trashEntry) {\n saveShellPrefs({\n desktop_trash_position: {\n right: Math.max(0, trashEntry.origX - dx),\n bottom: Math.max(0, trashEntry.origY - dy),\n },\n } as any);\n }\n\n // Persist items.\n const itemMoves = computedPositions.filter(p => p.entry.type === 'item');\n if (itemMoves.length > 0) {\n const updated = [...favDocs];\n const positionsPatch: Record<string, { right: number; top: number }> = {};\n // Single-item drag onto a folder still folds in (multi-drag never folds).\n const singleItem = itemMoves.length === 1 && entries.length === 1 ? itemMoves[0] : null;\n // Prefer the actively-hovered folder (live cursor hit-test) and fall\n // back to a position-overlap check for snap-to-grid edge cases.\n const droppedOnFolder = singleItem\n ? (hoveredFolder ?? folders.find((f, fi) => {\n const fp = getFolderPos(f, fi);\n return Math.abs(singleItem.finalRight - fp.right) < 40 && Math.abs(singleItem.finalTop - fp.top) < 40;\n }))\n : undefined;\n // Visual feedback: shrink the dragged icon into the folder before the\n // saved state actually removes it from the desktop.\n if (droppedOnFolder && singleItem?.entry.el) {\n const itemEl = singleItem.entry.el;\n const folderIdx = folders.indexOf(droppedOnFolder);\n const folderEl = document.querySelector(`[data-desktop-icon=\"folder-${folderIdx}\"]`) as HTMLElement | null;\n if (folderEl) {\n const ir = itemEl.getBoundingClientRect();\n const fr = folderEl.getBoundingClientRect();\n const dx = (fr.left + fr.width / 2) - (ir.left + ir.width / 2);\n const dy = (fr.top + fr.height / 2) - (ir.top + ir.height / 2);\n itemEl.style.transition = 'transform 220ms ease-out, opacity 220ms ease-out';\n itemEl.style.transform = `translate(${dx}px, ${dy}px) scale(0.2)`;\n itemEl.style.opacity = '0';\n }\n folderEl?.animate(\n [{ transform: 'scale(1)' }, { transform: 'scale(1.15)' }, { transform: 'scale(1)' }],\n { duration: 280, easing: 'ease-out' },\n );\n }\n for (const move of itemMoves) {\n const desktopIdx = favDocs.indexOf(desktopItems[move.entry.idx]);\n if (desktopIdx === -1) continue;\n if (droppedOnFolder) {\n updated[desktopIdx] = { ...updated[desktopIdx], folderId: droppedOnFolder.id, x: undefined, y: undefined, folderX: undefined, folderY: undefined };\n } else {\n updated[desktopIdx] = { ...updated[desktopIdx], x: move.finalRight, y: move.finalTop, folderId: undefined };\n positionsPatch[`item-${desktopIdx}`] = { right: move.finalRight, top: move.finalTop };\n }\n }\n // Defer the state update so the fold-in animation has time to play.\n const commit = () => {\n saveDocs(updated);\n if (Object.keys(positionsPatch).length > 0) {\n setLocalPositions(prev => ({ ...prev, ...positionsPatch }));\n }\n };\n if (droppedOnFolder) setTimeout(commit, 220);\n else commit();\n }\n\n // Persist folders.\n const folderMoves = computedPositions.filter(p => p.entry.type === 'folder');\n if (folderMoves.length > 0) {\n const updated = [...folders];\n const positionsPatch: Record<string, { right: number; top: number }> = {};\n for (const move of folderMoves) {\n updated[move.entry.idx] = { ...updated[move.entry.idx], x: move.finalRight, y: move.finalTop };\n positionsPatch[`folder-${move.entry.idx}`] = { right: move.finalRight, top: move.finalTop };\n }\n saveFolders(updated);\n setLocalPositions(prev => ({ ...prev, ...positionsPatch }));\n }\n\n setDragging(null);\n dragEntriesRef.current = [];\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [dragging, snapEnabled, favDocs, folders, desktopItems, shellPrefs]);\n\n // Clear local position overrides when profile data updates\n // Cache key has to include positions too — otherwise \"Snap to Grid\"\n // updates favDocs.x/y but the entityId list is unchanged, so the\n // localPositions overlay keeps the pre-snap values pinned in place.\n const favDocsKey = JSON.stringify(favDocs.map(d => `${d.entityId}:${d.x ?? ''}:${d.y ?? ''}:${d.folderId ?? ''}`));\n const foldersKey = JSON.stringify(folders.map(f => `${f.id}:${f.x ?? ''}:${f.y ?? ''}`));\n useEffect(() => { setLocalPositions({}); }, [favDocsKey, foldersKey]);\n\n // Re-publish the Files-app bridge whenever folders or their contents\n // change (the content keys above already capture both).\n useEffect(() => {\n const { folders: fs, favDocs: docs } = liveStateRef.current;\n const itemsByFolder: Record<string, DesktopItem[]> = {};\n for (const f of fs) itemsByFolder[f.id] = [];\n for (const d of docs) {\n if (d.folderId && itemsByFolder[d.folderId]) itemsByFolder[d.folderId].push(d);\n }\n publishDesktopFolders({\n folders: fs.map(f => ({ id: f.id, name: f.name, itemCount: itemsByFolder[f.id]?.length ?? 0 })),\n itemsByFolder,\n moveToDesktop: bridgeMoveToDesktop,\n removeShortcuts: bridgeRemoveShortcuts,\n });\n }, [favDocsKey, foldersKey, bridgeMoveToDesktop, bridgeRemoveShortcuts]);\n useEffect(() => () => publishDesktopFolders(null), []);\n\n // ── Rubber band selection ──\n const didRubberBandDragRef = useRef(false);\n const startRubberBand = (e: React.PointerEvent) => {\n if (e.button !== 0 || e.target !== containerRef.current) return;\n const rect = containerRef.current!.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setRubberBand({ startX: x, startY: y, endX: x, endY: y });\n didRubberBandDragRef.current = false;\n setSelected(new Set());\n };\n\n useEffect(() => {\n if (!rubberBand) return;\n const computeSelection = (minX: number, maxX: number, minY: number, maxY: number) => {\n const sel = new Set<string>();\n const cw = containerRef.current?.clientWidth || 800;\n desktopItems.forEach((item, i) => {\n const pos = getItemPos(item, i);\n const leftX = cw - pos.right - 80;\n if (leftX + 40 > minX && leftX < maxX && pos.top + 40 > minY && pos.top < maxY) {\n sel.add(`item-${i}`);\n }\n });\n folders.forEach((f, i) => {\n const pos = getFolderPos(f, i);\n const leftX = cw - pos.right - 80;\n if (leftX + 40 > minX && leftX < maxX && pos.top + 40 > minY && pos.top < maxY) {\n sel.add(`folder-${i}`);\n }\n });\n // The Trash is bottom-anchored (and movable), so measure its live DOM\n // rect instead of mirroring the right/top math used for the grid icons.\n const trashEl = containerRef.current?.querySelector('[data-desktop-icon=\"trash\"]');\n const containerRect = containerRef.current?.getBoundingClientRect();\n if (trashEl && containerRect) {\n const tr = trashEl.getBoundingClientRect();\n const tx = tr.left - containerRect.left;\n const ty = tr.top - containerRect.top;\n if (tx + tr.width > minX && tx < maxX && ty + tr.height > minY && ty < maxY) {\n sel.add('trash');\n }\n }\n return sel;\n };\n const move = (e: PointerEvent) => {\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n // Mark as a real drag once the cursor has moved more than a tap.\n const dx = x - rubberBand.startX;\n const dy = y - rubberBand.startY;\n if (dx * dx + dy * dy > 16) didRubberBandDragRef.current = true;\n setRubberBand(prev => prev ? { ...prev, endX: x, endY: y } : null);\n if (didRubberBandDragRef.current) {\n const minX = Math.min(rubberBand.startX, x);\n const maxX = Math.max(rubberBand.startX, x);\n const minY = Math.min(rubberBand.startY, y);\n const maxY = Math.max(rubberBand.startY, y);\n setSelected(computeSelection(minX, maxX, minY, maxY));\n }\n };\n const up = () => {\n setRubberBand(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [rubberBand]);\n\n // ── Context menu ──\n const handleDesktopContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n setContextMenu({ x: e.clientX, y: e.clientY });\n };\n\n const handleItemContextMenu = (e: React.MouseEvent, itemIdx: number) => {\n e.preventDefault();\n e.stopPropagation();\n setContextMenu({ x: e.clientX, y: e.clientY, itemIdx });\n };\n\n const handleFolderContextMenu = (e: React.MouseEvent, folderIdx: number) => {\n e.preventDefault();\n e.stopPropagation();\n setContextMenu({ x: e.clientX, y: e.clientY, folderIdx });\n };\n\n useEffect(() => {\n if (!contextMenu) return;\n const handler = () => setContextMenu(null);\n window.addEventListener('click', handler);\n return () => window.removeEventListener('click', handler);\n }, [contextMenu]);\n\n const createFolder = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n // Icons render right-anchored (style.right = pos.right). Convert the\n // cursor's left-from-container into a right-from-container so the new\n // folder lands under the click instead of mirroring across the desktop.\n const containerW = rect?.width ?? 0;\n const cursorLeft = contextMenu ? contextMenu.x - (rect?.left ?? 0) : containerW - 100;\n const cursorTop = contextMenu ? contextMenu.y - (rect?.top ?? 0) : 100;\n const x = Math.max(0, containerW - cursorLeft - 40);\n const y = Math.max(0, cursorTop - 20);\n const id = `folder-${Date.now()}`;\n saveFolders([...folders, { id, name: 'New Folder', x, y }]);\n setContextMenu(null);\n setRenamingFolder(id);\n setRenameValue('New Folder');\n };\n\n const doSnapAll = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n const h = rect?.height || 600;\n const colCount = Math.max(1, Math.floor(h / GRID));\n let slot = 0;\n const getSlotPos = () => {\n const col = Math.floor(slot / colCount);\n const row = slot % colCount;\n slot++;\n return { right: 20 + col * GRID, top: 10 + row * GRID };\n };\n // Arrange folders first, then items\n const updatedF = folders.map(f => {\n const pos = getSlotPos();\n return { ...f, x: pos.right, y: pos.top };\n });\n saveFolders(updatedF);\n const updated = favDocs.map(d => {\n if (d.folderId) return d;\n const pos = getSlotPos();\n return { ...d, x: pos.right, y: pos.top };\n });\n saveDocs(updated);\n setContextMenu(null);\n };\n\n const removeItem = (idx: number) => {\n const desktopIdx = favDocs.indexOf(desktopItems[idx]);\n saveDocs(favDocs.filter((_, i) => i !== desktopIdx));\n setContextMenu(null);\n };\n\n const removeFolder = (idx: number) => {\n const folder = folders[idx];\n if (folder.id === DOCUMENTS_FOLDER_ID) return; // system folder — undeletable\n // Move folder items back to desktop\n const updated = favDocs.map(d => d.folderId === folder.id ? { ...d, folderId: undefined } : d);\n saveDocs(updated);\n saveFolders(folders.filter((_, i) => i !== idx));\n setContextMenu(null);\n };\n\n const renameFolder = (id: string, name: string) => {\n saveFolders(folders.map(f => f.id === id ? { ...f, name } : f));\n setRenamingFolder(null);\n };\n\n // ── Sticky notes ──\n // Persist through the consumer-supplied callback when one is wired,\n // otherwise fall back to the prefs adapter under `notepad_notes` so\n // Desktop drags survive a refresh and stay in sync with what Notepad\n // wrote.\n const saveNotes = useCallback((updated: StickyNote[]) => {\n if (host.saveNotes) host.saveNotes(updated);\n else saveShellPrefs({ notepad_notes: updated });\n }, [host, saveShellPrefs]);\n\n const createStickyNote = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n const x = contextMenu ? contextMenu.x - (rect?.left || 0) : 100;\n const y = contextMenu ? contextMenu.y - (rect?.top || 0) : 100;\n const n: StickyNote = {\n id: `note-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n title: '', content: '', color: 'yellow', sticky: true,\n sticky_x: x, sticky_y: y, updated_at: new Date().toISOString(),\n };\n saveNotes([n, ...allNotes]);\n setEditingStickyId(n.id);\n setContextMenu(null);\n };\n\n const updateStickyContent = (id: string, content: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, content, updated_at: new Date().toISOString() } : n));\n };\n\n const removeStickyFromDesktop = (id: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, sticky: false } : n));\n };\n\n const deleteStickyNote = (id: string) => {\n saveNotes(allNotes.filter(n => n.id !== id));\n };\n\n const cycleStickyColor = (id: string) => {\n const STICKY_COLORS = ['yellow', 'blue', 'green', 'pink', 'purple', 'orange'];\n const note = allNotes.find(n => n.id === id);\n if (!note) return;\n const idx = STICKY_COLORS.indexOf(note.color);\n const next = STICKY_COLORS[(idx + 1) % STICKY_COLORS.length];\n saveNotes(allNotes.map(n => n.id === id ? { ...n, color: next } : n));\n };\n\n const toggleStickyOnTop = (id: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, sticky_on_top: !n.sticky_on_top } : n));\n };\n\n // Sticky drag\n useEffect(() => {\n if (!stickyDrag) return;\n const move = (e: PointerEvent) => {\n const el = document.querySelector(`[data-sticky-id=\"${stickyDrag.id}\"]`) as HTMLElement;\n if (el) {\n el.style.left = `${stickyDrag.origX + e.clientX - stickyDrag.startX}px`;\n el.style.right = 'auto';\n el.style.top = `${stickyDrag.origY + e.clientY - stickyDrag.startY}px`;\n }\n };\n const up = (e: PointerEvent) => {\n const finalX = stickyDrag.origX + e.clientX - stickyDrag.startX;\n const finalY = Math.max(0, stickyDrag.origY + e.clientY - stickyDrag.startY);\n const el = document.querySelector(`[data-sticky-id=\"${stickyDrag.id}\"]`) as HTMLElement;\n const noteW = el?.offsetWidth ?? 192;\n const centerX = finalX + noteW / 2;\n const anchor: 'left' | 'right' = centerX > window.innerWidth / 2 ? 'right' : 'left';\n // Store x as left offset for left-anchored, or right offset for right-anchored\n const xVal = anchor === 'right' ? window.innerWidth - finalX - noteW : finalX;\n saveNotes(allNotes.map(n => n.id === stickyDrag.id ? { ...n, sticky_x: xVal, sticky_y: finalY, sticky_anchor: anchor } : n));\n // Clear inline styles so React takes over\n if (el) { el.style.left = ''; el.style.right = ''; }\n setStickyDrag(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [stickyDrag, allNotes]);\n\n // Sticky resize\n useEffect(() => {\n if (!stickyResize) return;\n const move = (e: PointerEvent) => {\n const el = document.querySelector(`[data-sticky-id=\"${stickyResize.id}\"]`) as HTMLElement;\n if (el) {\n el.style.width = `${Math.max(140, stickyResize.origW + e.clientX - stickyResize.startX)}px`;\n el.style.height = `${Math.max(100, stickyResize.origH + e.clientY - stickyResize.startY)}px`;\n }\n };\n const up = (e: PointerEvent) => {\n const finalW = Math.max(140, stickyResize.origW + e.clientX - stickyResize.startX);\n const finalH = Math.max(100, stickyResize.origH + e.clientY - stickyResize.startY);\n saveNotes(allNotes.map(n => n.id === stickyResize.id ? { ...n, sticky_w: finalW, sticky_h: finalH } : n));\n setStickyResize(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [stickyResize, allNotes]);\n\n const STICKY_BG: Record<string, string> = {\n yellow: 'bg-yellow-100 border-yellow-300', blue: 'bg-blue-100 border-blue-300',\n green: 'bg-green-100 border-green-300', pink: 'bg-pink-100 border-pink-300',\n purple: 'bg-purple-100 border-purple-300', orange: 'bg-orange-100 border-orange-300',\n };\n\n // ── Render icon ──\n const renderIcon = (entityType: string, label: string, isSelected: boolean, entityId?: string, fileKind?: PreviewFileKind) => (\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <FileIconTile entityType={entityType} isSelected={isSelected} entityId={entityId} label={label} fileKind={fileKind} />\n <span className={`text-[10px] font-medium text-center leading-tight w-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n {label}\n </span>\n </div>\n );\n\n const menuStyle = (x: number, y: number): React.CSSProperties => ({\n ...(x + 180 > window.innerWidth ? { right: window.innerWidth - x } : { left: x }),\n ...(y + 250 > window.innerHeight ? { bottom: window.innerHeight - y } : { top: y }),\n });\n\n return (\n <div ref={containerRef} className=\"flex-1 relative overflow-hidden\"\n onPointerDown={startRubberBand}\n onContextMenu={handleDesktopContextMenu}\n onClick={() => {\n // Don't clear selection if the user just finished a rubber-band drag.\n if (didRubberBandDragRef.current) { didRubberBandDragRef.current = false; return; }\n setSelected(new Set());\n setContextMenu(null);\n }}\n >\n {/* Built-in Trash icon. Lives outside favDocs so it can't be\n deleted, renamed, or dropped into a folder, but the user can\n drag it around — its position persists to\n `prefs.desktop_trash_position`. Default position is the\n bottom-right corner, shifted in to clear the taskbar (the\n taskbar is `position: fixed` and overlays this container, so\n a naive `bottom: 20` would hide the icon under it). Double-\n click opens the Files app in trash view via the side-channel\n defined in Files.tsx. */}\n {(() => {\n const tb = taskbarMetrics();\n const defaultRight = 20 + (tb.position === 'right' ? tb.width : 0);\n const defaultBottom = 20 + (tb.position === 'bottom' ? tb.height : 0);\n const trashPos = (prefs as any).desktop_trash_position as { right: number; bottom: number } | undefined;\n const right = trashPos?.right ?? defaultRight;\n const bottom = trashPos?.bottom ?? defaultBottom;\n const isTrashSelected = selected.has('trash');\n\n const startTrashDrag = (e: React.PointerEvent) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n // When the Trash is part of a multi-selection, the whole selection\n // moves as one group through the shared drag pipeline (which knows\n // the trash is bottom-anchored). Solo drags keep this dedicated\n // path so the trash stays draggable on its own.\n if (selected.has('trash') && selected.size > 1) {\n startDrag('trash', 0, e);\n return;\n }\n const el = e.currentTarget as HTMLElement;\n const startX = e.clientX, startY = e.clientY;\n let moved = false;\n const move = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n if (!moved && (Math.abs(dx) > 3 || Math.abs(dy) > 3)) moved = true;\n if (!moved) return;\n // Drag is from-bottom-right, so cursor moving right shrinks the\n // right offset, and moving down shrinks the bottom offset.\n el.style.right = `${right - dx}px`;\n el.style.bottom = `${bottom - dy}px`;\n el.style.opacity = '0.7';\n el.style.zIndex = '100';\n };\n const up = (ev: PointerEvent) => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n el.style.opacity = '';\n el.style.zIndex = '';\n if (!moved) return;\n const newRight = Math.max(0, right - (ev.clientX - startX));\n const newBottom = Math.max(0, bottom - (ev.clientY - startY));\n saveShellPrefs({ desktop_trash_position: { right: newRight, bottom: newBottom } } as any);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n return (\n <div\n data-desktop-icon=\"trash\"\n style={{ position: 'absolute', right, bottom, zIndex: 1 }}\n onPointerDown={startTrashDrag}\n onClick={e => {\n e.stopPropagation();\n // Same selection contract as the other icons: plain click\n // selects, shift / cmd / ctrl toggles within the selection.\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has('trash') ? next.delete('trash') : next.add('trash'); return next; });\n } else if (!selected.has('trash')) {\n setSelected(new Set(['trash']));\n }\n }}\n onContextMenu={e => e.preventDefault()}\n onDoubleClick={e => {\n e.stopPropagation();\n // Side-channel contract owned by src/apps/Files.tsx: flag is\n // read on mount when Files isn't open yet; the event tells an\n // already-open instance to flip view.\n requestFilesTrashView();\n openPage('/files');\n }}\n className=\"cursor-default select-none\"\n title=\"Trash — double-click to open, drag to move\"\n >\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <div className={`w-12 h-12 flex items-center justify-center ${isTrashSelected ? 'rounded-lg bg-blue-400/30 ring-2 ring-blue-500' : ''}`}>\n <svg className=\"h-12 w-12 drop-shadow-[0_2px_3px_rgba(0,0,0,0.4)]\" viewBox=\"0 0 24 24\">\n {/* Solid heroicons trash, filled with silver. Subtle darker\n stroke gives it a metallic edge against light wallpapers. */}\n <path\n fill=\"#c0c4cc\"\n stroke=\"#5f6677\"\n strokeWidth=\"0.6\"\n strokeLinejoin=\"round\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M16.5 4.478v.227a48.816 48.816 0 013.878.512.75.75 0 11-.256 1.478l-.209-.035-1.005 13.07a3 3 0 01-2.991 2.77H8.084a3 3 0 01-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 01-.256-1.478A48.567 48.567 0 017.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 014.368 0c1.603.051 2.816 1.387 2.816 2.951zm-6.136-1.452a51.196 51.196 0 013.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 00-6 0v-.113c0-.794.609-1.428 1.364-1.452zm-.355 5.945a.75.75 0 10-1.5.058l.347 9a.75.75 0 101.499-.058l-.346-9zm5.48.058a.75.75 0 10-1.498-.058l-.347 9a.75.75 0 001.5.058l.346-9z\"\n />\n </svg>\n </div>\n <span className={`text-[10px] font-medium text-center leading-tight drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isTrashSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n Trash\n </span>\n </div>\n </div>\n );\n })()}\n\n {/* Desktop items */}\n {desktopItems.map((doc, i) => {\n const docIdx = favDocs.indexOf(doc);\n const pos = localPositions[`item-${docIdx}`] || getItemPos(doc, i);\n const isSelected = selected.has(`item-${i}`);\n return (\n <div key={`item-${doc.entityType}-${doc.entityId}-${i}`} data-desktop-icon={`item-${i}`}\n style={{ position: 'absolute', right: pos.right, top: pos.top, zIndex: 1 }}\n onPointerDown={e => { e.stopPropagation(); startDrag('item', i, e); }}\n onClick={e => {\n e.stopPropagation();\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has(`item-${i}`) ? next.delete(`item-${i}`) : next.add(`item-${i}`); return next; });\n } else if (!selected.has(`item-${i}`)) {\n setSelected(new Set([`item-${i}`]));\n }\n }}\n onContextMenu={e => handleItemContextMenu(e, i)}\n onDoubleClick={e => { e.stopPropagation(); openItem(doc); }}\n className=\"cursor-default select-none\"\n >\n {renderIcon(doc.entityType, doc.label, isSelected, doc.entityId, doc.fileKind)}\n </div>\n );\n })}\n\n {/* Folders */}\n {folders.map((folder, i) => {\n const pos = localPositions[`folder-${i}`] || getFolderPos(folder, i);\n const isSelected = selected.has(`folder-${i}`);\n const isHovered = hoverFolderIdx === i;\n const itemCount = folderItems(folder.id).length;\n return (\n <div key={`folder-${folder.id}`} data-desktop-icon={`folder-${i}`}\n style={{\n position: 'absolute', right: pos.right, top: pos.top, zIndex: 1,\n transform: isHovered ? 'scale(1.15)' : 'scale(1)',\n transition: 'transform 180ms ease-out',\n }}\n onPointerDown={e => { e.stopPropagation(); startDrag('folder', i, e); }}\n onClick={e => {\n e.stopPropagation();\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has(`folder-${i}`) ? next.delete(`folder-${i}`) : next.add(`folder-${i}`); return next; });\n } else if (!selected.has(`folder-${i}`)) {\n setSelected(new Set([`folder-${i}`]));\n }\n }}\n onContextMenu={e => handleFolderContextMenu(e, i)}\n onDoubleClick={e => { e.stopPropagation(); openDesktopFolder(folder.id); }}\n className=\"cursor-default select-none\"\n >\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <div className={`w-12 h-12 flex items-center justify-center ${isSelected ? 'rounded-lg bg-blue-400/30 ring-2 ring-blue-500' : ''} ${isHovered ? 'rounded-lg ring-4 ring-amber-400 shadow-[0_0_20px_rgba(245,158,11,0.6)]' : ''}`}>\n <FolderGlyph className=\"h-12 w-12 text-amber-500 drop-shadow-[0_2px_3px_rgba(0,0,0,0.3)]\" />\n </div>\n {renamingFolder === folder.id ? (\n <input autoFocus value={renameValue} onChange={e => setRenameValue(e.target.value)}\n onBlur={() => renameFolder(folder.id, renameValue)}\n onKeyDown={e => { if (e.key === 'Enter') renameFolder(folder.id, renameValue); if (e.key === 'Escape') setRenamingFolder(null); }}\n className=\"text-[10px] w-full text-center bg-white/80 rounded px-1 outline-none\"\n onClick={e => e.stopPropagation()}\n />\n ) : (\n <span className={`text-[10px] font-medium text-center leading-tight w-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n {folder.name}{itemCount > 0 ? ` (${itemCount})` : ''}\n </span>\n )}\n </div>\n </div>\n );\n })}\n\n {/* Sticky notes */}\n {stickyNotes.map(note => {\n const xVal = note.sticky_x ?? 100;\n const y = note.sticky_y ?? 100;\n const w = note.sticky_w ?? 192;\n const h = note.sticky_h ?? 148;\n const anchor = note.sticky_anchor || 'left';\n const bg = STICKY_BG[note.color] || STICKY_BG.yellow;\n const isEditing = editingStickyId === note.id;\n return (\n <div key={`sticky-${note.id}`} data-sticky-id={note.id}\n style={{ position: 'absolute', ...(anchor === 'right' ? { right: xVal } : { left: xVal }), top: y, width: w, height: h, zIndex: note.sticky_on_top ? 200 : isEditing ? 50 : 10 }}\n onClick={e => e.stopPropagation()}\n className={`rounded-lg shadow-lg border ${bg} select-none flex flex-col`}\n >\n {/* Header — drag handle */}\n <div className=\"flex items-center justify-between px-2 py-1 cursor-move border-b border-black/5\"\n onPointerDown={e => {\n if (e.button !== 0) return;\n e.preventDefault(); e.stopPropagation();\n // Always drag using left position; convert right-anchored to left\n const el = (e.target as HTMLElement).closest('[data-sticky-id]') as HTMLElement;\n const actualLeft = el ? el.getBoundingClientRect().left - (containerRef.current?.getBoundingClientRect().left ?? 0) : (anchor === 'right' ? window.innerWidth - xVal - w : xVal);\n setStickyDrag({ id: note.id, startX: e.clientX, startY: e.clientY, origX: actualLeft, origY: y });\n }}>\n <div className=\"flex items-center gap-1\">\n <button\n onPointerDown={e => e.stopPropagation()}\n onClick={e => { e.stopPropagation(); cycleStickyColor(note.id); }}\n title=\"Change color\"\n className=\"w-3 h-3 rounded-full bg-black/10 hover:bg-black/20 transition-colors\" />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); toggleStickyOnTop(note.id); }} title={note.sticky_on_top ? 'Remove from top' : 'Always on top'}\n className={`p-0.5 rounded transition-colors ${note.sticky_on_top ? 'text-blue-500' : 'text-black/20 hover:text-black/50'}`}>\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.914 5.046a5.25 5.25 0 01-1.414 0M15.75 9v6\" /><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12.75 12l3 3 3-3\" /></svg>\n </button>\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); removeStickyFromDesktop(note.id); }} title=\"Unpin from desktop\"\n className=\"p-0.5 rounded text-black/20 hover:text-black/50 transition-colors\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 12h-15\" /></svg>\n </button>\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); deleteStickyNote(note.id); }} title=\"Delete note\"\n className=\"p-0.5 rounded text-black/20 hover:text-red-500 transition-colors\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n </div>\n </div>\n {/* Content */}\n {isEditing ? (\n <textarea\n autoFocus\n defaultValue={note.content}\n onBlur={e => { updateStickyContent(note.id, e.target.value); setEditingStickyId(null); }}\n onKeyDown={e => { if (e.key === 'Escape') { updateStickyContent(note.id, (e.target as HTMLTextAreaElement).value); setEditingStickyId(null); } }}\n className=\"flex-1 w-full p-2 text-xs leading-relaxed bg-transparent outline-none resize-none placeholder:text-black/30\"\n placeholder=\"Write something...\"\n />\n ) : (\n <div className=\"flex-1 p-2 cursor-text overflow-hidden\" onDoubleClick={e => { e.stopPropagation(); setEditingStickyId(note.id); }}>\n <div className=\"text-xs leading-relaxed text-black/70\">\n {note.content ? renderStickyContent(note.id, note.content) : <span className=\"text-black/30 italic\">Double-click to edit...</span>}\n </div>\n </div>\n )}\n {/* Resize handle */}\n <div className=\"absolute bottom-0 right-0 w-4 h-4 cursor-nwse-resize\"\n onPointerDown={e => {\n if (e.button !== 0) return;\n e.preventDefault(); e.stopPropagation();\n const el = (e.target as HTMLElement).closest('[data-sticky-id]') as HTMLElement;\n setStickyResize({ id: note.id, startX: e.clientX, startY: e.clientY, origW: el?.offsetWidth ?? w, origH: el?.offsetHeight ?? h });\n }}>\n <svg className=\"w-3 h-3 text-black/15 absolute bottom-0.5 right-0.5\" viewBox=\"0 0 12 12\" fill=\"currentColor\">\n <circle cx=\"10\" cy=\"10\" r=\"1.5\" /><circle cx=\"6\" cy=\"10\" r=\"1.5\" /><circle cx=\"10\" cy=\"6\" r=\"1.5\" />\n </svg>\n </div>\n </div>\n );\n })}\n\n {/* Rubber band selection */}\n {rubberBand && (\n <div className=\"absolute border border-blue-400 bg-blue-400/10 pointer-events-none\" style={{\n left: Math.min(rubberBand.startX, rubberBand.endX),\n top: Math.min(rubberBand.startY, rubberBand.endY),\n width: Math.abs(rubberBand.endX - rubberBand.startX),\n height: Math.abs(rubberBand.endY - rubberBand.startY),\n }} />\n )}\n\n {/* Context menu — desktop */}\n {contextMenu && contextMenu.itemIdx == null && contextMenu.folderIdx == null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)}>\n <PopupMenuItem onClick={createStickyNote}>\n <svg className=\"h-4 w-4 text-yellow-500\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M4 4a2 2 0 012-2h8a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2V4z\" opacity=\"0.8\" /><path d=\"M14 14v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-6\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>\n New Sticky Note\n </PopupMenuItem>\n <PopupMenuItem onClick={createFolder}>\n <svg className=\"h-4 w-4 text-yellow-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z\" /></svg>\n Create Folder\n </PopupMenuItem>\n <PopupMenuItem onClick={doSnapAll}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z\" /></svg>\n Snap to Grid\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setContextMenu(null); setWidgetsOpen(true); }}>\n <svg className=\"h-4 w-4 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" /></svg>\n Manage Widgets…\n </PopupMenuItem>\n {/* Performance overlay toggle. It lives here, next to the other\n desktop-surface items, because the Preferences switch alone was\n not a findable entrance: it sits last in the Appearance pane,\n below Theme, Wallpaper and six transparency sliders — about a\n screen's worth of scrolling past the fold. A diagnostic has to be\n reachable by someone who is already frustrated, and that means\n right where the overlay itself appears. */}\n {!hiddenMenuItems.includes('perf-stats') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); saveShellPrefs({ show_desktop_stats: prefs.show_desktop_stats !== true }); }}>\n <svg className=\"h-4 w-4 text-emerald-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 20.25V15m5.25 5.25V9.75m5.25 10.5V4.5m5.25 15.75v-7.5\" /></svg>\n {prefs.show_desktop_stats === true ? 'Hide Performance Stats' : 'Show Performance Stats'}\n </PopupMenuItem>\n )}\n {!(hiddenMenuItems.includes('customization') && hiddenMenuItems.includes('favorites') && hiddenMenuItems.includes('about')) && <PopupMenuDivider />}\n {!hiddenMenuItems.includes('customization') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); openPage('/settings/customization'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42\" /></svg>\n Preferences\n </PopupMenuItem>\n )}\n {!hiddenMenuItems.includes('favorites') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); openPage('/settings/favorites'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" /></svg>\n Favorites\n </PopupMenuItem>\n )}\n {!hiddenMenuItems.includes('about') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); setAboutOpen(true); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" /></svg>\n {shellStrings.about.aboutPrefix} {host.productName ?? shellStrings.about.thisApp}\n </PopupMenuItem>\n )}\n {host.onReportBug && <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setContextMenu(null); host.onReportBug!(); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z\" /></svg>\n Suggestion or Bug\n </PopupMenuItem>\n </>}\n </PopupMenu>\n )}\n\n {/* Context menu — item */}\n {contextMenu && contextMenu.itemIdx != null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)} minWidth={160}>\n <PopupMenuItem onClick={() => { openItem(desktopItems[contextMenu.itemIdx!]); setContextMenu(null); }}>\n Open\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => removeItem(contextMenu.itemIdx!)}>\n Remove Shortcut\n </PopupMenuItem>\n </PopupMenu>\n )}\n\n {/* Context menu — folder */}\n {contextMenu && contextMenu.folderIdx != null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)} minWidth={160}>\n <PopupMenuItem onClick={() => { openDesktopFolder(folders[contextMenu.folderIdx!].id); setContextMenu(null); }}>\n Open\n </PopupMenuItem>\n {/* Recent Documents is a system folder — no rename, no delete. */}\n {folders[contextMenu.folderIdx!].id !== DOCUMENTS_FOLDER_ID && <>\n <PopupMenuItem onClick={() => { setRenamingFolder(folders[contextMenu.folderIdx!].id); setRenameValue(folders[contextMenu.folderIdx!].name); setContextMenu(null); }}>\n Rename\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => removeFolder(contextMenu.folderIdx!)}>\n Delete Folder\n </PopupMenuItem>\n </>}\n </PopupMenu>\n )}\n\n {/* Widget manager — add / remove desktop widgets */}\n <WidgetManager open={widgetsOpen} onClose={() => setWidgetsOpen(false)} />\n\n {/* About dialog */}\n {aboutOpen && (() => {\n const version = host.productVersion ?? APP_VERSION;\n return (\n <Modal open={true} onClose={() => setAboutOpen(false)} title={`${shellStrings.about.aboutPrefix} ${host.productName ?? shellStrings.about.thisApp}`} size=\"sm\" bodyScroll={false} compact dimensions={[340, 420]}>\n <div className=\"flex flex-col items-center\">\n {/* Logo & Title */}\n <div className=\"flex flex-col items-center gap-2 pt-4 pb-3 w-full\">\n <img src={host.productIcon ?? '/favicon.svg'} alt=\"\" className=\"h-16 w-16\" />\n <div className=\"text-center\">\n <h2 className=\"text-lg font-bold text-gray-900 tracking-wide\">{host.productName ?? 'react-os-shell'}</h2>\n {host.productTagline && <p className=\"text-xs text-gray-500\">{host.productTagline}</p>}\n <p className=\"text-[11px] text-gray-400 mt-1 font-mono\">{version}</p>\n </div>\n </div>\n\n {/* Open Source Licenses */}\n <div className=\"py-3 border-t border-gray-200 w-full px-4\">\n <h3 className=\"text-[10px] font-semibold text-gray-400 uppercase tracking-wide mb-2 text-center\">{shellStrings.about.openSourceLicenses}</h3>\n <div className=\"max-h-40 overflow-y-auto\">\n <table className=\"w-full text-[11px]\">\n <thead><tr className=\"text-gray-500 border-b border-gray-100\"><th className=\"text-left py-1 font-medium\">Package</th><th className=\"text-left py-1 font-medium\">License</th></tr></thead>\n <tbody className=\"divide-y divide-gray-50\">\n {[\n ['React', 'MIT', 'facebook/react'],\n ['React DOM', 'MIT', 'facebook/react'],\n ['React Router', 'MIT', 'remix-run/react-router'],\n ['TanStack Query', 'MIT', 'TanStack/query'],\n ['TanStack Table', 'MIT', 'TanStack/table'],\n ['React Hook Form', 'MIT', 'react-hook-form'],\n ['Axios', 'MIT', 'axios/axios'],\n ['Tailwind CSS', 'MIT', 'tailwindlabs/tailwindcss'],\n ['Headless UI', 'MIT', 'tailwindlabs/headlessui'],\n ['Heroicons', 'MIT', 'tailwindlabs/heroicons'],\n ['Recharts', 'MIT', 'recharts/recharts'],\n ['Zod', 'MIT', 'colinhacks/zod'],\n ['Vite', 'MIT', 'vitejs/vite'],\n ['TypeScript', 'Apache-2.0', 'microsoft/TypeScript'],\n ['jSpreadsheet CE', 'MIT', 'jspreadsheet/ce'],\n ['Django', 'BSD-3', 'django/django'],\n ['Django REST Framework', 'BSD-3', 'encode/django-rest-framework'],\n ['PostgreSQL', 'PostgreSQL', 'postgres/postgres'],\n ['Gunicorn', 'MIT', 'benoitc/gunicorn'],\n ].map(([name, license, repo]) => (\n <tr key={name} className=\"text-gray-600\">\n <td className=\"py-1\"><a href={`https://github.com/${repo}`} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-blue-600 hover:underline\">{name}</a></td>\n <td className=\"py-1 text-gray-400\">{license}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Copyright — bottom (consumer-configurable; hidden when neither field is supplied) */}\n {(host.productCopyright || host.productWebsite) && (\n <div className=\"pt-3 pb-2 border-t border-gray-200 w-full text-center\">\n {host.productCopyright && <p className=\"text-[10px] text-gray-400\">{host.productCopyright}</p>}\n {host.productWebsite && (\n <a href={host.productWebsite} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-[10px] text-blue-500 hover:underline\">\n {host.productWebsite.replace(/^https?:\\/\\//, '')}\n </a>\n )}\n </div>\n )}\n </div>\n </Modal>\n );\n })()}\n\n {/* Performance HUD — opt-in diagnostic, parked in the same corner as the\n version watermark: one row above it when both show, in its slot when\n the watermark is off. z-[240] floats it over windows (which stack\n below the taskbar's z-[250]) but under every piece of shell chrome,\n so it stays readable while you drag a window around — which is when\n the jank worth measuring actually happens. */}\n {prefs.show_desktop_stats === true && (() => {\n const versionShowing = prefs.show_desktop_version === true && !!(host.productVersion ?? APP_VERSION);\n const taskbarAtBottom = prefs.taskbar_position !== 'top'\n && prefs.taskbar_position !== 'left'\n && prefs.taskbar_position !== 'right';\n const side = prefs.taskbar_position === 'right' ? 'left-3' : 'right-3';\n // Standard spacing steps only — no arbitrary values. These class names\n // have to survive whatever Tailwind build each consuming portal runs,\n // and an arbitrary `bottom-[5.5rem]` silently resolves to nothing if a\n // consumer's scan misses the shell's dist. The stacked offsets simply\n // clear the watermark sitting below.\n const bottom = taskbarAtBottom\n ? (versionShowing ? 'bottom-24' : 'bottom-16')\n : (versionShowing ? 'bottom-8' : 'bottom-3');\n return (\n <div className={`absolute z-[240] ${side} ${bottom}`}>\n <PerfStats\n onClose={() => saveShellPrefs({ show_desktop_stats: false })}\n onSubmit={host.onSubmitPerfReport}\n />\n </div>\n );\n })()}\n\n {/* Version watermark on desktop — opt-in only. Hidden by default so\n consumer apps don't end up with two version labels (the bundled\n one and their own). Set prefs.show_desktop_version = true and\n provide host.productVersion to surface it. */}\n {prefs.show_desktop_version === true && (host.productVersion ?? APP_VERSION) && (() => {\n const tb = taskbarMetrics();\n return (\n <button\n onClick={(e) => { e.stopPropagation(); setWhatsNewOpen(true); }}\n style={{\n // ── BG#00623 ──────────────────────────────────────────────────\n // Above the desktop-icon layer. The icons declare `zIndex: 1`\n // and this declared nothing, so the Trash — whose default\n // position is `20 + taskbarHeight` from the same corner — painted\n // over the digits and took the click. Its handler calls\n // `stopPropagation()` and only changes the selection, so an\n // intercepted click did visibly nothing, which is exactly what\n // the report describes. Measured before this change, at 1851x1301:\n // 510 of the label's 630 pixels went to the Trash on a small\n // taskbar, 102 on a medium one.\n //\n // 2 and not more: the window layer and the taskbar's z-[250] must\n // still cover it, and the PerfStats HUD's z-[240] sits between.\n // Declared inline for the same reason the icons do — a consumer's\n // Tailwind scan cannot fail to generate a style attribute.\n zIndex: 2,\n // Clear of the taskbar at every size. This was a flat 64px, which\n // is right for a medium taskbar and 8px short of a large one: the\n // taskbar is `position: fixed` and paints over the desktop, so on\n // a large taskbar 336 of those same 630 pixels were underneath it.\n // The +8 below reproduces today's medium placement exactly, so the\n // label does not move for the common case.\n bottom: tb.position === 'bottom' ? tb.height + 4 : 8,\n ...(tb.position === 'right' ? { left: 4 } : { right: 4 }),\n }}\n // The padding is the hit target: the glyphs are 10px type at half\n // opacity in a 42x15 box, which is smaller than anything else on the\n // desktop you are expected to hit. It grows the box outwards only —\n // the insets above are pulled in by the same amount the padding adds\n // back, so the digits stay where they are drawn today.\n className=\"absolute px-2 py-1 text-[10px] text-white/50 font-mono select-none drop-shadow-[0_1px_1px_rgba(0,0,0,0.5)] hover:text-white/80 transition-colors cursor-pointer\"\n >\n {host.productVersion ?? APP_VERSION}\n </button>\n );\n })()}\n\n {/* What's New dialog — the modal body is the scroller. An inner box\n capped at a viewport fraction cannot grow into a fixed-height\n window, so everything below the cap was blank (BG#00600); worst\n maximized, where the window is the whole work area.\n\n `bodyScroll={false}` with a `min-h-0 flex-1 overflow-y-auto` wrapper\n (the idiom at Drawer.tsx:156 and SidebarLayout.tsx:139) is equally\n correct — this shape is one element shorter, and the guard in\n tests/whatsNewFillsWindow.test.tsx accepts either. What neither\n shape does is size the WINDOW to the changelog: a host with two\n entries still gets an `md` window with room to spare, and asks for\n the other behaviour with `autoHeight` / `autoMinHeight`.\n\n Entries are Markdown — every consumer writes them that way — so\n they go through MarkdownLite, the same renderer and the same\n wrapper classes the admin portal's VersionsPanel and AboutSettings\n use on these exact strings. */}\n {whatsNewOpen && (() => {\n const entries = host.productChangelog ?? changelog;\n return (\n <Modal open={true} onClose={() => setWhatsNewOpen(false)} title={shellStrings.about.whatsNew} size=\"md\">\n {entries.length === 0 ? (\n <div className=\"flex-1 flex items-center justify-center\">\n <p className=\"text-sm text-gray-400 text-center\">{shellStrings.about.noChangelog}</p>\n </div>\n ) : (\n <div className=\"space-y-5 px-1\">\n {entries.map((entry, i) => (\n <div key={entry.version}>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm font-bold text-gray-900 font-mono\">{entry.version}</span>\n <span className=\"text-xs text-gray-400\">{formatDate(entry.date)}</span>\n </div>\n <ul className=\"space-y-1.5 ml-1\">\n {entry.changes.map((change, j) => (\n <li key={j} className=\"flex items-start gap-2 text-sm text-gray-600\">\n <span className=\"text-blue-500 mt-1 shrink-0\">•</span>\n <MarkdownLite className=\"min-w-0 [&_p]:m-0\">{change}</MarkdownLite>\n </li>\n ))}\n </ul>\n {i < entries.length - 1 && <div className=\"border-b border-gray-200 mt-4\" />}\n </div>\n ))}\n </div>\n )}\n </Modal>\n );\n })()}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport BrandMark from '../forms/BrandMark';\n\ninterface StartupAnimationProps {\n onComplete: () => void;\n ready?: boolean;\n productName?: string;\n subtitle?: string;\n logo?: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n}\n\n/**\n * Startup splash animation — shown once when the app first loads after login.\n * Fades out after the animation completes, then unmounts.\n */\nexport default function StartupAnimation({ onComplete, ready = false, productName = 'react-os-shell', subtitle, logo = '/favicon.svg', adaptiveLogo = false, logoHasAlpha = null, logoIsLight = null }: StartupAnimationProps) {\n const [phase, setPhase] = useState<'logo' | 'text' | 'fade'>('logo');\n const [minTimePassed, setMinTimePassed] = useState(false);\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const fadingRef = useRef(false);\n\n useEffect(() => {\n const t1 = setTimeout(() => setPhase('text'), 600);\n const t2 = setTimeout(() => setMinTimePassed(true), 2000);\n // Safety: force complete after 5s even if ready never fires\n const t3 = setTimeout(() => {\n if (!fadingRef.current) { fadingRef.current = true; setPhase('fade'); setTimeout(() => onCompleteRef.current(), 500); }\n }, 5000);\n return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };\n }, []);\n\n // Fade out when both ready AND minimum time passed\n useEffect(() => {\n if (!ready || !minTimePassed || fadingRef.current) return;\n fadingRef.current = true;\n setPhase('fade');\n const t = setTimeout(() => onCompleteRef.current(), 500);\n return () => clearTimeout(t);\n }, [ready, minTimePassed]);\n\n return (\n <div\n data-startup-animation=\"\"\n className={`fixed inset-0 z-[9999] flex flex-col items-center justify-center transition-opacity duration-500 ${phase === 'fade' ? 'opacity-0 pointer-events-none' : 'opacity-100'}`}\n style={{ background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)' }}\n >\n {/* Glow effect */}\n <div className=\"absolute inset-0 overflow-hidden\">\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full opacity-20\"\n style={{ background: 'radial-gradient(circle, rgba(124,58,237,0.4) 0%, transparent 70%)', animation: 'pulse-glow 2s ease-in-out infinite' }} />\n </div>\n\n {/* Logo */}\n {/* The animation stays on the MARK, where it has always been. This\n wrapper owns the phase transition, and `spin-in` sets `transform`\n AND `opacity` with a forwards fill — animation declarations outrank\n normal ones, so putting it here would pin both at the 100% frame and\n leave the wrapper's scale/opacity classes doing nothing. */}\n <div className={`relative transition-all duration-700 ease-out ${phase === 'logo' ? 'scale-75 opacity-0' : 'scale-100 opacity-100'}`}>\n <BrandMark\n src={logo}\n alt=\"\"\n slot=\"compact\"\n surface=\"dark\"\n size={80}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n className=\"drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\"\n style={{ animation: 'spin-in 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards' }}\n />\n </div>\n\n {/* Title */}\n <div className={`mt-6 text-center transition-all duration-500 ${phase !== 'logo' ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>\n <h1 className=\"text-2xl font-bold tracking-[0.3em] text-white/90 uppercase\">{productName}</h1>\n <div className=\"mt-2 flex items-center justify-center gap-1.5\">\n {[0, 1, 2].map(i => (\n <div key={i} className=\"w-1.5 h-1.5 rounded-full bg-purple-400\"\n style={{ animation: `dot-bounce 1s ease-in-out ${i * 0.15}s infinite` }} />\n ))}\n </div>\n </div>\n\n {/* Subtitle (consumer-supplied — typically the company / product name) */}\n {subtitle && (\n <div className={`absolute bottom-8 transition-all duration-500 ${phase !== 'logo' ? 'opacity-40' : 'opacity-0'}`}>\n <p className=\"text-[10px] text-white/40 font-mono tracking-wider\">{subtitle}</p>\n </div>\n )}\n\n <style>{`\n @keyframes spin-in {\n 0% { transform: scale(0) rotate(-180deg); opacity: 0; }\n 100% { transform: scale(1) rotate(0deg); opacity: 1; }\n }\n @keyframes dot-bounce {\n 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes pulse-glow {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.15; }\n 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.25; }\n }\n /* Reduced motion: the fades stay, the movement goes. animation:none\n * (stylesheet !important beats the inline animation shorthands) parks\n * the spin/bounce/pulse at their base state; restricting transitions\n * to opacity turns the slide/scale phases into plain cross-fades.\n * Timings and the ready-gating are untouched — this is about motion,\n * not about how long the splash holds. */\n @media (prefers-reduced-motion: reduce) {\n [data-startup-animation], [data-startup-animation] * {\n animation: none !important;\n transition-property: opacity !important;\n }\n }\n `}</style>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { playLogout } from '../utils/sounds';\nimport { useShellStrings } from './strings';\nimport BrandMark from '../forms/BrandMark';\n\ninterface LogoutAnimationProps {\n onComplete: () => void;\n subtitle?: string;\n logo?: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n}\n\nexport default function LogoutAnimation({ onComplete, subtitle, logo = '/favicon.svg', adaptiveLogo = false, logoHasAlpha = null, logoIsLight = null }: LogoutAnimationProps) {\n // 'show' → greeting visible; 'out' → logo/title spin and fade away. The\n // full-screen cover itself stays opaque the whole time — it never fades to\n // transparent — so the desktop underneath is never revealed. onComplete\n // fires while the cover is still solid, so the consumer's login screen\n // swaps in behind it and the user goes straight from \"Goodbye\" to login\n // (no flash of the desktop in between).\n const [phase, setPhase] = useState<'show' | 'out'>('show');\n const strings = useShellStrings();\n\n useEffect(() => {\n playLogout();\n const t1 = setTimeout(() => setPhase('out'), 800);\n const t2 = setTimeout(onComplete, 2300);\n return () => { clearTimeout(t1); clearTimeout(t2); };\n }, [onComplete]);\n\n return (\n <div\n data-logout-animation=\"\"\n className=\"fixed inset-0 z-[9999] flex flex-col items-center justify-center\"\n style={{ background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)' }}\n >\n {/* Glow effect */}\n <div className=\"absolute inset-0 overflow-hidden\">\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full\"\n style={{\n background: 'radial-gradient(circle, rgba(124,58,237,0.4) 0%, transparent 70%)',\n animation: 'logout-glow 2s ease-in-out infinite',\n opacity: phase === 'show' ? 0.2 : 0,\n transition: 'opacity 1s',\n }} />\n </div>\n\n {/* Logo — spins out */}\n <div className={`relative transition-all duration-1000 ease-in ${phase === 'out' ? 'scale-0 opacity-0' : 'scale-100 opacity-100'}`}\n style={phase === 'out' ? { transform: 'scale(0) rotate(180deg)' } : undefined}>\n <BrandMark\n src={logo}\n alt=\"\"\n slot=\"compact\"\n surface=\"dark\"\n size={80}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n className=\"drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\"\n />\n </div>\n\n {/* Title — fades down */}\n <div className={`mt-6 text-center transition-all duration-700 ${phase === 'show' ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>\n <h1 className=\"text-2xl font-bold tracking-[0.3em] text-white/90 uppercase\">{strings.logout.goodbye}</h1>\n <p className=\"mt-2 text-xs text-white/40\">{strings.logout.seeYou}</p>\n </div>\n\n {/* Subtitle (consumer-supplied — typically the company / product name) */}\n {subtitle && (\n <div className={`absolute bottom-8 transition-all duration-500 ${phase === 'show' ? 'opacity-40' : 'opacity-0'}`}>\n <p className=\"text-[10px] text-white/40 font-mono tracking-wider\">{subtitle}</p>\n </div>\n )}\n\n <style>{`\n @keyframes logout-glow {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.15; }\n 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.25; }\n }\n /* Reduced motion: same contract as StartupAnimation — fades stay,\n * movement goes, the 2300ms cover-and-swap timing is untouched. */\n @media (prefers-reduced-motion: reduce) {\n [data-logout-animation], [data-logout-animation] * {\n animation: none !important;\n transition-property: opacity !important;\n }\n }\n `}</style>\n </div>\n );\n}\n","/**\n * SessionWindowRestore — reopen the windows the user had open.\n *\n * Window state is in-memory, so logging out — or just pressing F5 — has\n * always meant coming back to an empty desktop with the taskbar cleared.\n * Everything needed to rebuild it already existed: the window manager can\n * open a page window from its route and an entity window from its registry\n * key + id (it does exactly that when restoring a minimised item), and\n * ShellPrefs persists per-user state. This component is just the two wires:\n * it saves the identifying refs of the open windows (never their content),\n * and on a fresh mount with nothing open it replays them.\n *\n * Contracts:\n * - Off switch: `restore_windows: false` in prefs (Preferences → Behavior).\n * Default on.\n * - Restore runs ONCE per mount, and only when no window is already open —\n * a deep link that opened a window before this ran wins, we never stack\n * a stale session on top of it.\n * - Persisting starts only after the restore attempt, and writes only when\n * the open windows differ from the saved set — the set the restore read,\n * then the set last written that SETTLED (a save the adapter rejects does\n * not count, so the next change retries). So a mount, replayed or not, writes nothing\n * until the user opens or closes a window, and a consumer's adapter\n * re-rendering (a new `save` each render) writes nothing either.\n * Saves are debounced — opening five windows writes once.\n * - The saved refs are read from the prefs available AT MOUNT. The bundled\n * localStorage adapter is synchronous, so that is simply \"the prefs\"; a\n * consumer whose prefs hydrate later misses the restore for that load\n * rather than restoring at a surprising moment mid-session — and keeps its\n * saved set, because the empty desktop it mounted onto is not a change.\n * - Geometry is not session state. Moving or resizing a window changes no\n * ref, so it writes nothing here; each window's box is Modal's, kept in\n * browser localStorage (`erp_window_positions`).\n * - Part-number lookup windows are not restored: they open through a search\n * round-trip, not the registry, and a stale lookup re-running a search at\n * login is a surprise rather than a restoration.\n * - Draft windows (a New or Duplicate form — see draftWindow.ts) are neither\n * saved nor restored. Their id is a placeholder the endpoint 404s on, and\n * the snapshot that renders them is not session state: it is the form's\n * seed, not what the user typed, and a seed copied from yesterday's record\n * is not one to offer again at login. A ref saved before this rule is\n * skipped on restore, and the next write drops it from the saved set.\n */\nimport { useEffect, useRef } from 'react';\n\nimport { useWindowManager, type MinimizedItem } from './WindowManager';\nimport { useShellPrefsAdapter } from './ShellPrefs';\nimport { isDraftEntityId, isDraftEntityWindow } from './draftWindow';\n\nexport interface SessionWindowRef {\n type: 'page' | 'entity';\n route?: string;\n entityType?: string;\n entityId?: string;\n label?: string;\n}\n\n/** The persistable identity of each open window — content never leaves the\n * window, only the coordinates the registry needs to reopen it. */\nexport function toSessionRefs(openWindows: MinimizedItem[]): SessionWindowRef[] {\n const refs: SessionWindowRef[] = [];\n for (const w of openWindows) {\n if (w.type === 'page' && w.route) {\n refs.push({ type: 'page', route: w.route });\n } else if (w.entityType && w.entityId && w.type !== 'part_number' && !isDraftEntityWindow(w)) {\n refs.push({ type: 'entity', entityType: w.entityType, entityId: w.entityId, label: w.label, route: w.route });\n }\n }\n return refs;\n}\n\n/** Whether two ref lists name the same windows in the same order. Compared\n * field by field, not as JSON: a backend may hand the saved refs back with\n * their keys reordered (Postgres `jsonb` sorts them), which is no change. */\nexport function sameSessionRefs(a: SessionWindowRef[], b: SessionWindowRef[]): boolean {\n return a.length === b.length && a.every((r, i) => (\n r.type === b[i].type && r.route === b[i].route && r.entityType === b[i].entityType\n && r.entityId === b[i].entityId && r.label === b[i].label\n ));\n}\n\nconst SAVE_DEBOUNCE_MS = 800;\n\nexport default function SessionWindowRestore() {\n const { openWindows, openEntity, openPage } = useWindowManager();\n // The RAW adapter, not useShellPrefs: this is the one caller that needs a\n // failed write to come back as a rejection, so the write is retried rather\n // than recorded as saved. useShellPrefs swallows it for everyone else.\n const { prefs, save } = useShellPrefsAdapter();\n const restoredRef = useRef(false);\n // The set the prefs hold, as far as this mount knows: what the restore\n // read, then what was last written.\n const savedRef = useRef<SessionWindowRef[]>([]);\n // The refs of the write currently in flight, if any. Without this, a write\n // that has been fired but not yet settled compares different on every render\n // in between, and an adapter that hands over a new `save` each render (all\n // three EFFICIENT portals) would fire a second write for the same set.\n const pendingRef = useRef<SessionWindowRef[] | null>(null);\n // Identifies the most recent write, so one that settles late cannot move\n // `savedRef` back behind a newer one.\n const writeSeq = useRef(0);\n const saveTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // ── Restore, once, at mount ──\n useEffect(() => {\n if (restoredRef.current) return;\n restoredRef.current = true;\n const saved: SessionWindowRef[] = Array.isArray(prefs.session_windows) ? prefs.session_windows : [];\n savedRef.current = saved;\n if (prefs.restore_windows === false) return;\n if (openWindows.length > 0) return;\n for (const w of saved) {\n if (w.type === 'page' && w.route) openPage(w.route);\n else if (w.type === 'entity' && w.entityType && w.entityId && !isDraftEntityId(w.entityId)) {\n openEntity(w.entityType, w.entityId, undefined, w.label, w.route);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Persist on change, only after the restore attempt ──\n useEffect(() => {\n if (!restoredRef.current) return;\n clearTimeout(saveTimer.current);\n const refs = toSessionRefs(openWindows);\n // The desktop matches the saved set: nothing to write. This is what keeps\n // a mount whose prefs had not arrived from writing its empty desktop over\n // the set it never saw. It runs after the clear, so a window opened and\n // closed again inside the debounce cancels its own pending write.\n if (sameSessionRefs(refs, savedRef.current)) return;\n // Already on its way. Re-arming here is what would write it twice.\n if (pendingRef.current && sameSessionRefs(refs, pendingRef.current)) return;\n saveTimer.current = setTimeout(() => {\n // Advance the saved set when the write SETTLES, not when it is fired. A\n // rejected save must leave `savedRef` on the old set, so the next change\n // still compares different and writes the whole list again rather than\n // the shell believing a lost write landed and never retrying.\n // - `save` may return void (the bundled localStorage adapter does),\n // hence Promise.resolve.\n // - `seq` drops a write that settles out of order, so a slow earlier\n // write cannot pull `savedRef` back behind a later one.\n // - A rejection clears `pendingRef` without advancing `savedRef`, so\n // the next render or window change retries — which is how this\n // behaved before the set was tracked at all.\n // - An adapter that swallows its OWN failure resolves either way and\n // this cannot tell the two apart: it has to let the rejection reach\n // the shell. Every EFFICIENT portal adapter currently catches before\n // its `.then()`, so for those this is inert until they are changed.\n const seq = ++writeSeq.current;\n pendingRef.current = refs;\n void Promise.resolve(save({ session_windows: refs }))\n .then(() => {\n if (seq !== writeSeq.current) return;\n savedRef.current = refs;\n pendingRef.current = null;\n })\n .catch(() => { if (seq === writeSeq.current) pendingRef.current = null; });\n }, SAVE_DEBOUNCE_MS);\n return () => clearTimeout(saveTimer.current);\n }, [openWindows, save]);\n\n return null;\n}\n","import { useState, useEffect, useLayoutEffect, useRef, isValidElement, cloneElement, type ReactElement, type ReactNode } from 'react';\nimport {\n navSections as defaultNavSections,\n navIcons as defaultNavIcons,\n sectionIcons as defaultSectionIcons,\n startMenuCategories as defaultCategories,\n isSection,\n type NavSection,\n type NavItem,\n type StartMenuCategories,\n type VirtualSection,\n} from '../shell-config/nav';\nimport { visibleChildren as navVisibleChildren, isReachable, navVisible } from './nav-types';\nimport {\n openMenuLevel, closeMenuBelow, resolveMenuLevels, clampMenuTop, menuPanelLeft,\n type MenuAnchor,\n} from './menuPath';\nimport { markMenuOpen } from './perfEvents';\nimport { useAuth } from '../contexts/AuthContext';\nimport { glassStyle, GLASS_INPUT_BG } from '../utils/glass';\nimport { useIsMobile } from './useIsMobile';\n\ninterface StartMenuProps {\n open: boolean; onClose: () => void; openPage: (path: string) => void;\n openWindows: { route?: string; label: string }[];\n profile: any; user: any; onLogout: () => void; onNavigate: (path: string) => void;\n taskbarPosition: 'top' | 'bottom' | 'left' | 'right'; taskbarH: number; taskbarW?: number;\n /** Gap (px) between the menu and the taskbar edge; set per taskbar size by Layout. */\n taskbarGap?: number;\n size?: 'small' | 'medium' | 'large';\n /** Override the default nav sections (sections + top-level items). */\n navSections?: (NavSection | NavItem)[];\n /** Per-route icon map for items in the menu. */\n navIcons?: Record<string, ReactNode>;\n /** Per-section header icon map. */\n sectionIcons?: Record<string, ReactNode>;\n /** Section grouping + virtual flyouts (Utilities-style trays). */\n categories?: StartMenuCategories;\n}\n\nconst ITEM_H = 36; // approximate height per menu item in px\n\n/** Gap between a panel and the one it opened from. */\nconst PANEL_GAP = 4;\n/** Grace period before a submenu closes, so the pointer can cut the corner\n * across sibling rows and the gap on its way into the panel. */\nconst CLOSE_DELAY = 200;\n\ntype MenuLabelled = { label: string; menuLabel?: string };\n\nconst visibleMenuLabel = (entry: MenuLabelled) => entry.menuLabel ?? entry.label;\n\nconst isAbbreviated = (entry: MenuLabelled) =>\n Boolean(entry.menuLabel && entry.menuLabel !== entry.label);\n\n/** An abbreviated row is named \"<compact>, <full>\", in that order: the\n * accessible name has to START with the text on screen or voice control\n * (\"click AP\") stops matching the row the user can actually see — WCAG 2.5.3.\n * A row showing its own full label needs no override at all; its text content\n * already IS the name, and CSS truncation does not change that. */\nconst menuAriaLabel = (entry: MenuLabelled) =>\n isAbbreviated(entry) ? `${entry.menuLabel}, ${entry.label}` : undefined;\n\n/**\n * A row's visible name, with a native tooltip ONLY where what you can read is\n * not the whole name: an explicit compact `menuLabel`, or a label this row had\n * to clip. Titling every row instead hangs a tooltip off ordinary short labels\n * — and hovering a row is also what opens its flyout, so the two fight. The\n * measurement runs on enter, so it costs nothing until someone hovers.\n */\nfunction MenuLabel({ entry, className }: { entry: MenuLabelled; className: string }) {\n const abbreviated = isAbbreviated(entry);\n const [titled, setTitled] = useState(abbreviated);\n return (\n <span\n className={className}\n title={titled ? entry.label : undefined}\n data-menu-label\n onMouseEnter={e => setTitled(abbreviated || e.currentTarget.scrollWidth > e.currentTarget.clientWidth)}\n >\n {visibleMenuLabel(entry)}\n </span>\n );\n}\n\n/**\n * One flyout panel — the same component at every depth.\n *\n * It positions itself in a layout effect rather than from state. The `top` in\n * the style prop is only an estimate from the item count; the effect replaces\n * it with one measured off the rendered panel, before the browser paints. That\n * ordering is the point: a panel repositioned from state moves AFTER paint,\n * which slides its rows out from under a pointer that hasn't moved — and a row\n * that moves away from the pointer never gets its `mouseenter`, so the next\n * level opens late or not at all.\n */\nfunction MenuPanel({ left, anchorY, estHeight, minTop, maxBottom, flipped, className, style, onMouseEnter, onMouseLeave, children }: {\n left: number;\n anchorY: number;\n estHeight: number;\n minTop: number;\n maxBottom: number;\n /** Opened to the LEFT of its parent — slide in from that side too. */\n flipped?: boolean;\n className?: string;\n style?: React.CSSProperties;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n children: ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n // No dep array: any re-render can change the content's height, and the\n // correction costs one property write against the DOM node React just wrote.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.style.top = `${clampMenuTop(anchorY, el.offsetHeight, minTop, maxBottom)}px`;\n });\n return (\n <div\n ref={ref}\n data-menu-panel\n className={`fixed rounded-2xl overflow-hidden ${className ?? ''}`}\n style={{ left, top: clampMenuTop(anchorY, estHeight, minTop, maxBottom), animation: `${flipped ? 'submenu-in-left' : 'submenu-in'} 0.1s ease-out`, ...style }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </div>\n );\n}\n\nexport default function StartMenu({\n open, onClose, openPage, profile, user, onLogout,\n taskbarPosition, taskbarH, taskbarW = 0, taskbarGap = 4, size = 'medium',\n navSections = defaultNavSections,\n navIcons = defaultNavIcons,\n sectionIcons = defaultSectionIcons,\n categories = defaultCategories,\n}: StartMenuProps) {\n const erpLabels = new Set(categories.erp);\n const systemLabels = new Set(categories.system);\n const footerLabels = new Set(categories.footer ?? []);\n const virtualSections = categories.virtual ?? [];\n const virtualByLabel: Record<string, VirtualSection> = Object.fromEntries(\n virtualSections.map(v => [v.label, v]),\n );\n const { hasAnyPerm } = useAuth();\n // Flat rows pinned to the footer (next to the profile), e.g. System\n // Preferences. Rendered directly — no flyout — unlike `categories.footer`.\n const footerItems = (categories.footerItems ?? []).filter(item => navVisible(item, hasAnyPerm));\n const isMobile = useIsMobile();\n // Which flyouts are open, outermost first — one entry per panel, any depth.\n // `openPath[0]` is the section row hovered in the menu itself, `openPath[1]`\n // the row hovered inside the panel that opened, and so on. See `menuPath.ts`\n // for the rules; every level goes through them, so there is no such thing\n // here as \"the 3rd-level case\".\n const [openPath, setOpenPath] = useState<MenuAnchor[]>([]);\n const [search, setSearch] = useState('');\n const [searchIdx, setSearchIdx] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n // ONE close timer for the whole menu. Every handler that could close\n // something clears it before doing anything else, so a pending close from a\n // row the pointer merely passed over can never fire after a submenu has\n // opened and shut it under the cursor.\n const closeTimer = useRef<ReturnType<typeof setTimeout>>();\n\n useEffect(() => { if (!open) { setSearch(''); setOpenPath([]); setSearchIdx(0); } }, [open]);\n useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n // ── Perf marks ──\n // Each layer is a fresh frosted-glass surface measured, positioned and\n // animated in over everything already on screen, which makes opening one the\n // most expensive thing this menu does — and, on a slow machine, the moment\n // people notice. Marked from an effect rather than from the hover handlers so\n // every route in (pointer, keyboard, a section cleared and re-entered) is\n // counted once, and only when the layer actually renders.\n const deepestOpen = openPath.length > 0 ? openPath[openPath.length - 1].key : null;\n useEffect(() => { if (open) markMenuOpen('menu', 'start'); }, [open]);\n useEffect(() => { if (deepestOpen) markMenuOpen('submenu', deepestOpen); }, [deepestOpen]);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n const click = (e: PointerEvent | MouseEvent) => {\n if ((e.target as HTMLElement).closest('[data-menu-toggle]')) return;\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) onClose();\n };\n window.addEventListener('keydown', handler);\n window.addEventListener('pointerdown', click);\n return () => { window.removeEventListener('keydown', handler); window.removeEventListener('pointerdown', click); };\n }, [open, onClose]);\n\n if (!open) return null;\n\n const handleClick = (path: string) => { openPage(path); onClose(); };\n // A row is a destination (`to`) unless it carries an action of its own.\n const select = (item: NavItem) => {\n if (item.onSelect) { item.onSelect(); onClose(); return; }\n handleClick(item.to);\n };\n\n // Coarse-pointer / narrow viewport: render as a full-screen slide-up sheet\n // with search + a flat, tappable list instead of the dense desktop columns.\n if (isMobile) {\n const allItems: { item: NavItem; sectionLabel?: string }[] = [];\n // Recursively flatten — nested children at any depth show up as their own\n // rows so they can be searched/tapped from the mobile sheet too.\n const pushItem = (it: NavItem, sectionLabel?: string) => {\n if (!navVisible(it, hasAnyPerm)) return;\n // Same reachability rule as the desktop flyout — an empty group is not a\n // tap target, so don't list one.\n if (!isReachable(it, hasAnyPerm)) return;\n allItems.push({ item: it, sectionLabel });\n for (const c of navVisibleChildren(it, hasAnyPerm)) pushItem(c, it.label);\n };\n for (const entry of navSections) {\n if (isSection(entry)) {\n const sec = entry as NavSection;\n if (!navVisible(sec, hasAnyPerm)) continue;\n for (const it of sec.items) pushItem(it, sec.label);\n } else {\n pushItem(entry as NavItem);\n }\n }\n for (const it of footerItems) pushItem(it);\n const filtered = search.length >= 1\n ? allItems.filter(({ item }) => item.label.toLowerCase().includes(search.toLowerCase()))\n : allItems;\n\n return (\n <div\n ref={menuRef}\n className=\"fixed inset-0 z-[260] flex flex-col bg-white\"\n style={{ paddingBottom: 'var(--mobile-bottom-nav, 56px)' }}\n >\n {/* Sheet handle + header */}\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-gray-200\">\n <button onClick={onClose} className=\"p-2 -ml-1 rounded-full active:bg-gray-200 text-gray-700\" aria-label=\"Close menu\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n <div className={`flex-1 flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-3 py-2`}>\n <svg className=\"h-4 w-4 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" />\n </svg>\n <input\n value={search}\n onChange={e => setSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"flex-1 bg-transparent text-sm outline-none placeholder-gray-400\"\n autoFocus\n />\n </div>\n </div>\n\n {/* Mobile rows follow the same one-line naming contract as desktop.\n Both axes are still named deliberately: `overflow-y-auto` on its own\n computes the other axis to `auto` too, and one nav label with no\n break opportunity in it — 110px past a 174px flyout, measured — then\n hangs a horizontal scrollbar on a panel of fixed width. The label\n used to WRAP (`wrap-anywhere`) to stay inside that pinned axis; now\n every row is one line and each label truncates instead, so the axis\n still has to be pinned shut but nothing needs to wrap. */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden\">\n {filtered.length === 0 ? (\n <p className=\"text-sm text-gray-400 text-center py-12\">No matching apps</p>\n ) : (\n filtered.map(({ item, sectionLabel }, i) => {\n const icon = navIcons[item.to];\n return (\n <button\n key={`${item.to}-${i}`}\n onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className=\"w-full flex items-center gap-3 px-4 py-3 active:bg-gray-100 border-b border-gray-100 text-left\"\n >\n <span className=\"h-8 w-8 rounded-lg bg-gray-100 flex items-center justify-center text-gray-600 shrink-0\">\n {icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-5 w-5' })\n : null}\n </span>\n <div className=\"min-w-0 flex-1\">\n <MenuLabel entry={item} className=\"block truncate text-sm font-medium text-gray-900\" />\n {sectionLabel && <div className=\"text-[11px] text-gray-500 truncate\">{sectionLabel}</div>}\n </div>\n </button>\n );\n })\n )}\n </div>\n </div>\n );\n }\n\n // Use the \"vertical\" (sidebar-style) layout for top, left, right taskbar positions.\n // Only the bottom taskbar uses the original layout (top items first, ERP after divider).\n const isVertical = taskbarPosition !== 'bottom';\n // Top-level rows pass the same permission + reachability test as the rows in\n // a section. Read raw, a row gated on `perms`/`allPerms` showed to users who\n // could not open it — only the mobile sheet above checked — and still counted\n // toward `hasAppsGroup`, so a hidden row kept its divider.\n const topItems = (navSections.filter(item => !isSection(item)) as NavItem[])\n .filter(item => navVisible(item, hasAnyPerm) && isReachable(item, hasAnyPerm));\n const erpSections = navSections.filter(item => isSection(item) && erpLabels.has((item as NavSection).label));\n const systemSections = navSections.filter(item => isSection(item) && systemLabels.has((item as NavSection).label));\n const footerSections = navSections.filter(item => isSection(item) && footerLabels.has((item as NavSection).label));\n // The \"apps\" group = top-level items + system + virtual sections. Gates the\n // ERP↔apps divider so it only renders when both sides have content.\n const hasAppsGroup = topItems.length > 0 || systemSections.length > 0 || virtualSections.length > 0;\n\n const getVisibleItems = (section: NavSection) =>\n section.items.filter(item => navVisible(item, hasAnyPerm));\n\n const visibleChildren = (item: NavItem) => navVisibleChildren(item, hasAnyPerm);\n\n /** The sub-items a row opens — nothing for a leaf, and nothing for a group\n * whose every branch dead-ends in permission-hidden items. Same list the\n * chevron is drawn from, at every depth. */\n const submenuItems = (item: NavItem) =>\n visibleChildren(item).filter(child => isReachable(child, hasAnyPerm));\n\n // Search — walks nested children to any depth. Section column shows the\n // parent item label for children so users can tell nested entries apart.\n const matchTree = (it: NavItem, sectionLabel: string): (NavItem & { section: string })[] => {\n if (!navVisible(it, hasAnyPerm)) return [];\n // Same rule as the flyout: a group whose children are all hidden isn't a\n // reachable destination, so it shouldn't surface as a result either.\n if (!isReachable(it, hasAnyPerm)) return [];\n const kids = visibleChildren(it);\n const hits: (NavItem & { section: string })[] = [];\n if (it.label.toLowerCase().includes(search.toLowerCase())) {\n hits.push({ ...it, section: sectionLabel });\n }\n for (const c of kids) hits.push(...matchTree(c, it.label));\n return hits;\n };\n const searchResults = search.length >= 2 ? [\n ...navSections.flatMap(item => {\n if (isSection(item)) {\n const sec = item as NavSection;\n return sec.items.flatMap(i => matchTree(i, sec.label));\n }\n return matchTree(item as NavItem, '');\n }),\n ...footerItems.flatMap(item => matchTree(item, '')),\n ] : [];\n\n const posStyle: React.CSSProperties =\n taskbarPosition === 'top' ? { top: taskbarH + taskbarGap, left: 8 } :\n taskbarPosition === 'left' ? { top: 8, left: taskbarW + taskbarGap } :\n taskbarPosition === 'right' ? { top: 8, right: taskbarW + taskbarGap } :\n { bottom: taskbarH + taskbarGap, left: 8 };\n\n const iconEl = (path: string) => {\n const icon = navIcons[path];\n if (icon && isValidElement(icon)) return cloneElement(icon as ReactElement, { className: 'h-4 w-4 shrink-0' });\n return null;\n };\n\n const secIcon = (label: string) => {\n const icon = sectionIcons[label];\n if (icon && isValidElement(icon)) return cloneElement(icon as ReactElement, { className: 'h-4 w-4 shrink-0' });\n return null;\n };\n\n // Flyout data — either a real section or a configured virtual section\n const hoveredSection = openPath.length > 0 ? openPath[0].key : null;\n const hoveredVirtual = hoveredSection ? virtualByLabel[hoveredSection] : undefined;\n const hoveredData = hoveredVirtual\n ? null\n : (hoveredSection ? [...erpSections, ...systemSections, ...footerSections].find(s => (s as NavSection).label === hoveredSection) as NavSection | undefined : null);\n const flyoutItems = (hoveredVirtual\n ? hoveredVirtual.items\n : (hoveredData ? getVisibleItems(hoveredData) : [])\n ).filter(item => isReachable(item, hasAnyPerm));\n\n // Density from CSS variable — three tiers controlling the vertical gap between\n // rows: tight < normal < large. `normal` is the default and sits a little\n // tighter than `large`.\n const menuDensity = typeof document !== 'undefined' ? (getComputedStyle(document.documentElement).getPropertyValue('--menu-density')?.trim() || 'normal') : 'normal';\n const density: 'tight' | 'normal' | 'large' = menuDensity === 'tight' || menuDensity === 'large' ? menuDensity : 'normal';\n\n // Size-dependent styles, adjusted for density. `fwPx` is `fw` in pixels —\n // panels are placed before they render, so the flip-to-the-left decision\n // can't wait for a measurement.\n const sizeConfigByDensity = {\n tight: { small: { w: 'w-52', fw: 'w-44', fwPx: 176, text: 'text-xs', py: 'py-1', px: 'px-3', mw: 208, itemH: 24 }, medium: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-1', px: 'px-3', mw: 224, itemH: 26 }, large: { w: 'w-64', fw: 'w-52', fwPx: 208, text: 'text-sm', py: 'py-1.5', px: 'px-3', mw: 256, itemH: 30 } },\n normal: { small: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-1.5', px: 'px-3', mw: 224, itemH: 30 }, medium: { w: 'w-64', fw: 'w-56', fwPx: 224, text: 'text-sm', py: 'py-1.5', px: 'px-4', mw: 256, itemH: 32 }, large: { w: 'w-72', fw: 'w-60', fwPx: 240, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 288, itemH: 36 } },\n large: { small: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-2', px: 'px-3', mw: 224, itemH: 32 }, medium: { w: 'w-64', fw: 'w-56', fwPx: 224, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 256, itemH: 36 }, large: { w: 'w-72', fw: 'w-60', fwPx: 240, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 288, itemH: 36 } },\n };\n const sizeConfig = sizeConfigByDensity[density][size];\n const menuGlass = glassStyle();\n const itemCls = `w-full min-w-0 overflow-hidden whitespace-nowrap flex items-center gap-2 rounded-lg ${sizeConfig.px} ${sizeConfig.py} ${sizeConfig.text}`;\n const itemLabelCls = 'min-w-0 flex-1 truncate text-left';\n\n // The usable vertical span for a panel: the screen minus the taskbar edge and\n // an 8px gutter, so a flyout can never sit over the taskbar or run off the\n // bottom. The span is the viewport, NOT the main menu's rect: a submenu can\n // legitimately be taller than the menu that opened it (e.g. \"System\" with far\n // more items than the menu has rows). A panel taller than the span is capped\n // at `availH` and scrolls — see `maxHeight` below.\n const viewportH = typeof window !== 'undefined' ? window.innerHeight : 800;\n const viewportW = typeof window !== 'undefined' ? window.innerWidth : 1280;\n const minTop = (taskbarPosition === 'top' ? taskbarH : 0) + 8;\n const maxBottom = viewportH - (taskbarPosition === 'bottom' ? taskbarH : 0) - 8;\n const availH = Math.max(0, maxBottom - minTop);\n\n // Every open flyout's items, outermost first.\n const levels = resolveMenuLevels(flyoutItems, openPath, submenuItems);\n\n const cancelClose = () => clearTimeout(closeTimer.current);\n\n /**\n * Where the panel opened from a row in panel `depth` starts horizontally.\n *\n * Panel 0 is the main menu, so it gets measured. Deeper panels are ours: we\n * put them where `openPath` says, and `offsetWidth` is the untransformed\n * layout width — neither reading is disturbed by the `submenu-in` animation\n * still running on the panel the pointer is in, which a `getBoundingClientRect`\n * would pick up and shift the next panel by.\n */\n const nextPanelLeft = (depth: number, row: HTMLElement) => {\n const owner = row.closest('[data-menu-panel]') as HTMLElement | null;\n if (!owner) return { left: 0, flipped: false };\n const ownerLeft = depth === 0 ? owner.getBoundingClientRect().left : (openPath[depth - 1]?.left ?? 0);\n const ownerRight = depth === 0 ? owner.getBoundingClientRect().right : ownerLeft + owner.offsetWidth;\n const preferLeft = depth > 0 && (openPath[depth - 1]?.flipped ?? false);\n return menuPanelLeft(ownerLeft, ownerRight, sizeConfig.fwPx, viewportW, PANEL_GAP, preferLeft);\n };\n\n /** Hovering a row in panel `depth` that has a submenu — open it now. */\n const openSubmenu = (depth: number, key: string, e: React.MouseEvent) => {\n cancelClose();\n const row = e.currentTarget as HTMLElement;\n const rect = row.getBoundingClientRect();\n const anchor: MenuAnchor = { key, y: rect.top + rect.height / 2, ...nextPanelLeft(depth, row) };\n setOpenPath(prev => openMenuLevel(prev, depth, anchor));\n };\n\n /**\n * Nothing under panel `depth` is wanted any more — the pointer is on a row\n * with no submenu, or has left a panel entirely. Deferred by `CLOSE_DELAY`\n * because the pointer may simply be cutting the corner on its way into the\n * panel it just opened, and immediate by cancellation because whatever the\n * pointer lands on next re-states the intent.\n */\n const scheduleClose = (depth: number) => {\n cancelClose();\n closeTimer.current = setTimeout(() => setOpenPath(prev => closeMenuBelow(prev, depth)), CLOSE_DELAY);\n };\n\n const chevron = (\n <svg className=\"h-3.5 w-3.5 shrink-0 ml-auto text-gray-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" /></svg>\n );\n\n const renderSection = (section: NavSection, isErp: boolean) => {\n if (!navVisible(section, hasAnyPerm)) return null;\n const items = getVisibleItems(section);\n if (items.length === 0) return null;\n const isHovered = hoveredSection === section.label;\n return (\n <div key={section.label} onMouseEnter={e => openSubmenu(0, section.label, e)}>\n <button\n aria-label={menuAriaLabel(section)}\n className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}\n >\n {secIcon(section.label)}\n <MenuLabel entry={section} className={`${itemLabelCls} ${isErp ? 'font-medium' : ''}`} />\n {chevron}\n </button>\n {section.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n };\n\n const renderVirtualSection = (v: VirtualSection) => {\n if (v.items.length === 0) return null;\n const isHovered = hoveredSection === v.label;\n return (\n <div key={v.label} onMouseEnter={e => openSubmenu(0, v.label, e)}>\n <button\n aria-label={menuAriaLabel(v)}\n className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}\n >\n <span className=\"shrink-0\">{v.icon}</span>\n <MenuLabel entry={v} className={itemLabelCls} />\n {chevron}\n </button>\n </div>\n );\n };\n\n return (\n /* z-[1100]: sit above the entire window stack — normal windows climb to\n 50 + idx*10 + 1 and pinned-on-top windows render at 999 (see Modal.tsx),\n which previously painted over the open Start menu (BG#00259). 1100 clears\n both. Deliberately kept BELOW Exposé / mission-control (zIndex 2000–9999\n in Modal.tsx) and the transient full-screen overlay tier (toasts,\n startup, logout — z-[9999]), which should still cover the menu. */\n <div ref={menuRef} className=\"fixed z-[1100]\" style={posStyle}>\n <div className=\"flex\">\n {/* Main menu — panel 0. Entering or leaving it schedules the flyouts\n shut; whichever row the pointer settles on says otherwise, either by\n opening its own submenu or by scheduling the same close again. */}\n <div data-menu-panel className={`${sizeConfig.w} rounded-2xl flex ${isVertical ? 'flex-col-reverse' : 'flex-col'} overflow-hidden`}\n style={{ animation: 'menu-in 0.15s ease-out', ...menuGlass }}\n onMouseEnter={() => scheduleClose(0)}\n onMouseLeave={() => scheduleClose(0)}>\n\n {/* Search — at top for horizontal, at bottom for vertical */}\n <div className={`px-3 ${isVertical ? 'pb-3 pt-2 border-t border-white/20' : 'pt-3 pb-2'}`}\n onMouseEnter={() => scheduleClose(0)}>\n <div className={`flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-2.5 py-1.5`}>\n <svg className=\"h-3.5 w-3.5 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" /></svg>\n <input value={search} onChange={e => { setSearch(e.target.value); setOpenPath([]); setSearchIdx(0); }}\n onKeyDown={e => {\n if (search.length >= 2 && searchResults.length > 0) {\n if (e.key === 'ArrowDown') { e.preventDefault(); setSearchIdx(i => Math.min(i + 1, searchResults.length - 1)); }\n else if (e.key === 'ArrowUp') { e.preventDefault(); setSearchIdx(i => Math.max(i - 1, 0)); }\n else if (e.key === 'Enter') { e.preventDefault(); select(searchResults[searchIdx]); }\n }\n }}\n placeholder=\"Search...\"\n className=\"flex-1 bg-transparent text-xs outline-none placeholder-gray-400\" autoFocus />\n </div>\n </div>\n\n {search.length >= 2 ? (\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden px-1 pb-2 max-h-[400px]\">\n {searchResults.length === 0 ? (\n <p className=\"text-xs text-gray-400 text-center py-4\">No results</p>\n ) : searchResults.map((r, i) => (\n <button key={i} onClick={() => select(r)}\n onMouseEnter={() => setSearchIdx(i)}\n aria-label={menuAriaLabel(r)}\n className={`${itemCls} transition-colors ${i === searchIdx ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {iconEl(r.to)}\n <MenuLabel entry={r} className={itemLabelCls} />\n {r.section && <span className=\"max-w-[40%] shrink-0 truncate text-[10px] text-gray-400 ml-auto\">{r.section}</span>}\n </button>\n ))}\n </div>\n ) : (\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden px-1 pb-1 flex flex-col\">\n {isVertical && (<>\n {/* Reversed column → profile sits at the top, so footer items +\n sections render first to stay pinned next to it. */}\n {footerItems.map(item => (\n <button key={item.to} onClick={() => select(item)}\n onMouseEnter={() => scheduleClose(0)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n ))}\n {footerSections.map(s => renderSection(s as NavSection, false))}\n {(footerSections.length > 0 || footerItems.length > 0) && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {/* Vertical layout: ERP sections first */}\n {erpSections.map(s => renderSection(s as NavSection, true))}\n {erpSections.length > 0 && hasAppsGroup && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {/* Then top-level items + system */}\n {topItems.map(item => (\n <div key={item.to} onMouseEnter={() => scheduleClose(0)}>\n <button onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n ))}{systemSections.map(s => renderSection(s as NavSection, false))}\n {virtualSections.map(v => renderVirtualSection(v))}\n </>)}\n\n {!isVertical && (<>\n {/* Horizontal layout: top-level items first, ERP after divider */}\n {topItems.map(item => (\n <div key={item.to} onMouseEnter={() => scheduleClose(0)}>\n <button onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n ))}{systemSections.map(s => renderSection(s as NavSection, false))}\n {virtualSections.map(v => renderVirtualSection(v))}\n {hasAppsGroup && erpSections.length > 0 && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {erpSections.map(s => renderSection(s as NavSection, true))}\n {/* Footer items + sections: pinned just above the profile, divided from ERP. */}\n {(footerSections.length > 0 || footerItems.length > 0) && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {footerSections.map(s => renderSection(s as NavSection, false))}\n {footerItems.map(item => (\n <button key={item.to} onClick={() => select(item)}\n onMouseEnter={() => scheduleClose(0)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n ))}\n </>)}\n </div>\n )}\n\n {/* User profile — name + sign out on same row */}\n <div className={`${isVertical ? 'border-b' : 'border-t'} border-white/20 p-1`} onMouseEnter={() => scheduleClose(0)}>\n <div onClick={() => handleClick('/profile')}\n className=\"rounded-lg px-2 py-1.5 flex items-center gap-2.5 hover:bg-blue-50 hover:text-blue-700 transition-colors cursor-pointer\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-8 w-8 rounded-full object-cover border border-white/20 shrink-0\" />\n ) : (\n <div className=\"h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-sm font-bold text-blue-700 shrink-0\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <p className=\"flex-1 min-w-0 text-sm font-medium text-gray-900 truncate\">\n {profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}\n </p>\n <button onClick={e => { e.stopPropagation(); onClose(); onLogout(); }} title=\"Sign Out\"\n className=\"shrink-0 p-1.5 rounded-md text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9\" /></svg>\n </button>\n </div>\n </div>\n </div>\n\n {/* Flyouts — one panel per open level, centred on the row that opened\n it and clamped into the usable viewport span. Every level renders\n from this one loop: the section flyout is `levels[0]` and is built\n exactly like the one six levels down, so there is no depth at which\n the menu starts behaving differently. */}\n {search.length < 2 && levels.map((items, i) => (\n <MenuPanel\n key={`${i}:${openPath[i].key}`}\n left={openPath[i].left}\n anchorY={openPath[i].y}\n estHeight={items.length * sizeConfig.itemH + 12}\n minTop={minTop}\n maxBottom={maxBottom}\n flipped={openPath[i].flipped}\n className={sizeConfig.fw}\n style={menuGlass}\n /* Landing anywhere in this panel — a row, a divider, the padding —\n retires the branch below it. A row that has its own submenu\n cancels that on the way past, because React fires the panel's\n `mouseenter` before the row's. */\n onMouseEnter={() => scheduleClose(i + 1)}\n onMouseLeave={() => scheduleClose(i)}\n >\n <div className=\"py-1 px-1 overflow-y-auto overflow-x-hidden overscroll-contain\" style={{ maxHeight: availH }}>\n {items.map(item => {\n const kids = submenuItems(item);\n const isOpen = openPath[i + 1]?.key === item.to;\n return (\n <div key={item.to}\n onMouseEnter={kids.length > 0 ? e => openSubmenu(i + 1, item.to, e) : () => scheduleClose(i + 1)}>\n <button\n /* A group's `to` is a synthetic key by convention, so\n clicking one navigates nowhere — it opens its submenu,\n the same thing hovering it does, instead of closing the\n menu on a route that does not exist. */\n onClick={kids.length > 0 ? e => openSubmenu(i + 1, item.to, e) : () => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} transition-colors ${isOpen ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n {kids.length > 0 && chevron}\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n })}\n </div>\n </MenuPanel>\n ))}\n </div>\n\n <style>{`\n @keyframes menu-in { from { opacity: 0; transform: scale(0.95) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }\n @keyframes submenu-in { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: translateX(0); } }\n @keyframes submenu-in-left { from { opacity: 0; transform: translateX(4px); } to { opacity: 1; transform: translateX(0); } }\n `}</style>\n </div>\n );\n}\n","/**\n * Mobile landing screen — shown by <Layout> in place of the desktop chrome on\n * phone/tablet-portrait viewports (see useIsMobile).\n *\n * The shell no longer ships its own touch \"mobile mode\". Instead the consumer\n * wires a link to their dedicated mobile app (native deep link, App Store /\n * Play Store page, or a mobile-optimised web app) through Layout's `mobileApp`\n * prop, and this screen surfaces it. With no link configured it degrades to a\n * plain \"best viewed on desktop\" notice so a consumer that hasn't adopted the\n * prop yet still gets a coherent small-screen screen rather than the cramped\n * desktop shell.\n */\nimport type { CSSProperties } from 'react';\nimport { glassStyle } from '../utils/glass';\nimport BrandMark from '../forms/BrandMark';\n\nexport interface MobileAppConfig {\n /** Link the primary button opens — a native deep link, an App Store /\n * Play Store page, or a mobile-optimised web app. When omitted the screen\n * still renders (branding + message) but without a call-to-action. */\n url?: string;\n /** Primary button label. Defaults to `Open the app`. */\n ctaLabel?: string;\n /** Headline. Defaults to a message built from the product name. */\n heading?: string;\n /** Supporting copy under the headline. */\n description?: string;\n}\n\ninterface MobileAppLandingProps {\n productName: string;\n productIcon: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n /** Consumer-wired mobile-app link + copy. */\n config?: MobileAppConfig;\n /** Wallpaper / background style computed by Layout so the user's chosen\n * desktop background carries onto the landing screen. */\n wallpaperStyle?: CSSProperties;\n}\n\nexport default function MobileAppLanding({\n productName,\n productIcon,\n adaptiveLogo = false,\n logoHasAlpha = null,\n logoIsLight = null,\n config,\n wallpaperStyle,\n}: MobileAppLandingProps) {\n const hasLink = !!config?.url;\n const heading =\n config?.heading ??\n (hasLink\n ? `Continue in the ${productName} app`\n : `${productName} works best on desktop`);\n const description =\n config?.description ??\n (hasLink\n ? 'This experience is built for the mobile app. Open it to continue on your phone.'\n : 'Open this page on a larger screen to continue.');\n const ctaLabel = config?.ctaLabel ?? 'Open the app';\n\n return (\n <div\n className=\"flex-1 flex items-center justify-center p-6\"\n style={{ ...wallpaperStyle, paddingBottom: 'calc(env(safe-area-inset-bottom) + 1.5rem)' }}\n >\n <div\n className=\"w-full max-w-sm rounded-3xl p-8 flex flex-col items-center text-center\"\n style={glassStyle()}\n >\n <div className=\"h-20 w-20 rounded-2xl overflow-hidden bg-white/60 flex items-center justify-center shadow-sm mb-5\">\n <BrandMark\n src={productIcon}\n alt=\"\"\n slot=\"compact\"\n surface=\"light\"\n size={56}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n />\n </div>\n\n <h1 className=\"text-xl font-semibold text-gray-900 leading-snug\">{heading}</h1>\n <p className=\"mt-2 text-sm text-gray-600 leading-relaxed\">{description}</p>\n\n {hasLink && (\n <a\n href={config!.url}\n rel=\"noopener noreferrer\"\n className=\"mt-6 w-full inline-flex items-center justify-center gap-2 rounded-xl bg-blue-600 px-5 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-blue-700 active:bg-blue-800\"\n >\n {ctaLabel}\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3\" />\n </svg>\n </a>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, useMemo, useRef, useSyncExternalStore, isValidElement, cloneElement, lazy, Suspense, type ReactElement } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useAuth } from '../contexts/AuthContext';\nimport apiClient from '../api/client';\nimport GlobalSearch, { type SearchConfig } from './GlobalSearch';\nimport ShortcutHelp from './ShortcutHelp';\nimport ShellContextMenu from './ShellContextMenu';\nimport NotificationBell, { type NotificationsConfig } from './NotificationBell';\nimport { getPomoSnapshot, subscribePomo } from './pomodoroStore';\nimport { useShellPrefs } from './ShellPrefs';\nimport { SIDEBAR_STRIP_W } from './workArea';\nimport { useWindowManager } from './WindowManager';\nimport { useTheme } from '../hooks/useTheme';\nimport Desktop, { useDesktopHost } from './Desktop';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { playStartup } from '../utils/sounds';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport StartupAnimation from './StartupAnimation';\nimport LogoutAnimation from './LogoutAnimation';\nimport SessionWindowRestore from './SessionRestore';\nimport StartMenu from './StartMenu';\n// Sidebar is opt-in (`prefs.layout_mode === 'sidebar'`) and adds nothing\n// to the classic-mode bundle. lazy() also means consumers running a\n// stale source checkout where Sidebar.tsx hasn't been pulled yet won't\n// crash on module load — only when they actually flip into sidebar mode.\nconst Sidebar = lazy(() => import('./Sidebar'));\nimport MobileAppLanding, { type MobileAppConfig } from './MobileAppLanding';\nimport { useIsMobile } from './useIsMobile';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport {\n navIcons as defaultNavIcons,\n sectionIcons as defaultSectionIcons,\n navSections as defaultNavSections,\n startMenuCategories as defaultCategories,\n isSection,\n type NavItem,\n type NavSection,\n type StartMenuCategories,\n} from '../shell-config/nav';\nimport { WINDOW_REGISTRY, isPageEntry, type PageRegistryEntry } from '../windowRegistry/types';\nimport type { ReactNode } from 'react';\nimport BrandMark from '../forms/BrandMark';\n\n// Transitional re-exports — go away after each consumer migrates to importing\n// nav data from their own shell-config rather than from <Layout>.\nexport {\n defaultNavIcons as navIcons,\n defaultSectionIcons as sectionIcons,\n defaultNavSections as navSections,\n isSection,\n};\nexport type { NavItem, NavSection };\nexport type { MobileAppConfig };\n\n/**\n * The product's visual identity, in one object: the start-menu button, the\n * startup splash, the logout cover and the mobile landing all read from it.\n * The About dialog and What's New changelog belong to `DesktopHostConfig`\n * (`productName`, `productIcon`, `productChangelog`, …), which configures the\n * desktop; this configures the chrome around it.\n */\nexport interface ShellBranding {\n /** Product name — start-menu button, startup splash, mobile landing. */\n productName?: string;\n /** Logo URL — start-menu button, splash and logout covers. Defaults to `/favicon.svg`. */\n logo?: string;\n /** Apply the shared contrast treatment to arbitrary tenant artwork. */\n adaptiveLogo?: boolean;\n /** Server-detected transparency hint for `logo`. */\n logoHasAlpha?: boolean | null;\n /** Server-detected tone hint for `logo`. */\n logoIsLight?: boolean | null;\n /** Line under the product name on the splash and logout covers —\n * typically the company name. */\n tagline?: string;\n}\n\nexport interface LayoutProps {\n /** One-object form of the brand fields below; its fields win over them, so\n * a consumer can move over field by field. */\n branding?: ShellBranding;\n /** Brand label rendered on the start-menu button. */\n productName?: string;\n /** Icon URL rendered next to the brand label. Defaults to `/favicon.svg`. */\n productIcon?: string;\n /** Wallpaper image URLs for the desktop background. When omitted, falls back\n * to the wallpapers registered on the `DesktopHostProvider` (the same pool the\n * Customization picker shows); with neither, the desktop renders no image. */\n wallpapers?: string[];\n /** Override the default nav sections shown in the start menu. */\n navSections?: (NavSection | NavItem)[];\n /** Override the per-route icon map used by start menu and favorites. */\n navIcons?: Record<string, ReactNode>;\n /** Override the per-section header icon map used by start menu. */\n sectionIcons?: Record<string, ReactNode>;\n /** Override the start menu's section grouping + virtual flyouts. */\n categories?: StartMenuCategories;\n /** Notification system config — when omitted, the bell isn't rendered. */\n notifications?: NotificationsConfig;\n /** Universal search config — when omitted, Cmd-K opens the picker but no\n * results ever come back. */\n search?: SearchConfig;\n /** Custom node rendered in the system tray to the LEFT of the\n * notification bell (or above it on a vertical taskbar). Lets a host\n * app drop in icons like a server-status indicator without forking\n * the shell. The shell renders the node as-is — keep it small (a\n * single icon-sized button) so it fits the existing tray rhythm. */\n taskbarTrayLeft?: ReactNode;\n /** Taskbar clock popover config — lets the host surface per-day content\n * (e.g. tasks due that day) inside the mini month calendar. When omitted\n * the popover stays a plain date grid. */\n clockCalendar?: ClockCalendarConfig;\n /** Mobile-app link shown on phone/tablet-portrait viewports in place of the\n * desktop chrome. The shell has no built-in touch UI — wire a link to your\n * dedicated mobile app here (see MobileAppConfig). When omitted, small\n * screens get a plain \"best viewed on desktop\" notice. */\n mobileApp?: MobileAppConfig;\n /** The shell-wide right-click menu (`ShellContextMenu`). On by default;\n * `false` hands every right-click back to the browser — for a consumer\n * that is mid-migration, or that draws a menu of its own everywhere. */\n contextMenu?: boolean;\n}\n\nexport interface ClockCalendarConfig {\n /** Local dates (YYYY-MM-DD) to mark with a dot in the mini month grid —\n * typically days that have items on them. */\n markedDates?: string[];\n /** Render content for the selected day below the grid. The popover\n * defaults the selection to today when it opens, so clicking the clock\n * immediately shows today's items; clicking any day in the grid\n * re-renders the panel for that day (days outside the shown month also\n * flip the grid to their month). `close` dismisses the popover — call\n * it when a row click opens a window so the popup doesn't linger over\n * it. */\n renderDay?: (dateISO: string, api: { close: () => void }) => ReactNode;\n}\n\n\nfunction ProfileMenu({ profile, user, onLogout, onNavigate }: { profile: any; user: any; onLogout: () => void; onNavigate: (path: string) => void }) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState<{ left: number; top?: number; bottom?: number } | null>(null);\n\n useClickOutside(ref, useCallback(() => { if (open) setOpen(false); }, [open]));\n\n useEffect(() => {\n if (open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n // Center popup over button, clamp to viewport\n const popupW = 256; // w-64\n let left = rect.left + rect.width / 2 - popupW / 2;\n left = Math.max(8, Math.min(left, window.innerWidth - popupW - 8));\n if (taskbarPos === 'top') {\n setPos({ left, top: rect.bottom + 4 });\n } else {\n setPos({ left, bottom: window.innerHeight - rect.top + 4 });\n }\n }\n }, [open]);\n\n const groupNames: any[] = profile?.group_names ?? [];\n\n return (\n <div ref={ref} className=\"relative\">\n <button ref={buttonRef} onClick={() => setOpen(!open)} className=\"flex items-center gap-2 rounded-md px-2 py-1 hover:bg-gray-200 transition-colors text-left shrink-0\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-7 w-7 rounded-full object-cover border border-gray-300\" />\n ) : (\n <div className=\"h-7 w-7 rounded-full bg-gray-300 flex items-center justify-center text-[10px] font-bold text-gray-600\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <span className=\"text-xs font-medium text-gray-700 hidden sm:inline\">{profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}</span>\n </button>\n\n {open && pos && (\n <PopupMenu minWidth={256} style={{ left: pos.left, ...(pos.top != null ? { top: pos.top } : { bottom: pos.bottom }) }}>\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-gray-200/60\">\n <div className=\"flex items-center gap-3\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-10 w-10 rounded-full object-cover border border-gray-300\" />\n ) : (\n <div className=\"h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-lg font-bold text-blue-700\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-gray-900 truncate\">{profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}</p>\n <p className=\"text-xs text-gray-500 truncate\">{user?.email}</p>\n </div>\n </div>\n {groupNames.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-2\">\n {groupNames.map((g: any) => (\n <span key={typeof g === 'string' ? g : g.name} className=\"inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium bg-blue-100 text-blue-700\">\n {typeof g === 'string' ? g : g.name}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Menu items */}\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/profile'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z\" /></svg>\n My Profile\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/notifications'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" /></svg>\n Notifications\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/settings/favorites'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" /></svg>\n Favorites\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/settings/customization'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42\" /></svg>\n Preferences\n </PopupMenuItem>\n\n {/* Logout */}\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={async () => {\n setOpen(false);\n const { confirm } = await import('./ConfirmDialog');\n const ok = await confirm({\n title: 'Sign Out',\n message: 'Do you want to log out? All windows will reopen when you log back in.',\n confirmLabel: 'Sign Out',\n cancelLabel: 'Cancel',\n variant: 'warning',\n });\n if (ok) onLogout();\n }}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9\" /></svg>\n Sign Out\n </PopupMenuItem>\n </PopupMenu>\n )}\n\n </div>\n );\n}\n\nconst NAV_CATEGORIES = [\n { label: 'Clients', items: [\n { path: '/orders', label: 'Sales Orders' }, { path: '/invoices', label: 'Sales Invoices' },\n { path: '/warranty-claims', label: 'Warranty Claims' }, { path: '/clients', label: 'Clients' },\n { path: '/price-sheets', label: 'Price Sheets' },\n ]},\n { label: 'Vendors', items: [\n { path: '/vendor-orders', label: 'Purchase Orders' }, { path: '/qc-reports', label: 'QC Reports' },\n { path: '/production-progress', label: 'Production Progress' }, { path: '/vendor-shipments', label: 'Goods Receipt' },\n { path: '/vendor-invoices', label: 'Vendor Invoices' }, { path: '/vendor-payments', label: 'Vendor Payments' },\n { path: '/manufacturers', label: 'Vendors' }, { path: '/vendor-price-sheets', label: 'Vendor Price Sheets' },\n ]},\n { label: 'Inventory', items: [\n { path: '/goods-issue', label: 'Goods Issue' }, { path: '/stock-on-hand', label: 'Stock on Hand' },\n { path: '/warehouses', label: 'Warehouses' },\n ]},\n { label: 'Products', items: [\n { path: '/products', label: 'Part Numbers' }, { path: '/brands', label: 'Brands' },\n { path: '/designs', label: 'Designs' }, { path: '/wheel-finishes', label: 'Wheel Finishes' },\n ]},\n { label: 'R&D', items: [\n { path: '/projects', label: 'Projects' }, { path: '/proposals', label: 'Proposals' },\n { path: '/moulds', label: 'Moulds' }, { path: '/dfm-logs', label: 'DFM Logs' },\n { path: '/weight-logs', label: 'Weight Logs' },\n ]},\n { label: 'Finance', items: [\n { path: '/payments', label: 'Receipts' }, { path: '/bank-accounts', label: 'Bank Accounts' },\n ]},\n];\n\nfunction useFavorites(wallpapers?: string[]) {\n const { prefs, save } = useShellPrefs();\n const favorites: string[] = prefs.favorite_pages || [];\n\n const toggle = useCallback((path: string) => {\n const next = favorites.includes(path) ? favorites.filter((p: string) => p !== path) : [...favorites, path];\n save({ favorite_pages: next });\n }, [favorites, save]);\n\n const wallpaperPool = wallpapers && wallpapers.length > 0 ? wallpapers : [];\n const randomPickRef = useRef(wallpaperPool.length > 0 ? wallpaperPool[Math.floor(Math.random() * wallpaperPool.length)] : 'none');\n const rawBg: string = prefs.desktop_bg || (wallpaperPool.length > 0 ? 'random' : 'none');\n const desktopBg: string = rawBg === 'random' ? randomPickRef.current : rawBg;\n\n const setDesktopBg = useCallback((bg: string) => {\n save({ desktop_bg: bg });\n }, [save]);\n\n return { favorites, toggle, isFavorite: (path: string) => favorites.includes(path), desktopBg, setDesktopBg };\n}\n\nexport { useFavorites };\n\n/** Star button for list page titles — toggles favorite status */\nexport function FavoriteStar({ path }: { path?: string }) {\n const location = useLocation();\n const { isFavorite, toggle } = useFavorites();\n const currentPath = path || location.pathname;\n const fav = isFavorite(currentPath);\n return (\n <button onClick={() => toggle(currentPath)} title={fav ? 'Remove from favorites' : 'Add to favorites'}\n className={`shrink-0 transition-colors ${fav ? 'text-yellow-500 hover:text-yellow-600' : 'text-gray-300 hover:text-yellow-400'}`}>\n <svg className=\"h-5 w-5\" fill={fav ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" />\n </svg>\n </button>\n );\n}\n\nexport const ALL_TIMEZONES = [\n { tz: 'Pacific/Auckland', label: 'Auckland' }, { tz: 'Australia/Sydney', label: 'Sydney' },\n { tz: 'Australia/Adelaide', label: 'Adelaide' }, { tz: 'Australia/Brisbane', label: 'Brisbane' },\n { tz: 'Australia/Perth', label: 'Perth' }, { tz: 'Asia/Tokyo', label: 'Tokyo' },\n { tz: 'Asia/Seoul', label: 'Seoul' }, { tz: 'Asia/Shanghai', label: 'Shanghai' },\n { tz: 'Asia/Hong_Kong', label: 'Hong Kong' }, { tz: 'Asia/Singapore', label: 'Singapore' },\n { tz: 'Asia/Bangkok', label: 'Bangkok' }, { tz: 'Asia/Kolkata', label: 'Mumbai' },\n { tz: 'Asia/Dubai', label: 'Dubai' }, { tz: 'Europe/Moscow', label: 'Moscow' },\n { tz: 'Europe/Istanbul', label: 'Istanbul' }, { tz: 'Europe/Berlin', label: 'Berlin' },\n { tz: 'Europe/Paris', label: 'Paris' }, { tz: 'Europe/London', label: 'London' },\n { tz: 'America/Sao_Paulo', label: 'Sao Paulo' }, { tz: 'America/New_York', label: 'New York' },\n { tz: 'America/Chicago', label: 'Chicago' }, { tz: 'America/Denver', label: 'Denver' },\n { tz: 'America/Los_Angeles', label: 'Los Angeles' }, { tz: 'Pacific/Honolulu', label: 'Honolulu' },\n { tz: 'UTC', label: 'UTC' },\n];\n\nexport function ClockContent({ localTz, worldClocks, now, fmtTime, fmtDate, fmtOffset, removeClock, adding, setAdding, addClock, availableToAdd, showAdd }: {\n localTz: string; worldClocks: string[]; now: Date;\n fmtTime: (tz: string) => string; fmtDate: (tz: string) => string; fmtOffset: (tz: string) => string;\n removeClock: (tz: string) => void; adding: boolean; setAdding: (v: boolean) => void; addClock: (tz: string) => void;\n availableToAdd: { tz: string; label: string }[]; showAdd: boolean;\n}) {\n return (\n <>\n {/* Local time header */}\n <div className=\"px-4 py-3 border-b border-gray-200\">\n <p className=\"text-xs font-medium text-gray-500 uppercase tracking-wide\">Local Time</p>\n <div className=\"flex items-baseline justify-between mt-1\">\n <span className=\"text-2xl font-semibold text-gray-900 tabular-nums\">{fmtTime(localTz)}</span>\n <span className=\"text-xs text-gray-400\">{fmtOffset(localTz)}</span>\n </div>\n <p className=\"text-xs text-gray-500 mt-0.5\">{fmtDate(localTz)} · {localTz.replace(/_/g, ' ')}</p>\n </div>\n\n {/* World clocks */}\n <div className=\"max-h-60 overflow-y-auto\">\n {worldClocks.map(tz => {\n const info = ALL_TIMEZONES.find(t => t.tz === tz);\n const label = info?.label || tz.split('/').pop()?.replace(/_/g, ' ') || tz;\n return (\n <div key={tz} className=\"flex items-center justify-between px-4 py-2 hover:bg-gray-50 group\">\n <div>\n <p className=\"text-sm font-medium text-gray-900\">{label}</p>\n <p className=\"text-[10px] text-gray-400\">{fmtDate(tz)} · {fmtOffset(tz)}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-700 tabular-nums\">{fmtTime(tz)}</span>\n <button onClick={() => removeClock(tz)} className=\"opacity-0 group-hover:opacity-100 text-gray-300 hover:text-red-500 transition-all\" title=\"Remove\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n </div>\n </div>\n );\n })}\n {worldClocks.length === 0 && (\n <p className=\"text-sm text-gray-400 text-center py-4\">No world clocks added</p>\n )}\n </div>\n\n {/* Add timezone — only shown when not pinned */}\n {showAdd && (\n <div className=\"border-t border-gray-200 p-2\">\n {adding ? (\n <select autoFocus onChange={e => { if (e.target.value) addClock(e.target.value); }} onBlur={() => setAdding(false)}\n className=\"w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm focus:border-blue-500 focus:ring-blue-500\">\n <option value=\"\">Select timezone...</option>\n {availableToAdd.map(t => (\n <option key={t.tz} value={t.tz}>{t.label} ({fmtOffset(t.tz)})</option>\n ))}\n </select>\n ) : (\n <button onClick={() => setAdding(true)} className=\"w-full flex items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-700 transition-colors\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n Add World Clock\n </button>\n )}\n </div>\n )}\n </>\n );\n}\n\n/**\n * Compact countdown chip rendered in the system tray when a Pomodoro\n * session is in progress. Subscribes to `pomodoroStore` so it updates\n * once per second without re-rendering the whole shell. Tapping it opens\n * (or focuses) the Pomodoro widget.\n */\nfunction TaskbarPomodoro() {\n const snap = useSyncExternalStore(subscribePomo, getPomoSnapshot, getPomoSnapshot);\n const { openPage } = useWindowManager();\n\n // Show whenever the user has an active or paused-mid-session timer.\n const inSession = snap.running || (snap.remaining < snap.total && snap.remaining > 0);\n if (!inSession) return null;\n\n const mm = String(Math.floor(snap.remaining / 60)).padStart(2, '0');\n const ss = String(snap.remaining % 60).padStart(2, '0');\n const dot =\n snap.mode === 'focus' ? 'bg-blue-500' :\n snap.mode === 'short' ? 'bg-emerald-500' : 'bg-emerald-600';\n const label =\n snap.mode === 'focus' ? 'Focus' :\n snap.mode === 'short' ? 'Short break' : 'Long break';\n\n return (\n <button onClick={() => openPage('/pomodoro')}\n title={`${label} · ${mm}:${ss}${snap.running ? '' : ' (paused)'}`}\n className={`shrink-0 flex items-center gap-1.5 rounded-md px-2 py-1 text-[11px] font-mono font-semibold tabular-nums hover:bg-gray-200/50 transition-colors ${snap.running ? 'text-gray-800' : 'text-gray-400'}`}>\n <span className={`block w-1.5 h-1.5 rounded-full ${dot} ${snap.running ? 'animate-pulse' : 'opacity-60'}`} />\n {mm}:{ss}\n </button>\n );\n}\n\nfunction TaskbarClock({ clockCalendar }: { clockCalendar?: ClockCalendarConfig }) {\n const [now, setNow] = useState(new Date());\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const { openPage } = useWindowManager();\n\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 10000);\n return () => clearInterval(t);\n }, []);\n\n useClickOutside(ref, useCallback(() => { if (open) setOpen(false); }, [open]));\n\n return (\n <div ref={ref} className=\"relative shrink-0\">\n <button ref={buttonRef} onClick={() => setOpen(!open)} className=\"text-right leading-tight cursor-pointer hover:bg-gray-200/50 rounded px-1.5 py-0.5 transition-colors\">\n <p className=\"text-[11px] font-medium text-gray-800\">{now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })}</p>\n <p className=\"text-[10px] text-gray-700\">{now.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}</p>\n </button>\n\n {open && (() => {\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const rect = buttonRef.current?.getBoundingClientRect();\n const right = rect ? Math.max(8, window.innerWidth - rect.right) : 8;\n const posStyle = taskbarPos === 'top'\n ? { right, top: (rect?.bottom ?? 0) + 4 }\n : { right, bottom: window.innerHeight - (rect?.top ?? 0) + 4 };\n\n return (\n <div className=\"fixed z-[300] rounded-lg border border-gray-200 bg-white shadow-xl\" style={posStyle}>\n <CalendarPopup now={now} config={clockCalendar} close={() => setOpen(false)} />\n </div>\n );\n })()}\n </div>\n );\n}\n\nconst toISODate = (d: Date) =>\n `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n\n/**\n * Mini month calendar shown when the user clicks the taskbar clock.\n * Header has month + year and prev/next nav arrows; today is filled in\n * the accent colour; days outside the current month are dimmed.\n *\n * With a host-supplied `config` (see ClockCalendarConfig) the grid becomes\n * interactive: days are clickable, days in `markedDates` get a dot, and a\n * panel below the grid renders `renderDay` for the selected day (today on\n * open). Selection then moves the accent fill; today shows as an accent\n * number when not selected.\n */\nfunction CalendarPopup({ now, config, close }: { now: Date; config?: ClockCalendarConfig; close: () => void }) {\n const [month, setMonth] = useState(() => new Date(now.getFullYear(), now.getMonth(), 1));\n const [selected, setSelected] = useState(() => toISODate(now));\n const interactive = !!config?.renderDay;\n const markedSet = useMemo(() => new Set(config?.markedDates ?? []), [config?.markedDates]);\n\n const monthLabel = month.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });\n const fullDate = now.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' });\n const fullTime = now.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n\n const firstDay = month.getDay(); // 0 = Sunday\n const daysInMonth = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();\n const prevDays = new Date(month.getFullYear(), month.getMonth(), 0).getDate();\n\n const cells: { day: number; thisMonth: boolean; date: Date }[] = [];\n for (let i = firstDay - 1; i >= 0; i--) {\n const day = prevDays - i;\n cells.push({ day, thisMonth: false, date: new Date(month.getFullYear(), month.getMonth() - 1, day) });\n }\n for (let day = 1; day <= daysInMonth; day++) {\n cells.push({ day, thisMonth: true, date: new Date(month.getFullYear(), month.getMonth(), day) });\n }\n let nextDay = 1;\n while (cells.length < 42) {\n cells.push({ day: nextDay, thisMonth: false, date: new Date(month.getFullYear(), month.getMonth() + 1, nextDay) });\n nextDay++;\n }\n\n const today = new Date();\n const isToday = (d: Date) =>\n d.getFullYear() === today.getFullYear() &&\n d.getMonth() === today.getMonth() &&\n d.getDate() === today.getDate();\n\n const goPrev = () => setMonth(m => new Date(m.getFullYear(), m.getMonth() - 1, 1));\n const goNext = () => setMonth(m => new Date(m.getFullYear(), m.getMonth() + 1, 1));\n const goToday = () => setMonth(new Date(today.getFullYear(), today.getMonth(), 1));\n\n return (\n <div className={`${interactive ? 'w-[300px]' : 'w-[260px]'} p-3`}>\n {/* Live date + time line */}\n <div className=\"px-1 pb-2.5 border-b border-gray-100\">\n <div className=\"text-[11px] font-semibold text-gray-500 uppercase tracking-wide\">{fullDate}</div>\n <div className=\"text-2xl font-semibold text-gray-800 tabular-nums leading-tight mt-0.5\">{fullTime}</div>\n </div>\n\n {/* Month nav */}\n <div className=\"flex items-center justify-between mt-2.5 mb-2\">\n <button onClick={goPrev} className=\"p-1 rounded hover:bg-gray-100 text-gray-600\" aria-label=\"Previous month\">\n <svg className=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <button onClick={goToday} className=\"text-sm font-semibold text-gray-700 hover:text-blue-600 transition-colors\">\n {monthLabel}\n </button>\n <button onClick={goNext} className=\"p-1 rounded hover:bg-gray-100 text-gray-600\" aria-label=\"Next month\">\n <svg className=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n\n {/* Day labels */}\n <div className=\"grid grid-cols-7 mb-1 text-[10px] font-semibold text-gray-400 text-center uppercase tracking-wide\">\n {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((d, i) => <div key={i} className=\"py-1\">{d}</div>)}\n </div>\n\n {/* Day grid */}\n <div className=\"grid grid-cols-7 gap-px text-center\">\n {cells.map((cell, i) => {\n const todayCell = cell.thisMonth && isToday(cell.date);\n const iso = toISODate(cell.date);\n const isSelected = interactive && selected === iso;\n // Interactive: selection carries the accent fill; an unselected\n // today falls back to an accent-coloured number so it stays\n // findable. Static (no host config): today keeps the fill.\n const look = isSelected\n ? 'bg-blue-500 text-white font-semibold'\n : todayCell\n ? interactive\n ? 'text-blue-600 font-bold hover:bg-gray-100'\n : 'bg-blue-500 text-white font-semibold'\n : cell.thisMonth\n ? 'text-gray-700 hover:bg-gray-100'\n : interactive\n ? 'text-gray-300 hover:bg-gray-100'\n : 'text-gray-300';\n const dayClass = `relative text-[12px] py-1.5 rounded-md transition-colors ${look}`;\n const dot = markedSet.has(iso) && (\n <span\n className={`absolute bottom-[3px] left-1/2 -translate-x-1/2 h-1 w-1 rounded-full ${\n isSelected ? 'bg-white' : cell.thisMonth ? 'bg-blue-500' : 'bg-gray-300'\n }`}\n />\n );\n if (!interactive) {\n return (\n <div key={i} className={dayClass}>\n {cell.day}\n {dot}\n </div>\n );\n }\n return (\n <button\n key={i}\n onClick={() => {\n setSelected(iso);\n // Spilled prev/next-month days also flip the grid there.\n if (!cell.thisMonth) setMonth(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));\n }}\n aria-label={cell.date.toLocaleDateString(undefined, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}\n aria-pressed={isSelected}\n className={`cursor-pointer ${dayClass}`}\n >\n {cell.day}\n {dot}\n </button>\n );\n })}\n </div>\n\n {/* Host-rendered day panel (e.g. tasks due on the selected day).\n Keyed on the day so its scroll position resets per selection. */}\n {config?.renderDay && (\n <div key={selected} className=\"mt-2.5 max-h-[280px] overflow-y-auto border-t border-gray-100 pt-2\">\n {config.renderDay(selected, { close })}\n </div>\n )}\n </div>\n );\n}\n\nfunction TaskbarContextMenu({ x, y, position, size, onChangePosition, onChangeSize, onClose, onReportBug }: {\n x: number; y: number; position: string; size: string;\n onChangePosition: (v: string) => void; onChangeSize: (v: string) => void; onClose: () => void;\n onReportBug?: () => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n useClickOutside(ref, onClose);\n\n const posStyle: React.CSSProperties =\n position === 'top' ? { left: Math.min(x, window.innerWidth - 200), top: y + 4 } :\n position === 'left' ? { left: x + 4, top: Math.min(y, window.innerHeight - 300) } :\n position === 'right' ? { right: window.innerWidth - x + 4, top: Math.min(y, window.innerHeight - 300) } :\n { left: Math.min(x, window.innerWidth - 200), bottom: window.innerHeight - y + 4 };\n\n const check = (active: boolean) => active\n ? <svg className=\"h-3.5 w-3.5 text-blue-600 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>\n : <span className=\"w-3.5\" />;\n\n return (\n <div ref={ref} className=\"fixed z-[400] rounded-2xl py-1 min-w-[180px]\" style={{ ...posStyle, ...getGlassStyle() }}>\n <p className=\"px-3 py-1 text-[10px] font-semibold text-gray-400 uppercase tracking-wide\">Position</p>\n {(['bottom', 'top', 'left', 'right'] as const).map(pos => (\n <button key={pos} onClick={() => onChangePosition(pos)}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n {check(position === pos)}\n {pos.charAt(0).toUpperCase() + pos.slice(1)}\n </button>\n ))}\n <div className=\"border-t border-white/20 my-1 mx-3\" />\n <p className=\"px-3 py-1 text-[10px] font-semibold text-gray-400 uppercase tracking-wide\">Size</p>\n {(['small', 'medium', 'large'] as const).map(s => (\n <button key={s} onClick={() => onChangeSize(s)}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n {check(size === s)}\n {s.charAt(0).toUpperCase() + s.slice(1)}\n </button>\n ))}\n {onReportBug && <>\n <div className=\"border-t border-white/20 my-1 mx-3\" />\n <button onClick={() => { onClose(); onReportBug(); }}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n <svg className=\"h-3.5 w-3.5 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z\" /></svg>\n Suggestion or Bug\n </button>\n </>}\n </div>\n );\n}\n\n/** Pinned-favorites strip — every app the user has favorited\n * (prefs.favorite_pages, toggled via <FavoriteStar>) rendered as an\n * icon launcher next to the start-menu button. Click opens the app\n * window; right-click offers open / remove-from-favorites. */\nfunction TaskbarFavorites({ favorites, vertical, taskbarPosition, navSections, navIcons, onOpen, onToggleFavorite }: {\n favorites: string[];\n vertical: boolean;\n taskbarPosition: string;\n navSections: (NavSection | NavItem)[];\n navIcons: Record<string, ReactNode>;\n onOpen: (path: string) => void;\n onToggleFavorite: (path: string) => void;\n}) {\n const [menu, setMenu] = useState<{ x: number; y: number; path: string; label: string } | null>(null);\n\n // path → label from the nav tree (incl. nested children), falling back to\n // the window registry for favorites that aren't in the start menu.\n const labelFor = useMemo(() => {\n const map: Record<string, string> = {};\n const walk = (items: NavItem[]) => {\n for (const it of items) { map[it.to] = it.label; if (it.children) walk(it.children); }\n };\n for (const entry of navSections) {\n if (isSection(entry)) walk((entry as NavSection).items);\n else walk([entry as NavItem]);\n }\n return (path: string): string => {\n if (map[path]) return map[path];\n const reg = WINDOW_REGISTRY[path];\n if (reg && isPageEntry(reg)) return (reg as PageRegistryEntry).label;\n return path.replace(/^\\//, '');\n };\n }, [navSections]);\n\n if (favorites.length === 0) return null;\n\n // Same anchoring rules as the taskbar context menu — open away from the\n // taskbar edge so the menu never renders underneath it.\n const menuStyle = (x: number, y: number): React.CSSProperties =>\n taskbarPosition === 'top' ? { left: Math.min(x, window.innerWidth - 200), top: y + 4 } :\n taskbarPosition === 'left' ? { left: x + 4, top: Math.min(y, window.innerHeight - 120) } :\n taskbarPosition === 'right' ? { right: window.innerWidth - x + 4, top: Math.min(y, window.innerHeight - 120) } :\n { left: Math.min(x, window.innerWidth - 200), bottom: window.innerHeight - y + 4 };\n\n return (\n <>\n <div className={vertical\n ? 'w-full px-2 flex flex-wrap items-center justify-center gap-1 shrink-0 max-h-[30vh] overflow-y-auto'\n : 'flex items-center gap-1 shrink-0 max-w-[40vw] overflow-x-auto [scrollbar-width:none]'}>\n {favorites.map(path => {\n const label = labelFor(path);\n const icon = navIcons[path];\n return (\n <button key={path} onClick={() => onOpen(path)} title={label}\n onContextMenu={e => { e.preventDefault(); e.stopPropagation(); setMenu({ x: e.clientX, y: e.clientY, path, label }); }}\n className=\"flex items-center justify-center rounded-lg p-2 border bg-gray-50/40 border-gray-200/40 text-gray-600 hover:bg-gray-200/40 hover:text-gray-800 transition-colors shrink-0\">\n {icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-4 w-4' })\n : <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z\" /></svg>}\n </button>\n );\n })}\n </div>\n {menu && (\n <PopupMenu portal minWidth={180} style={menuStyle(menu.x, menu.y)} onClose={() => setMenu(null)}>\n <PopupMenuItem onClick={() => { setMenu(null); onOpen(menu.path); }}>\n {(() => {\n const icon = navIcons[menu.path];\n return icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-4 w-4 text-gray-400' })\n : <span className=\"w-4\" />;\n })()}\n Open {menu.label}\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => { setMenu(null); onToggleFavorite(menu.path); }}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" />\n </svg>\n Remove from Favorites\n </PopupMenuItem>\n </PopupMenu>\n )}\n </>\n );\n}\n\nexport default function Layout({\n branding,\n productName = 'react-os-shell',\n productIcon = '/favicon.svg',\n wallpapers,\n navSections = defaultNavSections,\n navIcons = defaultNavIcons,\n sectionIcons = defaultSectionIcons,\n categories = defaultCategories,\n notifications,\n search,\n taskbarTrayLeft,\n clockCalendar,\n mobileApp,\n contextMenu = true,\n}: LayoutProps = {}) {\n // `branding` wins over the loose props — one object, one place, and a\n // consumer can move over field by field.\n const brandName = branding?.productName ?? productName;\n const brandIcon = branding?.logo ?? productIcon;\n const brandTagline = branding?.tagline;\n const brandAdaptive = branding?.adaptiveLogo ?? false;\n const brandHasAlpha = branding?.logoHasAlpha ?? null;\n const brandIsLight = branding?.logoIsLight ?? null;\n const host = useDesktopHost();\n const { user, logout, hasAnyPerm } = useAuth();\n const { openPage, openEntity, openWindows } = useWindowManager();\n const [menuOpen, setMenuOpen] = useState(false);\n const isMobile = useIsMobile();\n\n // Profile is reserved for consumer integration; the shell only consumes prefs.\n const profile: any = user || {};\n\n useTheme();\n // Fall back to the host-registered wallpaper pool (the same source the\n // Customization picker reads) when no explicit `wallpapers` prop is given —\n // otherwise a host-only consumer gets an empty pool and `desktop_bg: 'random'`\n // (also the default for a user who's never picked one) collapses to 'none'.\n const { favorites, toggle: toggleFavorite, isFavorite, desktopBg, setDesktopBg } =\n useFavorites(wallpapers ?? host.wallpapers?.map(w => w.src));\n\n const { prefs, save: savePrefs } = useShellPrefs();\n\n // Layout mode — 'sidebar' opt-in for small-screen users. Forces a\n // persistent left strip, horizontal taskbar starting at the sidebar's\n // right edge, and always-maximized non-widget windows.\n const layoutMode: 'classic' | 'sidebar' = prefs.layout_mode === 'sidebar' ? 'sidebar' : 'classic';\n const sidebarMode = layoutMode === 'sidebar';\n const sidebarWidth = sidebarMode ? SIDEBAR_STRIP_W : 0;\n\n // Taskbar layout — when sidebar mode is active we force the taskbar\n // horizontal across the bottom; the design doesn't support a vertical\n // taskbar living next to the sidebar.\n const taskbarPositionRaw: string = prefs.taskbar_position || 'bottom';\n const taskbarPosition: string = sidebarMode ? 'bottom' : taskbarPositionRaw;\n const taskbarSize: string = prefs.taskbar_size || 'medium';\n const desktopDblClick: string = prefs.desktop_dblclick || 'deactivate';\n\n const isVerticalTaskbar = taskbarPosition === 'left' || taskbarPosition === 'right';\n const taskbarH = isVerticalTaskbar ? 0 : (taskbarSize === 'small' ? 42 : taskbarSize === 'large' ? 72 : 56);\n const taskbarW = isVerticalTaskbar ? (taskbarSize === 'small' ? 180 : taskbarSize === 'large' ? 260 : 220) : 0;\n // Gap between the Start menu and the taskbar edge, tuned per taskbar size.\n const taskbarGap = taskbarSize === 'small' ? 2 : taskbarSize === 'large' ? 6 : 4;\n const taskbarHClass = taskbarSize === 'small' ? 'h-[42px]' : taskbarSize === 'large' ? 'h-[72px]' : 'h-14';\n const taskbarWClass = taskbarSize === 'small' ? 'w-[180px]' : taskbarSize === 'large' ? 'w-[260px]' : 'w-[220px]';\n // \"Reduce transparency\" (Preferences → Customization): drop the frosted-glass\n // blur and make surfaces solid for better performance on older machines. The\n // root class drives the global stylesheet rule (blur strip + opacity vars) and\n // glassStyle(); the taskbar tints from a JS value below, so force it opaque here.\n const reduceTransparency = !!prefs.reduce_transparency;\n // Transparency preferences → CSS custom properties for Modal.tsx to read\n const taskbarOpacity = reduceTransparency ? 1 : (prefs.transparency_taskbar ?? 70) / 100;\n const menuOpacity = (prefs.transparency_start_menu ?? 95) / 100;\n const inactiveHeaderOpacity = (prefs.transparency_inactive_header ?? 70) / 100;\n const inactiveContentOpacity = (prefs.transparency_inactive_content ?? 80) / 100;\n const activeHeaderOpacity = (prefs.transparency_active_header ?? 80) / 100;\n const activeContentOpacity = (prefs.transparency_active_content ?? 90) / 100;\n useEffect(() => {\n const root = document.documentElement;\n // Drives the global reduce-transparency stylesheet rule (blur strip + solid\n // opacity vars) and glassStyle(). Kept in the same effect as the opacity\n // vars so both land on the same frame when the pref changes.\n root.classList.toggle('rosh-reduce-transparency', reduceTransparency);\n root.style.setProperty('--inactive-header-opacity', String(inactiveHeaderOpacity));\n root.style.setProperty('--inactive-content-opacity', String(inactiveContentOpacity));\n root.style.setProperty('--active-header-opacity', String(activeHeaderOpacity));\n root.style.setProperty('--active-content-opacity', String(activeContentOpacity));\n root.style.setProperty('--menu-opacity', String(menuOpacity));\n // Suffix `px` so consumers using these vars inside CSS calc() get a\n // valid length. JS readers (parseInt(...)) handle either form. Without\n // the unit, expressions like `calc(100vh - var(--taskbar-height) - 24px)`\n // are invalid and the browser drops the whole property — which previously\n // broke the Modal autoHeight cap for any consumer that wasn't a widget.\n root.style.setProperty('--taskbar-height', `${taskbarH}px`);\n root.style.setProperty('--taskbar-width', `${taskbarW}px`);\n root.style.setProperty('--taskbar-position', taskbarPosition);\n // Sidebar mode: width of the persistent left strip + a layout-mode\n // marker. Modal reads both — sidebar-width to offset its calcMaximized\n // box, layout-mode to switch into \"always maximized\" behaviour.\n root.style.setProperty('--sidebar-width', `${sidebarWidth}px`);\n root.style.setProperty('--layout-mode', layoutMode);\n // Tell already-mounted Modals to refresh their alwaysMaximized flag\n // (they don't have access to ShellPrefs context — they listen for\n // this event so the toggle takes effect immediately).\n window.dispatchEvent(new CustomEvent('react-os-shell:layout-mode-changed'));\n root.style.setProperty('--default-window-size', prefs.default_window_size || 'large');\n root.style.setProperty('--window-position', prefs.window_position || 'cascade');\n root.style.setProperty('--menu-density', prefs.menu_density || 'normal');\n // Menu size — affects font size and item padding across PopupMenu (context menus, dropdowns, notification popup, etc.)\n // Also drives the taskbar window-tab width so it stays proportional.\n const menuSize = prefs.start_menu_size || 'medium';\n const sizeVars: Record<string, { font: string; px: string; py: string; tabW: string; tabFont: string }> = {\n small: { font: '12px', px: '0.75rem', py: '0.25rem', tabW: '150px', tabFont: '11px' },\n medium: { font: '14px', px: '1rem', py: '0.5rem', tabW: '200px', tabFont: '12px' },\n large: { font: '15px', px: '1.125rem', py: '0.625rem', tabW: '240px', tabFont: '13px' },\n };\n const sv = sizeVars[menuSize] || sizeVars.medium;\n root.style.setProperty('--menu-font-size', sv.font);\n root.style.setProperty('--menu-padding-x', sv.px);\n root.style.setProperty('--menu-padding-y', sv.py);\n root.style.setProperty('--window-tab-width', sv.tabW);\n root.style.setProperty('--window-tab-font-size', sv.tabFont);\n }, [reduceTransparency, inactiveHeaderOpacity, inactiveContentOpacity, activeHeaderOpacity, activeContentOpacity, taskbarH, taskbarPosition, prefs.default_window_size, prefs.window_position, prefs.menu_density, prefs.start_menu_size, sidebarWidth, layoutMode]);\n\n // Bottom-nav reservation height, read by Modal to shrink fullscreen apps so\n // they don't render under a nav bar. The shell no longer paints a mobile\n // bottom nav, so this is always 0 — kept as an explicit set (not unset) so\n // Modal's `var(--mobile-bottom-nav, …)` fallback doesn't reintroduce a gap.\n useEffect(() => {\n document.documentElement.style.setProperty('--mobile-bottom-nav', '0px');\n }, []);\n const [balloonDismissed, setBalloonDismissed] = useState(false);\n const [isFullscreen, setIsFullscreen] = useState(!!document.fullscreenElement);\n const [taskbarMenu, setTaskbarMenu] = useState<{ x: number; y: number } | null>(null);\n const [showLogout, setShowLogout] = useState(false);\n\n const savePref = useCallback((key: string, value: any) => {\n savePrefs({ [key]: value });\n }, [savePrefs]);\n\n const toggleFullscreen = useCallback(async () => {\n if (document.fullscreenElement) {\n // Release keyboard lock before exiting\n if ((navigator as any).keyboard?.unlock) (navigator as any).keyboard.unlock();\n document.exitFullscreen();\n } else {\n await document.documentElement.requestFullscreen();\n // Lock Escape key so it goes to our app instead of exiting fullscreen\n if ((navigator as any).keyboard?.lock) {\n try { await (navigator as any).keyboard.lock(['Escape']); } catch { /* not supported or denied */ }\n }\n }\n }, []);\n\n // Sync fullscreen state with browser\n useEffect(() => {\n const handler = () => {\n setIsFullscreen(!!document.fullscreenElement);\n // Release keyboard lock when exiting fullscreen\n if (!document.fullscreenElement && (navigator as any).keyboard?.unlock) {\n (navigator as any).keyboard.unlock();\n }\n };\n document.addEventListener('fullscreenchange', handler);\n return () => document.removeEventListener('fullscreenchange', handler);\n }, []);\n\n // Auto-fullscreen on login\n const autoFullscreenDone = useRef(false);\n useEffect(() => {\n if (autoFullscreenDone.current) return;\n if (prefs.auto_fullscreen && !document.fullscreenElement) {\n autoFullscreenDone.current = true;\n // Needs a user gesture — use a one-time click listener\n const handler = async () => {\n if (!document.fullscreenElement) {\n try {\n await document.documentElement.requestFullscreen();\n if ((navigator as any).keyboard?.lock) (navigator as any).keyboard.lock(['Escape']).catch(() => {});\n } catch {}\n }\n document.removeEventListener('click', handler);\n };\n document.addEventListener('click', handler, { once: true });\n }\n }, [prefs.auto_fullscreen]);\n\n // Startup animation + sound\n const [showStartup, setShowStartup] = useState(false);\n const startupChecked = useRef(false);\n useEffect(() => {\n if (startupChecked.current) return;\n startupChecked.current = true;\n const key = 'erp_startup_shown';\n if (!sessionStorage.getItem(key)) {\n sessionStorage.setItem(key, '1');\n setShowStartup(true);\n }\n }, []);\n\n const startupSoundDone = useRef(false);\n useEffect(() => {\n if (startupSoundDone.current || !showStartup) return;\n startupSoundDone.current = true;\n setTimeout(() => playStartup(), 500);\n }, [showStartup]);\n\n // Hotkey: Ctrl+. / Cmd+. to toggle menu, F11 to toggle fullscreen\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if ((e.ctrlKey || e.metaKey) && e.key === '.') {\n e.preventDefault();\n setMenuOpen(prev => !prev);\n }\n if (e.ctrlKey && e.key === 'F11') {\n e.preventDefault();\n toggleFullscreen();\n }\n if (e.key === 'Escape' && document.fullscreenElement) {\n // Only exit fullscreen if no modals are open (let modals handle Escape first)\n const hasOpenModals = document.querySelectorAll('[data-modal-panel]').length > 0;\n if (!hasOpenModals) {\n e.preventDefault();\n toggleFullscreen();\n }\n }\n };\n window.addEventListener('keydown', handler);\n return () => { window.removeEventListener('keydown', handler); };\n }, [toggleFullscreen]);\n\n return (\n <div className=\"flex flex-col h-screen\">\n {/* Reopen last session's windows — see SessionRestore.tsx. */}\n <SessionWindowRestore />\n {showStartup && <StartupAnimation onComplete={() => setShowStartup(false)} ready={!!profile} productName={brandName} logo={brandIcon} subtitle={brandTagline} adaptiveLogo={brandAdaptive} logoHasAlpha={brandHasAlpha} logoIsLight={brandIsLight} />}\n {showLogout && <LogoutAnimation onComplete={() => { sessionStorage.removeItem('erp_startup_shown'); logout(); }} logo={brandIcon} subtitle={brandTagline} adaptiveLogo={brandAdaptive} logoHasAlpha={brandHasAlpha} logoIsLight={brandIsLight} />}\n {/* Start Menu — suppressed in sidebar mode (Sidebar replaces it). */}\n {!sidebarMode && (\n <StartMenu\n open={menuOpen}\n onClose={() => setMenuOpen(false)}\n openPage={(path) => { openPage(path); setMenuOpen(false); }}\n openWindows={openWindows}\n profile={profile}\n user={user}\n onLogout={() => setShowLogout(true)}\n onNavigate={(path) => { openPage(path); setMenuOpen(false); }}\n taskbarPosition={taskbarPosition as 'top' | 'bottom' | 'left' | 'right'}\n taskbarH={taskbarH}\n taskbarW={taskbarW}\n taskbarGap={taskbarGap}\n size={(prefs.start_menu_size || 'medium') as 'small' | 'medium' | 'large'}\n navSections={navSections}\n navIcons={navIcons}\n sectionIcons={sectionIcons}\n categories={categories}\n />\n )}\n\n {/* Sidebar — persistent left strip for sidebar layout mode.\n Lazy-imported so a stale source checkout missing Sidebar.tsx\n only blows up if the user flips into sidebar mode (vs. crashing\n at module load), and so the chunk is only fetched when needed. */}\n {sidebarMode && (\n <Suspense fallback={null}>\n <Sidebar\n width={sidebarWidth}\n openPage={(path) => openPage(path)}\n profile={profile}\n user={user}\n onLogout={() => setShowLogout(true)}\n onNavigate={(path) => openPage(path)}\n navSections={navSections}\n navIcons={navIcons}\n sectionIcons={sectionIcons}\n categories={categories}\n productName={brandName}\n productIcon={brandIcon}\n adaptiveLogo={brandAdaptive}\n logoHasAlpha={brandHasAlpha}\n logoIsLight={brandIsLight}\n />\n </Suspense>\n )}\n\n {(() => {\n // Shared wallpaper style used by both the desktop main area and the\n // mobile landing screen so the user's chosen background carries across\n // breakpoints.\n const wallpaperStyle: React.CSSProperties = {\n backgroundColor: desktopBg?.startsWith('#') ? desktopBg : desktopBg === 'none' ? (() => {\n const customBg = getComputedStyle(document.documentElement).getPropertyValue('--custom-bg-color')?.trim();\n if (customBg) return customBg;\n const t = document.documentElement.getAttribute('data-theme') || 'light';\n const map: Record<string, string> = { light: '#f3f4f6', dark: '#1e1e2e', pink: '#fdf2f8', green: '#f0fdf4', grey: '#d1d5db', blue: '#eff6ff' };\n return map[t] || '#f3f4f6';\n })() : '#1a1a2e',\n backgroundImage: desktopBg && desktopBg !== 'none' && !desktopBg.startsWith('#') ? `url(${desktopBg})` : 'none',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n backgroundRepeat: 'no-repeat',\n };\n\n if (isMobile) {\n return (\n <MobileAppLanding\n productName={brandName}\n productIcon={brandIcon}\n adaptiveLogo={brandAdaptive}\n logoHasAlpha={brandHasAlpha}\n logoIsLight={brandIsLight}\n config={mobileApp}\n wallpaperStyle={wallpaperStyle}\n />\n );\n }\n\n return (\n <>\n <div className=\"flex flex-1 min-h-0\">\n <main\n className=\"flex-1 flex flex-col overflow-hidden cursor-default\"\n onDoubleClick={() => {\n if (desktopDblClick === 'deactivate') { setMenuOpen(false); window.dispatchEvent(new CustomEvent('deactivate-all-modals')); }\n }}\n style={wallpaperStyle}\n >\n {/* Desktop with shortcuts, folders, and context menu */}\n <Desktop profile={profile} />\n </main>\n </div>\n\n {/* Taskbar — overlays content for transparency. In sidebar mode the\n left edge starts at the sidebar's right edge instead of x=0. */}\n <div className={`flex backdrop-blur-sm border-gray-200 z-[250] fixed ${\n isVerticalTaskbar\n ? `flex-col items-center ${taskbarWClass} py-3 gap-2 top-0 bottom-0 ${taskbarPosition === 'left' ? 'left-0 border-r' : 'right-0 border-l'}`\n : `items-center ${taskbarHClass} px-3 gap-2 right-0 ${taskbarPosition === 'top' ? 'top-0 border-b' : 'bottom-0 border-t'}`\n }`}\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${taskbarOpacity})`,\n ...(isVerticalTaskbar ? {} : { left: sidebarWidth }),\n }}\n // Hit-test target for drag-to-pin: dropping a page shortcut from the\n // desktop over the taskbar pins it to favorite_pages (see Desktop.tsx).\n data-taskbar-dropzone\n onContextMenu={e => { e.preventDefault(); setTaskbarMenu({ x: e.clientX, y: e.clientY }); }}>\n {/* ERP button — toggles Start Menu. Hidden in sidebar mode where\n the persistent left sidebar replaces the start-menu role. */}\n {!sidebarMode && <div className=\"relative shrink-0\">\n {openWindows.length === 0 && !menuOpen && !balloonDismissed && (\n <div className={`absolute left-1/2 -translate-x-1/2 whitespace-nowrap text-white text-[10px] font-medium pl-3 pr-2 py-1 rounded-full shadow-lg animate-bounce flex items-center gap-1 ${taskbarPosition === 'top' ? 'top-full mt-2' : '-top-8'}`}\n style={{ backgroundColor: 'var(--accent-600, #7c3aed)' }}>\n Click here to start\n <button onClick={(e) => { e.stopPropagation(); setBalloonDismissed(true); }} className=\"text-white/60 hover:text-white ml-1.5\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n <div className={`absolute left-1/2 -translate-x-1/2 border-[6px] border-transparent ${taskbarPosition === 'top' ? 'bottom-full border-b-[var(--accent-color,#7c3aed)]' : 'top-full border-t-[var(--accent-color,#7c3aed)]'}`}\n style={taskbarPosition === 'top' ? { borderBottomColor: 'var(--accent-600, #7c3aed)' } : { borderTopColor: 'var(--accent-600, #7c3aed)' }} />\n </div>\n )}\n <button data-menu-toggle onClick={() => setMenuOpen(prev => !prev)} title={menuOpen ? 'Close menu' : 'Open menu'}\n className={`group/erp relative flex items-center justify-center gap-1.5 rounded-lg px-4 py-2 text-xs font-medium border overflow-hidden transition-all ${isVerticalTaskbar ? 'w-full' : 'min-w-[140px]'} ${menuOpen ? 'bg-gray-200/40 border-gray-300/40 text-gray-800' : 'bg-gray-50/40 border-gray-200/40 text-gray-600 hover:text-gray-800'}`}\n style={{ transition: 'box-shadow 0.3s, border-color 0.3s' }}\n onMouseMove={e => { const r = e.currentTarget.getBoundingClientRect(); e.currentTarget.style.setProperty('--mx', `${e.clientX - r.left}px`); e.currentTarget.style.setProperty('--my', `${e.clientY - r.top}px`); }}\n onMouseEnter={e => { e.currentTarget.style.boxShadow = '0 0 15px rgba(255,255,255,0.2), 0 0 30px rgba(255,255,255,0.1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.4)'; }}\n onMouseLeave={e => { e.currentTarget.style.boxShadow = ''; e.currentTarget.style.borderColor = ''; }}>\n <span className=\"absolute inset-0 opacity-0 group-hover/erp:opacity-100 transition-opacity duration-200 pointer-events-none\"\n style={{ background: 'radial-gradient(circle 60px at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,0.25) 0%, transparent 100%)' }} />\n {brandIcon && (\n <BrandMark\n src={brandIcon}\n alt=\"\"\n slot=\"compact\"\n surface=\"light\"\n adaptive={brandAdaptive}\n hasAlpha={brandHasAlpha}\n isLight={brandIsLight}\n size={14}\n decorative\n className=\"relative z-10 opacity-60\"\n />\n )}\n <span className=\"relative z-10 truncate\">{brandName}</span>\n </button>\n </div>}\n\n {/* Pinned favorites — favorited apps as quick-launch icons next to\n the start-menu button. Hidden (with the button) in sidebar mode. */}\n {!sidebarMode && (\n <TaskbarFavorites\n favorites={favorites}\n vertical={isVerticalTaskbar}\n taskbarPosition={taskbarPosition}\n navSections={navSections}\n navIcons={navIcons}\n onOpen={(path) => openPage(path)}\n onToggleFavorite={toggleFavorite}\n />\n )}\n\n {/* Separator (only when the ERP button is also rendered) */}\n {!sidebarMode && <div className={isVerticalTaskbar ? 'h-px w-6 bg-gray-300 my-1' : 'w-px h-6 bg-gray-300 mx-1'} />}\n\n {/* Window tabs rendered here by WindowManagerProvider */}\n <div id=\"taskbar-windows\" className={`flex-1 flex ${isVerticalTaskbar ? 'flex-col items-center gap-1 min-h-0 overflow-y-auto w-full' : 'items-center gap-1.5 min-w-0 overflow-x-auto'}`} />\n\n {/* Separator */}\n <div className={isVerticalTaskbar ? 'h-px w-6 bg-gray-300 my-1' : 'w-px h-6 bg-gray-300 mx-1'} />\n\n {/* System tray */}\n {isVerticalTaskbar ? (\n /* Vertical: clock + bell evenly spaced */\n <div className=\"w-full px-2\">\n <div className={`flex items-center justify-center gap-2 ${taskbarPosition === 'right' ? 'flex-row-reverse' : ''}`}>\n <TaskbarClock clockCalendar={clockCalendar} />\n <TaskbarPomodoro />\n {/* Host-supplied tray content (e.g. server-status icon).\n Sits next to the notification bell on the bell's\n outer edge. */}\n {taskbarTrayLeft}\n {notifications && <NotificationBell {...notifications} popDirection={taskbarPosition === 'right' ? 'left' : 'right'} />}\n </div>\n </div>\n ) : (\n /* Horizontal: icons then clock */\n <>\n <TaskbarPomodoro />\n {taskbarTrayLeft}\n {notifications && <NotificationBell {...notifications} />}\n <TaskbarClock clockCalendar={clockCalendar} />\n </>\n )}\n </div>\n </>\n );\n })()}\n\n {/* Taskbar context menu */}\n {taskbarMenu && (\n <TaskbarContextMenu\n x={taskbarMenu.x} y={taskbarMenu.y}\n position={taskbarPosition}\n size={taskbarSize}\n onChangePosition={v => { savePref('taskbar_position', v); setTaskbarMenu(null); }}\n onChangeSize={v => { savePref('taskbar_size', v); setTaskbarMenu(null); }}\n onClose={() => setTaskbarMenu(null)}\n onReportBug={host.onReportBug}\n />\n )}\n\n {/* GlobalSearch no longer reaches for the window manager itself — that\n one import was what kept it out of `react-os-shell/ui`. Passing it in\n here keeps the desktop behaviour identical. */}\n <GlobalSearch\n {...search}\n onSelect={result => openEntity(result.entity_type, result.entity_id, undefined, result.label)}\n />\n <ShortcutHelp />\n {/* One right-click menu for the whole shell. Surfaces with their own\n menu already preventDefault(), so this only fills the gaps where\n the browser's native menu used to show through. */}\n <ShellContextMenu disabled={!contextMenu} />\n </div>\n );\n}\n","import { useRef, useState, useCallback, useEffect } from 'react';\nimport { ModalActions, forgetMaximizedWindowBoxes } from '../shell/Modal';\nimport { useDesktopHost } from '../shell/Desktop';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { applyThemePrefs, resolveTheme } from '../hooks/useTheme';\nimport { SOUND_PACKS, SOUND_PACK_KEYS, SOUND_TYPES, SOUND_TYPE_LABELS, getSoundConfig, setSoundForType, setAllSounds, soundsEnabled, previewSound, type SoundType } from '../utils/sounds';\n\n// Preview tiles use literal hex values via arbitrary Tailwind syntax so that the\n// active theme's [data-theme=\"...\"] !important overrides don't repaint them\n// (the Light preview must stay light even when Dark is the current theme).\nconst THEMES = [\n { key: 'system', label: 'System', bar1: 'bg-[#e5e7eb]', bar2: 'bg-[#e5e7eb]' },\n { key: 'light', label: 'Light', bar1: 'bg-[#e5e7eb]', bar2: 'bg-[#e5e7eb]' },\n { key: 'dark', label: 'Dark', bar1: 'bg-[#45475a]', bar2: 'bg-[#45475a]' },\n { key: 'pink', label: 'Blossom', bar1: 'bg-[#fbcfe8]', bar2: 'bg-[#fbcfe8]' },\n { key: 'green', label: 'Nature', bar1: 'bg-[#bbf7d0]', bar2: 'bg-[#bbf7d0]' },\n { key: 'grey', label: 'Quicksilver', bar1: 'bg-[#d1d5db]', bar2: 'bg-[#d1d5db]' },\n { key: 'blue', label: 'Ocean', bar1: 'bg-[#bfdbfe]', bar2: 'bg-[#bfdbfe]' },\n];\n\n// Default wallpaper list (consumer-overridable via DesktopHostProvider).\nconst DEFAULT_WALLPAPERS: { src: string; label: string }[] = [];\n\nfunction getVersion() {\n const now = new Date();\n return `v${String(now.getDate()).padStart(2, '0')}${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getHours()).padStart(2, '0')}.${String(now.getMinutes()).padStart(2, '0')}.${now.getFullYear()}`;\n}\n\nfunction previewColor(resolved: string, light: string, dark: string, pink: string, green: string, grey?: string, blue?: string) {\n if (resolved === 'dark') return dark;\n if (resolved === 'pink') return pink;\n if (resolved === 'green') return green;\n if (resolved === 'grey') return grey ?? light;\n if (resolved === 'blue') return blue ?? light;\n return light;\n}\n\n/** Sections that can be omitted from the inline Customization page when the\n * consumer renders them elsewhere (e.g. as separate entries in SystemPreferences). */\nexport type CustomizationOmitSection = 'behavior' | 'desktop';\n\n/** A logical group of the Customization page. Pass `section` to render only one\n * group, so the page can be split across separate SystemPreferences entries\n * (Appearance / Layout / Behavior). Omit `section` to render the whole page. */\nexport type CustomizationSection = 'appearance' | 'layout' | 'behavior';\n\nexport interface CustomizationProps {\n omit?: readonly CustomizationOmitSection[];\n /** Render only one logical group of settings. Omit to render everything. */\n section?: CustomizationSection;\n}\n\nexport default function Customization({ omit, section }: CustomizationProps = {}) {\n const omitSet = new Set(omit ?? []);\n // With `section` set, render only that group's blocks; otherwise render all.\n const inSection = (group: CustomizationSection) => section === undefined || section === group;\n const host = useDesktopHost();\n const WALLPAPERS = host.wallpapers && host.wallpapers.length > 0 ? host.wallpapers : DEFAULT_WALLPAPERS;\n const { prefs, save } = useShellPrefs();\n\n // Appearance writes (theme / accent / custom colors) persist through save(),\n // which on a backend-backed adapter round-trips to the server before `prefs`\n // reflects the new value — sometimes tens of seconds. Mirror the change\n // locally so the picker's selected state + live preview update on click;\n // applyThemePrefs (in setAppearance) repaints the desktop the same frame.\n // Each override is dropped once `prefs` catches up to it.\n const [optimisticAppearance, setOptimisticAppearance] = useState<Record<string, any>>({});\n const pref = (key: string) => (key in optimisticAppearance ? optimisticAppearance[key] : prefs[key]);\n useEffect(() => {\n setOptimisticAppearance(prev => {\n const next: Record<string, any> = {};\n let settled = false;\n for (const k of Object.keys(prev)) {\n if (prefs[k] === prev[k]) settled = true; // server caught up → drop override\n else next[k] = prev[k];\n }\n return settled ? next : prev;\n });\n }, [prefs]);\n\n // Apply an appearance patch to <html> immediately (no save round-trip wait),\n // reflect it in the optimistic mirror, then persist it in the background.\n const APPEARANCE_KEYS = ['theme', 'accent_color', 'custom_bg_color', 'custom_title_color', 'custom_window_color', 'custom_button_color'] as const;\n const setAppearance = (patch: Record<string, any>) => {\n const snapshot: Record<string, any> = { ...patch };\n for (const k of APPEARANCE_KEYS) if (!(k in snapshot)) snapshot[k] = pref(k);\n applyThemePrefs(snapshot);\n setOptimisticAppearance(prev => ({ ...prev, ...patch }));\n save(patch);\n };\n\n const currentTheme: string = pref('theme') || 'system';\n const resolved = resolveTheme(currentTheme);\n const rawBg: string = prefs.desktop_bg || (WALLPAPERS.length > 0 ? 'random' : 'none');\n const randomPickRef = useRef(WALLPAPERS.length > 0 ? WALLPAPERS[Math.floor(Math.random() * WALLPAPERS.length)].src : 'none');\n const desktopBg = rawBg === 'random' ? randomPickRef.current : rawBg;\n const customBg: string = prefs.desktop_bg_custom || '';\n const isColor = desktopBg?.startsWith('#');\n const presetPaths = new Set([...WALLPAPERS.map(w => w.src), 'random']);\n const isCustom = !isColor && desktopBg !== 'none' && rawBg !== 'random' && desktopBg && !presetPaths.has(desktopBg);\n\n const savePref = (key: string, value: any) => {\n save({ [key]: value });\n };\n\n // \"Reduce transparency\" — drops the frosted-glass blur and makes surfaces\n // solid (better performance on older machines). Toggle the root class now for\n // instant feedback (Layout's effect reconciles once the prefs adapter\n // settles) and mirror optimistically so the checkbox + slider disabling don't\n // lag the save round-trip. Reuses the appearance optimistic mirror + settle\n // effect above.\n const reduceOn = !!pref('reduce_transparency');\n const setReduce = (on: boolean) => {\n document.documentElement.classList.toggle('rosh-reduce-transparency', on);\n setOptimisticAppearance(prev => ({ ...prev, reduce_transparency: on }));\n save({ reduce_transparency: on });\n };\n\n // Debounced save for sliders — updates local state instantly, saves after 300ms idle\n const [localSliders, setLocalSliders] = useState<Record<string, number>>({});\n const sliderTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n const saveSlider = useCallback((key: string, value: number) => {\n setLocalSliders(prev => ({ ...prev, [key]: value }));\n // Apply CSS variable immediately for instant visual feedback\n const cssMap: Record<string, string> = {\n transparency_taskbar: '--taskbar-opacity',\n transparency_inactive_header: '--inactive-header-opacity',\n transparency_inactive_content: '--inactive-content-opacity',\n transparency_active_header: '--active-header-opacity',\n transparency_active_content: '--active-content-opacity',\n };\n if (cssMap[key]) {\n document.documentElement.style.setProperty(cssMap[key], String(value / 100));\n }\n if (sliderTimers.current[key]) clearTimeout(sliderTimers.current[key]);\n sliderTimers.current[key] = setTimeout(() => {\n savePref(key, value);\n setLocalSliders(prev => { const next = { ...prev }; delete next[key]; return next; });\n }, 300);\n }, [savePref]);\n // Cleanup timers on unmount\n useEffect(() => () => { Object.values(sliderTimers.current).forEach(clearTimeout); }, []);\n\n const prevTaskbarOpacity = (prefs.transparency_taskbar ?? 70) / 100;\n const prevActiveHeaderOpacity = (prefs.transparency_active_header ?? 80) / 100;\n const prevActiveContentOpacity = (prefs.transparency_active_content ?? 90) / 100;\n const taskbarBg = previewColor(resolved, 'bg-white/90', 'bg-[#1e1e2e]/90', 'bg-pink-50/90', 'bg-green-50/90', 'bg-gray-200/90', 'bg-blue-50/90');\n const iconBg = previewColor(resolved, 'bg-gray-200', 'bg-[#313244]', 'bg-pink-200', 'bg-green-200', 'bg-gray-400', 'bg-blue-200');\n const winBg = previewColor(resolved, 'bg-white border border-gray-200', 'bg-[#1e1e2e] border border-[#45475a]', 'bg-white border border-pink-200', 'bg-white border border-green-200', 'bg-gray-100 border border-gray-300', 'bg-blue-50 border border-blue-200');\n const headerBg = previewColor(resolved, 'bg-gray-100', 'bg-[#313244]', 'bg-pink-50', 'bg-green-50', 'bg-gray-300', 'bg-blue-100');\n const accentBg = previewColor(resolved, 'bg-blue-600', 'bg-blue-500', 'bg-pink-600', 'bg-green-600', 'bg-gray-700', 'bg-blue-700');\n\n return (\n <div className=\"space-y-6\">\n {inSection('appearance') && (\n <>\n {/* ── Live Preview ── */}\n <div className=\"flex justify-center\">\n <div className=\"rounded-lg border border-gray-200 overflow-hidden\" style={{ width: 480 }}>\n <div className=\"relative\" style={{ height: 300 }}>\n {/* Wallpaper */}\n {isColor ? (\n <div className=\"absolute inset-0\" style={{ backgroundColor: desktopBg }} />\n ) : (\n <img src={desktopBg} alt=\"\" className=\"absolute inset-0 w-full h-full object-cover\" />\n )}\n {/* Mini taskbar */}\n <div className={`absolute left-0 right-0 bottom-0 h-4 ${taskbarBg} border-t border-gray-200/50 flex items-center px-2 gap-1`} style={{ opacity: prevTaskbarOpacity }}>\n <div className={`h-2 w-8 rounded-sm ${accentBg}`} />\n <div className={`h-2 w-6 rounded-sm ${iconBg}`} />\n </div>\n {/* Desktop icons */}\n <div className=\"absolute left-4 top-4 flex gap-4\">\n {[\n { icon: '📋', label: 'Orders' },\n { icon: '📦', label: 'Products' },\n { icon: '📊', label: 'Reports' },\n ].map(d => (\n <div key={d.label} className=\"flex flex-col items-center gap-0.5 w-8\">\n <div className=\"text-sm drop-shadow\">{d.icon}</div>\n <span className=\"text-[5px] text-white font-medium drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)] leading-tight\">{d.label}</span>\n </div>\n ))}\n </div>\n {/* Mini window */}\n <div className={`absolute rounded shadow-md ${winBg}`} style={{ left: '35%', top: '20%', width: '55%', height: '55%' }}>\n <div className={`h-3 rounded-t ${headerBg} flex items-center px-1.5 gap-0.5`} style={{ opacity: prevActiveHeaderOpacity }}>\n <div className=\"w-1 h-1 rounded-full bg-red-400\" />\n <div className=\"w-1 h-1 rounded-full bg-yellow-400\" />\n <div className=\"w-1 h-1 rounded-full bg-green-400\" />\n </div>\n <div className=\"p-1.5 space-y-1\" style={{ opacity: prevActiveContentOpacity }}>\n <div className={`h-1 rounded w-3/4 ${iconBg}`} />\n <div className={`h-1 rounded w-1/2 ${iconBg}`} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* ── Theme ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Theme</h3>\n <div className=\"flex gap-3 flex-wrap\">\n {[...THEMES, { key: 'custom', label: 'Custom', bar1: 'bg-gray-200', bar2: 'bg-gray-200' }].map(t => {\n const isCustom = t.key === 'custom';\n const r = isCustom ? 'light' : resolveTheme(t.key);\n const customColor = pref('accent_color') || '#8b5cf6';\n const tAccent = isCustom ? '' : previewColor(r, 'bg-[#2563eb]', 'bg-[#3b82f6]', 'bg-[#db2777]', 'bg-[#16a34a]', 'bg-[#374151]', 'bg-[#1d4ed8]');\n const tBg = isCustom ? 'bg-[#ffffff] border-[#d1d5db]' : previewColor(r, 'bg-[#ffffff] border-[#d1d5db]', 'bg-[#1e1e2e] border-[#45475a]', 'bg-[#fdf2f8] border-[#f9a8d4]', 'bg-[#f0fdf4] border-[#86efac]', 'bg-[#e5e7eb] border-[#9ca3af]', 'bg-[#eff6ff] border-[#93c5fd]');\n return (\n <button key={t.key} onClick={() => {\n if (isCustom) {\n setAppearance(pref('accent_color') ? { theme: 'light' } : { theme: 'light', accent_color: '#8b5cf6' });\n } else {\n setAppearance({ theme: t.key, accent_color: null });\n }\n }}\n className={`flex flex-col items-center gap-1.5 rounded-lg border-2 p-3 transition-all ${(isCustom ? !!pref('accent_color') : currentTheme === t.key && !pref('accent_color')) ? 'border-blue-500 shadow-md' : 'border-gray-200 hover:border-gray-300'}`}>\n <div className={`w-20 h-14 rounded ${tBg} border overflow-hidden flex flex-col`}>\n {t.key === 'system' ? (\n <div className=\"flex-1 flex\">\n <div className=\"flex-1 flex flex-col bg-[#ffffff]\">\n <div className=\"h-2 bg-[#2563eb] w-full\" />\n <div className=\"flex-1 flex gap-0.5 p-0.5\">\n <div className=\"w-3 rounded-sm bg-[#f3f4f6]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1 rounded-sm w-3/4 bg-[#e5e7eb]\" />\n <div className=\"h-1 rounded-sm w-1/2 bg-[#e5e7eb]\" />\n </div>\n </div>\n </div>\n <div className=\"flex-1 flex flex-col bg-[#1e1e2e]\">\n <div className=\"h-2 bg-[#3b82f6] w-full\" />\n <div className=\"flex-1 flex gap-0.5 p-0.5\">\n <div className=\"w-3 rounded-sm bg-[#313244]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1 rounded-sm w-3/4 bg-[#45475a]\" />\n <div className=\"h-1 rounded-sm w-1/2 bg-[#45475a]\" />\n </div>\n </div>\n </div>\n </div>\n ) : isCustom ? (\n <>\n <div className=\"h-2 w-full\" style={{ backgroundColor: customColor }} />\n <div className=\"flex-1 flex gap-0.5 p-1\">\n <div className=\"w-4 rounded-sm bg-[#f3f4f6]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1.5 rounded-sm w-3/4 bg-[#e5e7eb]\" />\n <div className=\"h-1.5 rounded-sm w-1/2 bg-[#e5e7eb]\" />\n </div>\n </div>\n </>\n ) : (\n <>\n <div className={`h-2 ${tAccent} w-full`} />\n <div className=\"flex-1 flex gap-0.5 p-1\">\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className={`h-1.5 rounded-sm w-3/4 ${t.bar1}`} />\n <div className={`h-1.5 rounded-sm w-1/2 ${t.bar2}`} />\n </div>\n </div>\n </>\n )}\n </div>\n <span className={`text-xs font-medium ${(isCustom ? !!pref('accent_color') : currentTheme === t.key && !pref('accent_color')) ? 'text-blue-600' : 'text-gray-600'}`}>{t.label}</span>\n </button>\n );\n })}\n </div>\n\n {/* Custom color pickers — only visible when Custom theme is selected */}\n {pref('accent_color') && (\n <div className=\"mt-3 space-y-2\">\n {([\n { key: 'custom_bg_color', label: 'Background Color', defaultVal: '#f3f4f6' },\n { key: 'custom_title_color', label: 'Header & Footer Color', defaultVal: '#f9fafb' },\n { key: 'custom_window_color', label: 'Windows Background', defaultVal: '#ffffff' },\n { key: 'custom_button_color', label: 'Button Color', defaultVal: '#2563eb' },\n { key: 'accent_color', label: 'Accent Color', defaultVal: '#8b5cf6' },\n ]).map(item => (\n <div key={item.key} className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">{item.label}</span>\n <label className=\"w-8 h-8 rounded-lg border-2 border-gray-300 overflow-hidden cursor-pointer flex items-center justify-center shrink-0\"\n style={{ backgroundColor: pref(item.key) || item.defaultVal }}>\n <input type=\"color\" value={pref(item.key) || item.defaultVal}\n onChange={e => setAppearance({ [item.key]: e.target.value })}\n className=\"opacity-0 absolute w-0 h-0\" />\n </label>\n <span className=\"text-xs text-gray-500 font-mono\">{pref(item.key) || item.defaultVal}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* ── Desktop Wallpaper ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop Wallpaper</h3>\n <div className=\"flex gap-2 flex-wrap items-center\">\n <button onClick={() => savePref('desktop_bg', 'none')}\n className={`w-28 h-20 rounded border-2 overflow-hidden flex items-center justify-center ${rawBg === 'none' ? 'border-blue-500' : 'border-gray-300'}`}\n style={{ backgroundColor: previewColor(resolved, '#f3f4f6', '#1e1e2e', '#fdf2f8', '#f0fdf4', '#d1d5db', '#eff6ff') }}>\n <span className=\"text-[9px] text-gray-500\">None</span>\n </button>\n <button onClick={() => savePref('desktop_bg', 'random')}\n className={`w-28 h-20 rounded border-2 overflow-hidden flex items-center justify-center ${rawBg === 'random' ? 'border-blue-500' : 'border-gray-300'}`}>\n <div className=\"grid grid-cols-2 grid-rows-2 w-full h-full\">\n {WALLPAPERS.slice(0, 4).map(wp => (\n <img key={wp.src} src={wp.src} alt=\"\" loading=\"lazy\" className=\"w-full h-full object-cover\" />\n ))}\n </div>\n </button>\n {WALLPAPERS.map(wp => (\n <button key={wp.src} onClick={() => savePref('desktop_bg', wp.src)}\n className={`w-28 h-20 rounded border-2 overflow-hidden ${rawBg === wp.src ? 'border-blue-500' : 'border-gray-300'}`}>\n <img src={wp.src} alt={wp.label} loading=\"lazy\" className=\"w-full h-full object-cover\" />\n </button>\n ))}\n {(customBg || isCustom) && (\n <div className=\"relative group\">\n <button onClick={() => savePref('desktop_bg', customBg || desktopBg)}\n className={`w-28 h-20 rounded border-2 overflow-hidden ${isCustom ? 'border-blue-500' : 'border-gray-300'}`}>\n <img src={customBg || desktopBg} alt=\"Custom\" loading=\"lazy\" className=\"w-full h-full object-cover\" />\n </button>\n <button onClick={() => save({ desktop_bg: 'random', desktop_bg_custom: '' })}\n className=\"absolute -top-1.5 -right-1.5 h-4 w-4 rounded-full bg-red-500 text-white flex items-center justify-center text-[10px] leading-none opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-600 shadow\">×</button>\n </div>\n )}\n <label className=\"w-28 h-20 rounded border-2 border-gray-300 border-dashed overflow-hidden cursor-pointer flex items-center justify-center text-gray-400 hover:text-gray-600\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n <input type=\"file\" accept=\"image/*\" className=\"hidden\" onChange={e => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onloadend = () => {\n if (reader.result) {\n save({ desktop_bg: reader.result as string, desktop_bg_custom: reader.result as string });\n }\n };\n reader.readAsDataURL(file);\n }} />\n </label>\n </div>\n </div>\n\n {/* ── Transparency ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Transparency</h3>\n {/* Reduce transparency: master switch that overrides the sliders below.\n When on, the shell drops the frosted-glass blur and makes every\n surface solid — the sliders are disabled because they no longer\n have any effect. */}\n <label className=\"flex items-start gap-2 cursor-pointer mb-3\">\n <input type=\"checkbox\" checked={reduceOn} onChange={e => setReduce(e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Reduce transparency\n <span className=\"block text-xs text-gray-400\">\n Turn off the frosted-glass blur and make windows, menus and the taskbar solid.\n Improves performance on older machines.\n </span>\n </span>\n </label>\n <div className={`space-y-3 transition-opacity ${reduceOn ? 'opacity-40 pointer-events-none select-none' : ''}`}\n aria-disabled={reduceOn}>\n {([\n { key: 'transparency_taskbar', label: 'Taskbar', defaultVal: 70 },\n { key: 'transparency_start_menu', label: 'Start Menu', defaultVal: 70 },\n { key: 'transparency_inactive_header', label: 'Inactive Windows Header / Footer', defaultVal: 70 },\n { key: 'transparency_inactive_content', label: 'Inactive Windows Content', defaultVal: 80 },\n { key: 'transparency_active_header', label: 'Active Windows Header / Footer', defaultVal: 80 },\n { key: 'transparency_active_content', label: 'Active Windows Content', defaultVal: 90 },\n ] as const).map(item => {\n const val: number = localSliders[item.key] ?? prefs[item.key] ?? item.defaultVal;\n return (\n <div key={item.key} className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-64 shrink-0\">{item.label}</span>\n <input type=\"range\" min={20} max={100} value={val} disabled={reduceOn}\n onChange={e => saveSlider(item.key, Number(e.target.value))}\n className=\"flex-1 h-1.5 accent-blue-600 cursor-pointer disabled:cursor-not-allowed\" />\n <span className=\"text-xs text-gray-500 w-10 text-right font-mono\">{val}%</span>\n </div>\n );\n })}\n </div>\n </div>\n\n {/* ── Windows ── */}\n {/* SG#00372: the per-section accent stripe. Only does anything when the\n consumer wires `windowAccentForRoute` on WindowManagerProvider — with\n no accents configured the switch is harmless rather than hidden,\n because this panel has no way to ask whether any route has one. */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Windows</h3>\n <label className=\"flex items-start gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={!!pref('window_accent_stripe')}\n onChange={e => savePref('window_accent_stripe', e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Show section color stripe\n <span className=\"block text-xs text-gray-400\">\n Draws a thin colored line between a window's title bar and its content,\n one color per area of the app, so overlapping windows are easier to tell\n apart at a glance.\n </span>\n </span>\n </label>\n </div>\n\n {/* ── Diagnostics ── */}\n {/* Deliberately adjacent to Transparency: the switch above is the usual\n fix for a sluggish machine, and this is how you find out whether it\n was the right fix rather than guessing. */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Diagnostics</h3>\n <label className=\"flex items-start gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={!!pref('show_desktop_stats')}\n onChange={e => savePref('show_desktop_stats', e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Show performance stats\n <span className=\"block text-xs text-gray-400\">\n Overlays frame rate, worst frame time and a bottleneck reading on the desktop,\n beside the version number. Turn it on to check whether Reduce transparency\n actually helps on this machine — or whether the slowness is coming from\n somewhere else.\n </span>\n <span className=\"block text-xs text-gray-400 mt-1\">\n While it is on, each reading is recorded with what was happening at the time —\n how many windows were open, which one was on top, which menu or submenu you\n opened, how long you spent moving or resizing a window, and counts of clicks,\n keystrokes and scrolls. No page content or keystroke text is recorded. The log\n stays on this device unless you use the overlay's Report button, which sends it\n — with whatever you type in the box, and a description of this computer\n (browser, operating system, processor cores, memory, graphics card, screen,\n connection speed and whether you are on battery) — to the team as a bug report.\n </span>\n </span>\n </label>\n </div>\n </>\n )}\n\n {inSection('layout') && (\n <>\n {/* ── Layout Mode ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Layout Mode</h3>\n <p className=\"text-xs text-gray-500 mb-3\">\n Sidebar mode is designed for small screens — windows always run maximized\n and the start menu lives in a persistent left sidebar (sections expand inline\n instead of opening flyouts). Classic is the windowed mode: choosing it puts\n every open window back to its normal size.\n </p>\n <div className=\"flex gap-2\">\n {([\n { key: 'classic', label: 'Classic' },\n { key: 'sidebar', label: 'Sidebar' },\n ] as const).map(m => (\n <button\n key={m.key}\n onClick={() => {\n savePref('layout_mode', m.key);\n // Sidebar forces every window maximized through the\n // `--layout-mode` CSS var, so it must NOT also write the user's\n // 'Default window size' preference — doing so left classic mode\n // permanently opening windows full-screen once sidebar had been\n // tried even once. Classic instead undoes that stuck value and\n // asks live windows to drop back to their windowed size.\n if (m.key === 'classic') {\n if (prefs.default_window_size === 'maximized') savePref('default_window_size', 'large');\n // Open windows un-maximize now; closed ones would still\n // reopen at the full-screen box they saved while maximized.\n forgetMaximizedWindowBoxes();\n window.dispatchEvent(new CustomEvent('react-os-shell:restore-windowed'));\n }\n }}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.layout_mode || 'classic') === m.key\n ? 'bg-blue-600 text-white border-blue-600'\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}\n >\n {m.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* ── Taskbar ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Taskbar</h3>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Position</span>\n <div className=\"flex gap-2\">\n {(['bottom', 'top', 'left', 'right'] as const).map(pos => (\n <button key={pos} onClick={() => savePref('taskbar_position', pos)}\n disabled={prefs.layout_mode === 'sidebar'}\n title={prefs.layout_mode === 'sidebar' ? 'Sidebar mode forces a horizontal taskbar.' : undefined}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors disabled:opacity-40 disabled:cursor-not-allowed ${\n (prefs.taskbar_position || 'bottom') === pos ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{pos.charAt(0).toUpperCase() + pos.slice(1)}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n\n {/* ── Menu ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Menu</h3>\n <p className=\"text-xs text-gray-500 mb-3\">Controls font size, padding, taskbar height, and window button height across the Start Menu, context menus, dropdowns, and the notification popup.</p>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Size</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('start_menu_size', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.start_menu_size || 'medium') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Density</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'tight', label: 'Tight' },\n { key: 'normal', label: 'Normal' },\n { key: 'large', label: 'Large' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('menu_density', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.menu_density || 'normal') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n </>\n )}\n\n {/* ── Behavior ── */}\n {inSection('behavior') && !omitSet.has('behavior') && (\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Behavior</h3>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">New window position</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'center', label: 'Center' },\n { key: 'cascade', label: 'Cascade' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('window_position', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.window_position || 'cascade') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">Double-click desktop</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'deactivate', label: 'Deactivate all' },\n { key: 'nothing', label: 'Do nothing' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('desktop_dblclick', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.desktop_dblclick || 'deactivate') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">Default window size</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n { key: 'maximized', label: 'Maximized' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('default_window_size', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.default_window_size || 'large') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ── Desktop ── */}\n {inSection('behavior') && !omitSet.has('desktop') && (\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n {/* `?? false` — the watermark renders on an explicit `true` only, and\n a box ticked by default over a desktop with no version on it is\n the state BG#00623 arrived in. */}\n <input type=\"checkbox\" checked={prefs.show_desktop_version ?? false} onChange={e => savePref('show_desktop_version', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Show version on desktop</span>\n <span className=\"text-xs text-gray-400 ml-1 font-mono\">{getVersion()}</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input type=\"checkbox\" checked={prefs.auto_fullscreen ?? false} onChange={e => savePref('auto_fullscreen', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Enter full screen mode automatically</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input type=\"checkbox\" checked={prefs.restore_windows ?? true} onChange={e => savePref('restore_windows', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Reopen windows from the last session</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <SoundSettings />\n </div>\n )}\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n\nfunction SoundSettings() {\n const [enabled, setEnabled] = useState(soundsEnabled());\n const [config, setConfig] = useState(getSoundConfig());\n\n const update = (soundType: SoundType, packKey: string) => {\n setSoundForType(soundType, packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, soundType);\n };\n\n const applyAll = (packKey: string) => {\n setAllSounds(packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, 'success');\n };\n\n return (\n <div className=\"mt-2 space-y-2\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={enabled} onChange={e => { localStorage.setItem('erp_sounds', String(e.target.checked)); setEnabled(e.target.checked); }}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Sound effects</span>\n </label>\n {enabled && (\n <div className=\"ml-6\">\n <div className=\"border border-gray-200 rounded-lg overflow-hidden\">\n <table className=\"w-full text-[11px]\">\n <thead>\n <tr className=\"bg-gray-50\">\n <th className=\"px-2 py-1.5 text-left font-medium text-gray-500 w-24\"></th>\n {SOUND_PACK_KEYS.map(key => (\n <th key={key} className=\"px-1 py-1.5 text-center\">\n <button onClick={() => applyAll(key)} className=\"font-medium text-gray-500 hover:text-blue-600 transition-colors\">\n {SOUND_PACKS[key].label}\n </button>\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {SOUND_TYPES.map(soundType => (\n <tr key={soundType}>\n <td className=\"px-2 py-1.5 text-gray-700 font-medium\">{SOUND_TYPE_LABELS[soundType]}</td>\n {SOUND_PACK_KEYS.map(packKey => (\n <td key={packKey} className=\"px-1 py-1.5 text-center\">\n <button onClick={() => update(soundType, packKey)}\n className={`w-4 h-4 rounded-full border-2 transition-colors ${config[soundType] === packKey ? 'bg-blue-600 border-blue-600' : 'border-gray-300 hover:border-blue-400'}`} />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n","import { useShellPrefs } from '../shell/ShellPrefs';\nimport { ModalActions } from '../shell/Modal';\n\nconst WINDOW_POSITIONS = [\n { key: 'center', label: 'Center' },\n { key: 'cascade', label: 'Cascade' },\n];\n\nconst DESKTOP_DBLCLICK = [\n { key: 'deactivate', label: 'Deactivate all' },\n { key: 'nothing', label: 'Do nothing' },\n];\n\nconst WINDOW_SIZES = [\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n { key: 'maximized', label: 'Maximized' },\n];\n\n/**\n * Standalone Behavior settings panel — window position, double-click,\n * default window size, plus the two desktop-related toggles\n * (Show version on desktop, Enter full screen mode automatically).\n *\n * Reads/writes shell prefs via `useShellPrefs()`. Suitable for use as a\n * section in `SystemPreferences` or rendered standalone.\n */\nexport default function BehaviorPanel() {\n const { prefs, save } = useShellPrefs();\n const savePref = (key: string, value: any) => save({ [key]: value });\n\n const windowPosition: string = prefs.window_position || 'cascade';\n const desktopDblclick: string = prefs.desktop_dblclick || 'deactivate';\n const defaultWindowSize: string = prefs.default_window_size || 'large';\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Behavior</h3>\n <div className=\"space-y-3\">\n <Row\n label=\"New window position\"\n options={WINDOW_POSITIONS}\n value={windowPosition}\n onChange={v => savePref('window_position', v)}\n />\n <Row\n label=\"Double-click desktop\"\n options={DESKTOP_DBLCLICK}\n value={desktopDblclick}\n onChange={v => savePref('desktop_dblclick', v)}\n />\n <Row\n label=\"Default window size\"\n options={WINDOW_SIZES}\n value={defaultWindowSize}\n onChange={v => savePref('default_window_size', v)}\n />\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n // `?? false`, matching the render guard in `Desktop.tsx` and the\n // opt-in neighbour below. It read `?? true` while the watermark\n // drew only on an explicit `true`, so anyone who had never touched\n // this box saw it TICKED and had no version number on the desktop\n // — and, since the watermark is the only way in, no route to\n // What's New at all (BG#00623).\n checked={prefs.show_desktop_version ?? false}\n onChange={e => savePref('show_desktop_version', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Show version on desktop</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input\n type=\"checkbox\"\n checked={prefs.auto_fullscreen ?? false}\n onChange={e => savePref('auto_fullscreen', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Enter full screen mode automatically</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input\n type=\"checkbox\"\n checked={prefs.restore_windows ?? true}\n onChange={e => savePref('restore_windows', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Reopen windows from the last session</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n </div>\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n\nfunction Row({\n label,\n options,\n value,\n onChange,\n}: {\n label: string;\n options: { key: string; label: string }[];\n value: string;\n onChange: (v: string) => void;\n}) {\n return (\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">{label}</span>\n <div className=\"flex gap-2\">\n {options.map(o => (\n <button\n key={o.key}\n type=\"button\"\n onClick={() => onChange(o.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n value === o.key\n ? 'bg-blue-600 text-white border-blue-600'\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}\n >\n {o.label}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { ModalActions } from '../shell/Modal';\nimport {\n SOUND_PACKS,\n SOUND_PACK_KEYS,\n SOUND_TYPES,\n SOUND_TYPE_LABELS,\n getSoundConfig,\n setSoundForType,\n setAllSounds,\n soundsEnabled,\n previewSound,\n type SoundType,\n} from '../utils/sounds';\n\n/**\n * Standalone Sounds settings panel — sound effects toggle + per-event\n * sound-pack picker. Reads/writes the shell's `erp_sounds` and\n * `erp_sound_config` localStorage keys. Plays a preview when a pack is\n * picked. Suitable as a section in `SystemPreferences` or rendered\n * standalone.\n */\nexport default function SoundsPanel() {\n const [enabled, setEnabled] = useState(soundsEnabled());\n const [config, setConfig] = useState(getSoundConfig());\n\n const update = (soundType: SoundType, packKey: string) => {\n setSoundForType(soundType, packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, soundType);\n };\n\n const applyAll = (packKey: string) => {\n setAllSounds(packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, 'success');\n };\n\n return (\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-semibold text-gray-900\">Sounds</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={e => {\n localStorage.setItem('erp_sounds', String(e.target.checked));\n setEnabled(e.target.checked);\n }}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Sound effects</span>\n </label>\n\n {enabled && (\n <div className=\"border border-gray-200 rounded-lg overflow-hidden\">\n <table className=\"w-full text-[11px]\">\n <thead>\n <tr className=\"bg-gray-50\">\n <th className=\"px-2 py-1.5 text-left font-medium text-gray-500 w-24\"></th>\n {SOUND_PACK_KEYS.map(key => (\n <th key={key} className=\"px-1 py-1.5 text-center\">\n <button\n onClick={() => applyAll(key)}\n className=\"font-medium text-gray-500 hover:text-blue-600 transition-colors\"\n >\n {SOUND_PACKS[key].label}\n </button>\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {SOUND_TYPES.map(soundType => (\n <tr key={soundType}>\n <td className=\"px-2 py-1.5 text-gray-700 font-medium\">{SOUND_TYPE_LABELS[soundType]}</td>\n {SOUND_PACK_KEYS.map(packKey => (\n <td key={packKey} className=\"px-1 py-1.5 text-center\">\n <button\n onClick={() => update(soundType, packKey)}\n aria-label={`${SOUND_TYPE_LABELS[soundType]} — ${SOUND_PACKS[packKey].label}`}\n aria-pressed={config[soundType] === packKey}\n className={`w-4 h-4 rounded-full border-2 transition-colors ${\n config[soundType] === packKey\n ? 'bg-blue-600 border-blue-600'\n : 'border-gray-300 hover:border-blue-400'\n }`}\n />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport SidebarLayout from '../shell/SidebarLayout';\n\n/** One section in the SystemPreferences sidebar. */\nexport interface SystemPreferencesSection {\n /** Unique key, e.g. `'notifications'`, `'customization'`. */\n key: string;\n /** Sidebar label, e.g. \"Notifications\". */\n label: string;\n /** Short description shown under the label in the sidebar. */\n description?: string;\n /** Sidebar icon (any ReactNode — typically a 4×4 svg). */\n icon?: ReactNode;\n /** Body renderer. Receives no args; access shell prefs via your own hook. */\n render: () => ReactNode;\n}\n\nexport interface SystemPreferencesProps {\n /** Ordered sections — left sidebar lists these top-to-bottom, the matching\n * body renders on the right. The first section is selected by default\n * unless `defaultSelected` is supplied. */\n sections: readonly SystemPreferencesSection[];\n /** Key of the section to highlight on first render. Falls back to the first\n * section in `sections`. */\n defaultSelected?: string;\n /** Optional className applied to the outer flex container. */\n className?: string;\n}\n\n/**\n * Two-pane settings window: a fixed sidebar of sections on the left, the\n * active section's body on the right. Consumers compose by passing\n * `sections` — each entry has a `key`, `label`, optional `icon` and\n * `description`, and a `render()` callback that returns the body JSX.\n *\n * The shell exposes ready-made panels (`Customization`, `BehaviorPanel`,\n * `SoundsPanel`) that can be used as section bodies directly; portals\n * add their own sections (notification subscriptions, delivery defaults,\n * personal formatting prefs, etc.) alongside.\n *\n * Example:\n * ```tsx\n * <SystemPreferences sections={[\n * { key: 'notifications', label: 'Notifications', icon: <BellIcon />, render: () => <MyNotifications /> },\n * { key: 'customization', label: 'Customization', icon: <PaintBrushIcon />, render: () => <Customization omit={['behavior','desktop']} /> },\n * { key: 'behavior', label: 'Behavior', icon: <Cog6ToothIcon />, render: () => <BehaviorPanel /> },\n * { key: 'sounds', label: 'Sounds', icon: <SpeakerWaveIcon />, render: () => <SoundsPanel /> },\n * ]} />\n * ```\n */\nexport default function SystemPreferences({\n sections,\n defaultSelected,\n className,\n}: SystemPreferencesProps) {\n const initial = defaultSelected && sections.some(s => s.key === defaultSelected)\n ? defaultSelected\n : sections[0]?.key ?? '';\n const [selected, setSelected] = useState<string>(initial);\n const active = sections.find(s => s.key === selected) ?? sections[0];\n\n return (\n <SidebarLayout\n storageKey=\"shell.systemPreferences.sidebarWidth\"\n defaultWidth={240}\n minWidth={200}\n maxWidth={360}\n className={className}\n sidebarClassName=\"border-r border-gray-200 bg-gray-50\"\n sidebar={\n <nav className=\"px-1 py-1.5 space-y-0.5\">\n {sections.map(item => {\n const isActive = item.key === selected;\n return (\n <button\n key={item.key}\n type=\"button\"\n onClick={() => setSelected(item.key)}\n className={`w-full text-left rounded-lg px-3 py-2.5 text-sm transition-colors flex items-start gap-2.5 ${\n isActive ? 'bg-blue-50 text-blue-700' : 'hover:bg-gray-100 text-gray-700'\n }`}\n >\n {item.icon && (\n <span className={`mt-0.5 ${isActive ? 'text-blue-600' : 'text-gray-400'}`}>\n {item.icon}\n </span>\n )}\n <span className=\"min-w-0\">\n <span\n className={`block ${\n isActive ? 'font-semibold text-blue-700' : 'font-medium text-gray-800'\n }`}\n >\n {item.label}\n </span>\n {item.description && (\n <span className=\"block text-[11px] text-gray-500 mt-0.5\">\n {item.description}\n </span>\n )}\n </span>\n </button>\n );\n })}\n </nav>\n }\n >\n <main className=\"flex-1 min-w-0 overflow-auto p-4\">\n {active?.render()}\n </main>\n </SidebarLayout>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Keyboard + shift-click navigation for table rows.\n *\n * - J/K or Arrow keys to move focus\n * - Enter to open the focused row (calls `onSelect`)\n * - Space to toggle the focused row's checkbox (calls `onToggle`)\n * - Shift+J/K to extend selection while moving\n * - Shift+click to range-select (calls `onSelectRange`, which must ADD the range\n * rather than toggle it — the clicked checkbox is ticked on that assumption)\n * - Cmd/Ctrl+A to select/deselect all (calls `onSelectAll`)\n *\n * Each list instance gates its document-level listeners on `useModalActive`\n * so two open lists don't both react to the same shift-click.\n */\nexport default function useTableNav<T>(\n items: T[],\n onSelect: (item: T) => void,\n onToggle?: (item: T) => void,\n onSelectAll?: () => void,\n onSelectRange?: (from: number, to: number) => void,\n) {\n const [focusIdx, setFocusIdx] = useState(-1);\n const itemsRef = useRef(items);\n const onSelectRef = useRef(onSelect);\n const onToggleRef = useRef(onToggle);\n const onSelectAllRef = useRef(onSelectAll);\n const onSelectRangeRef = useRef(onSelectRange);\n const focusRef = useRef(focusIdx);\n const lastToggledRef = useRef(-1);\n const isActive = useModalActive();\n const isActiveRef = useRef(isActive);\n itemsRef.current = items;\n onSelectRef.current = onSelect;\n onToggleRef.current = onToggle;\n onSelectAllRef.current = onSelectAll;\n onSelectRangeRef.current = onSelectRange;\n focusRef.current = focusIdx;\n isActiveRef.current = isActive;\n\n const prevLen = useRef(items.length);\n useEffect(() => {\n if (items.length !== prevLen.current) {\n setFocusIdx(-1);\n lastToggledRef.current = -1;\n prevLen.current = items.length;\n }\n }, [items.length]);\n\n // Track normal checkbox clicks to set the anchor for Shift+click.\n // MUST be a capture-phase listener: the checkbox's own onClick calls\n // e.stopPropagation() (so toggling doesn't also open the row), and since\n // React delegates events at the root container — which sits *below*\n // document — that stopPropagation blocks any bubble-phase document listener.\n // Capture runs top-down before the event reaches the checkbox, so the anchor\n // is recorded even though bubbling is later stopped. Without this, the anchor\n // stayed -1 and \"click A, Shift+click B\" only toggled A and B individually\n // instead of selecting the range between them.\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (!isActiveRef.current) return;\n if (e.shiftKey) return;\n const target = e.target as HTMLElement;\n const row = target?.closest?.('[data-row-idx]');\n if (!row) return;\n if (target.tagName !== 'INPUT' || (target as HTMLInputElement).type !== 'checkbox') return;\n const idx = parseInt(row.getAttribute('data-row-idx')!, 10);\n if (!isNaN(idx)) {\n lastToggledRef.current = idx;\n setFocusIdx(idx);\n }\n };\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!isActiveRef.current) return;\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if ((e.target as HTMLElement)?.isContentEditable) return;\n\n if ((e.metaKey || e.ctrlKey) && e.key === 'a') {\n e.preventDefault();\n onSelectAllRef.current?.();\n return;\n }\n\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n\n const len = itemsRef.current.length;\n if (len === 0) return;\n\n const isDown = e.code === 'KeyJ' || e.key === 'j' || e.key === 'J' || e.key === 'ArrowDown';\n const isUp = e.code === 'KeyK' || e.key === 'k' || e.key === 'K' || e.key === 'ArrowUp';\n\n if (isDown || isUp) {\n e.preventDefault();\n const prev = focusRef.current;\n const next = isDown\n ? Math.min(prev + 1, len - 1)\n : Math.max(prev - 1, 0);\n if (next !== prev) {\n setFocusIdx(next);\n scrollRowIntoView(next);\n if (e.shiftKey && onToggleRef.current) {\n onToggleRef.current(itemsRef.current[next]);\n lastToggledRef.current = next;\n }\n }\n } else if (e.key === 'Enter' && focusRef.current >= 0 && focusRef.current < len) {\n e.preventDefault();\n onSelectRef.current(itemsRef.current[focusRef.current]);\n } else if (e.key === ' ' && focusRef.current >= 0 && focusRef.current < len) {\n e.preventDefault();\n if (e.shiftKey && lastToggledRef.current >= 0 && onSelectRangeRef.current) {\n const from = Math.min(lastToggledRef.current, focusRef.current);\n const to = Math.max(lastToggledRef.current, focusRef.current);\n onSelectRangeRef.current(from, to);\n } else {\n onToggleRef.current?.(itemsRef.current[focusRef.current]);\n }\n lastToggledRef.current = focusRef.current;\n }\n };\n\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, []);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (!isActiveRef.current) return;\n if (!e.shiftKey) return;\n const target = e.target as HTMLElement;\n const row = target?.closest?.('[data-row-idx]');\n if (!row) return;\n const clickedIdx = parseInt(row.getAttribute('data-row-idx')!, 10);\n if (isNaN(clickedIdx)) return;\n\n // Clicking the row's checkbox and clicking its body need different\n // handling below — the checkbox toggles itself, the body doesn't.\n const checkbox =\n target.tagName === 'INPUT' && (target as HTMLInputElement).type === 'checkbox'\n ? (target as HTMLInputElement)\n : null;\n\n const anchor = lastToggledRef.current;\n if (anchor < 0) {\n // Nothing to range from — this Shift+click is just a plain tick that\n // also becomes the anchor. On the checkbox its own onClick already\n // toggles the row; toggling here too cancels out and selects nothing.\n if (checkbox) {\n lastToggledRef.current = clickedIdx;\n setFocusIdx(clickedIdx);\n return;\n }\n onToggleRef.current?.(itemsRef.current[clickedIdx]);\n } else {\n const from = Math.min(anchor, clickedIdx);\n const to = Math.max(anchor, clickedIdx);\n if (onSelectRangeRef.current) {\n onSelectRangeRef.current(from, to);\n // A range select only ever ADDS, so the clicked checkbox must end up\n // ticked. Say so directly rather than leaving it to React: the\n // browser toggled it during the click's activation behaviour, and if\n // the row was already selected the `checked` prop doesn't change, so\n // React has no reason to write the DOM back.\n if (checkbox) checkbox.checked = true;\n } else if (onToggleRef.current) {\n for (let i = from; i <= to; i++) {\n onToggleRef.current(itemsRef.current[i]);\n }\n }\n }\n\n // Suppress the click — but NEVER on the checkbox itself. preventDefault()\n // on a checkbox runs the browser's \"canceled activation steps\", which\n // restore the pre-click checkedness at the END of dispatch — after the\n // microtask in which React commits the new selection. React's write is\n // overwritten and never repeated (the prop is unchanged on later\n // renders), so the Shift+clicked row alone rendered unticked while being\n // counted as selected. stopPropagation() is enough here: it keeps both\n // the checkbox's own toggle and the row-open handler from firing. On the\n // row body preventDefault() is still wanted, to stop a Shift+click on a\n // cell link opening a new window.\n if (!checkbox) e.preventDefault();\n e.stopPropagation();\n lastToggledRef.current = clickedIdx;\n setFocusIdx(clickedIdx);\n };\n\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n return focusIdx;\n}\n\nfunction scrollRowIntoView(idx: number) {\n requestAnimationFrame(() => {\n const row = document.querySelector(`[data-row-idx=\"${idx}\"]`);\n row?.scrollIntoView({ block: 'nearest' });\n });\n}\n","/**\n * The shared `GET /auth/default-columns/{tableId}/` probe.\n *\n * `useColumnConfig` and `useSort` both want the admin-saved defaults for a\n * table — the first for `visible_columns`, the second for `sort` — and both\n * used to fire their own raw axios GET on mount. A list page calls both, so\n * every list screen asked the same URL twice, and the consumer axios instances\n * carry no cache adapter and no in-flight dedupe, so both were real round\n * trips (SG#00590).\n *\n * Routing it through react-query under one key collapses that: the two hooks\n * on a screen share a single request, a second table with the same `tableId`\n * shares it too, and re-opening a window inside `staleTime` serves from cache.\n *\n * The query key is namespaced under `react-os-shell` so it cannot collide with\n * a consumer's own keys — including the persistence allow-lists some of them\n * key off `queryKey[0]`; these defaults are cheap to refetch and have no\n * business surviving in IndexedDB.\n *\n * The refetch options are set explicitly rather than inherited: consumers set\n * aggressive global `defaultOptions` (the admin portal polls every 60s and\n * refetches on window focus), and this endpoint changes only when an admin\n * edits a table's defaults. Inheriting would have turned a once-per-mount\n * fetch into a poll — worse than the bug being fixed.\n *\n * Using react-query here must NOT make a `<QueryClientProvider>` a condition\n * of calling `useSort`, which never needed one: `useQuery` resolves its client\n * before it reads `enabled`, so an `enabled` flag does not spare the\n * `tableId`-less caller. See `useResolvedQueryClient` below.\n */\nimport { useContext, useMemo } from 'react';\nimport { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport apiClient, { isShellApiClientConfigured } from '../api/client';\nimport type { SortState } from './types';\n\n/**\n * The client this probe runs on when the consumer has mounted none.\n *\n * `useSort` is a public hook that was pure React plus one raw axios GET, and\n * its `tableId`-less form reached no network at all. Routing the probe through\n * react-query would have made a provider mandatory for every caller of it,\n * including that one — a hard new requirement on a hook people already call,\n * failing at render with `No QueryClient set` rather than degrading.\n *\n * React forbids calling `useQuery` conditionally, so the client is what varies\n * instead: `useQuery(options, client)` takes an explicit one, and\n * `QueryClientContext` is part of react-query's public API, so the hook can\n * see for itself whether a provider is above it. With one, nothing changes and\n * the probe lives in the consumer's cache alongside everything else. Without\n * one, it lands in a client this module owns — created on first use, never\n * `mount()`ed (that only wires the focus/online refetching this query switches\n * off anyway), and shared by every hook in the process, so `useColumnConfig`\n * and `useSort` still collapse to a single request.\n *\n * A tree that mounts a provider around only part of itself gets two caches and\n * so two requests, which is what the raw GETs did everywhere. Consumers that\n * want the sharing mount the provider at the root, as all three portals do.\n */\nlet ownedClient: QueryClient | undefined;\n\nfunction useResolvedQueryClient(): QueryClient {\n const provided = useContext(QueryClientContext);\n if (provided) return provided;\n if (!ownedClient) ownedClient = new QueryClient();\n return ownedClient;\n}\n\n/**\n * Drop the owned client. Internal — not re-exported from `src/index.ts`, so it\n * is not part of the package's API: it appears in neither `dist/index.js` nor\n * `dist/index.d.ts` (only, as every line of source does, inside the sourcemap).\n *\n * It exists for the specs. A react-query entry left in cache holds a\n * five-minute garbage-collection timer, and node's test runner will not exit\n * while one is pending — a spec that renders without a provider would sit there\n * for five minutes after its last assertion. A spec that mounts its own\n * `<QueryClientProvider>` calls `client.clear()` for the same reason; this is\n * the same call for the client no spec has a handle on.\n */\nexport function __resetOwnedQueryClient(): void {\n ownedClient?.clear();\n ownedClient = undefined;\n}\n\nexport type ColumnViewport = 'desktop' | 'mobile';\n\n/** Shape of `GET /auth/default-columns/{tableId}/`. Every field is optional:\n * the endpoint answers a miss with `{visible_columns: [], sort: null}`, and\n * the shell's unwired `apiClient` proxy resolves `data: null`. */\nexport interface DefaultColumnConfig {\n visible_columns?: string[] | null;\n sort?: SortState | null;\n}\n\n/** Same media query `useIsMobile` uses, so the column/sort defaults split on\n * the same breakpoint as the rest of the UI's mobile affordances. Read once\n * per mount (see `useDefaultColumnConfig`) — a user who resizes past the\n * breakpoint mid-session picks the other row up on the next window. */\nexport function readColumnViewport(): ColumnViewport {\n return typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile'\n : 'desktop';\n}\n\nexport function defaultColumnConfigQueryKey(tableId: string, viewport: ColumnViewport) {\n return ['react-os-shell', 'default-columns', tableId, viewport] as const;\n}\n\n/**\n * Admin-saved defaults for `tableId`, or `undefined` while unknown.\n *\n * `undefined` covers all three of \"still in flight\", \"the request failed\" and\n * \"no api client is wired\" — every caller treats those the same way, by\n * leaving whatever it already had alone.\n */\nexport function useDefaultColumnConfig(tableId?: string): {\n defaultConfig: DefaultColumnConfig | undefined;\n viewport: ColumnViewport;\n} {\n // Once at mount, matching the pre-react-query behaviour: the viewport was\n // read inside a `[tableId]` effect, so it never changed under a live table.\n const viewport = useMemo(readColumnViewport, []);\n const queryClient = useResolvedQueryClient();\n\n const { data } = useQuery<DefaultColumnConfig | null>({\n queryKey: defaultColumnConfigQueryKey(tableId ?? '', viewport),\n queryFn: () =>\n apiClient\n .get(`/auth/default-columns/${tableId}/`, { params: { viewport } })\n .then((r) => (r?.data ?? null) as DefaultColumnConfig | null),\n // The raw callers gated on this so a consumer without a backend (the Pages\n // demo) fires no doomed HTTP. `useColumnConfig` never did; it does now.\n enabled: !!tableId && isShellApiClientConfigured(),\n // The raw callers made exactly one attempt and swallowed the failure.\n retry: false,\n staleTime: 5 * 60_000,\n refetchInterval: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n }, queryClient);\n\n return { defaultConfig: data ?? undefined, viewport };\n}\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { useDefaultColumnConfig } from './useDefaultColumnConfig';\nimport type { ColumnDef } from './types';\n\ninterface ColumnState {\n key: string;\n width: number;\n hidden?: boolean;\n}\n\n/** Whether two column states are the same arrangement. Used to turn a\n * re-delivery of unchanged prefs into a no-op rather than a re-render: the\n * prefs adapter hands the same value back after a refetch, and the effects\n * below run on every change of it. */\nfunction sameColumns(a: ColumnState[], b: ColumnState[]): boolean {\n return a.length === b.length &&\n a.every((c, i) => c.key === b[i].key && c.width === b[i].width && !!c.hidden === !!b[i].hidden);\n}\n\n/** Ensure _select column (if present) is always at index 0 and never hidden */\nfunction pinSelectColumn(cols: ColumnState[]): ColumnState[] {\n const selectIdx = cols.findIndex(c => c.key === '_select');\n if (selectIdx >= 0) {\n const [sel] = cols.splice(selectIdx, 1);\n sel.hidden = false;\n cols.unshift(sel);\n }\n return cols;\n}\n\n/**\n * Fold a changed `defaultColumns` back into live column state.\n *\n * `columns` is seeded once, at mount. A consumer whose column list changes\n * WHILE mounted — a comparison period switched on, a mode that reveals extra\n * measures, a permission resolving late — got nothing: the new columns never\n * reached the state, so they never rendered, and the only way to see them was\n * to close the window and open it again. Withdrawn columns had the mirror\n * problem, lingering in state until `orderedColumns` spread an `undefined`\n * definition over them.\n *\n * The user's own decisions win wherever they exist: an existing column keeps\n * its width, its hidden flag and its place in the order. A new one lands\n * beside the column it was DECLARED next to rather than at the far right,\n * because a column that only makes sense next to another — a prior-period\n * figure beside the current one — is useless eleven columns away from it.\n *\n * Returns `prev` unchanged when nothing differs, so a consumer that rebuilds\n * its `ColumnDef[]` array every render causes no re-render.\n */\nfunction reconcileColumns(\n prev: ColumnState[],\n defaultColumns: ColumnDef[],\n withdrawn: Map<string, ColumnState>,\n): ColumnState[] {\n const declared = new Set(defaultColumns.map(d => d.key));\n const known = new Set(prev.map(c => c.key));\n const added = defaultColumns.filter(d => !known.has(d.key));\n // `_select` is the grid's own column and is never in the consumer's list.\n const kept = prev.filter(c => c.key === '_select' || declared.has(c.key));\n if (!added.length && kept.length === prev.length) return prev;\n\n // Remember what the user had done to a column the consumer has withdrawn,\n // so a set that comes back — a comparison toggled off and on again —\n // returns as they left it instead of resetting to the declaration.\n for (const col of prev) {\n if (col.key !== '_select' && !declared.has(col.key)) withdrawn.set(col.key, col);\n }\n\n const out = [...kept];\n for (const def of added) {\n const at = defaultColumns.indexOf(def);\n // Walk back through the declaration for the nearest column already\n // placed, and land just after it. Consecutive new columns chain, so a\n // declared pair stays a pair.\n let anchor = -1;\n for (let i = at - 1; i >= 0; i -= 1) {\n const idx = out.findIndex(c => c.key === defaultColumns[i].key);\n if (idx >= 0) { anchor = idx; break; }\n }\n out.splice(anchor + 1, 0, withdrawn.get(def.key)\n ?? { key: def.key, width: def.defaultWidth || 150, hidden: def.defaultHidden });\n withdrawn.delete(def.key);\n }\n return pinSelectColumn(out);\n}\n\n/**\n * Resizable + reorderable + hideable column state for `<ResizableTable>`.\n *\n * Reads and persists per-user through the `<ShellPrefsProvider>` adapter\n * (`prefs.columns_{tableId}`), with a 1-second debounce on the save, and reads\n * per-viewport admin defaults through the shared\n * `GET /auth/default-columns/{tableId}?viewport=…` probe.\n *\n * The prefs half used to be a raw `GET /auth/me/` fired from a `[tableId]`\n * effect, outside react-query — so every list mount re-fetched the whole user\n * profile (~1.5 MB on prod), on a client with no cache adapter and no in-flight\n * dedupe, and a screen that also renders a column-aware CSV export paid for it\n * twice. The adapter already holds that profile in one cached query, which is\n * the same object the raw GET was reading `preferences` off (SG#00590).\n *\n * Three consequences worth knowing, because this is NOT behaviour-preserving:\n *\n * - **A `<ShellPrefsProvider>` is now required for server-side persistence.**\n * Without one, `useShellPrefs()` reads empty and drops saves, so column\n * config degrades to localStorage-only. All three consumers that render\n * `<EntityList>`/`<ResizableTable>` mount the provider.\n * - **Prefs and admin defaults resolve independently**, where the raw pair was\n * a single `Promise.all`. If the admin default lands while prefs are still\n * loading it applies first and the user's own config replaces it a beat\n * later, rather than never showing. `useSort` has always behaved this way;\n * the two hooks now agree. The precedence that used to be one `if/else if`\n * is now the `userSavedRef` guard below plus the order the two effects fire\n * in — `tests/columnConfigDefaultsPrecedence.test.tsx` pins both directions.\n * - **A failed save is silent here.** The old `useMutation` let a rejected\n * `PATCH` reach a consumer's global `MutationCache({ onError })` — the admin\n * portal toasted it. The adapter's `save` owns its own failures now, so a\n * consumer that wants that toast raises it inside the adapter.\n *\n * What it does NOT require is a `<QueryClientProvider>` — it used to, for the\n * `useMutation`. `useDefaultColumnConfig` falls back to a client the package\n * owns when no provider is mounted.\n */\nexport function useColumnConfig(tableId: string, defaultColumns: ColumnDef[]) {\n const { prefs, save } = useShellPrefs();\n const prefKey = `columns_${tableId}`;\n const userSaved = prefs[prefKey];\n const { defaultConfig } = useDefaultColumnConfig(tableId);\n\n const [columns, setColumns] = useState<ColumnState[]>(() => {\n const cached = localStorage.getItem(`col-config-${tableId}`);\n if (cached) {\n try {\n const parsed = JSON.parse(cached) as ColumnState[];\n const existing = new Set(parsed.map(c => c.key));\n const merged = pinSelectColumn([\n ...parsed.filter(c => defaultColumns.some(d => d.key === c.key)),\n // `hidden: d.defaultHidden` matches the server-prefs merge below.\n // A column added to the consumer's ColumnDef list since this cache\n // was written has no entry in it, so its `defaultHidden` is the\n // only opinion there is.\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n return merged;\n } catch { /* fall through */ }\n }\n return pinSelectColumn(defaultColumns.map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })));\n });\n\n const [draggedIdx, setDraggedIdx] = useState<number | null>(null);\n const [dropGap, setDropGap] = useState<number | null>(null);\n const resizingRef = useRef<{ idx: number; startX: number; startWidth: number } | null>(null);\n\n // A change made in THIS mount always wins over an async restore below —\n // needed now that the restore effects are keyed on values that can arrive\n // (or be re-delivered by a refetch) long after mount. Same guard `useSort`\n // has always carried.\n const touchedRef = useRef(false);\n const userSavedRef = useRef(userSaved);\n userSavedRef.current = userSaved;\n\n const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const saveRef = useRef(save);\n saveRef.current = save;\n\n const persistColumns = useCallback((cols: ColumnState[]) => {\n touchedRef.current = true;\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(cols));\n if (saveTimer.current) clearTimeout(saveTimer.current);\n // Through the adapter, not a raw `PATCH /auth/me/`: the adapter patches the\n // cached profile optimistically and invalidates it, so the value the\n // restore effect below reads back is the one we just saved. A raw PATCH\n // left that cache stale, and the next window opened would have restored the\n // pre-change columns over the fresh ones.\n saveTimer.current = setTimeout(() => { void saveRef.current({ [prefKey]: cols }); }, 1000);\n }, [tableId, prefKey]);\n\n // The debounce deliberately outlives unmount, as it always has: resizing a\n // column and closing the window inside the second must still reach the\n // server. `saveRef` keeps the adapter callback reachable for that; the\n // adapter's own work (cache write + PATCH) is not tied to this component.\n\n // The user's own saved config. It arrives from the prefs adapter, which is\n // backed by the consumer's single cached `/auth/me/` query — no request of\n // our own. Adapters resolve async, so a window opened before prefs land\n // starts on the localStorage/`ColumnDef` state and picks this up after.\n useEffect(() => {\n if (touchedRef.current || !Array.isArray(userSaved)) return;\n const existing = new Set(userSaved.map((c: any) => c.key));\n const merged = pinSelectColumn([\n // Copied, not referenced: `pinSelectColumn` writes `hidden` on the entry\n // it pins, and these objects belong to the consumer's cached profile now.\n ...userSaved.filter((c: any) => defaultColumns.some(d => d.key === c.key)).map((c: any) => ({ ...c })),\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n setColumns(prev => (sameColumns(prev, merged) ? prev : merged));\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(merged));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, userSaved]);\n\n // The admin-saved default — only consulted while the user has no config of\n // their own, exactly as the `else if` it replaces did. Read through the ref\n // so this reflects whatever prefs have resolved by the time the probe lands;\n // if they resolve later still, the effect above overrides.\n useEffect(() => {\n if (touchedRef.current || Array.isArray(userSavedRef.current)) return;\n const visible = defaultConfig?.visible_columns;\n // Non-empty system defaults — apply them. (An empty array is treated\n // as \"no admin opinion\" and we leave the initial useState value alone,\n // which uses the per-column `defaultHidden` flag from each ColumnDef.)\n if (!Array.isArray(visible) || visible.length === 0) return;\n const visibleSet = new Set(visible);\n const systemCols = pinSelectColumn(defaultColumns.map(d => ({\n key: d.key,\n width: d.defaultWidth || 150,\n hidden: !visibleSet.has(d.key),\n })));\n setColumns(prev => (sameColumns(prev, systemCols) ? prev : systemCols));\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(systemCols));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, defaultConfig]);\n\n // Follow the consumer's column list for as long as this stays mounted.\n // Deliberately NOT persisted: a column set that comes and goes with a UI\n // toggle would otherwise PATCH the user's profile on every flip. The\n // existing persist paths — resize, drag, hide, reset — still capture it the\n // moment the user actually decides something.\n const withdrawnRef = useRef(new Map<string, ColumnState>());\n useEffect(() => {\n setColumns(prev => reconcileColumns(prev, defaultColumns, withdrawnRef.current));\n }, [defaultColumns]);\n\n const visibleColumns = columns.filter(c => !c.hidden);\n\n const onResizeStart = useCallback((idx: number, e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const visCol = visibleColumns[idx];\n const realIdx = columns.findIndex(c => c.key === visCol.key);\n resizingRef.current = { idx: realIdx, startX: e.clientX, startWidth: columns[realIdx].width };\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!resizingRef.current) return;\n const { idx: i, startX, startWidth } = resizingRef.current;\n const minW = defaultColumns.find(d => d.key === columns[i].key)?.minWidth || 30;\n const newWidth = Math.max(minW, startWidth + ev.clientX - startX);\n setColumns(prev => {\n const updated = [...prev];\n updated[i] = { ...updated[i], width: newWidth };\n return updated;\n });\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n resizingRef.current = null;\n setColumns(prev => { persistColumns(prev); return prev; });\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n }, [columns, visibleColumns, defaultColumns, persistColumns]);\n\n const onDragStart = useCallback((idx: number) => {\n setDraggedIdx(idx);\n }, []);\n\n const onDragOver = useCallback((visIdx: number, e: React.DragEvent) => {\n e.preventDefault();\n if (draggedIdx === null) return;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n let gap = e.clientX < rect.left + rect.width / 2 ? visIdx : visIdx + 1;\n const vis = columns.filter(c => !c.hidden);\n if (vis[0]?.key === '_select' && gap === 0) gap = 1;\n setDropGap(gap);\n }, [draggedIdx, columns]);\n\n const onDrop = useCallback((_visIdx: number, e: React.DragEvent) => {\n e.preventDefault();\n if (draggedIdx === null || dropGap === null) {\n setDraggedIdx(null);\n setDropGap(null);\n return;\n }\n if (dropGap === draggedIdx || dropGap === draggedIdx + 1) {\n setDraggedIdx(null);\n setDropGap(null);\n return;\n }\n setColumns(prev => {\n const visible = prev.filter(c => !c.hidden);\n const moved = visible[draggedIdx];\n if (!moved) return prev;\n const fromReal = prev.findIndex(c => c.key === moved.key);\n let toReal: number;\n if (dropGap < visible.length) {\n toReal = prev.findIndex(c => c.key === visible[dropGap].key);\n } else {\n toReal = prev.findIndex(c => c.key === visible[visible.length - 1].key) + 1;\n }\n const updated = [...prev];\n const [item] = updated.splice(fromReal, 1);\n updated.splice(toReal > fromReal ? toReal - 1 : toReal, 0, item);\n persistColumns(updated);\n return updated;\n });\n setDraggedIdx(null);\n setDropGap(null);\n }, [draggedIdx, dropGap, persistColumns]);\n\n const onDragEnd = useCallback(() => {\n setDraggedIdx(null);\n setDropGap(null);\n }, []);\n\n const toggleColumn = useCallback((key: string) => {\n setColumns(prev => {\n const updated = prev.map(c => c.key === key ? { ...c, hidden: !c.hidden } : c);\n if (updated.filter(c => !c.hidden).length === 0) return prev;\n persistColumns(updated);\n return updated;\n });\n }, [persistColumns]);\n\n const resetColumns = useCallback(() => {\n // Carry `defaultHidden` through, exactly as the initial state and the\n // server-prefs merge above do. Dropping it made Reset un-hide every\n // column the consumer had hidden by default — and reset persists, to\n // localStorage and then to the user's profile, so nothing healed it on a\n // later load (BG#00576).\n const defaults = pinSelectColumn(defaultColumns.map(d => ({\n key: d.key,\n width: d.defaultWidth || 150,\n hidden: d.defaultHidden,\n })));\n setColumns(defaults);\n persistColumns(defaults);\n }, [defaultColumns, persistColumns]);\n\n const orderedColumns = visibleColumns.map(c => {\n const def = defaultColumns.find(d => d.key === c.key);\n return { ...def!, width: c.width };\n }).filter(Boolean);\n\n const allColumns = columns.map(c => {\n const def = defaultColumns.find(d => d.key === c.key);\n return { key: c.key, label: def?.label || c.key, hidden: !!c.hidden };\n });\n\n return {\n orderedColumns,\n allColumns,\n onResizeStart,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n toggleColumn,\n resetColumns,\n draggedIdx,\n dropGap,\n };\n}\n","import { useState, useRef, useCallback, useMemo } from 'react';\nimport { useColumnConfig } from './useColumnConfig';\nimport { useIsMobile } from '../shell/useIsMobile';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport apiClient from '../api/client';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { useShellAuth } from '../shell/ShellAuth';\nimport type { ColumnDef, SortState } from './types';\n\ninterface ResizableTableProps {\n tableId: string;\n columns: ColumnDef[];\n sort?: SortState;\n onSort?: (field: string) => void;\n footer?: React.ReactNode;\n afterBody?: React.ReactNode;\n /** Permission codename(s) that gate the \"Save as default for all users\" link\n * in the column picker. The shell's `useShellAuth().hasAnyPerm` is queried\n * against this list. Defaults to a single placeholder permission; consumers\n * with no admin gate can pass `[]` to hide the link entirely. */\n saveDefaultPerms?: string[];\n children: (orderedColumns: (ColumnDef & { width: number })[]) => React.ReactNode;\n}\n\n/**\n * Sticky-header, scrollable-body table primitive with:\n * - drag-to-reorder columns (with a blue drop-indicator line)\n * - resize columns by the right-edge handle\n * - hide/show columns via a glass popover picker\n * - admin-only \"Save as default for all users\" link in the picker\n * - per-user persistence (via the shell-registered apiClient)\n * - mobile-aware selection mode toggle\n */\nexport default function ResizableTable({\n tableId,\n columns,\n sort,\n onSort,\n footer,\n afterBody,\n saveDefaultPerms = ['change_numberingconfig'],\n children,\n}: ResizableTableProps) {\n const isMobile = useIsMobile();\n const [selectionMode, setSelectionMode] = useState(false);\n // Strip the `_select` column on mobile (unless selection mode is on) so it\n // doesn't take up scarce screen real estate.\n const effectiveColumns = useMemo(\n () => (isMobile && !selectionMode ? columns.filter(c => c.key !== '_select') : columns),\n [columns, isMobile, selectionMode],\n );\n const {\n orderedColumns,\n allColumns,\n onResizeStart,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n toggleColumn,\n resetColumns,\n draggedIdx,\n dropGap,\n } = useColumnConfig(tableId, effectiveColumns);\n const { hasAnyPerm } = useShellAuth();\n const [pickerOpen, setPickerOpen] = useState(false);\n const [savingDefault, setSavingDefault] = useState(false);\n const [savedDefault, setSavedDefault] = useState(false);\n const pickerRef = useRef<HTMLDivElement>(null);\n const isAdmin = saveDefaultPerms.length > 0 && hasAnyPerm(saveDefaultPerms);\n\n useClickOutside(pickerRef, useCallback(() => { if (pickerOpen) setPickerOpen(false); }, [pickerOpen]));\n\n /**\n * Column widths in PIXELS, with the table floored at the container width.\n *\n * These were percentages of the running total, on a `w-full` table — which\n * made every width a RATIO, never a size. The table then always measured\n * exactly its container, so:\n *\n * - a wide list crushed every column to fit. Thirteen columns in a 1118px\n * window came out at 91px each, and every currency figure was truncated\n * to `A$514…`. Adding a column made every other column narrower;\n * - the body's `overflow-x-auto` was dead code, because a table that can\n * never exceed its container never overflows;\n * - dragging a resize handle could only STEAL width from other columns.\n * Widening one narrowed its neighbours and the total never moved.\n *\n * Pixels plus `min-width: 100%` keep both behaviours honest. Under-full, the\n * table still stretches to the container and `table-layout: fixed`\n * distributes the slack proportionally, exactly as the percentages did.\n * Over-full, the table is finally wider than its container and scrolls\n * sideways instead of compressing.\n */\n const totalWidth = orderedColumns.reduce((sum, col) => sum + col.width, 0);\n const colWidths = orderedColumns.map(col => `${col.width}px`);\n const tableStyle = { tableLayout: 'fixed' as const, width: totalWidth, minWidth: '100%' };\n\n // The header is its own table, outside the body's scroller, so it has to be\n // driven: without this it stays put while the body scrolls under it and the\n // labels stop naming the columns beneath them.\n const headScrollRef = useRef<HTMLDivElement>(null);\n const onBodyScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n const head = headScrollRef.current;\n if (head) head.scrollLeft = e.currentTarget.scrollLeft;\n }, []);\n\n const saveAsDefault = async () => {\n setSavingDefault(true);\n const visibleKeys = allColumns.filter(c => !c.hidden).map(c => c.key);\n const viewport = isMobile ? 'mobile' : 'desktop';\n // Capture the sort the admin is looking at too, so \"default for all\n // users\" covers ordering as well as columns. Lists that don't wire a\n // `sort` prop omit the key and leave any previously-saved sort alone.\n const payload: Record<string, unknown> = { visible_columns: visibleKeys };\n if (sort) payload.sort = sort;\n try {\n await apiClient\n .patch(`/auth/default-columns/${tableId}/`, payload, { params: { viewport } })\n .catch(() =>\n apiClient.post('/auth/default-columns/', { table_id: tableId, viewport, ...payload }),\n );\n setSavedDefault(true);\n setTimeout(() => setSavedDefault(false), 2000);\n } catch { /* ignore */ }\n setSavingDefault(false);\n };\n\n const supportsSelection = useMemo(() => columns.some(c => c.key === '_select'), [columns]);\n\n return (\n <div className={`flex flex-col flex-1 min-h-0 ${isMobile ? '-mx-4' : ''}`}>\n {/* Fixed header — scrolled sideways by the body, never by the user, so\n `overflow-x-hidden` rather than `auto`: two horizontal scrollbars on\n one table is worse than none. */}\n <div ref={headScrollRef} className=\"shrink-0 overflow-x-hidden\">\n <table className=\"divide-y divide-gray-200\" style={tableStyle}>\n <colgroup>\n {orderedColumns.map((col, i) => (\n <col key={col.key} style={{ width: colWidths[i] }} />\n ))}\n </colgroup>\n <thead className=\"bg-gray-50\">\n <tr>\n {orderedColumns.map((col, idx) => {\n const colDef = columns.find(c => c.key === col.key);\n const sortField = colDef?.sortField ?? (col.key !== '_select' ? col.key : undefined);\n const isSorted = sort && sortField && sort.field === sortField;\n const isFixed = col.key === '_select';\n return (\n <th\n key={col.key}\n className={`px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase select-none relative ${draggedIdx === idx ? 'bg-blue-50' : ''}`}\n draggable={!isFixed}\n onDragStart={isFixed ? undefined : () => onDragStart(idx)}\n onDragOver={isFixed ? undefined : (e) => onDragOver(idx, e)}\n onDrop={isFixed ? undefined : (e) => onDrop(idx, e)}\n onDragEnd={isFixed ? undefined : onDragEnd}\n style={isFixed ? undefined : { cursor: 'grab' }}\n >\n <span\n className={`${isFixed ? '' : 'truncate pr-3'} block ${sortField && onSort ? 'cursor-pointer hover:text-gray-700' : ''}`}\n onClick={sortField && onSort ? (e) => { e.stopPropagation(); onSort(sortField); } : undefined}\n >\n {col.headerNode ?? col.label}\n {isSorted && <span className=\"ml-1\">{sort!.direction === 'asc' ? '▲' : '▼'}</span>}\n </span>\n {!isFixed && (\n <div\n className=\"absolute right-0 top-0 bottom-0 w-4 cursor-col-resize flex items-center justify-center z-10\"\n onMouseDown={(e) => onResizeStart(idx, e)}\n style={{ marginRight: -8 }}\n >\n <div className=\"w-0.5 h-full bg-gray-200 hover:bg-blue-500 transition-colors\" />\n </div>\n )}\n {dropGap === idx && (\n <div className=\"absolute left-0 top-0 bottom-0 w-0.5 bg-blue-500 z-20 pointer-events-none\" />\n )}\n {idx === orderedColumns.length - 1 && dropGap === orderedColumns.length && (\n <div className=\"absolute right-0 top-0 bottom-0 w-0.5 bg-blue-500 z-20 pointer-events-none\" />\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n </table>\n </div>\n\n {/* Scrollable body */}\n <div className=\"flex-1 overflow-y-auto overflow-x-auto min-h-0\" onScroll={onBodyScroll}>\n <table className=\"divide-y divide-gray-200\" style={tableStyle}>\n <colgroup>\n {orderedColumns.map((col, i) => (\n <col key={col.key} style={{ width: colWidths[i] }} />\n ))}\n </colgroup>\n {children(orderedColumns as any)}\n </table>\n {afterBody}\n </div>\n\n {/* Footer */}\n {footer !== undefined && (\n <div className=\"border-t border-gray-200 px-4 py-2 text-sm text-gray-500 shrink-0 flex items-center justify-between\">\n <span>{footer}</span>\n <div className=\"flex items-center gap-3 relative\" ref={pickerRef}>\n {isMobile && supportsSelection && (\n <button\n onClick={() => setSelectionMode(s => !s)}\n className={`text-[11px] px-2 py-0.5 rounded ${selectionMode ? 'bg-blue-600 text-white' : 'text-gray-500 hover:text-gray-700 border border-gray-300'}`}\n title={selectionMode ? 'Hide selection column' : 'Show selection column'}\n >\n {selectionMode ? 'Done' : 'Select'}\n </button>\n )}\n <button onClick={resetColumns} className=\"text-[10px] text-gray-400 hover:text-gray-600\">Reset</button>\n <button onClick={() => setPickerOpen(!pickerOpen)} className=\"text-gray-400 hover:text-gray-600\" title=\"Choose columns\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75\" />\n </svg>\n </button>\n {pickerOpen && (\n <div className=\"absolute bottom-full right-0 mb-1 w-52 rounded-2xl z-50 py-1 max-h-80 overflow-y-auto\" style={getGlassStyle()}>\n <p className=\"px-3 py-1.5 text-[10px] font-semibold text-gray-400 uppercase\">Columns</p>\n {allColumns.filter(col => col.key !== '_select').map(col => (\n <label key={col.key} className=\"flex items-center gap-2 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={!col.hidden}\n onChange={() => toggleColumn(col.key)}\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\n />\n {col.label}\n </label>\n ))}\n {isAdmin && (\n <div className=\"border-t border-gray-100 mt-1 pt-1 px-3 pb-1\">\n <button onClick={saveAsDefault} disabled={savingDefault}\n className={`text-[10px] w-full text-center py-1 rounded ${savedDefault ? 'text-green-600' : 'text-gray-500 hover:text-blue-600'}`}>\n {savingDefault ? '...' : savedDefault ? 'Saved as default' : 'Save as default for all users'}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode, RefObject, Dispatch, SetStateAction, MouseEvent } from 'react';\nimport { useRef, useState } from 'react';\nimport useTableNav from './useTableNav';\nimport ResizableTable from './ResizableTable';\nimport LoadingSpinner from '../shell/LoadingSpinner';\nimport ListFooter from './ListFooter';\nimport ListLoadError from './ListLoadError';\nimport Checkbox from '../forms/Checkbox';\nimport { useShellStrings } from '../shell/strings';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\nimport { keepsNativeMenu } from '../shell/contextMenuTarget';\nimport { copyToClipboard, selectionAt, type SelectedText } from '../shell/clipboard';\nimport { escapeHtml } from '../utils/escapeHtml';\nimport apiClient from '../api/client';\nimport toast from '../shell/toast';\n\nexport interface EntityListColumn {\n key: string;\n label: string;\n defaultWidth?: number;\n minWidth?: number;\n defaultHidden?: boolean;\n sortField?: string;\n headerNode?: ReactNode;\n}\n\n/** A page-supplied entry in the right-click bulk menu (e.g. invoice Post /\n * Cancel). `onClick` receives the currently-selected rows. Set `divider` to\n * render a separator above the item, `danger` for a destructive tint. */\nexport interface EntityListContextAction<T = unknown> {\n label: string;\n onClick: (items: T[]) => void;\n danger?: boolean;\n disabled?: boolean;\n divider?: boolean;\n}\n\nexport interface EntityListProps<T> {\n items: T[];\n isLoading: boolean;\n emptyState: ReactNode;\n totalCount?: number;\n\n /** When true and no rows have loaded yet, render {@link ListLoadError}\n * (with a retry) instead of `emptyState` — so a failed fetch reads as an\n * error, not \"nothing here\". Wire `useInfiniteScroll`'s `isError`. A\n * mid-scroll next-page failure (rows already loaded) keeps the list.\n * Defaults to unset → behaviour unchanged for existing callers. */\n isError?: boolean;\n /** Retry handler for the error state — wire the data source's `refetch`.\n * It also backs the row menu's Refresh item. */\n onRetry?: () => void;\n /** Heading for the error state, e.g. \"Couldn't load candidates\". Omit for\n * {@link ListLoadError}'s generic \"Couldn't load this list\" — name the\n * entity where the list has one, so an outage reads as *this* list failing. */\n errorTitle?: string;\n /** Explanatory line under {@link EntityListProps.errorTitle}. Omit for\n * ListLoadError's generic connection/retry message. */\n errorMessage?: string;\n\n tableId: string;\n columns: EntityListColumn[];\n renderCell: (item: T, colKey: string) => ReactNode;\n getRowId?: (item: T) => string | number;\n\n sort?: { field: string; direction: 'asc' | 'desc' };\n onSort?: (field: string) => void;\n\n selected: Set<string | number>;\n setSelected: Dispatch<SetStateAction<Set<string | number>>>;\n\n onRowClick: (item: T) => void;\n onRowHover?: (item: T) => void;\n getRowClassName?: (item: T) => string;\n\n footerLabel: string;\n footerExtra?: ReactNode;\n\n // Loose ref type so consumers on React 18 (RefObject<HTMLDivElement>) and\n // React 19 (RefObject<HTMLDivElement | null>) both type-check cleanly.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sentinelRef?: RefObject<any>;\n isFetchingNextPage?: boolean;\n\n /** Perm codenames that gate \"Save as default for all users\" in the column\n * picker. Defaults to `['change_numberingconfig']` (admin-portal's proxy\n * for admin access). Pass `[]` to hide the link entirely. */\n saveDefaultPerms?: string[];\n\n /** Right-click row menu. Every list has one, with nothing to wire: Open (the\n * row right-clicked), Copy for text selected under the pointer, Copy\n * `<first column>` and Copy rows (the ticked rows as a table of the visible\n * columns in their on-screen order, which pastes into a spreadsheet as\n * cells), Select all, Clear selection, and Refresh when `onRetry` is wired.\n * Provide `exportEndpoint` (a list's `<base>/export_csv/` path, relative to\n * the api base) to add \"Export selected to CSV\", which downloads just the\n * ticked rows (`?ids=`, honouring the visible/ordered columns). Provide\n * `contextActions` for domain actions (e.g. invoice Post / Cancel); they sit\n * between the copy items and the selection items. */\n exportEndpoint?: string;\n exportFilename?: string;\n contextActions?: (items: T[]) => EntityListContextAction<T>[];\n}\n\n/** An open row menu: where, over which row, and what it can copy. */\ninterface RowMenu<T> {\n x: number;\n y: number;\n /** The row right-clicked — what Open opens. */\n item: T;\n /** Text selected under the pointer, when there is some. */\n text: SelectedText | null;\n /** The first visible column, read off the row when the menu opens so it\n * follows the user's column order. Null when it has no label to name it by. */\n firstColumn: { key: string; label: string } | null;\n}\n\n/** A row's data cells in on-screen order — the tick-box column left out, and\n * only the row's own cells, never those of a table nested inside one. */\nfunction rowCells(row: Element): HTMLElement[] {\n return (Array.from(row.children) as HTMLElement[])\n .filter(td => td.dataset?.colKey !== undefined && td.dataset.colKey !== '_select');\n}\n\n/** A cell as the user reads it: the rendered text with whitespace collapsed,\n * so a badge or a two-line cell stays one spreadsheet cell. `innerText`\n * follows CSS, so a hidden element is not copied; jsdom has no `innerText`,\n * hence the fallback. */\nfunction cellText(td: HTMLElement): string {\n const raw = typeof td.innerText === 'string' ? td.innerText : td.textContent ?? '';\n return raw.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * The canonical pageless data grid for both portals. Wraps `<ResizableTable>`\n * with selection-checkbox logic, keyboard navigation, the standardized list\n * footer, an infinite-scroll sentinel hook-up, and a right-click row menu.\n *\n * Usage:\n *\n * const { sort, onSort } = useSort('mid', 'asc', 'suppliers');\n * const { items, totalCount, isLoading, isFetchingNextPage, sentinelRef } =\n * useInfiniteScroll<Supplier>({ queryKey: ['suppliers', filters],\n * fetchFn: (p) => getSuppliers(p) });\n *\n * <EntityList\n * items={items}\n * totalCount={totalCount}\n * isLoading={isLoading}\n * sentinelRef={sentinelRef}\n * isFetchingNextPage={isFetchingNextPage}\n * tableId=\"suppliers\"\n * columns={SUPPLIER_COLUMNS}\n * renderCell={(s, k) => …}\n * sort={sort} onSort={onSort}\n * selected={selected} setSelected={setSelected}\n * onRowClick={(s) => openEntity('supplier', s.id, s, s.mid, '/suppliers')}\n * exportEndpoint=\"/suppliers/export_csv/\" exportFilename=\"Suppliers.csv\"\n * footerLabel=\"suppliers\"\n * emptyState={<EmptyState message=\"No suppliers yet.\" />}\n * />\n */\nexport default function EntityList<T>(props: EntityListProps<T>) {\n const {\n items, isLoading, emptyState, totalCount,\n isError, onRetry, errorTitle, errorMessage,\n tableId, columns, renderCell, getRowId = (item: any) => item.id,\n sort, onSort,\n selected, setSelected,\n onRowClick, onRowHover, getRowClassName,\n footerLabel, footerExtra,\n sentinelRef, isFetchingNextPage,\n saveDefaultPerms,\n exportEndpoint, exportFilename = 'export.csv', contextActions,\n } = props;\n\n const [menu, setMenu] = useState<RowMenu<T> | null>(null);\n const bodyRef = useRef<HTMLTableSectionElement>(null);\n // The same catalog DataTable's selection column reads, so the two say the\n // same words — and say them in the consumer's language when a provider is\n // mounted. English defaults without one.\n const strings = useShellStrings();\n\n const toggleItem = (item: T) => {\n setSelected(prev => {\n const next = new Set(prev);\n const id = getRowId(item);\n if (next.has(id)) next.delete(id); else next.add(id);\n return next;\n });\n };\n\n const toggleAll = () => {\n setSelected(prev => prev.size === items.length ? new Set() : new Set(items.map(getRowId)));\n };\n\n const selectRange = (from: number, to: number) => {\n setSelected(prev => {\n const next = new Set(prev);\n for (let i = from; i <= to; i++) next.add(getRowId(items[i]));\n return next;\n });\n };\n\n const focusIdx = useTableNav(items, onRowClick, toggleItem, toggleAll, selectRange);\n\n // Right-click a row → the row menu. If the row isn't already selected it\n // becomes the selection (standard desktop behaviour); an existing\n // multi-selection is kept. The browser keeps its own menu wherever the\n // shell-wide one leaves it — a text field or an image inside a row, a\n // `data-native-context-menu` subtree — and on Shift+right-click. Everywhere\n // else the event is claimed, so `ShellContextMenu` stands down over a row.\n const handleRowContextMenu = (e: MouseEvent<HTMLTableRowElement>, item: T) => {\n if (e.shiftKey || keepsNativeMenu(e.target)) return;\n e.preventDefault();\n const id = getRowId(item);\n if (!selected.has(id)) setSelected(new Set([id]));\n // The first column as the user has arranged it, read off the row itself.\n const key = rowCells(e.currentTarget)[0]?.dataset.colKey;\n const label = key ? columns.find(c => c.key === key)?.label : undefined;\n setMenu({\n x: e.clientX,\n y: e.clientY,\n item,\n text: selectionAt(e.target),\n firstColumn: key && label ? { key, label } : null,\n });\n };\n\n const selectedItems = items.filter(i => selected.has(getRowId(i)));\n\n // The ticked rows as the user sees them: the visible columns in their\n // on-screen order, read off the rendered cells. Reading the DOM rather than\n // calling `renderCell` again is the point — a cell renders a badge, a link or\n // a formatted amount, and a copy should hold what is on screen, not an id or\n // an ISO date.\n const selectedTable = () => {\n const rows = [...(bodyRef.current?.querySelectorAll<HTMLTableRowElement>('tr[data-row-idx]') ?? [])]\n .filter(tr => {\n const it = items[Number(tr.dataset.rowIdx)];\n return it !== undefined && selected.has(getRowId(it));\n });\n const keys = rows.length ? rowCells(rows[0]).map(td => td.dataset.colKey ?? '') : [];\n const labelByKey = new Map(columns.map(c => [c.key, c.label]));\n return {\n keys,\n header: keys.map(k => labelByKey.get(k) ?? k),\n body: rows.map(tr => rowCells(tr).map(cellText)),\n };\n };\n\n const copyRows = () => {\n setMenu(null);\n const { header, body } = selectedTable();\n if (!body.length) return;\n const text = [header, ...body].map(cells => cells.join('\\t')).join('\\n');\n const html = '<table><thead><tr>'\n + header.map(h => `<th>${escapeHtml(h)}</th>`).join('')\n + '</tr></thead><tbody>'\n + body.map(cells => `<tr>${cells.map(c => `<td>${escapeHtml(c)}</td>`).join('')}</tr>`).join('')\n + '</tbody></table>';\n void copyToClipboard(body.length === 1 ? 'Row' : `${body.length} rows`, text, html);\n };\n\n const copyColumn = (column: { key: string; label: string }) => {\n setMenu(null);\n const { keys, body } = selectedTable();\n const at = keys.indexOf(column.key);\n if (at < 0 || !body.length) return;\n void copyToClipboard(column.label, body.map(cells => cells[at]).join('\\n'));\n };\n\n // The visible/ordered columns as `key|Label,…` so the export mirrors the grid\n // (ResizableTable persists the live config to localStorage under this key).\n const colsParam = () => {\n const labelByKey = new Map(columns.map(c => [c.key, c.label]));\n try {\n const raw = localStorage.getItem(`col-config-${tableId}`);\n if (raw) {\n const parsed = JSON.parse(raw) as { key: string; hidden?: boolean }[];\n const cols = parsed\n .filter(c => !c.hidden && c.key !== '_select' && labelByKey.has(c.key))\n .map(c => `${c.key}|${labelByKey.get(c.key)}`);\n if (cols.length) return cols.join(',');\n }\n } catch { /* fall back to defaults */ }\n return columns.filter(c => !c.defaultHidden).map(c => `${c.key}|${c.label}`).join(',');\n };\n\n const exportSelected = async () => {\n setMenu(null);\n const ids = [...selected];\n if (!ids.length || !exportEndpoint) return;\n const p = new URLSearchParams({ ids: ids.join(',') });\n const cols = colsParam();\n if (cols) p.set('cols', cols);\n const sep = exportEndpoint.includes('?') ? '&' : '?';\n try {\n const res = await apiClient.get(`${exportEndpoint}${sep}${p}`, { responseType: 'blob' });\n const url = window.URL.createObjectURL(new Blob([res.data], { type: 'text/csv' }));\n const a = document.createElement('a');\n a.href = url;\n a.download = exportFilename;\n a.click();\n window.URL.revokeObjectURL(url);\n // `ids.length` is what we ASKED for, not what came back. The backend caps\n // every list export (`MAX_EXPORT_ROWS` in efficient/mixins.py) and reports\n // the cut on `X-Truncated` / `X-Row-Count`, where the count is the rows\n // actually in the file. Announcing the request count without reading them\n // states a number the file does not contain (BG#00477). Axios lowercases\n // response header names. When the headers are absent — an older backend,\n // or a cross-origin response that does not expose them — this falls\n // through to the unchanged success message.\n const headers = res.headers ?? {};\n const rowCount = Number(headers['x-row-count']);\n if (String(headers['x-truncated']) === 'true') {\n const kept = Number.isFinite(rowCount) ? `${rowCount} of ${ids.length}` : `only some of the ${ids.length}`;\n toast.notify(`Exported ${kept} rows. The server capped this export, so the file is incomplete.`);\n return;\n }\n toast.success(`Exported ${ids.length} ${ids.length === 1 ? 'row' : 'rows'}.`);\n } catch {\n toast.error('CSV export failed.');\n }\n };\n\n if (isLoading) return <LoadingSpinner />;\n // A failed initial fetch (no rows) reads as an error with retry, not the\n // empty state. Once rows exist, a later next-page failure keeps the list.\n // `title`/`message` default inside ListLoadError, so passing undefined here\n // keeps the generic copy for callers that don't name their entity.\n if (isError && items.length === 0) {\n return <ListLoadError title={errorTitle} message={errorMessage} onRetry={onRetry} />;\n }\n if (items.length === 0) return <>{emptyState}</>;\n\n const allSelected = items.length > 0 && selected.size === items.length;\n // The state the header box was missing. \"Some of these rows are selected\" is\n // not \"none of them\": an unchecked select-all above three ticked rows says\n // the page is clear, and the operator's next click — meaning \"select\n // everything\" — selects everything, which is what it already looked like.\n const someSelected = selected.size > 0 && !allSelected;\n\n const fullColumns: EntityListColumn[] = [\n {\n key: '_select',\n label: '',\n defaultWidth: 52,\n minWidth: 52,\n headerNode: (\n <Checkbox\n aria-label={strings.table.selectAll}\n checked={allSelected}\n indeterminate={someSelected}\n onChange={toggleAll}\n // 14px, which is what this column has always drawn — a row of them\n // down a dense list reads differently at 16. It cannot be a class:\n // `Checkbox` carries `h-4 w-4` in its own base, and Tailwind emits\n // `.h-3\\.5` BEFORE `.h-4`, so `h-3.5` in the className loses the\n // cascade however it is ordered in the attribute. An inline style is\n // the kit's documented way out of exactly that.\n style={{ height: 14, width: 14 }}\n />\n ),\n },\n ...columns,\n ];\n\n const footer = (\n <ListFooter\n selectedCount={selected.size}\n loadedCount={items.length}\n totalCount={totalCount}\n label={footerLabel}\n isFetchingMore={isFetchingNextPage}\n extra={footerExtra}\n />\n );\n\n const afterBody = sentinelRef ? (\n <>\n <div ref={sentinelRef} />\n {isFetchingNextPage && (\n <div className=\"text-center py-3\"><span className=\"text-sm text-gray-500\">Loading more...</span></div>\n )}\n </>\n ) : undefined;\n\n let rowMenu: ReactNode = null;\n if (menu) {\n const { x, y, item, text, firstColumn } = menu;\n const actions = contextActions ? contextActions(selectedItems) : [];\n const count = selectedItems.length;\n const close = () => setMenu(null);\n const moreExist = totalCount !== undefined && totalCount > items.length;\n rowMenu = (\n <PopupMenu portal style={{ left: x, top: y }} onClose={close} minWidth={210}>\n <PopupMenuLabel>{selected.size} selected</PopupMenuLabel>\n <PopupMenuItem className=\"font-medium\" onClick={() => { close(); onRowClick(item); }}>Open</PopupMenuItem>\n <PopupMenuDivider />\n {text && (\n <PopupMenuItem onClick={() => { close(); void copyToClipboard('Text', text.text, text.html); }}>Copy</PopupMenuItem>\n )}\n {firstColumn && (\n <PopupMenuItem onClick={() => copyColumn(firstColumn)}>Copy {firstColumn.label}</PopupMenuItem>\n )}\n <PopupMenuItem disabled={count === 0} onClick={copyRows}>\n {count === 1 ? 'Copy row' : `Copy ${count} rows`}\n </PopupMenuItem>\n {exportEndpoint && (\n <PopupMenuItem onClick={exportSelected}>Export selected to CSV</PopupMenuItem>\n )}\n {actions.map((a, i) => (\n <div key={i}>\n {/* The page's actions get a divider of their own; one it asked for\n on its first action is that same line, not a second one. */}\n {(a.divider || i === 0) && <PopupMenuDivider />}\n <PopupMenuItem\n danger={a.danger}\n disabled={a.disabled}\n onClick={() => { close(); a.onClick(selectedItems); }}\n >\n {a.label}\n </PopupMenuItem>\n </div>\n ))}\n <PopupMenuDivider />\n {!allSelected && (\n <PopupMenuItem onClick={() => { close(); setSelected(new Set(items.map(getRowId))); }}>\n {moreExist ? `Select all ${items.length} loaded` : 'Select all'}\n </PopupMenuItem>\n )}\n <PopupMenuItem onClick={() => { close(); setSelected(new Set()); }}>Clear selection</PopupMenuItem>\n {onRetry && (\n <PopupMenuItem onClick={() => { close(); onRetry(); }}>Refresh</PopupMenuItem>\n )}\n </PopupMenu>\n );\n }\n\n return (\n <div className=\"flex-1 flex flex-col mb-1 bg-white rounded-lg shadow overflow-hidden\">\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <ResizableTable\n tableId={tableId}\n columns={fullColumns}\n sort={sort}\n onSort={onSort}\n footer={footer}\n afterBody={afterBody}\n saveDefaultPerms={saveDefaultPerms}\n >\n {(cols) => (\n <tbody ref={bodyRef} className=\"divide-y divide-gray-100\">\n {items.map((item, rowIdx) => {\n const id = getRowId(item);\n return (\n <tr\n key={id}\n data-row-idx={rowIdx}\n className={`cursor-pointer ${focusIdx === rowIdx ? 'bg-blue-50 ring-1 ring-inset ring-blue-300' : selected.has(id) ? 'bg-blue-50 hover:bg-blue-100' : 'hover:bg-gray-50'} ${getRowClassName?.(item) ?? ''}`}\n onClick={() => onRowClick(item)}\n onContextMenu={(e) => handleRowContextMenu(e, item)}\n onMouseEnter={onRowHover ? () => onRowHover(item) : undefined}\n >\n {cols.map(col => (\n <td key={col.key} data-col-key={col.key} className=\"px-4 py-3 whitespace-nowrap text-sm overflow-hidden\">\n {col.key === '_select' ? (\n <Checkbox\n aria-label={strings.table.selectRow}\n checked={selected.has(id)}\n onChange={() => toggleItem(item)}\n // The row itself opens the record. The box only\n // ever selects, so its click stops here — the\n // toggle rides `onChange`, which React raises from\n // the same native click as a separate synthetic\n // event and so survives the stop.\n onClick={e => e.stopPropagation()}\n // See the header box: 14px cannot be a class.\n style={{ height: 14, width: 14 }}\n />\n ) : renderCell(item, col.key)}\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n )}\n </ResizableTable>\n </div>\n\n {rowMenu}\n </div>\n );\n}\n","import { useEffect, useRef, useCallback } from 'react';\nimport { useInfiniteQuery } from '@tanstack/react-query';\nimport type { PaginatedResponse } from './types';\n\ninterface UseInfiniteScrollOptions<T> {\n /** queryKey segments — arbitrary cache shapes (filters often include booleans,\n * dates, undefined). Callers pass their natural filter shape. */\n queryKey: (string | Record<string, unknown>)[];\n fetchFn: (params: Record<string, string>) => Promise<PaginatedResponse<T>>;\n /** Extra query-string params. Undefined values are dropped so axios doesn't\n * serialise them as \"?key=undefined\". */\n extraParams?: Record<string, string | undefined>;\n pageSize?: number;\n}\n\n/**\n * Wraps TanStack `useInfiniteQuery` with an IntersectionObserver-driven\n * sentinel so attaching `sentinelRef` to a div near the bottom of a scrollable\n * container auto-fires `fetchNextPage` as the user scrolls.\n *\n * Works inside modal windows too — the observer roots itself on the nearest\n * scrollable ancestor rather than the viewport.\n */\nexport function useInfiniteScroll<T>({\n queryKey,\n fetchFn,\n extraParams = {},\n pageSize: _pageSize = 25,\n}: UseInfiniteScrollOptions<T>) {\n void _pageSize; // reserved for future use; current backend defaults are fine\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n const cleanExtra = Object.fromEntries(\n Object.entries(extraParams).filter(([, v]) => v !== undefined),\n ) as Record<string, string>;\n\n const query = useInfiniteQuery({\n queryKey,\n queryFn: ({ pageParam = 1 }) =>\n fetchFn({ page: String(pageParam), ...cleanExtra }),\n getNextPageParam: (lastPage, allPages) => {\n if (lastPage.next) {\n return allPages.length + 1;\n }\n return undefined;\n },\n initialPageParam: 1,\n });\n\n const { fetchNextPage, hasNextPage, isFetchingNextPage } = query;\n\n const handleObserver = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n const [entry] = entries;\n if (entry.isIntersecting && hasNextPage && !isFetchingNextPage) {\n fetchNextPage();\n }\n },\n [fetchNextPage, hasNextPage, isFetchingNextPage],\n );\n\n useEffect(() => {\n const el = sentinelRef.current;\n if (!el) return;\n\n // Find the nearest scrollable ancestor — using root:null (viewport) fails\n // when the list is inside a modal window because the sentinel can scroll\n // into view within the modal's own overflow container without ever\n // entering the viewport.\n let scrollParent: HTMLElement | null = el.parentElement;\n while (scrollParent) {\n const overflow = getComputedStyle(scrollParent).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') break;\n scrollParent = scrollParent.parentElement;\n }\n\n const observer = new IntersectionObserver(handleObserver, {\n root: scrollParent,\n rootMargin: '200px',\n threshold: 0,\n });\n\n observer.observe(el);\n return () => observer.disconnect();\n }, [handleObserver]);\n\n // Defensive: drop any null/undefined entries that creep in from a malformed\n // page payload (e.g. backend serializer returns null for soft-deleted\n // records). Otherwise downstream `.map(r => r.id)` blows up the whole list.\n //\n // Then de-dupe by `id` across pages. Offset pagination over a non-unique\n // ordering key — or a background refetch of the already-loaded pages while\n // the underlying data shifts — can hand back the same record on two pages;\n // flattening them would render that row twice (the duplicate-row bug). Keep\n // the first occurrence. Items without an `id` can't be de-duped, so keep them.\n const seenIds = new Set<unknown>();\n const allItems = (query.data?.pages.flatMap((page) => page?.results ?? []) ?? [])\n .filter((x): x is T => x != null)\n .filter((x) => {\n const id = (x as { id?: unknown }).id;\n if (id == null) return true;\n if (seenIds.has(id)) return false;\n seenIds.add(id);\n return true;\n });\n const totalCount = query.data?.pages[0]?.count ?? 0;\n\n return {\n items: allItems,\n totalCount,\n isLoading: query.isLoading,\n // Surface the query's error state so a failed fetch renders as an error\n // (with retry) rather than a misleading empty list. `refetch` is the retry.\n isError: query.isError,\n error: query.error,\n isFetchingNextPage,\n hasNextPage: !!hasNextPage,\n sentinelRef,\n refetch: query.refetch,\n };\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { useDefaultColumnConfig } from './useDefaultColumnConfig';\nimport type { SortState } from './types';\n\n/** Guard for values restored from prefs / localStorage / the backend —\n * anything that isn't a well-formed `{ field, direction }` is ignored. */\nfunction isValidSort(v: unknown): v is SortState {\n const s = v as SortState | null | undefined;\n return !!s && typeof s.field === 'string' && s.field.length > 0 &&\n (s.direction === 'asc' || s.direction === 'desc');\n}\n\n/** The part of a column `useSort` reads — `ColumnDef` and `EntityList`'s own\n * column both fit.\n *\n * Not `DataTable`: its columns nest inside groups and it offers a sort on\n * `sortable`, not on `sortField ?? key`. `DataTableColumn` satisfies this\n * interface structurally, so passing one typechecks and then drops sorts the\n * table does offer. `DataTable` owns its own sort state through\n * `onSortChange`. */\nexport interface SortableColumn {\n key: string;\n sortField?: string;\n}\n\n/** Is `field` one the table offers? Same rule `ResizableTable` uses to make a\n * header clickable: `sortField ?? key`, never `_select`, and `sortField: ''`\n * switches the sort off. */\nfunction isOffered(columns: ReadonlyArray<SortableColumn>, field: string): boolean {\n return columns.some(c => (c.sortField ?? (c.key !== '_select' ? c.key : '')) === field && field !== '');\n}\n\n/**\n * Sort-state hook used by list pages. Returns:\n * - `sort` — current `{ field, direction }`\n * - `onSort(field)` — toggle direction if same field, else activate asc\n * - `ordering` — DRF-style string (`'-mid'` for desc, `'mid'` for asc) ready\n * to drop into a query-string param.\n *\n * Pass `tableId` (the same id the list gives `<ResizableTable>`/`<EntityList>`)\n * to persist the user's choice alongside their column config. Restore order:\n * per-user pref (`prefs.sort_{tableId}` via the ShellPrefs adapter) → the\n * admin-saved default on `/auth/default-columns/{tableId}/` → the page's\n * `defaultField`/`defaultDir`. localStorage mirrors the last-applied value so\n * the first render (before async prefs arrive) already uses the last-known\n * sort instead of flashing the default and refetching. Without `tableId` the\n * hook is pure in-memory state, exactly as before.\n *\n * The admin default is read through `useDefaultColumnConfig`, shared with\n * `useColumnConfig` so a list page fetches that row once rather than twice\n * (SG#00590). That probe is a react-query query, but this hook still needs no\n * `<QueryClientProvider>` in either form: with no provider above it the probe\n * falls back to a client the package owns (see `useDefaultColumnConfig`), and\n * the `tableId`-less form issues no request at all, as before.\n *\n * Pass `options.columns` (the same array the table gets) and a sort the\n * columns do not offer is replaced by the page default in `sort` and\n * `ordering` — a save on a column since given `sortField: ''`, or on a key\n * whose column now sorts on another `sortField`. Without it that stale save\n * goes out as `?ordering=` on every open; DRF drops a term it cannot order by,\n * so the list comes back unsorted for good. Without `columns` — or while the\n * array is still empty, which is a list page whose columns are not built yet\n * rather than a table that offers no sort — nothing is checked, as before.\n */\nexport function useSort(\n defaultField: string,\n defaultDir: 'asc' | 'desc' = 'asc',\n tableId?: string,\n options?: { columns?: ReadonlyArray<SortableColumn> },\n) {\n const { prefs, save } = useShellPrefs();\n const prefKey = tableId ? `sort_${tableId}` : null;\n\n const [chosen, setSort] = useState<SortState>(() => {\n if (prefKey) {\n if (isValidSort(prefs[prefKey])) return prefs[prefKey];\n try {\n const cached = JSON.parse(localStorage.getItem(`sort-config-${tableId}`) || 'null');\n if (isValidSort(cached)) return cached;\n } catch { /* fall through */ }\n }\n return { field: defaultField, direction: defaultDir };\n });\n\n // A click this mount always wins over any async restore below.\n const touchedRef = useRef(false);\n const savedPref = prefKey ? prefs[prefKey] : undefined;\n const savedRef = useRef(savedPref);\n savedRef.current = savedPref;\n\n // Per-user pref — prefs adapters load async, so a window opened before they\n // arrive starts on the default; apply the pref when it turns up.\n useEffect(() => {\n if (touchedRef.current || !isValidSort(savedPref)) return;\n setSort(prev =>\n prev.field === savedPref.field && prev.direction === savedPref.direction ? prev : savedPref,\n );\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(savedPref)); } catch { /* ignore */ }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, (savedPref as SortState | undefined)?.field, (savedPref as SortState | undefined)?.direction]);\n\n // Admin-saved default — only consulted while the user has no pref of their\n // own (the per-user branch above overrides it whenever prefs resolve later).\n //\n // Shared with `useColumnConfig`, which wants `visible_columns` off the same\n // row: a list page calls both hooks, and each used to fire its own raw GET\n // for it (SG#00590). One react-query key, one request per screen.\n const { defaultConfig } = useDefaultColumnConfig(tableId);\n useEffect(() => {\n const dflt = defaultConfig?.sort;\n if (touchedRef.current || isValidSort(savedRef.current) || !isValidSort(dflt)) return;\n setSort(prev =>\n prev.field === dflt.field && prev.direction === dflt.direction ? prev : dflt,\n );\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(dflt)); } catch { /* ignore */ }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, defaultConfig]);\n\n // An EMPTY list is not an answer about what the table offers, it is a list\n // page whose columns have not been built yet — permission-filtered, or keyed\n // off a fetch. Reading it as \"offers nothing\" sent the page default on the\n // first render and the saved sort once the columns arrived: two requests per\n // open, the first of them sorted wrongly.\n const columns = options?.columns?.length ? options.columns : undefined;\n const sort: SortState = !columns || isOffered(columns, chosen.field)\n ? chosen\n : { field: defaultField, direction: defaultDir };\n\n const onSort = (field: string) => {\n touchedRef.current = true;\n const next: SortState =\n sort.field === field\n ? { field, direction: sort.direction === 'asc' ? 'desc' : 'asc' }\n : { field, direction: 'asc' };\n setSort(next);\n if (prefKey) {\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(next)); } catch { /* ignore */ }\n void save({ [prefKey]: next });\n }\n };\n\n const ordering = sort.direction === 'desc' ? `-${sort.field}` : sort.field;\n\n return { sort, onSort, ordering };\n}\n","import { useState, useRef, useEffect, useCallback, useId } from 'react';\nimport type { ReactNode, KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { XMarkIcon } from '@heroicons/react/20/solid';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { registerModalEscapeInterceptor } from './escapeInterceptors';\nimport { firstEnabledIndex, lastEnabledIndex, matchTypeahead, nextEnabledIndex } from '../forms/selectNav';\n\nexport interface FilterOption {\n label: string;\n field: string;\n options: { value: string; label: string }[];\n searchable?: boolean; // default true if > 8 options\n}\n\ninterface FilterBarProps {\n filters: FilterOption[];\n values: Record<string, string>;\n onChange: (field: string, value: string) => void;\n onClear: () => void;\n children?: ReactNode;\n}\n\n/**\n * FilterBar — a horizontal row of filter controls. Each filter renders a custom\n * listbox dropdown or, for long lists, a glass-styled searchable dropdown; a\n * \"Clear filters\" button appears when any filter is active. Pair with\n * `useFilters`.\n *\n * The short-list path used to render a native `<select>`, but a native select's\n * OS popup swallows every key event while open — so list-page hotkeys died\n * until it closed (BG#00421). PlainFilter is a custom listbox that keeps key\n * events flowing to the page.\n */\nexport default function FilterBar({ filters, values, onChange, onClear, children }: FilterBarProps) {\n const activeCount = Object.values(values).filter(Boolean).length;\n\n return (\n <div className=\"flex items-center gap-3 flex-wrap\">\n {filters.map(f => {\n const isSearchable = f.searchable ?? f.options.length > 8;\n return isSearchable ? (\n <SearchableFilter\n key={f.field}\n filter={f}\n value={values[f.field] || ''}\n onChange={v => onChange(f.field, v)}\n />\n ) : (\n <PlainFilter\n key={f.field}\n filter={f}\n value={values[f.field] || ''}\n onChange={v => onChange(f.field, v)}\n />\n );\n })}\n {children}\n {activeCount > 0 && (\n <button onClick={onClear} className=\"flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700\">\n <XMarkIcon className=\"h-4 w-4\" />\n Clear filters\n </button>\n )}\n </div>\n );\n}\n\n/**\n * PlainFilter — the short-list (<=8 option) filter control. A pill trigger plus\n * a glass listbox dropdown, styled to match SearchableFilter. Focus stays on\n * the trigger and the active option is tracked via `aria-activedescendant`\n * (combobox pattern), with full keyboard support: Arrow/Home/End move the active\n * option, Enter/Space select, letter typeahead jumps, Esc closes the listbox\n * only. The leading option clears the filter (value '').\n */\nfunction PlainFilter({ filter, value, onChange }: { filter: FilterOption; value: string; onChange: (v: string) => void }) {\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(-1);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const openRef = useRef(open);\n openRef.current = open;\n const typeahead = useRef<{ buffer: string; timer: ReturnType<typeof setTimeout> | null }>({ buffer: '', timer: null });\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (i: number) => `${baseId}-opt-${i}`;\n\n // Index 0 is the \"clear\" entry (value ''), so the option list and the trigger\n // label share one array and keyboard nav can land on \"All\".\n const items = [{ value: '', label: filter.label }, ...filter.options];\n const selectedIndex = value ? items.findIndex(o => o.value === value) : 0;\n const selectedLabel = value ? filter.options.find(o => o.value === value)?.label : null;\n\n const close = useCallback((refocus = true) => {\n setOpen(false);\n setActive(-1);\n if (refocus) triggerRef.current?.focus();\n }, []);\n\n const openList = useCallback(() => {\n setActive(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex(items));\n setOpen(true);\n }, [selectedIndex, items]);\n\n const commit = useCallback((i: number) => {\n const o = items[i];\n if (!o) return;\n onChange(o.value);\n close();\n }, [items, onChange, close]);\n\n useClickOutside(ref, useCallback(() => { if (open) close(false); }, [open, close]));\n\n // Esc closes the listbox first, without closing a parent modal/window — the\n // modal's capture-phase Esc handler beats a bubble-phase onKeyDown, so the\n // shell's interceptor seam is the only way to win the race. The local\n // onKeyDown still covers the no-modal (plain page) case.\n useEffect(() => {\n if (!open) return;\n return registerModalEscapeInterceptor(e => {\n if (e.key !== 'Escape' || !openRef.current) return false;\n close();\n return true;\n });\n }, [open, close]);\n\n useEffect(() => {\n if (!open || active < 0) return;\n listRef.current?.querySelector<HTMLElement>(`#${CSS.escape(optionId(active))}`)?.scrollIntoView({ block: 'nearest' });\n });\n\n const runTypeahead = (char: string) => {\n const ta = typeahead.current;\n if (ta.timer) clearTimeout(ta.timer);\n ta.buffer += char;\n ta.timer = setTimeout(() => { ta.buffer = ''; ta.timer = null; }, 500);\n const hit = matchTypeahead(items, ta.buffer, open ? active : selectedIndex);\n if (hit < 0) return;\n if (open) setActive(hit);\n else commit(hit);\n };\n\n const onKeyDown = (e: ReactKeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!open) openList(); else setActive(a => nextEnabledIndex(items, a, 1));\n return;\n case 'ArrowUp':\n e.preventDefault();\n if (!open) openList(); else setActive(a => nextEnabledIndex(items, a, -1));\n return;\n case 'Home':\n if (open) { e.preventDefault(); setActive(firstEnabledIndex(items)); }\n return;\n case 'End':\n if (open) { e.preventDefault(); setActive(lastEnabledIndex(items)); }\n return;\n case 'Enter':\n if (open) { e.preventDefault(); commit(active); }\n return;\n case ' ':\n e.preventDefault();\n if (!open) openList(); else commit(active);\n return;\n case 'Escape':\n if (open) { e.preventDefault(); e.stopPropagation(); close(); }\n return;\n case 'Tab':\n if (open) close(false);\n return;\n default:\n if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {\n e.preventDefault();\n runTypeahead(e.key);\n }\n }\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n ref={triggerRef}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-activedescendant={open && active >= 0 ? optionId(active) : undefined}\n onClick={() => (open ? close() : openList())}\n onKeyDown={onKeyDown}\n className={`flex items-center gap-1.5 border rounded-lg px-2.5 py-1.5 text-sm transition-colors ${value ? 'border-blue-400 bg-blue-50 text-blue-700' : 'border-gray-300 text-gray-600 hover:border-gray-400'}`}\n >\n <span className=\"truncate max-w-[140px]\">{selectedLabel || filter.label}</span>\n {value ? (\n // A span, not a button: this lives INSIDE the combobox <button>, and\n // `<button>` inside `<button>` is invalid HTML — React logs \"cannot\n // be a descendant of\" and warns of a hydration error. It stays out of\n // the a11y tree because clearing is already a first-class keyboard\n // action: index 0 of the listbox is the \"All\" entry (value ''). A\n // nested control here would only pad the combobox's accessible name\n // with an affordance Tab can't reach.\n <span\n aria-hidden=\"true\"\n onClick={e => { e.stopPropagation(); onChange(''); }}\n className=\"cursor-pointer text-blue-400 hover:text-blue-600\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <svg className={`h-3.5 w-3.5 text-gray-400 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n )}\n </button>\n\n {open && (\n <div ref={listRef} id={listboxId} role=\"listbox\" className=\"absolute top-full left-0 mt-1 w-56 rounded-2xl z-[400] max-h-52 overflow-y-auto py-1\" style={getGlassStyle()}>\n {items.map((o, i) => (\n <div\n key={o.value || '__all__'}\n id={optionId(i)}\n role=\"option\"\n aria-selected={i === selectedIndex}\n onPointerEnter={() => setActive(i)}\n onClick={() => commit(i)}\n className={`mx-1 cursor-pointer truncate rounded-lg px-3 py-1.5 text-sm\n ${i === active ? 'bg-blue-50 text-blue-700'\n : i === selectedIndex ? 'font-medium text-blue-600'\n : 'text-gray-700'}`}\n >\n {o.label}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SearchableFilter({ filter, value, onChange }: { filter: FilterOption; value: string; onChange: (v: string) => void }) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const ref = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const selectedLabel = value ? filter.options.find(o => o.value === value)?.label : null;\n\n useClickOutside(ref, useCallback(() => { if (open) { setOpen(false); setSearch(''); } }, [open]));\n\n useEffect(() => {\n if (open) setTimeout(() => inputRef.current?.focus(), 50);\n }, [open]);\n\n const filtered = search\n ? filter.options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : filter.options;\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n onClick={() => setOpen(!open)}\n className={`flex items-center gap-1.5 border rounded-lg px-2.5 py-1.5 text-sm transition-colors ${value ? 'border-blue-400 bg-blue-50 text-blue-700' : 'border-gray-300 text-gray-600 hover:border-gray-400'}`}\n >\n <span className=\"truncate max-w-[140px]\">{selectedLabel || filter.label}</span>\n {value ? (\n // Same nested-button fix as PlainFilter — the dropdown's leading\n // \"All\" button is the keyboard path to the same clear.\n <span\n aria-hidden=\"true\"\n onClick={e => { e.stopPropagation(); onChange(''); setSearch(''); }}\n className=\"cursor-pointer text-blue-400 hover:text-blue-600\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <svg className={`h-3.5 w-3.5 text-gray-400 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n )}\n </button>\n\n {open && (\n <div className=\"absolute top-full left-0 mt-1 w-56 rounded-2xl z-[400] overflow-hidden\" style={getGlassStyle()}>\n {/* Search input */}\n <div className=\"p-1.5 border-b border-gray-100\">\n <input\n ref={inputRef}\n value={search}\n onChange={e => setSearch(e.target.value)}\n placeholder={`Search ${filter.label.replace(/^All\\s*/i, '').toLowerCase()}...`}\n className=\"w-full rounded-md border border-gray-200 px-2.5 py-1.5 text-sm focus:border-blue-400 focus:ring-0 outline-none\"\n />\n </div>\n {/* Options */}\n <div className=\"max-h-52 overflow-y-auto\">\n {/* \"All\" option */}\n <button\n onClick={() => { onChange(''); setOpen(false); setSearch(''); }}\n className={`w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 ${!value ? 'text-blue-600 font-medium bg-blue-50/50' : 'text-gray-600'}`}\n >\n {filter.label}\n </button>\n {filtered.length === 0 ? (\n <p className=\"px-3 py-3 text-sm text-gray-400 text-center\">No matches</p>\n ) : (\n filtered.map(o => (\n <button\n key={o.value}\n onClick={() => { onChange(o.value); setOpen(false); setSearch(''); }}\n className={`w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 truncate ${value === o.value ? 'text-blue-600 font-medium bg-blue-50/50' : 'text-gray-700'}`}\n >\n {o.label}\n </button>\n ))\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** Local filter-state helper: tracks active filter values + derived params. */\nexport function useFilters() {\n const [filterValues, setFilterValues] = useState<Record<string, string>>({});\n\n const setFilter = (field: string, value: string) => {\n setFilterValues(prev => {\n const next = { ...prev };\n if (value) next[field] = value;\n else delete next[field];\n return next;\n });\n };\n\n const clearFilters = () => setFilterValues({});\n\n const filterParams: Record<string, string> = {};\n for (const [k, v] of Object.entries(filterValues)) {\n if (v) filterParams[k] = v;\n }\n\n return { filterValues, setFilter, clearFilters, filterParams };\n}\n","/**\n * A perf report as plain text, for whatever the host files it into.\n *\n * The attachment is complete but nobody opens it first. A bug tracker shows\n * descriptions, so a performance report whose description is one sentence\n * about a stutter sits in the list looking like every other vague complaint\n * while the numbers that would rank it stay zipped inside a 140 KB file.\n *\n * So the description carries the findings: the machine, then the verdict, the\n * median, the worst frame, and the gesture that was slowest. That last line is\n * what changed the HUD's usefulness — the log marks menu opens, flyout opens\n * and window move/resize separately, so \"slowest while: submenu (14 fps)\" is a\n * sentence the report can lead with instead of leaving a triager to guess from\n * an average taken across a whole session.\n *\n * This lives in the shell rather than in each consuming portal because it is\n * pure formatting of a shell type and was otherwise going to exist three\n * times — which is how three copies quietly stop agreeing about what a report\n * says. What stays portal-side is everything genuinely portal-shaped: which\n * endpoint to post to, and which module list to seed from.\n */\nimport { describeMachine } from './perfEnvironment';\nimport type { PerfReport } from './PerfStats';\n\n/** Groups worth naming in the description. More than this and the summary\n * stops being a summary; the attachment has the rest. */\nconst TOP_GROUPS = 3;\n\n/** A frame rate of zero is not a slow reading, it is the absence of one — the\n * thread was too blocked to deliver frames at all. Printing \"0 fps\" makes it\n * look like a measurement. */\nconst fps = (n: number): string => (n > 0 ? `${n.toFixed(0)} fps` : 'stalled');\n\nconst duration = (ms: number): string => {\n const seconds = Math.round(ms / 1000);\n return seconds < 60 ? `${seconds}s` : `${Math.round(seconds / 60)}m`;\n};\n\n/** The description body for a filed performance report. */\nexport function describePerfReport(report: PerfReport): string {\n const { summary, message, verdict, environment } = report;\n const lines: string[] = [`Performance report — ${verdict}`, ''];\n\n lines.push(message.trim() || '(No description given.)', '');\n\n // The machine, before the numbers. Whether 34 fps is a bad application or an\n // old laptop is not decidable from the frame rate, and a triager who has to\n // open the attachment to find out will mostly just guess instead.\n lines.push(`Machine: ${describeMachine(environment)}`);\n const net = environment.network;\n if (net?.effectiveType && net.effectiveType !== '4g') {\n // Only when it is not the unremarkable case — a slow link is a different\n // complaint from a slow UI, and worth separating before anyone profiles.\n lines.push(`Connection: ${net.effectiveType}${net.rttMs ? ` · ${net.rttMs} ms round trip` : ''}`);\n }\n lines.push('');\n\n lines.push(\n `Median ${fps(summary.medianFps)} over ${duration(summary.durationMs)} ` +\n `(${summary.samples} samples), worst frame ${summary.worstFrameMs.toFixed(0)} ms.`,\n );\n\n // Worst-first already, so the head of each list is the finding.\n const activity = summary.byActivity.slice(0, TOP_GROUPS);\n if (activity.length) {\n lines.push(\n `Slowest while: ${activity.map(a => `${a.kind} ${fps(a.medianFps)} (worst ${a.worstMs.toFixed(0)} ms)`).join(' · ')}`,\n );\n }\n\n const menu = summary.worstMenus[0];\n if (menu) lines.push(`Slowest menu: ${menu.key} — ${fps(menu.medianFps)}`);\n\n const win = summary.worstWindows[0];\n if (win) lines.push(`Slowest window: ${win.key} — ${fps(win.medianFps)}`);\n\n if (summary.idle && summary.interacting) {\n lines.push(`At rest ${fps(summary.idle.medianFps)} vs in use ${fps(summary.interacting.medianFps)}.`);\n }\n\n lines.push('', `Full log attached as ${report.filename}.`);\n return lines.join('\\n');\n}\n\n/** The attachment. A `File` rather than a `Blob` so the multipart part carries\n * the stamped filename the receiving end stores. */\nexport function perfReportFile(report: PerfReport): File {\n return new File([report.json], report.filename, { type: 'application/json' });\n}\n","/**\n * Pure helpers for reconciling a bulk-import grid (rows of string cells) against\n * an existing items array, keyed by a designated \"key column\" (e.g. a part\n * number, SKU, or code). No app/framework dependencies — usable by any consumer\n * of {@link BulkImportGrid}.\n *\n * Merge rule: a blank cell means \"don't touch the original\" — only an explicit\n * value (including \"0\") replaces what's already there. Existing rows the user\n * didn't mention in the bulk grid are left untouched. Unknown keys are appended\n * via the caller-supplied `newItem` factory.\n */\n\nexport type BulkRow = Record<string, string | undefined>;\n\nexport interface DuplicateGroup {\n /** Key value as it appeared in the first occurrence (trimmed, original casing). */\n key: string;\n /** Indices into the rows array where this key appears. Length is always >= 2. */\n rowIndices: number[];\n}\n\n/**\n * Find key values that appear more than once within a single bulk-import file.\n * Match is case-insensitive (consistent with {@link mergeBulkItems}). Blank key\n * cells are ignored. The caller is expected to surface these to the user before\n * merge so they can pick a per-group resolution.\n */\nexport function findDuplicateKeys(rows: BulkRow[], keyRowKey: string): DuplicateGroup[] {\n const groups = new Map<string, { key: string; rowIndices: number[] }>();\n rows.forEach((r, i) => {\n const raw = r[keyRowKey];\n const trimmed = typeof raw === 'string' ? raw.trim() : '';\n if (!trimmed) return;\n const dedupeKey = trimmed.toUpperCase();\n const existing = groups.get(dedupeKey);\n if (existing) existing.rowIndices.push(i);\n else groups.set(dedupeKey, { key: trimmed, rowIndices: [i] });\n });\n const out: DuplicateGroup[] = [];\n for (const g of groups.values()) {\n if (g.rowIndices.length >= 2) out.push(g);\n }\n return out;\n}\n\ninterface BaseItem {\n [key: string]: unknown;\n}\n\nexport interface MergeBulkResult<T> {\n merged: T[];\n importedCount: number;\n}\n\nexport interface MergeBulkOptions<T extends BaseItem> {\n /** Raw rows from BulkImportGrid. */\n rows: BulkRow[];\n /** Existing items array to merge into. */\n existing: T[];\n /**\n * Mapping from row column key → item field key.\n * MUST include the key-column mapping (e.g. `{ pn: 'part_number' }`).\n * Example: `{ pn: 'part_number', qty: 'quantity', price: 'unit_price' }`.\n */\n fieldMap: Record<string, string>;\n /**\n * The item field that holds the merge key — the value `fieldMap` maps the\n * grid's key column onto. Existing items are matched against this field\n * (case-insensitive). Defaults to `'part_number'`.\n */\n keyField?: string;\n /**\n * Build a brand-new item for a row whose key isn't in `existing`.\n * `filled` contains only the fields the user actually entered (mapped to\n * item-field keys via `fieldMap`); supply defaults for anything required\n * by your item shape.\n */\n newItem: (filled: Partial<T>) => T;\n}\n\n/** Pull out just the trimmed cells the user actually filled in. */\nfunction pickFilled(row: BulkRow, fieldMap: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [rowKey, itemField] of Object.entries(fieldMap)) {\n const v = row[rowKey];\n const trimmed = typeof v === 'string' ? v.trim() : '';\n if (trimmed !== '') out[itemField] = trimmed;\n }\n return out;\n}\n\nexport function mergeBulkItems<T extends BaseItem>(\n options: MergeBulkOptions<T>,\n): MergeBulkResult<T> {\n const { rows, existing, fieldMap, newItem, keyField = 'part_number' } = options;\n\n // Locate the row key that holds the merge key, and the matching item field.\n const keyEntry = Object.entries(fieldMap).find(([, v]) => v === keyField);\n if (!keyEntry) {\n throw new Error(`mergeBulkItems: fieldMap must map a row column to \"${keyField}\"`);\n }\n const keyRowKey = keyEntry[0];\n\n const validRows = rows.filter(r => (r[keyRowKey] ?? '').trim());\n if (validRows.length === 0) return { merged: existing, importedCount: 0 };\n\n const existingMap = new Map<string, number>();\n existing.forEach((item, i) => {\n const k = item[keyField];\n if (typeof k === 'string' && k.trim()) existingMap.set(k.toUpperCase(), i);\n });\n\n const result = [...existing];\n const added: T[] = [];\n\n for (const r of validRows) {\n const filled = pickFilled(r, fieldMap);\n const k = filled[keyField];\n if (!k) continue;\n const idx = existingMap.get(k.toUpperCase());\n\n if (idx !== undefined) {\n // Existing key — overwrite only the fields the user actually entered.\n result[idx] = { ...result[idx], ...filled } as T;\n } else {\n // Tag every new item so callers can highlight bulk-imported rows in\n // the UI without each call site repeating the flag in their newItem\n // factory. Form submit payloads always project to explicit fields, so\n // the flag never leaks to the backend.\n added.push({ ...newItem(filled as Partial<T>), _isNew: true } as T);\n }\n }\n\n return { merged: [...result, ...added], importedCount: validRows.length };\n}\n","import { useState, useCallback } from 'react';\nimport EditableGrid, { withSpareRow } from './EditableGrid';\nimport { FileIntakeAlert, useFileIntake } from '../forms/useFileIntake';\nimport type { GridColumn } from './EditableGrid';\nimport { CancelButton } from './Modal';\nimport { findDuplicateKeys } from '../utils/mergeBulkItems';\nimport type { DuplicateGroup } from '../utils/mergeBulkItems';\n\n/**\n * Semantic role of a column, used to auto-map CSV columns to fields and to\n * format the per-column totals. The first column is always the merge \"key\"\n * regardless of its declared kind.\n * - `key` — the identifier rows are de-duplicated/merged on (text-like).\n * - `price` — a money column (matched by `$`/decimals; totalled with 2 dp).\n * - `qty` — a whole-number quantity column.\n * - `text` — anything else; never auto-mapped, never totalled.\n */\nexport type BulkColumnKind = 'key' | 'price' | 'qty' | 'text';\n\nexport interface BulkColumn {\n key: string;\n title: string;\n width?: number;\n required?: boolean;\n /**\n * Hint for CSV auto-mapping and totals. Defaults: the first column is `key`,\n * every other column is `text`. Set `price`/`qty` to opt a column into\n * auto-detection and the totals strip.\n */\n kind?: BulkColumnKind;\n}\n\nexport interface BulkImportGridProps {\n /** Column definitions. The FIRST column is always the merge key. */\n columns: BulkColumn[];\n /** Called with the resolved, de-duplicated rows (one object per row, keyed by column key). */\n onImport: (rows: Record<string, string>[]) => Promise<void>;\n /** Called when the user cancels an in-progress mapping/duplicate review. */\n onCancel: () => void;\n /** Optional override for the help text shown above the grid. */\n description?: string;\n /**\n * When set, duplicate key values are merged into a single row with their\n * numeric columns summed, instead of offering keep-first / keep-last / skip.\n * Use for quantity-based imports where two rows of the same key mean \"both\" —\n * never for price imports, where summing prices would be nonsensical.\n */\n mergeDuplicates?: boolean;\n}\n\nfunction cleanNumber(s: string): string {\n if (!s) return '';\n return s.replace(/[$¥¥€£,\\s]/g, '');\n}\n\nfunction parseCSVLine(line: string): string[] {\n if (line.includes('\\t')) return line.split('\\t').map(s => s.trim());\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n for (const ch of line) {\n if (ch === '\"') { inQuotes = !inQuotes; continue; }\n if (ch === ',' && !inQuotes) { parts.push(current.trim()); current = ''; continue; }\n current += ch;\n }\n parts.push(current.trim());\n return parts;\n}\n\n/** Resolve a column's effective kind: first column is the key, else its declared kind or `text`. */\nfunction colKind(col: BulkColumn, index: number): BulkColumnKind {\n if (index === 0) return 'key';\n return col.kind ?? 'text';\n}\n\n// ── Column type detection ──\n\ntype DetectedType = 'skip' | 'key' | 'price' | 'qty';\n\nfunction detectColumnType(values: string[]): DetectedType {\n const nonEmpty = values.filter(v => v.trim());\n if (nonEmpty.length === 0) return 'skip';\n\n const allIntOrEmpty = values.every(v => !v.trim() || /^\\d+$/.test(v.trim()));\n if (allIntOrEmpty) {\n const nums = nonEmpty.map(v => parseInt(v));\n const isSequential = nums.length > 2 && nums.every((n, i) => i === 0 || n >= nums[i - 1]);\n if (isSequential) return 'skip';\n }\n\n const hasLetters = nonEmpty.some(v => /[a-zA-Z]/.test(v));\n const hasDollar = nonEmpty.some(v => /\\$/.test(v));\n const hasDecimals = nonEmpty.filter(v => /\\.\\d{2}$/.test(cleanNumber(v))).length > nonEmpty.length * 0.5;\n const allWholeNumbers = nonEmpty.every(v => /^\\d+$/.test(cleanNumber(v)));\n\n if (hasLetters && !hasDollar) return 'key';\n if (hasDollar) return 'price';\n if (hasDecimals) return 'price';\n if (allWholeNumbers) {\n const avg = nonEmpty.reduce((s, v) => s + parseInt(cleanNumber(v)), 0) / nonEmpty.length;\n if (avg > 10) return 'qty';\n return 'skip';\n }\n return 'key';\n}\n\nfunction autoMapColumns(csvData: string[][], targetColumns: BulkColumn[]): number[] | null {\n if (csvData.length === 0 || csvData[0].length === 0) return null;\n const csvColCount = csvData[0].length;\n const targetKinds = targetColumns.map((c, i) => colKind(c, i));\n\n const csvColTypes: DetectedType[] = [];\n for (let c = 0; c < csvColCount; c++) {\n const values = csvData.map(row => row[c] || '');\n csvColTypes.push(detectColumnType(values));\n }\n\n const mapping: number[] = new Array(targetColumns.length).fill(-1);\n const used = new Set<number>();\n\n for (let t = 0; t < targetColumns.length; t++) {\n const kind = targetKinds[t];\n if (kind === 'text') continue;\n for (let c = 0; c < csvColCount; c++) {\n if (used.has(c)) continue;\n if (csvColTypes[c] === kind) {\n mapping[t] = c;\n used.add(c);\n break;\n }\n }\n }\n\n // Spread any remaining detected price columns across still-unmapped price targets,\n // in order (handles e.g. two currency columns the per-kind pass couldn't disambiguate).\n const priceTargets = targetKinds.map((k, i) => ({ i, k })).filter(x => x.k === 'price');\n const priceCsvCols = csvColTypes.map((t, i) => ({ i, type: t })).filter(x => x.type === 'price' && !used.has(x.i));\n let pi = 0;\n for (const pt of priceTargets) {\n if (mapping[pt.i] === -1 && pi < priceCsvCols.length) {\n mapping[pt.i] = priceCsvCols[pi].i;\n used.add(priceCsvCols[pi].i);\n pi++;\n }\n }\n\n if (mapping[0] === -1) return null; // key column must map\n return mapping;\n}\n\n// ── Column mapping UI ──\n\nfunction ColumnMapper({ csvPreview, targetColumns, onConfirm, onCancel }: {\n csvPreview: string[][];\n targetColumns: BulkColumn[];\n onConfirm: (mapping: number[]) => void;\n onCancel: () => void;\n}) {\n const autoMapping = autoMapColumns(csvPreview, targetColumns);\n const [mapping, setMapping] = useState<number[]>(autoMapping || new Array(targetColumns.length).fill(-1));\n const csvColCount = csvPreview[0]?.length || 0;\n\n const keyMapped = mapping[0] >= 0;\n\n return (\n <div className=\"border border-blue-200 rounded-lg bg-blue-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-3\">Map CSV columns to fields</p>\n <div className=\"grid grid-cols-2 gap-x-6 gap-y-2 mb-4\">\n {targetColumns.map((col, ti) => (\n <div key={col.key} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-gray-700 w-28 shrink-0\">{col.title}</span>\n <select value={mapping[ti]} onChange={e => setMapping(prev => { const next = [...prev]; next[ti] = parseInt(e.target.value); return next; })}\n className=\"flex-1 border border-gray-300 rounded px-2 py-1 text-sm focus:border-blue-500 focus:ring-blue-500\">\n <option value={-1}>— Skip —</option>\n {Array.from({ length: csvColCount }, (_, ci) => (\n <option key={ci} value={ci}>Column {ci + 1} (e.g. {csvPreview[0]?.[ci] || ''})</option>\n ))}\n </select>\n </div>\n ))}\n </div>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-3\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {targetColumns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">{col.title}</th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {csvPreview.slice(0, 3).map((row, ri) => (\n <tr key={ri}>\n {targetColumns.map((col, ti) => (\n <td key={col.key} className=\"px-2 py-1 text-gray-700 font-mono\">\n {mapping[ti] >= 0 ? (row[mapping[ti]] || '') : <span className=\"text-gray-300\">—</span>}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-500\">{csvPreview.length} rows detected</span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={() => onConfirm(mapping)} disabled={!keyMapped}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50\">\n Confirm Mapping\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Duplicate-key review UI ──\n\ntype DupResolution = 'first' | 'last' | 'all' | 'skip';\n\nfunction DuplicateReview({\n rows,\n groups,\n columns,\n resolutions,\n onResolutionChange,\n onConfirm,\n onCancel,\n}: {\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n columns: BulkColumn[];\n resolutions: Record<string, DupResolution>;\n onResolutionChange: (dupKey: string, choice: DupResolution) => void;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n const totalKept = groups.reduce((acc, g) => {\n const r = resolutions[g.key.toUpperCase()];\n if (r === 'skip') return acc;\n if (r === 'all') return acc + g.rowIndices.length;\n return acc + 1; // first/last always collapse to a single row\n }, 0);\n const totalDropped = groups.reduce((acc, g) => {\n const r = resolutions[g.key.toUpperCase()];\n if (r === 'skip') return acc + g.rowIndices.length;\n if (r === 'all') return acc;\n return acc + (g.rowIndices.length - 1);\n }, 0);\n\n return (\n <div className=\"border border-amber-200 rounded-lg bg-amber-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-1\">Duplicate entries detected</p>\n <p className=\"text-xs text-gray-600 mb-3\">\n {groups.length} {groups.length === 1 ? 'value appears' : 'values appear'} more than once in your import.\n Choose how to handle each before proceeding.\n </p>\n <div className=\"space-y-3 mb-3 max-h-80 overflow-y-auto\">\n {groups.map(g => {\n const dupKey = g.key.toUpperCase();\n const choice = resolutions[dupKey] || 'first';\n return (\n <div key={dupKey} className=\"border border-amber-200 rounded bg-white p-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-mono font-medium text-gray-800\">{g.key}</span>\n <span className=\"text-xs text-gray-500\">{g.rowIndices.length} occurrences</span>\n </div>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-2\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {columns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">\n {col.title.replace(' *', '')}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {g.rowIndices.map((ri, occ) => (\n <tr key={ri} className={\n choice === 'skip' ? 'opacity-40' :\n (choice === 'first' && occ !== 0) || (choice === 'last' && occ !== g.rowIndices.length - 1)\n ? 'opacity-40 line-through' : ''\n }>\n {columns.map(col => (\n <td key={col.key} className=\"px-2 py-1 text-gray-700 font-mono\">\n {rows[ri]?.[col.key] || <span className=\"text-gray-300\">—</span>}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs\">\n {(['first', 'last', 'all', 'skip'] as DupResolution[]).map(opt => (\n <label key={opt} className=\"flex items-center gap-1 cursor-pointer\">\n <input\n type=\"radio\"\n name={`dup-${dupKey}`}\n value={opt}\n checked={choice === opt}\n onChange={() => onResolutionChange(dupKey, opt)}\n className=\"h-3 w-3 text-amber-600 focus:ring-amber-500\"\n />\n <span className=\"text-gray-700\">\n {opt === 'first' ? 'Keep first' : opt === 'last' ? 'Keep last' : opt === 'all' ? 'Keep all' : 'Skip all'}\n </span>\n </label>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-600\">\n {totalKept} kept · {totalDropped} dropped\n </span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={onConfirm}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Duplicate-key merge UI (mergeDuplicates mode) ──\n\n/**\n * Collapse each duplicate group into one row, summing numeric columns. The\n * merged row takes the slot of the group's first occurrence so import order is\n * preserved; later occurrences are dropped. Non-numeric / all-blank columns\n * collapse to blank (downstream merge treats blank as \"don't touch\").\n */\nfunction mergeDuplicateRows(\n rows: Record<string, string>[],\n groups: DuplicateGroup[],\n columns: BulkColumn[],\n): Record<string, string>[] {\n const keyCol = columns[0].key;\n const firstOf = new Map<number, DuplicateGroup>();\n const dropped = new Set<number>();\n for (const g of groups) {\n firstOf.set(g.rowIndices[0], g);\n g.rowIndices.slice(1).forEach(i => dropped.add(i));\n }\n const out: Record<string, string>[] = [];\n rows.forEach((row, i) => {\n const g = firstOf.get(i);\n if (g) {\n const merged: Record<string, string> = {};\n for (const col of columns) {\n if (col.key === keyCol) { merged[col.key] = g.key; continue; }\n const nums = g.rowIndices\n .map(ri => (rows[ri]?.[col.key] ?? '').trim())\n .filter(v => v !== '' && Number.isFinite(Number(v)))\n .map(Number);\n merged[col.key] = nums.length > 0 ? String(nums.reduce((s, n) => s + n, 0)) : '';\n }\n out.push(merged);\n } else if (!dropped.has(i)) {\n out.push(row);\n }\n });\n return out;\n}\n\nfunction MergeReview({\n rows,\n groups,\n columns,\n onConfirm,\n onCancel,\n}: {\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n columns: BulkColumn[];\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n const keyCol = columns[0].key;\n const dupRowCount = groups.reduce((acc, g) => acc + g.rowIndices.length, 0);\n\n return (\n <div className=\"border border-amber-200 rounded-lg bg-amber-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-1\">Duplicate entries detected</p>\n <p className=\"text-xs text-gray-600 mb-3\">\n {groups.length} {groups.length === 1 ? 'value appeared' : 'values appeared'} more than once.\n Each is merged into a single line with its quantity summed — review before proceeding.\n </p>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-3 bg-white max-h-80 overflow-y-auto\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {columns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">\n {col.title.replace(' *', '')}\n </th>\n ))}\n <th className=\"px-2 py-1 text-right text-gray-500 font-medium\">Merged from</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {groups.map(g => (\n <tr key={g.key.toUpperCase()}>\n {columns.map(col => {\n if (col.key === keyCol) {\n return (\n <td key={col.key} className=\"px-2 py-1 font-mono font-medium text-gray-800\">{g.key}</td>\n );\n }\n const nums = g.rowIndices\n .map(ri => (rows[ri]?.[col.key] ?? '').trim())\n .filter(v => v !== '' && Number.isFinite(Number(v)))\n .map(Number);\n if (nums.length === 0) {\n return <td key={col.key} className=\"px-2 py-1 text-gray-300\">—</td>;\n }\n const sum = nums.reduce((s, n) => s + n, 0);\n return (\n <td key={col.key} className=\"px-2 py-1 font-mono text-gray-700\">\n {nums.length > 1 && (\n <span className=\"text-gray-400\">{nums.join(' + ')} = </span>\n )}\n <span className=\"font-semibold text-gray-800\">{sum.toLocaleString()}</span>\n </td>\n );\n })}\n <td className=\"px-2 py-1 text-right text-gray-500\">{g.rowIndices.length} rows</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-600\">\n {dupRowCount} duplicate rows → {groups.length} merged line{groups.length === 1 ? '' : 's'}\n </span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={onConfirm}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Main Component ──\n\n/**\n * Spreadsheet-style bulk entry surface: type, paste, or upload a CSV/TSV, with\n * automatic column auto-mapping (with a manual mapping fallback) and duplicate\n * de-duplication (keep-first/last/all/skip, or summed merge in `mergeDuplicates`\n * mode). Purely presentational — owns local grid/CSV state and reports the\n * resolved rows via `onImport`; it does no fetching, auth, or persistence.\n *\n * Rows are de-duplicated and merged on the FIRST column (the \"key\"). Declare a\n * column's `kind` (`price`/`qty`) to opt it into CSV auto-detection and the\n * totals strip.\n */\nexport default function BulkImportGrid({ columns, onImport, description, mergeDuplicates = false }: BulkImportGridProps) {\n const [gridData, setGridData] = useState<string[][]>(() =>\n Array.from({ length: 15 }, () => Array(columns.length).fill(''))\n );\n const [importing, setImporting] = useState(false);\n const [error, setError] = useState('');\n const [pendingCSV, setPendingCSV] = useState<string[][] | null>(null);\n const [dupReview, setDupReview] = useState<{\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n resolutions: Record<string, DupResolution>;\n } | null>(null);\n const [mergeReview, setMergeReview] = useState<{\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n } | null>(null);\n\n const colCount = columns.length;\n const requiredLabel = columns[0]?.title?.replace(' *', '') || 'value';\n\n // Stats\n const filledRows = gridData.filter(row => row[0]?.trim());\n const filledCount = filledRows.length;\n const totals: Record<string, number> = {};\n for (let ci = 1; ci < columns.length; ci++) {\n if (colKind(columns[ci], ci) === 'text') continue;\n let sum = 0;\n for (const row of filledRows) {\n const v = parseFloat(cleanNumber(row[ci] || ''));\n if (!isNaN(v)) sum += v;\n }\n if (sum > 0) totals[columns[ci].key] = sum;\n }\n\n const gridColumns: GridColumn[] = columns.map(c => ({\n key: c.key,\n title: c.title,\n width: c.width,\n }));\n\n const loadDataIntoGrid = useCallback((data: string[][]) => {\n const cleaned = data.map(row => {\n const r = [...row];\n while (r.length < colCount) r.push('');\n return r.slice(0, colCount).map((cell, i) => {\n const kind = colKind(columns[i], i);\n return kind === 'price' || kind === 'qty' ? cleanNumber(cell) : cell;\n });\n });\n // Pad to minimum rows, and leave a spare line under a CSV long enough to\n // fill them — a paste on top of the upload needs somewhere to land too.\n while (cleaned.length < 15) cleaned.push(Array(colCount).fill(''));\n setGridData(withSpareRow(cleaned, colCount));\n }, [colCount, columns]);\n\n const loadCSVFile = (file: File) => {\n const reader = new FileReader();\n reader.onload = (ev) => {\n const text = (ev.target?.result as string) || '';\n const parsed = text.split('\\n').map(l => l.trim()).filter(Boolean).map(parseCSVLine);\n if (parsed.length === 0) return;\n\n const mapping = autoMapColumns(parsed, columns);\n if (mapping) {\n const mapped = parsed.map(row => columns.map((_, ti) => mapping[ti] >= 0 ? (row[mapping[ti]] || '') : ''));\n loadDataIntoGrid(mapped);\n } else {\n setPendingCSV(parsed);\n }\n };\n reader.readAsText(file);\n };\n\n // The whole panel is the drop target — a CSV dragged from the desktop lands\n // anywhere on it — and the \"Upload CSV\" button opens the same intake's dialog.\n const csvIntake = useFileIntake({\n accept: '.csv,.tsv,.txt', acceptHint: 'CSV · TSV · TXT', multiple: false,\n onAccept: ([file]) => loadCSVFile(file),\n });\n\n const handleMappingConfirm = (mapping: number[]) => {\n if (!pendingCSV) return;\n const mapped = pendingCSV.map(row => columns.map((_, ti) => mapping[ti] >= 0 ? (row[mapping[ti]] || '') : ''));\n loadDataIntoGrid(mapped);\n setPendingCSV(null);\n };\n\n const runImport = async (rows: Record<string, string>[]) => {\n setImporting(true);\n try { await onImport(rows); } catch { setError('Import failed.'); }\n setImporting(false);\n };\n\n const handleImport = async () => {\n const rows: Record<string, string>[] = gridData\n .filter(row => row[0]?.trim())\n .map(row => {\n const obj: Record<string, string> = {};\n columns.forEach((col, i) => {\n const val = row[i]?.trim() || '';\n // Currency symbols and thousands separators are noise in a number and\n // content in a description — strip them only where they're noise.\n const kind = colKind(col, i);\n obj[col.key] = kind === 'price' || kind === 'qty' ? cleanNumber(val) : val;\n });\n return obj;\n });\n if (rows.length === 0) { setError(`Enter at least one ${requiredLabel.toLowerCase()}.`); return; }\n setError('');\n\n const keyCol = columns[0].key;\n const groups = findDuplicateKeys(rows, keyCol);\n if (groups.length > 0) {\n if (mergeDuplicates) {\n setMergeReview({ rows, groups });\n } else {\n const resolutions: Record<string, DupResolution> = {};\n for (const g of groups) resolutions[g.key.toUpperCase()] = 'first';\n setDupReview({ rows, groups, resolutions });\n }\n return;\n }\n await runImport(rows);\n };\n\n const handleMergeConfirm = async () => {\n if (!mergeReview) return;\n const merged = mergeDuplicateRows(mergeReview.rows, mergeReview.groups, columns);\n setMergeReview(null);\n await runImport(merged);\n };\n\n const handleDupConfirm = async () => {\n if (!dupReview) return;\n const { rows, groups, resolutions } = dupReview;\n const drop = new Set<number>();\n for (const g of groups) {\n const choice = resolutions[g.key.toUpperCase()] || 'first';\n const idx = g.rowIndices;\n if (choice === 'first') {\n for (let i = 1; i < idx.length; i++) drop.add(idx[i]);\n } else if (choice === 'last') {\n for (let i = 0; i < idx.length - 1; i++) drop.add(idx[i]);\n } else if (choice === 'skip') {\n for (const j of idx) drop.add(j);\n }\n // 'all' keeps every occurrence — the rows import as separate lines\n }\n const filtered = rows.filter((_, i) => !drop.has(i));\n setDupReview(null);\n if (filtered.length === 0) { setError('All rows skipped.'); return; }\n await runImport(filtered);\n };\n\n const handleClear = () => {\n setGridData(Array.from({ length: 15 }, () => Array(colCount).fill('')));\n };\n\n const descText = description || `Paste from spreadsheets, type directly, or upload a CSV. Rows don't need to be in order — they'll be matched. Values not in the list will be added to the end. Fields left blank will not be affected.`;\n\n return (\n <div\n {...csvIntake.zoneProps}\n className={[\n 'border rounded-lg bg-gray-50 mb-3 overflow-hidden transition-colors',\n csvIntake.dragOver ? 'border-dashed border-blue-500 bg-blue-50' : 'border-gray-200',\n ].join(' ')}\n >\n <div className=\"px-4 pt-3 pb-2 flex items-center justify-between\">\n <p className=\"text-xs text-gray-500\">\n {descText}\n <span className=\"text-gray-400 ml-1\">({filledCount} lines{Object.keys(totals).length > 0 && ' · '}{Object.entries(totals).map(([k, v]) => {\n const col = columns.find(c => c.key === k);\n const label = col?.title?.replace(' *', '') || k;\n const isPrice = col ? colKind(col, columns.indexOf(col)) === 'price' : false;\n return `${label}: ${isPrice ? v.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : v.toLocaleString()}`;\n }).join(' · ')})</span>\n </p>\n <div className=\"flex items-center gap-2\">\n {filledCount > 0 && (\n <button type=\"button\" onClick={handleClear} className=\"text-gray-400 hover:text-gray-600 text-xs\">Clear</button>\n )}\n <input {...csvIntake.inputProps} />\n <button type=\"button\" onClick={csvIntake.open}\n className=\"text-blue-600 border border-blue-200 bg-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-50 hover:border-blue-300\">Upload CSV</button>\n <button type=\"button\" onClick={handleImport} disabled={importing || filledCount === 0}\n className=\"text-green-600 border border-green-200 bg-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-green-50 hover:border-green-300 disabled:opacity-50\">\n {importing ? 'Importing...' : `Import ${filledCount} Lines`}\n </button>\n </div>\n </div>\n\n {pendingCSV && (\n <div className=\"px-4 pb-2\">\n <ColumnMapper\n csvPreview={pendingCSV}\n targetColumns={columns}\n onConfirm={handleMappingConfirm}\n onCancel={() => setPendingCSV(null)}\n />\n </div>\n )}\n\n {dupReview && (\n <div className=\"px-4 pb-2\">\n <DuplicateReview\n rows={dupReview.rows}\n groups={dupReview.groups}\n columns={columns}\n resolutions={dupReview.resolutions}\n onResolutionChange={(dupKey, choice) =>\n setDupReview(prev => prev ? { ...prev, resolutions: { ...prev.resolutions, [dupKey]: choice } } : prev)\n }\n onConfirm={handleDupConfirm}\n onCancel={() => setDupReview(null)}\n />\n </div>\n )}\n\n {mergeReview && (\n <div className=\"px-4 pb-2\">\n <MergeReview\n rows={mergeReview.rows}\n groups={mergeReview.groups}\n columns={columns}\n onConfirm={handleMergeConfirm}\n onCancel={() => setMergeReview(null)}\n />\n </div>\n )}\n\n <EditableGrid columns={gridColumns} data={gridData} onChange={setGridData} />\n <FileIntakeAlert rejections={csvIntake.rejections} className=\"px-4 py-1\" />\n {error && <p className=\"text-xs text-red-600 px-4 py-1\">{error}</p>}\n </div>\n );\n}\n","/**\n * Server connectivity indicator for the system tray.\n *\n * Renders a small globe icon coloured by the result of polling a\n * consumer-supplied health check. Click the icon to open a popover with\n * detailed connection info — server host, latency, last successful ping,\n * signed-in user, app/build version, browser network state.\n *\n * green — last poll succeeded\n * amber — initial check still in flight\n * red — last poll failed (network down, server down, timeout,\n * or non-2xx response). Pulses to draw attention.\n *\n * Polls every `pollMs` (default 15 s). The default health check applies a\n * `requestTimeoutMs` (default 5 s) per-request timeout via AbortController;\n * a custom `healthCheck` owns its own timeout. Latency is captured around\n * each poll and shown live in the popover.\n *\n * Product-agnostic: the shell never hardcodes an endpoint, auth context, or\n * app version. The consumer injects the health check, the signed-in user's\n * display fields, and the build label via props (a thin per-app wrapper).\n */\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { VERSION } from '../version';\nimport { onOverlayOpen } from './overlayEvents';\nimport { Z_LAYERS } from './zLayers';\n\nconst DEFAULT_POLL_MS = 15_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 5_000;\n\ntype Status = 'checking' | 'connected' | 'disconnected';\n\n/** Result of a single health poll. `latencyMs` is optional; when omitted on\n * an ok result the indicator simply shows no latency for that poll. */\nexport interface HealthCheckResult {\n ok: boolean;\n latencyMs?: number;\n}\n\n/** Display fields for the signed-in user shown in the popover's Session\n * section. All optional — the indicator derives a sensible name and hides\n * the Role row when `role` is empty. Pass `null`/`undefined` for \"not\n * signed in\". */\nexport interface ServerStatusUser {\n name?: string;\n email?: string;\n /** Secondary label for the Role row (e.g. group names, portal, company).\n * Hidden when empty. */\n role?: string;\n}\n\nexport interface ServerStatusIndicatorProps {\n /**\n * Performs one health poll and resolves with the outcome. The shell calls\n * this on mount and on every interval tick. A custom implementation owns\n * its own timeout/abort. When omitted, the indicator polls `healthUrl`\n * (default `/api/health/`) with a `requestTimeoutMs` AbortController.\n */\n healthCheck?: () => Promise<HealthCheckResult>;\n /** URL used by the built-in fetcher when no `healthCheck` is supplied. */\n healthUrl?: string;\n /** Poll interval in ms. Default 15 000. */\n pollMs?: number;\n /** Per-request timeout for the built-in fetcher, in ms. Default 5 000. */\n requestTimeoutMs?: number;\n /** Signed-in user's display fields for the Session section. */\n user?: ServerStatusUser | null;\n /** Build/version label for the Build section. Defaults to the shell's own\n * package version. Pass the consuming app's version here. */\n version?: string;\n}\n\nfunction timeAgo(date: Date | null): string {\n if (!date) return '—';\n const diff = Math.max(0, Date.now() - date.getTime());\n if (diff < 1500) return 'just now';\n if (diff < 60_000) return `${Math.round(diff / 1000)}s ago`;\n if (diff < 3_600_000) return `${Math.round(diff / 60_000)}m ago`;\n return `${Math.round(diff / 3_600_000)}h ago`;\n}\n\n/**\n * System-tray globe that polls a health check and exposes connection details\n * in a click-to-open popover. Drop into a taskbar tray alongside the\n * notification bell; supply `healthCheck` (or `healthUrl`), `user`, and\n * `version` via a thin per-app wrapper.\n */\nexport default function ServerStatusIndicator({\n healthCheck,\n healthUrl = '/api/health/',\n pollMs = DEFAULT_POLL_MS,\n requestTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS,\n user,\n version = VERSION,\n}: ServerStatusIndicatorProps) {\n const [status, setStatus] = useState<Status>('checking');\n const [lastOkAt, setLastOkAt] = useState<Date | null>(null);\n const [lastFailAt, setLastFailAt] = useState<Date | null>(null);\n const [lastLatencyMs, setLastLatencyMs] = useState<number | null>(null);\n const [browserOnline, setBrowserOnline] = useState<boolean>(navigator.onLine);\n const [open, setOpen] = useState(false);\n const [popPos, setPopPos] = useState<{ left: number; top: number }>({ left: 0, top: 0 });\n // Tick state forces a re-render once per second while the popover is\n // open so the \"5s ago / 12s ago\" relative timestamps stay live.\n const [, setTick] = useState(0);\n const cancelRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popRef = useRef<HTMLDivElement>(null);\n\n // Keep the latest health-check props in a ref so the polling effect's\n // dependency list stays stable — a fresh inline `healthCheck` on every\n // render must not tear down and restart the interval each time.\n const healthCheckRef = useRef(healthCheck);\n const healthUrlRef = useRef(healthUrl);\n const requestTimeoutRef = useRef(requestTimeoutMs);\n healthCheckRef.current = healthCheck;\n healthUrlRef.current = healthUrl;\n requestTimeoutRef.current = requestTimeoutMs;\n\n const ping = useCallback(async () => {\n const t0 = performance.now();\n try {\n let result: HealthCheckResult;\n if (healthCheckRef.current) {\n result = await healthCheckRef.current();\n } else {\n // Built-in fetcher: GET the health URL with a per-request timeout.\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), requestTimeoutRef.current);\n try {\n const res = await fetch(healthUrlRef.current, {\n method: 'GET',\n cache: 'no-store',\n signal: ctrl.signal,\n });\n result = { ok: res.ok, latencyMs: Math.round(performance.now() - t0) };\n } finally {\n clearTimeout(timer);\n }\n }\n if (cancelRef.current) return;\n if (result.ok) {\n setStatus('connected');\n setLastOkAt(new Date());\n setLastLatencyMs(result.latencyMs ?? Math.round(performance.now() - t0));\n } else {\n setStatus('disconnected');\n setLastFailAt(new Date());\n }\n } catch {\n if (!cancelRef.current) {\n setStatus('disconnected');\n setLastFailAt(new Date());\n }\n }\n }, []);\n\n useEffect(() => {\n cancelRef.current = false;\n // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional mount-time health poll; ping() sets state only in async fetch/catch continuations (post-commit), and the immediate-on-mount + interval timing must be preserved\n ping();\n const id = setInterval(ping, pollMs);\n return () => {\n cancelRef.current = true;\n clearInterval(id);\n };\n }, [ping, pollMs]);\n\n // Browser-level network events — independent signal from the API\n // poll so the popover can distinguish \"you're offline\" from \"the\n // server is down\".\n useEffect(() => {\n const onOnline = () => setBrowserOnline(true);\n const onOffline = () => setBrowserOnline(false);\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n return () => {\n window.removeEventListener('online', onOnline);\n window.removeEventListener('offline', onOffline);\n };\n }, []);\n\n // Keep relative timestamps fresh while the popover is open.\n useEffect(() => {\n if (!open) return;\n const id = setInterval(() => setTick(t => t + 1), 1000);\n return () => clearInterval(id);\n }, [open]);\n\n // Anchor the popover horizontally centred on the icon. Vertically,\n // flip to ABOVE the icon when the icon sits in the lower half of\n // the viewport (taskbar-at-bottom case) — otherwise the popover\n // would extend below the screen edge or be hidden by the taskbar.\n // Recompute on resize and once after the popover renders, so we\n // can use its actual measured height instead of an estimate.\n const placePopover = useCallback(() => {\n if (!buttonRef.current) return;\n const r = buttonRef.current.getBoundingClientRect();\n const popW = 320;\n // Estimated until the popover mounts; we re-place once we have\n // the real measurement (see useLayoutEffect below). 320 is the\n // typical popover height for a connected session.\n const popH = popRef.current?.offsetHeight || 320;\n\n // Horizontal: centre on the icon's midpoint, clamp to viewport\n // so the popover never bleeds off either edge.\n const iconCenterX = r.left + r.width / 2;\n const left = Math.max(8, Math.min(window.innerWidth - popW - 8, iconCenterX - popW / 2));\n\n // Vertical: flip above when the icon is in the lower half of\n // the viewport (covers the taskbar-at-bottom layout that's the\n // default in this app). The 6 px gap matches the bell's spacing.\n const iconCenterY = r.top + r.height / 2;\n const popAbove = iconCenterY > window.innerHeight / 2;\n const top = popAbove\n ? Math.max(8, r.top - popH - 6)\n : r.bottom + 6;\n\n setPopPos({ left, top });\n }, []);\n\n useEffect(() => {\n if (!open) return;\n placePopover();\n window.addEventListener('resize', placePopover);\n return () => window.removeEventListener('resize', placePopover);\n }, [open, placePopover]);\n\n // Once the popover actually mounts we know its real height — re-place\n // synchronously before paint so the popover never visibly jumps from\n // the height estimate to the measured value.\n useLayoutEffect(() => {\n if (open && popRef.current) placePopover();\n }, [open, placePopover]);\n\n // Click-outside + Escape closes the popover, and so does an overlay opening:\n // the card is on the popup layer, above the overlay (see `overlayEvents.ts`).\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node;\n if (popRef.current?.contains(t)) return;\n if (buttonRef.current?.contains(t)) return;\n setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onDown);\n window.addEventListener('keydown', onKey);\n const offOverlay = onOverlayOpen(() => setOpen(false));\n return () => {\n window.removeEventListener('mousedown', onDown);\n window.removeEventListener('keydown', onKey);\n offOverlay();\n };\n }, [open]);\n\n const colour =\n status === 'connected' ? '#16a34a' /* green-600 */\n : status === 'disconnected' ? '#dc2626' /* red-600 */\n : '#9ca3af'; /* gray-400 */\n const label =\n status === 'connected' ? 'Connected'\n : status === 'disconnected' ? 'Disconnected'\n : 'Checking…';\n const dotClass =\n status === 'connected' ? 'bg-green-500'\n : status === 'disconnected' ? 'bg-red-500'\n : 'bg-gray-400';\n\n const userName =\n user\n ? (user.name?.trim() || user.email || '—')\n : 'Not signed in';\n const userRole = user?.role || '';\n\n return (\n <>\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={() => setOpen(o => !o)}\n className={`shrink-0 inline-flex items-center justify-center rounded-md p-2 transition-colors hover:bg-white/20 ${\n status === 'disconnected' && !open ? 'animate-pulse' : ''\n }`}\n title={`${label}${lastOkAt ? ` · last ok ${lastOkAt.toLocaleTimeString()}` : ''}`}\n aria-label={label}\n aria-expanded={open}\n >\n {/* Globe — meridian + equator strokes coloured by connection state. */}\n {/* h-5 matches the notification bell so all tray icons get the same\n hover pill. */}\n <svg className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke={colour}\n strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M2 12h20\" />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n </button>\n\n {open && createPortal(\n <div\n ref={popRef}\n role=\"dialog\"\n aria-label=\"Server connection details\"\n style={{ position: 'fixed', left: popPos.left, top: popPos.top, width: 320, zIndex: Z_LAYERS.popup }}\n className=\"rounded-lg border border-gray-200 bg-white shadow-lg overflow-hidden text-gray-800\"\n >\n {/* Header — status pill + headline timing. */}\n <div className=\"px-4 py-3 border-b border-gray-100 bg-gray-50/60\">\n <div className=\"flex items-center gap-2\">\n <span className={`inline-block h-2 w-2 rounded-full ${dotClass} ${status === 'disconnected' ? 'animate-pulse' : ''}`} />\n <span className=\"text-sm font-semibold text-gray-900\">{label}</span>\n {status === 'connected' && lastLatencyMs != null && (\n <span className=\"ml-auto text-[11px] text-gray-500 tabular-nums\">{lastLatencyMs} ms</span>\n )}\n </div>\n <p className=\"mt-1 text-[11px] text-gray-500\">\n {status === 'connected' && lastOkAt && <>Last poll {timeAgo(lastOkAt)}.</>}\n {status === 'disconnected' && lastFailAt && <>Last failure {timeAgo(lastFailAt)}.</>}\n {status === 'checking' && <>First poll in flight…</>}\n </p>\n </div>\n\n {/* Detail rows. Two-column grid: label / value, label is\n fixed width so values align tidily. */}\n <dl className=\"px-4 py-3 text-[12px] grid grid-cols-[88px_1fr] gap-x-3 gap-y-1.5\">\n <dt className=\"text-gray-500\">Server</dt>\n <dd className=\"font-mono text-gray-900 truncate\" title={window.location.origin}>{window.location.host}</dd>\n\n <dt className=\"text-gray-500\">Protocol</dt>\n <dd className=\"text-gray-900\">{window.location.protocol.replace(':', '').toUpperCase()}</dd>\n\n <dt className=\"text-gray-500\">Browser</dt>\n <dd className={browserOnline ? 'text-gray-900' : 'text-red-600 font-medium'}>\n {browserOnline ? 'Online' : 'Offline'}\n </dd>\n\n <dt className=\"text-gray-500\">Last OK</dt>\n <dd className=\"text-gray-900\">\n {lastOkAt ? (\n <>\n <span className=\"tabular-nums\">{lastOkAt.toLocaleTimeString()}</span>\n <span className=\"text-gray-400 ml-1\">· {timeAgo(lastOkAt)}</span>\n </>\n ) : '—'}\n </dd>\n\n {lastFailAt && (\n <>\n <dt className=\"text-gray-500\">Last fail</dt>\n <dd className=\"text-gray-900\">\n <span className=\"tabular-nums\">{lastFailAt.toLocaleTimeString()}</span>\n <span className=\"text-gray-400 ml-1\">· {timeAgo(lastFailAt)}</span>\n </dd>\n </>\n )}\n\n <dt className=\"text-gray-500\">Latency</dt>\n <dd className=\"text-gray-900 tabular-nums\">\n {lastLatencyMs != null ? `${lastLatencyMs} ms` : '—'}\n </dd>\n\n <dt className=\"text-gray-500\">Poll</dt>\n <dd className=\"text-gray-900\">every {Math.round(pollMs / 1000)} s</dd>\n\n <dt className=\"text-gray-500 mt-2 col-span-2 border-t border-gray-100 pt-2 text-[10px] uppercase tracking-wide font-semibold\">Session</dt>\n\n <dt className=\"text-gray-500\">User</dt>\n <dd className=\"text-gray-900 truncate\" title={userName}>{userName}</dd>\n\n {userRole && (\n <>\n <dt className=\"text-gray-500\">Role</dt>\n <dd className=\"text-gray-900 truncate\" title={userRole}>{userRole}</dd>\n </>\n )}\n\n <dt className=\"text-gray-500 mt-2 col-span-2 border-t border-gray-100 pt-2 text-[10px] uppercase tracking-wide font-semibold\">Build</dt>\n\n <dt className=\"text-gray-500\">App</dt>\n <dd className=\"font-mono text-gray-900 text-[11px] truncate\" title={version}>{version || '—'}</dd>\n\n <dt className=\"text-gray-500\">UA</dt>\n <dd className=\"text-gray-900 text-[11px] truncate\" title={navigator.userAgent}>\n {navigator.userAgent.split(' ').slice(-2).join(' ')}\n </dd>\n </dl>\n\n {/* Footer — manual refresh. */}\n <div className=\"px-4 py-2 border-t border-gray-100 bg-gray-50/60 flex items-center justify-between\">\n <span className=\"text-[10px] text-gray-400\">Click ↻ to ping now</span>\n <button\n type=\"button\"\n onClick={() => { setStatus('checking'); ping(); }}\n disabled={status === 'checking'}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-blue-600 hover:text-blue-800 disabled:opacity-50\"\n >\n <svg className=\"h-3 w-3\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4 4v5h5M20 20v-5h-5M5.5 9A7 7 0 0 1 17 6.5M18.5 15A7 7 0 0 1 7 17.5\" />\n </svg>\n Refresh\n </button>\n </div>\n </div>,\n document.body,\n )}\n </>\n );\n}\n","/**\n * ChangePasswordForm — a self-contained \"change my password\" form: three\n * password fields (current / new / confirm), client-side validation, inline\n * error display, and submit/loading state. It owns all of that, but stays\n * product-agnostic: it knows nothing about how a password is actually changed.\n *\n * The host injects that via `onSubmit(oldPassword, newPassword)`, which it runs\n * on a valid submit. If `onSubmit` rejects, its `Error.message` is shown inline\n * (so a wrapper can surface a field-specific API message there). On success the\n * form shows a confirmation screen with a Done button (the original admin\n * behaviour) and fires `onSuccess` when Done is clicked. Set\n * `confirmOnSuccess={false}` to skip the screen and call `onSuccess`\n * immediately instead (the customer/supplier behaviour).\n */\nimport { useState, type FormEvent } from 'react';\nimport FormField from '../forms/FormField';\nimport Input from '../forms/Input';\nimport Button from '../forms/Button';\nimport { CMD_ENTER } from './Kbd';\n\nexport interface ChangePasswordFormProps {\n /**\n * Perform the password change. Resolve to indicate success; reject with an\n * `Error` whose `message` becomes the inline error shown to the user.\n */\n onSubmit: (oldPassword: string, newPassword: string) => Promise<void>;\n /** Called after a successful change — on Done click, or immediately when\n * `confirmOnSuccess` is false. */\n onSuccess?: () => void;\n /**\n * Show a success confirmation screen with a Done button after a successful\n * change. When false, `onSuccess` fires immediately on success. Default true.\n */\n confirmOnSuccess?: boolean;\n /** Minimum length required for the new password. Default 8. */\n minLength?: number;\n /** Label for the submit button. Default 'Change Password'. */\n submitLabel?: string;\n /** Label for the Done button on the success screen. Default 'Done'. */\n doneLabel?: string;\n}\n\n/**\n * Product-agnostic change-password form. The host supplies `onSubmit` to do the\n * actual change (e.g. call an API then re-authenticate).\n */\nexport default function ChangePasswordForm({\n onSubmit,\n onSuccess,\n confirmOnSuccess = true,\n minLength = 8,\n submitLabel = 'Change Password',\n doneLabel = 'Done',\n}: ChangePasswordFormProps) {\n const [oldPassword, setOldPassword] = useState('');\n const [newPassword, setNewPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [error, setError] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [success, setSuccess] = useState(false);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!oldPassword) { setError('Current password is required.'); return; }\n if (newPassword.length < minLength) { setError(`New password must be at least ${minLength} characters.`); return; }\n if (newPassword !== confirmPassword) { setError('Passwords do not match.'); return; }\n setError('');\n setSubmitting(true);\n try {\n await onSubmit(oldPassword, newPassword);\n if (confirmOnSuccess) {\n setSuccess(true);\n } else {\n onSuccess?.();\n }\n } catch (err) {\n setError(err instanceof Error && err.message ? err.message : 'Failed to change password.');\n } finally {\n setSubmitting(false);\n }\n };\n\n if (success) {\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-md bg-green-50 px-4 py-3 flex items-start gap-3\">\n <svg className=\"h-5 w-5 text-green-600 shrink-0 mt-0.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <p className=\"text-sm font-medium text-green-800\">Your password has been changed successfully.</p>\n </div>\n <div className=\"flex justify-end pt-2 border-t border-gray-200\">\n <Button variant=\"primary\" onClick={() => onSuccess?.()}>{doneLabel}</Button>\n </div>\n </div>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <FormField label=\"Current Password\" required>\n <Input type=\"password\" value={oldPassword} onChange={e => setOldPassword(e.target.value)} required />\n </FormField>\n <FormField label=\"New Password\" required>\n <Input type=\"password\" value={newPassword} onChange={e => setNewPassword(e.target.value)} required minLength={minLength} />\n </FormField>\n <FormField label=\"Confirm Password\" required>\n <Input type=\"password\" value={confirmPassword} onChange={e => setConfirmPassword(e.target.value)} required />\n </FormField>\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n <div className=\"flex justify-end pt-2 border-t border-gray-200\">\n <Button type=\"submit\" variant=\"primary\" loading={submitting}>\n {submitting ? 'Changing...' : submitLabel}\n <kbd className=\"rounded border border-blue-400/50 bg-blue-500/30 px-1.5 py-0.5 text-[10px] font-medium\">{CMD_ENTER}</kbd>\n </Button>\n </div>\n </form>\n );\n}\n","/**\n * Give up waiting on a promise that may never settle.\n *\n * Written for PdfActionButton: the Preview window opens on a \"LOADING PDF\"\n * placeholder and swaps in the document when the consumer's `fetchPdf()`\n * resolves. If that promise never settles — a connection torn down mid-flight,\n * a worker killed, a request the browser abandoned — the placeholder stays on\n * screen for ever, so a document that is merely slow and one that is genuinely\n * dead look identical to the person waiting. That ambiguity is what produced\n * report BG#00511, where the only evidence available afterwards was the user's\n * memory of what the screen showed.\n *\n * The timeout resolves to {@link TIMED_OUT} rather than rejecting, because a\n * timeout is not an error the consumer raised — it is this side deciding to\n * stop waiting, and the caller needs to tell the two apart to say something\n * accurate about which happened.\n *\n * The losing promise is NOT cancelled. The shell is transport-agnostic and\n * never owns the request, so there is nothing here to abort; `work` may still\n * settle later and its result is simply dropped. Consumers that need real\n * cancellation should wire an AbortController into their own `fetchPdf`.\n */\n\n/** Returned in place of the value when `work` did not settle in time. */\nexport const TIMED_OUT: unique symbol = Symbol('react-os-shell:timed-out');\n\nexport type MaybeTimedOut<T> = T | typeof TIMED_OUT;\n\n/**\n * Resolve `work`, or {@link TIMED_OUT} if it takes longer than `ms`.\n *\n * A non-finite or non-positive `ms` disables the timeout and awaits `work`\n * unchanged, so a consumer can opt out with `0` or `Infinity` without the\n * caller branching. Rejections propagate untouched — this only ever converts\n * *silence* into a value, never a failure into a success.\n */\nexport async function withTimeout<T>(work: Promise<T>, ms: number): Promise<MaybeTimedOut<T>> {\n if (!Number.isFinite(ms) || ms <= 0) return work;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n work,\n new Promise<typeof TIMED_OUT>(resolve => {\n timer = setTimeout(() => resolve(TIMED_OUT), ms);\n }),\n ]);\n } finally {\n // Always clear it: when `work` wins, an uncleared timer holds the event\n // loop open for the rest of the interval, which in Node turns a fast unit\n // test into a slow one and in a browser keeps a closure alive needlessly.\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { ReactNode } from 'react';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport { useWindowManager } from './WindowManager';\nimport { setPdfPreview } from '../apps/_previewStage';\nimport { withTimeout, TIMED_OUT } from './withTimeout';\nimport toast from './toast';\n\nexport interface PdfActionButtonProps {\n /**\n * Resolves the PDF bytes. The consumer owns the transport (axios/fetch/etc.)\n * and any error reporting; returning `null` aborts the action without the\n * shell surfacing a toast (the consumer is expected to have explained the\n * failure already).\n */\n fetchPdf: () => Promise<Blob | null>;\n /** Filename used for download and shown in the Preview window (e.g. \"Invoice_CI#1234.pdf\"). */\n filename: string;\n /** Button label. */\n label?: string;\n /** Override the default button styling. */\n className?: string;\n /** Disabled state. */\n disabled?: boolean;\n /**\n * Optional email handler. When supplied, a \"Send by Email\" item (with a\n * divider above it) is added to the menu and an Email button is wired into\n * the Preview window — both invoked with the already-fetched blob so the\n * consumer can hand it to its own composer. Omit it to hide email entirely.\n */\n onEmail?: (blob: Blob) => void;\n /**\n * Optional notification fired after a Preview window has been opened with the\n * resolved PDF (e.g. to drop a Recent Documents shortcut). Receives the\n * filename so the consumer can label the entry.\n */\n onPreviewOpened?: (filename: string) => void;\n /**\n * How to show the Preview. Defaults to the window manager's\n * `openPage('/preview')`; a routed app without windows (no\n * `WindowManagerProvider`, so that `openPage` does nothing) passes its own —\n * a tab, a route or an overlay that mounts the shell's `Preview`.\n *\n * It is called where `openPage` would be: after the \"LOADING PDF\"\n * placeholder is staged and before the fetch, so the viewer opens on the\n * placeholder and swaps the document in itself. `onPreviewOpened` is too\n * late for this: it fires once the document has arrived, so nothing would\n * show while it loads.\n */\n openPreview?: () => void;\n /** Optional leading icon override for the button (defaults to a document glyph). */\n icon?: ReactNode;\n /**\n * How long to wait for `fetchPdf()` before giving up, in milliseconds.\n * Defaults to 30 seconds. Pass `0` (or `Infinity`) to wait for ever.\n *\n * This exists because a promise that never settles used to leave the Preview\n * window on its \"LOADING PDF\" placeholder indefinitely, so a slow document\n * and a dead one were indistinguishable to the person waiting. Timing out\n * turns that silence into a stated failure. The request itself is not\n * cancelled — the consumer owns the transport (see `withTimeout`).\n */\n timeoutMs?: number;\n}\n\n/** Long enough that a genuinely slow document still arrives (the slowest\n * observed in production was ~4 s through the live stack), short enough that\n * nobody sits in front of a dead placeholder wondering. */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nconst DEFAULT_BUTTON_CLASS =\n 'inline-flex items-center gap-1.5 bg-white text-gray-700 border border-gray-300 px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-gray-50 disabled:opacity-50';\n\nconst DocumentIcon = (\n <svg className=\"h-4 w-4 text-gray-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z\" /></svg>\n);\n\n/**\n * A dropdown PDF button that can Preview the document in the shell's Preview\n * window, Download it, or (when `onEmail` is supplied) hand the bytes to a\n * consumer-provided email composer.\n *\n * The shell is transport-agnostic: it never fetches the PDF itself. The\n * consumer injects a `fetchPdf()` resolver (typically wrapping its own HTTP\n * client) and the shell handles object-URL lifecycle, download, the loading\n * placeholder in Preview, and success toasts. App concerns (email composer,\n * recent-documents logging, where the Preview opens) are lifted to the\n * optional `onEmail` / `onPreviewOpened` / `openPreview` callbacks.\n */\nexport default function PdfActionButton({\n fetchPdf,\n filename,\n label = 'PDF',\n className,\n disabled,\n onEmail,\n onPreviewOpened,\n openPreview,\n icon,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n}: PdfActionButtonProps) {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const btnRef = useRef<HTMLButtonElement>(null);\n const [menuPos, setMenuPos] = useState<{ left: number; top: number }>({ left: 0, top: 0 });\n const { openPage } = useWindowManager();\n\n useEffect(() => {\n if (open && btnRef.current) {\n const rect = btnRef.current.getBoundingClientRect();\n setMenuPos({ left: rect.left, top: rect.bottom + 4 });\n }\n }, [open]);\n\n // Wrap the consumer's resolver so the spinner reflects in-flight fetches no\n // matter which action triggered them.\n const resolvePdf = async (): Promise<Blob | null | typeof TIMED_OUT> => {\n setLoading(true);\n try {\n return await withTimeout(fetchPdf(), timeoutMs);\n } finally {\n setLoading(false);\n }\n };\n\n const handleDownload = async () => {\n setOpen(false);\n const blob = await resolvePdf();\n // `null` means the consumer already told the user why. A timeout is ours,\n // so it would otherwise vanish with no explanation at all.\n if (blob === TIMED_OUT) {\n toast.error(`${filename} took too long to load. Please try again.`);\n return;\n }\n if (!blob) return;\n const url = window.URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n window.URL.revokeObjectURL(url);\n toast.success(`${filename} downloaded.`);\n };\n\n const handlePreview = async () => {\n setOpen(false);\n // Open the viewer immediately with a loading placeholder, then swap in the\n // resolved PDF once the blob arrives (only updates this very window).\n const handle = setPdfPreview({ filename, converting: true, convertingMessage: 'LOADING PDF' });\n if (openPreview) openPreview();\n else openPage('/preview');\n const blob = await resolvePdf();\n // Two different failures, deliberately worded differently: \"took too long\"\n // means the fetch never settled and we stopped waiting, \"Failed to load\"\n // means it settled with nothing. Telling them apart on screen is what lets\n // someone reporting a problem say which one they saw.\n if (blob === TIMED_OUT) {\n handle.update({\n filename, converting: false,\n convertingMessage: 'This document took too long to load. Close this window and try again.',\n });\n return;\n }\n if (!blob) {\n handle.update({ filename, converting: false, convertingMessage: 'Failed to load PDF.' });\n return;\n }\n const url = window.URL.createObjectURL(blob);\n // Wire the Preview window's Email button to the same already-fetched blob.\n handle.update({ url, filename, ...(onEmail ? { onEmail: () => onEmail(blob) } : {}) });\n onPreviewOpened?.(filename);\n };\n\n const handleEmail = async () => {\n setOpen(false);\n const blob = await resolvePdf();\n // TIMED_OUT is a symbol, so it is truthy — a plain `!blob` check would hand\n // it to the consumer's composer as if it were the document.\n if (blob === TIMED_OUT) {\n toast.error(`${filename} took too long to load. Please try again.`);\n return;\n }\n if (!blob || !onEmail) return;\n onEmail(blob);\n };\n\n const btnCls = className || DEFAULT_BUTTON_CLASS;\n\n return (\n <>\n <button ref={btnRef} type=\"button\" onClick={() => setOpen(!open)} disabled={disabled || loading} className={btnCls} data-menu-toggle>\n {icon ?? DocumentIcon}\n {loading ? 'Loading...' : label}\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n </button>\n\n {open && createPortal(\n <PopupMenu style={menuPos} onClose={() => setOpen(false)} minWidth={180}>\n <PopupMenuItem onClick={handlePreview}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z\" /><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\" /></svg>\n Preview\n </PopupMenuItem>\n <PopupMenuItem onClick={handleDownload}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3\" /></svg>\n Download\n </PopupMenuItem>\n {onEmail && (\n <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={handleEmail}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\" /></svg>\n Send by Email\n </PopupMenuItem>\n </>\n )}\n </PopupMenu>,\n document.body\n )}\n </>\n );\n}\n","/**\n * Shell-side entity fetcher — used by <WindowManager> when the user opens an\n * entity window. The shell knows the endpoint string (from the registry\n * entry) and the entity ID; the consumer translates that into an HTTP call\n * (or a mock, or whatever).\n *\n * Without a provider, the shell will throw if any code path tries to fetch\n * an entity — this is by design: a host that registers entity windows MUST\n * also wire the fetcher, or the open-entity flow has nothing to call.\n */\nimport { createContext, useContext, type ReactNode } from 'react';\n\nexport type EntityFetcher = (endpoint: string, id: string) => Promise<any>;\n\nconst EntityFetcherContext = createContext<EntityFetcher | null>(null);\n\nexport function ShellEntityFetcherProvider({\n value,\n children,\n}: { value: EntityFetcher; children: ReactNode }) {\n return <EntityFetcherContext.Provider value={value}>{children}</EntityFetcherContext.Provider>;\n}\n\n/** Returns the consumer-supplied entity fetcher, or a stub that throws\n * on call. Components that fetch entities call this hook eagerly so any\n * misconfiguration surfaces synchronously rather than at click-time. */\nexport function useShellEntityFetcher(): EntityFetcher {\n const ctx = useContext(EntityFetcherContext);\n return ctx ?? ((endpoint: string) => {\n throw new Error(\n `react-os-shell: cannot fetch ${endpoint} — no <ShellEntityFetcherProvider> mounted. ` +\n `If your app registers entity windows, supply an entityFetcher.`\n );\n });\n}\n","import { useEffect } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Registers Alt+Shift+N (Windows) / Opt+Shift+N (Mac) hotkey to trigger a \"New\" action.\n * Uses e.code (physical key) to avoid locale/modifier character issues.\n * Only fires for the active (frontmost) window, mirroring useEditHotkey — without\n * the guard every mounted window's hook answered one keypress at once, so with\n * two or more list windows open Alt+Shift+N fired \"New\" in all of them.\n */\nexport default function useNewHotkey(callback: () => void) {\n const isActive = useModalActive();\n useEffect(() => {\n if (!isActive) return;\n const handler = (e: KeyboardEvent) => {\n const isN = e.code === 'KeyN' || e.key === 'N' || e.key === 'n';\n if (e.altKey && e.shiftKey && isN && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n callback();\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [callback, isActive]);\n}\n","import { useEffect } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Registers Alt+Shift+E (Windows) / Opt+Shift+E (Mac) hotkey to trigger an \"Edit\" action.\n * Uses e.code (physical key) to avoid locale/modifier character issues.\n * Only fires for the active (frontmost) modal.\n */\nexport default function useEditHotkey(callback: (() => void) | null) {\n const isActive = useModalActive();\n useEffect(() => {\n if (!callback || !isActive) return;\n const handler = (e: KeyboardEvent) => {\n const isE = e.code === 'KeyE' || e.key === 'E' || e.key === 'e';\n if (e.altKey && e.shiftKey && isE && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n callback();\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [callback, isActive]);\n}\n","/**\n * Who a window-scoped shell CustomEvent is meant for.\n *\n * `modal-save` (Cmd+S) and `modal-duplicate` (Alt+Shift+D) are dispatched on\n * `document` by whichever `<Modal>` is frontmost. `document` reaches every\n * mounted window, so without a match the receiving hook in EVERY open form\n * answered a single keypress: two forms open meant one Cmd+S wrote both, and\n * depending on each form's mode that was a PATCH of a background record or a\n * brand new CREATE.\n *\n * Kept as a pure function, apart from the hooks, because this package's test\n * harness renders to static markup and cannot press a key — so the rule that\n * actually decides whether a foreign window writes is only testable if it is\n * not tangled up in an effect.\n */\nexport function isEventForModal(\n detail: unknown,\n modalId: string | null | undefined,\n): boolean {\n const from = (detail as { modalId?: unknown } | null | undefined)?.modalId;\n // No id on the wire: an older Modal dispatched it. Answer it, exactly as\n // before — a consumer newer than its shell keeps a working Cmd+S rather than\n // silently losing the shortcut altogether.\n if (typeof from !== 'string' || from === '') return true;\n // No id on the receiver: rendered outside any Modal, so there is no window to\n // be foreign to. Same reasoning — degrade to the old behaviour, do not go\n // silent.\n if (!modalId) return true;\n return from === modalId;\n}\n","import { useEffect } from 'react';\nimport { useEnclosingModalId } from '../shell/Modal';\nimport { isEventForModal } from '../shell/modalEventScope';\n\n/**\n * Registers a handler for the Cmd+S \"save and stay\" event dispatched by Modal.\n * The callback should save the form data WITHOUT closing the modal.\n *\n * Fires ONLY for the window the keystroke was aimed at. Modal restricts the\n * dispatch to the topmost modal, but the event goes to `document`, so without\n * this match every mounted window's hook answered one keypress — and with two\n * forms open, a single Cmd+S saved both. Depending on each form's mode that\n * either PATCHed a background record or CREATEd a brand new one, each with its\n * own success toast, so the user saw the write and misread which window it came\n * from.\n *\n * The match is on the originating modal's id rather than on\n * {@link useModalActive}, which asks a different question: \"is the frontmost\n * modal mine\". Every nested dialog a form opens pushes itself onto the\n * activation order, so a form with a child dialog open would read as inactive\n * and Cmd+S would silently do nothing where it used to save.\n *\n * An event with no `detail.modalId` is treated as \"for me\", so a consumer on a\n * newer package than the shell that dispatched it keeps working exactly as\n * before rather than losing Cmd+S entirely.\n */\nexport default function useModalSave(callback: (() => void) | null) {\n const modalId = useEnclosingModalId();\n useEffect(() => {\n if (!callback) return;\n const handler = (e: Event) => {\n if (!isEventForModal((e as CustomEvent).detail, modalId)) return;\n callback();\n };\n document.addEventListener('modal-save', handler);\n return () => document.removeEventListener('modal-save', handler);\n }, [callback, modalId]);\n}\n","import { useEffect } from 'react';\nimport { useEnclosingModalId } from '../shell/Modal';\nimport { isEventForModal } from '../shell/modalEventScope';\n\n/**\n * Registers a handler for the Alt+Shift+D \"save as new / duplicate\" event\n * dispatched by Modal. The callback should save the form data as a NEW record\n * (ignoring the current ID).\n *\n * Window-scoped for the same reason as {@link useModalSave}, and the stakes are\n * higher here: an unscoped duplicate created a second record from every open\n * form at once, and one consumer closes its window on success, so a background\n * window vanished as well.\n */\nexport default function useModalDuplicate(callback: (() => void) | null) {\n const modalId = useEnclosingModalId();\n useEffect(() => {\n if (!callback) return;\n const handler = (e: Event) => {\n if (!isEventForModal((e as CustomEvent).detail, modalId)) return;\n callback();\n };\n document.addEventListener('modal-duplicate', handler);\n return () => document.removeEventListener('modal-duplicate', handler);\n }, [callback, modalId]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/windowRegistry/createWindowRegistry.ts","../src/shell/windowTarget.ts","../src/shell/ShortcutHelp.tsx","../src/shell/ShellContextMenu.tsx","../src/shell/NotificationBell.tsx","../src/utils/env.ts","../src/shell/DevIndicator.tsx","../src/shell/WidgetManager.tsx","../src/shell/perfVerdict.ts","../src/shell/perfLog.ts","../src/shell/perfEnvironment.ts","../src/shell/PerfStats.tsx","../src/changelog.ts","../src/shell/Desktop.tsx","../src/shell/StartupAnimation.tsx","../src/shell/LogoutAnimation.tsx","../src/shell/SessionRestore.tsx","../src/shell/StartMenu.tsx","../src/shell/MobileAppLanding.tsx","../src/shell/Layout.tsx","../src/settings/Customization.tsx","../src/settings/BehaviorPanel.tsx","../src/settings/SoundsPanel.tsx","../src/settings/SystemPreferences.tsx","../src/data/useTableNav.ts","../src/data/useDefaultColumnConfig.ts","../src/data/useColumnConfig.ts","../src/data/ResizableTable.tsx","../src/data/EntityList.tsx","../src/data/useInfiniteScroll.ts","../src/data/useSort.ts","../src/shell/FilterBar.tsx","../src/shell/perfDescribe.ts","../src/utils/mergeBulkItems.ts","../src/shell/BulkImportGrid.tsx","../src/shell/ServerStatusIndicator.tsx","../src/shell/ChangePasswordForm.tsx","../src/shell/withTimeout.ts","../src/shell/PdfActionButton.tsx","../src/shell/ShellEntityFetcher.tsx","../src/hooks/useNewHotkey.ts","../src/hooks/useEditHotkey.ts","../src/shell/modalEventScope.ts","../src/hooks/useModalSave.ts","../src/hooks/useModalDuplicate.ts"],"names":["Dialog","useState","useEffect","selected","close","sections","jsxs","jsx","Fragment","fps","useRef","useCallback","useQueryClient","e","dx","dy","move","useLayoutEffect","navSections","navIcons","sectionIcons","isValidElement","cloneElement","visibleChildren","useSyncExternalStore","toISODate","useMemo","group","isCustom","Row","useContext","useQuery","LoadingSpinner","timeAgo","createPortal","createContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * createWindowRegistry — composes a window registry from one or more partial\n * registry maps. Used at the consumer's App layer to merge package-bundled\n * apps with the consumer's own entity windows.\n *\n * const windows = createWindowRegistry(\n * bundledApps, // utility + document + web apps from the package\n * entityWindows, // consumer-defined entity windows (e.g. Sales Order, Invoice)\n * );\n *\n * Later partials override earlier ones on the same key — handy when a\n * consumer wants to swap a built-in app for their own variant.\n */\nimport type { WindowRegistry } from './types';\n\nexport function createWindowRegistry(...partials: WindowRegistry[]): WindowRegistry {\n return Object.assign({}, ...partials);\n}\n","/**\n * Staging channels for app-mounted windows.\n *\n * ## The pattern this exists for\n *\n * Most windows are opened through `WindowManager` (`openEntity` / `openPage`),\n * which knows how to reuse one that is already open and bring it forward. But\n * some windows aren't opened at all — they are mounted once, for the life of the\n * session, and merely RETARGETED: one form builder that every \"Edit form\" entry\n * point points at, one media picker every slot borrows, one Edit Coupon window\n * per list. The host stays mounted and swaps what it is showing.\n *\n * That third kind used to have a hole in it. The window rose when it was first\n * created, because creating it is a mount and `Modal` raises a fresh mount. It\n * did NOT rise when it was asked for again, because asking again only changed\n * some content — and no amount of content changing is distinguishable, from\n * inside the shell, from a re-render. So a window that was already open but\n * buried under another one stayed buried, and the button that opened it read as\n * dead.\n *\n * ## Why the fix lives here and not at the call sites\n *\n * The shell could have exported \"raise this window\" and asked every button to\n * remember to call it. The four hand-written copies of this channel that this\n * module replaces are the argument against that: each carried a comment saying\n * it mirrored the others so they could not drift apart, and they had drifted\n * anyway — only one of the four had thought to make a repeat staging of the\n * SAME target observable. A rule that four call sites must remember is a rule\n * three of them will forget.\n *\n * So the ask is built into the channel. `set()` is the only way to show one of\n * these windows, and `set()` brings it forward.\n *\n * ## The two halves, and why they cannot be confused\n *\n * A window must come forward when it is asked for, and must NEVER come forward\n * on its own. Those pull against each other, and the separation here is\n * structural rather than a matter of care:\n *\n * - The raise is emitted from exactly one place — `set()`, an imperative\n * \"show this\" call. There is no path from rendering to raising. A window\n * that refetches, re-renders, receives a socket push or resolves a query\n * has no way to reach that line, so it cannot leap in front of somebody\n * typing in another window. Somebody has to ask.\n * - `set(null)` is a close, and closes never raise.\n *\n * Note what this deliberately does NOT do: gate the raise on a browser user\n * gesture. That reads like a stronger guarantee and is in fact a worse one —\n * a real user-initiated open can arrive without a gesture attached (an embedded\n * editor asking its host for a window relays the click through `postMessage`,\n * which lands in a plain listener with no activation), and the window would then\n * silently fail to rise for the one entry point that is hardest to test. The\n * contract is `set()` means the user asked; a caller staging a target for any\n * other reason says so with `{ raise: false }`.\n */\nimport { useSyncExternalStore } from 'react';\n\nimport { cancelWindowFront, requestWindowFront } from './Modal';\n\n/**\n * A target as the window receives it: what was asked for, plus the stamp that\n * makes THIS staging distinct from the last one.\n *\n * The stamp is not decoration. Without it, staging is only observable when the\n * target's contents change — so asking for the window that is already showing\n * exactly what you asked for would be a no-op, and \"New form\" on top of an open\n * blank form would neither reset it nor (before this module) raise it. Callers\n * never set `nav`; staging does.\n */\nexport type StagedTarget<T> = T & { readonly nav: number };\n\nexport interface WindowTargetOptions {\n /**\n * Whether staging this target should also bring the window forward.\n * Defaults to `true`, because staging a target is how the product says\n * \"the user asked to see this\".\n *\n * Pass `false` for the rare staging that is not a request to be looked at —\n * restoring a session's window state on load, say, where several windows are\n * re-staged at once and none of them was just asked for.\n */\n raise?: boolean;\n}\n\nexport interface WindowTarget<T> {\n /** The stable key the window's `Modal` must be given, so the shell can find\n * it to raise. Read it straight off the channel:\n * `<Modal windowKey={myTarget.windowKey}>`. */\n readonly windowKey: string;\n /** Point the window at something — or `null` to close it. A non-null target\n * also brings the window forward, whether it was closed, open and buried, or\n * already showing this very thing. */\n set(target: T | null, options?: WindowTargetOptions): void;\n /** What is staged right now (`null` if nothing) — for readers outside React. */\n get(): StagedTarget<T> | null;\n /** Watch for stagings. Returns its own unsubscribe. */\n subscribe(listener: () => void): () => void;\n}\n\n/**\n * Create the staging channel for one app-mounted window.\n *\n * `windowKey` identifies the window to the shell and must match the `windowKey`\n * given to that window's `Modal`. Use a stable, namespaced string — it also\n * becomes the key the window's position and stacking order are remembered\n * under, so it outlives a page refresh.\n */\nexport function createWindowTarget<T extends object>(windowKey: string): WindowTarget<T> {\n let current: StagedTarget<T> | null = null;\n let nav = 0;\n const listeners = new Set<() => void>();\n\n const emit = () => { listeners.forEach((fn) => fn()); };\n\n return {\n windowKey,\n set(target, options) {\n if (target === null) {\n current = null;\n // Withdraw an ask that nothing ever mounted to honour. Staging and\n // then immediately clearing (an editor request cancelled before the\n // window rendered) would otherwise leave the request in the shell to\n // be claimed by the next, unrelated open.\n cancelWindowFront(windowKey);\n emit();\n return;\n }\n current = { ...target, nav: ++nav };\n emit();\n if (options?.raise !== false) requestWindowFront(windowKey);\n },\n get() { return current; },\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n };\n}\n\n/**\n * Read the staged target inside the window's host component, re-rendering\n * whenever a new one is staged — including a fresh staging of an identical\n * target, which `nav` makes a distinct value.\n *\n * Replaces the `useState` + `useEffect(subscribe)` pair every hand-written\n * version of this channel used to carry, and closes that pair's own gap: it\n * reads the currently-staged target during render rather than after mount, so a\n * host mounted while something is already staged shows it on its first frame.\n */\nexport function useWindowTarget<T extends object>(target: WindowTarget<T>): StagedTarget<T> | null {\n return useSyncExternalStore(target.subscribe, target.get, target.get);\n}\n","import { useState, useEffect } from 'react';\nimport { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react';\nimport { CMD_ENTER, CMD_S, CMD_K, CMD_DOT, CMD_A, CMD_Z, CMD_SHIFT_Z, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, MOD, SHIFT, ENTER } from './Kbd';\nimport { useDismissPopupsOnOpen } from './useDismissPopupsOnOpen';\nimport { Z_LAYERS } from './zLayers';\n\nconst sections = [\n {\n title: 'Global',\n shortcuts: [\n { keys: CMD_K, description: 'Search' },\n { keys: CMD_DOT, description: 'Toggle sidebar' },\n { keys: 'Ctrl F11', description: 'Toggle fullscreen' },\n { keys: 'ESC', description: 'Exit fullscreen (when no windows open)' },\n { keys: '?', description: 'Show keyboard shortcuts' },\n ],\n },\n {\n // The title bar is a tab stop; these act on the focused window's bar.\n title: 'Windows (title bar focused)',\n shortcuts: [\n { keys: '←↑→↓', description: 'Move window' },\n { keys: `${SHIFT} Arrows`, description: 'Resize window' },\n { keys: `${MOD} ←/→`, description: 'Snap to left / right half' },\n { keys: `${MOD} ↑`, description: 'Maximize' },\n { keys: `${MOD} ↓`, description: 'Restore / minimize' },\n { keys: ENTER, description: 'Toggle maximize' },\n ],\n },\n {\n title: 'Lists',\n shortcuts: [\n { keys: 'J / \\u2193', description: 'Next row' },\n { keys: 'K / \\u2191', description: 'Previous row' },\n { keys: '\\u23CE', description: 'Open selected row' },\n { keys: '\\u21E7J / \\u21E7K', description: 'Move and select' },\n { keys: '\\u21E7 Click', description: 'Range select' },\n { keys: 'Space', description: 'Toggle row checkbox' },\n { keys: CMD_A, description: 'Select / deselect all' },\n { keys: ALT_SHIFT_N, description: 'Create new item' },\n { keys: ALT_SHIFT_E, description: 'Edit selected item' },\n ],\n },\n {\n title: 'Modals / Forms',\n shortcuts: [\n { keys: CMD_ENTER, description: 'Submit' },\n { keys: CMD_S, description: 'Save' },\n { keys: ALT_SHIFT_D, description: 'Save as new (duplicate)' },\n { keys: CMD_Z, description: 'Undo the last change to the form' },\n { keys: CMD_SHIFT_Z, description: 'Redo it' },\n { keys: 'ESC', description: 'Close modal' },\n ],\n },\n];\n\nexport default function ShortcutHelp() {\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n const toggle = () => setOpen(prev => !prev);\n document.addEventListener('toggle-shortcut-help', toggle);\n return () => document.removeEventListener('toggle-shortcut-help', toggle);\n }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === '?' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if ((e.target as HTMLElement)?.isContentEditable) return;\n e.preventDefault();\n setOpen(prev => !prev);\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, []);\n\n // An overlay like the palette and Dialog: opening it closes the popups that\n // would otherwise float above its backdrop (see `overlayEvents.ts`). The\n // `?` key never fires from a text field, but a menu or the server-status\n // card can be open, and `toggle-shortcut-help` arrives from anywhere.\n useDismissPopupsOnOpen(open);\n\n return (\n <Dialog open={open} onClose={() => setOpen(false)} className=\"relative\" style={{ zIndex: Z_LAYERS.overlay }}>\n <DialogBackdrop className=\"fixed inset-0 bg-black/30 transition-opacity\" />\n <div className=\"fixed inset-0 flex items-center justify-center p-6\">\n <DialogPanel className=\"w-full max-w-md rounded-lg bg-white shadow-xl\">\n <div className=\"flex items-center justify-between px-5 pt-5 pb-3 border-b border-gray-200\">\n <h2 className=\"text-base font-semibold text-gray-900\">Keyboard Shortcuts</h2>\n <button onClick={() => setOpen(false)} className=\"text-gray-400 hover:text-gray-500 text-sm\">\n ESC\n </button>\n </div>\n <div className=\"px-5 py-4 space-y-5 max-h-[60vh] overflow-y-auto\">\n {sections.map(section => (\n <div key={section.title}>\n <h3 className=\"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2\">{section.title}</h3>\n <div className=\"space-y-1.5\">\n {section.shortcuts.map(s => (\n <div key={s.keys + s.description} className=\"flex items-center justify-between\">\n <span className=\"text-sm text-gray-700\">{s.description}</span>\n <kbd className=\"inline-flex items-center rounded border border-gray-300 bg-gray-50 px-2 py-0.5 text-xs font-medium text-gray-600 font-mono\">\n {s.keys}\n </kbd>\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n <div className=\"px-5 py-3 border-t border-gray-100 text-center\">\n <span className=\"text-xs text-gray-400\">Press <kbd className=\"rounded border border-gray-300 bg-gray-50 px-1.5 py-0.5 text-[10px] font-medium text-gray-500\">?</kbd> to toggle</span>\n </div>\n </DialogPanel>\n </div>\n </Dialog>\n );\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, MenuIcon } from './PopupMenu';\nimport { copyToClipboard, selectionAt, type SelectedText } from './clipboard';\nimport {\n describeContextTarget,\n keepsNativeMenu,\n type ShellContextTarget,\n} from './contextMenuTarget';\n\n/**\n * One context menu for the whole shell.\n *\n * Right-click used to be a patchwork: fourteen surfaces in this package drew\n * their own menu, and everywhere else the browser's native menu appeared,\n * which reads as a hole in a desktop OS. This component closes the hole with a\n * single `contextmenu` listener on the document, and does it without touching\n * any of those handlers:\n *\n * - Every existing handler calls `preventDefault()`, so by the time the\n * event bubbles to the document it is already spoken for. The listener\n * checks `defaultPrevented` and stands down — the specific menu wins,\n * exactly as it does today. `PopupMenu` claims right-clicks on itself the\n * same way, so a menu never opens on top of another one.\n * - Whatever the browser's own menu does better keeps it (`keepsNativeMenu`):\n * text fields, for spellcheck and \"Add to dictionary\"; images, canvases and\n * media, for Save / Copy image and the playback controls.\n * - A touch long-press keeps it too. It fires `contextmenu`, and taking it\n * would cancel the browser's touch text selection.\n * - Shift+right-click anywhere reaches the browser's real menu, so \"Inspect\"\n * is still one gesture away for developers.\n *\n * Mounted by `Layout` (`contextMenu={false}` turns it off), so a consumer gets\n * it without wiring anything. It is exported too, for a screen that renders\n * outside the shell layout.\n */\n\nconst ICONS = {\n copy: 'M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m0 0H5.625',\n open: 'M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25',\n back: 'M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18',\n forward: 'M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3',\n reload: 'M16.023 9.348h4.992V4.356m-4.993 4.992l3.181-3.183a8.25 8.25 0 00-13.803 3.7M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7',\n link: 'M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244',\n} as const;\n\nfunction openInNewTab(url: string) {\n window.open(url, '_blank', 'noopener,noreferrer');\n}\n\nexport interface ShellContextMenuProps {\n /** Turn this instance off — every right-click falls through to the browser.\n * Under `Layout`, pass `contextMenu={false}` to `Layout` instead: it mounts\n * its own instance. */\n disabled?: boolean;\n}\n\ninterface OpenMenu {\n x: number;\n y: number;\n target: ShellContextTarget;\n selected: SelectedText | null;\n}\n\nexport default function ShellContextMenu({ disabled }: ShellContextMenuProps = {}) {\n const [menu, setMenu] = useState<OpenMenu | null>(null);\n\n useEffect(() => {\n if (disabled) return;\n const onContextMenu = (e: MouseEvent) => {\n // A surface with its own menu has already called preventDefault().\n if (e.defaultPrevented) return;\n // Developer escape hatch — the browser's real menu, with Inspect on it.\n if (e.shiftKey) return;\n // Browsers dispatch `contextmenu` as a PointerEvent. A touch long-press\n // is how text gets selected by touch; taking it would cancel that.\n if ((e as PointerEvent).pointerType === 'touch') return;\n // The element actually clicked. A document listener sees `e.target`\n // retargeted to the host when the click lands inside a shadow root.\n const target = (typeof e.composedPath === 'function' ? e.composedPath()[0] : undefined) ?? e.target;\n if (keepsNativeMenu(target)) return;\n\n e.preventDefault();\n const selected = selectionAt(target);\n setMenu({\n x: e.clientX,\n y: e.clientY,\n target: describeContextTarget(target, selected?.text),\n selected,\n });\n };\n document.addEventListener('contextmenu', onContextMenu);\n return () => { document.removeEventListener('contextmenu', onContextMenu); };\n }, [disabled]);\n\n // A window that scrolls or resizes under an open menu leaves it anchored to\n // nothing; close rather than follow. Scroll is captured, so a scroll inside\n // a window's own scroll area counts, not only the page's.\n useEffect(() => {\n if (!menu) return;\n const close = () => setMenu(null);\n window.addEventListener('resize', close);\n window.addEventListener('blur', close);\n window.addEventListener('scroll', close, true);\n return () => {\n window.removeEventListener('resize', close);\n window.removeEventListener('blur', close);\n window.removeEventListener('scroll', close, true);\n };\n }, [menu]);\n\n if (!menu) return null;\n\n const { linkUrl } = menu.target;\n const { selected } = menu;\n const close = () => setMenu(null);\n const run = (fn: () => void) => () => { fn(); close(); };\n\n const sections: ReactNode[][] = [];\n\n if (selected) {\n sections.push([\n <PopupMenuItem key=\"copy\" onClick={run(() => void copyToClipboard('Text', selected.text, selected.html))}>\n <MenuIcon d={ICONS.copy} />Copy\n </PopupMenuItem>,\n ]);\n }\n\n if (linkUrl) {\n sections.push([\n <PopupMenuItem key=\"open-link\" onClick={run(() => openInNewTab(linkUrl))}>\n <MenuIcon d={ICONS.open} />Open link in new tab\n </PopupMenuItem>,\n <PopupMenuItem key=\"copy-link\" onClick={run(() => void copyToClipboard('Link address', linkUrl))}>\n <MenuIcon d={ICONS.link} />Copy link address\n </PopupMenuItem>,\n ]);\n }\n\n // The default section is always drawn, so the menu is never empty and the\n // same four page actions sit in the same place whatever was clicked. Reload\n // and Back leave the page, which a dirty window (`useWindowDirty`) holds with\n // the browser's own \"Leave site?\" prompt.\n sections.push([\n <PopupMenuItem key=\"back\" onClick={run(() => window.history.back())}>\n <MenuIcon d={ICONS.back} />Back\n </PopupMenuItem>,\n <PopupMenuItem key=\"forward\" onClick={run(() => window.history.forward())}>\n <MenuIcon d={ICONS.forward} />Forward\n </PopupMenuItem>,\n <PopupMenuItem key=\"reload\" onClick={run(() => window.location.reload())}>\n <MenuIcon d={ICONS.reload} />Reload\n </PopupMenuItem>,\n <PopupMenuItem key=\"copy-page\" onClick={run(() => void copyToClipboard('Page address', window.location.href))}>\n <MenuIcon d={ICONS.link} />Copy page address\n </PopupMenuItem>,\n ]);\n\n return (\n <PopupMenu\n portal\n minWidth={200}\n style={{ left: menu.x, top: menu.y }}\n onClose={close}\n className=\"shell-context-menu\"\n >\n <div data-shell-context-menu={menu.target.kind}>\n {sections.map((items, i) => (\n <div key={i}>\n {i > 0 && <PopupMenuDivider />}\n {items}\n </div>\n ))}\n </div>\n </PopupMenu>\n );\n}\n","import { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { formatDate } from '../utils/date';\nimport { playNotification } from '../utils/sounds';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from './PopupMenu';\nimport { useShellPrefs } from './ShellPrefs';\nimport { useShellStrings } from './strings';\n\n/** Generic notification shape consumed by the shell. Consumer-specific\n * fields live on `extra` (or just on additional properties — TS structural\n * typing is permissive). */\nexport interface ShellNotification {\n id: string;\n title: string;\n message?: string;\n entity_type?: string;\n entity_id?: string;\n entity_label?: string;\n is_read: boolean;\n actor_name?: string;\n created_at: string;\n}\n\n/** Config bundle for the notification system. Supplied by the consumer;\n * the shell never calls a hardcoded URL. */\nexport interface NotificationsConfig {\n /** Hook called inside <NotificationBell> on every render. Return the\n * current unread count for the signed-in user. */\n useUnreadCount: () => number;\n /** Fetcher for the dropdown list (most recent first). */\n list: (params?: { page_size?: number }) => Promise<{ results: ShellNotification[] }>;\n /** Mark a single notification as read. */\n markRead: (id: string) => Promise<unknown>;\n /** Mark every unread notification as read. */\n markAllRead: () => Promise<unknown>;\n /** Click handler for a notification item. */\n onItemClick: (notif: ShellNotification) => void;\n /** Click handler for \"View all notifications\". When omitted, the link is hidden. */\n onViewAll?: () => void;\n}\n\nfunction timeAgo(dateStr: string): string {\n const diff = Date.now() - new Date(dateStr).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n if (days < 7) return `${days}d ago`;\n return formatDate(dateStr);\n}\n\n/** How long the pop-up card stays up. It used to be a flat 5s, which was\n * fine while the card clipped everything to one line — now that it shows\n * the whole message, a five-line notification needs longer than five\n * seconds or it vanishes mid-sentence. ~15 chars/sec ≈ 200 wpm, floored at\n * the old 5s so short notifications behave exactly as before, and capped so\n * a long one never parks on screen. */\nexport function readingTimeMs(notif: ShellNotification): number {\n const chars = (notif.title?.length ?? 0) + (notif.message?.length ?? 0);\n return Math.min(12000, Math.max(5000, Math.round(chars / 15) * 1000));\n}\n\ninterface NotificationBellProps extends NotificationsConfig {\n popDirection?: 'left' | 'right';\n}\n\nexport default function NotificationBell({\n useUnreadCount, list, markRead, markAllRead, onItemClick, onViewAll, popDirection,\n}: NotificationBellProps) {\n const [open, setOpen] = useState(false);\n const strings = useShellStrings().notifications;\n // Do Not Disturb: the badge keeps counting, the interruptions stop — no\n // pop-up card, no browser Notification, no sound. Persisted per user.\n const { prefs, save: savePrefs } = useShellPrefs();\n const dnd = prefs.notifications_dnd === true;\n const toggleDnd = () => savePrefs({ notifications_dnd: !dnd });\n const dropdownRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const queryClient = useQueryClient();\n\n const unreadCount = useUnreadCount();\n\n useEffect(() => {\n if ('Notification' in window && Notification.permission === 'default') Notification.requestPermission();\n }, []);\n\n // Extracted click flow shared by the bell popup, the toast, and the\n // browser-Notification fallback. Optimistic mark-read + invoke consumer\n // `onItemClick` to open the entity.\n const handleClick = useCallback((notif: ShellNotification) => {\n if (!notif.is_read) {\n queryClient.setQueryData(['notification-unread-count'], (old: any) => old ? { ...old, count: Math.max(0, (old.count || 0) - 1) } : old);\n queryClient.setQueryData(['notifications-dropdown'], (old: any) => {\n if (!old?.results) return old;\n return { ...old, results: old.results.map((n: any) => n.id === notif.id ? { ...n, is_read: true } : n) };\n });\n markRead(notif.id).catch(() => {\n queryClient.invalidateQueries({ queryKey: ['notification-unread-count'] });\n queryClient.invalidateQueries({ queryKey: ['notifications-dropdown'] });\n });\n }\n setOpen(false);\n onItemClick(notif);\n }, [queryClient, markRead, onItemClick]);\n\n // The actionable in-page notification — top-right, click anywhere on the\n // card to open the entity (same behavior as clicking the same item in the\n // bell popup), X to dismiss only. Lives as React state (not via toast.info)\n // so the click target is a first-class part of the notification system.\n const [inlineNotif, setInlineNotif] = useState<ShellNotification | null>(null);\n const inlineTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const dismissInline = useCallback(() => {\n if (inlineTimerRef.current) { clearTimeout(inlineTimerRef.current); inlineTimerRef.current = null; }\n setInlineNotif(null);\n }, []);\n const showInlineNotif = useCallback((notif: ShellNotification, durationMs = readingTimeMs(notif)) => {\n setInlineNotif(notif);\n playNotification();\n if (inlineTimerRef.current) clearTimeout(inlineTimerRef.current);\n inlineTimerRef.current = setTimeout(() => setInlineNotif(null), durationMs);\n }, []);\n useEffect(() => () => { if (inlineTimerRef.current) clearTimeout(inlineTimerRef.current); }, []);\n\n const prevCountRef = useRef<number | null>(null);\n useEffect(() => {\n if (prevCountRef.current === null) { prevCountRef.current = unreadCount; return; }\n // DND suppresses the interruptions but not the counter: prevCountRef still\n // advances below, so turning DND off later does not replay a backlog.\n if (unreadCount > prevCountRef.current && !dnd) {\n list({ page_size: 1 }).then(data => {\n const latest = data?.results?.[0];\n if (!latest) return;\n const title = latest.title || 'New Notification';\n const body = latest.message || latest.entity_label || '';\n if (document.hidden) {\n if ('Notification' in window && Notification.permission === 'granted') {\n const n = new Notification(title, { body, icon: '/favicon.svg', tag: `notif-${latest.id}` });\n n.onclick = () => { window.focus(); handleClick(latest); n.close(); };\n }\n } else {\n showInlineNotif(latest);\n }\n }).catch(() => {});\n }\n prevCountRef.current = unreadCount;\n }, [unreadCount, list, showInlineNotif, dnd]);\n\n // Always run on mount + every 30s so the dropdown is always populated\n // with cached data before the first click — no loading-state flash.\n const { data: notifData } = useQuery({\n queryKey: ['notifications-dropdown'],\n queryFn: () => list({ page_size: 30 }),\n staleTime: 30_000,\n refetchInterval: 30_000,\n });\n const notifications: ShellNotification[] = notifData?.results ?? [];\n\n // Outside-click is handled by PopupMenu's own onClose listener. Since the\n // popup is portaled into document.body it doesn't sit inside dropdownRef,\n // so any handler scoped to dropdownRef would fire pointerdown on items\n // inside the popup and close it before their onClick runs — see #issue.\n\n const handleMarkAllRead = () => {\n queryClient.setQueryData(['notification-unread-count'], (old: any) => old ? { ...old, count: 0 } : old);\n queryClient.setQueryData(['notifications-dropdown'], (old: any) => {\n if (!old?.results) return old;\n return { ...old, results: old.results.map((n: any) => ({ ...n, is_read: true })) };\n });\n markAllRead().then(() => {\n queryClient.invalidateQueries({ queryKey: ['notification-unread-count'] });\n queryClient.invalidateQueries({ queryKey: ['notifications-dropdown'] });\n });\n };\n\n const [dropdownPos, setDropdownPos] = useState<Record<string, number | string>>({});\n const calcPos = useCallback(() => {\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 56;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const verticalReserve = (taskbarPos === 'top' || taskbarPos === 'bottom') ? taskbarH + 16 : 16;\n const maxHeight = `calc(100vh - ${verticalReserve}px)`;\n if (popDirection === 'right') setDropdownPos({ left: taskbarW + 8, bottom: 8, maxHeight });\n else if (popDirection === 'left') setDropdownPos({ right: taskbarW + 8, bottom: 8, maxHeight });\n else if (taskbarPos === 'top') setDropdownPos({ right: 8, top: taskbarH + 8, maxHeight });\n else setDropdownPos({ right: 8, bottom: taskbarH + 8, maxHeight });\n }, [popDirection]);\n // Run synchronously before paint so the dropdown renders at the right\n // position on first open (otherwise it briefly flashes at viewport origin).\n useLayoutEffect(() => {\n if (!open) return;\n calcPos();\n }, [open, calcPos]);\n useEffect(() => {\n if (!open) return;\n window.addEventListener('resize', calcPos);\n return () => window.removeEventListener('resize', calcPos);\n }, [open, calcPos]);\n\n return (\n <div ref={dropdownRef} className=\"relative\">\n <button ref={buttonRef} data-menu-toggle\n onMouseEnter={() => queryClient.prefetchQuery({ queryKey: ['notifications-dropdown'], queryFn: () => list({ page_size: 30 }) })}\n onClick={() => setOpen(prev => !prev)}\n title={dnd ? strings.dndOn : strings.title}\n className=\"relative shrink-0 rounded-md p-2 text-gray-900 hover:text-black hover:bg-white/20 transition-colors\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n {unreadCount > 0 && (\n <span className=\"absolute top-0.5 right-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n {dnd && (\n /* A quiet moon on the bell: DND is on. Decorative — the button's\n title and the popover toggle carry the state for AT. */\n <span aria-hidden=\"true\" className=\"absolute bottom-0.5 right-0.5 flex h-3 w-3 items-center justify-center rounded-full bg-indigo-500 text-white\">\n <svg className=\"h-2 w-2\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z\"/></svg>\n </span>\n )}\n </button>\n\n {open && createPortal(\n <PopupMenu minWidth={320} className=\"w-80 flex flex-col overflow-hidden\" style={{ ...dropdownPos }} onClose={() => setOpen(false)}>\n <PopupMenuLabel>\n <span className=\"flex items-center justify-between w-full gap-2\">\n <span>{strings.title}</span>\n <span className=\"flex items-center gap-2\">\n {unreadCount > 0 && (\n <button onClick={handleMarkAllRead} className=\"text-[10px] text-blue-600 hover:text-blue-700 font-medium normal-case tracking-normal\">\n {strings.markAllRead}\n </button>\n )}\n <button\n onClick={toggleDnd}\n aria-pressed={dnd}\n title={strings.dnd}\n className={`rounded p-0.5 transition-colors ${dnd ? 'text-indigo-600 bg-indigo-50' : 'text-gray-400 hover:text-gray-600'}`}\n >\n <svg className=\"h-3.5 w-3.5\" fill={dnd ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z\" />\n </svg>\n </button>\n </span>\n </span>\n </PopupMenuLabel>\n <PopupMenuDivider />\n {/* Both axes are named on purpose. `overflow-y: auto` on its own makes\n the other axis compute to `auto` as well, so a fraction of a pixel\n of horizontal overflow — a rounding error on the item's\n `calc(100% - 8px)`, a title with no break opportunity in it — hangs\n a horizontal scrollbar under a dropdown of fixed width that has\n nothing to scroll sideways to. */}\n <div className=\"overflow-y-auto overflow-x-hidden\" style={{ flex: '1 1 auto', minHeight: 0 }}>\n {notifications.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\n <svg className=\"h-8 w-8 text-gray-300 mb-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n <p className=\"text-sm text-gray-600 font-medium\">{strings.caughtUp}</p>\n <p className=\"text-xs text-gray-400 mt-0.5\">{strings.empty}</p>\n </div>\n ) : (\n notifications.map(notif => (\n <PopupMenuItem key={notif.id} onClick={() => handleClick(notif)}>\n <div className=\"pt-0.5 shrink-0\">\n {!notif.is_read ? <div className=\"h-2 w-2 rounded-full bg-blue-500\" /> : <div className=\"h-2 w-2\" />}\n </div>\n <div className=\"min-w-0 flex-1\">\n {/* The message truncates, but the title wraps — `break-words` so a\n long unbroken token (a container or reference number) wraps\n instead of running out under the hidden axis above. */}\n <p className={`text-sm leading-tight break-words ${!notif.is_read ? 'font-medium' : ''}`}>{notif.title}</p>\n {notif.message && <p className=\"text-xs text-gray-500 mt-0.5 truncate\">{notif.message}</p>}\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-[10px] text-gray-400\">{timeAgo(notif.created_at)}</span>\n {notif.actor_name && <span className=\"text-[10px] text-gray-400\">by {notif.actor_name}</span>}\n </div>\n </div>\n </PopupMenuItem>\n ))\n )}\n </div>\n {onViewAll && (\n <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setOpen(false); onViewAll(); }}>\n <span className=\"w-full text-center text-xs text-blue-600 font-medium\">{strings.viewAll}</span>\n </PopupMenuItem>\n </>\n )}\n </PopupMenu>,\n document.body\n )}\n\n {inlineNotif && createPortal(\n <>\n <style>{`@keyframes notif-in { from { opacity: 0; transform: translateX(30px) scale(0.95); } to { opacity: 1; transform: translateX(0) scale(1); } }`}</style>\n <div\n onClick={() => { handleClick(inlineNotif); dismissInline(); }}\n className=\"fixed top-4 right-4 z-[9999] w-[320px] max-w-[calc(100vw-2rem)] cursor-pointer rounded-2xl bg-white/85 backdrop-blur-md border border-white/40 shadow-2xl flex items-start gap-3 px-4 py-3\"\n style={{ animation: 'notif-in 300ms cubic-bezier(0.4,0,0.2,1)' }}\n >\n <div className=\"h-9 w-9 shrink-0 rounded-lg bg-blue-500/15 flex items-center justify-center\">\n <svg className=\"h-5 w-5 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" />\n </svg>\n </div>\n {/* Title and message wrap to as many lines as they need — the card\n grows instead of clipping, so the notification is readable\n without opening it. max-h is only a runaway guard (a very long\n message can't push the dismiss X off-screen); normal ones never\n reach it. break-words keeps an unbroken token (URL, long ref)\n from overflowing the 320px card. */}\n <div className=\"flex-1 min-w-0 max-h-[60vh] overflow-y-auto\">\n <div className=\"text-[11px] font-semibold uppercase tracking-wide text-blue-600 mb-0.5\">{strings.cardLabel}</div>\n <div className=\"text-sm font-medium text-gray-800 leading-snug break-words\">{inlineNotif.title}</div>\n {inlineNotif.message && (\n <div className=\"text-xs text-gray-500 leading-snug break-words mt-0.5\">{inlineNotif.message}</div>\n )}\n </div>\n <button\n onClick={(e) => { e.stopPropagation(); dismissInline(); }}\n className=\"shrink-0 p-1 -mr-1 -mt-1 text-gray-400 hover:text-gray-600 transition-colors\"\n aria-label={strings.dismiss}\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </>,\n document.body\n )}\n </div>\n );\n}\n","/**\n * Dev-environment detection + browser chrome.\n *\n * A deployed bundle is byte-identical across hosts (CI builds once and promotes\n * the same image between environments), so build-time signals like\n * `import.meta.env.MODE` can't tell a developer's machine from a deployed site —\n * only the runtime hostname can. `isDevEnv()` is therefore gated on\n * `localhost`/`127.0.0.1`, and everything dev-only (the <DevIndicator/> tray\n * badge, the `[DEV]` tab-title prefix) keys off it so it never leaks onto a\n * deployed host.\n */\n\n/** Tooltip/banner copy for the dev indicator. */\nexport const DEV_BANNER_TEXT =\n 'LOCAL DEV ENVIRONMENT — running against your local backend; not connected to the live system';\n\n/**\n * True only when served from a developer's own machine.\n *\n * Gated on `localhost`/`127.0.0.1` only (not `*.local` mDNS names), so a\n * teammate reaching a dev server over the LAN doesn't get the dev chrome.\n */\nexport function isDevEnv(): boolean {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n}\n\n/**\n * Apply local-dev browser chrome: prefix the tab title with `[DEV]` and,\n * optionally, swap the favicon. No-op outside localhost. Idempotent — safe to\n * call at startup and again whenever a route overwrites `document.title`.\n *\n * Call before React mounts (e.g. in `main.tsx`) so the title is correct on the\n * first paint. Pass `faviconHref` only if the host actually ships that asset.\n */\nexport function applyDevTitle(opts?: { faviconHref?: string }): void {\n if (!isDevEnv()) return;\n\n if (!document.title.startsWith('[DEV]')) {\n document.title = `[DEV] ${document.title}`;\n }\n\n if (opts?.faviconHref) {\n const icon = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]');\n if (icon) icon.href = opts.faviconHref;\n }\n}\n","import { isDevEnv, DEV_BANNER_TEXT } from '../utils/env';\n\n/**\n * System-tray badge shown only when the app is served from a developer's own\n * machine (localhost / 127.0.0.1). Drop it into the host's `taskbarTrayLeft`\n * slot — it renders nothing off-localhost, so it's safe to leave wired on every\n * build. Visibility is gated on the runtime hostname; see utils/env.ts.\n */\nexport default function DevIndicator() {\n if (!isDevEnv()) return null;\n\n return (\n <div\n className=\"shrink-0 inline-flex items-center gap-1 rounded-md bg-blue-600 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-blue-50 select-none\"\n title={DEV_BANNER_TEXT}\n >\n <svg className=\"h-3 w-3 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4\" />\n </svg>\n <span>Dev</span>\n </div>\n );\n}\n","import { useMemo, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { setWindowPosition } from './Modal';\nimport { useWindowManager } from './WindowManager';\nimport { WINDOW_REGISTRY, isPageEntry, type PageRegistryEntry } from '../windowRegistry/types';\nimport { navIcons } from '../shell-config/nav';\n\ninterface AvailableWidget {\n route: string;\n label: string;\n entry: PageRegistryEntry;\n}\n\n/** Generic fallback glyph for widgets the consumer hasn't given a navIcon. */\nfunction FallbackIcon() {\n return (\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n </svg>\n );\n}\n\nfunction widgetIcon(entry: PageRegistryEntry, route: string) {\n const icon = navIcons[entry.icon ?? route];\n if (icon && isValidElement(icon)) {\n return cloneElement(icon as ReactElement, { className: 'h-5 w-5' });\n }\n return <FallbackIcon />;\n}\n\n/**\n * Widget gallery — the \"manage widgets on the desktop\" surface.\n *\n * Enumerates every widget-flagged page in the live window registry (so it\n * automatically lists whatever the consumer registered, not just the bundled\n * five) and cross-references the window manager's `openWindows` to know which\n * are currently sitting on the desktop. Adding a widget calls `openPage`\n * (which drops the chrome-less panel onto the desktop and persists it via the\n * normal open-windows session store); removing one calls `closeEntity` on the\n * live window. No new persistence layer — it drives the same plumbing the\n * Start Menu already uses.\n *\n * Surfaced from the desktop right-click menu (\"Manage Widgets…\") and exported\n * so a consumer can also register it as a window or wire it to a tray button.\n */\nexport default function WidgetManager({ open, onClose }: { open: boolean; onClose: () => void }) {\n const { openWindows, openPage, closeEntity } = useWindowManager();\n\n // Widget-flagged page entries from the live registry, alphabetised.\n const widgets = useMemo<AvailableWidget[]>(() => {\n if (!open) return [];\n return Object.entries(WINDOW_REGISTRY)\n .filter(([, e]) => isPageEntry(e) && (e as PageRegistryEntry).widget)\n .map(([route, e]) => ({ route, label: (e as PageRegistryEntry).label, entry: e as PageRegistryEntry }))\n .sort((a, b) => a.label.localeCompare(b.label));\n }, [open]);\n\n if (!open) return null;\n\n // route → the live open-window item (widgets aren't multi-instance, so at\n // most one per route).\n const activeByRoute = new Map(openWindows.filter(w => w.route).map(w => [w.route!, w]));\n const isActive = (route: string) => activeByRoute.has(route);\n\n // ── Placement ────────────────────────────────────────────────────────────\n // Newly-added widgets drop into the top-left corner and stack downward so\n // they never cover an existing widget. We read the live on-screen rects of\n // any widgets already on the desktop and place the new one below the lowest\n // one in the left column, wrapping to a new column when the column fills.\n const PAD = 20, GAP = 16;\n type Rect = { x: number; y: number; w: number; h: number };\n\n const workArea = () => {\n const cs = getComputedStyle(document.documentElement);\n const tbH = parseInt(cs.getPropertyValue('--taskbar-height')) || 0;\n const tbW = parseInt(cs.getPropertyValue('--taskbar-width')) || 0;\n const tbPos = cs.getPropertyValue('--taskbar-position').trim() || 'bottom';\n const sidebarW = parseInt(cs.getPropertyValue('--sidebar-width')) || 0;\n return {\n leftOffset: (tbPos === 'left' ? tbW : 0) + sidebarW + PAD,\n topOffset: (tbPos === 'top' ? tbH : 0) + PAD,\n maxBottom: window.innerHeight - (tbPos === 'bottom' ? tbH : 0) - PAD,\n };\n };\n\n const liveWidgetRects = (): Rect[] =>\n [...document.querySelectorAll<HTMLElement>('[data-modal-panel][data-widget]')]\n .map(el => { const r = el.getBoundingClientRect(); return { x: r.left, y: r.top, w: r.width, h: r.height }; })\n .filter(r => r.w > 0 && r.h > 0);\n\n const computeSlot = (occupied: Rect[], w: number, h: number) => {\n const { leftOffset, topOffset, maxBottom } = workArea();\n const rightLimit = window.innerWidth - PAD;\n const lowestInColumn = (colX: number) => {\n const ov = occupied.filter(r => r.x < colX + w && r.x + r.w > colX);\n return ov.length ? Math.max(...ov.map(r => r.y + r.h)) + GAP : topOffset;\n };\n let x = leftOffset, y = lowestInColumn(x), guard = 0;\n // Move to a fresh column when this one is full — but never push a widget\n // off the right edge: only wrap if the next column still fits on-screen.\n while (y + h > maxBottom && x + (w + GAP) + w <= rightLimit && guard < 12) {\n x += w + GAP; y = lowestInColumn(x); guard++;\n }\n return { x, y };\n };\n\n const dimsFor = (route: string) => {\n const e = WINDOW_REGISTRY[route] as PageRegistryEntry;\n return { w: e?.dimensions?.[0] ?? 320, h: e?.dimensions?.[1] ?? 240, auto: !!e?.autoHeight };\n };\n\n // Place a widget into a free top-left slot, then open it. We choose the slot\n // from the *live* rects of widgets already on the desktop, so the new one\n // stacks below their real (content-aware) heights. `autoHeight` widgets\n // shrink to their content, so we only reserve a small slice of height for\n // them when picking a column — otherwise their full dimension height would\n // push later widgets into needless extra columns. The seeded `h` is just a\n // first-paint placeholder; autoHeight widgets re-measure on open.\n const placeAndOpen = (route: string) => {\n const { w, h, auto } = dimsFor(route);\n const selfH = auto ? Math.min(h, 160) : h;\n const { x, y } = computeSlot(liveWidgetRects(), w, selfH);\n setWindowPosition(`page:${route}`, { x, y, w, h });\n openPage(route);\n };\n\n // Resolve once the just-opened widget has rendered with a real height, so the\n // next placement in a batch can read its actual rect (capped so a slow lazy\n // chunk never hangs the loop).\n const waitForWidget = (route: string) => new Promise<void>(resolve => {\n const sel = `[data-modal-panel][data-window-key=\"page:${route}\"]`;\n let n = 0;\n const tick = () => {\n const el = document.querySelector(sel) as HTMLElement | null;\n if ((el && el.getBoundingClientRect().height > 40) || n++ > 30) resolve();\n else setTimeout(tick, 30);\n };\n setTimeout(tick, 30);\n });\n\n const add = (route: string) => { if (!isActive(route)) placeAndOpen(route); };\n const remove = (route: string) => { const w = activeByRoute.get(route); if (w) closeEntity(w.id); };\n const toggle = (route: string) => { isActive(route) ? remove(route) : add(route); };\n\n const activeCount = widgets.reduce((n, w) => n + (isActive(w.route) ? 1 : 0), 0);\n const allActive = widgets.length > 0 && activeCount === widgets.length;\n const addAll = async () => {\n for (const w of widgets) {\n if (isActive(w.route)) continue;\n placeAndOpen(w.route);\n await waitForWidget(w.route);\n }\n };\n const removeAll = () => widgets.forEach(w => remove(w.route));\n\n const widgetGlyph = (\n <svg className=\"h-5 w-5 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n </svg>\n );\n\n return (\n <Modal open={open} onClose={onClose} title=\"Widgets\" icon={widgetGlyph} size=\"md\" compact dimensions={[480, 560]}>\n <div className=\"flex flex-col h-full\">\n {/* Summary + bulk actions */}\n <div className=\"flex items-center justify-between gap-2 px-1 pb-3\">\n <p className=\"text-xs text-gray-500\">\n {widgets.length === 0\n ? 'No widgets available'\n : <><span className=\"font-semibold text-gray-700\">{activeCount}</span> of {widgets.length} on your desktop</>}\n </p>\n {widgets.length > 0 && (\n <button\n onClick={allActive ? removeAll : addAll}\n className=\"text-xs font-medium text-blue-600 hover:text-blue-700 hover:underline\">\n {allActive ? 'Remove all' : 'Add all'}\n </button>\n )}\n </div>\n\n {/* Gallery */}\n <div className=\"flex-1 overflow-y-auto -mx-1 px-1\">\n {widgets.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center text-center py-12 text-gray-400\">\n <div className=\"opacity-60 mb-2\">{widgetGlyph}</div>\n <p className=\"text-sm\">No widgets are registered.</p>\n <p className=\"text-xs mt-1\">Widgets like Weather, Currency, and the Pomodoro timer appear here once available.</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n {widgets.map(({ route, label, entry }) => {\n const active = isActive(route);\n return (\n <button\n key={route}\n onClick={() => toggle(route)}\n title={active ? `Remove ${label} from desktop` : `Add ${label} to desktop`}\n className={`group relative flex items-center gap-3 rounded-xl border p-3 text-left transition-colors ${\n active\n ? 'border-blue-300 bg-blue-50/70 hover:bg-blue-50'\n : 'border-gray-200 bg-white/60 hover:border-gray-300 hover:bg-gray-50'\n }`}>\n <span className={`shrink-0 flex items-center justify-center h-10 w-10 rounded-lg ${\n active ? 'bg-blue-100 text-blue-600' : 'bg-gray-100 text-gray-500'\n }`}>\n {widgetIcon(entry, route)}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-medium text-gray-900 truncate\">{label}</span>\n <span className={`block text-[11px] ${active ? 'text-blue-600' : 'text-gray-400'}`}>\n {active ? 'On desktop' : 'Available'}\n </span>\n </span>\n {/* Toggle affordance */}\n <span className={`shrink-0 inline-flex items-center justify-center h-6 w-6 rounded-full border transition-colors ${\n active\n ? 'border-blue-500 bg-blue-500 text-white group-hover:border-red-400 group-hover:bg-red-400'\n : 'border-gray-300 text-gray-400 group-hover:border-blue-400 group-hover:text-blue-500'\n }`}>\n {active ? (\n <>\n {/* check by default, swap to × on hover to signal removal */}\n <svg className=\"h-3.5 w-3.5 group-hover:hidden\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>\n <svg className=\"h-3.5 w-3.5 hidden group-hover:block\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </>\n ) : (\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n )}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* Hint */}\n <p className=\"shrink-0 pt-3 mt-1 border-t border-gray-100 text-[11px] text-gray-400 leading-relaxed\">\n Drag a widget anywhere on the desktop to reposition it. Right-click a widget for its appearance settings.\n </p>\n </div>\n </Modal>\n );\n}\n","/**\n * Frame-timing maths + bottleneck attribution for the desktop perf HUD.\n *\n * Split out from `PerfStats.tsx` because the interesting part is the\n * *attribution*, and attribution is pure: given a frame rate and how much of\n * the wall clock the main thread spent blocked, decide whether a janky UI is\n * the GPU's fault or JavaScript's. That decision is what the HUD exists for —\n * \"the UI feels laggy\" is not actionable, \"you are GPU-bound\" is — so it lives\n * where a test can pin it.\n *\n * The discriminator: frames are landing late, but the main thread is idle.\n * If JS were the problem the main thread would be busy, so late frames plus an\n * idle thread means the cost is downstream of script — compositing, paint,\n * backdrop-filter. The shell leans hard on frosted glass (`utils/glass.ts`\n * blurs at a 40px radius), which is exactly the kind of work that shows up\n * here and nowhere in a JS profile.\n */\n\n/** Frame rate at or above which we call the UI smooth. Below 60 because\n * rAF sampling is noisy and a display may be capped at 60Hz anyway — a\n * steady 55 is not a complaint anyone would file. */\nexport const SMOOTH_FPS = 50;\n\n/** Share of wall-clock time in long tasks that makes JS the prime suspect.\n * `longtask` entries are >50ms by definition, so even 20% means the thread\n * is stalling several times a second — visible as jank on its own. */\nexport const BLOCKED_PCT_CPU = 20;\n\nexport type BottleneckKind = 'smooth' | 'gpu' | 'cpu' | 'unknown';\n\nexport interface PerfReading {\n /** Frames per second across the sample window. */\n fps: number;\n /** Mean frame interval, ms. */\n frameMs: number;\n /** Slowest single frame in the window, ms — where the jank actually lives. */\n worstMs: number;\n /** Percentage of wall-clock time the main thread spent inside long tasks\n * (0–100), or null when the browser exposes no `longtask` observer.\n * Null is load-bearing: without it we cannot separate GPU from CPU, and\n * guessing would defeat the point of the HUD. */\n blockedPct: number | null;\n}\n\nexport interface Verdict {\n kind: BottleneckKind;\n /** Headline, for the HUD's verdict row. */\n label: string;\n /** One line of what to do about it. */\n detail: string;\n}\n\n/** Reached from two directions — frames arriving late, and frames not arriving\n * at all because the thread is too busy to deliver them — so it lives in one\n * place rather than being spelled out twice. */\nconst CPU_BOUND: Verdict = {\n kind: 'cpu',\n label: 'CPU-bound (JavaScript)',\n detail: 'The main thread is blocked. Rendering settings will not help — this is script or data work.',\n};\n\n/** Turn a window of rAF timestamps into a frame-rate reading.\n * Needs two timestamps to describe one interval; anything less is not yet a\n * measurement and reports zeroes rather than a fabricated 0 fps. */\nexport function summariseFrames(timestamps: number[]): Pick<PerfReading, 'fps' | 'frameMs' | 'worstMs'> {\n if (timestamps.length < 2) return { fps: 0, frameMs: 0, worstMs: 0 };\n\n let worstMs = 0;\n for (let i = 1; i < timestamps.length; i++) {\n const delta = timestamps[i] - timestamps[i - 1];\n if (delta > worstMs) worstMs = delta;\n }\n\n const spanMs = timestamps[timestamps.length - 1] - timestamps[0];\n // A window where every timestamp collapsed to the same instant is not a\n // 0-second span we can divide by — treat it as no reading.\n if (spanMs <= 0) return { fps: 0, frameMs: 0, worstMs: 0 };\n\n const intervals = timestamps.length - 1;\n return {\n fps: (intervals / spanMs) * 1000,\n frameMs: spanMs / intervals,\n worstMs,\n };\n}\n\n/**\n * Attribute a reading to a bottleneck.\n *\n * Order matters: smooth wins outright (nobody cares what a healthy frame rate\n * is *not* bound by), and an unknown block share can only ever downgrade to\n * `unknown` — never to `gpu`. Blaming the GPU because the browser withheld\n * long-task timing would be a confident wrong answer, which is worse than no\n * answer when someone is about to go change settings on the strength of it.\n */\nexport function classify(reading: PerfReading): Verdict {\n const { fps, blockedPct } = reading;\n const threadBlocked = blockedPct !== null && blockedPct >= BLOCKED_PCT_CPU;\n\n if (!Number.isFinite(fps) || fps <= 0) {\n // No readable frame rate — but if the main thread is also blocked, the\n // blocking is *why* there are no frames: a starved thread never gets to\n // service `requestAnimationFrame`, so the samples dry up. That is the most\n // severe CPU-bound case there is, and it must not be reported as an\n // absence of data — \"Measuring…\" would leave the HUD at its least useful\n // exactly when the machine is at its worst.\n if (threadBlocked) return CPU_BOUND;\n return { kind: 'unknown', label: 'Measuring…', detail: 'Collecting frame timings.' };\n }\n\n if (fps >= SMOOTH_FPS) {\n return {\n kind: 'smooth',\n label: 'Smooth',\n detail: 'Frames are landing on time. No rendering bottleneck here.',\n };\n }\n\n if (blockedPct === null) {\n return {\n kind: 'unknown',\n label: 'Janky — cause unknown',\n detail: 'This browser reports no long-task timing, so GPU and JS cannot be told apart. Try Chrome or Edge.',\n };\n }\n\n if (threadBlocked) return CPU_BOUND;\n\n return {\n kind: 'gpu',\n label: 'GPU-bound (compositing)',\n detail: 'Frames are late while the main thread sits idle. Try Preferences → Customization → Reduce transparency.',\n };\n}\n","/**\n * Session log for the desktop perf HUD — and the analysis that turns it into\n * a conclusion.\n *\n * A live frame rate tells you the UI is slow *now*. It does not tell you what\n * made it slow, and the person watching it is usually the last person able to\n * say. So while the HUD is on, every reading is stamped with what was\n * happening around it: how many windows were open, which one was on top,\n * whether the user was clicking, typing, scrolling or dragging. The log is\n * exportable, so a laggy machine somewhere else can produce evidence rather\n * than an adjective.\n *\n * The maths here is deliberately non-clever. Median rather than mean, because\n * one 400ms stall would drag a mean somewhere no frame ever was. Buckets\n * rather than a fitted curve, because \"6 windows open halves the frame rate\"\n * is a sentence someone can act on and a correlation coefficient is not.\n */\nimport type { BottleneckKind } from './perfVerdict';\n\n/** One flush interval's worth of measurement plus its context. Keys are short\n * because thousands of these get JSON-serialised into localStorage and into\n * whatever the user sends afterwards. */\nexport interface PerfLogRecord {\n /** Milliseconds since logging began. */\n t: number;\n fps: number;\n frameMs: number;\n worstMs: number;\n blockedPct: number | null;\n heapMB: number | null;\n verdict: BottleneckKind;\n /** Open shell windows at the moment of the reading. */\n windows: number;\n /** Identity of the topmost window, when there is one — so a summary can name\n * the screen that was slow rather than just the count. */\n active: string | null;\n clicks: number;\n keys: number;\n scrolls: number;\n /** Milliseconds spent with the pointer down and moving. Dragging is the\n * single most compositing-heavy thing a user does in a window shell, so it\n * gets its own axis rather than being lumped in with clicks. Covers any\n * drag — a window gesture, a desktop icon, a text selection; `moveMs` and\n * `resizeMs` below are the window subset of it. */\n dragMs: number;\n /** Start-menu opens (`perfEvents`). */\n menus: number;\n /** Flyout opens — 2nd- and 3rd-level menus. Hover-opened flyouts fire no\n * click and no keypress, so before this axis existed the frame a submenu\n * painted on was filed as *idle*, which is where the jank people actually\n * report was going missing. */\n submenus: number;\n /** Last menu or flyout opened in the interval, so one can be named. */\n menuKey: string | null;\n /** Milliseconds spent dragging a window by its title bar. */\n moveMs: number;\n /** Milliseconds spent dragging a window's resize handle. */\n resizeMs: number;\n}\n\nexport interface FpsGroup {\n samples: number;\n /** Median across the group's *measurable* samples — see `summariseLog`. Zero\n * when every sample in the group stalled. */\n medianFps: number;\n /** Slowest single frame anywhere in the group. For a group of brief\n * interactions this is the number that matters: a flyout that costs one\n * 300ms frame barely moves a median but is exactly what the user saw. */\n worstMs: number;\n /** Samples too blocked to report a frame rate at all. Kept beside the median\n * rather than folded into it, so a group that is entirely stalls reads as\n * the emergency it is instead of as a 0 fps reading. */\n stalls: number;\n}\n\n/**\n * What the user was doing during a sample, reduced to one label.\n *\n * A single interval routinely carries several axes at once — opening a flyout\n * involves a click, a pointer move and a menu mark — so the ranking below\n * decides which one the sample is filed under. It runs most-specific first:\n * the deliberate, expensive gesture beats the incidental click that came with\n * it, because filing a janky submenu open under \"click\" is how you end up\n * optimising the wrong thing.\n */\nexport type ActivityKind = 'submenu' | 'menu' | 'resize' | 'move' | 'scroll' | 'type' | 'click' | 'idle';\n\nconst ACTIVITY_ORDER: { kind: ActivityKind; test: (r: PerfLogRecord) => boolean }[] = [\n { kind: 'submenu', test: r => r.submenus > 0 },\n { kind: 'menu', test: r => r.menus > 0 },\n { kind: 'resize', test: r => r.resizeMs > 0 },\n { kind: 'move', test: r => r.moveMs > 0 },\n { kind: 'scroll', test: r => r.scrolls > 0 },\n { kind: 'type', test: r => r.keys > 0 },\n { kind: 'click', test: r => r.clicks > 0 || r.dragMs > 0 },\n];\n\n/** File a sample under the one thing most likely to have cost it. */\nexport function classifyActivity(r: PerfLogRecord): ActivityKind {\n return ACTIVITY_ORDER.find(entry => entry.test(r))?.kind ?? 'idle';\n}\n\nexport interface LogSummary {\n samples: number;\n durationMs: number;\n medianFps: number;\n worstFrameMs: number;\n /** Fraction of samples in each verdict, 0–1. */\n verdictShare: Record<BottleneckKind, number>;\n /** Split by whether the user was doing anything. The gap between these two\n * is the headline: a desktop that is smooth at rest and janky in use has a\n * rendering cost that only shows up under interaction. */\n interacting: FpsGroup | null;\n idle: FpsGroup | null;\n /** Frame rate per kind of interaction, worst-first — the answer to \"which\n * gesture is slow\", which is the question a report is usually filed to\n * ask. */\n byActivity: (FpsGroup & { kind: ActivityKind })[];\n /** Frame rate against how many windows were open. */\n byWindowCount: (FpsGroup & { windows: number })[];\n /** Windows ranked worst-first, so the slowest screen names itself. */\n worstWindows: (FpsGroup & { key: string })[];\n /** Menus and flyouts ranked worst-first, same idea one layer up. */\n worstMenus: (FpsGroup & { key: string })[];\n}\n\n/** Records kept in memory before the oldest are dropped. At one record per\n * 500ms this is about 20 minutes — long enough to catch an intermittent\n * stall, small enough to serialise without thinking about it. */\nexport const LOG_CAP = 2400;\n\n/** Minimum samples before a group is reported. One unlucky reading is not a\n * finding, and a summary that names a window off a single sample invites\n * someone to go optimise the wrong screen. */\nexport const MIN_GROUP_SAMPLES = 4;\n\n/** The floor for menu and gesture groups. Lower because these events are rare\n * by construction — a flyout opens inside a single 500ms interval, not across\n * twenty of them, so holding them to the window floor would suppress exactly\n * the findings the axes were added for. Two still rules out a one-off, and\n * every group carries its own `samples` for whoever reads it. */\nexport const MIN_EVENT_SAMPLES = 2;\n\n/** Append with a cap, oldest dropped first. Returns a new array — callers hold\n * this in React state, where mutation would not re-render. */\nexport function appendRecord(log: PerfLogRecord[], record: PerfLogRecord, cap = LOG_CAP): PerfLogRecord[] {\n const next = log.length >= cap ? log.slice(log.length - cap + 1) : log.slice();\n next.push(record);\n return next;\n}\n\n/** True when the user was doing something during the interval. */\nexport function isInteracting(r: PerfLogRecord): boolean {\n return classifyActivity(r) !== 'idle';\n}\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = values.slice().sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\n/**\n * Reduce a bucket of samples to a group.\n *\n * A reading taken while the main thread was too blocked to deliver frames\n * carries fps 0. Letting those into a median would report a frame rate the\n * display never showed, so the median is taken over the measurable samples\n * only — but the stall is not thrown away, because a stall is the worst thing\n * in the log. It survives as `stalls`, and its frame time still sets\n * `worstMs`.\n */\nfunction group(records: PerfLogRecord[]): FpsGroup {\n const measured = records.filter(r => r.fps > 0);\n return {\n samples: records.length,\n medianFps: median(measured.map(r => r.fps)),\n worstMs: records.reduce((worst, r) => (r.worstMs > worst ? r.worstMs : worst), 0),\n stalls: records.length - measured.length,\n };\n}\n\n/** Bucket by a key, dropping records that have none. */\nfunction bucket<K>(records: PerfLogRecord[], keyOf: (r: PerfLogRecord) => K | null): Map<K, PerfLogRecord[]> {\n const map = new Map<K, PerfLogRecord[]>();\n for (const r of records) {\n const key = keyOf(r);\n if (key === null) continue;\n const existing = map.get(key);\n if (existing) existing.push(r); else map.set(key, [r]);\n }\n return map;\n}\n\n/** Groups worst-first. A group that stalled outright sorts above one that\n * merely ran slowly — `medianFps` is 0 there, which is already the bottom of\n * the order, and that is the correct place for it. */\nfunction rankWorstFirst<T extends FpsGroup>(groups: T[]): T[] {\n return groups.sort((a, b) => a.medianFps - b.medianFps);\n}\n\n/** Reduce a log to the handful of statements worth acting on. */\nexport function summariseLog(log: PerfLogRecord[]): LogSummary {\n const empty: LogSummary = {\n samples: 0,\n durationMs: 0,\n medianFps: 0,\n worstFrameMs: 0,\n verdictShare: { smooth: 0, gpu: 0, cpu: 0, unknown: 0 },\n interacting: null,\n idle: null,\n byActivity: [],\n byWindowCount: [],\n worstWindows: [],\n worstMenus: [],\n };\n if (!log.length) return empty;\n\n const verdictShare = { ...empty.verdictShare };\n for (const r of log) verdictShare[r.verdict] += 1 / log.length;\n\n const interacting = log.filter(isInteracting);\n const idle = log.filter(r => !isInteracting(r));\n\n return {\n samples: log.length,\n durationMs: log[log.length - 1].t - log[0].t,\n medianFps: median(log.filter(r => r.fps > 0).map(r => r.fps)),\n worstFrameMs: log.reduce((worst, r) => (r.worstMs > worst ? r.worstMs : worst), 0),\n verdictShare,\n interacting: interacting.length >= MIN_GROUP_SAMPLES ? group(interacting) : null,\n idle: idle.length >= MIN_GROUP_SAMPLES ? group(idle) : null,\n byActivity: rankWorstFirst(\n [...bucket(log, classifyActivity).entries()]\n .filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES)\n .map(([kind, rs]) => ({ kind, ...group(rs) })),\n ),\n byWindowCount: [...bucket(log, r => r.windows).entries()]\n .filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES)\n .map(([windows, rs]) => ({ windows, ...group(rs) }))\n .sort((a, b) => a.windows - b.windows),\n worstWindows: rankWorstFirst(\n [...bucket(log, r => r.active).entries()]\n .filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES)\n .map(([key, rs]) => ({ key, ...group(rs) })),\n ),\n worstMenus: rankWorstFirst(\n [...bucket(log, r => r.menuKey).entries()]\n .filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES)\n .map(([key, rs]) => ({ key, ...group(rs) })),\n ),\n };\n}\n\nconst CSV_COLUMNS: (keyof PerfLogRecord)[] = [\n 't', 'fps', 'frameMs', 'worstMs', 'blockedPct', 'heapMB',\n 'verdict', 'windows', 'active', 'clicks', 'keys', 'scrolls', 'dragMs',\n 'menus', 'submenus', 'menuKey', 'moveMs', 'resizeMs',\n];\n\n/** Flat CSV, for opening in a spreadsheet without writing any code. */\nexport function toCsv(log: PerfLogRecord[]): string {\n const cell = (value: unknown): string => {\n if (value === null || value === undefined) return '';\n const text = typeof value === 'number' ? String(Math.round(value * 10) / 10) : String(value);\n // Window and menu keys are app-supplied text and can contain a comma or a\n // quote — a section label is literally whatever the nav config says.\n return /[\",\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n };\n return [\n CSV_COLUMNS.join(','),\n ...log.map(r => CSV_COLUMNS.map(c => cell(r[c])).join(',')),\n ].join('\\n');\n}\n","/**\n * What machine the readings came off.\n *\n * A frame rate without a machine attached is half a report. \"GPU-bound\n * (compositing)\" means something very different on an Intel UHD 620 driving a\n * 4K panel than on an M3 Max, and the first question anyone triaging a\n * slowdown asks is which one they are looking at — a question the reporter is\n * usually the worst-placed person to answer, and often simply cannot.\n *\n * The user agent alone does not settle it. Chromium freezes its UA string, so\n * Windows 11 reports itself as Windows 10 and an ARM machine looks like an x86\n * one; and no UA string has ever named the GPU, which is the part that matters\n * most here. So this reads the specifics directly, from four sources:\n *\n * - **Synchronous navigator and screen fields** — cores, memory, panel,\n * network, display settings. Cheap, and occasionally withheld.\n * - **A WebGL context**, purely to ask the driver its own name. Created and\n * destroyed inside one call, at report time and never during measurement,\n * because a live context is exactly the sort of thing that would show up in\n * the numbers it is meant to explain.\n * - **Client hints and the battery**, both async, both unchanging, so both\n * are resolved once when the HUD mounts rather than while a report is being\n * assembled.\n * - **Media queries**, for the settings that change how much compositing the\n * browser is being asked to do in the first place.\n *\n * Everything is best-effort and every field degrades to null. Firefox and\n * Safari withhold `deviceMemory`; Safari has no client hints; a blocklisted\n * driver refuses WebGL. A report missing one line is a far smaller loss than a\n * report that failed to send, so nothing here is allowed to throw.\n */\n\n/** Async platform detail from `navigator.userAgentData`. */\nexport interface PlatformHints {\n /** 'macOS', 'Windows', 'Linux', … */\n platform: string | null;\n /** The real OS version, which the frozen UA string no longer carries. */\n platformVersion: string | null;\n /** 'arm' | 'x86' — an Intel Mac and an Apple Silicon Mac are not the same\n * machine and do not have the same compositing story. */\n architecture: string | null;\n /** Device model, on mobile. */\n model: string | null;\n /** Browser name and full version, e.g. 'Chrome 141.0.7390.55'. */\n browser: string | null;\n}\n\n/** Power state. A laptop in Low Power Mode is capped at 30 fps by the OS, which\n * is the single most common cause of \"it halved this afternoon\". */\nexport interface BatteryInfo {\n charging: boolean;\n /** 0–1. */\n level: number;\n}\n\n/** The parts that cannot be read synchronously, resolved once on mount. */\nexport interface AsyncEnvironment {\n hints: PlatformHints | null;\n battery: BatteryInfo | null;\n}\n\nexport interface PerfEnvironment {\n userAgent: string;\n /** Browser name and version from client hints; null outside Chromium, where\n * `userAgent` above is the fallback. */\n browser: string | null;\n platform: string | null;\n platformVersion: string | null;\n architecture: string | null;\n model: string | null;\n /** Logical cores. The shell is single-threaded, so this mostly says how much\n * else the machine can be doing at once. */\n cpuCores: number | null;\n /** Approximate RAM in GB. Deliberately coarse — the spec has browsers round\n * to a power of two and permits clamping to 8 to blunt fingerprinting, so\n * treat it as a floor (\"this much or more\"), not a measurement. Chromium\n * only; Firefox and Safari publish nothing. */\n deviceMemoryGB: number | null;\n /** The driver's own name for itself, e.g. 'Apple M3 Max' or\n * 'ANGLE (Intel, Intel(R) UHD Graphics 620 …)'. */\n gpu: string | null;\n gpuVendor: string | null;\n /** False when the browser fell back to software rendering — which explains a\n * GPU-bound verdict outright. */\n webglAvailable: boolean;\n screen: { width: number; height: number; dpr: number; colorDepth: number | null };\n /** The window, which is what actually gets composited — a maximised window on\n * a 4K panel and a small one are different amounts of work. */\n viewport: { width: number; height: number };\n /** Heap ceiling this tab was given, MB. Chromium only. */\n heapLimitMB: number | null;\n /** Effective connection class, downlink Mb/s and round-trip ms. Separates a\n * UI that is slow from a UI that is waiting. */\n network: { effectiveType: string | null; downlinkMbps: number | null; rttMs: number | null; saveData: boolean } | null;\n battery: BatteryInfo | null;\n /** Settings that change how much work the browser is being asked to do. */\n prefersReducedMotion: boolean;\n forcedColors: boolean;\n /** The shell's own \"reduce transparency\" — the first thing to suggest, and\n * the first thing to check has not already been tried. */\n reducedTransparency: boolean;\n /** Screens can be scaled; a report from a 4K panel at 200% is not the same as\n * one at 100%. */\n touchPoints: number | null;\n}\n\ninterface UADataLike {\n platform?: string;\n brands?: { brand: string; version: string }[];\n getHighEntropyValues?: (hints: string[]) => Promise<Record<string, unknown>>;\n}\n\ninterface ChromeMemoryLike {\n jsHeapSizeLimit: number;\n}\n\ninterface ConnectionLike {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n}\n\ninterface BatteryManagerLike {\n charging: boolean;\n level: number;\n}\n\n/** Chromium reports itself under several brands, most of them decoys (\"Not;A\n * Brand\") planted to break naive UA sniffing. Pick the real one. */\nfunction pickBrand(brands: { brand: string; version: string }[] | undefined): string | null {\n if (!brands?.length) return null;\n const real = brands.filter(b => !/not[^a-z]*a[^a-z]*brand/i.test(b.brand));\n // Chromium itself is the generic engine brand; the specific product (Chrome,\n // Edge, Opera) is what someone reproducing the report needs to install.\n const named = real.find(b => b.brand !== 'Chromium') ?? real[0];\n return named ? `${named.brand} ${named.version}` : null;\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === 'string' && value ? value : null;\n}\n\n/**\n * Resolve everything that needs a promise. Call once, keep the result — the\n * values cannot change for the life of the page, and the prompt some browsers\n * attach to high-entropy hints must not fire while someone is filing a report.\n *\n * Never rejects. A browser with no client hints and no battery API is the\n * normal case outside Chromium, not an error worth handling at the call site.\n */\nexport async function requestAsyncEnvironment(): Promise<AsyncEnvironment> {\n return { hints: await readHints(), battery: await readBattery() };\n}\n\nasync function readHints(): Promise<PlatformHints | null> {\n const uaData = (navigator as Navigator & { userAgentData?: UADataLike }).userAgentData;\n if (!uaData) return null;\n const base: PlatformHints = {\n platform: uaData.platform ?? null,\n platformVersion: null,\n architecture: null,\n model: null,\n browser: pickBrand(uaData.brands),\n };\n if (!uaData.getHighEntropyValues) return base;\n try {\n const high = await uaData.getHighEntropyValues([\n 'platform',\n 'platformVersion',\n 'architecture',\n 'model',\n 'fullVersionList',\n ]);\n const full = high.fullVersionList as { brand: string; version: string }[] | undefined;\n return {\n platform: asString(high.platform) ?? base.platform,\n platformVersion: asString(high.platformVersion),\n architecture: asString(high.architecture),\n model: asString(high.model),\n // The full list carries the build number; the low-entropy brands only\n // carry the major, which is not enough to match against a known bug.\n browser: pickBrand(full) ?? base.browser,\n };\n } catch {\n // The browser may decline the high-entropy set outright.\n return base;\n }\n}\n\nasync function readBattery(): Promise<BatteryInfo | null> {\n const getBattery = (navigator as Navigator & { getBattery?: () => Promise<BatteryManagerLike> }).getBattery;\n if (!getBattery) return null;\n try {\n const battery = await getBattery.call(navigator);\n return { charging: battery.charging, level: battery.level };\n } catch {\n return null;\n }\n}\n\n/**\n * Ask the GPU its name, then throw the context away.\n *\n * `WEBGL_debug_renderer_info` is the extension that returns the unmasked\n * string; without it `RENDERER` reports a generic sanitised name, which is\n * still worth having. The context is explicitly lost afterwards because\n * browsers cap how many may exist at once, and a diagnostic must not be the\n * thing that exhausts them.\n */\nexport function readGpu(): { renderer: string | null; vendor: string | null; available: boolean } {\n if (typeof document === 'undefined') return { renderer: null, vendor: null, available: false };\n try {\n const gl = document.createElement('canvas').getContext('webgl');\n if (!gl) return { renderer: null, vendor: null, available: false };\n const debug = gl.getExtension('WEBGL_debug_renderer_info');\n const renderer = debug ? gl.getParameter(debug.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER);\n const vendor = debug ? gl.getParameter(debug.UNMASKED_VENDOR_WEBGL) : gl.getParameter(gl.VENDOR);\n gl.getExtension('WEBGL_lose_context')?.loseContext();\n return { renderer: asString(renderer), vendor: asString(vendor), available: true };\n } catch {\n // A blocklisted driver, a headless browser, or WebGL disabled outright —\n // all of which are themselves an answer to \"why is compositing slow\".\n return { renderer: null, vendor: null, available: false };\n }\n}\n\nfunction matches(query: string): boolean {\n try {\n return window.matchMedia(query).matches;\n } catch {\n return false;\n }\n}\n\n/** Snapshot the machine. Synchronous — pass what `requestAsyncEnvironment`\n * resolved earlier, or null if it never arrived. */\nexport function readEnvironment(async_: AsyncEnvironment | null): PerfEnvironment {\n const nav = navigator as Navigator & { deviceMemory?: number; connection?: ConnectionLike };\n const memory = (performance as Performance & { memory?: ChromeMemoryLike }).memory;\n const hints = async_?.hints ?? null;\n const gpu = readGpu();\n const conn = nav.connection;\n return {\n userAgent: nav.userAgent,\n browser: hints?.browser ?? null,\n platform: hints?.platform ?? null,\n platformVersion: hints?.platformVersion ?? null,\n architecture: hints?.architecture ?? null,\n model: hints?.model ?? null,\n cpuCores: typeof nav.hardwareConcurrency === 'number' ? nav.hardwareConcurrency : null,\n deviceMemoryGB: typeof nav.deviceMemory === 'number' ? nav.deviceMemory : null,\n gpu: gpu.renderer,\n gpuVendor: gpu.vendor,\n webglAvailable: gpu.available,\n screen: {\n width: screen.width,\n height: screen.height,\n dpr: window.devicePixelRatio,\n colorDepth: typeof screen.colorDepth === 'number' ? screen.colorDepth : null,\n },\n viewport: { width: window.innerWidth, height: window.innerHeight },\n heapLimitMB: memory ? Math.round(memory.jsHeapSizeLimit / 1048576) : null,\n network: conn\n ? {\n effectiveType: asString(conn.effectiveType),\n downlinkMbps: typeof conn.downlink === 'number' ? conn.downlink : null,\n rttMs: typeof conn.rtt === 'number' ? conn.rtt : null,\n saveData: conn.saveData === true,\n }\n : null,\n battery: async_?.battery ?? null,\n prefersReducedMotion: matches('(prefers-reduced-motion: reduce)'),\n forcedColors: matches('(forced-colors: active)'),\n reducedTransparency: document.documentElement.classList.contains('rosh-reduce-transparency'),\n touchPoints: typeof nav.maxTouchPoints === 'number' ? nav.maxTouchPoints : null,\n };\n}\n\n/**\n * One line naming the machine, for a report title or a bug-tracker\n * description — the place where a reader decides whether this report is about\n * a slow machine or a slow application. The full record is in the attachment;\n * this is the digest.\n *\n * Omits what it does not know rather than printing \"unknown\": a line of\n * absences reads as a broken probe, when in truth Firefox simply does not\n * publish RAM.\n */\nexport function describeMachine(env: PerfEnvironment): string {\n const parts: string[] = [];\n if (env.browser) parts.push(env.browser);\n const os = [env.platform, env.platformVersion].filter(Boolean).join(' ');\n if (os) parts.push(env.architecture ? `${os} (${env.architecture})` : os);\n if (env.gpu) parts.push(env.gpu);\n else if (!env.webglAvailable) parts.push('no WebGL (software rendering)');\n if (env.cpuCores) parts.push(`${env.cpuCores} cores`);\n if (env.deviceMemoryGB) parts.push(`${env.deviceMemoryGB}GB+ RAM`);\n parts.push(`${env.screen.width}×${env.screen.height} @${env.screen.dpr}x`);\n // Flags only when they are true — each one is a live explanation for a low\n // frame rate, and a list of \"off\" states is noise.\n if (env.battery && !env.battery.charging) parts.push(`on battery ${Math.round(env.battery.level * 100)}%`);\n if (env.reducedTransparency) parts.push('reduce transparency on');\n if (env.prefersReducedMotion) parts.push('reduced motion');\n return parts.join(' · ');\n}\n","/**\n * Desktop performance HUD — an opt-in overlay that measures where the UI is\n * actually spending its time, so \"it feels laggy\" can become a number someone\n * can act on, and a report someone can file.\n *\n * Filing is the end of the story, not an export: the person who can see the\n * jank is rarely the person who can fix it, and a downloaded JSON that has to\n * be found, attached and explained mostly does not get sent. One button\n * freezes the log, asks the one question a log cannot answer — what were you\n * doing? — and hands both to the host's feedback channel.\n *\n * Two rules shape the implementation, both about not corrupting the reading:\n *\n * 1. **The HUD must be nearly free to render.** The rAF loop and the activity\n * counters write to refs and never set state; a 500ms interval is the only\n * thing that re-renders, and the session log lives in a ref too — only its\n * size is state, because only its size is on screen. A HUD that\n * re-rendered per frame would be measuring itself.\n * 2. **No frosted glass on the panel.** Every other surface in the shell\n * uses `glassStyle()`, but a perf overlay that costs a 40px backdrop blur\n * would add exactly the GPU load it is trying to attribute. Solid\n * background, deliberately.\n *\n * Caveat worth knowing when reading the numbers: a running rAF loop keeps the\n * browser rendering continuously, so an idle desktop with the HUD open is\n * doing more work than an idle desktop without it. Read the numbers while\n * actually using the UI — scrolling, dragging a window, opening a menu — which\n * is when the interesting jank happens anyway.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { classify, summariseFrames, type PerfReading, type Verdict } from './perfVerdict';\nimport { appendRecord, summariseLog, type LogSummary, type PerfLogRecord } from './perfLog';\nimport { drainPerfEvents, setPerfCollecting } from './perfEvents';\nimport {\n readEnvironment,\n requestAsyncEnvironment,\n type AsyncEnvironment,\n type PerfEnvironment,\n} from './perfEnvironment';\n\n/** How often the accumulated frame data is turned into a render and a log record. */\nconst FLUSH_MS = 500;\n/** Rolling window of frames each reading is computed from. */\nconst WINDOW_MS = 1000;\n/** Sparkline width, in flush samples — 40 × 500ms ≈ 20s of history, enough to\n * catch intermittent hitches (a periodic refetch, a GC pause) that a single\n * instantaneous number hides. */\nconst HISTORY = 40;\n/** The log is mirrored to localStorage this often, so a reload or a crash does\n * not throw away a session someone spent ten minutes reproducing. Throttled\n * rather than per-flush because serialising thousands of records twice a\n * second would itself become main-thread work the HUD would then report. */\nconst PERSIST_EVERY_MS = 10_000;\nconst LOG_STORAGE_KEY = 'react-os-shell:perf-log';\n/** Longest gap between two pointer moves still counted as drag time. Far above\n * one frame even on a machine in trouble, so a real drag is never clipped; a\n * gap beyond it means the pointer stopped. */\nconst MAX_DRAG_GAP_MS = 100;\n\n/** Chrome exposes heap numbers off `performance`; nothing else does, and it is\n * not in any spec — hence the local shape rather than a lib type. */\ninterface ChromeMemory {\n usedJSHeapSize: number;\n jsHeapSizeLimit: number;\n}\n\nconst VERDICT_STYLES: Record<Verdict['kind'], { dot: string; text: string }> = {\n smooth: { dot: 'bg-emerald-400', text: 'text-emerald-300' },\n gpu: { dot: 'bg-amber-400', text: 'text-amber-300' },\n cpu: { dot: 'bg-sky-400', text: 'text-sky-300' },\n unknown: { dot: 'bg-gray-400', text: 'text-gray-300' },\n};\n\n/** Count the open shell windows and identify the topmost one. Read from the\n * DOM rather than threaded through context because that is how the shell\n * already counts its own windows (Layout, WindowManager), and a diagnostic\n * should observe what is really on screen rather than trust a mirror of it. */\nfunction readWindows(): { windows: number; active: string | null } {\n if (typeof document === 'undefined') return { windows: 0, active: null };\n const panels = document.querySelectorAll<HTMLElement>('[data-modal-panel]');\n let active: string | null = null;\n let topZ = -Infinity;\n panels.forEach(panel => {\n const z = parseInt(window.getComputedStyle(panel).zIndex, 10);\n // `auto` parses to NaN; fall back to DOM order, which is paint order.\n const rank = Number.isFinite(z) ? z : 0;\n if (rank >= topZ) {\n topZ = rank;\n active = panel.dataset.windowKey ?? panel.dataset.modalId ?? null;\n }\n });\n return { windows: panels.length, active };\n}\n\n/** A finished report, handed to the host to file. The JSON is pre-serialised\n * because the host's job is to attach it, not to re-derive it; `summary` and\n * `verdict` come along so a host can title or route the report without\n * parsing the attachment back apart. */\nexport interface PerfReport {\n /** What the user typed about what they were doing. May be empty. */\n message: string;\n /** Suggested attachment filename, stamped with the local time. */\n filename: string;\n /** The whole report — environment, summary and every raw record. */\n json: string;\n summary: LogSummary;\n /** The HUD's current headline, e.g. \"GPU-bound (compositing)\". */\n verdict: string;\n /** The machine the readings came off — GPU, cores, memory, OS, screen. A\n * verdict of \"GPU-bound\" is not actionable until you know which GPU. */\n environment: PerfEnvironment;\n}\n\nexport interface PerfStatsProps {\n /** Dismiss handler — the shell wires this to turn the pref back off, so the\n * HUD can be closed from itself rather than only from Preferences. */\n onClose?: () => void;\n /** File the report through the host's own feedback channel — the whole point\n * of the HUD, since a log that reaches nobody fixes nothing. Rejecting\n * surfaces the error and keeps the composer open with the text intact.\n * Without it the button downloads the same JSON instead, so the shell stays\n * usable standalone. */\n onSubmit?: (report: PerfReport) => void | Promise<void>;\n className?: string;\n}\n\nexport default function PerfStats({ onClose, onSubmit, className = '' }: PerfStatsProps) {\n const framesRef = useRef<number[]>([]);\n const blockedMsRef = useRef(0);\n const activityRef = useRef({ clicks: 0, keys: 0, scrolls: 0, dragMs: 0 });\n const dragRef = useRef({ down: false, since: 0 });\n const logRef = useRef<PerfLogRecord[]>([]);\n const startedAtRef = useRef(0);\n const persistedAtRef = useRef(0);\n\n /** The log as it stood when the composer opened. Frozen there so the twenty\n * seconds someone spends typing \"the second-level menu stutters\" do not\n * become twenty samples of typing at the end of the very report that\n * sentence is about. */\n const snapshotRef = useRef<PerfLogRecord[] | null>(null);\n /** Client hints and battery state are async and unchanging, so they are\n * fetched once here and read synchronously when a report is built. */\n const envRef = useRef<AsyncEnvironment | null>(null);\n\n const [longTaskSupported, setLongTaskSupported] = useState(false);\n const [reading, setReading] = useState<PerfReading>({ fps: 0, frameMs: 0, worstMs: 0, blockedPct: null });\n const [history, setHistory] = useState<number[]>([]);\n const [heap, setHeap] = useState<{ usedMB: number; limitMB: number } | null>(null);\n const [logSize, setLogSize] = useState(0);\n const [composing, setComposing] = useState(false);\n const [message, setMessage] = useState('');\n const [sending, setSending] = useState(false);\n const [sendError, setSendError] = useState<string | null>(null);\n\n // ── Interaction marks: menus and window gestures only accumulate while the\n // HUD is up. See perfEvents for why a counter left running would lie.\n useEffect(() => {\n setPerfCollecting(true);\n return () => setPerfCollecting(false);\n }, []);\n\n // ── Machine detail. Resolved on mount rather than at report time: the values\n // cannot change, and some browsers gate high-entropy hints behind a\n // prompt that must not fire while someone is filing a report.\n useEffect(() => {\n let live = true;\n requestAsyncEnvironment().then(env => { if (live) envRef.current = env; });\n return () => { live = false; };\n }, []);\n\n // ── Frame sampling: refs only, so this never triggers a render ──\n useEffect(() => {\n let raf = 0;\n const tick = (now: number) => {\n const frames = framesRef.current;\n frames.push(now);\n const cutoff = now - WINDOW_MS;\n while (frames.length && frames[0] < cutoff) frames.shift();\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, []);\n\n // ── Long tasks: the signal that separates a busy main thread from a busy GPU ──\n useEffect(() => {\n if (typeof PerformanceObserver === 'undefined') return;\n let observer: PerformanceObserver | undefined;\n try {\n observer = new PerformanceObserver(list => {\n for (const entry of list.getEntries()) blockedMsRef.current += entry.duration;\n });\n observer.observe({ entryTypes: ['longtask'] });\n setLongTaskSupported(true);\n } catch {\n // Safari has no `longtask` entry type. Leaving `longTaskSupported`\n // false makes the verdict report \"cause unknown\" rather than silently\n // attributing every dropped frame to the GPU.\n return;\n }\n return () => observer?.disconnect();\n }, []);\n\n // ── Activity: what the user was doing while the frames were being measured ──\n useEffect(() => {\n // Every handler reads `activityRef.current` at call time rather than\n // closing over the object. The flush zeroes these counters in place for\n // the same reason: an earlier version swapped in a fresh object each\n // flush, which silently orphaned the one these listeners were still\n // incrementing — the log kept recording zero activity forever after the\n // first interval, while looking perfectly healthy.\n const onPointerDown = () => {\n activityRef.current.clicks++;\n dragRef.current = { down: true, since: performance.now() };\n };\n const onPointerMove = () => {\n if (!dragRef.current.down) return;\n const now = performance.now();\n const gap = now - dragRef.current.since;\n dragRef.current.since = now;\n // Only time the pointer actually spent moving. Without the cap, a press\n // held still for five seconds and then nudged credits all five to the\n // move it ended on — which is how a 500ms interval came to report 5,004ms\n // of dragging, a number that cannot be true and quietly discredits the\n // column beside it. A gap this long is a stationary press, not a drag.\n if (gap <= MAX_DRAG_GAP_MS) activityRef.current.dragMs += gap;\n };\n const onPointerUp = () => { dragRef.current.down = false; };\n const onKeyDown = () => { activityRef.current.keys++; };\n const onWheel = () => { activityRef.current.scrolls++; };\n\n // Capture phase, so a handler that stops propagation cannot hide activity\n // from the log; passive, so the HUD never delays the very input it times.\n const opts = { capture: true, passive: true } as const;\n window.addEventListener('pointerdown', onPointerDown, opts);\n window.addEventListener('pointermove', onPointerMove, opts);\n window.addEventListener('pointerup', onPointerUp, opts);\n window.addEventListener('pointercancel', onPointerUp, opts);\n window.addEventListener('keydown', onKeyDown, opts);\n window.addEventListener('wheel', onWheel, opts);\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, opts);\n window.removeEventListener('pointermove', onPointerMove, opts);\n window.removeEventListener('pointerup', onPointerUp, opts);\n window.removeEventListener('pointercancel', onPointerUp, opts);\n window.removeEventListener('keydown', onKeyDown, opts);\n window.removeEventListener('wheel', onWheel, opts);\n };\n }, []);\n\n const persist = useCallback(() => {\n try {\n localStorage.setItem(LOG_STORAGE_KEY, JSON.stringify(logRef.current));\n } catch {\n // A full or disabled localStorage must never take the HUD down — the\n // in-memory log and the exports still work without it.\n }\n }, []);\n\n // ── Durability: the throttle above can leave up to PERSIST_EVERY_MS of\n // unsaved tail, and the tail is exactly the part someone was watching\n // when they gave up and closed the tab. Flush on the way out. `pagehide`\n // rather than `beforeunload` because it also fires when a tab is frozen\n // or restored from the back/forward cache, which `beforeunload` misses.\n useEffect(() => {\n const onHide = () => persist();\n window.addEventListener('pagehide', onHide);\n document.addEventListener('visibilitychange', onHide);\n return () => {\n window.removeEventListener('pagehide', onHide);\n document.removeEventListener('visibilitychange', onHide);\n persist();\n };\n }, [persist]);\n\n // ── Flush: the only thing here that renders ──\n useEffect(() => {\n const id = setInterval(() => {\n const now = performance.now();\n if (!startedAtRef.current) startedAtRef.current = now;\n\n const frames = summariseFrames(framesRef.current);\n const blockedPct = longTaskSupported\n ? Math.min(100, (blockedMsRef.current / FLUSH_MS) * 100)\n : null;\n blockedMsRef.current = 0;\n\n const memory = (performance as Performance & { memory?: ChromeMemory }).memory;\n const heapMB = memory ? memory.usedJSHeapSize / 1048576 : null;\n const nextReading: PerfReading = { ...frames, blockedPct };\n\n const activity = activityRef.current;\n const events = drainPerfEvents();\n const { windows, active } = readWindows();\n logRef.current = appendRecord(logRef.current, {\n t: Math.round(now - startedAtRef.current),\n ...frames,\n blockedPct,\n heapMB,\n verdict: classify(nextReading).kind,\n windows,\n active,\n clicks: activity.clicks,\n keys: activity.keys,\n scrolls: activity.scrolls,\n dragMs: Math.round(activity.dragMs),\n menus: events.menus,\n submenus: events.submenus,\n menuKey: events.menuKey,\n moveMs: Math.round(events.moveMs),\n resizeMs: Math.round(events.resizeMs),\n });\n // Zero in place — never reassign. See the listener effect above.\n activity.clicks = 0;\n activity.keys = 0;\n activity.scrolls = 0;\n activity.dragMs = 0;\n\n // Zero means \"never written\", so the first flush always persists. Timing\n // the throttle off `performance.now()` alone would measure from page\n // load, not from when logging started — opening the HUD on a fresh page\n // would then leave the log unsaved for the first ten seconds, while\n // opening it on a long-lived tab would save on the very first flush.\n if (!persistedAtRef.current || now - persistedAtRef.current >= PERSIST_EVERY_MS) {\n persistedAtRef.current = now;\n persist();\n }\n\n setReading(nextReading);\n setHistory(prev => [...prev, frames.fps].slice(-HISTORY));\n setHeap(memory ? { usedMB: memory.usedJSHeapSize / 1048576, limitMB: memory.jsHeapSizeLimit / 1048576 } : null);\n setLogSize(logRef.current.length);\n }, FLUSH_MS);\n return () => clearInterval(id);\n }, [longTaskSupported, persist]);\n\n /** Freeze the log and open the composer. */\n const beginReport = useCallback(() => {\n snapshotRef.current = logRef.current.slice();\n setSendError(null);\n setComposing(true);\n }, []);\n\n const verdict = classify(reading);\n\n /** Build the report from the frozen snapshot. The summary rides alongside the\n * raw records so whoever opens the file gets the conclusion without having\n * to run the analysis themselves, and the user's own sentence goes in the\n * file too — the attachment has to stand alone once it is detached from the\n * message that carried it. */\n const buildReport = useCallback((): PerfReport => {\n const records = snapshotRef.current ?? logRef.current;\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n const summary = summariseLog(records);\n const environment = readEnvironment(envRef.current);\n return {\n message,\n filename: `perf-log-${stamp}.json`,\n summary,\n environment,\n verdict: verdict.label,\n json: JSON.stringify(\n {\n generatedAt: new Date().toISOString(),\n message,\n verdict: verdict.label,\n environment,\n summary,\n records,\n },\n null,\n 2,\n ),\n };\n }, [message, verdict.label]);\n\n /** Fallback when no host channel is wired: the same JSON, to disk. */\n const downloadReport = useCallback((report: PerfReport) => {\n const url = URL.createObjectURL(new Blob([report.json], { type: 'application/json' }));\n const link = document.createElement('a');\n link.href = url;\n link.download = report.filename;\n link.click();\n URL.revokeObjectURL(url);\n }, []);\n\n const send = useCallback(async () => {\n const report = buildReport();\n setSending(true);\n setSendError(null);\n try {\n if (onSubmit) await onSubmit(report);\n else downloadReport(report);\n snapshotRef.current = null;\n setMessage('');\n setComposing(false);\n } catch (err) {\n // Keep the composer open with the text intact — retyping a description\n // of something that has already stopped happening is how a report stops\n // getting filed at all.\n setSendError(err instanceof Error && err.message ? err.message : 'Could not send. Try again.');\n } finally {\n setSending(false);\n }\n }, [buildReport, downloadReport, onSubmit]);\n\n const styles = VERDICT_STYLES[verdict.kind];\n const peak = Math.max(60, ...history);\n const loggedSeconds = Math.round((logSize * FLUSH_MS) / 1000);\n const sendLabel = onSubmit ? 'Send' : 'Download';\n const reportSamples = snapshotRef.current?.length ?? logSize;\n\n return (\n <div\n className={`w-56 rounded-lg border border-white/15 bg-[#11111b]/95 px-3 py-2 font-mono text-[10px] text-white/80 shadow-lg select-none ${className}`}\n /* No backdrop-filter here on purpose — see the module docstring. */\n role=\"status\"\n aria-live=\"off\"\n aria-label=\"Performance statistics\"\n >\n <div className=\"mb-1.5 flex items-center justify-between\">\n <span className=\"text-[9px] uppercase tracking-wider text-white/40\">Performance</span>\n {onClose && (\n <button\n onClick={onClose}\n className=\"-mr-1 px-1 leading-none text-white/40 transition-colors hover:text-white/90\"\n aria-label=\"Hide performance statistics\"\n >\n ×\n </button>\n )}\n </div>\n\n <div className=\"flex items-baseline justify-between\">\n <span className={`text-base font-semibold tabular-nums ${styles.text}`}>\n {reading.fps ? reading.fps.toFixed(0) : '—'}\n <span className=\"ml-1 text-[10px] font-normal text-white/40\">fps</span>\n </span>\n <span className=\"tabular-nums text-white/50\">\n {reading.frameMs ? `${reading.frameMs.toFixed(1)} ms` : '—'}\n </span>\n </div>\n\n {/* Frame-rate history. Plain divs: cheap to lay out, and a shape is far\n quicker to read than a column of numbers when hunting a periodic hitch. */}\n <div className=\"mt-1.5 flex h-5 items-end gap-px\" aria-hidden=\"true\">\n {Array.from({ length: HISTORY }, (_, i) => {\n const value = history[history.length - HISTORY + i];\n return (\n <div\n key={i}\n className={`flex-1 rounded-sm ${value === undefined ? 'bg-white/5' : styles.dot}`}\n style={{ height: value === undefined ? '2px' : `${Math.max(6, (value / peak) * 100)}%` }}\n />\n );\n })}\n </div>\n\n <dl className=\"mt-2 space-y-0.5\">\n <Row label=\"worst frame\" value={reading.worstMs ? `${reading.worstMs.toFixed(0)} ms` : '—'} />\n <Row\n label=\"main thread\"\n value={reading.blockedPct === null ? 'n/a' : `${reading.blockedPct.toFixed(0)}% blocked`}\n />\n <Row\n label=\"JS heap\"\n value={heap ? `${heap.usedMB.toFixed(0)} / ${heap.limitMB.toFixed(0)} MB` : 'n/a'}\n />\n </dl>\n\n <div className=\"mt-2 border-t border-white/10 pt-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <span className={`h-1.5 w-1.5 shrink-0 rounded-full ${styles.dot}`} aria-hidden=\"true\" />\n <span className={`font-semibold ${styles.text}`}>{verdict.label}</span>\n </div>\n <p className=\"mt-0.5 leading-snug text-white/45\">{verdict.detail}</p>\n </div>\n\n <div className=\"mt-2 border-t border-white/10 pt-1.5\">\n {composing ? (\n /* Composer. `select-text` because the panel as a whole is\n `select-none` — without it the user cannot correct their own\n sentence. */\n <div className=\"select-text space-y-1.5\">\n <label className=\"block text-white/40\" htmlFor=\"perf-report-message\">\n What were you doing?\n </label>\n <textarea\n id=\"perf-report-message\"\n value={message}\n onChange={e => setMessage(e.target.value)}\n rows={3}\n autoFocus\n placeholder=\"e.g. opening the second-level menu stutters\"\n className=\"w-full resize-none rounded border border-white/15 bg-black/40 px-1.5 py-1 font-mono text-[10px] text-white/90 placeholder:text-white/25 focus:border-white/40 focus:outline-none\"\n />\n {sendError && <p className=\"leading-snug text-rose-300\">{sendError}</p>}\n <div className=\"flex items-center justify-between\">\n {/* Just the count — \"samples attached\" wraps to a second line in\n the panel's 224px and shoves the buttons down. */}\n <span className=\"text-white/35\">{reportSamples} samples</span>\n <span className=\"flex gap-1\">\n <button\n onClick={() => { setComposing(false); snapshotRef.current = null; setSendError(null); }}\n disabled={sending}\n className=\"rounded border border-white/15 px-1.5 py-0.5 text-white/50 transition-colors hover:border-white/30 hover:text-white disabled:opacity-40\"\n >\n Cancel\n </button>\n <button\n onClick={send}\n disabled={sending}\n className=\"rounded border border-white/30 bg-white/10 px-1.5 py-0.5 text-white/90 transition-colors hover:bg-white/20 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {sending ? 'Sending…' : sendLabel}\n </button>\n </span>\n </div>\n </div>\n ) : (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-white/35\">\n log {logSize} · {loggedSeconds < 60 ? `${loggedSeconds}s` : `${Math.round(loggedSeconds / 60)}m`}\n </span>\n <button\n onClick={beginReport}\n disabled={!logSize}\n className=\"rounded border border-white/15 px-1.5 py-0.5 text-white/60 transition-colors hover:border-white/30 hover:text-white disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {onSubmit ? 'Report this' : 'Save report'}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-baseline justify-between gap-2\">\n <dt className=\"text-white/40\">{label}</dt>\n <dd className=\"tabular-nums text-white/70\">{value}</dd>\n </div>\n );\n}\n","/**\n * INTERNAL stub — Desktop's What's New modal references the consumer-side\n * changelog. The package ships no built-in changelog; the consumer wires\n * their own through `DesktopHostConfig.productChangelog` (the What's New\n * dialog reads it first, and this empty default keeps the import compiling\n * when they don't). Layout's `branding` prop carries the rest of the visual\n * identity — name, logo, tagline.\n */\nexport interface ChangelogEntry {\n version: string;\n date: string;\n changes: string[];\n}\nconst changelog: ChangelogEntry[] = [];\nexport default changelog;\n","import { useState, useRef, useEffect, useCallback, createContext, useContext, type ReactNode } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useWindowManager } from './WindowManager';\nimport { useShellStrings } from './strings';\nimport { useShellPrefs } from './ShellPrefs';\nimport Modal from './Modal';\nimport MarkdownLite from './Markdown';\nimport WidgetManager from './WidgetManager';\nimport PerfStats, { type PerfReport } from './PerfStats';\nimport { APP_VERSION } from '../version';\nimport changelog, { type ChangelogEntry } from '../changelog';\nimport toast from './toast';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport { formatDate } from '../utils/date';\nimport {\n openPreviewFile,\n PREVIEW_OPENED_EVENT,\n type PreviewFileKind,\n type PreviewOpenedDetail,\n} from '../utils/openPreviewFile';\n\n// Icon tiles, entity-icon config and the Files-app bridge live in\n// desktopIcons.tsx so Files can share them without importing Desktop.\nimport {\n FileIconTile,\n FolderGlyph,\n publishDesktopFolders,\n requestFilesDesktopFolderView,\n requestFilesTrashView,\n type DesktopItem,\n} from './desktopIcons';\n\nconst DOCUMENTS_FOLDER_ID = 'documents';\nconst DOCUMENTS_FOLDER_NAME = 'Recent Documents';\n\ninterface DesktopFolder {\n id: string;\n name: string;\n x?: number;\n y?: number;\n}\n\nconst GRID = 90; // snap grid size\n\nfunction snapToGrid(x: number, y: number) {\n return { x: Math.round(x / GRID) * GRID, y: Math.round(y / GRID) * GRID };\n}\n\n// ── Consumer-supplied desktop config ────────────────────────────────────────\n//\n// Desktop talks to two consumer-specific things:\n// 1. A sticky-note ref resolver — turns `PREFIX#NUMBER` into an entity\n// window-registry key + id. Implementations look up numbering configs\n// and search the consumer's REST API.\n// 2. Persistence callbacks — where to save the user's reordered shortcuts,\n// created folders, snap toggle, etc. The shell hands the new array; the\n// consumer commits it (server profile, localStorage, whatever).\n//\n// Both default to no-ops, so the desktop renders as a static surface when no\n// provider is mounted.\n\nexport interface StickyEntityRef {\n /** Window-registry key used by `openEntity`. */\n entityType: string;\n entityId: string;\n /** Optional human-readable label (defaults to `${prefix}#${number}`). */\n label?: string;\n /** Optional pre-fetched entity payload passed to openEntity as snapshot. */\n snapshot?: unknown;\n}\n\nexport type StickyResolver = (prefix: string, number: string) => Promise<StickyEntityRef | null>;\n\n/** Optional items in the desktop right-click menu that a consumer can hide via\n * {@link DesktopHostConfig.hiddenContextMenuItems} — e.g. when they're surfaced\n * under Preferences instead. `'customization'` is the Preferences/Customization\n * shortcut, `'favorites'` the Favorites shortcut, `'about'` the About item,\n * `'perf-stats'` the performance-overlay toggle. */\nexport type DesktopContextMenuItem = 'customization' | 'favorites' | 'about' | 'perf-stats';\n\nexport interface DesktopHostConfig {\n /** Product name shown in the About dialog and desktop context menu. */\n productName?: string;\n /** Tagline shown under the product name in the About dialog. */\n productTagline?: string;\n /** Icon URL shown in the About dialog. Defaults to `/favicon.svg`. */\n productIcon?: string;\n /** Version string shown on the desktop watermark and About dialog. Falls\n * back to the react-os-shell package version if omitted. */\n productVersion?: string;\n /** Changelog rendered in the \"What's New\" dialog. Hidden when omitted. */\n productChangelog?: ChangelogEntry[];\n /** Copyright line in the About dialog footer. Hidden when omitted. */\n productCopyright?: string;\n /** Website URL in the About dialog footer. Hidden when omitted. */\n productWebsite?: string;\n /** Wallpaper picker options for the Customization settings page. */\n wallpapers?: { src: string; label: string }[];\n /** Resolves sticky-note refs (e.g. \"SO#27150\") to window-registry coords. */\n stickyResolver?: StickyResolver;\n /** Persists the user's desktop shortcut list. */\n saveShortcuts?: (items: DesktopItem[]) => void | Promise<void>;\n /** Persists the user's folder list. */\n saveFolders?: (folders: DesktopFolder[]) => void | Promise<void>;\n /** Persists the snap-to-grid preference. */\n saveSnap?: (snap: boolean) => void | Promise<void>;\n /** Persists the user's notepad / sticky-note content. */\n saveNotes?: (notes: unknown[]) => void | Promise<void>;\n /** Desktop right-click menu items to hide (all shown by default). Pass keys\n * here when the consumer surfaces them elsewhere — e.g. under Preferences. */\n hiddenContextMenuItems?: DesktopContextMenuItem[];\n /** Open the consumer's own \"report a bug / suggestion\" UI. When set, the\n * desktop and taskbar right-click menus show a \"Suggestion or Bug\" item that\n * calls this. Lets a consumer that files feedback natively (the shell itself\n * dropped bug reporting in v3.0.0) surface the familiar right-click entry. */\n onReportBug?: () => void;\n /** File a performance report from the desktop perf HUD through the same\n * feedback channel, with the session log attached. Unset, the HUD's button\n * downloads the report instead — which is a strictly worse outcome, because\n * a file on someone's Downloads folder is not a bug report. Rejecting shows\n * the error in the HUD and keeps what the user typed. */\n onSubmitPerfReport?: (report: PerfReport) => void | Promise<void>;\n}\n\nconst DesktopHostContext = createContext<DesktopHostConfig>({});\n\nexport function DesktopHostProvider({ value, children }: { value: DesktopHostConfig; children: ReactNode }) {\n return <DesktopHostContext.Provider value={value}>{children}</DesktopHostContext.Provider>;\n}\n\nexport function useDesktopHost(): DesktopHostConfig {\n return useContext(DesktopHostContext);\n}\n\n/**\n * The taskbar's EFFECTIVE position and thickness, for the desktop furniture\n * anchored to whichever corner it leaves free — the Trash tile below, and the\n * version watermark.\n *\n * Read from the custom properties `Layout` publishes on `<html>`, not from\n * `prefs.taskbar_position`, for two reasons: those carry the EFFECTIVE values\n * (sidebar mode forces the taskbar horizontal whatever the preference says),\n * and a `<Desktop>` mounted without a `<Layout>` — which is an exported,\n * supported shape — has no taskbar at all and no preference that says so.\n *\n * They are written in an effect, so the first render of a fresh mount reads\n * zero and the corner settles on the next one. That is the behaviour the Trash\n * has always had; the watermark now shares it rather than the two disagreeing.\n */\nfunction taskbarMetrics() {\n const cs = typeof document !== 'undefined' ? getComputedStyle(document.documentElement) : null;\n const position = (cs?.getPropertyValue('--taskbar-position') || 'bottom').trim();\n const vertical = position === 'left' || position === 'right';\n const height = parseInt(cs?.getPropertyValue('--taskbar-height') || '0') || 0;\n const width = parseInt(cs?.getPropertyValue('--taskbar-width') || '0') || 0;\n return { position, vertical, height, width };\n}\n\nexport default function Desktop({ profile }: { profile: any }) {\n const shellStrings = useShellStrings();\n const queryClient = useQueryClient();\n const { openEntity, openPage } = useWindowManager();\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Read desktop preferences from the consumer prefs adapter so they stay\n // in sync with what apps like Notepad write. Some legacy code paths\n // also expect them under profile.preferences — fall back to that for\n // consumers who haven't migrated.\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs = { ...(profile?.preferences || {}), ...shellPrefs };\n const favDocs: DesktopItem[] = prefs.favorite_documents || [];\n // \"Recent Documents\" is a system folder: like the Trash it is always on the\n // desktop and cannot be deleted or renamed. Injected at render rather than\n // persisted so it exists from first load even on an empty profile; a stored\n // copy (when present) contributes its position while the canonical name\n // wins — which also migrates pre-2.6 desktops whose stored copy is still\n // called \"Documents\".\n const storedFolders: DesktopFolder[] = prefs.desktop_folders || [];\n const folders: DesktopFolder[] = storedFolders.some(f => f.id === DOCUMENTS_FOLDER_ID)\n ? storedFolders.map(f => f.id === DOCUMENTS_FOLDER_ID ? { ...f, name: DOCUMENTS_FOLDER_NAME } : f)\n : [...storedFolders, { id: DOCUMENTS_FOLDER_ID, name: DOCUMENTS_FOLDER_NAME }];\n const snapEnabled: boolean = prefs.desktop_snap ?? false;\n\n // Sticky notes from notepad\n interface StickyNote { id: string; title: string; content: string; color: string; sticky: boolean; sticky_x?: number; sticky_y?: number; sticky_w?: number; sticky_h?: number; sticky_on_top?: boolean; sticky_anchor?: 'left' | 'right'; updated_at: string; }\n const allNotes: StickyNote[] = prefs.notepad_notes || [];\n const stickyNotes = allNotes.filter(n => n.sticky);\n\n // ── Entity reference support for sticky notes ──\n // The PREFIX#NUMBER → entity lookup is consumer-supplied; the shell only\n // calls the resolver and hands the result to openEntity().\n const host = useDesktopHost();\n const hiddenMenuItems = host.hiddenContextMenuItems ?? [];\n const openStickyRef = async (prefix: string, number: string) => {\n const refNum = `${prefix}#${number}`;\n if (!host.stickyResolver) { toast.error(`Unknown reference: ${refNum}`); return; }\n try {\n const result = await host.stickyResolver(prefix, number);\n if (result) openEntity(result.entityType, result.entityId, result.snapshot, result.label ?? refNum);\n else toast.error(`${refNum} not found`);\n } catch {\n toast.error(`Failed to open ${refNum}`);\n }\n };\n\n const toggleStickyCheckbox = (noteId: string, charIndex: number) => {\n const note = allNotes.find(n => n.id === noteId);\n if (!note) return;\n const content = note.content;\n const match = content.slice(charIndex).match(/^\\[([ xX]?)\\]/);\n if (!match) return;\n const isChecked = match[1] === 'x' || match[1] === 'X';\n const replacement = isChecked ? '[ ]' : '[x]';\n const updated = content.slice(0, charIndex) + replacement + content.slice(charIndex + match[0].length);\n saveNotes(allNotes.map(n => n.id === noteId ? { ...n, content: updated, updated_at: new Date().toISOString() } : n));\n };\n\n const renderStickyContent = (noteId: string, text: string): ReactNode[] => {\n if (!text) return [];\n const lines = text.split('\\n');\n let charOffset = 0;\n return lines.map((line, li) => {\n const lineStart = charOffset;\n charOffset += line.length + 1;\n const tokens: { idx: number; len: number; render: () => ReactNode }[] = [];\n\n // Entity references — rendered as clickable when a resolver is configured;\n // if the resolver returns null at click-time the user sees a \"not found\" toast.\n const refRegex = /([A-Z]{2,4})#(\\d{4,6})/g;\n let m: RegExpExecArray | null;\n while ((m = refRegex.exec(line)) !== null) {\n if (host.stickyResolver) {\n const prefix = m[1], num = m[2], startIdx = m.index, matchText = m[0];\n tokens.push({ idx: startIdx, len: matchText.length, render: () => (\n <button key={`r-${li}-${startIdx}`} onClick={e => { e.stopPropagation(); openStickyRef(prefix, num); }}\n className=\"text-blue-700 hover:underline font-medium cursor-pointer\">{matchText}</button>\n )});\n }\n }\n\n // Checkboxes\n const cbRegex = /\\[([ xX]?)\\]/g;\n while ((m = cbRegex.exec(line)) !== null) {\n const isChecked = m[1] === 'x' || m[1] === 'X';\n const startIdx = m.index;\n const contentCharIdx = lineStart + startIdx;\n tokens.push({ idx: startIdx, len: m[0].length, render: () => (\n <button key={`c-${li}-${startIdx}`} onClick={e => { e.stopPropagation(); toggleStickyCheckbox(noteId, contentCharIdx); }}\n className={`inline-flex items-center justify-center w-3.5 h-3.5 rounded border ${isChecked ? 'bg-blue-500 border-blue-500 text-white' : 'border-gray-500 bg-white/50 hover:border-blue-400'} cursor-pointer align-text-bottom mr-0.5`}>\n {isChecked && <svg className=\"w-2.5 h-2.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>}\n </button>\n )});\n }\n\n tokens.sort((a, b) => a.idx - b.idx);\n const parts: ReactNode[] = [];\n let lastIdx = 0;\n for (const t of tokens) {\n if (t.idx > lastIdx) parts.push(<span key={`t-${li}-${lastIdx}`}>{line.slice(lastIdx, t.idx)}</span>);\n parts.push(t.render());\n lastIdx = t.idx + t.len;\n }\n if (lastIdx < line.length) parts.push(<span key={`t-${li}-${lastIdx}`}>{line.slice(lastIdx)}</span>);\n if (parts.length === 0) parts.push(<span key={`e-${li}`}>{'\\u200B'}</span>);\n\n const lineHasChecked = /^\\[x\\]/i.test(line.trimStart());\n return <div key={li} className={lineHasChecked ? 'line-through opacity-50' : ''}>{parts}</div>;\n });\n };\n\n // State\n const [dragging, setDragging] = useState<{ type: 'item' | 'folder' | 'trash'; idx: number; startX: number; startY: number; origX: number; origY: number } | null>(null);\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number; itemIdx?: number; folderIdx?: number } | null>(null);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [rubberBand, setRubberBand] = useState<{ startX: number; startY: number; endX: number; endY: number } | null>(null);\n const [aboutOpen, setAboutOpen] = useState(false);\n const [whatsNewOpen, setWhatsNewOpen] = useState(false);\n const [widgetsOpen, setWidgetsOpen] = useState(false);\n const [renamingFolder, setRenamingFolder] = useState<string | null>(null);\n const [renameValue, setRenameValue] = useState('');\n const [editingStickyId, setEditingStickyId] = useState<string | null>(null);\n const [stickyDrag, setStickyDrag] = useState<{ id: string; startX: number; startY: number; origX: number; origY: number } | null>(null);\n const [stickyResize, setStickyResize] = useState<{ id: string; startX: number; startY: number; origW: number; origH: number } | null>(null);\n // Index of the folder the user is currently hovering while dragging an\n // icon — drives the lift / glow animation and the on-drop fold-in.\n const [hoverFolderIdx, setHoverFolderIdx] = useState<number | null>(null);\n const hoverFolderIdxRef = useRef<number | null>(null);\n\n // Save helpers — delegate persistence to the consumer-supplied callbacks\n // when wired, otherwise write through the prefs adapter so backend-less\n // demos still survive a reload.\n const saveDocs = useCallback((docs: DesktopItem[]) => {\n if (host.saveShortcuts) host.saveShortcuts(docs);\n else saveShellPrefs({ favorite_documents: docs });\n }, [host, saveShellPrefs]);\n\n const saveFolders = useCallback((f: DesktopFolder[]) => {\n if (host.saveFolders) host.saveFolders(f);\n else saveShellPrefs({ desktop_folders: f });\n }, [host, saveShellPrefs]);\n\n const saveSnap = useCallback((v: boolean) => {\n if (host.saveSnap) host.saveSnap(v);\n else saveShellPrefs({ desktop_snap: v });\n }, [host, saveShellPrefs]);\n\n // Latest-state refs so handlers registered once (the preview-opened event\n // listener, the Files-app bridge callbacks) always read the current\n // folders / favDocs instead of stale closure values from initial mount.\n const liveStateRef = useRef({ folders, favDocs, saveFolders, saveDocs });\n liveStateRef.current = { folders, favDocs, saveFolders, saveDocs };\n\n // When the user previews a file (via Files app or a Recent Documents\n // shortcut), drop a dedup'd shortcut into the \"Recent Documents\" system\n // folder. The folder always exists, so there is nothing to create here.\n useEffect(() => {\n const handler = (e: Event) => {\n const detail = (e as CustomEvent<PreviewOpenedDetail>).detail;\n if (!detail?.filePath) return;\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const deduped = docs.filter(d =>\n !(d.entityType === 'preview-file' && d.filePath === detail.filePath),\n );\n const next: DesktopItem = {\n entityType: 'preview-file',\n entityId: detail.filePath,\n label: detail.filename,\n filePath: detail.filePath,\n fileKind: detail.kind,\n folderId: DOCUMENTS_FOLDER_ID,\n };\n sd([next, ...deduped]);\n };\n window.addEventListener(PREVIEW_OPENED_EVENT, handler);\n return () => window.removeEventListener(PREVIEW_OPENED_EVENT, handler);\n }, []);\n\n // Positions stored as { right, top } — distance from right/top edges\n // This keeps icons anchored to the top-right regardless of window size\n const getDefaultPos = (idx: number) => {\n const col = Math.floor(idx / 8);\n const row = idx % 8;\n return { right: 20 + col * GRID, top: 20 + row * GRID };\n };\n\n const getItemPos = (item: DesktopItem, idx: number) => {\n if (item.x != null && item.y != null) return { right: item.x, top: item.y };\n return getDefaultPos(idx);\n };\n\n const getFolderPos = (folder: DesktopFolder, idx: number) => {\n if (folder.x != null && folder.y != null) return { right: folder.x, top: folder.y };\n return getDefaultPos(favDocs.filter(d => !d.folderId).length + idx);\n };\n\n // Items not in any folder\n const desktopItems = favDocs.filter(d => !d.folderId);\n const folderItems = (folderId: string) => favDocs.filter(d => d.folderId === folderId);\n\n // Open a shortcut — shared by icon double-click and the context menu.\n const openItem = (item: DesktopItem) => {\n if (item.entityType === 'preview-file' && item.filePath && item.fileKind) {\n openPreviewFile({\n filePath: item.filePath,\n filename: item.label,\n kind: item.fileKind,\n onStaged: route => openPage(route),\n });\n } else if (item.entityType === 'page') {\n openPage(item.entityId);\n } else {\n openEntity(item.entityType, item.entityId, null, item.label);\n }\n };\n\n // Desktop folders open in the Files app (same side-channel the Trash icon\n // uses): flag + event for an already-open instance, then route to /files.\n const openDesktopFolder = (folderId: string) => {\n requestFilesDesktopFolderView(folderId);\n openPage('/files');\n };\n\n // ── Files-app bridge ──\n // Publish the live folder list (and mutation callbacks) so the Files app\n // can list desktop folders in its sidebar and render their contents.\n const bridgeMoveToDesktop = useCallback((toMove: DesktopItem[]) => {\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const ids = new Set(toMove.map(t => `${t.entityType}|${t.entityId}`));\n sd(docs.map(d =>\n d.folderId && ids.has(`${d.entityType}|${d.entityId}`)\n ? { ...d, folderId: undefined, folderX: undefined, folderY: undefined }\n : d,\n ));\n }, []);\n\n const bridgeRemoveShortcuts = useCallback((toRemove: DesktopItem[]) => {\n const { favDocs: docs, saveDocs: sd } = liveStateRef.current;\n const ids = new Set(toRemove.map(t => `${t.entityType}|${t.entityId}`));\n sd(docs.filter(d => !(d.folderId && ids.has(`${d.entityType}|${d.entityId}`))));\n }, []);\n\n // ── Drag logic ──\n // Local position overrides — applied immediately on drop, before API responds\n const [localPositions, setLocalPositions] = useState<Record<string, { right: number; top: number }>>({});\n // When the drag starts on a selected icon, all selected icons move together.\n // dragEntriesRef holds one entry per moving icon: its element, type, index,\n // and origin position (relative to the desktop). The Trash rides along too\n // when it's part of the selection — its entry stores the BOTTOM offset in\n // `origY` (the icon is bottom-anchored), every other type stores the top.\n type DragEntry = { key: string; type: 'item' | 'folder' | 'trash'; idx: number; origX: number; origY: number; el: HTMLElement | null };\n const dragEntriesRef = useRef<DragEntry[]>([]);\n\n const startDrag = (type: 'item' | 'folder' | 'trash', idx: number, e: React.PointerEvent) => {\n if (e.button !== 0) return;\n const primaryKey = type === 'trash' ? 'trash' : `${type}-${idx}`;\n // If the icon being grabbed is in the current selection, every selected\n // icon comes along. Otherwise it's a single-icon drag and we replace\n // the selection with just this one.\n const draggingMulti = selected.has(primaryKey) && selected.size > 1;\n const keys = draggingMulti ? Array.from(selected) : [primaryKey];\n\n const entries: DragEntry[] = [];\n for (const key of keys) {\n if (key.startsWith('item-')) {\n const i = parseInt(key.slice(5), 10);\n const itm = desktopItems[i];\n if (!itm) continue;\n const pos = getItemPos(itm, i);\n const el = document.querySelector(`[data-desktop-icon=\"${key}\"]`) as HTMLElement | null;\n entries.push({ key, type: 'item', idx: i, origX: pos.right, origY: pos.top, el });\n } else if (key.startsWith('folder-')) {\n const i = parseInt(key.slice(7), 10);\n const f = folders[i];\n if (!f) continue;\n const pos = getFolderPos(f, i);\n const el = document.querySelector(`[data-desktop-icon=\"${key}\"]`) as HTMLElement | null;\n entries.push({ key, type: 'folder', idx: i, origX: pos.right, origY: pos.top, el });\n } else if (key === 'trash') {\n const el = document.querySelector('[data-desktop-icon=\"trash\"]') as HTMLElement | null;\n if (!el) continue;\n // Read the live inline offsets React set (right/bottom anchoring).\n const right = parseFloat(el.style.right || '0') || 0;\n const bottom = parseFloat(el.style.bottom || '0') || 0;\n entries.push({ key, type: 'trash', idx: 0, origX: right, origY: bottom, el });\n }\n }\n dragEntriesRef.current = entries;\n const primaryEntry = entries.find(e => e.key === primaryKey) ?? entries[0];\n if (!primaryEntry) return;\n setDragging({ type, idx, startX: e.clientX, startY: e.clientY, origX: primaryEntry.origX, origY: primaryEntry.origY });\n e.preventDefault();\n };\n\n useEffect(() => {\n if (!dragging) return;\n const entries = dragEntriesRef.current;\n // Single-icon drags can fold into a folder; track which folder the\n // cursor is currently hovering over so the folder element can react\n // (scale + glow) and so we can short-circuit the right-overlap test\n // on drop.\n const isSingleItemDrag = entries.length === 1 && entries[0].type === 'item';\n\n // Drag-to-pin helpers: a single page shortcut dropped onto the taskbar\n // pins it to the taskbar strip (prefs.favorite_pages — see Layout.tsx,\n // which tags the bar with data-taskbar-dropzone). Returns the route to pin,\n // or null when the drag isn't a lone page shortcut.\n const draggedPageRoute = (): string | null => {\n if (!isSingleItemDrag) return null;\n const itm = desktopItems[entries[0].idx];\n return itm?.entityType === 'page' ? itm.entityId : null;\n };\n const taskbarEl = (): HTMLElement | null =>\n document.querySelector('[data-taskbar-dropzone]') as HTMLElement | null;\n const pointOverTaskbar = (x: number, y: number): boolean => {\n const tb = taskbarEl();\n if (!tb) return false;\n const r = tb.getBoundingClientRect();\n return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;\n };\n const setTaskbarDropHint = (on: boolean) => {\n const tb = taskbarEl();\n if (!tb) return;\n tb.style.outline = on ? '2px solid var(--accent-600, #7c3aed)' : '';\n tb.style.outlineOffset = on ? '-2px' : '';\n };\n\n const move = (e: PointerEvent) => {\n const dx = e.clientX - dragging.startX;\n const dy = e.clientY - dragging.startY;\n // Apply delta to every dragged icon.\n for (const entry of entries) {\n if (!entry.el) continue;\n // Moving right → decrease right offset; moving down → increase top\n // offset — except the Trash, whose origY is a BOTTOM offset, so\n // moving down decreases it.\n entry.el.style.right = `${entry.origX - dx}px`;\n if (entry.type === 'trash') {\n entry.el.style.bottom = `${entry.origY - dy}px`;\n } else {\n entry.el.style.top = `${entry.origY + dy}px`;\n entry.el.style.left = 'auto';\n }\n entry.el.style.zIndex = '100';\n entry.el.style.opacity = '0.7';\n }\n // Detect hover-over-folder for drop-into-folder UX.\n if (isSingleItemDrag) {\n const elsBelow = document.elementsFromPoint(e.clientX, e.clientY);\n let nextHover: number | null = null;\n for (const el of elsBelow) {\n const fk = (el as HTMLElement).closest?.('[data-desktop-icon^=\"folder-\"]');\n if (fk) {\n const key = (fk as HTMLElement).getAttribute('data-desktop-icon');\n if (key) nextHover = parseInt(key.slice(7), 10);\n break;\n }\n }\n hoverFolderIdxRef.current = nextHover;\n setHoverFolderIdx(prev => (prev === nextHover ? prev : nextHover));\n // Light the taskbar when a page shortcut is dragged over it.\n setTaskbarDropHint(draggedPageRoute() != null && pointOverTaskbar(e.clientX, e.clientY));\n }\n };\n const up = (e: PointerEvent) => {\n const dx = e.clientX - dragging.startX;\n const dy = e.clientY - dragging.startY;\n // Reset visual transform overrides on every dragged icon.\n for (const entry of entries) {\n if (!entry.el) continue;\n entry.el.style.zIndex = '';\n entry.el.style.opacity = '';\n }\n\n // Drag-to-pin: a lone page shortcut released over the taskbar gets pinned\n // to the taskbar strip (prefs.favorite_pages) instead of being moved.\n const pinRoute = draggedPageRoute();\n if (pinRoute && pointOverTaskbar(e.clientX, e.clientY)) {\n setTaskbarDropHint(false);\n // Snap the icon back to where it started — no position change persisted.\n for (const entry of entries) {\n if (!entry.el) continue;\n entry.el.style.left = 'auto';\n entry.el.style.right = `${entry.origX}px`;\n entry.el.style.top = `${entry.origY}px`;\n }\n const pages: string[] = Array.isArray(shellPrefs.favorite_pages) ? shellPrefs.favorite_pages : [];\n if (!pages.includes(pinRoute)) saveShellPrefs({ favorite_pages: [...pages, pinRoute] } as any);\n hoverFolderIdxRef.current = null;\n setHoverFolderIdx(null);\n setDragging(null);\n dragEntriesRef.current = [];\n return;\n }\n setTaskbarDropHint(false);\n\n const liveHoverIdx = hoverFolderIdxRef.current;\n const hoveredFolder = liveHoverIdx != null ? folders[liveHoverIdx] : null;\n hoverFolderIdxRef.current = null;\n setHoverFolderIdx(null);\n\n // Compute final positions for each dragged entry. The Trash is\n // bottom-anchored and never snaps — handled separately below.\n const computedPositions = entries.filter(en => en.type !== 'trash').map(entry => {\n let finalRight = entry.origX - dx;\n let finalTop = Math.max(0, entry.origY + dy);\n if (snapEnabled) { const s = snapToGrid(finalRight, finalTop); finalRight = s.x; finalTop = s.y; }\n finalRight = Math.max(0, finalRight);\n return { entry, finalRight, finalTop };\n });\n\n // Persist the trash's new corner offsets when it rode along.\n const trashEntry = entries.find(en => en.type === 'trash');\n if (trashEntry) {\n saveShellPrefs({\n desktop_trash_position: {\n right: Math.max(0, trashEntry.origX - dx),\n bottom: Math.max(0, trashEntry.origY - dy),\n },\n } as any);\n }\n\n // Persist items.\n const itemMoves = computedPositions.filter(p => p.entry.type === 'item');\n if (itemMoves.length > 0) {\n const updated = [...favDocs];\n const positionsPatch: Record<string, { right: number; top: number }> = {};\n // Single-item drag onto a folder still folds in (multi-drag never folds).\n const singleItem = itemMoves.length === 1 && entries.length === 1 ? itemMoves[0] : null;\n // Prefer the actively-hovered folder (live cursor hit-test) and fall\n // back to a position-overlap check for snap-to-grid edge cases.\n const droppedOnFolder = singleItem\n ? (hoveredFolder ?? folders.find((f, fi) => {\n const fp = getFolderPos(f, fi);\n return Math.abs(singleItem.finalRight - fp.right) < 40 && Math.abs(singleItem.finalTop - fp.top) < 40;\n }))\n : undefined;\n // Visual feedback: shrink the dragged icon into the folder before the\n // saved state actually removes it from the desktop.\n if (droppedOnFolder && singleItem?.entry.el) {\n const itemEl = singleItem.entry.el;\n const folderIdx = folders.indexOf(droppedOnFolder);\n const folderEl = document.querySelector(`[data-desktop-icon=\"folder-${folderIdx}\"]`) as HTMLElement | null;\n if (folderEl) {\n const ir = itemEl.getBoundingClientRect();\n const fr = folderEl.getBoundingClientRect();\n const dx = (fr.left + fr.width / 2) - (ir.left + ir.width / 2);\n const dy = (fr.top + fr.height / 2) - (ir.top + ir.height / 2);\n itemEl.style.transition = 'transform 220ms ease-out, opacity 220ms ease-out';\n itemEl.style.transform = `translate(${dx}px, ${dy}px) scale(0.2)`;\n itemEl.style.opacity = '0';\n }\n folderEl?.animate(\n [{ transform: 'scale(1)' }, { transform: 'scale(1.15)' }, { transform: 'scale(1)' }],\n { duration: 280, easing: 'ease-out' },\n );\n }\n for (const move of itemMoves) {\n const desktopIdx = favDocs.indexOf(desktopItems[move.entry.idx]);\n if (desktopIdx === -1) continue;\n if (droppedOnFolder) {\n updated[desktopIdx] = { ...updated[desktopIdx], folderId: droppedOnFolder.id, x: undefined, y: undefined, folderX: undefined, folderY: undefined };\n } else {\n updated[desktopIdx] = { ...updated[desktopIdx], x: move.finalRight, y: move.finalTop, folderId: undefined };\n positionsPatch[`item-${desktopIdx}`] = { right: move.finalRight, top: move.finalTop };\n }\n }\n // Defer the state update so the fold-in animation has time to play.\n const commit = () => {\n saveDocs(updated);\n if (Object.keys(positionsPatch).length > 0) {\n setLocalPositions(prev => ({ ...prev, ...positionsPatch }));\n }\n };\n if (droppedOnFolder) setTimeout(commit, 220);\n else commit();\n }\n\n // Persist folders.\n const folderMoves = computedPositions.filter(p => p.entry.type === 'folder');\n if (folderMoves.length > 0) {\n const updated = [...folders];\n const positionsPatch: Record<string, { right: number; top: number }> = {};\n for (const move of folderMoves) {\n updated[move.entry.idx] = { ...updated[move.entry.idx], x: move.finalRight, y: move.finalTop };\n positionsPatch[`folder-${move.entry.idx}`] = { right: move.finalRight, top: move.finalTop };\n }\n saveFolders(updated);\n setLocalPositions(prev => ({ ...prev, ...positionsPatch }));\n }\n\n setDragging(null);\n dragEntriesRef.current = [];\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [dragging, snapEnabled, favDocs, folders, desktopItems, shellPrefs]);\n\n // Clear local position overrides when profile data updates\n // Cache key has to include positions too — otherwise \"Snap to Grid\"\n // updates favDocs.x/y but the entityId list is unchanged, so the\n // localPositions overlay keeps the pre-snap values pinned in place.\n const favDocsKey = JSON.stringify(favDocs.map(d => `${d.entityId}:${d.x ?? ''}:${d.y ?? ''}:${d.folderId ?? ''}`));\n const foldersKey = JSON.stringify(folders.map(f => `${f.id}:${f.x ?? ''}:${f.y ?? ''}`));\n useEffect(() => { setLocalPositions({}); }, [favDocsKey, foldersKey]);\n\n // Re-publish the Files-app bridge whenever folders or their contents\n // change (the content keys above already capture both).\n useEffect(() => {\n const { folders: fs, favDocs: docs } = liveStateRef.current;\n const itemsByFolder: Record<string, DesktopItem[]> = {};\n for (const f of fs) itemsByFolder[f.id] = [];\n for (const d of docs) {\n if (d.folderId && itemsByFolder[d.folderId]) itemsByFolder[d.folderId].push(d);\n }\n publishDesktopFolders({\n folders: fs.map(f => ({ id: f.id, name: f.name, itemCount: itemsByFolder[f.id]?.length ?? 0 })),\n itemsByFolder,\n moveToDesktop: bridgeMoveToDesktop,\n removeShortcuts: bridgeRemoveShortcuts,\n });\n }, [favDocsKey, foldersKey, bridgeMoveToDesktop, bridgeRemoveShortcuts]);\n useEffect(() => () => publishDesktopFolders(null), []);\n\n // ── Rubber band selection ──\n const didRubberBandDragRef = useRef(false);\n const startRubberBand = (e: React.PointerEvent) => {\n if (e.button !== 0 || e.target !== containerRef.current) return;\n const rect = containerRef.current!.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setRubberBand({ startX: x, startY: y, endX: x, endY: y });\n didRubberBandDragRef.current = false;\n setSelected(new Set());\n };\n\n useEffect(() => {\n if (!rubberBand) return;\n const computeSelection = (minX: number, maxX: number, minY: number, maxY: number) => {\n const sel = new Set<string>();\n const cw = containerRef.current?.clientWidth || 800;\n desktopItems.forEach((item, i) => {\n const pos = getItemPos(item, i);\n const leftX = cw - pos.right - 80;\n if (leftX + 40 > minX && leftX < maxX && pos.top + 40 > minY && pos.top < maxY) {\n sel.add(`item-${i}`);\n }\n });\n folders.forEach((f, i) => {\n const pos = getFolderPos(f, i);\n const leftX = cw - pos.right - 80;\n if (leftX + 40 > minX && leftX < maxX && pos.top + 40 > minY && pos.top < maxY) {\n sel.add(`folder-${i}`);\n }\n });\n // The Trash is bottom-anchored (and movable), so measure its live DOM\n // rect instead of mirroring the right/top math used for the grid icons.\n const trashEl = containerRef.current?.querySelector('[data-desktop-icon=\"trash\"]');\n const containerRect = containerRef.current?.getBoundingClientRect();\n if (trashEl && containerRect) {\n const tr = trashEl.getBoundingClientRect();\n const tx = tr.left - containerRect.left;\n const ty = tr.top - containerRect.top;\n if (tx + tr.width > minX && tx < maxX && ty + tr.height > minY && ty < maxY) {\n sel.add('trash');\n }\n }\n return sel;\n };\n const move = (e: PointerEvent) => {\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n // Mark as a real drag once the cursor has moved more than a tap.\n const dx = x - rubberBand.startX;\n const dy = y - rubberBand.startY;\n if (dx * dx + dy * dy > 16) didRubberBandDragRef.current = true;\n setRubberBand(prev => prev ? { ...prev, endX: x, endY: y } : null);\n if (didRubberBandDragRef.current) {\n const minX = Math.min(rubberBand.startX, x);\n const maxX = Math.max(rubberBand.startX, x);\n const minY = Math.min(rubberBand.startY, y);\n const maxY = Math.max(rubberBand.startY, y);\n setSelected(computeSelection(minX, maxX, minY, maxY));\n }\n };\n const up = () => {\n setRubberBand(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [rubberBand]);\n\n // ── Context menu ──\n const handleDesktopContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n setContextMenu({ x: e.clientX, y: e.clientY });\n };\n\n const handleItemContextMenu = (e: React.MouseEvent, itemIdx: number) => {\n e.preventDefault();\n e.stopPropagation();\n setContextMenu({ x: e.clientX, y: e.clientY, itemIdx });\n };\n\n const handleFolderContextMenu = (e: React.MouseEvent, folderIdx: number) => {\n e.preventDefault();\n e.stopPropagation();\n setContextMenu({ x: e.clientX, y: e.clientY, folderIdx });\n };\n\n useEffect(() => {\n if (!contextMenu) return;\n const handler = () => setContextMenu(null);\n window.addEventListener('click', handler);\n return () => window.removeEventListener('click', handler);\n }, [contextMenu]);\n\n const createFolder = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n // Icons render right-anchored (style.right = pos.right). Convert the\n // cursor's left-from-container into a right-from-container so the new\n // folder lands under the click instead of mirroring across the desktop.\n const containerW = rect?.width ?? 0;\n const cursorLeft = contextMenu ? contextMenu.x - (rect?.left ?? 0) : containerW - 100;\n const cursorTop = contextMenu ? contextMenu.y - (rect?.top ?? 0) : 100;\n const x = Math.max(0, containerW - cursorLeft - 40);\n const y = Math.max(0, cursorTop - 20);\n const id = `folder-${Date.now()}`;\n saveFolders([...folders, { id, name: 'New Folder', x, y }]);\n setContextMenu(null);\n setRenamingFolder(id);\n setRenameValue('New Folder');\n };\n\n const doSnapAll = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n const h = rect?.height || 600;\n const colCount = Math.max(1, Math.floor(h / GRID));\n let slot = 0;\n const getSlotPos = () => {\n const col = Math.floor(slot / colCount);\n const row = slot % colCount;\n slot++;\n return { right: 20 + col * GRID, top: 10 + row * GRID };\n };\n // Arrange folders first, then items\n const updatedF = folders.map(f => {\n const pos = getSlotPos();\n return { ...f, x: pos.right, y: pos.top };\n });\n saveFolders(updatedF);\n const updated = favDocs.map(d => {\n if (d.folderId) return d;\n const pos = getSlotPos();\n return { ...d, x: pos.right, y: pos.top };\n });\n saveDocs(updated);\n setContextMenu(null);\n };\n\n const removeItem = (idx: number) => {\n const desktopIdx = favDocs.indexOf(desktopItems[idx]);\n saveDocs(favDocs.filter((_, i) => i !== desktopIdx));\n setContextMenu(null);\n };\n\n const removeFolder = (idx: number) => {\n const folder = folders[idx];\n if (folder.id === DOCUMENTS_FOLDER_ID) return; // system folder — undeletable\n // Move folder items back to desktop\n const updated = favDocs.map(d => d.folderId === folder.id ? { ...d, folderId: undefined } : d);\n saveDocs(updated);\n saveFolders(folders.filter((_, i) => i !== idx));\n setContextMenu(null);\n };\n\n const renameFolder = (id: string, name: string) => {\n saveFolders(folders.map(f => f.id === id ? { ...f, name } : f));\n setRenamingFolder(null);\n };\n\n // ── Sticky notes ──\n // Persist through the consumer-supplied callback when one is wired,\n // otherwise fall back to the prefs adapter under `notepad_notes` so\n // Desktop drags survive a refresh and stay in sync with what Notepad\n // wrote.\n const saveNotes = useCallback((updated: StickyNote[]) => {\n if (host.saveNotes) host.saveNotes(updated);\n else saveShellPrefs({ notepad_notes: updated });\n }, [host, saveShellPrefs]);\n\n const createStickyNote = () => {\n const rect = containerRef.current?.getBoundingClientRect();\n const x = contextMenu ? contextMenu.x - (rect?.left || 0) : 100;\n const y = contextMenu ? contextMenu.y - (rect?.top || 0) : 100;\n const n: StickyNote = {\n id: `note-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n title: '', content: '', color: 'yellow', sticky: true,\n sticky_x: x, sticky_y: y, updated_at: new Date().toISOString(),\n };\n saveNotes([n, ...allNotes]);\n setEditingStickyId(n.id);\n setContextMenu(null);\n };\n\n const updateStickyContent = (id: string, content: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, content, updated_at: new Date().toISOString() } : n));\n };\n\n const removeStickyFromDesktop = (id: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, sticky: false } : n));\n };\n\n const deleteStickyNote = (id: string) => {\n saveNotes(allNotes.filter(n => n.id !== id));\n };\n\n const cycleStickyColor = (id: string) => {\n const STICKY_COLORS = ['yellow', 'blue', 'green', 'pink', 'purple', 'orange'];\n const note = allNotes.find(n => n.id === id);\n if (!note) return;\n const idx = STICKY_COLORS.indexOf(note.color);\n const next = STICKY_COLORS[(idx + 1) % STICKY_COLORS.length];\n saveNotes(allNotes.map(n => n.id === id ? { ...n, color: next } : n));\n };\n\n const toggleStickyOnTop = (id: string) => {\n saveNotes(allNotes.map(n => n.id === id ? { ...n, sticky_on_top: !n.sticky_on_top } : n));\n };\n\n // Sticky drag\n useEffect(() => {\n if (!stickyDrag) return;\n const move = (e: PointerEvent) => {\n const el = document.querySelector(`[data-sticky-id=\"${stickyDrag.id}\"]`) as HTMLElement;\n if (el) {\n el.style.left = `${stickyDrag.origX + e.clientX - stickyDrag.startX}px`;\n el.style.right = 'auto';\n el.style.top = `${stickyDrag.origY + e.clientY - stickyDrag.startY}px`;\n }\n };\n const up = (e: PointerEvent) => {\n const finalX = stickyDrag.origX + e.clientX - stickyDrag.startX;\n const finalY = Math.max(0, stickyDrag.origY + e.clientY - stickyDrag.startY);\n const el = document.querySelector(`[data-sticky-id=\"${stickyDrag.id}\"]`) as HTMLElement;\n const noteW = el?.offsetWidth ?? 192;\n const centerX = finalX + noteW / 2;\n const anchor: 'left' | 'right' = centerX > window.innerWidth / 2 ? 'right' : 'left';\n // Store x as left offset for left-anchored, or right offset for right-anchored\n const xVal = anchor === 'right' ? window.innerWidth - finalX - noteW : finalX;\n saveNotes(allNotes.map(n => n.id === stickyDrag.id ? { ...n, sticky_x: xVal, sticky_y: finalY, sticky_anchor: anchor } : n));\n // Clear inline styles so React takes over\n if (el) { el.style.left = ''; el.style.right = ''; }\n setStickyDrag(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [stickyDrag, allNotes]);\n\n // Sticky resize\n useEffect(() => {\n if (!stickyResize) return;\n const move = (e: PointerEvent) => {\n const el = document.querySelector(`[data-sticky-id=\"${stickyResize.id}\"]`) as HTMLElement;\n if (el) {\n el.style.width = `${Math.max(140, stickyResize.origW + e.clientX - stickyResize.startX)}px`;\n el.style.height = `${Math.max(100, stickyResize.origH + e.clientY - stickyResize.startY)}px`;\n }\n };\n const up = (e: PointerEvent) => {\n const finalW = Math.max(140, stickyResize.origW + e.clientX - stickyResize.startX);\n const finalH = Math.max(100, stickyResize.origH + e.clientY - stickyResize.startY);\n saveNotes(allNotes.map(n => n.id === stickyResize.id ? { ...n, sticky_w: finalW, sticky_h: finalH } : n));\n setStickyResize(null);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };\n }, [stickyResize, allNotes]);\n\n const STICKY_BG: Record<string, string> = {\n yellow: 'bg-yellow-100 border-yellow-300', blue: 'bg-blue-100 border-blue-300',\n green: 'bg-green-100 border-green-300', pink: 'bg-pink-100 border-pink-300',\n purple: 'bg-purple-100 border-purple-300', orange: 'bg-orange-100 border-orange-300',\n };\n\n // ── Render icon ──\n const renderIcon = (entityType: string, label: string, isSelected: boolean, entityId?: string, fileKind?: PreviewFileKind) => (\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <FileIconTile entityType={entityType} isSelected={isSelected} entityId={entityId} label={label} fileKind={fileKind} />\n <span className={`text-[10px] font-medium text-center leading-tight w-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n {label}\n </span>\n </div>\n );\n\n const menuStyle = (x: number, y: number): React.CSSProperties => ({\n ...(x + 180 > window.innerWidth ? { right: window.innerWidth - x } : { left: x }),\n ...(y + 250 > window.innerHeight ? { bottom: window.innerHeight - y } : { top: y }),\n });\n\n return (\n <div ref={containerRef} className=\"flex-1 relative overflow-hidden\"\n onPointerDown={startRubberBand}\n onContextMenu={handleDesktopContextMenu}\n onClick={() => {\n // Don't clear selection if the user just finished a rubber-band drag.\n if (didRubberBandDragRef.current) { didRubberBandDragRef.current = false; return; }\n setSelected(new Set());\n setContextMenu(null);\n }}\n >\n {/* Built-in Trash icon. Lives outside favDocs so it can't be\n deleted, renamed, or dropped into a folder, but the user can\n drag it around — its position persists to\n `prefs.desktop_trash_position`. Default position is the\n bottom-right corner, shifted in to clear the taskbar (the\n taskbar is `position: fixed` and overlays this container, so\n a naive `bottom: 20` would hide the icon under it). Double-\n click opens the Files app in trash view via the side-channel\n defined in Files.tsx. */}\n {(() => {\n const tb = taskbarMetrics();\n const defaultRight = 20 + (tb.position === 'right' ? tb.width : 0);\n const defaultBottom = 20 + (tb.position === 'bottom' ? tb.height : 0);\n const trashPos = (prefs as any).desktop_trash_position as { right: number; bottom: number } | undefined;\n const right = trashPos?.right ?? defaultRight;\n const bottom = trashPos?.bottom ?? defaultBottom;\n const isTrashSelected = selected.has('trash');\n\n const startTrashDrag = (e: React.PointerEvent) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n // When the Trash is part of a multi-selection, the whole selection\n // moves as one group through the shared drag pipeline (which knows\n // the trash is bottom-anchored). Solo drags keep this dedicated\n // path so the trash stays draggable on its own.\n if (selected.has('trash') && selected.size > 1) {\n startDrag('trash', 0, e);\n return;\n }\n const el = e.currentTarget as HTMLElement;\n const startX = e.clientX, startY = e.clientY;\n let moved = false;\n const move = (ev: PointerEvent) => {\n const dx = ev.clientX - startX;\n const dy = ev.clientY - startY;\n if (!moved && (Math.abs(dx) > 3 || Math.abs(dy) > 3)) moved = true;\n if (!moved) return;\n // Drag is from-bottom-right, so cursor moving right shrinks the\n // right offset, and moving down shrinks the bottom offset.\n el.style.right = `${right - dx}px`;\n el.style.bottom = `${bottom - dy}px`;\n el.style.opacity = '0.7';\n el.style.zIndex = '100';\n };\n const up = (ev: PointerEvent) => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n el.style.opacity = '';\n el.style.zIndex = '';\n if (!moved) return;\n const newRight = Math.max(0, right - (ev.clientX - startX));\n const newBottom = Math.max(0, bottom - (ev.clientY - startY));\n saveShellPrefs({ desktop_trash_position: { right: newRight, bottom: newBottom } } as any);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n return (\n <div\n data-desktop-icon=\"trash\"\n style={{ position: 'absolute', right, bottom, zIndex: 1 }}\n onPointerDown={startTrashDrag}\n onClick={e => {\n e.stopPropagation();\n // Same selection contract as the other icons: plain click\n // selects, shift / cmd / ctrl toggles within the selection.\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has('trash') ? next.delete('trash') : next.add('trash'); return next; });\n } else if (!selected.has('trash')) {\n setSelected(new Set(['trash']));\n }\n }}\n onContextMenu={e => e.preventDefault()}\n onDoubleClick={e => {\n e.stopPropagation();\n // Side-channel contract owned by src/apps/Files.tsx: flag is\n // read on mount when Files isn't open yet; the event tells an\n // already-open instance to flip view.\n requestFilesTrashView();\n openPage('/files');\n }}\n className=\"cursor-default select-none\"\n title=\"Trash — double-click to open, drag to move\"\n >\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <div className={`w-12 h-12 flex items-center justify-center ${isTrashSelected ? 'rounded-lg bg-blue-400/30 ring-2 ring-blue-500' : ''}`}>\n <svg className=\"h-12 w-12 drop-shadow-[0_2px_3px_rgba(0,0,0,0.4)]\" viewBox=\"0 0 24 24\">\n {/* Solid heroicons trash, filled with silver. Subtle darker\n stroke gives it a metallic edge against light wallpapers. */}\n <path\n fill=\"#c0c4cc\"\n stroke=\"#5f6677\"\n strokeWidth=\"0.6\"\n strokeLinejoin=\"round\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M16.5 4.478v.227a48.816 48.816 0 013.878.512.75.75 0 11-.256 1.478l-.209-.035-1.005 13.07a3 3 0 01-2.991 2.77H8.084a3 3 0 01-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 01-.256-1.478A48.567 48.567 0 017.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 014.368 0c1.603.051 2.816 1.387 2.816 2.951zm-6.136-1.452a51.196 51.196 0 013.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 00-6 0v-.113c0-.794.609-1.428 1.364-1.452zm-.355 5.945a.75.75 0 10-1.5.058l.347 9a.75.75 0 101.499-.058l-.346-9zm5.48.058a.75.75 0 10-1.498-.058l-.347 9a.75.75 0 001.5.058l.346-9z\"\n />\n </svg>\n </div>\n <span className={`text-[10px] font-medium text-center leading-tight drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isTrashSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n Trash\n </span>\n </div>\n </div>\n );\n })()}\n\n {/* Desktop items */}\n {desktopItems.map((doc, i) => {\n const docIdx = favDocs.indexOf(doc);\n const pos = localPositions[`item-${docIdx}`] || getItemPos(doc, i);\n const isSelected = selected.has(`item-${i}`);\n return (\n <div key={`item-${doc.entityType}-${doc.entityId}-${i}`} data-desktop-icon={`item-${i}`}\n style={{ position: 'absolute', right: pos.right, top: pos.top, zIndex: 1 }}\n onPointerDown={e => { e.stopPropagation(); startDrag('item', i, e); }}\n onClick={e => {\n e.stopPropagation();\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has(`item-${i}`) ? next.delete(`item-${i}`) : next.add(`item-${i}`); return next; });\n } else if (!selected.has(`item-${i}`)) {\n setSelected(new Set([`item-${i}`]));\n }\n }}\n onContextMenu={e => handleItemContextMenu(e, i)}\n onDoubleClick={e => { e.stopPropagation(); openItem(doc); }}\n className=\"cursor-default select-none\"\n >\n {renderIcon(doc.entityType, doc.label, isSelected, doc.entityId, doc.fileKind)}\n </div>\n );\n })}\n\n {/* Folders */}\n {folders.map((folder, i) => {\n const pos = localPositions[`folder-${i}`] || getFolderPos(folder, i);\n const isSelected = selected.has(`folder-${i}`);\n const isHovered = hoverFolderIdx === i;\n const itemCount = folderItems(folder.id).length;\n return (\n <div key={`folder-${folder.id}`} data-desktop-icon={`folder-${i}`}\n style={{\n position: 'absolute', right: pos.right, top: pos.top, zIndex: 1,\n transform: isHovered ? 'scale(1.15)' : 'scale(1)',\n transition: 'transform 180ms ease-out',\n }}\n onPointerDown={e => { e.stopPropagation(); startDrag('folder', i, e); }}\n onClick={e => {\n e.stopPropagation();\n if (e.shiftKey || e.metaKey || e.ctrlKey) {\n setSelected(prev => { const next = new Set(prev); next.has(`folder-${i}`) ? next.delete(`folder-${i}`) : next.add(`folder-${i}`); return next; });\n } else if (!selected.has(`folder-${i}`)) {\n setSelected(new Set([`folder-${i}`]));\n }\n }}\n onContextMenu={e => handleFolderContextMenu(e, i)}\n onDoubleClick={e => { e.stopPropagation(); openDesktopFolder(folder.id); }}\n className=\"cursor-default select-none\"\n >\n <div className=\"flex flex-col items-center gap-1 w-20 p-2\">\n <div className={`w-12 h-12 flex items-center justify-center ${isSelected ? 'rounded-lg bg-blue-400/30 ring-2 ring-blue-500' : ''} ${isHovered ? 'rounded-lg ring-4 ring-amber-400 shadow-[0_0_20px_rgba(245,158,11,0.6)]' : ''}`}>\n <FolderGlyph className=\"h-12 w-12 text-amber-500 drop-shadow-[0_2px_3px_rgba(0,0,0,0.3)]\" />\n </div>\n {renamingFolder === folder.id ? (\n <input autoFocus value={renameValue} onChange={e => setRenameValue(e.target.value)}\n onBlur={() => renameFolder(folder.id, renameValue)}\n onKeyDown={e => { if (e.key === 'Enter') renameFolder(folder.id, renameValue); if (e.key === 'Escape') setRenamingFolder(null); }}\n className=\"text-[10px] w-full text-center bg-white/80 rounded px-1 outline-none\"\n onClick={e => e.stopPropagation()}\n />\n ) : (\n <span className={`text-[10px] font-medium text-center leading-tight w-full drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)] ${isSelected ? 'text-blue-200 bg-blue-600/60 rounded px-1' : 'text-white'}`}>\n {folder.name}{itemCount > 0 ? ` (${itemCount})` : ''}\n </span>\n )}\n </div>\n </div>\n );\n })}\n\n {/* Sticky notes */}\n {stickyNotes.map(note => {\n const xVal = note.sticky_x ?? 100;\n const y = note.sticky_y ?? 100;\n const w = note.sticky_w ?? 192;\n const h = note.sticky_h ?? 148;\n const anchor = note.sticky_anchor || 'left';\n const bg = STICKY_BG[note.color] || STICKY_BG.yellow;\n const isEditing = editingStickyId === note.id;\n return (\n <div key={`sticky-${note.id}`} data-sticky-id={note.id}\n style={{ position: 'absolute', ...(anchor === 'right' ? { right: xVal } : { left: xVal }), top: y, width: w, height: h, zIndex: note.sticky_on_top ? 200 : isEditing ? 50 : 10 }}\n onClick={e => e.stopPropagation()}\n className={`rounded-lg shadow-lg border ${bg} select-none flex flex-col`}\n >\n {/* Header — drag handle */}\n <div className=\"flex items-center justify-between px-2 py-1 cursor-move border-b border-black/5\"\n onPointerDown={e => {\n if (e.button !== 0) return;\n e.preventDefault(); e.stopPropagation();\n // Always drag using left position; convert right-anchored to left\n const el = (e.target as HTMLElement).closest('[data-sticky-id]') as HTMLElement;\n const actualLeft = el ? el.getBoundingClientRect().left - (containerRef.current?.getBoundingClientRect().left ?? 0) : (anchor === 'right' ? window.innerWidth - xVal - w : xVal);\n setStickyDrag({ id: note.id, startX: e.clientX, startY: e.clientY, origX: actualLeft, origY: y });\n }}>\n <div className=\"flex items-center gap-1\">\n <button\n onPointerDown={e => e.stopPropagation()}\n onClick={e => { e.stopPropagation(); cycleStickyColor(note.id); }}\n title=\"Change color\"\n className=\"w-3 h-3 rounded-full bg-black/10 hover:bg-black/20 transition-colors\" />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); toggleStickyOnTop(note.id); }} title={note.sticky_on_top ? 'Remove from top' : 'Always on top'}\n className={`p-0.5 rounded transition-colors ${note.sticky_on_top ? 'text-blue-500' : 'text-black/20 hover:text-black/50'}`}>\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.914 5.046a5.25 5.25 0 01-1.414 0M15.75 9v6\" /><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12.75 12l3 3 3-3\" /></svg>\n </button>\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); removeStickyFromDesktop(note.id); }} title=\"Unpin from desktop\"\n className=\"p-0.5 rounded text-black/20 hover:text-black/50 transition-colors\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 12h-15\" /></svg>\n </button>\n <button onPointerDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); deleteStickyNote(note.id); }} title=\"Delete note\"\n className=\"p-0.5 rounded text-black/20 hover:text-red-500 transition-colors\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n </div>\n </div>\n {/* Content */}\n {isEditing ? (\n <textarea\n autoFocus\n defaultValue={note.content}\n onBlur={e => { updateStickyContent(note.id, e.target.value); setEditingStickyId(null); }}\n onKeyDown={e => { if (e.key === 'Escape') { updateStickyContent(note.id, (e.target as HTMLTextAreaElement).value); setEditingStickyId(null); } }}\n className=\"flex-1 w-full p-2 text-xs leading-relaxed bg-transparent outline-none resize-none placeholder:text-black/30\"\n placeholder=\"Write something...\"\n />\n ) : (\n <div className=\"flex-1 p-2 cursor-text overflow-hidden\" onDoubleClick={e => { e.stopPropagation(); setEditingStickyId(note.id); }}>\n <div className=\"text-xs leading-relaxed text-black/70\">\n {note.content ? renderStickyContent(note.id, note.content) : <span className=\"text-black/30 italic\">Double-click to edit...</span>}\n </div>\n </div>\n )}\n {/* Resize handle */}\n <div className=\"absolute bottom-0 right-0 w-4 h-4 cursor-nwse-resize\"\n onPointerDown={e => {\n if (e.button !== 0) return;\n e.preventDefault(); e.stopPropagation();\n const el = (e.target as HTMLElement).closest('[data-sticky-id]') as HTMLElement;\n setStickyResize({ id: note.id, startX: e.clientX, startY: e.clientY, origW: el?.offsetWidth ?? w, origH: el?.offsetHeight ?? h });\n }}>\n <svg className=\"w-3 h-3 text-black/15 absolute bottom-0.5 right-0.5\" viewBox=\"0 0 12 12\" fill=\"currentColor\">\n <circle cx=\"10\" cy=\"10\" r=\"1.5\" /><circle cx=\"6\" cy=\"10\" r=\"1.5\" /><circle cx=\"10\" cy=\"6\" r=\"1.5\" />\n </svg>\n </div>\n </div>\n );\n })}\n\n {/* Rubber band selection */}\n {rubberBand && (\n <div className=\"absolute border border-blue-400 bg-blue-400/10 pointer-events-none\" style={{\n left: Math.min(rubberBand.startX, rubberBand.endX),\n top: Math.min(rubberBand.startY, rubberBand.endY),\n width: Math.abs(rubberBand.endX - rubberBand.startX),\n height: Math.abs(rubberBand.endY - rubberBand.startY),\n }} />\n )}\n\n {/* Context menu — desktop */}\n {contextMenu && contextMenu.itemIdx == null && contextMenu.folderIdx == null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)}>\n <PopupMenuItem onClick={createStickyNote}>\n <svg className=\"h-4 w-4 text-yellow-500\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M4 4a2 2 0 012-2h8a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2V4z\" opacity=\"0.8\" /><path d=\"M14 14v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-6\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>\n New Sticky Note\n </PopupMenuItem>\n <PopupMenuItem onClick={createFolder}>\n <svg className=\"h-4 w-4 text-yellow-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z\" /></svg>\n Create Folder\n </PopupMenuItem>\n <PopupMenuItem onClick={doSnapAll}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z\" /></svg>\n Snap to Grid\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setContextMenu(null); setWidgetsOpen(true); }}>\n <svg className=\"h-4 w-4 text-blue-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" /><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" /></svg>\n Manage Widgets…\n </PopupMenuItem>\n {/* Performance overlay toggle. It lives here, next to the other\n desktop-surface items, because the Preferences switch alone was\n not a findable entrance: it sits last in the Appearance pane,\n below Theme, Wallpaper and six transparency sliders — about a\n screen's worth of scrolling past the fold. A diagnostic has to be\n reachable by someone who is already frustrated, and that means\n right where the overlay itself appears. */}\n {!hiddenMenuItems.includes('perf-stats') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); saveShellPrefs({ show_desktop_stats: prefs.show_desktop_stats !== true }); }}>\n <svg className=\"h-4 w-4 text-emerald-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 20.25V15m5.25 5.25V9.75m5.25 10.5V4.5m5.25 15.75v-7.5\" /></svg>\n {prefs.show_desktop_stats === true ? 'Hide Performance Stats' : 'Show Performance Stats'}\n </PopupMenuItem>\n )}\n {!(hiddenMenuItems.includes('customization') && hiddenMenuItems.includes('favorites') && hiddenMenuItems.includes('about')) && <PopupMenuDivider />}\n {!hiddenMenuItems.includes('customization') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); openPage('/settings/customization'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42\" /></svg>\n Preferences\n </PopupMenuItem>\n )}\n {!hiddenMenuItems.includes('favorites') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); openPage('/settings/favorites'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" /></svg>\n Favorites\n </PopupMenuItem>\n )}\n {!hiddenMenuItems.includes('about') && (\n <PopupMenuItem onClick={() => { setContextMenu(null); setAboutOpen(true); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" /></svg>\n {shellStrings.about.aboutPrefix} {host.productName ?? shellStrings.about.thisApp}\n </PopupMenuItem>\n )}\n {host.onReportBug && <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setContextMenu(null); host.onReportBug!(); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z\" /></svg>\n Suggestion or Bug\n </PopupMenuItem>\n </>}\n </PopupMenu>\n )}\n\n {/* Context menu — item */}\n {contextMenu && contextMenu.itemIdx != null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)} minWidth={160}>\n <PopupMenuItem onClick={() => { openItem(desktopItems[contextMenu.itemIdx!]); setContextMenu(null); }}>\n Open\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => removeItem(contextMenu.itemIdx!)}>\n Remove Shortcut\n </PopupMenuItem>\n </PopupMenu>\n )}\n\n {/* Context menu — folder */}\n {contextMenu && contextMenu.folderIdx != null && (\n <PopupMenu style={menuStyle(contextMenu.x, contextMenu.y)} minWidth={160}>\n <PopupMenuItem onClick={() => { openDesktopFolder(folders[contextMenu.folderIdx!].id); setContextMenu(null); }}>\n Open\n </PopupMenuItem>\n {/* Recent Documents is a system folder — no rename, no delete. */}\n {folders[contextMenu.folderIdx!].id !== DOCUMENTS_FOLDER_ID && <>\n <PopupMenuItem onClick={() => { setRenamingFolder(folders[contextMenu.folderIdx!].id); setRenameValue(folders[contextMenu.folderIdx!].name); setContextMenu(null); }}>\n Rename\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => removeFolder(contextMenu.folderIdx!)}>\n Delete Folder\n </PopupMenuItem>\n </>}\n </PopupMenu>\n )}\n\n {/* Widget manager — add / remove desktop widgets */}\n <WidgetManager open={widgetsOpen} onClose={() => setWidgetsOpen(false)} />\n\n {/* About dialog */}\n {aboutOpen && (() => {\n const version = host.productVersion ?? APP_VERSION;\n return (\n <Modal open={true} onClose={() => setAboutOpen(false)} title={`${shellStrings.about.aboutPrefix} ${host.productName ?? shellStrings.about.thisApp}`} size=\"sm\" bodyScroll={false} compact dimensions={[340, 420]}>\n <div className=\"flex flex-col items-center\">\n {/* Logo & Title */}\n <div className=\"flex flex-col items-center gap-2 pt-4 pb-3 w-full\">\n <img src={host.productIcon ?? '/favicon.svg'} alt=\"\" className=\"h-16 w-16\" />\n <div className=\"text-center\">\n <h2 className=\"text-lg font-bold text-gray-900 tracking-wide\">{host.productName ?? 'react-os-shell'}</h2>\n {host.productTagline && <p className=\"text-xs text-gray-500\">{host.productTagline}</p>}\n <p className=\"text-[11px] text-gray-400 mt-1 font-mono\">{version}</p>\n </div>\n </div>\n\n {/* Open Source Licenses */}\n <div className=\"py-3 border-t border-gray-200 w-full px-4\">\n <h3 className=\"text-[10px] font-semibold text-gray-400 uppercase tracking-wide mb-2 text-center\">{shellStrings.about.openSourceLicenses}</h3>\n <div className=\"max-h-40 overflow-y-auto\">\n <table className=\"w-full text-[11px]\">\n <thead><tr className=\"text-gray-500 border-b border-gray-100\"><th className=\"text-left py-1 font-medium\">Package</th><th className=\"text-left py-1 font-medium\">License</th></tr></thead>\n <tbody className=\"divide-y divide-gray-50\">\n {[\n ['React', 'MIT', 'facebook/react'],\n ['React DOM', 'MIT', 'facebook/react'],\n ['React Router', 'MIT', 'remix-run/react-router'],\n ['TanStack Query', 'MIT', 'TanStack/query'],\n ['TanStack Table', 'MIT', 'TanStack/table'],\n ['React Hook Form', 'MIT', 'react-hook-form'],\n ['Axios', 'MIT', 'axios/axios'],\n ['Tailwind CSS', 'MIT', 'tailwindlabs/tailwindcss'],\n ['Headless UI', 'MIT', 'tailwindlabs/headlessui'],\n ['Heroicons', 'MIT', 'tailwindlabs/heroicons'],\n ['Recharts', 'MIT', 'recharts/recharts'],\n ['Zod', 'MIT', 'colinhacks/zod'],\n ['Vite', 'MIT', 'vitejs/vite'],\n ['TypeScript', 'Apache-2.0', 'microsoft/TypeScript'],\n ['jSpreadsheet CE', 'MIT', 'jspreadsheet/ce'],\n ['Django', 'BSD-3', 'django/django'],\n ['Django REST Framework', 'BSD-3', 'encode/django-rest-framework'],\n ['PostgreSQL', 'PostgreSQL', 'postgres/postgres'],\n ['Gunicorn', 'MIT', 'benoitc/gunicorn'],\n ].map(([name, license, repo]) => (\n <tr key={name} className=\"text-gray-600\">\n <td className=\"py-1\"><a href={`https://github.com/${repo}`} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-blue-600 hover:underline\">{name}</a></td>\n <td className=\"py-1 text-gray-400\">{license}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Copyright — bottom (consumer-configurable; hidden when neither field is supplied) */}\n {(host.productCopyright || host.productWebsite) && (\n <div className=\"pt-3 pb-2 border-t border-gray-200 w-full text-center\">\n {host.productCopyright && <p className=\"text-[10px] text-gray-400\">{host.productCopyright}</p>}\n {host.productWebsite && (\n <a href={host.productWebsite} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-[10px] text-blue-500 hover:underline\">\n {host.productWebsite.replace(/^https?:\\/\\//, '')}\n </a>\n )}\n </div>\n )}\n </div>\n </Modal>\n );\n })()}\n\n {/* Performance HUD — opt-in diagnostic, parked in the same corner as the\n version watermark: one row above it when both show, in its slot when\n the watermark is off. z-[240] floats it over windows (which stack\n below the taskbar's z-[250]) but under every piece of shell chrome,\n so it stays readable while you drag a window around — which is when\n the jank worth measuring actually happens. */}\n {prefs.show_desktop_stats === true && (() => {\n const versionShowing = prefs.show_desktop_version === true && !!(host.productVersion ?? APP_VERSION);\n const taskbarAtBottom = prefs.taskbar_position !== 'top'\n && prefs.taskbar_position !== 'left'\n && prefs.taskbar_position !== 'right';\n const side = prefs.taskbar_position === 'right' ? 'left-3' : 'right-3';\n // Standard spacing steps only — no arbitrary values. These class names\n // have to survive whatever Tailwind build each consuming portal runs,\n // and an arbitrary `bottom-[5.5rem]` silently resolves to nothing if a\n // consumer's scan misses the shell's dist. The stacked offsets simply\n // clear the watermark sitting below.\n const bottom = taskbarAtBottom\n ? (versionShowing ? 'bottom-24' : 'bottom-16')\n : (versionShowing ? 'bottom-8' : 'bottom-3');\n return (\n <div className={`absolute z-[240] ${side} ${bottom}`}>\n <PerfStats\n onClose={() => saveShellPrefs({ show_desktop_stats: false })}\n onSubmit={host.onSubmitPerfReport}\n />\n </div>\n );\n })()}\n\n {/* Version watermark on desktop — opt-in only. Hidden by default so\n consumer apps don't end up with two version labels (the bundled\n one and their own). Set prefs.show_desktop_version = true and\n provide host.productVersion to surface it. */}\n {prefs.show_desktop_version === true && (host.productVersion ?? APP_VERSION) && (() => {\n const tb = taskbarMetrics();\n return (\n <button\n onClick={(e) => { e.stopPropagation(); setWhatsNewOpen(true); }}\n style={{\n // ── BG#00623 ──────────────────────────────────────────────────\n // Above the desktop-icon layer. The icons declare `zIndex: 1`\n // and this declared nothing, so the Trash — whose default\n // position is `20 + taskbarHeight` from the same corner — painted\n // over the digits and took the click. Its handler calls\n // `stopPropagation()` and only changes the selection, so an\n // intercepted click did visibly nothing, which is exactly what\n // the report describes. Measured before this change, at 1851x1301:\n // 510 of the label's 630 pixels went to the Trash on a small\n // taskbar, 102 on a medium one.\n //\n // 2 and not more: the window layer and the taskbar's z-[250] must\n // still cover it, and the PerfStats HUD's z-[240] sits between.\n // Declared inline for the same reason the icons do — a consumer's\n // Tailwind scan cannot fail to generate a style attribute.\n zIndex: 2,\n // Clear of the taskbar at every size. This was a flat 64px, which\n // is right for a medium taskbar and 8px short of a large one: the\n // taskbar is `position: fixed` and paints over the desktop, so on\n // a large taskbar 336 of those same 630 pixels were underneath it.\n // The +8 below reproduces today's medium placement exactly, so the\n // label does not move for the common case.\n bottom: tb.position === 'bottom' ? tb.height + 4 : 8,\n ...(tb.position === 'right' ? { left: 4 } : { right: 4 }),\n }}\n // The padding is the hit target: the glyphs are 10px type at half\n // opacity in a 42x15 box, which is smaller than anything else on the\n // desktop you are expected to hit. It grows the box outwards only —\n // the insets above are pulled in by the same amount the padding adds\n // back, so the digits stay where they are drawn today.\n className=\"absolute px-2 py-1 text-[10px] text-white/50 font-mono select-none drop-shadow-[0_1px_1px_rgba(0,0,0,0.5)] hover:text-white/80 transition-colors cursor-pointer\"\n >\n {host.productVersion ?? APP_VERSION}\n </button>\n );\n })()}\n\n {/* What's New dialog — the modal body is the scroller. An inner box\n capped at a viewport fraction cannot grow into a fixed-height\n window, so everything below the cap was blank (BG#00600); worst\n maximized, where the window is the whole work area.\n\n `bodyScroll={false}` with a `min-h-0 flex-1 overflow-y-auto` wrapper\n (the idiom at Drawer.tsx:156 and SidebarLayout.tsx:139) is equally\n correct — this shape is one element shorter, and the guard in\n tests/whatsNewFillsWindow.test.tsx accepts either. What neither\n shape does is size the WINDOW to the changelog: a host with two\n entries still gets an `md` window with room to spare, and asks for\n the other behaviour with `autoHeight` / `autoMinHeight`.\n\n Entries are Markdown — every consumer writes them that way — so\n they go through MarkdownLite, the same renderer and the same\n wrapper classes the admin portal's VersionsPanel and AboutSettings\n use on these exact strings. */}\n {whatsNewOpen && (() => {\n const entries = host.productChangelog ?? changelog;\n return (\n <Modal open={true} onClose={() => setWhatsNewOpen(false)} title={shellStrings.about.whatsNew} size=\"md\">\n {entries.length === 0 ? (\n <div className=\"flex-1 flex items-center justify-center\">\n <p className=\"text-sm text-gray-400 text-center\">{shellStrings.about.noChangelog}</p>\n </div>\n ) : (\n <div className=\"space-y-5 px-1\">\n {entries.map((entry, i) => (\n <div key={entry.version}>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm font-bold text-gray-900 font-mono\">{entry.version}</span>\n <span className=\"text-xs text-gray-400\">{formatDate(entry.date)}</span>\n </div>\n <ul className=\"space-y-1.5 ml-1\">\n {entry.changes.map((change, j) => (\n <li key={j} className=\"flex items-start gap-2 text-sm text-gray-600\">\n <span className=\"text-blue-500 mt-1 shrink-0\">•</span>\n <MarkdownLite className=\"min-w-0 [&_p]:m-0\">{change}</MarkdownLite>\n </li>\n ))}\n </ul>\n {i < entries.length - 1 && <div className=\"border-b border-gray-200 mt-4\" />}\n </div>\n ))}\n </div>\n )}\n </Modal>\n );\n })()}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport BrandMark from '../forms/BrandMark';\n\ninterface StartupAnimationProps {\n onComplete: () => void;\n ready?: boolean;\n productName?: string;\n subtitle?: string;\n logo?: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n}\n\n/**\n * Startup splash animation — shown once when the app first loads after login.\n * Fades out after the animation completes, then unmounts.\n */\nexport default function StartupAnimation({ onComplete, ready = false, productName = 'react-os-shell', subtitle, logo = '/favicon.svg', adaptiveLogo = false, logoHasAlpha = null, logoIsLight = null }: StartupAnimationProps) {\n const [phase, setPhase] = useState<'logo' | 'text' | 'fade'>('logo');\n const [minTimePassed, setMinTimePassed] = useState(false);\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const fadingRef = useRef(false);\n\n useEffect(() => {\n const t1 = setTimeout(() => setPhase('text'), 600);\n const t2 = setTimeout(() => setMinTimePassed(true), 2000);\n // Safety: force complete after 5s even if ready never fires\n const t3 = setTimeout(() => {\n if (!fadingRef.current) { fadingRef.current = true; setPhase('fade'); setTimeout(() => onCompleteRef.current(), 500); }\n }, 5000);\n return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };\n }, []);\n\n // Fade out when both ready AND minimum time passed\n useEffect(() => {\n if (!ready || !minTimePassed || fadingRef.current) return;\n fadingRef.current = true;\n setPhase('fade');\n const t = setTimeout(() => onCompleteRef.current(), 500);\n return () => clearTimeout(t);\n }, [ready, minTimePassed]);\n\n return (\n <div\n data-startup-animation=\"\"\n className={`fixed inset-0 z-[9999] flex flex-col items-center justify-center transition-opacity duration-500 ${phase === 'fade' ? 'opacity-0 pointer-events-none' : 'opacity-100'}`}\n style={{ background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)' }}\n >\n {/* Glow effect */}\n <div className=\"absolute inset-0 overflow-hidden\">\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full opacity-20\"\n style={{ background: 'radial-gradient(circle, rgba(124,58,237,0.4) 0%, transparent 70%)', animation: 'pulse-glow 2s ease-in-out infinite' }} />\n </div>\n\n {/* Logo */}\n {/* The animation stays on the MARK, where it has always been. This\n wrapper owns the phase transition, and `spin-in` sets `transform`\n AND `opacity` with a forwards fill — animation declarations outrank\n normal ones, so putting it here would pin both at the 100% frame and\n leave the wrapper's scale/opacity classes doing nothing. */}\n <div className={`relative transition-all duration-700 ease-out ${phase === 'logo' ? 'scale-75 opacity-0' : 'scale-100 opacity-100'}`}>\n <BrandMark\n src={logo}\n alt=\"\"\n slot=\"compact\"\n surface=\"dark\"\n size={80}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n className=\"drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\"\n style={{ animation: 'spin-in 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards' }}\n />\n </div>\n\n {/* Title */}\n <div className={`mt-6 text-center transition-all duration-500 ${phase !== 'logo' ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>\n <h1 className=\"text-2xl font-bold tracking-[0.3em] text-white/90 uppercase\">{productName}</h1>\n <div className=\"mt-2 flex items-center justify-center gap-1.5\">\n {[0, 1, 2].map(i => (\n <div key={i} className=\"w-1.5 h-1.5 rounded-full bg-purple-400\"\n style={{ animation: `dot-bounce 1s ease-in-out ${i * 0.15}s infinite` }} />\n ))}\n </div>\n </div>\n\n {/* Subtitle (consumer-supplied — typically the company / product name) */}\n {subtitle && (\n <div className={`absolute bottom-8 transition-all duration-500 ${phase !== 'logo' ? 'opacity-40' : 'opacity-0'}`}>\n <p className=\"text-[10px] text-white/40 font-mono tracking-wider\">{subtitle}</p>\n </div>\n )}\n\n <style>{`\n @keyframes spin-in {\n 0% { transform: scale(0) rotate(-180deg); opacity: 0; }\n 100% { transform: scale(1) rotate(0deg); opacity: 1; }\n }\n @keyframes dot-bounce {\n 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }\n 40% { transform: scale(1); opacity: 1; }\n }\n @keyframes pulse-glow {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.15; }\n 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.25; }\n }\n /* Reduced motion: the fades stay, the movement goes. animation:none\n * (stylesheet !important beats the inline animation shorthands) parks\n * the spin/bounce/pulse at their base state; restricting transitions\n * to opacity turns the slide/scale phases into plain cross-fades.\n * Timings and the ready-gating are untouched — this is about motion,\n * not about how long the splash holds. */\n @media (prefers-reduced-motion: reduce) {\n [data-startup-animation], [data-startup-animation] * {\n animation: none !important;\n transition-property: opacity !important;\n }\n }\n `}</style>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { playLogout } from '../utils/sounds';\nimport { useShellStrings } from './strings';\nimport BrandMark from '../forms/BrandMark';\n\ninterface LogoutAnimationProps {\n onComplete: () => void;\n subtitle?: string;\n logo?: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n}\n\nexport default function LogoutAnimation({ onComplete, subtitle, logo = '/favicon.svg', adaptiveLogo = false, logoHasAlpha = null, logoIsLight = null }: LogoutAnimationProps) {\n // 'show' → greeting visible; 'out' → logo/title spin and fade away. The\n // full-screen cover itself stays opaque the whole time — it never fades to\n // transparent — so the desktop underneath is never revealed. onComplete\n // fires while the cover is still solid, so the consumer's login screen\n // swaps in behind it and the user goes straight from \"Goodbye\" to login\n // (no flash of the desktop in between).\n const [phase, setPhase] = useState<'show' | 'out'>('show');\n const strings = useShellStrings();\n\n useEffect(() => {\n playLogout();\n const t1 = setTimeout(() => setPhase('out'), 800);\n const t2 = setTimeout(onComplete, 2300);\n return () => { clearTimeout(t1); clearTimeout(t2); };\n }, [onComplete]);\n\n return (\n <div\n data-logout-animation=\"\"\n className=\"fixed inset-0 z-[9999] flex flex-col items-center justify-center\"\n style={{ background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)' }}\n >\n {/* Glow effect */}\n <div className=\"absolute inset-0 overflow-hidden\">\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full\"\n style={{\n background: 'radial-gradient(circle, rgba(124,58,237,0.4) 0%, transparent 70%)',\n animation: 'logout-glow 2s ease-in-out infinite',\n opacity: phase === 'show' ? 0.2 : 0,\n transition: 'opacity 1s',\n }} />\n </div>\n\n {/* Logo — spins out */}\n <div className={`relative transition-all duration-1000 ease-in ${phase === 'out' ? 'scale-0 opacity-0' : 'scale-100 opacity-100'}`}\n style={phase === 'out' ? { transform: 'scale(0) rotate(180deg)' } : undefined}>\n <BrandMark\n src={logo}\n alt=\"\"\n slot=\"compact\"\n surface=\"dark\"\n size={80}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n className=\"drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\"\n />\n </div>\n\n {/* Title — fades down */}\n <div className={`mt-6 text-center transition-all duration-700 ${phase === 'show' ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>\n <h1 className=\"text-2xl font-bold tracking-[0.3em] text-white/90 uppercase\">{strings.logout.goodbye}</h1>\n <p className=\"mt-2 text-xs text-white/40\">{strings.logout.seeYou}</p>\n </div>\n\n {/* Subtitle (consumer-supplied — typically the company / product name) */}\n {subtitle && (\n <div className={`absolute bottom-8 transition-all duration-500 ${phase === 'show' ? 'opacity-40' : 'opacity-0'}`}>\n <p className=\"text-[10px] text-white/40 font-mono tracking-wider\">{subtitle}</p>\n </div>\n )}\n\n <style>{`\n @keyframes logout-glow {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.15; }\n 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.25; }\n }\n /* Reduced motion: same contract as StartupAnimation — fades stay,\n * movement goes, the 2300ms cover-and-swap timing is untouched. */\n @media (prefers-reduced-motion: reduce) {\n [data-logout-animation], [data-logout-animation] * {\n animation: none !important;\n transition-property: opacity !important;\n }\n }\n `}</style>\n </div>\n );\n}\n","/**\n * SessionWindowRestore — reopen the windows the user had open.\n *\n * Window state is in-memory, so logging out — or just pressing F5 — has\n * always meant coming back to an empty desktop with the taskbar cleared.\n * Everything needed to rebuild it already existed: the window manager can\n * open a page window from its route and an entity window from its registry\n * key + id (it does exactly that when restoring a minimised item), and\n * ShellPrefs persists per-user state. This component is just the two wires:\n * it saves the identifying refs of the open windows (never their content),\n * and on a fresh mount with nothing open it replays them.\n *\n * Contracts:\n * - Off switch: `restore_windows: false` in prefs (Preferences → Behavior).\n * Default on.\n * - Restore runs ONCE per mount, and only when no window is already open —\n * a deep link that opened a window before this ran wins, we never stack\n * a stale session on top of it.\n * - Persisting starts only after the restore attempt, and writes only when\n * the open windows differ from the saved set — the set the restore read,\n * then the set last written that SETTLED (a save the adapter rejects does\n * not count, so the next change retries). So a mount, replayed or not, writes nothing\n * until the user opens or closes a window, and a consumer's adapter\n * re-rendering (a new `save` each render) writes nothing either.\n * Saves are debounced — opening five windows writes once.\n * - The saved refs are read from the prefs available AT MOUNT. The bundled\n * localStorage adapter is synchronous, so that is simply \"the prefs\"; a\n * consumer whose prefs hydrate later misses the restore for that load\n * rather than restoring at a surprising moment mid-session — and keeps its\n * saved set, because the empty desktop it mounted onto is not a change.\n * - Geometry is not session state. Moving or resizing a window changes no\n * ref, so it writes nothing here; each window's box is Modal's, kept in\n * browser localStorage (`erp_window_positions`).\n * - Part-number lookup windows are not restored: they open through a search\n * round-trip, not the registry, and a stale lookup re-running a search at\n * login is a surprise rather than a restoration.\n * - Draft windows (a New or Duplicate form — see draftWindow.ts) are neither\n * saved nor restored. Their id is a placeholder the endpoint 404s on, and\n * the snapshot that renders them is not session state: it is the form's\n * seed, not what the user typed, and a seed copied from yesterday's record\n * is not one to offer again at login. A ref saved before this rule is\n * skipped on restore, and the next write drops it from the saved set.\n */\nimport { useEffect, useRef } from 'react';\n\nimport { useWindowManager, type MinimizedItem } from './WindowManager';\nimport { useShellPrefsAdapter } from './ShellPrefs';\nimport { isDraftEntityId, isDraftEntityWindow } from './draftWindow';\n\nexport interface SessionWindowRef {\n type: 'page' | 'entity';\n route?: string;\n entityType?: string;\n entityId?: string;\n label?: string;\n}\n\n/** The persistable identity of each open window — content never leaves the\n * window, only the coordinates the registry needs to reopen it. */\nexport function toSessionRefs(openWindows: MinimizedItem[]): SessionWindowRef[] {\n const refs: SessionWindowRef[] = [];\n for (const w of openWindows) {\n if (w.type === 'page' && w.route) {\n refs.push({ type: 'page', route: w.route });\n } else if (w.entityType && w.entityId && w.type !== 'part_number' && !isDraftEntityWindow(w)) {\n refs.push({ type: 'entity', entityType: w.entityType, entityId: w.entityId, label: w.label, route: w.route });\n }\n }\n return refs;\n}\n\n/** Whether two ref lists name the same windows in the same order. Compared\n * field by field, not as JSON: a backend may hand the saved refs back with\n * their keys reordered (Postgres `jsonb` sorts them), which is no change. */\nexport function sameSessionRefs(a: SessionWindowRef[], b: SessionWindowRef[]): boolean {\n return a.length === b.length && a.every((r, i) => (\n r.type === b[i].type && r.route === b[i].route && r.entityType === b[i].entityType\n && r.entityId === b[i].entityId && r.label === b[i].label\n ));\n}\n\nconst SAVE_DEBOUNCE_MS = 800;\n\nexport default function SessionWindowRestore() {\n const { openWindows, openEntity, openPage } = useWindowManager();\n // The RAW adapter, not useShellPrefs: this is the one caller that needs a\n // failed write to come back as a rejection, so the write is retried rather\n // than recorded as saved. useShellPrefs swallows it for everyone else.\n const { prefs, save } = useShellPrefsAdapter();\n const restoredRef = useRef(false);\n // The set the prefs hold, as far as this mount knows: what the restore\n // read, then what was last written.\n const savedRef = useRef<SessionWindowRef[]>([]);\n // The refs of the write currently in flight, if any. Without this, a write\n // that has been fired but not yet settled compares different on every render\n // in between, and an adapter that hands over a new `save` each render (all\n // three EFFICIENT portals) would fire a second write for the same set.\n const pendingRef = useRef<SessionWindowRef[] | null>(null);\n // Identifies the most recent write, so one that settles late cannot move\n // `savedRef` back behind a newer one.\n const writeSeq = useRef(0);\n const saveTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // ── Restore, once, at mount ──\n useEffect(() => {\n if (restoredRef.current) return;\n restoredRef.current = true;\n const saved: SessionWindowRef[] = Array.isArray(prefs.session_windows) ? prefs.session_windows : [];\n savedRef.current = saved;\n if (prefs.restore_windows === false) return;\n if (openWindows.length > 0) return;\n for (const w of saved) {\n if (w.type === 'page' && w.route) openPage(w.route);\n else if (w.type === 'entity' && w.entityType && w.entityId && !isDraftEntityId(w.entityId)) {\n openEntity(w.entityType, w.entityId, undefined, w.label, w.route);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Persist on change, only after the restore attempt ──\n useEffect(() => {\n if (!restoredRef.current) return;\n clearTimeout(saveTimer.current);\n const refs = toSessionRefs(openWindows);\n // The desktop matches the saved set: nothing to write. This is what keeps\n // a mount whose prefs had not arrived from writing its empty desktop over\n // the set it never saw. It runs after the clear, so a window opened and\n // closed again inside the debounce cancels its own pending write.\n if (sameSessionRefs(refs, savedRef.current)) return;\n // Already on its way. Re-arming here is what would write it twice.\n if (pendingRef.current && sameSessionRefs(refs, pendingRef.current)) return;\n saveTimer.current = setTimeout(() => {\n // Advance the saved set when the write SETTLES, not when it is fired. A\n // rejected save must leave `savedRef` on the old set, so the next change\n // still compares different and writes the whole list again rather than\n // the shell believing a lost write landed and never retrying.\n // - `save` may return void (the bundled localStorage adapter does),\n // hence Promise.resolve.\n // - `seq` drops a write that settles out of order, so a slow earlier\n // write cannot pull `savedRef` back behind a later one.\n // - A rejection clears `pendingRef` without advancing `savedRef`, so\n // the next render or window change retries — which is how this\n // behaved before the set was tracked at all.\n // - An adapter that swallows its OWN failure resolves either way and\n // this cannot tell the two apart: it has to let the rejection reach\n // the shell. Every EFFICIENT portal adapter currently catches before\n // its `.then()`, so for those this is inert until they are changed.\n const seq = ++writeSeq.current;\n pendingRef.current = refs;\n void Promise.resolve(save({ session_windows: refs }))\n .then(() => {\n if (seq !== writeSeq.current) return;\n savedRef.current = refs;\n pendingRef.current = null;\n })\n .catch(() => { if (seq === writeSeq.current) pendingRef.current = null; });\n }, SAVE_DEBOUNCE_MS);\n return () => clearTimeout(saveTimer.current);\n }, [openWindows, save]);\n\n return null;\n}\n","import { useState, useEffect, useLayoutEffect, useRef, isValidElement, cloneElement, type ReactElement, type ReactNode } from 'react';\nimport {\n navSections as defaultNavSections,\n navIcons as defaultNavIcons,\n sectionIcons as defaultSectionIcons,\n startMenuCategories as defaultCategories,\n isSection,\n type NavSection,\n type NavItem,\n type StartMenuCategories,\n type VirtualSection,\n} from '../shell-config/nav';\nimport { visibleChildren as navVisibleChildren, isReachable, navVisible } from './nav-types';\nimport {\n openMenuLevel, closeMenuBelow, resolveMenuLevels, clampMenuTop, menuPanelLeft,\n type MenuAnchor,\n} from './menuPath';\nimport { markMenuOpen } from './perfEvents';\nimport { useAuth } from '../contexts/AuthContext';\nimport { glassStyle, GLASS_INPUT_BG } from '../utils/glass';\nimport { useIsMobile } from './useIsMobile';\n\ninterface StartMenuProps {\n open: boolean; onClose: () => void; openPage: (path: string) => void;\n openWindows: { route?: string; label: string }[];\n profile: any; user: any; onLogout: () => void; onNavigate: (path: string) => void;\n taskbarPosition: 'top' | 'bottom' | 'left' | 'right'; taskbarH: number; taskbarW?: number;\n /** Gap (px) between the menu and the taskbar edge; set per taskbar size by Layout. */\n taskbarGap?: number;\n size?: 'small' | 'medium' | 'large';\n /** Override the default nav sections (sections + top-level items). */\n navSections?: (NavSection | NavItem)[];\n /** Per-route icon map for items in the menu. */\n navIcons?: Record<string, ReactNode>;\n /** Per-section header icon map. */\n sectionIcons?: Record<string, ReactNode>;\n /** Section grouping + virtual flyouts (Utilities-style trays). */\n categories?: StartMenuCategories;\n}\n\nconst ITEM_H = 36; // approximate height per menu item in px\n\n/** Gap between a panel and the one it opened from. */\nconst PANEL_GAP = 4;\n/** Grace period before a submenu closes, so the pointer can cut the corner\n * across sibling rows and the gap on its way into the panel. */\nconst CLOSE_DELAY = 200;\n\ntype MenuLabelled = { label: string; menuLabel?: string };\n\nconst visibleMenuLabel = (entry: MenuLabelled) => entry.menuLabel ?? entry.label;\n\nconst isAbbreviated = (entry: MenuLabelled) =>\n Boolean(entry.menuLabel && entry.menuLabel !== entry.label);\n\n/** An abbreviated row is named \"<compact>, <full>\", in that order: the\n * accessible name has to START with the text on screen or voice control\n * (\"click AP\") stops matching the row the user can actually see — WCAG 2.5.3.\n * A row showing its own full label needs no override at all; its text content\n * already IS the name, and CSS truncation does not change that. */\nconst menuAriaLabel = (entry: MenuLabelled) =>\n isAbbreviated(entry) ? `${entry.menuLabel}, ${entry.label}` : undefined;\n\n/**\n * A row's visible name, with a native tooltip ONLY where what you can read is\n * not the whole name: an explicit compact `menuLabel`, or a label this row had\n * to clip. Titling every row instead hangs a tooltip off ordinary short labels\n * — and hovering a row is also what opens its flyout, so the two fight. The\n * measurement runs on enter, so it costs nothing until someone hovers.\n */\nfunction MenuLabel({ entry, className }: { entry: MenuLabelled; className: string }) {\n const abbreviated = isAbbreviated(entry);\n const [titled, setTitled] = useState(abbreviated);\n return (\n <span\n className={className}\n title={titled ? entry.label : undefined}\n data-menu-label\n onMouseEnter={e => setTitled(abbreviated || e.currentTarget.scrollWidth > e.currentTarget.clientWidth)}\n >\n {visibleMenuLabel(entry)}\n </span>\n );\n}\n\n/**\n * One flyout panel — the same component at every depth.\n *\n * It positions itself in a layout effect rather than from state. The `top` in\n * the style prop is only an estimate from the item count; the effect replaces\n * it with one measured off the rendered panel, before the browser paints. That\n * ordering is the point: a panel repositioned from state moves AFTER paint,\n * which slides its rows out from under a pointer that hasn't moved — and a row\n * that moves away from the pointer never gets its `mouseenter`, so the next\n * level opens late or not at all.\n */\nfunction MenuPanel({ left, anchorY, estHeight, minTop, maxBottom, flipped, className, style, onMouseEnter, onMouseLeave, children }: {\n left: number;\n anchorY: number;\n estHeight: number;\n minTop: number;\n maxBottom: number;\n /** Opened to the LEFT of its parent — slide in from that side too. */\n flipped?: boolean;\n className?: string;\n style?: React.CSSProperties;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n children: ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n // No dep array: any re-render can change the content's height, and the\n // correction costs one property write against the DOM node React just wrote.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.style.top = `${clampMenuTop(anchorY, el.offsetHeight, minTop, maxBottom)}px`;\n });\n return (\n <div\n ref={ref}\n data-menu-panel\n className={`fixed rounded-2xl overflow-hidden ${className ?? ''}`}\n style={{ left, top: clampMenuTop(anchorY, estHeight, minTop, maxBottom), animation: `${flipped ? 'submenu-in-left' : 'submenu-in'} 0.1s ease-out`, ...style }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </div>\n );\n}\n\nexport default function StartMenu({\n open, onClose, openPage, profile, user, onLogout,\n taskbarPosition, taskbarH, taskbarW = 0, taskbarGap = 4, size = 'medium',\n navSections = defaultNavSections,\n navIcons = defaultNavIcons,\n sectionIcons = defaultSectionIcons,\n categories = defaultCategories,\n}: StartMenuProps) {\n const erpLabels = new Set(categories.erp);\n const systemLabels = new Set(categories.system);\n const footerLabels = new Set(categories.footer ?? []);\n const virtualSections = categories.virtual ?? [];\n const virtualByLabel: Record<string, VirtualSection> = Object.fromEntries(\n virtualSections.map(v => [v.label, v]),\n );\n const { hasAnyPerm } = useAuth();\n // Flat rows pinned to the footer (next to the profile), e.g. System\n // Preferences. Rendered directly — no flyout — unlike `categories.footer`.\n const footerItems = (categories.footerItems ?? []).filter(item => navVisible(item, hasAnyPerm));\n const isMobile = useIsMobile();\n // Which flyouts are open, outermost first — one entry per panel, any depth.\n // `openPath[0]` is the section row hovered in the menu itself, `openPath[1]`\n // the row hovered inside the panel that opened, and so on. See `menuPath.ts`\n // for the rules; every level goes through them, so there is no such thing\n // here as \"the 3rd-level case\".\n const [openPath, setOpenPath] = useState<MenuAnchor[]>([]);\n const [search, setSearch] = useState('');\n const [searchIdx, setSearchIdx] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n // ONE close timer for the whole menu. Every handler that could close\n // something clears it before doing anything else, so a pending close from a\n // row the pointer merely passed over can never fire after a submenu has\n // opened and shut it under the cursor.\n const closeTimer = useRef<ReturnType<typeof setTimeout>>();\n\n useEffect(() => { if (!open) { setSearch(''); setOpenPath([]); setSearchIdx(0); } }, [open]);\n useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n // ── Perf marks ──\n // Each layer is a fresh frosted-glass surface measured, positioned and\n // animated in over everything already on screen, which makes opening one the\n // most expensive thing this menu does — and, on a slow machine, the moment\n // people notice. Marked from an effect rather than from the hover handlers so\n // every route in (pointer, keyboard, a section cleared and re-entered) is\n // counted once, and only when the layer actually renders.\n const deepestOpen = openPath.length > 0 ? openPath[openPath.length - 1].key : null;\n useEffect(() => { if (open) markMenuOpen('menu', 'start'); }, [open]);\n useEffect(() => { if (deepestOpen) markMenuOpen('submenu', deepestOpen); }, [deepestOpen]);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n const click = (e: PointerEvent | MouseEvent) => {\n if ((e.target as HTMLElement).closest('[data-menu-toggle]')) return;\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) onClose();\n };\n window.addEventListener('keydown', handler);\n window.addEventListener('pointerdown', click);\n return () => { window.removeEventListener('keydown', handler); window.removeEventListener('pointerdown', click); };\n }, [open, onClose]);\n\n if (!open) return null;\n\n const handleClick = (path: string) => { openPage(path); onClose(); };\n // A row is a destination (`to`) unless it carries an action of its own.\n const select = (item: NavItem) => {\n if (item.onSelect) { item.onSelect(); onClose(); return; }\n handleClick(item.to);\n };\n\n // Coarse-pointer / narrow viewport: render as a full-screen slide-up sheet\n // with search + a flat, tappable list instead of the dense desktop columns.\n if (isMobile) {\n const allItems: { item: NavItem; sectionLabel?: string }[] = [];\n // Recursively flatten — nested children at any depth show up as their own\n // rows so they can be searched/tapped from the mobile sheet too.\n const pushItem = (it: NavItem, sectionLabel?: string) => {\n if (!navVisible(it, hasAnyPerm)) return;\n // Same reachability rule as the desktop flyout — an empty group is not a\n // tap target, so don't list one.\n if (!isReachable(it, hasAnyPerm)) return;\n allItems.push({ item: it, sectionLabel });\n for (const c of navVisibleChildren(it, hasAnyPerm)) pushItem(c, it.label);\n };\n for (const entry of navSections) {\n if (isSection(entry)) {\n const sec = entry as NavSection;\n if (!navVisible(sec, hasAnyPerm)) continue;\n for (const it of sec.items) pushItem(it, sec.label);\n } else {\n pushItem(entry as NavItem);\n }\n }\n for (const it of footerItems) pushItem(it);\n const filtered = search.length >= 1\n ? allItems.filter(({ item }) => item.label.toLowerCase().includes(search.toLowerCase()))\n : allItems;\n\n return (\n <div\n ref={menuRef}\n className=\"fixed inset-0 z-[260] flex flex-col bg-white\"\n style={{ paddingBottom: 'var(--mobile-bottom-nav, 56px)' }}\n >\n {/* Sheet handle + header */}\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-gray-200\">\n <button onClick={onClose} className=\"p-2 -ml-1 rounded-full active:bg-gray-200 text-gray-700\" aria-label=\"Close menu\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n <div className={`flex-1 flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-3 py-2`}>\n <svg className=\"h-4 w-4 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" />\n </svg>\n <input\n value={search}\n onChange={e => setSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"flex-1 bg-transparent text-sm outline-none placeholder-gray-400\"\n autoFocus\n />\n </div>\n </div>\n\n {/* Mobile rows follow the same one-line naming contract as desktop.\n Both axes are still named deliberately: `overflow-y-auto` on its own\n computes the other axis to `auto` too, and one nav label with no\n break opportunity in it — 110px past a 174px flyout, measured — then\n hangs a horizontal scrollbar on a panel of fixed width. The label\n used to WRAP (`wrap-anywhere`) to stay inside that pinned axis; now\n every row is one line and each label truncates instead, so the axis\n still has to be pinned shut but nothing needs to wrap. */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden\">\n {filtered.length === 0 ? (\n <p className=\"text-sm text-gray-400 text-center py-12\">No matching apps</p>\n ) : (\n filtered.map(({ item, sectionLabel }, i) => {\n const icon = navIcons[item.to];\n return (\n <button\n key={`${item.to}-${i}`}\n onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className=\"w-full flex items-center gap-3 px-4 py-3 active:bg-gray-100 border-b border-gray-100 text-left\"\n >\n <span className=\"h-8 w-8 rounded-lg bg-gray-100 flex items-center justify-center text-gray-600 shrink-0\">\n {icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-5 w-5' })\n : null}\n </span>\n <div className=\"min-w-0 flex-1\">\n <MenuLabel entry={item} className=\"block truncate text-sm font-medium text-gray-900\" />\n {sectionLabel && <div className=\"text-[11px] text-gray-500 truncate\">{sectionLabel}</div>}\n </div>\n </button>\n );\n })\n )}\n </div>\n </div>\n );\n }\n\n // Use the \"vertical\" (sidebar-style) layout for top, left, right taskbar positions.\n // Only the bottom taskbar uses the original layout (top items first, ERP after divider).\n const isVertical = taskbarPosition !== 'bottom';\n // Top-level rows pass the same permission + reachability test as the rows in\n // a section. Read raw, a row gated on `perms`/`allPerms` showed to users who\n // could not open it — only the mobile sheet above checked — and still counted\n // toward `hasAppsGroup`, so a hidden row kept its divider.\n const topItems = (navSections.filter(item => !isSection(item)) as NavItem[])\n .filter(item => navVisible(item, hasAnyPerm) && isReachable(item, hasAnyPerm));\n const erpSections = navSections.filter(item => isSection(item) && erpLabels.has((item as NavSection).label));\n const systemSections = navSections.filter(item => isSection(item) && systemLabels.has((item as NavSection).label));\n const footerSections = navSections.filter(item => isSection(item) && footerLabels.has((item as NavSection).label));\n // The \"apps\" group = top-level items + system + virtual sections. Gates the\n // ERP↔apps divider so it only renders when both sides have content.\n const hasAppsGroup = topItems.length > 0 || systemSections.length > 0 || virtualSections.length > 0;\n\n const getVisibleItems = (section: NavSection) =>\n section.items.filter(item => navVisible(item, hasAnyPerm));\n\n const visibleChildren = (item: NavItem) => navVisibleChildren(item, hasAnyPerm);\n\n /** The sub-items a row opens — nothing for a leaf, and nothing for a group\n * whose every branch dead-ends in permission-hidden items. Same list the\n * chevron is drawn from, at every depth. */\n const submenuItems = (item: NavItem) =>\n visibleChildren(item).filter(child => isReachable(child, hasAnyPerm));\n\n // Search — walks nested children to any depth. Section column shows the\n // parent item label for children so users can tell nested entries apart.\n const matchTree = (it: NavItem, sectionLabel: string): (NavItem & { section: string })[] => {\n if (!navVisible(it, hasAnyPerm)) return [];\n // Same rule as the flyout: a group whose children are all hidden isn't a\n // reachable destination, so it shouldn't surface as a result either.\n if (!isReachable(it, hasAnyPerm)) return [];\n const kids = visibleChildren(it);\n const hits: (NavItem & { section: string })[] = [];\n if (it.label.toLowerCase().includes(search.toLowerCase())) {\n hits.push({ ...it, section: sectionLabel });\n }\n for (const c of kids) hits.push(...matchTree(c, it.label));\n return hits;\n };\n const searchResults = search.length >= 2 ? [\n ...navSections.flatMap(item => {\n if (isSection(item)) {\n const sec = item as NavSection;\n return sec.items.flatMap(i => matchTree(i, sec.label));\n }\n return matchTree(item as NavItem, '');\n }),\n ...footerItems.flatMap(item => matchTree(item, '')),\n ] : [];\n\n const posStyle: React.CSSProperties =\n taskbarPosition === 'top' ? { top: taskbarH + taskbarGap, left: 8 } :\n taskbarPosition === 'left' ? { top: 8, left: taskbarW + taskbarGap } :\n taskbarPosition === 'right' ? { top: 8, right: taskbarW + taskbarGap } :\n { bottom: taskbarH + taskbarGap, left: 8 };\n\n const iconEl = (path: string) => {\n const icon = navIcons[path];\n if (icon && isValidElement(icon)) return cloneElement(icon as ReactElement, { className: 'h-4 w-4 shrink-0' });\n return null;\n };\n\n const secIcon = (label: string) => {\n const icon = sectionIcons[label];\n if (icon && isValidElement(icon)) return cloneElement(icon as ReactElement, { className: 'h-4 w-4 shrink-0' });\n return null;\n };\n\n // Flyout data — either a real section or a configured virtual section\n const hoveredSection = openPath.length > 0 ? openPath[0].key : null;\n const hoveredVirtual = hoveredSection ? virtualByLabel[hoveredSection] : undefined;\n const hoveredData = hoveredVirtual\n ? null\n : (hoveredSection ? [...erpSections, ...systemSections, ...footerSections].find(s => (s as NavSection).label === hoveredSection) as NavSection | undefined : null);\n const flyoutItems = (hoveredVirtual\n ? hoveredVirtual.items\n : (hoveredData ? getVisibleItems(hoveredData) : [])\n ).filter(item => isReachable(item, hasAnyPerm));\n\n // Density from CSS variable — three tiers controlling the vertical gap between\n // rows: tight < normal < large. `normal` is the default and sits a little\n // tighter than `large`.\n const menuDensity = typeof document !== 'undefined' ? (getComputedStyle(document.documentElement).getPropertyValue('--menu-density')?.trim() || 'normal') : 'normal';\n const density: 'tight' | 'normal' | 'large' = menuDensity === 'tight' || menuDensity === 'large' ? menuDensity : 'normal';\n\n // Size-dependent styles, adjusted for density. `fwPx` is `fw` in pixels —\n // panels are placed before they render, so the flip-to-the-left decision\n // can't wait for a measurement.\n const sizeConfigByDensity = {\n tight: { small: { w: 'w-52', fw: 'w-44', fwPx: 176, text: 'text-xs', py: 'py-1', px: 'px-3', mw: 208, itemH: 24 }, medium: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-1', px: 'px-3', mw: 224, itemH: 26 }, large: { w: 'w-64', fw: 'w-52', fwPx: 208, text: 'text-sm', py: 'py-1.5', px: 'px-3', mw: 256, itemH: 30 } },\n normal: { small: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-1.5', px: 'px-3', mw: 224, itemH: 30 }, medium: { w: 'w-64', fw: 'w-56', fwPx: 224, text: 'text-sm', py: 'py-1.5', px: 'px-4', mw: 256, itemH: 32 }, large: { w: 'w-72', fw: 'w-60', fwPx: 240, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 288, itemH: 36 } },\n large: { small: { w: 'w-56', fw: 'w-48', fwPx: 192, text: 'text-xs', py: 'py-2', px: 'px-3', mw: 224, itemH: 32 }, medium: { w: 'w-64', fw: 'w-56', fwPx: 224, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 256, itemH: 36 }, large: { w: 'w-72', fw: 'w-60', fwPx: 240, text: 'text-sm', py: 'py-2', px: 'px-4', mw: 288, itemH: 36 } },\n };\n const sizeConfig = sizeConfigByDensity[density][size];\n const menuGlass = glassStyle();\n const itemCls = `w-full min-w-0 overflow-hidden whitespace-nowrap flex items-center gap-2 rounded-lg ${sizeConfig.px} ${sizeConfig.py} ${sizeConfig.text}`;\n const itemLabelCls = 'min-w-0 flex-1 truncate text-left';\n\n // The usable vertical span for a panel: the screen minus the taskbar edge and\n // an 8px gutter, so a flyout can never sit over the taskbar or run off the\n // bottom. The span is the viewport, NOT the main menu's rect: a submenu can\n // legitimately be taller than the menu that opened it (e.g. \"System\" with far\n // more items than the menu has rows). A panel taller than the span is capped\n // at `availH` and scrolls — see `maxHeight` below.\n const viewportH = typeof window !== 'undefined' ? window.innerHeight : 800;\n const viewportW = typeof window !== 'undefined' ? window.innerWidth : 1280;\n const minTop = (taskbarPosition === 'top' ? taskbarH : 0) + 8;\n const maxBottom = viewportH - (taskbarPosition === 'bottom' ? taskbarH : 0) - 8;\n const availH = Math.max(0, maxBottom - minTop);\n\n // Every open flyout's items, outermost first.\n const levels = resolveMenuLevels(flyoutItems, openPath, submenuItems);\n\n const cancelClose = () => clearTimeout(closeTimer.current);\n\n /**\n * Where the panel opened from a row in panel `depth` starts horizontally.\n *\n * Panel 0 is the main menu, so it gets measured. Deeper panels are ours: we\n * put them where `openPath` says, and `offsetWidth` is the untransformed\n * layout width — neither reading is disturbed by the `submenu-in` animation\n * still running on the panel the pointer is in, which a `getBoundingClientRect`\n * would pick up and shift the next panel by.\n */\n const nextPanelLeft = (depth: number, row: HTMLElement) => {\n const owner = row.closest('[data-menu-panel]') as HTMLElement | null;\n if (!owner) return { left: 0, flipped: false };\n const ownerLeft = depth === 0 ? owner.getBoundingClientRect().left : (openPath[depth - 1]?.left ?? 0);\n const ownerRight = depth === 0 ? owner.getBoundingClientRect().right : ownerLeft + owner.offsetWidth;\n const preferLeft = depth > 0 && (openPath[depth - 1]?.flipped ?? false);\n return menuPanelLeft(ownerLeft, ownerRight, sizeConfig.fwPx, viewportW, PANEL_GAP, preferLeft);\n };\n\n /** Hovering a row in panel `depth` that has a submenu — open it now. */\n const openSubmenu = (depth: number, key: string, e: React.MouseEvent) => {\n cancelClose();\n const row = e.currentTarget as HTMLElement;\n const rect = row.getBoundingClientRect();\n const anchor: MenuAnchor = { key, y: rect.top + rect.height / 2, ...nextPanelLeft(depth, row) };\n setOpenPath(prev => openMenuLevel(prev, depth, anchor));\n };\n\n /**\n * Nothing under panel `depth` is wanted any more — the pointer is on a row\n * with no submenu, or has left a panel entirely. Deferred by `CLOSE_DELAY`\n * because the pointer may simply be cutting the corner on its way into the\n * panel it just opened, and immediate by cancellation because whatever the\n * pointer lands on next re-states the intent.\n */\n const scheduleClose = (depth: number) => {\n cancelClose();\n closeTimer.current = setTimeout(() => setOpenPath(prev => closeMenuBelow(prev, depth)), CLOSE_DELAY);\n };\n\n const chevron = (\n <svg className=\"h-3.5 w-3.5 shrink-0 ml-auto text-gray-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" /></svg>\n );\n\n const renderSection = (section: NavSection, isErp: boolean) => {\n if (!navVisible(section, hasAnyPerm)) return null;\n const items = getVisibleItems(section);\n if (items.length === 0) return null;\n const isHovered = hoveredSection === section.label;\n return (\n <div key={section.label} onMouseEnter={e => openSubmenu(0, section.label, e)}>\n <button\n aria-label={menuAriaLabel(section)}\n className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}\n >\n {secIcon(section.label)}\n <MenuLabel entry={section} className={`${itemLabelCls} ${isErp ? 'font-medium' : ''}`} />\n {chevron}\n </button>\n {section.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n };\n\n const renderVirtualSection = (v: VirtualSection) => {\n if (v.items.length === 0) return null;\n const isHovered = hoveredSection === v.label;\n return (\n <div key={v.label} onMouseEnter={e => openSubmenu(0, v.label, e)}>\n <button\n aria-label={menuAriaLabel(v)}\n className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}\n >\n <span className=\"shrink-0\">{v.icon}</span>\n <MenuLabel entry={v} className={itemLabelCls} />\n {chevron}\n </button>\n </div>\n );\n };\n\n return (\n /* z-[1100]: sit above the entire window stack — normal windows climb to\n 50 + idx*10 + 1 and pinned-on-top windows render at 999 (see Modal.tsx),\n which previously painted over the open Start menu (BG#00259). 1100 clears\n both. Deliberately kept BELOW Exposé / mission-control (zIndex 2000–9999\n in Modal.tsx) and the transient full-screen overlay tier (toasts,\n startup, logout — z-[9999]), which should still cover the menu. */\n <div ref={menuRef} className=\"fixed z-[1100]\" style={posStyle}>\n <div className=\"flex\">\n {/* Main menu — panel 0. Entering or leaving it schedules the flyouts\n shut; whichever row the pointer settles on says otherwise, either by\n opening its own submenu or by scheduling the same close again. */}\n <div data-menu-panel className={`${sizeConfig.w} rounded-2xl flex ${isVertical ? 'flex-col-reverse' : 'flex-col'} overflow-hidden`}\n style={{ animation: 'menu-in 0.15s ease-out', ...menuGlass }}\n onMouseEnter={() => scheduleClose(0)}\n onMouseLeave={() => scheduleClose(0)}>\n\n {/* Search — at top for horizontal, at bottom for vertical */}\n <div className={`px-3 ${isVertical ? 'pb-3 pt-2 border-t border-white/20' : 'pt-3 pb-2'}`}\n onMouseEnter={() => scheduleClose(0)}>\n <div className={`flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-2.5 py-1.5`}>\n <svg className=\"h-3.5 w-3.5 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" /></svg>\n <input value={search} onChange={e => { setSearch(e.target.value); setOpenPath([]); setSearchIdx(0); }}\n onKeyDown={e => {\n if (search.length >= 2 && searchResults.length > 0) {\n if (e.key === 'ArrowDown') { e.preventDefault(); setSearchIdx(i => Math.min(i + 1, searchResults.length - 1)); }\n else if (e.key === 'ArrowUp') { e.preventDefault(); setSearchIdx(i => Math.max(i - 1, 0)); }\n else if (e.key === 'Enter') { e.preventDefault(); select(searchResults[searchIdx]); }\n }\n }}\n placeholder=\"Search...\"\n className=\"flex-1 bg-transparent text-xs outline-none placeholder-gray-400\" autoFocus />\n </div>\n </div>\n\n {search.length >= 2 ? (\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden px-1 pb-2 max-h-[400px]\">\n {searchResults.length === 0 ? (\n <p className=\"text-xs text-gray-400 text-center py-4\">No results</p>\n ) : searchResults.map((r, i) => (\n <button key={i} onClick={() => select(r)}\n onMouseEnter={() => setSearchIdx(i)}\n aria-label={menuAriaLabel(r)}\n className={`${itemCls} transition-colors ${i === searchIdx ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {iconEl(r.to)}\n <MenuLabel entry={r} className={itemLabelCls} />\n {r.section && <span className=\"max-w-[40%] shrink-0 truncate text-[10px] text-gray-400 ml-auto\">{r.section}</span>}\n </button>\n ))}\n </div>\n ) : (\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden px-1 pb-1 flex flex-col\">\n {isVertical && (<>\n {/* Reversed column → profile sits at the top, so footer items +\n sections render first to stay pinned next to it. */}\n {footerItems.map(item => (\n <button key={item.to} onClick={() => select(item)}\n onMouseEnter={() => scheduleClose(0)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n ))}\n {footerSections.map(s => renderSection(s as NavSection, false))}\n {(footerSections.length > 0 || footerItems.length > 0) && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {/* Vertical layout: ERP sections first */}\n {erpSections.map(s => renderSection(s as NavSection, true))}\n {erpSections.length > 0 && hasAppsGroup && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {/* Then top-level items + system */}\n {topItems.map(item => (\n <div key={item.to} onMouseEnter={() => scheduleClose(0)}>\n <button onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n ))}{systemSections.map(s => renderSection(s as NavSection, false))}\n {virtualSections.map(v => renderVirtualSection(v))}\n </>)}\n\n {!isVertical && (<>\n {/* Horizontal layout: top-level items first, ERP after divider */}\n {topItems.map(item => (\n <div key={item.to} onMouseEnter={() => scheduleClose(0)}>\n <button onClick={() => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n ))}{systemSections.map(s => renderSection(s as NavSection, false))}\n {virtualSections.map(v => renderVirtualSection(v))}\n {hasAppsGroup && erpSections.length > 0 && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {erpSections.map(s => renderSection(s as NavSection, true))}\n {/* Footer items + sections: pinned just above the profile, divided from ERP. */}\n {(footerSections.length > 0 || footerItems.length > 0) && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n {footerSections.map(s => renderSection(s as NavSection, false))}\n {footerItems.map(item => (\n <button key={item.to} onClick={() => select(item)}\n onMouseEnter={() => scheduleClose(0)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n </button>\n ))}\n </>)}\n </div>\n )}\n\n {/* User profile — name + sign out on same row */}\n <div className={`${isVertical ? 'border-b' : 'border-t'} border-white/20 p-1`} onMouseEnter={() => scheduleClose(0)}>\n <div onClick={() => handleClick('/profile')}\n className=\"rounded-lg px-2 py-1.5 flex items-center gap-2.5 hover:bg-blue-50 hover:text-blue-700 transition-colors cursor-pointer\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-8 w-8 rounded-full object-cover border border-white/20 shrink-0\" />\n ) : (\n <div className=\"h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-sm font-bold text-blue-700 shrink-0\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <p className=\"flex-1 min-w-0 text-sm font-medium text-gray-900 truncate\">\n {profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}\n </p>\n <button onClick={e => { e.stopPropagation(); onClose(); onLogout(); }} title=\"Sign Out\"\n className=\"shrink-0 p-1.5 rounded-md text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9\" /></svg>\n </button>\n </div>\n </div>\n </div>\n\n {/* Flyouts — one panel per open level, centred on the row that opened\n it and clamped into the usable viewport span. Every level renders\n from this one loop: the section flyout is `levels[0]` and is built\n exactly like the one six levels down, so there is no depth at which\n the menu starts behaving differently. */}\n {search.length < 2 && levels.map((items, i) => (\n <MenuPanel\n key={`${i}:${openPath[i].key}`}\n left={openPath[i].left}\n anchorY={openPath[i].y}\n estHeight={items.length * sizeConfig.itemH + 12}\n minTop={minTop}\n maxBottom={maxBottom}\n flipped={openPath[i].flipped}\n className={sizeConfig.fw}\n style={menuGlass}\n /* Landing anywhere in this panel — a row, a divider, the padding —\n retires the branch below it. A row that has its own submenu\n cancels that on the way past, because React fires the panel's\n `mouseenter` before the row's. */\n onMouseEnter={() => scheduleClose(i + 1)}\n onMouseLeave={() => scheduleClose(i)}\n >\n <div className=\"py-1 px-1 overflow-y-auto overflow-x-hidden overscroll-contain\" style={{ maxHeight: availH }}>\n {items.map(item => {\n const kids = submenuItems(item);\n const isOpen = openPath[i + 1]?.key === item.to;\n return (\n <div key={item.to}\n onMouseEnter={kids.length > 0 ? e => openSubmenu(i + 1, item.to, e) : () => scheduleClose(i + 1)}>\n <button\n /* A group's `to` is a synthetic key by convention, so\n clicking one navigates nowhere — it opens its submenu,\n the same thing hovering it does, instead of closing the\n menu on a route that does not exist. */\n onClick={kids.length > 0 ? e => openSubmenu(i + 1, item.to, e) : () => select(item)}\n aria-label={menuAriaLabel(item)}\n className={`${itemCls} transition-colors ${isOpen ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {iconEl(item.to)}\n <MenuLabel entry={item} className={itemLabelCls} />\n {kids.length > 0 && chevron}\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n })}\n </div>\n </MenuPanel>\n ))}\n </div>\n\n <style>{`\n @keyframes menu-in { from { opacity: 0; transform: scale(0.95) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }\n @keyframes submenu-in { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: translateX(0); } }\n @keyframes submenu-in-left { from { opacity: 0; transform: translateX(4px); } to { opacity: 1; transform: translateX(0); } }\n `}</style>\n </div>\n );\n}\n","/**\n * Mobile landing screen — shown by <Layout> in place of the desktop chrome on\n * phone/tablet-portrait viewports (see useIsMobile).\n *\n * The shell no longer ships its own touch \"mobile mode\". Instead the consumer\n * wires a link to their dedicated mobile app (native deep link, App Store /\n * Play Store page, or a mobile-optimised web app) through Layout's `mobileApp`\n * prop, and this screen surfaces it. With no link configured it degrades to a\n * plain \"best viewed on desktop\" notice so a consumer that hasn't adopted the\n * prop yet still gets a coherent small-screen screen rather than the cramped\n * desktop shell.\n */\nimport type { CSSProperties } from 'react';\nimport { glassStyle } from '../utils/glass';\nimport BrandMark from '../forms/BrandMark';\n\nexport interface MobileAppConfig {\n /** Link the primary button opens — a native deep link, an App Store /\n * Play Store page, or a mobile-optimised web app. When omitted the screen\n * still renders (branding + message) but without a call-to-action. */\n url?: string;\n /** Primary button label. Defaults to `Open the app`. */\n ctaLabel?: string;\n /** Headline. Defaults to a message built from the product name. */\n heading?: string;\n /** Supporting copy under the headline. */\n description?: string;\n}\n\ninterface MobileAppLandingProps {\n productName: string;\n productIcon: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n /** Consumer-wired mobile-app link + copy. */\n config?: MobileAppConfig;\n /** Wallpaper / background style computed by Layout so the user's chosen\n * desktop background carries onto the landing screen. */\n wallpaperStyle?: CSSProperties;\n}\n\nexport default function MobileAppLanding({\n productName,\n productIcon,\n adaptiveLogo = false,\n logoHasAlpha = null,\n logoIsLight = null,\n config,\n wallpaperStyle,\n}: MobileAppLandingProps) {\n const hasLink = !!config?.url;\n const heading =\n config?.heading ??\n (hasLink\n ? `Continue in the ${productName} app`\n : `${productName} works best on desktop`);\n const description =\n config?.description ??\n (hasLink\n ? 'This experience is built for the mobile app. Open it to continue on your phone.'\n : 'Open this page on a larger screen to continue.');\n const ctaLabel = config?.ctaLabel ?? 'Open the app';\n\n return (\n <div\n className=\"flex-1 flex items-center justify-center p-6\"\n style={{ ...wallpaperStyle, paddingBottom: 'calc(env(safe-area-inset-bottom) + 1.5rem)' }}\n >\n <div\n className=\"w-full max-w-sm rounded-3xl p-8 flex flex-col items-center text-center\"\n style={glassStyle()}\n >\n <div className=\"h-20 w-20 rounded-2xl overflow-hidden bg-white/60 flex items-center justify-center shadow-sm mb-5\">\n <BrandMark\n src={productIcon}\n alt=\"\"\n slot=\"compact\"\n surface=\"light\"\n size={56}\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n decorative\n />\n </div>\n\n <h1 className=\"text-xl font-semibold text-gray-900 leading-snug\">{heading}</h1>\n <p className=\"mt-2 text-sm text-gray-600 leading-relaxed\">{description}</p>\n\n {hasLink && (\n <a\n href={config!.url}\n rel=\"noopener noreferrer\"\n className=\"mt-6 w-full inline-flex items-center justify-center gap-2 rounded-xl bg-blue-600 px-5 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-blue-700 active:bg-blue-800\"\n >\n {ctaLabel}\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3\" />\n </svg>\n </a>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, useMemo, useRef, useSyncExternalStore, isValidElement, cloneElement, lazy, Suspense, type ReactElement } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useAuth } from '../contexts/AuthContext';\nimport apiClient from '../api/client';\nimport GlobalSearch, { type SearchConfig } from './GlobalSearch';\nimport ShortcutHelp from './ShortcutHelp';\nimport ShellContextMenu from './ShellContextMenu';\nimport NotificationBell, { type NotificationsConfig } from './NotificationBell';\nimport { getPomoSnapshot, subscribePomo } from './pomodoroStore';\nimport { useShellPrefs } from './ShellPrefs';\nimport { SIDEBAR_STRIP_W } from './workArea';\nimport { useWindowManager } from './WindowManager';\nimport { useTheme } from '../hooks/useTheme';\nimport Desktop, { useDesktopHost } from './Desktop';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { playStartup } from '../utils/sounds';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport StartupAnimation from './StartupAnimation';\nimport LogoutAnimation from './LogoutAnimation';\nimport SessionWindowRestore from './SessionRestore';\nimport StartMenu from './StartMenu';\n// Sidebar is opt-in (`prefs.layout_mode === 'sidebar'`) and adds nothing\n// to the classic-mode bundle. lazy() also means consumers running a\n// stale source checkout where Sidebar.tsx hasn't been pulled yet won't\n// crash on module load — only when they actually flip into sidebar mode.\nconst Sidebar = lazy(() => import('./Sidebar'));\nimport MobileAppLanding, { type MobileAppConfig } from './MobileAppLanding';\nimport { useIsMobile } from './useIsMobile';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport {\n navIcons as defaultNavIcons,\n sectionIcons as defaultSectionIcons,\n navSections as defaultNavSections,\n startMenuCategories as defaultCategories,\n isSection,\n type NavItem,\n type NavSection,\n type StartMenuCategories,\n} from '../shell-config/nav';\nimport { WINDOW_REGISTRY, isPageEntry, type PageRegistryEntry } from '../windowRegistry/types';\nimport type { ReactNode } from 'react';\nimport BrandMark from '../forms/BrandMark';\n\n// Transitional re-exports — go away after each consumer migrates to importing\n// nav data from their own shell-config rather than from <Layout>.\nexport {\n defaultNavIcons as navIcons,\n defaultSectionIcons as sectionIcons,\n defaultNavSections as navSections,\n isSection,\n};\nexport type { NavItem, NavSection };\nexport type { MobileAppConfig };\n\n/**\n * The product's visual identity, in one object: the start-menu button, the\n * startup splash, the logout cover and the mobile landing all read from it.\n * The About dialog and What's New changelog belong to `DesktopHostConfig`\n * (`productName`, `productIcon`, `productChangelog`, …), which configures the\n * desktop; this configures the chrome around it.\n */\nexport interface ShellBranding {\n /** Product name — start-menu button, startup splash, mobile landing. */\n productName?: string;\n /** Logo URL — start-menu button, splash and logout covers. Defaults to `/favicon.svg`. */\n logo?: string;\n /** Apply the shared contrast treatment to arbitrary tenant artwork. */\n adaptiveLogo?: boolean;\n /** Server-detected transparency hint for `logo`. */\n logoHasAlpha?: boolean | null;\n /** Server-detected tone hint for `logo`. */\n logoIsLight?: boolean | null;\n /** Line under the product name on the splash and logout covers —\n * typically the company name. */\n tagline?: string;\n}\n\nexport interface LayoutProps {\n /** One-object form of the brand fields below; its fields win over them, so\n * a consumer can move over field by field. */\n branding?: ShellBranding;\n /** Brand label rendered on the start-menu button. */\n productName?: string;\n /** Icon URL rendered next to the brand label. Defaults to `/favicon.svg`. */\n productIcon?: string;\n /** Wallpaper image URLs for the desktop background. When omitted, falls back\n * to the wallpapers registered on the `DesktopHostProvider` (the same pool the\n * Customization picker shows); with neither, the desktop renders no image. */\n wallpapers?: string[];\n /** Override the default nav sections shown in the start menu. */\n navSections?: (NavSection | NavItem)[];\n /** Override the per-route icon map used by start menu and favorites. */\n navIcons?: Record<string, ReactNode>;\n /** Override the per-section header icon map used by start menu. */\n sectionIcons?: Record<string, ReactNode>;\n /** Override the start menu's section grouping + virtual flyouts. */\n categories?: StartMenuCategories;\n /** Notification system config — when omitted, the bell isn't rendered. */\n notifications?: NotificationsConfig;\n /** Universal search config — when omitted, Cmd-K opens the picker but no\n * results ever come back. */\n search?: SearchConfig;\n /** Custom node rendered in the system tray to the LEFT of the\n * notification bell (or above it on a vertical taskbar). Lets a host\n * app drop in icons like a server-status indicator without forking\n * the shell. The shell renders the node as-is — keep it small (a\n * single icon-sized button) so it fits the existing tray rhythm. */\n taskbarTrayLeft?: ReactNode;\n /** Taskbar clock popover config — lets the host surface per-day content\n * (e.g. tasks due that day) inside the mini month calendar. When omitted\n * the popover stays a plain date grid. */\n clockCalendar?: ClockCalendarConfig;\n /** Mobile-app link shown on phone/tablet-portrait viewports in place of the\n * desktop chrome. The shell has no built-in touch UI — wire a link to your\n * dedicated mobile app here (see MobileAppConfig). When omitted, small\n * screens get a plain \"best viewed on desktop\" notice. */\n mobileApp?: MobileAppConfig;\n /** The shell-wide right-click menu (`ShellContextMenu`). On by default;\n * `false` hands every right-click back to the browser — for a consumer\n * that is mid-migration, or that draws a menu of its own everywhere. */\n contextMenu?: boolean;\n}\n\nexport interface ClockCalendarConfig {\n /** Local dates (YYYY-MM-DD) to mark with a dot in the mini month grid —\n * typically days that have items on them. */\n markedDates?: string[];\n /** Render content for the selected day below the grid. The popover\n * defaults the selection to today when it opens, so clicking the clock\n * immediately shows today's items; clicking any day in the grid\n * re-renders the panel for that day (days outside the shown month also\n * flip the grid to their month). `close` dismisses the popover — call\n * it when a row click opens a window so the popup doesn't linger over\n * it. */\n renderDay?: (dateISO: string, api: { close: () => void }) => ReactNode;\n}\n\n\nfunction ProfileMenu({ profile, user, onLogout, onNavigate }: { profile: any; user: any; onLogout: () => void; onNavigate: (path: string) => void }) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState<{ left: number; top?: number; bottom?: number } | null>(null);\n\n useClickOutside(ref, useCallback(() => { if (open) setOpen(false); }, [open]));\n\n useEffect(() => {\n if (open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n // Center popup over button, clamp to viewport\n const popupW = 256; // w-64\n let left = rect.left + rect.width / 2 - popupW / 2;\n left = Math.max(8, Math.min(left, window.innerWidth - popupW - 8));\n if (taskbarPos === 'top') {\n setPos({ left, top: rect.bottom + 4 });\n } else {\n setPos({ left, bottom: window.innerHeight - rect.top + 4 });\n }\n }\n }, [open]);\n\n const groupNames: any[] = profile?.group_names ?? [];\n\n return (\n <div ref={ref} className=\"relative\">\n <button ref={buttonRef} onClick={() => setOpen(!open)} className=\"flex items-center gap-2 rounded-md px-2 py-1 hover:bg-gray-200 transition-colors text-left shrink-0\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-7 w-7 rounded-full object-cover border border-gray-300\" />\n ) : (\n <div className=\"h-7 w-7 rounded-full bg-gray-300 flex items-center justify-center text-[10px] font-bold text-gray-600\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <span className=\"text-xs font-medium text-gray-700 hidden sm:inline\">{profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}</span>\n </button>\n\n {open && pos && (\n <PopupMenu minWidth={256} style={{ left: pos.left, ...(pos.top != null ? { top: pos.top } : { bottom: pos.bottom }) }}>\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-gray-200/60\">\n <div className=\"flex items-center gap-3\">\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-10 w-10 rounded-full object-cover border border-gray-300\" />\n ) : (\n <div className=\"h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-lg font-bold text-blue-700\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-gray-900 truncate\">{profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}</p>\n <p className=\"text-xs text-gray-500 truncate\">{user?.email}</p>\n </div>\n </div>\n {groupNames.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-2\">\n {groupNames.map((g: any) => (\n <span key={typeof g === 'string' ? g : g.name} className=\"inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium bg-blue-100 text-blue-700\">\n {typeof g === 'string' ? g : g.name}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Menu items */}\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/profile'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z\" /></svg>\n My Profile\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/notifications'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\" /></svg>\n Notifications\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/settings/favorites'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" /></svg>\n Favorites\n </PopupMenuItem>\n <PopupMenuItem onClick={() => { setOpen(false); onNavigate('/settings/customization'); }}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42\" /></svg>\n Preferences\n </PopupMenuItem>\n\n {/* Logout */}\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={async () => {\n setOpen(false);\n const { confirm } = await import('./ConfirmDialog');\n const ok = await confirm({\n title: 'Sign Out',\n message: 'Do you want to log out? All windows will reopen when you log back in.',\n confirmLabel: 'Sign Out',\n cancelLabel: 'Cancel',\n variant: 'warning',\n });\n if (ok) onLogout();\n }}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9\" /></svg>\n Sign Out\n </PopupMenuItem>\n </PopupMenu>\n )}\n\n </div>\n );\n}\n\nconst NAV_CATEGORIES = [\n { label: 'Clients', items: [\n { path: '/orders', label: 'Sales Orders' }, { path: '/invoices', label: 'Sales Invoices' },\n { path: '/warranty-claims', label: 'Warranty Claims' }, { path: '/clients', label: 'Clients' },\n { path: '/price-sheets', label: 'Price Sheets' },\n ]},\n { label: 'Vendors', items: [\n { path: '/vendor-orders', label: 'Purchase Orders' }, { path: '/qc-reports', label: 'QC Reports' },\n { path: '/production-progress', label: 'Production Progress' }, { path: '/vendor-shipments', label: 'Goods Receipt' },\n { path: '/vendor-invoices', label: 'Vendor Invoices' }, { path: '/vendor-payments', label: 'Vendor Payments' },\n { path: '/manufacturers', label: 'Vendors' }, { path: '/vendor-price-sheets', label: 'Vendor Price Sheets' },\n ]},\n { label: 'Inventory', items: [\n { path: '/goods-issue', label: 'Goods Issue' }, { path: '/stock-on-hand', label: 'Stock on Hand' },\n { path: '/warehouses', label: 'Warehouses' },\n ]},\n { label: 'Products', items: [\n { path: '/products', label: 'Part Numbers' }, { path: '/brands', label: 'Brands' },\n { path: '/designs', label: 'Designs' }, { path: '/wheel-finishes', label: 'Wheel Finishes' },\n ]},\n { label: 'R&D', items: [\n { path: '/projects', label: 'Projects' }, { path: '/proposals', label: 'Proposals' },\n { path: '/moulds', label: 'Moulds' }, { path: '/dfm-logs', label: 'DFM Logs' },\n { path: '/weight-logs', label: 'Weight Logs' },\n ]},\n { label: 'Finance', items: [\n { path: '/payments', label: 'Receipts' }, { path: '/bank-accounts', label: 'Bank Accounts' },\n ]},\n];\n\nfunction useFavorites(wallpapers?: string[]) {\n const { prefs, save } = useShellPrefs();\n const favorites: string[] = prefs.favorite_pages || [];\n\n const toggle = useCallback((path: string) => {\n const next = favorites.includes(path) ? favorites.filter((p: string) => p !== path) : [...favorites, path];\n save({ favorite_pages: next });\n }, [favorites, save]);\n\n const wallpaperPool = wallpapers && wallpapers.length > 0 ? wallpapers : [];\n const randomPickRef = useRef(wallpaperPool.length > 0 ? wallpaperPool[Math.floor(Math.random() * wallpaperPool.length)] : 'none');\n const rawBg: string = prefs.desktop_bg || (wallpaperPool.length > 0 ? 'random' : 'none');\n const desktopBg: string = rawBg === 'random' ? randomPickRef.current : rawBg;\n\n const setDesktopBg = useCallback((bg: string) => {\n save({ desktop_bg: bg });\n }, [save]);\n\n return { favorites, toggle, isFavorite: (path: string) => favorites.includes(path), desktopBg, setDesktopBg };\n}\n\nexport { useFavorites };\n\n/** Star button for list page titles — toggles favorite status */\nexport function FavoriteStar({ path }: { path?: string }) {\n const location = useLocation();\n const { isFavorite, toggle } = useFavorites();\n const currentPath = path || location.pathname;\n const fav = isFavorite(currentPath);\n return (\n <button onClick={() => toggle(currentPath)} title={fav ? 'Remove from favorites' : 'Add to favorites'}\n className={`shrink-0 transition-colors ${fav ? 'text-yellow-500 hover:text-yellow-600' : 'text-gray-300 hover:text-yellow-400'}`}>\n <svg className=\"h-5 w-5\" fill={fav ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" />\n </svg>\n </button>\n );\n}\n\nexport const ALL_TIMEZONES = [\n { tz: 'Pacific/Auckland', label: 'Auckland' }, { tz: 'Australia/Sydney', label: 'Sydney' },\n { tz: 'Australia/Adelaide', label: 'Adelaide' }, { tz: 'Australia/Brisbane', label: 'Brisbane' },\n { tz: 'Australia/Perth', label: 'Perth' }, { tz: 'Asia/Tokyo', label: 'Tokyo' },\n { tz: 'Asia/Seoul', label: 'Seoul' }, { tz: 'Asia/Shanghai', label: 'Shanghai' },\n { tz: 'Asia/Hong_Kong', label: 'Hong Kong' }, { tz: 'Asia/Singapore', label: 'Singapore' },\n { tz: 'Asia/Bangkok', label: 'Bangkok' }, { tz: 'Asia/Kolkata', label: 'Mumbai' },\n { tz: 'Asia/Dubai', label: 'Dubai' }, { tz: 'Europe/Moscow', label: 'Moscow' },\n { tz: 'Europe/Istanbul', label: 'Istanbul' }, { tz: 'Europe/Berlin', label: 'Berlin' },\n { tz: 'Europe/Paris', label: 'Paris' }, { tz: 'Europe/London', label: 'London' },\n { tz: 'America/Sao_Paulo', label: 'Sao Paulo' }, { tz: 'America/New_York', label: 'New York' },\n { tz: 'America/Chicago', label: 'Chicago' }, { tz: 'America/Denver', label: 'Denver' },\n { tz: 'America/Los_Angeles', label: 'Los Angeles' }, { tz: 'Pacific/Honolulu', label: 'Honolulu' },\n { tz: 'UTC', label: 'UTC' },\n];\n\nexport function ClockContent({ localTz, worldClocks, now, fmtTime, fmtDate, fmtOffset, removeClock, adding, setAdding, addClock, availableToAdd, showAdd }: {\n localTz: string; worldClocks: string[]; now: Date;\n fmtTime: (tz: string) => string; fmtDate: (tz: string) => string; fmtOffset: (tz: string) => string;\n removeClock: (tz: string) => void; adding: boolean; setAdding: (v: boolean) => void; addClock: (tz: string) => void;\n availableToAdd: { tz: string; label: string }[]; showAdd: boolean;\n}) {\n return (\n <>\n {/* Local time header */}\n <div className=\"px-4 py-3 border-b border-gray-200\">\n <p className=\"text-xs font-medium text-gray-500 uppercase tracking-wide\">Local Time</p>\n <div className=\"flex items-baseline justify-between mt-1\">\n <span className=\"text-2xl font-semibold text-gray-900 tabular-nums\">{fmtTime(localTz)}</span>\n <span className=\"text-xs text-gray-400\">{fmtOffset(localTz)}</span>\n </div>\n <p className=\"text-xs text-gray-500 mt-0.5\">{fmtDate(localTz)} · {localTz.replace(/_/g, ' ')}</p>\n </div>\n\n {/* World clocks */}\n <div className=\"max-h-60 overflow-y-auto\">\n {worldClocks.map(tz => {\n const info = ALL_TIMEZONES.find(t => t.tz === tz);\n const label = info?.label || tz.split('/').pop()?.replace(/_/g, ' ') || tz;\n return (\n <div key={tz} className=\"flex items-center justify-between px-4 py-2 hover:bg-gray-50 group\">\n <div>\n <p className=\"text-sm font-medium text-gray-900\">{label}</p>\n <p className=\"text-[10px] text-gray-400\">{fmtDate(tz)} · {fmtOffset(tz)}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-700 tabular-nums\">{fmtTime(tz)}</span>\n <button onClick={() => removeClock(tz)} className=\"opacity-0 group-hover:opacity-100 text-gray-300 hover:text-red-500 transition-all\" title=\"Remove\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n </div>\n </div>\n );\n })}\n {worldClocks.length === 0 && (\n <p className=\"text-sm text-gray-400 text-center py-4\">No world clocks added</p>\n )}\n </div>\n\n {/* Add timezone — only shown when not pinned */}\n {showAdd && (\n <div className=\"border-t border-gray-200 p-2\">\n {adding ? (\n <select autoFocus onChange={e => { if (e.target.value) addClock(e.target.value); }} onBlur={() => setAdding(false)}\n className=\"w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm focus:border-blue-500 focus:ring-blue-500\">\n <option value=\"\">Select timezone...</option>\n {availableToAdd.map(t => (\n <option key={t.tz} value={t.tz}>{t.label} ({fmtOffset(t.tz)})</option>\n ))}\n </select>\n ) : (\n <button onClick={() => setAdding(true)} className=\"w-full flex items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-700 transition-colors\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n Add World Clock\n </button>\n )}\n </div>\n )}\n </>\n );\n}\n\n/**\n * Compact countdown chip rendered in the system tray when a Pomodoro\n * session is in progress. Subscribes to `pomodoroStore` so it updates\n * once per second without re-rendering the whole shell. Tapping it opens\n * (or focuses) the Pomodoro widget.\n */\nfunction TaskbarPomodoro() {\n const snap = useSyncExternalStore(subscribePomo, getPomoSnapshot, getPomoSnapshot);\n const { openPage } = useWindowManager();\n\n // Show whenever the user has an active or paused-mid-session timer.\n const inSession = snap.running || (snap.remaining < snap.total && snap.remaining > 0);\n if (!inSession) return null;\n\n const mm = String(Math.floor(snap.remaining / 60)).padStart(2, '0');\n const ss = String(snap.remaining % 60).padStart(2, '0');\n const dot =\n snap.mode === 'focus' ? 'bg-blue-500' :\n snap.mode === 'short' ? 'bg-emerald-500' : 'bg-emerald-600';\n const label =\n snap.mode === 'focus' ? 'Focus' :\n snap.mode === 'short' ? 'Short break' : 'Long break';\n\n return (\n <button onClick={() => openPage('/pomodoro')}\n title={`${label} · ${mm}:${ss}${snap.running ? '' : ' (paused)'}`}\n className={`shrink-0 flex items-center gap-1.5 rounded-md px-2 py-1 text-[11px] font-mono font-semibold tabular-nums hover:bg-gray-200/50 transition-colors ${snap.running ? 'text-gray-800' : 'text-gray-400'}`}>\n <span className={`block w-1.5 h-1.5 rounded-full ${dot} ${snap.running ? 'animate-pulse' : 'opacity-60'}`} />\n {mm}:{ss}\n </button>\n );\n}\n\nfunction TaskbarClock({ clockCalendar }: { clockCalendar?: ClockCalendarConfig }) {\n const [now, setNow] = useState(new Date());\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const { openPage } = useWindowManager();\n\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 10000);\n return () => clearInterval(t);\n }, []);\n\n useClickOutside(ref, useCallback(() => { if (open) setOpen(false); }, [open]));\n\n return (\n <div ref={ref} className=\"relative shrink-0\">\n <button ref={buttonRef} onClick={() => setOpen(!open)} className=\"text-right leading-tight cursor-pointer hover:bg-gray-200/50 rounded px-1.5 py-0.5 transition-colors\">\n <p className=\"text-[11px] font-medium text-gray-800\">{now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })}</p>\n <p className=\"text-[10px] text-gray-700\">{now.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}</p>\n </button>\n\n {open && (() => {\n const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const rect = buttonRef.current?.getBoundingClientRect();\n const right = rect ? Math.max(8, window.innerWidth - rect.right) : 8;\n const posStyle = taskbarPos === 'top'\n ? { right, top: (rect?.bottom ?? 0) + 4 }\n : { right, bottom: window.innerHeight - (rect?.top ?? 0) + 4 };\n\n return (\n <div className=\"fixed z-[300] rounded-lg border border-gray-200 bg-white shadow-xl\" style={posStyle}>\n <CalendarPopup now={now} config={clockCalendar} close={() => setOpen(false)} />\n </div>\n );\n })()}\n </div>\n );\n}\n\nconst toISODate = (d: Date) =>\n `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n\n/**\n * Mini month calendar shown when the user clicks the taskbar clock.\n * Header has month + year and prev/next nav arrows; today is filled in\n * the accent colour; days outside the current month are dimmed.\n *\n * With a host-supplied `config` (see ClockCalendarConfig) the grid becomes\n * interactive: days are clickable, days in `markedDates` get a dot, and a\n * panel below the grid renders `renderDay` for the selected day (today on\n * open). Selection then moves the accent fill; today shows as an accent\n * number when not selected.\n */\nfunction CalendarPopup({ now, config, close }: { now: Date; config?: ClockCalendarConfig; close: () => void }) {\n const [month, setMonth] = useState(() => new Date(now.getFullYear(), now.getMonth(), 1));\n const [selected, setSelected] = useState(() => toISODate(now));\n const interactive = !!config?.renderDay;\n const markedSet = useMemo(() => new Set(config?.markedDates ?? []), [config?.markedDates]);\n\n const monthLabel = month.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });\n const fullDate = now.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' });\n const fullTime = now.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n\n const firstDay = month.getDay(); // 0 = Sunday\n const daysInMonth = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();\n const prevDays = new Date(month.getFullYear(), month.getMonth(), 0).getDate();\n\n const cells: { day: number; thisMonth: boolean; date: Date }[] = [];\n for (let i = firstDay - 1; i >= 0; i--) {\n const day = prevDays - i;\n cells.push({ day, thisMonth: false, date: new Date(month.getFullYear(), month.getMonth() - 1, day) });\n }\n for (let day = 1; day <= daysInMonth; day++) {\n cells.push({ day, thisMonth: true, date: new Date(month.getFullYear(), month.getMonth(), day) });\n }\n let nextDay = 1;\n while (cells.length < 42) {\n cells.push({ day: nextDay, thisMonth: false, date: new Date(month.getFullYear(), month.getMonth() + 1, nextDay) });\n nextDay++;\n }\n\n const today = new Date();\n const isToday = (d: Date) =>\n d.getFullYear() === today.getFullYear() &&\n d.getMonth() === today.getMonth() &&\n d.getDate() === today.getDate();\n\n const goPrev = () => setMonth(m => new Date(m.getFullYear(), m.getMonth() - 1, 1));\n const goNext = () => setMonth(m => new Date(m.getFullYear(), m.getMonth() + 1, 1));\n const goToday = () => setMonth(new Date(today.getFullYear(), today.getMonth(), 1));\n\n return (\n <div className={`${interactive ? 'w-[300px]' : 'w-[260px]'} p-3`}>\n {/* Live date + time line */}\n <div className=\"px-1 pb-2.5 border-b border-gray-100\">\n <div className=\"text-[11px] font-semibold text-gray-500 uppercase tracking-wide\">{fullDate}</div>\n <div className=\"text-2xl font-semibold text-gray-800 tabular-nums leading-tight mt-0.5\">{fullTime}</div>\n </div>\n\n {/* Month nav */}\n <div className=\"flex items-center justify-between mt-2.5 mb-2\">\n <button onClick={goPrev} className=\"p-1 rounded hover:bg-gray-100 text-gray-600\" aria-label=\"Previous month\">\n <svg className=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n <button onClick={goToday} className=\"text-sm font-semibold text-gray-700 hover:text-blue-600 transition-colors\">\n {monthLabel}\n </button>\n <button onClick={goNext} className=\"p-1 rounded hover:bg-gray-100 text-gray-600\" aria-label=\"Next month\">\n <svg className=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n\n {/* Day labels */}\n <div className=\"grid grid-cols-7 mb-1 text-[10px] font-semibold text-gray-400 text-center uppercase tracking-wide\">\n {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((d, i) => <div key={i} className=\"py-1\">{d}</div>)}\n </div>\n\n {/* Day grid */}\n <div className=\"grid grid-cols-7 gap-px text-center\">\n {cells.map((cell, i) => {\n const todayCell = cell.thisMonth && isToday(cell.date);\n const iso = toISODate(cell.date);\n const isSelected = interactive && selected === iso;\n // Interactive: selection carries the accent fill; an unselected\n // today falls back to an accent-coloured number so it stays\n // findable. Static (no host config): today keeps the fill.\n const look = isSelected\n ? 'bg-blue-500 text-white font-semibold'\n : todayCell\n ? interactive\n ? 'text-blue-600 font-bold hover:bg-gray-100'\n : 'bg-blue-500 text-white font-semibold'\n : cell.thisMonth\n ? 'text-gray-700 hover:bg-gray-100'\n : interactive\n ? 'text-gray-300 hover:bg-gray-100'\n : 'text-gray-300';\n const dayClass = `relative text-[12px] py-1.5 rounded-md transition-colors ${look}`;\n const dot = markedSet.has(iso) && (\n <span\n className={`absolute bottom-[3px] left-1/2 -translate-x-1/2 h-1 w-1 rounded-full ${\n isSelected ? 'bg-white' : cell.thisMonth ? 'bg-blue-500' : 'bg-gray-300'\n }`}\n />\n );\n if (!interactive) {\n return (\n <div key={i} className={dayClass}>\n {cell.day}\n {dot}\n </div>\n );\n }\n return (\n <button\n key={i}\n onClick={() => {\n setSelected(iso);\n // Spilled prev/next-month days also flip the grid there.\n if (!cell.thisMonth) setMonth(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));\n }}\n aria-label={cell.date.toLocaleDateString(undefined, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}\n aria-pressed={isSelected}\n className={`cursor-pointer ${dayClass}`}\n >\n {cell.day}\n {dot}\n </button>\n );\n })}\n </div>\n\n {/* Host-rendered day panel (e.g. tasks due on the selected day).\n Keyed on the day so its scroll position resets per selection. */}\n {config?.renderDay && (\n <div key={selected} className=\"mt-2.5 max-h-[280px] overflow-y-auto border-t border-gray-100 pt-2\">\n {config.renderDay(selected, { close })}\n </div>\n )}\n </div>\n );\n}\n\nfunction TaskbarContextMenu({ x, y, position, size, onChangePosition, onChangeSize, onClose, onReportBug }: {\n x: number; y: number; position: string; size: string;\n onChangePosition: (v: string) => void; onChangeSize: (v: string) => void; onClose: () => void;\n onReportBug?: () => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n useClickOutside(ref, onClose);\n\n const posStyle: React.CSSProperties =\n position === 'top' ? { left: Math.min(x, window.innerWidth - 200), top: y + 4 } :\n position === 'left' ? { left: x + 4, top: Math.min(y, window.innerHeight - 300) } :\n position === 'right' ? { right: window.innerWidth - x + 4, top: Math.min(y, window.innerHeight - 300) } :\n { left: Math.min(x, window.innerWidth - 200), bottom: window.innerHeight - y + 4 };\n\n const check = (active: boolean) => active\n ? <svg className=\"h-3.5 w-3.5 text-blue-600 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>\n : <span className=\"w-3.5\" />;\n\n return (\n <div ref={ref} className=\"fixed z-[400] rounded-2xl py-1 min-w-[180px]\" style={{ ...posStyle, ...getGlassStyle() }}>\n <p className=\"px-3 py-1 text-[10px] font-semibold text-gray-400 uppercase tracking-wide\">Position</p>\n {(['bottom', 'top', 'left', 'right'] as const).map(pos => (\n <button key={pos} onClick={() => onChangePosition(pos)}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n {check(position === pos)}\n {pos.charAt(0).toUpperCase() + pos.slice(1)}\n </button>\n ))}\n <div className=\"border-t border-white/20 my-1 mx-3\" />\n <p className=\"px-3 py-1 text-[10px] font-semibold text-gray-400 uppercase tracking-wide\">Size</p>\n {(['small', 'medium', 'large'] as const).map(s => (\n <button key={s} onClick={() => onChangeSize(s)}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n {check(size === s)}\n {s.charAt(0).toUpperCase() + s.slice(1)}\n </button>\n ))}\n {onReportBug && <>\n <div className=\"border-t border-white/20 my-1 mx-3\" />\n <button onClick={() => { onClose(); onReportBug(); }}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors rounded-lg mx-1 flex items-center gap-2\" style={{ width: 'calc(100% - 8px)' }}>\n <svg className=\"h-3.5 w-3.5 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z\" /></svg>\n Suggestion or Bug\n </button>\n </>}\n </div>\n );\n}\n\n/** Pinned-favorites strip — every app the user has favorited\n * (prefs.favorite_pages, toggled via <FavoriteStar>) rendered as an\n * icon launcher next to the start-menu button. Click opens the app\n * window; right-click offers open / remove-from-favorites. */\nfunction TaskbarFavorites({ favorites, vertical, taskbarPosition, navSections, navIcons, onOpen, onToggleFavorite }: {\n favorites: string[];\n vertical: boolean;\n taskbarPosition: string;\n navSections: (NavSection | NavItem)[];\n navIcons: Record<string, ReactNode>;\n onOpen: (path: string) => void;\n onToggleFavorite: (path: string) => void;\n}) {\n const [menu, setMenu] = useState<{ x: number; y: number; path: string; label: string } | null>(null);\n\n // path → label from the nav tree (incl. nested children), falling back to\n // the window registry for favorites that aren't in the start menu.\n const labelFor = useMemo(() => {\n const map: Record<string, string> = {};\n const walk = (items: NavItem[]) => {\n for (const it of items) { map[it.to] = it.label; if (it.children) walk(it.children); }\n };\n for (const entry of navSections) {\n if (isSection(entry)) walk((entry as NavSection).items);\n else walk([entry as NavItem]);\n }\n return (path: string): string => {\n if (map[path]) return map[path];\n const reg = WINDOW_REGISTRY[path];\n if (reg && isPageEntry(reg)) return (reg as PageRegistryEntry).label;\n return path.replace(/^\\//, '');\n };\n }, [navSections]);\n\n if (favorites.length === 0) return null;\n\n // Same anchoring rules as the taskbar context menu — open away from the\n // taskbar edge so the menu never renders underneath it.\n const menuStyle = (x: number, y: number): React.CSSProperties =>\n taskbarPosition === 'top' ? { left: Math.min(x, window.innerWidth - 200), top: y + 4 } :\n taskbarPosition === 'left' ? { left: x + 4, top: Math.min(y, window.innerHeight - 120) } :\n taskbarPosition === 'right' ? { right: window.innerWidth - x + 4, top: Math.min(y, window.innerHeight - 120) } :\n { left: Math.min(x, window.innerWidth - 200), bottom: window.innerHeight - y + 4 };\n\n return (\n <>\n <div className={vertical\n ? 'w-full px-2 flex flex-wrap items-center justify-center gap-1 shrink-0 max-h-[30vh] overflow-y-auto'\n : 'flex items-center gap-1 shrink-0 max-w-[40vw] overflow-x-auto [scrollbar-width:none]'}>\n {favorites.map(path => {\n const label = labelFor(path);\n const icon = navIcons[path];\n return (\n <button key={path} onClick={() => onOpen(path)} title={label}\n onContextMenu={e => { e.preventDefault(); e.stopPropagation(); setMenu({ x: e.clientX, y: e.clientY, path, label }); }}\n className=\"flex items-center justify-center rounded-lg p-2 border bg-gray-50/40 border-gray-200/40 text-gray-600 hover:bg-gray-200/40 hover:text-gray-800 transition-colors shrink-0\">\n {icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-4 w-4' })\n : <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z\" /></svg>}\n </button>\n );\n })}\n </div>\n {menu && (\n <PopupMenu portal minWidth={180} style={menuStyle(menu.x, menu.y)} onClose={() => setMenu(null)}>\n <PopupMenuItem onClick={() => { setMenu(null); onOpen(menu.path); }}>\n {(() => {\n const icon = navIcons[menu.path];\n return icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: 'h-4 w-4 text-gray-400' })\n : <span className=\"w-4\" />;\n })()}\n Open {menu.label}\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => { setMenu(null); onToggleFavorite(menu.path); }}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z\" />\n </svg>\n Remove from Favorites\n </PopupMenuItem>\n </PopupMenu>\n )}\n </>\n );\n}\n\nexport default function Layout({\n branding,\n productName = 'react-os-shell',\n productIcon = '/favicon.svg',\n wallpapers,\n navSections = defaultNavSections,\n navIcons = defaultNavIcons,\n sectionIcons = defaultSectionIcons,\n categories = defaultCategories,\n notifications,\n search,\n taskbarTrayLeft,\n clockCalendar,\n mobileApp,\n contextMenu = true,\n}: LayoutProps = {}) {\n // `branding` wins over the loose props — one object, one place, and a\n // consumer can move over field by field.\n const brandName = branding?.productName ?? productName;\n const brandIcon = branding?.logo ?? productIcon;\n const brandTagline = branding?.tagline;\n const brandAdaptive = branding?.adaptiveLogo ?? false;\n const brandHasAlpha = branding?.logoHasAlpha ?? null;\n const brandIsLight = branding?.logoIsLight ?? null;\n const host = useDesktopHost();\n const { user, logout, hasAnyPerm } = useAuth();\n const { openPage, openEntity, openWindows } = useWindowManager();\n const [menuOpen, setMenuOpen] = useState(false);\n const isMobile = useIsMobile();\n\n // Profile is reserved for consumer integration; the shell only consumes prefs.\n const profile: any = user || {};\n\n useTheme();\n // Fall back to the host-registered wallpaper pool (the same source the\n // Customization picker reads) when no explicit `wallpapers` prop is given —\n // otherwise a host-only consumer gets an empty pool and `desktop_bg: 'random'`\n // (also the default for a user who's never picked one) collapses to 'none'.\n const { favorites, toggle: toggleFavorite, isFavorite, desktopBg, setDesktopBg } =\n useFavorites(wallpapers ?? host.wallpapers?.map(w => w.src));\n\n const { prefs, save: savePrefs } = useShellPrefs();\n\n // Layout mode — 'sidebar' opt-in for small-screen users. Forces a\n // persistent left strip, horizontal taskbar starting at the sidebar's\n // right edge, and always-maximized non-widget windows.\n const layoutMode: 'classic' | 'sidebar' = prefs.layout_mode === 'sidebar' ? 'sidebar' : 'classic';\n const sidebarMode = layoutMode === 'sidebar';\n const sidebarWidth = sidebarMode ? SIDEBAR_STRIP_W : 0;\n\n // Taskbar layout — when sidebar mode is active we force the taskbar\n // horizontal across the bottom; the design doesn't support a vertical\n // taskbar living next to the sidebar.\n const taskbarPositionRaw: string = prefs.taskbar_position || 'bottom';\n const taskbarPosition: string = sidebarMode ? 'bottom' : taskbarPositionRaw;\n const taskbarSize: string = prefs.taskbar_size || 'medium';\n const desktopDblClick: string = prefs.desktop_dblclick || 'deactivate';\n\n const isVerticalTaskbar = taskbarPosition === 'left' || taskbarPosition === 'right';\n const taskbarH = isVerticalTaskbar ? 0 : (taskbarSize === 'small' ? 42 : taskbarSize === 'large' ? 72 : 56);\n const taskbarW = isVerticalTaskbar ? (taskbarSize === 'small' ? 180 : taskbarSize === 'large' ? 260 : 220) : 0;\n // Gap between the Start menu and the taskbar edge, tuned per taskbar size.\n const taskbarGap = taskbarSize === 'small' ? 2 : taskbarSize === 'large' ? 6 : 4;\n const taskbarHClass = taskbarSize === 'small' ? 'h-[42px]' : taskbarSize === 'large' ? 'h-[72px]' : 'h-14';\n const taskbarWClass = taskbarSize === 'small' ? 'w-[180px]' : taskbarSize === 'large' ? 'w-[260px]' : 'w-[220px]';\n // \"Reduce transparency\" (Preferences → Customization): drop the frosted-glass\n // blur and make surfaces solid for better performance on older machines. The\n // root class drives the global stylesheet rule (blur strip + opacity vars) and\n // glassStyle(); the taskbar tints from a JS value below, so force it opaque here.\n const reduceTransparency = !!prefs.reduce_transparency;\n // Transparency preferences → CSS custom properties for Modal.tsx to read\n const taskbarOpacity = reduceTransparency ? 1 : (prefs.transparency_taskbar ?? 70) / 100;\n const menuOpacity = (prefs.transparency_start_menu ?? 95) / 100;\n const inactiveHeaderOpacity = (prefs.transparency_inactive_header ?? 70) / 100;\n const inactiveContentOpacity = (prefs.transparency_inactive_content ?? 80) / 100;\n const activeHeaderOpacity = (prefs.transparency_active_header ?? 80) / 100;\n const activeContentOpacity = (prefs.transparency_active_content ?? 90) / 100;\n useEffect(() => {\n const root = document.documentElement;\n // Drives the global reduce-transparency stylesheet rule (blur strip + solid\n // opacity vars) and glassStyle(). Kept in the same effect as the opacity\n // vars so both land on the same frame when the pref changes.\n root.classList.toggle('rosh-reduce-transparency', reduceTransparency);\n root.style.setProperty('--inactive-header-opacity', String(inactiveHeaderOpacity));\n root.style.setProperty('--inactive-content-opacity', String(inactiveContentOpacity));\n root.style.setProperty('--active-header-opacity', String(activeHeaderOpacity));\n root.style.setProperty('--active-content-opacity', String(activeContentOpacity));\n root.style.setProperty('--menu-opacity', String(menuOpacity));\n // Suffix `px` so consumers using these vars inside CSS calc() get a\n // valid length. JS readers (parseInt(...)) handle either form. Without\n // the unit, expressions like `calc(100vh - var(--taskbar-height) - 24px)`\n // are invalid and the browser drops the whole property — which previously\n // broke the Modal autoHeight cap for any consumer that wasn't a widget.\n root.style.setProperty('--taskbar-height', `${taskbarH}px`);\n root.style.setProperty('--taskbar-width', `${taskbarW}px`);\n root.style.setProperty('--taskbar-position', taskbarPosition);\n // Sidebar mode: width of the persistent left strip + a layout-mode\n // marker. Modal reads both — sidebar-width to offset its calcMaximized\n // box, layout-mode to switch into \"always maximized\" behaviour.\n root.style.setProperty('--sidebar-width', `${sidebarWidth}px`);\n root.style.setProperty('--layout-mode', layoutMode);\n // Tell already-mounted Modals to refresh their alwaysMaximized flag\n // (they don't have access to ShellPrefs context — they listen for\n // this event so the toggle takes effect immediately).\n window.dispatchEvent(new CustomEvent('react-os-shell:layout-mode-changed'));\n root.style.setProperty('--default-window-size', prefs.default_window_size || 'large');\n root.style.setProperty('--window-position', prefs.window_position || 'cascade');\n root.style.setProperty('--menu-density', prefs.menu_density || 'normal');\n // Menu size — affects font size and item padding across PopupMenu (context menus, dropdowns, notification popup, etc.)\n // Also drives the taskbar window-tab width so it stays proportional.\n const menuSize = prefs.start_menu_size || 'medium';\n const sizeVars: Record<string, { font: string; px: string; py: string; tabW: string; tabFont: string }> = {\n small: { font: '12px', px: '0.75rem', py: '0.25rem', tabW: '150px', tabFont: '11px' },\n medium: { font: '14px', px: '1rem', py: '0.5rem', tabW: '200px', tabFont: '12px' },\n large: { font: '15px', px: '1.125rem', py: '0.625rem', tabW: '240px', tabFont: '13px' },\n };\n const sv = sizeVars[menuSize] || sizeVars.medium;\n root.style.setProperty('--menu-font-size', sv.font);\n root.style.setProperty('--menu-padding-x', sv.px);\n root.style.setProperty('--menu-padding-y', sv.py);\n root.style.setProperty('--window-tab-width', sv.tabW);\n root.style.setProperty('--window-tab-font-size', sv.tabFont);\n }, [reduceTransparency, inactiveHeaderOpacity, inactiveContentOpacity, activeHeaderOpacity, activeContentOpacity, taskbarH, taskbarPosition, prefs.default_window_size, prefs.window_position, prefs.menu_density, prefs.start_menu_size, sidebarWidth, layoutMode]);\n\n // Bottom-nav reservation height, read by Modal to shrink fullscreen apps so\n // they don't render under a nav bar. The shell no longer paints a mobile\n // bottom nav, so this is always 0 — kept as an explicit set (not unset) so\n // Modal's `var(--mobile-bottom-nav, …)` fallback doesn't reintroduce a gap.\n useEffect(() => {\n document.documentElement.style.setProperty('--mobile-bottom-nav', '0px');\n }, []);\n const [balloonDismissed, setBalloonDismissed] = useState(false);\n const [isFullscreen, setIsFullscreen] = useState(!!document.fullscreenElement);\n const [taskbarMenu, setTaskbarMenu] = useState<{ x: number; y: number } | null>(null);\n const [showLogout, setShowLogout] = useState(false);\n\n const savePref = useCallback((key: string, value: any) => {\n savePrefs({ [key]: value });\n }, [savePrefs]);\n\n const toggleFullscreen = useCallback(async () => {\n if (document.fullscreenElement) {\n // Release keyboard lock before exiting\n if ((navigator as any).keyboard?.unlock) (navigator as any).keyboard.unlock();\n document.exitFullscreen();\n } else {\n await document.documentElement.requestFullscreen();\n // Lock Escape key so it goes to our app instead of exiting fullscreen\n if ((navigator as any).keyboard?.lock) {\n try { await (navigator as any).keyboard.lock(['Escape']); } catch { /* not supported or denied */ }\n }\n }\n }, []);\n\n // Sync fullscreen state with browser\n useEffect(() => {\n const handler = () => {\n setIsFullscreen(!!document.fullscreenElement);\n // Release keyboard lock when exiting fullscreen\n if (!document.fullscreenElement && (navigator as any).keyboard?.unlock) {\n (navigator as any).keyboard.unlock();\n }\n };\n document.addEventListener('fullscreenchange', handler);\n return () => document.removeEventListener('fullscreenchange', handler);\n }, []);\n\n // Auto-fullscreen on login\n const autoFullscreenDone = useRef(false);\n useEffect(() => {\n if (autoFullscreenDone.current) return;\n if (prefs.auto_fullscreen && !document.fullscreenElement) {\n autoFullscreenDone.current = true;\n // Needs a user gesture — use a one-time click listener\n const handler = async () => {\n if (!document.fullscreenElement) {\n try {\n await document.documentElement.requestFullscreen();\n if ((navigator as any).keyboard?.lock) (navigator as any).keyboard.lock(['Escape']).catch(() => {});\n } catch {}\n }\n document.removeEventListener('click', handler);\n };\n document.addEventListener('click', handler, { once: true });\n }\n }, [prefs.auto_fullscreen]);\n\n // Startup animation + sound\n const [showStartup, setShowStartup] = useState(false);\n const startupChecked = useRef(false);\n useEffect(() => {\n if (startupChecked.current) return;\n startupChecked.current = true;\n const key = 'erp_startup_shown';\n if (!sessionStorage.getItem(key)) {\n sessionStorage.setItem(key, '1');\n setShowStartup(true);\n }\n }, []);\n\n const startupSoundDone = useRef(false);\n useEffect(() => {\n if (startupSoundDone.current || !showStartup) return;\n startupSoundDone.current = true;\n setTimeout(() => playStartup(), 500);\n }, [showStartup]);\n\n // Hotkey: Ctrl+. / Cmd+. to toggle menu, F11 to toggle fullscreen\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if ((e.ctrlKey || e.metaKey) && e.key === '.') {\n e.preventDefault();\n setMenuOpen(prev => !prev);\n }\n if (e.ctrlKey && e.key === 'F11') {\n e.preventDefault();\n toggleFullscreen();\n }\n if (e.key === 'Escape' && document.fullscreenElement) {\n // Only exit fullscreen if no modals are open (let modals handle Escape first)\n const hasOpenModals = document.querySelectorAll('[data-modal-panel]').length > 0;\n if (!hasOpenModals) {\n e.preventDefault();\n toggleFullscreen();\n }\n }\n };\n window.addEventListener('keydown', handler);\n return () => { window.removeEventListener('keydown', handler); };\n }, [toggleFullscreen]);\n\n return (\n <div className=\"flex flex-col h-screen\">\n {/* Reopen last session's windows — see SessionRestore.tsx. */}\n <SessionWindowRestore />\n {showStartup && <StartupAnimation onComplete={() => setShowStartup(false)} ready={!!profile} productName={brandName} logo={brandIcon} subtitle={brandTagline} adaptiveLogo={brandAdaptive} logoHasAlpha={brandHasAlpha} logoIsLight={brandIsLight} />}\n {showLogout && <LogoutAnimation onComplete={() => { sessionStorage.removeItem('erp_startup_shown'); logout(); }} logo={brandIcon} subtitle={brandTagline} adaptiveLogo={brandAdaptive} logoHasAlpha={brandHasAlpha} logoIsLight={brandIsLight} />}\n {/* Start Menu — suppressed in sidebar mode (Sidebar replaces it). */}\n {!sidebarMode && (\n <StartMenu\n open={menuOpen}\n onClose={() => setMenuOpen(false)}\n openPage={(path) => { openPage(path); setMenuOpen(false); }}\n openWindows={openWindows}\n profile={profile}\n user={user}\n onLogout={() => setShowLogout(true)}\n onNavigate={(path) => { openPage(path); setMenuOpen(false); }}\n taskbarPosition={taskbarPosition as 'top' | 'bottom' | 'left' | 'right'}\n taskbarH={taskbarH}\n taskbarW={taskbarW}\n taskbarGap={taskbarGap}\n size={(prefs.start_menu_size || 'medium') as 'small' | 'medium' | 'large'}\n navSections={navSections}\n navIcons={navIcons}\n sectionIcons={sectionIcons}\n categories={categories}\n />\n )}\n\n {/* Sidebar — persistent left strip for sidebar layout mode.\n Lazy-imported so a stale source checkout missing Sidebar.tsx\n only blows up if the user flips into sidebar mode (vs. crashing\n at module load), and so the chunk is only fetched when needed. */}\n {sidebarMode && (\n <Suspense fallback={null}>\n <Sidebar\n width={sidebarWidth}\n openPage={(path) => openPage(path)}\n profile={profile}\n user={user}\n onLogout={() => setShowLogout(true)}\n onNavigate={(path) => openPage(path)}\n navSections={navSections}\n navIcons={navIcons}\n sectionIcons={sectionIcons}\n categories={categories}\n productName={brandName}\n productIcon={brandIcon}\n adaptiveLogo={brandAdaptive}\n logoHasAlpha={brandHasAlpha}\n logoIsLight={brandIsLight}\n />\n </Suspense>\n )}\n\n {(() => {\n // Shared wallpaper style used by both the desktop main area and the\n // mobile landing screen so the user's chosen background carries across\n // breakpoints.\n const wallpaperStyle: React.CSSProperties = {\n backgroundColor: desktopBg?.startsWith('#') ? desktopBg : desktopBg === 'none' ? (() => {\n const customBg = getComputedStyle(document.documentElement).getPropertyValue('--custom-bg-color')?.trim();\n if (customBg) return customBg;\n const t = document.documentElement.getAttribute('data-theme') || 'light';\n const map: Record<string, string> = { light: '#f3f4f6', dark: '#1e1e2e', pink: '#fdf2f8', green: '#f0fdf4', grey: '#d1d5db', blue: '#eff6ff' };\n return map[t] || '#f3f4f6';\n })() : '#1a1a2e',\n backgroundImage: desktopBg && desktopBg !== 'none' && !desktopBg.startsWith('#') ? `url(${desktopBg})` : 'none',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n backgroundRepeat: 'no-repeat',\n };\n\n if (isMobile) {\n return (\n <MobileAppLanding\n productName={brandName}\n productIcon={brandIcon}\n adaptiveLogo={brandAdaptive}\n logoHasAlpha={brandHasAlpha}\n logoIsLight={brandIsLight}\n config={mobileApp}\n wallpaperStyle={wallpaperStyle}\n />\n );\n }\n\n return (\n <>\n <div className=\"flex flex-1 min-h-0\">\n <main\n className=\"flex-1 flex flex-col overflow-hidden cursor-default\"\n onDoubleClick={() => {\n if (desktopDblClick === 'deactivate') { setMenuOpen(false); window.dispatchEvent(new CustomEvent('deactivate-all-modals')); }\n }}\n style={wallpaperStyle}\n >\n {/* Desktop with shortcuts, folders, and context menu */}\n <Desktop profile={profile} />\n </main>\n </div>\n\n {/* Taskbar — overlays content for transparency. In sidebar mode the\n left edge starts at the sidebar's right edge instead of x=0. */}\n <div className={`flex backdrop-blur-sm border-gray-200 z-[250] fixed ${\n isVerticalTaskbar\n ? `flex-col items-center ${taskbarWClass} py-3 gap-2 top-0 bottom-0 ${taskbarPosition === 'left' ? 'left-0 border-r' : 'right-0 border-l'}`\n : `items-center ${taskbarHClass} px-3 gap-2 right-0 ${taskbarPosition === 'top' ? 'top-0 border-b' : 'bottom-0 border-t'}`\n }`}\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${taskbarOpacity})`,\n ...(isVerticalTaskbar ? {} : { left: sidebarWidth }),\n }}\n // Hit-test target for drag-to-pin: dropping a page shortcut from the\n // desktop over the taskbar pins it to favorite_pages (see Desktop.tsx).\n data-taskbar-dropzone\n onContextMenu={e => { e.preventDefault(); setTaskbarMenu({ x: e.clientX, y: e.clientY }); }}>\n {/* ERP button — toggles Start Menu. Hidden in sidebar mode where\n the persistent left sidebar replaces the start-menu role. */}\n {!sidebarMode && <div className=\"relative shrink-0\">\n {openWindows.length === 0 && !menuOpen && !balloonDismissed && (\n <div className={`absolute left-1/2 -translate-x-1/2 whitespace-nowrap text-white text-[10px] font-medium pl-3 pr-2 py-1 rounded-full shadow-lg animate-bounce flex items-center gap-1 ${taskbarPosition === 'top' ? 'top-full mt-2' : '-top-8'}`}\n style={{ backgroundColor: 'var(--accent-600, #7c3aed)' }}>\n Click here to start\n <button onClick={(e) => { e.stopPropagation(); setBalloonDismissed(true); }} className=\"text-white/60 hover:text-white ml-1.5\">\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n <div className={`absolute left-1/2 -translate-x-1/2 border-[6px] border-transparent ${taskbarPosition === 'top' ? 'bottom-full border-b-[var(--accent-color,#7c3aed)]' : 'top-full border-t-[var(--accent-color,#7c3aed)]'}`}\n style={taskbarPosition === 'top' ? { borderBottomColor: 'var(--accent-600, #7c3aed)' } : { borderTopColor: 'var(--accent-600, #7c3aed)' }} />\n </div>\n )}\n <button data-menu-toggle onClick={() => setMenuOpen(prev => !prev)} title={menuOpen ? 'Close menu' : 'Open menu'}\n className={`group/erp relative flex items-center justify-center gap-1.5 rounded-lg px-4 py-2 text-xs font-medium border overflow-hidden transition-all ${isVerticalTaskbar ? 'w-full' : 'min-w-[140px]'} ${menuOpen ? 'bg-gray-200/40 border-gray-300/40 text-gray-800' : 'bg-gray-50/40 border-gray-200/40 text-gray-600 hover:text-gray-800'}`}\n style={{ transition: 'box-shadow 0.3s, border-color 0.3s' }}\n onMouseMove={e => { const r = e.currentTarget.getBoundingClientRect(); e.currentTarget.style.setProperty('--mx', `${e.clientX - r.left}px`); e.currentTarget.style.setProperty('--my', `${e.clientY - r.top}px`); }}\n onMouseEnter={e => { e.currentTarget.style.boxShadow = '0 0 15px rgba(255,255,255,0.2), 0 0 30px rgba(255,255,255,0.1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.4)'; }}\n onMouseLeave={e => { e.currentTarget.style.boxShadow = ''; e.currentTarget.style.borderColor = ''; }}>\n <span className=\"absolute inset-0 opacity-0 group-hover/erp:opacity-100 transition-opacity duration-200 pointer-events-none\"\n style={{ background: 'radial-gradient(circle 60px at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,0.25) 0%, transparent 100%)' }} />\n {brandIcon && (\n <BrandMark\n src={brandIcon}\n alt=\"\"\n slot=\"compact\"\n surface=\"light\"\n adaptive={brandAdaptive}\n hasAlpha={brandHasAlpha}\n isLight={brandIsLight}\n size={14}\n decorative\n className=\"relative z-10 opacity-60\"\n />\n )}\n <span className=\"relative z-10 truncate\">{brandName}</span>\n </button>\n </div>}\n\n {/* Pinned favorites — favorited apps as quick-launch icons next to\n the start-menu button. Hidden (with the button) in sidebar mode. */}\n {!sidebarMode && (\n <TaskbarFavorites\n favorites={favorites}\n vertical={isVerticalTaskbar}\n taskbarPosition={taskbarPosition}\n navSections={navSections}\n navIcons={navIcons}\n onOpen={(path) => openPage(path)}\n onToggleFavorite={toggleFavorite}\n />\n )}\n\n {/* Separator (only when the ERP button is also rendered) */}\n {!sidebarMode && <div className={isVerticalTaskbar ? 'h-px w-6 bg-gray-300 my-1' : 'w-px h-6 bg-gray-300 mx-1'} />}\n\n {/* Window tabs rendered here by WindowManagerProvider */}\n <div id=\"taskbar-windows\" className={`flex-1 flex ${isVerticalTaskbar ? 'flex-col items-center gap-1 min-h-0 overflow-y-auto w-full' : 'items-center gap-1.5 min-w-0 overflow-x-auto'}`} />\n\n {/* Separator */}\n <div className={isVerticalTaskbar ? 'h-px w-6 bg-gray-300 my-1' : 'w-px h-6 bg-gray-300 mx-1'} />\n\n {/* System tray */}\n {isVerticalTaskbar ? (\n /* Vertical: clock + bell evenly spaced */\n <div className=\"w-full px-2\">\n <div className={`flex items-center justify-center gap-2 ${taskbarPosition === 'right' ? 'flex-row-reverse' : ''}`}>\n <TaskbarClock clockCalendar={clockCalendar} />\n <TaskbarPomodoro />\n {/* Host-supplied tray content (e.g. server-status icon).\n Sits next to the notification bell on the bell's\n outer edge. */}\n {taskbarTrayLeft}\n {notifications && <NotificationBell {...notifications} popDirection={taskbarPosition === 'right' ? 'left' : 'right'} />}\n </div>\n </div>\n ) : (\n /* Horizontal: icons then clock */\n <>\n <TaskbarPomodoro />\n {taskbarTrayLeft}\n {notifications && <NotificationBell {...notifications} />}\n <TaskbarClock clockCalendar={clockCalendar} />\n </>\n )}\n </div>\n </>\n );\n })()}\n\n {/* Taskbar context menu */}\n {taskbarMenu && (\n <TaskbarContextMenu\n x={taskbarMenu.x} y={taskbarMenu.y}\n position={taskbarPosition}\n size={taskbarSize}\n onChangePosition={v => { savePref('taskbar_position', v); setTaskbarMenu(null); }}\n onChangeSize={v => { savePref('taskbar_size', v); setTaskbarMenu(null); }}\n onClose={() => setTaskbarMenu(null)}\n onReportBug={host.onReportBug}\n />\n )}\n\n {/* GlobalSearch no longer reaches for the window manager itself — that\n one import was what kept it out of `react-os-shell/ui`. Passing it in\n here keeps the desktop behaviour identical. */}\n <GlobalSearch\n {...search}\n onSelect={result => openEntity(result.entity_type, result.entity_id, undefined, result.label)}\n />\n <ShortcutHelp />\n {/* One right-click menu for the whole shell. Surfaces with their own\n menu already preventDefault(), so this only fills the gaps where\n the browser's native menu used to show through. */}\n <ShellContextMenu disabled={!contextMenu} />\n </div>\n );\n}\n","import { useRef, useState, useCallback, useEffect } from 'react';\nimport { ModalActions, forgetMaximizedWindowBoxes } from '../shell/Modal';\nimport { useDesktopHost } from '../shell/Desktop';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { applyThemePrefs, resolveTheme } from '../hooks/useTheme';\nimport { SOUND_PACKS, SOUND_PACK_KEYS, SOUND_TYPES, SOUND_TYPE_LABELS, getSoundConfig, setSoundForType, setAllSounds, soundsEnabled, previewSound, type SoundType } from '../utils/sounds';\n\n// Preview tiles use literal hex values via arbitrary Tailwind syntax so that the\n// active theme's [data-theme=\"...\"] !important overrides don't repaint them\n// (the Light preview must stay light even when Dark is the current theme).\nconst THEMES = [\n { key: 'system', label: 'System', bar1: 'bg-[#e5e7eb]', bar2: 'bg-[#e5e7eb]' },\n { key: 'light', label: 'Light', bar1: 'bg-[#e5e7eb]', bar2: 'bg-[#e5e7eb]' },\n { key: 'dark', label: 'Dark', bar1: 'bg-[#45475a]', bar2: 'bg-[#45475a]' },\n { key: 'pink', label: 'Blossom', bar1: 'bg-[#fbcfe8]', bar2: 'bg-[#fbcfe8]' },\n { key: 'green', label: 'Nature', bar1: 'bg-[#bbf7d0]', bar2: 'bg-[#bbf7d0]' },\n { key: 'grey', label: 'Quicksilver', bar1: 'bg-[#d1d5db]', bar2: 'bg-[#d1d5db]' },\n { key: 'blue', label: 'Ocean', bar1: 'bg-[#bfdbfe]', bar2: 'bg-[#bfdbfe]' },\n];\n\n// Default wallpaper list (consumer-overridable via DesktopHostProvider).\nconst DEFAULT_WALLPAPERS: { src: string; label: string }[] = [];\n\nfunction getVersion() {\n const now = new Date();\n return `v${String(now.getDate()).padStart(2, '0')}${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getHours()).padStart(2, '0')}.${String(now.getMinutes()).padStart(2, '0')}.${now.getFullYear()}`;\n}\n\nfunction previewColor(resolved: string, light: string, dark: string, pink: string, green: string, grey?: string, blue?: string) {\n if (resolved === 'dark') return dark;\n if (resolved === 'pink') return pink;\n if (resolved === 'green') return green;\n if (resolved === 'grey') return grey ?? light;\n if (resolved === 'blue') return blue ?? light;\n return light;\n}\n\n/** Sections that can be omitted from the inline Customization page when the\n * consumer renders them elsewhere (e.g. as separate entries in SystemPreferences). */\nexport type CustomizationOmitSection = 'behavior' | 'desktop';\n\n/** A logical group of the Customization page. Pass `section` to render only one\n * group, so the page can be split across separate SystemPreferences entries\n * (Appearance / Layout / Behavior). Omit `section` to render the whole page. */\nexport type CustomizationSection = 'appearance' | 'layout' | 'behavior';\n\nexport interface CustomizationProps {\n omit?: readonly CustomizationOmitSection[];\n /** Render only one logical group of settings. Omit to render everything. */\n section?: CustomizationSection;\n}\n\nexport default function Customization({ omit, section }: CustomizationProps = {}) {\n const omitSet = new Set(omit ?? []);\n // With `section` set, render only that group's blocks; otherwise render all.\n const inSection = (group: CustomizationSection) => section === undefined || section === group;\n const host = useDesktopHost();\n const WALLPAPERS = host.wallpapers && host.wallpapers.length > 0 ? host.wallpapers : DEFAULT_WALLPAPERS;\n const { prefs, save } = useShellPrefs();\n\n // Appearance writes (theme / accent / custom colors) persist through save(),\n // which on a backend-backed adapter round-trips to the server before `prefs`\n // reflects the new value — sometimes tens of seconds. Mirror the change\n // locally so the picker's selected state + live preview update on click;\n // applyThemePrefs (in setAppearance) repaints the desktop the same frame.\n // Each override is dropped once `prefs` catches up to it.\n const [optimisticAppearance, setOptimisticAppearance] = useState<Record<string, any>>({});\n const pref = (key: string) => (key in optimisticAppearance ? optimisticAppearance[key] : prefs[key]);\n useEffect(() => {\n setOptimisticAppearance(prev => {\n const next: Record<string, any> = {};\n let settled = false;\n for (const k of Object.keys(prev)) {\n if (prefs[k] === prev[k]) settled = true; // server caught up → drop override\n else next[k] = prev[k];\n }\n return settled ? next : prev;\n });\n }, [prefs]);\n\n // Apply an appearance patch to <html> immediately (no save round-trip wait),\n // reflect it in the optimistic mirror, then persist it in the background.\n const APPEARANCE_KEYS = ['theme', 'accent_color', 'custom_bg_color', 'custom_title_color', 'custom_window_color', 'custom_button_color'] as const;\n const setAppearance = (patch: Record<string, any>) => {\n const snapshot: Record<string, any> = { ...patch };\n for (const k of APPEARANCE_KEYS) if (!(k in snapshot)) snapshot[k] = pref(k);\n applyThemePrefs(snapshot);\n setOptimisticAppearance(prev => ({ ...prev, ...patch }));\n save(patch);\n };\n\n const currentTheme: string = pref('theme') || 'system';\n const resolved = resolveTheme(currentTheme);\n const rawBg: string = prefs.desktop_bg || (WALLPAPERS.length > 0 ? 'random' : 'none');\n const randomPickRef = useRef(WALLPAPERS.length > 0 ? WALLPAPERS[Math.floor(Math.random() * WALLPAPERS.length)].src : 'none');\n const desktopBg = rawBg === 'random' ? randomPickRef.current : rawBg;\n const customBg: string = prefs.desktop_bg_custom || '';\n const isColor = desktopBg?.startsWith('#');\n const presetPaths = new Set([...WALLPAPERS.map(w => w.src), 'random']);\n const isCustom = !isColor && desktopBg !== 'none' && rawBg !== 'random' && desktopBg && !presetPaths.has(desktopBg);\n\n const savePref = (key: string, value: any) => {\n save({ [key]: value });\n };\n\n // \"Reduce transparency\" — drops the frosted-glass blur and makes surfaces\n // solid (better performance on older machines). Toggle the root class now for\n // instant feedback (Layout's effect reconciles once the prefs adapter\n // settles) and mirror optimistically so the checkbox + slider disabling don't\n // lag the save round-trip. Reuses the appearance optimistic mirror + settle\n // effect above.\n const reduceOn = !!pref('reduce_transparency');\n const setReduce = (on: boolean) => {\n document.documentElement.classList.toggle('rosh-reduce-transparency', on);\n setOptimisticAppearance(prev => ({ ...prev, reduce_transparency: on }));\n save({ reduce_transparency: on });\n };\n\n // Debounced save for sliders — updates local state instantly, saves after 300ms idle\n const [localSliders, setLocalSliders] = useState<Record<string, number>>({});\n const sliderTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n const saveSlider = useCallback((key: string, value: number) => {\n setLocalSliders(prev => ({ ...prev, [key]: value }));\n // Apply CSS variable immediately for instant visual feedback\n const cssMap: Record<string, string> = {\n transparency_taskbar: '--taskbar-opacity',\n transparency_inactive_header: '--inactive-header-opacity',\n transparency_inactive_content: '--inactive-content-opacity',\n transparency_active_header: '--active-header-opacity',\n transparency_active_content: '--active-content-opacity',\n };\n if (cssMap[key]) {\n document.documentElement.style.setProperty(cssMap[key], String(value / 100));\n }\n if (sliderTimers.current[key]) clearTimeout(sliderTimers.current[key]);\n sliderTimers.current[key] = setTimeout(() => {\n savePref(key, value);\n setLocalSliders(prev => { const next = { ...prev }; delete next[key]; return next; });\n }, 300);\n }, [savePref]);\n // Cleanup timers on unmount\n useEffect(() => () => { Object.values(sliderTimers.current).forEach(clearTimeout); }, []);\n\n const prevTaskbarOpacity = (prefs.transparency_taskbar ?? 70) / 100;\n const prevActiveHeaderOpacity = (prefs.transparency_active_header ?? 80) / 100;\n const prevActiveContentOpacity = (prefs.transparency_active_content ?? 90) / 100;\n const taskbarBg = previewColor(resolved, 'bg-white/90', 'bg-[#1e1e2e]/90', 'bg-pink-50/90', 'bg-green-50/90', 'bg-gray-200/90', 'bg-blue-50/90');\n const iconBg = previewColor(resolved, 'bg-gray-200', 'bg-[#313244]', 'bg-pink-200', 'bg-green-200', 'bg-gray-400', 'bg-blue-200');\n const winBg = previewColor(resolved, 'bg-white border border-gray-200', 'bg-[#1e1e2e] border border-[#45475a]', 'bg-white border border-pink-200', 'bg-white border border-green-200', 'bg-gray-100 border border-gray-300', 'bg-blue-50 border border-blue-200');\n const headerBg = previewColor(resolved, 'bg-gray-100', 'bg-[#313244]', 'bg-pink-50', 'bg-green-50', 'bg-gray-300', 'bg-blue-100');\n const accentBg = previewColor(resolved, 'bg-blue-600', 'bg-blue-500', 'bg-pink-600', 'bg-green-600', 'bg-gray-700', 'bg-blue-700');\n\n return (\n <div className=\"space-y-6\">\n {inSection('appearance') && (\n <>\n {/* ── Live Preview ── */}\n <div className=\"flex justify-center\">\n <div className=\"rounded-lg border border-gray-200 overflow-hidden\" style={{ width: 480 }}>\n <div className=\"relative\" style={{ height: 300 }}>\n {/* Wallpaper */}\n {isColor ? (\n <div className=\"absolute inset-0\" style={{ backgroundColor: desktopBg }} />\n ) : (\n <img src={desktopBg} alt=\"\" className=\"absolute inset-0 w-full h-full object-cover\" />\n )}\n {/* Mini taskbar */}\n <div className={`absolute left-0 right-0 bottom-0 h-4 ${taskbarBg} border-t border-gray-200/50 flex items-center px-2 gap-1`} style={{ opacity: prevTaskbarOpacity }}>\n <div className={`h-2 w-8 rounded-sm ${accentBg}`} />\n <div className={`h-2 w-6 rounded-sm ${iconBg}`} />\n </div>\n {/* Desktop icons */}\n <div className=\"absolute left-4 top-4 flex gap-4\">\n {[\n { icon: '📋', label: 'Orders' },\n { icon: '📦', label: 'Products' },\n { icon: '📊', label: 'Reports' },\n ].map(d => (\n <div key={d.label} className=\"flex flex-col items-center gap-0.5 w-8\">\n <div className=\"text-sm drop-shadow\">{d.icon}</div>\n <span className=\"text-[5px] text-white font-medium drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)] leading-tight\">{d.label}</span>\n </div>\n ))}\n </div>\n {/* Mini window */}\n <div className={`absolute rounded shadow-md ${winBg}`} style={{ left: '35%', top: '20%', width: '55%', height: '55%' }}>\n <div className={`h-3 rounded-t ${headerBg} flex items-center px-1.5 gap-0.5`} style={{ opacity: prevActiveHeaderOpacity }}>\n <div className=\"w-1 h-1 rounded-full bg-red-400\" />\n <div className=\"w-1 h-1 rounded-full bg-yellow-400\" />\n <div className=\"w-1 h-1 rounded-full bg-green-400\" />\n </div>\n <div className=\"p-1.5 space-y-1\" style={{ opacity: prevActiveContentOpacity }}>\n <div className={`h-1 rounded w-3/4 ${iconBg}`} />\n <div className={`h-1 rounded w-1/2 ${iconBg}`} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* ── Theme ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Theme</h3>\n <div className=\"flex gap-3 flex-wrap\">\n {[...THEMES, { key: 'custom', label: 'Custom', bar1: 'bg-gray-200', bar2: 'bg-gray-200' }].map(t => {\n const isCustom = t.key === 'custom';\n const r = isCustom ? 'light' : resolveTheme(t.key);\n const customColor = pref('accent_color') || '#8b5cf6';\n const tAccent = isCustom ? '' : previewColor(r, 'bg-[#2563eb]', 'bg-[#3b82f6]', 'bg-[#db2777]', 'bg-[#16a34a]', 'bg-[#374151]', 'bg-[#1d4ed8]');\n const tBg = isCustom ? 'bg-[#ffffff] border-[#d1d5db]' : previewColor(r, 'bg-[#ffffff] border-[#d1d5db]', 'bg-[#1e1e2e] border-[#45475a]', 'bg-[#fdf2f8] border-[#f9a8d4]', 'bg-[#f0fdf4] border-[#86efac]', 'bg-[#e5e7eb] border-[#9ca3af]', 'bg-[#eff6ff] border-[#93c5fd]');\n return (\n <button key={t.key} onClick={() => {\n if (isCustom) {\n setAppearance(pref('accent_color') ? { theme: 'light' } : { theme: 'light', accent_color: '#8b5cf6' });\n } else {\n setAppearance({ theme: t.key, accent_color: null });\n }\n }}\n className={`flex flex-col items-center gap-1.5 rounded-lg border-2 p-3 transition-all ${(isCustom ? !!pref('accent_color') : currentTheme === t.key && !pref('accent_color')) ? 'border-blue-500 shadow-md' : 'border-gray-200 hover:border-gray-300'}`}>\n <div className={`w-20 h-14 rounded ${tBg} border overflow-hidden flex flex-col`}>\n {t.key === 'system' ? (\n <div className=\"flex-1 flex\">\n <div className=\"flex-1 flex flex-col bg-[#ffffff]\">\n <div className=\"h-2 bg-[#2563eb] w-full\" />\n <div className=\"flex-1 flex gap-0.5 p-0.5\">\n <div className=\"w-3 rounded-sm bg-[#f3f4f6]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1 rounded-sm w-3/4 bg-[#e5e7eb]\" />\n <div className=\"h-1 rounded-sm w-1/2 bg-[#e5e7eb]\" />\n </div>\n </div>\n </div>\n <div className=\"flex-1 flex flex-col bg-[#1e1e2e]\">\n <div className=\"h-2 bg-[#3b82f6] w-full\" />\n <div className=\"flex-1 flex gap-0.5 p-0.5\">\n <div className=\"w-3 rounded-sm bg-[#313244]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1 rounded-sm w-3/4 bg-[#45475a]\" />\n <div className=\"h-1 rounded-sm w-1/2 bg-[#45475a]\" />\n </div>\n </div>\n </div>\n </div>\n ) : isCustom ? (\n <>\n <div className=\"h-2 w-full\" style={{ backgroundColor: customColor }} />\n <div className=\"flex-1 flex gap-0.5 p-1\">\n <div className=\"w-4 rounded-sm bg-[#f3f4f6]\" />\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className=\"h-1.5 rounded-sm w-3/4 bg-[#e5e7eb]\" />\n <div className=\"h-1.5 rounded-sm w-1/2 bg-[#e5e7eb]\" />\n </div>\n </div>\n </>\n ) : (\n <>\n <div className={`h-2 ${tAccent} w-full`} />\n <div className=\"flex-1 flex gap-0.5 p-1\">\n <div className=\"flex-1 flex flex-col gap-0.5\">\n <div className={`h-1.5 rounded-sm w-3/4 ${t.bar1}`} />\n <div className={`h-1.5 rounded-sm w-1/2 ${t.bar2}`} />\n </div>\n </div>\n </>\n )}\n </div>\n <span className={`text-xs font-medium ${(isCustom ? !!pref('accent_color') : currentTheme === t.key && !pref('accent_color')) ? 'text-blue-600' : 'text-gray-600'}`}>{t.label}</span>\n </button>\n );\n })}\n </div>\n\n {/* Custom color pickers — only visible when Custom theme is selected */}\n {pref('accent_color') && (\n <div className=\"mt-3 space-y-2\">\n {([\n { key: 'custom_bg_color', label: 'Background Color', defaultVal: '#f3f4f6' },\n { key: 'custom_title_color', label: 'Header & Footer Color', defaultVal: '#f9fafb' },\n { key: 'custom_window_color', label: 'Windows Background', defaultVal: '#ffffff' },\n { key: 'custom_button_color', label: 'Button Color', defaultVal: '#2563eb' },\n { key: 'accent_color', label: 'Accent Color', defaultVal: '#8b5cf6' },\n ]).map(item => (\n <div key={item.key} className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">{item.label}</span>\n <label className=\"w-8 h-8 rounded-lg border-2 border-gray-300 overflow-hidden cursor-pointer flex items-center justify-center shrink-0\"\n style={{ backgroundColor: pref(item.key) || item.defaultVal }}>\n <input type=\"color\" value={pref(item.key) || item.defaultVal}\n onChange={e => setAppearance({ [item.key]: e.target.value })}\n className=\"opacity-0 absolute w-0 h-0\" />\n </label>\n <span className=\"text-xs text-gray-500 font-mono\">{pref(item.key) || item.defaultVal}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* ── Desktop Wallpaper ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop Wallpaper</h3>\n <div className=\"flex gap-2 flex-wrap items-center\">\n <button onClick={() => savePref('desktop_bg', 'none')}\n className={`w-28 h-20 rounded border-2 overflow-hidden flex items-center justify-center ${rawBg === 'none' ? 'border-blue-500' : 'border-gray-300'}`}\n style={{ backgroundColor: previewColor(resolved, '#f3f4f6', '#1e1e2e', '#fdf2f8', '#f0fdf4', '#d1d5db', '#eff6ff') }}>\n <span className=\"text-[9px] text-gray-500\">None</span>\n </button>\n <button onClick={() => savePref('desktop_bg', 'random')}\n className={`w-28 h-20 rounded border-2 overflow-hidden flex items-center justify-center ${rawBg === 'random' ? 'border-blue-500' : 'border-gray-300'}`}>\n <div className=\"grid grid-cols-2 grid-rows-2 w-full h-full\">\n {WALLPAPERS.slice(0, 4).map(wp => (\n <img key={wp.src} src={wp.src} alt=\"\" loading=\"lazy\" className=\"w-full h-full object-cover\" />\n ))}\n </div>\n </button>\n {WALLPAPERS.map(wp => (\n <button key={wp.src} onClick={() => savePref('desktop_bg', wp.src)}\n className={`w-28 h-20 rounded border-2 overflow-hidden ${rawBg === wp.src ? 'border-blue-500' : 'border-gray-300'}`}>\n <img src={wp.src} alt={wp.label} loading=\"lazy\" className=\"w-full h-full object-cover\" />\n </button>\n ))}\n {(customBg || isCustom) && (\n <div className=\"relative group\">\n <button onClick={() => savePref('desktop_bg', customBg || desktopBg)}\n className={`w-28 h-20 rounded border-2 overflow-hidden ${isCustom ? 'border-blue-500' : 'border-gray-300'}`}>\n <img src={customBg || desktopBg} alt=\"Custom\" loading=\"lazy\" className=\"w-full h-full object-cover\" />\n </button>\n <button onClick={() => save({ desktop_bg: 'random', desktop_bg_custom: '' })}\n className=\"absolute -top-1.5 -right-1.5 h-4 w-4 rounded-full bg-red-500 text-white flex items-center justify-center text-[10px] leading-none opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-600 shadow\">×</button>\n </div>\n )}\n <label className=\"w-28 h-20 rounded border-2 border-gray-300 border-dashed overflow-hidden cursor-pointer flex items-center justify-center text-gray-400 hover:text-gray-600\">\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /></svg>\n <input type=\"file\" accept=\"image/*\" className=\"hidden\" onChange={e => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onloadend = () => {\n if (reader.result) {\n save({ desktop_bg: reader.result as string, desktop_bg_custom: reader.result as string });\n }\n };\n reader.readAsDataURL(file);\n }} />\n </label>\n </div>\n </div>\n\n {/* ── Transparency ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Transparency</h3>\n {/* Reduce transparency: master switch that overrides the sliders below.\n When on, the shell drops the frosted-glass blur and makes every\n surface solid — the sliders are disabled because they no longer\n have any effect. */}\n <label className=\"flex items-start gap-2 cursor-pointer mb-3\">\n <input type=\"checkbox\" checked={reduceOn} onChange={e => setReduce(e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Reduce transparency\n <span className=\"block text-xs text-gray-400\">\n Turn off the frosted-glass blur and make windows, menus and the taskbar solid.\n Improves performance on older machines.\n </span>\n </span>\n </label>\n <div className={`space-y-3 transition-opacity ${reduceOn ? 'opacity-40 pointer-events-none select-none' : ''}`}\n aria-disabled={reduceOn}>\n {([\n { key: 'transparency_taskbar', label: 'Taskbar', defaultVal: 70 },\n { key: 'transparency_start_menu', label: 'Start Menu', defaultVal: 70 },\n { key: 'transparency_inactive_header', label: 'Inactive Windows Header / Footer', defaultVal: 70 },\n { key: 'transparency_inactive_content', label: 'Inactive Windows Content', defaultVal: 80 },\n { key: 'transparency_active_header', label: 'Active Windows Header / Footer', defaultVal: 80 },\n { key: 'transparency_active_content', label: 'Active Windows Content', defaultVal: 90 },\n ] as const).map(item => {\n const val: number = localSliders[item.key] ?? prefs[item.key] ?? item.defaultVal;\n return (\n <div key={item.key} className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-64 shrink-0\">{item.label}</span>\n <input type=\"range\" min={20} max={100} value={val} disabled={reduceOn}\n onChange={e => saveSlider(item.key, Number(e.target.value))}\n className=\"flex-1 h-1.5 accent-blue-600 cursor-pointer disabled:cursor-not-allowed\" />\n <span className=\"text-xs text-gray-500 w-10 text-right font-mono\">{val}%</span>\n </div>\n );\n })}\n </div>\n </div>\n\n {/* ── Windows ── */}\n {/* SG#00372: the per-section accent stripe. Only does anything when the\n consumer wires `windowAccentForRoute` on WindowManagerProvider — with\n no accents configured the switch is harmless rather than hidden,\n because this panel has no way to ask whether any route has one. */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Windows</h3>\n <label className=\"flex items-start gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={!!pref('window_accent_stripe')}\n onChange={e => savePref('window_accent_stripe', e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Show section color stripe\n <span className=\"block text-xs text-gray-400\">\n Draws a thin colored line between a window's title bar and its content,\n one color per area of the app, so overlapping windows are easier to tell\n apart at a glance.\n </span>\n </span>\n </label>\n </div>\n\n {/* ── Diagnostics ── */}\n {/* Deliberately adjacent to Transparency: the switch above is the usual\n fix for a sluggish machine, and this is how you find out whether it\n was the right fix rather than guessing. */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Diagnostics</h3>\n <label className=\"flex items-start gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={!!pref('show_desktop_stats')}\n onChange={e => savePref('show_desktop_stats', e.target.checked)}\n className=\"h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">\n Show performance stats\n <span className=\"block text-xs text-gray-400\">\n Overlays frame rate, worst frame time and a bottleneck reading on the desktop,\n beside the version number. Turn it on to check whether Reduce transparency\n actually helps on this machine — or whether the slowness is coming from\n somewhere else.\n </span>\n <span className=\"block text-xs text-gray-400 mt-1\">\n While it is on, each reading is recorded with what was happening at the time —\n how many windows were open, which one was on top, which menu or submenu you\n opened, how long you spent moving or resizing a window, and counts of clicks,\n keystrokes and scrolls. No page content or keystroke text is recorded. The log\n stays on this device unless you use the overlay's Report button, which sends it\n — with whatever you type in the box, and a description of this computer\n (browser, operating system, processor cores, memory, graphics card, screen,\n connection speed and whether you are on battery) — to the team as a bug report.\n </span>\n </span>\n </label>\n </div>\n </>\n )}\n\n {inSection('layout') && (\n <>\n {/* ── Layout Mode ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Layout Mode</h3>\n <p className=\"text-xs text-gray-500 mb-3\">\n Sidebar mode is designed for small screens — windows always run maximized\n and the start menu lives in a persistent left sidebar (sections expand inline\n instead of opening flyouts). Classic is the windowed mode: choosing it puts\n every open window back to its normal size.\n </p>\n <div className=\"flex gap-2\">\n {([\n { key: 'classic', label: 'Classic' },\n { key: 'sidebar', label: 'Sidebar' },\n ] as const).map(m => (\n <button\n key={m.key}\n onClick={() => {\n savePref('layout_mode', m.key);\n // Sidebar forces every window maximized through the\n // `--layout-mode` CSS var, so it must NOT also write the user's\n // 'Default window size' preference — doing so left classic mode\n // permanently opening windows full-screen once sidebar had been\n // tried even once. Classic instead undoes that stuck value and\n // asks live windows to drop back to their windowed size.\n if (m.key === 'classic') {\n if (prefs.default_window_size === 'maximized') savePref('default_window_size', 'large');\n // Open windows un-maximize now; closed ones would still\n // reopen at the full-screen box they saved while maximized.\n forgetMaximizedWindowBoxes();\n window.dispatchEvent(new CustomEvent('react-os-shell:restore-windowed'));\n }\n }}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.layout_mode || 'classic') === m.key\n ? 'bg-blue-600 text-white border-blue-600'\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}\n >\n {m.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* ── Taskbar ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Taskbar</h3>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Position</span>\n <div className=\"flex gap-2\">\n {(['bottom', 'top', 'left', 'right'] as const).map(pos => (\n <button key={pos} onClick={() => savePref('taskbar_position', pos)}\n disabled={prefs.layout_mode === 'sidebar'}\n title={prefs.layout_mode === 'sidebar' ? 'Sidebar mode forces a horizontal taskbar.' : undefined}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors disabled:opacity-40 disabled:cursor-not-allowed ${\n (prefs.taskbar_position || 'bottom') === pos ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{pos.charAt(0).toUpperCase() + pos.slice(1)}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n\n {/* ── Menu ── */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Menu</h3>\n <p className=\"text-xs text-gray-500 mb-3\">Controls font size, padding, taskbar height, and window button height across the Start Menu, context menus, dropdowns, and the notification popup.</p>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Size</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('start_menu_size', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.start_menu_size || 'medium') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-24 shrink-0\">Density</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'tight', label: 'Tight' },\n { key: 'normal', label: 'Normal' },\n { key: 'large', label: 'Large' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('menu_density', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.menu_density || 'normal') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n </>\n )}\n\n {/* ── Behavior ── */}\n {inSection('behavior') && !omitSet.has('behavior') && (\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Behavior</h3>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">New window position</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'center', label: 'Center' },\n { key: 'cascade', label: 'Cascade' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('window_position', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.window_position || 'cascade') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">Double-click desktop</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'deactivate', label: 'Deactivate all' },\n { key: 'nothing', label: 'Do nothing' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('desktop_dblclick', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.desktop_dblclick || 'deactivate') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">Default window size</span>\n <div className=\"flex gap-2\">\n {([\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n { key: 'maximized', label: 'Maximized' },\n ]).map(s => (\n <button key={s.key} onClick={() => savePref('default_window_size', s.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n (prefs.default_window_size || 'large') === s.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}>{s.label}</button>\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* ── Desktop ── */}\n {inSection('behavior') && !omitSet.has('desktop') && (\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n {/* `?? false` — the watermark renders on an explicit `true` only, and\n a box ticked by default over a desktop with no version on it is\n the state BG#00623 arrived in. */}\n <input type=\"checkbox\" checked={prefs.show_desktop_version ?? false} onChange={e => savePref('show_desktop_version', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Show version on desktop</span>\n <span className=\"text-xs text-gray-400 ml-1 font-mono\">{getVersion()}</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input type=\"checkbox\" checked={prefs.auto_fullscreen ?? false} onChange={e => savePref('auto_fullscreen', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Enter full screen mode automatically</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input type=\"checkbox\" checked={prefs.restore_windows ?? true} onChange={e => savePref('restore_windows', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Reopen windows from the last session</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <SoundSettings />\n </div>\n )}\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n\nfunction SoundSettings() {\n const [enabled, setEnabled] = useState(soundsEnabled());\n const [config, setConfig] = useState(getSoundConfig());\n\n const update = (soundType: SoundType, packKey: string) => {\n setSoundForType(soundType, packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, soundType);\n };\n\n const applyAll = (packKey: string) => {\n setAllSounds(packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, 'success');\n };\n\n return (\n <div className=\"mt-2 space-y-2\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={enabled} onChange={e => { localStorage.setItem('erp_sounds', String(e.target.checked)); setEnabled(e.target.checked); }}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">Sound effects</span>\n </label>\n {enabled && (\n <div className=\"ml-6\">\n <div className=\"border border-gray-200 rounded-lg overflow-hidden\">\n <table className=\"w-full text-[11px]\">\n <thead>\n <tr className=\"bg-gray-50\">\n <th className=\"px-2 py-1.5 text-left font-medium text-gray-500 w-24\"></th>\n {SOUND_PACK_KEYS.map(key => (\n <th key={key} className=\"px-1 py-1.5 text-center\">\n <button onClick={() => applyAll(key)} className=\"font-medium text-gray-500 hover:text-blue-600 transition-colors\">\n {SOUND_PACKS[key].label}\n </button>\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {SOUND_TYPES.map(soundType => (\n <tr key={soundType}>\n <td className=\"px-2 py-1.5 text-gray-700 font-medium\">{SOUND_TYPE_LABELS[soundType]}</td>\n {SOUND_PACK_KEYS.map(packKey => (\n <td key={packKey} className=\"px-1 py-1.5 text-center\">\n <button onClick={() => update(soundType, packKey)}\n className={`w-4 h-4 rounded-full border-2 transition-colors ${config[soundType] === packKey ? 'bg-blue-600 border-blue-600' : 'border-gray-300 hover:border-blue-400'}`} />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n","import { useShellPrefs } from '../shell/ShellPrefs';\nimport { ModalActions } from '../shell/Modal';\n\nconst WINDOW_POSITIONS = [\n { key: 'center', label: 'Center' },\n { key: 'cascade', label: 'Cascade' },\n];\n\nconst DESKTOP_DBLCLICK = [\n { key: 'deactivate', label: 'Deactivate all' },\n { key: 'nothing', label: 'Do nothing' },\n];\n\nconst WINDOW_SIZES = [\n { key: 'small', label: 'Small' },\n { key: 'medium', label: 'Medium' },\n { key: 'large', label: 'Large' },\n { key: 'maximized', label: 'Maximized' },\n];\n\n/**\n * Standalone Behavior settings panel — window position, double-click,\n * default window size, plus the two desktop-related toggles\n * (Show version on desktop, Enter full screen mode automatically).\n *\n * Reads/writes shell prefs via `useShellPrefs()`. Suitable for use as a\n * section in `SystemPreferences` or rendered standalone.\n */\nexport default function BehaviorPanel() {\n const { prefs, save } = useShellPrefs();\n const savePref = (key: string, value: any) => save({ [key]: value });\n\n const windowPosition: string = prefs.window_position || 'cascade';\n const desktopDblclick: string = prefs.desktop_dblclick || 'deactivate';\n const defaultWindowSize: string = prefs.default_window_size || 'large';\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Behavior</h3>\n <div className=\"space-y-3\">\n <Row\n label=\"New window position\"\n options={WINDOW_POSITIONS}\n value={windowPosition}\n onChange={v => savePref('window_position', v)}\n />\n <Row\n label=\"Double-click desktop\"\n options={DESKTOP_DBLCLICK}\n value={desktopDblclick}\n onChange={v => savePref('desktop_dblclick', v)}\n />\n <Row\n label=\"Default window size\"\n options={WINDOW_SIZES}\n value={defaultWindowSize}\n onChange={v => savePref('default_window_size', v)}\n />\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Desktop</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n // `?? false`, matching the render guard in `Desktop.tsx` and the\n // opt-in neighbour below. It read `?? true` while the watermark\n // drew only on an explicit `true`, so anyone who had never touched\n // this box saw it TICKED and had no version number on the desktop\n // — and, since the watermark is the only way in, no route to\n // What's New at all (BG#00623).\n checked={prefs.show_desktop_version ?? false}\n onChange={e => savePref('show_desktop_version', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Show version on desktop</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input\n type=\"checkbox\"\n checked={prefs.auto_fullscreen ?? false}\n onChange={e => savePref('auto_fullscreen', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Enter full screen mode automatically</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer mt-2\">\n <input\n type=\"checkbox\"\n checked={prefs.restore_windows ?? true}\n onChange={e => savePref('restore_windows', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Reopen windows from the last session</span>\n <span className=\"text-xs text-gray-400 ml-1\">— on login</span>\n </label>\n </div>\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n\nfunction Row({\n label,\n options,\n value,\n onChange,\n}: {\n label: string;\n options: { key: string; label: string }[];\n value: string;\n onChange: (v: string) => void;\n}) {\n return (\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-gray-700 w-40 shrink-0\">{label}</span>\n <div className=\"flex gap-2\">\n {options.map(o => (\n <button\n key={o.key}\n type=\"button\"\n onClick={() => onChange(o.key)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n value === o.key\n ? 'bg-blue-600 text-white border-blue-600'\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'\n }`}\n >\n {o.label}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { ModalActions } from '../shell/Modal';\nimport {\n SOUND_PACKS,\n SOUND_PACK_KEYS,\n SOUND_TYPES,\n SOUND_TYPE_LABELS,\n getSoundConfig,\n setSoundForType,\n setAllSounds,\n soundsEnabled,\n previewSound,\n type SoundType,\n} from '../utils/sounds';\n\n/**\n * Standalone Sounds settings panel — sound effects toggle + per-event\n * sound-pack picker. Reads/writes the shell's `erp_sounds` and\n * `erp_sound_config` localStorage keys. Plays a preview when a pack is\n * picked. Suitable as a section in `SystemPreferences` or rendered\n * standalone.\n */\nexport default function SoundsPanel() {\n const [enabled, setEnabled] = useState(soundsEnabled());\n const [config, setConfig] = useState(getSoundConfig());\n\n const update = (soundType: SoundType, packKey: string) => {\n setSoundForType(soundType, packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, soundType);\n };\n\n const applyAll = (packKey: string) => {\n setAllSounds(packKey);\n setConfig(getSoundConfig());\n previewSound(packKey, 'success');\n };\n\n return (\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-semibold text-gray-900\">Sounds</h3>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={e => {\n localStorage.setItem('erp_sounds', String(e.target.checked));\n setEnabled(e.target.checked);\n }}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600\"\n />\n <span className=\"text-sm text-gray-700\">Sound effects</span>\n </label>\n\n {enabled && (\n <div className=\"border border-gray-200 rounded-lg overflow-hidden\">\n <table className=\"w-full text-[11px]\">\n <thead>\n <tr className=\"bg-gray-50\">\n <th className=\"px-2 py-1.5 text-left font-medium text-gray-500 w-24\"></th>\n {SOUND_PACK_KEYS.map(key => (\n <th key={key} className=\"px-1 py-1.5 text-center\">\n <button\n onClick={() => applyAll(key)}\n className=\"font-medium text-gray-500 hover:text-blue-600 transition-colors\"\n >\n {SOUND_PACKS[key].label}\n </button>\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {SOUND_TYPES.map(soundType => (\n <tr key={soundType}>\n <td className=\"px-2 py-1.5 text-gray-700 font-medium\">{SOUND_TYPE_LABELS[soundType]}</td>\n {SOUND_PACK_KEYS.map(packKey => (\n <td key={packKey} className=\"px-1 py-1.5 text-center\">\n <button\n onClick={() => update(soundType, packKey)}\n aria-label={`${SOUND_TYPE_LABELS[soundType]} — ${SOUND_PACKS[packKey].label}`}\n aria-pressed={config[soundType] === packKey}\n className={`w-4 h-4 rounded-full border-2 transition-colors ${\n config[soundType] === packKey\n ? 'bg-blue-600 border-blue-600'\n : 'border-gray-300 hover:border-blue-400'\n }`}\n />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n <ModalActions>\n <span className=\"text-xs text-gray-400\">Changes are saved automatically</span>\n </ModalActions>\n </div>\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport SidebarLayout from '../shell/SidebarLayout';\n\n/** One section in the SystemPreferences sidebar. */\nexport interface SystemPreferencesSection {\n /** Unique key, e.g. `'notifications'`, `'customization'`. */\n key: string;\n /** Sidebar label, e.g. \"Notifications\". */\n label: string;\n /** Short description shown under the label in the sidebar. */\n description?: string;\n /** Sidebar icon (any ReactNode — typically a 4×4 svg). */\n icon?: ReactNode;\n /** Body renderer. Receives no args; access shell prefs via your own hook. */\n render: () => ReactNode;\n}\n\nexport interface SystemPreferencesProps {\n /** Ordered sections — left sidebar lists these top-to-bottom, the matching\n * body renders on the right. The first section is selected by default\n * unless `defaultSelected` is supplied. */\n sections: readonly SystemPreferencesSection[];\n /** Key of the section to highlight on first render. Falls back to the first\n * section in `sections`. */\n defaultSelected?: string;\n /** Optional className applied to the outer flex container. */\n className?: string;\n}\n\n/**\n * Two-pane settings window: a fixed sidebar of sections on the left, the\n * active section's body on the right. Consumers compose by passing\n * `sections` — each entry has a `key`, `label`, optional `icon` and\n * `description`, and a `render()` callback that returns the body JSX.\n *\n * The shell exposes ready-made panels (`Customization`, `BehaviorPanel`,\n * `SoundsPanel`) that can be used as section bodies directly; portals\n * add their own sections (notification subscriptions, delivery defaults,\n * personal formatting prefs, etc.) alongside.\n *\n * Example:\n * ```tsx\n * <SystemPreferences sections={[\n * { key: 'notifications', label: 'Notifications', icon: <BellIcon />, render: () => <MyNotifications /> },\n * { key: 'customization', label: 'Customization', icon: <PaintBrushIcon />, render: () => <Customization omit={['behavior','desktop']} /> },\n * { key: 'behavior', label: 'Behavior', icon: <Cog6ToothIcon />, render: () => <BehaviorPanel /> },\n * { key: 'sounds', label: 'Sounds', icon: <SpeakerWaveIcon />, render: () => <SoundsPanel /> },\n * ]} />\n * ```\n */\nexport default function SystemPreferences({\n sections,\n defaultSelected,\n className,\n}: SystemPreferencesProps) {\n const initial = defaultSelected && sections.some(s => s.key === defaultSelected)\n ? defaultSelected\n : sections[0]?.key ?? '';\n const [selected, setSelected] = useState<string>(initial);\n const active = sections.find(s => s.key === selected) ?? sections[0];\n\n return (\n <SidebarLayout\n storageKey=\"shell.systemPreferences.sidebarWidth\"\n defaultWidth={240}\n minWidth={200}\n maxWidth={360}\n className={className}\n sidebarClassName=\"border-r border-gray-200 bg-gray-50\"\n sidebar={\n <nav className=\"px-1 py-1.5 space-y-0.5\">\n {sections.map(item => {\n const isActive = item.key === selected;\n return (\n <button\n key={item.key}\n type=\"button\"\n onClick={() => setSelected(item.key)}\n className={`w-full text-left rounded-lg px-3 py-2.5 text-sm transition-colors flex items-start gap-2.5 ${\n isActive ? 'bg-blue-50 text-blue-700' : 'hover:bg-gray-100 text-gray-700'\n }`}\n >\n {item.icon && (\n <span className={`mt-0.5 ${isActive ? 'text-blue-600' : 'text-gray-400'}`}>\n {item.icon}\n </span>\n )}\n <span className=\"min-w-0\">\n <span\n className={`block ${\n isActive ? 'font-semibold text-blue-700' : 'font-medium text-gray-800'\n }`}\n >\n {item.label}\n </span>\n {item.description && (\n <span className=\"block text-[11px] text-gray-500 mt-0.5\">\n {item.description}\n </span>\n )}\n </span>\n </button>\n );\n })}\n </nav>\n }\n >\n <main className=\"flex-1 min-w-0 overflow-auto p-4\">\n {active?.render()}\n </main>\n </SidebarLayout>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Keyboard + shift-click navigation for table rows.\n *\n * - J/K or Arrow keys to move focus\n * - Enter to open the focused row (calls `onSelect`)\n * - Space to toggle the focused row's checkbox (calls `onToggle`)\n * - Shift+J/K to extend selection while moving\n * - Shift+click to range-select (calls `onSelectRange`, which must ADD the range\n * rather than toggle it — the clicked checkbox is ticked on that assumption)\n * - Cmd/Ctrl+A to select/deselect all (calls `onSelectAll`)\n *\n * Each list instance gates its document-level listeners on `useModalActive`\n * so two open lists don't both react to the same shift-click.\n */\nexport default function useTableNav<T>(\n items: T[],\n onSelect: (item: T) => void,\n onToggle?: (item: T) => void,\n onSelectAll?: () => void,\n onSelectRange?: (from: number, to: number) => void,\n) {\n const [focusIdx, setFocusIdx] = useState(-1);\n const itemsRef = useRef(items);\n const onSelectRef = useRef(onSelect);\n const onToggleRef = useRef(onToggle);\n const onSelectAllRef = useRef(onSelectAll);\n const onSelectRangeRef = useRef(onSelectRange);\n const focusRef = useRef(focusIdx);\n const lastToggledRef = useRef(-1);\n const isActive = useModalActive();\n const isActiveRef = useRef(isActive);\n itemsRef.current = items;\n onSelectRef.current = onSelect;\n onToggleRef.current = onToggle;\n onSelectAllRef.current = onSelectAll;\n onSelectRangeRef.current = onSelectRange;\n focusRef.current = focusIdx;\n isActiveRef.current = isActive;\n\n // The highlight a checkbox click moves, set once the click is over. The\n // click listeners below run in the capture phase, ahead of React, and a\n // plain setState there renders in the microtask straight after them — after\n // the browser has flipped the box but before React has read the flip. That\n // render writes the box back to its old `checked`, React then sees no change\n // and never calls onChange: the first click on a row only highlighted it and\n // the second ticked it (BG#00895). One timer turn later the whole click has\n // been dispatched, onChange included. The Shift+click anchor still lives in\n // a ref and is set at once.\n const focusTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const focusAfterEvent = (idx: number) => {\n clearTimeout(focusTimerRef.current);\n focusTimerRef.current = setTimeout(() => setFocusIdx(idx), 0);\n };\n useEffect(() => () => clearTimeout(focusTimerRef.current), []);\n\n const prevLen = useRef(items.length);\n useEffect(() => {\n if (items.length !== prevLen.current) {\n clearTimeout(focusTimerRef.current);\n setFocusIdx(-1);\n lastToggledRef.current = -1;\n prevLen.current = items.length;\n }\n }, [items.length]);\n\n // Track normal checkbox clicks to set the anchor for Shift+click.\n // MUST be a capture-phase listener: the checkbox's own onClick calls\n // e.stopPropagation() (so toggling doesn't also open the row), and since\n // React delegates events at the root container — which sits *below*\n // document — that stopPropagation blocks any bubble-phase document listener.\n // Capture runs top-down before the event reaches the checkbox, so the anchor\n // is recorded even though bubbling is later stopped. Without this, the anchor\n // stayed -1 and \"click A, Shift+click B\" only toggled A and B individually\n // instead of selecting the range between them.\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (!isActiveRef.current) return;\n if (e.shiftKey) return;\n const target = e.target as HTMLElement;\n const row = target?.closest?.('[data-row-idx]');\n if (!row) return;\n if (target.tagName !== 'INPUT' || (target as HTMLInputElement).type !== 'checkbox') return;\n const idx = parseInt(row.getAttribute('data-row-idx')!, 10);\n if (!isNaN(idx)) {\n lastToggledRef.current = idx;\n focusAfterEvent(idx);\n }\n };\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!isActiveRef.current) return;\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if ((e.target as HTMLElement)?.isContentEditable) return;\n\n if ((e.metaKey || e.ctrlKey) && e.key === 'a') {\n e.preventDefault();\n onSelectAllRef.current?.();\n return;\n }\n\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n\n const len = itemsRef.current.length;\n if (len === 0) return;\n\n const isDown = e.code === 'KeyJ' || e.key === 'j' || e.key === 'J' || e.key === 'ArrowDown';\n const isUp = e.code === 'KeyK' || e.key === 'k' || e.key === 'K' || e.key === 'ArrowUp';\n\n if (isDown || isUp) {\n e.preventDefault();\n const prev = focusRef.current;\n const next = isDown\n ? Math.min(prev + 1, len - 1)\n : Math.max(prev - 1, 0);\n if (next !== prev) {\n setFocusIdx(next);\n scrollRowIntoView(next);\n if (e.shiftKey && onToggleRef.current) {\n onToggleRef.current(itemsRef.current[next]);\n lastToggledRef.current = next;\n }\n }\n } else if (e.key === 'Enter' && focusRef.current >= 0 && focusRef.current < len) {\n e.preventDefault();\n onSelectRef.current(itemsRef.current[focusRef.current]);\n } else if (e.key === ' ' && focusRef.current >= 0 && focusRef.current < len) {\n e.preventDefault();\n if (e.shiftKey && lastToggledRef.current >= 0 && onSelectRangeRef.current) {\n const from = Math.min(lastToggledRef.current, focusRef.current);\n const to = Math.max(lastToggledRef.current, focusRef.current);\n onSelectRangeRef.current(from, to);\n } else {\n onToggleRef.current?.(itemsRef.current[focusRef.current]);\n }\n lastToggledRef.current = focusRef.current;\n }\n };\n\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, []);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (!isActiveRef.current) return;\n if (!e.shiftKey) return;\n const target = e.target as HTMLElement;\n const row = target?.closest?.('[data-row-idx]');\n if (!row) return;\n const clickedIdx = parseInt(row.getAttribute('data-row-idx')!, 10);\n if (isNaN(clickedIdx)) return;\n\n // Clicking the row's checkbox and clicking its body need different\n // handling below — the checkbox toggles itself, the body doesn't.\n const checkbox =\n target.tagName === 'INPUT' && (target as HTMLInputElement).type === 'checkbox'\n ? (target as HTMLInputElement)\n : null;\n\n const anchor = lastToggledRef.current;\n if (anchor < 0) {\n // Nothing to range from — this Shift+click is just a plain tick that\n // also becomes the anchor. On the checkbox its own onClick already\n // toggles the row; toggling here too cancels out and selects nothing.\n // The highlight waits for the click to finish, as a plain click's does.\n if (checkbox) {\n lastToggledRef.current = clickedIdx;\n focusAfterEvent(clickedIdx);\n return;\n }\n onToggleRef.current?.(itemsRef.current[clickedIdx]);\n } else {\n const from = Math.min(anchor, clickedIdx);\n const to = Math.max(anchor, clickedIdx);\n if (onSelectRangeRef.current) {\n onSelectRangeRef.current(from, to);\n // A range select only ever ADDS, so the clicked checkbox must end up\n // ticked. Say so directly rather than leaving it to React: the\n // browser toggled it during the click's activation behaviour, and if\n // the row was already selected the `checked` prop doesn't change, so\n // React has no reason to write the DOM back.\n if (checkbox) checkbox.checked = true;\n } else if (onToggleRef.current) {\n for (let i = from; i <= to; i++) {\n onToggleRef.current(itemsRef.current[i]);\n }\n }\n }\n\n // Suppress the click — but NEVER on the checkbox itself. preventDefault()\n // on a checkbox runs the browser's \"canceled activation steps\", which\n // restore the pre-click checkedness at the END of dispatch — after the\n // microtask in which React commits the new selection. React's write is\n // overwritten and never repeated (the prop is unchanged on later\n // renders), so the Shift+clicked row alone rendered unticked while being\n // counted as selected. stopPropagation() is enough here: it keeps both\n // the checkbox's own toggle and the row-open handler from firing. On the\n // row body preventDefault() is still wanted, to stop a Shift+click on a\n // cell link opening a new window.\n if (!checkbox) e.preventDefault();\n e.stopPropagation();\n lastToggledRef.current = clickedIdx;\n setFocusIdx(clickedIdx);\n };\n\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n return focusIdx;\n}\n\nfunction scrollRowIntoView(idx: number) {\n requestAnimationFrame(() => {\n const row = document.querySelector(`[data-row-idx=\"${idx}\"]`);\n row?.scrollIntoView({ block: 'nearest' });\n });\n}\n","/**\n * The shared `GET /auth/default-columns/{tableId}/` probe.\n *\n * `useColumnConfig` and `useSort` both want the admin-saved defaults for a\n * table — the first for `visible_columns`, the second for `sort` — and both\n * used to fire their own raw axios GET on mount. A list page calls both, so\n * every list screen asked the same URL twice, and the consumer axios instances\n * carry no cache adapter and no in-flight dedupe, so both were real round\n * trips (SG#00590).\n *\n * Routing it through react-query under one key collapses that: the two hooks\n * on a screen share a single request, a second table with the same `tableId`\n * shares it too, and re-opening a window inside `staleTime` serves from cache.\n *\n * The query key is namespaced under `react-os-shell` so it cannot collide with\n * a consumer's own keys — including the persistence allow-lists some of them\n * key off `queryKey[0]`; these defaults are cheap to refetch and have no\n * business surviving in IndexedDB.\n *\n * The refetch options are set explicitly rather than inherited: consumers set\n * aggressive global `defaultOptions` (the admin portal polls every 60s and\n * refetches on window focus), and this endpoint changes only when an admin\n * edits a table's defaults. Inheriting would have turned a once-per-mount\n * fetch into a poll — worse than the bug being fixed.\n *\n * Using react-query here must NOT make a `<QueryClientProvider>` a condition\n * of calling `useSort`, which never needed one: `useQuery` resolves its client\n * before it reads `enabled`, so an `enabled` flag does not spare the\n * `tableId`-less caller. See `useResolvedQueryClient` below.\n */\nimport { useContext, useMemo } from 'react';\nimport { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport apiClient, { isShellApiClientConfigured } from '../api/client';\nimport type { SortState } from './types';\n\n/**\n * The client this probe runs on when the consumer has mounted none.\n *\n * `useSort` is a public hook that was pure React plus one raw axios GET, and\n * its `tableId`-less form reached no network at all. Routing the probe through\n * react-query would have made a provider mandatory for every caller of it,\n * including that one — a hard new requirement on a hook people already call,\n * failing at render with `No QueryClient set` rather than degrading.\n *\n * React forbids calling `useQuery` conditionally, so the client is what varies\n * instead: `useQuery(options, client)` takes an explicit one, and\n * `QueryClientContext` is part of react-query's public API, so the hook can\n * see for itself whether a provider is above it. With one, nothing changes and\n * the probe lives in the consumer's cache alongside everything else. Without\n * one, it lands in a client this module owns — created on first use, never\n * `mount()`ed (that only wires the focus/online refetching this query switches\n * off anyway), and shared by every hook in the process, so `useColumnConfig`\n * and `useSort` still collapse to a single request.\n *\n * A tree that mounts a provider around only part of itself gets two caches and\n * so two requests, which is what the raw GETs did everywhere. Consumers that\n * want the sharing mount the provider at the root, as all three portals do.\n */\nlet ownedClient: QueryClient | undefined;\n\nfunction useResolvedQueryClient(): QueryClient {\n const provided = useContext(QueryClientContext);\n if (provided) return provided;\n if (!ownedClient) ownedClient = new QueryClient();\n return ownedClient;\n}\n\n/**\n * Drop the owned client. Internal — not re-exported from `src/index.ts`, so it\n * is not part of the package's API: it appears in neither `dist/index.js` nor\n * `dist/index.d.ts` (only, as every line of source does, inside the sourcemap).\n *\n * It exists for the specs. A react-query entry left in cache holds a\n * five-minute garbage-collection timer, and node's test runner will not exit\n * while one is pending — a spec that renders without a provider would sit there\n * for five minutes after its last assertion. A spec that mounts its own\n * `<QueryClientProvider>` calls `client.clear()` for the same reason; this is\n * the same call for the client no spec has a handle on.\n */\nexport function __resetOwnedQueryClient(): void {\n ownedClient?.clear();\n ownedClient = undefined;\n}\n\nexport type ColumnViewport = 'desktop' | 'mobile';\n\n/** Shape of `GET /auth/default-columns/{tableId}/`. Every field is optional:\n * the endpoint answers a miss with `{visible_columns: [], sort: null}`, and\n * the shell's unwired `apiClient` proxy resolves `data: null`. */\nexport interface DefaultColumnConfig {\n visible_columns?: string[] | null;\n sort?: SortState | null;\n}\n\n/** Same media query `useIsMobile` uses, so the column/sort defaults split on\n * the same breakpoint as the rest of the UI's mobile affordances. Read once\n * per mount (see `useDefaultColumnConfig`) — a user who resizes past the\n * breakpoint mid-session picks the other row up on the next window. */\nexport function readColumnViewport(): ColumnViewport {\n return typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile'\n : 'desktop';\n}\n\nexport function defaultColumnConfigQueryKey(tableId: string, viewport: ColumnViewport) {\n return ['react-os-shell', 'default-columns', tableId, viewport] as const;\n}\n\n/**\n * Admin-saved defaults for `tableId`, or `undefined` while unknown.\n *\n * `undefined` covers all three of \"still in flight\", \"the request failed\" and\n * \"no api client is wired\" — every caller treats those the same way, by\n * leaving whatever it already had alone.\n */\nexport function useDefaultColumnConfig(tableId?: string): {\n defaultConfig: DefaultColumnConfig | undefined;\n viewport: ColumnViewport;\n} {\n // Once at mount, matching the pre-react-query behaviour: the viewport was\n // read inside a `[tableId]` effect, so it never changed under a live table.\n const viewport = useMemo(readColumnViewport, []);\n const queryClient = useResolvedQueryClient();\n\n const { data } = useQuery<DefaultColumnConfig | null>({\n queryKey: defaultColumnConfigQueryKey(tableId ?? '', viewport),\n queryFn: () =>\n apiClient\n .get(`/auth/default-columns/${tableId}/`, { params: { viewport } })\n .then((r) => (r?.data ?? null) as DefaultColumnConfig | null),\n // The raw callers gated on this so a consumer without a backend (the Pages\n // demo) fires no doomed HTTP. `useColumnConfig` never did; it does now.\n enabled: !!tableId && isShellApiClientConfigured(),\n // The raw callers made exactly one attempt and swallowed the failure.\n retry: false,\n staleTime: 5 * 60_000,\n refetchInterval: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n }, queryClient);\n\n return { defaultConfig: data ?? undefined, viewport };\n}\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { useDefaultColumnConfig } from './useDefaultColumnConfig';\nimport type { ColumnDef } from './types';\n\ninterface ColumnState {\n key: string;\n width: number;\n hidden?: boolean;\n}\n\n/** Whether two column states are the same arrangement. Used to turn a\n * re-delivery of unchanged prefs into a no-op rather than a re-render: the\n * prefs adapter hands the same value back after a refetch, and the effects\n * below run on every change of it. */\nfunction sameColumns(a: ColumnState[], b: ColumnState[]): boolean {\n return a.length === b.length &&\n a.every((c, i) => c.key === b[i].key && c.width === b[i].width && !!c.hidden === !!b[i].hidden);\n}\n\n/** Ensure _select column (if present) is always at index 0 and never hidden */\nfunction pinSelectColumn(cols: ColumnState[]): ColumnState[] {\n const selectIdx = cols.findIndex(c => c.key === '_select');\n if (selectIdx >= 0) {\n const [sel] = cols.splice(selectIdx, 1);\n sel.hidden = false;\n cols.unshift(sel);\n }\n return cols;\n}\n\n/**\n * Fold a changed `defaultColumns` back into live column state.\n *\n * `columns` is seeded once, at mount. A consumer whose column list changes\n * WHILE mounted — a comparison period switched on, a mode that reveals extra\n * measures, a permission resolving late — got nothing: the new columns never\n * reached the state, so they never rendered, and the only way to see them was\n * to close the window and open it again. Withdrawn columns had the mirror\n * problem, lingering in state until `orderedColumns` spread an `undefined`\n * definition over them.\n *\n * The user's own decisions win wherever they exist: an existing column keeps\n * its width, its hidden flag and its place in the order. A new one lands\n * beside the column it was DECLARED next to rather than at the far right,\n * because a column that only makes sense next to another — a prior-period\n * figure beside the current one — is useless eleven columns away from it.\n *\n * Returns `prev` unchanged when nothing differs, so a consumer that rebuilds\n * its `ColumnDef[]` array every render causes no re-render.\n */\nfunction reconcileColumns(\n prev: ColumnState[],\n defaultColumns: ColumnDef[],\n withdrawn: Map<string, ColumnState>,\n): ColumnState[] {\n const declared = new Set(defaultColumns.map(d => d.key));\n const known = new Set(prev.map(c => c.key));\n const added = defaultColumns.filter(d => !known.has(d.key));\n // `_select` is the grid's own column and is never in the consumer's list.\n const kept = prev.filter(c => c.key === '_select' || declared.has(c.key));\n if (!added.length && kept.length === prev.length) return prev;\n\n // Remember what the user had done to a column the consumer has withdrawn,\n // so a set that comes back — a comparison toggled off and on again —\n // returns as they left it instead of resetting to the declaration.\n for (const col of prev) {\n if (col.key !== '_select' && !declared.has(col.key)) withdrawn.set(col.key, col);\n }\n\n const out = [...kept];\n for (const def of added) {\n const at = defaultColumns.indexOf(def);\n // Walk back through the declaration for the nearest column already\n // placed, and land just after it. Consecutive new columns chain, so a\n // declared pair stays a pair.\n let anchor = -1;\n for (let i = at - 1; i >= 0; i -= 1) {\n const idx = out.findIndex(c => c.key === defaultColumns[i].key);\n if (idx >= 0) { anchor = idx; break; }\n }\n out.splice(anchor + 1, 0, withdrawn.get(def.key)\n ?? { key: def.key, width: def.defaultWidth || 150, hidden: def.defaultHidden });\n withdrawn.delete(def.key);\n }\n return pinSelectColumn(out);\n}\n\n/**\n * Resizable + reorderable + hideable column state for `<ResizableTable>`.\n *\n * Reads and persists per-user through the `<ShellPrefsProvider>` adapter\n * (`prefs.columns_{tableId}`), with a 1-second debounce on the save, and reads\n * per-viewport admin defaults through the shared\n * `GET /auth/default-columns/{tableId}?viewport=…` probe.\n *\n * The prefs half used to be a raw `GET /auth/me/` fired from a `[tableId]`\n * effect, outside react-query — so every list mount re-fetched the whole user\n * profile (~1.5 MB on prod), on a client with no cache adapter and no in-flight\n * dedupe, and a screen that also renders a column-aware CSV export paid for it\n * twice. The adapter already holds that profile in one cached query, which is\n * the same object the raw GET was reading `preferences` off (SG#00590).\n *\n * Three consequences worth knowing, because this is NOT behaviour-preserving:\n *\n * - **A `<ShellPrefsProvider>` is now required for server-side persistence.**\n * Without one, `useShellPrefs()` reads empty and drops saves, so column\n * config degrades to localStorage-only. All three consumers that render\n * `<EntityList>`/`<ResizableTable>` mount the provider.\n * - **Prefs and admin defaults resolve independently**, where the raw pair was\n * a single `Promise.all`. If the admin default lands while prefs are still\n * loading it applies first and the user's own config replaces it a beat\n * later, rather than never showing. `useSort` has always behaved this way;\n * the two hooks now agree. The precedence that used to be one `if/else if`\n * is now the `userSavedRef` guard below plus the order the two effects fire\n * in — `tests/columnConfigDefaultsPrecedence.test.tsx` pins both directions.\n * - **A failed save is silent here.** The old `useMutation` let a rejected\n * `PATCH` reach a consumer's global `MutationCache({ onError })` — the admin\n * portal toasted it. The adapter's `save` owns its own failures now, so a\n * consumer that wants that toast raises it inside the adapter.\n *\n * What it does NOT require is a `<QueryClientProvider>` — it used to, for the\n * `useMutation`. `useDefaultColumnConfig` falls back to a client the package\n * owns when no provider is mounted.\n */\nexport function useColumnConfig(tableId: string, defaultColumns: ColumnDef[]) {\n const { prefs, save } = useShellPrefs();\n const prefKey = `columns_${tableId}`;\n const userSaved = prefs[prefKey];\n const { defaultConfig } = useDefaultColumnConfig(tableId);\n\n const [columns, setColumns] = useState<ColumnState[]>(() => {\n const cached = localStorage.getItem(`col-config-${tableId}`);\n if (cached) {\n try {\n const parsed = JSON.parse(cached) as ColumnState[];\n const existing = new Set(parsed.map(c => c.key));\n const merged = pinSelectColumn([\n ...parsed.filter(c => defaultColumns.some(d => d.key === c.key)),\n // `hidden: d.defaultHidden` matches the server-prefs merge below.\n // A column added to the consumer's ColumnDef list since this cache\n // was written has no entry in it, so its `defaultHidden` is the\n // only opinion there is.\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n return merged;\n } catch { /* fall through */ }\n }\n return pinSelectColumn(defaultColumns.map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })));\n });\n\n const [draggedIdx, setDraggedIdx] = useState<number | null>(null);\n const [dropGap, setDropGap] = useState<number | null>(null);\n const resizingRef = useRef<{ idx: number; startX: number; startWidth: number } | null>(null);\n\n // A change made in THIS mount always wins over an async restore below —\n // needed now that the restore effects are keyed on values that can arrive\n // (or be re-delivered by a refetch) long after mount. Same guard `useSort`\n // has always carried.\n const touchedRef = useRef(false);\n const userSavedRef = useRef(userSaved);\n userSavedRef.current = userSaved;\n\n const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const saveRef = useRef(save);\n saveRef.current = save;\n\n const persistColumns = useCallback((cols: ColumnState[]) => {\n touchedRef.current = true;\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(cols));\n if (saveTimer.current) clearTimeout(saveTimer.current);\n // Through the adapter, not a raw `PATCH /auth/me/`: the adapter patches the\n // cached profile optimistically and invalidates it, so the value the\n // restore effect below reads back is the one we just saved. A raw PATCH\n // left that cache stale, and the next window opened would have restored the\n // pre-change columns over the fresh ones.\n saveTimer.current = setTimeout(() => { void saveRef.current({ [prefKey]: cols }); }, 1000);\n }, [tableId, prefKey]);\n\n // The debounce deliberately outlives unmount, as it always has: resizing a\n // column and closing the window inside the second must still reach the\n // server. `saveRef` keeps the adapter callback reachable for that; the\n // adapter's own work (cache write + PATCH) is not tied to this component.\n\n // The user's own saved config. It arrives from the prefs adapter, which is\n // backed by the consumer's single cached `/auth/me/` query — no request of\n // our own. Adapters resolve async, so a window opened before prefs land\n // starts on the localStorage/`ColumnDef` state and picks this up after.\n useEffect(() => {\n if (touchedRef.current || !Array.isArray(userSaved)) return;\n const existing = new Set(userSaved.map((c: any) => c.key));\n const merged = pinSelectColumn([\n // Copied, not referenced: `pinSelectColumn` writes `hidden` on the entry\n // it pins, and these objects belong to the consumer's cached profile now.\n ...userSaved.filter((c: any) => defaultColumns.some(d => d.key === c.key)).map((c: any) => ({ ...c })),\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n setColumns(prev => (sameColumns(prev, merged) ? prev : merged));\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(merged));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, userSaved]);\n\n // The admin-saved default — only consulted while the user has no config of\n // their own, exactly as the `else if` it replaces did. Read through the ref\n // so this reflects whatever prefs have resolved by the time the probe lands;\n // if they resolve later still, the effect above overrides.\n useEffect(() => {\n if (touchedRef.current || Array.isArray(userSavedRef.current)) return;\n const visible = defaultConfig?.visible_columns;\n // Non-empty system defaults — apply them. (An empty array is treated\n // as \"no admin opinion\" and we leave the initial useState value alone,\n // which uses the per-column `defaultHidden` flag from each ColumnDef.)\n if (!Array.isArray(visible) || visible.length === 0) return;\n const visibleSet = new Set(visible);\n const systemCols = pinSelectColumn(defaultColumns.map(d => ({\n key: d.key,\n width: d.defaultWidth || 150,\n hidden: !visibleSet.has(d.key),\n })));\n setColumns(prev => (sameColumns(prev, systemCols) ? prev : systemCols));\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(systemCols));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, defaultConfig]);\n\n // Follow the consumer's column list for as long as this stays mounted.\n // Deliberately NOT persisted: a column set that comes and goes with a UI\n // toggle would otherwise PATCH the user's profile on every flip. The\n // existing persist paths — resize, drag, hide, reset — still capture it the\n // moment the user actually decides something.\n const withdrawnRef = useRef(new Map<string, ColumnState>());\n useEffect(() => {\n setColumns(prev => reconcileColumns(prev, defaultColumns, withdrawnRef.current));\n }, [defaultColumns]);\n\n const visibleColumns = columns.filter(c => !c.hidden);\n\n const onResizeStart = useCallback((idx: number, e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const visCol = visibleColumns[idx];\n const realIdx = columns.findIndex(c => c.key === visCol.key);\n resizingRef.current = { idx: realIdx, startX: e.clientX, startWidth: columns[realIdx].width };\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!resizingRef.current) return;\n const { idx: i, startX, startWidth } = resizingRef.current;\n const minW = defaultColumns.find(d => d.key === columns[i].key)?.minWidth || 30;\n const newWidth = Math.max(minW, startWidth + ev.clientX - startX);\n setColumns(prev => {\n const updated = [...prev];\n updated[i] = { ...updated[i], width: newWidth };\n return updated;\n });\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n resizingRef.current = null;\n setColumns(prev => { persistColumns(prev); return prev; });\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n }, [columns, visibleColumns, defaultColumns, persistColumns]);\n\n const onDragStart = useCallback((idx: number) => {\n setDraggedIdx(idx);\n }, []);\n\n const onDragOver = useCallback((visIdx: number, e: React.DragEvent) => {\n e.preventDefault();\n if (draggedIdx === null) return;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n let gap = e.clientX < rect.left + rect.width / 2 ? visIdx : visIdx + 1;\n const vis = columns.filter(c => !c.hidden);\n if (vis[0]?.key === '_select' && gap === 0) gap = 1;\n setDropGap(gap);\n }, [draggedIdx, columns]);\n\n const onDrop = useCallback((_visIdx: number, e: React.DragEvent) => {\n e.preventDefault();\n if (draggedIdx === null || dropGap === null) {\n setDraggedIdx(null);\n setDropGap(null);\n return;\n }\n if (dropGap === draggedIdx || dropGap === draggedIdx + 1) {\n setDraggedIdx(null);\n setDropGap(null);\n return;\n }\n setColumns(prev => {\n const visible = prev.filter(c => !c.hidden);\n const moved = visible[draggedIdx];\n if (!moved) return prev;\n const fromReal = prev.findIndex(c => c.key === moved.key);\n let toReal: number;\n if (dropGap < visible.length) {\n toReal = prev.findIndex(c => c.key === visible[dropGap].key);\n } else {\n toReal = prev.findIndex(c => c.key === visible[visible.length - 1].key) + 1;\n }\n const updated = [...prev];\n const [item] = updated.splice(fromReal, 1);\n updated.splice(toReal > fromReal ? toReal - 1 : toReal, 0, item);\n persistColumns(updated);\n return updated;\n });\n setDraggedIdx(null);\n setDropGap(null);\n }, [draggedIdx, dropGap, persistColumns]);\n\n const onDragEnd = useCallback(() => {\n setDraggedIdx(null);\n setDropGap(null);\n }, []);\n\n const toggleColumn = useCallback((key: string) => {\n setColumns(prev => {\n const updated = prev.map(c => c.key === key ? { ...c, hidden: !c.hidden } : c);\n if (updated.filter(c => !c.hidden).length === 0) return prev;\n persistColumns(updated);\n return updated;\n });\n }, [persistColumns]);\n\n const resetColumns = useCallback(() => {\n // Carry `defaultHidden` through, exactly as the initial state and the\n // server-prefs merge above do. Dropping it made Reset un-hide every\n // column the consumer had hidden by default — and reset persists, to\n // localStorage and then to the user's profile, so nothing healed it on a\n // later load (BG#00576).\n const defaults = pinSelectColumn(defaultColumns.map(d => ({\n key: d.key,\n width: d.defaultWidth || 150,\n hidden: d.defaultHidden,\n })));\n setColumns(defaults);\n persistColumns(defaults);\n }, [defaultColumns, persistColumns]);\n\n const orderedColumns = visibleColumns.map(c => {\n const def = defaultColumns.find(d => d.key === c.key);\n return { ...def!, width: c.width };\n }).filter(Boolean);\n\n const allColumns = columns.map(c => {\n const def = defaultColumns.find(d => d.key === c.key);\n return { key: c.key, label: def?.label || c.key, hidden: !!c.hidden };\n });\n\n return {\n orderedColumns,\n allColumns,\n onResizeStart,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n toggleColumn,\n resetColumns,\n draggedIdx,\n dropGap,\n };\n}\n","import { useState, useRef, useCallback, useMemo } from 'react';\nimport { useColumnConfig } from './useColumnConfig';\nimport { useIsMobile } from '../shell/useIsMobile';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport apiClient from '../api/client';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { useShellAuth } from '../shell/ShellAuth';\nimport type { ColumnDef, SortState } from './types';\n\ninterface ResizableTableProps {\n tableId: string;\n columns: ColumnDef[];\n sort?: SortState;\n onSort?: (field: string) => void;\n footer?: React.ReactNode;\n afterBody?: React.ReactNode;\n /** Permission codename(s) that gate the \"Save as default for all users\" link\n * in the column picker. The shell's `useShellAuth().hasAnyPerm` is queried\n * against this list. Defaults to a single placeholder permission; consumers\n * with no admin gate can pass `[]` to hide the link entirely. */\n saveDefaultPerms?: string[];\n children: (orderedColumns: (ColumnDef & { width: number })[]) => React.ReactNode;\n}\n\n/**\n * Sticky-header, scrollable-body table primitive with:\n * - drag-to-reorder columns (with a blue drop-indicator line)\n * - resize columns by the right-edge handle\n * - hide/show columns via a glass popover picker\n * - admin-only \"Save as default for all users\" link in the picker\n * - per-user persistence (via the shell-registered apiClient)\n * - mobile-aware selection mode toggle\n */\nexport default function ResizableTable({\n tableId,\n columns,\n sort,\n onSort,\n footer,\n afterBody,\n saveDefaultPerms = ['change_numberingconfig'],\n children,\n}: ResizableTableProps) {\n const isMobile = useIsMobile();\n const [selectionMode, setSelectionMode] = useState(false);\n // Strip the `_select` column on mobile (unless selection mode is on) so it\n // doesn't take up scarce screen real estate.\n const effectiveColumns = useMemo(\n () => (isMobile && !selectionMode ? columns.filter(c => c.key !== '_select') : columns),\n [columns, isMobile, selectionMode],\n );\n const {\n orderedColumns,\n allColumns,\n onResizeStart,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n toggleColumn,\n resetColumns,\n draggedIdx,\n dropGap,\n } = useColumnConfig(tableId, effectiveColumns);\n const { hasAnyPerm } = useShellAuth();\n const [pickerOpen, setPickerOpen] = useState(false);\n const [savingDefault, setSavingDefault] = useState(false);\n const [savedDefault, setSavedDefault] = useState(false);\n const pickerRef = useRef<HTMLDivElement>(null);\n const isAdmin = saveDefaultPerms.length > 0 && hasAnyPerm(saveDefaultPerms);\n\n useClickOutside(pickerRef, useCallback(() => { if (pickerOpen) setPickerOpen(false); }, [pickerOpen]));\n\n /**\n * Column widths in PIXELS, with the table floored at the container width.\n *\n * These were percentages of the running total, on a `w-full` table — which\n * made every width a RATIO, never a size. The table then always measured\n * exactly its container, so:\n *\n * - a wide list crushed every column to fit. Thirteen columns in a 1118px\n * window came out at 91px each, and every currency figure was truncated\n * to `A$514…`. Adding a column made every other column narrower;\n * - the body's `overflow-x-auto` was dead code, because a table that can\n * never exceed its container never overflows;\n * - dragging a resize handle could only STEAL width from other columns.\n * Widening one narrowed its neighbours and the total never moved.\n *\n * Pixels plus `min-width: 100%` keep both behaviours honest. Under-full, the\n * table still stretches to the container and `table-layout: fixed`\n * distributes the slack proportionally, exactly as the percentages did.\n * Over-full, the table is finally wider than its container and scrolls\n * sideways instead of compressing.\n */\n const totalWidth = orderedColumns.reduce((sum, col) => sum + col.width, 0);\n const colWidths = orderedColumns.map(col => `${col.width}px`);\n const tableStyle = { tableLayout: 'fixed' as const, width: totalWidth, minWidth: '100%' };\n\n // The header is its own table, outside the body's scroller, so it has to be\n // driven: without this it stays put while the body scrolls under it and the\n // labels stop naming the columns beneath them.\n const headScrollRef = useRef<HTMLDivElement>(null);\n const onBodyScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n const head = headScrollRef.current;\n if (head) head.scrollLeft = e.currentTarget.scrollLeft;\n }, []);\n\n const saveAsDefault = async () => {\n setSavingDefault(true);\n const visibleKeys = allColumns.filter(c => !c.hidden).map(c => c.key);\n const viewport = isMobile ? 'mobile' : 'desktop';\n // Capture the sort the admin is looking at too, so \"default for all\n // users\" covers ordering as well as columns. Lists that don't wire a\n // `sort` prop omit the key and leave any previously-saved sort alone.\n const payload: Record<string, unknown> = { visible_columns: visibleKeys };\n if (sort) payload.sort = sort;\n try {\n await apiClient\n .patch(`/auth/default-columns/${tableId}/`, payload, { params: { viewport } })\n .catch(() =>\n apiClient.post('/auth/default-columns/', { table_id: tableId, viewport, ...payload }),\n );\n setSavedDefault(true);\n setTimeout(() => setSavedDefault(false), 2000);\n } catch { /* ignore */ }\n setSavingDefault(false);\n };\n\n const supportsSelection = useMemo(() => columns.some(c => c.key === '_select'), [columns]);\n\n return (\n <div className={`flex flex-col flex-1 min-h-0 ${isMobile ? '-mx-4' : ''}`}>\n {/* Fixed header — scrolled sideways by the body, never by the user, so\n `overflow-x-hidden` rather than `auto`: two horizontal scrollbars on\n one table is worse than none. */}\n <div ref={headScrollRef} className=\"shrink-0 overflow-x-hidden\">\n <table className=\"divide-y divide-gray-200\" style={tableStyle}>\n <colgroup>\n {orderedColumns.map((col, i) => (\n <col key={col.key} style={{ width: colWidths[i] }} />\n ))}\n </colgroup>\n <thead className=\"bg-gray-50\">\n <tr>\n {orderedColumns.map((col, idx) => {\n const colDef = columns.find(c => c.key === col.key);\n const sortField = colDef?.sortField ?? (col.key !== '_select' ? col.key : undefined);\n const isSorted = sort && sortField && sort.field === sortField;\n const isFixed = col.key === '_select';\n return (\n <th\n key={col.key}\n className={`px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase select-none relative ${draggedIdx === idx ? 'bg-blue-50' : ''}`}\n draggable={!isFixed}\n onDragStart={isFixed ? undefined : () => onDragStart(idx)}\n onDragOver={isFixed ? undefined : (e) => onDragOver(idx, e)}\n onDrop={isFixed ? undefined : (e) => onDrop(idx, e)}\n onDragEnd={isFixed ? undefined : onDragEnd}\n style={isFixed ? undefined : { cursor: 'grab' }}\n >\n <span\n className={`${isFixed ? '' : 'truncate pr-3'} block ${sortField && onSort ? 'cursor-pointer hover:text-gray-700' : ''}`}\n onClick={sortField && onSort ? (e) => { e.stopPropagation(); onSort(sortField); } : undefined}\n >\n {col.headerNode ?? col.label}\n {isSorted && <span className=\"ml-1\">{sort!.direction === 'asc' ? '▲' : '▼'}</span>}\n </span>\n {!isFixed && (\n <div\n className=\"absolute right-0 top-0 bottom-0 w-4 cursor-col-resize flex items-center justify-center z-10\"\n onMouseDown={(e) => onResizeStart(idx, e)}\n style={{ marginRight: -8 }}\n >\n <div className=\"w-0.5 h-full bg-gray-200 hover:bg-blue-500 transition-colors\" />\n </div>\n )}\n {dropGap === idx && (\n <div className=\"absolute left-0 top-0 bottom-0 w-0.5 bg-blue-500 z-20 pointer-events-none\" />\n )}\n {idx === orderedColumns.length - 1 && dropGap === orderedColumns.length && (\n <div className=\"absolute right-0 top-0 bottom-0 w-0.5 bg-blue-500 z-20 pointer-events-none\" />\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n </table>\n </div>\n\n {/* Scrollable body */}\n <div className=\"flex-1 overflow-y-auto overflow-x-auto min-h-0\" onScroll={onBodyScroll}>\n <table className=\"divide-y divide-gray-200\" style={tableStyle}>\n <colgroup>\n {orderedColumns.map((col, i) => (\n <col key={col.key} style={{ width: colWidths[i] }} />\n ))}\n </colgroup>\n {children(orderedColumns as any)}\n </table>\n {afterBody}\n </div>\n\n {/* Footer */}\n {footer !== undefined && (\n <div className=\"border-t border-gray-200 px-4 py-2 text-sm text-gray-500 shrink-0 flex items-center justify-between\">\n <span>{footer}</span>\n <div className=\"flex items-center gap-3 relative\" ref={pickerRef}>\n {isMobile && supportsSelection && (\n <button\n onClick={() => setSelectionMode(s => !s)}\n className={`text-[11px] px-2 py-0.5 rounded ${selectionMode ? 'bg-blue-600 text-white' : 'text-gray-500 hover:text-gray-700 border border-gray-300'}`}\n title={selectionMode ? 'Hide selection column' : 'Show selection column'}\n >\n {selectionMode ? 'Done' : 'Select'}\n </button>\n )}\n <button onClick={resetColumns} className=\"text-[10px] text-gray-400 hover:text-gray-600\">Reset</button>\n <button onClick={() => setPickerOpen(!pickerOpen)} className=\"text-gray-400 hover:text-gray-600\" title=\"Choose columns\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75\" />\n </svg>\n </button>\n {pickerOpen && (\n <div className=\"absolute bottom-full right-0 mb-1 w-52 rounded-2xl z-50 py-1 max-h-80 overflow-y-auto\" style={getGlassStyle()}>\n <p className=\"px-3 py-1.5 text-[10px] font-semibold text-gray-400 uppercase\">Columns</p>\n {allColumns.filter(col => col.key !== '_select').map(col => (\n <label key={col.key} className=\"flex items-center gap-2 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={!col.hidden}\n onChange={() => toggleColumn(col.key)}\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\n />\n {col.label}\n </label>\n ))}\n {isAdmin && (\n <div className=\"border-t border-gray-100 mt-1 pt-1 px-3 pb-1\">\n <button onClick={saveAsDefault} disabled={savingDefault}\n className={`text-[10px] w-full text-center py-1 rounded ${savedDefault ? 'text-green-600' : 'text-gray-500 hover:text-blue-600'}`}>\n {savingDefault ? '...' : savedDefault ? 'Saved as default' : 'Save as default for all users'}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode, RefObject, Dispatch, SetStateAction, MouseEvent } from 'react';\nimport { useRef, useState } from 'react';\nimport useTableNav from './useTableNav';\nimport ResizableTable from './ResizableTable';\nimport LoadingSpinner from '../shell/LoadingSpinner';\nimport ListFooter from './ListFooter';\nimport ListLoadError from './ListLoadError';\nimport Checkbox from '../forms/Checkbox';\nimport { useShellStrings } from '../shell/strings';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\nimport { keepsNativeMenu } from '../shell/contextMenuTarget';\nimport { copyToClipboard, selectionAt, type SelectedText } from '../shell/clipboard';\nimport { escapeHtml } from '../utils/escapeHtml';\nimport apiClient from '../api/client';\nimport toast from '../shell/toast';\n\nexport interface EntityListColumn {\n key: string;\n label: string;\n defaultWidth?: number;\n minWidth?: number;\n defaultHidden?: boolean;\n sortField?: string;\n headerNode?: ReactNode;\n}\n\n/** A page-supplied entry in the right-click bulk menu (e.g. invoice Post /\n * Cancel). `onClick` receives the currently-selected rows. Set `divider` to\n * render a separator above the item, `danger` for a destructive tint. */\nexport interface EntityListContextAction<T = unknown> {\n label: string;\n onClick: (items: T[]) => void;\n danger?: boolean;\n disabled?: boolean;\n divider?: boolean;\n}\n\nexport interface EntityListProps<T> {\n items: T[];\n isLoading: boolean;\n emptyState: ReactNode;\n totalCount?: number;\n\n /** When true and no rows have loaded yet, render {@link ListLoadError}\n * (with a retry) instead of `emptyState` — so a failed fetch reads as an\n * error, not \"nothing here\". Wire `useInfiniteScroll`'s `isError`. A\n * mid-scroll next-page failure (rows already loaded) keeps the list.\n * Defaults to unset → behaviour unchanged for existing callers. */\n isError?: boolean;\n /** Retry handler for the error state — wire the data source's `refetch`.\n * It also backs the row menu's Refresh item. */\n onRetry?: () => void;\n /** Heading for the error state, e.g. \"Couldn't load candidates\". Omit for\n * {@link ListLoadError}'s generic \"Couldn't load this list\" — name the\n * entity where the list has one, so an outage reads as *this* list failing. */\n errorTitle?: string;\n /** Explanatory line under {@link EntityListProps.errorTitle}. Omit for\n * ListLoadError's generic connection/retry message. */\n errorMessage?: string;\n\n tableId: string;\n columns: EntityListColumn[];\n renderCell: (item: T, colKey: string) => ReactNode;\n getRowId?: (item: T) => string | number;\n\n sort?: { field: string; direction: 'asc' | 'desc' };\n onSort?: (field: string) => void;\n\n selected: Set<string | number>;\n setSelected: Dispatch<SetStateAction<Set<string | number>>>;\n\n onRowClick: (item: T) => void;\n onRowHover?: (item: T) => void;\n getRowClassName?: (item: T) => string;\n\n footerLabel: string;\n footerExtra?: ReactNode;\n\n // Loose ref type so consumers on React 18 (RefObject<HTMLDivElement>) and\n // React 19 (RefObject<HTMLDivElement | null>) both type-check cleanly.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sentinelRef?: RefObject<any>;\n isFetchingNextPage?: boolean;\n\n /** Perm codenames that gate \"Save as default for all users\" in the column\n * picker. Defaults to `['change_numberingconfig']` (admin-portal's proxy\n * for admin access). Pass `[]` to hide the link entirely. */\n saveDefaultPerms?: string[];\n\n /** Right-click row menu. Every list has one, with nothing to wire: Open (the\n * row right-clicked), Copy for text selected under the pointer, Copy\n * `<first column>` and Copy rows (the ticked rows as a table of the visible\n * columns in their on-screen order, which pastes into a spreadsheet as\n * cells), Select all, Clear selection, and Refresh when `onRetry` is wired.\n * Provide `exportEndpoint` (a list's `<base>/export_csv/` path, relative to\n * the api base) to add \"Export selected to CSV\", which downloads just the\n * ticked rows (`?ids=`, honouring the visible/ordered columns). Provide\n * `contextActions` for domain actions (e.g. invoice Post / Cancel); they sit\n * between the copy items and the selection items. */\n exportEndpoint?: string;\n exportFilename?: string;\n contextActions?: (items: T[]) => EntityListContextAction<T>[];\n}\n\n/** An open row menu: where, over which row, and what it can copy. */\ninterface RowMenu<T> {\n x: number;\n y: number;\n /** The row right-clicked — what Open opens. */\n item: T;\n /** Text selected under the pointer, when there is some. */\n text: SelectedText | null;\n /** The first visible column, read off the row when the menu opens so it\n * follows the user's column order. Null when it has no label to name it by. */\n firstColumn: { key: string; label: string } | null;\n}\n\n/** A row's data cells in on-screen order — the tick-box column left out, and\n * only the row's own cells, never those of a table nested inside one. */\nfunction rowCells(row: Element): HTMLElement[] {\n return (Array.from(row.children) as HTMLElement[])\n .filter(td => td.dataset?.colKey !== undefined && td.dataset.colKey !== '_select');\n}\n\n/** A cell as the user reads it: the rendered text with whitespace collapsed,\n * so a badge or a two-line cell stays one spreadsheet cell. `innerText`\n * follows CSS, so a hidden element is not copied; jsdom has no `innerText`,\n * hence the fallback. */\nfunction cellText(td: HTMLElement): string {\n const raw = typeof td.innerText === 'string' ? td.innerText : td.textContent ?? '';\n return raw.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * The canonical pageless data grid for both portals. Wraps `<ResizableTable>`\n * with selection-checkbox logic, keyboard navigation, the standardized list\n * footer, an infinite-scroll sentinel hook-up, and a right-click row menu.\n *\n * Usage:\n *\n * const { sort, onSort } = useSort('mid', 'asc', 'suppliers');\n * const { items, totalCount, isLoading, isFetchingNextPage, sentinelRef } =\n * useInfiniteScroll<Supplier>({ queryKey: ['suppliers', filters],\n * fetchFn: (p) => getSuppliers(p) });\n *\n * <EntityList\n * items={items}\n * totalCount={totalCount}\n * isLoading={isLoading}\n * sentinelRef={sentinelRef}\n * isFetchingNextPage={isFetchingNextPage}\n * tableId=\"suppliers\"\n * columns={SUPPLIER_COLUMNS}\n * renderCell={(s, k) => …}\n * sort={sort} onSort={onSort}\n * selected={selected} setSelected={setSelected}\n * onRowClick={(s) => openEntity('supplier', s.id, s, s.mid, '/suppliers')}\n * exportEndpoint=\"/suppliers/export_csv/\" exportFilename=\"Suppliers.csv\"\n * footerLabel=\"suppliers\"\n * emptyState={<EmptyState message=\"No suppliers yet.\" />}\n * />\n */\nexport default function EntityList<T>(props: EntityListProps<T>) {\n const {\n items, isLoading, emptyState, totalCount,\n isError, onRetry, errorTitle, errorMessage,\n tableId, columns, renderCell, getRowId = (item: any) => item.id,\n sort, onSort,\n selected, setSelected,\n onRowClick, onRowHover, getRowClassName,\n footerLabel, footerExtra,\n sentinelRef, isFetchingNextPage,\n saveDefaultPerms,\n exportEndpoint, exportFilename = 'export.csv', contextActions,\n } = props;\n\n const [menu, setMenu] = useState<RowMenu<T> | null>(null);\n const bodyRef = useRef<HTMLTableSectionElement>(null);\n // The same catalog DataTable's selection column reads, so the two say the\n // same words — and say them in the consumer's language when a provider is\n // mounted. English defaults without one.\n const strings = useShellStrings();\n\n const toggleItem = (item: T) => {\n setSelected(prev => {\n const next = new Set(prev);\n const id = getRowId(item);\n if (next.has(id)) next.delete(id); else next.add(id);\n return next;\n });\n };\n\n const toggleAll = () => {\n setSelected(prev => prev.size === items.length ? new Set() : new Set(items.map(getRowId)));\n };\n\n const selectRange = (from: number, to: number) => {\n setSelected(prev => {\n const next = new Set(prev);\n for (let i = from; i <= to; i++) next.add(getRowId(items[i]));\n return next;\n });\n };\n\n const focusIdx = useTableNav(items, onRowClick, toggleItem, toggleAll, selectRange);\n\n // Right-click a row → the row menu. If the row isn't already selected it\n // becomes the selection (standard desktop behaviour); an existing\n // multi-selection is kept. The browser keeps its own menu wherever the\n // shell-wide one leaves it — a text field or an image inside a row, a\n // `data-native-context-menu` subtree — and on Shift+right-click. Everywhere\n // else the event is claimed, so `ShellContextMenu` stands down over a row.\n const handleRowContextMenu = (e: MouseEvent<HTMLTableRowElement>, item: T) => {\n if (e.shiftKey || keepsNativeMenu(e.target)) return;\n e.preventDefault();\n const id = getRowId(item);\n if (!selected.has(id)) setSelected(new Set([id]));\n // The first column as the user has arranged it, read off the row itself.\n const key = rowCells(e.currentTarget)[0]?.dataset.colKey;\n const label = key ? columns.find(c => c.key === key)?.label : undefined;\n setMenu({\n x: e.clientX,\n y: e.clientY,\n item,\n text: selectionAt(e.target),\n firstColumn: key && label ? { key, label } : null,\n });\n };\n\n const selectedItems = items.filter(i => selected.has(getRowId(i)));\n\n // The ticked rows as the user sees them: the visible columns in their\n // on-screen order, read off the rendered cells. Reading the DOM rather than\n // calling `renderCell` again is the point — a cell renders a badge, a link or\n // a formatted amount, and a copy should hold what is on screen, not an id or\n // an ISO date.\n const selectedTable = () => {\n const rows = [...(bodyRef.current?.querySelectorAll<HTMLTableRowElement>('tr[data-row-idx]') ?? [])]\n .filter(tr => {\n const it = items[Number(tr.dataset.rowIdx)];\n return it !== undefined && selected.has(getRowId(it));\n });\n const keys = rows.length ? rowCells(rows[0]).map(td => td.dataset.colKey ?? '') : [];\n const labelByKey = new Map(columns.map(c => [c.key, c.label]));\n return {\n keys,\n header: keys.map(k => labelByKey.get(k) ?? k),\n body: rows.map(tr => rowCells(tr).map(cellText)),\n };\n };\n\n const copyRows = () => {\n setMenu(null);\n const { header, body } = selectedTable();\n if (!body.length) return;\n const text = [header, ...body].map(cells => cells.join('\\t')).join('\\n');\n const html = '<table><thead><tr>'\n + header.map(h => `<th>${escapeHtml(h)}</th>`).join('')\n + '</tr></thead><tbody>'\n + body.map(cells => `<tr>${cells.map(c => `<td>${escapeHtml(c)}</td>`).join('')}</tr>`).join('')\n + '</tbody></table>';\n void copyToClipboard(body.length === 1 ? 'Row' : `${body.length} rows`, text, html);\n };\n\n const copyColumn = (column: { key: string; label: string }) => {\n setMenu(null);\n const { keys, body } = selectedTable();\n const at = keys.indexOf(column.key);\n if (at < 0 || !body.length) return;\n void copyToClipboard(column.label, body.map(cells => cells[at]).join('\\n'));\n };\n\n // The visible/ordered columns as `key|Label,…` so the export mirrors the grid\n // (ResizableTable persists the live config to localStorage under this key).\n const colsParam = () => {\n const labelByKey = new Map(columns.map(c => [c.key, c.label]));\n try {\n const raw = localStorage.getItem(`col-config-${tableId}`);\n if (raw) {\n const parsed = JSON.parse(raw) as { key: string; hidden?: boolean }[];\n const cols = parsed\n .filter(c => !c.hidden && c.key !== '_select' && labelByKey.has(c.key))\n .map(c => `${c.key}|${labelByKey.get(c.key)}`);\n if (cols.length) return cols.join(',');\n }\n } catch { /* fall back to defaults */ }\n return columns.filter(c => !c.defaultHidden).map(c => `${c.key}|${c.label}`).join(',');\n };\n\n const exportSelected = async () => {\n setMenu(null);\n const ids = [...selected];\n if (!ids.length || !exportEndpoint) return;\n const p = new URLSearchParams({ ids: ids.join(',') });\n const cols = colsParam();\n if (cols) p.set('cols', cols);\n const sep = exportEndpoint.includes('?') ? '&' : '?';\n try {\n const res = await apiClient.get(`${exportEndpoint}${sep}${p}`, { responseType: 'blob' });\n const url = window.URL.createObjectURL(new Blob([res.data], { type: 'text/csv' }));\n const a = document.createElement('a');\n a.href = url;\n a.download = exportFilename;\n a.click();\n window.URL.revokeObjectURL(url);\n // `ids.length` is what we ASKED for, not what came back. The backend caps\n // every list export (`MAX_EXPORT_ROWS` in efficient/mixins.py) and reports\n // the cut on `X-Truncated` / `X-Row-Count`, where the count is the rows\n // actually in the file. Announcing the request count without reading them\n // states a number the file does not contain (BG#00477). Axios lowercases\n // response header names. When the headers are absent — an older backend,\n // or a cross-origin response that does not expose them — this falls\n // through to the unchanged success message.\n const headers = res.headers ?? {};\n const rowCount = Number(headers['x-row-count']);\n if (String(headers['x-truncated']) === 'true') {\n const kept = Number.isFinite(rowCount) ? `${rowCount} of ${ids.length}` : `only some of the ${ids.length}`;\n toast.notify(`Exported ${kept} rows. The server capped this export, so the file is incomplete.`);\n return;\n }\n toast.success(`Exported ${ids.length} ${ids.length === 1 ? 'row' : 'rows'}.`);\n } catch {\n toast.error('CSV export failed.');\n }\n };\n\n if (isLoading) return <LoadingSpinner />;\n // A failed initial fetch (no rows) reads as an error with retry, not the\n // empty state. Once rows exist, a later next-page failure keeps the list.\n // `title`/`message` default inside ListLoadError, so passing undefined here\n // keeps the generic copy for callers that don't name their entity.\n if (isError && items.length === 0) {\n return <ListLoadError title={errorTitle} message={errorMessage} onRetry={onRetry} />;\n }\n if (items.length === 0) return <>{emptyState}</>;\n\n const allSelected = items.length > 0 && selected.size === items.length;\n // The state the header box was missing. \"Some of these rows are selected\" is\n // not \"none of them\": an unchecked select-all above three ticked rows says\n // the page is clear, and the operator's next click — meaning \"select\n // everything\" — selects everything, which is what it already looked like.\n const someSelected = selected.size > 0 && !allSelected;\n\n const fullColumns: EntityListColumn[] = [\n {\n key: '_select',\n label: '',\n defaultWidth: 52,\n minWidth: 52,\n headerNode: (\n <Checkbox\n aria-label={strings.table.selectAll}\n checked={allSelected}\n indeterminate={someSelected}\n onChange={toggleAll}\n // 14px, which is what this column has always drawn — a row of them\n // down a dense list reads differently at 16. It cannot be a class:\n // `Checkbox` carries `h-4 w-4` in its own base, and Tailwind emits\n // `.h-3\\.5` BEFORE `.h-4`, so `h-3.5` in the className loses the\n // cascade however it is ordered in the attribute. An inline style is\n // the kit's documented way out of exactly that.\n style={{ height: 14, width: 14 }}\n />\n ),\n },\n ...columns,\n ];\n\n const footer = (\n <ListFooter\n selectedCount={selected.size}\n loadedCount={items.length}\n totalCount={totalCount}\n label={footerLabel}\n isFetchingMore={isFetchingNextPage}\n extra={footerExtra}\n />\n );\n\n const afterBody = sentinelRef ? (\n <>\n <div ref={sentinelRef} />\n {isFetchingNextPage && (\n <div className=\"text-center py-3\"><span className=\"text-sm text-gray-500\">Loading more...</span></div>\n )}\n </>\n ) : undefined;\n\n let rowMenu: ReactNode = null;\n if (menu) {\n const { x, y, item, text, firstColumn } = menu;\n const actions = contextActions ? contextActions(selectedItems) : [];\n const count = selectedItems.length;\n const close = () => setMenu(null);\n const moreExist = totalCount !== undefined && totalCount > items.length;\n rowMenu = (\n <PopupMenu portal style={{ left: x, top: y }} onClose={close} minWidth={210}>\n <PopupMenuLabel>{selected.size} selected</PopupMenuLabel>\n <PopupMenuItem className=\"font-medium\" onClick={() => { close(); onRowClick(item); }}>Open</PopupMenuItem>\n <PopupMenuDivider />\n {text && (\n <PopupMenuItem onClick={() => { close(); void copyToClipboard('Text', text.text, text.html); }}>Copy</PopupMenuItem>\n )}\n {firstColumn && (\n <PopupMenuItem onClick={() => copyColumn(firstColumn)}>Copy {firstColumn.label}</PopupMenuItem>\n )}\n <PopupMenuItem disabled={count === 0} onClick={copyRows}>\n {count === 1 ? 'Copy row' : `Copy ${count} rows`}\n </PopupMenuItem>\n {exportEndpoint && (\n <PopupMenuItem onClick={exportSelected}>Export selected to CSV</PopupMenuItem>\n )}\n {actions.map((a, i) => (\n <div key={i}>\n {/* The page's actions get a divider of their own; one it asked for\n on its first action is that same line, not a second one. */}\n {(a.divider || i === 0) && <PopupMenuDivider />}\n <PopupMenuItem\n danger={a.danger}\n disabled={a.disabled}\n onClick={() => { close(); a.onClick(selectedItems); }}\n >\n {a.label}\n </PopupMenuItem>\n </div>\n ))}\n <PopupMenuDivider />\n {!allSelected && (\n <PopupMenuItem onClick={() => { close(); setSelected(new Set(items.map(getRowId))); }}>\n {moreExist ? `Select all ${items.length} loaded` : 'Select all'}\n </PopupMenuItem>\n )}\n <PopupMenuItem onClick={() => { close(); setSelected(new Set()); }}>Clear selection</PopupMenuItem>\n {onRetry && (\n <PopupMenuItem onClick={() => { close(); onRetry(); }}>Refresh</PopupMenuItem>\n )}\n </PopupMenu>\n );\n }\n\n return (\n <div className=\"flex-1 flex flex-col mb-1 bg-white rounded-lg shadow overflow-hidden\">\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <ResizableTable\n tableId={tableId}\n columns={fullColumns}\n sort={sort}\n onSort={onSort}\n footer={footer}\n afterBody={afterBody}\n saveDefaultPerms={saveDefaultPerms}\n >\n {(cols) => (\n <tbody ref={bodyRef} className=\"divide-y divide-gray-100\">\n {items.map((item, rowIdx) => {\n const id = getRowId(item);\n return (\n <tr\n key={id}\n data-row-idx={rowIdx}\n className={`cursor-pointer ${focusIdx === rowIdx ? 'bg-blue-50 ring-1 ring-inset ring-blue-300' : selected.has(id) ? 'bg-blue-50 hover:bg-blue-100' : 'hover:bg-gray-50'} ${getRowClassName?.(item) ?? ''}`}\n onClick={() => onRowClick(item)}\n onContextMenu={(e) => handleRowContextMenu(e, item)}\n onMouseEnter={onRowHover ? () => onRowHover(item) : undefined}\n >\n {cols.map(col => (\n <td key={col.key} data-col-key={col.key} className=\"px-4 py-3 whitespace-nowrap text-sm overflow-hidden\">\n {col.key === '_select' ? (\n <Checkbox\n aria-label={strings.table.selectRow}\n checked={selected.has(id)}\n onChange={() => toggleItem(item)}\n // The row itself opens the record. The box only\n // ever selects, so its click stops here — the\n // toggle rides `onChange`, which React raises from\n // the same native click as a separate synthetic\n // event and so survives the stop.\n onClick={e => e.stopPropagation()}\n // See the header box: 14px cannot be a class.\n style={{ height: 14, width: 14 }}\n />\n ) : renderCell(item, col.key)}\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n )}\n </ResizableTable>\n </div>\n\n {rowMenu}\n </div>\n );\n}\n","import { useEffect, useRef, useCallback } from 'react';\nimport { useInfiniteQuery } from '@tanstack/react-query';\nimport type { PaginatedResponse } from './types';\n\ninterface UseInfiniteScrollOptions<T> {\n /** queryKey segments — arbitrary cache shapes (filters often include booleans,\n * dates, undefined). Callers pass their natural filter shape. */\n queryKey: (string | Record<string, unknown>)[];\n fetchFn: (params: Record<string, string>) => Promise<PaginatedResponse<T>>;\n /** Extra query-string params. Undefined values are dropped so axios doesn't\n * serialise them as \"?key=undefined\". */\n extraParams?: Record<string, string | undefined>;\n pageSize?: number;\n}\n\n/**\n * Wraps TanStack `useInfiniteQuery` with an IntersectionObserver-driven\n * sentinel so attaching `sentinelRef` to a div near the bottom of a scrollable\n * container auto-fires `fetchNextPage` as the user scrolls.\n *\n * Works inside modal windows too — the observer roots itself on the nearest\n * scrollable ancestor rather than the viewport.\n */\nexport function useInfiniteScroll<T>({\n queryKey,\n fetchFn,\n extraParams = {},\n pageSize: _pageSize = 25,\n}: UseInfiniteScrollOptions<T>) {\n void _pageSize; // reserved for future use; current backend defaults are fine\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n const cleanExtra = Object.fromEntries(\n Object.entries(extraParams).filter(([, v]) => v !== undefined),\n ) as Record<string, string>;\n\n const query = useInfiniteQuery({\n queryKey,\n queryFn: ({ pageParam = 1 }) =>\n fetchFn({ page: String(pageParam), ...cleanExtra }),\n getNextPageParam: (lastPage, allPages) => {\n if (lastPage.next) {\n return allPages.length + 1;\n }\n return undefined;\n },\n initialPageParam: 1,\n });\n\n const { fetchNextPage, hasNextPage, isFetchingNextPage } = query;\n\n const handleObserver = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n const [entry] = entries;\n if (entry.isIntersecting && hasNextPage && !isFetchingNextPage) {\n fetchNextPage();\n }\n },\n [fetchNextPage, hasNextPage, isFetchingNextPage],\n );\n\n useEffect(() => {\n const el = sentinelRef.current;\n if (!el) return;\n\n // Find the nearest scrollable ancestor — using root:null (viewport) fails\n // when the list is inside a modal window because the sentinel can scroll\n // into view within the modal's own overflow container without ever\n // entering the viewport.\n let scrollParent: HTMLElement | null = el.parentElement;\n while (scrollParent) {\n const overflow = getComputedStyle(scrollParent).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') break;\n scrollParent = scrollParent.parentElement;\n }\n\n const observer = new IntersectionObserver(handleObserver, {\n root: scrollParent,\n rootMargin: '200px',\n threshold: 0,\n });\n\n observer.observe(el);\n return () => observer.disconnect();\n }, [handleObserver]);\n\n // Defensive: drop any null/undefined entries that creep in from a malformed\n // page payload (e.g. backend serializer returns null for soft-deleted\n // records). Otherwise downstream `.map(r => r.id)` blows up the whole list.\n //\n // Then de-dupe by `id` across pages. Offset pagination over a non-unique\n // ordering key — or a background refetch of the already-loaded pages while\n // the underlying data shifts — can hand back the same record on two pages;\n // flattening them would render that row twice (the duplicate-row bug). Keep\n // the first occurrence. Items without an `id` can't be de-duped, so keep them.\n const seenIds = new Set<unknown>();\n const allItems = (query.data?.pages.flatMap((page) => page?.results ?? []) ?? [])\n .filter((x): x is T => x != null)\n .filter((x) => {\n const id = (x as { id?: unknown }).id;\n if (id == null) return true;\n if (seenIds.has(id)) return false;\n seenIds.add(id);\n return true;\n });\n const totalCount = query.data?.pages[0]?.count ?? 0;\n\n return {\n items: allItems,\n totalCount,\n isLoading: query.isLoading,\n // Surface the query's error state so a failed fetch renders as an error\n // (with retry) rather than a misleading empty list. `refetch` is the retry.\n isError: query.isError,\n error: query.error,\n isFetchingNextPage,\n hasNextPage: !!hasNextPage,\n sentinelRef,\n refetch: query.refetch,\n };\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { useDefaultColumnConfig } from './useDefaultColumnConfig';\nimport type { SortState } from './types';\n\n/** Guard for values restored from prefs / localStorage / the backend —\n * anything that isn't a well-formed `{ field, direction }` is ignored. */\nfunction isValidSort(v: unknown): v is SortState {\n const s = v as SortState | null | undefined;\n return !!s && typeof s.field === 'string' && s.field.length > 0 &&\n (s.direction === 'asc' || s.direction === 'desc');\n}\n\n/** The part of a column `useSort` reads — `ColumnDef` and `EntityList`'s own\n * column both fit.\n *\n * Not `DataTable`: its columns nest inside groups and it offers a sort on\n * `sortable`, not on `sortField ?? key`. `DataTableColumn` satisfies this\n * interface structurally, so passing one typechecks and then drops sorts the\n * table does offer. `DataTable` owns its own sort state through\n * `onSortChange`. */\nexport interface SortableColumn {\n key: string;\n sortField?: string;\n}\n\n/** Is `field` one the table offers? Same rule `ResizableTable` uses to make a\n * header clickable: `sortField ?? key`, never `_select`, and `sortField: ''`\n * switches the sort off. */\nfunction isOffered(columns: ReadonlyArray<SortableColumn>, field: string): boolean {\n return columns.some(c => (c.sortField ?? (c.key !== '_select' ? c.key : '')) === field && field !== '');\n}\n\n/**\n * Sort-state hook used by list pages. Returns:\n * - `sort` — current `{ field, direction }`\n * - `onSort(field)` — toggle direction if same field, else activate asc\n * - `ordering` — DRF-style string (`'-mid'` for desc, `'mid'` for asc) ready\n * to drop into a query-string param.\n *\n * Pass `tableId` (the same id the list gives `<ResizableTable>`/`<EntityList>`)\n * to persist the user's choice alongside their column config. Restore order:\n * per-user pref (`prefs.sort_{tableId}` via the ShellPrefs adapter) → the\n * admin-saved default on `/auth/default-columns/{tableId}/` → the page's\n * `defaultField`/`defaultDir`. localStorage mirrors the last-applied value so\n * the first render (before async prefs arrive) already uses the last-known\n * sort instead of flashing the default and refetching. Without `tableId` the\n * hook is pure in-memory state, exactly as before.\n *\n * The admin default is read through `useDefaultColumnConfig`, shared with\n * `useColumnConfig` so a list page fetches that row once rather than twice\n * (SG#00590). That probe is a react-query query, but this hook still needs no\n * `<QueryClientProvider>` in either form: with no provider above it the probe\n * falls back to a client the package owns (see `useDefaultColumnConfig`), and\n * the `tableId`-less form issues no request at all, as before.\n *\n * Pass `options.columns` (the same array the table gets) and a sort the\n * columns do not offer is replaced by the page default in `sort` and\n * `ordering` — a save on a column since given `sortField: ''`, or on a key\n * whose column now sorts on another `sortField`. Without it that stale save\n * goes out as `?ordering=` on every open; DRF drops a term it cannot order by,\n * so the list comes back unsorted for good. Without `columns` — or while the\n * array is still empty, which is a list page whose columns are not built yet\n * rather than a table that offers no sort — nothing is checked, as before.\n */\nexport function useSort(\n defaultField: string,\n defaultDir: 'asc' | 'desc' = 'asc',\n tableId?: string,\n options?: { columns?: ReadonlyArray<SortableColumn> },\n) {\n const { prefs, save } = useShellPrefs();\n const prefKey = tableId ? `sort_${tableId}` : null;\n\n const [chosen, setSort] = useState<SortState>(() => {\n if (prefKey) {\n if (isValidSort(prefs[prefKey])) return prefs[prefKey];\n try {\n const cached = JSON.parse(localStorage.getItem(`sort-config-${tableId}`) || 'null');\n if (isValidSort(cached)) return cached;\n } catch { /* fall through */ }\n }\n return { field: defaultField, direction: defaultDir };\n });\n\n // A click this mount always wins over any async restore below.\n const touchedRef = useRef(false);\n const savedPref = prefKey ? prefs[prefKey] : undefined;\n const savedRef = useRef(savedPref);\n savedRef.current = savedPref;\n\n // Per-user pref — prefs adapters load async, so a window opened before they\n // arrive starts on the default; apply the pref when it turns up.\n useEffect(() => {\n if (touchedRef.current || !isValidSort(savedPref)) return;\n setSort(prev =>\n prev.field === savedPref.field && prev.direction === savedPref.direction ? prev : savedPref,\n );\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(savedPref)); } catch { /* ignore */ }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, (savedPref as SortState | undefined)?.field, (savedPref as SortState | undefined)?.direction]);\n\n // Admin-saved default — only consulted while the user has no pref of their\n // own (the per-user branch above overrides it whenever prefs resolve later).\n //\n // Shared with `useColumnConfig`, which wants `visible_columns` off the same\n // row: a list page calls both hooks, and each used to fire its own raw GET\n // for it (SG#00590). One react-query key, one request per screen.\n const { defaultConfig } = useDefaultColumnConfig(tableId);\n useEffect(() => {\n const dflt = defaultConfig?.sort;\n if (touchedRef.current || isValidSort(savedRef.current) || !isValidSort(dflt)) return;\n setSort(prev =>\n prev.field === dflt.field && prev.direction === dflt.direction ? prev : dflt,\n );\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(dflt)); } catch { /* ignore */ }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId, defaultConfig]);\n\n // An EMPTY list is not an answer about what the table offers, it is a list\n // page whose columns have not been built yet — permission-filtered, or keyed\n // off a fetch. Reading it as \"offers nothing\" sent the page default on the\n // first render and the saved sort once the columns arrived: two requests per\n // open, the first of them sorted wrongly.\n const columns = options?.columns?.length ? options.columns : undefined;\n const sort: SortState = !columns || isOffered(columns, chosen.field)\n ? chosen\n : { field: defaultField, direction: defaultDir };\n\n const onSort = (field: string) => {\n touchedRef.current = true;\n const next: SortState =\n sort.field === field\n ? { field, direction: sort.direction === 'asc' ? 'desc' : 'asc' }\n : { field, direction: 'asc' };\n setSort(next);\n if (prefKey) {\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(next)); } catch { /* ignore */ }\n void save({ [prefKey]: next });\n }\n };\n\n const ordering = sort.direction === 'desc' ? `-${sort.field}` : sort.field;\n\n return { sort, onSort, ordering };\n}\n","import { useState, useRef, useEffect, useCallback, useId } from 'react';\nimport type { ReactNode, KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { XMarkIcon } from '@heroicons/react/20/solid';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport useClickOutside from '../hooks/useClickOutside';\nimport { registerModalEscapeInterceptor } from './escapeInterceptors';\nimport { firstEnabledIndex, lastEnabledIndex, matchTypeahead, nextEnabledIndex } from '../forms/selectNav';\n\nexport interface FilterOption {\n label: string;\n field: string;\n options: { value: string; label: string }[];\n searchable?: boolean; // default true if > 8 options\n}\n\ninterface FilterBarProps {\n filters: FilterOption[];\n values: Record<string, string>;\n onChange: (field: string, value: string) => void;\n onClear: () => void;\n children?: ReactNode;\n}\n\n/**\n * FilterBar — a horizontal row of filter controls. Each filter renders a custom\n * listbox dropdown or, for long lists, a glass-styled searchable dropdown; a\n * \"Clear filters\" button appears when any filter is active. Pair with\n * `useFilters`.\n *\n * The short-list path used to render a native `<select>`, but a native select's\n * OS popup swallows every key event while open — so list-page hotkeys died\n * until it closed (BG#00421). PlainFilter is a custom listbox that keeps key\n * events flowing to the page.\n */\nexport default function FilterBar({ filters, values, onChange, onClear, children }: FilterBarProps) {\n const activeCount = Object.values(values).filter(Boolean).length;\n\n return (\n <div className=\"flex items-center gap-3 flex-wrap\">\n {filters.map(f => {\n const isSearchable = f.searchable ?? f.options.length > 8;\n return isSearchable ? (\n <SearchableFilter\n key={f.field}\n filter={f}\n value={values[f.field] || ''}\n onChange={v => onChange(f.field, v)}\n />\n ) : (\n <PlainFilter\n key={f.field}\n filter={f}\n value={values[f.field] || ''}\n onChange={v => onChange(f.field, v)}\n />\n );\n })}\n {children}\n {activeCount > 0 && (\n <button onClick={onClear} className=\"flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700\">\n <XMarkIcon className=\"h-4 w-4\" />\n Clear filters\n </button>\n )}\n </div>\n );\n}\n\n/**\n * PlainFilter — the short-list (<=8 option) filter control. A pill trigger plus\n * a glass listbox dropdown, styled to match SearchableFilter. Focus stays on\n * the trigger and the active option is tracked via `aria-activedescendant`\n * (combobox pattern), with full keyboard support: Arrow/Home/End move the active\n * option, Enter/Space select, letter typeahead jumps, Esc closes the listbox\n * only. The leading option clears the filter (value '').\n */\nfunction PlainFilter({ filter, value, onChange }: { filter: FilterOption; value: string; onChange: (v: string) => void }) {\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(-1);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const openRef = useRef(open);\n openRef.current = open;\n const typeahead = useRef<{ buffer: string; timer: ReturnType<typeof setTimeout> | null }>({ buffer: '', timer: null });\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (i: number) => `${baseId}-opt-${i}`;\n\n // Index 0 is the \"clear\" entry (value ''), so the option list and the trigger\n // label share one array and keyboard nav can land on \"All\".\n const items = [{ value: '', label: filter.label }, ...filter.options];\n const selectedIndex = value ? items.findIndex(o => o.value === value) : 0;\n const selectedLabel = value ? filter.options.find(o => o.value === value)?.label : null;\n\n const close = useCallback((refocus = true) => {\n setOpen(false);\n setActive(-1);\n if (refocus) triggerRef.current?.focus();\n }, []);\n\n const openList = useCallback(() => {\n setActive(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex(items));\n setOpen(true);\n }, [selectedIndex, items]);\n\n const commit = useCallback((i: number) => {\n const o = items[i];\n if (!o) return;\n onChange(o.value);\n close();\n }, [items, onChange, close]);\n\n useClickOutside(ref, useCallback(() => { if (open) close(false); }, [open, close]));\n\n // Esc closes the listbox first, without closing a parent modal/window — the\n // modal's capture-phase Esc handler beats a bubble-phase onKeyDown, so the\n // shell's interceptor seam is the only way to win the race. The local\n // onKeyDown still covers the no-modal (plain page) case.\n useEffect(() => {\n if (!open) return;\n return registerModalEscapeInterceptor(e => {\n if (e.key !== 'Escape' || !openRef.current) return false;\n close();\n return true;\n });\n }, [open, close]);\n\n useEffect(() => {\n if (!open || active < 0) return;\n listRef.current?.querySelector<HTMLElement>(`#${CSS.escape(optionId(active))}`)?.scrollIntoView({ block: 'nearest' });\n });\n\n const runTypeahead = (char: string) => {\n const ta = typeahead.current;\n if (ta.timer) clearTimeout(ta.timer);\n ta.buffer += char;\n ta.timer = setTimeout(() => { ta.buffer = ''; ta.timer = null; }, 500);\n const hit = matchTypeahead(items, ta.buffer, open ? active : selectedIndex);\n if (hit < 0) return;\n if (open) setActive(hit);\n else commit(hit);\n };\n\n const onKeyDown = (e: ReactKeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!open) openList(); else setActive(a => nextEnabledIndex(items, a, 1));\n return;\n case 'ArrowUp':\n e.preventDefault();\n if (!open) openList(); else setActive(a => nextEnabledIndex(items, a, -1));\n return;\n case 'Home':\n if (open) { e.preventDefault(); setActive(firstEnabledIndex(items)); }\n return;\n case 'End':\n if (open) { e.preventDefault(); setActive(lastEnabledIndex(items)); }\n return;\n case 'Enter':\n if (open) { e.preventDefault(); commit(active); }\n return;\n case ' ':\n e.preventDefault();\n if (!open) openList(); else commit(active);\n return;\n case 'Escape':\n if (open) { e.preventDefault(); e.stopPropagation(); close(); }\n return;\n case 'Tab':\n if (open) close(false);\n return;\n default:\n if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {\n e.preventDefault();\n runTypeahead(e.key);\n }\n }\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n ref={triggerRef}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-activedescendant={open && active >= 0 ? optionId(active) : undefined}\n onClick={() => (open ? close() : openList())}\n onKeyDown={onKeyDown}\n className={`flex items-center gap-1.5 border rounded-lg px-2.5 py-1.5 text-sm transition-colors ${value ? 'border-blue-400 bg-blue-50 text-blue-700' : 'border-gray-300 text-gray-600 hover:border-gray-400'}`}\n >\n <span className=\"truncate max-w-[140px]\">{selectedLabel || filter.label}</span>\n {value ? (\n // A span, not a button: this lives INSIDE the combobox <button>, and\n // `<button>` inside `<button>` is invalid HTML — React logs \"cannot\n // be a descendant of\" and warns of a hydration error. It stays out of\n // the a11y tree because clearing is already a first-class keyboard\n // action: index 0 of the listbox is the \"All\" entry (value ''). A\n // nested control here would only pad the combobox's accessible name\n // with an affordance Tab can't reach.\n <span\n aria-hidden=\"true\"\n onClick={e => { e.stopPropagation(); onChange(''); }}\n className=\"cursor-pointer text-blue-400 hover:text-blue-600\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <svg className={`h-3.5 w-3.5 text-gray-400 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n )}\n </button>\n\n {open && (\n <div ref={listRef} id={listboxId} role=\"listbox\" className=\"absolute top-full left-0 mt-1 w-56 rounded-2xl z-[400] max-h-52 overflow-y-auto py-1\" style={getGlassStyle()}>\n {items.map((o, i) => (\n <div\n key={o.value || '__all__'}\n id={optionId(i)}\n role=\"option\"\n aria-selected={i === selectedIndex}\n onPointerEnter={() => setActive(i)}\n onClick={() => commit(i)}\n className={`mx-1 cursor-pointer truncate rounded-lg px-3 py-1.5 text-sm\n ${i === active ? 'bg-blue-50 text-blue-700'\n : i === selectedIndex ? 'font-medium text-blue-600'\n : 'text-gray-700'}`}\n >\n {o.label}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SearchableFilter({ filter, value, onChange }: { filter: FilterOption; value: string; onChange: (v: string) => void }) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const ref = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const selectedLabel = value ? filter.options.find(o => o.value === value)?.label : null;\n\n useClickOutside(ref, useCallback(() => { if (open) { setOpen(false); setSearch(''); } }, [open]));\n\n useEffect(() => {\n if (open) setTimeout(() => inputRef.current?.focus(), 50);\n }, [open]);\n\n const filtered = search\n ? filter.options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : filter.options;\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n onClick={() => setOpen(!open)}\n className={`flex items-center gap-1.5 border rounded-lg px-2.5 py-1.5 text-sm transition-colors ${value ? 'border-blue-400 bg-blue-50 text-blue-700' : 'border-gray-300 text-gray-600 hover:border-gray-400'}`}\n >\n <span className=\"truncate max-w-[140px]\">{selectedLabel || filter.label}</span>\n {value ? (\n // Same nested-button fix as PlainFilter — the dropdown's leading\n // \"All\" button is the keyboard path to the same clear.\n <span\n aria-hidden=\"true\"\n onClick={e => { e.stopPropagation(); onChange(''); setSearch(''); }}\n className=\"cursor-pointer text-blue-400 hover:text-blue-600\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" />\n </span>\n ) : (\n <svg className={`h-3.5 w-3.5 text-gray-400 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n )}\n </button>\n\n {open && (\n <div className=\"absolute top-full left-0 mt-1 w-56 rounded-2xl z-[400] overflow-hidden\" style={getGlassStyle()}>\n {/* Search input */}\n <div className=\"p-1.5 border-b border-gray-100\">\n <input\n ref={inputRef}\n value={search}\n onChange={e => setSearch(e.target.value)}\n placeholder={`Search ${filter.label.replace(/^All\\s*/i, '').toLowerCase()}...`}\n className=\"w-full rounded-md border border-gray-200 px-2.5 py-1.5 text-sm focus:border-blue-400 focus:ring-0 outline-none\"\n />\n </div>\n {/* Options */}\n <div className=\"max-h-52 overflow-y-auto\">\n {/* \"All\" option */}\n <button\n onClick={() => { onChange(''); setOpen(false); setSearch(''); }}\n className={`w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 ${!value ? 'text-blue-600 font-medium bg-blue-50/50' : 'text-gray-600'}`}\n >\n {filter.label}\n </button>\n {filtered.length === 0 ? (\n <p className=\"px-3 py-3 text-sm text-gray-400 text-center\">No matches</p>\n ) : (\n filtered.map(o => (\n <button\n key={o.value}\n onClick={() => { onChange(o.value); setOpen(false); setSearch(''); }}\n className={`w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 truncate ${value === o.value ? 'text-blue-600 font-medium bg-blue-50/50' : 'text-gray-700'}`}\n >\n {o.label}\n </button>\n ))\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/** Local filter-state helper: tracks active filter values + derived params. */\nexport function useFilters() {\n const [filterValues, setFilterValues] = useState<Record<string, string>>({});\n\n const setFilter = (field: string, value: string) => {\n setFilterValues(prev => {\n const next = { ...prev };\n if (value) next[field] = value;\n else delete next[field];\n return next;\n });\n };\n\n const clearFilters = () => setFilterValues({});\n\n const filterParams: Record<string, string> = {};\n for (const [k, v] of Object.entries(filterValues)) {\n if (v) filterParams[k] = v;\n }\n\n return { filterValues, setFilter, clearFilters, filterParams };\n}\n","/**\n * A perf report as plain text, for whatever the host files it into.\n *\n * The attachment is complete but nobody opens it first. A bug tracker shows\n * descriptions, so a performance report whose description is one sentence\n * about a stutter sits in the list looking like every other vague complaint\n * while the numbers that would rank it stay zipped inside a 140 KB file.\n *\n * So the description carries the findings: the machine, then the verdict, the\n * median, the worst frame, and the gesture that was slowest. That last line is\n * what changed the HUD's usefulness — the log marks menu opens, flyout opens\n * and window move/resize separately, so \"slowest while: submenu (14 fps)\" is a\n * sentence the report can lead with instead of leaving a triager to guess from\n * an average taken across a whole session.\n *\n * This lives in the shell rather than in each consuming portal because it is\n * pure formatting of a shell type and was otherwise going to exist three\n * times — which is how three copies quietly stop agreeing about what a report\n * says. What stays portal-side is everything genuinely portal-shaped: which\n * endpoint to post to, and which module list to seed from.\n */\nimport { describeMachine } from './perfEnvironment';\nimport type { PerfReport } from './PerfStats';\n\n/** Groups worth naming in the description. More than this and the summary\n * stops being a summary; the attachment has the rest. */\nconst TOP_GROUPS = 3;\n\n/** A frame rate of zero is not a slow reading, it is the absence of one — the\n * thread was too blocked to deliver frames at all. Printing \"0 fps\" makes it\n * look like a measurement. */\nconst fps = (n: number): string => (n > 0 ? `${n.toFixed(0)} fps` : 'stalled');\n\nconst duration = (ms: number): string => {\n const seconds = Math.round(ms / 1000);\n return seconds < 60 ? `${seconds}s` : `${Math.round(seconds / 60)}m`;\n};\n\n/** The description body for a filed performance report. */\nexport function describePerfReport(report: PerfReport): string {\n const { summary, message, verdict, environment } = report;\n const lines: string[] = [`Performance report — ${verdict}`, ''];\n\n lines.push(message.trim() || '(No description given.)', '');\n\n // The machine, before the numbers. Whether 34 fps is a bad application or an\n // old laptop is not decidable from the frame rate, and a triager who has to\n // open the attachment to find out will mostly just guess instead.\n lines.push(`Machine: ${describeMachine(environment)}`);\n const net = environment.network;\n if (net?.effectiveType && net.effectiveType !== '4g') {\n // Only when it is not the unremarkable case — a slow link is a different\n // complaint from a slow UI, and worth separating before anyone profiles.\n lines.push(`Connection: ${net.effectiveType}${net.rttMs ? ` · ${net.rttMs} ms round trip` : ''}`);\n }\n lines.push('');\n\n lines.push(\n `Median ${fps(summary.medianFps)} over ${duration(summary.durationMs)} ` +\n `(${summary.samples} samples), worst frame ${summary.worstFrameMs.toFixed(0)} ms.`,\n );\n\n // Worst-first already, so the head of each list is the finding.\n const activity = summary.byActivity.slice(0, TOP_GROUPS);\n if (activity.length) {\n lines.push(\n `Slowest while: ${activity.map(a => `${a.kind} ${fps(a.medianFps)} (worst ${a.worstMs.toFixed(0)} ms)`).join(' · ')}`,\n );\n }\n\n const menu = summary.worstMenus[0];\n if (menu) lines.push(`Slowest menu: ${menu.key} — ${fps(menu.medianFps)}`);\n\n const win = summary.worstWindows[0];\n if (win) lines.push(`Slowest window: ${win.key} — ${fps(win.medianFps)}`);\n\n if (summary.idle && summary.interacting) {\n lines.push(`At rest ${fps(summary.idle.medianFps)} vs in use ${fps(summary.interacting.medianFps)}.`);\n }\n\n lines.push('', `Full log attached as ${report.filename}.`);\n return lines.join('\\n');\n}\n\n/** The attachment. A `File` rather than a `Blob` so the multipart part carries\n * the stamped filename the receiving end stores. */\nexport function perfReportFile(report: PerfReport): File {\n return new File([report.json], report.filename, { type: 'application/json' });\n}\n","/**\n * Pure helpers for reconciling a bulk-import grid (rows of string cells) against\n * an existing items array, keyed by a designated \"key column\" (e.g. a part\n * number, SKU, or code). No app/framework dependencies — usable by any consumer\n * of {@link BulkImportGrid}.\n *\n * Merge rule: a blank cell means \"don't touch the original\" — only an explicit\n * value (including \"0\") replaces what's already there. Existing rows the user\n * didn't mention in the bulk grid are left untouched. Unknown keys are appended\n * via the caller-supplied `newItem` factory.\n */\n\nexport type BulkRow = Record<string, string | undefined>;\n\nexport interface DuplicateGroup {\n /** Key value as it appeared in the first occurrence (trimmed, original casing). */\n key: string;\n /** Indices into the rows array where this key appears. Length is always >= 2. */\n rowIndices: number[];\n}\n\n/**\n * Find key values that appear more than once within a single bulk-import file.\n * Match is case-insensitive (consistent with {@link mergeBulkItems}). Blank key\n * cells are ignored. The caller is expected to surface these to the user before\n * merge so they can pick a per-group resolution.\n */\nexport function findDuplicateKeys(rows: BulkRow[], keyRowKey: string): DuplicateGroup[] {\n const groups = new Map<string, { key: string; rowIndices: number[] }>();\n rows.forEach((r, i) => {\n const raw = r[keyRowKey];\n const trimmed = typeof raw === 'string' ? raw.trim() : '';\n if (!trimmed) return;\n const dedupeKey = trimmed.toUpperCase();\n const existing = groups.get(dedupeKey);\n if (existing) existing.rowIndices.push(i);\n else groups.set(dedupeKey, { key: trimmed, rowIndices: [i] });\n });\n const out: DuplicateGroup[] = [];\n for (const g of groups.values()) {\n if (g.rowIndices.length >= 2) out.push(g);\n }\n return out;\n}\n\ninterface BaseItem {\n [key: string]: unknown;\n}\n\nexport interface MergeBulkResult<T> {\n merged: T[];\n importedCount: number;\n}\n\nexport interface MergeBulkOptions<T extends BaseItem> {\n /** Raw rows from BulkImportGrid. */\n rows: BulkRow[];\n /** Existing items array to merge into. */\n existing: T[];\n /**\n * Mapping from row column key → item field key.\n * MUST include the key-column mapping (e.g. `{ pn: 'part_number' }`).\n * Example: `{ pn: 'part_number', qty: 'quantity', price: 'unit_price' }`.\n */\n fieldMap: Record<string, string>;\n /**\n * The item field that holds the merge key — the value `fieldMap` maps the\n * grid's key column onto. Existing items are matched against this field\n * (case-insensitive). Defaults to `'part_number'`.\n */\n keyField?: string;\n /**\n * Build a brand-new item for a row whose key isn't in `existing`.\n * `filled` contains only the fields the user actually entered (mapped to\n * item-field keys via `fieldMap`); supply defaults for anything required\n * by your item shape.\n */\n newItem: (filled: Partial<T>) => T;\n}\n\n/** Pull out just the trimmed cells the user actually filled in. */\nfunction pickFilled(row: BulkRow, fieldMap: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [rowKey, itemField] of Object.entries(fieldMap)) {\n const v = row[rowKey];\n const trimmed = typeof v === 'string' ? v.trim() : '';\n if (trimmed !== '') out[itemField] = trimmed;\n }\n return out;\n}\n\nexport function mergeBulkItems<T extends BaseItem>(\n options: MergeBulkOptions<T>,\n): MergeBulkResult<T> {\n const { rows, existing, fieldMap, newItem, keyField = 'part_number' } = options;\n\n // Locate the row key that holds the merge key, and the matching item field.\n const keyEntry = Object.entries(fieldMap).find(([, v]) => v === keyField);\n if (!keyEntry) {\n throw new Error(`mergeBulkItems: fieldMap must map a row column to \"${keyField}\"`);\n }\n const keyRowKey = keyEntry[0];\n\n const validRows = rows.filter(r => (r[keyRowKey] ?? '').trim());\n if (validRows.length === 0) return { merged: existing, importedCount: 0 };\n\n const existingMap = new Map<string, number>();\n existing.forEach((item, i) => {\n const k = item[keyField];\n if (typeof k === 'string' && k.trim()) existingMap.set(k.toUpperCase(), i);\n });\n\n const result = [...existing];\n const added: T[] = [];\n\n for (const r of validRows) {\n const filled = pickFilled(r, fieldMap);\n const k = filled[keyField];\n if (!k) continue;\n const idx = existingMap.get(k.toUpperCase());\n\n if (idx !== undefined) {\n // Existing key — overwrite only the fields the user actually entered.\n result[idx] = { ...result[idx], ...filled } as T;\n } else {\n // Tag every new item so callers can highlight bulk-imported rows in\n // the UI without each call site repeating the flag in their newItem\n // factory. Form submit payloads always project to explicit fields, so\n // the flag never leaks to the backend.\n added.push({ ...newItem(filled as Partial<T>), _isNew: true } as T);\n }\n }\n\n return { merged: [...result, ...added], importedCount: validRows.length };\n}\n","import { useState, useCallback } from 'react';\nimport EditableGrid, { withSpareRow } from './EditableGrid';\nimport { FileIntakeAlert, useFileIntake } from '../forms/useFileIntake';\nimport type { GridColumn } from './EditableGrid';\nimport { CancelButton } from './Modal';\nimport { findDuplicateKeys } from '../utils/mergeBulkItems';\nimport type { DuplicateGroup } from '../utils/mergeBulkItems';\n\n/**\n * Semantic role of a column, used to auto-map CSV columns to fields and to\n * format the per-column totals. The first column is always the merge \"key\"\n * regardless of its declared kind.\n * - `key` — the identifier rows are de-duplicated/merged on (text-like).\n * - `price` — a money column (matched by `$`/decimals; totalled with 2 dp).\n * - `qty` — a whole-number quantity column.\n * - `text` — anything else; never auto-mapped, never totalled.\n */\nexport type BulkColumnKind = 'key' | 'price' | 'qty' | 'text';\n\nexport interface BulkColumn {\n key: string;\n title: string;\n width?: number;\n required?: boolean;\n /**\n * Hint for CSV auto-mapping and totals. Defaults: the first column is `key`,\n * every other column is `text`. Set `price`/`qty` to opt a column into\n * auto-detection and the totals strip.\n */\n kind?: BulkColumnKind;\n}\n\nexport interface BulkImportGridProps {\n /** Column definitions. The FIRST column is always the merge key. */\n columns: BulkColumn[];\n /** Called with the resolved, de-duplicated rows (one object per row, keyed by column key). */\n onImport: (rows: Record<string, string>[]) => Promise<void>;\n /** Called when the user cancels an in-progress mapping/duplicate review. */\n onCancel: () => void;\n /** Optional override for the help text shown above the grid. */\n description?: string;\n /**\n * When set, duplicate key values are merged into a single row with their\n * numeric columns summed, instead of offering keep-first / keep-last / skip.\n * Use for quantity-based imports where two rows of the same key mean \"both\" —\n * never for price imports, where summing prices would be nonsensical.\n */\n mergeDuplicates?: boolean;\n}\n\nfunction cleanNumber(s: string): string {\n if (!s) return '';\n return s.replace(/[$¥¥€£,\\s]/g, '');\n}\n\nfunction parseCSVLine(line: string): string[] {\n if (line.includes('\\t')) return line.split('\\t').map(s => s.trim());\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n for (const ch of line) {\n if (ch === '\"') { inQuotes = !inQuotes; continue; }\n if (ch === ',' && !inQuotes) { parts.push(current.trim()); current = ''; continue; }\n current += ch;\n }\n parts.push(current.trim());\n return parts;\n}\n\n/** Resolve a column's effective kind: first column is the key, else its declared kind or `text`. */\nfunction colKind(col: BulkColumn, index: number): BulkColumnKind {\n if (index === 0) return 'key';\n return col.kind ?? 'text';\n}\n\n// ── Column type detection ──\n\ntype DetectedType = 'skip' | 'key' | 'price' | 'qty';\n\nfunction detectColumnType(values: string[]): DetectedType {\n const nonEmpty = values.filter(v => v.trim());\n if (nonEmpty.length === 0) return 'skip';\n\n const allIntOrEmpty = values.every(v => !v.trim() || /^\\d+$/.test(v.trim()));\n if (allIntOrEmpty) {\n const nums = nonEmpty.map(v => parseInt(v));\n const isSequential = nums.length > 2 && nums.every((n, i) => i === 0 || n >= nums[i - 1]);\n if (isSequential) return 'skip';\n }\n\n const hasLetters = nonEmpty.some(v => /[a-zA-Z]/.test(v));\n const hasDollar = nonEmpty.some(v => /\\$/.test(v));\n const hasDecimals = nonEmpty.filter(v => /\\.\\d{2}$/.test(cleanNumber(v))).length > nonEmpty.length * 0.5;\n const allWholeNumbers = nonEmpty.every(v => /^\\d+$/.test(cleanNumber(v)));\n\n if (hasLetters && !hasDollar) return 'key';\n if (hasDollar) return 'price';\n if (hasDecimals) return 'price';\n if (allWholeNumbers) {\n const avg = nonEmpty.reduce((s, v) => s + parseInt(cleanNumber(v)), 0) / nonEmpty.length;\n if (avg > 10) return 'qty';\n return 'skip';\n }\n return 'key';\n}\n\nfunction autoMapColumns(csvData: string[][], targetColumns: BulkColumn[]): number[] | null {\n if (csvData.length === 0 || csvData[0].length === 0) return null;\n const csvColCount = csvData[0].length;\n const targetKinds = targetColumns.map((c, i) => colKind(c, i));\n\n const csvColTypes: DetectedType[] = [];\n for (let c = 0; c < csvColCount; c++) {\n const values = csvData.map(row => row[c] || '');\n csvColTypes.push(detectColumnType(values));\n }\n\n const mapping: number[] = new Array(targetColumns.length).fill(-1);\n const used = new Set<number>();\n\n for (let t = 0; t < targetColumns.length; t++) {\n const kind = targetKinds[t];\n if (kind === 'text') continue;\n for (let c = 0; c < csvColCount; c++) {\n if (used.has(c)) continue;\n if (csvColTypes[c] === kind) {\n mapping[t] = c;\n used.add(c);\n break;\n }\n }\n }\n\n // Spread any remaining detected price columns across still-unmapped price targets,\n // in order (handles e.g. two currency columns the per-kind pass couldn't disambiguate).\n const priceTargets = targetKinds.map((k, i) => ({ i, k })).filter(x => x.k === 'price');\n const priceCsvCols = csvColTypes.map((t, i) => ({ i, type: t })).filter(x => x.type === 'price' && !used.has(x.i));\n let pi = 0;\n for (const pt of priceTargets) {\n if (mapping[pt.i] === -1 && pi < priceCsvCols.length) {\n mapping[pt.i] = priceCsvCols[pi].i;\n used.add(priceCsvCols[pi].i);\n pi++;\n }\n }\n\n if (mapping[0] === -1) return null; // key column must map\n return mapping;\n}\n\n// ── Column mapping UI ──\n\nfunction ColumnMapper({ csvPreview, targetColumns, onConfirm, onCancel }: {\n csvPreview: string[][];\n targetColumns: BulkColumn[];\n onConfirm: (mapping: number[]) => void;\n onCancel: () => void;\n}) {\n const autoMapping = autoMapColumns(csvPreview, targetColumns);\n const [mapping, setMapping] = useState<number[]>(autoMapping || new Array(targetColumns.length).fill(-1));\n const csvColCount = csvPreview[0]?.length || 0;\n\n const keyMapped = mapping[0] >= 0;\n\n return (\n <div className=\"border border-blue-200 rounded-lg bg-blue-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-3\">Map CSV columns to fields</p>\n <div className=\"grid grid-cols-2 gap-x-6 gap-y-2 mb-4\">\n {targetColumns.map((col, ti) => (\n <div key={col.key} className=\"flex items-center gap-2\">\n <span className=\"text-sm text-gray-700 w-28 shrink-0\">{col.title}</span>\n <select value={mapping[ti]} onChange={e => setMapping(prev => { const next = [...prev]; next[ti] = parseInt(e.target.value); return next; })}\n className=\"flex-1 border border-gray-300 rounded px-2 py-1 text-sm focus:border-blue-500 focus:ring-blue-500\">\n <option value={-1}>— Skip —</option>\n {Array.from({ length: csvColCount }, (_, ci) => (\n <option key={ci} value={ci}>Column {ci + 1} (e.g. {csvPreview[0]?.[ci] || ''})</option>\n ))}\n </select>\n </div>\n ))}\n </div>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-3\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {targetColumns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">{col.title}</th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {csvPreview.slice(0, 3).map((row, ri) => (\n <tr key={ri}>\n {targetColumns.map((col, ti) => (\n <td key={col.key} className=\"px-2 py-1 text-gray-700 font-mono\">\n {mapping[ti] >= 0 ? (row[mapping[ti]] || '') : <span className=\"text-gray-300\">—</span>}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-500\">{csvPreview.length} rows detected</span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={() => onConfirm(mapping)} disabled={!keyMapped}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50\">\n Confirm Mapping\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Duplicate-key review UI ──\n\ntype DupResolution = 'first' | 'last' | 'all' | 'skip';\n\nfunction DuplicateReview({\n rows,\n groups,\n columns,\n resolutions,\n onResolutionChange,\n onConfirm,\n onCancel,\n}: {\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n columns: BulkColumn[];\n resolutions: Record<string, DupResolution>;\n onResolutionChange: (dupKey: string, choice: DupResolution) => void;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n const totalKept = groups.reduce((acc, g) => {\n const r = resolutions[g.key.toUpperCase()];\n if (r === 'skip') return acc;\n if (r === 'all') return acc + g.rowIndices.length;\n return acc + 1; // first/last always collapse to a single row\n }, 0);\n const totalDropped = groups.reduce((acc, g) => {\n const r = resolutions[g.key.toUpperCase()];\n if (r === 'skip') return acc + g.rowIndices.length;\n if (r === 'all') return acc;\n return acc + (g.rowIndices.length - 1);\n }, 0);\n\n return (\n <div className=\"border border-amber-200 rounded-lg bg-amber-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-1\">Duplicate entries detected</p>\n <p className=\"text-xs text-gray-600 mb-3\">\n {groups.length} {groups.length === 1 ? 'value appears' : 'values appear'} more than once in your import.\n Choose how to handle each before proceeding.\n </p>\n <div className=\"space-y-3 mb-3 max-h-80 overflow-y-auto\">\n {groups.map(g => {\n const dupKey = g.key.toUpperCase();\n const choice = resolutions[dupKey] || 'first';\n return (\n <div key={dupKey} className=\"border border-amber-200 rounded bg-white p-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-mono font-medium text-gray-800\">{g.key}</span>\n <span className=\"text-xs text-gray-500\">{g.rowIndices.length} occurrences</span>\n </div>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-2\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {columns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">\n {col.title.replace(' *', '')}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {g.rowIndices.map((ri, occ) => (\n <tr key={ri} className={\n choice === 'skip' ? 'opacity-40' :\n (choice === 'first' && occ !== 0) || (choice === 'last' && occ !== g.rowIndices.length - 1)\n ? 'opacity-40 line-through' : ''\n }>\n {columns.map(col => (\n <td key={col.key} className=\"px-2 py-1 text-gray-700 font-mono\">\n {rows[ri]?.[col.key] || <span className=\"text-gray-300\">—</span>}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs\">\n {(['first', 'last', 'all', 'skip'] as DupResolution[]).map(opt => (\n <label key={opt} className=\"flex items-center gap-1 cursor-pointer\">\n <input\n type=\"radio\"\n name={`dup-${dupKey}`}\n value={opt}\n checked={choice === opt}\n onChange={() => onResolutionChange(dupKey, opt)}\n className=\"h-3 w-3 text-amber-600 focus:ring-amber-500\"\n />\n <span className=\"text-gray-700\">\n {opt === 'first' ? 'Keep first' : opt === 'last' ? 'Keep last' : opt === 'all' ? 'Keep all' : 'Skip all'}\n </span>\n </label>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-600\">\n {totalKept} kept · {totalDropped} dropped\n </span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={onConfirm}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Duplicate-key merge UI (mergeDuplicates mode) ──\n\n/**\n * Collapse each duplicate group into one row, summing numeric columns. The\n * merged row takes the slot of the group's first occurrence so import order is\n * preserved; later occurrences are dropped. Non-numeric / all-blank columns\n * collapse to blank (downstream merge treats blank as \"don't touch\").\n */\nfunction mergeDuplicateRows(\n rows: Record<string, string>[],\n groups: DuplicateGroup[],\n columns: BulkColumn[],\n): Record<string, string>[] {\n const keyCol = columns[0].key;\n const firstOf = new Map<number, DuplicateGroup>();\n const dropped = new Set<number>();\n for (const g of groups) {\n firstOf.set(g.rowIndices[0], g);\n g.rowIndices.slice(1).forEach(i => dropped.add(i));\n }\n const out: Record<string, string>[] = [];\n rows.forEach((row, i) => {\n const g = firstOf.get(i);\n if (g) {\n const merged: Record<string, string> = {};\n for (const col of columns) {\n if (col.key === keyCol) { merged[col.key] = g.key; continue; }\n const nums = g.rowIndices\n .map(ri => (rows[ri]?.[col.key] ?? '').trim())\n .filter(v => v !== '' && Number.isFinite(Number(v)))\n .map(Number);\n merged[col.key] = nums.length > 0 ? String(nums.reduce((s, n) => s + n, 0)) : '';\n }\n out.push(merged);\n } else if (!dropped.has(i)) {\n out.push(row);\n }\n });\n return out;\n}\n\nfunction MergeReview({\n rows,\n groups,\n columns,\n onConfirm,\n onCancel,\n}: {\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n columns: BulkColumn[];\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n const keyCol = columns[0].key;\n const dupRowCount = groups.reduce((acc, g) => acc + g.rowIndices.length, 0);\n\n return (\n <div className=\"border border-amber-200 rounded-lg bg-amber-50 p-4 mb-3\">\n <p className=\"text-sm font-medium text-gray-800 mb-1\">Duplicate entries detected</p>\n <p className=\"text-xs text-gray-600 mb-3\">\n {groups.length} {groups.length === 1 ? 'value appeared' : 'values appeared'} more than once.\n Each is merged into a single line with its quantity summed — review before proceeding.\n </p>\n <div className=\"border border-gray-200 rounded overflow-hidden mb-3 bg-white max-h-80 overflow-y-auto\">\n <table className=\"min-w-full text-xs\">\n <thead className=\"bg-gray-100\">\n <tr>\n {columns.map(col => (\n <th key={col.key} className=\"px-2 py-1 text-left text-gray-500 font-medium\">\n {col.title.replace(' *', '')}\n </th>\n ))}\n <th className=\"px-2 py-1 text-right text-gray-500 font-medium\">Merged from</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {groups.map(g => (\n <tr key={g.key.toUpperCase()}>\n {columns.map(col => {\n if (col.key === keyCol) {\n return (\n <td key={col.key} className=\"px-2 py-1 font-mono font-medium text-gray-800\">{g.key}</td>\n );\n }\n const nums = g.rowIndices\n .map(ri => (rows[ri]?.[col.key] ?? '').trim())\n .filter(v => v !== '' && Number.isFinite(Number(v)))\n .map(Number);\n if (nums.length === 0) {\n return <td key={col.key} className=\"px-2 py-1 text-gray-300\">—</td>;\n }\n const sum = nums.reduce((s, n) => s + n, 0);\n return (\n <td key={col.key} className=\"px-2 py-1 font-mono text-gray-700\">\n {nums.length > 1 && (\n <span className=\"text-gray-400\">{nums.join(' + ')} = </span>\n )}\n <span className=\"font-semibold text-gray-800\">{sum.toLocaleString()}</span>\n </td>\n );\n })}\n <td className=\"px-2 py-1 text-right text-gray-500\">{g.rowIndices.length} rows</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-gray-600\">\n {dupRowCount} duplicate rows → {groups.length} merged line{groups.length === 1 ? '' : 's'}\n </span>\n <div className=\"flex gap-2\">\n <CancelButton onClick={onCancel} className=\"text-sm text-gray-500 hover:text-gray-700\">Cancel</CancelButton>\n <button type=\"button\" onClick={onConfirm}\n className=\"bg-blue-600 text-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-700\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// ── Main Component ──\n\n/**\n * Spreadsheet-style bulk entry surface: type, paste, or upload a CSV/TSV, with\n * automatic column auto-mapping (with a manual mapping fallback) and duplicate\n * de-duplication (keep-first/last/all/skip, or summed merge in `mergeDuplicates`\n * mode). Purely presentational — owns local grid/CSV state and reports the\n * resolved rows via `onImport`; it does no fetching, auth, or persistence.\n *\n * Rows are de-duplicated and merged on the FIRST column (the \"key\"). Declare a\n * column's `kind` (`price`/`qty`) to opt it into CSV auto-detection and the\n * totals strip.\n */\nexport default function BulkImportGrid({ columns, onImport, description, mergeDuplicates = false }: BulkImportGridProps) {\n const [gridData, setGridData] = useState<string[][]>(() =>\n Array.from({ length: 15 }, () => Array(columns.length).fill(''))\n );\n const [importing, setImporting] = useState(false);\n const [error, setError] = useState('');\n const [pendingCSV, setPendingCSV] = useState<string[][] | null>(null);\n const [dupReview, setDupReview] = useState<{\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n resolutions: Record<string, DupResolution>;\n } | null>(null);\n const [mergeReview, setMergeReview] = useState<{\n rows: Record<string, string>[];\n groups: DuplicateGroup[];\n } | null>(null);\n\n const colCount = columns.length;\n const requiredLabel = columns[0]?.title?.replace(' *', '') || 'value';\n\n // Stats\n const filledRows = gridData.filter(row => row[0]?.trim());\n const filledCount = filledRows.length;\n const totals: Record<string, number> = {};\n for (let ci = 1; ci < columns.length; ci++) {\n if (colKind(columns[ci], ci) === 'text') continue;\n let sum = 0;\n for (const row of filledRows) {\n const v = parseFloat(cleanNumber(row[ci] || ''));\n if (!isNaN(v)) sum += v;\n }\n if (sum > 0) totals[columns[ci].key] = sum;\n }\n\n const gridColumns: GridColumn[] = columns.map(c => ({\n key: c.key,\n title: c.title,\n width: c.width,\n }));\n\n const loadDataIntoGrid = useCallback((data: string[][]) => {\n const cleaned = data.map(row => {\n const r = [...row];\n while (r.length < colCount) r.push('');\n return r.slice(0, colCount).map((cell, i) => {\n const kind = colKind(columns[i], i);\n return kind === 'price' || kind === 'qty' ? cleanNumber(cell) : cell;\n });\n });\n // Pad to minimum rows, and leave a spare line under a CSV long enough to\n // fill them — a paste on top of the upload needs somewhere to land too.\n while (cleaned.length < 15) cleaned.push(Array(colCount).fill(''));\n setGridData(withSpareRow(cleaned, colCount));\n }, [colCount, columns]);\n\n const loadCSVFile = (file: File) => {\n const reader = new FileReader();\n reader.onload = (ev) => {\n const text = (ev.target?.result as string) || '';\n const parsed = text.split('\\n').map(l => l.trim()).filter(Boolean).map(parseCSVLine);\n if (parsed.length === 0) return;\n\n const mapping = autoMapColumns(parsed, columns);\n if (mapping) {\n const mapped = parsed.map(row => columns.map((_, ti) => mapping[ti] >= 0 ? (row[mapping[ti]] || '') : ''));\n loadDataIntoGrid(mapped);\n } else {\n setPendingCSV(parsed);\n }\n };\n reader.readAsText(file);\n };\n\n // The whole panel is the drop target — a CSV dragged from the desktop lands\n // anywhere on it — and the \"Upload CSV\" button opens the same intake's dialog.\n const csvIntake = useFileIntake({\n accept: '.csv,.tsv,.txt', acceptHint: 'CSV · TSV · TXT', multiple: false,\n onAccept: ([file]) => loadCSVFile(file),\n });\n\n const handleMappingConfirm = (mapping: number[]) => {\n if (!pendingCSV) return;\n const mapped = pendingCSV.map(row => columns.map((_, ti) => mapping[ti] >= 0 ? (row[mapping[ti]] || '') : ''));\n loadDataIntoGrid(mapped);\n setPendingCSV(null);\n };\n\n const runImport = async (rows: Record<string, string>[]) => {\n setImporting(true);\n try { await onImport(rows); } catch { setError('Import failed.'); }\n setImporting(false);\n };\n\n const handleImport = async () => {\n const rows: Record<string, string>[] = gridData\n .filter(row => row[0]?.trim())\n .map(row => {\n const obj: Record<string, string> = {};\n columns.forEach((col, i) => {\n const val = row[i]?.trim() || '';\n // Currency symbols and thousands separators are noise in a number and\n // content in a description — strip them only where they're noise.\n const kind = colKind(col, i);\n obj[col.key] = kind === 'price' || kind === 'qty' ? cleanNumber(val) : val;\n });\n return obj;\n });\n if (rows.length === 0) { setError(`Enter at least one ${requiredLabel.toLowerCase()}.`); return; }\n setError('');\n\n const keyCol = columns[0].key;\n const groups = findDuplicateKeys(rows, keyCol);\n if (groups.length > 0) {\n if (mergeDuplicates) {\n setMergeReview({ rows, groups });\n } else {\n const resolutions: Record<string, DupResolution> = {};\n for (const g of groups) resolutions[g.key.toUpperCase()] = 'first';\n setDupReview({ rows, groups, resolutions });\n }\n return;\n }\n await runImport(rows);\n };\n\n const handleMergeConfirm = async () => {\n if (!mergeReview) return;\n const merged = mergeDuplicateRows(mergeReview.rows, mergeReview.groups, columns);\n setMergeReview(null);\n await runImport(merged);\n };\n\n const handleDupConfirm = async () => {\n if (!dupReview) return;\n const { rows, groups, resolutions } = dupReview;\n const drop = new Set<number>();\n for (const g of groups) {\n const choice = resolutions[g.key.toUpperCase()] || 'first';\n const idx = g.rowIndices;\n if (choice === 'first') {\n for (let i = 1; i < idx.length; i++) drop.add(idx[i]);\n } else if (choice === 'last') {\n for (let i = 0; i < idx.length - 1; i++) drop.add(idx[i]);\n } else if (choice === 'skip') {\n for (const j of idx) drop.add(j);\n }\n // 'all' keeps every occurrence — the rows import as separate lines\n }\n const filtered = rows.filter((_, i) => !drop.has(i));\n setDupReview(null);\n if (filtered.length === 0) { setError('All rows skipped.'); return; }\n await runImport(filtered);\n };\n\n const handleClear = () => {\n setGridData(Array.from({ length: 15 }, () => Array(colCount).fill('')));\n };\n\n const descText = description || `Paste from spreadsheets, type directly, or upload a CSV. Rows don't need to be in order — they'll be matched. Values not in the list will be added to the end. Fields left blank will not be affected.`;\n\n return (\n <div\n {...csvIntake.zoneProps}\n className={[\n 'border rounded-lg bg-gray-50 mb-3 overflow-hidden transition-colors',\n csvIntake.dragOver ? 'border-dashed border-blue-500 bg-blue-50' : 'border-gray-200',\n ].join(' ')}\n >\n <div className=\"px-4 pt-3 pb-2 flex items-center justify-between\">\n <p className=\"text-xs text-gray-500\">\n {descText}\n <span className=\"text-gray-400 ml-1\">({filledCount} lines{Object.keys(totals).length > 0 && ' · '}{Object.entries(totals).map(([k, v]) => {\n const col = columns.find(c => c.key === k);\n const label = col?.title?.replace(' *', '') || k;\n const isPrice = col ? colKind(col, columns.indexOf(col)) === 'price' : false;\n return `${label}: ${isPrice ? v.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : v.toLocaleString()}`;\n }).join(' · ')})</span>\n </p>\n <div className=\"flex items-center gap-2\">\n {filledCount > 0 && (\n <button type=\"button\" onClick={handleClear} className=\"text-gray-400 hover:text-gray-600 text-xs\">Clear</button>\n )}\n <input {...csvIntake.inputProps} />\n <button type=\"button\" onClick={csvIntake.open}\n className=\"text-blue-600 border border-blue-200 bg-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-blue-50 hover:border-blue-300\">Upload CSV</button>\n <button type=\"button\" onClick={handleImport} disabled={importing || filledCount === 0}\n className=\"text-green-600 border border-green-200 bg-white px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-green-50 hover:border-green-300 disabled:opacity-50\">\n {importing ? 'Importing...' : `Import ${filledCount} Lines`}\n </button>\n </div>\n </div>\n\n {pendingCSV && (\n <div className=\"px-4 pb-2\">\n <ColumnMapper\n csvPreview={pendingCSV}\n targetColumns={columns}\n onConfirm={handleMappingConfirm}\n onCancel={() => setPendingCSV(null)}\n />\n </div>\n )}\n\n {dupReview && (\n <div className=\"px-4 pb-2\">\n <DuplicateReview\n rows={dupReview.rows}\n groups={dupReview.groups}\n columns={columns}\n resolutions={dupReview.resolutions}\n onResolutionChange={(dupKey, choice) =>\n setDupReview(prev => prev ? { ...prev, resolutions: { ...prev.resolutions, [dupKey]: choice } } : prev)\n }\n onConfirm={handleDupConfirm}\n onCancel={() => setDupReview(null)}\n />\n </div>\n )}\n\n {mergeReview && (\n <div className=\"px-4 pb-2\">\n <MergeReview\n rows={mergeReview.rows}\n groups={mergeReview.groups}\n columns={columns}\n onConfirm={handleMergeConfirm}\n onCancel={() => setMergeReview(null)}\n />\n </div>\n )}\n\n <EditableGrid columns={gridColumns} data={gridData} onChange={setGridData} />\n <FileIntakeAlert rejections={csvIntake.rejections} className=\"px-4 py-1\" />\n {error && <p className=\"text-xs text-red-600 px-4 py-1\">{error}</p>}\n </div>\n );\n}\n","/**\n * Server connectivity indicator for the system tray.\n *\n * Renders a small globe icon coloured by the result of polling a\n * consumer-supplied health check. Click the icon to open a popover with\n * detailed connection info — server host, latency, last successful ping,\n * signed-in user, app/build version, browser network state.\n *\n * green — last poll succeeded\n * amber — initial check still in flight\n * red — last poll failed (network down, server down, timeout,\n * or non-2xx response). Pulses to draw attention.\n *\n * Polls every `pollMs` (default 15 s). The default health check applies a\n * `requestTimeoutMs` (default 5 s) per-request timeout via AbortController;\n * a custom `healthCheck` owns its own timeout. Latency is captured around\n * each poll and shown live in the popover.\n *\n * Product-agnostic: the shell never hardcodes an endpoint, auth context, or\n * app version. The consumer injects the health check, the signed-in user's\n * display fields, and the build label via props (a thin per-app wrapper).\n */\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { VERSION } from '../version';\nimport { onOverlayOpen } from './overlayEvents';\nimport { Z_LAYERS } from './zLayers';\n\nconst DEFAULT_POLL_MS = 15_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 5_000;\n\ntype Status = 'checking' | 'connected' | 'disconnected';\n\n/** Result of a single health poll. `latencyMs` is optional; when omitted on\n * an ok result the indicator simply shows no latency for that poll. */\nexport interface HealthCheckResult {\n ok: boolean;\n latencyMs?: number;\n}\n\n/** Display fields for the signed-in user shown in the popover's Session\n * section. All optional — the indicator derives a sensible name and hides\n * the Role row when `role` is empty. Pass `null`/`undefined` for \"not\n * signed in\". */\nexport interface ServerStatusUser {\n name?: string;\n email?: string;\n /** Secondary label for the Role row (e.g. group names, portal, company).\n * Hidden when empty. */\n role?: string;\n}\n\nexport interface ServerStatusIndicatorProps {\n /**\n * Performs one health poll and resolves with the outcome. The shell calls\n * this on mount and on every interval tick. A custom implementation owns\n * its own timeout/abort. When omitted, the indicator polls `healthUrl`\n * (default `/api/health/`) with a `requestTimeoutMs` AbortController.\n */\n healthCheck?: () => Promise<HealthCheckResult>;\n /** URL used by the built-in fetcher when no `healthCheck` is supplied. */\n healthUrl?: string;\n /** Poll interval in ms. Default 15 000. */\n pollMs?: number;\n /** Per-request timeout for the built-in fetcher, in ms. Default 5 000. */\n requestTimeoutMs?: number;\n /** Signed-in user's display fields for the Session section. */\n user?: ServerStatusUser | null;\n /** Build/version label for the Build section. Defaults to the shell's own\n * package version. Pass the consuming app's version here. */\n version?: string;\n}\n\nfunction timeAgo(date: Date | null): string {\n if (!date) return '—';\n const diff = Math.max(0, Date.now() - date.getTime());\n if (diff < 1500) return 'just now';\n if (diff < 60_000) return `${Math.round(diff / 1000)}s ago`;\n if (diff < 3_600_000) return `${Math.round(diff / 60_000)}m ago`;\n return `${Math.round(diff / 3_600_000)}h ago`;\n}\n\n/**\n * System-tray globe that polls a health check and exposes connection details\n * in a click-to-open popover. Drop into a taskbar tray alongside the\n * notification bell; supply `healthCheck` (or `healthUrl`), `user`, and\n * `version` via a thin per-app wrapper.\n */\nexport default function ServerStatusIndicator({\n healthCheck,\n healthUrl = '/api/health/',\n pollMs = DEFAULT_POLL_MS,\n requestTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS,\n user,\n version = VERSION,\n}: ServerStatusIndicatorProps) {\n const [status, setStatus] = useState<Status>('checking');\n const [lastOkAt, setLastOkAt] = useState<Date | null>(null);\n const [lastFailAt, setLastFailAt] = useState<Date | null>(null);\n const [lastLatencyMs, setLastLatencyMs] = useState<number | null>(null);\n const [browserOnline, setBrowserOnline] = useState<boolean>(navigator.onLine);\n const [open, setOpen] = useState(false);\n const [popPos, setPopPos] = useState<{ left: number; top: number }>({ left: 0, top: 0 });\n // Tick state forces a re-render once per second while the popover is\n // open so the \"5s ago / 12s ago\" relative timestamps stay live.\n const [, setTick] = useState(0);\n const cancelRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popRef = useRef<HTMLDivElement>(null);\n\n // Keep the latest health-check props in a ref so the polling effect's\n // dependency list stays stable — a fresh inline `healthCheck` on every\n // render must not tear down and restart the interval each time.\n const healthCheckRef = useRef(healthCheck);\n const healthUrlRef = useRef(healthUrl);\n const requestTimeoutRef = useRef(requestTimeoutMs);\n healthCheckRef.current = healthCheck;\n healthUrlRef.current = healthUrl;\n requestTimeoutRef.current = requestTimeoutMs;\n\n const ping = useCallback(async () => {\n const t0 = performance.now();\n try {\n let result: HealthCheckResult;\n if (healthCheckRef.current) {\n result = await healthCheckRef.current();\n } else {\n // Built-in fetcher: GET the health URL with a per-request timeout.\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), requestTimeoutRef.current);\n try {\n const res = await fetch(healthUrlRef.current, {\n method: 'GET',\n cache: 'no-store',\n signal: ctrl.signal,\n });\n result = { ok: res.ok, latencyMs: Math.round(performance.now() - t0) };\n } finally {\n clearTimeout(timer);\n }\n }\n if (cancelRef.current) return;\n if (result.ok) {\n setStatus('connected');\n setLastOkAt(new Date());\n setLastLatencyMs(result.latencyMs ?? Math.round(performance.now() - t0));\n } else {\n setStatus('disconnected');\n setLastFailAt(new Date());\n }\n } catch {\n if (!cancelRef.current) {\n setStatus('disconnected');\n setLastFailAt(new Date());\n }\n }\n }, []);\n\n useEffect(() => {\n cancelRef.current = false;\n // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional mount-time health poll; ping() sets state only in async fetch/catch continuations (post-commit), and the immediate-on-mount + interval timing must be preserved\n ping();\n const id = setInterval(ping, pollMs);\n return () => {\n cancelRef.current = true;\n clearInterval(id);\n };\n }, [ping, pollMs]);\n\n // Browser-level network events — independent signal from the API\n // poll so the popover can distinguish \"you're offline\" from \"the\n // server is down\".\n useEffect(() => {\n const onOnline = () => setBrowserOnline(true);\n const onOffline = () => setBrowserOnline(false);\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n return () => {\n window.removeEventListener('online', onOnline);\n window.removeEventListener('offline', onOffline);\n };\n }, []);\n\n // Keep relative timestamps fresh while the popover is open.\n useEffect(() => {\n if (!open) return;\n const id = setInterval(() => setTick(t => t + 1), 1000);\n return () => clearInterval(id);\n }, [open]);\n\n // Anchor the popover horizontally centred on the icon. Vertically,\n // flip to ABOVE the icon when the icon sits in the lower half of\n // the viewport (taskbar-at-bottom case) — otherwise the popover\n // would extend below the screen edge or be hidden by the taskbar.\n // Recompute on resize and once after the popover renders, so we\n // can use its actual measured height instead of an estimate.\n const placePopover = useCallback(() => {\n if (!buttonRef.current) return;\n const r = buttonRef.current.getBoundingClientRect();\n const popW = 320;\n // Estimated until the popover mounts; we re-place once we have\n // the real measurement (see useLayoutEffect below). 320 is the\n // typical popover height for a connected session.\n const popH = popRef.current?.offsetHeight || 320;\n\n // Horizontal: centre on the icon's midpoint, clamp to viewport\n // so the popover never bleeds off either edge.\n const iconCenterX = r.left + r.width / 2;\n const left = Math.max(8, Math.min(window.innerWidth - popW - 8, iconCenterX - popW / 2));\n\n // Vertical: flip above when the icon is in the lower half of\n // the viewport (covers the taskbar-at-bottom layout that's the\n // default in this app). The 6 px gap matches the bell's spacing.\n const iconCenterY = r.top + r.height / 2;\n const popAbove = iconCenterY > window.innerHeight / 2;\n const top = popAbove\n ? Math.max(8, r.top - popH - 6)\n : r.bottom + 6;\n\n setPopPos({ left, top });\n }, []);\n\n useEffect(() => {\n if (!open) return;\n placePopover();\n window.addEventListener('resize', placePopover);\n return () => window.removeEventListener('resize', placePopover);\n }, [open, placePopover]);\n\n // Once the popover actually mounts we know its real height — re-place\n // synchronously before paint so the popover never visibly jumps from\n // the height estimate to the measured value.\n useLayoutEffect(() => {\n if (open && popRef.current) placePopover();\n }, [open, placePopover]);\n\n // Click-outside + Escape closes the popover, and so does an overlay opening:\n // the card is on the popup layer, above the overlay (see `overlayEvents.ts`).\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node;\n if (popRef.current?.contains(t)) return;\n if (buttonRef.current?.contains(t)) return;\n setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onDown);\n window.addEventListener('keydown', onKey);\n const offOverlay = onOverlayOpen(() => setOpen(false));\n return () => {\n window.removeEventListener('mousedown', onDown);\n window.removeEventListener('keydown', onKey);\n offOverlay();\n };\n }, [open]);\n\n const colour =\n status === 'connected' ? '#16a34a' /* green-600 */\n : status === 'disconnected' ? '#dc2626' /* red-600 */\n : '#9ca3af'; /* gray-400 */\n const label =\n status === 'connected' ? 'Connected'\n : status === 'disconnected' ? 'Disconnected'\n : 'Checking…';\n const dotClass =\n status === 'connected' ? 'bg-green-500'\n : status === 'disconnected' ? 'bg-red-500'\n : 'bg-gray-400';\n\n const userName =\n user\n ? (user.name?.trim() || user.email || '—')\n : 'Not signed in';\n const userRole = user?.role || '';\n\n return (\n <>\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={() => setOpen(o => !o)}\n className={`shrink-0 inline-flex items-center justify-center rounded-md p-2 transition-colors hover:bg-white/20 ${\n status === 'disconnected' && !open ? 'animate-pulse' : ''\n }`}\n title={`${label}${lastOkAt ? ` · last ok ${lastOkAt.toLocaleTimeString()}` : ''}`}\n aria-label={label}\n aria-expanded={open}\n >\n {/* Globe — meridian + equator strokes coloured by connection state. */}\n {/* h-5 matches the notification bell so all tray icons get the same\n hover pill. */}\n <svg className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke={colour}\n strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M2 12h20\" />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n </button>\n\n {open && createPortal(\n <div\n ref={popRef}\n role=\"dialog\"\n aria-label=\"Server connection details\"\n style={{ position: 'fixed', left: popPos.left, top: popPos.top, width: 320, zIndex: Z_LAYERS.popup }}\n className=\"rounded-lg border border-gray-200 bg-white shadow-lg overflow-hidden text-gray-800\"\n >\n {/* Header — status pill + headline timing. */}\n <div className=\"px-4 py-3 border-b border-gray-100 bg-gray-50/60\">\n <div className=\"flex items-center gap-2\">\n <span className={`inline-block h-2 w-2 rounded-full ${dotClass} ${status === 'disconnected' ? 'animate-pulse' : ''}`} />\n <span className=\"text-sm font-semibold text-gray-900\">{label}</span>\n {status === 'connected' && lastLatencyMs != null && (\n <span className=\"ml-auto text-[11px] text-gray-500 tabular-nums\">{lastLatencyMs} ms</span>\n )}\n </div>\n <p className=\"mt-1 text-[11px] text-gray-500\">\n {status === 'connected' && lastOkAt && <>Last poll {timeAgo(lastOkAt)}.</>}\n {status === 'disconnected' && lastFailAt && <>Last failure {timeAgo(lastFailAt)}.</>}\n {status === 'checking' && <>First poll in flight…</>}\n </p>\n </div>\n\n {/* Detail rows. Two-column grid: label / value, label is\n fixed width so values align tidily. */}\n <dl className=\"px-4 py-3 text-[12px] grid grid-cols-[88px_1fr] gap-x-3 gap-y-1.5\">\n <dt className=\"text-gray-500\">Server</dt>\n <dd className=\"font-mono text-gray-900 truncate\" title={window.location.origin}>{window.location.host}</dd>\n\n <dt className=\"text-gray-500\">Protocol</dt>\n <dd className=\"text-gray-900\">{window.location.protocol.replace(':', '').toUpperCase()}</dd>\n\n <dt className=\"text-gray-500\">Browser</dt>\n <dd className={browserOnline ? 'text-gray-900' : 'text-red-600 font-medium'}>\n {browserOnline ? 'Online' : 'Offline'}\n </dd>\n\n <dt className=\"text-gray-500\">Last OK</dt>\n <dd className=\"text-gray-900\">\n {lastOkAt ? (\n <>\n <span className=\"tabular-nums\">{lastOkAt.toLocaleTimeString()}</span>\n <span className=\"text-gray-400 ml-1\">· {timeAgo(lastOkAt)}</span>\n </>\n ) : '—'}\n </dd>\n\n {lastFailAt && (\n <>\n <dt className=\"text-gray-500\">Last fail</dt>\n <dd className=\"text-gray-900\">\n <span className=\"tabular-nums\">{lastFailAt.toLocaleTimeString()}</span>\n <span className=\"text-gray-400 ml-1\">· {timeAgo(lastFailAt)}</span>\n </dd>\n </>\n )}\n\n <dt className=\"text-gray-500\">Latency</dt>\n <dd className=\"text-gray-900 tabular-nums\">\n {lastLatencyMs != null ? `${lastLatencyMs} ms` : '—'}\n </dd>\n\n <dt className=\"text-gray-500\">Poll</dt>\n <dd className=\"text-gray-900\">every {Math.round(pollMs / 1000)} s</dd>\n\n <dt className=\"text-gray-500 mt-2 col-span-2 border-t border-gray-100 pt-2 text-[10px] uppercase tracking-wide font-semibold\">Session</dt>\n\n <dt className=\"text-gray-500\">User</dt>\n <dd className=\"text-gray-900 truncate\" title={userName}>{userName}</dd>\n\n {userRole && (\n <>\n <dt className=\"text-gray-500\">Role</dt>\n <dd className=\"text-gray-900 truncate\" title={userRole}>{userRole}</dd>\n </>\n )}\n\n <dt className=\"text-gray-500 mt-2 col-span-2 border-t border-gray-100 pt-2 text-[10px] uppercase tracking-wide font-semibold\">Build</dt>\n\n <dt className=\"text-gray-500\">App</dt>\n <dd className=\"font-mono text-gray-900 text-[11px] truncate\" title={version}>{version || '—'}</dd>\n\n <dt className=\"text-gray-500\">UA</dt>\n <dd className=\"text-gray-900 text-[11px] truncate\" title={navigator.userAgent}>\n {navigator.userAgent.split(' ').slice(-2).join(' ')}\n </dd>\n </dl>\n\n {/* Footer — manual refresh. */}\n <div className=\"px-4 py-2 border-t border-gray-100 bg-gray-50/60 flex items-center justify-between\">\n <span className=\"text-[10px] text-gray-400\">Click ↻ to ping now</span>\n <button\n type=\"button\"\n onClick={() => { setStatus('checking'); ping(); }}\n disabled={status === 'checking'}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-blue-600 hover:text-blue-800 disabled:opacity-50\"\n >\n <svg className=\"h-3 w-3\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4 4v5h5M20 20v-5h-5M5.5 9A7 7 0 0 1 17 6.5M18.5 15A7 7 0 0 1 7 17.5\" />\n </svg>\n Refresh\n </button>\n </div>\n </div>,\n document.body,\n )}\n </>\n );\n}\n","/**\n * ChangePasswordForm — a self-contained \"change my password\" form: three\n * password fields (current / new / confirm), client-side validation, inline\n * error display, and submit/loading state. It owns all of that, but stays\n * product-agnostic: it knows nothing about how a password is actually changed.\n *\n * The host injects that via `onSubmit(oldPassword, newPassword)`, which it runs\n * on a valid submit. If `onSubmit` rejects, its `Error.message` is shown inline\n * (so a wrapper can surface a field-specific API message there). On success the\n * form shows a confirmation screen with a Done button (the original admin\n * behaviour) and fires `onSuccess` when Done is clicked. Set\n * `confirmOnSuccess={false}` to skip the screen and call `onSuccess`\n * immediately instead (the customer/supplier behaviour).\n */\nimport { useState, type FormEvent } from 'react';\nimport FormField from '../forms/FormField';\nimport Input from '../forms/Input';\nimport Button from '../forms/Button';\nimport { CMD_ENTER } from './Kbd';\n\nexport interface ChangePasswordFormProps {\n /**\n * Perform the password change. Resolve to indicate success; reject with an\n * `Error` whose `message` becomes the inline error shown to the user.\n */\n onSubmit: (oldPassword: string, newPassword: string) => Promise<void>;\n /** Called after a successful change — on Done click, or immediately when\n * `confirmOnSuccess` is false. */\n onSuccess?: () => void;\n /**\n * Show a success confirmation screen with a Done button after a successful\n * change. When false, `onSuccess` fires immediately on success. Default true.\n */\n confirmOnSuccess?: boolean;\n /** Minimum length required for the new password. Default 8. */\n minLength?: number;\n /** Label for the submit button. Default 'Change Password'. */\n submitLabel?: string;\n /** Label for the Done button on the success screen. Default 'Done'. */\n doneLabel?: string;\n}\n\n/**\n * Product-agnostic change-password form. The host supplies `onSubmit` to do the\n * actual change (e.g. call an API then re-authenticate).\n */\nexport default function ChangePasswordForm({\n onSubmit,\n onSuccess,\n confirmOnSuccess = true,\n minLength = 8,\n submitLabel = 'Change Password',\n doneLabel = 'Done',\n}: ChangePasswordFormProps) {\n const [oldPassword, setOldPassword] = useState('');\n const [newPassword, setNewPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [error, setError] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [success, setSuccess] = useState(false);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!oldPassword) { setError('Current password is required.'); return; }\n if (newPassword.length < minLength) { setError(`New password must be at least ${minLength} characters.`); return; }\n if (newPassword !== confirmPassword) { setError('Passwords do not match.'); return; }\n setError('');\n setSubmitting(true);\n try {\n await onSubmit(oldPassword, newPassword);\n if (confirmOnSuccess) {\n setSuccess(true);\n } else {\n onSuccess?.();\n }\n } catch (err) {\n setError(err instanceof Error && err.message ? err.message : 'Failed to change password.');\n } finally {\n setSubmitting(false);\n }\n };\n\n if (success) {\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-md bg-green-50 px-4 py-3 flex items-start gap-3\">\n <svg className=\"h-5 w-5 text-green-600 shrink-0 mt-0.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <p className=\"text-sm font-medium text-green-800\">Your password has been changed successfully.</p>\n </div>\n <div className=\"flex justify-end pt-2 border-t border-gray-200\">\n <Button variant=\"primary\" onClick={() => onSuccess?.()}>{doneLabel}</Button>\n </div>\n </div>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <FormField label=\"Current Password\" required>\n <Input type=\"password\" value={oldPassword} onChange={e => setOldPassword(e.target.value)} required />\n </FormField>\n <FormField label=\"New Password\" required>\n <Input type=\"password\" value={newPassword} onChange={e => setNewPassword(e.target.value)} required minLength={minLength} />\n </FormField>\n <FormField label=\"Confirm Password\" required>\n <Input type=\"password\" value={confirmPassword} onChange={e => setConfirmPassword(e.target.value)} required />\n </FormField>\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n <div className=\"flex justify-end pt-2 border-t border-gray-200\">\n <Button type=\"submit\" variant=\"primary\" loading={submitting}>\n {submitting ? 'Changing...' : submitLabel}\n <kbd className=\"rounded border border-blue-400/50 bg-blue-500/30 px-1.5 py-0.5 text-[10px] font-medium\">{CMD_ENTER}</kbd>\n </Button>\n </div>\n </form>\n );\n}\n","/**\n * Give up waiting on a promise that may never settle.\n *\n * Written for PdfActionButton: the Preview window opens on a \"LOADING PDF\"\n * placeholder and swaps in the document when the consumer's `fetchPdf()`\n * resolves. If that promise never settles — a connection torn down mid-flight,\n * a worker killed, a request the browser abandoned — the placeholder stays on\n * screen for ever, so a document that is merely slow and one that is genuinely\n * dead look identical to the person waiting. That ambiguity is what produced\n * report BG#00511, where the only evidence available afterwards was the user's\n * memory of what the screen showed.\n *\n * The timeout resolves to {@link TIMED_OUT} rather than rejecting, because a\n * timeout is not an error the consumer raised — it is this side deciding to\n * stop waiting, and the caller needs to tell the two apart to say something\n * accurate about which happened.\n *\n * The losing promise is NOT cancelled. The shell is transport-agnostic and\n * never owns the request, so there is nothing here to abort; `work` may still\n * settle later and its result is simply dropped. Consumers that need real\n * cancellation should wire an AbortController into their own `fetchPdf`.\n */\n\n/** Returned in place of the value when `work` did not settle in time. */\nexport const TIMED_OUT: unique symbol = Symbol('react-os-shell:timed-out');\n\nexport type MaybeTimedOut<T> = T | typeof TIMED_OUT;\n\n/**\n * Resolve `work`, or {@link TIMED_OUT} if it takes longer than `ms`.\n *\n * A non-finite or non-positive `ms` disables the timeout and awaits `work`\n * unchanged, so a consumer can opt out with `0` or `Infinity` without the\n * caller branching. Rejections propagate untouched — this only ever converts\n * *silence* into a value, never a failure into a success.\n */\nexport async function withTimeout<T>(work: Promise<T>, ms: number): Promise<MaybeTimedOut<T>> {\n if (!Number.isFinite(ms) || ms <= 0) return work;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n work,\n new Promise<typeof TIMED_OUT>(resolve => {\n timer = setTimeout(() => resolve(TIMED_OUT), ms);\n }),\n ]);\n } finally {\n // Always clear it: when `work` wins, an uncleared timer holds the event\n // loop open for the rest of the interval, which in Node turns a fast unit\n // test into a slow one and in a browser keeps a closure alive needlessly.\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { ReactNode } from 'react';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport { useWindowManager } from './WindowManager';\nimport { setPdfPreview } from '../apps/_previewStage';\nimport { withTimeout, TIMED_OUT } from './withTimeout';\nimport toast from './toast';\n\nexport interface PdfActionButtonProps {\n /**\n * Resolves the PDF bytes. The consumer owns the transport (axios/fetch/etc.)\n * and any error reporting; returning `null` aborts the action without the\n * shell surfacing a toast (the consumer is expected to have explained the\n * failure already).\n */\n fetchPdf: () => Promise<Blob | null>;\n /** Filename used for download and shown in the Preview window (e.g. \"Invoice_CI#1234.pdf\"). */\n filename: string;\n /** Button label. */\n label?: string;\n /** Override the default button styling. */\n className?: string;\n /** Disabled state. */\n disabled?: boolean;\n /**\n * Optional email handler. When supplied, a \"Send by Email\" item (with a\n * divider above it) is added to the menu and an Email button is wired into\n * the Preview window — both invoked with the already-fetched blob so the\n * consumer can hand it to its own composer. Omit it to hide email entirely.\n */\n onEmail?: (blob: Blob) => void;\n /**\n * Optional notification fired after a Preview window has been opened with the\n * resolved PDF (e.g. to drop a Recent Documents shortcut). Receives the\n * filename so the consumer can label the entry.\n */\n onPreviewOpened?: (filename: string) => void;\n /**\n * How to show the Preview. Defaults to the window manager's\n * `openPage('/preview')`; a routed app without windows (no\n * `WindowManagerProvider`, so that `openPage` does nothing) passes its own —\n * a tab, a route or an overlay that mounts the shell's `Preview`.\n *\n * It is called where `openPage` would be: after the \"LOADING PDF\"\n * placeholder is staged and before the fetch, so the viewer opens on the\n * placeholder and swaps the document in itself. `onPreviewOpened` is too\n * late for this: it fires once the document has arrived, so nothing would\n * show while it loads.\n */\n openPreview?: () => void;\n /** Optional leading icon override for the button (defaults to a document glyph). */\n icon?: ReactNode;\n /**\n * How long to wait for `fetchPdf()` before giving up, in milliseconds.\n * Defaults to 30 seconds. Pass `0` (or `Infinity`) to wait for ever.\n *\n * This exists because a promise that never settles used to leave the Preview\n * window on its \"LOADING PDF\" placeholder indefinitely, so a slow document\n * and a dead one were indistinguishable to the person waiting. Timing out\n * turns that silence into a stated failure. The request itself is not\n * cancelled — the consumer owns the transport (see `withTimeout`).\n */\n timeoutMs?: number;\n}\n\n/** Long enough that a genuinely slow document still arrives (the slowest\n * observed in production was ~4 s through the live stack), short enough that\n * nobody sits in front of a dead placeholder wondering. */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nconst DEFAULT_BUTTON_CLASS =\n 'inline-flex items-center gap-1.5 bg-white text-gray-700 border border-gray-300 px-3 py-1.5 text-sm font-medium rounded-lg hover:bg-gray-50 disabled:opacity-50';\n\nconst DocumentIcon = (\n <svg className=\"h-4 w-4 text-gray-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z\" /></svg>\n);\n\n/**\n * A dropdown PDF button that can Preview the document in the shell's Preview\n * window, Download it, or (when `onEmail` is supplied) hand the bytes to a\n * consumer-provided email composer.\n *\n * The shell is transport-agnostic: it never fetches the PDF itself. The\n * consumer injects a `fetchPdf()` resolver (typically wrapping its own HTTP\n * client) and the shell handles object-URL lifecycle, download, the loading\n * placeholder in Preview, and success toasts. App concerns (email composer,\n * recent-documents logging, where the Preview opens) are lifted to the\n * optional `onEmail` / `onPreviewOpened` / `openPreview` callbacks.\n */\nexport default function PdfActionButton({\n fetchPdf,\n filename,\n label = 'PDF',\n className,\n disabled,\n onEmail,\n onPreviewOpened,\n openPreview,\n icon,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n}: PdfActionButtonProps) {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const btnRef = useRef<HTMLButtonElement>(null);\n const [menuPos, setMenuPos] = useState<{ left: number; top: number }>({ left: 0, top: 0 });\n const { openPage } = useWindowManager();\n\n useEffect(() => {\n if (open && btnRef.current) {\n const rect = btnRef.current.getBoundingClientRect();\n setMenuPos({ left: rect.left, top: rect.bottom + 4 });\n }\n }, [open]);\n\n // Wrap the consumer's resolver so the spinner reflects in-flight fetches no\n // matter which action triggered them.\n const resolvePdf = async (): Promise<Blob | null | typeof TIMED_OUT> => {\n setLoading(true);\n try {\n return await withTimeout(fetchPdf(), timeoutMs);\n } finally {\n setLoading(false);\n }\n };\n\n const handleDownload = async () => {\n setOpen(false);\n const blob = await resolvePdf();\n // `null` means the consumer already told the user why. A timeout is ours,\n // so it would otherwise vanish with no explanation at all.\n if (blob === TIMED_OUT) {\n toast.error(`${filename} took too long to load. Please try again.`);\n return;\n }\n if (!blob) return;\n const url = window.URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n window.URL.revokeObjectURL(url);\n toast.success(`${filename} downloaded.`);\n };\n\n const handlePreview = async () => {\n setOpen(false);\n // Open the viewer immediately with a loading placeholder, then swap in the\n // resolved PDF once the blob arrives (only updates this very window).\n const handle = setPdfPreview({ filename, converting: true, convertingMessage: 'LOADING PDF' });\n if (openPreview) openPreview();\n else openPage('/preview');\n const blob = await resolvePdf();\n // Two different failures, deliberately worded differently: \"took too long\"\n // means the fetch never settled and we stopped waiting, \"Failed to load\"\n // means it settled with nothing. Telling them apart on screen is what lets\n // someone reporting a problem say which one they saw.\n if (blob === TIMED_OUT) {\n handle.update({\n filename, converting: false,\n convertingMessage: 'This document took too long to load. Close this window and try again.',\n });\n return;\n }\n if (!blob) {\n handle.update({ filename, converting: false, convertingMessage: 'Failed to load PDF.' });\n return;\n }\n const url = window.URL.createObjectURL(blob);\n // Wire the Preview window's Email button to the same already-fetched blob.\n handle.update({ url, filename, ...(onEmail ? { onEmail: () => onEmail(blob) } : {}) });\n onPreviewOpened?.(filename);\n };\n\n const handleEmail = async () => {\n setOpen(false);\n const blob = await resolvePdf();\n // TIMED_OUT is a symbol, so it is truthy — a plain `!blob` check would hand\n // it to the consumer's composer as if it were the document.\n if (blob === TIMED_OUT) {\n toast.error(`${filename} took too long to load. Please try again.`);\n return;\n }\n if (!blob || !onEmail) return;\n onEmail(blob);\n };\n\n const btnCls = className || DEFAULT_BUTTON_CLASS;\n\n return (\n <>\n <button ref={btnRef} type=\"button\" onClick={() => setOpen(!open)} disabled={disabled || loading} className={btnCls} data-menu-toggle>\n {icon ?? DocumentIcon}\n {loading ? 'Loading...' : label}\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" /></svg>\n </button>\n\n {open && createPortal(\n <PopupMenu style={menuPos} onClose={() => setOpen(false)} minWidth={180}>\n <PopupMenuItem onClick={handlePreview}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z\" /><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\" /></svg>\n Preview\n </PopupMenuItem>\n <PopupMenuItem onClick={handleDownload}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3\" /></svg>\n Download\n </PopupMenuItem>\n {onEmail && (\n <>\n <PopupMenuDivider />\n <PopupMenuItem onClick={handleEmail}>\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\" /></svg>\n Send by Email\n </PopupMenuItem>\n </>\n )}\n </PopupMenu>,\n document.body\n )}\n </>\n );\n}\n","/**\n * Shell-side entity fetcher — used by <WindowManager> when the user opens an\n * entity window. The shell knows the endpoint string (from the registry\n * entry) and the entity ID; the consumer translates that into an HTTP call\n * (or a mock, or whatever).\n *\n * Without a provider, the shell will throw if any code path tries to fetch\n * an entity — this is by design: a host that registers entity windows MUST\n * also wire the fetcher, or the open-entity flow has nothing to call.\n */\nimport { createContext, useContext, type ReactNode } from 'react';\n\nexport type EntityFetcher = (endpoint: string, id: string) => Promise<any>;\n\nconst EntityFetcherContext = createContext<EntityFetcher | null>(null);\n\nexport function ShellEntityFetcherProvider({\n value,\n children,\n}: { value: EntityFetcher; children: ReactNode }) {\n return <EntityFetcherContext.Provider value={value}>{children}</EntityFetcherContext.Provider>;\n}\n\n/** Returns the consumer-supplied entity fetcher, or a stub that throws\n * on call. Components that fetch entities call this hook eagerly so any\n * misconfiguration surfaces synchronously rather than at click-time. */\nexport function useShellEntityFetcher(): EntityFetcher {\n const ctx = useContext(EntityFetcherContext);\n return ctx ?? ((endpoint: string) => {\n throw new Error(\n `react-os-shell: cannot fetch ${endpoint} — no <ShellEntityFetcherProvider> mounted. ` +\n `If your app registers entity windows, supply an entityFetcher.`\n );\n });\n}\n","import { useEffect } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Registers Alt+Shift+N (Windows) / Opt+Shift+N (Mac) hotkey to trigger a \"New\" action.\n * Uses e.code (physical key) to avoid locale/modifier character issues.\n * Only fires for the active (frontmost) window, mirroring useEditHotkey — without\n * the guard every mounted window's hook answered one keypress at once, so with\n * two or more list windows open Alt+Shift+N fired \"New\" in all of them.\n */\nexport default function useNewHotkey(callback: () => void) {\n const isActive = useModalActive();\n useEffect(() => {\n if (!isActive) return;\n const handler = (e: KeyboardEvent) => {\n const isN = e.code === 'KeyN' || e.key === 'N' || e.key === 'n';\n if (e.altKey && e.shiftKey && isN && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n callback();\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [callback, isActive]);\n}\n","import { useEffect } from 'react';\nimport { useModalActive } from '../shell/Modal';\n\n/**\n * Registers Alt+Shift+E (Windows) / Opt+Shift+E (Mac) hotkey to trigger an \"Edit\" action.\n * Uses e.code (physical key) to avoid locale/modifier character issues.\n * Only fires for the active (frontmost) modal.\n */\nexport default function useEditHotkey(callback: (() => void) | null) {\n const isActive = useModalActive();\n useEffect(() => {\n if (!callback || !isActive) return;\n const handler = (e: KeyboardEvent) => {\n const isE = e.code === 'KeyE' || e.key === 'E' || e.key === 'e';\n if (e.altKey && e.shiftKey && isE && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n callback();\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [callback, isActive]);\n}\n","/**\n * Who a window-scoped shell CustomEvent is meant for.\n *\n * `modal-save` (Cmd+S) and `modal-duplicate` (Alt+Shift+D) are dispatched on\n * `document` by whichever `<Modal>` is frontmost. `document` reaches every\n * mounted window, so without a match the receiving hook in EVERY open form\n * answered a single keypress: two forms open meant one Cmd+S wrote both, and\n * depending on each form's mode that was a PATCH of a background record or a\n * brand new CREATE.\n *\n * Kept as a pure function, apart from the hooks, because this package's test\n * harness renders to static markup and cannot press a key — so the rule that\n * actually decides whether a foreign window writes is only testable if it is\n * not tangled up in an effect.\n */\nexport function isEventForModal(\n detail: unknown,\n modalId: string | null | undefined,\n): boolean {\n const from = (detail as { modalId?: unknown } | null | undefined)?.modalId;\n // No id on the wire: an older Modal dispatched it. Answer it, exactly as\n // before — a consumer newer than its shell keeps a working Cmd+S rather than\n // silently losing the shortcut altogether.\n if (typeof from !== 'string' || from === '') return true;\n // No id on the receiver: rendered outside any Modal, so there is no window to\n // be foreign to. Same reasoning — degrade to the old behaviour, do not go\n // silent.\n if (!modalId) return true;\n return from === modalId;\n}\n","import { useEffect } from 'react';\nimport { useEnclosingModalId } from '../shell/Modal';\nimport { isEventForModal } from '../shell/modalEventScope';\n\n/**\n * Registers a handler for the Cmd+S \"save and stay\" event dispatched by Modal.\n * The callback should save the form data WITHOUT closing the modal.\n *\n * Fires ONLY for the window the keystroke was aimed at. Modal restricts the\n * dispatch to the topmost modal, but the event goes to `document`, so without\n * this match every mounted window's hook answered one keypress — and with two\n * forms open, a single Cmd+S saved both. Depending on each form's mode that\n * either PATCHed a background record or CREATEd a brand new one, each with its\n * own success toast, so the user saw the write and misread which window it came\n * from.\n *\n * The match is on the originating modal's id rather than on\n * {@link useModalActive}, which asks a different question: \"is the frontmost\n * modal mine\". Every nested dialog a form opens pushes itself onto the\n * activation order, so a form with a child dialog open would read as inactive\n * and Cmd+S would silently do nothing where it used to save.\n *\n * An event with no `detail.modalId` is treated as \"for me\", so a consumer on a\n * newer package than the shell that dispatched it keeps working exactly as\n * before rather than losing Cmd+S entirely.\n */\nexport default function useModalSave(callback: (() => void) | null) {\n const modalId = useEnclosingModalId();\n useEffect(() => {\n if (!callback) return;\n const handler = (e: Event) => {\n if (!isEventForModal((e as CustomEvent).detail, modalId)) return;\n callback();\n };\n document.addEventListener('modal-save', handler);\n return () => document.removeEventListener('modal-save', handler);\n }, [callback, modalId]);\n}\n","import { useEffect } from 'react';\nimport { useEnclosingModalId } from '../shell/Modal';\nimport { isEventForModal } from '../shell/modalEventScope';\n\n/**\n * Registers a handler for the Alt+Shift+D \"save as new / duplicate\" event\n * dispatched by Modal. The callback should save the form data as a NEW record\n * (ignoring the current ID).\n *\n * Window-scoped for the same reason as {@link useModalSave}, and the stakes are\n * higher here: an unscoped duplicate created a second record from every open\n * form at once, and one consumer closes its window on success, so a background\n * window vanished as well.\n */\nexport default function useModalDuplicate(callback: (() => void) | null) {\n const modalId = useEnclosingModalId();\n useEffect(() => {\n if (!callback) return;\n const handler = (e: Event) => {\n if (!isEventForModal((e as CustomEvent).detail, modalId)) return;\n callback();\n };\n document.addEventListener('modal-duplicate', handler);\n return () => document.removeEventListener('modal-duplicate', handler);\n }, [callback, modalId]);\n}\n"]}
|