react-os-shell 4.76.0 → 4.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/windowRegistry/createWindowRegistry.ts","../src/shell/windowTarget.ts","../src/shell/ShortcutHelp.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/menuPath.ts","../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/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/UndoControls.tsx","../src/shell/ServerStatusIndicator.tsx","../src/shell/ChangePasswordForm.tsx","../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","jsxs","jsx","Fragment","fps","useRef","useCallback","useQueryClient","e","dx","dy","move","useLayoutEffect","navSections","navIcons","sectionIcons","isValidElement","cloneElement","visibleChildren","useSyncExternalStore","toISODate","useMemo","group","isCustom","Row","sections","LoadingSpinner","timeAgo","createPortal","createContext","useContext"],"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';\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 return (\n <Dialog open={open} onClose={() => setOpen(false)} className=\"relative z-[9999]\">\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 { 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 <div className=\"overflow-y-auto\" 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 <p className={`text-sm leading-tight ${!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 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\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 cs = typeof document !== 'undefined' ? getComputedStyle(document.documentElement) : null;\n const tbH = parseInt(cs?.getPropertyValue('--taskbar-height') || '0') || 0;\n const tbW = parseInt(cs?.getPropertyValue('--taskbar-width') || '0') || 0;\n const tbPos = (cs?.getPropertyValue('--taskbar-position') || 'bottom').trim();\n const defaultRight = 20 + (tbPos === 'right' ? tbW : 0);\n const defaultBottom = 20 + (tbPos === 'bottom' ? tbH : 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 const showVersion: boolean = prefs.show_desktop_version ?? true;\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 <button\n onClick={(e) => { e.stopPropagation(); setWhatsNewOpen(true); }}\n className={`absolute bottom-3 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 prefs.taskbar_position === 'top' ? 'right-3' :\n prefs.taskbar_position === 'left' ? 'right-3' :\n prefs.taskbar_position === 'right' ? 'left-3' :\n 'right-3 !bottom-16'\n }`}\n >\n {host.productVersion ?? APP_VERSION}\n </button>\n )}\n\n {/* What's New dialog */}\n {whatsNewOpen && (() => {\n const entries = host.productChangelog ?? changelog;\n return (\n <Modal open={true} onClose={() => setWhatsNewOpen(false)} title={shellStrings.about.whatsNew} size=\"md\" bodyScroll={false}>\n <div className=\"space-y-5 max-h-[60vh] overflow-y-auto px-1\">\n {entries.length === 0 ? (\n <p className=\"text-sm text-gray-400 text-center py-6\">{shellStrings.about.noChangelog}</p>\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\">&#8226;</span>\n {change}\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 </Modal>\n );\n })()}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\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' }: { onComplete: () => void; ready?: boolean; productName?: string; subtitle?: string; logo?: string }) {\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 <div className={`relative transition-all duration-700 ease-out ${phase === 'logo' ? 'scale-75 opacity-0' : 'scale-100 opacity-100'}`}>\n <img src={logo} alt=\"\" className=\"h-20 w-20 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 </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';\n\nexport default function LogoutAnimation({ onComplete, subtitle, logo = '/favicon.svg' }: { onComplete: () => void; subtitle?: string; logo?: string }) {\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 <img src={logo} alt=\"\" className=\"h-20 w-20 drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\" />\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, so mounting with an\n * empty desktop cannot overwrite the saved set it was about to replay.\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.\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 */\nimport { useEffect, useRef } from 'react';\n\nimport { useWindowManager, type MinimizedItem } from './WindowManager';\nimport { useShellPrefs } from './ShellPrefs';\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') {\n refs.push({ type: 'entity', entityType: w.entityType, entityId: w.entityId, label: w.label, route: w.route });\n }\n }\n return refs;\n}\n\nconst SAVE_DEBOUNCE_MS = 800;\n\nexport default function SessionWindowRestore() {\n const { openWindows, openEntity, openPage } = useWindowManager();\n const { prefs, save } = useShellPrefs();\n const restoredRef = useRef(false);\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 if (prefs.restore_windows === false) return;\n if (openWindows.length > 0) return;\n const saved: SessionWindowRef[] = Array.isArray(prefs.session_windows) ? prefs.session_windows : [];\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) openEntity(w.entityType, w.entityId, undefined, w.label, w.route);\n }\n // The restore itself changes openWindows, which the persist effect below\n // will re-save — same refs, harmless, and it confirms the round-trip.\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 saveTimer.current = setTimeout(() => save({ session_windows: refs }), SAVE_DEBOUNCE_MS);\n return () => clearTimeout(saveTimer.current);\n }, [openWindows, save]);\n\n return null;\n}\n","/**\n * The open-submenu path of a hover menu — the whole state machine <StartMenu>\n * uses to decide which flyouts are open, at any depth.\n *\n * ## Why this exists\n *\n * The menu used to have TWO mechanisms: one that opened a section's flyout\n * (`hoveredSection` + its timer) and a second, separately written one that\n * opened a flyout under an item inside that flyout (`hoveredChild` + its own\n * timer). They looked alike but behaved differently, and the second one had\n * the bugs — a stale close-timer from a sibling row could fire *after* a\n * submenu had opened and shut it under the cursor, which is what \"the next\n * level is slow, or sometimes doesn't open at all\" actually was. There was\n * also no third mechanism, so a 4th level simply never rendered.\n *\n * One path, one set of rules, any depth. Panels are numbered from the root\n * menu: panel 0 is the menu itself, and `path[i]` is the row that opened panel\n * `i + 1`. So `path.length` is the number of open flyouts, and closing\n * everything under panel `d` is just truncating the path to `d`.\n *\n * All of it is pure: hover geometry comes in as numbers, so the rules can be\n * tested without a DOM.\n */\n\n/** One open flyout: which row opened it, and where it goes. */\nexport interface MenuAnchor {\n /** Identity of the row that opened this panel — a section label or an item\n * route. Also what marks that row as the open one. */\n key: string;\n /** Viewport Y of the opening row's centre; the panel is centred on it. */\n y: number;\n /** Viewport X of the panel's left edge. Resolved when the row is hovered,\n * because it depends on where the panel that owns the row ended up. */\n left: number;\n /** Whether this panel had to open to the LEFT of the one that owns its row.\n * Carried so the next level down can keep going the same way. */\n flipped: boolean;\n}\n\n/**\n * Open `anchor` as the submenu of a row in panel `depth`, closing anything\n * deeper (the previous branch the user was down).\n *\n * Returns the SAME array when that panel is already open for that key and\n * nothing deeper is open, so a repeated `mouseenter` on a row the user is\n * already on can't re-render the menu — and can't reset the panel's open\n * animation.\n */\nexport function openMenuLevel(path: MenuAnchor[], depth: number, anchor: MenuAnchor): MenuAnchor[] {\n if (path.length === depth + 1 && path[depth].key === anchor.key) return path;\n return [...path.slice(0, depth), anchor];\n}\n\n/**\n * Close panel `depth + 1` and everything under it — what hovering a row with\n * no submenu, or leaving a panel, eventually leads to.\n *\n * Also identity-stable: nothing to close means the same array back.\n */\nexport function closeMenuBelow(path: MenuAnchor[], depth: number): MenuAnchor[] {\n const keep = Math.max(0, depth);\n return path.length > keep ? path.slice(0, keep) : path;\n}\n\n/**\n * The items each open panel shows: `[0]` is the flyout the root row opened,\n * `[1]` its child, and so on for as long as the path keeps resolving.\n *\n * Stops early rather than rendering an empty panel, so a path left over from a\n * branch that has since disappeared (a permission change, nav data swapped\n * under the menu) degrades to the levels that still exist.\n */\nexport function resolveMenuLevels<T extends { to: string }>(\n rootItems: T[],\n path: MenuAnchor[],\n childrenOf: (item: T) => T[],\n): T[][] {\n if (path.length === 0 || rootItems.length === 0) return [];\n const levels: T[][] = [rootItems];\n for (let i = 1; i < path.length; i++) {\n const parent = levels[i - 1].find(item => item.to === path[i].key);\n const kids = parent ? childrenOf(parent) : [];\n if (kids.length === 0) break;\n levels.push(kids);\n }\n return levels;\n}\n\n/**\n * Where a panel of height `height` sits when centred on `anchorY`, kept inside\n * the usable vertical span (`minTop`..`maxBottom` — the viewport minus the\n * taskbar edge and a gutter).\n *\n * A panel taller than the span is pinned to the top of it and scrolls; that is\n * why the height is clamped before it is centred, and not after.\n */\nexport function clampMenuTop(anchorY: number, height: number, minTop: number, maxBottom: number): number {\n const span = Math.max(0, maxBottom - minTop);\n const h = Math.min(height, span);\n const top = anchorY - h / 2;\n if (top < minTop) return minTop;\n if (top + h > maxBottom) return Math.max(minTop, maxBottom - h);\n return top;\n}\n\n/**\n * Where a panel of width `width` sits horizontally: to the right of the panel\n * that owns the hovered row, or flipped to its left when there isn't room.\n *\n * The flip is what makes depth open-ended. Every level costs another panel\n * width, so a deep enough branch always runs out of screen — and a menu opened\n * from a right-hand taskbar runs out on the very first one.\n *\n * `preferLeft` keeps a branch that has already turned around going the same\n * way. Without it the levels ping-pong: one flips left over its grandparent,\n * the next finds room on the right again and lands back on top of its\n * grandparent, and the chain folds into two stacks of panels.\n */\nexport function menuPanelLeft(\n ownerLeft: number,\n ownerRight: number,\n width: number,\n viewportW: number,\n gap: number,\n preferLeft = false,\n margin = 8,\n): { left: number; flipped: boolean } {\n const onRight = ownerRight + gap;\n const onLeft = ownerLeft - gap - width;\n const rightFits = onRight + width <= viewportW - margin;\n const leftFits = onLeft >= margin;\n if (preferLeft && leftFits) return { left: onLeft, flipped: true };\n if (rightFits) return { left: onRight, flipped: false };\n if (leftFits) return { left: onLeft, flipped: true };\n // Neither side fits: hug the edge the panel was heading for rather than\n // hang off the screen.\n return preferLeft\n ? { left: margin, flipped: true }\n : { left: Math.max(margin, viewportW - margin - width), flipped: false };\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\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\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 {/* Flat list */}\n <div className=\"flex-1 overflow-y-auto\">\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={() => handleClick(item.to)}\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 <div className=\"text-sm font-medium text-gray-900 truncate\">{item.label}</div>\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 const topItems = navSections.filter(item => !isSection(item)) as NavItem[];\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' });\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' });\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 flex items-center gap-2 rounded-lg ${sizeConfig.px} ${sizeConfig.py} ${sizeConfig.text}`;\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 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 className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {secIcon(section.label)}\n <span className={isErp ? 'font-medium' : ''}>{section.label}</span>\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 className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {v.icon}\n <span>{v.label}</span>\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(); handleClick(searchResults[searchIdx].to); }\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 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={() => handleClick(r.to)}\n onMouseEnter={() => setSearchIdx(i)}\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 <span>{r.label}</span>\n {r.section && <span className=\"text-[10px] text-gray-400 ml-auto\">{r.section}</span>}\n </button>\n ))}\n </div>\n ) : (\n <div className=\"flex-1 overflow-y-auto 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={() => handleClick(item.to)}\n onMouseEnter={() => scheduleClose(0)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n onMouseEnter={() => scheduleClose(0)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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 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) : () => handleClick(item.to)}\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 <span>{item.label}</span>\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';\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 /** 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 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 <img src={productIcon} alt=\"\" className=\"h-full w-full object-contain p-3\" />\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 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';\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 /** 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}\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)} &middot; {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)} &middot; {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}: 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 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} />}\n {showLogout && <LogoutAnimation onComplete={() => { sessionStorage.removeItem('erp_startup_shown'); logout(); }} logo={brandIcon} subtitle={brandTagline} />}\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 />\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 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 && <img src={brandIcon} alt=\"\" className=\"relative z-10 h-3.5 w-3.5 shrink-0 opacity-60\" />}\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, null, result.label)}\n />\n <ShortcutHelp />\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\">&times;</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 colour stripe\n <span className=\"block text-xs text-gray-400\">\n Draws a thin coloured line between a window's title bar and its content,\n one colour 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 <input type=\"checkbox\" checked={prefs.show_desktop_version ?? true} 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 checked={prefs.show_desktop_version ?? true}\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","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport apiClient from '../api/client';\nimport type { ColumnDef } from './types';\n\ninterface ColumnState {\n key: string;\n width: number;\n hidden?: boolean;\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 * Resizable + reorderable + hideable column state for `<ResizableTable>`.\n *\n * Persists per-user via `PATCH /auth/me/` (`preferences.columns_{tableId}`)\n * with a 1-second debounce, and per-viewport admin defaults via\n * `GET /auth/default-columns/{tableId}?viewport=…`. The consumer wires these\n * endpoints on its backend; the shell's `apiClient` proxy resolves to the\n * consumer-registered axios instance (`setShellApiClient`).\n */\nexport function useColumnConfig(tableId: string, defaultColumns: ColumnDef[]) {\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 ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150 })),\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 const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const saveMut = useMutation({\n mutationFn: (cols: ColumnState[]) =>\n apiClient.patch('/auth/me/', {\n preferences: { [`columns_${tableId}`]: cols },\n }),\n });\n\n const persistColumns = useCallback((cols: ColumnState[]) => {\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(cols));\n if (saveTimer.current) clearTimeout(saveTimer.current);\n saveTimer.current = setTimeout(() => saveMut.mutate(cols), 1000);\n }, [tableId, saveMut]);\n\n useEffect(() => {\n // Pick the viewport once at mount, using the same query as `useIsMobile`\n // so the column-defaults split lines up with the rest of the UI's mobile\n // affordances. Refresh covers users who resize past the breakpoint\n // mid-session.\n const viewport: 'desktop' | 'mobile' =\n typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile' : 'desktop';\n\n Promise.all([\n apiClient.get('/auth/me/').catch(() => null),\n apiClient.get(`/auth/default-columns/${tableId}/`, { params: { viewport } }).catch(() => null),\n ]).then(([userRes, defaultRes]) => {\n const prefs = userRes?.data?.preferences;\n const userSaved = prefs?.[`columns_${tableId}`];\n\n if (userSaved && Array.isArray(userSaved)) {\n const existing = new Set(userSaved.map((c: any) => c.key));\n const merged = pinSelectColumn([\n ...userSaved.filter((c: any) => defaultColumns.some(d => d.key === c.key)),\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n setColumns(merged);\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(merged));\n } else if (Array.isArray(defaultRes?.data?.visible_columns) && defaultRes.data.visible_columns.length > 0) {\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 const visibleSet = new Set(defaultRes.data.visible_columns as string[]);\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(systemCols);\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(systemCols));\n }\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId]);\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 const defaults = defaultColumns.map(d => ({ key: d.key, width: d.defaultWidth || 150 }));\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 const totalWidth = orderedColumns.reduce((sum, col) => sum + col.width, 0);\n const colWidths = orderedColumns.map(col => `${(col.width / totalWidth) * 100}%`);\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 */}\n <table className=\"w-full divide-y divide-gray-200 shrink-0\" style={{ tableLayout: 'fixed' }}>\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\n {/* Scrollable body */}\n <div className=\"flex-1 overflow-y-auto overflow-x-auto min-h-0\">\n <table className=\"w-full divide-y divide-gray-200\" style={{ tableLayout: 'fixed' }}>\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 { 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 { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\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 onRetry?: () => void;\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 bulk-action menu. Provide `exportEndpoint` (a list's\n * `<base>/export_csv/` path, relative to the api base) to get a built-in\n * \"Export selected to CSV\" that downloads just the ticked rows (`?ids=`,\n * honouring the visible/ordered columns). Provide `contextActions` for\n * domain actions (e.g. invoice Post / Cancel). When neither is set the list\n * has no context menu — unchanged behaviour. \"Clear selection\" is always\n * offered once a menu exists. */\n exportEndpoint?: string;\n exportFilename?: string;\n contextActions?: (items: T[]) => EntityListContextAction<T>[];\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 bulk 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,\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<{ x: number; y: number } | null>(null);\n const hasMenu = !!exportEndpoint || !!contextActions;\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 → bulk menu. If the row isn't already selected it becomes\n // the selection (standard desktop behaviour); an existing multi-selection is\n // kept. Only fires when the list opted into a menu.\n const handleRowContextMenu = (e: MouseEvent, item: T) => {\n if (!hasMenu) return;\n e.preventDefault();\n const id = getRowId(item);\n if (!selected.has(id)) setSelected(new Set([id]));\n setMenu({ x: e.clientX, y: e.clientY });\n };\n\n const selectedItems = items.filter(i => selected.has(getRowId(i)));\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 if (isError && items.length === 0) return <ListLoadError onRetry={onRetry} />;\n if (items.length === 0) return <>{emptyState}</>;\n\n const allSelected = items.length > 0 && selected.size === items.length;\n\n const fullColumns: EntityListColumn[] = [\n {\n key: '_select',\n label: '',\n defaultWidth: 52,\n minWidth: 52,\n headerNode: (\n <input\n type=\"checkbox\"\n checked={allSelected}\n onChange={toggleAll}\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\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 const actions = menu && contextActions ? contextActions(selectedItems) : [];\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 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={hasMenu ? (e) => handleRowContextMenu(e, item) : undefined}\n onMouseEnter={onRowHover ? () => onRowHover(item) : undefined}\n >\n {cols.map(col => (\n <td key={col.key} className=\"px-4 py-3 whitespace-nowrap text-sm overflow-hidden\">\n {col.key === '_select' ? (\n <input\n type=\"checkbox\"\n checked={selected.has(id)}\n onClick={e => { e.stopPropagation(); toggleItem(item); }}\n readOnly\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\n />\n ) : renderCell(item, col.key)}\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n )}\n </ResizableTable>\n </div>\n\n {menu && (\n <PopupMenu portal style={{ left: menu.x, top: menu.y }} onClose={() => setMenu(null)} minWidth={210}>\n <PopupMenuLabel>{selected.size} selected</PopupMenuLabel>\n {exportEndpoint && (\n <PopupMenuItem onClick={exportSelected}>Export selected to CSV</PopupMenuItem>\n )}\n {actions.map((a, i) => (\n <div key={i}>\n {a.divider && <PopupMenuDivider />}\n <PopupMenuItem\n danger={a.danger}\n disabled={a.disabled}\n onClick={() => { setMenu(null); a.onClick(selectedItems); }}\n >\n {a.label}\n </PopupMenuItem>\n </div>\n ))}\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setMenu(null); setSelected(new Set()); }}>Clear selection</PopupMenuItem>\n </PopupMenu>\n )}\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 apiClient, { isShellApiClientConfigured } from '../api/client';\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/**\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 */\nexport function useSort(defaultField: string, defaultDir: 'asc' | 'desc' = 'asc', tableId?: string) {\n const { prefs, save } = useShellPrefs();\n const prefKey = tableId ? `sort_${tableId}` : null;\n\n const [sort, 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 useEffect(() => {\n if (!tableId || !isShellApiClientConfigured()) return;\n // Same viewport heuristic as useColumnConfig, so the sort default rides\n // the same per-viewport row the column defaults live on.\n const viewport: 'desktop' | 'mobile' =\n typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile' : 'desktop';\n apiClient.get(`/auth/default-columns/${tableId}/`, { params: { viewport } })\n .then(res => {\n const dflt = res?.data?.sort;\n if (touchedRef.current || isValidSort(savedRef.current) || !isValidSort(dflt)) return;\n setSort(dflt);\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(dflt)); } catch { /* ignore */ }\n })\n .catch(() => { /* no admin default — keep the page default */ });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId]);\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, useRef, useCallback } from 'react';\nimport EditableGrid, { withSpareRow } from './EditableGrid';\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 fileRef = useRef<HTMLInputElement>(null);\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 handleCSV = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\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 if (fileRef.current) fileRef.current.value = '';\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 className=\"border border-gray-200 rounded-lg bg-gray-50 mb-3 overflow-hidden\">\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 ref={fileRef} type=\"file\" accept=\".csv,.tsv,.txt\" onChange={handleCSV} className=\"hidden\" />\n <button type=\"button\" onClick={() => fileRef.current?.click()}\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 {error && <p className=\"text-xs text-red-600 px-4 py-1\">{error}</p>}\n </div>\n );\n}\n","import { CMD_Z, CMD_SHIFT_Z } from './Kbd';\nimport { useUndo } from './UndoProvider';\n\nexport interface UndoControlsProps {\n /** Extra classes for the wrapping row. */\n className?: string;\n}\n\n/** Quiet by design — these sit beside the real actions and matter only in the\n * moment after something went wrong. */\nconst BTN =\n 'text-xs text-gray-500 hover:text-gray-700 disabled:opacity-40 disabled:hover:text-gray-500 disabled:cursor-default';\n\n/**\n * Undo/Redo for the enclosing form, reading the stack from {@link UndoProvider}.\n *\n * Put it wherever the form's actions live — a window header, a section header,\n * beside the save button. The keys work without it; this is for discoverability\n * and for the mouse. Both buttons stay rendered and go disabled, so the row\n * does not reflow the moment there is something to undo.\n *\n * Renders nothing for a user who may not edit the record — dead buttons on a\n * read-only form read as something broken rather than something withheld.\n */\nexport default function UndoControls({ className = '' }: UndoControlsProps) {\n const { undo, redo, canUndo, canRedo, undoLabel, redoLabel, enabled } = useUndo();\n\n if (!enabled) return null;\n\n return (\n <div className={`flex items-center gap-2 ${className}`}>\n <button\n type=\"button\"\n onClick={undo}\n disabled={!canUndo}\n title={canUndo ? `Undo ${undoLabel} (${CMD_Z})` : 'Nothing to undo'}\n className={BTN}\n >\n Undo\n </button>\n <button\n type=\"button\"\n onClick={redo}\n disabled={!canRedo}\n title={canRedo ? `Redo ${redoLabel} (${CMD_SHIFT_Z})` : 'Nothing to redo'}\n className={BTN}\n >\n Redo\n </button>\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';\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.\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 return () => {\n window.removeEventListener('mousedown', onDown);\n window.removeEventListener('keydown', onKey);\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: 10_000 }}\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","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 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 /** Optional leading icon override for the button (defaults to a document glyph). */\n icon?: ReactNode;\n}\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) are lifted to the optional `onEmail` /\n * `onPreviewOpened` callbacks.\n */\nexport default function PdfActionButton({\n fetchPdf,\n filename,\n label = 'PDF',\n className,\n disabled,\n onEmail,\n onPreviewOpened,\n icon,\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> => {\n setLoading(true);\n try {\n return await fetchPdf();\n } finally {\n setLoading(false);\n }\n };\n\n const handleDownload = async () => {\n setOpen(false);\n const blob = await resolvePdf();\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 openPage('/preview');\n const blob = await resolvePdf();\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 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/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/menuPath.ts","../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/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/UndoControls.tsx","../src/shell/ServerStatusIndicator.tsx","../src/shell/ChangePasswordForm.tsx","../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","jsxs","jsx","Fragment","fps","useRef","useCallback","useQueryClient","e","dx","dy","move","useLayoutEffect","navSections","navIcons","sectionIcons","isValidElement","cloneElement","visibleChildren","useSyncExternalStore","toISODate","useMemo","group","isCustom","Row","sections","LoadingSpinner","timeAgo","createPortal","createContext","useContext"],"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';\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 return (\n <Dialog open={open} onClose={() => setOpen(false)} className=\"relative z-[9999]\">\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 { 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 <div className=\"overflow-y-auto\" 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 <p className={`text-sm leading-tight ${!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 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\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 cs = typeof document !== 'undefined' ? getComputedStyle(document.documentElement) : null;\n const tbH = parseInt(cs?.getPropertyValue('--taskbar-height') || '0') || 0;\n const tbW = parseInt(cs?.getPropertyValue('--taskbar-width') || '0') || 0;\n const tbPos = (cs?.getPropertyValue('--taskbar-position') || 'bottom').trim();\n const defaultRight = 20 + (tbPos === 'right' ? tbW : 0);\n const defaultBottom = 20 + (tbPos === 'bottom' ? tbH : 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 const showVersion: boolean = prefs.show_desktop_version ?? true;\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 <button\n onClick={(e) => { e.stopPropagation(); setWhatsNewOpen(true); }}\n className={`absolute bottom-3 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 prefs.taskbar_position === 'top' ? 'right-3' :\n prefs.taskbar_position === 'left' ? 'right-3' :\n prefs.taskbar_position === 'right' ? 'left-3' :\n 'right-3 !bottom-16'\n }`}\n >\n {host.productVersion ?? APP_VERSION}\n </button>\n )}\n\n {/* What's New dialog */}\n {whatsNewOpen && (() => {\n const entries = host.productChangelog ?? changelog;\n return (\n <Modal open={true} onClose={() => setWhatsNewOpen(false)} title={shellStrings.about.whatsNew} size=\"md\" bodyScroll={false}>\n <div className=\"space-y-5 max-h-[60vh] overflow-y-auto px-1\">\n {entries.length === 0 ? (\n <p className=\"text-sm text-gray-400 text-center py-6\">{shellStrings.about.noChangelog}</p>\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\">&#8226;</span>\n {change}\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 </Modal>\n );\n })()}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\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' }: { onComplete: () => void; ready?: boolean; productName?: string; subtitle?: string; logo?: string }) {\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 <div className={`relative transition-all duration-700 ease-out ${phase === 'logo' ? 'scale-75 opacity-0' : 'scale-100 opacity-100'}`}>\n <img src={logo} alt=\"\" className=\"h-20 w-20 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 </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';\n\nexport default function LogoutAnimation({ onComplete, subtitle, logo = '/favicon.svg' }: { onComplete: () => void; subtitle?: string; logo?: string }) {\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 <img src={logo} alt=\"\" className=\"h-20 w-20 drop-shadow-[0_0_30px_rgba(124,58,237,0.5)]\" />\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, so mounting with an\n * empty desktop cannot overwrite the saved set it was about to replay.\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.\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 */\nimport { useEffect, useRef } from 'react';\n\nimport { useWindowManager, type MinimizedItem } from './WindowManager';\nimport { useShellPrefs } from './ShellPrefs';\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') {\n refs.push({ type: 'entity', entityType: w.entityType, entityId: w.entityId, label: w.label, route: w.route });\n }\n }\n return refs;\n}\n\nconst SAVE_DEBOUNCE_MS = 800;\n\nexport default function SessionWindowRestore() {\n const { openWindows, openEntity, openPage } = useWindowManager();\n const { prefs, save } = useShellPrefs();\n const restoredRef = useRef(false);\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 if (prefs.restore_windows === false) return;\n if (openWindows.length > 0) return;\n const saved: SessionWindowRef[] = Array.isArray(prefs.session_windows) ? prefs.session_windows : [];\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) openEntity(w.entityType, w.entityId, undefined, w.label, w.route);\n }\n // The restore itself changes openWindows, which the persist effect below\n // will re-save — same refs, harmless, and it confirms the round-trip.\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 saveTimer.current = setTimeout(() => save({ session_windows: refs }), SAVE_DEBOUNCE_MS);\n return () => clearTimeout(saveTimer.current);\n }, [openWindows, save]);\n\n return null;\n}\n","/**\n * The open-submenu path of a hover menu — the whole state machine <StartMenu>\n * uses to decide which flyouts are open, at any depth.\n *\n * ## Why this exists\n *\n * The menu used to have TWO mechanisms: one that opened a section's flyout\n * (`hoveredSection` + its timer) and a second, separately written one that\n * opened a flyout under an item inside that flyout (`hoveredChild` + its own\n * timer). They looked alike but behaved differently, and the second one had\n * the bugs — a stale close-timer from a sibling row could fire *after* a\n * submenu had opened and shut it under the cursor, which is what \"the next\n * level is slow, or sometimes doesn't open at all\" actually was. There was\n * also no third mechanism, so a 4th level simply never rendered.\n *\n * One path, one set of rules, any depth. Panels are numbered from the root\n * menu: panel 0 is the menu itself, and `path[i]` is the row that opened panel\n * `i + 1`. So `path.length` is the number of open flyouts, and closing\n * everything under panel `d` is just truncating the path to `d`.\n *\n * All of it is pure: hover geometry comes in as numbers, so the rules can be\n * tested without a DOM.\n */\n\n/** One open flyout: which row opened it, and where it goes. */\nexport interface MenuAnchor {\n /** Identity of the row that opened this panel — a section label or an item\n * route. Also what marks that row as the open one. */\n key: string;\n /** Viewport Y of the opening row's centre; the panel is centred on it. */\n y: number;\n /** Viewport X of the panel's left edge. Resolved when the row is hovered,\n * because it depends on where the panel that owns the row ended up. */\n left: number;\n /** Whether this panel had to open to the LEFT of the one that owns its row.\n * Carried so the next level down can keep going the same way. */\n flipped: boolean;\n}\n\n/**\n * Open `anchor` as the submenu of a row in panel `depth`, closing anything\n * deeper (the previous branch the user was down).\n *\n * Returns the SAME array when that panel is already open for that key and\n * nothing deeper is open, so a repeated `mouseenter` on a row the user is\n * already on can't re-render the menu — and can't reset the panel's open\n * animation.\n */\nexport function openMenuLevel(path: MenuAnchor[], depth: number, anchor: MenuAnchor): MenuAnchor[] {\n if (path.length === depth + 1 && path[depth].key === anchor.key) return path;\n return [...path.slice(0, depth), anchor];\n}\n\n/**\n * Close panel `depth + 1` and everything under it — what hovering a row with\n * no submenu, or leaving a panel, eventually leads to.\n *\n * Also identity-stable: nothing to close means the same array back.\n */\nexport function closeMenuBelow(path: MenuAnchor[], depth: number): MenuAnchor[] {\n const keep = Math.max(0, depth);\n return path.length > keep ? path.slice(0, keep) : path;\n}\n\n/**\n * The items each open panel shows: `[0]` is the flyout the root row opened,\n * `[1]` its child, and so on for as long as the path keeps resolving.\n *\n * Stops early rather than rendering an empty panel, so a path left over from a\n * branch that has since disappeared (a permission change, nav data swapped\n * under the menu) degrades to the levels that still exist.\n */\nexport function resolveMenuLevels<T extends { to: string }>(\n rootItems: T[],\n path: MenuAnchor[],\n childrenOf: (item: T) => T[],\n): T[][] {\n if (path.length === 0 || rootItems.length === 0) return [];\n const levels: T[][] = [rootItems];\n for (let i = 1; i < path.length; i++) {\n const parent = levels[i - 1].find(item => item.to === path[i].key);\n const kids = parent ? childrenOf(parent) : [];\n if (kids.length === 0) break;\n levels.push(kids);\n }\n return levels;\n}\n\n/**\n * Where a panel of height `height` sits when centred on `anchorY`, kept inside\n * the usable vertical span (`minTop`..`maxBottom` — the viewport minus the\n * taskbar edge and a gutter).\n *\n * A panel taller than the span is pinned to the top of it and scrolls; that is\n * why the height is clamped before it is centred, and not after.\n */\nexport function clampMenuTop(anchorY: number, height: number, minTop: number, maxBottom: number): number {\n const span = Math.max(0, maxBottom - minTop);\n const h = Math.min(height, span);\n const top = anchorY - h / 2;\n if (top < minTop) return minTop;\n if (top + h > maxBottom) return Math.max(minTop, maxBottom - h);\n return top;\n}\n\n/**\n * Where a panel of width `width` sits horizontally: to the right of the panel\n * that owns the hovered row, or flipped to its left when there isn't room.\n *\n * The flip is what makes depth open-ended. Every level costs another panel\n * width, so a deep enough branch always runs out of screen — and a menu opened\n * from a right-hand taskbar runs out on the very first one.\n *\n * `preferLeft` keeps a branch that has already turned around going the same\n * way. Without it the levels ping-pong: one flips left over its grandparent,\n * the next finds room on the right again and lands back on top of its\n * grandparent, and the chain folds into two stacks of panels.\n */\nexport function menuPanelLeft(\n ownerLeft: number,\n ownerRight: number,\n width: number,\n viewportW: number,\n gap: number,\n preferLeft = false,\n margin = 8,\n): { left: number; flipped: boolean } {\n const onRight = ownerRight + gap;\n const onLeft = ownerLeft - gap - width;\n const rightFits = onRight + width <= viewportW - margin;\n const leftFits = onLeft >= margin;\n if (preferLeft && leftFits) return { left: onLeft, flipped: true };\n if (rightFits) return { left: onRight, flipped: false };\n if (leftFits) return { left: onLeft, flipped: true };\n // Neither side fits: hug the edge the panel was heading for rather than\n // hang off the screen.\n return preferLeft\n ? { left: margin, flipped: true }\n : { left: Math.max(margin, viewportW - margin - width), flipped: false };\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\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\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 {/* Flat list */}\n <div className=\"flex-1 overflow-y-auto\">\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={() => handleClick(item.to)}\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 <div className=\"text-sm font-medium text-gray-900 truncate\">{item.label}</div>\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 const topItems = navSections.filter(item => !isSection(item)) as NavItem[];\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' });\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' });\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 flex items-center gap-2 rounded-lg ${sizeConfig.px} ${sizeConfig.py} ${sizeConfig.text}`;\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 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 className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {secIcon(section.label)}\n <span className={isErp ? 'font-medium' : ''}>{section.label}</span>\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 className={`${itemCls} transition-colors ${isHovered ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}`}>\n {v.icon}\n <span>{v.label}</span>\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(); handleClick(searchResults[searchIdx].to); }\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 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={() => handleClick(r.to)}\n onMouseEnter={() => setSearchIdx(i)}\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 <span>{r.label}</span>\n {r.section && <span className=\"text-[10px] text-gray-400 ml-auto\">{r.section}</span>}\n </button>\n ))}\n </div>\n ) : (\n <div className=\"flex-1 overflow-y-auto 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={() => handleClick(item.to)}\n onMouseEnter={() => scheduleClose(0)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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={() => handleClick(item.to)}\n onMouseEnter={() => scheduleClose(0)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}>\n {iconEl(item.to)}\n <span>{item.label}</span>\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 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) : () => handleClick(item.to)}\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 <span>{item.label}</span>\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';\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 /** 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 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 <img src={productIcon} alt=\"\" className=\"h-full w-full object-contain p-3\" />\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 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';\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 /** 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}\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)} &middot; {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)} &middot; {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}: 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 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} />}\n {showLogout && <LogoutAnimation onComplete={() => { sessionStorage.removeItem('erp_startup_shown'); logout(); }} logo={brandIcon} subtitle={brandTagline} />}\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 />\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 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 && <img src={brandIcon} alt=\"\" className=\"relative z-10 h-3.5 w-3.5 shrink-0 opacity-60\" />}\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, null, result.label)}\n />\n <ShortcutHelp />\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\">&times;</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 colour stripe\n <span className=\"block text-xs text-gray-400\">\n Draws a thin coloured line between a window's title bar and its content,\n one colour 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 <input type=\"checkbox\" checked={prefs.show_desktop_version ?? true} 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 checked={prefs.show_desktop_version ?? true}\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","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport apiClient from '../api/client';\nimport type { ColumnDef } from './types';\n\ninterface ColumnState {\n key: string;\n width: number;\n hidden?: boolean;\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 * Resizable + reorderable + hideable column state for `<ResizableTable>`.\n *\n * Persists per-user via `PATCH /auth/me/` (`preferences.columns_{tableId}`)\n * with a 1-second debounce, and per-viewport admin defaults via\n * `GET /auth/default-columns/{tableId}?viewport=…`. The consumer wires these\n * endpoints on its backend; the shell's `apiClient` proxy resolves to the\n * consumer-registered axios instance (`setShellApiClient`).\n */\nexport function useColumnConfig(tableId: string, defaultColumns: ColumnDef[]) {\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 ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150 })),\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 const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const saveMut = useMutation({\n mutationFn: (cols: ColumnState[]) =>\n apiClient.patch('/auth/me/', {\n preferences: { [`columns_${tableId}`]: cols },\n }),\n });\n\n const persistColumns = useCallback((cols: ColumnState[]) => {\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(cols));\n if (saveTimer.current) clearTimeout(saveTimer.current);\n saveTimer.current = setTimeout(() => saveMut.mutate(cols), 1000);\n }, [tableId, saveMut]);\n\n useEffect(() => {\n // Pick the viewport once at mount, using the same query as `useIsMobile`\n // so the column-defaults split lines up with the rest of the UI's mobile\n // affordances. Refresh covers users who resize past the breakpoint\n // mid-session.\n const viewport: 'desktop' | 'mobile' =\n typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile' : 'desktop';\n\n Promise.all([\n apiClient.get('/auth/me/').catch(() => null),\n apiClient.get(`/auth/default-columns/${tableId}/`, { params: { viewport } }).catch(() => null),\n ]).then(([userRes, defaultRes]) => {\n const prefs = userRes?.data?.preferences;\n const userSaved = prefs?.[`columns_${tableId}`];\n\n if (userSaved && Array.isArray(userSaved)) {\n const existing = new Set(userSaved.map((c: any) => c.key));\n const merged = pinSelectColumn([\n ...userSaved.filter((c: any) => defaultColumns.some(d => d.key === c.key)),\n ...defaultColumns.filter(d => !existing.has(d.key)).map(d => ({ key: d.key, width: d.defaultWidth || 150, hidden: d.defaultHidden })),\n ]);\n setColumns(merged);\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(merged));\n } else if (Array.isArray(defaultRes?.data?.visible_columns) && defaultRes.data.visible_columns.length > 0) {\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 const visibleSet = new Set(defaultRes.data.visible_columns as string[]);\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(systemCols);\n localStorage.setItem(`col-config-${tableId}`, JSON.stringify(systemCols));\n }\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId]);\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 const defaults = defaultColumns.map(d => ({ key: d.key, width: d.defaultWidth || 150 }));\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 const totalWidth = orderedColumns.reduce((sum, col) => sum + col.width, 0);\n const colWidths = orderedColumns.map(col => `${(col.width / totalWidth) * 100}%`);\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 */}\n <table className=\"w-full divide-y divide-gray-200 shrink-0\" style={{ tableLayout: 'fixed' }}>\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\n {/* Scrollable body */}\n <div className=\"flex-1 overflow-y-auto overflow-x-auto min-h-0\">\n <table className=\"w-full divide-y divide-gray-200\" style={{ tableLayout: 'fixed' }}>\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 { 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 { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\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 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 bulk-action menu. Provide `exportEndpoint` (a list's\n * `<base>/export_csv/` path, relative to the api base) to get a built-in\n * \"Export selected to CSV\" that downloads just the ticked rows (`?ids=`,\n * honouring the visible/ordered columns). Provide `contextActions` for\n * domain actions (e.g. invoice Post / Cancel). When neither is set the list\n * has no context menu — unchanged behaviour. \"Clear selection\" is always\n * offered once a menu exists. */\n exportEndpoint?: string;\n exportFilename?: string;\n contextActions?: (items: T[]) => EntityListContextAction<T>[];\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 bulk 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<{ x: number; y: number } | null>(null);\n const hasMenu = !!exportEndpoint || !!contextActions;\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 → bulk menu. If the row isn't already selected it becomes\n // the selection (standard desktop behaviour); an existing multi-selection is\n // kept. Only fires when the list opted into a menu.\n const handleRowContextMenu = (e: MouseEvent, item: T) => {\n if (!hasMenu) return;\n e.preventDefault();\n const id = getRowId(item);\n if (!selected.has(id)) setSelected(new Set([id]));\n setMenu({ x: e.clientX, y: e.clientY });\n };\n\n const selectedItems = items.filter(i => selected.has(getRowId(i)));\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\n const fullColumns: EntityListColumn[] = [\n {\n key: '_select',\n label: '',\n defaultWidth: 52,\n minWidth: 52,\n headerNode: (\n <input\n type=\"checkbox\"\n checked={allSelected}\n onChange={toggleAll}\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\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 const actions = menu && contextActions ? contextActions(selectedItems) : [];\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 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={hasMenu ? (e) => handleRowContextMenu(e, item) : undefined}\n onMouseEnter={onRowHover ? () => onRowHover(item) : undefined}\n >\n {cols.map(col => (\n <td key={col.key} className=\"px-4 py-3 whitespace-nowrap text-sm overflow-hidden\">\n {col.key === '_select' ? (\n <input\n type=\"checkbox\"\n checked={selected.has(id)}\n onClick={e => { e.stopPropagation(); toggleItem(item); }}\n readOnly\n className=\"h-3.5 w-3.5 rounded border-gray-300 text-blue-600\"\n />\n ) : renderCell(item, col.key)}\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n )}\n </ResizableTable>\n </div>\n\n {menu && (\n <PopupMenu portal style={{ left: menu.x, top: menu.y }} onClose={() => setMenu(null)} minWidth={210}>\n <PopupMenuLabel>{selected.size} selected</PopupMenuLabel>\n {exportEndpoint && (\n <PopupMenuItem onClick={exportSelected}>Export selected to CSV</PopupMenuItem>\n )}\n {actions.map((a, i) => (\n <div key={i}>\n {a.divider && <PopupMenuDivider />}\n <PopupMenuItem\n danger={a.danger}\n disabled={a.disabled}\n onClick={() => { setMenu(null); a.onClick(selectedItems); }}\n >\n {a.label}\n </PopupMenuItem>\n </div>\n ))}\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setMenu(null); setSelected(new Set()); }}>Clear selection</PopupMenuItem>\n </PopupMenu>\n )}\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 apiClient, { isShellApiClientConfigured } from '../api/client';\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/**\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 */\nexport function useSort(defaultField: string, defaultDir: 'asc' | 'desc' = 'asc', tableId?: string) {\n const { prefs, save } = useShellPrefs();\n const prefKey = tableId ? `sort_${tableId}` : null;\n\n const [sort, 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 useEffect(() => {\n if (!tableId || !isShellApiClientConfigured()) return;\n // Same viewport heuristic as useColumnConfig, so the sort default rides\n // the same per-viewport row the column defaults live on.\n const viewport: 'desktop' | 'mobile' =\n typeof window !== 'undefined' &&\n window.matchMedia('(max-width: 767px), (pointer: coarse)').matches\n ? 'mobile' : 'desktop';\n apiClient.get(`/auth/default-columns/${tableId}/`, { params: { viewport } })\n .then(res => {\n const dflt = res?.data?.sort;\n if (touchedRef.current || isValidSort(savedRef.current) || !isValidSort(dflt)) return;\n setSort(dflt);\n try { localStorage.setItem(`sort-config-${tableId}`, JSON.stringify(dflt)); } catch { /* ignore */ }\n })\n .catch(() => { /* no admin default — keep the page default */ });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tableId]);\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, useRef, useCallback } from 'react';\nimport EditableGrid, { withSpareRow } from './EditableGrid';\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 fileRef = useRef<HTMLInputElement>(null);\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 handleCSV = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\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 if (fileRef.current) fileRef.current.value = '';\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 className=\"border border-gray-200 rounded-lg bg-gray-50 mb-3 overflow-hidden\">\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 ref={fileRef} type=\"file\" accept=\".csv,.tsv,.txt\" onChange={handleCSV} className=\"hidden\" />\n <button type=\"button\" onClick={() => fileRef.current?.click()}\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 {error && <p className=\"text-xs text-red-600 px-4 py-1\">{error}</p>}\n </div>\n );\n}\n","import { CMD_Z, CMD_SHIFT_Z } from './Kbd';\nimport { useUndo } from './UndoProvider';\n\nexport interface UndoControlsProps {\n /** Extra classes for the wrapping row. */\n className?: string;\n}\n\n/** Quiet by design — these sit beside the real actions and matter only in the\n * moment after something went wrong. */\nconst BTN =\n 'text-xs text-gray-500 hover:text-gray-700 disabled:opacity-40 disabled:hover:text-gray-500 disabled:cursor-default';\n\n/**\n * Undo/Redo for the enclosing form, reading the stack from {@link UndoProvider}.\n *\n * Put it wherever the form's actions live — a window header, a section header,\n * beside the save button. The keys work without it; this is for discoverability\n * and for the mouse. Both buttons stay rendered and go disabled, so the row\n * does not reflow the moment there is something to undo.\n *\n * Renders nothing for a user who may not edit the record — dead buttons on a\n * read-only form read as something broken rather than something withheld.\n */\nexport default function UndoControls({ className = '' }: UndoControlsProps) {\n const { undo, redo, canUndo, canRedo, undoLabel, redoLabel, enabled } = useUndo();\n\n if (!enabled) return null;\n\n return (\n <div className={`flex items-center gap-2 ${className}`}>\n <button\n type=\"button\"\n onClick={undo}\n disabled={!canUndo}\n title={canUndo ? `Undo ${undoLabel} (${CMD_Z})` : 'Nothing to undo'}\n className={BTN}\n >\n Undo\n </button>\n <button\n type=\"button\"\n onClick={redo}\n disabled={!canRedo}\n title={canRedo ? `Redo ${redoLabel} (${CMD_SHIFT_Z})` : 'Nothing to redo'}\n className={BTN}\n >\n Redo\n </button>\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';\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.\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 return () => {\n window.removeEventListener('mousedown', onDown);\n window.removeEventListener('keydown', onKey);\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: 10_000 }}\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","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 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 /** Optional leading icon override for the button (defaults to a document glyph). */\n icon?: ReactNode;\n}\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) are lifted to the optional `onEmail` /\n * `onPreviewOpened` callbacks.\n */\nexport default function PdfActionButton({\n fetchPdf,\n filename,\n label = 'PDF',\n className,\n disabled,\n onEmail,\n onPreviewOpened,\n icon,\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> => {\n setLoading(true);\n try {\n return await fetchPdf();\n } finally {\n setLoading(false);\n }\n };\n\n const handleDownload = async () => {\n setOpen(false);\n const blob = await resolvePdf();\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 openPage('/preview');\n const blob = await resolvePdf();\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 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"]}