nudge-ui 0.2.4 → 0.2.6

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 (642) hide show
  1. package/dist/cli/agentCommand.d.ts +0 -1
  2. package/dist/cli/agentCommand.js +4 -29
  3. package/dist/client.mjs +987 -221
  4. package/dist/compiler/ast.d.ts +0 -6
  5. package/dist/compiler/ast.js +0 -5
  6. package/dist/compiler/componentContractTypes.d.ts +11 -5
  7. package/dist/compiler/componentContracts.js +3 -9
  8. package/dist/compiler/componentInstrumentation.d.ts +2 -13
  9. package/dist/compiler/componentInstrumentation.js +3 -12
  10. package/dist/compiler/componentPolicyResolution.d.ts +3 -22
  11. package/dist/compiler/componentPolicyResolution.js +6 -38
  12. package/dist/compiler/identityAttributes.d.ts +2 -0
  13. package/dist/compiler/identityAttributes.js +2 -0
  14. package/dist/compiler/index.d.ts +0 -1
  15. package/dist/compiler/index.js +0 -1
  16. package/dist/compiler/packageComponentContracts.d.ts +10 -19
  17. package/dist/compiler/packageComponentContracts.js +60 -43
  18. package/dist/compiler/reactComponentProtocols.d.ts +0 -7
  19. package/dist/compiler/reactComponentProtocols.js +0 -7
  20. package/dist/compiler/reactIdentity.d.ts +2 -2
  21. package/dist/compiler/reactIdentity.js +41 -43
  22. package/dist/compiler/sourcePaths.d.ts +4 -8
  23. package/dist/compiler/sourcePaths.js +6 -8
  24. package/dist/css/dialects/index.d.ts +2 -21
  25. package/dist/css/dialects/index.js +2 -9
  26. package/dist/css/dialects/tailwind.d.ts +2 -16
  27. package/dist/css/dialects/tailwind.js +2 -25
  28. package/dist/css/dialects/vanillaExtract.d.ts +1 -9
  29. package/dist/css/dialects/vanillaExtract.js +0 -1
  30. package/dist/css/index.d.ts +0 -8
  31. package/dist/css/index.js +0 -8
  32. package/dist/css/model/index.d.ts +6 -38
  33. package/dist/css/model/index.js +0 -9
  34. package/dist/css/token-inventory/index.d.ts +0 -23
  35. package/dist/css/token-inventory/index.js +0 -23
  36. package/dist/css/token-inventory/inventory.js +4 -16
  37. package/dist/css/token-inventory/parseStylesheet.d.ts +1 -9
  38. package/dist/css/token-inventory/parseStylesheet.js +5 -42
  39. package/dist/css/token-inventory/policy.d.ts +2 -39
  40. package/dist/css/token-inventory/policy.js +2 -39
  41. package/dist/css/token-inventory/types.d.ts +2 -15
  42. package/dist/css/value-semantics/borderSemantics.d.ts +1 -8
  43. package/dist/css/value-semantics/borderSemantics.js +5 -23
  44. package/dist/css/value-semantics/boxSemantics.d.ts +2 -25
  45. package/dist/css/value-semantics/boxSemantics.js +1 -7
  46. package/dist/css/value-semantics/colorSemantics.d.ts +6 -60
  47. package/dist/css/value-semantics/colorSemantics.js +9 -40
  48. package/dist/css/value-semantics/cssSyntax.d.ts +10 -10
  49. package/dist/css/value-semantics/cssSyntax.js +39 -11
  50. package/dist/css/value-semantics/fontSemantics.d.ts +3 -19
  51. package/dist/css/value-semantics/fontSemantics.js +7 -25
  52. package/dist/css/value-semantics/index.d.ts +1 -12
  53. package/dist/css/value-semantics/index.js +1 -12
  54. package/dist/css/value-semantics/propertyPolicy.d.ts +6 -53
  55. package/dist/css/value-semantics/propertyPolicy.js +47 -59
  56. package/dist/css/value-semantics/stringMaps.d.ts +0 -1
  57. package/dist/css/value-semantics/structuredValues.d.ts +3 -37
  58. package/dist/css/value-semantics/structuredValues.js +6 -17
  59. package/dist/css/value-semantics/tokenInterpretation.d.ts +8 -50
  60. package/dist/css/value-semantics/tokenInterpretation.js +7 -21
  61. package/dist/hosts/astro/astroRuntimeConfig.d.ts +0 -1
  62. package/dist/hosts/astro/astroRuntimeConfig.js +0 -1
  63. package/dist/hosts/astro/clientAsset.d.ts +1 -5
  64. package/dist/hosts/astro/clientAsset.js +1 -5
  65. package/dist/hosts/astro/clientTransport.d.ts +0 -1
  66. package/dist/hosts/astro/clientTransport.js +4 -9
  67. package/dist/hosts/astro/integration.d.ts +2 -28
  68. package/dist/hosts/astro/integration.js +7 -36
  69. package/dist/hosts/astro/markdownIdentity.d.ts +0 -3
  70. package/dist/hosts/astro/markdownIdentity.js +0 -3
  71. package/dist/hosts/astro/middleware.d.ts +1 -12
  72. package/dist/hosts/astro/middleware.js +1 -12
  73. package/dist/hosts/astro/projectContext.d.ts +1 -9
  74. package/dist/hosts/astro/projectContext.js +2 -11
  75. package/dist/hosts/astro/responseInstrumentation.d.ts +4 -33
  76. package/dist/hosts/astro/responseInstrumentation.js +5 -34
  77. package/dist/hosts/environment.d.ts +0 -8
  78. package/dist/hosts/environment.js +0 -1
  79. package/dist/hosts/next/index.js +1 -3
  80. package/dist/hosts/next/loader.d.ts +5 -44
  81. package/dist/hosts/next/loader.js +22 -103
  82. package/dist/hosts/next/loaders/identity-loader.cjs +111 -65
  83. package/dist/hosts/next/loaders/loader-plugin.cjs +111 -65
  84. package/dist/hosts/next/manifest.d.ts +2 -16
  85. package/dist/hosts/next/manifest.js +18 -20
  86. package/dist/hosts/next/mount.d.ts +1 -11
  87. package/dist/hosts/next/mount.js +1 -11
  88. package/dist/hosts/next/repositoryScope.d.ts +2 -17
  89. package/dist/hosts/next/repositoryScope.js +2 -17
  90. package/dist/hosts/next/sidecar.d.ts +0 -13
  91. package/dist/hosts/next/sidecar.js +25 -110
  92. package/dist/hosts/next/wrapper.d.ts +0 -31
  93. package/dist/hosts/next/wrapper.js +14 -71
  94. package/dist/hosts/projectBridge.d.ts +0 -2
  95. package/dist/hosts/projectBridge.js +3 -19
  96. package/dist/hosts/reactRendererCapture.d.ts +2 -0
  97. package/dist/hosts/reactRendererCapture.js +12 -0
  98. package/dist/hosts/static/cli.d.ts +0 -4
  99. package/dist/hosts/static/cli.js +0 -3
  100. package/dist/hosts/static/html/bootstrap.d.ts +1 -18
  101. package/dist/hosts/static/html/bootstrap.js +2 -14
  102. package/dist/hosts/static/manifest.d.ts +2 -15
  103. package/dist/hosts/static/manifest.js +5 -18
  104. package/dist/hosts/static/server.d.ts +4 -38
  105. package/dist/hosts/static/server.js +17 -67
  106. package/dist/hosts/vite/index.d.ts +0 -10
  107. package/dist/hosts/vite/index.js +0 -10
  108. package/dist/hosts/vite/react.d.ts +4 -17
  109. package/dist/hosts/vite/react.js +18 -35
  110. package/dist/hosts/vite/tokens/activeStylesheets.d.ts +1 -10
  111. package/dist/hosts/vite/tokens/activeStylesheets.js +3 -8
  112. package/dist/hosts/vite/tokens/fileMap.d.ts +0 -1
  113. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.d.ts +2 -15
  114. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.js +3 -10
  115. package/dist/hosts/vite/vite.d.ts +5 -26
  116. package/dist/hosts/vite/vite.js +44 -80
  117. package/dist/html/dom.d.ts +0 -1
  118. package/dist/html/dom.js +0 -1
  119. package/dist/html/identity.d.ts +1 -15
  120. package/dist/html/identity.js +1 -8
  121. package/dist/html/insertions.d.ts +2 -8
  122. package/dist/html/insertions.js +1 -1
  123. package/dist/inspector/agent/McpConnectionDialog.d.ts +1 -6
  124. package/dist/inspector/agent/McpConnectionDialog.js +8 -9
  125. package/dist/inspector/agent/activity.d.ts +2 -2
  126. package/dist/inspector/agent/activity.js +4 -3
  127. package/dist/inspector/agent/client.d.ts +3 -27
  128. package/dist/inspector/agent/client.js +43 -91
  129. package/dist/inspector/agent/connectionStatus.d.ts +3 -2
  130. package/dist/inspector/agent/connectionStatus.js +25 -1
  131. package/dist/inspector/agent/httpTransport.d.ts +0 -8
  132. package/dist/inspector/agent/httpTransport.js +42 -176
  133. package/dist/inspector/agent/protocol.d.ts +1 -10
  134. package/dist/inspector/agent/protocol.js +1 -9
  135. package/dist/inspector/agent/verification.d.ts +3 -20
  136. package/dist/inspector/agent/verification.js +10 -43
  137. package/dist/inspector/boot.d.ts +5 -0
  138. package/dist/inspector/boot.js +289 -0
  139. package/dist/inspector/canvas/AgentActivityOverlay.d.ts +3 -2
  140. package/dist/inspector/canvas/AgentActivityOverlay.js +7 -4
  141. package/dist/inspector/canvas/CanvasCard.js +26 -24
  142. package/dist/inspector/canvas/CanvasElementOverlay.js +196 -174
  143. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  144. package/dist/inspector/canvas/CanvasWorkspace.js +87 -124
  145. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
  146. package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
  147. package/dist/inspector/canvas/PageCard.d.ts +9 -0
  148. package/dist/inspector/canvas/PageCard.js +50 -0
  149. package/dist/inspector/canvas/SketchToolOptions.d.ts +4 -0
  150. package/dist/inspector/canvas/SketchToolOptions.js +80 -0
  151. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
  152. package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
  153. package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +16 -0
  154. package/dist/inspector/canvas/ToolOptionsDrawer.js +71 -0
  155. package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -4
  156. package/dist/inspector/canvas/activeCanvasDocument.js +0 -2
  157. package/dist/inspector/canvas/agentPresentation.d.ts +2 -13
  158. package/dist/inspector/canvas/agentPresentation.js +3 -14
  159. package/dist/inspector/canvas/assets/eraser.svg +28 -0
  160. package/dist/inspector/canvas/assets/pen.svg +25 -0
  161. package/dist/inspector/canvas/canvasFrame.d.ts +12 -0
  162. package/dist/inspector/canvas/canvasFrame.js +9 -0
  163. package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
  164. package/dist/inspector/canvas/canvasGestures.js +0 -6
  165. package/dist/inspector/canvas/canvasResize.d.ts +1 -6
  166. package/dist/inspector/canvas/canvasResize.js +1 -6
  167. package/dist/inspector/canvas/canvasStore.d.ts +5 -7
  168. package/dist/inspector/canvas/canvasStore.js +42 -21
  169. package/dist/inspector/canvas/frameConnection.d.ts +42 -0
  170. package/dist/inspector/canvas/frameConnection.js +73 -0
  171. package/dist/inspector/canvas/frameContent.d.ts +0 -1
  172. package/dist/inspector/canvas/frameLifecycle.d.ts +12 -0
  173. package/dist/inspector/canvas/frameLifecycle.js +11 -0
  174. package/dist/inspector/canvas/frameProtocol.d.ts +20 -38
  175. package/dist/inspector/canvas/frameProtocol.js +37 -24
  176. package/dist/inspector/canvas/frameScrollbarStyles.d.ts +0 -1
  177. package/dist/inspector/canvas/frameScrollbarStyles.js +0 -1
  178. package/dist/inspector/canvas/layout.d.ts +10 -22
  179. package/dist/inspector/canvas/layout.js +0 -3
  180. package/dist/inspector/canvas/normalizeUrl.js +1 -8
  181. package/dist/inspector/canvas/pageSurface.d.ts +6 -0
  182. package/dist/inspector/canvas/pageSurface.js +29 -0
  183. package/dist/inspector/canvas/projection.d.ts +14 -25
  184. package/dist/inspector/canvas/projection.js +64 -87
  185. package/dist/inspector/canvas/rendererBootstrap.d.ts +8 -1
  186. package/dist/inspector/canvas/rendererBootstrap.js +10 -15
  187. package/dist/inspector/canvas/rendererCidIndex.d.ts +0 -5
  188. package/dist/inspector/canvas/rendererCidIndex.js +0 -5
  189. package/dist/inspector/canvas/rendererElementSelector.js +38 -28
  190. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -6
  191. package/dist/inspector/canvas/rendererMessageRouter.js +12 -17
  192. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +3 -1
  193. package/dist/inspector/canvas/rendererSelectionProxy.js +7 -40
  194. package/dist/inspector/canvas/rendererStylesheet.d.ts +0 -1
  195. package/dist/inspector/canvas/rendererStylesheet.js +23 -1
  196. package/dist/inspector/canvas/resizeHandleScale.d.ts +1 -10
  197. package/dist/inspector/canvas/resizeHandleScale.js +1 -10
  198. package/dist/inspector/canvas/sessionStore.d.ts +3 -9
  199. package/dist/inspector/canvas/sessionStore.js +33 -43
  200. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  201. package/dist/inspector/canvas/staleChangeDetector.js +11 -26
  202. package/dist/inspector/canvas/toolbarScale.d.ts +1 -4
  203. package/dist/inspector/canvas/toolbarScale.js +1 -4
  204. package/dist/inspector/canvas/useCanvasLayoutAnimation.d.ts +0 -1
  205. package/dist/inspector/canvas/useCanvasLayoutAnimation.js +0 -1
  206. package/dist/inspector/canvas/viewStore.js +1 -1
  207. package/dist/inspector/canvas/wheelPan.d.ts +1 -1
  208. package/dist/inspector/canvas/wheelPan.js +1 -1
  209. package/dist/inspector/canvas/workspaceLease.d.ts +1 -5
  210. package/dist/inspector/canvas/workspaceLease.js +1 -7
  211. package/dist/inspector/changes/codecs.d.ts +1 -0
  212. package/dist/inspector/changes/codecs.js +21 -5
  213. package/dist/inspector/changes/draftPreview.d.ts +7 -0
  214. package/dist/inspector/changes/draftPreview.js +118 -0
  215. package/dist/inspector/changes/editModel.d.ts +11 -13
  216. package/dist/inspector/changes/editModel.js +9 -4
  217. package/dist/inspector/changes/managedStyleProjection.js +6 -15
  218. package/dist/inspector/changes/model.d.ts +0 -5
  219. package/dist/inspector/changes/model.js +1 -8
  220. package/dist/inspector/changes/previewDiagnostics.d.ts +2 -12
  221. package/dist/inspector/changes/previewDiagnostics.js +5 -21
  222. package/dist/inspector/changes/previewVerification.d.ts +25 -0
  223. package/dist/inspector/changes/previewVerification.js +34 -0
  224. package/dist/inspector/changes/structuralTypes.d.ts +2 -4
  225. package/dist/inspector/changes/types.d.ts +11 -8
  226. package/dist/inspector/clientManifest.d.ts +17 -6
  227. package/dist/inspector/clientManifest.js +16 -3
  228. package/dist/inspector/comments/CommentsOverlay.js +66 -23
  229. package/dist/inspector/comments/element.d.ts +1 -2
  230. package/dist/inspector/comments/element.js +1 -2
  231. package/dist/inspector/comments/store.d.ts +1 -1
  232. package/dist/inspector/comments/store.js +4 -3
  233. package/dist/inspector/comments/verification.d.ts +8 -2
  234. package/dist/inspector/comments/verification.js +19 -11
  235. package/dist/inspector/componentSemantics/ComponentPropsSection.d.ts +8 -0
  236. package/dist/inspector/componentSemantics/ComponentPropsSection.js +12 -8
  237. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +2 -9
  238. package/dist/inspector/componentSemantics/adapterRegistry.js +2 -9
  239. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  240. package/dist/inspector/componentSemantics/changeModel.js +2 -4
  241. package/dist/inspector/componentSemantics/react/callsites.d.ts +28 -0
  242. package/dist/inspector/componentSemantics/react/callsites.js +261 -0
  243. package/dist/inspector/componentSemantics/react/devtoolsHook.d.ts +23 -0
  244. package/dist/inspector/componentSemantics/react/devtoolsHook.js +71 -0
  245. package/dist/inspector/componentSemantics/react/fibers.d.ts +17 -0
  246. package/dist/inspector/componentSemantics/react/fibers.js +30 -0
  247. package/dist/inspector/componentSemantics/{reactRuntime.d.ts → react/runtime.d.ts} +3 -2
  248. package/dist/inspector/componentSemantics/{reactRuntime.js → react/runtime.js} +70 -53
  249. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +2 -18
  250. package/dist/inspector/componentSemantics/runtimeBridge.js +5 -19
  251. package/dist/inspector/componentSemantics/textBinding.d.ts +2 -11
  252. package/dist/inspector/componentSemantics/textBinding.js +20 -87
  253. package/dist/inspector/componentSemantics/types.d.ts +8 -27
  254. package/dist/inspector/componentSemantics/types.js +0 -1
  255. package/dist/inspector/conformance/borderCases.d.ts +0 -5
  256. package/dist/inspector/conformance/borderCases.js +0 -5
  257. package/dist/inspector/conformance/colorCases.d.ts +0 -6
  258. package/dist/inspector/conformance/colorCases.js +0 -6
  259. package/dist/inspector/conformance/fixture.d.ts +1 -5
  260. package/dist/inspector/conformance/fixture.js +1 -5
  261. package/dist/inspector/conformance/spacingCases.d.ts +0 -4
  262. package/dist/inspector/conformance/spacingCases.js +0 -4
  263. package/dist/inspector/conformance/typographyCases.d.ts +0 -5
  264. package/dist/inspector/conformance/typographyCases.js +0 -5
  265. package/dist/inspector/drafts/draftStore.d.ts +95 -0
  266. package/dist/inspector/drafts/draftStore.js +461 -0
  267. package/dist/inspector/drafts/model.d.ts +14 -14
  268. package/dist/inspector/drafts/model.js +4 -2
  269. package/dist/inspector/drafts/store.d.ts +47 -16
  270. package/dist/inspector/drafts/store.js +137 -170
  271. package/dist/inspector/editScope.d.ts +0 -1
  272. package/dist/inspector/editScope.js +0 -1
  273. package/dist/inspector/index.d.ts +2 -4
  274. package/dist/inspector/index.js +2 -264
  275. package/dist/inspector/inline-text/inlineTextDiagnostics.d.ts +0 -2
  276. package/dist/inspector/inline-text/inlineTextDiagnostics.js +0 -2
  277. package/dist/inspector/inline-text/inlineTextEditor.d.ts +3 -9
  278. package/dist/inspector/inline-text/inlineTextEditor.js +27 -81
  279. package/dist/inspector/inline-text/inlineTextLifecycle.js +1 -6
  280. package/dist/inspector/inline-text/textEditChange.d.ts +1 -2
  281. package/dist/inspector/inspection/bridge.d.ts +3 -7
  282. package/dist/inspector/inspection/bridge.js +6 -13
  283. package/dist/inspector/inspection/browserCssInspection.d.ts +12 -11
  284. package/dist/inspector/inspection/browserCssInspection.js +32 -14
  285. package/dist/inspector/inspection/browserCssInspectionRegistry.d.ts +0 -7
  286. package/dist/inspector/inspection/browserCssInspectionRegistry.js +1 -16
  287. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  288. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  289. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  290. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  291. package/dist/inspector/inspection/selectionProperty.d.ts +1 -6
  292. package/dist/inspector/inspection/selectionProperty.js +1 -5
  293. package/dist/inspector/inspection/useBrowserCssInspection.d.ts +1 -5
  294. package/dist/inspector/inspection/useBrowserCssInspection.js +22 -59
  295. package/dist/inspector/iterations/capture.d.ts +2 -2
  296. package/dist/inspector/iterations/capture.js +4 -9
  297. package/dist/inspector/iterations/client.d.ts +2 -2
  298. package/dist/inspector/iterations/client.js +0 -1
  299. package/dist/inspector/iterations/coordinator.d.ts +4 -4
  300. package/dist/inspector/iterations/coordinator.js +5 -4
  301. package/dist/inspector/iterations/prompt.d.ts +0 -1
  302. package/dist/inspector/iterations/prompt.js +9 -9
  303. package/dist/inspector/overlay/DomNavigator.d.ts +3 -1
  304. package/dist/inspector/overlay/DomNavigator.js +39 -15
  305. package/dist/inspector/overlay/DropGuideOverlay.d.ts +0 -1
  306. package/dist/inspector/overlay/DropGuideOverlay.js +0 -1
  307. package/dist/inspector/overlay/MeasurementGuideOverlay.d.ts +1 -8
  308. package/dist/inspector/overlay/MeasurementGuideOverlay.js +1 -5
  309. package/dist/inspector/overlay/clickPolicy.d.ts +3 -14
  310. package/dist/inspector/overlay/clickPolicy.js +3 -14
  311. package/dist/inspector/overlay/dropGuide.d.ts +0 -3
  312. package/dist/inspector/overlay/dropGuide.js +0 -3
  313. package/dist/inspector/overlay/frameThrottle.d.ts +0 -1
  314. package/dist/inspector/overlay/frameThrottle.js +0 -1
  315. package/dist/inspector/overlay/interactionStyles.d.ts +1 -1
  316. package/dist/inspector/overlay/interactionStyles.js +19 -8
  317. package/dist/inspector/overlay/measurementGeometry.js +4 -12
  318. package/dist/inspector/overlay/selectedGeometry.d.ts +1 -6
  319. package/dist/inspector/overlay/selectedGeometry.js +1 -8
  320. package/dist/inspector/overlay/spacingGestures.d.ts +14 -21
  321. package/dist/inspector/overlay/spacingGestures.js +151 -31
  322. package/dist/inspector/overlay/structuralGestures.d.ts +2 -9
  323. package/dist/inspector/overlay/structuralGestures.js +1 -4
  324. package/dist/inspector/pageInspector.d.ts +33 -0
  325. package/dist/inspector/pageInspector.js +335 -0
  326. package/dist/inspector/projection/cssEscapes.d.ts +0 -1
  327. package/dist/inspector/projection/cssEscapes.js +2 -4
  328. package/dist/inspector/projection/draftProjection.d.ts +6 -10
  329. package/dist/inspector/projection/draftProjection.js +8 -7
  330. package/dist/inspector/projection/managedStylesheet.d.ts +1 -7
  331. package/dist/inspector/projection/managedStylesheet.js +28 -26
  332. package/dist/inspector/projection/renderedInstance.d.ts +5 -28
  333. package/dist/inspector/projection/renderedInstance.js +13 -33
  334. package/dist/inspector/projection/structuralProjection.d.ts +7 -48
  335. package/dist/inspector/projection/structuralProjection.js +31 -96
  336. package/dist/inspector/projection/textProjection.d.ts +7 -13
  337. package/dist/inspector/projection/textProjection.js +35 -80
  338. package/dist/inspector/prompt/PromptSettingsDialog.d.ts +0 -1
  339. package/dist/inspector/prompt/PromptSettingsDialog.js +0 -1
  340. package/dist/inspector/prompt/clipboardHandoff.d.ts +1 -0
  341. package/dist/inspector/prompt/clipboardHandoff.js +34 -16
  342. package/dist/inspector/prompt/generatePrompt.d.ts +2 -2
  343. package/dist/inspector/prompt/generatePrompt.js +247 -166
  344. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  345. package/dist/inspector/prompt/promptDocument.js +8 -0
  346. package/dist/inspector/prompt/promptSettings.d.ts +0 -3
  347. package/dist/inspector/prompt/promptSettings.js +7 -8
  348. package/dist/inspector/runtime/devFlag.d.ts +2 -25
  349. package/dist/inspector/runtime/devFlag.js +4 -31
  350. package/dist/inspector/runtime/documentStylesheetOrder.d.ts +0 -2
  351. package/dist/inspector/runtime/editorShell.d.ts +0 -1
  352. package/dist/inspector/runtime/editorShell.js +0 -1
  353. package/dist/inspector/runtime/inspectorStorage.d.ts +11 -0
  354. package/dist/inspector/runtime/inspectorStorage.js +37 -0
  355. package/dist/inspector/runtime/ownedStylesheets.d.ts +14 -0
  356. package/dist/inspector/runtime/ownedStylesheets.js +66 -0
  357. package/dist/inspector/runtime/runtimeConfig.d.ts +14 -84
  358. package/dist/inspector/runtime/runtimeConfig.js +18 -50
  359. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +19 -0
  360. package/dist/inspector/runtime/runtimeIdentityClaims.js +178 -0
  361. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +6 -23
  362. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +103 -52
  363. package/dist/inspector/runtime/useRuntimeConfig.d.ts +1 -8
  364. package/dist/inspector/runtime/useRuntimeConfig.js +1 -8
  365. package/dist/inspector/selection/editScope.d.ts +2 -7
  366. package/dist/inspector/selection/editScope.js +15 -14
  367. package/dist/inspector/selection/editTarget.d.ts +1 -5
  368. package/dist/inspector/selection/hierarchy.d.ts +11 -11
  369. package/dist/inspector/selection/hierarchy.js +42 -24
  370. package/dist/inspector/selection/selectionStore.d.ts +0 -3
  371. package/dist/inspector/selection/selectionStore.js +5 -16
  372. package/dist/inspector/selection/sourceSite.d.ts +1 -5
  373. package/dist/inspector/selection/sourceSite.js +2 -8
  374. package/dist/inspector/selection/styleSelection.d.ts +1 -5
  375. package/dist/inspector/selection/styleSelection.js +1 -5
  376. package/dist/inspector/session/lifecycle.d.ts +1 -9
  377. package/dist/inspector/session/lifecycle.js +0 -1
  378. package/dist/inspector/session/sessionContext.d.ts +0 -4
  379. package/dist/inspector/session/sessionContext.js +0 -4
  380. package/dist/inspector/session/sessionFactory.d.ts +0 -9
  381. package/dist/inspector/session/sessionFactory.js +0 -6
  382. package/dist/inspector/settings/SettingsDialog.d.ts +0 -1
  383. package/dist/inspector/settings/SettingsDialog.js +5 -3
  384. package/dist/inspector/shell/AgentStatusButton.d.ts +3 -2
  385. package/dist/inspector/shell/AgentStatusButton.js +7 -7
  386. package/dist/inspector/shell/AppShell.js +6 -2
  387. package/dist/inspector/shell/ChangesLog.js +29 -12
  388. package/dist/inspector/shell/CopyPromptButton.d.ts +2 -1
  389. package/dist/inspector/shell/CopyPromptButton.js +62 -55
  390. package/dist/inspector/shell/EmptyState.js +3 -3
  391. package/dist/inspector/shell/InspectorEditors.d.ts +16 -0
  392. package/dist/inspector/shell/InspectorEditors.js +14 -0
  393. package/dist/inspector/shell/InspectorPanel.d.ts +12 -0
  394. package/dist/inspector/shell/InspectorPanel.js +8 -0
  395. package/dist/inspector/shell/InspectorSelection.d.ts +24 -0
  396. package/dist/inspector/shell/InspectorSelection.js +20 -0
  397. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  398. package/dist/inspector/shell/InspectorShell.js +44 -58
  399. package/dist/inspector/shell/NudgeLogoIcon.d.ts +5 -0
  400. package/dist/inspector/shell/NudgeLogoIcon.js +5 -0
  401. package/dist/inspector/shell/PeekOriginalButton.d.ts +0 -5
  402. package/dist/inspector/shell/PeekOriginalButton.js +3 -8
  403. package/dist/inspector/shell/PeekOriginalIcon.d.ts +0 -5
  404. package/dist/inspector/shell/PeekOriginalIcon.js +0 -5
  405. package/dist/inspector/shell/PromptActionButton.d.ts +21 -0
  406. package/dist/inspector/shell/PromptActionButton.js +14 -0
  407. package/dist/inspector/shell/elementName.d.ts +5 -0
  408. package/dist/inspector/shell/elementName.js +29 -0
  409. package/dist/inspector/shell/interactionStatePreview.d.ts +6 -0
  410. package/dist/inspector/shell/interactionStatePreview.js +107 -0
  411. package/dist/inspector/shell/originalPreview.d.ts +1 -5
  412. package/dist/inspector/shell/originalPreview.js +5 -37
  413. package/dist/inspector/shell/stateValue.d.ts +1 -2
  414. package/dist/inspector/shell/stateValue.js +4 -8
  415. package/dist/inspector/shell/styleState.d.ts +1 -2
  416. package/dist/inspector/shell/styleState.js +1 -2
  417. package/dist/inspector/sketch/SketchEditor.js +5 -5
  418. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  419. package/dist/inspector/sketch/SketchFrameOverlay.js +13 -16
  420. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  421. package/dist/inspector/sketch/SketchOverlay.js +138 -263
  422. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -2
  423. package/dist/inspector/sketch/SketchPromptPanel.js +8 -2
  424. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  425. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  426. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  427. package/dist/inspector/sketch/SketchWorkspace.js +70 -37
  428. package/dist/inspector/sketch/capture.d.ts +12 -3
  429. package/dist/inspector/sketch/capture.js +31 -14
  430. package/dist/inspector/sketch/copySketch.d.ts +4 -0
  431. package/dist/inspector/sketch/copySketch.js +43 -0
  432. package/dist/inspector/sketch/drawingTools.d.ts +15 -0
  433. package/dist/inspector/sketch/drawingTools.js +46 -0
  434. package/dist/inspector/sketch/frameHeading.d.ts +3 -0
  435. package/dist/inspector/sketch/frameHeading.js +23 -0
  436. package/dist/inspector/sketch/freehand.d.ts +0 -1
  437. package/dist/inspector/sketch/freehand.js +3 -4
  438. package/dist/inspector/sketch/geometry.d.ts +2 -1
  439. package/dist/inspector/sketch/geometry.js +15 -1
  440. package/dist/inspector/sketch/handoff.js +0 -1
  441. package/dist/inspector/sketch/history.d.ts +26 -0
  442. package/dist/inspector/sketch/history.js +55 -0
  443. package/dist/inspector/sketch/interaction.d.ts +3 -5
  444. package/dist/inspector/sketch/interaction.js +8 -11
  445. package/dist/inspector/sketch/model.d.ts +33 -6
  446. package/dist/inspector/sketch/model.js +101 -63
  447. package/dist/inspector/sketch/persistence.d.ts +14 -1
  448. package/dist/inspector/sketch/persistence.js +64 -8
  449. package/dist/inspector/sketch/raster.d.ts +3 -2
  450. package/dist/inspector/sketch/raster.js +40 -20
  451. package/dist/inspector/sketch/store.d.ts +1 -1
  452. package/dist/inspector/sketch/store.js +3 -4
  453. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  454. package/dist/inspector/sketch/videoFrames.js +80 -0
  455. package/dist/inspector/spacing/projection.d.ts +0 -8
  456. package/dist/inspector/spacing/projection.js +38 -20
  457. package/dist/inspector/styleEditors/BackgroundEditor.js +3 -2
  458. package/dist/inspector/styleEditors/BorderEditor.js +30 -135
  459. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  460. package/dist/inspector/styleEditors/ChildPlacement.d.ts +12 -0
  461. package/dist/inspector/styleEditors/ChildPlacement.js +9 -0
  462. package/dist/inspector/styleEditors/FlexControls.d.ts +35 -0
  463. package/dist/inspector/styleEditors/FlexControls.js +158 -0
  464. package/dist/inspector/styleEditors/GapField.d.ts +5 -2
  465. package/dist/inspector/styleEditors/GapField.js +3 -4
  466. package/dist/inspector/styleEditors/GridChildSection.d.ts +0 -5
  467. package/dist/inspector/styleEditors/GridChildSection.js +0 -5
  468. package/dist/inspector/styleEditors/GridPicker.d.ts +1 -1
  469. package/dist/inspector/styleEditors/GridPicker.js +2 -4
  470. package/dist/inspector/styleEditors/GridSection.d.ts +10 -8
  471. package/dist/inspector/styleEditors/GridSection.js +22 -9
  472. package/dist/inspector/styleEditors/GridValueField.d.ts +1 -5
  473. package/dist/inspector/styleEditors/GridValueField.js +2 -8
  474. package/dist/inspector/styleEditors/ImageBackgroundEditor.d.ts +0 -1
  475. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -2
  476. package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +0 -1
  477. package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +0 -1
  478. package/dist/inspector/styleEditors/LayoutComboField.js +0 -5
  479. package/dist/inspector/styleEditors/LayoutModeRow.d.ts +14 -0
  480. package/dist/inspector/styleEditors/LayoutModeRow.js +60 -0
  481. package/dist/inspector/styleEditors/LayoutSection.d.ts +2 -2
  482. package/dist/inspector/styleEditors/LayoutSection.js +30 -356
  483. package/dist/inspector/styleEditors/OpacityEditor.js +7 -5
  484. package/dist/inspector/styleEditors/PositionControls.d.ts +18 -0
  485. package/dist/inspector/styleEditors/PositionControls.js +16 -0
  486. package/dist/inspector/styleEditors/SizeSection.d.ts +18 -0
  487. package/dist/inspector/styleEditors/SizeSection.js +71 -0
  488. package/dist/inspector/styleEditors/{SpacingBox.d.ts → SpacingField.d.ts} +3 -10
  489. package/dist/inspector/styleEditors/{SpacingBox.js → SpacingField.js} +15 -29
  490. package/dist/inspector/styleEditors/Typography.js +2 -4
  491. package/dist/inspector/styleEditors/borderModel.d.ts +36 -0
  492. package/dist/inspector/styleEditors/borderModel.js +105 -0
  493. package/dist/inspector/styleEditors/completeCssValue.d.ts +1 -5
  494. package/dist/inspector/styleEditors/completeCssValue.js +3 -13
  495. package/dist/inspector/styleEditors/fieldValue.d.ts +20 -0
  496. package/dist/inspector/styleEditors/fieldValue.js +26 -0
  497. package/dist/inspector/styleEditors/gradientValue.d.ts +1 -1
  498. package/dist/inspector/styleEditors/gradientValue.js +3 -2
  499. package/dist/inspector/styleEditors/gridChildModel.d.ts +7 -47
  500. package/dist/inspector/styleEditors/gridChildModel.js +6 -37
  501. package/dist/inspector/styleEditors/hiddenSizeOverrides.d.ts +5 -0
  502. package/dist/inspector/styleEditors/hiddenSizeOverrides.js +42 -0
  503. package/dist/inspector/styleEditors/inlineAuthored.d.ts +1 -8
  504. package/dist/inspector/styleEditors/inlineAuthored.js +3 -17
  505. package/dist/inspector/styleEditors/layoutMode.d.ts +15 -0
  506. package/dist/inspector/styleEditors/layoutMode.js +33 -0
  507. package/dist/inspector/styleEditors/layoutPreviewState.d.ts +0 -1
  508. package/dist/inspector/styleEditors/layoutPreviewState.js +0 -1
  509. package/dist/inspector/styleEditors/layoutValue.d.ts +2 -8
  510. package/dist/inspector/styleEditors/layoutValue.js +6 -15
  511. package/dist/inspector/styleEditors/nudgeValue.d.ts +1 -13
  512. package/dist/inspector/styleEditors/nudgeValue.js +1 -13
  513. package/dist/inspector/styleEditors/rowLookup.d.ts +1 -5
  514. package/dist/inspector/styleEditors/rowLookup.js +1 -5
  515. package/dist/inspector/styleEditors/stringRecord.d.ts +1 -2
  516. package/dist/inspector/styleEditors/stylePresence.d.ts +0 -2
  517. package/dist/inspector/styleEditors/stylePresence.js +1 -4
  518. package/dist/inspector/styleEditors/textRelevance.d.ts +1 -1
  519. package/dist/inspector/styleEditors/textRelevance.js +1 -1
  520. package/dist/inspector/styleEditors/useFieldVisibility.js +1 -2
  521. package/dist/inspector/styleEditors/useLayoutContext.d.ts +13 -0
  522. package/dist/inspector/styleEditors/useLayoutContext.js +53 -0
  523. package/dist/inspector/styleEditors/valuePolicy.d.ts +1 -5
  524. package/dist/inspector/styleEditors/valuePolicy.js +0 -1
  525. package/dist/inspector/testing.d.ts +1 -4
  526. package/dist/inspector/testing.js +1 -4
  527. package/dist/inspector/tokens/TokenChip.d.ts +1 -4
  528. package/dist/inspector/tokens/TokenChip.js +1 -4
  529. package/dist/inspector/tokens/TokenField.d.ts +4 -3
  530. package/dist/inspector/tokens/TokenField.js +53 -32
  531. package/dist/inspector/tokens/TokensPanel.js +2 -1
  532. package/dist/inspector/tokens/catalog.d.ts +2 -10
  533. package/dist/inspector/tokens/catalog.js +5 -12
  534. package/dist/inspector/tokens/dragPointerLock.d.ts +0 -1
  535. package/dist/inspector/tokens/dragPointerLock.js +2 -3
  536. package/dist/inspector/tokens/editActions.d.ts +4 -4
  537. package/dist/inspector/tokens/editActions.js +11 -7
  538. package/dist/inspector/tokens/resolution/cascade.d.ts +1 -5
  539. package/dist/inspector/tokens/resolution/cascade.js +1 -5
  540. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +11 -0
  541. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +82 -0
  542. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +4 -19
  543. package/dist/inspector/tokens/resolution/cssomCollector.js +186 -122
  544. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +2 -0
  545. package/dist/inspector/tokens/resolution/nestedSelectors.js +63 -0
  546. package/dist/inspector/tokens/resolution/ruleMatching.d.ts +4 -14
  547. package/dist/inspector/tokens/resolution/ruleMatching.js +136 -63
  548. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +3 -14
  549. package/dist/inspector/tokens/resolution/selectorSemantics.js +12 -27
  550. package/dist/inspector/tokens/resolution.d.ts +11 -27
  551. package/dist/inspector/tokens/resolution.js +105 -181
  552. package/dist/inspector/tokens/tokenAvailability.d.ts +2 -14
  553. package/dist/inspector/tokens/tokenAvailability.js +6 -38
  554. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  555. package/dist/inspector/tokens/tokenEdits.js +1 -1
  556. package/dist/inspector/tokens/valueSemanticsAdapter.d.ts +0 -1
  557. package/dist/inspector/tokens/valueSemanticsAdapter.js +18 -2
  558. package/dist/inspector/ui/AtRuleContext.d.ts +5 -5
  559. package/dist/inspector/ui/AtRuleContext.js +8 -6
  560. package/dist/inspector/ui/ControlSurface.d.ts +0 -4
  561. package/dist/inspector/ui/Disclosure.d.ts +0 -5
  562. package/dist/inspector/ui/Disclosure.js +0 -4
  563. package/dist/inspector/ui/InlineStyleWarning.d.ts +0 -1
  564. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  565. package/dist/inspector/ui/InspectorPopover.d.ts +1 -5
  566. package/dist/inspector/ui/InspectorPopover.js +1 -5
  567. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  568. package/dist/inspector/ui/InspectorStyle.js +26 -0
  569. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  570. package/dist/inspector/ui/PopoverListbox.js +3 -3
  571. package/dist/inspector/ui/SegmentedControl.d.ts +4 -4
  572. package/dist/inspector/ui/SegmentedControl.js +6 -4
  573. package/dist/inspector/ui/SideValuesField.d.ts +1 -6
  574. package/dist/inspector/ui/SideValuesField.js +2 -8
  575. package/dist/inspector/ui/Toast.d.ts +10 -0
  576. package/dist/inspector/ui/Toast.js +26 -0
  577. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  578. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  579. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  580. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  581. package/dist/inspector/ui/atRuleSegments.d.ts +13 -0
  582. package/dist/inspector/ui/atRuleSegments.js +34 -0
  583. package/dist/inspector/ui/classNames.d.ts +0 -1
  584. package/dist/inspector/ui/classNames.js +0 -1
  585. package/dist/inspector/ui/customCursors.d.ts +11 -0
  586. package/dist/inspector/ui/customCursors.js +29 -7
  587. package/dist/inspector/ui/styles.js +25 -25
  588. package/dist/inspector/workspace/commands.js +1 -2
  589. package/dist/inspector/workspace/controller.js +20 -2
  590. package/dist/inspector/workspace/handoff.d.ts +1 -5
  591. package/dist/inspector/workspace/handoff.js +4 -7
  592. package/dist/inspector/workspace/sentItems.d.ts +3 -6
  593. package/dist/inspector/workspace/sentItems.js +6 -24
  594. package/dist/inspector/workspace/timeline.d.ts +28 -11
  595. package/dist/inspector/workspace/timeline.js +117 -96
  596. package/dist/internal/agent-protocol.d.ts +53 -38
  597. package/dist/internal/agent-protocol.js +151 -42
  598. package/dist/nudge-ui.mjs +155 -92
  599. package/dist/project/artifacts.js +24 -21
  600. package/dist/project/files.d.ts +0 -1
  601. package/dist/project/files.js +2 -9
  602. package/dist/project/identity.d.ts +1 -5
  603. package/dist/project/identity.js +1 -5
  604. package/dist/project/mcpPackage.d.ts +3 -0
  605. package/dist/project/mcpPackage.js +55 -0
  606. package/dist/project/pathPolicy.d.ts +1 -6
  607. package/dist/project/pathPolicy.js +1 -6
  608. package/dist/project/tokens.d.ts +2 -12
  609. package/dist/project/tokens.js +4 -15
  610. package/dist/transport/editor.d.ts +1 -12
  611. package/dist/transport/editor.js +2 -13
  612. package/dist/transport/index.d.ts +0 -5
  613. package/dist/transport/index.js +0 -5
  614. package/dist/transport/routes.d.ts +0 -5
  615. package/dist/transport/routes.js +0 -5
  616. package/package.json +16 -5
  617. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  618. package/dist/inspector/canvas/measurementProjection.js +0 -16
  619. package/dist/inspector/changes/changesLog.d.ts +0 -49
  620. package/dist/inspector/changes/changesLog.js +0 -255
  621. package/dist/inspector/changes/draftChanges.d.ts +0 -58
  622. package/dist/inspector/changes/draftChanges.js +0 -304
  623. package/dist/inspector/conformance/projection.d.ts +0 -2
  624. package/dist/inspector/conformance/projection.js +0 -3
  625. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  626. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  627. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  628. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  629. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  630. package/dist/inspector/overlay/elementSelector.js +0 -111
  631. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  632. package/dist/inspector/sketch/SketchChanges.js +0 -72
  633. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  634. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  635. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  636. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
  637. package/dist/inspector/styleEditors/InsetSection.d.ts +0 -15
  638. package/dist/inspector/styleEditors/InsetSection.js +0 -15
  639. package/dist/inspector/styleEditors/PositionInsets.d.ts +0 -15
  640. package/dist/inspector/styleEditors/PositionInsets.js +0 -12
  641. package/dist/inspector/tokens/TokenDropdown.d.ts +0 -13
  642. package/dist/inspector/tokens/TokenDropdown.js +0 -59
@@ -3,6 +3,7 @@ import { IconMessageCircle, IconMessageCircleFilled, IconPointer2, IconSketching
3
3
  import { IconButton } from "../ui/IconButton.js";
4
4
  import { Tooltip } from "../ui/Tooltip.js";
5
5
  import { DesignPointerFilledIcon, SelectPlayFilledIcon, SelectPlayOutlineIcon, SketchThickIcon, } from "./CanvasToolIcons.js";
6
+ import { SketchToolOptions } from "./SketchToolOptions.js";
6
7
  export const CANVAS_ZOOM_LEVELS = [0.25, 0.5, 0.9, 1];
7
8
  export function closestCanvasZoomLevel(zoom) {
8
9
  let closest = CANVAS_ZOOM_LEVELS[0];
@@ -24,5 +25,5 @@ function ToolButton({ tool, activeTool, disabled, label, shortcut, icon, activeI
24
25
  return (_jsx(Tooltip, { content: label, shortcut: shortcut, stableTrigger: true, children: _jsx(IconButton, { variant: "quiet", size: "large", className: "canvas-toolbar__tool", label: label, "aria-pressed": active, "data-test": `canvas-tool-${tool}`, "data-active": active ? "true" : "false", disabled: disabled, onClick: () => onToolChange(tool), children: active ? activeIcon : icon }) }));
25
26
  }
26
27
  export function CanvasToolbar({ tool, sketchEnabled, onToolChange, }) {
27
- return (_jsxs("div", { className: "canvas-toolbar", "data-test": "canvas-toolbar", role: "toolbar", "aria-label": "Canvas tools", children: [_jsxs("div", { className: "canvas-toolbar__tools", role: "group", "aria-label": "Interaction tools", children: [_jsx(ToolButton, { tool: "design", activeTool: tool, label: "Select", shortcut: "V", icon: _jsx(IconPointer2, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(DesignPointerFilledIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }), _jsx(ToolButton, { tool: "comment", activeTool: tool, label: "Comment", shortcut: "C", icon: _jsx(IconMessageCircle, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(IconMessageCircleFilled, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }), _jsx(ToolButton, { tool: "sketch", activeTool: tool, label: "Pencil", shortcut: "P", disabled: !sketchEnabled, icon: _jsx(IconSketching, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(SketchThickIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange })] }), _jsx("div", { className: "canvas-toolbar__divider", "aria-hidden": "true" }), _jsx("div", { className: "canvas-toolbar__tools", role: "group", "aria-label": "Preview tools", children: _jsx(ToolButton, { tool: "select", activeTool: tool, label: "Use app normally", shortcut: "Hold A", icon: _jsx(SelectPlayOutlineIcon, { size: ICON_SIZE, "aria-hidden": "true" }), activeIcon: _jsx(SelectPlayFilledIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }) })] }));
28
+ return (_jsxs("div", { className: "canvas-toolbar", "data-test": "canvas-toolbar", role: "toolbar", "aria-label": "Canvas tools", children: [_jsxs("div", { className: "canvas-toolbar__tools", role: "group", "aria-label": "Interaction tools", children: [_jsx(ToolButton, { tool: "design", activeTool: tool, label: "Select", shortcut: "V", icon: _jsx(IconPointer2, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(DesignPointerFilledIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }), _jsx(ToolButton, { tool: "comment", activeTool: tool, label: "Comment", shortcut: "C", icon: _jsx(IconMessageCircle, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(IconMessageCircleFilled, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }), _jsx(ToolButton, { tool: "sketch", activeTool: tool, label: "Pencil", shortcut: "P", disabled: !sketchEnabled, icon: _jsx(IconSketching, { size: ICON_SIZE, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), activeIcon: _jsx(SketchThickIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }), _jsx(SketchToolOptions, { open: tool === "sketch" && sketchEnabled })] }), _jsx("div", { className: "canvas-toolbar__divider", "aria-hidden": "true" }), _jsx("div", { className: "canvas-toolbar__tools", role: "group", "aria-label": "Preview tools", children: _jsx(ToolButton, { tool: "select", activeTool: tool, label: "Use app normally", shortcut: "Hold A", icon: _jsx(SelectPlayOutlineIcon, { size: ICON_SIZE, "aria-hidden": "true" }), activeIcon: _jsx(SelectPlayFilledIcon, { size: ICON_SIZE, "aria-hidden": "true" }), onToolChange: onToolChange }) })] }));
28
29
  }
@@ -2,34 +2,35 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { getCanonicalFrameProjection } from "./projection.js";
3
3
  import { getDraftForCard } from "../drafts/store.js";
4
4
  import { iterationId, contentSourceUrl, getLinkedFrameIds } from "./frameContent.js";
5
- import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
5
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
6
6
  import { IconCornerLeftUp } from "@tabler/icons-react";
7
7
  import { useCanvasCards, activateIframeWorkspace, getSelectedCardId, getFocusedCardId, getCanvasCards, batchCanvasChanges, fitAllCards, focusCanvasCards, focusCard, useSelectedCardId, useFocusedCardId, resizeCard, setCardPosition, updateCardTitle, addCanvasCard, selectCard, deselectCard, CARD_GAP, updateCardUrl, } from "./canvasStore.js";
8
8
  import { setBoardCamera, getBoardCamera, setCanvasPresentation, hasFitAllRan, useBoardCamera, useCanvasPresentation, useCanvasPresentationTransitioning, useCanvasLayoutTransitioning, useTemporaryAppInteraction, setTemporaryAppInteraction, } from "./viewStore.js";
9
9
  import { CanvasCard } from "./CanvasCard.js";
10
+ import { PageCard } from "./PageCard.js";
11
+ import { isPageSurface } from "./pageSurface.js";
12
+ import { canvasFrameHost } from "./canvasFrame.js";
10
13
  import { useCanvasLayoutAnimation } from "./useCanvasLayoutAnimation.js";
11
14
  import { Button } from "../ui/Button.js";
12
15
  import { useCanvasMode } from "./viewStore.js";
13
- import { subscribeChanges } from "../changes/changesLog.js";
16
+ import { getActiveDraftChanges, getChangesList, subscribeActiveDraftChanges } from "../drafts/store.js";
14
17
  import { subscribeOriginalPreview, isOriginalPreviewActive } from "../shell/originalPreview.js";
15
18
  import { recordCanvasStructuralProjectionReports } from "../projection/structuralProjection.js";
16
19
  import { recordCanvasRenderedInstanceProjectionReports } from "../projection/renderedInstance.js";
17
20
  import { recordCanvasTextProjectionReports } from "../projection/textProjection.js";
18
- import { getChangesList, isPreviewableChange } from "../changes/changesLog.js";
19
- import { changeKey } from "../changes/model.js";
20
- import { getActiveDraftChanges } from "../changes/draftChanges.js";
21
- import { beginPreviewAttempt, publishPreviewDiagnostic } from "../changes/previewDiagnostics.js";
22
- import { verifyManagedStyleProjection } from "../changes/managedStyleProjection.js";
23
- import { getCanvasPreviewDocument, getRegisteredFrames, isCanvasCanonicalProjectionRevisionCurrent, PROJECT_ID, projectToAllReadyCards, recordCanvasProjectionApplied, WORKSPACE_ID, } from "./projection.js";
21
+ import { beginPreviewAttempt } from "../changes/previewDiagnostics.js";
22
+ import { verifyPreviewChanges } from "../changes/previewVerification.js";
23
+ import { getCanvasPreviewDocument, getRegisteredFrames, isCanvasCanonicalProjectionRevisionCurrent, projectToAllReadyCards, recordCanvasProjectionApplied, getFrameRegistryVersion, subscribeFrameRegistry, } from "./projection.js";
24
+ import { connectFrame, toViewportPoint } from "./frameConnection.js";
24
25
  import { normalizeUrl, normalizedUrlKey } from "./normalizeUrl.js";
25
26
  import { createNudgeUiEditorUrl } from "../../transport/editor.js";
26
27
  import { disposeInlineTextEdit } from "../inline-text/inlineTextEditor.js";
27
- import { PROTOCOL_VERSION, isProjectionAppliedMessage, isKeyboardShortcutMessage, isRenderedInstanceProjectionReportMessage, isTextProjectionReportMessage, isStructuralProjectionReportMessage, } from "./frameProtocol.js";
28
+ import { isProjectionAppliedMessage, isKeyboardShortcutMessage, isRenderedInstanceProjectionReportMessage, isTextProjectionReportMessage, isStructuralProjectionReportMessage, } from "./frameProtocol.js";
28
29
  import { wheelPanDelta } from "./wheelPan.js";
29
- import { iframePointToClientPoint, zoomCameraAtPointer } from "./canvasGestures.js";
30
- const canvasWorkspaceStyles = ".canvas-workspace {\n position: fixed;\n inset: 0;\n display: flex;\n flex-direction: column;\n background: var(--surface-panel);\n pointer-events: auto;\n}\n\n.canvas-workspace__board {\n flex: 1;\n overflow: hidden;\n position: relative;\n background: var(--surface-panel);\n}\n\n.canvas-workspace__focus-action {\n position: absolute;\n top: max(12px, env(safe-area-inset-top));\n left: max(12px, env(safe-area-inset-left));\n z-index: calc(var(--z-index) - 1);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-4);\n border-radius: var(--radius-12);\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n pointer-events: auto;\n}\n\n.canvas-workspace__board.is-grabbable {\n cursor: grab;\n}\n\n.canvas-workspace__board.is-grabbing {\n cursor: grabbing;\n}\n\n/* Canvas gestures take precedence over every card interaction while Space is\n held. This also closes the short postMessage gap before an iframe receives\n its mirrored modifier state. */\n.canvas-workspace__board.is-grabbable .canvas-card,\n.canvas-workspace__board.is-grabbing .canvas-card {\n pointer-events: none;\n}\n\n.canvas-workspace__board-content {\n position: absolute;\n width: 100%;\n height: 100%;\n /*\n * Leave `will-change` unset so the browser can re-rasterize this subtree at\n * the current camera scale. A permanent `will-change: transform` promotes\n * it to a fixed bitmap, which makes iframe content look soft when zoomed.\n */\n}\n\n.canvas-workspace__board.is-grabbing .canvas-workspace__board-content {\n /* Panning benefits from a cached composited layer; zoom restores the crisp\n * default path as soon as the gesture ends. */\n will-change: transform;\n}\n\n.canvas-workspace[data-presentation=\"focus\"] .canvas-workspace__board-content {\n inset: 0;\n transform: none !important;\n}\n\n.canvas-workspace.is-presentation-transitioning .canvas-card:not(.is-presentation-card) {\n visibility: hidden !important;\n pointer-events: none !important;\n}\n\n.canvas-workspace__target-error {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n color: #6b7280;\n font: 500 14px/1.4 system-ui, sans-serif;\n}\n\n/* Moving iframes must not acquire hover state beneath a stationary pointer. */\n.canvas-workspace.is-presentation-transitioning .canvas-card__iframe,\n.canvas-workspace__board.is-layout-transitioning .canvas-card__iframe {\n pointer-events: none;\n}\n";
30
+ import { zoomCameraAtPointer } from "./canvasGestures.js";
31
+ const canvasWorkspaceStyles = ".canvas-workspace {\n position: fixed;\n inset: 0;\n display: flex;\n flex-direction: column;\n background: var(--surface-panel);\n pointer-events: auto;\n}\n\n.canvas-workspace__board {\n flex: 1;\n overflow: hidden;\n position: relative;\n background: var(--surface-panel);\n}\n\n.canvas-workspace__focus-action {\n position: absolute;\n top: max(12px, env(safe-area-inset-top));\n left: max(12px, env(safe-area-inset-left));\n z-index: calc(var(--z-index) - 1);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-4);\n border-radius: var(--radius-12);\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n pointer-events: auto;\n}\n\n.canvas-workspace__board.is-grabbable {\n cursor: grab;\n}\n\n.canvas-workspace__board.is-grabbing {\n cursor: grabbing;\n}\n\n/* Canvas gestures take precedence over every card interaction while Space is\n held. This also closes the short postMessage gap before an iframe receives\n its mirrored modifier state. */\n.canvas-workspace__board.is-grabbable .canvas-card,\n.canvas-workspace__board.is-grabbing .canvas-card {\n pointer-events: none;\n}\n\n.canvas-workspace__board-content {\n position: absolute;\n width: 100%;\n height: 100%;\n /*\n * Leave `will-change` unset so the browser can re-rasterize this subtree at\n * the current camera scale. A permanent `will-change: transform` promotes\n * it to a fixed bitmap, which makes iframe content look soft when zoomed.\n */\n}\n\n.canvas-workspace__board.is-grabbing .canvas-workspace__board-content {\n /* Panning benefits from a cached composited layer; zoom restores the crisp\n * default path as soon as the gesture ends. */\n will-change: transform;\n}\n\n.canvas-workspace[data-presentation=\"focus\"] .canvas-workspace__board-content {\n inset: 0;\n transform: none !important;\n}\n\n.canvas-workspace.is-presentation-transitioning .canvas-card:not(.is-presentation-card) {\n visibility: hidden !important;\n pointer-events: none !important;\n}\n\n.canvas-workspace__target-error {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n color: #6b7280;\n font: 500 14px/1.4 system-ui, sans-serif;\n}\n\n/* Moving iframes must not acquire hover state beneath a stationary pointer. */\n.canvas-workspace.is-presentation-transitioning .canvas-card__iframe,\n.canvas-workspace__board.is-layout-transitioning .canvas-card__iframe {\n pointer-events: none;\n}\n\n/* The page surface edits the live page under the workspace, so only the\n toolbar takes pointer input. */\n.canvas-workspace[data-surface=\"page\"],\n.canvas-workspace[data-surface=\"page\"] .canvas-workspace__board {\n background: transparent;\n pointer-events: none;\n}\n\n.canvas-workspace[data-surface=\"page\"] .canvas-toolbar {\n pointer-events: auto;\n}\n";
31
32
  const canvasCardStyles = ".canvas-card {\n position: relative;\n}\n\n/* Extend the card's hover region to the toolbar above the iframe. */\n.canvas-card::before {\n content: \"\";\n position: absolute;\n right: 0;\n bottom: 100%;\n left: 0;\n height: calc((var(--control-height-large) + var(--space-16)) * var(--canvas-toolbar-scale, 1));\n pointer-events: auto;\n}\n\n.canvas-card__frame {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--surface-panel);\n border-radius: 0;\n overflow: hidden;\n}\n\n.canvas-card.is-selected .canvas-card__frame {\n outline: 2px solid var(--frame-accent, var(--accent));\n outline-offset: -2px;\n}\n\n.canvas-card.is-focus-presentation .canvas-card__frame {\n outline: none;\n}\n\n.canvas-card.is-focused.is-selected:not(.is-linked) .canvas-card__frame {\n animation: canvas-card-focus 900ms ease-out;\n}\n\n@keyframes canvas-card-focus {\n 0%, 35% { outline: 3px solid var(--frame-accent, var(--accent)); outline-offset: -3px; }\n 100% { outline: 0 solid transparent; outline-offset: -2px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .canvas-card.is-focused .canvas-card__frame {\n animation: none;\n }\n}\n\n.canvas-card__header {\n display: flex;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + var(--space-8));\n justify-content: flex-end;\n z-index: 3;\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n}\n\n.canvas-card__drag-surface {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--space-8);\n flex: 0 1 auto;\n margin-right: auto;\n min-width: 0;\n min-height: var(--control-height-large);\n padding: 0;\n cursor: grab;\n user-select: none;\n touch-action: none;\n}\n\n.canvas-card.is-dragging .canvas-card__drag-surface {\n cursor: grabbing;\n}\n\n.canvas-card__identity {\n display: flex;\n align-items: center;\n gap: var(--space-8);\n min-width: 0;\n}\n\n.canvas-card__dimensions {\n display: flex;\n align-items: center;\n gap: var(--space-8);\n position: relative;\n flex: 0 1 auto;\n min-width: 0;\n max-width: 260px;\n color: var(--text-secondary);\n font-size: var(--font-size-base);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n}\n\n.canvas-card__title {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.canvas-card__live-badge,\n.canvas-card__iteration-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 20px;\n height: 20px;\n background: var(--accent-surface);\n color: var(--accent);\n border-radius: var(--radius-4);\n pointer-events: auto;\n}\n\n.canvas-card__floating-toolbar {\n position: absolute;\n left: 50%;\n flex-shrink: 0;\n width: max-content;\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n transform: translate(-50%, calc(-24px + var(--space-4)));\n transition: opacity 140ms ease-out, transform 140ms ease-out, visibility 140ms;\n}\n\n.canvas-card:hover .canvas-card__floating-toolbar,\n.canvas-card:focus-within .canvas-card__floating-toolbar,\n.canvas-card__floating-toolbar[data-busy=\"true\"] {\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n transform: translate(-50%, -24px);\n}\n\n.canvas-card__actions.canvas-toolbar {\n position: static;\n width: max-content;\n transform: none;\n white-space: nowrap;\n}\n\n.canvas-card__actions .canvas-toolbar__divider {\n margin-inline: 0;\n}\n\n@media (hover: none) {\n .canvas-card.is-selected .canvas-card__floating-toolbar {\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n transform: translate(-50%, -24px);\n }\n}\n\n.canvas-card.is-dragging .canvas-card__floating-toolbar,\n.canvas-workspace__board.is-grabbable .canvas-card__floating-toolbar,\n.canvas-workspace__board.is-grabbing .canvas-card__floating-toolbar,\n.canvas-workspace.is-presentation-transitioning .canvas-card__floating-toolbar,\n.canvas-workspace__board.is-layout-transitioning .canvas-card__floating-toolbar {\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n transition: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .canvas-card__floating-toolbar { transition: none; }\n}\n\n.canvas-card__iteration-error {\n position: absolute;\n right: 0;\n bottom: calc(100% + var(--space-8));\n color: var(--text-danger, #b42318);\n font-size: 12px;\n white-space: nowrap;\n}\n\n.canvas-card__iframe {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n}\n\n.canvas-card__sketch-overlay {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: block;\n pointer-events: none;\n}\n\n.canvas-card__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--text-muted, #777777);\n font-size: 12px;\n font-weight: 500;\n}\n\n.canvas-card__error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 100%;\n padding: 20px;\n text-align: center;\n}\n\n.canvas-card__error p {\n margin: 0;\n color: var(--text-muted, #777777);\n font-size: 12px;\n font-weight: 500;\n}\n\n.canvas-card__error-actions {\n display: flex;\n gap: 8px;\n}\n\n.canvas-card__resize-handle {\n position: absolute;\n z-index: 3;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n padding: 4px;\n color: var(--text-muted, #777777);\n opacity: 0;\n transition: opacity 150ms ease;\n touch-action: none;\n user-select: none;\n}\n\n.canvas-card__resize-handle--top,\n.canvas-card__resize-handle--bottom {\n right: 16px;\n left: 16px;\n height: 16px;\n cursor: ns-resize;\n}\n\n.canvas-card__resize-handle--top {\n top: 0;\n}\n\n.canvas-card__resize-handle--bottom {\n bottom: 0;\n}\n\n.canvas-card__resize-handle--left,\n.canvas-card__resize-handle--right {\n top: 16px;\n bottom: 16px;\n width: 16px;\n cursor: ew-resize;\n}\n\n.canvas-card__resize-handle--left {\n left: 0;\n}\n\n.canvas-card__resize-handle--right {\n right: 0;\n}\n\n.canvas-card__resize-handle--top-left,\n.canvas-card__resize-handle--top-right,\n.canvas-card__resize-handle--bottom-right,\n.canvas-card__resize-handle--bottom-left {\n z-index: 4;\n width: 24px;\n height: 24px;\n cursor: nwse-resize;\n}\n\n.canvas-card__resize-handle--top-left {\n top: 0;\n left: 0;\n}\n\n.canvas-card__resize-handle--top-right {\n top: 0;\n right: 0;\n cursor: nesw-resize;\n}\n\n.canvas-card__resize-handle--bottom-right {\n right: 0;\n bottom: 0;\n}\n\n.canvas-card__resize-handle--bottom-left {\n bottom: 0;\n left: 0;\n cursor: nesw-resize;\n}\n\n.canvas-card:hover .canvas-card__resize-handle,\n.canvas-card:focus-within .canvas-card__resize-handle {\n opacity: 1;\n}\n\n.canvas-card__resize-handle:hover {\n color: var(--accent);\n}\n\n.canvas-card__resize-handle:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n opacity: 1;\n}\n\n.canvas-card.is-linked {\n --frame-accent: #a855f7;\n}\n\n.canvas-card.is-linked:not(.is-focus-presentation) .canvas-card__frame {\n outline: 2px solid var(--frame-accent);\n outline-offset: -2px;\n}\n\n.canvas-card__iteration-badge {\n color: var(--text-secondary);\n background: var(--surface-raised-2x);\n}\n";
32
- const foundationStyles = ":host {\n all: initial;\n --surface-panel: #F5F5F4;\n --surface-control: var(--surface-well);\n --surface-control-hover: var(--surface-well-2x);\n --surface-raised: #FAFAFA;\n --surface-raised-2x: #fff ;\n --surface-raised-hover: #F5F5F4;\n --surface-well: hsla(0, 0%, 0%, 0.05);\n --surface-well-2x: hsla(0, 0%, 0%, 0.10);\n\n --border-subtle: hsla(0, 0%, 0%, 0.1);\n --border-medium: hsla(0, 0%, 0%, 0.2);\n --border-strong: #d8d8d8;\n\n --text-primary: #242424;\n --text-secondary: #6f6f6f;\n --text-muted: #777777;\n --text-muted-subtle: #a1a1a1;\n\n --accent: #0096ff;\n --accent-surface: rgba(0, 176, 255, 0.15);\n --warning: #d97706;\n --warning-text: #9a5b00;\n --warning-surface: #fff6e5;\n --danger: #df4b4b;\n --danger-text: #bd3636;\n --danger-surface: rgba(223, 75, 75, 0.2);\n --success: #2e7d52;\n\n --space-0: 0;\n --space-4: 4px;\n --space-8: 8px;\n --space-12: 12px;\n --space-16: 16px;\n --space-20: 20px;\n --space-24: 24px;\n --space-32: 32px;\n --space-40: 40px;\n --space-48: 48px;\n\n /* Radius */\n --radius-0: 0;\n --radius-4: 4px;\n --radius-8: 8px;\n --radius-12: 12px;\n --radius-16: 16px;\n --radius-20: 20px;\n --radius-24: 24px;\n --radius-pill: 999px;\n\n --radius-control: var(--radius-8);\n --shadow-outline: 0 0 0 1px rgba(0, 0, 0, 0.05);\n --shadow-popup: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 16px rgba(0, 0, 0, 0.10);\n --shadow-control: inset 0 -2px 0 rgba(0, 0, 0, 0.03), 0 0 0 0.5px rgba(0, 0, 0, 0.25);\n --z-index: 2147483647;\n\n --font-family: \"Inter Variable\", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --font-size-base: 12px;\n --font-size-small: 10px;\n --font-weight-base: 400;\n --font-weight-label: 600;\n\n /* Control semantic sizes */\n --control-height-small: 24px;\n --control-height-large: 32px;\n --control-height-xlarge: 40px;\n --label-column: 104px;\n\n --icon-size-small: 16px;\n --icon-size-large: 20px;\n --icon-stroke-width: 1.5px;\n\n position: fixed;\n inset: 0;\n z-index: var(--z-index);\n pointer-events: none;\n font-family: var(--font-family);\n background: transparent;\n box-sizing: border-box;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton,\ninput,\nselect {\n font-family: inherit;\n}\n";
33
+ const foundationStyles = ":host {\n all: initial;\n --surface-panel: #fff;\n --surface-control: var(--surface-well);\n --surface-control-hover: var(--surface-well-2x);\n --surface-raised: #FAFAFA;\n --surface-raised-2x: #fff ;\n --surface-raised-hover: #F5F5F4;\n --surface-well: hsla(0, 0%, 0%, 0.05);\n --surface-well-2x: hsla(0, 0%, 0%, 0.10);\n /* Inverse surfaces mirror the landing palette for dark, high-emphasis controls. */\n --surface-inverse: #1f201e;\n --surface-inverse-hover: #343532;\n\n --border-subtle: hsla(0, 0%, 0%, 0.1);\n --border-medium: hsla(0, 0%, 0%, 0.2);\n --border-strong: #d8d8d8;\n\n --text-primary: #242424;\n --text-secondary: #6f6f6f;\n --text-muted: #777777;\n --text-muted-subtle: #a1a1a1;\n --text-inverse: #fff;\n\n --accent: #0096ff;\n --linked: #8b5cf6;\n --accent-surface: rgba(0, 176, 255, 0.15);\n --warning: #d97706;\n --warning-text: #9a5b00;\n --warning-surface: #fff6e5;\n --danger: #df4b4b;\n --danger-text: #bd3636;\n --danger-surface: rgba(223, 75, 75, 0.2);\n --success: #2e7d52;\n\n --space-0: 0;\n --space-4: 4px;\n --space-8: 8px;\n --space-12: 12px;\n --space-16: 16px;\n --space-20: 20px;\n --space-24: 24px;\n --space-32: 32px;\n --space-40: 40px;\n --space-48: 48px;\n\n /* Radius */\n --radius-0: 0;\n --radius-4: 4px;\n --radius-6: 6px;\n --radius-8: 8px;\n --radius-12: 12px;\n --radius-16: 16px;\n --radius-20: 20px;\n --radius-24: 24px;\n --radius-pill: 999px;\n\n --radius-control: var(--radius-8);\n --shadow-outline: 0 0 0 1px rgba(0, 0, 0, 0.05);\n --shadow-popup: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 16px rgba(0, 0, 0, 0.10);\n --shadow-control-outline: 0 0 0 0.5px rgba(0, 0, 0, 0.25);\n --shadow-control: inset 0 -2px 0 rgba(0, 0, 0, 0.03), var(--shadow-control-outline);\n --z-index: 2147483647;\n\n --font-family: \"Inter Variable\", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --font-size-base: 12px;\n --font-size-small: 10px;\n --font-weight-base: 400;\n --font-weight-label: 600;\n\n /* Control semantic sizes */\n --control-height-small: 24px;\n --control-height-large: 32px;\n --control-height-xlarge: 40px;\n --label-column: 104px;\n\n --icon-size-small: 16px;\n --icon-size-large: 20px;\n --icon-stroke-width: 1.5px;\n\n position: fixed;\n inset: 0;\n z-index: var(--z-index);\n pointer-events: none;\n font-family: var(--font-family);\n background: transparent;\n box-sizing: border-box;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton,\ninput,\nselect {\n font-family: inherit;\n}\n";
33
34
  import { useInspectorOpen } from "../shell/openStore.js";
34
35
  import { isEditableEvent } from "../shell/shortcuts.js";
35
36
  import { acknowledgeAgentRendererReady } from "./agentPresentation.js";
@@ -39,7 +40,8 @@ import { useNudgeUiRuntimeConfig } from "../runtime/useRuntimeConfig.js";
39
40
  import { subscribeCanvasRendererMessages } from "./rendererMessageRouter.js";
40
41
  import { adjacentCanvasZoomLevel, CanvasToolbar, } from "./CanvasToolbar.js";
41
42
  import { APP_INTERACTION_KEY, canvasToolForEvent, canvasToolForCode } from "./keyboardShortcuts.js";
42
- const canvasToolbarStyles = ".canvas-toolbar {\n position: absolute;\n left: 50%;\n bottom: var(--space-20);\n /* Keep the persistent controls above the live sketch surface. The sketch\n toolbar gets the next layer so both toolbars remain available together. */\n z-index: calc(var(--z-index) - 2);\n display: flex;\n align-items: center;\n gap: var(--space-4);\n padding: var(--space-4);\n border-radius: var(--radius-12);\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n transform: translateX(-50%);\n pointer-events: auto;\n}\n\n/* The live sketch surface is a separate stacking context. Keep a copy of the\n toolbar at the root layer while sketching so pointer events reach the\n controls instead of the full-screen SVG drawing surface. */\n.canvas-toolbar__portal {\n position: fixed;\n inset: 0;\n z-index: var(--z-index);\n pointer-events: none;\n}\n\n.canvas-toolbar__portal > .canvas-toolbar {\n pointer-events: auto;\n}\n\n.canvas-toolbar__tools {\n display: flex;\n align-items: center;\n gap: var(--space-4);\n}\n\n.canvas-toolbar__divider {\n flex-shrink: 0;\n width: 1px;\n height: var(--control-height-small);\n margin-inline: 0;\n background: var(--border-subtle);\n}\n\n.canvas-toolbar__tool[data-active=\"true\"] {\n background: var(--accent-surface);\n color: var(--accent);\n}\n";
43
+ const canvasToolbarStyles = ".canvas-toolbar {\n position: absolute;\n left: 50%;\n bottom: var(--space-20);\n /* Keep the persistent controls above the live sketch surface. The sketch\n toolbar gets the next layer so both toolbars remain available together. */\n z-index: calc(var(--z-index) - 2);\n display: flex;\n align-items: center;\n gap: var(--space-4);\n padding: var(--space-4);\n border-radius: var(--radius-12);\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n transform: translateX(-50%);\n pointer-events: auto;\n}\n\n/* The live sketch surface is a separate stacking context. Keep a copy of the\n toolbar at the root layer while sketching so pointer events reach the\n controls instead of the full-screen SVG drawing surface. */\n.canvas-toolbar__portal {\n position: fixed;\n inset: 0;\n z-index: var(--z-index);\n pointer-events: none;\n}\n\n.canvas-toolbar__portal > .canvas-toolbar {\n pointer-events: auto;\n}\n\n.canvas-toolbar__tools {\n display: flex;\n align-items: center;\n gap: var(--space-4);\n}\n\n.canvas-toolbar__divider {\n flex-shrink: 0;\n width: 1px;\n height: var(--control-height-small);\n margin-inline: 0;\n background: var(--border-subtle);\n}\n\n.canvas-toolbar__tool[data-active=\"true\"] {\n background: var(--accent-surface);\n color: var(--accent);\n}\n\n/* Tool options slide out beside their tool. The component sets an explicit\n pixel width (0 or the content's natural width) so the toolbar grows smoothly. */\n.tool-options {\n flex-shrink: 0;\n margin-inline-start: calc(var(--space-4) * -1);\n /* Clip the slide horizontally only. Vertically the clip reaches the bar's\n padding, so illustrations that bleed to its bottom edge are never cut\n while the drawer is still animating open. */\n clip-path: inset(-64px 0 calc(var(--space-4) * -1));\n opacity: 0;\n transition:\n width 220ms cubic-bezier(0.2, 0, 0, 1),\n margin-inline-start 220ms cubic-bezier(0.2, 0, 0, 1),\n opacity 160ms ease;\n}\n\n.tool-options[data-expanded=\"true\"] {\n margin-inline-start: 0;\n opacity: 1;\n}\n\n/* Once the slide finishes, let tool content and popovers rise above the bar. */\n.tool-options[data-settled=\"true\"] {\n clip-path: none;\n}\n\n.tool-options[aria-hidden=\"true\"] {\n pointer-events: none;\n}\n\n.tool-options__inner {\n display: flex;\n align-items: center;\n gap: var(--space-4);\n width: max-content;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .tool-options {\n transition: none;\n }\n}\n";
44
+ const sketchToolOptionsStyles = "/* Pen, eraser, color and rectangle options shown in the canvas toolbar drawer. */\n\n.sketch-options__illustrated {\n appearance: none;\n position: relative;\n flex-shrink: 0;\n width: var(--control-height-xlarge);\n height: var(--control-height-xlarge);\n padding: 0;\n border: 0;\n border-radius: var(--radius-control);\n background: transparent;\n cursor: pointer;\n /* Clip the illustration at the toolbar's bottom edge, never above it. */\n clip-path: inset(-64px calc(var(--space-4) * -1) calc(var(--space-4) * -1));\n}\n\n/* Well behind the active tool, running through the toolbar padding to its bottom edge. */\n.sketch-options__illustrated::before {\n content: \"\";\n position: absolute;\n inset: 0 0 calc(var(--space-4) * -1);\n border-radius: var(--radius-control) var(--radius-control) 0 0;\n background: var(--surface-well);\n opacity: 0;\n transition: opacity 180ms ease;\n}\n\n.tool-options[data-settled=\"true\"] .sketch-options__illustrated[data-active=\"true\"]::before {\n opacity: 1;\n}\n\n.sketch-options__illustration {\n /* Artwork below the original crop line; lets the base stay visible while raised. */\n --illustration-bleed: 0px;\n position: absolute;\n left: 50%;\n /* Extend through the toolbar padding so the base sits on its bottom edge. */\n bottom: calc(var(--space-4) * -1 - var(--illustration-bleed));\n filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.12));\n transform: translate(-50%, 0);\n transition: transform 180ms cubic-bezier(0.2, 0, 0, 1);\n}\n\n.sketch-options__illustration--pen {\n --illustration-bleed: 9px;\n}\n\n.sketch-options__illustration--eraser {\n --illustration-bleed: 11px;\n}\n\n.sketch-options__illustrated:hover .sketch-options__illustration {\n transform: translate(-50%, calc(var(--space-4) * -1));\n}\n\n.tool-options[data-settled=\"true\"] .sketch-options__illustrated[data-active=\"true\"] .sketch-options__illustration {\n transform: translate(-50%, 0);\n}\n\n.sketch-options__illustrated:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n}\n\n/* The rectangle shares the pen and eraser's quiet well instead of the accent active style. */\n.canvas-toolbar__tool.sketch-options__rectangle[data-active=\"true\"] {\n background: var(--surface-well);\n color: var(--text-primary);\n}\n\n.sketch-options__color {\n position: relative;\n display: flex;\n}\n\n.sketch-options__color-trigger {\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--control-height-xlarge);\n height: var(--control-height-xlarge);\n padding: 0;\n border: 0;\n border-radius: var(--radius-control);\n background: transparent;\n color: var(--text-primary);\n cursor: pointer;\n transition: background-color 120ms ease;\n}\n\n.sketch-options__color-trigger:hover,\n.sketch-options__color-trigger[data-open=\"true\"] {\n background: var(--surface-well);\n}\n\n.sketch-options__swatch {\n display: block;\n /* Fades back in as the palette collapses onto it. */\n transition: opacity 120ms ease 150ms;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);\n}\n\n/* The hexagon frames the trigger, so its swatch steps aside while the palette is open. */\n.sketch-options__color-trigger[data-open=\"true\"] .sketch-options__swatch {\n opacity: 0;\n transition-delay: 0s;\n}\n\n/* Colors pop out as a hexagon of overlapping swatches centered on the color trigger. */\n.sketch-options__palette {\n position: absolute;\n z-index: 1;\n left: 50%;\n top: 50%;\n width: 0;\n height: 0;\n}\n\n.sketch-options__palette-option {\n appearance: none;\n position: absolute;\n left: calc(var(--swatch-size) / -2);\n top: calc(var(--swatch-size) / -2);\n width: var(--swatch-size);\n height: var(--swatch-size);\n padding: 0;\n border: 0;\n border-radius: 50%;\n cursor: pointer;\n translate: var(--swatch-x) var(--swatch-y);\n box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);\n transition:\n scale 120ms cubic-bezier(0.2, 0, 0, 1),\n box-shadow 120ms ease;\n animation: sketch-options-swatch-in 180ms cubic-bezier(0.2, 0, 0, 1) var(--swatch-delay, 0ms) backwards;\n}\n\n.sketch-options__palette-option:hover {\n scale: 1.05;\n}\n\n/* The selected swatch sits above its neighbors, separated from them by a light rim. */\n.sketch-options__palette-option[data-active=\"true\"] {\n box-shadow:\n inset 0 0 0 1px rgba(0, 0, 0, 0.08),\n 0 0 0 2px var(--surface-raised-2x),\n 0 2px 8px rgba(0, 0, 0, 0.2);\n}\n\n.sketch-options__palette-option:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n\n.sketch-options__palette[data-state=\"closing\"] {\n pointer-events: none;\n}\n\n/* Closing plays the fan-out in reverse, last swatch first. */\n.sketch-options__palette[data-state=\"closing\"] .sketch-options__palette-option {\n animation: sketch-options-swatch-out 180ms cubic-bezier(0.2, 0, 0, 1) var(--swatch-delay-out, 0ms) forwards;\n}\n\n@keyframes sketch-options-swatch-out {\n to {\n opacity: 0;\n scale: 0.4;\n translate: 0 0;\n }\n}\n\n@keyframes sketch-options-swatch-in {\n from {\n opacity: 0;\n scale: 0.4;\n translate: 0 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sketch-options__illustrated::before,\n .sketch-options__illustration {\n transition: none;\n }\n\n .sketch-options__palette-option {\n animation: none;\n transition: none;\n }\n}\n";
43
45
  import { getActiveCanvasFrame } from "./activeCanvasDocument.js";
44
46
  import { startSketchCapture } from "../sketch/SketchWorkspace.js";
45
47
  import { cancelSketchInteraction, useSketchInteractionActive } from "../sketch/interaction.js";
@@ -48,7 +50,8 @@ import { createCommentCursor, DESIGN_SELECT_CURSOR, PAN_CURSOR } from "../ui/cus
48
50
  import { addLinkedFrame, createIteration as createWorkspaceIteration, removeFrame } from "../workspace/commands.js";
49
51
  import { getSelectedElements, setSelectedElement } from "../selection/selectionStore.js";
50
52
  import { setCommentToolActive } from "../comments/store.js";
51
- const WORKSPACE_STYLES = [foundationStyles, canvasWorkspaceStyles, canvasCardStyles, canvasToolbarStyles].join("\n");
53
+ import { InspectorStyle } from "../ui/InspectorStyle.js";
54
+ const WORKSPACE_STYLES = [foundationStyles, canvasWorkspaceStyles, canvasCardStyles, canvasToolbarStyles, sketchToolOptionsStyles].join("\n");
52
55
  const PRESENTATION_TRANSITION_MS = 200;
53
56
  function snapshotRect(rect) {
54
57
  return {
@@ -60,6 +63,7 @@ function snapshotRect(rect) {
60
63
  }
61
64
  export function CanvasWorkspace({ primaryUrl }) {
62
65
  const mode = useCanvasMode();
66
+ const pageSurface = isPageSurface();
63
67
  const runtimeConfig = useNudgeUiRuntimeConfig();
64
68
  const inspectorSession = useInspectorSession();
65
69
  const inspectorOpen = useInspectorOpen();
@@ -70,8 +74,10 @@ export function CanvasWorkspace({ primaryUrl }) {
70
74
  const selectedCardId = useSelectedCardId();
71
75
  const focusedCardId = useFocusedCardId();
72
76
  const sketchActive = useSketchInteractionActive();
73
- const sketchEnabled = isNudgeUiDev() && runtimeConfig.demo !== true;
77
+ const sketchEnabled = isNudgeUiDev()
78
+ && (runtimeConfig.demo !== true || isNudgeUiFeatureEnabled(runtimeConfig.features, "sketch"));
74
79
  const canvasIterationsEnabled = isNudgeUiFeatureEnabled(runtimeConfig.features, "canvasIterations");
80
+ useSyncExternalStore(subscribeFrameRegistry, getFrameRegistryVersion);
75
81
  const sketchAvailable = sketchEnabled && getActiveCanvasFrame() !== null;
76
82
  const boardRef = useRef(null);
77
83
  useCanvasLayoutAnimation(boardRef, cards, camera, presentation);
@@ -81,16 +87,17 @@ export function CanvasWorkspace({ primaryUrl }) {
81
87
  const framePanContextRef = useRef(null);
82
88
  const spaceHeldRef = useRef(false);
83
89
  const fitAllScheduledRef = useRef(false);
84
- const activatedTargetRef = useRef(null);
90
+ // Track the consumed primaryUrl prop separately from navigation inside a frame.
91
+ const activatedPrimaryUrlRef = useRef(null);
85
92
  const demoSeededRef = useRef(false);
86
93
  const previousPresentationRef = useRef(presentation);
87
94
  const presentationAnimationRef = useRef(null);
88
95
  const [boardCursorClass, setBoardCursorClass] = useState("");
89
- const [selectedTool, setInteractionTool] = useState("design");
96
+ const [selectedTool, setInteractionTool] = useState(runtimeConfig.demo === true ? "select" : "design");
90
97
  const temporaryAppInteraction = useTemporaryAppInteraction();
91
98
  const interactionTool = temporaryAppInteraction ? "select" : selectedTool;
92
99
  const layoutTransitioning = useCanvasLayoutTransitioning();
93
- const rendererInteractionsEnabled = interactionTool !== "select" && !layoutTransitioning;
100
+ const rendererInteractionsEnabled = interactionTool !== "select" && !layoutTransitioning && !sketchActive;
94
101
  const rendererCursor = interactionTool === "comment" ? "comment" : "design";
95
102
  const boardCursor = boardCursorClass === "is-grabbing"
96
103
  ? "grabbing"
@@ -120,8 +127,7 @@ export function CanvasWorkspace({ primaryUrl }) {
120
127
  : null;
121
128
  if (!board || !card || !cardElement || typeof cardElement.animate !== "function" || camera.zoom <= 0)
122
129
  return;
123
- // The previous layout is already gone, so derive it: focus fills the
124
- // board, and canvas places the card through the camera.
130
+ // The previous layout is gone, so derive it: focus fills the board, canvas places the card through the camera.
125
131
  const boardRect = snapshotRect(board.getBoundingClientRect());
126
132
  const canvasRect = {
127
133
  left: boardRect.left + camera.x + card.x * camera.zoom,
@@ -157,9 +163,9 @@ export function CanvasWorkspace({ primaryUrl }) {
157
163
  const board = boardRef.current;
158
164
  if (!primaryUrl || !board)
159
165
  return;
160
- if (activatedTargetRef.current === primaryUrl && cards.length > 0)
166
+ if (activatedPrimaryUrlRef.current === primaryUrl && cards.length > 0)
161
167
  return;
162
- activatedTargetRef.current = primaryUrl;
168
+ activatedPrimaryUrlRef.current = primaryUrl;
163
169
  const viewport = {
164
170
  width: board.clientWidth,
165
171
  height: board.clientHeight,
@@ -219,7 +225,9 @@ export function CanvasWorkspace({ primaryUrl }) {
219
225
  }
220
226
  }, [primaryUrl, cards.length, presentation, runtimeConfig.demo, runtimeConfig.demoPages, runtimeConfig.demoCardLabels]);
221
227
  useEffect(() => {
222
- if (primaryUrl && activatedTargetRef.current !== primaryUrl)
228
+ if (pageSurface)
229
+ return;
230
+ if (primaryUrl && activatedPrimaryUrlRef.current !== primaryUrl)
223
231
  return;
224
232
  const activeCardId = selectedCardId ?? focusedCardId ?? cards[0]?.id;
225
233
  const activeCard = cards.find((card) => card.id === activeCardId);
@@ -230,63 +238,31 @@ export function CanvasWorkspace({ primaryUrl }) {
230
238
  window.history.replaceState(window.history.state, "", editorUrl);
231
239
  }
232
240
  }, [cards, focusedCardId, primaryUrl, selectedCardId]);
233
- const sendPanModifier = useCallback((iframe, cardId, spaceHeld) => {
234
- iframe.contentWindow?.postMessage({
235
- type: "pan-modifier",
236
- protocolVersion: PROTOCOL_VERSION,
237
- projectId: PROJECT_ID,
238
- workspaceId: WORKSPACE_ID,
239
- cardId,
240
- spaceHeld,
241
- cursor: spaceHeld ? "drag" : rendererCursor,
242
- }, window.location.origin);
243
- }, [rendererCursor]);
244
- const sendInspectorInteractionState = useCallback((iframe, cardId, open, interactionsEnabled, cursor) => {
245
- iframe.contentWindow?.postMessage({
241
+ const sendInspectorInteractionState = useCallback((frame, open, interactionsEnabled, cursor) => {
242
+ frame.post({
246
243
  type: "inspector-interaction-state",
247
- protocolVersion: PROTOCOL_VERSION,
248
- projectId: PROJECT_ID,
249
- workspaceId: WORKSPACE_ID,
250
- cardId,
251
244
  open,
252
245
  interactionsEnabled,
253
246
  cursor,
254
- commentCursor: cursor === "comment" ? createCommentCursor(boardRef.current) : undefined,
255
- }, window.location.origin);
256
- }, []);
257
- const sendLinkTargetState = useCallback((iframe, cardId, openInCard) => {
258
- iframe.contentWindow?.postMessage({
259
- type: "link-target-state",
260
- protocolVersion: PROTOCOL_VERSION,
261
- projectId: PROJECT_ID,
262
- workspaceId: WORKSPACE_ID,
263
- cardId,
264
- openInCard,
265
- }, window.location.origin);
247
+ ...(cursor === "comment" ? { commentCursor: createCommentCursor(boardRef.current) } : {}),
248
+ });
266
249
  }, []);
267
- const sendBoardGestureState = useCallback((iframe, cardId, enabled) => {
268
- iframe.contentWindow?.postMessage({
269
- type: "board-gesture-state",
270
- protocolVersion: PROTOCOL_VERSION,
271
- projectId: PROJECT_ID,
272
- workspaceId: WORKSPACE_ID,
273
- cardId,
274
- enabled,
275
- panScroll: enabled && interactionTool !== "select",
276
- }, window.location.origin);
250
+ const sendBoardGestureState = useCallback((frame, enabled) => {
251
+ frame.post({ type: "board-gesture-state", enabled, panScroll: enabled && interactionTool !== "select" });
277
252
  }, [interactionTool]);
278
253
  useEffect(() => {
279
254
  for (const [cardId, iframe] of getRegisteredFrames()) {
280
- sendInspectorInteractionState(iframe, cardId, inspectorOpen, rendererInteractionsEnabled, rendererCursor);
281
- sendBoardGestureState(iframe, cardId, presentation === "canvas");
282
- sendLinkTargetState(iframe, cardId, linksOpenInCards);
255
+ const frame = connectFrame(cardId, iframe);
256
+ sendInspectorInteractionState(frame, inspectorOpen, rendererInteractionsEnabled, rendererCursor);
257
+ sendBoardGestureState(frame, presentation === "canvas");
258
+ frame.post({ type: "link-target-state", openInCard: linksOpenInCards });
283
259
  }
284
- }, [inspectorOpen, linksOpenInCards, presentation, rendererCursor, rendererInteractionsEnabled, sendBoardGestureState, sendInspectorInteractionState, sendLinkTargetState]);
260
+ }, [inspectorOpen, linksOpenInCards, presentation, rendererCursor, rendererInteractionsEnabled, sendBoardGestureState, sendInspectorInteractionState]);
285
261
  const broadcastPanModifier = useCallback((spaceHeld) => {
286
262
  for (const [cardId, iframe] of getRegisteredFrames()) {
287
- sendPanModifier(iframe, cardId, spaceHeld);
263
+ connectFrame(cardId, iframe).post({ type: "pan-modifier", spaceHeld });
288
264
  }
289
- }, [sendPanModifier]);
265
+ }, []);
290
266
  const zoomAtPointer = useCallback((point, deltaY) => {
291
267
  const board = boardRef.current;
292
268
  if (!board)
@@ -347,7 +323,7 @@ export function CanvasWorkspace({ primaryUrl }) {
347
323
  if (nextTool === "sketch") {
348
324
  if (!sketchEnabled)
349
325
  return;
350
- const hostElement = getActiveCanvasFrame();
326
+ const hostElement = canvasFrameHost(getActiveCanvasFrame());
351
327
  if (!hostElement)
352
328
  return;
353
329
  stopPanMode();
@@ -413,6 +389,8 @@ export function CanvasWorkspace({ primaryUrl }) {
413
389
  return () => window.removeEventListener("keydown", onKeyDown, true);
414
390
  }, [handleToolChange, mode, sketchAvailable]);
415
391
  const handleZoomStep = useCallback((direction) => {
392
+ if (sketchActive)
393
+ return;
416
394
  if (presentation === "focus") {
417
395
  if (direction < 0) {
418
396
  batchCanvasChanges(() => {
@@ -437,7 +415,7 @@ export function CanvasWorkspace({ primaryUrl }) {
437
415
  if (nextZoom === null)
438
416
  return;
439
417
  setBoardCamera({ ...getBoardCamera(), zoom: nextZoom });
440
- }, [presentation]);
418
+ }, [presentation, sketchActive]);
441
419
  const showCanvas = useCallback(() => {
442
420
  handleZoomStep(-1);
443
421
  }, [handleZoomStep]);
@@ -476,7 +454,7 @@ export function CanvasWorkspace({ primaryUrl }) {
476
454
  broadcastPanModifier(false);
477
455
  }, [broadcastPanModifier, endPanning, presentation]);
478
456
  useEffect(() => {
479
- const stopChanges = subscribeChanges(() => {
457
+ const stopChanges = subscribeActiveDraftChanges(() => {
480
458
  projectToAllReadyCards();
481
459
  });
482
460
  const stopPreview = subscribeOriginalPreview(() => {
@@ -488,7 +466,8 @@ export function CanvasWorkspace({ primaryUrl }) {
488
466
  };
489
467
  }, []);
490
468
  useEffect(() => {
491
- return subscribeCanvasRendererMessages(({ cardId, iframe, identity, message: msg }) => {
469
+ return subscribeCanvasRendererMessages(({ frame, message: msg }) => {
470
+ const { identity } = frame;
492
471
  if (msg.type === "renderer-hello")
493
472
  return;
494
473
  if (msg.type === "app-interaction-modifier") {
@@ -504,46 +483,34 @@ export function CanvasWorkspace({ primaryUrl }) {
504
483
  }
505
484
  return;
506
485
  }
507
- const frame = { cardId, iframe };
508
486
  const syncActiveFrameUrl = (url) => {
509
487
  if (getCanvasCards().some((card) => card.id === frame.cardId && iterationId(card.content)))
510
488
  return;
511
489
  const activeCardId = getSelectedCardId() ?? getFocusedCardId() ?? getCanvasCards()[0]?.id;
512
- if (activeCardId === frame.cardId || getCanvasCards().length === 1) {
513
- activatedTargetRef.current = url;
490
+ if (!pageSurface && (activeCardId === frame.cardId || getCanvasCards().length === 1)) {
514
491
  window.history.replaceState(window.history.state, "", createNudgeUiEditorUrl(url));
515
492
  }
516
493
  updateCardUrl(frame.cardId, url);
517
494
  };
518
495
  if (isProjectionAppliedMessage(msg, identity)) {
519
496
  recordCanvasProjectionApplied(frame.cardId, msg.revision);
520
- // While hold-to-view-original is active the frame intentionally shows
521
- // the page without inspector changes; skip conflict verification.
497
+ // Peek shows the page without inspector changes; skip conflict verification.
522
498
  if (isOriginalPreviewActive())
523
499
  return;
524
- const frameDocument = frame.iframe.contentDocument;
500
+ const frameDocument = frame.document();
525
501
  const plan = getCanonicalFrameProjection(frame.cardId, msg.revision);
526
502
  const draft = getDraftForCard(frame.cardId);
527
503
  if (frameDocument && plan && draft && isCanvasCanonicalProjectionRevisionCurrent(frameDocument, msg.revision)) {
528
504
  const attempt = beginPreviewAttempt(getCanvasPreviewDocument(frame.cardId), plan.draftRevision);
529
505
  if (attempt) {
530
- for (const change of draft.contents.changes) {
531
- if (!isPreviewableChange(change))
532
- continue;
533
- const result = verifyManagedStyleProjection(change, null, frameDocument);
534
- if (result) {
535
- publishPreviewDiagnostic(attempt, changeKey(change), result);
536
- if (result.status === "conflict" && result.reason === "animation") {
537
- window.setTimeout(() => {
538
- if (!isCanvasCanonicalProjectionRevisionCurrent(frameDocument, msg.revision))
539
- return;
540
- const settled = verifyManagedStyleProjection(change, null, frameDocument);
541
- if (settled)
542
- publishPreviewDiagnostic(attempt, changeKey(change), settled);
543
- }, 300);
544
- }
545
- }
546
- }
506
+ verifyPreviewChanges({
507
+ changes: draft.contents.changes,
508
+ document: frameDocument,
509
+ attempt,
510
+ targetFor: () => null,
511
+ isCurrent: () => isCanvasCanonicalProjectionRevisionCurrent(frameDocument, msg.revision),
512
+ retryAnimation: (run) => window.setTimeout(run, 300),
513
+ });
547
514
  }
548
515
  }
549
516
  return;
@@ -569,12 +536,11 @@ export function CanvasWorkspace({ primaryUrl }) {
569
536
  if (msg.type === "frame-ready") {
570
537
  acknowledgeAgentRendererReady(frame.cardId);
571
538
  syncActiveFrameUrl(msg.url);
572
- // A card can finish loading after Space was pressed on the controller.
573
- // Seed it with the current modifier state before its first pointer event.
574
- sendPanModifier(frame.iframe, frame.cardId, spaceHeldRef.current);
575
- sendInspectorInteractionState(frame.iframe, frame.cardId, inspectorOpen, rendererInteractionsEnabled, spaceHeldRef.current ? "drag" : rendererCursor);
576
- sendBoardGestureState(frame.iframe, frame.cardId, presentation === "canvas");
577
- sendLinkTargetState(frame.iframe, frame.cardId, linksOpenInCards);
539
+ // A card can load after Space was pressed, so seed the current modifier state.
540
+ frame.post({ type: "pan-modifier", spaceHeld: spaceHeldRef.current });
541
+ sendInspectorInteractionState(frame, inspectorOpen, rendererInteractionsEnabled, spaceHeldRef.current ? "drag" : rendererCursor);
542
+ sendBoardGestureState(frame, presentation === "canvas");
543
+ frame.post({ type: "link-target-state", openInCard: linksOpenInCards });
578
544
  }
579
545
  if (msg.type === "pan-modifier") {
580
546
  if (presentation !== "canvas")
@@ -587,34 +553,25 @@ export function CanvasWorkspace({ primaryUrl }) {
587
553
  return;
588
554
  }
589
555
  if (msg.type === "wheel-pan") {
590
- if (presentation === "canvas" && interactionTool !== "select")
556
+ if (presentation === "canvas" && !sketchActive && interactionTool !== "select")
591
557
  panCanvasByWheel(msg.deltaX, msg.deltaY);
592
558
  return;
593
559
  }
594
560
  if (msg.type === "zoom") {
595
- if (presentation !== "canvas")
561
+ if (presentation !== "canvas" || sketchActive)
596
562
  return;
597
- const iframeRect = frame.iframe.getBoundingClientRect();
598
- const point = iframePointToClientPoint(iframeRect, msg.point, getBoardCamera().zoom);
599
- zoomAtPointer(point, msg.deltaY);
563
+ zoomAtPointer(toViewportPoint(frame.viewport(), msg.point), msg.deltaY);
600
564
  return;
601
565
  }
566
+ // The pan moves the frame, so every pan point maps through the viewport captured at pan start.
602
567
  const pointInBoard = (point) => {
603
568
  const context = framePanContextRef.current;
604
- if (!context)
605
- return null;
606
- return {
607
- x: context.left + point.x * context.zoom,
608
- y: context.top + point.y * context.zoom,
609
- };
569
+ return context ? toViewportPoint(context, point) : null;
610
570
  };
611
571
  if (msg.type === "pan-start") {
612
- const iframeRect = frame.iframe.getBoundingClientRect();
613
- framePanContextRef.current = {
614
- left: iframeRect.left,
615
- top: iframeRect.top,
616
- zoom: getBoardCamera().zoom,
617
- };
572
+ if (sketchActive)
573
+ return;
574
+ framePanContextRef.current = frame.viewport();
618
575
  const point = pointInBoard(msg.point);
619
576
  if (point)
620
577
  startPanning(point);
@@ -632,7 +589,7 @@ export function CanvasWorkspace({ primaryUrl }) {
632
589
  return;
633
590
  }
634
591
  if (msg.type === "frame-metadata") {
635
- const frameDocument = frame.iframe.contentDocument;
592
+ const frameDocument = frame.document();
636
593
  if (frameDocument)
637
594
  disposeInlineTextEdit("route-disposed", frameDocument);
638
595
  if (msg.url)
@@ -663,11 +620,11 @@ export function CanvasWorkspace({ primaryUrl }) {
663
620
  activateIframeWorkspace(msg.url, { width: boardRef.current?.clientWidth ?? window.innerWidth, height: boardRef.current?.clientHeight ?? window.innerHeight }, { replaceActiveCard: true });
664
621
  return;
665
622
  }
666
- const frameDocument = frame.iframe.contentDocument;
623
+ const frameDocument = frame.document();
667
624
  if (frameDocument)
668
625
  disposeInlineTextEdit("route-disposed", frameDocument);
669
626
  });
670
- }, [broadcastPanModifier, endPanning, handleToolChange, interactionTool, mode, panCanvasByWheel, inspectorOpen, linksOpenInCards, movePanning, presentation, rendererCursor, rendererInteractionsEnabled, sendBoardGestureState, sendInspectorInteractionState, sendLinkTargetState, sendPanModifier, sketchAvailable, startPanning, zoomAtPointer]);
627
+ }, [broadcastPanModifier, endPanning, handleToolChange, interactionTool, mode, panCanvasByWheel, inspectorOpen, linksOpenInCards, movePanning, presentation, rendererCursor, rendererInteractionsEnabled, sendBoardGestureState, sendInspectorInteractionState, sketchActive, sketchAvailable, startPanning, zoomAtPointer]);
671
628
  useEffect(() => {
672
629
  if (mode === "canvas" && !hasFitAllRan()) {
673
630
  if (!fitAllScheduledRef.current) {
@@ -758,8 +715,13 @@ export function CanvasWorkspace({ primaryUrl }) {
758
715
  function handleGlobalWheel(e) {
759
716
  const zoom = e.ctrlKey || e.metaKey;
760
717
  const board = boardRef.current;
761
- if (zoom && sketchActive)
718
+ if (sketchActive) {
719
+ if (e.composedPath().some((node) => node instanceof Element && node.closest(".sketch__prompt-panel, .sketch__annotation-editor, .panel")))
720
+ return;
721
+ e.preventDefault();
722
+ e.stopPropagation();
762
723
  return;
724
+ }
763
725
  const path = e.composedPath();
764
726
  // Comment pins overlay the board without being its DOM descendants.
765
727
  const overCommentPin = path.some((node) => node instanceof Element && node.matches(".comment-pin"));
@@ -777,10 +739,11 @@ export function CanvasWorkspace({ primaryUrl }) {
777
739
  window.addEventListener("wheel", handleGlobalWheel, { capture: true, passive: false });
778
740
  return () => window.removeEventListener("wheel", handleGlobalWheel, { capture: true });
779
741
  }, [mode, presentation, sketchActive, interactionTool, panCanvasByWheel, zoomAtPointer]);
780
- const renderCard = (card) => (_jsx(CanvasCard, { card: card, presentation: presentation, presentationCard: card.id === presentationCardId, linkedToActive: linkedFrameIds.includes(card.id), onShowFocus: showFocus, onDuplicate: duplicateDesign, onCreateIteration: canvasIterationsEnabled ? createIteration : undefined, documentOwner: inspectorSession }, card.id));
742
+ // Every page card would share the one page renderer, so extra restored cards stay unmounted.
743
+ const renderCard = (card) => pageSurface ? (card.id === presentationCardId ? _jsx(PageCard, { card: card, documentOwner: inspectorSession }, card.id) : null) : (_jsx(CanvasCard, { card: card, presentation: presentation, presentationCard: card.id === presentationCardId, linkedToActive: linkedFrameIds.includes(card.id), onShowFocus: showFocus, onDuplicate: duplicateDesign, onCreateIteration: canvasIterationsEnabled ? createIteration : undefined, documentOwner: inspectorSession }, card.id));
781
744
  if (mode !== "canvas")
782
745
  return null;
783
- return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "canvas-styles", children: WORKSPACE_STYLES }), _jsx("div", { className: `canvas-workspace${presentationTransitioning ? " is-presentation-transitioning" : ""}`, "data-test": "canvas-workspace", "data-presentation": presentation, style: { right: inspectorOpen ? "min(320px, 100vw)" : 0 }, children: _jsxs("div", { className: `canvas-workspace__board ${boardCursorClass}${layoutTransitioning ? " is-layout-transitioning" : ""}`.trim(), "data-test": "canvas-board", ref: boardRef, style: { cursor: boardCursor }, onPointerDown: handleBoardPointerDown, onClick: handleBoardClick, children: [!primaryUrl ? (_jsx("div", { className: "canvas-workspace__target-error", "data-test": "canvas-target-error", children: "This editor URL does not identify an application page." })) : null, inspectorOpen && presentation === "focus" ? (_jsx("div", { className: "canvas-workspace__focus-action", "data-test": "canvas-show-canvas", children: _jsxs(Button, { variant: "quiet", size: "default", type: "button", onClick: showCanvas, children: [_jsx(IconCornerLeftUp, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), "Canvas"] }) })) : null, _jsx("div", { className: "canvas-workspace__board-content", style: {
746
+ return (_jsxs(_Fragment, { children: [_jsx(InspectorStyle, { testId: "canvas-styles", css: WORKSPACE_STYLES }), _jsx("div", { className: `canvas-workspace${presentationTransitioning ? " is-presentation-transitioning" : ""}`, "data-test": "canvas-workspace", "data-presentation": presentation, "data-surface": pageSurface ? "page" : undefined, style: { right: inspectorOpen ? "min(320px, 100vw)" : 0 }, children: _jsxs("div", { className: `canvas-workspace__board ${boardCursorClass}${layoutTransitioning ? " is-layout-transitioning" : ""}`.trim(), "data-test": "canvas-board", ref: boardRef, style: { cursor: boardCursor }, onPointerDown: handleBoardPointerDown, onClick: handleBoardClick, children: [!primaryUrl ? (_jsx("div", { className: "canvas-workspace__target-error", "data-test": "canvas-target-error", children: "This editor URL does not identify an application page." })) : null, inspectorOpen && presentation === "focus" && !pageSurface ? (_jsx("div", { className: "canvas-workspace__focus-action", "data-test": "canvas-show-canvas", children: _jsxs(Button, { variant: "quiet", size: "default", type: "button", onClick: showCanvas, children: [_jsx(IconCornerLeftUp, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), "Canvas"] }) })) : null, _jsx("div", { className: "canvas-workspace__board-content", style: {
784
747
  transform: `translate(${camera.x}px, ${camera.y}px) scale(${camera.zoom})`,
785
748
  transformOrigin: "0 0",
786
749
  }, "data-test": "canvas-board-content", children: cards.map(renderCard) }), inspectorOpen && !sketchActive ? (_jsx(CanvasToolbar, { tool: interactionTool, sketchEnabled: sketchAvailable, onToolChange: handleToolChange })) : null] }) }), inspectorOpen && sketchActive ? (_jsx("div", { className: "canvas-toolbar__portal", "data-test": "canvas-toolbar-portal", style: { right: inspectorOpen ? "min(320px, 100vw)" : 0 }, children: _jsx(CanvasToolbar, { tool: interactionTool, sketchEnabled: sketchAvailable, onToolChange: handleToolChange }) })) : null] }));
@@ -1,6 +1,7 @@
1
1
  import type { ReactElement } from "react";
2
2
  interface LockedWorkspaceNoticeProps {
3
- onTakeover: () => void;
3
+ onTakeover: () => void | Promise<void>;
4
+ storageError?: boolean;
4
5
  }
5
- export declare function LockedWorkspaceNotice({ onTakeover }: LockedWorkspaceNoticeProps): ReactElement;
6
+ export declare function LockedWorkspaceNotice({ onTakeover, storageError }: LockedWorkspaceNoticeProps): ReactElement;
6
7
  export {};
@@ -4,14 +4,18 @@ import { requestTakeover } from "./workspaceLease.js";
4
4
  import { Button } from "../ui/Button.js";
5
5
  import { UI_STYLES } from "../ui/styles.js";
6
6
  const lockedWorkspaceStyles = ".locked-notice {\n position: fixed;\n top: max(12px, env(safe-area-inset-top));\n right: max(12px, env(safe-area-inset-right));\n width: min(320px, calc(100vw - 24px));\n padding: 18px;\n border-radius: 12px;\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n color: var(--text-primary);\n font-family: var(--font-family);\n pointer-events: auto;\n}\n\n.locked-notice__message {\n margin-bottom: 14px;\n font-size: 14px;\n font-weight: 650;\n}\n";
7
- export function LockedWorkspaceNotice({ onTakeover }) {
7
+ import { InspectorStyle } from "../ui/InspectorStyle.js";
8
+ export function LockedWorkspaceNotice({ onTakeover, storageError = false }) {
8
9
  const [takingOver, setTakingOver] = useState(false);
9
- function handleTakeover() {
10
+ async function handleTakeover() {
10
11
  setTakingOver(true);
11
- if (requestTakeover())
12
- onTakeover();
13
- else
12
+ try {
13
+ if (requestTakeover())
14
+ await onTakeover();
15
+ }
16
+ finally {
14
17
  setTakingOver(false);
18
+ }
15
19
  }
16
- return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "locked-workspace-styles", children: `${UI_STYLES}\n${lockedWorkspaceStyles}` }), _jsxs("aside", { className: "locked-notice", "data-test": "locked-workspace-notice", "aria-live": "polite", children: [_jsx("div", { className: "locked-notice__message", children: "Nudge UI is open in another tab" }), _jsx(Button, { "data-test": "takeover-here", disabled: takingOver, onClick: handleTakeover, children: takingOver ? "Taking over..." : "Take Over Here" })] })] }));
20
+ return (_jsxs(_Fragment, { children: [_jsx(InspectorStyle, { testId: "locked-workspace-styles", css: `${UI_STYLES}\n${lockedWorkspaceStyles}` }), _jsxs("aside", { className: "locked-notice", "data-test": "locked-workspace-notice", "aria-live": "polite", children: [_jsx("div", { className: "locked-notice__message", children: storageError ? "Can’t load saved changes. Try again." : "Nudge UI is open in another tab" }), _jsx(Button, { "data-test": "takeover-here", disabled: takingOver, onClick: handleTakeover, children: takingOver ? "Taking over..." : "Take Over Here" })] })] }));
17
21
  }
@@ -0,0 +1,9 @@
1
+ import { type ReactElement } from "react";
2
+ import type { CanvasCard } from "./canvasStore.js";
3
+ import type { InspectorSession } from "../session/sessionFactory.js";
4
+ interface PageCardProps {
5
+ card: CanvasCard;
6
+ documentOwner?: InspectorSession;
7
+ }
8
+ export declare function PageCard({ card, documentOwner }: PageCardProps): ReactElement;
9
+ export {};