@1agh/maude 0.28.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/README.md +3 -3
  2. package/{plugins/design/dev-server → apps/studio}/ai-banner.tsx +1 -2
  3. package/apps/studio/annotations-align.ts +149 -0
  4. package/apps/studio/annotations-bindings.ts +197 -0
  5. package/{plugins/design/dev-server → apps/studio}/annotations-context-toolbar.tsx +681 -151
  6. package/apps/studio/annotations-groups.ts +270 -0
  7. package/apps/studio/annotations-layer.tsx +4537 -0
  8. package/apps/studio/annotations-model.ts +2077 -0
  9. package/apps/studio/annotations-snap.ts +125 -0
  10. package/{plugins/design/dev-server → apps/studio}/api.ts +616 -70
  11. package/{plugins/design/dev-server → apps/studio}/artboard-activity-overlay.tsx +1 -1
  12. package/{plugins/design/dev-server → apps/studio}/artboard-marquee.tsx +1 -1
  13. package/apps/studio/bin/_motion-sample-playwright.mjs +129 -0
  14. package/{plugins/design/dev-server → apps/studio}/bin/_png-playwright.mjs +1 -1
  15. package/apps/studio/bin/annotate.mjs +732 -0
  16. package/apps/studio/bin/annotate.sh +17 -0
  17. package/{plugins/design/dev-server → apps/studio}/bin/canvas-edit.sh +1 -1
  18. package/{plugins/design/dev-server → apps/studio}/bin/draw-proof.sh +37 -2
  19. package/{plugins/design/dev-server → apps/studio}/bin/preflight.sh +1 -1
  20. package/apps/studio/bin/read-annotations.mjs +573 -0
  21. package/apps/studio/bin/read-annotations.sh +11 -0
  22. package/{plugins/design/dev-server → apps/studio}/bin/runtime-health.sh +1 -1
  23. package/{plugins/design/dev-server → apps/studio}/bin/screenshot.sh +62 -2
  24. package/{plugins/design/dev-server → apps/studio}/bin/server-up.sh +9 -3
  25. package/apps/studio/bin/to-lottie-verify.html +68 -0
  26. package/apps/studio/bin/to-lottie.sh +128 -0
  27. package/{plugins/design/dev-server → apps/studio}/build.ts +6 -4
  28. package/{plugins/design/dev-server → apps/studio}/canvas-arrowheads.ts +79 -10
  29. package/{plugins/design/dev-server → apps/studio}/canvas-comment-mount.tsx +1 -1
  30. package/apps/studio/canvas-create.ts +104 -0
  31. package/{plugins/design/dev-server → apps/studio}/canvas-cursors.ts +48 -12
  32. package/{plugins/design/dev-server → apps/studio}/canvas-edit.ts +257 -7
  33. package/{plugins/design/dev-server → apps/studio}/canvas-icons.tsx +165 -1
  34. package/{plugins/design/dev-server → apps/studio}/canvas-lib-inline.ts +1 -1
  35. package/{plugins/design/dev-server → apps/studio}/canvas-lib-resolver.ts +1 -1
  36. package/{plugins/design/dev-server → apps/studio}/canvas-lib.tsx +31 -12
  37. package/{plugins/design/dev-server → apps/studio}/canvas-shell.tsx +360 -48
  38. package/apps/studio/client/app.jsx +6742 -0
  39. package/apps/studio/client/canvas-url.js +81 -0
  40. package/{plugins/design/dev-server → apps/studio}/client/comments-overlay.css +41 -27
  41. package/apps/studio/client/index.html +16 -0
  42. package/apps/studio/client/styles/1-tokens-maude.css +296 -0
  43. package/apps/studio/client/styles/3-shell-maude.css +1161 -0
  44. package/{plugins/design/dev-server → apps/studio}/client/styles/3-shell.css +129 -0
  45. package/apps/studio/client/styles/4-components-maude.css +74 -0
  46. package/{plugins/design/dev-server → apps/studio}/client/styles/4-components.css +396 -34
  47. package/apps/studio/client/styles/5-maude-overrides.css +137 -0
  48. package/{plugins/design/dev-server → apps/studio}/client/styles/_index.css +9 -0
  49. package/{plugins/design/dev-server → apps/studio}/client/styles.css +1 -1
  50. package/apps/studio/client/tour/overlay.jsx +279 -0
  51. package/apps/studio/client/tour/usage-tour.js +48 -0
  52. package/apps/studio/client/whats-new-seen.js +52 -0
  53. package/apps/studio/client/whats-new.jsx +250 -0
  54. package/{plugins/design/dev-server → apps/studio}/commands/annotation-strokes-command.ts +2 -2
  55. package/{plugins/design/dev-server → apps/studio}/commands/equal-spacing-command.ts +1 -1
  56. package/{plugins/design/dev-server → apps/studio}/commands/move-artboards-command.ts +2 -2
  57. package/{plugins/design/dev-server → apps/studio}/comments-overlay.tsx +32 -11
  58. package/{plugins/design/dev-server → apps/studio}/context-menu.tsx +5 -4
  59. package/{plugins/design/dev-server → apps/studio}/contextual-toolbar.tsx +18 -7
  60. package/{plugins/design/dev-server → apps/studio}/cursors-overlay.tsx +21 -21
  61. package/apps/studio/dist/client.bundle.js +25545 -0
  62. package/apps/studio/dist/comment-mount.js +2046 -0
  63. package/apps/studio/dist/styles.css +8018 -0
  64. package/apps/studio/dom-selection.ts +342 -0
  65. package/apps/studio/draw/animate.ts +333 -0
  66. package/{plugins/design/dev-server → apps/studio}/draw/brush.ts +1 -1
  67. package/{plugins/design/dev-server → apps/studio}/draw/composition.ts +1 -1
  68. package/{plugins/design/dev-server → apps/studio}/draw/geometry.ts +1 -1
  69. package/{plugins/design/dev-server → apps/studio}/draw/index.ts +4 -1
  70. package/{plugins/design/dev-server → apps/studio}/draw/layout.ts +1 -1
  71. package/apps/studio/draw/morph.ts +204 -0
  72. package/{plugins/design/dev-server → apps/studio}/draw/optimize.ts +1 -1
  73. package/{plugins/design/dev-server → apps/studio}/draw/palette.ts +1 -1
  74. package/{plugins/design/dev-server → apps/studio}/draw/primitives.ts +1 -1
  75. package/apps/studio/draw/serialize-animate.ts +324 -0
  76. package/{plugins/design/dev-server → apps/studio}/draw/serialize.ts +9 -3
  77. package/apps/studio/draw/test/animate.test.ts +172 -0
  78. package/apps/studio/draw/test/morph.test.ts +107 -0
  79. package/apps/studio/draw/test/serialize-animate.test.ts +142 -0
  80. package/{plugins/design/dev-server → apps/studio}/equal-spacing-detector.ts +1 -1
  81. package/{plugins/design/dev-server → apps/studio}/equal-spacing-handles.tsx +7 -29
  82. package/{plugins/design/dev-server → apps/studio}/export-dialog.tsx +16 -4
  83. package/{plugins/design/dev-server → apps/studio}/history.ts +20 -3
  84. package/{plugins/design/dev-server → apps/studio}/http.ts +226 -6
  85. package/{plugins/design/dev-server → apps/studio}/input-router.tsx +15 -1
  86. package/{plugins/design/dev-server → apps/studio}/inspect.ts +50 -4
  87. package/{plugins/design/dev-server → apps/studio}/marquee-overlay.tsx +5 -2
  88. package/{plugins/design/dev-server → apps/studio}/participants-chrome.tsx +2 -8
  89. package/{plugins/design/dev-server → apps/studio}/paths.ts +15 -11
  90. package/{plugins/design/dev-server → apps/studio}/server.ts +23 -2
  91. package/{plugins/design/dev-server → apps/studio}/sync/agent.ts +231 -57
  92. package/{plugins/design/dev-server → apps/studio}/sync/codec.ts +45 -0
  93. package/apps/studio/sync/cold-start.ts +158 -0
  94. package/{plugins/design/dev-server → apps/studio}/sync/connection-state.ts +58 -2
  95. package/{plugins/design/dev-server → apps/studio}/sync/index.ts +563 -221
  96. package/apps/studio/sync/journal.ts +190 -0
  97. package/apps/studio/sync/migrate-seed.ts +321 -0
  98. package/{plugins/design/dev-server → apps/studio}/sync/projection.ts +22 -3
  99. package/{plugins/design/dev-server → apps/studio}/sync/status.ts +15 -4
  100. package/{plugins/design/dev-server → apps/studio}/test/activity.test.ts +1 -7
  101. package/apps/studio/test/annotate-write.test.ts +184 -0
  102. package/apps/studio/test/annotations-align.test.ts +88 -0
  103. package/apps/studio/test/annotations-bindings.test.ts +124 -0
  104. package/apps/studio/test/annotations-groups.test.ts +231 -0
  105. package/{plugins/design/dev-server → apps/studio}/test/annotations-layer.test.ts +63 -0
  106. package/{plugins/design/dev-server → apps/studio}/test/annotations-roundtrip.test.ts +97 -0
  107. package/apps/studio/test/annotations-snap.test.ts +79 -0
  108. package/apps/studio/test/annotations-text-format.test.ts +396 -0
  109. package/apps/studio/test/asset-api.test.ts +149 -0
  110. package/apps/studio/test/canvas-create-api.test.ts +361 -0
  111. package/{plugins/design/dev-server → apps/studio}/test/canvas-cursors.test.ts +2 -0
  112. package/apps/studio/test/canvas-edit.test.ts +319 -0
  113. package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-resolver.test.ts +1 -1
  114. package/apps/studio/test/canvas-media-drop.test.ts +158 -0
  115. package/{plugins/design/dev-server → apps/studio}/test/canvas-origin-gate.test.ts +25 -1
  116. package/apps/studio/test/canvas-url.test.ts +99 -0
  117. package/{plugins/design/dev-server → apps/studio}/test/collab-bridge.test.ts +0 -2
  118. package/{plugins/design/dev-server → apps/studio}/test/collab-room.test.ts +2 -7
  119. package/{plugins/design/dev-server → apps/studio}/test/csp-canvas-shell.test.ts +5 -0
  120. package/apps/studio/test/csrf-write-guard.test.ts +52 -0
  121. package/apps/studio/test/figjam-v3-model.test.ts +342 -0
  122. package/apps/studio/test/fixtures/figjam-v3-groups-bindings.svg +1 -0
  123. package/apps/studio/test/index-data-canvas-ds.test.ts +97 -0
  124. package/apps/studio/test/motion-sample.test.ts +35 -0
  125. package/{plugins/design/dev-server → apps/studio}/test/perf-harness.ts +1 -1
  126. package/{plugins/design/dev-server → apps/studio}/test/phase-3.6-smoke.test.ts +3 -1
  127. package/apps/studio/test/read-annotations.test.ts +409 -0
  128. package/{plugins/design/dev-server → apps/studio}/test/sanitize-annotation-svg.test.ts +108 -2
  129. package/{plugins/design/dev-server → apps/studio}/test/shared-doc-convergence.test.ts +1 -1
  130. package/apps/studio/test/shared-doc-migrate.test.ts +369 -0
  131. package/apps/studio/test/sync-agent.test.ts +575 -0
  132. package/{plugins/design/dev-server → apps/studio}/test/sync-codec.test.ts +65 -0
  133. package/apps/studio/test/sync-cold-start.test.ts +244 -0
  134. package/{plugins/design/dev-server → apps/studio}/test/sync-connection-state.test.ts +68 -0
  135. package/{plugins/design/dev-server → apps/studio}/test/sync-hardening.test.ts +0 -8
  136. package/{plugins/design/dev-server → apps/studio}/test/sync-hubs-config.test.ts +0 -1
  137. package/apps/studio/test/sync-incident-replay.test.ts +211 -0
  138. package/apps/studio/test/sync-journal.test.ts +176 -0
  139. package/{plugins/design/dev-server → apps/studio}/test/sync-runtime.test.ts +360 -5
  140. package/{plugins/design/dev-server → apps/studio}/test/sync-status.test.ts +66 -0
  141. package/apps/studio/test/tour-overlay.test.tsx +56 -0
  142. package/apps/studio/test/use-annotation-resize.test.ts +402 -0
  143. package/{plugins/design/dev-server → apps/studio}/test/use-artboard-drag.test.ts +0 -1
  144. package/{plugins/design/dev-server → apps/studio}/test/use-collab.test.ts +0 -0
  145. package/{plugins/design/dev-server → apps/studio}/test/use-tool-mode.test.tsx +8 -2
  146. package/apps/studio/test/whats-new.test.ts +101 -0
  147. package/apps/studio/text-imports.d.ts +9 -0
  148. package/{plugins/design/dev-server → apps/studio}/tool-palette.tsx +15 -70
  149. package/{plugins/design/dev-server → apps/studio}/undo-hud.tsx +1 -2
  150. package/{plugins/design/dev-server → apps/studio}/undo-stack.ts +1 -1
  151. package/{plugins/design/dev-server → apps/studio}/use-agent-presence.tsx +5 -3
  152. package/apps/studio/use-annotation-resize.tsx +912 -0
  153. package/{plugins/design/dev-server → apps/studio}/use-annotation-selection.tsx +17 -5
  154. package/{plugins/design/dev-server → apps/studio}/use-annotations-visibility.tsx +1 -1
  155. package/{plugins/design/dev-server → apps/studio}/use-artboard-drag.tsx +1 -1
  156. package/{plugins/design/dev-server → apps/studio}/use-canvas-activity.tsx +3 -3
  157. package/apps/studio/use-canvas-media-drop.tsx +343 -0
  158. package/{plugins/design/dev-server → apps/studio}/use-collab.tsx +21 -16
  159. package/{plugins/design/dev-server → apps/studio}/use-cursor-modifiers.tsx +1 -1
  160. package/{plugins/design/dev-server → apps/studio}/use-keyboard-discipline.tsx +5 -2
  161. package/{plugins/design/dev-server → apps/studio}/use-selection-set.tsx +18 -1
  162. package/{plugins/design/dev-server → apps/studio}/use-snap-guides.tsx +1 -1
  163. package/{plugins/design/dev-server → apps/studio}/use-tool-mode.tsx +8 -2
  164. package/{plugins/design/dev-server → apps/studio}/use-undo-stack.tsx +1 -1
  165. package/apps/studio/whats-new.json +264 -0
  166. package/apps/studio/whats-new.schema.json +86 -0
  167. package/apps/studio/whats-new.ts +87 -0
  168. package/cli/bin/maude.mjs +10 -0
  169. package/cli/commands/design-link.test.mjs +84 -0
  170. package/cli/commands/design.mjs +16 -7
  171. package/cli/commands/design.test.mjs +40 -0
  172. package/cli/commands/help.mjs +8 -2
  173. package/cli/commands/hub.mjs +3 -3
  174. package/cli/commands/hub.test.mjs +1 -1
  175. package/cli/commands/scenario-report.mjs +2 -9
  176. package/cli/lib/design-link.mjs +51 -1
  177. package/cli/lib/flow-design-integration.test.mjs +1 -1
  178. package/cli/lib/gitignore-block.mjs +1 -0
  179. package/cli/lib/plugin-cli-reachability.test.mjs +8 -7
  180. package/cli/lib/preflight.mjs +1 -1
  181. package/package.json +15 -15
  182. package/plugins/design/templates/_shell.html +28 -4
  183. package/plugins/design/templates/brief-board.tsx.template +61 -0
  184. package/plugins/design/templates/canvas.tsx.template +1 -1
  185. package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +1 -1
  186. package/plugins/design/templates/design-system-inspiration/core/preview/_motion-readme.md.tpl +1 -1
  187. package/plugins/flow/.claude-plugin/config.schema.json +16 -0
  188. package/plugins/design/dev-server/annotations-layer.tsx +0 -3402
  189. package/plugins/design/dev-server/client/app.jsx +0 -2985
  190. package/plugins/design/dev-server/client/index.html +0 -15
  191. package/plugins/design/dev-server/dist/client.bundle.js +0 -20692
  192. package/plugins/design/dev-server/dist/comment-mount.js +0 -1924
  193. package/plugins/design/dev-server/dist/styles.css +0 -2710
  194. package/plugins/design/dev-server/dom-selection.ts +0 -156
  195. package/plugins/design/dev-server/sync/migrate-seed.ts +0 -163
  196. package/plugins/design/dev-server/test/canvas-edit.test.ts +0 -139
  197. package/plugins/design/dev-server/test/shared-doc-migrate.test.ts +0 -159
  198. package/plugins/design/dev-server/test/sync-agent.test.ts +0 -305
  199. package/plugins/design/dev-server/test/use-annotation-resize.test.ts +0 -200
  200. package/plugins/design/dev-server/use-annotation-resize.tsx +0 -449
  201. /package/{plugins/design/dev-server → apps/studio}/activity.ts +0 -0
  202. /package/{plugins/design/dev-server → apps/studio}/bin/_enumerate-artboards-playwright.mjs +0 -0
  203. /package/{plugins/design/dev-server → apps/studio}/bin/_html-playwright.mjs +0 -0
  204. /package/{plugins/design/dev-server → apps/studio}/bin/_pdf-playwright.mjs +0 -0
  205. /package/{plugins/design/dev-server → apps/studio}/bin/_pptx-playwright.mjs +0 -0
  206. /package/{plugins/design/dev-server → apps/studio}/bin/_pw-launch.mjs +0 -0
  207. /package/{plugins/design/dev-server → apps/studio}/bin/_screenshot-playwright.mjs +0 -0
  208. /package/{plugins/design/dev-server → apps/studio}/bin/_svg-optimize.mjs +0 -0
  209. /package/{plugins/design/dev-server → apps/studio}/bin/_svg-playwright.mjs +0 -0
  210. /package/{plugins/design/dev-server → apps/studio}/bin/asset-sweep.sh +0 -0
  211. /package/{plugins/design/dev-server → apps/studio}/bin/bootstrap-check.sh +0 -0
  212. /package/{plugins/design/dev-server → apps/studio}/bin/check-runtime-bundles.sh +0 -0
  213. /package/{plugins/design/dev-server → apps/studio}/bin/draw-build.sh +0 -0
  214. /package/{plugins/design/dev-server → apps/studio}/bin/handoff.sh +0 -0
  215. /package/{plugins/design/dev-server → apps/studio}/bin/prep.sh +0 -0
  216. /package/{plugins/design/dev-server → apps/studio}/bin/scenario-report.mjs +0 -0
  217. /package/{plugins/design/dev-server → apps/studio}/bin/slug.sh +0 -0
  218. /package/{plugins/design/dev-server → apps/studio}/bin/smoke.sh +0 -0
  219. /package/{plugins/design/dev-server → apps/studio}/bin/svg-optimize.sh +0 -0
  220. /package/{plugins/design/dev-server → apps/studio}/bin/visual-sanity.sh +0 -0
  221. /package/{plugins/design/dev-server → apps/studio}/boot-self-heal.ts +0 -0
  222. /package/{plugins/design/dev-server → apps/studio}/canvas-build.ts +0 -0
  223. /package/{plugins/design/dev-server → apps/studio}/canvas-header.ts +0 -0
  224. /package/{plugins/design/dev-server → apps/studio}/canvas-meta.schema.json +0 -0
  225. /package/{plugins/design/dev-server → apps/studio}/canvas-pipeline.ts +0 -0
  226. /package/{plugins/design/dev-server → apps/studio}/client/hmr.mjs +0 -0
  227. /package/{plugins/design/dev-server → apps/studio}/client/iframe-lazy.mjs +0 -0
  228. /package/{plugins/design/dev-server → apps/studio}/client/styles/0-reset.css +0 -0
  229. /package/{plugins/design/dev-server → apps/studio}/client/styles/1-tokens.css +0 -0
  230. /package/{plugins/design/dev-server → apps/studio}/client/styles/2-layout.css +0 -0
  231. /package/{plugins/design/dev-server → apps/studio}/client/styles/5-utilities.css +0 -0
  232. /package/{plugins/design/dev-server → apps/studio}/collab/ai-activity.ts +0 -0
  233. /package/{plugins/design/dev-server → apps/studio}/collab/awareness-bridge.ts +0 -0
  234. /package/{plugins/design/dev-server → apps/studio}/collab/git-lifecycle.ts +0 -0
  235. /package/{plugins/design/dev-server → apps/studio}/collab/index.ts +0 -0
  236. /package/{plugins/design/dev-server → apps/studio}/collab/persistence.ts +0 -0
  237. /package/{plugins/design/dev-server → apps/studio}/collab/protocol.ts +0 -0
  238. /package/{plugins/design/dev-server → apps/studio}/collab/registry.ts +0 -0
  239. /package/{plugins/design/dev-server → apps/studio}/collab/room.ts +0 -0
  240. /package/{plugins/design/dev-server → apps/studio}/config.schema.json +0 -0
  241. /package/{plugins/design/dev-server → apps/studio}/context.ts +0 -0
  242. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/.min-sizes.json +0 -0
  243. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/lib0_decoding.js +0 -0
  244. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/lib0_encoding.js +0 -0
  245. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/motion.js +0 -0
  246. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/motion_react.js +0 -0
  247. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/pixi-js.js +0 -0
  248. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react-dom.js +0 -0
  249. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react-dom_client.js +0 -0
  250. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react.js +0 -0
  251. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react_jsx-dev-runtime.js +0 -0
  252. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react_jsx-runtime.js +0 -0
  253. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/y-protocols_awareness.js +0 -0
  254. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/y-protocols_sync.js +0 -0
  255. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/yjs.js +0 -0
  256. /package/{plugins/design/dev-server → apps/studio}/draw/test/brush.test.ts +0 -0
  257. /package/{plugins/design/dev-server → apps/studio}/draw/test/composition.test.ts +0 -0
  258. /package/{plugins/design/dev-server → apps/studio}/draw/test/geometry.test.ts +0 -0
  259. /package/{plugins/design/dev-server → apps/studio}/draw/test/gradient.test.ts +0 -0
  260. /package/{plugins/design/dev-server → apps/studio}/draw/test/layout.test.ts +0 -0
  261. /package/{plugins/design/dev-server → apps/studio}/draw/test/optimize.test.ts +0 -0
  262. /package/{plugins/design/dev-server → apps/studio}/draw/test/palette.test.ts +0 -0
  263. /package/{plugins/design/dev-server → apps/studio}/draw/test/primitives.test.ts +0 -0
  264. /package/{plugins/design/dev-server → apps/studio}/draw/test/serialize.test.ts +0 -0
  265. /package/{plugins/design/dev-server → apps/studio}/examples/README.md +0 -0
  266. /package/{plugins/design/dev-server → apps/studio}/examples/perf-100-artboards.tsx +0 -0
  267. /package/{plugins/design/dev-server → apps/studio}/exporters/_browser-bundles.ts +0 -0
  268. /package/{plugins/design/dev-server → apps/studio}/exporters/canva-handoff-prompt.ts +0 -0
  269. /package/{plugins/design/dev-server → apps/studio}/exporters/canva.ts +0 -0
  270. /package/{plugins/design/dev-server → apps/studio}/exporters/html.ts +0 -0
  271. /package/{plugins/design/dev-server → apps/studio}/exporters/index.ts +0 -0
  272. /package/{plugins/design/dev-server → apps/studio}/exporters/pdf.ts +0 -0
  273. /package/{plugins/design/dev-server → apps/studio}/exporters/png.ts +0 -0
  274. /package/{plugins/design/dev-server → apps/studio}/exporters/pptx.ts +0 -0
  275. /package/{plugins/design/dev-server → apps/studio}/exporters/scope.ts +0 -0
  276. /package/{plugins/design/dev-server → apps/studio}/exporters/svg.ts +0 -0
  277. /package/{plugins/design/dev-server → apps/studio}/exporters/zip.ts +0 -0
  278. /package/{plugins/design/dev-server → apps/studio}/fs-watch.ts +0 -0
  279. /package/{plugins/design/dev-server → apps/studio}/handoff.ts +0 -0
  280. /package/{plugins/design/dev-server → apps/studio}/hmr-broadcast.ts +0 -0
  281. /package/{plugins/design/dev-server → apps/studio}/locator.ts +0 -0
  282. /package/{plugins/design/dev-server → apps/studio}/mem.ts +0 -0
  283. /package/{plugins/design/dev-server → apps/studio}/runtime-bundle.ts +0 -0
  284. /package/{plugins/design/dev-server → apps/studio}/server.mjs +0 -0
  285. /package/{plugins/design/dev-server → apps/studio}/sync/atomic-write.ts +0 -0
  286. /package/{plugins/design/dev-server → apps/studio}/sync/echo-guard.ts +0 -0
  287. /package/{plugins/design/dev-server → apps/studio}/sync/fs-mirror.ts +0 -0
  288. /package/{plugins/design/dev-server → apps/studio}/sync/hubs-config.ts +0 -0
  289. /package/{plugins/design/dev-server → apps/studio}/sync/materialize.ts +0 -0
  290. /package/{plugins/design/dev-server → apps/studio}/sync/origins.ts +0 -0
  291. /package/{plugins/design/dev-server → apps/studio}/sync/untrusted.ts +0 -0
  292. /package/{plugins/design/dev-server → apps/studio}/test/_helpers.ts +0 -0
  293. /package/{plugins/design/dev-server → apps/studio}/test/active-state.test.ts +0 -0
  294. /package/{plugins/design/dev-server → apps/studio}/test/ai-activity.test.ts +0 -0
  295. /package/{plugins/design/dev-server → apps/studio}/test/annotation-strokes-command.test.ts +0 -0
  296. /package/{plugins/design/dev-server → apps/studio}/test/annotations-api.test.ts +0 -0
  297. /package/{plugins/design/dev-server → apps/studio}/test/annotations-draw-modifiers.test.ts +0 -0
  298. /package/{plugins/design/dev-server → apps/studio}/test/artboard-activity-overlay.test.tsx +0 -0
  299. /package/{plugins/design/dev-server → apps/studio}/test/binary-smoke.test.ts +0 -0
  300. /package/{plugins/design/dev-server → apps/studio}/test/boot-self-heal.test.ts +0 -0
  301. /package/{plugins/design/dev-server → apps/studio}/test/bundle-smoke.test.ts +0 -0
  302. /package/{plugins/design/dev-server → apps/studio}/test/canvas-build.test.ts +0 -0
  303. /package/{plugins/design/dev-server → apps/studio}/test/canvas-header.test.ts +0 -0
  304. /package/{plugins/design/dev-server → apps/studio}/test/canvas-hmr-runtime.test.tsx +0 -0
  305. /package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-inline.test.ts +0 -0
  306. /package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-motion.test.ts +0 -0
  307. /package/{plugins/design/dev-server → apps/studio}/test/canvas-meta-api.test.ts +0 -0
  308. /package/{plugins/design/dev-server → apps/studio}/test/canvas-pipeline.test.ts +0 -0
  309. /package/{plugins/design/dev-server → apps/studio}/test/canvas-route.test.ts +0 -0
  310. /package/{plugins/design/dev-server → apps/studio}/test/collab-annotations-bridge.test.ts +0 -0
  311. /package/{plugins/design/dev-server → apps/studio}/test/collab-awareness-bridge.test.ts +0 -0
  312. /package/{plugins/design/dev-server → apps/studio}/test/collab-loopback.test.ts +0 -0
  313. /package/{plugins/design/dev-server → apps/studio}/test/collab-protocol.test.ts +0 -0
  314. /package/{plugins/design/dev-server → apps/studio}/test/collab-reseed-guard.test.ts +0 -0
  315. /package/{plugins/design/dev-server → apps/studio}/test/collab-stress.test.ts +0 -0
  316. /package/{plugins/design/dev-server → apps/studio}/test/comment-mount.test.ts +0 -0
  317. /package/{plugins/design/dev-server → apps/studio}/test/comments-api.test.ts +0 -0
  318. /package/{plugins/design/dev-server → apps/studio}/test/compile-entry.test.ts +0 -0
  319. /package/{plugins/design/dev-server → apps/studio}/test/context-resolve-tokens.test.ts +0 -0
  320. /package/{plugins/design/dev-server → apps/studio}/test/equal-spacing-detector.test.ts +0 -0
  321. /package/{plugins/design/dev-server → apps/studio}/test/exporters/canva.test.ts +0 -0
  322. /package/{plugins/design/dev-server → apps/studio}/test/exporters/endpoint.test.ts +0 -0
  323. /package/{plugins/design/dev-server → apps/studio}/test/exporters/history.test.ts +0 -0
  324. /package/{plugins/design/dev-server → apps/studio}/test/exporters/html.test.ts +0 -0
  325. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pdf.test.ts +0 -0
  326. /package/{plugins/design/dev-server → apps/studio}/test/exporters/png.test.ts +0 -0
  327. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx-deck.test.ts +0 -0
  328. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx.test.ts +0 -0
  329. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pw-launch.test.ts +0 -0
  330. /package/{plugins/design/dev-server → apps/studio}/test/exporters/scope.test.ts +0 -0
  331. /package/{plugins/design/dev-server → apps/studio}/test/exporters/svg.test.ts +0 -0
  332. /package/{plugins/design/dev-server → apps/studio}/test/exporters/zip.test.ts +0 -0
  333. /package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-20-annotations.svg +0 -0
  334. /package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-21-annotations.svg +0 -0
  335. /package/{plugins/design/dev-server → apps/studio}/test/fs-watch.test.ts +0 -0
  336. /package/{plugins/design/dev-server → apps/studio}/test/git-lifecycle.test.ts +0 -0
  337. /package/{plugins/design/dev-server → apps/studio}/test/handoff-static-frames.test.ts +0 -0
  338. /package/{plugins/design/dev-server → apps/studio}/test/handoff.test.ts +0 -0
  339. /package/{plugins/design/dev-server → apps/studio}/test/history-rollback.test.ts +0 -0
  340. /package/{plugins/design/dev-server → apps/studio}/test/hmr-broadcast.test.ts +0 -0
  341. /package/{plugins/design/dev-server → apps/studio}/test/hmr-classify.test.ts +0 -0
  342. /package/{plugins/design/dev-server → apps/studio}/test/input-router.test.ts +0 -0
  343. /package/{plugins/design/dev-server → apps/studio}/test/locator.test.ts +0 -0
  344. /package/{plugins/design/dev-server → apps/studio}/test/marquee-overlay.test.ts +0 -0
  345. /package/{plugins/design/dev-server → apps/studio}/test/move-artboards-command.test.ts +0 -0
  346. /package/{plugins/design/dev-server → apps/studio}/test/participants-chrome.test.ts +0 -0
  347. /package/{plugins/design/dev-server → apps/studio}/test/paths.test.ts +0 -0
  348. /package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle-error-mapping.test.ts +0 -0
  349. /package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle.test.ts +0 -0
  350. /package/{plugins/design/dev-server → apps/studio}/test/server-lifecycle.test.ts +0 -0
  351. /package/{plugins/design/dev-server → apps/studio}/test/shared-doc-foundation.test.ts +0 -0
  352. /package/{plugins/design/dev-server → apps/studio}/test/shared-doc-projection.test.ts +0 -0
  353. /package/{plugins/design/dev-server → apps/studio}/test/snap-distance-pill.test.ts +0 -0
  354. /package/{plugins/design/dev-server → apps/studio}/test/sync-atomic-write.test.ts +0 -0
  355. /package/{plugins/design/dev-server → apps/studio}/test/sync-echo-guard.test.ts +0 -0
  356. /package/{plugins/design/dev-server → apps/studio}/test/sync-fs-mirror.test.ts +0 -0
  357. /package/{plugins/design/dev-server → apps/studio}/test/sync-meta-codec.test.ts +0 -0
  358. /package/{plugins/design/dev-server → apps/studio}/test/sync-untrusted.test.ts +0 -0
  359. /package/{plugins/design/dev-server → apps/studio}/test/system-endpoint.test.ts +0 -0
  360. /package/{plugins/design/dev-server → apps/studio}/test/tool-palette.test.tsx +0 -0
  361. /package/{plugins/design/dev-server → apps/studio}/test/undo-stack.test.ts +0 -0
  362. /package/{plugins/design/dev-server → apps/studio}/test/use-agent-presence.test.tsx +0 -0
  363. /package/{plugins/design/dev-server → apps/studio}/test/use-annotation-selection.test.tsx +0 -0
  364. /package/{plugins/design/dev-server → apps/studio}/test/use-canvas-activity.test.tsx +0 -0
  365. /package/{plugins/design/dev-server → apps/studio}/test/use-cursor-modifiers.test.ts +0 -0
  366. /package/{plugins/design/dev-server → apps/studio}/test/use-keyboard-discipline.test.ts +0 -0
  367. /package/{plugins/design/dev-server → apps/studio}/test/use-selection-set.test.tsx +0 -0
  368. /package/{plugins/design/dev-server → apps/studio}/test/use-snap-guides.test.ts +0 -0
  369. /package/{plugins/design/dev-server → apps/studio}/test/use-undo-stack.test.tsx +0 -0
  370. /package/{plugins/design/dev-server → apps/studio}/test/ws-handshake.test.ts +0 -0
  371. /package/{plugins/design/dev-server → apps/studio}/tsconfig.json +0 -0
  372. /package/{plugins/design/dev-server → apps/studio}/ws.ts +0 -0
@@ -0,0 +1,137 @@
1
+ /* @layer components — maude redesign of the remaining legacy shell surfaces (Plan B).
2
+ *
3
+ * The HelpModal, in-app tour, what's-new (toast/panel), SystemView and CommentBar
4
+ * still carry their original project-DS "industrial catalogue" structure — hard
5
+ * offset shadows (`8px 8px 0`), full-contrast `--u-fg-0` borders, all-mono type,
6
+ * square edges, far-right-pushed description columns. Even after the `--u-*`
7
+ * bridge made them maude-COLORED, the STRUCTURE read as old. These overrides
8
+ * restyle them to the maude material (soft elevation, hairline borders, soft
9
+ * radii, Inter body + mono labels) WITHOUT rewriting their JSX. Scoped under
10
+ * `.maude` so they win over the legacy `@layer components` rules and only apply
11
+ * inside the studio shell. Remove a block once its surface is ported to `.st-*`.
12
+ */
13
+
14
+ @layer components {
15
+
16
+ /* ─── HelpModal ────────────────────────────────────────────────────────────── */
17
+ .maude .help-modal {
18
+ background: var(--bg-2);
19
+ border: 1px solid var(--border-strong);
20
+ border-radius: var(--radius-lg);
21
+ box-shadow: var(--shadow-lg);
22
+ font-family: var(--font-body);
23
+ }
24
+ .maude .help-modal-backdrop { background: color-mix(in oklab, var(--bg-0) 62%, transparent); }
25
+ .maude .help-modal-hd {
26
+ border-bottom: 1px solid var(--border-subtle);
27
+ background: var(--bg-1);
28
+ /* title + SKU sat glued together (flex space-between, no gap) */
29
+ justify-content: flex-start;
30
+ gap: var(--space-4);
31
+ }
32
+ .maude .help-modal-hd .title { font-family: var(--font-display); font-weight: 600; letter-spacing: var(--tracking-tight); text-transform: none; color: var(--fg-0); }
33
+ .maude .help-modal-hd .sku { font-family: var(--font-mono); color: var(--fg-3); }
34
+ .maude .help-modal-close { color: var(--fg-2); border-radius: var(--radius-sm); }
35
+ .maude .help-modal-close:hover { background: var(--bg-3); color: var(--fg-0); }
36
+ .maude .help-modal-body details { border-bottom: 1px solid var(--border-subtle); }
37
+ .maude .help-modal-body details > summary { color: var(--fg-2); font-family: var(--font-mono); letter-spacing: var(--tracking-wide); }
38
+ .maude .help-modal-body details[open] > summary { color: var(--fg-0); }
39
+ .maude .help-modal-body ul, .maude .help-modal-body ol { font-family: var(--font-body); }
40
+ /* the load-bearing fix — descriptions sat far-right (margin-left:auto). Pull them
41
+ inline-left next to the key so each row reads as a definition, maude-style. */
42
+ .maude .help-modal-body li { gap: var(--space-3); }
43
+ .maude .help-modal-body li > span { margin-left: 0; text-align: left; color: var(--fg-2); font-size: var(--type-xs); }
44
+ .maude .help-modal-body li > code,
45
+ .maude .help-modal-body .cmds code { font-family: var(--font-mono); background: var(--bg-3); color: var(--accent); border-radius: var(--radius-xs); }
46
+ .maude .help-modal-body kbd {
47
+ font-family: var(--font-mono); background: var(--bg-2); color: var(--fg-1);
48
+ border: 1px solid var(--border-default); border-bottom-width: 2px; border-radius: var(--radius-xs);
49
+ }
50
+ .maude .mdcc-tour__back { background: var(--bg-3); color: var(--fg-1); border: 1px solid var(--border-default); border-radius: var(--radius-sm); font-family: var(--font-body); }
51
+ .maude .mdcc-tour__back:hover { background: var(--bg-4); color: var(--fg-0); }
52
+
53
+ /* ─── In-app tour ──────────────────────────────────────────────────────────── */
54
+ .maude .mdcc-tour__card, .mdcc-tour__card {
55
+ background: var(--bg-2); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
56
+ box-shadow: var(--shadow-lg); font-family: var(--font-body); color: var(--fg-0);
57
+ }
58
+ .mdcc-tour__title { font-family: var(--font-display); font-weight: 600; letter-spacing: var(--tracking-tight); color: var(--fg-0); }
59
+ .mdcc-tour__body { color: var(--fg-1); font-family: var(--font-body); }
60
+ .mdcc-tour__step { font-family: var(--font-mono); color: var(--fg-3); }
61
+ .mdcc-tour__spot { border-radius: var(--radius-md); box-shadow: 0 0 0 2px var(--accent), 0 0 0 9999px color-mix(in oklab, var(--bg-0) 55%, transparent); }
62
+ .mdcc-tour__next { background: var(--accent); color: var(--accent-fg); border: 1px solid var(--accent); border-radius: var(--radius-sm); font-family: var(--font-body); font-weight: 500; }
63
+ .mdcc-tour__next:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
64
+ .mdcc-tour__skip { background: transparent; color: var(--fg-2); border: 0; font-family: var(--font-body); }
65
+ .mdcc-tour__skip:hover { color: var(--fg-0); }
66
+
67
+ /* tour nudge (first-run) */
68
+ .maude .mdcc-tour-nudge {
69
+ background: var(--bg-2); border: 1px solid var(--border-default); border-left: 3px solid var(--accent);
70
+ border-radius: var(--radius-md); box-shadow: var(--shadow-lg); font-family: var(--font-body); color: var(--fg-1);
71
+ /* raised above the in-canvas zoom pill (bottom-left), same as .st-toast */
72
+ bottom: 84px;
73
+ }
74
+ .maude .mdcc-tour-nudge__cta { background: var(--accent); color: var(--accent-fg); border: 0; border-radius: var(--radius-sm); font-family: var(--font-body); font-weight: 500; }
75
+ .maude .mdcc-tour-nudge__cta:hover { background: var(--accent-hover); }
76
+ .maude .mdcc-tour-nudge__skip { color: var(--fg-3); }
77
+ .maude .mdcc-tour-nudge__skip:hover { color: var(--fg-0); }
78
+
79
+ /* ─── What's-new (toast / panel) ───────────────────────────────────────────── */
80
+ .maude .mdcc-wn-toast, .mdcc-wn-toast {
81
+ background: var(--bg-2); border: 1px solid var(--border-default); border-left: 3px solid var(--accent);
82
+ border-radius: var(--radius-md); box-shadow: var(--shadow-lg); font-family: var(--font-body); color: var(--fg-1);
83
+ }
84
+ .mdcc-wn-toast__mark { color: var(--accent); }
85
+ .mdcc-wn-toast__title { font-family: var(--font-display); font-weight: 600; color: var(--fg-0); }
86
+ .mdcc-wn-toast__summary { color: var(--fg-1); }
87
+ .mdcc-wn-toast__cta { background: var(--accent); color: var(--accent-fg); border: 0; border-radius: var(--radius-sm); font-family: var(--font-body); font-weight: 500; }
88
+ .mdcc-wn-toast__cta:hover { background: var(--accent-hover); }
89
+ .mdcc-wn-toast__close { color: var(--fg-3); border-radius: var(--radius-sm); }
90
+ .mdcc-wn-toast__close:hover { background: var(--bg-3); color: var(--fg-0); }
91
+ .maude .mdcc-wn-panel, .mdcc-wn-panel {
92
+ background: var(--bg-2); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
93
+ box-shadow: var(--shadow-lg); font-family: var(--font-body); color: var(--fg-0);
94
+ }
95
+ .mdcc-wn-item { border-bottom: 1px solid var(--border-subtle); }
96
+ .mdcc-wn-item__title { font-family: var(--font-display); font-weight: 600; color: var(--fg-0); }
97
+ .mdcc-wn-item__ver { font-family: var(--font-mono); color: var(--fg-3); }
98
+ .mdcc-wn-item__summary { color: var(--fg-1); }
99
+ .mdcc-wn-kind { font-family: var(--font-mono); letter-spacing: var(--tracking-wide); text-transform: uppercase; font-size: 10px; color: var(--accent); background: var(--accent-tint); border-radius: var(--radius-pill); padding: 1px 7px; }
100
+ .mdcc-wn-item__tour, .mdcc-wn-item__more { color: var(--accent); font-family: var(--font-body); background: transparent; border: 0; }
101
+ .mdcc-wn-empty { color: var(--fg-3); }
102
+
103
+ /* ─── SystemView (DS overview) ─────────────────────────────────────────────── */
104
+ .maude .sv { font-family: var(--font-body); color: var(--fg-0); }
105
+ .maude .sv-header { border-bottom: 1px solid var(--border-subtle); }
106
+ .maude .sv-sku { font-family: var(--font-mono); color: var(--accent); letter-spacing: var(--tracking-wide); }
107
+ .maude .sv-title { font-family: var(--font-display); font-weight: 600; letter-spacing: var(--tracking-tight); color: var(--fg-0); text-transform: none; }
108
+ .maude .sv-loc code { font-family: var(--font-mono); color: var(--fg-3); }
109
+ .maude .sv-ds-picker { font-family: var(--font-mono); color: var(--fg-2); }
110
+ .maude .sv-ds-picker select { background: var(--bg-3); color: var(--fg-0); border: 1px solid var(--border-default); border-radius: var(--radius-sm); font-family: var(--font-mono); padding: 2px 6px; }
111
+ .maude .sv-ds-description { color: var(--fg-1); font-family: var(--font-body); }
112
+ .maude .sv-section h2 { font-family: var(--font-mono); color: var(--fg-2); letter-spacing: var(--tracking-wide); text-transform: uppercase; font-size: var(--type-xs); border-bottom: 1px solid var(--border-subtle); }
113
+ .maude .sv-h-num, .maude .sv-count { font-family: var(--font-mono); color: var(--fg-3); }
114
+ .maude .sv-tok-cell { border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-1); overflow: hidden; }
115
+ .maude .sv-tok-swatch { border-radius: 0; }
116
+ /* token meta — the legacy side-by-side row wrapped long names across 3 lines
117
+ * ("--presence-" / "offline"); stack name over value, each on one nowrap line. */
118
+ .maude .sv-tok-meta {
119
+ flex-direction: column;
120
+ align-items: flex-start;
121
+ justify-content: flex-start;
122
+ gap: 1px;
123
+ padding: var(--space-2) var(--space-3);
124
+ }
125
+ .maude .sv-tok-name { font-family: var(--font-mono); color: var(--fg-0); white-space: nowrap; max-width: 100%; }
126
+ .maude .sv-tok-value { font-family: var(--font-mono); color: var(--fg-2); max-width: 100%; }
127
+ .maude .sv-type-row { border-bottom: 1px solid var(--border-subtle); }
128
+ .maude .sv-type-tok { font-family: var(--font-mono); color: var(--fg-2); }
129
+ .maude .sv-preview-card { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--bg-1); overflow: hidden; box-shadow: var(--shadow-sm); }
130
+ .maude .sv-preview-card:hover { border-color: var(--border-default); box-shadow: var(--shadow-md); }
131
+ .maude .sv-preview-foot { font-family: var(--font-mono); }
132
+ .maude .sv-preview-foot strong { color: var(--fg-0); font-family: var(--font-body); }
133
+ .maude .sv-preview-foot code { color: var(--fg-3); }
134
+ .maude .sv-empty { color: var(--fg-3); }
135
+ .maude .sv-empty code { font-family: var(--font-mono); background: var(--bg-3); color: var(--accent); border-radius: var(--radius-xs); padding: 1px 5px; }
136
+
137
+ }
@@ -18,7 +18,16 @@
18
18
 
19
19
  @import url('./0-reset.css');
20
20
  @import url('./1-tokens.css');
21
+ /* Plan B — maude DS token ladder, scoped under `.maude[data-theme]` (additive;
22
+ drives the rewritten `.st-*` chrome without disturbing the legacy amber tokens). */
23
+ @import url('./1-tokens-maude.css');
21
24
  @import url('./2-layout.css');
22
25
  @import url('./3-shell.css');
26
+ /* Plan B — maude DS studio chrome (.st-* ported from Studio.css), grown per slice. */
27
+ @import url('./3-shell-maude.css');
23
28
  @import url('./4-components.css');
29
+ /* Plan B — maude DS shared component classes (.btn/.kbd/.callout), scoped under `.maude`. */
30
+ @import url('./4-components-maude.css');
31
+ /* Plan B — maude redesign of remaining legacy shell surfaces (HelpModal, tour, what's-new, SystemView, CommentBar). */
32
+ @import url('./5-maude-overrides.css');
24
33
  @import url('./5-utilities.css');
@@ -974,7 +974,7 @@ button { font: inherit; }
974
974
  }
975
975
  /* Phase 6 — the shell-side composer / focused-row / pin-strip surfaces are
976
976
  * gone; pins + composer + thread popover live inside the canvas iframe
977
- * (plugins/design/dev-server/comments-overlay.{tsx,css}). The remaining
977
+ * (apps/studio/comments-overlay.{tsx,css}). The remaining
978
978
  * `.comment-bar` and `.cb-row.strip` rules below render the residual
979
979
  * open-count summary the shell still surfaces in the BottomBar. */
980
980
 
@@ -0,0 +1,279 @@
1
+ // overlay.jsx — hand-rolled guided-tour engine (zero runtime dep, DDR-B).
2
+ //
3
+ // One <TourOverlay steps={[…]} open onClose onComplete bus hasSelection hasCanvas/>
4
+ // drives both the per-feature spotlight tours (a What's New entry's `tour[]`) and
5
+ // the evergreen usage tour.
6
+ //
7
+ // A step is { target, title, body, placement?, ...setup }. The engine does more
8
+ // than spotlight: before each step it puts the shell into the state the target
9
+ // needs, then waits for the element to actually render before measuring — so the
10
+ // tour *walks the user through the live feature* instead of floating a modal over
11
+ // a missing element. Setup directives (all optional):
12
+ // canvas: true → ensure a canvas is open (bus.setup opens the first)
13
+ // inspector: true → open the right-hand Inspector
14
+ // tab: 'inspect'|'layers'|'css' → switch the Inspector tab
15
+ // requireSelection: true → the target only exists once an element is ⌘-clicked
16
+ // in the canvas; the card shows a "⌘-click to continue"
17
+ // hint and the spotlight snaps onto the real row the
18
+ // moment a selection lands.
19
+ // A step whose target still can't be resolved shows centered (no spotlight) — the
20
+ // tour never dead-ends on a missing element.
21
+ //
22
+ // A11y: role="dialog" + aria-modal, focus moves to the primary button on each
23
+ // step and is trapped within the card, focus is restored on close, Esc skips,
24
+ // ←/→ navigate. prefers-reduced-motion disables the spotlight transition.
25
+
26
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
27
+
28
+ function getRect(target) {
29
+ if (typeof document === 'undefined' || !target) return null;
30
+ try {
31
+ const el = document.querySelector(target);
32
+ if (!el) return null;
33
+ const r = el.getBoundingClientRect();
34
+ if (r.width === 0 && r.height === 0) return null;
35
+ return r;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
41
+ const CARD_W = 320;
42
+ const CARD_H_EST = 184;
43
+
44
+ function computeCardStyle(rect) {
45
+ if (typeof window === 'undefined' || !rect) {
46
+ return { top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: CARD_W };
47
+ }
48
+ const vw = window.innerWidth;
49
+ const vh = window.innerHeight;
50
+ const placeLeft = rect.left > CARD_W + 36 && vw - rect.right < CARD_W + 36;
51
+ if (placeLeft) {
52
+ // Panel-on-the-right targets (the Inspector): park the card to its left so it
53
+ // never covers the very thing it's pointing at.
54
+ const top = Math.min(Math.max(12, rect.top), vh - CARD_H_EST - 12);
55
+ return { top, left: Math.max(12, rect.left - CARD_W - 16), width: CARD_W };
56
+ }
57
+ const roomBelow = vh - rect.bottom;
58
+ const top =
59
+ roomBelow > CARD_H_EST + 24 ? rect.bottom + 12 : Math.max(12, rect.top - CARD_H_EST - 12);
60
+ const left = Math.min(Math.max(12, rect.left), vw - CARD_W - 12);
61
+ return { top, left, width: CARD_W };
62
+ }
63
+
64
+ export function TourOverlay({ steps, open, onClose, onComplete, bus, hasSelection, hasCanvas }) {
65
+ const [i, setI] = useState(0);
66
+ const [rect, setRect] = useState(null);
67
+ const cardRef = useRef(null);
68
+ const prevFocus = useRef(null);
69
+ const pollRef = useRef(null);
70
+ // The bus is rebuilt by the parent on every render; ref it so its identity
71
+ // churn never re-triggers the per-step setup effect (which would thrash).
72
+ const busRef = useRef(bus);
73
+ busRef.current = bus;
74
+
75
+ const step = steps[i] || null;
76
+
77
+ const measure = useCallback(() => {
78
+ if (!step) {
79
+ setRect(null);
80
+ return null;
81
+ }
82
+ const r = getRect(step.target);
83
+ setRect(r);
84
+ return r;
85
+ }, [step]);
86
+
87
+ // Reset to the first step whenever a tour (re)opens.
88
+ useEffect(() => {
89
+ if (open) setI(0);
90
+ }, [open]);
91
+
92
+ // Per-step: run the step's setup (open canvas / inspector / switch tab), then
93
+ // poll for the target to render before settling on a measurement. React state
94
+ // updates + the canvas-shell round-trip are async, so a single synchronous
95
+ // querySelector almost always misses on the first frame.
96
+ // biome-ignore lint/correctness/useExhaustiveDependencies: re-run only on step/selection change; bus + measure reached via ref/stable closures on purpose.
97
+ useLayoutEffect(() => {
98
+ if (!open || !step) return undefined;
99
+ let cancelled = false;
100
+ setRect(null);
101
+
102
+ // Establish the UI state this step wants to highlight.
103
+ try {
104
+ busRef.current?.setup?.(step);
105
+ } catch {}
106
+
107
+ let tries = 0;
108
+ const MAX = 24; // ~3s at 130ms
109
+ const tick = () => {
110
+ if (cancelled) return;
111
+ const r = measure();
112
+ const settled = r || tries >= MAX;
113
+ if (settled) {
114
+ if (r) {
115
+ try {
116
+ document.querySelector(step.target)?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
117
+ } catch {}
118
+ // Re-measure after the scroll so the spotlight is glued post-layout.
119
+ requestAnimationFrame(() => {
120
+ if (!cancelled) measure();
121
+ });
122
+ }
123
+ return;
124
+ }
125
+ tries += 1;
126
+ pollRef.current = setTimeout(tick, 130);
127
+ };
128
+ tick();
129
+
130
+ return () => {
131
+ cancelled = true;
132
+ if (pollRef.current) clearTimeout(pollRef.current);
133
+ };
134
+ // Re-run when the step changes OR a selection arrives (a requireSelection
135
+ // target pops into existence the moment the user ⌘-clicks). `bus`/`measure`
136
+ // are reached through refs/stable closures to avoid identity-churn re-runs.
137
+ }, [open, i, hasSelection]);
138
+
139
+ // Keep the spotlight glued to its target through scroll/resize; restore focus.
140
+ useEffect(() => {
141
+ if (!open) return undefined;
142
+ prevFocus.current = document.activeElement;
143
+ const onMove = () => measure();
144
+ window.addEventListener('resize', onMove);
145
+ window.addEventListener('scroll', onMove, true);
146
+ return () => {
147
+ window.removeEventListener('resize', onMove);
148
+ window.removeEventListener('scroll', onMove, true);
149
+ try {
150
+ prevFocus.current?.focus?.();
151
+ } catch {}
152
+ };
153
+ }, [open, measure]);
154
+
155
+ const last = i >= steps.length - 1;
156
+ const next = useCallback(() => {
157
+ if (last) {
158
+ onComplete?.();
159
+ onClose?.();
160
+ } else {
161
+ setI((n) => Math.min(n + 1, steps.length - 1));
162
+ }
163
+ }, [last, onComplete, onClose, steps.length]);
164
+ const back = useCallback(() => setI((n) => Math.max(0, n - 1)), []);
165
+
166
+ // Keyboard: Esc skips, ←/→ navigate, Tab is trapped within the card buttons.
167
+ useEffect(() => {
168
+ if (!open) return undefined;
169
+ function onKey(e) {
170
+ if (e.key === 'Escape') {
171
+ e.preventDefault();
172
+ onClose?.();
173
+ } else if (e.key === 'ArrowRight') {
174
+ e.preventDefault();
175
+ next();
176
+ } else if (e.key === 'ArrowLeft') {
177
+ e.preventDefault();
178
+ back();
179
+ } else if (e.key === 'Tab') {
180
+ const card = cardRef.current;
181
+ if (!card) return;
182
+ const f = card.querySelectorAll('button');
183
+ if (!f.length) return;
184
+ const first = f[0];
185
+ const lastEl = f[f.length - 1];
186
+ if (e.shiftKey && document.activeElement === first) {
187
+ e.preventDefault();
188
+ lastEl.focus();
189
+ } else if (!e.shiftKey && document.activeElement === lastEl) {
190
+ e.preventDefault();
191
+ first.focus();
192
+ }
193
+ }
194
+ }
195
+ window.addEventListener('keydown', onKey, true);
196
+ return () => window.removeEventListener('keydown', onKey, true);
197
+ }, [open, next, back, onClose]);
198
+
199
+ // Move focus to the primary action on each step (accessible dialog behavior).
200
+ useEffect(() => {
201
+ if (!open) return undefined;
202
+ const t = setTimeout(() => {
203
+ const primary = cardRef.current?.querySelector('[data-tour-primary]');
204
+ try {
205
+ primary?.focus();
206
+ } catch {}
207
+ }, 0);
208
+ return () => clearTimeout(t);
209
+ }, [open, i]);
210
+
211
+ if (!open || !steps.length || !step) return null;
212
+ const pad = 6;
213
+ const spot = rect
214
+ ? {
215
+ top: rect.top - pad,
216
+ left: rect.left - pad,
217
+ width: rect.width + pad * 2,
218
+ height: rect.height + pad * 2,
219
+ }
220
+ : null;
221
+
222
+ // A requireSelection step whose target hasn't materialized yet: tell the user
223
+ // the one action only they can take (the canvas iframe is cross-origin, so the
224
+ // tour can't ⌘-click for them — DDR-054).
225
+ const needSelHint = !!step.requireSelection && !hasSelection;
226
+ const needCanvasHint = (!!step.canvas || !!step.requireSelection) && hasCanvas === false;
227
+
228
+ return (
229
+ <div className="mdcc-tour" role="presentation">
230
+ {spot ? (
231
+ <div className="mdcc-tour__spot" style={spot} aria-hidden="true" />
232
+ ) : (
233
+ <div className="mdcc-tour__scrim" aria-hidden="true" />
234
+ )}
235
+ <div
236
+ className="mdcc-tour__card"
237
+ ref={cardRef}
238
+ role="dialog"
239
+ aria-modal="true"
240
+ aria-labelledby="mdcc-tour-title"
241
+ aria-describedby="mdcc-tour-body"
242
+ style={computeCardStyle(rect)}
243
+ >
244
+ <div className="mdcc-tour__step">
245
+ {i + 1} / {steps.length}
246
+ </div>
247
+ <div className="mdcc-tour__title" id="mdcc-tour-title">
248
+ {step.title}
249
+ </div>
250
+ <div className="mdcc-tour__body" id="mdcc-tour-body">
251
+ {step.body}
252
+ </div>
253
+ {(needCanvasHint || needSelHint) && (
254
+ <div className="mdcc-tour__hint" role="status" aria-live="polite">
255
+ <span className="mdcc-tour__hint-dot" aria-hidden="true" />
256
+ {needCanvasHint
257
+ ? 'Open any canvas from the sidebar to follow along.'
258
+ : 'Hold ⌘ and click an element in the canvas — the panel fills in live.'}
259
+ </div>
260
+ )}
261
+ <div className="mdcc-tour__actions">
262
+ <button type="button" className="mdcc-tour__skip" onClick={onClose}>
263
+ Skip
264
+ </button>
265
+ <div className="mdcc-tour__nav">
266
+ {i > 0 && (
267
+ <button type="button" className="mdcc-tour__back" onClick={back}>
268
+ Back
269
+ </button>
270
+ )}
271
+ <button type="button" className="mdcc-tour__next" data-tour-primary onClick={next}>
272
+ {last ? 'Done' : 'Next'}
273
+ </button>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </div>
278
+ );
279
+ }
@@ -0,0 +1,48 @@
1
+ // usage-tour.js — the evergreen "how the Maude UI works" walkthrough.
2
+ //
3
+ // Targets stable [data-tour] anchors (redesign-proof — styling classes get
4
+ // renamed, these don't) on elements that exist at first load: the sidebar, the
5
+ // viewport, the menus, the Inspector, the What's New badge, and Help. The
6
+ // Inspector step carries `inspector: true` so the engine opens the panel before
7
+ // spotlighting it. Steps whose target is missing are shown centered by the
8
+ // overlay, so this stays resilient to chrome changes. Reached from Help →
9
+ // "Take the tour" and offered once on first run.
10
+
11
+ export const USAGE_TOUR = [
12
+ {
13
+ target: "[data-tour='sidebar']",
14
+ title: 'Your canvases live here',
15
+ body: 'Every mock in the project shows up in this tree. Click one to open it in a tab — or use “+ board” to spin up a blank brief-board, no command needed.',
16
+ placement: 'right',
17
+ },
18
+ {
19
+ target: "[data-tour='viewport']",
20
+ title: 'The canvas',
21
+ body: 'Open a canvas, then ⌘-hover to preview the element under your cursor and ⌘-click to select it. Right-click for Copy CSS / Fit / Reset.',
22
+ },
23
+ {
24
+ target: "[data-tour='menus']",
25
+ title: 'Menus & tools',
26
+ body: 'View toggles panels (tree, comments, Inspector); Selection and Tools act on the active canvas. Press ? for every shortcut.',
27
+ placement: 'bottom',
28
+ },
29
+ {
30
+ target: "[data-tour='inspector']",
31
+ inspector: true,
32
+ title: 'The Inspector',
33
+ body: 'Opened from View → Inspector (or press I). Inspect · Layers · CSS — ⌘-click any element and edit its CSS against your design tokens, right here. No AI round-trip.',
34
+ placement: 'left',
35
+ },
36
+ {
37
+ target: "[data-tour='whatsnew']",
38
+ title: 'What’s new',
39
+ body: 'New features land here. Click the ✦ badge any time to catch up on what shipped — some entries come with a guided tour like this one.',
40
+ placement: 'bottom',
41
+ },
42
+ {
43
+ target: "[data-tour='help']",
44
+ title: 'Help is one key away',
45
+ body: 'Press ? for the full keyboard cheat-sheet — and you can restart this tour from the Help menu whenever you like.',
46
+ placement: 'bottom',
47
+ },
48
+ ];
@@ -0,0 +1,52 @@
1
+ // whats-new-seen.js — pure, browser-safe "what have I already seen?" logic.
2
+ //
3
+ // No React, no DOM, no node imports — so it's bundled into the client AND
4
+ // imported directly by bun:test (test/whats-new.test.ts). Keep it that way.
5
+
6
+ /** Parse a semver-ish string into a [major, minor, patch] triple, or null. */
7
+ export function parseVer(v) {
8
+ if (typeof v !== 'string') return null;
9
+ const m = v.match(/^(\d+)\.(\d+)\.(\d+)/);
10
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
11
+ }
12
+
13
+ /**
14
+ * Is version `a` strictly newer than `b`?
15
+ * - Unparseable `a` (e.g. "dev") → not newer (false).
16
+ * - Unparseable `b` but parseable `a` → newer (true): a real release outranks
17
+ * a non-version "seen" marker, so the entry surfaces.
18
+ */
19
+ export function verGt(a, b) {
20
+ const pa = parseVer(a);
21
+ const pb = parseVer(b);
22
+ if (!pa) return false;
23
+ if (!pb) return true;
24
+ for (let i = 0; i < 3; i++) {
25
+ if (pa[i] !== pb[i]) return pa[i] > pb[i];
26
+ }
27
+ return false;
28
+ }
29
+
30
+ /**
31
+ * Entries the user hasn't seen yet, given the version they last acknowledged.
32
+ * A pending entry (version == null) is always unseen until acknowledged.
33
+ */
34
+ export function computeUnseen(entries, seenVersion) {
35
+ if (!Array.isArray(entries)) return [];
36
+ return entries.filter((e) => e && (e.version == null || verGt(e.version, seenVersion)));
37
+ }
38
+
39
+ /**
40
+ * The version to persist as "seen" after the user reads the panel — the highest
41
+ * of the current feed version and every entry's version. Stamping this clears
42
+ * the unseen set (pending entries excepted — they have no version to outrank).
43
+ */
44
+ export function bestSeenVersion(entries, currentVersion) {
45
+ let best = currentVersion;
46
+ if (Array.isArray(entries)) {
47
+ for (const e of entries) {
48
+ if (e && e.version && verGt(e.version, best)) best = e.version;
49
+ }
50
+ }
51
+ return best;
52
+ }