@vgai/editor 0.2.0 → 0.4.0-canary.20260715.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 (430) hide show
  1. package/README.md +24 -0
  2. package/dist/assets/axe-C7YBtOuM.js +30 -0
  3. package/dist/assets/browserAll-DDtGGE48.js +1 -0
  4. package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
  5. package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
  6. package/dist/assets/game-BdTHR2_X.js +1 -0
  7. package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
  8. package/dist/assets/game-CcHfYxjP.js +1 -0
  9. package/dist/assets/game-Cqzj_lpD.js +1 -0
  10. package/dist/assets/game-DSZdeCHu.js +1 -0
  11. package/dist/assets/game-Dch9sAPc.js +1 -0
  12. package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
  13. package/dist/assets/game-loop-DMIgSMV-.js +1 -0
  14. package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
  15. package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
  16. package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
  17. package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
  18. package/dist/assets/index-CQEfi217.js +15412 -0
  19. package/dist/assets/index-Dvi-V0NE.css +1 -0
  20. package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
  21. package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
  22. package/dist/assets/react-18-C9eHn8x1.js +1 -0
  23. package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
  24. package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
  25. package/dist/index.html +15 -13
  26. package/dist/ingest/racing-game/vgai.game.json +5 -4
  27. package/dist/ingest/simcity/vgai.game.json +5 -4
  28. package/dist/ingest/tanks/vgai.game.json +5 -4
  29. package/dist/project-scripts.bundle.js +3917 -0
  30. package/dist/scenes/untitled.vscn.json +2 -0
  31. package/dist-server/packaged.mjs +7697 -3435
  32. package/package.json +31 -4
  33. package/scripts/probe-reporter.ts +349 -0
  34. package/scripts/run-probe.ts +2260 -0
  35. package/server/asset-catalog-audit.ts +268 -0
  36. package/server/asset-catalog-v2.ts +146 -0
  37. package/server/asset-library-routes.ts +276 -58
  38. package/server/canonical-path.ts +1 -1
  39. package/server/dev.ts +148 -44
  40. package/server/editor-server.ts +888 -61
  41. package/server/editor-sse.ts +115 -4
  42. package/server/harness-chat-service.ts +796 -0
  43. package/server/local-asset-catalog.ts +157 -22
  44. package/server/packaged.ts +51 -21
  45. package/server/process-shutdown.ts +136 -0
  46. package/server/prod.ts +9 -6
  47. package/server/project-hmr-files.ts +41 -0
  48. package/server/project-operations.ts +343 -0
  49. package/server/project-optimize-deps-entries.ts +4 -4
  50. package/server/project-output-writer.ts +156 -0
  51. package/server/project-validation.ts +140 -0
  52. package/server/project-view.ts +8 -50
  53. package/server/server-utils.ts +75 -10
  54. package/server/session-registry.ts +12 -0
  55. package/src/EditorContext.tsx +107 -3
  56. package/src/action-registry.ts +115 -17
  57. package/src/adapter-resolver.ts +213 -478
  58. package/src/asset-events.ts +64 -1
  59. package/src/asset-preview.ts +906 -0
  60. package/src/asset-selection.ts +121 -0
  61. package/src/asset-workflow/asset-capabilities.ts +259 -0
  62. package/src/asset-workflow/asset-editor-errors.ts +46 -0
  63. package/src/asset-workflow/asset-import-pipeline.ts +176 -0
  64. package/src/asset-workflow/asset-library-query.ts +107 -0
  65. package/src/asset-workflow/asset-types.ts +192 -0
  66. package/src/asset-workflow/asset-workflow-quality.ts +65 -0
  67. package/src/asset-workflow/import-contract.ts +113 -0
  68. package/src/asset-workflow/model-conversion.ts +126 -0
  69. package/src/asset-workflow/model-inspection.ts +185 -0
  70. package/src/asset-workflow/project-asset-commands.ts +23 -0
  71. package/src/asset-workflow/project-asset-health.ts +153 -0
  72. package/src/asset-workflow/project-asset-operations.ts +119 -0
  73. package/src/asset-workflow/thumbnail-system.ts +172 -0
  74. package/src/authoring/active-systems.ts +15 -0
  75. package/src/authoring/boundary-authoring-adapter.ts +16 -5
  76. package/src/authoring/composite-authoring-adapter.ts +305 -124
  77. package/src/authoring/design-time-layers.ts +300 -117
  78. package/src/authoring/edit-mode-authoring.ts +278 -293
  79. package/src/authoring/embed-only-adapter.ts +4 -2
  80. package/src/authoring/first-party-hierarchy-menu.ts +7 -2
  81. package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
  82. package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
  83. package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
  84. package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
  85. package/src/authoring/first-party-inspector/register.tsx +13 -2
  86. package/src/authoring/ingest-authoring-adapter.ts +142 -45
  87. package/src/authoring/mount-failure-report.ts +5 -5
  88. package/src/authoring/provenance.ts +41 -0
  89. package/src/authoring/react-dom-authoring-adapter.ts +92 -92
  90. package/src/authoring/react-inspector-section.tsx +489 -51
  91. package/src/authoring/react-world-authoring-adapter.ts +541 -306
  92. package/src/authoring/story-overlay.ts +1 -1
  93. package/src/authoring/story-types.ts +11 -0
  94. package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
  95. package/src/authoring/viewport-tool-context.ts +78 -0
  96. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  97. package/src/authoring/world-hidden-viewport.ts +186 -0
  98. package/src/authoring/world-pan-state.ts +33 -17
  99. package/src/authoring/world-session-state.ts +1 -1
  100. package/src/authoring/world2d-authoring-adapter.ts +109 -52
  101. package/src/availability-tick.ts +56 -0
  102. package/src/browser-play-entry.ts +5 -5
  103. package/src/browser-project-scripts.ts +1 -0
  104. package/src/build-identity.ts +15 -0
  105. package/src/command-listener.ts +893 -19
  106. package/src/components/AlignToolbar.tsx +74 -63
  107. package/src/components/AppRoot.tsx +193 -26
  108. package/src/components/ApplicationMenus.tsx +272 -0
  109. package/src/components/AssetBrowser.tsx +1450 -293
  110. package/src/components/AssetEditorShell.tsx +141 -0
  111. package/src/components/AssetImportDetails.tsx +218 -0
  112. package/src/components/AssetLibraryPanel.tsx +14 -0
  113. package/src/components/CameraInfo.tsx +11 -20
  114. package/src/components/CenterDocuments.tsx +585 -0
  115. package/src/components/CommandPalette.tsx +75 -30
  116. package/src/components/ConsolePanel.css +55 -0
  117. package/src/components/ConsolePanel.tsx +57 -112
  118. package/src/components/DebugConsolePanel.tsx +461 -0
  119. package/src/components/DebuggerPanel.tsx +165 -0
  120. package/src/components/DefaultEditorLayout.tsx +167 -231
  121. package/src/components/GameHierarchy.tsx +873 -290
  122. package/src/components/GamePerformanceOverlay.tsx +46 -0
  123. package/src/components/HarnessChatPanel.tsx +2352 -0
  124. package/src/components/HistoryPanel.tsx +226 -0
  125. package/src/components/Inspector.tsx +153 -99
  126. package/src/components/InspectorToolSection.tsx +6 -4
  127. package/src/components/MountFailureBanner.tsx +31 -48
  128. package/src/components/NetworkSection.tsx +25 -14
  129. package/src/components/OnlineAssetBrowser.tsx +794 -343
  130. package/src/components/OverlayReportBanner.tsx +38 -64
  131. package/src/components/PerformancePanel.tsx +206 -0
  132. package/src/components/PlayBar.tsx +93 -263
  133. package/src/components/PrefabSaveDialog.tsx +55 -127
  134. package/src/components/ProjectHeader.css +60 -0
  135. package/src/components/ProjectHeader.tsx +170 -105
  136. package/src/components/ProjectScreen.tsx +246 -184
  137. package/src/components/ReactCanvasControls.tsx +185 -0
  138. package/src/components/ResolutionPicker.tsx +85 -0
  139. package/src/components/RootActivateDialog.tsx +39 -68
  140. package/src/components/SaveDialog.tsx +55 -127
  141. package/src/components/SaveStatus.tsx +11 -29
  142. package/src/components/StartupLoadingScreen.tsx +96 -0
  143. package/src/components/StateWatchPanel.tsx +302 -0
  144. package/src/components/StatsOverlay.tsx +12 -5
  145. package/src/components/StatusBar.tsx +64 -0
  146. package/src/components/ThemeManagerDialog.css +89 -0
  147. package/src/components/ThemeManagerDialog.tsx +371 -0
  148. package/src/components/ToolHost.tsx +26 -15
  149. package/src/components/Toolbar.tsx +117 -214
  150. package/src/components/VgaiVoxelLogo.tsx +89 -0
  151. package/src/components/ViewportOverlay.tsx +97 -172
  152. package/src/components/ViewportPanel.tsx +130 -31
  153. package/src/components/WorkspaceDock.tsx +891 -0
  154. package/src/components/WorldSelectionOverlay.tsx +51 -63
  155. package/src/components/WorldTextEditor.tsx +9 -5
  156. package/src/components/asset-documents.tsx +390 -0
  157. package/src/components/asset-editor-persistence.ts +44 -0
  158. package/src/components/asset-selection-section.tsx +338 -0
  159. package/src/components/asset-viewers/AudioViewer.tsx +73 -21
  160. package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
  161. package/src/components/asset-viewers/ImageViewer.tsx +43 -11
  162. package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
  163. package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
  164. package/src/components/asset-viewers/ModelViewer.tsx +805 -121
  165. package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
  166. package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
  167. package/src/components/asset-workflow.css +506 -0
  168. package/src/components/build-documents.tsx +696 -0
  169. package/src/components/core-utilities.tsx +75 -0
  170. package/src/components/data-documents.tsx +364 -0
  171. package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
  172. package/src/components/debugger-panel-state.ts +57 -0
  173. package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
  174. package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
  175. package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
  176. package/src/components/inspector-widgets/FontPicker.tsx +13 -21
  177. package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
  178. package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
  179. package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
  180. package/src/components/inspector-widgets/shared.tsx +90 -49
  181. package/src/components/inspectors/AnimationSection.tsx +39 -40
  182. package/src/components/inspectors/AudioSection.tsx +28 -39
  183. package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
  184. package/src/components/inspectors/CameraSection.tsx +14 -23
  185. package/src/components/inspectors/ComponentsSection.tsx +39 -43
  186. package/src/components/inspectors/JointsSection.tsx +34 -43
  187. package/src/components/inspectors/LightSection.tsx +90 -35
  188. package/src/components/inspectors/MaterialSection.tsx +137 -174
  189. package/src/components/inspectors/MeshSection.tsx +9 -17
  190. package/src/components/inspectors/NavigationSection.tsx +8 -15
  191. package/src/components/inspectors/ParticleSection.tsx +91 -76
  192. package/src/components/inspectors/PhysicsSection.tsx +42 -46
  193. package/src/components/inspectors/PostProcessingSection.tsx +28 -36
  194. package/src/components/inspectors/RenderingSection.tsx +12 -20
  195. package/src/components/inspectors/ShadowSection.tsx +7 -8
  196. package/src/components/inspectors/SplineSection.tsx +31 -42
  197. package/src/components/inspectors/TransformSection.tsx +14 -22
  198. package/src/components/patterns/Dialog.tsx +95 -0
  199. package/src/components/patterns/Fields.tsx +44 -0
  200. package/src/components/patterns/List.tsx +25 -0
  201. package/src/components/patterns/StateSurface.tsx +40 -0
  202. package/src/components/patterns/Surfaces.tsx +115 -0
  203. package/src/components/patterns/Tabs.tsx +80 -0
  204. package/src/components/patterns/Toolbar.tsx +51 -0
  205. package/src/components/patterns/Tree.tsx +72 -0
  206. package/src/components/primitives/Button.tsx +46 -0
  207. package/src/components/primitives/ColorInput.tsx +11 -47
  208. package/src/components/primitives/EditorIcon.tsx +99 -0
  209. package/src/components/primitives/FormControls.tsx +71 -0
  210. package/src/components/primitives/JsonInput.tsx +15 -2
  211. package/src/components/primitives/Layout.tsx +100 -0
  212. package/src/components/primitives/Menu.tsx +105 -0
  213. package/src/components/primitives/NumberInput.tsx +8 -35
  214. package/src/components/primitives/Panel.tsx +49 -44
  215. package/src/components/primitives/SectionHeader.tsx +10 -28
  216. package/src/components/primitives/Text.tsx +46 -0
  217. package/src/components/primitives/Tooltip.tsx +20 -12
  218. package/src/components/primitives/Vec3Input.tsx +3 -0
  219. package/src/components/primitives/banner-tones.ts +33 -0
  220. package/src/components/primitives/editor-icons.ts +102 -0
  221. package/src/components/primitives/panel-header-styles.ts +30 -0
  222. package/src/components/project-operation-documents.tsx +226 -0
  223. package/src/components/status-contributions.tsx +175 -0
  224. package/src/components/story-documents-register.ts +15 -0
  225. package/src/components/story-documents.tsx +1185 -0
  226. package/src/components/tool-documents.tsx +110 -0
  227. package/src/components/workspace-dock.css +293 -0
  228. package/src/components/workspace-history.ts +33 -0
  229. package/src/components/world-documents.tsx +145 -0
  230. package/src/components/xstate-documents.tsx +209 -0
  231. package/src/composite-screenshot.ts +248 -0
  232. package/src/design-system/index.ts +70 -0
  233. package/src/design-system-stories/Foundation.stories.tsx +183 -0
  234. package/src/design-system-stories/Patterns.stories.tsx +251 -0
  235. package/src/design-system-stories/Workspace.stories.tsx +538 -0
  236. package/src/doctor/report.ts +57 -13
  237. package/src/editor-api.ts +295 -31
  238. package/src/editor-compatibility.ts +200 -0
  239. package/src/editor-console.ts +35 -17
  240. package/src/editor-hotkeys.ts +85 -33
  241. package/src/editor-store.ts +538 -233
  242. package/src/editor-viewport.ts +160 -34
  243. package/src/entity-factory.ts +14 -3
  244. package/src/gizmo-registry.ts +21 -5
  245. package/src/harness-chat-editor-context.ts +37 -0
  246. package/src/harness-chat-indicator.ts +68 -0
  247. package/src/harness-chat-layout.ts +53 -0
  248. package/src/harness-chat-lifecycle.ts +170 -0
  249. package/src/harness-chat-reconnect.ts +85 -0
  250. package/src/harness-chat-types.ts +409 -0
  251. package/src/hierarchy-drop.ts +50 -0
  252. package/src/hierarchy-expansion-state.ts +100 -0
  253. package/src/hierarchy-menu-registry.ts +1 -1
  254. package/src/hierarchy-projection.ts +76 -0
  255. package/src/history/editor-session.ts +21 -0
  256. package/src/history/history-commands.ts +147 -0
  257. package/src/history/history-service.ts +904 -0
  258. package/src/history/json-history-resource.ts +165 -0
  259. package/src/history/persistence-coordinator.ts +35 -0
  260. package/src/history/project-file-history.ts +266 -0
  261. package/src/history/project-root-history-backends.ts +53 -0
  262. package/src/history/resource-registry.ts +209 -0
  263. package/src/history/snapshot-store.ts +108 -0
  264. package/src/history/source-history-backend.ts +374 -0
  265. package/src/history/types.ts +100 -0
  266. package/src/hmr-registration-group.ts +67 -0
  267. package/src/hmr-stable-react-context.ts +23 -0
  268. package/src/hosted-example.ts +12 -2
  269. package/src/hotkeys.ts +89 -18
  270. package/src/ingest/discovery-react.ts +9 -10
  271. package/src/ingest/discovery.ts +4 -4
  272. package/src/ingest/discovery2d.ts +5 -5
  273. package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
  274. package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
  275. package/src/ingest/games/games-fps/vgai.game.json +3 -3
  276. package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
  277. package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
  278. package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
  279. package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
  280. package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
  281. package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
  282. package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
  283. package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
  284. package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
  285. package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
  286. package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
  287. package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
  288. package/src/ingest/types.ts +1 -1
  289. package/src/ingest-mode.ts +47 -52
  290. package/src/ingest-siblings.ts +23 -33
  291. package/src/initial-scene.ts +1 -2
  292. package/src/main.tsx +16 -8
  293. package/src/manifest-project.ts +10 -12
  294. package/src/model-thumbnail.ts +261 -26
  295. package/src/module-mode.ts +44 -50
  296. package/src/play-log-events.ts +26 -0
  297. package/src/play-mode.ts +495 -401
  298. package/src/play-scene-adoption.ts +23 -0
  299. package/src/playground/main.ts +68 -24
  300. package/src/playwright-shim.ts +473 -0
  301. package/src/project-manager.ts +90 -10
  302. package/src/project-operations.ts +112 -0
  303. package/src/project-story-discovery.ts +25 -0
  304. package/src/project-tool-discovery.ts +43 -0
  305. package/src/scene-serializer.ts +0 -6
  306. package/src/scene-sync.ts +7 -2
  307. package/src/script-loader.ts +3 -3
  308. package/src/skeleton-helper.ts +57 -0
  309. package/src/storage/seed.ts +68 -8
  310. package/src/stories/StoryPreviewMount.tsx +265 -0
  311. package/src/stories/action-stories.fixture.tsx +44 -0
  312. package/src/stories/button-stories.fixture.tsx +50 -0
  313. package/src/stories/compose-project-stories.ts +182 -0
  314. package/src/stories/loader-stories.fixture.tsx +53 -0
  315. package/src/stories/story-discovery.ts +130 -0
  316. package/src/stories/story-registry.ts +146 -0
  317. package/src/theme-css.ts +1049 -0
  318. package/src/theme-library.ts +238 -0
  319. package/src/theme-preference.ts +130 -0
  320. package/src/theme.ts +527 -0
  321. package/src/tool-loader.ts +80 -24
  322. package/src/ui-source/inspect.ts +27 -4
  323. package/src/ui-source/source-write-backend.ts +83 -22
  324. package/src/widgets/index.ts +9 -18
  325. package/src/workspace-aux-commands.ts +11 -0
  326. package/src/workspace-dock-controller.ts +64 -0
  327. package/src/workspace-document-ids.ts +5 -0
  328. package/src/workspace-document-registry.ts +367 -0
  329. package/src/workspace-state-persistence.ts +455 -0
  330. package/src/workspace-status-registry.ts +110 -0
  331. package/src/workspace-utility-commands.ts +49 -0
  332. package/src/workspace-utility-registry.ts +161 -0
  333. package/src/world-document-routing.ts +16 -0
  334. package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
  335. package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
  336. package/src/xstate-inspect/use-live-actor-state.ts +39 -0
  337. package/src/xstate-inspect/xstate-graph.ts +265 -0
  338. package/src/xstate-inspect/xstate-layout.ts +76 -0
  339. package/src/z-index.ts +26 -0
  340. package/template/.claude/skills/editor/SKILL.md +129 -90
  341. package/template/AGENTS.md +1110 -0
  342. package/template/CLAUDE.md +1 -512
  343. package/template/IDIOMS.md +50 -0
  344. package/template/check-idioms.ts +706 -0
  345. package/template/manifest-entry-modules-plugin.ts +53 -0
  346. package/template/package.json +13 -4
  347. package/template/public/scenes/default.scn2d.json +6 -0
  348. package/template/public/scenes/default.vscn.json +7 -1
  349. package/template/public/scenes/untitled.vscn.json +10 -0
  350. package/template/scripts/playtest.ts +40 -0
  351. package/template/server/loopback.ts +75 -0
  352. package/template/server/rooms/arena-room.ts +69 -1
  353. package/template/server/rooms/game-room.ts +68 -1
  354. package/template/src/data/README.md +9 -4
  355. package/template/src/data/data-ref.ts +35 -0
  356. package/template/src/data/tuning.schema.ts +1 -1
  357. package/template/src/main.ts +41 -62
  358. package/template/src/manifest-entry-modules.d.ts +3 -0
  359. package/template/src/operations/README.md +88 -0
  360. package/template/src/runtime/pixi-adapter.ts +24 -0
  361. package/template/src/scripts/components/data-spinner.ts +43 -2
  362. package/template/src/scripts/components/spin-lap-math.ts +27 -0
  363. package/template/src/tools/README.md +5 -3
  364. package/template/src/tools/example.tool.tsx +13 -7
  365. package/template/src/ui/Button.stories.tsx +66 -0
  366. package/template/src/ui/RebindPanel.tsx +2 -6
  367. package/template/src/ui/game.tsx +17 -0
  368. package/template/tests/acceptance/example.spec.ts +64 -0
  369. package/template/tests/logic/example.test.ts +31 -0
  370. package/template/tests/logic/room.test.ts +100 -0
  371. package/template/tests/tsconfig.json +30 -0
  372. package/template/validate-manifest.ts +5 -5
  373. package/template/validate-scenes.ts +50 -18
  374. package/template/vgai.game.json +20 -13
  375. package/template/vite.config.ts +77 -16
  376. package/vite-plugin-ui-oid.ts +261 -17
  377. package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
  378. package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
  379. package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
  380. package/dist/assets/browserAll-CEkWYlFk.js +0 -1
  381. package/dist/assets/create-runtime-DYIWr3va.js +0 -1
  382. package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
  383. package/dist/assets/game-8SDZPPgH.js +0 -1
  384. package/dist/assets/game-CevorxyV.js +0 -1
  385. package/dist/assets/game-Di7XlywD.js +0 -1
  386. package/dist/assets/game-DjnCaw8R.js +0 -1
  387. package/dist/assets/game-Q9A0aXSV.js +0 -1
  388. package/dist/assets/index-CPVV6pjw.js +0 -1
  389. package/dist/assets/index-CpOnYyeD.js +0 -213
  390. package/dist/assets/index-Dr8H_6Rl.js +0 -1
  391. package/dist/assets/index-_bCaipUk.js +0 -13650
  392. package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
  393. package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
  394. package/dist/assets/scene-query-BivAHhJu.js +0 -1
  395. package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
  396. package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
  397. package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
  398. package/src/authoring/scene-ui-layer.ts +0 -485
  399. package/src/authoring/ui-authoring-adapter.ts +0 -325
  400. package/src/authoring/ui-hierarchy-menu.ts +0 -40
  401. package/src/authoring/ui-inspector-sections.tsx +0 -156
  402. package/src/authoring/undo-timeline.ts +0 -145
  403. package/src/components/BottomPanel.tsx +0 -326
  404. package/src/components/BuildPanel.tsx +0 -455
  405. package/src/components/FolderTree.tsx +0 -179
  406. package/src/components/RightPanel.tsx +0 -166
  407. package/src/components/WorldContextMenu.tsx +0 -257
  408. package/src/components/asset-viewers/AssetViewer.tsx +0 -38
  409. package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
  410. package/src/scene-ui-mode/active-scene-ui.ts +0 -58
  411. package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
  412. package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
  413. package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
  414. package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
  415. package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
  416. package/src/ui-editor/inspector.tsx +0 -563
  417. package/src/ui-editor/node-ops.ts +0 -266
  418. package/src/ui-editor/overlay.tsx +0 -380
  419. package/src/ui-editor/palette.tsx +0 -114
  420. package/src/ui-editor/react-store.ts +0 -78
  421. package/src/ui-editor/timeline-panel.tsx +0 -443
  422. package/src/ui-editor/ui-edit-store.ts +0 -552
  423. package/src/ui-editor/ui-prefab.ts +0 -95
  424. package/template/project.json +0 -9
  425. package/template/src/scripts/main.ts +0 -94
  426. package/template/src/ui/DefaultHud.tsx +0 -40
  427. package/template/src/ui/game-state.tsx +0 -37
  428. package/template/src/ui/mount-default-hud.tsx +0 -19
  429. package/template/src/ui/mount-ui.ts +0 -15
  430. package/vite-plugin-react-world-provider.ts +0 -81
@@ -0,0 +1,57 @@
1
+ import { showWorkspaceUtility } from '../workspace-dock-controller';
2
+ import { DEBUGGER_UTILITY_ID } from '../workspace-utility-commands';
3
+
4
+ export type DebuggerTabId = 'state' | 'profiler' | 'network' | 'machines' | 'commands';
5
+
6
+ let activeTab: DebuggerTabId = 'profiler';
7
+ let selectedMachineNodeId: string | null = null;
8
+ let version = 0;
9
+ const listeners = new Set<() => void>();
10
+
11
+ function notify(): void {
12
+ version++;
13
+ for (const listener of listeners) listener();
14
+ }
15
+
16
+ export function subscribeDebuggerPanel(listener: () => void): () => void {
17
+ listeners.add(listener);
18
+ return () => listeners.delete(listener);
19
+ }
20
+
21
+ export function debuggerPanelVersion(): number {
22
+ return version;
23
+ }
24
+
25
+ export function activeDebuggerTab(): DebuggerTabId {
26
+ return activeTab;
27
+ }
28
+
29
+ export function debuggerMachineNodeId(): string | null {
30
+ return selectedMachineNodeId;
31
+ }
32
+
33
+ export function setDebuggerTab(tab: DebuggerTabId, machineNodeId?: string): void {
34
+ const nextMachine = machineNodeId ?? selectedMachineNodeId;
35
+ if (activeTab === tab && selectedMachineNodeId === nextMachine) return;
36
+ activeTab = tab;
37
+ selectedMachineNodeId = nextMachine;
38
+ notify();
39
+ }
40
+
41
+ export function selectDebuggerMachine(nodeId: string): void {
42
+ if (selectedMachineNodeId === nodeId) return;
43
+ selectedMachineNodeId = nodeId;
44
+ notify();
45
+ }
46
+
47
+ /** Open one live-observation tool without replacing the document it observes. */
48
+ export function openDebuggerPanel(tab: DebuggerTabId, machineNodeId?: string): void {
49
+ setDebuggerTab(tab, machineNodeId);
50
+ showWorkspaceUtility(DEBUGGER_UTILITY_ID);
51
+ }
52
+
53
+ export function __resetDebuggerPanelForTest(): void {
54
+ activeTab = 'profiler';
55
+ selectedMachineNodeId = null;
56
+ notify();
57
+ }
@@ -1,3 +1,4 @@
1
+ import { Button } from '../../design-system';
1
2
  /**
2
3
  * AlignmentGrid — a 3×3 flex `justify-content`×`align-items` picker (spec 27
3
4
  * §5 C1). Ported from `visual-edit/inspector.tsx`'s `AlignmentGrid`
@@ -94,7 +95,7 @@ function AlignmentCell({
94
95
  alignItems: 'center',
95
96
  justifyContent: 'center',
96
97
  cursor: disabled ? 'not-allowed' : 'pointer',
97
- borderRadius: 2,
98
+ borderRadius: THEME.radiusSmall,
98
99
  background: isActive ? THEME.accent : 'transparent',
99
100
  }}
100
101
  >
@@ -103,7 +104,7 @@ function AlignmentCell({
103
104
  width: isActive ? 6 : 4,
104
105
  height: isActive ? 6 : 4,
105
106
  borderRadius: '50%',
106
- background: isActive ? '#fff' : THEME.textMuted,
107
+ background: isActive ? THEME.onAccent : THEME.textMuted,
107
108
  }}
108
109
  />
109
110
  </div>
@@ -127,7 +128,7 @@ export function AlignmentGrid({
127
128
  gridTemplateRows: 'repeat(3, 16px)',
128
129
  gap: 1,
129
130
  background: THEME.inputBg,
130
- borderRadius: 6,
131
+ borderRadius: THEME.radiusMedium,
131
132
  padding: 4,
132
133
  opacity: disabled ? 0.35 : 1,
133
134
  }}
@@ -164,24 +165,17 @@ export function AnchorPresets({ onSelect, disabled }: AnchorPresetsProps): React
164
165
  return (
165
166
  <div data-testid="anchor-presets" style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
166
167
  {Object.entries(ANCHOR_PRESETS).map(([name, preset]) => (
167
- <button
168
+ <Button
168
169
  key={name}
169
170
  type="button"
171
+ variant="secondary"
172
+ size="compact"
170
173
  data-testid={`anchor-preset-${name}`}
171
174
  disabled={disabled}
172
175
  onClick={() => onSelect(name, preset)}
173
- style={{
174
- background: 'rgba(255,255,255,0.06)',
175
- border: `1px solid ${THEME.border}`,
176
- borderRadius: 3,
177
- color: THEME.text,
178
- fontSize: 10,
179
- padding: '3px 6px',
180
- cursor: disabled ? 'not-allowed' : 'pointer',
181
- }}
182
176
  >
183
177
  {name}
184
- </button>
178
+ </Button>
185
179
  ))}
186
180
  </div>
187
181
  );
@@ -1,3 +1,4 @@
1
+ import { Button, Select } from '../../design-system';
1
2
  /**
2
3
  * BorderEditor (per-side width/style/color) + BorderRadiusEditor (per-corner)
3
4
  * (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s `BorderEditor`
@@ -6,17 +7,12 @@
6
7
  * radius is the common case; independent sides are one click away).
7
8
  */
8
9
 
10
+ import { faBorderAll, faBorderTopLeft } from '@fortawesome/free-solid-svg-icons';
9
11
  import { useState } from 'react';
12
+ import { EditorIcon } from '../../design-system';
10
13
  import { ColorSwatch } from './ColorPicker';
11
14
  import { ScrubbableInput } from './ScrubbableInput';
12
- import {
13
- type ChangeHandlers,
14
- fireChange,
15
- fireEnd,
16
- inputStyle,
17
- miniButtonStyle,
18
- THEME,
19
- } from './shared';
15
+ import { type ChangeHandlers, fireChange, fireEnd, THEME } from './shared';
20
16
 
21
17
  const BORDER_STYLES = ['none', 'solid', 'dashed', 'dotted', 'double'];
22
18
 
@@ -101,28 +97,34 @@ export function BorderEditor({
101
97
  onChangeEnd={(v) => applyAll({ width: v }, true)}
102
98
  style={{ width: 64 }}
103
99
  />
104
- <select
100
+ <Select
101
+ className="vgai-select"
105
102
  data-testid="border-style"
106
103
  value={value.top.style}
107
104
  disabled={disabled}
108
105
  onChange={(e) => applyAll({ style: e.target.value }, true)}
109
- style={{ ...inputStyle(disabled), flex: 1, cursor: disabled ? 'not-allowed' : 'pointer' }}
106
+ style={{
107
+ flex: 1,
108
+ ...(disabled ? { background: THEME.dynamicBg, color: THEME.dynamic } : null),
109
+ }}
110
110
  >
111
111
  {BORDER_STYLES.map((o) => (
112
112
  <option key={o} value={o}>
113
113
  {o}
114
114
  </option>
115
115
  ))}
116
- </select>
117
- <button
116
+ </Select>
117
+ <Button
118
118
  type="button"
119
119
  data-testid="border-expand"
120
120
  title="Per-side borders"
121
+ aria-label="Edit borders per side"
121
122
  onClick={() => setExpanded(true)}
122
- style={miniButtonStyle}
123
+ variant="ghost"
124
+ size="compact"
123
125
  >
124
- ⊞
125
- </button>
126
+ <EditorIcon icon={faBorderAll} />
127
+ </Button>
126
128
  </div>
127
129
  );
128
130
  }
@@ -142,15 +144,17 @@ export function BorderEditor({
142
144
  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
143
145
  <span style={{ fontSize: 10, color: THEME.textMuted }}>Per-side</span>
144
146
  <div style={{ flex: 1 }} />
145
- <button
147
+ <Button
146
148
  type="button"
149
+ variant="primary"
150
+ size="compact"
147
151
  data-testid="border-collapse"
148
152
  title="Uniform border"
153
+ aria-label="Use one border for all sides"
149
154
  onClick={() => setExpanded(false)}
150
- style={{ ...miniButtonStyle, background: THEME.accent, color: '#fff' }}
151
155
  >
152
- ⊞
153
- </button>
156
+ <EditorIcon icon={faBorderAll} />
157
+ </Button>
154
158
  </div>
155
159
  {sides.map(({ key, label }) => (
156
160
  <div key={key} style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
@@ -176,16 +180,16 @@ export function BorderEditor({
176
180
  onChangeEnd={(v) => applySide(key, { width: v }, true)}
177
181
  style={{ width: 48 }}
178
182
  />
179
- <select
183
+ <Select
184
+ className="vgai-select"
180
185
  data-testid={`border-${key}-style`}
181
186
  value={value[key].style}
182
187
  disabled={disabled}
183
188
  onChange={(e) => applySide(key, { style: e.target.value }, true)}
184
189
  style={{
185
- ...inputStyle(disabled),
186
190
  flex: 1,
187
191
  fontSize: 10,
188
- cursor: disabled ? 'not-allowed' : 'pointer',
192
+ ...(disabled ? { background: THEME.dynamicBg, color: THEME.dynamic } : null),
189
193
  }}
190
194
  >
191
195
  {BORDER_STYLES.map((o) => (
@@ -193,7 +197,7 @@ export function BorderEditor({
193
197
  {o}
194
198
  </option>
195
199
  ))}
196
- </select>
200
+ </Select>
197
201
  </div>
198
202
  ))}
199
203
  </div>
@@ -243,7 +247,7 @@ export function BorderRadiusEditor({
243
247
  >
244
248
  <ScrubbableInput
245
249
  testId="border-radius"
246
- label="⬔"
250
+ label={<EditorIcon icon={faBorderTopLeft} label="Radius" />}
247
251
  value={value.topLeft}
248
252
  min={0}
249
253
  disabled={disabled}
@@ -251,15 +255,17 @@ export function BorderRadiusEditor({
251
255
  onChangeEnd={(v) => applyAll(v, true)}
252
256
  style={{ flex: 1 }}
253
257
  />
254
- <button
258
+ <Button
255
259
  type="button"
256
260
  data-testid="border-radius-expand"
257
261
  title="Independent corners"
262
+ aria-label="Edit radius per corner"
258
263
  onClick={() => setExpanded(true)}
259
- style={miniButtonStyle}
264
+ variant="ghost"
265
+ size="compact"
260
266
  >
261
- ⊞
262
- </button>
267
+ <EditorIcon icon={faBorderTopLeft} />
268
+ </Button>
263
269
  </div>
264
270
  );
265
271
  }
@@ -274,17 +280,19 @@ export function BorderRadiusEditor({
274
280
  return (
275
281
  <div data-testid="border-radius-editor-expanded">
276
282
  <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>
277
- <span style={{ fontSize: 10, color: THEME.textMuted }}>⬔ corners</span>
283
+ <span style={{ fontSize: 10, color: THEME.textMuted }}>Corners</span>
278
284
  <div style={{ flex: 1 }} />
279
- <button
285
+ <Button
280
286
  type="button"
287
+ variant="primary"
288
+ size="compact"
281
289
  data-testid="border-radius-collapse"
282
290
  title="Uniform radius"
291
+ aria-label="Use one radius for all corners"
283
292
  onClick={() => setExpanded(false)}
284
- style={{ ...miniButtonStyle, background: THEME.accent, color: '#fff' }}
285
293
  >
286
- ⊞
287
- </button>
294
+ <EditorIcon icon={faBorderTopLeft} />
295
+ </Button>
288
296
  </div>
289
297
  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 3 }}>
290
298
  {corners.map(({ key, label }) => (
@@ -1,3 +1,4 @@
1
+ import { Button, TextInput } from '../../design-system';
1
2
  /**
2
3
  * ColorPicker — HSV area + hue/alpha sliders, hex↔rgb↔hsl format cycle,
3
4
  * eyedropper, recent colors (spec 27 §5 C1). Ported from
@@ -36,7 +37,7 @@ import {
36
37
  rgbToHsv,
37
38
  toHex,
38
39
  } from './color-utils';
39
- import { FONT, FONT_MONO, fireChange, fireEnd, inputStyle, THEME } from './shared';
40
+ import { FONT_MONO, fireChange, fireEnd, inputStyle, popoverStyle, THEME } from './shared';
40
41
 
41
42
  const PICKER_W = 200;
42
43
  const PICKER_H = 150;
@@ -306,9 +307,7 @@ export function ColorPicker({
306
307
  data-testid="inspector-color-picker"
307
308
  onMouseDown={(e) => e.stopPropagation()}
308
309
  style={{
309
- background: THEME.surface,
310
- border: `1px solid ${THEME.border}`,
311
- borderRadius: 6,
310
+ ...popoverStyle,
312
311
  padding: 10,
313
312
  width: PICKER_W + 16,
314
313
  boxSizing: 'border-box',
@@ -320,7 +319,7 @@ export function ColorPicker({
320
319
  width={PICKER_W}
321
320
  height={PICKER_H}
322
321
  onMouseDown={(e) => beginDrag('sat', e)}
323
- style={{ cursor: 'crosshair', borderRadius: 4, display: 'block' }}
322
+ style={{ cursor: 'crosshair', borderRadius: THEME.radiusSmall, display: 'block' }}
324
323
  />
325
324
  <canvas
326
325
  ref={hueCanvasRef}
@@ -328,7 +327,12 @@ export function ColorPicker({
328
327
  width={PICKER_W}
329
328
  height={HUE_H}
330
329
  onMouseDown={(e) => beginDrag('hue', e)}
331
- style={{ cursor: 'pointer', borderRadius: 3, display: 'block', marginTop: 6 }}
330
+ style={{
331
+ cursor: 'pointer',
332
+ borderRadius: THEME.radiusSmall,
333
+ display: 'block',
334
+ marginTop: 6,
335
+ }}
332
336
  />
333
337
  <canvas
334
338
  ref={alphaCanvasRef}
@@ -336,20 +340,25 @@ export function ColorPicker({
336
340
  width={PICKER_W}
337
341
  height={HUE_H}
338
342
  onMouseDown={(e) => beginDrag('alpha', e)}
339
- style={{ cursor: 'pointer', borderRadius: 3, display: 'block', marginTop: 6 }}
343
+ style={{
344
+ cursor: 'pointer',
345
+ borderRadius: THEME.radiusSmall,
346
+ display: 'block',
347
+ marginTop: 6,
348
+ }}
340
349
  />
341
350
  <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginTop: 8 }}>
342
351
  <div
343
352
  style={{
344
353
  width: 22,
345
354
  height: 22,
346
- borderRadius: 4,
355
+ borderRadius: THEME.radiusSmall,
347
356
  flexShrink: 0,
348
357
  border: `1px solid ${THEME.border}`,
349
358
  background: previewBg,
350
359
  }}
351
360
  />
352
- <input
361
+ <TextInput
353
362
  type="text"
354
363
  data-testid="color-picker-text"
355
364
  value={colorInput}
@@ -360,46 +369,29 @@ export function ColorPicker({
360
369
  onBlur={handleColorInputSubmit}
361
370
  style={{ ...inputStyle(), flex: 1, fontFamily: FONT_MONO, fontSize: 10 }}
362
371
  />
363
- <button
372
+ <Button
364
373
  type="button"
374
+ variant="secondary"
375
+ size="compact"
365
376
  data-testid="color-format-toggle"
366
377
  onClick={cycleFormat}
367
378
  title="Cycle color format"
368
- style={{
369
- background: 'rgba(255,255,255,0.06)',
370
- border: 'none',
371
- borderRadius: 3,
372
- color: THEME.textMuted,
373
- fontSize: 9,
374
- fontWeight: 600,
375
- padding: '3px 5px',
376
- cursor: 'pointer',
377
- flexShrink: 0,
378
- fontFamily: FONT,
379
- }}
379
+ style={{ flexShrink: 0 }}
380
380
  >
381
381
  {format.toUpperCase()}
382
- </button>
382
+ </Button>
383
383
  {(canEyedrop || eyedropperFallback || onEyedropperPick) && (
384
- <button
384
+ <Button
385
385
  type="button"
386
+ variant="secondary"
387
+ size="compact"
386
388
  data-testid="color-picker-eyedropper"
387
389
  onClick={handleEyedropper}
388
390
  title="Eyedropper"
389
- style={{
390
- background: 'rgba(255,255,255,0.06)',
391
- border: 'none',
392
- borderRadius: 3,
393
- color: THEME.textMuted,
394
- fontSize: 11,
395
- padding: '3px 5px',
396
- cursor: 'pointer',
397
- flexShrink: 0,
398
- lineHeight: 1,
399
- }}
391
+ style={{ flexShrink: 0 }}
400
392
  >
401
393
  ⌖
402
- </button>
394
+ </Button>
403
395
  )}
404
396
  </div>
405
397
  {recentColors && recentColors.length > 0 && (
@@ -428,7 +420,7 @@ export function ColorPicker({
428
420
  style={{
429
421
  width: 16,
430
422
  height: 16,
431
- borderRadius: 3,
423
+ borderRadius: THEME.radiusSmall,
432
424
  cursor: 'pointer',
433
425
  background: rc,
434
426
  border: `1px solid ${THEME.border}`,
@@ -474,7 +466,7 @@ export function ColorSwatch({
474
466
  style={{
475
467
  width: 20,
476
468
  height: 20,
477
- borderRadius: 4,
469
+ borderRadius: THEME.radiusSmall,
478
470
  flexShrink: 0,
479
471
  background: hex,
480
472
  border: `1px solid ${THEME.border}`,
@@ -485,7 +477,15 @@ export function ColorSwatch({
485
477
  <span style={{ fontSize: 10, color: THEME.textMuted, flexShrink: 0 }}>{label}</span>
486
478
  )}
487
479
  {open && !disabled && (
488
- <div style={{ position: 'absolute', zIndex: 100, top: '100%', left: 0, marginTop: 4 }}>
480
+ <div
481
+ style={{
482
+ position: 'absolute',
483
+ zIndex: 'var(--vgai-z-dropdown)',
484
+ top: '100%',
485
+ left: 0,
486
+ marginTop: 4,
487
+ }}
488
+ >
489
489
  <ColorPicker
490
490
  value={value}
491
491
  onChange={onChange}
@@ -1,3 +1,4 @@
1
+ import { Button, TextInput } from '../../design-system';
1
2
  /**
2
3
  * FontPicker — a searchable, windowed (virtualized-by-hand, no new dep) font
3
4
  * list (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s
@@ -10,7 +11,8 @@
10
11
  */
11
12
 
12
13
  import { useEffect, useMemo, useRef, useState } from 'react';
13
- import { type ChangeHandlers, FONT, FONT_MONO, inputStyle, THEME } from './shared';
14
+ import { DisclosureIcon } from '../../design-system';
15
+ import { type ChangeHandlers, FONT, inputStyle, popoverStyle, THEME } from './shared';
14
16
 
15
17
  const ITEM_HEIGHT = 28;
16
18
  const MAX_VISIBLE = 10;
@@ -80,46 +82,36 @@ export function FontPicker({
80
82
 
81
83
  return (
82
84
  <div ref={containerRef} data-testid={testId} style={{ position: 'relative', flex: 1 }}>
83
- <button
85
+ <Button
84
86
  type="button"
87
+ variant="secondary"
88
+ className="vgai-field-trigger"
89
+ disabled={disabled}
85
90
  data-testid="font-picker-input"
86
91
  onClick={() => {
87
92
  if (!disabled) setOpen((v) => !v);
88
93
  }}
89
- style={{
90
- ...inputStyle(disabled),
91
- width: '100%',
92
- textAlign: 'left',
93
- fontSize: 10,
94
- fontFamily: FONT_MONO,
95
- cursor: disabled ? 'not-allowed' : 'pointer',
96
- display: 'flex',
97
- alignItems: 'center',
98
- justifyContent: 'space-between',
99
- }}
100
94
  >
101
95
  <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
102
96
  {displayValue || '—'}
103
97
  </span>
104
- <span style={{ fontSize: 8, color: THEME.textMuted, marginLeft: 4 }}>▼</span>
105
- </button>
98
+ <DisclosureIcon direction="down" tone="muted" style={{ marginLeft: 4 }} />
99
+ </Button>
106
100
  {open && (
107
101
  <div
108
102
  data-testid="font-picker-dropdown"
109
103
  style={{
104
+ ...popoverStyle,
110
105
  position: 'absolute',
111
106
  top: '100%',
112
107
  left: 0,
113
108
  right: 0,
114
- zIndex: 100,
115
- background: THEME.bg,
116
- border: `1px solid ${THEME.border}`,
117
- borderRadius: 4,
109
+ zIndex: 'var(--vgai-z-dropdown)',
118
110
  marginTop: 2,
119
111
  }}
120
112
  >
121
113
  <div style={{ padding: 4 }}>
122
- <input
114
+ <TextInput
123
115
  ref={searchRef}
124
116
  type="text"
125
117
  data-testid="font-picker-search"
@@ -164,7 +156,7 @@ export function FontPicker({
164
156
  cursor: 'pointer',
165
157
  fontSize: 12,
166
158
  background: isActive ? THEME.accent : 'transparent',
167
- color: isActive ? '#fff' : THEME.text,
159
+ color: isActive ? THEME.onAccent : THEME.text,
168
160
  }}
169
161
  >
170
162
  <span
@@ -1,3 +1,4 @@
1
+ import { Button } from '../../design-system';
1
2
  /**
2
3
  * GradientEditor — solid/gradient toggle, stop list (add/remove/drag),
3
4
  * linear/radial toggle, angle (spec 27 §5 C1). Ported from
@@ -151,7 +152,7 @@ export function GradientEditor({
151
152
  data-testid="gradient-preview"
152
153
  style={{
153
154
  height: 20,
154
- borderRadius: 4,
155
+ borderRadius: THEME.radiusSmall,
155
156
  border: `1px solid ${THEME.border}`,
156
157
  background: composeGradient(value),
157
158
  }}
@@ -212,35 +213,26 @@ export function GradientEditor({
212
213
  />
213
214
  <span style={{ fontSize: 9, color: THEME.textMuted }}>Stop {selectedStop + 1}</span>
214
215
  {value.stops.length > 2 && (
215
- <button
216
+ <Button
216
217
  type="button"
218
+ variant="ghost"
219
+ size="compact"
220
+ aria-label="Remove gradient stop"
217
221
  data-testid="gradient-remove-stop"
218
222
  onClick={() => removeStop(selectedStop)}
219
- style={{
220
- background: 'none',
221
- border: 'none',
222
- color: THEME.textMuted,
223
- cursor: 'pointer',
224
- fontSize: 10,
225
- }}
226
223
  >
227
224
  ×
228
- </button>
225
+ </Button>
229
226
  )}
230
- <button
227
+ <Button
231
228
  type="button"
229
+ variant="ghost"
230
+ size="compact"
232
231
  data-testid="gradient-add-stop"
233
232
  onClick={addStop}
234
- style={{
235
- background: 'none',
236
- border: 'none',
237
- color: THEME.accent,
238
- cursor: 'pointer',
239
- fontSize: 10,
240
- }}
241
233
  >
242
234
  + stop
243
- </button>
235
+ </Button>
244
236
  </div>
245
237
  <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
246
238
  <div style={{ display: 'flex', gap: 1, flex: 1 }}>
@@ -1,3 +1,4 @@
1
+ import { TextInput } from '../../design-system';
1
2
  /**
2
3
  * ScrubbableInput — a numeric input whose LABEL is a drag-to-scrub handle
3
4
  * (spec 27 §5 C1). Ported from `visual-edit/inspector.tsx`'s `ScrubbableInput`
@@ -11,11 +12,11 @@
11
12
  * into whatever CSS string they write.
12
13
  */
13
14
 
14
- import { useMemo, useRef } from 'react';
15
+ import { type ReactNode, useMemo, useRef } from 'react';
15
16
  import { type ChangeHandlers, fireChange, fireEnd, inputStyle, rowStyle, THEME } from './shared';
16
17
 
17
18
  export interface ScrubbableInputProps extends ChangeHandlers<number> {
18
- label: string;
19
+ label: ReactNode;
19
20
  unit?: string | undefined;
20
21
  step?: number | undefined;
21
22
  min?: number | undefined;
@@ -119,8 +120,10 @@ export function ScrubbableInput({
119
120
  return (
120
121
  <div style={{ ...rowStyle, ...extraStyle }}>
121
122
  <span
123
+ className="vgai-scrub-label"
122
124
  data-testid={testId ? `${testId}-label` : undefined}
123
125
  onMouseDown={handleScrubStart}
126
+ data-disabled={disabled || undefined}
124
127
  style={{
125
128
  fontSize: 11,
126
129
  color: disabled ? THEME.dynamic : THEME.textMuted,
@@ -132,7 +135,7 @@ export function ScrubbableInput({
132
135
  >
133
136
  {label}
134
137
  </span>
135
- <input
138
+ <TextInput
136
139
  data-testid={testId}
137
140
  type="text"
138
141
  value={`${value}${unit}`}