react-os-shell 3.28.1 → 3.28.3
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/{Browser-AR4QP23G.js → Browser-OE4RRSNX.js} +5 -5
- package/dist/{Browser-AR4QP23G.js.map → Browser-OE4RRSNX.js.map} +1 -1
- package/dist/{Calculator-7MRLC77Q.js → Calculator-BJGIBI4Y.js} +4 -4
- package/dist/{Calculator-7MRLC77Q.js.map → Calculator-BJGIBI4Y.js.map} +1 -1
- package/dist/ConfirmDialog-LPE2X6OJ.js +4 -0
- package/dist/{ConfirmDialog-2BV43KSW.js.map → ConfirmDialog-LPE2X6OJ.js.map} +1 -1
- package/dist/{CurrencyConverter-6UTL2ZBY.js → CurrencyConverter-CHTBKF6J.js} +4 -4
- package/dist/{CurrencyConverter-6UTL2ZBY.js.map → CurrencyConverter-CHTBKF6J.js.map} +1 -1
- package/dist/{Documents-FQKIQ4GH.js → Documents-D6Q75QR7.js} +5 -5
- package/dist/{Documents-FQKIQ4GH.js.map → Documents-D6Q75QR7.js.map} +1 -1
- package/dist/{Files-NTUFLWY3.js → Files-ROREKNZQ.js} +5 -5
- package/dist/{Files-NTUFLWY3.js.map → Files-ROREKNZQ.js.map} +1 -1
- package/dist/{Notepad-MQQSDSLT.js → Notepad-5P66KO2D.js} +5 -5
- package/dist/{Notepad-MQQSDSLT.js.map → Notepad-5P66KO2D.js.map} +1 -1
- package/dist/{PomodoroTimer-YI4D7OLV.js → PomodoroTimer-NLIPU5UR.js} +5 -5
- package/dist/{PomodoroTimer-YI4D7OLV.js.map → PomodoroTimer-NLIPU5UR.js.map} +1 -1
- package/dist/{Preview-2GUM6NO7.js → Preview-7F27UNJW.js} +5 -5
- package/dist/{Preview-2GUM6NO7.js.map → Preview-7F27UNJW.js.map} +1 -1
- package/dist/{Spreadsheet-6JWSE5NC.js → Spreadsheet-NKJBGBWK.js} +5 -5
- package/dist/{Spreadsheet-6JWSE5NC.js.map → Spreadsheet-NKJBGBWK.js.map} +1 -1
- package/dist/{Stock-KQA6QWZ2.js → Stock-Q5TKAAYK.js} +4 -4
- package/dist/{Stock-KQA6QWZ2.js.map → Stock-Q5TKAAYK.js.map} +1 -1
- package/dist/{Weather-45REOKUY.js → Weather-ZZBMC3TS.js} +4 -4
- package/dist/{Weather-45REOKUY.js.map → Weather-ZZBMC3TS.js.map} +1 -1
- package/dist/{WorldClock-EJNEFDWZ.js → WorldClock-ILLIOFRX.js} +4 -4
- package/dist/{WorldClock-EJNEFDWZ.js.map → WorldClock-ILLIOFRX.js.map} +1 -1
- package/dist/apps/index.js +15 -15
- package/dist/{chunk-IU7MSBRI.js → chunk-6LMWM4ZE.js} +34 -7
- package/dist/chunk-6LMWM4ZE.js.map +1 -0
- package/dist/{chunk-EWRKU7EF.js → chunk-7GNI7HRH.js} +3 -3
- package/dist/{chunk-EWRKU7EF.js.map → chunk-7GNI7HRH.js.map} +1 -1
- package/dist/{chunk-WWT4XQJL.js → chunk-AKPD4Z34.js} +3 -3
- package/dist/{chunk-WWT4XQJL.js.map → chunk-AKPD4Z34.js.map} +1 -1
- package/dist/chunk-KFJA5CYZ.js +7 -0
- package/dist/{chunk-CZW7CTI6.js.map → chunk-KFJA5CYZ.js.map} +1 -1
- package/dist/{chunk-GHGD4GKR.js → chunk-WCV2646Z.js} +4 -4
- package/dist/{chunk-GHGD4GKR.js.map → chunk-WCV2646Z.js.map} +1 -1
- package/dist/index.js +14 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/ConfirmDialog-2BV43KSW.js +0 -4
- package/dist/chunk-CZW7CTI6.js +0 -7
- package/dist/chunk-IU7MSBRI.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api/client.ts","../src/shell/entityFetchPolicy.ts","../src/windowRegistry/types.ts","../src/shell/WindowErrorBoundary.tsx","../src/shell/LoadingSpinner.tsx","../src/shell/WindowManager.tsx","../src/shell/PopupMenu.tsx","../src/shell/useIsMobile.ts","../src/shell/mobileSwipeStore.ts","../src/shell/ShellPrefs.tsx","../src/shell/workArea.ts","../src/shell/Modal.tsx","../src/shell/ConfirmDialog.tsx"],"names":["jsx","Component","jsxs","id","useRef","useEffect","createPortal","useSyncExternalStore","createContext","useState","useCallback","useContext","workArea","isValidElement","confirm","a","useLayoutEffect","cloneElement","content","Fragment","XMarkIcon"],"mappings":"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","file":"chunk-6LMWM4ZE.js","sourcesContent":["/**\n * INTERNAL stub — bridges legacy `apiClient.get/patch('/auth/me/', ...)` calls\n * inside the shell to the new <ShellPrefsProvider> contract. This keeps the\n * package's copied source compiling without rewriting every call site at\n * once; consumer-supplied prefs flow through `<ShellPrefsProvider>`.\n *\n * Outside calls (anything not hitting `/auth/me/`) need the consumer to mount\n * <ShellEntityFetcherProvider> and wire `entityFetcher` on <WindowManager>.\n *\n * When `setShellApiClient` has not been called, HTTP methods resolve with an\n * empty payload instead of throwing — so consumers without a backend (the\n * Pages demo, for instance) can still mount the shell. A one-time console\n * warning surfaces the missing wiring without crashing the app.\n *\n * Long-term this file is removed when each call site migrates to\n * `useShellPrefs()` directly.\n */\nimport type { AxiosInstance } from 'axios';\n\nlet _apiClient: AxiosInstance | null = null;\n\n/** Consumer registers their own axios instance — typically the same one\n * they use elsewhere. The package only delegates HTTP to this. */\nexport function setShellApiClient(instance: AxiosInstance) {\n _apiClient = instance;\n}\n\n/** Whether the consumer has wired an api client. Internal shell queries gate\n * themselves on this so demos / consumers without a backend don't fire\n * doomed HTTP requests. */\nexport function isShellApiClientConfigured(): boolean {\n return _apiClient !== null;\n}\n\n// HTTP methods that resolve with empty data when no client is wired. Internal\n// callers gate on `isShellApiClientConfigured()` so this branch shouldn't\n// fire normally; it remains as a safety net for consumer-supplied apps that\n// import the shell's `apiClient` directly without setting one up.\nconst NOOP_METHODS = new Set([\n 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'request',\n]);\n\nconst apiClient: AxiosInstance = new Proxy({} as AxiosInstance, {\n get(_t, prop) {\n if (_apiClient) return (_apiClient as any)[prop];\n if (typeof prop === 'string' && NOOP_METHODS.has(prop)) {\n return () => Promise.resolve({ data: null, status: 0, statusText: '', headers: {}, config: {} });\n }\n return undefined;\n },\n});\n\nexport default apiClient;\n// Re-export the axios type for legacy code that imports it.\nexport type { AxiosInstance };\n","/**\n * Retry / poll policy for a restored entity window's detail fetch.\n *\n * A window restored from the saved session (`RestoredRegistryModal` in\n * `WindowManager`) re-reads its entity on mount, on window focus, and on a 60s\n * fallback interval. That is right for a record that still exists — but it was\n * applied just as eagerly to one that does not. TanStack's default `retry: 3`\n * (1s/2s/4s backoff) on top of the 60s interval kept a permanently-404ing\n * window asking forever, ~4 requests a minute, for as long as the tab stayed\n * open. The window itself looks fine the whole time: it renders from the\n * `entitySnapshot` saved alongside it, so nothing surfaces to the user and\n * nothing ever stops.\n *\n * Production hit exactly that. One saved receipt window whose `entityId` was a\n * document number rather than a uuid produced 2,848 404s on\n * `GET /api/receipts/RP/` from a single browser in 48 hours — continuous,\n * overnight, resuming on every page load because the window list is restored\n * from localStorage.\n *\n * The rule: a 4xx is the server saying *this request is wrong*. Repeating it\n * verbatim cannot change the answer, so stop — do not retry it, and do not\n * keep polling it. Anything else (a 5xx, a timeout, an offline blip) is the\n * server or the network having a bad moment, and is still worth another go.\n */\n\n/** 4xx codes that are nonetheless worth retrying: the server is asking us to\n * wait, not telling us the request is malformed. */\nconst RETRYABLE_CLIENT_STATUSES = new Set([\n 408, // Request Timeout\n 429, // Too Many Requests\n]);\n\n/** Attempts after the first, for errors that are actually worth repeating.\n * Matches TanStack's own default so transient failures behave as before. */\nexport const ENTITY_FETCH_MAX_RETRIES = 3;\n\n/** The fallback poll cadence for a live entity window. WebSocket pushes are\n * the primary update path; this only covers the socket being unavailable. */\nexport const ENTITY_REFETCH_INTERVAL_MS = 60_000;\n\n/**\n * Whether `error` is a client error that repeating cannot fix (4xx, except the\n * explicitly retryable ones).\n *\n * An error with no numeric `response.status` — a network failure, a DNS blip,\n * an aborted request, anything thrown before a reply arrived — is deliberately\n * NOT permanent: those are exactly the cases retrying exists for.\n */\nexport function isPermanentClientError(error: unknown): boolean {\n const status = (error as { response?: { status?: unknown } } | null | undefined)?.response?.status;\n if (typeof status !== 'number') return false;\n return status >= 400 && status < 500 && !RETRYABLE_CLIENT_STATUSES.has(status);\n}\n\n/** `retry` for the entity detail query — never repeats a permanent 4xx. */\nexport function shouldRetryEntityFetch(failureCount: number, error: unknown): boolean {\n return !isPermanentClientError(error) && failureCount < ENTITY_FETCH_MAX_RETRIES;\n}\n\n/** `refetchInterval` for the entity detail query — stops polling a window\n * whose entity the server has told us is not there. */\nexport function entityRefetchInterval(error: unknown): number | false {\n return isPermanentClientError(error) ? false : ENTITY_REFETCH_INTERVAL_MS;\n}\n\n/**\n * Build the detail URL for an entity window.\n *\n * The id is encoded because it is not always the uuid the registry assumes: it\n * comes from saved session state and can be anything a past build (or a future\n * one) put there. An id carrying a `#` — a document number like `RP#60001`,\n * say — otherwise truncates the URL at the fragment before it is ever sent,\n * turning a wrong-but-legible request into a silently different one. Encoding\n * is a no-op for a uuid and keeps a bad id honest: it 404s as itself.\n */\nexport function entityDetailUrl(endpoint: string, entityId: string): string {\n return `${endpoint}${encodeURIComponent(entityId)}/`;\n}\n","/**\n * Window registry types — generic shell concepts (no consumer-specific data).\n *\n * Two kinds of entries can be registered:\n * - PageRegistryEntry: a lazy-loaded React component rendered as a windowed\n * page (Calculator, Notepad, Sales Order list, etc.).\n * - ModalRegistryEntry: a detail-modal definition that fetches an entity\n * from a REST endpoint and hands it to a render function (Sales Order\n * detail, Bug Report detail, etc.).\n *\n * Consumers compose their full registry by passing entries to\n * `createWindowRegistry()` (see ./createWindowRegistry).\n */\nimport type { ReactNode, LazyExoticComponent } from 'react';\n\n/** Page window entry — renders a lazy-loaded page component. */\nexport interface PageRegistryEntry {\n component: LazyExoticComponent<any>;\n label: string;\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';\n allowPinOnTop?: boolean;\n /** Utility apps don't show as taskbar window tabs. */\n utility?: boolean;\n /** Initial position hint. */\n initialPosition?: 'top-right' | 'top-left';\n /** Widget mode: no title bar, drag via body, right-click context menu. */\n widget?: boolean;\n /** Compact title bar: smaller header with title + close only, no footer. */\n compact?: boolean;\n /** App-style window for self-chromed apps (Preview, Files, Browser, etc.):\n * small title bar with full controls, no body padding, no footer. */\n appStyle?: boolean;\n /** Flush body — keeps the STANDARD full title bar and footer, but drops the\n * body padding so the app's content (e.g. a `<SidebarLayout>`) sits flush to\n * the window edges. Implies `bodyScroll: false`; the app manages its own\n * scrolling. Use for two-pane / sidebar apps that want normal window chrome. */\n flushBody?: boolean;\n /** Custom window dimensions [width, height] in pixels. */\n dimensions?: [number, number];\n /** Auto-size window height to its content. Naturally-flowing content (forms,\n * settings, simple tools) shrinks the window to hug it; a fill-height root\n * (`h-full` / `flex-1` between a fixed header and footer) keeps the normal\n * size-ladder height and scrolls internally rather than collapsing. */\n autoHeight?: boolean;\n /** Floor for `autoHeight` (px). Defaults to 240. */\n autoMinHeight?: number;\n /** When true, openPage(path) opens a new instance each time instead of\n * activating an existing one. Each instance gets a unique window id and\n * the taskbar groups them under a single icon. */\n multiInstance?: boolean;\n /** Collapse this window with other windows that share the same\n * `taskbarGroup.key` into ONE taskbar button — even across DIFFERENT routes\n * — showing the group `label` and a window count. Without it, windows group\n * by route only (so only same-route `multiInstance` copies stack). `icon` is\n * a navIcon route key for the grouped button's icon. Use for a family of\n * related windows, e.g. a hub + the editors it opens. */\n taskbarGroup?: { key: string; label: string; icon?: string };\n /** navIcon route key for window title icon (e.g. '/orders'). */\n icon?: string;\n}\n\n/** Entity window entry — renders a detail modal with API data. */\nexport interface ModalRegistryEntry {\n /** API endpoint prefix — entity fetched via GET {endpoint}{id}/. */\n endpoint: string;\n /** How to render the detail content. */\n render: (entity: any, onClose: () => void, entityId?: string, editing?: boolean, setEditing?: (v: boolean) => void) => ReactNode;\n /** Generate modal title from entity data. Editing state passed for Edit button. */\n title: (entity: any, editing?: boolean, setEditing?: (v: boolean) => void) => ReactNode;\n /** Generate modal footer from entity data. */\n footer?: (entity: any) => ReactNode;\n /** Modal size. */\n size?: string;\n /** Custom open dimensions [width, height] in px (clamped to the viewport).\n * Overrides the size ladder and any stale per-window size the shell\n * persisted — use for content-heavy detail windows that must open large. */\n dimensions?: [number, number];\n /** If true, the component fetches its own data — pass ID, not entity. */\n selfFetching?: boolean;\n /** If true, the component renders its own Modal — skip outer Modal wrapper. */\n rendersOwnModal?: boolean;\n /** Query key prefix for React Query — must match what detail components invalidate. */\n queryKey?: string;\n /** Auto-size window height to its content. See PageRegistryEntry.autoHeight. */\n autoHeight?: boolean;\n /** Floor for `autoHeight` (px). Defaults to 240. */\n autoMinHeight?: number;\n /** App-style window: small title bar, no body padding, no footer. */\n appStyle?: boolean;\n /** navIcon route key for window title icon (e.g. '/orders'). */\n icon?: string;\n}\n\nexport type WindowRegistryEntry = PageRegistryEntry | ModalRegistryEntry;\n\nexport type WindowRegistry = Record<string, WindowRegistryEntry>;\n\n/** Type guard: true if entry is a page window (has `component`). */\nexport function isPageEntry(entry: WindowRegistryEntry): entry is PageRegistryEntry {\n return 'component' in entry;\n}\n\n/** Type guard: true if entry is an entity window (has `endpoint`). */\nexport function isEntityEntry(entry: WindowRegistryEntry): entry is ModalRegistryEntry {\n return 'endpoint' in entry;\n}\n\n/** Module-level registry — the package no longer ships entity/page data;\n * consumers register their composed registry once at app startup via\n * setShellWindowRegistry(). The shell's WindowManager reads from here at\n * every openEntity / openPage call. */\nlet _registry: WindowRegistry = {};\n\nexport function setShellWindowRegistry(registry: WindowRegistry): void {\n _registry = registry;\n}\n\n/** Live proxy onto the consumer-registered registry — reads always reflect\n * the latest setShellWindowRegistry() call. */\nexport const WINDOW_REGISTRY: WindowRegistry = new Proxy({} as WindowRegistry, {\n get(_t, prop: string) { return _registry[prop]; },\n has(_t, prop: string) { return prop in _registry; },\n ownKeys() { return Object.keys(_registry); },\n getOwnPropertyDescriptor(_t, prop: string) {\n if (prop in _registry) {\n return { configurable: true, enumerable: true, value: _registry[prop] };\n }\n return undefined;\n },\n});\n","import { Component, type ErrorInfo, type ReactNode } from 'react';\n\n/** Inline crash state rendered in place of a window's content. Centers itself\n * in whatever space the body gives it; `onReload` resets the owning boundary\n * so the content remounts from scratch. */\nexport function WindowCrashedFallback({ error, onReload }: { error: Error; onReload: () => void }) {\n return (\n <div className=\"flex-1 flex flex-col items-center justify-center gap-3 px-6 py-12 text-center\">\n <svg className=\"h-8 w-8 text-amber-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z\" />\n </svg>\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-gray-700\">This window crashed</p>\n <p className=\"mt-1 text-xs text-gray-400 max-w-sm break-words\">{error.message || String(error)}</p>\n </div>\n <button type=\"button\" onClick={onReload}\n className=\"bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 text-sm font-medium rounded-lg\">\n Reload window\n </button>\n </div>\n );\n}\n\ninterface WindowErrorBoundaryProps {\n children: ReactNode;\n /** Replaces the default inline {@link WindowCrashedFallback}. `reset`\n * clears the caught error so the children remount. */\n fallback?: (error: Error, reset: () => void) => ReactNode;\n}\n\n/**\n * Error boundary around a window's content. Without it, a page/entity\n * component that throws during render propagates to the root and unmounts the\n * entire desktop. With it, only the crashed window's body is replaced — the\n * window chrome (close/minimize), the taskbar and every other window keep\n * running. Modal wraps its body in one; WindowManager wraps each whole window\n * in another as a last resort for crashes outside the body (e.g. a registry\n * `title()` throwing on malformed data).\n */\nexport default class WindowErrorBoundary extends Component<WindowErrorBoundaryProps, { error: Error | null }> {\n state: { error: Error | null } = { error: null };\n\n static getDerivedStateFromError(error: unknown) {\n return { error: error instanceof Error ? error : new Error(String(error)) };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('[react-os-shell] window content crashed:', error, info.componentStack);\n }\n\n reset = () => this.setState({ error: null });\n\n render() {\n const { error } = this.state;\n if (error) {\n return this.props.fallback\n ? this.props.fallback(error, this.reset)\n : <WindowCrashedFallback error={error} onReload={this.reset} />;\n }\n return this.props.children;\n }\n}\n","export default function LoadingSpinner() {\n return <div className=\"flex items-center justify-center p-8 text-sm text-gray-400\">Loading...</div>;\n}\n","import { createContext, useContext, useState, useCallback, useEffect, useLayoutEffect, useRef, useSyncExternalStore, cloneElement, isValidElement, Suspense, type ReactNode, type ReactElement } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { createPortal } from 'react-dom';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport apiClient, { isShellApiClientConfigured } from '../api/client';\nimport { entityDetailUrl, entityRefetchInterval, shouldRetryEntityFetch } from './entityFetchPolicy';\nimport { WINDOW_REGISTRY, isPageEntry, isEntityEntry, type PageRegistryEntry, type ModalRegistryEntry } from '../windowRegistry/types';\nimport Modal, { triggerSplitView, modalDepthRef, getActiveModalId, subscribeActive, activateModal, ExposeBackdrop, WindowShortcutProvider, setWindowDefaultPosition, isPanelFullyVisible, panelOffscreenBearing, revealWindow, type WindowShortcutSpec } from './Modal';\nimport WindowErrorBoundary, { WindowCrashedFallback } from './WindowErrorBoundary';\nimport PartNumberDetailPopup from './PartNumberDetailPopup';\nimport LoadingSpinner from './LoadingSpinner';\nimport { navIcons } from '../shell-config/nav';\n\n\ninterface SavedBox {\n x: number; y: number; w: number; h: number; maximized: boolean;\n}\n\nexport interface MinimizedItem {\n id: string;\n type: 'part_number' | 'modal' | 'page';\n label: string;\n /** Route path for icon lookup (e.g. '/orders', '/invoices') */\n route?: string;\n savedBox?: SavedBox;\n /** Entity registry key (e.g. 'order', 'manufacturer') for restore */\n entityType?: string;\n /** Entity UUID for API fetch on cross-page restore */\n entityId?: string;\n /** Cached entity data for instant rendering while refetch happens */\n entitySnapshot?: any;\n /** windowKey of the window that was active when this opened — used by the\n * mobile swipe-to-back gesture to reveal the parent (e.g. the list a\n * detail entity was opened from) instead of the home wallpaper. Undefined\n * when this window opened directly from home / the start menu. */\n openedFrom?: string;\n}\n\ninterface MinimizedContextType {\n openWindows: MinimizedItem[];\n openEntity: (entityType: string, entityId: string, snapshot?: any, label?: string, route?: string) => void;\n openPage: (path: string) => void;\n closeEntity: (id: string) => void;\n /** @deprecated kept for backward compat — aliases openEntity/closeEntity */\n minimize: (item: MinimizedItem) => void;\n items: MinimizedItem[];\n restore: (item: MinimizedItem) => void;\n remove: (id: string) => void;\n restoreIfMinimized: (label: string) => boolean;\n openItems: MinimizedItem[];\n}\n\nconst MinimizedContext = createContext<MinimizedContextType>({\n openWindows: [],\n openEntity: () => {},\n openPage: () => {},\n closeEntity: () => {},\n minimize: () => {},\n items: [],\n restore: () => {},\n remove: () => {},\n restoreIfMinimized: () => false,\n openItems: [],\n});\n\nexport function useWindowManager() {\n return useContext(MinimizedContext);\n}\n\nfunction RestoredPartNumber({ partNumber, savedBox, onClose, onMinimize }: { partNumber: string; savedBox?: SavedBox; onClose: () => void; onMinimize: (sb: SavedBox) => void }) {\n const { data: pn, isLoading } = useQuery({\n queryKey: ['part-number-lookup', partNumber],\n enabled: isShellApiClientConfigured(),\n queryFn: () => apiClient.get('/products/part-numbers/', { params: { search: partNumber, page_size: 1 } }).then(r => {\n const results = r.data?.results ?? r.data ?? [];\n return results.find((p: any) => p.part_number === partNumber) || results[0] || null;\n }),\n });\n\n return (\n <Modal\n open={true}\n onClose={onClose}\n onMinimize={onMinimize}\n initialBox={savedBox}\n size=\"2xl\"\n title={pn ? (\n <span className=\"flex items-center gap-2\">\n {pn.part_number}\n <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${pn.is_active ? 'bg-green-100 text-green-800' : 'bg-gray-300 text-gray-800'}`}>{pn.is_active ? 'Active' : 'Inactive'}</span>\n </span>\n ) : partNumber}\n footer={pn ? (\n <>\n <span className=\"text-gray-500\">{pn.brand_name} · {pn.category_name || 'Wheel'} · {pn.manufacturer_mid || '—'}</span>\n <span className=\"text-gray-400\">Stock: <b className=\"text-gray-700\">{pn.stock_quantity ?? 0}</b></span>\n </>\n ) : undefined}\n >\n {isLoading ? <div className=\"flex items-center justify-center py-12\"><LoadingSpinner /></div> : pn ? <PartNumberDetailPopup pn={pn} /> : <p className=\"text-sm text-gray-500\">Part number not found.</p>}\n </Modal>\n );\n}\n\n/** Window → desktop-shortcut spec for the Modal window menu's \"Add to\n * Desktop\" item. Pages save as entityType 'page' keyed by route; entities\n * by registry key + id. Windows with no stable identity return null and\n * get no menu item. */\nfunction shortcutSpecFor(item: MinimizedItem): WindowShortcutSpec | null {\n const entityType = item.type === 'page' ? 'page' : (item.entityType || '');\n const entityId = item.type === 'page' ? (item.route || '') : (item.entityId || '');\n if (!entityType || !entityId) return null;\n return { entityType, entityId, label: item.label };\n}\n\nfunction PageWindow({ item, onClose, accentRgb }: { item: MinimizedItem; onClose: () => void; accentRgb?: string }) {\n const raw = WINDOW_REGISTRY[item.route!];\n if (!raw || !isPageEntry(raw)) return null;\n const entry = raw as PageRegistryEntry;\n const Component = entry.component;\n return (\n <Modal open={true} onClose={onClose} icon={navIcons[item.route!]} title={entry.label} size={entry.size || '2xl'} allowPinOnTop={entry.allowPinOnTop} initialPosition={entry.initialPosition} widget={entry.widget} compact={entry.compact} appStyle={entry.appStyle} flushBody={entry.flushBody} autoHeight={entry.autoHeight} autoMinHeight={entry.autoMinHeight} dimensions={entry.dimensions} windowKey={item.id} openedFromKey={item.openedFrom} accentRgb={accentRgb}>\n <Suspense fallback={<div className=\"flex items-center justify-center py-12\"><LoadingSpinner /></div>}>\n <Component />\n </Suspense>\n </Modal>\n );\n}\n\n/** Star button to favorite a document — saves to preferences.favorite_documents */\nexport function DocFavStar({ entityType, entityId, label }: { entityType: string; entityId: string; label: string }) {\n const queryClient = useQueryClient();\n const { data: profile } = useQuery({ queryKey: ['my-profile-sidebar'], enabled: isShellApiClientConfigured(), queryFn: () => apiClient.get('/auth/me/').then(r => r.data) });\n const favDocs: { entityType: string; entityId: string; label: string }[] = (profile?.preferences || {}).favorite_documents || [];\n const isFav = favDocs.some(d => d.entityType === entityType && d.entityId === entityId);\n\n const toggle = () => {\n const next = isFav\n ? favDocs.filter(d => !(d.entityType === entityType && d.entityId === entityId))\n : [...favDocs, { entityType, entityId, label }];\n apiClient.patch('/auth/me/', { preferences: { favorite_documents: next } }).then(() => {\n queryClient.invalidateQueries({ queryKey: ['my-profile-sidebar'] });\n });\n };\n\n return (\n <button onClick={toggle} title={isFav ? 'Remove from desktop' : 'Add to desktop'}\n className={`shrink-0 transition-colors ${isFav ? 'text-yellow-500 hover:text-yellow-600' : 'text-gray-300 hover:text-yellow-400'}`}>\n <svg className=\"h-4 w-4\" fill={isFav ? '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\nfunction RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }: { item: MinimizedItem; onClose: () => void; onMinimize: (sb: SavedBox) => void; accentRgb?: string }) {\n const raw = WINDOW_REGISTRY[item.entityType!];\n if (!raw || !isEntityEntry(raw)) return null;\n const entry = raw as ModalRegistryEntry;\n\n const [editing, setEditing] = useState(false);\n\n // Use queryKey from registry (matches what detail components invalidate) or derive from endpoint\n const qkPrefix = entry.queryKey || entry.endpoint.replace(/^\\/|\\/$/g, '').split('/').pop() || item.entityType;\n const isDuplicate = item.entitySnapshot?._duplicate;\n // Unsaved \"create\" windows carry a placeholder id like `new-1783415283039`\n // (openEntity mints these for a not-yet-persisted record). There is nothing to\n // fetch — the GET would always 404 — so skip the detail query, exactly as we\n // do for duplicate windows. The snapshot already drives the create form.\n const isDraft = typeof item.entityId === 'string' && item.entityId.startsWith('new-');\n const { data: entity, isLoading, refetch } = useQuery({\n queryKey: [qkPrefix, item.entityId],\n queryFn: () => apiClient.get(entityDetailUrl(entry.endpoint, String(item.entityId))).then(r => r.data),\n initialData: item.entitySnapshot,\n initialDataUpdatedAt: 0, // Treat snapshot as stale so query refetches immediately\n enabled: !entry.selfFetching && !isDuplicate && !isDraft && isShellApiClientConfigured(),\n staleTime: 0,\n refetchOnWindowFocus: true,\n refetchOnMount: 'always',\n // Fallback polling; WebSocket provides instant updates. A window whose\n // entity the server says is not there stops polling instead of asking\n // every 60s forever — see entityFetchPolicy.\n refetchInterval: query => entityRefetchInterval(query.state.error),\n refetchIntervalInBackground: false,\n retry: shouldRetryEntityFetch,\n });\n\n // Refetch entity data whenever this modal is activated (brought to front)\n useEffect(() => {\n if (entry.selfFetching || isDuplicate || isDraft) return;\n const handler = () => { refetch(); };\n window.addEventListener('modal-reorder', handler);\n return () => window.removeEventListener('modal-reorder', handler);\n }, [refetch, entry.selfFetching, isDuplicate, isDraft]);\n\n // When editing, close/ESC exits edit mode instead of closing the window\n const handleClose = useCallback(() => {\n if (editing) {\n setEditing(false);\n } else {\n onClose();\n }\n }, [editing, onClose]);\n\n const titleBase = entry.selfFetching\n ? item.label\n : (entity ? entry.title(entity, editing, setEditing) : item.label);\n\n const entityIconKey = (entry as ModalRegistryEntry).icon;\n const entityIcon = entityIconKey ? navIcons[entityIconKey] : null;\n const titleContent = titleBase;\n\n const footerContent = (!entry.selfFetching && entity && entry.footer && !isDuplicate)\n ? entry.footer(entity)\n : undefined;\n\n // Components that render their own Modal — skip outer wrapper\n if (entry.rendersOwnModal) {\n // selfFetching components handle their own data loading — always render them\n if (entry.selfFetching) {\n return (\n <Suspense fallback={<LoadingSpinner />}>\n {entry.render(entity ?? item.entitySnapshot, handleClose, item.entityId, editing, setEditing)}\n </Suspense>\n );\n }\n return (\n <Suspense fallback={<LoadingSpinner />}>\n {isLoading && !entity ? (\n <LoadingSpinner />\n ) : entity ? (\n entry.render(entity, handleClose, item.entityId, editing, setEditing)\n ) : (\n <Modal open={true} onClose={onClose} title={item.label} size={(entry.size || '2xl') as any}>\n <p className=\"text-sm text-gray-500 py-8 text-center\">Not found.</p>\n </Modal>\n )}\n </Suspense>\n );\n }\n\n return (\n <Modal\n open={true}\n onClose={handleClose}\n onMinimize={onMinimize}\n initialBox={item.savedBox}\n icon={entityIcon}\n title={titleContent}\n footer={footerContent}\n copyText={item.label}\n windowKey={item.id}\n openedFromKey={item.openedFrom}\n size={(entry.size || '2xl') as any}\n dimensions={entry.dimensions}\n autoHeight={entry.autoHeight}\n autoMinHeight={entry.autoMinHeight}\n appStyle={entry.appStyle}\n accentRgb={accentRgb}\n >\n <Suspense fallback={<LoadingSpinner />}>\n {entry.selfFetching ? (\n entry.render(null, handleClose, item.entityId, editing, setEditing)\n ) : isLoading && !entity ? (\n <LoadingSpinner />\n ) : entity ? (\n entry.render(entity, handleClose, item.entityId, editing, setEditing)\n ) : (\n <p className=\"text-sm text-gray-500 py-8 text-center\">Not found.</p>\n )}\n </Suspense>\n </Modal>\n );\n}\n\n\n/** Find a modal panel by its window key (the openWindows item id). */\nfunction findPanelByWindowKey(key: string): HTMLElement | null {\n return document.querySelector(`[data-modal-panel][data-window-key=\"${key}\"]`) as HTMLElement | null;\n}\n\n/** Look up the windowKey of whichever modal is currently active. Used when\n * opening a new window so we can record what was on screen at the moment of\n * open as the new window's `openedFrom` — drives the mobile swipe-to-back\n * gesture's \"reveal the parent\" behavior. Returns undefined when nothing is\n * active (i.e. the user opened from home / start menu). */\nfunction currentlyActiveWindowKey(): string | undefined {\n const activeId = getActiveModalId();\n if (!activeId) return undefined;\n const panel = document.querySelector(`[data-modal-panel][data-modal-id=\"${activeId}\"]`) as HTMLElement | null;\n return panel?.getAttribute('data-window-key') ?? undefined;\n}\n\n/** Module-level mirror of windowKey → route for the currently-open\n * windows. Kept in sync by the Provider's effect (see below). Lets\n * non-React code (e.g. a bug-report submit callback) ask \"which app\n * window is the user currently looking at\" without grabbing context.\n * Bug-report and similar HeadlessUI dialogs don't go through the\n * shell's Modal store, so the active window key keeps pointing at\n * the underlying app window even while such a dialog is open. */\nconst routeByWindowKey = new Map<string, string>();\n\n/** Public, framework-free helper: route ('/orders', '/qc-reports', …)\n * of the window the user is currently focused on. Returns undefined\n * when no app window is active (start menu / dashboard with nothing\n * open). Useful for code paths that fire outside React render — the\n * shell consumer can stamp metadata on a payload (e.g. \"which module\n * is this bug report against?\") without needing to lift state. */\nexport function getActiveWindowRoute(): string | undefined {\n const key = currentlyActiveWindowKey();\n if (!key) return undefined;\n return routeByWindowKey.get(key);\n}\n\n/** Find a modal panel whose title text contains `label`. Used as a fallback\n * when no window key is available (legacy code paths). */\nfunction findPanelByLabel(label: string): HTMLElement | null {\n const panels = document.querySelectorAll('[data-modal-panel]');\n for (const p of Array.from(panels)) {\n const t = p.querySelector('[data-window-title]');\n if (t?.textContent?.includes(label)) return p as HTMLElement;\n }\n return null;\n}\n\n// Aero-peek: while the user hovers a taskbar thumbnail, the window it belongs\n// to is raised above its siblings and stays fully opaque, while every other\n// window falls back a layer and fades to 40%. Toggled purely via a body class\n// + a marker attribute — never touches a panel's inline styles, so it cleans\n// up for free and can't be stranded. The dim animates (transition is scoped to\n// `.rosh-peeking`); dropping the class snaps every window crisply back.\n// Mirrors `ensureGestureStyle` in Modal.tsx.\n//\n// The raise has to be `!important`: a panel's z-index is an inline style (see\n// Modal.tsx, `zIndex: pinnedOnTop ? 999 : zIndex + 1`), and an author\n// `!important` declaration is the only thing in the cascade that beats inline\n// without writing to `panel.style` — which a stray `modal-reorder` would\n// clobber — or calling `activateModal`, which would turn a hover into a click.\n//\n// 249 sits above every window in the ladder (50 + index*10 + 1) but below the\n// taskbar at z-250, so a peeked window never paints over the very thumbnail\n// you are hovering. A window that is currently pinned on top rides the 999\n// lane instead, so raising it to 249 would *demote* it — hence the\n// `[data-pinned-top]` exemption, the same reason Windows leaves topmost\n// windows out of Aero Peek. (`data-utility` is not the test: it only means the\n// window *may* be pinned, and every bundled app sets it.)\nconst PEEK_STYLE_ID = 'rosh-peek-style';\nconst PEEK_Z = 249;\nfunction ensurePeekStyle() {\n if (typeof document === 'undefined' || document.getElementById(PEEK_STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = PEEK_STYLE_ID;\n style.textContent =\n 'body.rosh-peeking [data-modal-panel]{transition:opacity .18s ease}' +\n 'body.rosh-peeking [data-modal-panel]:not([data-peek-focus]){opacity:.4}' +\n 'body.rosh-peeking [data-modal-panel][data-peek-focus]{opacity:1}' +\n `body.rosh-peeking [data-modal-panel][data-peek-focus]:not([data-pinned-top]){z-index:${PEEK_Z}!important}` +\n // Someone who turned transparency off gets the raise, not a fade.\n 'html.rosh-reduce-transparency body.rosh-peeking [data-modal-panel]:not([data-peek-focus]){opacity:.92}' +\n '@media (prefers-reduced-motion:reduce){body.rosh-peeking [data-modal-panel]{transition:none}}';\n document.head.appendChild(style);\n}\n\n/** Bring `panel` forward by fading every other open window to 40%. Passing\n * null clears the effect. Re-marking a different panel while already peeking\n * keeps the body class on, so sliding between thumbnails cross-fades the two\n * windows instead of flashing everything back to full opacity. */\nfunction setPeekFocus(panel: HTMLElement | null) {\n if (typeof document === 'undefined') return;\n ensurePeekStyle();\n document.querySelectorAll('[data-modal-panel][data-peek-focus]')\n .forEach(el => el.removeAttribute('data-peek-focus'));\n if (panel) panel.setAttribute('data-peek-focus', '');\n document.body.classList.toggle('rosh-peeking', !!panel);\n}\n\n/** Drop the peek — restore every window to full opacity. */\nfunction clearPeekFocus() {\n if (typeof document === 'undefined') return;\n document.body.classList.remove('rosh-peeking');\n document.querySelectorAll('[data-modal-panel][data-peek-focus]')\n .forEach(el => el.removeAttribute('data-peek-focus'));\n}\n\n/** Render a single window snapshot. The card sizes itself to the source\n * panel's aspect ratio (clamped to maxW × maxH) so the snapshot fills\n * the card with no empty letterboxing. When the source window is\n * hidden (zero rect — e.g. show-desktop just minimised it) we fall\n * back to a frosted card with the icon + label so the preview is\n * never empty. When `titleAbove` is true the bottom overlay label\n * is dropped — the parent renders the title in a row above instead. */\n/** Snapshot card for an open window. Exported for the mobile switcher.\n * See JSDoc above for sizing/snapshot semantics. */\nexport function ThumbCard({ id, label, maxW, maxH, titleAbove = false, onClick, onClose }: {\n id: string; label: string; maxW: number; maxH: number; titleAbove?: boolean; onClick?: () => void; onClose?: () => void;\n}) {\n const previewRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<{ w: number; h: number }>({ w: maxW, h: Math.round(maxH * 0.75) });\n const [hasSnapshot, setHasSnapshot] = useState(false);\n\n useLayoutEffect(() => {\n const inner = previewRef.current;\n if (!inner) return;\n const target = findPanelByWindowKey(id) ?? findPanelByLabel(label);\n if (!target) { setHasSnapshot(false); return; }\n const rect = target.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) { setHasSnapshot(false); return; }\n const ratio = Math.min(maxW / rect.width, maxH / rect.height);\n const cardW = Math.max(80, Math.round(rect.width * ratio));\n const cardH = Math.max(60, Math.round(rect.height * ratio));\n setSize({ w: cardW, h: cardH });\n setHasSnapshot(true);\n const clone = target.cloneNode(true) as HTMLElement;\n clone.style.position = 'absolute';\n clone.style.top = '0'; clone.style.left = '0';\n clone.style.right = 'auto'; clone.style.bottom = 'auto';\n clone.style.width = rect.width + 'px';\n clone.style.height = rect.height + 'px';\n clone.style.transform = `scale(${ratio})`;\n clone.style.transformOrigin = 'top left';\n clone.style.pointerEvents = 'none';\n clone.style.animation = 'none';\n clone.removeAttribute('data-modal-panel');\n clone.removeAttribute('data-modal-id');\n clone.removeAttribute('data-window-key');\n clone.querySelectorAll<HTMLElement>('[role=\"dialog\"], [data-portal]').forEach(el => { el.style.display = 'none'; });\n inner.innerHTML = '';\n inner.appendChild(clone);\n return () => { inner.innerHTML = ''; };\n }, [id, label, maxW, maxH]);\n\n return (\n <div\n style={{ width: size.w, height: size.h }}\n className=\"relative rounded-md overflow-hidden bg-white/95 border border-gray-300 shadow-md cursor-pointer ring-2 ring-transparent group-hover:ring-blue-400 transition shrink-0\"\n onClick={onClick}\n >\n <div ref={previewRef} className=\"absolute inset-0 overflow-hidden\" />\n {!hasSnapshot && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center text-gray-400 bg-gray-50\">\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n <span className=\"mt-1 text-[10px] uppercase tracking-wide\">Hidden</span>\n </div>\n )}\n {!titleAbove && (\n <div className=\"absolute bottom-0 left-0 right-0 px-2 py-1 text-[10px] font-medium text-white bg-gradient-to-t from-black/80 to-transparent truncate pointer-events-none\">\n {label}\n </div>\n )}\n {onClose && (\n <button\n onClick={(e) => { e.stopPropagation(); onClose(); }}\n className=\"absolute top-1 right-1 h-5 w-5 rounded-full bg-gray-900/90 ring-1 ring-white/80 shadow-sm hover:bg-red-500 text-white flex items-center justify-center\"\n title=\"Close window\"\n >\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>\n </button>\n )}\n </div>\n );\n}\n\n/** Hover popover — single thumbnail for a single window, or a row of\n * thumbnails for a grouped set so the user can pick which instance to\n * activate. Each thumb sizes to its window's aspect ratio (clamped).\n * After mount, the popover measures its own bounding box and centers\n * itself horizontally on the button below — fixed-width math doesn't\n * hold once cards reflect their source aspect ratios. */\nfunction TaskbarTabPreview({ items, anchorEl, onActivate, onClose, onMouseEnter, onMouseLeave }: {\n items: MinimizedItem[]; anchorEl: HTMLElement; onActivate: (id: string) => void; onClose: (id: string) => void;\n onMouseEnter: () => void; onMouseLeave: () => void;\n}) {\n const MAX_W = 240;\n const MAX_H = 160;\n const isGroup = items.length > 1;\n const popoverRef = useRef<HTMLDivElement>(null);\n // Provisional position (off-screen above viewport) so we can measure the\n // actual rendered size before snapping into place. This avoids a single\n // mis-aligned frame.\n const [pos, setPos] = useState<{ left: number; top: number; ready: boolean }>({ left: -9999, top: -9999, ready: false });\n const [taskbarPos, setTaskbarPos] = useState<string>(() =>\n typeof document !== 'undefined'\n ? (getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom')\n : 'bottom'\n );\n\n useLayoutEffect(() => {\n const el = popoverRef.current;\n if (!el) return;\n const measure = () => {\n const tabRect = anchorEl.getBoundingClientRect();\n const popRect = el.getBoundingClientRect();\n const tbPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n setTaskbarPos(tbPos);\n let left = tabRect.left + tabRect.width / 2 - popRect.width / 2;\n let top: number;\n if (tbPos === 'top') {\n top = tabRect.bottom + 8;\n } else if (tbPos === 'left') {\n left = tabRect.right + 8;\n top = tabRect.top + tabRect.height / 2 - popRect.height / 2;\n } else if (tbPos === 'right') {\n left = tabRect.left - popRect.width - 8;\n top = tabRect.top + tabRect.height / 2 - popRect.height / 2;\n } else {\n // bottom\n top = tabRect.top - popRect.height - 8;\n }\n // Clamp to viewport.\n left = Math.max(8, Math.min(left, window.innerWidth - popRect.width - 8));\n top = Math.max(8, Math.min(top, window.innerHeight - popRect.height - 8));\n setPos({ left, top, ready: true });\n };\n measure();\n // Re-measure when child cards finalise their size (they pick their\n // dimensions in a useLayoutEffect after the first paint).\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => ro.disconnect();\n }, [anchorEl, items.length]);\n\n // Safety net: always drop the peek when the popover unmounts, so the\n // desktop never gets stranded dimmed if the mouse never fires a leave\n // (e.g. the popover closes because its taskbar button was activated).\n useEffect(() => clearPeekFocus, []);\n\n // When the taskbar is on top, the popover hangs below the tab, so the\n // snapshot should sit closest to the tab (i.e. on top of the popover) and\n // the title sits beneath it. Every other taskbar position keeps the title\n // above the snapshot.\n const titleBelow = taskbarPos === 'top';\n const titleClass = `${titleBelow ? 'mt-1' : 'mb-1'} max-w-[240px] truncate text-[11px] font-medium text-gray-900 bg-white/80 px-2 py-0.5 rounded shadow-sm ring-2 ring-transparent transition group-hover:ring-blue-400`;\n\n return createPortal(\n <div\n ref={popoverRef}\n style={{\n position: 'fixed', left: pos.left, top: pos.top, zIndex: 9999,\n maxWidth: 'calc(100vw - 16px)',\n opacity: pos.ready ? 1 : 0,\n }}\n className={isGroup ? 'flex gap-2 flex-wrap' : ''}\n onMouseEnter={onMouseEnter}\n onMouseLeave={() => { clearPeekFocus(); onMouseLeave(); }}\n >\n {items.map(it => {\n const panel = findPanelByWindowKey(it.id) ?? findPanelByLabel(it.label);\n // Null unless this window is (partly) outside the work area. The arrow\n // lives here, on the taskbar chrome, rather than floating on the\n // desktop: the thumbnail already shows the window's content, so all\n // that's missing is which way it went — and clicking fetches it back.\n const bearing = panel ? panelOffscreenBearing(panel) : null;\n return (\n <div\n key={it.id}\n className=\"group flex flex-col items-center\"\n onMouseEnter={() => setPeekFocus(panel)}\n >\n {!titleBelow && <span className={titleClass}>{it.label}</span>}\n <ThumbCard\n id={it.id}\n label={it.label}\n maxW={MAX_W}\n maxH={MAX_H}\n titleAbove\n onClick={() => onActivate(it.id)}\n onClose={() => onClose(it.id)}\n />\n {titleBelow && <span className={titleClass}>{it.label}</span>}\n {bearing !== null && (\n <span\n title=\"This window is off screen — click to bring it back\"\n className=\"mt-1 inline-flex items-center gap-1 rounded bg-amber-500 px-1.5 py-0.5 text-[10px] font-semibold text-white shadow-sm\"\n >\n <svg className=\"h-3 w-3\" style={{ transform: `rotate(${bearing}deg)` }} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 12h14m0 0l-5-5m5 5l-5 5\" />\n </svg>\n Off screen\n </span>\n )}\n </div>\n );\n })}\n </div>,\n document.body,\n );\n}\n\nfunction TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActivate, onActivateById }: {\n openWindows: MinimizedItem[]; onRemove: (id: string) => void; onCloseAll: () => void; onSplitView: () => void;\n onActivate: (label: string) => void;\n onActivateById: (id: string) => void;\n}) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n useEffect(() => {\n const el = document.getElementById('taskbar-windows');\n if (el) setTarget(el);\n else { const t = setInterval(() => { const e = document.getElementById('taskbar-windows'); if (e) { setTarget(e); clearInterval(t); } }, 100); return () => clearInterval(t); }\n }, []);\n\n const activeModalId = useSyncExternalStore(subscribeActive, getActiveModalId);\n\n // Off-screen markers are read straight off the panels' live rects, so the\n // tabs need re-rendering whenever a window settles (`modal-geometry`, fired\n // once per drag/resize/snap/reveal — never per frame) or the viewport moves\n // under them.\n const [, setGeomTick] = useState(0);\n useEffect(() => {\n const bump = () => setGeomTick(t => t + 1);\n window.addEventListener('modal-geometry', bump);\n window.addEventListener('resize', bump);\n return () => {\n window.removeEventListener('modal-geometry', bump);\n window.removeEventListener('resize', bump);\n };\n }, []);\n\n // Re-render the taskbar when any window's title changes so the dynamic\n // title (e.g. \"Untitled - Spreadsheets\") shows up on the tab.\n const [, forceTick] = useState(0);\n useEffect(() => {\n const onTitle = () => forceTick(t => t + 1);\n window.addEventListener('window-title-update', onTitle);\n return () => window.removeEventListener('window-title-update', onTitle);\n }, []);\n const liveTitle = (label: string): string => {\n const panel = findPanelByLabel(label);\n const titleEl = panel?.querySelector('[data-window-title]');\n return titleEl?.textContent?.trim() || label;\n };\n\n const [hoveredItems, setHoveredItems] = useState<MinimizedItem[] | null>(null);\n const [hoveredAnchor, setHoveredAnchor] = useState<HTMLElement | null>(null);\n const hoverTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const handleEnter = (items: MinimizedItem[], el: HTMLElement) => {\n if (hoverTimerRef.current) { clearTimeout(hoverTimerRef.current); hoverTimerRef.current = null; }\n hoverTimerRef.current = setTimeout(() => { setHoveredItems(items); setHoveredAnchor(el); }, 350);\n };\n const handleLeave = () => {\n if (hoverTimerRef.current) { clearTimeout(hoverTimerRef.current); hoverTimerRef.current = null; }\n hoverTimerRef.current = setTimeout(() => { setHoveredItems(null); setHoveredAnchor(null); }, 150);\n };\n const cancelLeave = () => {\n if (hoverTimerRef.current) { clearTimeout(hoverTimerRef.current); hoverTimerRef.current = null; }\n };\n // Filter out utility apps (e.g. calculator) from taskbar tabs\n const tabWindows = openWindows.filter(item => !item.route || !(WINDOW_REGISTRY[item.route] as PageRegistryEntry)?.utility);\n if (!target || tabWindows.length === 0) return null;\n\n // Group windows into one taskbar button with a count badge instead of N\n // tabs. Same-route `multiInstance` copies stack; windows that declare a\n // shared `taskbarGroup.key` also stack ACROSS routes (e.g. the Storefront\n // console + the editors it opens), taking the group's label + icon.\n type Group = { key: string; route?: string; label: string; items: MinimizedItem[] };\n const groups: Group[] = [];\n const idx = new Map<string, number>();\n for (const item of tabWindows) {\n const entry = item.route ? (WINDOW_REGISTRY[item.route] as PageRegistryEntry | undefined) : undefined;\n const grp = entry?.taskbarGroup;\n const key = grp?.key ?? item.route ?? `entity:${item.id}`;\n const i = idx.get(key);\n if (i !== undefined) {\n groups[i].items.push(item);\n } else {\n idx.set(key, groups.length);\n // A cross-route group shows its own label + icon; a plain route group\n // shows the window's registry label + its own route icon (as before).\n const label = grp?.label ?? entry?.label ?? item.label;\n groups.push({ key, route: grp?.icon ?? item.route, label, items: [item] });\n }\n }\n\n return createPortal(\n <>\n {groups.map(group => {\n const icon = group.route ? navIcons[group.route] : null;\n // The \"primary\" item for activation/preview: the most recently opened.\n const primary = group.items[group.items.length - 1];\n // Group is active if any of its instances is the active modal.\n let isActive = false;\n if (activeModalId) {\n const panel = document.querySelector(`[data-modal-id=\"${activeModalId}\"]`);\n if (panel) {\n const titleEl = panel.querySelector('[data-window-title]');\n const titleText = titleEl?.textContent ?? '';\n isActive = group.items.some(it => titleText.includes(it.label));\n }\n }\n const isGrouped = group.items.length > 1;\n // Ambient \"you have a window out there\" signal, visible before the\n // user hovers anything.\n const offscreen = group.items.some(it => {\n const p = findPanelByWindowKey(it.id) ?? findPanelByLabel(it.label);\n return !!p && !isPanelFullyVisible(p);\n });\n\n return (\n <button key={group.key} onClick={() => onActivateById(primary.id)}\n onMouseEnter={(e) => handleEnter(group.items, e.currentTarget)}\n onMouseLeave={handleLeave}\n onDoubleClick={(e) => { e.stopPropagation(); window.dispatchEvent(new CustomEvent('modal-center', { detail: { label: primary.label } })); }}\n onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); window.dispatchEvent(new CustomEvent('modal-context-menu', { detail: { label: primary.label, x: e.clientX, y: e.clientY } })); }}\n style={{ width: 'var(--window-tab-width, 200px)', fontSize: 'var(--window-tab-font-size, 12px)' }}\n data-tab-group={group.key}\n className={`group relative flex items-center gap-1.5 rounded-lg px-3 py-2 font-medium transition-all min-w-0 shrink ${\n isActive ? 'bg-blue-100/60 border border-blue-400/60 text-blue-700' : 'bg-gray-50/40 border border-gray-200/40 text-gray-700 hover:bg-gray-200/40'\n }`}>\n {icon && isValidElement(icon)\n ? cloneElement(icon as ReactElement, { className: `h-3.5 w-3.5 shrink-0 ${isActive ? 'text-blue-600' : 'text-gray-400'}` })\n : <svg className={`h-3.5 w-3.5 shrink-0 ${isActive ? 'text-blue-600' : 'text-gray-400'}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4\" /></svg>\n }\n <span className=\"truncate flex-1\">{isGrouped ? group.label : liveTitle(primary.label)}</span>\n {offscreen && (\n <span title=\"Off screen — click to bring this window back\" className=\"shrink-0 h-1.5 w-1.5 rounded-full bg-amber-500\" />\n )}\n {isGrouped && (\n <span className=\"shrink-0 px-1.5 py-0.5 rounded-full bg-blue-500/80 text-white text-[10px] font-bold leading-none\">{group.items.length}</span>\n )}\n {!isGrouped && (\n <span role=\"button\" onClick={(e) => { e.stopPropagation(); onRemove(primary.id); }} className=\"ml-auto text-gray-400 hover:text-red-500 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity\">\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 </span>\n )}\n </button>\n );\n })}\n <div className=\"flex-1\" />\n {tabWindows.length >= 2 && (\n <button onClick={onSplitView} title=\"Exposé — show all open windows as thumbnails\"\n className=\"flex items-center gap-1 rounded px-2 py-1 text-[11px] font-medium text-blue-600 border border-blue-300 hover:bg-blue-50 transition-colors shrink-0\">\n {/* 2×2 grid icon — exposé toggle, mirrors macOS Mission Control. */}\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1\" />\n </svg>\n Exposé\n </button>\n )}\n {hoveredItems && hoveredAnchor && (\n <TaskbarTabPreview\n items={hoveredItems}\n anchorEl={hoveredAnchor}\n onActivate={(id) => { onActivateById(id); setHoveredItems(null); setHoveredAnchor(null); }}\n onClose={(id) => { onRemove(id); setHoveredItems(null); setHoveredAnchor(null); }}\n onMouseEnter={cancelLeave}\n onMouseLeave={handleLeave}\n />\n )}\n </>,\n target\n );\n}\n\nconst SESSION_KEY = 'erp_open_windows';\n\nfunction saveWindowState(windows: MinimizedItem[]) {\n try {\n const serializable = windows.map(w => ({ ...w, entitySnapshot: undefined }));\n localStorage.setItem(SESSION_KEY, JSON.stringify(serializable));\n } catch { /* storage full */ }\n}\n\nconst DEFAULT_WIDGETS: MinimizedItem[] = [\n { id: 'page:/weather', type: 'page', label: 'Weather', route: '/weather' },\n { id: 'page:/currency', type: 'page', label: 'Currency Converter', route: '/currency' },\n { id: 'page:/world-clock', type: 'page', label: 'World Clock', route: '/world-clock' },\n];\n\n/**\n * Lay the first-run default widgets out in a tidy top-left column — mirroring\n * the Widget Manager's placement — so a brand-new account opens with its widgets\n * stacked down the left edge instead of piled in the centre (which is what\n * Modal's `calcWindowed` no-saved-position fallback does). We seed the shared\n * window-position store *before* the widgets mount, so each Modal restores from\n * it on open. `setWindowDefaultPosition` is a no-op once a real saved position\n * exists, so this never disturbs a returning user who has dragged things around.\n *\n * Every default widget is `autoHeight`, so it re-measures to its content on open\n * — the heights here are only first-paint estimates for a non-overlapping stack.\n */\nfunction seedDefaultWidgetPositions(widgets: MinimizedItem[]) {\n const PAD = 20, GAP = 16, MAX_AUTO_H = 220;\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 const leftStart = (tbPos === 'left' ? tbW : 0) + sidebarW + PAD;\n const topStart = (tbPos === 'top' ? tbH : 0) + PAD;\n const maxBottom = window.innerHeight - (tbPos === 'bottom' ? tbH : 0) - PAD;\n const rightLimit = window.innerWidth - PAD;\n\n let x = leftStart, y = topStart;\n for (const item of widgets) {\n if (!item.route) continue;\n const e = WINDOW_REGISTRY[item.route];\n if (!e || !isPageEntry(e)) continue;\n const entry = e as PageRegistryEntry;\n const w = entry.dimensions?.[0] ?? 320;\n const h = entry.dimensions?.[1] ?? 240;\n const stackH = entry.autoHeight ? Math.min(h, MAX_AUTO_H) : h;\n // Wrap to a fresh column when this one is full — but only if the next column\n // still fits on-screen, so a widget never gets pushed off the right edge.\n if (y > topStart && y + stackH > maxBottom && x + (w + GAP) + w <= rightLimit) {\n x += w + GAP;\n y = topStart;\n }\n setWindowDefaultPosition(item.id, { x, y, w, h });\n y += stackH + GAP;\n }\n}\n\n/** Heal a restored session against the legacy id-collision bug. Builds before\n * 3.14.1 derived a modal window's `id` from its (non-unique) label, so two\n * records sharing a label persisted with the same `id` — duplicate React keys\n * left one window un-closeable, and a plain reload restored it just as broken.\n * Re-key any collided modal to its stable entity identity (matching what\n * `openEntity` now emits) and drop any that still collide (the same entity\n * persisted twice), so a reload resolves a stuck pair instead of resurrecting\n * it. Non-collided windows keep their stored id so their saved box/z-order is\n * preserved. */\nfunction healWindowIds(items: MinimizedItem[]): MinimizedItem[] {\n const counts = new Map<string, number>();\n for (const it of items) counts.set(it.id, (counts.get(it.id) ?? 0) + 1);\n const seen = new Set<string>();\n const out: MinimizedItem[] = [];\n for (const it of items) {\n let id = it.id;\n if ((counts.get(it.id) ?? 0) > 1 && it.type === 'modal' && it.entityType && it.entityId) {\n id = `${it.entityType}:${it.entityId}`;\n }\n if (seen.has(id)) continue;\n seen.add(id);\n out.push(id === it.id ? it : { ...it, id });\n }\n return out;\n}\n\nfunction restoreWindowState(): MinimizedItem[] {\n try {\n if (window.location.pathname === '/login') return [];\n if (!localStorage.getItem('access_token')) return [];\n const stored = localStorage.getItem(SESSION_KEY);\n if (stored) return healWindowIds(JSON.parse(stored));\n } catch { /* corrupt data */ }\n // First run for this account — no saved session yet. Seed a top-left stack so\n // the default widgets don't open piled in the centre of the desktop.\n seedDefaultWidgetPositions(DEFAULT_WIDGETS);\n return DEFAULT_WIDGETS;\n}\n\nconst AUTH_PAGES = ['/login', '/forgot-password', '/reset-password', '/force-change-password'];\n\nexport function WindowManagerProvider({ children, windowAccentForRoute }: {\n children: ReactNode;\n /** SG#00372: optional per-section window accent. Called with each open\n * window's route ('/sales-orders', '/payments', …); return an `R G B`\n * triple (e.g. '91 141 190') to give that window a thin accent stripe on\n * its title bar (see Modal's `accentRgb`), or undefined for no accent.\n * The consumer owns the route→section→colour mapping; omitting the prop\n * keeps every window exactly as before. */\n windowAccentForRoute?: (route: string) => string | undefined;\n}) {\n const location = useLocation();\n const isAuthPage = AUTH_PAGES.some(p => location.pathname.startsWith(p));\n const [openWindows, setOpenWindows] = useState<MinimizedItem[]>(() => restoreWindowState());\n\n // Persist window state on every change — but don't save empty on initial mount (login page)\n const hasUserActed = useRef(false);\n useEffect(() => {\n if (openWindows.length > 0) hasUserActed.current = true;\n if (hasUserActed.current) saveWindowState(openWindows);\n\n // Mirror windowKey → route into the module-level map exported as\n // `getActiveWindowRoute()`. Snapshot semantics: we rebuild from\n // scratch on every change so closed windows drop out cleanly.\n routeByWindowKey.clear();\n for (const w of openWindows) {\n if (w.route) routeByWindowKey.set(w.id, w.route);\n }\n }, [openWindows]);\n\n const closeEntity = useCallback((id: string) => {\n setOpenWindows(prev => prev.filter(m => m.id !== id));\n }, []);\n\n // Bring the just-spawned window with `windowKey` to the front after React\n // renders its panel. Without this, mountModal would slot the new modal into\n // its previously-saved z-order (from localStorage), placing it behind the\n // currently active window — wrong for user-initiated opens.\n const activateAfterMount = (windowKey: string) => {\n setTimeout(() => {\n const panel = document.querySelector(`[data-modal-panel][data-window-key=\"${windowKey}\"]`);\n const mid = panel?.getAttribute('data-modal-id');\n if (mid) activateModal(mid);\n }, 50);\n };\n\n const openEntity = useCallback((entityType: string, entityId: string, snapshot?: any, label?: string, route?: string) => {\n if (!WINDOW_REGISTRY[entityType] || !isEntityEntry(WINDOW_REGISTRY[entityType])) return;\n // The window's identity must equal the dedup identity (entityType + entityId),\n // NOT the human `label`. Two different records that share a label — e.g. two\n // wheel finishes on the same design (\"Yakama\") — would otherwise both get\n // `id = label`, so they collided: duplicate React keys in the render map and a\n // shared `windowKey`/`boxKey`. Closing one then filtered both out of state but\n // left the other's portal panel stranded, its close button a no-op. Keying by\n // the entity identity guarantees no two live windows can share an id (that's\n // exactly what the `existing` dedup below already enforces).\n const id = `${entityType}:${entityId}`;\n const openedFrom = currentlyActiveWindowKey();\n // If already open, just activate it\n setOpenWindows(prev => {\n // Compare entityId as a string so a numeric id from one call site and the\n // string form from another (`42` vs '42') still dedup to one window — and\n // stay consistent with `id` above, which coerces both to the same string.\n const existing = prev.find(m => m.entityType === entityType && String(m.entityId) === String(entityId));\n if (existing) {\n activateAfterMount(existing.id);\n return prev;\n }\n activateAfterMount(id);\n return [...prev, {\n id, type: 'modal' as const, label: label || entityId,\n route: route || window.location.pathname,\n entityType, entityId, entitySnapshot: snapshot,\n openedFrom,\n }];\n });\n }, []);\n\n /** Open a page as a window — reuse if already open */\n const openPage = useCallback((path: string) => {\n if (!WINDOW_REGISTRY[path] || !isPageEntry(WINDOW_REGISTRY[path])) return;\n const entry = WINDOW_REGISTRY[path] as PageRegistryEntry;\n const openedFrom = currentlyActiveWindowKey();\n setOpenWindows(prev => {\n // Multi-instance pages always spawn a new window with a unique id.\n // The window is identified by `id`, never by label — so every instance\n // keeps the plain registry label. The instance count surfaces only as the\n // taskbar group's blue count badge (derived live at render). Baking a\n // `${label} N` ordinal into the stored label used to strand a stale\n // number on a lone leftover window (close #1 of two, and #2's tab still\n // read \"Designs 2\" with no badge, since a single window never groups).\n if (entry.multiInstance) {\n const id = `page:${path}:${Math.random().toString(36).slice(2, 8)}`;\n activateAfterMount(id);\n return [...prev, {\n id, type: 'page' as const,\n label: entry.label,\n route: path,\n openedFrom,\n }];\n }\n const existing = prev.find(m => m.type === 'page' && m.route === path);\n if (existing) {\n // Widgets toggle on/off; non-widgets activate (bring to front)\n if (entry.widget) {\n return prev.filter(m => m !== existing);\n }\n activateAfterMount(existing.id);\n return prev;\n }\n const id = `page:${path}`;\n activateAfterMount(id);\n return [...prev, {\n id, type: 'page' as const, label: entry.label,\n route: path,\n openedFrom,\n }];\n });\n }, []);\n\n // Backward compat stubs\n const minimize = useCallback(() => {}, []);\n const restore = useCallback(() => {}, []);\n const remove = closeEntity;\n const restoreIfMinimized = () => false;\n\n return (\n <MinimizedContext.Provider value={{ openWindows, openEntity, openPage, closeEntity, minimize, items: [], openItems: openWindows, restore, remove, restoreIfMinimized }}>\n {children}\n\n {/* Taskbar windows */}\n <TaskbarWindows\n openWindows={openWindows}\n onRemove={closeEntity}\n onCloseAll={() => setOpenWindows([])}\n onSplitView={triggerSplitView}\n onActivate={(label) => {\n const panels = document.querySelectorAll('[data-modal-panel]');\n panels.forEach(p => {\n const titleEl = p.querySelector('[data-window-title]');\n if (titleEl?.textContent?.includes(label)) {\n const mid = p.getAttribute('data-modal-id');\n if (mid) activateModal(mid);\n }\n });\n }}\n onActivateById={(id) => {\n const panel = document.querySelector(`[data-modal-panel][data-window-key=\"${id}\"]`) as HTMLElement | null;\n if (!panel) return;\n // Focusing a window you can't see achieves nothing — fetch it back\n // first. `revealWindow` activates it as part of the rescue.\n if (!isPanelFullyVisible(panel)) { revealWindow(id); return; }\n const mid = panel.getAttribute('data-modal-id');\n if (mid) activateModal(mid);\n }}\n />\n\n {/* Exposé backdrop — singleton overlay shown when exposé mode is on. */}\n <ExposeBackdrop />\n\n {/* All open windows — pages and entities (hidden on auth pages).\n Modal already guards its body content; this outer boundary is the\n last resort for crashes outside the body — a registry title()/footer()\n throwing on malformed data, or a rendersOwnModal component dying\n before its Modal mounts — so one bad window can never unmount the\n desktop. The fallback swaps the window for a plain Modal carrying the\n same crash state; its close button still removes the window. */}\n {!isAuthPage && openWindows.map(item => {\n // SG#00372: resolve the window's per-section accent from its route.\n const accentRgb = item.route ? windowAccentForRoute?.(item.route) : undefined;\n return (\n <WindowErrorBoundary\n key={item.id}\n fallback={(error, reset) => (\n <Modal open={true} onClose={() => closeEntity(item.id)} title={item.label} size=\"md\" autoHeight windowKey={item.id}>\n <WindowCrashedFallback error={error} onReload={reset} />\n </Modal>\n )}\n >\n <WindowShortcutProvider spec={shortcutSpecFor(item)}>\n {item.type === 'page' ? (\n <PageWindow item={item} onClose={() => closeEntity(item.id)} accentRgb={accentRgb} />\n ) : (\n <RestoredRegistryModal\n item={item}\n onClose={() => closeEntity(item.id)}\n onMinimize={() => {}}\n accentRgb={accentRgb}\n />\n )}\n </WindowShortcutProvider>\n </WindowErrorBoundary>\n );\n })}\n </MinimizedContext.Provider>\n );\n}\n","import { useEffect, useRef, type ReactNode, type CSSProperties } from 'react';\nimport { createPortal } from 'react-dom';\nimport { glassStyle, GLASS_DIVIDER } from '../utils/glass';\n\n/**\n * Unified popup menu component — used for all context menus, dropdowns, and flyouts.\n * Reads --menu-density CSS variable: 'tight', 'normal' (default), or 'large'.\n */\n\nexport interface PopupMenuProps {\n children: ReactNode;\n style?: CSSProperties;\n className?: string;\n onClose?: () => void;\n minWidth?: number;\n /** Render into document.body instead of in place. Required when the menu\n * is opened from INSIDE a window: the window panel is a transformed /\n * backdrop-filtered `overflow-hidden` container, which both re-anchors\n * `position: fixed` descendants to itself and clips them — a menu\n * positioned at viewport coordinates ends up offset or invisible.\n * Portaling restores true viewport positioning. */\n portal?: boolean;\n}\n\nfunction getDensity(): 'tight' | 'normal' | 'large' {\n return (getComputedStyle(document.documentElement).getPropertyValue('--menu-density')?.trim() as any) || 'normal';\n}\n\n/** Container for a popup menu — auto-clamps to stay within viewport */\nexport function PopupMenu({ children, style, className = '', onClose, minWidth = 180, portal = false }: PopupMenuProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!onClose) return;\n const handleClick = (e: PointerEvent | MouseEvent) => {\n if ((e.target as HTMLElement).closest('[data-menu-toggle]')) return;\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const handleKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('pointerdown', handleClick);\n window.addEventListener('keydown', handleKey);\n return () => { window.removeEventListener('pointerdown', handleClick); window.removeEventListener('keydown', handleKey); };\n }, [onClose]);\n\n // After render, clamp position to viewport boundaries\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n requestAnimationFrame(() => {\n const rect = el.getBoundingClientRect();\n const margin = 8;\n // Clamp right edge\n if (rect.right > window.innerWidth - margin) {\n const overflow = rect.right - window.innerWidth + margin;\n if (el.style.left) {\n el.style.left = `${parseFloat(el.style.left) - overflow}px`;\n } else if (!el.style.right) {\n el.style.left = `${rect.left - overflow}px`;\n }\n }\n // Clamp left edge\n if (rect.left < margin) {\n if (el.style.left) {\n el.style.left = `${margin}px`;\n } else if (el.style.right) {\n el.style.right = `${window.innerWidth - rect.width - margin}px`;\n }\n }\n // Clamp bottom edge\n if (rect.bottom > window.innerHeight - margin) {\n const overflow = rect.bottom - window.innerHeight + margin;\n if (el.style.top) {\n el.style.top = `${parseFloat(el.style.top) - overflow}px`;\n } else if (el.style.bottom) {\n // Already anchored to bottom, just clamp\n el.style.bottom = `${margin}px`;\n } else {\n el.style.top = `${rect.top - overflow}px`;\n }\n }\n // Clamp top edge\n if (rect.top < margin) {\n if (el.style.top) {\n el.style.top = `${margin}px`;\n } else if (el.style.bottom) {\n el.style.bottom = `${window.innerHeight - rect.height - margin}px`;\n }\n }\n });\n });\n\n const density = getDensity();\n\n const menu = (\n <div ref={ref}\n className={`fixed z-[400] rounded-2xl ${density === 'tight' ? 'py-1' : density === 'large' ? 'py-2' : 'py-1.5'} ${className}`}\n style={{ minWidth, animation: 'popup-in 0.12s ease-out', ...glassStyle(), ...style }}>\n {children}\n <style>{`@keyframes popup-in { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }`}</style>\n </div>\n );\n\n return portal ? createPortal(menu, document.body) : menu;\n}\n\n/** A clickable menu item */\nexport function PopupMenuItem({ onClick, children, className = '', danger, disabled }: {\n onClick?: () => void;\n children: ReactNode;\n className?: string;\n danger?: boolean;\n disabled?: boolean;\n}) {\n const density = getDensity();\n // Vertical gap between items. `normal` sits a little tighter than the raw\n // size padding; `large` adds a bit more room. Floored at the tight value so\n // the reduced `normal` never drops below `tight` at the smallest menu size.\n const itemPadY = density === 'tight' ? '0.25rem'\n : density === 'large' ? '0.6rem'\n : 'max(0.25rem, calc(var(--menu-padding-y, 0.5rem) - 0.1rem))';\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`w-full flex items-center gap-2 text-left transition-colors rounded-lg mx-auto\n ${danger ? 'text-red-600 hover:bg-red-50' : 'text-gray-700 hover:bg-blue-50 hover:text-blue-700'}\n ${disabled ? 'opacity-40 cursor-not-allowed' : ''}\n ${className}`}\n style={{\n width: 'calc(100% - 8px)',\n marginLeft: 4,\n marginRight: 4,\n fontSize: 'var(--menu-font-size, 14px)',\n paddingLeft: 'var(--menu-padding-x, 1rem)',\n paddingRight: 'var(--menu-padding-x, 1rem)',\n paddingTop: itemPadY,\n paddingBottom: itemPadY,\n }}\n >\n {children}\n </button>\n );\n}\n\n/** A divider line between menu items */\nexport function PopupMenuDivider() {\n const density = getDensity();\n return <div className={`border-t ${GLASS_DIVIDER} ${density === 'tight' ? 'my-0.5' : density === 'large' ? 'my-1.5' : 'my-1'} mx-3`} />;\n}\n\n/** A section header label */\nexport function PopupMenuLabel({ children }: { children: ReactNode }) {\n const density = getDensity();\n const labelPadY = density === 'tight' ? '0.125rem' : density === 'large' ? '0.375rem' : '0.25rem';\n return (\n <div\n className=\"text-[10px] font-medium text-gray-400 uppercase tracking-wider\"\n style={{\n paddingLeft: 'var(--menu-padding-x, 1rem)',\n paddingRight: 'var(--menu-padding-x, 1rem)',\n paddingTop: labelPadY,\n paddingBottom: labelPadY,\n }}\n >\n {children}\n </div>\n );\n}\n\n/** An icon helper */\nexport function MenuIcon({ d, className = 'h-4 w-4 text-gray-400' }: { d: string; className?: string }) {\n return (\n <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d={d} />\n </svg>\n );\n}\n","/**\n * Mobile breakpoint hook — single source of truth for \"is this a phone/tablet\n * portrait viewport?\" Drives whether <Layout> renders the desktop chrome\n * (windows / taskbar / start menu sidebar) or <MobileShell> (home / fullscreen\n * apps / bottom-nav switcher).\n *\n * Locked at 768 px so iPad portrait gets the mobile shell. Also OR's with\n * `pointer: coarse` so touch-only devices that happen to be wider (e.g. an\n * Android tablet in landscape) still get touch-appropriate UI.\n */\nimport { useSyncExternalStore } from 'react';\n\nconst QUERY = '(max-width: 767px), (pointer: coarse)';\n\nfunction getSnapshot(): boolean {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia(QUERY).matches;\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n\nfunction subscribe(cb: () => void): () => void {\n if (typeof window === 'undefined' || !window.matchMedia) return () => {};\n const mql = window.matchMedia(QUERY);\n // Older Safari uses addListener; modern browsers use addEventListener.\n if (mql.addEventListener) {\n mql.addEventListener('change', cb);\n return () => mql.removeEventListener('change', cb);\n }\n mql.addListener(cb);\n return () => mql.removeListener(cb);\n}\n\nexport function useIsMobile(): boolean {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","/**\n * Module-level state shared by all <Modal> instances on mobile during a\n * swipe-to-back gesture. The swiping window publishes its parent windowKey\n * here when the gesture starts; the parent Modal reads it (via\n * `useSyncExternalStore`) and renders itself visible underneath the sliding\n * panel even though it isn't the active window. When the gesture ends or\n * cancels, the parent key is cleared and the parent goes back to hidden.\n */\n\nlet _parentKey: string | null = null;\nconst subs = new Set<() => void>();\n\nexport function getSwipingParentKey(): string | null {\n return _parentKey;\n}\n\nexport function setSwipingParentKey(key: string | null): void {\n if (_parentKey === key) return;\n _parentKey = key;\n for (const cb of subs) cb();\n}\n\nexport function subscribeSwipingParentKey(cb: () => void): () => void {\n subs.add(cb);\n return () => { subs.delete(cb); };\n}\n","/**\n * Shell-side user-preferences surface — the package never owns where prefs\n * live. The consumer supplies a hook returning the current prefs object plus\n * a save callback; the shell reads keys it knows about (theme,\n * taskbar_position, taskbar_size, world_clocks, favorite_documents,\n * desktop_folders, desktop_snap, notepad_notes, …) and patches them.\n *\n * When no provider is mounted, the shell falls back to localStorage scoped\n * by `storageKey` — so the package works out of the box for a backend-less\n * consumer.\n */\nimport { createContext, useContext, useState, useCallback, type ReactNode } from 'react';\n\nexport interface ShellPrefsAdapter {\n /** The current prefs object. The shell reads its known keys directly off\n * this; consumer-private keys are ignored. */\n prefs: Record<string, any>;\n /** Patch a subset of prefs. The shell calls this with shallow diffs. */\n save: (patch: Record<string, any>) => Promise<void> | void;\n}\n\nconst ShellPrefsContext = createContext<ShellPrefsAdapter | null>(null);\n\nexport function ShellPrefsProvider({\n value,\n children,\n}: { value: ShellPrefsAdapter; children: ReactNode }) {\n return <ShellPrefsContext.Provider value={value}>{children}</ShellPrefsContext.Provider>;\n}\n\n/** Default localStorage-backed adapter — useful when the consumer doesn't\n * ship a backend. Pass the result into <ShellPrefsProvider value={…}>.\n *\n * `defaults` are merged behind whatever's already stored, so they only\n * apply for keys the user hasn't set yet. Useful for opting out of bundled\n * features (e.g. `{ show_desktop_version: false }`). */\nexport function useLocalStoragePrefs(\n storageKey = 'react-os-shell:prefs',\n defaults?: Record<string, any>,\n): ShellPrefsAdapter {\n const [prefs, setPrefs] = useState<Record<string, any>>(() => {\n try {\n const stored = JSON.parse(localStorage.getItem(storageKey) || '{}');\n return { ...(defaults ?? {}), ...stored };\n } catch { return { ...(defaults ?? {}) }; }\n });\n const save = useCallback((patch: Record<string, any>) => {\n setPrefs(prev => {\n const next = { ...prev, ...patch };\n try { localStorage.setItem(storageKey, JSON.stringify(next)); } catch {}\n return next;\n });\n }, [storageKey]);\n return { prefs, save };\n}\n\n/** Returns the active prefs adapter. When no provider is mounted, returns a\n * no-op adapter that reads as empty and silently drops saves — components\n * still render, but persistence is a no-op. */\nexport function useShellPrefs(): ShellPrefsAdapter {\n const ctx = useContext(ShellPrefsContext);\n if (ctx) return ctx;\n return { prefs: {}, save: () => {} };\n}\n","/**\n * Work-area geometry — the rectangle a maximized window occupies.\n *\n * Layout owns the chrome (taskbar, sidebar strip) and publishes its sizes as\n * CSS custom properties on <html>; everything here derives from those, so the\n * maths has a single input and no React dependency. Modal reads them live\n * rather than through context, which is what lets an open window react to a\n * preference change without remounting.\n */\n\n/** Width of the persistent left strip that sidebar layout mode reserves. */\nexport const SIDEBAR_STRIP_W = 280;\n\nexport interface Box { x: number; y: number; w: number; h: number }\n\n/** The viewport minus the taskbar, and minus the sidebar strip when one is reserved. */\nexport function computeMaximizedBox(): Box {\n const cs = getComputedStyle(document.documentElement);\n const taskbarH = parseInt(cs.getPropertyValue('--taskbar-height')) || 0;\n const taskbarW = 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 x: (tbPos === 'left' ? taskbarW : 0) + sidebarW,\n y: tbPos === 'top' ? taskbarH : 0,\n w: window.innerWidth - (tbPos === 'left' || tbPos === 'right' ? taskbarW : 0) - sidebarW,\n h: window.innerHeight - (tbPos === 'top' || tbPos === 'bottom' ? taskbarH : 0),\n };\n}\n\n/**\n * Is this saved box really \"the whole work area\" — i.e. was it saved by a\n * maximized window rather than chosen by the user?\n *\n * Both axes must fill, which is what separates a maximized box from the\n * dangerous near-misses: a half-screen snap fills the height only, a short\n * full-width window fills the width only. The tolerance absorbs sub-pixel\n * rects and browser zoom, where an exact match would miss the real boxes.\n *\n * Widths are matched against the work area both with and without the sidebar\n * strip, because a box saved in sidebar mode has to be recognised from classic\n * mode — and vice versa, since the caller may run either side of Layout\n * releasing the strip.\n */\nexport function boxFillsWorkArea(box: Box, workArea: Box, sidebarReserved: boolean): boolean {\n const TOL = 4;\n const otherW = sidebarReserved ? workArea.w + SIDEBAR_STRIP_W : workArea.w - SIDEBAR_STRIP_W;\n const fillsWidth = Math.abs(box.w - workArea.w) <= TOL || Math.abs(box.w - otherW) <= TOL;\n return Math.abs(box.h - workArea.h) <= TOL && fillsWidth;\n}\n\n/** Whether sidebar layout mode currently reserves its left strip. */\nexport function isSidebarStripReserved(): boolean {\n return (parseInt(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-width')) || 0) > 0;\n}\n\n/**\n * Sidebar layout mode locks every non-widget window to the maximized box.\n * Published by Layout as `--layout-mode` on <html>.\n */\nexport function readAlwaysMaximizedFlag(): boolean {\n if (typeof document === 'undefined') return false;\n return getComputedStyle(document.documentElement).getPropertyValue('--layout-mode')?.trim() === 'sidebar';\n}\n","import { useEffect, useLayoutEffect, useCallback, useRef, useState, createContext, useContext, useSyncExternalStore, cloneElement, isValidElement, type ReactNode, type ReactElement } from 'react';\nimport { createPortal } from 'react-dom';\nimport { XMarkIcon } from '@heroicons/react/24/outline';\nimport { confirm } from './ConfirmDialog';\nimport { useWindowManager } from './WindowManager';\nimport { glassStyle as getGlassStyle } from '../utils/glass';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider } from './PopupMenu';\nimport { useIsMobile } from './useIsMobile';\nimport { getSwipingParentKey, setSwipingParentKey, subscribeSwipingParentKey } from './mobileSwipeStore';\nimport WindowErrorBoundary from './WindowErrorBoundary';\nimport { useShellPrefs } from './ShellPrefs';\nimport { boxFillsWorkArea, computeMaximizedBox, isSidebarStripReserved, readAlwaysMaximizedFlag } from './workArea';\n\n/** Context that passes the modal's unique ID to children */\nconst ModalIdContext = createContext<string>('');\n\n/** Desktop-shortcut spec for the window menu's \"Add to Desktop\" item —\n * the shape saved into `prefs.favorite_documents` (what <Desktop> renders\n * as icons). Pages use entityType 'page' keyed by route; entities use\n * their registry key + id. */\nexport interface WindowShortcutSpec {\n entityType: string;\n entityId: string;\n label: string;\n}\n\nconst WindowShortcutContext = createContext<WindowShortcutSpec | null>(null);\n\n/** Wraps each top-level app window (see WindowManagerProvider) so its Modal\n * can offer \"Add to Desktop\" — including consumer components that render\n * their own Modal, which a child-component approach can't reach. The\n * outermost Modal consumes the spec and re-provides null, so nested\n * dialogs don't repeat the item. */\nexport function WindowShortcutProvider({ spec, children }: { spec: WindowShortcutSpec | null; children: ReactNode }) {\n return <WindowShortcutContext.Provider value={spec}>{children}</WindowShortcutContext.Provider>;\n}\n\n/**\n * Extract just the text from a title ReactNode for non-interactive\n * contexts like the expose-mode tile header — strips buttons, inputs,\n * kbd hints, and SVG decorations so only the document/page name shows.\n *\n * The title can be anything from a plain string to a flex row with an\n * inline edit button and a copy icon. Tiles in expose mode are scaled\n * down and not interactive (clicking focuses the window), so rendering\n * the whole tree is at best ugly and at worst clipped.\n */\nconst TITLE_STRIP_TYPES = new Set(['button', 'input', 'textarea', 'select', 'kbd', 'svg']);\nfunction extractTitleText(node: ReactNode): string {\n if (node == null || typeof node === 'boolean') return '';\n if (typeof node === 'string') return node;\n if (typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(extractTitleText).join('');\n if (isValidElement(node)) {\n const el = node as ReactElement<{ children?: ReactNode }>;\n const tag = typeof el.type === 'string' ? el.type : '';\n if (TITLE_STRIP_TYPES.has(tag)) return '';\n return extractTitleText(el.props?.children);\n }\n return '';\n}\n\n/** Hook for widget components to register a settings handler for the right-click menu. */\nexport function useWidgetSettings(handler: () => void) {\n const id = useContext(ModalIdContext);\n useEffect(() => {\n if (!id) return;\n const listener = (e: Event) => { if ((e as CustomEvent).detail === id) handler(); };\n window.addEventListener('widget-open-settings', listener);\n return () => window.removeEventListener('widget-open-settings', listener);\n }, [handler, id]);\n}\n\n/** Registry for extra window menu items added by child components */\nconst _extraMenuItems: Record<string, { label: string; icon?: React.ReactNode; onClick: () => void }[]> = {};\n\n/** Hook to add custom items to the window title menu from inside a modal */\nexport function useWindowMenuItem(label: string, onClick: () => void, icon?: React.ReactNode) {\n const id = useContext(ModalIdContext);\n useEffect(() => {\n if (!id) return;\n if (!_extraMenuItems[id]) _extraMenuItems[id] = [];\n const item = { label, icon, onClick };\n _extraMenuItems[id].push(item);\n return () => { _extraMenuItems[id] = (_extraMenuItems[id] || []).filter(i => i !== item); };\n }, [id, label, onClick, icon]);\n}\n\n/** Component that updates the surrounding window's title bar. Render anywhere\n * inside a Modal-rendered page. Cross-bundle safe (uses DOM traversal rather\n * than React Context, which has separate instances in each bundle). */\nexport function WindowTitle({ title }: { title: string }) {\n const ref = useRef<HTMLSpanElement>(null);\n useEffect(() => {\n const handle = setTimeout(() => {\n const panel = ref.current?.closest('[data-modal-id]');\n const id = panel?.getAttribute('data-modal-id');\n if (id) window.dispatchEvent(new CustomEvent('window-title-update', { detail: { id, title } }));\n }, 0);\n return () => clearTimeout(handle);\n }, [title]);\n return <span ref={ref} style={{ display: 'none' }} aria-hidden=\"true\" />;\n}\n\n/** @deprecated Use <WindowTitle> instead — the hook variant doesn't work\n * across bundle boundaries (apps barrel has its own ModalIdContext). */\nexport function useWindowTitle(_title: string) {\n // Intentionally a no-op now. Kept for type compatibility during migration.\n}\n\n/**\n * Portal component — renders children into the nearest Modal's footer actions area.\n * position=\"left\" for destructive actions (Delete), default is right for primary actions.\n */\nexport function CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n navigator.clipboard.writeText(text).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n };\n return (\n <button onClick={handleCopy} title={copied ? 'Copied!' : `Copy ${text}`}\n className=\"shrink-0 text-gray-400 hover:text-gray-600 transition-colors\">\n {copied ? (\n <svg className=\"w-4 h-4 text-green-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" /></svg>\n ) : (\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" /></svg>\n )}\n </button>\n );\n}\n\n// Context to pass action container refs from Modal to ModalActions\ninterface ModalActionsCtx {\n rightRef: React.RefObject<HTMLDivElement | null>;\n leftRef: React.RefObject<HTMLDivElement | null>;\n notify: () => void;\n active: boolean;\n isDirty: boolean;\n}\nconst ModalActionsContext = createContext<ModalActionsCtx | null>(null);\n\n/** Hook to check if the current modal is active (frontmost) */\nexport function useModalActive(): boolean {\n const activeId = useSyncExternalStore(subscribeActive, getActiveModalId);\n const ctx = useContext(ModalActionsContext);\n return ctx?.active ?? (activationOrder.length <= 1 || activeId != null);\n}\n\nexport function ModalActions({ children, position = 'right' }: { children: React.ReactNode; position?: 'left' | 'right' }) {\n const ctx = useContext(ModalActionsContext);\n const [target, setTarget] = useState<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!ctx) return;\n const ref = position === 'left' ? ctx.leftRef : ctx.rightRef;\n const check = () => {\n if (ref.current) { setTarget(ref.current); ctx.notify(); return true; }\n return false;\n };\n if (check()) return;\n // Ref might not be set yet — retry\n const t = setInterval(() => { if (check()) clearInterval(t); }, 50);\n const cleanup = setTimeout(() => clearInterval(t), 2000);\n return () => { clearInterval(t); clearTimeout(cleanup); };\n }, [ctx, position]);\n\n if (!target) return null;\n return createPortal(children, target);\n}\n\n/**\n * Cancel button that checks for unsaved changes before calling onClick.\n * Automatically detects dirty state from the nearest Modal context.\n */\nexport function CancelButton({ onClick, children, className }: { onClick: () => void; children?: React.ReactNode; className?: string }) {\n const ctx = useContext(ModalActionsContext);\n\n const handleClick = async () => {\n if (ctx?.isDirty) {\n const { confirm } = await import('./ConfirmDialog');\n const ok = await confirm({\n title: 'Discard changes?',\n message: 'You have unsaved changes. Are you sure you want to cancel? All changes will be lost.',\n confirmLabel: 'Discard',\n cancelLabel: 'Keep Editing',\n variant: 'warning',\n });\n if (!ok) return;\n }\n onClick();\n };\n\n return (\n <button type=\"button\" onClick={handleClick}\n className={className || 'bg-white text-gray-700 border border-gray-300 px-4 py-2 text-sm font-medium rounded-lg hover:bg-gray-50'}>\n {children || 'Cancel'}\n </button>\n );\n}\n\n// ── Window position persistence ──\nconst WP_KEY = 'erp_window_positions';\nlet _windowPositions: Record<string, { x: number; y: number; w: number; h: number }> = {};\ntry {\n const stored = localStorage.getItem(WP_KEY);\n if (stored) _windowPositions = JSON.parse(stored);\n} catch {}\nlet _saveTimer: ReturnType<typeof setTimeout> | null = null;\nfunction _savePositionsDebounced() {\n if (_saveTimer) clearTimeout(_saveTimer);\n _saveTimer = setTimeout(() => {\n try { localStorage.setItem(WP_KEY, JSON.stringify(_windowPositions)); } catch {}\n }, 500);\n}\n\n// ── Window activation (z-order) persistence ──\nconst AO_KEY = 'erp_activation_order';\nlet _activationOrderKeys: string[] = [];\ntry {\n const stored = localStorage.getItem(AO_KEY);\n const parsed = stored ? JSON.parse(stored) : null;\n if (Array.isArray(parsed) && parsed.every(k => typeof k === 'string')) _activationOrderKeys = parsed;\n} catch {}\nlet _saveOrderTimer: ReturnType<typeof setTimeout> | null = null;\nfunction _saveOrderDebounced() {\n if (_saveOrderTimer) clearTimeout(_saveOrderTimer);\n _saveOrderTimer = setTimeout(() => {\n try { localStorage.setItem(AO_KEY, JSON.stringify(_activationOrderKeys)); } catch {}\n }, 500);\n}\n\n/**\n * Seed an initial position for a window — applied only when no saved\n * position already exists for the given key. Use this from the consumer\n * to lay out the first-run desktop without overwriting whatever the user\n * has subsequently dragged the windows to.\n *\n * The key matches the window's `windowKey` — for `openPage('/weather')`\n * that's `'page:/weather'`.\n */\nexport function setWindowDefaultPosition(key: string, pos: { x: number; y: number; w: number; h: number }) {\n if (_windowPositions[key]) return;\n _windowPositions[key] = pos;\n _savePositionsDebounced();\n}\n\n/** Read the saved box for a window key (viewport-relative px), or null. */\nexport function getWindowPosition(key: string): { x: number; y: number; w: number; h: number } | null {\n return _windowPositions[key] ? { ..._windowPositions[key] } : null;\n}\n\n/**\n * Force a window's saved position — unlike `setWindowDefaultPosition` this\n * overwrites any existing entry. Use when the consumer wants to deliberately\n * (re)place a window, e.g. the Widget Manager dropping a freshly-added widget\n * into a tidy top-left slot regardless of where it last sat. For `autoHeight`\n * windows the `h` here is only a first-paint placeholder — the window\n * re-measures its content height on open.\n */\nexport function setWindowPosition(key: string, pos: { x: number; y: number; w: number; h: number }) {\n _windowPositions[key] = pos;\n _savePositionsDebounced();\n}\n\n/**\n * Forget every saved box that is really \"the whole work area\".\n *\n * A window that was maximized persists its full-screen geometry under its\n * `windowKey`, so it reopens filling the screen even after the shell is back\n * in windowed mode — the box outlives the setting that produced it. Layout\n * Mode → Classic calls this so those windows fall back to the normal size\n * ladder on their next open. `boxFillsWorkArea` is what keeps it from\n * forgetting a window the user sized and placed by hand.\n */\nexport function forgetMaximizedWindowBoxes() {\n const workArea = computeMaximizedBox();\n const sidebarReserved = isSidebarStripReserved();\n let changed = false;\n for (const key of Object.keys(_windowPositions)) {\n if (boxFillsWorkArea(_windowPositions[key], workArea, sidebarReserved)) {\n delete _windowPositions[key];\n changed = true;\n }\n }\n if (changed) _savePositionsDebounced();\n}\n\ninterface ModalProps {\n open: boolean;\n onClose: () => void;\n title: React.ReactNode;\n /** Window icon — shown before title, clicking it opens window menu */\n icon?: React.ReactNode;\n /** Text to copy when the copy icon in the header is clicked (e.g. entity number) */\n copyText?: string;\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';\n dirty?: boolean | 'auto';\n onNext?: () => void;\n onPrev?: () => void;\n footer?: React.ReactNode;\n /** When true, body uses overflow-hidden — child content manages its own scrolling */\n bodyScroll?: false;\n /** Custom minimize handler — called instead of the default global minimize */\n onMinimize?: (savedBox: { x: number; y: number; w: number; h: number; maximized: boolean }) => void;\n /** Restore to a previously saved position/size */\n initialBox?: { x: number; y: number; w: number; h: number; maximized: boolean };\n /** Footer actions (right side) — alternative to ModalActions portal */\n actions?: React.ReactNode;\n /** Footer actions (left side) — alternative to ModalActions portal */\n actionsLeft?: React.ReactNode;\n /** Allow the window to be pinned on top of all others */\n allowPinOnTop?: boolean;\n /** Initial position hint */\n initialPosition?: 'top-right' | 'top-left';\n /** Widget mode: no title/footer, drag anywhere, right-click context menu */\n widget?: boolean;\n /** Compact title bar: smaller header with title + close only, no minimize/maximize */\n compact?: boolean;\n /** App-style window: full title bar but body uses no padding so the app's own\n * chrome (toolbars, menus) sits flush against the window frame. For\n * self-chromed apps like Preview, Files, Browser. Implies `bodyScroll: false`\n * — apps manage their own scrolling internally. */\n appStyle?: boolean;\n /** Flush body: keeps the STANDARD full title bar and footer, but drops the\n * body padding so the content sits flush to the window edges (e.g. a\n * `<SidebarLayout>`). Implies `bodyScroll: false`. */\n flushBody?: boolean;\n /** Auto-size height based on content. Window's height adapts to whatever the\n * body renders; floored by `autoMinHeight` and capped to the available\n * viewport so nothing overflows the screen. Naturally-flowing content (a\n * form, a table) shrinks the window to hug it; a fill-height root (`h-full` /\n * `flex-1` between a fixed header and footer) keeps the normal size-ladder\n * height and scrolls internally rather than collapsing. */\n autoHeight?: boolean;\n /** Minimum height (px) when `autoHeight` is on. Defaults to 240. */\n autoMinHeight?: number;\n /** Custom menu items for widget right-click context menu */\n widgetMenu?: React.ReactNode;\n /** Custom window dimensions [width, height] in pixels */\n dimensions?: [number, number];\n /** Stable key for persisting window position to sessionStorage */\n windowKey?: string;\n /** windowKey of whichever window was active when this one opened. On\n * mobile, swipe-to-back broadcasts this value so the parent window can\n * un-hide itself underneath the sliding panel. */\n openedFromKey?: string;\n /** Per-section window accent (SG#00372): an `R G B` triple (e.g.\n * '91 141 190'). When set, the panel publishes it as the\n * `--window-accent-rgb` CSS custom property and renders a thin accent\n * stripe across the top of the title bar, so overlapping windows from\n * different app sections are distinguishable at a glance. The header\n * itself stays theme-neutral — themes and the user's custom header\n * colour are untouched. Absent = exactly the previous rendering. */\n accentRgb?: string;\n children: React.ReactNode;\n}\n\nconst sizeDefaults: Record<string, number> = {\n sm: 384, md: 512, lg: 672, xl: 896, '2xl': 1152, '3xl': 1408,\n};\n\n// The user's \"Default window size\" preference (Settings → Behavior). Layout\n// publishes it as the `--default-window-size` CSS var; here it scales a\n// freshly-opened window's initial height. 'large' is the default and opens\n// windows taller than 'medium' (the old fixed ladder), 'small' opens them\n// shorter, and 'maximized' opens non-widget windows filling the work area\n// (handled separately via the maximized state). Widgets ignore the pref —\n// they're content-sized utilities. Windows with explicit `dimensions` keep\n// their height for small/medium/large.\ntype WindowSizePref = 'small' | 'medium' | 'large' | 'maximized';\nconst readDefaultWindowSize = (): WindowSizePref => {\n if (typeof document === 'undefined') return 'large';\n const v = getComputedStyle(document.documentElement).getPropertyValue('--default-window-size')?.trim();\n return v === 'small' || v === 'medium' || v === 'maximized' ? v : 'large';\n};\n// Multiplier applied to the per-size open-height ladder. 'medium' reproduces\n// the previous fixed heights; 'large' (the default) opens 25 % taller.\nconst windowHeightScale: Record<WindowSizePref, number> = {\n small: 0.8, medium: 1, large: 1.25, maximized: 1.25,\n};\n\n// Track modal depth for stacking z-index and ESC handling\nexport let modalDepth = 0;\nexport const modalStack: string[] = [];\nexport const modalDepthRef = { get: () => modalDepth, inc: () => ++modalDepth, dec: () => --modalDepth };\n\n// Activation order — last element is the frontmost modal\nconst activationOrder: string[] = [];\nconst activeListeners = new Set<() => void>();\n// Bi-directional map between live (random per-mount) modalIds and stable\n// window keys (`windowKey || copyText`). Stable keys outlive page refreshes\n// and let us slot remounted modals back into their previous z-order.\nconst _modalIdByKey = new Map<string, string>();\nconst _keyByModalId = new Map<string, string>();\n\nfunction _insertModalIdForKey(modalId: string, key: string) {\n const savedIdx = _activationOrderKeys.indexOf(key);\n if (savedIdx === -1) { activationOrder.push(modalId); return; }\n let insertAt = activationOrder.length;\n for (let i = 0; i < activationOrder.length; i++) {\n const otherKey = _keyByModalId.get(activationOrder[i]);\n if (!otherKey) continue;\n const otherIdx = _activationOrderKeys.indexOf(otherKey);\n if (otherIdx > savedIdx) { insertAt = i; break; }\n }\n activationOrder.splice(insertAt, 0, modalId);\n}\n\nexport function mountModal(modalId: string, key: string | null) {\n if (!key) {\n activationOrder.push(modalId);\n } else {\n _modalIdByKey.set(key, modalId);\n _keyByModalId.set(modalId, key);\n _insertModalIdForKey(modalId, key);\n if (_activationOrderKeys.indexOf(key) === -1) {\n _activationOrderKeys.push(key);\n _saveOrderDebounced();\n }\n }\n activeListeners.forEach(fn => fn());\n window.dispatchEvent(new CustomEvent('modal-reorder'));\n}\n\nexport function activateModal(id: string) {\n const idx = activationOrder.indexOf(id);\n if (idx !== -1) activationOrder.splice(idx, 1);\n activationOrder.push(id);\n const key = _keyByModalId.get(id);\n if (key) {\n const kidx = _activationOrderKeys.indexOf(key);\n if (kidx !== -1) _activationOrderKeys.splice(kidx, 1);\n _activationOrderKeys.push(key);\n _saveOrderDebounced();\n }\n activeListeners.forEach(fn => fn());\n window.dispatchEvent(new CustomEvent('modal-reorder'));\n}\n\nfunction _minimizeModal(modalId: string) {\n const idx = activationOrder.indexOf(modalId);\n if (idx !== -1) activationOrder.splice(idx, 1);\n const key = _keyByModalId.get(modalId);\n if (key) {\n const kidx = _activationOrderKeys.indexOf(key);\n if (kidx !== -1) { _activationOrderKeys.splice(kidx, 1); _saveOrderDebounced(); }\n }\n activeListeners.forEach(fn => fn());\n window.dispatchEvent(new CustomEvent('modal-reorder'));\n}\n\n// Track which modal IDs belong to widget windows; widgets stay visible when\n// the user double-clicks the desktop (\"show desktop\"), only regular windows\n// are hidden.\nconst widgetIds = new Set<string>();\nexport function deactivateAllModals() {\n for (let i = activationOrder.length - 1; i >= 0; i--) {\n if (!widgetIds.has(activationOrder[i])) activationOrder.splice(i, 1);\n }\n _activationOrderKeys = _activationOrderKeys.filter(k => {\n const mid = _modalIdByKey.get(k);\n return mid != null && widgetIds.has(mid);\n });\n _saveOrderDebounced();\n activeListeners.forEach(fn => fn());\n window.dispatchEvent(new CustomEvent('modal-reorder'));\n}\n// ── Window snapping ──────────────────────────────────────────────────────\n// Aero/Magnet-style edge snapping. The drag handler watches the cursor\n// position and calls into these helpers. A single translucent preview\n// element is reused across drags (lazily created, kept around in body).\n\ntype SnapZone = 'top' | 'left' | 'right' | 'tl' | 'tr' | 'bl' | 'br';\nconst EDGE_THRESHOLD = 8; // px from edge to trigger half-screen snap\nconst CORNER_THRESHOLD = 32; // px square at each corner for quarter-screen snap\n\ninterface Box { x: number; y: number; w: number; h: number; }\n\nfunction workArea(): Box {\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 0;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const tbPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const x = tbPos === 'left' ? taskbarW : 0;\n const y = tbPos === 'top' ? taskbarH : 0;\n const w = window.innerWidth - (tbPos === 'left' || tbPos === 'right' ? taskbarW : 0);\n const h = window.innerHeight - (tbPos === 'top' || tbPos === 'bottom' ? taskbarH : 0);\n return { x, y, w, h };\n}\n\n// ── Keeping windows reachable ────────────────────────────────────────────\n// A window may be parked mostly off-screen on purpose — macOS allows it, and\n// so do we. What neither macOS nor Windows allows is a window you can no\n// longer grab: Windows pins the caption inside the work area, macOS forbids\n// going under the menu bar. We enforce the same invariant, which is also the\n// only defence against the browser viewport shrinking out from under a window.\nconst CAPTION_H = 40; // title-bar height that must stay inside the work area\nconst MIN_VISIBLE_X = 80; // horizontal strip that must stay grabbable\n\n/** Smallest move that keeps `box` grabbable. Never resizes. Returns `box`\n * itself when nothing moved, so callers can `setBox(clampReachable)` without\n * forcing a re-render or re-persisting an untouched window. */\nfunction clampReachable(box: Box, a: Box = workArea()): Box {\n const x = Math.min(Math.max(box.x, a.x + MIN_VISIBLE_X - box.w), a.x + a.w - MIN_VISIBLE_X);\n const y = Math.min(Math.max(box.y, a.y), a.y + a.h - CAPTION_H);\n return x === box.x && y === box.y ? box : { ...box, x, y };\n}\n\n/** Smallest move that brings the whole window back on screen. Shrinks it only\n * when it is larger than the work area. */\nfunction clampFullyVisible(box: Box, a: Box = workArea()): Box {\n const w = Math.min(box.w, a.w);\n const h = Math.min(box.h, a.h);\n return {\n w, h,\n x: Math.min(Math.max(box.x, a.x), a.x + a.w - w),\n y: Math.min(Math.max(box.y, a.y), a.y + a.h - h),\n };\n}\n\n/** Does every edge of this window sit inside the work area? A hidden panel\n * (minimised, or hidden by show-desktop) measures 0×0 and is never reported\n * off-screen — there is nothing to rescue. */\nexport function isPanelFullyVisible(panel: HTMLElement): boolean {\n const r = panel.getBoundingClientRect();\n if (r.width === 0 || r.height === 0) return true;\n const a = workArea();\n const EPS = 1;\n return r.left >= a.x - EPS && r.top >= a.y - EPS\n && r.right <= a.x + a.w + EPS && r.bottom <= a.y + a.h + EPS;\n}\n\n/** Bearing in degrees from the work-area centre toward an off-screen window\n * (0 = right, 90 = down), for the taskbar's off-screen chevron. Null when the\n * window is fully visible. */\nexport function panelOffscreenBearing(panel: HTMLElement): number | null {\n if (isPanelFullyVisible(panel)) return null;\n const r = panel.getBoundingClientRect();\n const a = workArea();\n const dx = (r.left + r.width / 2) - (a.x + a.w / 2);\n const dy = (r.top + r.height / 2) - (a.y + a.h / 2);\n return Math.atan2(dy, dx) * 180 / Math.PI;\n}\n\n/** Ask the window owning `windowKey` to slide fully back into the work area\n * and take focus. Handled by the `modal-reveal` listener each Modal installs.\n * Unlike `modal-center` this keeps the window's size and roughly its position\n * — it is a rescue, not a re-layout. */\nexport function revealWindow(windowKey: string) {\n window.dispatchEvent(new CustomEvent('modal-reveal', { detail: { windowKey } }));\n}\n\nfunction calcSnapBox(zone: SnapZone): Box {\n const a = workArea();\n const halfW = Math.floor(a.w / 2);\n const halfH = Math.floor(a.h / 2);\n switch (zone) {\n case 'top': return { x: a.x, y: a.y, w: a.w, h: a.h };\n case 'left': return { x: a.x, y: a.y, w: halfW, h: a.h };\n case 'right': return { x: a.x + halfW, y: a.y, w: a.w - halfW, h: a.h };\n case 'tl': return { x: a.x, y: a.y, w: halfW, h: halfH };\n case 'tr': return { x: a.x + halfW, y: a.y, w: a.w - halfW, h: halfH };\n case 'bl': return { x: a.x, y: a.y + halfH, w: halfW, h: a.h - halfH };\n case 'br': return { x: a.x + halfW, y: a.y + halfH, w: a.w - halfW, h: a.h - halfH };\n }\n}\n\nfunction detectSnapZone(clientX: number, clientY: number): SnapZone | null {\n const a = workArea();\n const nearLeft = clientX <= a.x + EDGE_THRESHOLD;\n const nearRight = clientX >= a.x + a.w - EDGE_THRESHOLD;\n const nearTop = clientY <= a.y + EDGE_THRESHOLD;\n const nearBottom = clientY >= a.y + a.h - EDGE_THRESHOLD;\n // Corners take priority over edges (larger detection square).\n const cornerLeft = clientX <= a.x + CORNER_THRESHOLD;\n const cornerRight = clientX >= a.x + a.w - CORNER_THRESHOLD;\n const cornerTop = clientY <= a.y + CORNER_THRESHOLD;\n const cornerBottom = clientY >= a.y + a.h - CORNER_THRESHOLD;\n if (nearTop && cornerLeft) return 'tl';\n if (nearTop && cornerRight) return 'tr';\n if (nearBottom && cornerLeft) return 'bl';\n if (nearBottom && cornerRight)return 'br';\n if (cornerTop && nearLeft) return 'tl';\n if (cornerTop && nearRight) return 'tr';\n if (cornerBottom && nearLeft) return 'bl';\n if (cornerBottom && nearRight)return 'br';\n if (nearTop) return 'top';\n if (nearLeft) return 'left';\n if (nearRight) return 'right';\n return null;\n}\n\nlet snapPreviewEl: HTMLDivElement | null = null;\nfunction getSnapPreviewEl(): HTMLDivElement {\n if (!snapPreviewEl) {\n snapPreviewEl = document.createElement('div');\n snapPreviewEl.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 40',\n 'border-radius: 8px',\n 'background: rgba(59, 130, 246, 0.18)',\n 'border: 2px solid rgb(59, 130, 246)',\n 'transition: left 120ms ease, top 120ms ease, width 120ms ease, height 120ms ease, opacity 120ms ease',\n 'opacity: 0',\n 'display: none',\n ].join(';');\n document.body.appendChild(snapPreviewEl);\n }\n return snapPreviewEl;\n}\nfunction showSnapPreview(box: Box) {\n const el = getSnapPreviewEl();\n el.style.display = 'block';\n el.style.left = `${box.x}px`;\n el.style.top = `${box.y}px`;\n el.style.width = `${box.w}px`;\n el.style.height = `${box.h}px`;\n el.style.opacity = '1';\n}\nfunction hideSnapPreview() {\n if (!snapPreviewEl) return;\n snapPreviewEl.style.opacity = '0';\n snapPreviewEl.style.display = 'none';\n}\n\n// ── Pointer-gesture shield (drag/resize) ──────────────────────────────\n// A window drag/resize must keep receiving pointer events for the WHOLE\n// gesture. The move/up listeners live on `window`, which only sees events\n// dispatched within this document. Without pointer capture, the instant the\n// cursor crosses an overlapping window whose body is an <iframe> (e.g. an\n// embedded editor preview), the browser routes pointermove/pointerup into that\n// iframe's own document — the parent listeners fall silent, so the drag freezes\n// and can stick to the cursor (\"the background window interferes with the\n// active window\"). For the gesture's duration we therefore:\n// 1. capture the pointer on the grabbed handle so events stay in this doc;\n// 2. mount a transparent full-viewport shield so the pointer never reaches a\n// background iframe even if capture is unavailable, and background windows\n// don't react to the moving cursor; and\n// 3. flag <body> so every window is promoted to its own compositor layer,\n// so moving the foreground window doesn't repaint the windows behind it.\n// Backdrop-blur is intentionally KEPT on every window for the gesture's\n// duration so the frosted \"wallpaper-through-glass\" look never flickers\n// off while dragging. Only the grabbed (top) window re-samples its blur\n// per frame — its backdrop shifts as it moves; the static windows below\n// it don't, so the cost is a single moving glass surface.\nconst GESTURE_STYLE_ID = 'rosh-gesture-style';\nfunction ensureGestureStyle() {\n if (typeof document === 'undefined' || document.getElementById(GESTURE_STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = GESTURE_STYLE_ID;\n style.textContent =\n // Promote every window to its own compositor layer for the gesture so\n // dragging the foreground window doesn't repaint the ones behind it. We do\n // NOT drop backdrop-blur — every window keeps its frosted glass while a\n // drag/resize is in progress (only the grabbed window re-samples, cheaply).\n 'body.rosh-gesturing [data-modal-panel]{will-change:transform}';\n document.head.appendChild(style);\n}\n\nconst RESIZE_CURSOR: Record<'se' | 'sw' | 'ne' | 'nw' | 'n' | 's' | 'e' | 'w', string> = {\n se: 'nwse-resize', nw: 'nwse-resize', sw: 'nesw-resize', ne: 'nesw-resize',\n n: 'ns-resize', s: 'ns-resize', e: 'ew-resize', w: 'ew-resize',\n};\n\n// Pointer travel (px) before a title-bar / resize press counts as a real\n// drag. Below this a press-and-hold (or a plain click) is NOT a gesture, so\n// `beginPointerGesture` (pointer capture, drag shield, compositor-layer\n// promotion) never engages — a press/click that isn't a drag leaves the\n// windows completely untouched.\nconst DRAG_THRESHOLD = 4;\n\n/** Begin a drag/resize pointer gesture on `handle`: capture the pointer, mount\n * a transparent shield with `cursor`, and promote windows to their own\n * compositor layers. Returns an idempotent cleanup for the pointerup handler. */\nfunction beginPointerGesture(handle: HTMLElement, pointerId: number, cursor: string): () => void {\n ensureGestureStyle();\n try { handle.setPointerCapture(pointerId); } catch { /* capture unsupported for this input */ }\n document.body.classList.add('rosh-gesturing');\n const shield = document.createElement('div');\n shield.setAttribute('data-drag-shield', '');\n shield.style.cssText = `position:fixed;inset:0;z-index:2147483647;cursor:${cursor};background:transparent;touch-action:none`;\n document.body.appendChild(shield);\n let done = false;\n return () => {\n if (done) return;\n done = true;\n try { handle.releasePointerCapture(pointerId); } catch { /* already released on pointerup */ }\n shield.remove();\n document.body.classList.remove('rosh-gesturing');\n };\n}\n\n// Listen for deactivate-all event from taskbar\nwindow.addEventListener('deactivate-all-modals', deactivateAllModals);\nfunction getZForModal(id: string): number {\n const idx = activationOrder.indexOf(id);\n if (idx === -1) return -1; // Behind everything — hidden below listing page\n return 50 + idx * 10;\n}\nexport function getActiveModalId() {\n return activationOrder[activationOrder.length - 1] || null;\n}\nexport function subscribeActive(cb: () => void) {\n activeListeners.add(cb);\n return () => { activeListeners.delete(cb); };\n}\n\n// ── Escape interceptors ────────────────────────────────────────────────────\n// Window content can claim an Escape press before the topmost-modal handler\n// closes the window — e.g. the DXF Preview's measure tool exits AutoCAD-style\n// (clear the command input, then the tool, and only a further Esc closes the\n// window). Interceptors run in registration order; the first to return true\n// consumes the event (the modal neither closes nor sees it). An interceptor\n// is global, so it must check it belongs to the *active* modal itself (via\n// `getActiveModalId()`) before consuming.\nconst escapeInterceptors = new Set<(e: KeyboardEvent) => boolean>();\n/** Register an Escape interceptor; returns an unregister function. */\nexport function registerModalEscapeInterceptor(fn: (e: KeyboardEvent) => boolean): () => void {\n escapeInterceptors.add(fn);\n return () => { escapeInterceptors.delete(fn); };\n}\nfunction runEscapeInterceptors(e: KeyboardEvent): boolean {\n for (const fn of escapeInterceptors) {\n try {\n if (fn(e)) return true;\n } catch { /* a broken interceptor must not block closing */ }\n }\n return false;\n}\n/** Hook: returns true if this modal ID is the frontmost */\nfunction useIsActiveModal(modalId: string): boolean {\n const activeId = useSyncExternalStore(subscribeActive, getActiveModalId);\n return activationOrder.length <= 1 || activeId === modalId;\n}\n\n// ── Exposé / Mission-Control mode ─────────────────────────────────────────\n//\n// Module-level toggle that, when on, visually scales every open modal\n// down into a non-overlapping grid (CSS transform; the modals stay where\n// they are layout-wise, so exiting just clears the transform). Each\n// scaled tile renders the live modal content as a thumbnail, plus a\n// label below; clicking a tile activates that modal and exits exposé;\n// clicking the backdrop (or pressing Escape, or the taskbar button\n// again) exits without changing the active modal.\nlet _exposeOn = false;\nconst _exposeListeners = new Set<() => void>();\nfunction _notifyExpose() { _exposeListeners.forEach((fn) => fn()); }\nfunction subscribeExpose(fn: () => void) { _exposeListeners.add(fn); return () => _exposeListeners.delete(fn); }\nfunction getExposeState() { return _exposeOn; }\nfunction setExposeState(v: boolean) {\n if (_exposeOn === v) return;\n _exposeOn = v;\n _notifyExpose();\n}\nexport function toggleExposeMode() { setExposeState(!_exposeOn); }\nexport function exitExposeMode() { setExposeState(false); }\n\n// When the user clicks a thumbnail to leave exposé, we publish that modal's\n// id here so all panels know which one is the \"spotlight\" pick. The picked\n// panel animates from its tile back to its real box; unpicked panels stay\n// pinned in their tile and fade out so the picked window has a clean stage.\nlet _exposeExitFocusId: string | null = null;\nconst _exposeExitListeners = new Set<() => void>();\nfunction subscribeExposeExitFocus(fn: () => void) {\n _exposeExitListeners.add(fn); return () => _exposeExitListeners.delete(fn);\n}\nfunction getExposeExitFocus() { return _exposeExitFocusId; }\nfunction setExposeExitFocus(id: string | null) {\n if (_exposeExitFocusId === id) return;\n _exposeExitFocusId = id;\n _exposeExitListeners.forEach(fn => fn());\n}\n\n// Keyboard-driven cycling through expose tiles (e.g. an ⌥⇧W shortcut in\n// the host app). The highlight is purely visual feedback while the user\n// browses; only commitExposeHighlight() actually focuses a window. The\n// distinction matters because a host that pre-selects a window on every\n// keystroke would otherwise rapidly thrash window state.\nlet _exposeHighlightId: string | null = null;\nconst _exposeHighlightListeners = new Set<() => void>();\nfunction subscribeExposeHighlight(fn: () => void) {\n _exposeHighlightListeners.add(fn);\n return () => _exposeHighlightListeners.delete(fn);\n}\nfunction getExposeHighlight() { return _exposeHighlightId; }\nexport function setExposeHighlight(id: string | null) {\n if (_exposeHighlightId === id) return;\n _exposeHighlightId = id;\n _exposeHighlightListeners.forEach(fn => fn());\n}\n/**\n * Commit the current keyboard highlight: focus the highlighted window\n * and exit exposé with the standard \"picked tile glides back\" animation.\n * No-op when no highlight is set.\n */\nexport function commitExposeHighlight() {\n if (!_exposeHighlightId) {\n setExposeState(false);\n return;\n }\n const id = _exposeHighlightId;\n // Set exit-focus BEFORE flipping expose off, so panels see the picked\n // id on their first exit-render and pick the right role (matches the\n // mouse-click path at the bottom of this file).\n setExposeExitFocus(id);\n setExposeHighlight(null);\n setExposeState(false);\n}\nexport { getExposeHighlight, subscribeExposeHighlight };\n\n// Backwards-compat — old taskbar wiring fires this event; treat it as a toggle.\nfunction triggerSplitView() {\n setExposeState(!_exposeOn);\n window.dispatchEvent(new CustomEvent('modal-split-view'));\n}\nexport { triggerSplitView };\n\n// Escape exits exposé. Also clear the highlight so a re-entry starts fresh.\nwindow.addEventListener('keydown', (e) => {\n if (_exposeOn && e.key === 'Escape') {\n setExposeHighlight(null);\n setExposeState(false);\n }\n});\n\ninterface ExposeTile { x: number; y: number; w: number; h: number; }\n\n/**\n * Compute the grid cell rectangle for a given modal id when exposé is on.\n * Returns null when the modal isn't tileable (utility / widget / pinned).\n *\n * Layout: roughly-square grid (cols=ceil(sqrt(N)), rows=ceil(N/cols)).\n * Tiles in the last row are centred when the row is short. The grid\n * uses the document work-area minus the taskbar.\n */\nfunction computeExposeTile(modalId: string): ExposeTile | null {\n if (typeof document === 'undefined') return null;\n const allPanels = Array.from(document.querySelectorAll('[data-modal-panel]'));\n // Skip utility, widget, and panels that have been hidden via display:none.\n const tileable: HTMLElement[] = allPanels.filter((p) => {\n const el = p as HTMLElement;\n if (el.hasAttribute('data-utility') || el.hasAttribute('data-widget')) return false;\n if (el.style.display === 'none') return false;\n return true;\n }) as HTMLElement[];\n // Stable ordering by data-modal-id so the same window lands in the same\n // tile each time exposé is opened — avoids visual reshuffling.\n tileable.sort((a, b) => (a.getAttribute('data-modal-id') || '').localeCompare(b.getAttribute('data-modal-id') || ''));\n const myIdx = tileable.findIndex((p) => p.getAttribute('data-modal-id') === modalId);\n const count = tileable.length;\n if (myIdx < 0 || count < 1) return null;\n\n const cols = Math.ceil(Math.sqrt(count));\n const rows = Math.ceil(count / cols);\n const myRow = Math.floor(myIdx / cols);\n const myCol = myIdx % cols;\n const lastRowCount = count - cols * (rows - 1);\n const isLastRow = myRow === rows - 1 && lastRowCount < cols;\n\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 0;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const tbPos = (getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position') || 'bottom').trim();\n const xOffset = tbPos === 'left' ? taskbarW : 0;\n const xRight = tbPos === 'right' ? taskbarW : 0;\n const yOffset = tbPos === 'top' ? taskbarH : 0;\n const yBottom = (tbPos === 'top' || tbPos === 'left' || tbPos === 'right') ? 0 : taskbarH;\n const a = {\n x: xOffset, y: yOffset,\n w: window.innerWidth - xOffset - xRight,\n h: window.innerHeight - yOffset - yBottom,\n };\n // Layout constants. Generous gaps + label space below each tile so the\n // grid reads as separate windows the way macOS Exposé does.\n const gapX = 20;\n const gapY = 14;\n const labelH = 22;\n const cellW = (a.w - gapX * (cols + 1)) / cols;\n const cellH = (a.h - gapY * (rows + 1) - labelH * rows) / rows;\n\n const lastRowOffsetX = isLastRow ? ((cols - lastRowCount) * (cellW + gapX)) / 2 : 0;\n const tileX = a.x + gapX + myCol * (cellW + gapX) + lastRowOffsetX;\n const tileY = a.y + gapY + myRow * (cellH + gapY + labelH);\n return { x: tileX, y: tileY, w: cellW, h: cellH };\n}\n\n/**\n * Singleton backdrop that's shown while exposé mode is on. Click anywhere\n * (outside a window thumbnail) to exit exposé. Should be mounted exactly\n * once, near the root — typically by WindowManager.\n *\n * Fades in when exposé opens and out over the same window the panels use\n * to settle back, so the user sees a single coordinated transition rather\n * than the dim disappearing the instant a tile is clicked.\n */\nexport function ExposeBackdrop() {\n const on = useSyncExternalStore(subscribeExpose, getExposeState);\n const [mounted, setMounted] = useState(on);\n const [visible, setVisible] = useState(on);\n useEffect(() => {\n if (on) {\n setMounted(true);\n // Next frame so the opacity:0 → opacity:1 transition kicks in.\n const id = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(id);\n }\n setVisible(false);\n const t = setTimeout(() => setMounted(false), 280);\n return () => clearTimeout(t);\n }, [on]);\n if (!mounted || typeof document === 'undefined') return null;\n return createPortal(\n <div\n onMouseDown={(e) => { e.stopPropagation(); setExposeState(false); }}\n style={{\n position: 'fixed', inset: 0,\n background: 'rgba(0,0,0,0.55)',\n backdropFilter: 'blur(2px)',\n WebkitBackdropFilter: 'blur(2px)',\n zIndex: 2000,\n cursor: 'pointer',\n opacity: visible ? 1 : 0,\n transition: 'opacity 260ms cubic-bezier(0.2, 0.8, 0.2, 1)',\n pointerEvents: visible ? 'auto' : 'none',\n }}\n />,\n document.body\n );\n}\n\n\nexport default function Modal({ open, onClose, title, icon, copyText, size = 'lg', dirty = false, onNext, onPrev, footer, bodyScroll, onMinimize, initialBox, actions, actionsLeft, allowPinOnTop, initialPosition, widget, compact, appStyle, flushBody, autoHeight, autoMinHeight, widgetMenu, dimensions, windowKey, openedFromKey, accentRgb, children }: ModalProps) {\n const isMobile = useIsMobile();\n // Mobile swipe-from-left-edge gesture: track horizontal offset of the panel.\n // 0 = at rest. While the user is dragging from the left edge, this grows\n // with the finger. On release, if past the threshold the panel slides off\n // and `onClose` fires; otherwise it animates back to 0.\n const [swipeX, setSwipeX] = useState(0);\n const [swipeDragging, setSwipeDragging] = useState(false);\n const swipeStartRef = useRef<{ startX: number; startY: number; pointerId: number } | null>(null);\n const swipeXRef = useRef(0);\n useEffect(() => { swipeXRef.current = swipeX; }, [swipeX]);\n\n const handleEdgePointerDown = useCallback((e: React.PointerEvent) => {\n if (!isMobile) return;\n swipeStartRef.current = { startX: e.clientX, startY: e.clientY, pointerId: e.pointerId };\n setSwipeDragging(true);\n // Tell sibling Modals which window's parent should reveal itself behind\n // this swipe — `null` (no `openedFromKey`) means \"this is a top-level\n // app, fall back to the home wallpaper\".\n setSwipingParentKey(openedFromKey ?? null);\n }, [isMobile, openedFromKey]);\n\n // Subscribe to the swipe store so non-active panels can render themselves\n // visible underneath a sibling that's currently being swiped to its parent.\n const swipingParentKey = useSyncExternalStore(subscribeSwipingParentKey, getSwipingParentKey);\n\n // Move + release wired globally during a swipe so the panel keeps tracking\n // the finger even if it leaves the edge zone (e.g. the user drags clear\n // across the screen).\n useEffect(() => {\n if (!swipeDragging) return;\n const onMove = (ev: PointerEvent) => {\n if (!swipeStartRef.current) return;\n const dx = ev.clientX - swipeStartRef.current.startX;\n const dy = Math.abs(ev.clientY - swipeStartRef.current.startY);\n if (dy > Math.abs(dx) + 12) {\n // Vertical movement dominates — abandon the gesture so the user can\n // scroll content normally.\n swipeStartRef.current = null;\n setSwipeDragging(false);\n setSwipeX(0);\n setSwipingParentKey(null);\n return;\n }\n setSwipeX(Math.max(0, dx));\n };\n const onUp = () => {\n if (!swipeStartRef.current) return;\n const threshold = window.innerWidth * 0.3;\n const past = swipeXRef.current > threshold;\n swipeStartRef.current = null;\n setSwipeDragging(false);\n if (past) {\n // Swipe-from-edge closes the current window so whatever was opened\n // before it (the parent list, or — if this was a top-level app —\n // home) becomes visible underneath. MobileShell falls back to home\n // when the close empties openWindows.\n setSwipeX(window.innerWidth);\n setTimeout(() => {\n onClose();\n setSwipeX(0);\n setSwipingParentKey(null);\n }, 180);\n } else {\n setSwipeX(0);\n setSwipingParentKey(null);\n }\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onUp);\n return () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n window.removeEventListener('pointercancel', onUp);\n };\n }, [swipeDragging]);\n const [displayTitle, setDisplayTitle] = useState<React.ReactNode>(title);\n useEffect(() => { setDisplayTitle(title); }, [title]);\n const [touched, setTouched] = useState(false);\n const [pinnedOnTop, setPinnedOnTop] = useState(false);\n const [windowMenu, setWindowMenu] = useState<{ x: number; y: number } | null>(null);\n // \"Add to Desktop\" — spec provided by the WindowManager around each open\n // window; null for nested dialogs (the outermost Modal re-provides null\n // below) and for Modals used outside the window system.\n const shortcutSpec = useContext(WindowShortcutContext);\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const favDocs: WindowShortcutSpec[] = shellPrefs.favorite_documents || [];\n const isOnDesktop = !!shortcutSpec && favDocs.some(d => d.entityType === shortcutSpec.entityType && d.entityId === shortcutSpec.entityId);\n const toggleDesktopShortcut = useCallback(() => {\n if (!shortcutSpec) return;\n const next = isOnDesktop\n ? favDocs.filter(d => !(d.entityType === shortcutSpec.entityType && d.entityId === shortcutSpec.entityId))\n : [...favDocs, { entityType: shortcutSpec.entityType, entityId: shortcutSpec.entityId, label: shortcutSpec.label }];\n saveShellPrefs({ favorite_documents: next });\n }, [shortcutSpec, isOnDesktop, favDocs, saveShellPrefs]);\n const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number } | null>(null);\n // Widget anchoring: 'left' or 'right' — determines which edge the widget is fixed to\n const [widgetAnchor, setWidgetAnchor] = useState<'left' | 'right'>(initialPosition === 'top-right' ? 'right' : 'left');\n const closingRef = useRef(false);\n const panelRef = useRef<HTMLDivElement>(null);\n // SG#00372: publish the per-section accent as a CSS custom property on the\n // panel element (same setProperty convention as the theme vars in\n // Layout/useTheme). The accent stripe below and any theme CSS read it via\n // `var(--window-accent-rgb)`. React never manages this key in the panel's\n // `style` prop, so the two can't fight over it.\n useLayoutEffect(() => {\n const el = panelRef.current;\n if (!el) return;\n if (accentRgb) el.style.setProperty('--window-accent-rgb', accentRgb);\n else el.style.removeProperty('--window-accent-rgb');\n }, [accentRgb]);\n // SG#00391: set when a mousedown on an INACTIVE window's interactive element\n // was swallowed to raise-only — the paired click (which is what would\n // navigate an <a> or fire a button's onClick) must be eaten too.\n const swallowInactiveClickRef = useRef(false);\n const bodyRef = useRef<HTMLDivElement>(null);\n const actionsRef = useRef<HTMLDivElement>(null);\n const actionsLeftRef = useRef<HTMLDivElement>(null);\n const [hasActions, setHasActions] = useState(false);\n // Every window must surface a clickable icon — it's the only entry point\n // to the window menu. Fall back to a generic \"window\" glyph when the\n // consumer hasn't supplied one. Consumer icons rarely include explicit\n // size classes (the start menu adds them via cloneElement), so we also\n // size them here to keep the title bar layout stable.\n const fallbackIcon = (\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n );\n const effectiveIcon = icon && isValidElement(icon)\n ? cloneElement(icon as React.ReactElement, {\n className: `h-4 w-4 ${(icon as React.ReactElement).props?.className ?? ''}`.trim(),\n } as any)\n : (icon ?? fallbackIcon);\n const renderIconButton = () => (\n <button\n onPointerDown={e => e.stopPropagation()}\n onClick={e => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n setWindowMenu(prev => prev ? null : { x: rect.left, y: rect.bottom + 4 });\n }}\n className=\"shrink-0 p-0.5 rounded hover:bg-gray-200/50 transition-colors\"\n title=\"Window menu\"\n >\n {effectiveIcon}\n </button>\n );\n const padding = 40;\n const { minimize: globalMinimize, items: minimizedItems, restoreIfMinimized } = useWindowManager();\n const modalId = useRef(`modal-${Math.random().toString(36).slice(2, 8)}`).current;\n\n // Mark widget windows so deactivate-all (show desktop) skips them.\n useEffect(() => {\n if (widget) {\n widgetIds.add(modalId);\n return () => { widgetIds.delete(modalId); };\n }\n }, [widget, modalId]);\n\n useEffect(() => {\n const handler = (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail?.id === modalId) setDisplayTitle(detail.title);\n };\n window.addEventListener('window-title-update', handler);\n return () => window.removeEventListener('window-title-update', handler);\n }, [modalId]);\n const [zIndex, setZIndex] = useState(50);\n const isActive = useIsActiveModal(modalId);\n\n // Exposé: when enabled, every tileable modal scales down via CSS\n // transform into its grid cell. Utility, widget, and pinned panels\n // sit out — they keep their normal layout.\n const exposeOn = useSyncExternalStore(subscribeExpose, getExposeState);\n const exposeExitFocusId = useSyncExternalStore(subscribeExposeExitFocus, getExposeExitFocus);\n const exposeHighlightId = useSyncExternalStore(subscribeExposeHighlight, getExposeHighlight);\n const isExposeTileable = !allowPinOnTop && !widget;\n const exposeActive = exposeOn && isExposeTileable;\n // Hover highlight for the thumbnail while in exposé.\n const [exposeHovered, setExposeHovered] = useState(false);\n // Keyboard-driven highlight (set externally via setExposeHighlight). Same\n // glow as hover so cycling visually matches what a mouse user sees.\n const exposeKeyboardHighlight = exposeActive && exposeHighlightId === modalId;\n // Exit-animation window: keep `transition: transform` on the panel for ~320ms\n // after exposé closes so the panel slides smoothly back to its real box\n // instead of snapping. Without this, removing `exposeStyle` drops the\n // transition prop instantly and the browser sees no animatable change.\n // The window the user clicked (when leaving via thumbnail) becomes the\n // \"picked\" one: same glide-home animation as everyone else, but with a\n // spring-y curve and elevated z-index so it reads as the focal point.\n const [exposeExiting, setExposeExiting] = useState(false);\n const exposeExitRole = (exposeExiting && isExposeTileable && exposeExitFocusId === modalId)\n ? 'picked' as const\n : null;\n const prevExposeActiveRef = useRef(exposeActive);\n useEffect(() => {\n if (prevExposeActiveRef.current && !exposeActive) {\n setExposeExiting(true);\n // Wait long enough for the picked window's spring (640 ms) to settle\n // before stripping the transition rule, otherwise the late-overshoot\n // tail snaps to the final position.\n const t = setTimeout(() => {\n setExposeExiting(false);\n // Only the picked modal resets the global focus; other panels read\n // it from the store during the whole window so no race.\n if (_exposeExitFocusId === modalId) setExposeExitFocus(null);\n }, 700);\n prevExposeActiveRef.current = exposeActive;\n return () => clearTimeout(t);\n }\n prevExposeActiveRef.current = exposeActive;\n }, [exposeActive, modalId]);\n // Reset hover whenever exposé toggles off so the highlight ring doesn't\n // linger past the transition.\n useEffect(() => { if (!exposeActive) setExposeHovered(false); }, [exposeActive]);\n\n\n // Track whether ModalActions portal has content (either left or right)\n useEffect(() => {\n const r = actionsRef.current;\n const l = actionsLeftRef.current;\n if (!r && !l) return;\n const check = () => setHasActions((r?.childElementCount ?? 0) + (l?.childElementCount ?? 0) > 0);\n check();\n const obs = new MutationObserver(check);\n if (r) obs.observe(r, { childList: true });\n if (l) obs.observe(l, { childList: true });\n return () => obs.disconnect();\n }, [open]);\n\n // Forward submit-button clicks from portaled actions to the form\n // (React onClick won't fire for portal children — must use native listener)\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n const btn = (e.target as HTMLElement).closest('button[type=\"submit\"]');\n if (btn && panelRef.current) {\n const form = panelRef.current.querySelector('form');\n if (form) { e.preventDefault(); form.requestSubmit(); }\n }\n };\n const r = actionsRef.current;\n const l = actionsLeftRef.current;\n if (r) r.addEventListener('click', handler);\n if (l) l.addEventListener('click', handler);\n return () => { if (r) r.removeEventListener('click', handler); if (l) l.removeEventListener('click', handler); };\n }, [open]);\n\n // ── Draggable/resizable state ──\n const isNested = useRef(false);\n\n const calcMaximized = useCallback(computeMaximizedBox, []);\n\n const calcWindowed = useCallback(() => {\n const sw = 0;\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 0;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const tbPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const leftOffset = tbPos === 'left' ? taskbarW : 0;\n const rightOffset = tbPos === 'right' ? taskbarW : 0;\n const targetW = dimensions ? dimensions[0] : (sizeDefaults[size] || 672);\n const availW = window.innerWidth - sw - leftOffset - rightOffset - padding * 2;\n const availH = window.innerHeight - taskbarH - padding * 2;\n const w = Math.min(targetW, availW);\n // Initial-open height ladder. 320 px is the open-time floor — the CSS\n // minHeight (~240 px at line ~1500) stays in place as the manual-resize\n // floor, so users can still drag a window smaller. xl/2xl previously had\n // no cap and ballooned to fill the entire viewport on tall screens;\n // they're now bounded at 800 / 920 px. The ladder is then scaled by the\n // user's \"Default window size\" preference — 'large' (the default) opens\n // 25 % taller than the old fixed values, 'small' shorter, 'medium' keeps\n // them. All caps are further clamped to the available viewport, so small\n // screens still get a window that fits.\n const heightScale = windowHeightScale[readDefaultWindowSize()];\n const h = dimensions\n ? Math.min(dimensions[1], availH)\n : (() => { const minH = 320; const maxH = (size === 'sm' ? 500 : size === 'md' ? 600 : size === 'lg' ? 700 : size === 'xl' ? 800 : 920) * heightScale; return Math.max(minH, Math.min(maxH, window.innerHeight - taskbarH - 80)); })();\n // Window position mode\n const posMode = getComputedStyle(document.documentElement).getPropertyValue('--window-position')?.trim() || 'cascade';\n const offset = posMode === 'cascade' ? (activationOrder.length - 1) * 30 : 0;\n const maxOffsetX = availW - w;\n const maxOffsetY = availH - h;\n // Position hints\n if (initialPosition === 'top-right') {\n return { x: window.innerWidth - w - padding, y: padding, w, h };\n }\n if (initialPosition === 'top-left') {\n return { x: sw + padding, y: padding, w, h };\n }\n return {\n x: sw + Math.max(padding, (availW - w) / 2 + padding) + Math.min(offset, Math.max(0, maxOffsetX)),\n y: Math.max(padding, (availH - h) / 2) + Math.min(offset, Math.max(0, maxOffsetY)),\n w, h,\n };\n }, [size]);\n\n const interceptedRef = useRef(false);\n if (!open) interceptedRef.current = false;\n\n const boxKey = windowKey || copyText || null;\n\n useEffect(() => {\n if (!open) return;\n modalDepthRef.inc();\n modalStack.push(modalId);\n mountModal(modalId, boxKey);\n // Inline dialogs (a list's detail Modal, a confirm) have no `windowKey`, so\n // they never pass through WindowManager's `activateAfterMount` and never\n // survive a refresh. mountModal would otherwise slot them into a stale\n // saved z-order (from a prior open, keyed by `copyText`) — dropping them\n // BEHIND the window they were opened from, which reads as \"nothing opened\".\n // A user-initiated open must come to the front, so raise keyless modals\n // here. WindowManager-managed windows (windowKey set) are fronted by\n // activateAfterMount instead and must keep their restored order on refresh.\n if (!windowKey) activateModal(modalId);\n isNested.current = false; // All modals are independent top-level windows\n setZIndex(getZForModal(modalId));\n // Listen for reorder events to update z-index\n const onReorder = () => {\n setZIndex(getZForModal(modalId));\n };\n // The old \"split view\" handler used to setBox to tile windows side\n // by side. Exposé replaces that with a non-destructive overlay\n // (CSS transform on the panel, see further down) — so this handler\n // is now a no-op. Kept around as an event listener target only so\n // the prior wiring keeps working until every consumer migrates.\n const onSplitView = () => { /* no-op: exposé toggle handled by setExposeState */ };\n\n // Center window on double-click from taskbar\n const onCenter = (e: Event) => {\n const label = (e as CustomEvent).detail?.label;\n if (!label) return;\n const titleEl = panelRef.current?.querySelector('[data-window-title]');\n if (!titleEl?.textContent?.includes(label)) return;\n activateModal(modalId);\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 0;\n const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-width')) || 0;\n const tbPos = getComputedStyle(document.documentElement).getPropertyValue('--taskbar-position')?.trim() || 'bottom';\n const leftOff = tbPos === 'left' ? taskbarW : 0;\n const rightOff = tbPos === 'right' ? taskbarW : 0;\n const availW = window.innerWidth - leftOff - rightOff;\n const availH = window.innerHeight - taskbarH;\n // Clamp size to viewport if bigger\n const w = Math.min(boxRef.current.w, availW - 40);\n const h = Math.min(boxRef.current.h, availH - 40);\n const x = leftOff + (availW - w) / 2;\n const y = (tbPos === 'top' ? taskbarH : 0) + (availH - h) / 2;\n setBox({ x, y, w, h });\n setMaximized(false);\n };\n // Context menu from taskbar right-click\n const onCtxMenu = (e: Event) => {\n const { label, x, y } = (e as CustomEvent).detail || {};\n if (!label) return;\n const titleEl = panelRef.current?.querySelector('[data-window-title]');\n if (!titleEl?.textContent?.includes(label)) return;\n activateModal(modalId);\n setWindowMenu({ x, y });\n };\n\n // Rescue a window the user can't reach: the smallest move that puts it\n // fully back inside the work area, shrinking it only if it is bigger than\n // the work area. Fired when the taskbar's off-screen thumbnail is clicked.\n // Deliberately narrower than `onCenter` — the window keeps its size and\n // roughly its place, because a rescue shouldn't re-layout your desktop.\n const onReveal = (e: Event) => {\n if ((e as CustomEvent).detail?.windowKey !== windowKey) return;\n activateModal(modalId);\n const cur = boxRef.current;\n const next = clampFullyVisible(cur);\n if (next.x === cur.x && next.y === cur.y && next.w === cur.w && next.h === cur.h) return;\n const panel = panelRef.current;\n const stillness = typeof window.matchMedia === 'function'\n && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (panel && !stillness) {\n // Animate it home so the user sees where it came from. Mid-slide the\n // panel's rect still measures as off-screen, so the taskbar marker\n // would survive its own rescue — re-poll once the window has landed.\n // `transitionend` is the honest signal; the timer is a fallback,\n // because a slide with no movement on any axis never fires one.\n let settled = false;\n const done = () => {\n if (settled) return;\n settled = true;\n panel.style.transition = '';\n window.dispatchEvent(new CustomEvent('modal-geometry'));\n };\n panel.style.transition = 'left .28s ease, top .28s ease, width .28s ease, height .28s ease';\n panel.addEventListener('transitionend', done, { once: true });\n window.setTimeout(done, 400);\n }\n setBox(next);\n };\n\n window.addEventListener('modal-reorder', onReorder);\n window.addEventListener('modal-split-view', onSplitView);\n window.addEventListener('modal-center', onCenter);\n window.addEventListener('modal-reveal', onReveal);\n window.addEventListener('modal-context-menu', onCtxMenu);\n return () => {\n modalDepthRef.dec();\n const idx = modalStack.indexOf(modalId);\n if (idx !== -1) modalStack.splice(idx, 1);\n const aidx = activationOrder.indexOf(modalId);\n if (aidx !== -1) { activationOrder.splice(aidx, 1); activeListeners.forEach(fn => fn()); }\n const cleanupKey = _keyByModalId.get(modalId);\n if (cleanupKey) { _keyByModalId.delete(modalId); _modalIdByKey.delete(cleanupKey); }\n window.removeEventListener('modal-reorder', onReorder);\n window.removeEventListener('modal-split-view', onSplitView);\n window.removeEventListener('modal-center', onCenter);\n window.removeEventListener('modal-reveal', onReveal);\n window.removeEventListener('modal-context-menu', onCtxMenu);\n // Notify remaining modals to recalc z-index\n window.dispatchEvent(new CustomEvent('modal-reorder'));\n };\n }, [open, modalId, boxKey, calcMaximized]);\n\n // 'Maximized' default-window-size preference: a freshly-opened non-widget\n // window fills the work area. Widgets (small content-sized utilities) and\n // windows restored from a saved/explicit box are exempt.\n const openMaximized = !widget && readDefaultWindowSize() === 'maximized';\n\n // Restore saved position from window position store\n const [box, setBox] = useState(() => {\n if (boxKey && _windowPositions[boxKey]) {\n const saved = { ..._windowPositions[boxKey] };\n // If dimensions are specified, enforce them (override cached size but keep position)\n if (dimensions) { saved.w = dimensions[0]; if (!autoHeight) saved.h = dimensions[1]; }\n // A box saved on a larger screen must not reopen out of reach.\n return clampReachable(saved);\n }\n if (initialBox) return { x: initialBox.x, y: initialBox.y, w: initialBox.w, h: initialBox.h };\n return openMaximized ? calcMaximized() : calcWindowed();\n });\n // `autoHeight` is a *one-shot* \"size to content at open time\" hint, not a\n // continuous CSS rule. The panel always renders at a *definite* height\n // (`box.h`, seeded from the normal windowed size ladder), and the layout\n // effect below measures the content and adjusts `box.h` to hug it — then\n // freezes, so the window behaves as a normal fixed-size window from there\n // on (drag/resize don't re-shrink it). `autoHeight` windows always\n // re-measure on open so they stay content-aware; the saved box restores\n // position + width but its `h` is only a placeholder.\n //\n // Crucially we measure against a definite panel height rather than\n // `height: auto`. A naturally-flowing detail (a table, a form) hugs its\n // content either way, but content whose root fills its parent — the common\n // `header / flex-1 scroll region / footer` detail layout — collapses to\n // nothing under a content-sized parent and used to freeze at the\n // `autoMinHeight` floor (a useless ~240px sliver). Keeping the panel\n // definite lets such content fill the ladder height; the measurement only\n // shrinks the window when the content genuinely *doesn't* fill it.\n const [autoHeightResolved, setAutoHeightResolved] = useState(() => !autoHeight);\n // Always-maximized layout: when the Layout sets `--layout-mode: sidebar`\n // on <html>, every non-widget Modal becomes immovable and locked to\n // calcMaximized() — no windowed state, no drag-to-restore, no maximize\n // toggle button. Layout dispatches a custom event whenever the pref\n // flips so already-mounted windows refresh without needing to remount.\n const [alwaysMaximizedRaw, setAlwaysMaximizedRaw] = useState<boolean>(() => readAlwaysMaximizedFlag());\n useEffect(() => {\n const refresh = () => setAlwaysMaximizedRaw(readAlwaysMaximizedFlag());\n window.addEventListener('react-os-shell:layout-mode-changed', refresh);\n return () => window.removeEventListener('react-os-shell:layout-mode-changed', refresh);\n }, []);\n const alwaysMaximized = alwaysMaximizedRaw && !widget;\n const [maximized, setMaximized] = useState(() => {\n // Saved positions and explicit restore boxes keep their own state (the\n // open effect below restores `initialBox.maximized`); a fresh window\n // honours the 'maximized' default-window-size preference.\n if ((boxKey && _windowPositions[boxKey]) || initialBox) return alwaysMaximized;\n return alwaysMaximized || openMaximized;\n });\n const boxRef = useRef(box);\n boxRef.current = box;\n\n // autoHeight measurement. The panel renders at a definite height the whole\n // time; here we measure the body's content and nudge `box.h` so the window\n // hugs it. A single first-paint measurement is unreliable — the open\n // animation, the lazy/Suspense body, and async data each settle over\n // several frames, so we track the body with a ResizeObserver:\n // • Widgets stay content-sized for their whole life (never freeze), so a\n // widget grows/shrinks with its content — a World Clock gains height as\n // each city's weather loads or when the user adds a city, a Currency\n // widget hugs its rows. This holds only while a widget's root is\n // naturally-flowing: a fill-height widget root (`h-full` / `flex-1`)\n // would still trip the fill-detection below and pin to the ladder\n // height, so widget roots must hug their own content rather than fill.\n // Widgets aren't user-resizable, so there's nothing to preserve by\n // freezing.\n // • Other autoHeight windows (e.g. settings dialogs, entity details)\n // measure-then-freeze once the height holds steady, then behave as\n // normal fixed-size windows (draggable/resizable, no further reactivity).\n //\n // The measurement distinguishes content that *fills* its container from\n // content that doesn't, so it never collapses a fill-height layout:\n // 1. With the body temporarily content-sized, read its natural outer\n // height (`bodyNatural`) and the content root's own height.\n // 2. Restore the body to its definite flex height and re-read the content\n // root. If the content root grew, it's a fill-height layout (flex-1 /\n // h-full) — keep the ladder height so it doesn't collapse. Otherwise\n // the content is naturally-flowing — size the window to chrome +\n // `bodyNatural`, clamped between the floor and the viewport.\n //\n // Two things make this robust against content that arrives *after* the first\n // paint — the common case where a detail component fetches its own data and\n // renders a small spinner before swapping in the real, taller content:\n // • We freeze (commit the height and stop reacting) only once we've\n // measured real content — a height *above the floor*. While the body\n // still measures at the floor (a loading spinner / pre-data placeholder)\n // we keep observing, so the window grows to the loaded content instead of\n // locking at a collapsed sliver. Without this, a fetch slower than the\n // freeze delay froze the window at the spinner height on first open\n // (a reopen, with the data cached, rendered tall content immediately and\n // looked fine — the tell-tale of this race).\n // • The ResizeObserver tracks the live *content root*, not the body (which\n // is a fixed flex height and so never resizes when content changes\n // inside it). That catches async rows, late images, and font swaps; a\n // MutationObserver on the body re-points it when the root element itself\n // is replaced (spinner → content).\n useLayoutEffect(() => {\n if (autoHeightResolved) return;\n const panel = panelRef.current;\n const body = bodyRef.current;\n if (!panel || !body) return;\n const floor = autoMinHeight ?? (widget ? 0 : 240);\n const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--taskbar-height')) || 0;\n let lastH = 0;\n let freezeTimer: ReturnType<typeof setTimeout> | null = null;\n let observed: Element | null = null;\n const measure = () => {\n const content = body.firstElementChild as HTMLElement | null;\n if (!content || panel.offsetHeight <= 0) return;\n // Keep the ResizeObserver pointed at the current content root so growth\n // inside the fixed-height body (data swapping in, images/fonts loading)\n // re-triggers measurement.\n if (content !== observed) {\n if (observed) ro.unobserve(observed);\n ro.observe(content);\n observed = content;\n }\n const chrome = panel.offsetHeight - body.offsetHeight; // title bar + footer\n // Pass 1: let the body size to its content and note the natural heights.\n const prevFlex = body.style.flex, prevOverflow = body.style.overflowY, prevHeight = body.style.height;\n body.style.flex = '0 0 auto';\n body.style.height = 'auto';\n body.style.overflowY = 'visible';\n const bodyNatural = body.offsetHeight;\n const contentNatural = content.offsetHeight;\n // Pass 2: restore the definite flex height and see if the content grew.\n body.style.flex = prevFlex;\n body.style.height = prevHeight;\n body.style.overflowY = prevOverflow;\n const contentFilled = content.offsetHeight;\n const fillsContainer = contentFilled > contentNatural + 4;\n const viewportCap = Math.max(floor, window.innerHeight - taskbarH - Math.max(0, boxRef.current.y) - 24);\n const target = fillsContainer\n ? Math.min(boxRef.current.h, viewportCap)\n : Math.min(Math.max(floor, chrome + bodyNatural), viewportCap);\n const changed = Math.abs(target - lastH) > 1;\n if (changed) {\n lastH = target;\n setBox(prev => (Math.abs(prev.h - target) > 1 ? { ...prev, h: target } : prev));\n }\n // Freeze (commit the height and stop reacting) only once real content —\n // taller than the floor — has settled. Re-evaluated on every measure so\n // the freeze is *disarmed* whenever the body sits at the floor (a loading\n // spinner / pre-data placeholder, or a brief open-animation transient).\n // Otherwise an early transient above the floor could arm the timer and\n // lock the window at the collapsed floor height before the real, taller\n // content arrives — the bug where a detail window opened as a sliver on\n // first (uncached) open but was fine on reopen. Fill-height content\n // reports the ladder height (> floor), so it still freezes promptly.\n if (!widget) {\n if (target <= floor) {\n if (freezeTimer) { clearTimeout(freezeTimer); freezeTimer = null; }\n } else if (changed || freezeTimer === null) {\n if (freezeTimer) clearTimeout(freezeTimer);\n freezeTimer = setTimeout(() => setAutoHeightResolved(true), 160);\n }\n }\n };\n const ro = new ResizeObserver(measure);\n measure();\n const mo = new MutationObserver(measure);\n mo.observe(body, { childList: true, subtree: true, characterData: true });\n return () => { ro.disconnect(); mo.disconnect(); if (freezeTimer) clearTimeout(freezeTimer); };\n }, [autoHeightResolved, widget, autoMinHeight]);\n\n // When sidebar mode is toggled at runtime, snap existing windows to the\n // maximized box so they instantly fill the new work area.\n useEffect(() => {\n if (alwaysMaximized) {\n setMaximized(true);\n setBox(calcMaximized());\n }\n }, [alwaysMaximized, calcMaximized]);\n\n // Picking 'Classic' in Layout Mode means \"windowed\": every non-widget window\n // drops out of maximized and back onto the normal size ladder, whether it was\n // maximized by sidebar mode, by the default-window-size preference, or by\n // hand. Widgets are content-sized and never maximized, so they're exempt.\n // Layout Mode fires this on every Classic click — not only on a sidebar →\n // classic transition — so a shell already stuck full-screen can be recovered\n // without hunting through Behavior.\n //\n // The handler deliberately does *not* re-read `--layout-mode`: Layout writes\n // that var in an effect that lands after the click handler, so a guard here\n // would still see the outgoing 'sidebar' and skip the restore. Un-maximizing\n // unconditionally is safe either way — if the shell really is still in\n // sidebar mode, the alwaysMaximized effect above puts the window straight\n // back.\n useEffect(() => {\n if (widget) return;\n const restore = () => { setMaximized(false); setBox(calcWindowed()); };\n window.addEventListener('react-os-shell:restore-windowed', restore);\n return () => window.removeEventListener('react-os-shell:restore-windowed', restore);\n }, [widget, calcWindowed]);\n\n // Persist box position on changes (debounced to localStorage)\n useEffect(() => {\n if (open && boxKey) {\n _windowPositions[boxKey] = box;\n _savePositionsDebounced();\n }\n // Let the taskbar recompute its off-screen markers. `box` only changes on a\n // settled gesture (drag/resize commit, snap, reveal) — never per frame.\n if (open) window.dispatchEvent(new CustomEvent('modal-geometry'));\n }, [box, open, boxKey]);\n\n // Sync on viewport resize: refit a maximized window, and rescue a windowed\n // one the viewport has shrunk out from under.\n useEffect(() => {\n if (!open) return;\n const sync = () => {\n if (maximized) { setBox(calcMaximized()); return; }\n // Mid-gesture the panel is driven by inline styles, not `box` — leave it.\n if (document.body.classList.contains('rosh-gesturing')) return;\n // `clampReachable` returns the same object when nothing moved, so a\n // window that is already reachable neither re-renders nor re-persists.\n setBox(clampReachable);\n };\n window.addEventListener('resize', sync);\n // Only observe DOM changes when maximized — avoids unnecessary re-renders\n let observer: MutationObserver | null = null;\n if (maximized) {\n observer = new MutationObserver(sync);\n observer.observe(document.body, { childList: true, subtree: false, attributes: true, attributeFilter: ['class'] });\n }\n return () => { window.removeEventListener('resize', sync); observer?.disconnect(); };\n }, [open, maximized, calcMaximized]);\n\n // Reset when modal opens — skip if we have a saved position\n useEffect(() => {\n if (!open) return;\n setTouched(false);\n closingRef.current = false;\n // If we have a saved position in the store, restore it instead of resetting.\n // For `autoHeight` windows the stored `h` is only a placeholder — height is\n // owned by live measurement — so keep the currently-measured `h` rather\n // than clobbering it back to the (stale/seeded) saved value.\n if (boxKey && _windowPositions[boxKey]) {\n const saved = _windowPositions[boxKey];\n setBox(prev => clampReachable(autoHeight ? { ...saved, h: prev.h } : { ...saved }));\n return;\n }\n if (initialBox) {\n setBox({ x: initialBox.x, y: initialBox.y, w: initialBox.w, h: initialBox.h });\n setMaximized(initialBox.maximized);\n }\n // Don't call calcWindowed() here — useState already set the initial position\n }, [open]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Auto-detect dirty\n useEffect(() => {\n if (!open || dirty !== 'auto') return;\n const handler = (e: Event) => { if (panelRef.current?.contains(e.target as HTMLElement)) setTouched(true); };\n document.addEventListener('input', handler, true);\n document.addEventListener('change', handler, true);\n return () => { document.removeEventListener('input', handler, true); document.removeEventListener('change', handler, true); };\n }, [open, dirty]);\n\n const isDirty = dirty === 'auto' ? touched : dirty === true;\n\n const guardedClose = useCallback(async () => {\n if (closingRef.current) return;\n if (isDirty) {\n closingRef.current = true;\n const ok = await confirm({ title: 'Discard changes?', message: 'You have unsaved changes. Are you sure you want to close? All changes will be lost.', confirmLabel: 'Discard', cancelLabel: 'Keep Editing', variant: 'warning' });\n closingRef.current = false;\n if (!ok) return;\n }\n onClose();\n }, [isDirty, onClose]);\n\n // Pre-snap box: if the user drags a window that's currently snapped to an\n // edge, restore it to its previous \"natural\" size so dragging it across\n // the screen feels right. Set on snap-drop, consumed on next drag start.\n const preSnapBoxRef = useRef<Box | null>(null);\n\n // ── Drag ──\n const startDrag = useCallback((e: React.PointerEvent) => {\n if (e.button !== 0) return;\n if ((e.target as HTMLElement).closest('button, input, a, kbd, select, textarea')) return;\n setWindowMenu(null);\n activateModal(modalId);\n // In sidebar layout mode the window is locked to the work area —\n // the title bar still activates the window but doesn't drag it.\n if (alwaysMaximized) { e.preventDefault(); return; }\n e.preventDefault();\n // The gesture (pointer capture, drag shield, compositor-layer promotion)\n // is deferred until the pointer actually moves past DRAG_THRESHOLD — a\n // press-and-hold or a plain click on the title bar must not engage any of\n // it. `null` until the first real move; started in `move`, ended in `up`.\n const dragHandle = e.currentTarget as HTMLElement;\n const dragPointerId = e.pointerId;\n let endGesture: (() => void) | null = null;\n const sx = e.clientX, sy = e.clientY;\n const panel = panelRef.current;\n const rect = panel?.getBoundingClientRect();\n\n // If this window is currently snapped, restore its pre-snap dimensions\n // and reposition so the cursor lands roughly in the title bar.\n let ox: number, oy: number, actualH: number, actualW: number;\n if (preSnapBoxRef.current) {\n const restore = preSnapBoxRef.current;\n preSnapBoxRef.current = null;\n actualW = restore.w;\n actualH = restore.h;\n // Center the restored window horizontally on the cursor; keep title\n // bar at cursor Y.\n const offsetX = rect ? Math.min(Math.max(20, e.clientX - rect.left), restore.w - 20) : restore.w / 2;\n ox = e.clientX - offsetX;\n oy = e.clientY - 12;\n if (panel) {\n panel.style.width = `${actualW}px`;\n panel.style.height = `${actualH}px`;\n panel.style.left = `${ox}px`;\n panel.style.top = `${oy}px`;\n }\n } else {\n ox = rect ? rect.left : boxRef.current.x;\n oy = rect ? rect.top : boxRef.current.y;\n actualH = rect ? rect.height : boxRef.current.h;\n actualW = rect ? rect.width : boxRef.current.w;\n }\n setMaximized(false);\n setBox(b => ({ ...b, x: ox, y: oy, w: actualW, h: actualH }));\n\n // Snap zone tracking — only re-render preview when zone CHANGES.\n let currentZone: SnapZone | null = null;\n\n const move = (ev: PointerEvent) => {\n // Promote to a real drag gesture on the first move past the threshold.\n if (!endGesture) {\n if (Math.abs(ev.clientX - sx) < DRAG_THRESHOLD && Math.abs(ev.clientY - sy) < DRAG_THRESHOLD) return;\n endGesture = beginPointerGesture(dragHandle, dragPointerId, 'move');\n // The exposé exit path leaves `transition: transform` on the panel for\n // ~320ms — a drag starting inside that window would animate/lag every\n // frame's translate below, so pin transitions off for the gesture.\n if (panel) panel.style.transition = 'none';\n }\n const nx = ox + ev.clientX - sx;\n const ny = Math.max(0, oy + ev.clientY - sy);\n // Move via transform, NOT left/top: mutating left/top invalidates layout\n // of the whole window subtree every frame — reflowing a heavy list at\n // pointer rate is what made drags stutter on older machines. translate()\n // runs on the compositor against the will-change:transform layer the\n // gesture style promotes, so the window's contents are never re-laid-out\n // or repainted mid-drag. Inline left/top stay pinned at the gesture\n // origin (matching the `box` state set above), so a mid-drag React\n // re-render re-applies the same origin and can't fight the transform —\n // with left/top writes it would snap the window back for a frame.\n if (panel) panel.style.transform = `translate(${nx - ox}px, ${ny - oy}px)`;\n boxRef.current = { ...boxRef.current, x: nx, y: ny };\n\n // Snap detection: ignore for widgets so they keep free-positioning.\n if (!widget) {\n const zone = detectSnapZone(ev.clientX, ev.clientY);\n if (zone !== currentZone) {\n currentZone = zone;\n if (zone) showSnapPreview(calcSnapBox(zone));\n else hideSnapPreview();\n }\n }\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n endGesture?.();\n hideSnapPreview();\n // Commit the drag through the reachability clamp — the pointer can leave\n // the viewport, so without this a window can be shoved past the right or\n // bottom edge and never grabbed again.\n const finalBox = clampReachable({ ...boxRef.current });\n boxRef.current = finalBox;\n\n // Snap drop: lock to the snap target, save the pre-snap size for next drag.\n if (!widget && currentZone) {\n preSnapBoxRef.current = { x: ox, y: oy, w: actualW, h: actualH };\n const snapped = calcSnapBox(currentZone);\n // Commit the snap target inline in the same frame the transform is\n // cleared, so the panel never flashes back to the gesture origin.\n if (panel) {\n panel.style.left = `${snapped.x}px`;\n panel.style.top = `${snapped.y}px`;\n panel.style.width = `${snapped.w}px`;\n panel.style.height = `${snapped.h}px`;\n panel.style.transform = '';\n panel.style.transition = '';\n }\n setBox(snapped);\n return;\n }\n\n // For widgets, determine anchor side based on center position vs viewport midpoint\n if (widget) {\n const centerX = finalBox.x + finalBox.w / 2;\n const mid = window.innerWidth / 2;\n setWidgetAnchor(centerX > mid ? 'right' : 'left');\n }\n // Commit the drag delta into inline left/top and clear the transform in\n // one style pass, then sync React state once — the inline position holds\n // the window in place until the re-render lands.\n if (panel) {\n panel.style.left = `${finalBox.x}px`;\n panel.style.top = `${finalBox.y}px`;\n panel.style.transform = '';\n panel.style.transition = '';\n }\n setBox(finalBox);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n }, []);\n\n // ── Resize ──\n const startResizeCorner = useCallback((e: React.PointerEvent, corner: 'se' | 'sw' | 'ne' | 'nw' | 'n' | 's' | 'e' | 'w') => {\n if (e.button !== 0) return;\n e.preventDefault(); e.stopPropagation();\n // Deferred until the pointer moves past DRAG_THRESHOLD (see startDrag) so a\n // stray press on a resize edge doesn't flatten every frosted window.\n const resizeHandle = e.currentTarget as HTMLElement;\n const resizePointerId = e.pointerId;\n let endGesture: (() => void) | null = null;\n const sx = e.clientX, sy = e.clientY;\n const panel = panelRef.current;\n // Always use the live rendered rect as the origin so we don't drift\n // when the panel was previously maximised or pinned.\n const rect = panel?.getBoundingClientRect();\n const ox = rect ? rect.left : boxRef.current.x;\n const oy = rect ? rect.top : boxRef.current.y;\n const ow = rect ? rect.width : boxRef.current.w;\n const oh = rect ? rect.height : boxRef.current.h;\n const MIN_W = 384;\n const MIN_H = 400;\n const isWest = corner === 'sw' || corner === 'nw' || corner === 'w';\n const isNorth = corner === 'ne' || corner === 'nw' || corner === 'n';\n const isEast = corner === 'se' || corner === 'ne' || corner === 'e';\n const isSouth = corner === 'se' || corner === 'sw' || corner === 's';\n setMaximized(false);\n // Pin the box to the actual rendered coordinates immediately so the\n // panel does not jump if it was previously maximised.\n setBox({ x: ox, y: oy, w: ow, h: oh });\n boxRef.current = { x: ox, y: oy, w: ow, h: oh };\n\n const compute = (dx: number, dy: number) => {\n let nx = ox, ny = oy, nw = ow, nh = oh;\n if (isEast) nw = Math.max(MIN_W, ow + dx);\n if (isSouth) nh = Math.max(MIN_H, oh + dy);\n if (isWest) {\n const targetW = Math.max(MIN_W, ow - dx);\n // Anchor the east edge: as W grows/shrinks, x moves opposite so the\n // east edge (ox + ow) stays fixed.\n nx = ox + ow - targetW;\n nw = targetW;\n }\n if (isNorth) {\n const targetH = Math.max(MIN_H, oh - dy);\n ny = oy + oh - targetH;\n nh = targetH;\n }\n return { x: nx, y: ny, w: nw, h: nh };\n };\n\n let raf = 0;\n let pending: { x: number; y: number; w: number; h: number } | null = null;\n const flush = () => {\n raf = 0;\n if (!pending) return;\n const next = pending; pending = null;\n boxRef.current = next;\n // Write straight to the DOM per frame. Routing every frame through\n // setBox re-rendered the whole window — reflowing a heavy <iframe> body\n // on each animation frame. React state is synced once on pointer-up\n // (mirrors the drag path, which also keeps inline styles mid-gesture).\n if (panel) {\n panel.style.left = `${next.x}px`;\n panel.style.top = `${next.y}px`;\n panel.style.width = `${next.w}px`;\n panel.style.height = `${next.h}px`;\n }\n };\n const move = (ev: PointerEvent) => {\n // Promote to a real resize gesture on the first move past the threshold.\n if (!endGesture) {\n if (Math.abs(ev.clientX - sx) < DRAG_THRESHOLD && Math.abs(ev.clientY - sy) < DRAG_THRESHOLD) return;\n endGesture = beginPointerGesture(resizeHandle, resizePointerId, RESIZE_CURSOR[corner]);\n }\n pending = compute(ev.clientX - sx, ev.clientY - sy);\n if (!raf) raf = requestAnimationFrame(flush);\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n if (raf) cancelAnimationFrame(raf);\n flush();\n endGesture?.();\n setBox({ ...boxRef.current });\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n }, []);\n\n const reset = () => { setMaximized(true); setBox(calcMaximized()); };\n const handleMinimize = () => {\n const saved = { ...boxRef.current, maximized };\n if (onMinimize) {\n onMinimize(saved);\n } else {\n const label = typeof title === 'string' ? title : (panelRef.current?.querySelector('[data-window-title]')?.textContent || 'Window');\n const route = window.location.pathname;\n globalMinimize({\n id: copyText || label || modalId, type: 'modal', label, route, savedBox: saved,\n });\n onClose();\n }\n };\n\n // ── Submit modal ──\n const submitModal = useCallback(() => {\n const panel = panelRef.current;\n if (!panel) return;\n const form = panel.querySelector('form');\n if (form) { form.requestSubmit(); } else {\n const btn = panel.querySelector<HTMLButtonElement>('button[type=\"submit\"], button[data-submit], button.bg-green-600, button.bg-blue-600');\n if (btn && !btn.disabled) btn.click();\n }\n }, []);\n\n // Cmd+Enter submits, bare Enter prevented — only for topmost modal\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (activationOrder[activationOrder.length - 1] !== modalId) return;\n if (e.key === 'Enter') {\n const target = e.target as HTMLElement;\n if (target.tagName === 'TEXTAREA' || target.isContentEditable) return;\n if (e.metaKey || e.ctrlKey) { e.preventDefault(); submitModal(); }\n else if (target.tagName === 'INPUT' && target.closest('form')) {\n // Let Enter submit the form naturally (e.g. password fields)\n return;\n }\n else { e.preventDefault(); }\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [open, submitModal, modalId]);\n\n // Cmd+S save-and-stay, Alt+Shift+D duplicate — only for topmost modal\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (activationOrder[activationOrder.length - 1] !== modalId) return;\n if ((e.metaKey || e.ctrlKey) && e.key === 's') { e.preventDefault(); document.dispatchEvent(new CustomEvent('modal-save')); setTouched(false); }\n else if (e.altKey && e.shiftKey && (e.code === 'KeyD' || e.key === 'D' || e.key === 'd')) { e.preventDefault(); document.dispatchEvent(new CustomEvent('modal-duplicate')); }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [open]);\n\n // ESC → close only the topmost modal (with dirty guard)\n useEffect(() => {\n if (!open) return;\n // Widgets (Calculator, Weather, Currency, Pomodoro, World Clock, etc.) are\n // ambient — ESC shouldn't close them. They have their own right-click Close.\n if (widget) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && activationOrder[activationOrder.length - 1] === modalId) {\n // Window content gets first refusal (measure tools, command bars…).\n if (runEscapeInterceptors(e)) { e.preventDefault(); e.stopPropagation(); return; }\n e.preventDefault(); e.stopPropagation(); guardedClose();\n }\n };\n window.addEventListener('keydown', handler, true);\n return () => window.removeEventListener('keydown', handler, true);\n }, [open, guardedClose, modalId, widget]);\n\n // J/K navigation\n const hasNav = open && (onNext !== undefined || onPrev !== undefined);\n const showBoundaryToast = useCallback((edge: 'top' | 'bottom') => {\n const existing = document.getElementById('nav-boundary-toast');\n if (existing) existing.remove();\n const lines = edge === 'bottom'\n ? [\"That's the last one, chief.\", \"You've hit rock bottom... of the list.\", \"End of the line, buddy.\", \"Nothing left. Go outside.\", \"Congratulations, you scrolled to the void.\", \"There's no more. I checked.\", \"You've reached the edge of the known universe.\", \"Plot twist: there is no next one.\", \"Even scrolling has limits. Unlike your ambition.\", \"Last one. Time to touch grass.\"]\n : [\"Already at the top. Overachiever.\", \"There is no item above this. Trust me.\", \"You're #1. Literally.\", \"Can't go higher. You've peaked.\", \"This is it. The summit. The top.\", \"First item. No VIP lounge above this.\", \"Going up? Nope. Elevator's broken.\", \"You want negative indexes? Bold.\", \"Top of the list. Top of the world.\", \"The only way is down from here.\"];\n const msg = lines[Math.floor(Math.random() * lines.length)];\n const toast = document.createElement('div');\n toast.id = 'nav-boundary-toast';\n toast.className = 'fixed bottom-6 left-1/2 -translate-x-1/2 z-[9999] bg-gray-900 text-white px-5 py-2.5 rounded-lg shadow-lg text-sm font-medium transition-opacity duration-300';\n toast.textContent = msg;\n document.body.appendChild(toast);\n setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 300); }, 2000);\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (activationOrder[activationOrder.length - 1] !== modalId) 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 if (e.key === 'j' && hasNav) { e.preventDefault(); if (onNext) onNext(); else showBoundaryToast('bottom'); }\n if (e.key === 'k' && hasNav) { e.preventDefault(); if (onPrev) onPrev(); else showBoundaryToast('top'); }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [open, onNext, onPrev, hasNav, showBoundaryToast, modalId]);\n\n // When minimized, stay mounted but hidden (preserves all state)\n if (!open || interceptedRef.current) return null;\n\n // ── Full window — render via portal when nested to escape parent overflow:hidden ──\n const exposeTile = exposeActive ? computeExposeTile(modalId) : null;\n // Factor that shrinks a full-size window into its exposé tile. Hoisted so the\n // hover close-button can counter-scale (1/exposeScale) back to a real,\n // clickable on-screen size no matter how small the tile is.\n const exposeScale = exposeActive && exposeTile\n ? Math.min(exposeTile.w / box.w, exposeTile.h / box.h)\n : 1;\n const exposeStyle = (() => {\n if (exposeActive && exposeTile) {\n const scale = exposeScale;\n const scaledW = box.w * scale;\n const scaledH = box.h * scale;\n const tx = exposeTile.x + (exposeTile.w - scaledW) / 2 - box.x;\n const ty = exposeTile.y + (exposeTile.h - scaledH) / 2 - box.y;\n // Hover and keyboard-cycle both light the tile up. They share the\n // same glow so a mouse user and a keyboard user are always looking\n // at the same visual cue. When both apply (mouse hovering the\n // currently-keyboard-highlighted tile), hover wins z-index-wise so\n // the hover ring stays readable above neighbours.\n const lit = exposeHovered || exposeKeyboardHighlight;\n return {\n transform: `translate(${tx}px, ${ty}px) scale(${scale})`,\n transformOrigin: 'top left' as const,\n transition: 'transform 280ms cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 280ms',\n cursor: 'pointer',\n // Lifted tile sits above its neighbours so the glow isn't clipped.\n zIndex: lit ? 2020 : 2010,\n boxShadow: lit\n ? '0 24px 72px rgba(0,0,0,0.6), 0 0 0 2px rgba(255,255,255,0.55), 0 0 36px 12px rgba(96,165,250,0.85), 0 0 96px 28px rgba(96,165,250,0.55)'\n : '0 16px 48px rgba(0,0,0,0.55)',\n pointerEvents: 'auto' as const,\n };\n }\n if (exposeExiting && isExposeTileable) {\n // All tileable windows glide from their thumbnail back to their real\n // position simultaneously — preserve the transition rule so the\n // transform-from-tile animates instead of snapping. The \"picked\" one\n // (when the user clicked a thumbnail to leave) gets a spring-y curve\n // and an elevated z-index so it reads as the focal point of the move.\n // Durations are deliberately on the slow side (~600 ms) so the user\n // can read the choreography as every window slides back home.\n const picked = exposeExitRole === 'picked';\n return {\n transition: picked\n ? 'transform 640ms cubic-bezier(0.34, 1.42, 0.64, 1), box-shadow 600ms'\n : 'transform 600ms cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 600ms',\n ...(picked ? { zIndex: 2030 } : {}),\n };\n }\n return null;\n })();\n\n const content = (\n <div>\n {/* Window */}\n {/* `data-utility` marks a window that *may* be pinned on top; `data-pinned-top`\n marks one that currently *is*, and so is riding the 999 lane rather than the\n activation-order ladder. The taskbar's peek needs the latter to know which\n windows it must not restack. */}\n <div ref={panelRef} data-modal-panel data-modal-id={modalId} data-window-key={windowKey || undefined} {...(allowPinOnTop ? { 'data-utility': '' } : {})} {...(pinnedOnTop ? { 'data-pinned-top': '' } : {})} {...(widget ? { 'data-widget': '' } : {})}\n className={`fixed rounded-2xl flex flex-col overflow-hidden ${widget ? (isActive ? 'shadow-2xl' : 'shadow-lg') : `border ${isActive ? 'shadow-2xl border-gray-200' : 'shadow-lg border-gray-300'}`}`}\n onMouseDownCapture={(e) => {\n swallowInactiveClickRef.current = false;\n if (exposeActive) {\n // The exposé close button handles its own click — let it through so\n // the capture-phase \"select this window\" logic doesn't swallow it.\n if ((e.target as HTMLElement).closest('[data-expose-close]')) return;\n // In exposé mode, any click on a tileable window selects it.\n e.preventDefault();\n e.stopPropagation();\n // Publish the picked id BEFORE flipping exposeState off so all\n // panels see it on their first exit-render and pick the right\n // role (picked vs unpicked).\n setExposeExitFocus(modalId);\n setExposeState(false);\n activateModal(modalId);\n return;\n }\n // SG#00391: a primary-button press on an INACTIVE window's\n // interactive element raises the window and does nothing else — no\n // click-through (a link in a background tile used to navigate when\n // the user only meant to bring the window forward). Widgets and\n // pinned-on-top utility panels keep the pass-through; the active\n // window is untouched. Title-bar chrome ([data-window-chrome]:\n // close/minimize/maximize/pin/icon-menu) is exempt so a background\n // window still closes in ONE click. preventDefault here only affects\n // interactive targets, so text selection over background content is\n // unchanged.\n if (!isActive && !widget && !pinnedOnTop && e.button === 0) {\n const target = e.target as HTMLElement;\n // Ignore events bubbling out of a nested child modal's panel.\n if (target.closest('[data-modal-panel]') === panelRef.current\n && target.closest('button, input, a, select, textarea')\n && !target.closest('[data-window-chrome]')) {\n e.preventDefault();\n e.stopPropagation();\n swallowInactiveClickRef.current = true;\n setWindowMenu(null);\n activateModal(modalId);\n // If the mouseup lands OUTSIDE the panel (drag off the control),\n // no paired click reaches onClickCapture and the flag would eat\n // the next keyboard/programmatic click. mouseup fires before\n // click in the same task, so clear on the next tick — after the\n // paired click (if any) has been dispatched and consumed.\n window.addEventListener('mouseup', () => {\n setTimeout(() => { swallowInactiveClickRef.current = false; }, 0);\n }, { once: true });\n }\n }\n }}\n onClickCapture={(e) => {\n // Second half of the SG#00391 swallow: activation already happened\n // on mousedown; eat exactly the paired click so the control never\n // fires. The flag (not `isActive`, which is already true by now)\n // guards against double-activation and against eating later clicks.\n if (swallowInactiveClickRef.current) {\n swallowInactiveClickRef.current = false;\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n onMouseDown={(e) => {\n if (exposeActive) return;\n setWindowMenu(null);\n // Don't activate if the click is inside a child modal (nested portal)\n const targetPanel = (e.target as HTMLElement).closest('[data-modal-panel]');\n if (targetPanel && targetPanel !== panelRef.current) return;\n if (!(e.target as HTMLElement).closest('button, input, a, select, textarea')) {\n activateModal(modalId);\n }\n }}\n style={isMobile ? {\n // Mobile fullscreen: ignore stored box, fill viewport down to bottom\n // nav. Widgets stay hidden on mobile. Only the active window is\n // visible — all others hidden so swipe-right reveals the home\n // wallpaper backdrop. Exception: when a sibling Modal is being\n // swiped to-back and we're its `openedFrom` parent, un-hide so the\n // user sees their parent list during the slide instead of just the\n // wallpaper.\n zIndex: zIndex + 1,\n top: 0, left: 0, right: 0,\n bottom: 'var(--mobile-bottom-nav, 56px)',\n width: 'auto', height: 'auto',\n transform: `translateX(${swipeX}px)`,\n transition: swipeDragging ? 'none' : 'transform 180ms ease-out',\n ...(widget ? { display: 'none' } : {}),\n ...(zIndex < 0 ? { display: 'none' } : {}),\n ...((!isActive && !pinnedOnTop && !(swipingParentKey && windowKey === swipingParentKey)) ? { display: 'none' } : {}),\n } : {\n // The panel is always a definite height — even while an `autoHeight`\n // window is still measuring (box.h is seeded from the size ladder).\n // The measurement effect adjusts box.h to hug the content; rendering\n // at a definite height the whole way through means fill-height\n // content (flex-1 / h-full) never collapses to the floor.\n zIndex: pinnedOnTop ? 999 : zIndex + 1, width: box.w, height: box.h, top: box.y,\n ...(widget && widgetAnchor === 'right' ? { right: window.innerWidth - box.x - box.w } : { left: box.x }),\n ...(zIndex < 0 && !pinnedOnTop ? { display: 'none' } : {}),\n ...(exposeStyle ?? {}),\n }}\n >\n {/* Mobile swipe-from-left-edge gesture zone. Captures pointerdown only\n * in the leftmost 22px so it doesn't interfere with normal taps or\n * scrolls in the body. */}\n {isMobile && !widget && (\n <div\n onPointerDown={handleEdgePointerDown}\n className=\"absolute top-0 bottom-0 left-0 w-[22px] z-[5]\"\n style={{ touchAction: 'pan-y' }}\n aria-hidden=\"true\"\n />\n )}\n\n {/* SG#00372: per-section accent stripe — a thin line across the top\n * edge of the title bar, painted from --window-accent-rgb (set by the\n * effect above when the consumer passes `accentRgb`). Overlapping\n * windows from different app sections become distinguishable while\n * the header itself stays theme-neutral. pointer-events-none keeps\n * title-bar dragging/clicking unaffected; the overflow-hidden panel\n * clips it to the rounded corners. Widgets have no title bar and\n * mobile windows are fullscreen, so neither renders it. */}\n {accentRgb && !widget && !isMobile && (\n <div aria-hidden=\"true\"\n className=\"absolute top-0 left-0 right-0 h-[3px] z-[6] pointer-events-none\"\n style={{ backgroundColor: `rgb(var(--window-accent-rgb) / ${isActive ? 0.9 : 0.55})` }} />\n )}\n\n {/* HEADER — draggable on desktop, hidden on mobile (apps go fullscreen\n * with a swipe-from-left-edge gesture to close). */}\n {widget ? (\n /* Widget: no title bar — drag via body, close via right-click context menu */\n null\n ) : isMobile ? (\n null\n ) : compact ? (\n /* Compact: smaller title bar with title + close only */\n <div onPointerDown={startDrag} data-window-chrome=\"\"\n className={`flex items-center justify-between px-3 py-1.5 border-b border-gray-200 shrink-0 cursor-move select-none rounded-t-2xl ${isActive ? 'backdrop-blur-sm' : ''}`}\n style={{ touchAction: 'none', backgroundColor: isActive ? `rgb(var(--window-header-rgb) / var(--active-header-opacity, 0.8))` : `rgb(var(--window-header-rgb) / var(--inactive-header-opacity, 0.7))` }}>\n <div data-window-title className=\"text-sm font-medium min-w-0 flex-1 truncate flex items-center gap-1.5\" style={{ color: isActive ? 'var(--window-title-active, rgb(17 24 39))' : 'var(--window-title-inactive, rgb(156 163 175))' }}>\n {!exposeActive && renderIconButton()}\n <span className=\"truncate\">{exposeActive ? extractTitleText(displayTitle) : displayTitle}</span>\n </div>\n {!exposeActive && (\n <div className=\"flex items-center gap-1 shrink-0 ml-2\">\n {allowPinOnTop && (\n <button onClick={() => setPinnedOnTop(p => !p)} title={pinnedOnTop ? 'Unpin from top' : 'Pin on top'}\n className={`p-0.5 rounded hover:bg-gray-200 ${pinnedOnTop ? 'text-blue-600' : 'text-gray-400 hover:text-gray-600'}`}>\n <svg className=\"h-3 w-3\" fill={pinnedOnTop ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9\" /></svg>\n </button>\n )}\n <button type=\"button\" onClick={guardedClose} className=\"rounded p-0.5 text-gray-400 hover:text-gray-600 hover:bg-gray-200\">\n <XMarkIcon className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </div>\n ) : appStyle ? (\n /* App style: small title bar like compact, but keeps minimize/maximize for full window control. */\n <div onPointerDown={startDrag} data-window-chrome=\"\"\n className={`flex items-center justify-between px-3 py-1.5 border-b border-gray-200 shrink-0 cursor-move select-none rounded-t-2xl ${isActive ? 'backdrop-blur-sm' : ''}`}\n style={{ touchAction: 'none', backgroundColor: isActive ? `rgb(var(--window-header-rgb) / var(--active-header-opacity, 0.8))` : `rgb(var(--window-header-rgb) / var(--inactive-header-opacity, 0.7))` }}>\n <div data-window-title className=\"text-sm font-medium min-w-0 flex-1 truncate flex items-center gap-1.5\" style={{ color: isActive ? 'var(--window-title-active, rgb(17 24 39))' : 'var(--window-title-inactive, rgb(156 163 175))' }}>\n {!exposeActive && renderIconButton()}\n <span className=\"truncate\">{exposeActive ? extractTitleText(displayTitle) : displayTitle}</span>\n </div>\n {!exposeActive && (\n <div className=\"flex items-center gap-0.5 shrink-0 ml-2\">\n {allowPinOnTop && (\n <button onClick={() => setPinnedOnTop(p => !p)} title={pinnedOnTop ? 'Unpin from top' : 'Pin on top'}\n className={`p-0.5 rounded hover:bg-gray-200 ${pinnedOnTop ? 'text-blue-600' : 'text-gray-400 hover:text-gray-600'}`}>\n <svg className=\"h-3 w-3\" fill={pinnedOnTop ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9\" /></svg>\n </button>\n )}\n <button onClick={() => _minimizeModal(modalId)} title=\"Minimize\" className=\"text-gray-400 hover:text-gray-600 px-1 py-0.5 rounded hover:bg-gray-200 text-xs leading-none\">─</button>\n {!alwaysMaximized && (\n <button onClick={() => { if (maximized) { setMaximized(false); setBox(calcWindowed()); } else { reset(); } }} title={maximized ? 'Windowed' : 'Maximize'} className=\"text-gray-400 hover:text-gray-600 px-1 py-0.5 rounded hover:bg-gray-200 text-xs leading-none\">{maximized ? '❐' : '⤢'}</button>\n )}\n <button type=\"button\" onClick={guardedClose} className=\"rounded p-0.5 text-gray-400 hover:text-gray-600 hover:bg-gray-200\">\n <XMarkIcon className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </div>\n ) : (\n <div onPointerDown={startDrag} data-window-chrome=\"\"\n className={`flex items-center justify-between px-4 py-2.5 border-b border-gray-200 shrink-0 cursor-move select-none rounded-t-2xl ${isActive ? 'backdrop-blur-sm' : ''}`}\n style={{ touchAction: 'none', backgroundColor: isActive ? `rgb(var(--window-header-rgb) / var(--active-header-opacity, 0.8))` : `rgb(var(--window-header-rgb) / var(--inactive-header-opacity, 0.7))` }}>\n <div data-window-title className=\"text-base font-medium min-w-0 flex-1 truncate flex items-center gap-2\" style={{ color: isActive ? 'var(--window-title-active, rgb(17 24 39))' : 'var(--window-title-inactive, rgb(156 163 175))' }}>\n {!exposeActive && renderIconButton()}\n <span className=\"truncate\">{exposeActive ? extractTitleText(displayTitle) : displayTitle}</span>\n </div>\n {!exposeActive && (\n <div className=\"flex items-center gap-1.5 shrink-0 ml-4\">\n {hasNav && (\n <span className=\"flex items-center gap-1 mr-1 text-[10px] text-gray-400\">\n <kbd className=\"rounded border border-gray-300 bg-gray-200 px-1.5 py-0.5 font-medium text-gray-500\">K</kbd><span>Prev</span>\n <kbd className=\"rounded border border-gray-300 bg-gray-200 px-1.5 py-0.5 font-medium ml-1 text-gray-500\">J</kbd><span>Next</span>\n </span>\n )}\n {allowPinOnTop && (\n <button onClick={() => setPinnedOnTop(p => !p)} title={pinnedOnTop ? 'Unpin from top' : 'Pin on top'}\n className={`text-xs px-2 py-1 rounded hover:bg-gray-200 ${pinnedOnTop ? 'text-blue-600' : 'text-gray-400 hover:text-gray-600'}`}>\n <svg className=\"h-3.5 w-3.5\" fill={pinnedOnTop ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9\" /></svg>\n </button>\n )}\n <button onClick={() => _minimizeModal(modalId)} title=\"Minimize\" className=\"text-gray-400 hover:text-gray-600 text-xs px-2 py-1 rounded hover:bg-gray-200\">─</button>\n {!alwaysMaximized && (\n <button onClick={() => { if (maximized) { setMaximized(false); setBox(calcWindowed()); } else { reset(); } }} title={maximized ? 'Windowed' : 'Maximize'} className=\"text-gray-400 hover:text-gray-600 text-xs px-2 py-1 rounded hover:bg-gray-200\">{maximized ? '❐' : '⤢'}</button>\n )}\n <kbd className=\"rounded border border-gray-300 bg-gray-200 px-1.5 py-0.5 text-[10px] font-medium text-gray-400\">ESC</kbd>\n <button type=\"button\" onClick={guardedClose} className=\"rounded-md text-gray-400 hover:text-gray-600\">\n <XMarkIcon className=\"h-5 w-5\" />\n </button>\n </div>\n )}\n </div>\n )}\n\n {/* BODY */}\n <ModalIdContext.Provider value={modalId}>\n <ModalActionsContext.Provider value={{ rightRef: actionsRef as React.RefObject<HTMLDivElement | null>, leftRef: actionsLeftRef as React.RefObject<HTMLDivElement | null>, notify: () => setHasActions(true), active: isActive, isDirty }}>\n <div\n ref={bodyRef}\n {...(widget ? { onPointerDown: startDrag, onContextMenu: (e: React.MouseEvent) => { e.preventDefault(); setCtxMenu({ x: e.clientX, y: e.clientY }); } } : {})}\n className={`flex-1 min-h-0 flex flex-col ${widget ? 'p-0 cursor-move' : appStyle ? 'p-0' : flushBody ? 'p-0' : compact ? 'p-2' : 'p-4'} ${widget ? '' : 'backdrop-blur-sm'} ${(bodyScroll === false || appStyle || flushBody) ? 'overflow-hidden' : 'overflow-y-auto overscroll-contain'} ${widget ? 'rounded-2xl select-none' : ''}`}\n style={{ ...(widget ? { touchAction: 'none' } : {}), backgroundColor: widget ? 'transparent' : (isActive ? `rgb(var(--window-content-rgb) / var(--active-content-opacity, 0.9))` : `rgb(var(--window-content-rgb) / var(--inactive-content-opacity, 0.8))`) }}>\n {/* A throwing page/entity component must not unmount the desktop —\n the boundary swaps the body for an inline crash state while the\n window chrome (close/minimize) and all other windows keep running. */}\n <WindowErrorBoundary>\n {children}\n </WindowErrorBoundary>\n </div>\n </ModalActionsContext.Provider>\n </ModalIdContext.Provider>\n\n {/* Widget right-click context menu */}\n {widget && ctxMenu && (\n <PopupMenu minWidth={160} style={{ left: ctxMenu.x, top: ctxMenu.y }} onClose={() => setCtxMenu(null)}>\n <PopupMenuItem onClick={() => { setCtxMenu(null); window.dispatchEvent(new CustomEvent('widget-open-settings', { detail: modalId })); }}>\n Settings\n </PopupMenuItem>\n <PopupMenuDivider />\n {widgetMenu && (\n <>\n {widgetMenu}\n <PopupMenuDivider />\n </>\n )}\n <PopupMenuItem onClick={() => { setCtxMenu(null); setPinnedOnTop(p => !p); }}>\n <span className=\"flex-1\">Always on Top</span>\n {pinnedOnTop && <svg className=\"h-4 w-4 text-blue-600 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" /></svg>}\n </PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem onClick={() => { setCtxMenu(null); guardedClose(); }}>\n Close\n </PopupMenuItem>\n </PopupMenu>\n )}\n\n {/* FOOTER — always rendered; visible when footer prop or portal actions exist; hidden for widgets/compact */}\n <div onPointerDown={startDrag}\n className={`px-4 py-2 border-t border-gray-200 shrink-0 flex items-center justify-between text-xs select-none cursor-move${isActive ? ' backdrop-blur-sm' : ''}${widget || compact || appStyle || isMobile || (!footer && !hasActions && !actions && !actionsLeft) ? ' hidden' : ''}`}\n style={{ touchAction: 'none', backgroundColor: isActive ? `rgb(var(--window-footer-rgb) / var(--active-header-opacity, 0.8))` : `rgb(var(--window-footer-rgb) / var(--inactive-header-opacity, 0.7))` }}>\n <div className=\"flex items-center gap-2 min-w-0\">\n {actionsLeft}\n <div ref={actionsLeftRef} data-modal-actions-left className=\"flex items-center gap-2\" />\n {footer}\n </div>\n <div className=\"flex items-center gap-2 ml-auto\">\n <div ref={actionsRef} data-modal-actions className=\"flex items-center gap-2\" />\n {actions}\n </div>\n </div>\n\n {/* RESIZE HANDLES — corners and edges (hidden in widget/mobile/exposé mode; only rendered when active to avoid z-index bleed on inactive windows) */}\n {!widget && !isMobile && !exposeActive && isActive && <>\n <div onPointerDown={e => startResizeCorner(e, 'se')} className=\"absolute bottom-0 right-0 w-3 h-3 cursor-nwse-resize z-10\" />\n <div onPointerDown={e => startResizeCorner(e, 'sw')} className=\"absolute bottom-0 left-0 w-3 h-3 cursor-nesw-resize z-10\" />\n <div onPointerDown={e => startResizeCorner(e, 'ne')} className=\"absolute top-0 right-0 w-3 h-3 cursor-nesw-resize z-10\" />\n <div onPointerDown={e => startResizeCorner(e, 'nw')} className=\"absolute top-0 left-0 w-3 h-3 cursor-nwse-resize z-10\" />\n <div onPointerDown={e => startResizeCorner(e, 'n')} className=\"absolute top-0 left-3 right-3 h-1 cursor-ns-resize\" />\n <div onPointerDown={e => startResizeCorner(e, 's')} className=\"absolute bottom-0 left-3 right-3 h-1 cursor-ns-resize\" />\n <div onPointerDown={e => startResizeCorner(e, 'e')} className=\"absolute top-3 bottom-3 right-0 w-1 cursor-ew-resize\" />\n <div onPointerDown={e => startResizeCorner(e, 'w')} className=\"absolute top-3 bottom-3 left-0 w-1 cursor-ew-resize\" />\n </>}\n {/* EXPOSÉ click capture — sits above all content so any click selects this window */}\n {exposeActive && (\n <div\n className=\"absolute inset-0\"\n style={{ zIndex: 9999, cursor: 'pointer', background: 'transparent' }}\n onMouseEnter={() => setExposeHovered(true)}\n onMouseLeave={() => setExposeHovered(false)}\n onMouseDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n // Activate the picked window first so its z-index lifts it\n // above the others while every panel animates back to its\n // real position. setExposeState(false) starts that exit\n // animation; the panel keeps `transition: transform` for\n // ~320ms via exposeExiting.\n activateModal(modalId);\n setExposeState(false);\n }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); }}\n >\n {/* Close button — revealed while the tile is hovered, pinned to the\n * tile's top-right corner. It lives INSIDE the hover-capture layer\n * (not as a sibling) so sliding the pointer onto it doesn't fire a\n * mouseleave and flicker the hover off. Counter-scaled by\n * 1/exposeScale so it stays a real ~30px target however small the\n * tile is; honours the dirty-close confirm via `guardedClose`. */}\n {exposeHovered && (\n <button\n type=\"button\"\n data-expose-close\n aria-label=\"Close window\"\n title=\"Close\"\n className=\"absolute flex items-center justify-center rounded-full bg-black/55 text-white shadow-lg ring-1 ring-white/40 transition-colors hover:bg-red-500\"\n style={{\n top: 8,\n right: 8,\n width: 30,\n height: 30,\n transform: `scale(${1 / exposeScale})`,\n transformOrigin: 'top right',\n zIndex: 10000,\n }}\n onMouseDown={(e) => { e.stopPropagation(); e.preventDefault(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); guardedClose(); }}\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 )}\n </div>\n )}\n </div>\n {/* EXPOSÉ label — title under the thumbnail (no hover styling on the\n * text — the glow on the thumbnail itself is the affordance). */}\n {exposeActive && exposeTile && (\n <div\n className=\"fixed pointer-events-none select-none truncate text-center\"\n style={{\n left: exposeTile.x,\n top: exposeTile.y + exposeTile.h + 4,\n width: exposeTile.w,\n zIndex: exposeHovered ? 2021 : 2011,\n color: 'white',\n fontSize: 12,\n fontWeight: 500,\n textShadow: '0 1px 2px rgba(0,0,0,0.6)',\n }}\n >\n {extractTitleText(displayTitle)}\n </div>\n )}\n </div>\n );\n\n // Window context menu\n const windowMenuEl = windowMenu && (\n <PopupMenu style={{ left: windowMenu.x, top: windowMenu.y }} onClose={() => setWindowMenu(null)} minWidth={160}>\n {!widget && !compact && (<>\n <PopupMenuItem onClick={() => { _minimizeModal(modalId); setWindowMenu(null); }}>\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=\"M19.5 12h-15\" /></svg>\n Minimize\n </PopupMenuItem>\n {!alwaysMaximized && (maximized ? (\n <PopupMenuItem onClick={() => { setMaximized(false); setBox(calcWindowed()); setWindowMenu(null); }}>\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 4.5v15m6-15v15M4.5 9h15M4.5 15h15\" /></svg>\n Windowed\n </PopupMenuItem>\n ) : (\n <PopupMenuItem onClick={() => { reset(); setWindowMenu(null); }}>\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 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15\" /></svg>\n Maximize\n </PopupMenuItem>\n ))}\n\n </>)}\n {allowPinOnTop && (\n <PopupMenuItem onClick={() => { setPinnedOnTop(p => !p); setWindowMenu(null); }}>\n <svg className={`h-4 w-4 ${pinnedOnTop ? 'text-blue-600' : 'text-gray-400'}`} fill={pinnedOnTop ? 'currentColor' : 'none'} viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9\" /></svg>\n {pinnedOnTop ? 'Unpin from Top' : 'Pin on Top'}\n </PopupMenuItem>\n )}\n {shortcutSpec && (\n <PopupMenuItem onClick={() => { setWindowMenu(null); toggleDesktopShortcut(); }}>\n <svg className={`h-4 w-4 ${isOnDesktop ? 'text-yellow-500' : 'text-gray-400'}`} fill={isOnDesktop ? '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 {isOnDesktop ? 'Remove from Desktop' : 'Add to Desktop'}\n </PopupMenuItem>\n )}\n {/* Custom menu items registered by child components */}\n {(_extraMenuItems[modalId] || []).length > 0 && (<>\n {(_extraMenuItems[modalId] || []).map((item, i) => (\n <PopupMenuItem key={i} onClick={() => { setWindowMenu(null); item.onClick(); }}>\n {item.icon}\n {item.label}\n </PopupMenuItem>\n ))}\n </>)}\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={() => { setWindowMenu(null); guardedClose(); }}>\n <XMarkIcon className=\"h-4 w-4\" />\n Close\n </PopupMenuItem>\n </PopupMenu>\n );\n\n // Always portal to body — ensures DOM persists when hidden/minimized.\n // Re-providing a null shortcut spec stops dialogs nested inside this\n // window from also offering \"Add to Desktop\" for it.\n return createPortal(\n <WindowShortcutContext.Provider value={null}>{content}{windowMenuEl}</WindowShortcutContext.Provider>,\n document.body,\n );\n}\n","import { createContext, useContext, useState, useCallback, useRef, useEffect } from 'react';\nimport { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';\nimport { ExclamationTriangleIcon, XMarkIcon } from '@heroicons/react/24/outline';\nimport { registerModalEscapeInterceptor } from './Modal';\n\ninterface ConfirmOptions {\n title?: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n variant?: 'danger' | 'warning' | 'info';\n}\n\ntype ConfirmFn = (options: ConfirmOptions | string) => Promise<boolean>;\n\nconst ConfirmContext = createContext<ConfirmFn>(() => Promise.resolve(false));\n\nexport const useConfirm = () => useContext(ConfirmContext);\n\n// Global callable — works without a hook, usable from any click handler\nlet globalConfirmFn: ConfirmFn = () => Promise.resolve(false);\nexport const confirm = (opts: ConfirmOptions | string) => globalConfirmFn(opts);\n\n// Destructive confirm — requires typing a word (case-sensitive) to confirm\ninterface DestructiveConfirmOptions {\n title?: string;\n message: string;\n confirmWord: string; // e.g. \"Delete\" or \"Cancel\" — user must type this exactly\n variant?: 'danger' | 'warning';\n}\ntype DestructiveConfirmFn = (options: DestructiveConfirmOptions) => Promise<boolean>;\nlet globalDestructiveConfirmFn: DestructiveConfirmFn = () => Promise.resolve(false);\nexport const confirmDestructive = (opts: DestructiveConfirmOptions) => globalDestructiveConfirmFn(opts);\n\n// Prompt — windowed replacement for native window.prompt(). Resolves to the\n// trimmed string, or null if the user cancelled. Empty input counts as\n// cancel by default; pass `allowEmpty: true` to opt in.\ninterface PromptOptions {\n title?: string;\n message?: string;\n defaultValue?: string;\n placeholder?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n allowEmpty?: boolean;\n}\ntype PromptFn = (options: PromptOptions | string) => Promise<string | null>;\nlet globalPromptFn: PromptFn = () => Promise.resolve(null);\nexport const prompt = (opts: PromptOptions | string) => globalPromptFn(opts);\n\nexport function ConfirmProvider({ children }: { children: React.ReactNode }) {\n const [open, setOpen] = useState(false);\n const [options, setOptions] = useState<ConfirmOptions>({ message: '' });\n const resolveRef = useRef<(value: boolean) => void>();\n\n const confirmFn: ConfirmFn = useCallback((opts) => {\n const normalized = typeof opts === 'string' ? { message: opts } : opts;\n setOptions(normalized);\n setOpen(true);\n return new Promise<boolean>((resolve) => {\n resolveRef.current = resolve;\n });\n }, []);\n\n // Destructive confirm state\n const [dOpen, setDOpen] = useState(false);\n const [dOptions, setDOptions] = useState<DestructiveConfirmOptions>({ message: '', confirmWord: 'Delete' });\n const [dInput, setDInput] = useState('');\n const dResolveRef = useRef<(value: boolean) => void>();\n\n const destructiveConfirmFn: DestructiveConfirmFn = useCallback((opts) => {\n setDOptions(opts);\n setDInput('');\n setDOpen(true);\n return new Promise<boolean>((resolve) => {\n dResolveRef.current = resolve;\n });\n }, []);\n\n // Prompt state\n const [pOpen, setPOpen] = useState(false);\n const [pOptions, setPOptions] = useState<PromptOptions>({});\n const [pInput, setPInput] = useState('');\n const pResolveRef = useRef<(value: string | null) => void>();\n\n const promptFn: PromptFn = useCallback((opts) => {\n const normalized = typeof opts === 'string' ? { message: opts } : opts;\n setPOptions(normalized);\n setPInput(normalized.defaultValue ?? '');\n setPOpen(true);\n return new Promise<string | null>((resolve) => {\n pResolveRef.current = resolve;\n });\n }, []);\n\n useEffect(() => {\n globalConfirmFn = confirmFn;\n globalDestructiveConfirmFn = destructiveConfirmFn;\n globalPromptFn = promptFn;\n }, [confirmFn, destructiveConfirmFn, promptFn]);\n\n const handleClose = (result: boolean) => {\n setOpen(false);\n resolveRef.current?.(result);\n };\n\n const handleDClose = (result: boolean) => {\n setDOpen(false);\n setDInput('');\n dResolveRef.current?.(result);\n };\n\n const handlePClose = (commit: boolean) => {\n if (commit) {\n const trimmed = pInput.trim();\n if (!trimmed && !pOptions.allowEmpty) {\n // Empty + not opted-in to allow empty: treat Save as Cancel.\n setPOpen(false);\n pResolveRef.current?.(null);\n return;\n }\n setPOpen(false);\n pResolveRef.current?.(trimmed);\n } else {\n setPOpen(false);\n pResolveRef.current?.(null);\n }\n };\n\n // A confirm/destructive/prompt dialog floats above every shell window\n // (z-9999) but is NOT a shell Modal, so it's absent from the window activation\n // order. Without this, pressing Escape over a dialog reaches the frontmost\n // Modal's window-close handler and closes the WINDOW BENEATH the dialog. While\n // any dialog is open, claim Escape via the shell's escape-interceptor hook and\n // dismiss the TOP-MOST open dialog instead. Returning true makes Modal\n // preventDefault/stopPropagation and skip its window close; stopping the event\n // in the window capture phase also pre-empts Headless UI's own (bubble-phase)\n // Escape listener, so the dialog's onClose never double-fires. With no shell\n // window beneath, no interceptor runs and Headless UI closes the dialog itself.\n useEffect(() => {\n if (!open && !dOpen && !pOpen) return;\n return registerModalEscapeInterceptor(() => {\n // Paint order confirm < destructive < prompt → dismiss the top-most first.\n if (pOpen) { handlePClose(false); return true; }\n if (dOpen) { handleDClose(false); return true; }\n if (open) { handleClose(false); return true; }\n return false;\n });\n // The close handlers' cancel paths don't read transient input, so they're\n // safe to close over; re-register only when which dialog is open changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, dOpen, pOpen]);\n\n const variant = options.variant || (options.confirmLabel?.toLowerCase().includes('delete') || options.message.toLowerCase().includes('delete') ? 'danger' : 'info');\n const confirmBtnClass = variant === 'danger'\n ? 'bg-red-600 hover:bg-red-700 text-white'\n : variant === 'warning'\n ? 'bg-yellow-600 hover:bg-yellow-700 text-white'\n : 'bg-blue-600 hover:bg-blue-700 text-white';\n const iconClass = variant === 'danger'\n ? 'text-red-600 bg-red-100'\n : variant === 'warning'\n ? 'text-yellow-600 bg-yellow-100'\n : 'text-blue-600 bg-blue-100';\n\n return (\n <ConfirmContext.Provider value={confirmFn}>\n {children}\n <Dialog open={open} onClose={() => handleClose(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-4\">\n <DialogPanel className=\"w-full max-w-md rounded-lg bg-white p-6 shadow-xl\">\n <div className=\"flex gap-4\">\n <div className={`shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${iconClass}`}>\n <ExclamationTriangleIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"flex-1\">\n <DialogTitle className=\"text-base font-semibold text-gray-900\">\n {options.title || 'Confirm'}\n </DialogTitle>\n <p className=\"mt-2 text-sm text-gray-600\">{options.message}</p>\n </div>\n </div>\n <div className=\"mt-6 flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => handleClose(false)}\n className=\"bg-white text-gray-700 border border-gray-300 px-4 py-2 text-sm font-medium rounded-lg hover:bg-gray-50\"\n >\n {options.cancelLabel || 'Cancel'}\n </button>\n <button\n type=\"button\"\n onClick={() => handleClose(true)}\n className={`px-4 py-2 text-sm font-medium rounded-lg ${confirmBtnClass}`}\n >\n {options.confirmLabel || 'OK'}\n </button>\n </div>\n </DialogPanel>\n </div>\n </Dialog>\n {/* Destructive Confirm Dialog — requires typing to confirm */}\n <Dialog open={dOpen} onClose={() => handleDClose(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-4\">\n <DialogPanel className=\"relative w-full max-w-md rounded-lg bg-white p-6 shadow-xl\">\n <button\n type=\"button\"\n onClick={() => handleDClose(false)}\n aria-label=\"Close\"\n className=\"absolute right-4 top-4 rounded-md p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600\"\n >\n <XMarkIcon className=\"h-5 w-5\" />\n </button>\n <div className=\"flex gap-4\">\n <div className={`shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${dOptions.variant === 'warning' ? 'text-yellow-600 bg-yellow-100' : 'text-red-600 bg-red-100'}`}>\n <ExclamationTriangleIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"flex-1\">\n <DialogTitle className=\"text-base font-semibold text-gray-900 pr-6\">\n {dOptions.title || 'Confirm Action'}\n </DialogTitle>\n <p className=\"mt-2 text-sm text-gray-600\">{dOptions.message}</p>\n <p className=\"mt-3 text-sm text-gray-700\">\n Type <kbd className=\"rounded border border-gray-300 bg-gray-50 px-1.5 py-0.5 text-xs font-bold text-red-600 font-mono\">{dOptions.confirmWord}</kbd> to confirm:\n </p>\n <input\n autoFocus\n type=\"text\"\n value={dInput}\n onChange={e => setDInput(e.target.value)}\n onKeyDown={e => { if (e.key === 'Enter' && dInput === dOptions.confirmWord) handleDClose(true); }}\n placeholder={dOptions.confirmWord}\n className=\"mt-2 w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-red-500 focus:ring-red-500\"\n />\n </div>\n </div>\n <div className=\"mt-6 flex justify-end gap-3\">\n <button type=\"button\" onClick={() => handleDClose(false)}\n className=\"bg-white text-gray-700 border border-gray-300 px-4 py-2 text-sm font-medium rounded-lg hover:bg-gray-50\">\n Dismiss\n </button>\n <button type=\"button\" onClick={() => handleDClose(true)}\n disabled={dInput !== dOptions.confirmWord}\n className={`px-4 py-2 text-sm font-medium rounded-lg disabled:opacity-40 ${dOptions.variant === 'warning' ? 'bg-yellow-600 hover:bg-yellow-700 text-white' : 'bg-red-600 hover:bg-red-700 text-white'}`}>\n {dOptions.confirmWord}\n </button>\n </div>\n </DialogPanel>\n </div>\n </Dialog>\n {/* Prompt Dialog — windowed replacement for window.prompt() */}\n <Dialog open={pOpen} onClose={() => handlePClose(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-4\">\n <DialogPanel className=\"w-full max-w-md rounded-lg bg-white p-6 shadow-xl\">\n <DialogTitle className=\"text-base font-semibold text-gray-900\">\n {pOptions.title || 'Enter a value'}\n </DialogTitle>\n {pOptions.message && (\n <p className=\"mt-2 text-sm text-gray-600\">{pOptions.message}</p>\n )}\n <input\n autoFocus\n type=\"text\"\n value={pInput}\n onChange={(e) => setPInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handlePClose(true);\n else if (e.key === 'Escape') handlePClose(false);\n }}\n onFocus={(e) => e.target.select()}\n placeholder={pOptions.placeholder}\n className=\"mt-3 w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none\"\n />\n <div className=\"mt-6 flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => handlePClose(false)}\n className=\"bg-white text-gray-700 border border-gray-300 px-4 py-2 text-sm font-medium rounded-lg hover:bg-gray-50\"\n >\n {pOptions.cancelLabel || 'Cancel'}\n </button>\n <button\n type=\"button\"\n onClick={() => handlePClose(true)}\n disabled={!pOptions.allowEmpty && !pInput.trim()}\n className=\"bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 text-sm font-medium rounded-lg disabled:opacity-40\"\n >\n {pOptions.confirmLabel || 'OK'}\n </button>\n </div>\n </DialogPanel>\n </div>\n </Dialog>\n </ConfirmContext.Provider>\n );\n}\n"]}
|