@tangle-network/agent-app 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{DesignCanvas-3JEEIT6Y.js → DesignCanvas-JTSAL6KX.js} +2 -2
  2. package/dist/DesignCanvasEditor-YPVETLZG.js +9 -0
  3. package/dist/{chunk-F5KTWRO7.js → chunk-2W4YCAFH.js} +5 -1
  4. package/dist/chunk-2W4YCAFH.js.map +1 -0
  5. package/dist/{chunk-4NXVI7PW.js → chunk-FA4XR66Y.js} +2 -2
  6. package/dist/chunk-FA4XR66Y.js.map +1 -0
  7. package/dist/{chunk-QAQBR6KQ.js → chunk-JZZ6AWF4.js} +3 -2
  8. package/dist/{chunk-QAQBR6KQ.js.map → chunk-JZZ6AWF4.js.map} +1 -1
  9. package/dist/{chunk-ETX4O4BB.js → chunk-LUE4HO5C.js} +95 -177
  10. package/dist/chunk-LUE4HO5C.js.map +1 -0
  11. package/dist/{chunk-SSX2A6XX.js → chunk-MH6AVXQ7.js} +2 -2
  12. package/dist/{chunk-2Q73HGDI.js → chunk-NSKJFV4Y.js} +17 -5
  13. package/dist/chunk-NSKJFV4Y.js.map +1 -0
  14. package/dist/design-canvas/index.d.ts +2 -2
  15. package/dist/design-canvas-react/index.d.ts +16 -2
  16. package/dist/design-canvas-react/index.js +4 -4
  17. package/dist/eval/index.d.ts +1 -1
  18. package/dist/eval/index.js +1 -1
  19. package/dist/index.d.ts +5 -3
  20. package/dist/index.js +10 -8
  21. package/dist/{mcp-CIupfjxV.d.ts → mcp-eZCmkgCF.d.ts} +1 -1
  22. package/dist/preset-cloudflare/index.d.ts +1 -1
  23. package/dist/runtime/index.d.ts +94 -161
  24. package/dist/runtime/index.js +8 -6
  25. package/dist/sequences/index.d.ts +2 -2
  26. package/dist/tools/index.d.ts +4 -4
  27. package/dist/tools/index.js +2 -2
  28. package/dist/{types-By4B3K37.d.ts → types-2rOJo8Hc.d.ts} +6 -3
  29. package/package.json +5 -4
  30. package/dist/DesignCanvasEditor-37LPJIIR.js +0 -9
  31. package/dist/chunk-2Q73HGDI.js.map +0 -1
  32. package/dist/chunk-4NXVI7PW.js.map +0 -1
  33. package/dist/chunk-ETX4O4BB.js.map +0 -1
  34. package/dist/chunk-F5KTWRO7.js.map +0 -1
  35. /package/dist/{DesignCanvas-3JEEIT6Y.js.map → DesignCanvas-JTSAL6KX.js.map} +0 -0
  36. /package/dist/{DesignCanvasEditor-37LPJIIR.js.map → DesignCanvasEditor-YPVETLZG.js.map} +0 -0
  37. /package/dist/{chunk-SSX2A6XX.js.map → chunk-MH6AVXQ7.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/design-canvas-react/components/DesignCanvas.tsx","../src/design-canvas-react/engine/command-stack.ts","../src/design-canvas-react/engine/commands.ts","../src/design-canvas-react/components/ruler-math.ts","../src/design-canvas-react/components/BleedTrimOverlay.tsx","../src/design-canvas-react/components/PagesStrip.tsx","../src/design-canvas-react/components/glyphs.tsx","../src/design-canvas-react/components/Rulers.tsx","../src/design-canvas-react/components/Toolbar.tsx","../src/design-canvas-react/components/ZoomControls.tsx"],"sourcesContent":["/**\n * Root editor shell. Products mount exactly this component. Layout mirrors\n * Polotno: optional left side panel | main column | optional right agent panel.\n *\n * Main column stacks top→bottom:\n * Toolbar (undo/redo, view toggles, selection attrs, page props)\n * Rulers + Workspace (the Workspace is injected by the integrator via the\n * `renderWorkspace` prop — it owns Konva and is Konva-\n * specific; this chrome stays canvas-free)\n * bottom row: PagesStrip + ZoomControls\n *\n * Command lifecycle:\n * - The command stack lives here; every panel receives callbacks, never the\n * stack itself.\n * - `onApplyOperations` is called optimistically after every command. If it\n * rejects, the command is rolled back locally. If it resolves with a fresh\n * `document`, the stack rebases via `stack.reset(document)` — this preserves\n * history while reconciling server-minted ids or normalised values.\n * - `setView` (zoom/pan/selection/toggles) never enters history.\n * - Keyboard: Mod+Z undo · Shift+Mod+Z / Mod+Y redo · Delete/Backspace deletes\n * the selection · F fits the page (forwarded to workspace via ref).\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { SceneDocument, SceneElement } from '../../design-canvas/model'\nimport { findElement, requirePage } from '../../design-canvas/model'\nimport type { SceneAttrsPatch, SceneOperation } from '../../design-canvas/operations'\nimport type { PageBleed } from '../../design-canvas/model'\nimport type { DesignCanvasProps, SceneCommand } from '../contracts'\nimport { createSceneCommandStack } from '../engine/command-stack'\nimport {\n addPageCommand,\n bindSlotCommand,\n deleteElementCommand,\n deletePageCommand,\n duplicatePageCommand,\n groupElementsCommand,\n multiSetAttrsCommand,\n reorderElementCommand,\n reorderPageCommand,\n setAttrsCommand,\n setPageGuidesCommand,\n setPagePropsCommand,\n ungroupElementCommand,\n} from '../engine/commands'\nimport { clampIndex, indexBackward, indexForward, topIndex } from './ruler-math'\nimport { BleedTrimOverlay } from './BleedTrimOverlay'\nimport { LayersPanel } from './LayersPanel'\nimport { PagesStrip } from './PagesStrip'\nimport { Rulers } from './Rulers'\nimport { Toolbar } from './Toolbar'\nimport { ZoomControls } from './ZoomControls'\n\n/** Callers inject a workspace renderer so this chrome stays Konva-free. The\n * workspace occupies the scrollable area between the rulers and the bottom bar. */\nexport interface DesignCanvasFullProps extends DesignCanvasProps {\n /**\n * Render the Konva canvas workspace into the slot this shell provides.\n * The shell passes viewport dimensions, view-state, and the shared command\n * stack so `WorkspaceView` can commit gestures through the same stack the\n * chrome uses for undo/redo and layers-panel selection.\n *\n * `onFitRef` is a ref the workspace fills with a fit-page callback; the\n * shell calls it when the user presses F or clicks the Fit button.\n */\n renderWorkspace(ctx: {\n document: SceneDocument\n activePageId: string\n selectedElementIds: string[]\n zoom: number\n panX: number\n panY: number\n gridEnabled: boolean\n gridSize: number\n snapEnabled: boolean\n showBleed: boolean\n canWrite: boolean\n /** The chrome's command stack. Pass to WorkspaceView so gestures, undo,\n * and layers-panel selection share a single state machine. */\n stack: ReturnType<typeof createSceneCommandStack>\n activePage: SceneDocument['pages'][number] | undefined\n onFitRef: React.MutableRefObject<(() => void) | null>\n onZoomChange(zoom: number): void\n onPanChange(panX: number, panY: number): void\n onSelectElements(ids: string[], additive: boolean): void\n }): React.ReactNode\n\n /**\n * Generates page thumbnails for the PagesStrip. Injected by the integrator\n * (who has Konva access) so the chrome doesn't import Konva directly.\n */\n renderThumbnail(page: SceneDocument['pages'][number]): Promise<string | null>\n}\n\nfunction mintId(): string {\n const uuid = globalThis.crypto && 'randomUUID' in globalThis.crypto\n ? globalThis.crypto.randomUUID()\n : null\n return `local-${uuid ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`\n}\n\nfunction isTypingTarget(target: EventTarget | null): boolean {\n return (\n target instanceof Element &&\n target.closest('input, textarea, select, [contenteditable=\"true\"]') !== null\n )\n}\n\n/** Commit a command: execute optimistically, persist via `onApplyOperations`,\n * roll back locally on rejection. The command reference is captured at call\n * time so the rejection handler removes that specific command regardless of\n * how many further commands the user has executed while the save was pending. */\nfunction useCommitCommand(\n stack: ReturnType<typeof createSceneCommandStack>,\n onApplyOperations: DesignCanvasProps['onApplyOperations'],\n canWrite: boolean,\n setError: (msg: string | null) => void,\n) {\n return useCallback(\n (command: SceneCommand) => {\n if (!canWrite) return\n try {\n stack.execute(command)\n } catch (error) {\n setError(error instanceof Error ? error.message : String(error))\n return\n }\n const ops = command.operations()\n void onApplyOperations(ops)\n .then((result) => {\n if (result.document) {\n // Server re-minted ids or normalised the document: rebase without\n // clearing history. History holds transforms, not snapshots, so\n // rebasing cannot stale it; a later undo re-applies the inverse\n // transform to the current (rebased) document.\n stack.reset(result.document)\n }\n })\n .catch((error: unknown) => {\n // Roll back the specific command that failed. stack.rollback() splices\n // this command out of history and applies its inverse to the current\n // state — commands the user executed while this save was in-flight are\n // not disturbed (their undo entries are preserved). If the command is\n // no longer in the stack (double-fire or already reset), rollback is a\n // safe no-op.\n stack.rollback(command)\n setError(error instanceof Error ? error.message : String(error))\n })\n },\n [stack, onApplyOperations, canWrite, setError],\n )\n}\n\nexport function DesignCanvas({\n document: initialDocument,\n rev: initialRev,\n canWrite,\n onApplyOperations,\n onSelectionChange,\n renderAgentPanel,\n renderSidePanel,\n onExport,\n className,\n renderWorkspace,\n renderThumbnail,\n}: DesignCanvasFullProps) {\n // The command stack is created once from the initial document. Subsequent\n // server refreshes come in via the prop and are applied via reset().\n const stack = useMemo(\n () => createSceneCommandStack(initialDocument, initialDocument.pages[0]?.id ?? 'page-1'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n\n const editorState = useSyncExternalStore(stack.subscribe, stack.getState, stack.getState)\n\n // Track the applied document prop to detect server refreshes.\n const appliedDocumentRef = useRef(initialDocument)\n useEffect(() => {\n if (appliedDocumentRef.current === initialDocument) return\n appliedDocumentRef.current = initialDocument\n stack.reset(initialDocument)\n }, [initialDocument, stack])\n\n const [commitError, setCommitError] = useState<string | null>(null)\n\n const commit = useCommitCommand(stack, onApplyOperations, canWrite, setCommitError)\n\n // Notify host when selection changes.\n const selectionChangeRef = useRef(onSelectionChange)\n selectionChangeRef.current = onSelectionChange\n useEffect(() => {\n const page = editorState.document.pages.find((p) => p.id === editorState.activePageId)\n if (!page) return\n const selected = editorState.selectedElementIds\n .map((id) => page.elements.find((el) => el.id === id))\n .filter((el): el is SceneElement => el !== undefined)\n selectionChangeRef.current?.(selected)\n }, [editorState.selectedElementIds, editorState.activePageId, editorState.document])\n\n // Workspace fit callback ref — the workspace fills this; the shell calls it.\n const fitRef = useRef<(() => void) | null>(null)\n\n // ---------------------------------------------------------------------------\n // View-state helpers (no history)\n // ---------------------------------------------------------------------------\n\n const setZoom = useCallback((zoom: number) => stack.setView({ zoom }), [stack])\n const setPan = useCallback((panX: number, panY: number) => stack.setView({ panX, panY }), [stack])\n const setActivePage = useCallback((activePageId: string) => stack.setView({ activePageId, selectedElementIds: [] }), [stack])\n\n const setSelectedElements = useCallback(\n (ids: string[], additive: boolean) => {\n if (!additive) {\n stack.setView({ selectedElementIds: ids })\n return\n }\n const current = new Set(editorState.selectedElementIds)\n for (const id of ids) {\n if (current.has(id)) current.delete(id)\n else current.add(id)\n }\n stack.setView({ selectedElementIds: [...current] })\n },\n [stack, editorState.selectedElementIds],\n )\n\n // ---------------------------------------------------------------------------\n // Element commands\n // ---------------------------------------------------------------------------\n\n const handleSetAttrs = useCallback(\n (elementId: string, attrs: SceneAttrsPatch) => {\n const page = requirePage(editorState.document, editorState.activePageId)\n // findElement searches group children; page.elements.find misses nested elements.\n const found = findElement(page, elementId)\n if (!found) return\n if (found.element.locked) return\n const priorAttrs: SceneAttrsPatch = Object.fromEntries(\n Object.keys(attrs).map((k) => [k, (found.element as unknown as Record<string, unknown>)[k]]),\n ) as SceneAttrsPatch\n commit(\n setAttrsCommand({\n pageId: editorState.activePageId,\n elementId,\n attrs,\n priorAttrs,\n }),\n )\n },\n [commit, editorState.activePageId, editorState.document],\n )\n\n const handleMultiSetAttrs = useCallback(\n (patches: Array<{ elementId: string; attrs: SceneAttrsPatch }>) => {\n const page = requirePage(editorState.document, editorState.activePageId)\n const entries = patches.flatMap(({ elementId, attrs }) => {\n const found = findElement(page, elementId)\n // Skip elements that are missing (concurrent delete) or locked.\n if (!found || found.element.locked) return []\n const priorAttrs = Object.fromEntries(\n Object.keys(attrs).map((k) => [k, (found.element as unknown as Record<string, unknown>)[k]]),\n ) as SceneAttrsPatch\n return [{ pageId: editorState.activePageId, elementId, attrs, priorAttrs }]\n })\n if (entries.length === 0) return\n commit(multiSetAttrsCommand(entries))\n },\n [commit, editorState.activePageId, editorState.document],\n )\n\n const handleReorder = useCallback(\n (elementId: string, toIndex: number, ownerLength: number, direction: 'front' | 'back' | 'forward' | 'backward') => {\n const page = requirePage(editorState.document, editorState.activePageId)\n // findElement searches group children so nested elements are reorderable.\n const found = findElement(page, elementId)\n if (!found) return\n const currentIndex = found.index\n const target =\n direction === 'front'\n ? topIndex(ownerLength)\n : direction === 'back'\n ? 0\n : direction === 'forward'\n ? indexForward(currentIndex, ownerLength)\n : indexBackward(currentIndex)\n const clamped = clampIndex(target, ownerLength)\n if (clamped === currentIndex) return\n commit(reorderElementCommand({ pageId: editorState.activePageId, elementId, toIndex: clamped }))\n },\n [commit, editorState.activePageId, editorState.document],\n )\n\n const handleDelete = useCallback(\n (elementIds: string[]) => {\n for (const elementId of elementIds) {\n commit(\n deleteElementCommand({\n document: editorState.document,\n pageId: editorState.activePageId,\n elementId,\n }),\n )\n }\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n const handleGroup = useCallback(\n (elementIds: string[]) => {\n commit(\n groupElementsCommand({\n document: editorState.document,\n pageId: editorState.activePageId,\n elementIds,\n groupId: mintId(),\n }),\n )\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n const handleUngroup = useCallback(\n (groupId: string) => {\n commit(ungroupElementCommand({ document: editorState.document, pageId: editorState.activePageId, groupId }))\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n const handleBindSlot = useCallback(\n (elementId: string, slot: string | null) => {\n commit(bindSlotCommand({ document: editorState.document, pageId: editorState.activePageId, elementId, slot }))\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n // ---------------------------------------------------------------------------\n // Page commands\n // ---------------------------------------------------------------------------\n\n const handleSetPageProps = useCallback(\n (props: { name?: string; width?: number; height?: number; background?: string; bleed?: PageBleed | null }) => {\n commit(setPagePropsCommand({ document: editorState.document, pageId: editorState.activePageId, props }))\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n const handleSetPageGuides = useCallback(\n (guides: { vertical: number[]; horizontal: number[] }) => {\n commit(setPageGuidesCommand({ document: editorState.document, pageId: editorState.activePageId, guides }))\n },\n [commit, editorState.document, editorState.activePageId],\n )\n\n const handleAddPage = useCallback(() => {\n const pageId = mintId()\n commit(addPageCommand({ pageId }))\n setActivePage(pageId)\n }, [commit, setActivePage])\n\n const handleDuplicatePage = useCallback(\n (sourcePageId: string) => {\n const pageId = mintId()\n commit(duplicatePageCommand({ document: editorState.document, sourcePageId, pageId }))\n setActivePage(pageId)\n },\n [commit, editorState.document, setActivePage],\n )\n\n const handleDeletePage = useCallback(\n (pageId: string) => {\n commit(deletePageCommand({ document: editorState.document, pageId }))\n },\n [commit, editorState.document],\n )\n\n const handleReorderPage = useCallback(\n (pageId: string, toIndex: number) => {\n commit(reorderPageCommand({ pageId, toIndex }))\n },\n [commit],\n )\n\n // ---------------------------------------------------------------------------\n // Undo / redo\n // ---------------------------------------------------------------------------\n\n const handleUndo = useCallback(() => {\n if (!canWrite || !stack.canUndo()) return\n let command\n try {\n command = stack.undo()\n } catch (error) {\n setCommitError(`Undo failed: ${error instanceof Error ? error.message : String(error)}`)\n return\n }\n // Persist the inverse so the server tracks the undo; on rejection re-execute\n // to re-apply the original forward state.\n void onApplyOperations(command.inverseOperations())\n .then((result) => {\n if (result.document) stack.reset(result.document)\n })\n .catch((error: unknown) => {\n if (stack.canRedo()) {\n try { stack.redo() } catch { /* concurrent edit; next reset reconciles */ }\n }\n setCommitError(error instanceof Error ? error.message : String(error))\n })\n }, [stack, canWrite, onApplyOperations])\n\n const handleRedo = useCallback(() => {\n if (!canWrite || !stack.canRedo()) return\n let command\n try {\n command = stack.redo()\n } catch (error) {\n setCommitError(`Redo failed: ${error instanceof Error ? error.message : String(error)}`)\n return\n }\n void onApplyOperations(command.operations())\n .then((result) => {\n if (result.document) stack.reset(result.document)\n })\n .catch((error: unknown) => {\n if (stack.canUndo()) {\n try { stack.undo() } catch { /* concurrent edit; next reset reconciles */ }\n }\n setCommitError(error instanceof Error ? error.message : String(error))\n })\n }, [stack, canWrite, onApplyOperations])\n\n // ---------------------------------------------------------------------------\n // Keyboard shortcuts\n // ---------------------------------------------------------------------------\n\n useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n const mod = event.metaKey || event.ctrlKey\n if (mod && !isTypingTarget(event.target)) {\n if (event.key.toLowerCase() === 'z') {\n event.preventDefault()\n if (event.shiftKey) handleRedo()\n else handleUndo()\n return\n }\n if (event.key.toLowerCase() === 'y') {\n event.preventDefault()\n handleRedo()\n return\n }\n }\n if ((event.key === 'Delete' || event.key === 'Backspace') && !isTypingTarget(event.target)) {\n if (!canWrite || editorState.selectedElementIds.length === 0) return\n event.preventDefault()\n handleDelete(editorState.selectedElementIds)\n return\n }\n if (event.key.toLowerCase() === 'f' && !isTypingTarget(event.target)) {\n event.preventDefault()\n fitRef.current?.()\n }\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n })\n\n // ---------------------------------------------------------------------------\n // Derived state for render\n // ---------------------------------------------------------------------------\n\n const activePage = useMemo(\n () => editorState.document.pages.find((p) => p.id === editorState.activePageId),\n [editorState.document, editorState.activePageId],\n )\n\n const selectedElements = useMemo(() => {\n if (!activePage) return []\n return editorState.selectedElementIds\n .map((id) => activePage.elements.find((el) => el.id === id))\n .filter((el): el is SceneElement => el !== undefined)\n }, [activePage, editorState.selectedElementIds])\n\n if (!activePage) {\n return (\n <div className={`flex h-full items-center justify-center bg-[var(--bg-input)] text-[var(--text-muted)] ${className ?? ''}`}>\n No pages in document\n </div>\n )\n }\n\n // Bleed extents in screen px for the overlay\n const bleedScreen = editorState.showBleed && activePage.bleed\n ? {\n top: activePage.bleed.top * editorState.zoom,\n right: activePage.bleed.right * editorState.zoom,\n bottom: activePage.bleed.bottom * editorState.zoom,\n left: activePage.bleed.left * editorState.zoom,\n }\n : null\n\n return (\n <div className={`flex h-full min-h-0 bg-[var(--bg-input)] text-[var(--text-primary)] ${className ?? ''}`}>\n {/* Optional left side panel (asset/template browser, etc.) */}\n {renderSidePanel ? (\n <aside className=\"flex w-64 shrink-0 flex-col overflow-hidden border-r border-[var(--border-default)]\">\n {renderSidePanel()}\n </aside>\n ) : null}\n\n {/* Main column */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Toolbar */}\n <Toolbar\n page={activePage}\n selectedElements={selectedElements}\n canWrite={canWrite}\n canUndo={stack.canUndo()}\n canRedo={stack.canRedo()}\n gridEnabled={editorState.gridEnabled}\n snapEnabled={editorState.snapEnabled}\n showRulers={editorState.showRulers}\n showBleed={editorState.showBleed}\n onUndo={handleUndo}\n onRedo={handleRedo}\n onToggleGrid={() => stack.setView({ gridEnabled: !editorState.gridEnabled })}\n onToggleSnap={() => stack.setView({ snapEnabled: !editorState.snapEnabled })}\n onToggleRulers={() => stack.setView({ showRulers: !editorState.showRulers })}\n onToggleBleed={() => stack.setView({ showBleed: !editorState.showBleed })}\n onSetAttrs={handleSetAttrs}\n onSetPageProps={handleSetPageProps}\n onSetPageGuides={handleSetPageGuides}\n onReorder={handleReorder}\n onGroup={handleGroup}\n onUngroup={handleUngroup}\n onDelete={handleDelete}\n onBindSlot={handleBindSlot}\n />\n\n {/* Error bar */}\n {commitError ? (\n <div\n className=\"flex shrink-0 items-center justify-between gap-3 border-b border-rose-500/30 bg-rose-500/10 px-3 py-1.5 text-xs text-rose-300\"\n role=\"alert\"\n >\n <span className=\"min-w-0 truncate\">{commitError}</span>\n <button\n type=\"button\"\n onClick={() => setCommitError(null)}\n className=\"shrink-0 underline-offset-2 hover:underline\"\n >\n Dismiss\n </button>\n </div>\n ) : null}\n\n {/* Rulers + Workspace area */}\n <div className=\"relative min-h-0 flex-1\">\n {/* Rulers overlay inside the workspace container */}\n <Rulers\n pageWidth={activePage.width}\n pageHeight={activePage.height}\n zoom={editorState.zoom}\n scrollLeft={-editorState.panX / editorState.zoom}\n scrollTop={-editorState.panY / editorState.zoom}\n showRulers={editorState.showRulers}\n guides={activePage.guides}\n onGuidesChange={handleSetPageGuides}\n />\n\n {/* Bleed overlay — absolutely positioned over the workspace */}\n {bleedScreen && activePage.bleed ? (\n <div\n className=\"pointer-events-none absolute inset-0 z-10 overflow-hidden\"\n aria-hidden\n >\n <div\n style={{\n position: 'absolute',\n left: editorState.panX,\n top: editorState.panY,\n }}\n >\n <BleedTrimOverlay\n pageWidthPx={activePage.width * editorState.zoom}\n pageHeightPx={activePage.height * editorState.zoom}\n bleed={bleedScreen}\n />\n </div>\n </div>\n ) : null}\n\n {/* Workspace slot (Konva; injected by integrator) */}\n {renderWorkspace({\n document: editorState.document,\n activePageId: editorState.activePageId,\n selectedElementIds: editorState.selectedElementIds,\n zoom: editorState.zoom,\n panX: editorState.panX,\n panY: editorState.panY,\n gridEnabled: editorState.gridEnabled,\n gridSize: editorState.gridSize,\n snapEnabled: editorState.snapEnabled,\n showBleed: editorState.showBleed,\n canWrite,\n stack,\n activePage,\n onFitRef: fitRef,\n onZoomChange: setZoom,\n onPanChange: setPan,\n onSelectElements: setSelectedElements,\n })}\n </div>\n\n {/* Bottom row: PagesStrip + ZoomControls */}\n <div className=\"flex shrink-0 items-stretch border-t border-[var(--border-default)]\">\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n <PagesStrip\n pages={editorState.document.pages}\n activePageId={editorState.activePageId}\n canWrite={canWrite}\n renderThumbnail={renderThumbnail}\n onSelectPage={setActivePage}\n onAddPage={handleAddPage}\n onDuplicatePage={handleDuplicatePage}\n onDeletePage={handleDeletePage}\n onReorderPage={handleReorderPage}\n />\n </div>\n <div className=\"flex shrink-0 items-center border-l border-[var(--border-default)]\">\n <ZoomControls\n zoom={editorState.zoom}\n onZoom={setZoom}\n onFit={() => fitRef.current?.()}\n />\n </div>\n </div>\n </div>\n\n {/* Optional right agent panel */}\n {renderAgentPanel ? (\n <aside className=\"flex w-80 shrink-0 flex-col overflow-hidden border-l border-[var(--border-default)]\">\n {renderAgentPanel({ selectedElements, activePageId: editorState.activePageId })}\n </aside>\n ) : null}\n\n {/* Layers panel lives in the left side panel slot by convention; products\n that want it standalone can render LayersPanel directly. */}\n </div>\n )\n}\n\nexport default DesignCanvas\n","/**\n * Undo/redo command stack over immutable `EditorSceneState`.\n *\n * History entries hold COMMANDS (state transforms + durable operations\n * captured at construction), never snapshots. Rebasing the document via\n * `reset()` therefore cannot stale the history: a later undo re-applies the\n * inverse transform to whatever document is current. If the rebase removed an\n * element a historical command targets, that transform throws (fail loud)\n * rather than silently editing the wrong element.\n *\n * `setView` updates volatile view state (zoom/pan/selection/toggles) without\n * touching history — view changes are never undo steps.\n */\n\nimport type { SceneDocument } from '../../design-canvas/model'\nimport type { EditorSceneState, SceneCommand, SceneCommandStack } from '../contracts'\n\n/** Oldest entries are dropped past this bound; redo stack is cleared on execute. */\nexport const SCENE_COMMAND_HISTORY_LIMIT = 200\n\nexport function createSceneCommandStack(document: SceneDocument, activePageId: string): SceneCommandStack {\n let state: EditorSceneState = {\n document,\n activePageId,\n selectedElementIds: [],\n zoom: 1,\n panX: 0,\n panY: 0,\n gridEnabled: false,\n gridSize: 10,\n snapEnabled: true,\n showRulers: true,\n showBleed: false,\n }\n\n const undoStack: SceneCommand[] = []\n const redoStack: SceneCommand[] = []\n const listeners = new Set<() => void>()\n\n const notify = (): void => {\n for (const listener of [...listeners]) listener()\n }\n\n return {\n execute(command: SceneCommand): void {\n state = command.execute(state)\n undoStack.push(command)\n if (undoStack.length > SCENE_COMMAND_HISTORY_LIMIT) {\n undoStack.splice(0, undoStack.length - SCENE_COMMAND_HISTORY_LIMIT)\n }\n redoStack.length = 0\n notify()\n },\n\n // Both transforms run BEFORE the stacks move: a throwing transform (e.g.\n // missing element after reset()) leaves history and state exactly as they\n // were. The entry is never silently destroyed — the caller can retry after\n // the next server refresh restores the target.\n undo(): SceneCommand {\n const command = undoStack[undoStack.length - 1]\n if (!command) throw new Error('nothing to undo — guard with canUndo() before calling undo()')\n state = command.undo(state)\n undoStack.pop()\n redoStack.push(command)\n notify()\n return command\n },\n\n redo(): SceneCommand {\n const command = redoStack[redoStack.length - 1]\n if (!command) throw new Error('nothing to redo — guard with canRedo() before calling redo()')\n state = command.execute(state)\n redoStack.pop()\n undoStack.push(command)\n notify()\n return command\n },\n\n canUndo(): boolean {\n return undoStack.length > 0\n },\n\n canRedo(): boolean {\n return redoStack.length > 0\n },\n\n subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n\n getState(): EditorSceneState {\n return state\n },\n\n setView(patch: Partial<Omit<EditorSceneState, 'document'>>): void {\n state = { ...state, ...patch }\n notify()\n },\n\n rollback(command: SceneCommand): void {\n const idx = undoStack.lastIndexOf(command)\n // Command not in history — stale or double-fire rejection handler; no-op.\n if (idx === -1) return\n\n // Apply the command's inverse against the current state. For non-overlapping\n // edits (different elements or different attributes) this is exact: the\n // inverse commutes freely past all subsequent commands. For overlapping edits\n // on the same attribute the result is defined but not semantically perfect;\n // the persistence layer should trigger an onResyncRequired refetch in that\n // case so the server document reconciles.\n state = command.undo(state)\n\n // Splice the target command out of the undo stack.\n undoStack.splice(idx, 1)\n\n // Clear the redo stack: its entries were computed relative to a history that\n // included this command, so they are now stale.\n redoStack.length = 0\n\n notify()\n },\n\n /** Rebase onto a server-refreshed document. History survives; selection\n * drops ids the refresh removed so view state never dangles. */\n reset(newDocument: SceneDocument): void {\n // Collect all live element ids across all pages for selection cleanup\n const liveElementIds = new Set<string>()\n for (const page of newDocument.pages) {\n collectElementIds(page.elements, liveElementIds)\n }\n // If the active page was removed, fall back to the first page\n const activePageExists = newDocument.pages.some((p) => p.id === state.activePageId)\n const activePageId = activePageExists ? state.activePageId : (newDocument.pages[0]?.id ?? state.activePageId)\n state = {\n ...state,\n document: newDocument,\n activePageId,\n selectedElementIds: state.selectedElementIds.filter((id) => liveElementIds.has(id)),\n }\n notify()\n },\n }\n}\n\nfunction collectElementIds(elements: ReturnType<typeof Array.prototype.slice>, ids: Set<string>): void {\n for (const el of elements as Array<{ id: string; kind: string; children?: unknown[] }>) {\n ids.add(el.id)\n if (el.kind === 'group' && Array.isArray(el.children)) {\n collectElementIds(el.children as Array<{ id: string; kind: string; children?: unknown[] }>, ids)\n }\n }\n}\n","/**\n * Concrete `SceneCommand` factories for the design-canvas editor. Every factory\n * captures the inverse from PRE-state at construction — undo is a value\n * computed once, never re-derived from current state later. Local execute/undo\n * update `EditorSceneState` immutably by routing through `applySceneOperation`\n * so optimistic state matches what the server-side dispatcher will persist.\n *\n * Drag gestures coalesce: pointer moves update volatile state, ONE command\n * executes on pointer release with (finalAttrs, priorAttrs). `setAttrsCommand`\n * is that gesture command — one undo step per drag/transform/toolbar change.\n * `multiSetAttrsCommand` collects N set_attrs ops into one undo step for\n * multi-select transforms.\n *\n * Group/ungroup route through `applySceneOperation` so the group-origin\n * rebasing in `apply.ts` is the single source of truth for both optimistic and\n * server state.\n */\n\nimport type { SceneDocument, SceneElement, ScenePage } from '../../design-canvas/model'\nimport { requireElement, requirePage } from '../../design-canvas/model'\nimport { applySceneOperation, applySceneOperations } from '../../design-canvas/apply'\nimport type {\n AddElementOperation,\n DeleteElementOperation,\n SceneAttrsPatch,\n SceneOperation,\n} from '../../design-canvas/operations'\nimport type { EditorSceneState, SceneCommand } from '../contracts'\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nfunction applyOps(state: EditorSceneState, ops: SceneOperation[]): EditorSceneState {\n return { ...state, document: applySceneOperations(state.document, ops) }\n}\n\nfunction applyOp(state: EditorSceneState, op: SceneOperation): EditorSceneState {\n return { ...state, document: applySceneOperation(state.document, op) }\n}\n\n// ---------------------------------------------------------------------------\n// add_element / inverse = delete_element\n// ---------------------------------------------------------------------------\n\nexport interface AddElementInput {\n pageId: string\n element: SceneElement\n /** Insertion z-index within owner; omitted → top. */\n index?: number\n /** Parent group id; omitted → page root. */\n parentGroupId?: string\n}\n\nexport function addElementCommand(input: AddElementInput): SceneCommand {\n const addOp: SceneOperation = {\n type: 'add_element',\n pageId: input.pageId,\n element: structuredClone(input.element),\n ...(input.index !== undefined ? { index: input.index } : {}),\n ...(input.parentGroupId !== undefined ? { parentGroupId: input.parentGroupId } : {}),\n }\n const deleteOp: SceneOperation = {\n type: 'delete_element',\n pageId: input.pageId,\n elementId: input.element.id,\n }\n\n return {\n label: `Add ${input.element.kind}`,\n execute: (state) => applyOp(state, addOp),\n undo: (state) => applyOp(state, deleteOp),\n operations: () => [structuredClone(addOp)],\n inverseOperations: () => [structuredClone(deleteOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// set_attrs — THE gesture command (one undo step per drag/transform)\n// ---------------------------------------------------------------------------\n\nexport interface SetAttrsInput {\n pageId: string\n elementId: string\n /** Final attribute values after the gesture. */\n attrs: SceneAttrsPatch\n /** Attribute values BEFORE the gesture began — inverse is built from these. */\n priorAttrs: SceneAttrsPatch\n}\n\nexport function setAttrsCommand(input: SetAttrsInput): SceneCommand {\n const forwardOp: SceneOperation = {\n type: 'set_attrs',\n pageId: input.pageId,\n elementId: input.elementId,\n attrs: structuredClone(input.attrs),\n }\n const inverseOp: SceneOperation = {\n type: 'set_attrs',\n pageId: input.pageId,\n elementId: input.elementId,\n attrs: structuredClone(input.priorAttrs),\n }\n\n return {\n label: 'Edit element',\n execute: (state) => applyOp(state, forwardOp),\n undo: (state) => applyOp(state, inverseOp),\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => [structuredClone(inverseOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// multi-select set_attrs — N set_attrs ops, one undo step\n// ---------------------------------------------------------------------------\n\nexport interface MultiSetAttrsEntry {\n pageId: string\n elementId: string\n attrs: SceneAttrsPatch\n priorAttrs: SceneAttrsPatch\n}\n\nexport function multiSetAttrsCommand(entries: MultiSetAttrsEntry[]): SceneCommand {\n if (entries.length === 0) throw new Error('multiSetAttrsCommand: entries must not be empty')\n\n const forwardOps: SceneOperation[] = entries.map((e) => ({\n type: 'set_attrs' as const,\n pageId: e.pageId,\n elementId: e.elementId,\n attrs: structuredClone(e.attrs),\n }))\n const inverseOps: SceneOperation[] = entries.map((e) => ({\n type: 'set_attrs' as const,\n pageId: e.pageId,\n elementId: e.elementId,\n attrs: structuredClone(e.priorAttrs),\n }))\n\n return {\n label: `Edit ${entries.length} elements`,\n execute: (state) => applyOps(state, forwardOps),\n undo: (state) => applyOps(state, inverseOps),\n operations: () => structuredClone(forwardOps),\n inverseOperations: () => structuredClone(inverseOps),\n }\n}\n\n// ---------------------------------------------------------------------------\n// reorder_element\n// ---------------------------------------------------------------------------\n\nexport interface ReorderElementInput {\n pageId: string\n elementId: string\n toIndex: number\n}\n\nexport function reorderElementCommand(input: ReorderElementInput): SceneCommand {\n // Capture the element's current index at construction for the inverse\n let capturedFromIndex: number | null = null\n\n const forwardOp: SceneOperation = {\n type: 'reorder_element',\n pageId: input.pageId,\n elementId: input.elementId,\n toIndex: input.toIndex,\n }\n\n return {\n label: 'Reorder element',\n execute: (state) => {\n // Guard: on redo the element is already at toIndex, so we must not\n // overwrite the captured origin with the wrong position.\n if (capturedFromIndex === null) {\n const page = requirePage(state.document, input.pageId)\n const { index } = requireElement(page, input.elementId)\n capturedFromIndex = index\n }\n return applyOp(state, forwardOp)\n },\n undo: (state) => {\n if (capturedFromIndex === null) {\n throw new Error('reorderElementCommand: undo called before execute')\n }\n return applyOp(state, {\n type: 'reorder_element',\n pageId: input.pageId,\n elementId: input.elementId,\n toIndex: capturedFromIndex,\n })\n },\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => {\n if (capturedFromIndex === null) {\n throw new Error('reorderElementCommand: inverseOperations called before execute')\n }\n return [{\n type: 'reorder_element' as const,\n pageId: input.pageId,\n elementId: input.elementId,\n toIndex: capturedFromIndex,\n }]\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// delete_element / inverse = add_element (full snapshot + index + parent)\n// ---------------------------------------------------------------------------\n\nexport interface DeleteElementInput {\n document: SceneDocument\n pageId: string\n elementId: string\n}\n\nexport function deleteElementCommand(input: DeleteElementInput): SceneCommand {\n const page = requirePage(input.document, input.pageId)\n const { element, owner, index } = requireElement(page, input.elementId)\n const snapshot = structuredClone(element)\n\n // Determine parentGroupId by finding which group owns this element\n const parentGroupId = findParentGroupId(page, owner)\n\n const deleteOp: DeleteElementOperation = {\n type: 'delete_element',\n pageId: input.pageId,\n elementId: input.elementId,\n }\n const addOp: AddElementOperation = {\n type: 'add_element',\n pageId: input.pageId,\n element: snapshot,\n index,\n ...(parentGroupId !== undefined ? { parentGroupId } : {}),\n }\n\n return {\n label: `Delete ${element.kind}`,\n execute: (state) => {\n const next = applyOp(state, deleteOp)\n return {\n ...next,\n selectedElementIds: next.selectedElementIds.filter((id) => id !== input.elementId),\n }\n },\n undo: (state) => applyOp(state, addOp),\n operations: () => [structuredClone(deleteOp)],\n inverseOperations: () => [structuredClone(addOp)],\n }\n}\n\nfunction findParentGroupId(page: ScenePage, owner: SceneElement[]): string | undefined {\n if (owner === page.elements) return undefined\n // Walk the element tree looking for a group whose children === owner\n return findGroupWithChildren(page.elements, owner)\n}\n\nfunction findGroupWithChildren(elements: SceneElement[], target: SceneElement[]): string | undefined {\n for (const el of elements) {\n if (el.kind === 'group') {\n if (el.children === target) return el.id\n const found = findGroupWithChildren(el.children, target)\n if (found !== undefined) return found\n }\n }\n return undefined\n}\n\n// ---------------------------------------------------------------------------\n// group_elements / inverse = ungroup_element\n// ---------------------------------------------------------------------------\n\nexport interface GroupElementsInput {\n document: SceneDocument\n pageId: string\n elementIds: string[]\n groupId: string\n name?: string\n}\n\nexport function groupElementsCommand(input: GroupElementsInput): SceneCommand {\n if (input.elementIds.length < 2) {\n throw new Error('groupElementsCommand: requires ≥ 2 elementIds')\n }\n\n const groupOp: SceneOperation = {\n type: 'group_elements',\n pageId: input.pageId,\n elementIds: input.elementIds.slice(),\n groupId: input.groupId,\n ...(input.name !== undefined ? { name: input.name } : {}),\n }\n const ungroupOp: SceneOperation = {\n type: 'ungroup_element',\n pageId: input.pageId,\n groupId: input.groupId,\n }\n\n return {\n label: `Group ${input.elementIds.length} elements`,\n execute: (state) => {\n const next = applyOp(state, groupOp)\n return {\n ...next,\n selectedElementIds: [input.groupId],\n }\n },\n undo: (state) => {\n const next = applyOp(state, ungroupOp)\n return { ...next, selectedElementIds: input.elementIds.slice() }\n },\n operations: () => [structuredClone(groupOp)],\n inverseOperations: () => [structuredClone(ungroupOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// ungroup_element / inverse = group_elements (re-using original ids)\n// ---------------------------------------------------------------------------\n\nexport interface UngroupElementInput {\n document: SceneDocument\n pageId: string\n groupId: string\n}\n\nexport function ungroupElementCommand(input: UngroupElementInput): SceneCommand {\n const page = requirePage(input.document, input.pageId)\n const { element } = requireElement(page, input.groupId)\n if (element.kind !== 'group') {\n throw new Error(`ungroupElementCommand: element ${input.groupId} is kind ${element.kind}, not group`)\n }\n const childIds = element.children.map((c) => c.id)\n\n const ungroupOp: SceneOperation = {\n type: 'ungroup_element',\n pageId: input.pageId,\n groupId: input.groupId,\n }\n const regroupOp: SceneOperation = {\n type: 'group_elements',\n pageId: input.pageId,\n elementIds: childIds,\n groupId: input.groupId,\n name: element.name,\n }\n\n return {\n label: `Ungroup`,\n execute: (state) => {\n const next = applyOp(state, ungroupOp)\n return { ...next, selectedElementIds: childIds.slice() }\n },\n undo: (state) => {\n const next = applyOp(state, regroupOp)\n return { ...next, selectedElementIds: [input.groupId] }\n },\n operations: () => [structuredClone(ungroupOp)],\n inverseOperations: () => [structuredClone(regroupOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// Page commands\n// ---------------------------------------------------------------------------\n\nexport interface AddPageInput {\n pageId: string\n options?: import('../../design-canvas/model').NewPageOptions\n index?: number\n}\n\nexport function addPageCommand(input: AddPageInput): SceneCommand {\n const addOp: SceneOperation = {\n type: 'add_page',\n pageId: input.pageId,\n ...(input.options !== undefined ? { options: input.options } : {}),\n ...(input.index !== undefined ? { index: input.index } : {}),\n }\n const deleteOp: SceneOperation = { type: 'delete_page', pageId: input.pageId }\n\n return {\n label: 'Add page',\n execute: (state) => {\n const next = applyOp(state, addOp)\n return { ...next, activePageId: input.pageId }\n },\n undo: (state) => {\n const next = applyOp(state, deleteOp)\n // Switch active page to first surviving page if we deleted the active one\n const activeExists = next.document.pages.some((p) => p.id === next.activePageId)\n return activeExists ? next : { ...next, activePageId: next.document.pages[0]!.id }\n },\n operations: () => [structuredClone(addOp)],\n inverseOperations: () => [structuredClone(deleteOp)],\n }\n}\n\nexport interface DuplicatePageInput {\n document: SceneDocument\n sourcePageId: string\n /** Caller-minted id for the copy. */\n pageId: string\n}\n\nexport function duplicatePageCommand(input: DuplicatePageInput): SceneCommand {\n requirePage(input.document, input.sourcePageId)\n\n const dupOp: SceneOperation = {\n type: 'duplicate_page',\n sourcePageId: input.sourcePageId,\n pageId: input.pageId,\n }\n const deleteOp: SceneOperation = { type: 'delete_page', pageId: input.pageId }\n\n return {\n label: 'Duplicate page',\n execute: (state) => {\n const next = applyOp(state, dupOp)\n return { ...next, activePageId: input.pageId }\n },\n undo: (state) => {\n const next = applyOp(state, deleteOp)\n const activeExists = next.document.pages.some((p) => p.id === next.activePageId)\n return activeExists ? next : { ...next, activePageId: input.sourcePageId }\n },\n operations: () => [structuredClone(dupOp)],\n inverseOperations: () => [structuredClone(deleteOp)],\n }\n}\n\nexport interface DeletePageInput {\n document: SceneDocument\n pageId: string\n}\n\nexport function deletePageCommand(input: DeletePageInput): SceneCommand {\n if (input.document.pages.length <= 1) {\n throw new Error('deletePageCommand: cannot delete the last page')\n }\n const page = requirePage(input.document, input.pageId)\n const currentIndex = input.document.pages.findIndex((p) => p.id === input.pageId)\n const snapshot = structuredClone(page)\n\n const deleteOp: SceneOperation = { type: 'delete_page', pageId: input.pageId }\n\n // Undo uses add_page + per-element add_element to restore the full snapshot.\n // The page shell is added first, then elements are inserted in z-order so\n // subsequent undo/redo round-trips see the correct stack. This also makes\n // inverseOperations() safe to emit server-side: the server will see the same\n // full restore instead of a bare shell.\n function buildRestoreOps(): SceneOperation[] {\n const ops: SceneOperation[] = [\n {\n type: 'add_page',\n pageId: snapshot.id,\n options: {\n name: snapshot.name,\n width: snapshot.width,\n height: snapshot.height,\n background: snapshot.background,\n },\n index: currentIndex,\n },\n ]\n if (snapshot.bleed) {\n ops.push({ type: 'set_page_props', pageId: snapshot.id, bleed: snapshot.bleed })\n }\n if (snapshot.guides.vertical.length > 0 || snapshot.guides.horizontal.length > 0) {\n ops.push({ type: 'set_page_guides', pageId: snapshot.id, guides: snapshot.guides })\n }\n for (let i = 0; i < snapshot.elements.length; i++) {\n ops.push({\n type: 'add_element',\n pageId: snapshot.id,\n element: structuredClone(snapshot.elements[i]!),\n index: i,\n })\n }\n return ops\n }\n\n return {\n label: 'Delete page',\n execute: (state) => {\n const next = applyOp(state, deleteOp)\n const activeExists = next.document.pages.some((p) => p.id === next.activePageId)\n if (activeExists) return next\n const fallbackIndex = Math.min(currentIndex, next.document.pages.length - 1)\n return { ...next, activePageId: next.document.pages[fallbackIndex]!.id }\n },\n undo: (state) => {\n const next = applyOps(state, buildRestoreOps())\n return { ...next, activePageId: input.pageId }\n },\n operations: () => [structuredClone(deleteOp)],\n inverseOperations: () => buildRestoreOps(),\n }\n}\n\nexport interface ReorderPageInput {\n pageId: string\n toIndex: number\n}\n\nexport function reorderPageCommand(input: ReorderPageInput): SceneCommand {\n let capturedFromIndex: number | null = null\n\n const forwardOp: SceneOperation = {\n type: 'reorder_page',\n pageId: input.pageId,\n toIndex: input.toIndex,\n }\n\n return {\n label: 'Reorder page',\n execute: (state) => {\n // Guard: on redo the page is already at toIndex; capture only on first execute.\n if (capturedFromIndex === null) {\n capturedFromIndex = state.document.pages.findIndex((p) => p.id === input.pageId)\n if (capturedFromIndex === -1) throw new Error(`reorderPageCommand: page ${input.pageId} not found`)\n }\n return applyOp(state, forwardOp)\n },\n undo: (state) => {\n if (capturedFromIndex === null) throw new Error('reorderPageCommand: undo called before execute')\n return applyOp(state, {\n type: 'reorder_page',\n pageId: input.pageId,\n toIndex: capturedFromIndex,\n })\n },\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => {\n if (capturedFromIndex === null) throw new Error('reorderPageCommand: inverseOperations called before execute')\n return [{ type: 'reorder_page' as const, pageId: input.pageId, toIndex: capturedFromIndex }]\n },\n }\n}\n\nexport interface SetPagePropsInput {\n document: SceneDocument\n pageId: string\n props: {\n name?: string\n width?: number\n height?: number\n background?: string\n bleed?: import('../../design-canvas/model').PageBleed | null\n }\n}\n\nexport function setPagePropsCommand(input: SetPagePropsInput): SceneCommand {\n const page = requirePage(input.document, input.pageId)\n const prior: NonNullable<import('../../design-canvas/operations').SetPagePropsOperation> = {\n type: 'set_page_props',\n pageId: input.pageId,\n ...(input.props.name !== undefined ? { name: page.name } : {}),\n ...(input.props.width !== undefined ? { width: page.width } : {}),\n ...(input.props.height !== undefined ? { height: page.height } : {}),\n ...(input.props.background !== undefined ? { background: page.background } : {}),\n ...(input.props.bleed !== undefined ? { bleed: page.bleed } : {}),\n }\n\n const forwardOp: SceneOperation = {\n type: 'set_page_props',\n pageId: input.pageId,\n ...input.props,\n }\n\n return {\n label: 'Edit page',\n execute: (state) => applyOp(state, forwardOp),\n undo: (state) => applyOp(state, prior),\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => [structuredClone(prior) as SceneOperation],\n }\n}\n\nexport interface SetPageGuidesInput {\n document: SceneDocument\n pageId: string\n guides: import('../../design-canvas/model').PageGuides\n}\n\nexport function setPageGuidesCommand(input: SetPageGuidesInput): SceneCommand {\n const page = requirePage(input.document, input.pageId)\n const priorGuides = structuredClone(page.guides)\n\n const forwardOp: SceneOperation = {\n type: 'set_page_guides',\n pageId: input.pageId,\n guides: structuredClone(input.guides),\n }\n const inverseOp: SceneOperation = {\n type: 'set_page_guides',\n pageId: input.pageId,\n guides: priorGuides,\n }\n\n return {\n label: 'Edit guides',\n execute: (state) => applyOp(state, forwardOp),\n undo: (state) => applyOp(state, inverseOp),\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => [structuredClone(inverseOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// bind_slot\n// ---------------------------------------------------------------------------\n\nexport interface BindSlotInput {\n document: SceneDocument\n pageId: string\n elementId: string\n slot: string | null\n}\n\nexport function bindSlotCommand(input: BindSlotInput): SceneCommand {\n const page = requirePage(input.document, input.pageId)\n const { element } = requireElement(page, input.elementId)\n const priorSlot = element.slot ?? null\n\n const forwardOp: SceneOperation = {\n type: 'bind_slot',\n pageId: input.pageId,\n elementId: input.elementId,\n slot: input.slot,\n }\n const inverseOp: SceneOperation = {\n type: 'bind_slot',\n pageId: input.pageId,\n elementId: input.elementId,\n slot: priorSlot,\n }\n\n return {\n label: input.slot === null ? 'Unbind slot' : `Bind slot \"${input.slot}\"`,\n execute: (state) => applyOp(state, forwardOp),\n undo: (state) => applyOp(state, inverseOp),\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => [structuredClone(inverseOp)],\n }\n}\n\n// ---------------------------------------------------------------------------\n// set_document_title\n// ---------------------------------------------------------------------------\n\nexport interface SetDocumentTitleInput {\n document: SceneDocument\n title: string\n}\n\nexport function setDocumentTitleCommand(input: SetDocumentTitleInput): SceneCommand {\n const priorTitle = input.document.title\n\n const forwardOp: SceneOperation = { type: 'set_document_title', title: input.title }\n const inverseOp: SceneOperation = { type: 'set_document_title', title: priorTitle }\n\n return {\n label: `Rename document`,\n execute: (state) => applyOp(state, forwardOp),\n undo: (state) => applyOp(state, inverseOp),\n operations: () => [structuredClone(forwardOp)],\n inverseOperations: () => [structuredClone(inverseOp)],\n }\n}\n","/**\n * Pure ruler tick-step and label math for the canvas rulers. Nothing here\n * touches React or the DOM — all interaction geometry is extracted so it can\n * be unit-tested without a browser.\n *\n * Canvas rulers show document-coordinate values (CSS px). Tick density adapts\n * to the current zoom so major ticks never sit closer than `minMajorSpacingPx`\n * screen pixels apart. The step table covers typical design zoom ranges; beyond\n * the table the step grows by doubling the last candidate.\n */\n\n/** Ordered candidate major-tick steps in document px. Chosen so common design\n * values (10, 50, 100, 500…) are always available as label boundaries. */\nconst TICK_STEP_CANDIDATES_PX = [1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000] as const\n\nexport interface TickStep {\n /** Document-coordinate step between major ticks. */\n major: number\n /** Document-coordinate step between minor ticks (major / 5). */\n minor: number\n /** True when minor ticks should be drawn (they sit ≥ minMinorSpacingPx apart). */\n drawMinor: boolean\n}\n\n/**\n * Select the major tick step that keeps major ticks ≥ minMajorSpacingPx apart\n * at the given zoom. Minor ticks are rendered when they'd clear minMinorSpacingPx.\n *\n * Both spacing thresholds are SCREEN pixels — the caller provides `zoom` (screen\n * px per document px) so the result is zoom-independent.\n */\nexport function selectTickStep(input: {\n zoom: number\n minMajorSpacingPx?: number\n minMinorSpacingPx?: number\n}): TickStep {\n if (!Number.isFinite(input.zoom) || input.zoom <= 0) {\n throw new Error(`zoom must be a positive finite number, got ${input.zoom}`)\n }\n const minMajor = input.minMajorSpacingPx ?? 40\n const minMinor = input.minMinorSpacingPx ?? 8\n\n let major = TICK_STEP_CANDIDATES_PX[TICK_STEP_CANDIDATES_PX.length - 1]!\n for (const candidate of TICK_STEP_CANDIDATES_PX) {\n if (candidate * input.zoom >= minMajor) {\n major = candidate\n break\n }\n }\n // Beyond the table: double until the constraint is satisfied.\n while (major * input.zoom < minMajor) {\n major = major * 2\n }\n\n const minor = major / 5\n const drawMinor = minor * input.zoom >= minMinor\n\n return { major, minor, drawMinor }\n}\n\nexport interface RulerTick {\n /** Position in document coordinates. */\n position: number\n /** Label text, or null for a minor tick. */\n label: string | null\n}\n\n/**\n * Generate all ticks visible in a ruler of `documentLength` document-px,\n * given the current tick step. The caller clips to the viewport; this produces\n * all ticks for the full document extent so the ruler can be rendered\n * declaratively without a separate clipping pass.\n */\nexport function buildRulerTicks(input: {\n documentLength: number\n step: TickStep\n}): RulerTick[] {\n if (input.documentLength <= 0) return []\n\n const { major, minor, drawMinor } = input.step\n const ticks: RulerTick[] = []\n\n for (let pos = 0; pos <= input.documentLength; pos += major) {\n ticks.push({ position: pos, label: formatRulerLabel(pos) })\n if (!drawMinor) continue\n for (let m = 1; m < 5; m += 1) {\n const minorPos = pos + m * minor\n if (minorPos >= input.documentLength) break\n ticks.push({ position: minorPos, label: null })\n }\n }\n\n return ticks\n}\n\n/** Format a document-px position as a compact label: integers stay whole,\n * decimals are rounded to 1 place. Values ≥ 1000 are compacted to \"1k\" etc. */\nexport function formatRulerLabel(value: number): string {\n if (!Number.isFinite(value)) return ''\n if (Math.abs(value) >= 1000) {\n const k = value / 1000\n return `${Number.isInteger(k) ? k : k.toFixed(1)}k`\n }\n return Number.isInteger(value) ? String(value) : value.toFixed(1)\n}\n\n/**\n * Convert a screen-coordinate pointer position to a document-coordinate guide\n * drop position, given the ruler's scroll offset and zoom. Used by both the\n * horizontal and vertical ruler drag-guide creation paths.\n *\n * `scrollOffset` is how many document-px of the ruler are scrolled off-screen\n * to the left/top. `pointerScreenPx` is the cursor position in screen px\n * relative to the ruler element's origin.\n */\nexport function screenToDocumentPosition(input: {\n pointerScreenPx: number\n scrollOffset: number\n zoom: number\n}): number {\n if (!Number.isFinite(input.zoom) || input.zoom <= 0) {\n throw new Error(`zoom must be a positive finite number, got ${input.zoom}`)\n }\n return input.pointerScreenPx / input.zoom + input.scrollOffset\n}\n\n/** Snap a guide drop position to the nearest major tick if within\n * `snapThresholdPx` document px; otherwise returns the raw position. */\nexport function snapGuideToTick(position: number, step: TickStep, snapThresholdPx: number): number {\n const nearest = Math.round(position / step.major) * step.major\n return Math.abs(nearest - position) <= snapThresholdPx ? nearest : position\n}\n\n// ---------------------------------------------------------------------------\n// Z-order index math — extracted so Toolbar and LayersPanel agree\n// ---------------------------------------------------------------------------\n\n/** Index of the topmost element for a given owner length. */\nexport function topIndex(ownerLength: number): number {\n return ownerLength - 1\n}\n\n/** Move an element one step toward the top (higher index = above in z-order).\n * Returns the current index unchanged if already at the top. */\nexport function indexForward(current: number, ownerLength: number): number {\n return Math.min(current + 1, ownerLength - 1)\n}\n\n/** Move an element one step toward the bottom (lower index = below). Returns\n * the current index unchanged if already at the bottom. */\nexport function indexBackward(current: number): number {\n return Math.max(current - 1, 0)\n}\n\n/** Clamp an arbitrary target index to valid range. */\nexport function clampIndex(target: number, ownerLength: number): number {\n return Math.max(0, Math.min(target, ownerLength - 1))\n}\n","/**\n * Semi-transparent bleed tint drawn OUTSIDE the page bounds, with trim-mark\n * corner indicators. Renders as an absolutely-positioned div layered over the\n * workspace canvas; node name 'overlay:bleed' lets automated tests target it.\n *\n * Conditionally rendered: parent mounts this only when `showBleed && bleed`.\n * All dimensions are in SCREEN pixels (caller applies the zoom factor).\n */\n\nimport type { PageBleed } from '../../design-canvas/model'\n\nexport interface BleedTrimOverlayProps {\n /** Page dimensions in screen pixels (already multiplied by zoom). */\n pageWidthPx: number\n pageHeightPx: number\n /** Bleed extents in SCREEN pixels (caller multiplies doc-px by zoom). */\n bleed: {\n top: number\n right: number\n bottom: number\n left: number\n }\n}\n\n/** Length in screen pixels of each trim-mark arm. */\nconst TRIM_MARK_PX = 12\n\n/** How far trim marks sit from the page corner (in screen px). */\nconst TRIM_MARK_OFFSET_PX = 4\n\nexport function BleedTrimOverlay({ pageWidthPx, pageHeightPx, bleed }: BleedTrimOverlayProps) {\n const totalW = bleed.left + pageWidthPx + bleed.right\n const totalH = bleed.top + pageHeightPx + bleed.bottom\n\n return (\n <div\n data-node=\"overlay:bleed\"\n className=\"pointer-events-none absolute\"\n style={{\n top: -bleed.top,\n left: -bleed.left,\n width: totalW,\n height: totalH,\n }}\n aria-hidden\n >\n {/* Bleed tint strips — four sides */}\n {/* top */}\n <div\n className=\"absolute bg-rose-500/10\"\n style={{ top: 0, left: 0, width: totalW, height: bleed.top }}\n />\n {/* bottom */}\n <div\n className=\"absolute bg-rose-500/10\"\n style={{ bottom: 0, left: 0, width: totalW, height: bleed.bottom }}\n />\n {/* left */}\n <div\n className=\"absolute bg-rose-500/10\"\n style={{ top: bleed.top, left: 0, width: bleed.left, height: pageHeightPx }}\n />\n {/* right */}\n <div\n className=\"absolute bg-rose-500/10\"\n style={{ top: bleed.top, right: 0, width: bleed.right, height: pageHeightPx }}\n />\n\n {/* Trim marks — one per corner, two lines each */}\n <TrimMark corner=\"tl\" bleed={bleed} />\n <TrimMark corner=\"tr\" bleed={bleed} pageWidthPx={pageWidthPx} />\n <TrimMark corner=\"bl\" bleed={bleed} pageHeightPx={pageHeightPx} />\n <TrimMark corner=\"br\" bleed={bleed} pageWidthPx={pageWidthPx} pageHeightPx={pageHeightPx} />\n </div>\n )\n}\n\ntype Corner = 'tl' | 'tr' | 'bl' | 'br'\n\ninterface TrimMarkProps {\n corner: Corner\n bleed: BleedTrimOverlayProps['bleed']\n pageWidthPx?: number\n pageHeightPx?: number\n}\n\nfunction TrimMark({ corner, bleed, pageWidthPx = 0, pageHeightPx = 0 }: TrimMarkProps) {\n const isRight = corner === 'tr' || corner === 'br'\n const isBottom = corner === 'bl' || corner === 'br'\n\n const xBase = isRight ? bleed.left + pageWidthPx : bleed.left\n const yBase = isBottom ? bleed.top + pageHeightPx : bleed.top\n\n // Horizontal arm\n const hX = isRight ? xBase + TRIM_MARK_OFFSET_PX : xBase - TRIM_MARK_OFFSET_PX - TRIM_MARK_PX\n const hY = yBase - 0.5\n\n // Vertical arm\n const vX = xBase - 0.5\n const vY = isBottom ? yBase + TRIM_MARK_OFFSET_PX : yBase - TRIM_MARK_OFFSET_PX - TRIM_MARK_PX\n\n return (\n <>\n <div\n className=\"absolute bg-[var(--text-muted)]\"\n style={{ left: hX, top: hY, width: TRIM_MARK_PX, height: 1 }}\n />\n <div\n className=\"absolute bg-[var(--text-muted)]\"\n style={{ left: vX, top: vY, width: 1, height: TRIM_MARK_PX }}\n />\n </>\n )\n}\n","/**\n * Horizontal page-thumbnail strip shown at the bottom of the editor. The active\n * page is highlighted. Thumbnails are rendered externally (Konva; the host\n * injects `renderThumbnail` so this component stays canvas-free and testable).\n *\n * Actions: add page, duplicate active page, delete active page (disabled when\n * only one page remains), drag-reorder pages. The strip is read-only when\n * `canWrite` is false.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { ScenePage } from '../../design-canvas/model'\nimport { DuplicateGlyph, PageGlyph, PlusGlyph, TrashGlyph } from './glyphs'\n\nexport interface PagesStripProps {\n pages: ScenePage[]\n activePageId: string\n canWrite: boolean\n /**\n * The host provides this to generate thumbnail data-URLs. The strip calls it\n * on mount and debounces re-calls on document changes. Returns null when the\n * thumbnail is not yet available (the strip renders a placeholder instead).\n */\n renderThumbnail(page: ScenePage): Promise<string | null>\n onSelectPage(pageId: string): void\n onAddPage(): void\n onDuplicatePage(pageId: string): void\n onDeletePage(pageId: string): void\n onReorderPage(pageId: string, toIndex: number): void\n}\n\nconst THUMBNAIL_W = 80\nconst THUMBNAIL_H = 56\n\nconst BTN =\n 'flex h-6 w-6 items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] disabled:cursor-default disabled:opacity-40'\n\nexport function PagesStrip({\n pages,\n activePageId,\n canWrite,\n renderThumbnail,\n onSelectPage,\n onAddPage,\n onDuplicatePage,\n onDeletePage,\n onReorderPage,\n}: PagesStripProps) {\n // Map from page id → data URL; null while loading.\n const [thumbnails, setThumbnails] = useState<Record<string, string | null>>({})\n const thumbnailVersionRef = useRef(0)\n\n useEffect(() => {\n // Debounce thumbnail regeneration: bump the version on every render cycle\n // and only apply results from the CURRENT version.\n const version = ++thumbnailVersionRef.current\n let cancelled = false\n\n async function generate() {\n const results: Record<string, string | null> = {}\n for (const page of pages) {\n if (cancelled) return\n try {\n results[page.id] = await renderThumbnail(page)\n } catch {\n results[page.id] = null\n }\n }\n if (!cancelled && thumbnailVersionRef.current === version) {\n setThumbnails(results)\n }\n }\n\n void generate()\n return () => {\n cancelled = true\n }\n // renderThumbnail is assumed stable (host memoizes it); pages is the dep.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pages])\n\n // Drag-reorder\n const dragIndexRef = useRef<number | null>(null)\n const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)\n\n return (\n <div\n className=\"flex h-[84px] shrink-0 items-center gap-2 overflow-x-auto border-t border-[var(--border-default)] bg-[var(--bg-input)] px-2\"\n aria-label=\"Pages\"\n >\n {pages.map((page, index) => {\n const isActive = page.id === activePageId\n const thumbUrl = thumbnails[page.id]\n\n return (\n <div\n key={page.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`Page ${index + 1}: ${page.name}${isActive ? ' (active)' : ''}`}\n aria-pressed={isActive}\n draggable={canWrite}\n onDragStart={() => {\n dragIndexRef.current = index\n }}\n onDragOver={(event) => {\n if (dragIndexRef.current === null) return\n event.preventDefault()\n setDragOverIndex(index)\n }}\n onDragLeave={() => setDragOverIndex(null)}\n onDrop={() => {\n const from = dragIndexRef.current\n if (from !== null && from !== index) {\n onReorderPage(pages[from]!.id, index)\n }\n dragIndexRef.current = null\n setDragOverIndex(null)\n }}\n onDragEnd={() => {\n dragIndexRef.current = null\n setDragOverIndex(null)\n }}\n onClick={() => onSelectPage(page.id)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onSelectPage(page.id)\n }\n }}\n className={[\n 'group relative flex shrink-0 cursor-pointer flex-col items-center gap-1 rounded p-1 transition',\n isActive\n ? 'ring-2 ring-[var(--brand-primary)]'\n : 'hover:bg-[var(--border-default)]/40',\n dragOverIndex === index ? 'ring-1 ring-[var(--brand-primary)]/60' : '',\n ].join(' ')}\n >\n {/* Thumbnail or placeholder */}\n <div\n className=\"overflow-hidden rounded border border-[var(--border-default)] bg-white\"\n style={{ width: THUMBNAIL_W, height: THUMBNAIL_H }}\n >\n {thumbUrl ? (\n <img\n src={thumbUrl}\n alt={page.name}\n className=\"h-full w-full object-cover\"\n draggable={false}\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <PageGlyph className=\"h-5 w-5 text-[var(--text-muted)]\" />\n </div>\n )}\n </div>\n\n {/* Page name */}\n <span className=\"max-w-[80px] truncate text-[10px] text-[var(--text-secondary)]\">\n {page.name}\n </span>\n\n {/* Per-page action buttons — visible on hover or when active */}\n {canWrite ? (\n <div className=\"pointer-events-none absolute -top-1 right-0 flex gap-0.5 opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100\">\n <button\n type=\"button\"\n aria-label={`Duplicate page ${page.name}`}\n onClick={(event) => {\n event.stopPropagation()\n onDuplicatePage(page.id)\n }}\n className={BTN}\n >\n <DuplicateGlyph className=\"h-3 w-3\" />\n </button>\n <button\n type=\"button\"\n aria-label={`Delete page ${page.name}`}\n disabled={pages.length <= 1}\n onClick={(event) => {\n event.stopPropagation()\n if (pages.length > 1) onDeletePage(page.id)\n }}\n className={BTN}\n >\n <TrashGlyph className=\"h-3 w-3 text-rose-400\" />\n </button>\n </div>\n ) : null}\n </div>\n )\n })}\n\n {/* Add page button */}\n {canWrite ? (\n <button\n type=\"button\"\n aria-label=\"Add page\"\n onClick={onAddPage}\n className=\"flex h-[72px] w-[80px] shrink-0 flex-col items-center justify-center gap-1 rounded border border-dashed border-[var(--border-default)] text-[var(--text-muted)] transition hover:border-[var(--brand-primary)] hover:text-[var(--brand-primary)]\"\n >\n <PlusGlyph className=\"h-4 w-4\" />\n <span className=\"text-[10px]\">Add page</span>\n </button>\n ) : null}\n </div>\n )\n}\n","/**\n * Inline SVG glyphs for the design canvas editor. No external icon dependency —\n * same convention as sequences-react/components/glyphs.tsx.\n */\n\ninterface GlyphProps {\n className?: string\n}\n\nfunction glyph(paths: React.ReactNode) {\n return function Glyph({ className }: GlyphProps) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n {paths}\n </svg>\n )\n }\n}\n\nexport const UndoGlyph = glyph(<path d=\"M3 7v6h6M3 13a9 9 0 1 0 3-7.7\" />)\nexport const RedoGlyph = glyph(<path d=\"M21 7v6h-6M21 13a9 9 0 1 1-3-7.7\" />)\n\nexport const EyeGlyph = glyph(\n <>\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </>,\n)\n\nexport const EyeOffGlyph = glyph(\n <>\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"m1 1 22 22\" />\n </>,\n)\n\nexport const LockGlyph = glyph(\n <>\n <rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\" />\n <path d=\"M8 11V7a4 4 0 0 1 8 0v4\" />\n </>,\n)\n\nexport const UnlockGlyph = glyph(\n <>\n <rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\" />\n <path d=\"M8 11V7a4 4 0 1 1 8 0\" />\n </>,\n)\n\nexport const TrashGlyph = glyph(\n <>\n <path d=\"M3 6h18M19 6l-1 14H6L5 6M10 6V4h4v2\" />\n </>,\n)\n\nexport const GroupGlyph = glyph(\n <>\n <rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\" />\n <rect x=\"14\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\" />\n <rect x=\"2\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\" />\n <rect x=\"14\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\" />\n </>,\n)\n\nexport const UngroupGlyph = glyph(\n <>\n <path d=\"M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2\" />\n </>,\n)\n\nexport const BringFrontGlyph = glyph(\n <>\n <rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"1\" />\n <path d=\"M4 4h12v4H4z\" opacity=\".4\" />\n </>,\n)\n\nexport const SendBackGlyph = glyph(\n <>\n <rect x=\"4\" y=\"4\" width=\"12\" height=\"12\" rx=\"1\" opacity=\".4\" />\n <path d=\"M8 8h12v12H8z\" />\n </>,\n)\n\nexport const AlignLeftGlyph = glyph(\n <>\n <path d=\"M3 4v16M7 8h10M7 16h6\" />\n </>,\n)\nexport const AlignCenterGlyph = glyph(\n <>\n <path d=\"M12 4v16M7 8h10M9 16h6\" />\n </>,\n)\nexport const AlignRightGlyph = glyph(\n <>\n <path d=\"M21 4v16M7 8h10M11 16h6\" />\n </>,\n)\n\nexport const BoldGlyph = glyph(<path d=\"M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z\" fill=\"currentColor\" stroke=\"none\" />)\nexport const ItalicGlyph = glyph(<path d=\"M11 4h6M7 20h6M14 4 8 20\" />)\n\nexport const PlusGlyph = glyph(<path d=\"M12 5v14M5 12h14\" />)\nexport const ChevronDownGlyph = glyph(<path d=\"m6 9 6 6 6-6\" />)\nexport const ChevronRightGlyph = glyph(<path d=\"m9 18 6-6-6-6\" />)\n\nexport const RectGlyph = glyph(<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />)\nexport const EllipseGlyph = glyph(<ellipse cx=\"12\" cy=\"12\" rx=\"10\" ry=\"7\" />)\nexport const LineGlyph = glyph(<path d=\"M5 19 19 5\" />)\nexport const TextGlyph = glyph(<path d=\"M4 7V4h16v3M9 20h6M12 4v16\" />)\nexport const ImageGlyph = glyph(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21\" />\n </>,\n)\nexport const VideoGlyph = glyph(\n <>\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"18\" rx=\"2\" />\n <path d=\"m10 8 6 4-6 4z\" fill=\"currentColor\" stroke=\"none\" />\n </>,\n)\n\nexport const SlotGlyph = glyph(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M12 1v4M12 19v4M4.2 4.2l2.8 2.8M17 17l2.8 2.8M1 12h4M19 12h4M4.2 19.8l2.8-2.8M17 7 19.8 4.2\" />\n </>,\n)\n\nexport const FitGlyph = glyph(\n <>\n <path d=\"M3 3h4v4H3zM17 3h4v4h-4zM3 17h4v4H3zM17 17h4v4h-4z\" />\n <path d=\"M7 5h10M5 7v10M19 7v10M7 19h10\" />\n </>,\n)\n\nexport const PageGlyph = glyph(\n <>\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </>,\n)\n\nexport const GridGlyph = glyph(\n <>\n <path d=\"M3 3h18v18H3zM3 9h18M3 15h18M9 3v18M15 3v18\" />\n </>,\n)\n\nexport const RulerGlyph = glyph(\n <>\n <path d=\"M1 9v6l12 6V9L1 3z\" />\n <path d=\"m13 15 9-4.5V4.5L13 9\" />\n <path d=\"M5 12v3M8 13.5v2.5M11 15v3\" />\n </>,\n)\n\nexport const MagnetGlyph = glyph(\n <>\n <path d=\"m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3z\" />\n <path d=\"m5 8 4 4M12 15l4 4\" />\n </>,\n)\n\nexport const BleedGlyph = glyph(\n <>\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" strokeDasharray=\"3 2\" />\n <rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" />\n </>,\n)\n\nexport const DuplicateGlyph = glyph(\n <>\n <rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" />\n <path d=\"M4 16V4a2 2 0 0 1 2-2h12\" />\n </>,\n)\n\nexport const ZoomFitGlyph = glyph(\n <>\n <path d=\"M15 3h6v6M14 10l6.1-6.1M9 21H3v-6M10 14l-6.1 6.1\" />\n </>,\n)\n","/**\n * Horizontal (top) and vertical (left) canvas rulers. Each ruler:\n * - Draws zoom-scaled tick marks via `buildRulerTicks` / `selectTickStep`.\n * - Shows a pointer-position indicator (a hairline that follows the cursor).\n * - Supports guide creation by dragging OUT of the ruler: a live preview line\n * appears while dragging; on drop a `set_page_guides` command is emitted.\n * - Existing guides that are dragged BACK into the ruler are deleted.\n *\n * All interaction math lives in ruler-math.ts and is testable without a DOM.\n * The rulers themselves are pure DOM (no Konva); they sit in a CSS grid slot\n * next to the workspace canvas.\n */\n\nimport { useCallback, useRef, useState } from 'react'\nimport type { PageGuides } from '../../design-canvas/model'\nimport { buildRulerTicks, screenToDocumentPosition, selectTickStep } from './ruler-math'\n\nconst RULER_SIZE_PX = 20\n\nexport interface RulersProps {\n /** Page width in document px. */\n pageWidth: number\n /** Page height in document px. */\n pageHeight: number\n zoom: number\n /** How many doc-px of the canvas are scrolled off-screen left/top. */\n scrollLeft: number\n scrollTop: number\n showRulers: boolean\n guides: PageGuides\n /** Emitted when the user drops a guide or deletes one back into the ruler. */\n onGuidesChange(guides: PageGuides): void\n}\n\n/** Minimum px from ruler edge before a guide drag counts as \"delete\". */\nconst DELETE_THRESHOLD_PX = RULER_SIZE_PX + 4\n\nexport function Rulers({ pageWidth, pageHeight, zoom, scrollLeft, scrollTop, showRulers, guides, onGuidesChange }: RulersProps) {\n if (!showRulers) return null\n\n return (\n <>\n {/* Corner filler */}\n <div\n className=\"absolute top-0 left-0 z-20 shrink-0 border-b border-r border-[var(--border-default)] bg-[var(--bg-input)]\"\n style={{ width: RULER_SIZE_PX, height: RULER_SIZE_PX }}\n />\n\n <HorizontalRuler\n pageWidth={pageWidth}\n zoom={zoom}\n scrollLeft={scrollLeft}\n guides={guides}\n onGuidesChange={onGuidesChange}\n />\n\n <VerticalRuler\n pageHeight={pageHeight}\n zoom={zoom}\n scrollTop={scrollTop}\n guides={guides}\n onGuidesChange={onGuidesChange}\n />\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Horizontal ruler\n// ---------------------------------------------------------------------------\n\ninterface HorizontalRulerProps {\n pageWidth: number\n zoom: number\n scrollLeft: number\n guides: PageGuides\n onGuidesChange(guides: PageGuides): void\n}\n\nfunction HorizontalRuler({ pageWidth, zoom, scrollLeft, guides, onGuidesChange }: HorizontalRulerProps) {\n const ref = useRef<HTMLDivElement>(null)\n const [pointerX, setPointerX] = useState<number | null>(null)\n const [dragGuideX, setDragGuideX] = useState<number | null>(null)\n const dragGuideIndexRef = useRef<number | null>(null)\n\n const step = selectTickStep({ zoom, minMajorSpacingPx: 40 })\n const ticks = buildRulerTicks({ documentLength: pageWidth, step })\n\n function screenXToDoc(clientX: number): number {\n if (!ref.current) return 0\n const rect = ref.current.getBoundingClientRect()\n return screenToDocumentPosition({ pointerScreenPx: clientX - rect.left, scrollOffset: scrollLeft, zoom })\n }\n\n function handlePointerDown(event: React.PointerEvent<HTMLDivElement>) {\n if (event.button !== 0) return\n event.preventDefault()\n event.currentTarget.setPointerCapture(event.pointerId)\n const docX = screenXToDoc(event.clientX)\n // Check if pointer is near an existing guide (within 4 screen px).\n const threshold = 4 / zoom\n const nearIdx = guides.vertical.findIndex((g) => Math.abs(g - docX) <= threshold)\n if (nearIdx >= 0) {\n dragGuideIndexRef.current = nearIdx\n } else {\n dragGuideIndexRef.current = null\n }\n setDragGuideX(docX)\n }\n\n function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {\n if (!ref.current) return\n const rect = ref.current.getBoundingClientRect()\n const localY = event.clientY - rect.top\n setPointerX(event.clientX - rect.left)\n if (!event.currentTarget.hasPointerCapture(event.pointerId)) return\n const docX = screenXToDoc(event.clientX)\n // If pointer moves BELOW the ruler, treat as \"dragging to canvas\" — show guide.\n if (localY > DELETE_THRESHOLD_PX) {\n setDragGuideX(docX)\n } else {\n // Dragged back into ruler — signal delete on release.\n setDragGuideX(null)\n }\n }\n\n function handlePointerUp(event: React.PointerEvent<HTMLDivElement>) {\n if (!event.currentTarget.hasPointerCapture(event.pointerId)) return\n event.currentTarget.releasePointerCapture(event.pointerId)\n\n const rect = ref.current?.getBoundingClientRect()\n const localY = rect ? event.clientY - rect.top : 0\n const deletingExisting = dragGuideIndexRef.current !== null\n const docX = screenXToDoc(event.clientX)\n\n const vertical = [...guides.vertical]\n\n if (localY <= DELETE_THRESHOLD_PX && deletingExisting) {\n // Dragged existing guide back into ruler — delete it.\n vertical.splice(dragGuideIndexRef.current!, 1)\n } else if (localY > DELETE_THRESHOLD_PX) {\n if (deletingExisting) {\n // Moved existing guide to new position.\n vertical[dragGuideIndexRef.current!] = docX\n } else {\n // New guide.\n vertical.push(docX)\n }\n }\n\n dragGuideIndexRef.current = null\n setDragGuideX(null)\n onGuidesChange({ ...guides, vertical })\n }\n\n function handlePointerLeave() {\n setPointerX(null)\n }\n\n return (\n <div\n ref={ref}\n className=\"absolute top-0 left-0 right-0 z-10 cursor-ew-resize select-none overflow-hidden border-b border-[var(--border-default)] bg-[var(--bg-input)]\"\n style={{ height: RULER_SIZE_PX, marginLeft: RULER_SIZE_PX }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerLeave={handlePointerLeave}\n >\n {ticks.map((tick) => {\n const screenX = tick.position * zoom - scrollLeft * zoom\n return (\n <div\n key={tick.position}\n className={`absolute bottom-0 w-px bg-[var(--border-default)] ${tick.label !== null ? 'top-1.5' : 'top-[14px]'}`}\n style={{ left: screenX }}\n >\n {tick.label !== null ? (\n <span className=\"absolute -top-1 left-0.5 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]\">\n {tick.label}\n </span>\n ) : null}\n </div>\n )\n })}\n\n {/* Pointer indicator */}\n {pointerX !== null ? (\n <div className=\"pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]/60\" style={{ left: pointerX }} />\n ) : null}\n\n {/* Live drag-guide preview */}\n {dragGuideX !== null ? (\n <div\n className=\"pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]\"\n style={{ left: dragGuideX * zoom - scrollLeft * zoom }}\n />\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Vertical ruler\n// ---------------------------------------------------------------------------\n\ninterface VerticalRulerProps {\n pageHeight: number\n zoom: number\n scrollTop: number\n guides: PageGuides\n onGuidesChange(guides: PageGuides): void\n}\n\nfunction VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange }: VerticalRulerProps) {\n const ref = useRef<HTMLDivElement>(null)\n const [pointerY, setPointerY] = useState<number | null>(null)\n const [dragGuideY, setDragGuideY] = useState<number | null>(null)\n const dragGuideIndexRef = useRef<number | null>(null)\n\n const step = selectTickStep({ zoom, minMajorSpacingPx: 40 })\n const ticks = buildRulerTicks({ documentLength: pageHeight, step })\n\n function screenYToDoc(clientY: number): number {\n if (!ref.current) return 0\n const rect = ref.current.getBoundingClientRect()\n return screenToDocumentPosition({ pointerScreenPx: clientY - rect.top, scrollOffset: scrollTop, zoom })\n }\n\n function handlePointerDown(event: React.PointerEvent<HTMLDivElement>) {\n if (event.button !== 0) return\n event.preventDefault()\n event.currentTarget.setPointerCapture(event.pointerId)\n const docY = screenYToDoc(event.clientY)\n const threshold = 4 / zoom\n const nearIdx = guides.horizontal.findIndex((g) => Math.abs(g - docY) <= threshold)\n dragGuideIndexRef.current = nearIdx >= 0 ? nearIdx : null\n setDragGuideY(docY)\n }\n\n function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {\n if (!ref.current) return\n const rect = ref.current.getBoundingClientRect()\n const localX = event.clientX - rect.left\n setPointerY(event.clientY - rect.top)\n if (!event.currentTarget.hasPointerCapture(event.pointerId)) return\n const docY = screenYToDoc(event.clientY)\n if (localX > DELETE_THRESHOLD_PX) {\n setDragGuideY(docY)\n } else {\n setDragGuideY(null)\n }\n }\n\n function handlePointerUp(event: React.PointerEvent<HTMLDivElement>) {\n if (!event.currentTarget.hasPointerCapture(event.pointerId)) return\n event.currentTarget.releasePointerCapture(event.pointerId)\n\n const rect = ref.current?.getBoundingClientRect()\n const localX = rect ? event.clientX - rect.left : 0\n const deletingExisting = dragGuideIndexRef.current !== null\n const docY = screenYToDoc(event.clientY)\n\n const horizontal = [...guides.horizontal]\n\n if (localX <= DELETE_THRESHOLD_PX && deletingExisting) {\n horizontal.splice(dragGuideIndexRef.current!, 1)\n } else if (localX > DELETE_THRESHOLD_PX) {\n if (deletingExisting) {\n horizontal[dragGuideIndexRef.current!] = docY\n } else {\n horizontal.push(docY)\n }\n }\n\n dragGuideIndexRef.current = null\n setDragGuideY(null)\n onGuidesChange({ ...guides, horizontal })\n }\n\n function handlePointerLeave() {\n setPointerY(null)\n }\n\n return (\n <div\n ref={ref}\n className=\"absolute top-0 left-0 bottom-0 z-10 cursor-ns-resize select-none overflow-hidden border-r border-[var(--border-default)] bg-[var(--bg-input)]\"\n style={{ width: RULER_SIZE_PX, marginTop: RULER_SIZE_PX }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerLeave={handlePointerLeave}\n >\n {ticks.map((tick) => {\n const screenY = tick.position * zoom - scrollTop * zoom\n return (\n <div\n key={tick.position}\n className={`absolute right-0 h-px bg-[var(--border-default)] ${tick.label !== null ? 'left-1.5' : 'left-[14px]'}`}\n style={{ top: screenY }}\n >\n {tick.label !== null ? (\n <span\n className=\"absolute top-0.5 left-0 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]\"\n style={{ transform: 'rotate(-90deg)', transformOrigin: '0 0', marginTop: 4 }}\n >\n {tick.label}\n </span>\n ) : null}\n </div>\n )\n })}\n\n {pointerY !== null ? (\n <div className=\"pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]/60\" style={{ top: pointerY }} />\n ) : null}\n\n {dragGuideY !== null ? (\n <div\n className=\"pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]\"\n style={{ top: dragGuideY * zoom - scrollTop * zoom }}\n />\n ) : null}\n </div>\n )\n}\n","/**\n * Selection-aware toolbar. When elements are selected it shows per-kind\n * attribute controls; when nothing is selected it shows page-props controls.\n * Every number input commits on blur or Enter as a single command (not\n * per-keystroke). The toolbar is stateless beyond transient input focus;\n * the caller owns the command stack.\n */\n\nimport { useRef, useState } from 'react'\nimport type { SceneElement, ScenePage, TextElement, RectElement, EllipseElement, ImageElement } from '../../design-canvas/model'\nimport type { SceneAttrsPatch } from '../../design-canvas/operations'\nimport type { PageBleed } from '../../design-canvas/model'\nimport { matchPreset, SIZE_PRESETS } from '../../design-canvas/export-presets'\nimport {\n AlignCenterGlyph,\n AlignLeftGlyph,\n AlignRightGlyph,\n BleedGlyph,\n BoldGlyph,\n BringFrontGlyph,\n DuplicateGlyph,\n FitGlyph,\n GridGlyph,\n GroupGlyph,\n ItalicGlyph,\n LockGlyph,\n MagnetGlyph,\n RedoGlyph,\n RulerGlyph,\n SendBackGlyph,\n SlotGlyph,\n TrashGlyph,\n UndoGlyph,\n UngroupGlyph,\n UnlockGlyph,\n} from './glyphs'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ToolbarProps {\n page: ScenePage\n selectedElements: SceneElement[]\n canWrite: boolean\n canUndo: boolean\n canRedo: boolean\n gridEnabled: boolean\n snapEnabled: boolean\n showRulers: boolean\n showBleed: boolean\n onUndo(): void\n onRedo(): void\n onToggleGrid(): void\n onToggleSnap(): void\n onToggleRulers(): void\n onToggleBleed(): void\n /** Emit attrs patch for each selected element. */\n onSetAttrs(elementId: string, attrs: SceneAttrsPatch): void\n onSetPageProps(props: { name?: string; width?: number; height?: number; background?: string; bleed?: PageBleed | null }): void\n onSetPageGuides(guides: { vertical: number[]; horizontal: number[] }): void\n onReorder(elementId: string, toIndex: number, ownerLength: number, direction: 'front' | 'back' | 'forward' | 'backward'): void\n onGroup(elementIds: string[]): void\n onUngroup(groupId: string): void\n onDelete(elementIds: string[]): void\n onBindSlot(elementId: string, slot: string | null): void\n}\n\n// ---------------------------------------------------------------------------\n// Small helpers\n// ---------------------------------------------------------------------------\n\nconst BTN =\n 'flex h-7 w-7 items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] disabled:cursor-default disabled:opacity-40'\n\nconst BTN_ACTIVE = `${BTN} border-[var(--brand-primary)] text-[var(--brand-primary)] hover:text-[var(--brand-primary)]`\n\nconst SEP = <div className=\"mx-1 h-5 w-px bg-[var(--border-default)]\" />\n\nfunction NumberInput({\n label,\n value,\n onCommit,\n min,\n step = 1,\n className = 'w-16',\n}: {\n label: string\n value: number\n onCommit(v: number): void\n min?: number\n step?: number\n className?: string\n}) {\n const [raw, setRaw] = useState<string | null>(null)\n\n function commit(v: string) {\n const n = parseFloat(v)\n if (Number.isFinite(n) && (min === undefined || n >= min)) onCommit(n)\n setRaw(null)\n }\n\n return (\n <label className=\"flex flex-col items-center gap-0.5\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">{label}</span>\n <input\n type=\"number\"\n value={raw ?? value}\n min={min}\n step={step}\n onChange={(event) => setRaw(event.target.value)}\n onBlur={(event) => commit(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') commit((event.target as HTMLInputElement).value)\n if (event.key === 'Escape') setRaw(null)\n }}\n className={`${className} rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0.5 text-center text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]`}\n />\n </label>\n )\n}\n\nfunction ColorSwatch({ label, value, onCommit }: { label: string; value: string; onCommit(v: string): void }) {\n return (\n <label className=\"flex flex-col items-center gap-0.5 cursor-pointer\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">{label}</span>\n <input\n type=\"color\"\n value={value.startsWith('#') ? value : '#ffffff'}\n onChange={(event) => onCommit(event.target.value)}\n className=\"h-6 w-10 cursor-pointer rounded border border-[var(--border-default)] p-0.5\"\n />\n </label>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Main toolbar\n// ---------------------------------------------------------------------------\n\nexport function Toolbar({\n page,\n selectedElements,\n canWrite,\n canUndo,\n canRedo,\n gridEnabled,\n snapEnabled,\n showRulers,\n showBleed,\n onUndo,\n onRedo,\n onToggleGrid,\n onToggleSnap,\n onToggleRulers,\n onToggleBleed,\n onSetAttrs,\n onSetPageProps,\n onSetPageGuides,\n onReorder,\n onGroup,\n onUngroup,\n onDelete,\n onBindSlot,\n}: ToolbarProps) {\n const hasSelection = selectedElements.length > 0\n const single = selectedElements.length === 1 ? selectedElements[0]! : null\n const allSameKind = selectedElements.length > 0 && selectedElements.every((e) => e.kind === selectedElements[0]!.kind)\n const firstKind = selectedElements[0]?.kind\n\n // Shared multi-element patch helper.\n function patchAll(attrs: SceneAttrsPatch) {\n for (const el of selectedElements) onSetAttrs(el.id, attrs)\n }\n\n // Z-order helpers operate on the single selection only (multi-element\n // z-order is a complex multi-step operation; single is the common case).\n function reorderSingle(direction: 'front' | 'back' | 'forward' | 'backward') {\n if (!single) return\n // ownerLength requires knowing the owner; we use page.elements length for\n // root-level elements. Group children are handled via the layers panel.\n onReorder(single.id, 0, page.elements.length, direction)\n }\n\n const selectedIds = selectedElements.map((e) => e.id)\n const isGroup = single?.kind === 'group'\n const groupable = selectedElements.length >= 2\n\n // ----\n\n return (\n <div className=\"flex h-11 shrink-0 items-center gap-2 overflow-x-auto border-b border-[var(--border-default)] bg-[var(--bg-input)] px-3\">\n {/* Undo / Redo */}\n <button type=\"button\" aria-label=\"Undo\" disabled={!canUndo || !canWrite} onClick={onUndo} className={BTN}>\n <UndoGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button type=\"button\" aria-label=\"Redo\" disabled={!canRedo || !canWrite} onClick={onRedo} className={BTN}>\n <RedoGlyph className=\"h-3.5 w-3.5\" />\n </button>\n\n {SEP}\n\n {/* View toggles */}\n <button type=\"button\" aria-label=\"Toggle rulers\" aria-pressed={showRulers} onClick={onToggleRulers} className={showRulers ? BTN_ACTIVE : BTN}>\n <RulerGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button type=\"button\" aria-label=\"Toggle grid\" aria-pressed={gridEnabled} onClick={onToggleGrid} className={gridEnabled ? BTN_ACTIVE : BTN}>\n <GridGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button type=\"button\" aria-label=\"Toggle snap\" aria-pressed={snapEnabled} onClick={onToggleSnap} className={snapEnabled ? BTN_ACTIVE : BTN}>\n <MagnetGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button type=\"button\" aria-label=\"Toggle bleed overlay\" aria-pressed={showBleed} onClick={onToggleBleed} className={showBleed ? BTN_ACTIVE : BTN} disabled={!page.bleed}>\n <BleedGlyph className=\"h-3.5 w-3.5\" />\n </button>\n\n {SEP}\n\n {hasSelection ? (\n <SelectionControls\n elements={selectedElements}\n single={single}\n isGroup={isGroup}\n groupable={groupable}\n allSameKind={allSameKind}\n firstKind={firstKind}\n canWrite={canWrite}\n patchAll={patchAll}\n reorderSingle={reorderSingle}\n onGroup={() => onGroup(selectedIds)}\n onUngroup={() => { if (single) onUngroup(single.id) }}\n onDelete={() => onDelete(selectedIds)}\n onBindSlot={single ? (slot) => onBindSlot(single.id, slot) : undefined}\n currentSlot={single?.slot ?? null}\n />\n ) : (\n <PagePropsControls\n page={page}\n canWrite={canWrite}\n onSetPageProps={onSetPageProps}\n onSetPageGuides={onSetPageGuides}\n />\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Selection controls\n// ---------------------------------------------------------------------------\n\ninterface SelectionControlsProps {\n elements: SceneElement[]\n single: SceneElement | null\n isGroup: boolean\n groupable: boolean\n allSameKind: boolean\n firstKind: SceneElement['kind'] | undefined\n canWrite: boolean\n patchAll(attrs: SceneAttrsPatch): void\n reorderSingle(direction: 'front' | 'back' | 'forward' | 'backward'): void\n onGroup(): void\n onUngroup(): void\n onDelete(): void\n onBindSlot?(slot: string | null): void\n currentSlot: string | null\n}\n\nfunction SelectionControls({\n elements,\n single,\n isGroup,\n groupable,\n allSameKind,\n firstKind,\n canWrite,\n patchAll,\n reorderSingle,\n onGroup,\n onUngroup,\n onDelete,\n onBindSlot,\n currentSlot,\n}: SelectionControlsProps) {\n const [slotPopoverOpen, setSlotPopoverOpen] = useState(false)\n const [slotInput, setSlotInput] = useState('')\n const firstEl = elements[0]!\n\n return (\n <>\n {/* Kind-specific attrs */}\n {allSameKind && firstKind === 'text' && single ? (\n <TextControls element={single as TextElement} canWrite={canWrite} onPatch={(attrs) => patchAll(attrs)} />\n ) : null}\n\n {allSameKind && (firstKind === 'rect') && single ? (\n <ShapeControls element={single as RectElement} canWrite={canWrite} onPatch={(attrs) => patchAll(attrs)} showCornerRadius />\n ) : null}\n\n {allSameKind && firstKind === 'ellipse' && single ? (\n <ShapeControls element={single as EllipseElement} canWrite={canWrite} onPatch={(attrs) => patchAll(attrs)} showCornerRadius={false} />\n ) : null}\n\n {allSameKind && firstKind === 'image' && single ? (\n <ImageControls element={single as ImageElement} canWrite={canWrite} onPatch={(attrs) => patchAll(attrs)} />\n ) : null}\n\n {SEP}\n\n {/* Shared: opacity + rotation */}\n <NumberInput\n label=\"Opacity\"\n value={Math.round((firstEl.opacity ?? 1) * 100)}\n min={0}\n onCommit={(v) => patchAll({ opacity: Math.max(0, Math.min(1, v / 100)) })}\n className=\"w-14\"\n />\n <NumberInput\n label=\"Rotation\"\n value={Math.round(firstEl.rotation ?? 0)}\n onCommit={(v) => patchAll({ rotation: v })}\n className=\"w-14\"\n />\n\n {SEP}\n\n {/* Z-order (single selection) */}\n {single ? (\n <>\n <button type=\"button\" aria-label=\"Bring to front\" disabled={!canWrite} onClick={() => reorderSingle('front')} className={BTN}>\n <BringFrontGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button type=\"button\" aria-label=\"Send to back\" disabled={!canWrite} onClick={() => reorderSingle('back')} className={BTN}>\n <SendBackGlyph className=\"h-3.5 w-3.5\" />\n </button>\n {SEP}\n </>\n ) : null}\n\n {/* Group / Ungroup */}\n {groupable ? (\n <button type=\"button\" aria-label=\"Group elements\" disabled={!canWrite} onClick={onGroup} className={BTN}>\n <GroupGlyph className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n {isGroup ? (\n <button type=\"button\" aria-label=\"Ungroup\" disabled={!canWrite} onClick={onUngroup} className={BTN}>\n <UngroupGlyph className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n\n {/* Lock */}\n {single ? (\n <button\n type=\"button\"\n aria-label={single.locked ? 'Unlock element' : 'Lock element'}\n disabled={!canWrite}\n onClick={() => patchAll({ locked: !single.locked })}\n className={single.locked ? BTN_ACTIVE : BTN}\n >\n {single.locked ? <LockGlyph className=\"h-3.5 w-3.5\" /> : <UnlockGlyph className=\"h-3.5 w-3.5\" />}\n </button>\n ) : null}\n\n {/* Slot binding (single element only) */}\n {single && onBindSlot ? (\n <div className=\"relative\">\n <button\n type=\"button\"\n aria-label={currentSlot ? `Slot: ${currentSlot}` : 'Bind slot'}\n onClick={() => { setSlotInput(currentSlot ?? ''); setSlotPopoverOpen((v) => !v) }}\n className={currentSlot ? BTN_ACTIVE : BTN}\n title={currentSlot ? `Slot: ${currentSlot}` : 'Bind slot'}\n >\n <SlotGlyph className=\"h-3.5 w-3.5\" />\n </button>\n {slotPopoverOpen ? (\n <div className=\"absolute top-full left-0 z-50 mt-1 flex w-48 flex-col gap-2 rounded border border-[var(--border-default)] bg-[var(--bg-input)] p-2 shadow-lg\">\n <input\n autoFocus\n value={slotInput}\n onChange={(event) => setSlotInput(event.target.value)}\n placeholder=\"slot-name\"\n className=\"rounded border border-[var(--border-default)] bg-transparent px-2 py-1 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => { onBindSlot(slotInput.trim() || null); setSlotPopoverOpen(false) }}\n className=\"flex-1 rounded border border-[var(--brand-primary)] px-2 py-0.5 text-[11px] text-[var(--brand-primary)] hover:bg-[var(--brand-primary)]/10\"\n >\n {slotInput.trim() ? 'Bind' : 'Unbind'}\n </button>\n <button\n type=\"button\"\n onClick={() => setSlotPopoverOpen(false)}\n className=\"rounded border border-[var(--border-default)] px-2 py-0.5 text-[11px] text-[var(--text-secondary)]\"\n >\n Cancel\n </button>\n </div>\n </div>\n ) : null}\n </div>\n ) : null}\n\n {SEP}\n\n {/* Delete */}\n <button type=\"button\" aria-label=\"Delete selection\" disabled={!canWrite} onClick={onDelete} className={BTN}>\n <TrashGlyph className=\"h-3.5 w-3.5 text-rose-400\" />\n </button>\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Kind-specific controls\n// ---------------------------------------------------------------------------\n\nfunction TextControls({ element, canWrite, onPatch }: { element: TextElement; canWrite: boolean; onPatch(attrs: SceneAttrsPatch): void }) {\n return (\n <>\n <input\n type=\"text\"\n aria-label=\"Font family\"\n value={element.fontFamily}\n disabled={!canWrite}\n onChange={(event) => onPatch({ fontFamily: event.target.value })}\n className=\"w-28 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n placeholder=\"Font\"\n />\n <NumberInput label=\"Size\" value={element.fontSize} min={1} onCommit={(v) => onPatch({ fontSize: v })} className=\"w-12\" />\n <button\n type=\"button\"\n aria-label=\"Bold\"\n disabled={!canWrite}\n onClick={() => onPatch({ fontStyle: element.fontStyle === 'bold' || element.fontStyle === 'bold italic' ? (element.fontStyle === 'bold italic' ? 'italic' : 'normal') : (element.fontStyle === 'italic' ? 'bold italic' : 'bold') })}\n className={element.fontStyle?.includes('bold') ? BTN_ACTIVE : BTN}\n >\n <BoldGlyph className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n aria-label=\"Italic\"\n disabled={!canWrite}\n onClick={() => onPatch({ fontStyle: element.fontStyle === 'italic' || element.fontStyle === 'bold italic' ? (element.fontStyle === 'bold italic' ? 'bold' : 'normal') : (element.fontStyle === 'bold' ? 'bold italic' : 'italic') })}\n className={element.fontStyle?.includes('italic') ? BTN_ACTIVE : BTN}\n >\n <ItalicGlyph className=\"h-3.5 w-3.5\" />\n </button>\n {(['left', 'center', 'right'] as const).map((align) => (\n <button\n key={align}\n type=\"button\"\n aria-label={`Align ${align}`}\n disabled={!canWrite}\n onClick={() => onPatch({ align })}\n className={element.align === align ? BTN_ACTIVE : BTN}\n >\n {align === 'left' ? <AlignLeftGlyph className=\"h-3.5 w-3.5\" /> : align === 'center' ? <AlignCenterGlyph className=\"h-3.5 w-3.5\" /> : <AlignRightGlyph className=\"h-3.5 w-3.5\" />}\n </button>\n ))}\n <NumberInput label=\"Line H\" value={element.lineHeight} step={0.1} min={0.5} onCommit={(v) => onPatch({ lineHeight: v })} className=\"w-12\" />\n <NumberInput label=\"Spacing\" value={element.letterSpacing} step={0.5} onCommit={(v) => onPatch({ letterSpacing: v })} className=\"w-14\" />\n <ColorSwatch label=\"Fill\" value={element.fill} onCommit={(v) => onPatch({ fill: v })} />\n </>\n )\n}\n\nfunction ShapeControls({ element, canWrite, onPatch, showCornerRadius }: { element: RectElement | EllipseElement; canWrite: boolean; onPatch(attrs: SceneAttrsPatch): void; showCornerRadius: boolean }) {\n return (\n <>\n <ColorSwatch label=\"Fill\" value={element.fill} onCommit={(v) => onPatch({ fill: v })} />\n <ColorSwatch label=\"Stroke\" value={element.stroke ?? '#000000'} onCommit={(v) => onPatch({ stroke: v })} />\n <NumberInput label=\"Stroke W\" value={element.strokeWidth ?? 0} min={0} onCommit={(v) => onPatch({ strokeWidth: v })} className=\"w-14\" />\n {showCornerRadius && 'cornerRadius' in element ? (\n <NumberInput label=\"Corner R\" value={(element as RectElement).cornerRadius ?? 0} min={0} onCommit={(v) => onPatch({ cornerRadius: v })} className=\"w-14\" />\n ) : null}\n </>\n )\n}\n\nfunction ImageControls({ element, canWrite, onPatch }: { element: ImageElement; canWrite: boolean; onPatch(attrs: SceneAttrsPatch): void }) {\n return (\n <label className=\"flex flex-col items-center gap-0.5\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">Fit</span>\n <select\n value={element.fit}\n disabled={!canWrite}\n onChange={(event) => onPatch({ fit: event.target.value as ImageElement['fit'] })}\n className=\"rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0.5 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n >\n <option value=\"fill\">Fill</option>\n <option value=\"cover\">Cover</option>\n <option value=\"contain\">Contain</option>\n </select>\n </label>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Page props controls (no selection)\n// ---------------------------------------------------------------------------\n\ninterface PagePropsControlsProps {\n page: ScenePage\n canWrite: boolean\n onSetPageProps(props: { name?: string; width?: number; height?: number; background?: string; bleed?: PageBleed | null }): void\n onSetPageGuides(guides: { vertical: number[]; horizontal: number[] }): void\n}\n\nfunction PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides }: PagePropsControlsProps) {\n const matchedPreset = matchPreset(page.width, page.height)\n const [customW, setCustomW] = useState<string | null>(null)\n const [customH, setCustomH] = useState<string | null>(null)\n\n function commitDimension(dim: 'width' | 'height', raw: string) {\n const v = parseFloat(raw)\n if (Number.isFinite(v) && v > 0) onSetPageProps({ [dim]: v })\n if (dim === 'width') setCustomW(null)\n else setCustomH(null)\n }\n\n return (\n <>\n {/* Page name */}\n <input\n type=\"text\"\n aria-label=\"Page name\"\n value={page.name}\n disabled={!canWrite}\n onChange={(event) => onSetPageProps({ name: event.target.value })}\n className=\"w-28 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n />\n\n {SEP}\n\n {/* Size preset */}\n <label className=\"flex flex-col items-center gap-0.5\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">Preset</span>\n <select\n value={matchedPreset?.id ?? 'custom'}\n disabled={!canWrite}\n onChange={(event) => {\n const preset = SIZE_PRESETS.find((p) => p.id === event.target.value)\n if (preset) onSetPageProps({ width: preset.width, height: preset.height })\n }}\n className=\"rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0.5 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n >\n <option value=\"custom\">Custom</option>\n {SIZE_PRESETS.map((p) => (\n <option key={p.id} value={p.id}>{p.label}</option>\n ))}\n </select>\n </label>\n\n {/* Custom W × H */}\n <label className=\"flex flex-col items-center gap-0.5\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">W</span>\n <input\n type=\"number\"\n value={customW ?? page.width}\n min={1}\n disabled={!canWrite}\n onChange={(event) => setCustomW(event.target.value)}\n onBlur={(event) => commitDimension('width', event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') commitDimension('width', (event.target as HTMLInputElement).value)\n if (event.key === 'Escape') setCustomW(null)\n }}\n className=\"w-16 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0.5 text-center text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n />\n </label>\n <span className=\"text-[var(--text-muted)]\">×</span>\n <label className=\"flex flex-col items-center gap-0.5\">\n <span className=\"text-[9px] uppercase tracking-wide text-[var(--text-muted)]\">H</span>\n <input\n type=\"number\"\n value={customH ?? page.height}\n min={1}\n disabled={!canWrite}\n onChange={(event) => setCustomH(event.target.value)}\n onBlur={(event) => commitDimension('height', event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') commitDimension('height', (event.target as HTMLInputElement).value)\n if (event.key === 'Escape') setCustomH(null)\n }}\n className=\"w-16 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0.5 text-center text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n />\n </label>\n\n {SEP}\n\n <ColorSwatch label=\"BG\" value={page.background} onCommit={(v) => onSetPageProps({ background: v })} />\n\n {SEP}\n\n {/* Bleed controls */}\n <BleedControls page={page} canWrite={canWrite} onSetPageProps={onSetPageProps} />\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Bleed sub-controls\n// ---------------------------------------------------------------------------\n\nfunction BleedControls({ page, canWrite, onSetPageProps }: { page: ScenePage; canWrite: boolean; onSetPageProps: PagePropsControlsProps['onSetPageProps'] }) {\n const bleed = page.bleed\n\n function setBleedSide(side: keyof PageBleed, value: number) {\n const current = bleed ?? { top: 0, right: 0, bottom: 0, left: 0 }\n onSetPageProps({ bleed: { ...current, [side]: value } })\n }\n\n if (!bleed) {\n return (\n <button\n type=\"button\"\n disabled={!canWrite}\n onClick={() => onSetPageProps({ bleed: { top: 3, right: 3, bottom: 3, left: 3 } })}\n className={BTN}\n title=\"Enable bleed\"\n >\n <BleedGlyph className=\"h-3.5 w-3.5\" />\n </button>\n )\n }\n\n return (\n <>\n {(['top', 'right', 'bottom', 'left'] as const).map((side) => (\n <NumberInput\n key={side}\n label={`Bleed ${side[0]!.toUpperCase()}`}\n value={bleed[side]}\n min={0}\n onCommit={(v) => setBleedSide(side, v)}\n className=\"w-12\"\n />\n ))}\n <button\n type=\"button\"\n disabled={!canWrite}\n onClick={() => onSetPageProps({ bleed: null })}\n className={BTN}\n title=\"Remove bleed\"\n >\n ×\n </button>\n </>\n )\n}\n","/**\n * Canvas zoom controls: fit-to-page, 100%, zoom-out/in buttons, and a percent\n * readout. Stateless — zoom lives in the editor's view state, updated through\n * onZoom.\n */\n\nimport { ZoomFitGlyph } from './glyphs'\n\nexport interface ZoomControlsProps {\n zoom: number\n onZoom(zoom: number): void\n onFit(): void\n}\n\nconst STEP = 0.1\nconst MIN = 0.05\nconst MAX = 32\n\nconst BTN =\n 'flex h-6 w-6 items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] disabled:cursor-default disabled:opacity-40'\n\nexport function ZoomControls({ zoom, onZoom, onFit }: ZoomControlsProps) {\n function zoomOut() {\n onZoom(Math.max(MIN, parseFloat((zoom - STEP).toFixed(4))))\n }\n function zoomIn() {\n onZoom(Math.min(MAX, parseFloat((zoom + STEP).toFixed(4))))\n }\n function resetHundred() {\n onZoom(1)\n }\n\n return (\n <div className=\"flex items-center gap-1 px-2\">\n <button\n type=\"button\"\n aria-label=\"Fit page to viewport\"\n onClick={onFit}\n className={BTN}\n title=\"Fit page (F)\"\n >\n <ZoomFitGlyph className=\"h-3.5 w-3.5\" />\n </button>\n\n <button\n type=\"button\"\n aria-label=\"Zoom out\"\n onClick={zoomOut}\n disabled={zoom <= MIN}\n className={BTN}\n >\n <span className=\"text-base leading-none\">−</span>\n </button>\n\n <button\n type=\"button\"\n aria-label=\"Reset to 100%\"\n onClick={resetHundred}\n className=\"rounded px-1.5 py-0.5 font-mono text-[11px] tabular-nums text-[var(--text-secondary)] transition hover:bg-[var(--border-default)] hover:text-[var(--text-primary)]\"\n title=\"Reset to 100%\"\n >\n {Math.round(zoom * 100)}%\n </button>\n\n <button\n type=\"button\"\n aria-label=\"Zoom in\"\n onClick={zoomIn}\n disabled={zoom >= MAX}\n className={BTN}\n >\n <span className=\"text-sm leading-none\">+</span>\n </button>\n </div>\n )\n}\n"],"mappings":"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","names":["useCallback","useEffect","useRef","useState","activePageId","Fragment","jsx","jsxs","jsx","jsxs","useRef","useState","Fragment","jsx","jsxs","useRef","useState","useState","Fragment","jsx","jsxs","BTN","useState","jsx","jsxs","BTN","jsx","jsxs","useCallback","useRef","useEffect","useState"]}