@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,1049 @@
1
+ /**
2
+ * Global editor stylesheet injector (editor-style-polish U0). Installs a
3
+ * single `<style id="vgai-editor-theme">` tag, idempotently, mirroring the
4
+ * one real precedent for runtime-injected CSS in this codebase
5
+ * (`ProjectScreen.tsx`'s own `<style>` tag — the only place today with real
6
+ * `:hover`/`:focus-visible`/`:disabled` support, per the audit's THEME L).
7
+ *
8
+ * Values are interpolated from `theme.ts` — the single source of truth — so
9
+ * this sheet can never drift from the plain-TS token module the way
10
+ * `ProjectScreen.tsx`'s own hand-retyped palette drifted from everyone else's.
11
+ *
12
+ * SCOPE FENCE: variables live on `.vgai-editor-theme`, component paint uses
13
+ * the reserved `.vgai-*` namespace, and scrollbar policy is scoped beneath
14
+ * the theme root. Game content is not a second consumer of this sheet.
15
+ */
16
+
17
+ import {
18
+ chromeSize,
19
+ controlSize,
20
+ EDITOR_THEME_CLASS,
21
+ editorThemeVariables,
22
+ fontSize,
23
+ graphiteDarkEditorTheme,
24
+ space,
25
+ strokeWidth,
26
+ zIndex,
27
+ } from './theme';
28
+
29
+ const STYLE_TAG_ID = 'vgai-editor-theme';
30
+
31
+ function buildCss(): string {
32
+ const themeDeclarations = Object.entries(editorThemeVariables(graphiteDarkEditorTheme))
33
+ .map(([name, value]) => ` ${name}: ${value};`)
34
+ .join('\n');
35
+ return `
36
+ .${EDITOR_THEME_CLASS} {
37
+ ${themeDeclarations}
38
+
39
+ /* Legacy aliases. New code consumes the semantic variables above. */
40
+ --vgai-bg-0: var(--vgai-surface-shell);
41
+ --vgai-bg-1: var(--vgai-surface-panel);
42
+ --vgai-bg-2: var(--vgai-surface-chrome);
43
+ --vgai-bg-3: var(--vgai-surface-raised);
44
+ --vgai-bg-inset: var(--vgai-surface-inset);
45
+
46
+ /* Borders */
47
+ --vgai-border-1: var(--vgai-boundary-default);
48
+ --vgai-border-2: var(--vgai-boundary-strong);
49
+
50
+ /* Text */
51
+ --vgai-text-1: var(--vgai-content-primary);
52
+ --vgai-text-2: var(--vgai-content-muted);
53
+ --vgai-text-3: var(--vgai-content-dim);
54
+
55
+ /* Spacing scale */
56
+ --vgai-space-1: ${space[1]}px;
57
+ --vgai-space-2: ${space[2]}px;
58
+ --vgai-space-3: ${space[3]}px;
59
+ --vgai-space-4: ${space[4]}px;
60
+ --vgai-space-5: ${space[5]}px;
61
+ --vgai-space-6: ${space[6]}px;
62
+ --vgai-space-8: ${space[8]}px;
63
+ --vgai-space-10: ${space[10]}px;
64
+ --vgai-space-12: ${space[12]}px;
65
+
66
+ /* Semantic chrome + control dimensions */
67
+ --vgai-command-bar-height: ${chromeSize.commandBar}px;
68
+ --vgai-panel-header-height: ${chromeSize.panelHeader}px;
69
+ --vgai-local-toolbar-height: ${chromeSize.localToolbar}px;
70
+ --vgai-tree-row-height: ${chromeSize.treeRow}px;
71
+ --vgai-status-bar-height: ${chromeSize.statusBar}px;
72
+ --vgai-control-compact-height: ${controlSize.compact}px;
73
+ --vgai-control-default-height: ${controlSize.default}px;
74
+ --vgai-control-comfortable-height: ${controlSize.comfortable}px;
75
+ --vgai-stroke-resting: ${strokeWidth.resting}px;
76
+ --vgai-stroke-active: ${strokeWidth.active}px;
77
+
78
+ /* Type scale */
79
+ --vgai-font-xs: ${fontSize.xs}px;
80
+ --vgai-font-sm: ${fontSize.sm}px;
81
+ --vgai-font-base: ${fontSize.base}px;
82
+ --vgai-font-md: ${fontSize.md}px;
83
+ --vgai-font-lg: ${fontSize.lg}px;
84
+ --vgai-font-xl: ${fontSize.xl}px;
85
+ --vgai-font-2xl: ${fontSize['2xl']}px;
86
+ --vgai-font-heading: ${fontSize.heading}px;
87
+ /* Z-index scale */
88
+ --vgai-z-base: ${zIndex.base};
89
+ --vgai-z-overlay-low: ${zIndex.overlayLow};
90
+ --vgai-z-dropdown: ${zIndex.dropdown};
91
+ --vgai-z-sticky: ${zIndex.sticky};
92
+ --vgai-z-toast: ${zIndex.toast};
93
+ --vgai-z-modal: ${zIndex.modal};
94
+ }
95
+
96
+ /* Native controls otherwise fall back to the browser's unrelated UI font.
97
+ * Keep the reset scoped to the editor shell; component classes and inline
98
+ * styles can still opt into a different size or the monospace stack. */
99
+ .vgai-editor-shell button,
100
+ .vgai-editor-shell input,
101
+ .vgai-editor-shell select,
102
+ .vgai-editor-shell textarea {
103
+ font-family: inherit;
104
+ }
105
+
106
+ .vgai-editor-shell button {
107
+ font-size: inherit;
108
+ }
109
+
110
+ .vgai-sr-only {
111
+ position: absolute;
112
+ width: 1px;
113
+ height: 1px;
114
+ padding: 0;
115
+ overflow: hidden;
116
+ clip: rect(0, 0, 0, 0);
117
+ white-space: nowrap;
118
+ border: 0;
119
+ }
120
+
121
+ /* ---------------------------------------------------------------------- */
122
+ /* Canonical editor button family. All product button paint and states live */
123
+ /* here; solid remains only as a source-compatibility alias for tools. */
124
+ /* ---------------------------------------------------------------------- */
125
+
126
+ .vgai-btn {
127
+ display: inline-flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ gap: var(--vgai-space-2);
131
+ font-family: var(--vgai-font-sans);
132
+ font-size: var(--vgai-font-md);
133
+ line-height: 1;
134
+ border-radius: var(--vgai-radius-sm);
135
+ cursor: pointer;
136
+ border: 1px solid transparent;
137
+ box-sizing: border-box;
138
+ transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease, filter 0.12s ease;
139
+ }
140
+
141
+ .vgai-btn[data-size='compact'] {
142
+ height: var(--vgai-control-compact-height);
143
+ padding-top: 0;
144
+ padding-bottom: 0;
145
+ font-size: var(--vgai-font-base);
146
+ }
147
+ .vgai-btn[data-size='default'] {
148
+ height: var(--vgai-control-default-height);
149
+ padding-top: 0;
150
+ padding-bottom: 0;
151
+ font-size: var(--vgai-font-base);
152
+ }
153
+ .vgai-btn[data-size='comfortable'] {
154
+ height: var(--vgai-control-comfortable-height);
155
+ padding-top: 0;
156
+ padding-bottom: 0;
157
+ font-size: var(--vgai-font-md);
158
+ }
159
+
160
+ .vgai-btn[data-variant='primary'],
161
+ .vgai-btn[data-variant='solid'] {
162
+ background: var(--vgai-accent);
163
+ color: var(--vgai-content-on-accent);
164
+ border-color: var(--vgai-accent);
165
+ padding: var(--vgai-space-3) var(--vgai-space-6);
166
+ font-weight: 600;
167
+ }
168
+ .vgai-btn[data-variant='primary']:hover:not(:disabled),
169
+ .vgai-btn[data-variant='solid']:hover:not(:disabled) { filter: brightness(1.08); }
170
+ .vgai-btn[data-variant='primary']:active:not(:disabled),
171
+ .vgai-btn[data-variant='solid']:active:not(:disabled) { filter: brightness(0.92); }
172
+
173
+ .vgai-btn[data-variant='secondary'] {
174
+ background: var(--vgai-surface-raised);
175
+ color: var(--vgai-content-primary);
176
+ border-color: var(--vgai-boundary-strong);
177
+ padding-inline: var(--vgai-space-4);
178
+ }
179
+ .vgai-btn[data-variant='secondary']:hover:not(:disabled) {
180
+ background: var(--vgai-surface-chrome);
181
+ border-color: var(--vgai-accent);
182
+ }
183
+ .vgai-btn[data-variant='secondary']:active:not(:disabled) { background: var(--vgai-surface-inset); }
184
+
185
+ .vgai-btn[data-variant='outline'] {
186
+ background: transparent;
187
+ color: var(--vgai-content-primary);
188
+ border-color: var(--vgai-boundary-default);
189
+ padding-inline: var(--vgai-space-4);
190
+ }
191
+ .vgai-btn[data-variant='outline']:hover:not(:disabled) {
192
+ background: var(--vgai-neutral-hover);
193
+ border-color: var(--vgai-boundary-strong);
194
+ }
195
+ .vgai-btn[data-variant='outline']:active:not(:disabled) { background: var(--vgai-neutral-active); }
196
+
197
+ .vgai-btn[data-variant='ghost'] {
198
+ background: transparent;
199
+ color: var(--vgai-content-muted);
200
+ border-color: transparent;
201
+ padding-inline: var(--vgai-space-3);
202
+ }
203
+ .vgai-btn[data-variant='ghost']:hover:not(:disabled) {
204
+ color: var(--vgai-content-primary);
205
+ background: var(--vgai-neutral-hover);
206
+ }
207
+ .vgai-btn[data-variant='ghost']:active:not(:disabled) { background: var(--vgai-neutral-active); }
208
+
209
+ .vgai-btn[data-variant='danger'] {
210
+ color: var(--vgai-danger);
211
+ background: var(--vgai-danger-muted);
212
+ border-color: var(--vgai-danger);
213
+ padding-inline: var(--vgai-space-4);
214
+ }
215
+ .vgai-btn[data-variant='danger']:hover:not(:disabled) { filter: brightness(1.12); }
216
+ .vgai-btn[data-variant='danger']:active:not(:disabled) { filter: brightness(0.9); }
217
+
218
+ .vgai-btn[data-variant='success'] {
219
+ color: var(--vgai-content-on-accent);
220
+ background: var(--vgai-success);
221
+ border-color: var(--vgai-success);
222
+ padding-inline: var(--vgai-space-4);
223
+ font-weight: 600;
224
+ }
225
+ .vgai-btn[data-variant='success']:hover:not(:disabled) { filter: brightness(1.1); }
226
+ .vgai-btn[data-variant='success']:active:not(:disabled) { filter: brightness(0.92); }
227
+
228
+ .vgai-btn[aria-pressed='true'] {
229
+ color: var(--vgai-accent);
230
+ background: var(--vgai-accent-muted);
231
+ border-color: var(--vgai-accent);
232
+ }
233
+ .vgai-btn[aria-busy='true'] { cursor: progress; }
234
+
235
+ .vgai-btn[data-icon='true'] {
236
+ width: var(--vgai-control-default-height);
237
+ padding: 0;
238
+ }
239
+ .vgai-btn[data-icon='true'][data-size='compact'] {
240
+ width: var(--vgai-control-compact-height);
241
+ }
242
+ .vgai-btn[data-icon='true'][data-size='comfortable'] {
243
+ width: var(--vgai-control-comfortable-height);
244
+ }
245
+
246
+ .vgai-btn:disabled,
247
+ .vgai-btn[aria-disabled='true'] {
248
+ opacity: 0.4;
249
+ cursor: not-allowed;
250
+ filter: none;
251
+ }
252
+
253
+ .vgai-btn:focus-visible {
254
+ outline: var(--vgai-focus-ring);
255
+ outline-offset: 1px;
256
+ }
257
+
258
+ .vgai-debugger-machine {
259
+ display: block;
260
+ width: 100%;
261
+ height: auto;
262
+ justify-content: flex-start;
263
+ border-left: var(--vgai-stroke-active) solid transparent;
264
+ padding: var(--vgai-space-3) var(--vgai-space-4);
265
+ text-align: left;
266
+ }
267
+ .vgai-debugger-machine[data-selected='true'] {
268
+ border-left-color: var(--vgai-accent);
269
+ background: var(--vgai-surface-chrome);
270
+ }
271
+ .vgai-performance-overlay {
272
+ pointer-events: auto;
273
+ display: grid;
274
+ grid-template-columns: repeat(5, auto);
275
+ width: auto;
276
+ height: auto;
277
+ gap: var(--vgai-space-5);
278
+ border-color: var(--vgai-boundary-strong);
279
+ background: var(--vgai-surface-overlay);
280
+ color: var(--vgai-content-primary);
281
+ padding: var(--vgai-space-3) var(--vgai-space-4);
282
+ font-family: var(--vgai-font-mono);
283
+ font-size: var(--vgai-font-sm);
284
+ }
285
+ .vgai-performance-overlay[data-enabled='true'] { border-color: var(--vgai-accent); }
286
+ .vgai-field-trigger {
287
+ width: 100%;
288
+ justify-content: space-between;
289
+ overflow: hidden;
290
+ font-family: var(--vgai-font-mono);
291
+ text-align: left;
292
+ }
293
+ .vgai-inspector-group-trigger {
294
+ width: 100%;
295
+ height: auto;
296
+ justify-content: flex-start;
297
+ padding: var(--vgai-space-4);
298
+ font-weight: 600;
299
+ text-align: left;
300
+ text-transform: uppercase;
301
+ letter-spacing: 0.4px;
302
+ }
303
+ .vgai-hierarchy-more {
304
+ width: 100%;
305
+ height: var(--vgai-tree-row-height);
306
+ justify-content: flex-start;
307
+ font-style: italic;
308
+ text-align: left;
309
+ }
310
+ .vgai-btn.vgai-tree-caret {
311
+ width: 12px;
312
+ height: 18px;
313
+ flex: 0 0 12px;
314
+ font-size: var(--vgai-font-xs);
315
+ }
316
+ .vgai-chat-icon {
317
+ width: var(--vgai-control-default-height);
318
+ padding-inline: 0;
319
+ }
320
+ .vgai-chat-session-row {
321
+ width: 100%;
322
+ height: auto;
323
+ justify-content: flex-start;
324
+ padding: var(--vgai-space-4);
325
+ text-align: left;
326
+ }
327
+ .vgai-chat-session-row[data-selected='true'] { background: var(--vgai-surface-raised); }
328
+ .vgai-chat-harness-trigger {
329
+ max-width: 190px;
330
+ overflow: hidden;
331
+ white-space: nowrap;
332
+ }
333
+ .vgai-chat-header-trigger {
334
+ min-width: 0;
335
+ flex: 1;
336
+ justify-content: flex-start;
337
+ overflow: hidden;
338
+ text-align: left;
339
+ }
340
+ .vgai-chat-header-trigger[aria-expanded='true'] {
341
+ border-color: var(--vgai-boundary-strong);
342
+ background: var(--vgai-surface-chrome);
343
+ }
344
+ .vgai-save-status { gap: var(--vgai-space-3); }
345
+ .vgai-save-status[data-save-state='unsaved'] { color: var(--vgai-warn); }
346
+ .vgai-save-status[data-save-state='failed'] { color: var(--vgai-danger); }
347
+ .vgai-save-status-dot {
348
+ width: 7px;
349
+ height: 7px;
350
+ flex: 0 0 7px;
351
+ border-radius: var(--vgai-radius-full);
352
+ background: currentColor;
353
+ }
354
+ .vgai-status-action { color: var(--vgai-content-dim); }
355
+ .vgai-status-action[data-has-errors='true'],
356
+ .vgai-status-action[data-connection-state='error'] { color: var(--vgai-danger); }
357
+ .vgai-status-action[data-connection-state='connecting'] { color: var(--vgai-warn); }
358
+ .vgai-status-action[data-connection-state='connected'] { color: var(--vgai-success); }
359
+
360
+ /* ---------------------------------------------------------------------- */
361
+ /* .vgai-input / .vgai-select / .vgai-checkbox — shared form-control */
362
+ /* classes. */
363
+ /* ---------------------------------------------------------------------- */
364
+
365
+ .vgai-input {
366
+ background: var(--vgai-bg-inset);
367
+ color: var(--vgai-text-1);
368
+ border: 1px solid var(--vgai-border-1);
369
+ border-radius: var(--vgai-radius-sm);
370
+ padding: var(--vgai-space-1) var(--vgai-space-3);
371
+ font-size: var(--vgai-font-base);
372
+ font-family: var(--vgai-font-sans);
373
+ outline: none;
374
+ min-width: 0;
375
+ min-height: var(--vgai-control-default-height);
376
+ box-sizing: border-box;
377
+ }
378
+ .vgai-input:hover:not(:disabled) { border-color: var(--vgai-border-2); }
379
+ .vgai-input:focus-visible {
380
+ border-color: var(--vgai-accent);
381
+ outline: var(--vgai-focus-ring);
382
+ outline-offset: -1px;
383
+ }
384
+ .vgai-input[aria-invalid='true'] {
385
+ border-color: var(--vgai-danger);
386
+ }
387
+ .vgai-input:disabled {
388
+ opacity: 0.5;
389
+ cursor: not-allowed;
390
+ }
391
+
392
+ .vgai-select {
393
+ appearance: none;
394
+ -webkit-appearance: none;
395
+ background-color: var(--vgai-bg-inset);
396
+ background-image: var(--vgai-select-chevron);
397
+ background-repeat: no-repeat;
398
+ background-position: right 6px center;
399
+ background-size: 8px 5px;
400
+ color: var(--vgai-text-1);
401
+ border: 1px solid var(--vgai-border-1);
402
+ border-radius: var(--vgai-radius-sm);
403
+ padding: var(--vgai-space-1) var(--vgai-space-6) var(--vgai-space-1) var(--vgai-space-3);
404
+ font-size: var(--vgai-font-base);
405
+ font-family: var(--vgai-font-sans);
406
+ outline: none;
407
+ min-height: var(--vgai-control-default-height);
408
+ box-sizing: border-box;
409
+ cursor: pointer;
410
+ }
411
+ .vgai-select:hover:not(:disabled) { border-color: var(--vgai-border-2); }
412
+ .vgai-select:focus-visible {
413
+ border-color: var(--vgai-accent);
414
+ outline: var(--vgai-focus-ring);
415
+ outline-offset: -1px;
416
+ }
417
+ .vgai-select:disabled {
418
+ opacity: 0.5;
419
+ cursor: not-allowed;
420
+ }
421
+ .vgai-select option {
422
+ background: var(--vgai-bg-2);
423
+ color: var(--vgai-text-1);
424
+ }
425
+
426
+ .vgai-checkbox {
427
+ accent-color: var(--vgai-accent);
428
+ width: 13px;
429
+ height: 13px;
430
+ cursor: pointer;
431
+ margin: 0;
432
+ }
433
+ .vgai-checkbox:focus-visible {
434
+ outline: var(--vgai-focus-ring);
435
+ outline-offset: 2px;
436
+ }
437
+ .vgai-checkbox:indeterminate { accent-color: var(--vgai-warn); }
438
+ .vgai-checkbox:disabled {
439
+ opacity: 0.5;
440
+ cursor: not-allowed;
441
+ }
442
+
443
+ .vgai-color-swatch {
444
+ width: var(--vgai-control-compact-height);
445
+ height: var(--vgai-control-compact-height);
446
+ flex: 0 0 auto;
447
+ padding: 0;
448
+ overflow: hidden;
449
+ background: transparent;
450
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
451
+ border-radius: var(--vgai-radius-sm);
452
+ cursor: pointer;
453
+ }
454
+ .vgai-color-swatch:hover:not(:disabled) { border-color: var(--vgai-boundary-strong); }
455
+ .vgai-color-swatch:focus-visible,
456
+ .vgai-file-input:focus-visible,
457
+ .vgai-range:focus-visible { outline: var(--vgai-focus-ring); outline-offset: 2px; }
458
+ .vgai-color-swatch:disabled,
459
+ .vgai-file-input:disabled,
460
+ .vgai-range:disabled { opacity: 0.5; cursor: not-allowed; }
461
+ .vgai-file-input { color: var(--vgai-content-muted); font: inherit; }
462
+ .vgai-range { min-width: 0; accent-color: var(--vgai-accent); }
463
+
464
+ .vgai-number-input,
465
+ .vgai-color-input { display: flex; min-width: 0; align-items: center; gap: var(--vgai-space-2); }
466
+ .vgai-number-input-label {
467
+ width: 12px;
468
+ flex: 0 0 auto;
469
+ color: var(--vgai-content-muted);
470
+ font-size: var(--vgai-font-sm);
471
+ font-weight: 600;
472
+ text-align: center;
473
+ user-select: none;
474
+ }
475
+ .vgai-number-input-editor,
476
+ .vgai-number-input-scrub,
477
+ .vgai-color-input > .vgai-input { width: 100%; min-width: 0; }
478
+ .vgai-number-input-scrub {
479
+ box-sizing: border-box;
480
+ overflow: hidden;
481
+ padding: 2px 6px;
482
+ color: var(--vgai-content-primary);
483
+ background: var(--vgai-surface-inset);
484
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
485
+ border-radius: var(--vgai-radius-sm);
486
+ font-size: var(--vgai-font-base);
487
+ text-overflow: ellipsis;
488
+ white-space: nowrap;
489
+ cursor: ew-resize;
490
+ user-select: none;
491
+ }
492
+ .vgai-number-input-scrub:hover { border-color: var(--vgai-boundary-strong); }
493
+ .vgai-scrub-label { transition: color 0.12s ease, filter 0.12s ease; }
494
+ .vgai-scrub-label:hover:not([data-disabled='true']) { color: var(--vgai-content-primary) !important; }
495
+ .vgai-number-input-scrub[data-mixed='true'],
496
+ .vgai-color-input > .vgai-input[data-mixed='true'] { color: var(--vgai-content-dim); font-style: italic; }
497
+ .vgai-color-input-mixed {
498
+ width: var(--vgai-control-compact-height);
499
+ height: var(--vgai-control-compact-height);
500
+ flex: 0 0 auto;
501
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
502
+ border-radius: var(--vgai-radius-sm);
503
+ background-color: var(--vgai-surface-inset);
504
+ background-image: linear-gradient(45deg, var(--vgai-content-dim) 25%, transparent 25%, transparent 75%, var(--vgai-content-dim) 75%), linear-gradient(45deg, var(--vgai-content-dim) 25%, transparent 25%, transparent 75%, var(--vgai-content-dim) 75%);
505
+ background-position: 0 0, 4px 4px;
506
+ background-size: 8px 8px;
507
+ }
508
+
509
+ .vgai-section { border-bottom: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); }
510
+ .vgai-section-header {
511
+ display: flex;
512
+ width: 100%;
513
+ min-height: var(--vgai-control-default-height);
514
+ align-items: center;
515
+ gap: var(--vgai-space-2);
516
+ padding: var(--vgai-space-2) var(--vgai-space-4);
517
+ color: var(--vgai-content-primary);
518
+ background: transparent;
519
+ border: 0;
520
+ font: inherit;
521
+ font-size: var(--vgai-font-base);
522
+ font-weight: 600;
523
+ text-align: left;
524
+ cursor: pointer;
525
+ }
526
+ .vgai-section-header:hover { background: var(--vgai-neutral-hover); }
527
+ .vgai-section-header:focus-visible { outline: var(--vgai-focus-ring); outline-offset: -2px; }
528
+ .vgai-section-body { padding: 0 var(--vgai-space-4) var(--vgai-space-4); }
529
+
530
+ .vgai-xstate-node {
531
+ display: flex;
532
+ flex-direction: column;
533
+ align-items: flex-start;
534
+ justify-content: center;
535
+ gap: var(--vgai-space-1);
536
+ padding: var(--vgai-space-3) var(--vgai-space-5);
537
+ color: var(--vgai-content-primary);
538
+ background: var(--vgai-surface-panel);
539
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-strong);
540
+ font-size: var(--vgai-font-base);
541
+ text-align: left;
542
+ transition: background 0.1s ease, border-color 0.1s ease, box-shadow 0.1s ease;
543
+ }
544
+ .vgai-xstate-node:hover { background: var(--vgai-surface-chrome); }
545
+ .vgai-xstate-node[data-active='true'] { border-color: var(--vgai-success); }
546
+ .vgai-xstate-node[data-selected='true'] {
547
+ border-color: var(--vgai-accent);
548
+ box-shadow: 0 0 0 var(--vgai-stroke-resting) var(--vgai-accent);
549
+ }
550
+ .vgai-xstate-node-type { color: var(--vgai-content-dim); transition: color 0.1s ease; }
551
+ .vgai-xstate-node:hover .vgai-xstate-node-type,
552
+ .vgai-xstate-node[data-selected='true'] .vgai-xstate-node-type { color: var(--vgai-content-primary); }
553
+
554
+ /* ---------------------------------------------------------------------- */
555
+ /* Layout, typography, and surface primitives. Product code composes these */
556
+ /* roles instead of restating their visual recipes in inline objects. */
557
+ /* ---------------------------------------------------------------------- */
558
+
559
+ .vgai-stack { display: flex; min-width: 0; flex-direction: column; }
560
+ .vgai-inline { display: flex; min-width: 0; }
561
+ .vgai-spacer { min-width: 0; flex: 1 1 auto; }
562
+ .vgai-actions { flex: 0 0 auto; }
563
+ .vgai-divider { flex: 0 0 auto; background: var(--vgai-boundary-default); }
564
+ .vgai-divider[data-orientation='horizontal'] { width: 100%; height: var(--vgai-stroke-resting); }
565
+ .vgai-divider[data-orientation='vertical'] { width: var(--vgai-stroke-resting); height: 16px; }
566
+
567
+ .vgai-text {
568
+ min-width: 0;
569
+ margin: 0;
570
+ color: var(--vgai-content-primary);
571
+ font-family: var(--vgai-font-sans);
572
+ font-size: var(--vgai-font-base);
573
+ font-weight: 400;
574
+ line-height: 1.35;
575
+ }
576
+ .vgai-text[data-variant='caption'] { font-size: var(--vgai-font-sm); }
577
+ .vgai-text[data-variant='body'] { font-size: var(--vgai-font-base); }
578
+ .vgai-text[data-variant='label'] { font-size: var(--vgai-font-base); font-weight: 600; }
579
+ .vgai-text[data-variant='title'] { font-size: var(--vgai-font-md); font-weight: 600; }
580
+ .vgai-text[data-variant='heading'] { font-size: var(--vgai-font-xl); font-weight: 600; }
581
+ .vgai-text[data-variant='display'] { font-size: var(--vgai-font-heading); font-weight: 600; }
582
+ .vgai-text[data-variant='code'] { font-family: var(--vgai-font-mono); font-size: var(--vgai-font-base); }
583
+ .vgai-text[data-tone='muted'] { color: var(--vgai-content-muted); }
584
+ .vgai-text[data-tone='dim'] { color: var(--vgai-content-dim); }
585
+ .vgai-text[data-tone='accent'] { color: var(--vgai-accent); }
586
+ .vgai-text[data-tone='danger'] { color: var(--vgai-danger); }
587
+ .vgai-text[data-tone='warning'] { color: var(--vgai-warn); }
588
+ .vgai-text[data-tone='success'] { color: var(--vgai-success); }
589
+ .vgai-text[data-truncate='true'] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
590
+ .vgai-text[data-selectable='true'] { user-select: text; }
591
+
592
+ .vgai-surface {
593
+ min-width: 0;
594
+ color: var(--vgai-content-primary);
595
+ background: var(--vgai-surface-panel);
596
+ box-sizing: border-box;
597
+ }
598
+ .vgai-surface[data-variant='shell'] { background: var(--vgai-surface-shell); }
599
+ .vgai-surface[data-variant='panel'] { background: var(--vgai-surface-panel); }
600
+ .vgai-surface[data-variant='chrome'] { background: var(--vgai-surface-chrome); }
601
+ .vgai-surface[data-variant='raised'] { background: var(--vgai-surface-raised); }
602
+ .vgai-surface[data-variant='inset'] { background: var(--vgai-surface-inset); }
603
+ .vgai-surface[data-variant='overlay'] { background: var(--vgai-surface-overlay); }
604
+ .vgai-surface[data-border='true'] { border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); }
605
+ .vgai-surface[data-scroll='true'] { min-height: 0; overflow: auto; }
606
+
607
+ /* Modal composition. Product dialogs supply content; this family owns chrome. */
608
+ .vgai-dialog-scrim {
609
+ position: fixed;
610
+ inset: 0;
611
+ z-index: var(--vgai-z-modal);
612
+ display: flex;
613
+ align-items: center;
614
+ justify-content: center;
615
+ padding: var(--vgai-space-10);
616
+ background: var(--vgai-scrim);
617
+ pointer-events: auto;
618
+ box-sizing: border-box;
619
+ }
620
+ .vgai-dialog {
621
+ display: flex;
622
+ width: min(520px, calc(100vw - 48px));
623
+ max-height: calc(100vh - 48px);
624
+ min-width: 360px;
625
+ flex-direction: column;
626
+ overflow: hidden;
627
+ color: var(--vgai-content-primary);
628
+ background: var(--vgai-surface-chrome);
629
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-strong);
630
+ border-radius: var(--vgai-radius-lg);
631
+ box-shadow: var(--vgai-shadow-lg);
632
+ box-sizing: border-box;
633
+ }
634
+ .vgai-dialog[data-size='compact'] { width: min(420px, calc(100vw - 48px)); }
635
+ .vgai-dialog[data-size='wide'] { width: min(920px, calc(100vw - 48px)); height: min(720px, calc(100vh - 48px)); }
636
+ .vgai-dialog-header { padding: var(--vgai-space-8) var(--vgai-space-10); border-bottom: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); }
637
+ .vgai-dialog-body { min-height: 0; padding: var(--vgai-space-8) var(--vgai-space-10); overflow: auto; }
638
+ .vgai-dialog-footer { justify-content: flex-end; padding: var(--vgai-space-6) var(--vgai-space-10); border-top: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); }
639
+ .vgai-dialog-field { display: grid; min-width: 0; gap: var(--vgai-space-2); }
640
+ .vgai-dialog-field > .vgai-input { width: 100%; }
641
+ .vgai-joined-field { align-items: stretch; gap: 0; }
642
+ .vgai-joined-field > .vgai-input { width: 100%; border-top-right-radius: 0; border-bottom-right-radius: 0; }
643
+ .vgai-joined-field-suffix { display: inline-flex; flex: 0 0 auto; align-items: center; padding: 0 var(--vgai-space-4); color: var(--vgai-content-dim); background: var(--vgai-surface-raised); border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); border-left: 0; border-radius: 0 var(--vgai-radius-sm) var(--vgai-radius-sm) 0; white-space: nowrap; }
644
+
645
+ /* ---------------------------------------------------------------------- */
646
+ /* .vgai-menu / .vgai-menu-item — shared floating-menu classes (optional, */
647
+ /* for later units). */
648
+ /* ---------------------------------------------------------------------- */
649
+
650
+ .vgai-menu {
651
+ background: var(--vgai-bg-2);
652
+ border: 1px solid var(--vgai-border-1);
653
+ border-radius: var(--vgai-radius-md);
654
+ box-shadow: var(--vgai-shadow-md);
655
+ padding: var(--vgai-space-2);
656
+ z-index: var(--vgai-z-toast);
657
+ }
658
+ .vgai-menu-item {
659
+ display: flex;
660
+ align-items: center;
661
+ width: 100%;
662
+ min-height: var(--vgai-control-default-height);
663
+ box-sizing: border-box;
664
+ border: 0;
665
+ background: transparent;
666
+ padding: var(--vgai-space-2) var(--vgai-space-4);
667
+ border-radius: var(--vgai-radius-sm);
668
+ font-size: var(--vgai-font-base);
669
+ color: var(--vgai-text-1);
670
+ cursor: pointer;
671
+ user-select: none;
672
+ font-family: inherit;
673
+ text-align: left;
674
+ white-space: nowrap;
675
+ }
676
+ .vgai-menu-item:hover {
677
+ background: var(--vgai-accent-muted);
678
+ }
679
+ .vgai-menu-item:focus-visible {
680
+ outline: var(--vgai-focus-ring);
681
+ outline-offset: -1px;
682
+ }
683
+ .vgai-menu-item:disabled {
684
+ color: var(--vgai-text-3);
685
+ cursor: default;
686
+ }
687
+ .vgai-menu-item:disabled:hover {
688
+ background: transparent;
689
+ }
690
+ .vgai-menu-separator { height: var(--vgai-stroke-resting); margin: var(--vgai-space-1) var(--vgai-space-2); border: 0; background: var(--vgai-boundary-default); }
691
+
692
+ .vgai-menu-trigger {
693
+ height: 100%;
694
+ border: 0;
695
+ border-radius: var(--vgai-radius-sm);
696
+ background: transparent;
697
+ color: var(--vgai-text-2);
698
+ padding: 0 var(--vgai-space-3);
699
+ cursor: pointer;
700
+ font: inherit;
701
+ }
702
+ .vgai-menu-trigger:hover,
703
+ .vgai-menu-trigger[aria-expanded='true'] {
704
+ color: var(--vgai-text-1);
705
+ background: var(--vgai-bg-3);
706
+ }
707
+ .vgai-menu-trigger:focus-visible {
708
+ outline: var(--vgai-focus-ring);
709
+ outline-offset: -1px;
710
+ }
711
+
712
+ /* ---------------------------------------------------------------------- */
713
+ /* Editor composition patterns: toolbars, tabs, trees, fields, and states. */
714
+ /* ---------------------------------------------------------------------- */
715
+
716
+ .vgai-toolbar {
717
+ display: flex;
718
+ min-width: 0;
719
+ min-height: var(--vgai-local-toolbar-height);
720
+ align-items: center;
721
+ gap: var(--vgai-space-2);
722
+ padding: 0 var(--vgai-space-3);
723
+ color: var(--vgai-content-primary);
724
+ background: var(--vgai-surface-panel);
725
+ border-bottom: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
726
+ box-sizing: border-box;
727
+ }
728
+ .vgai-toolbar[data-compact='true'] {
729
+ min-height: var(--vgai-control-default-height);
730
+ padding-inline: var(--vgai-space-2);
731
+ }
732
+ .vgai-toolbar-group {
733
+ display: inline-flex;
734
+ min-width: 0;
735
+ align-items: center;
736
+ gap: var(--vgai-space-2);
737
+ }
738
+ .vgai-toolbar-divider {
739
+ width: 1px;
740
+ height: 16px;
741
+ flex: 0 0 auto;
742
+ margin: 0 var(--vgai-space-1);
743
+ background: var(--vgai-boundary-default);
744
+ }
745
+ .vgai-floating-toolbar {
746
+ min-height: auto;
747
+ padding: var(--vgai-space-2) var(--vgai-space-3);
748
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-strong);
749
+ border-radius: var(--vgai-radius-md);
750
+ background: color-mix(in srgb, var(--vgai-surface-panel) 90%, transparent);
751
+ box-shadow: var(--vgai-shadow-sm);
752
+ backdrop-filter: blur(8px);
753
+ pointer-events: auto;
754
+ }
755
+ .vgai-split-button { display: inline-flex; min-width: 0; align-items: stretch; }
756
+ .vgai-split-button > .vgai-btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
757
+ .vgai-split-button > .vgai-btn + .vgai-btn { min-width: 20px; padding-inline: var(--vgai-space-1); border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
758
+ .vgai-keycap { padding: 1px var(--vgai-space-2); color: var(--vgai-content-primary); background: var(--vgai-surface-raised); border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default); border-radius: var(--vgai-radius-sm); font-family: var(--vgai-font-mono); font-size: var(--vgai-font-sm); }
759
+ .vgai-viewport-toolbar { position: absolute; top: var(--vgai-space-4); z-index: var(--vgai-z-sticky); }
760
+ .vgai-viewport-toolbar-left { left: var(--vgai-space-4); }
761
+ .vgai-viewport-toolbar-right { right: var(--vgai-space-4); }
762
+ .vgai-viewport-popover-anchor { position: relative; display: inline-flex; align-items: center; }
763
+ .vgai-snap-popover { position: absolute; top: calc(100% + var(--vgai-space-2)); left: 0; z-index: var(--vgai-z-modal); width: 170px; padding: var(--vgai-space-4); }
764
+ .vgai-helpers-menu { position: absolute; top: calc(100% + var(--vgai-space-2)); right: 0; z-index: var(--vgai-z-sticky); min-width: 140px; }
765
+ .vgai-menu-check { display: inline-flex; width: 14px; flex: 0 0 auto; justify-content: center; margin-right: var(--vgai-space-2); }
766
+ .vgai-selectable { transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease; }
767
+ .vgai-selectable:hover { background: var(--vgai-neutral-hover); }
768
+ .vgai-selectable[data-selected='true'] { background: var(--vgai-accent-muted); }
769
+ .vgai-list-button { display: block; width: 100%; min-width: 0; border: 0; border-left: var(--vgai-stroke-active) solid transparent; background: transparent; color: var(--vgai-content-muted); padding: var(--vgai-space-3) var(--vgai-space-4); text-align: left; font: inherit; cursor: pointer; box-sizing: border-box; }
770
+ .vgai-list-button:hover { color: var(--vgai-content-primary); background: var(--vgai-neutral-hover); }
771
+ .vgai-list-button[data-selected='true'] { color: var(--vgai-content-primary); background: var(--vgai-accent-muted); }
772
+ .vgai-list-button[data-selected='true'][data-accent='bar'] { border-left-color: var(--vgai-accent); }
773
+ .vgai-list-button:disabled { opacity: 0.5; cursor: default; }
774
+ .vgai-list-button:focus-visible { outline: var(--vgai-focus-ring); outline-offset: -2px; }
775
+ .vgai-playbar { pointer-events: auto; }
776
+ .vgai-playbar-popover-anchor { position: relative; }
777
+ .vgai-resolution-menu { position: absolute; top: calc(100% + var(--vgai-space-2)); right: 0; z-index: var(--vgai-z-sticky); min-width: 220px; }
778
+ .vgai-resolution-menu [aria-checked='true'] { color: var(--vgai-content-primary); background: var(--vgai-accent-muted); }
779
+ .vgai-camera-info { position: absolute; right: var(--vgai-space-4); bottom: var(--vgai-space-4); padding: var(--vgai-space-2) var(--vgai-space-3); border-radius: var(--vgai-radius-md); backdrop-filter: blur(8px); pointer-events: none; }
780
+ .vgai-react-canvas-controls { position: absolute; right: var(--vgai-space-6); bottom: var(--vgai-space-6); z-index: var(--vgai-z-sticky); overflow: visible; }
781
+ .vgai-react-viewport-select { border-color: transparent; background-color: transparent; }
782
+
783
+ .vgai-tabs {
784
+ display: flex;
785
+ height: var(--vgai-panel-header-height);
786
+ min-width: 0;
787
+ align-items: stretch;
788
+ gap: 2px;
789
+ padding-inline: var(--vgai-space-2);
790
+ overflow: hidden;
791
+ background: var(--vgai-surface-chrome);
792
+ border-bottom: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
793
+ }
794
+ .vgai-tab {
795
+ position: relative;
796
+ display: inline-flex;
797
+ min-width: 0;
798
+ max-width: 220px;
799
+ align-items: center;
800
+ gap: var(--vgai-space-2);
801
+ padding: 0 var(--vgai-space-4);
802
+ color: var(--vgai-content-muted);
803
+ background: transparent;
804
+ border: 0;
805
+ font: inherit;
806
+ cursor: pointer;
807
+ }
808
+ .vgai-tab:hover { color: var(--vgai-content-primary); background: var(--vgai-surface-raised); }
809
+ .vgai-tab[data-selected='true'] { color: var(--vgai-content-primary); }
810
+ .vgai-tab[data-selected='true']::after {
811
+ position: absolute;
812
+ right: var(--vgai-space-4);
813
+ bottom: 0;
814
+ left: var(--vgai-space-4);
815
+ height: var(--vgai-stroke-active);
816
+ border-radius: 2px 2px 0 0;
817
+ background: var(--vgai-accent);
818
+ content: '';
819
+ }
820
+ .vgai-tab:focus-visible { outline: var(--vgai-focus-ring); outline-offset: -2px; }
821
+ .vgai-tab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
822
+ .vgai-tab-dirty {
823
+ width: 6px;
824
+ height: 6px;
825
+ flex: 0 0 auto;
826
+ border-radius: var(--vgai-radius-full);
827
+ background: var(--vgai-warn);
828
+ }
829
+ .vgai-tab-badge,
830
+ .vgai-badge {
831
+ display: inline-flex;
832
+ min-width: 15px;
833
+ height: 15px;
834
+ align-items: center;
835
+ justify-content: center;
836
+ padding: 0 var(--vgai-space-1);
837
+ border-radius: var(--vgai-radius-full);
838
+ color: var(--vgai-surface-shell);
839
+ background: var(--vgai-content-muted);
840
+ font-size: var(--vgai-font-xs);
841
+ line-height: 1;
842
+ box-sizing: border-box;
843
+ }
844
+
845
+ .vgai-tree { min-width: 0; color: var(--vgai-content-primary); }
846
+ .vgai-tree-row {
847
+ display: flex;
848
+ height: var(--vgai-tree-row-height);
849
+ min-width: 0;
850
+ align-items: center;
851
+ gap: var(--vgai-space-2);
852
+ padding-right: var(--vgai-space-2);
853
+ color: var(--vgai-content-muted);
854
+ border-left: var(--vgai-stroke-active) solid transparent;
855
+ box-sizing: border-box;
856
+ cursor: default;
857
+ user-select: none;
858
+ }
859
+ .vgai-tree-row:hover { color: var(--vgai-content-primary); background: var(--vgai-neutral-hover); }
860
+ .vgai-tree-row[data-selected='true'] {
861
+ color: var(--vgai-content-primary);
862
+ background: var(--vgai-accent-muted);
863
+ border-left-color: var(--vgai-accent);
864
+ }
865
+ .vgai-tree-row[data-muted='true'] { color: var(--vgai-content-dim); }
866
+ .vgai-tree-row[data-dragging='true'] {
867
+ color: var(--vgai-content-muted);
868
+ background: var(--vgai-neutral-hover);
869
+ outline: 1px dashed var(--vgai-boundary-strong);
870
+ outline-offset: -1px;
871
+ }
872
+ .vgai-tree-row:focus-visible { outline: var(--vgai-focus-ring); outline-offset: -2px; }
873
+ .vgai-tree-row-leading { display: inline-flex; width: 14px; flex: 0 0 auto; justify-content: center; }
874
+ .vgai-tree-row-label { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
875
+ .vgai-tree-row-actions { display: inline-flex; flex: 0 0 auto; align-items: center; gap: var(--vgai-space-1); }
876
+
877
+ .vgai-field-group { display: grid; gap: var(--vgai-space-3); padding: var(--vgai-space-4); }
878
+ .vgai-field-row {
879
+ display: grid;
880
+ grid-template-columns: minmax(64px, 84px) minmax(0, 1fr);
881
+ min-width: 0;
882
+ align-items: center;
883
+ gap: var(--vgai-space-3);
884
+ }
885
+ .vgai-field-row[data-compact='true'] { grid-template-columns: minmax(52px, 72px) minmax(0, 1fr); }
886
+ .vgai-field-label { min-width: 0; color: var(--vgai-content-muted); font-size: var(--vgai-font-base); }
887
+ .vgai-field-control { display: flex; min-width: 0; align-items: center; gap: var(--vgai-space-2); }
888
+ .vgai-field-hint {
889
+ grid-column: 2;
890
+ color: var(--vgai-content-dim);
891
+ font-size: var(--vgai-font-sm);
892
+ line-height: 1.35;
893
+ }
894
+
895
+ .vgai-state-surface {
896
+ display: flex;
897
+ min-width: 0;
898
+ min-height: 120px;
899
+ flex-direction: column;
900
+ align-items: center;
901
+ justify-content: center;
902
+ gap: var(--vgai-space-3);
903
+ padding: var(--vgai-space-8);
904
+ color: var(--vgai-content-muted);
905
+ text-align: center;
906
+ box-sizing: border-box;
907
+ }
908
+ .vgai-state-surface[data-compact='true'] { min-height: 64px; padding: var(--vgai-space-4); }
909
+ .vgai-state-surface[data-tone='error'] { color: var(--vgai-danger); }
910
+ .vgai-state-surface[data-tone='success'] { color: var(--vgai-success); }
911
+ .vgai-state-surface[data-tone='loading'] .vgai-state-surface-icon { animation: editor-spin 0.8s linear infinite; }
912
+ .vgai-state-surface-icon { color: currentColor; font-size: var(--vgai-font-2xl); }
913
+ .vgai-state-surface-title { color: var(--vgai-content-primary); font-size: var(--vgai-font-md); }
914
+ .vgai-state-surface-description { max-width: 42ch; color: var(--vgai-content-dim); line-height: 1.45; }
915
+ .vgai-state-surface-action { margin-top: var(--vgai-space-2); }
916
+
917
+ .vgai-banner {
918
+ display: flex;
919
+ min-width: 0;
920
+ align-items: center;
921
+ gap: var(--vgai-space-3);
922
+ padding: var(--vgai-space-3) var(--vgai-space-5);
923
+ border-bottom: var(--vgai-stroke-resting) solid var(--vgai-accent);
924
+ color: var(--vgai-accent);
925
+ background: var(--vgai-accent-muted);
926
+ box-sizing: border-box;
927
+ }
928
+ .vgai-banner[data-tone='warning'] { color: var(--vgai-warn); border-color: var(--vgai-warn); background: var(--vgai-warn-muted); }
929
+ .vgai-banner[data-tone='error'] { color: var(--vgai-danger); border-color: var(--vgai-danger); background: var(--vgai-danger-faint); }
930
+ .vgai-banner[data-tone='success'] { color: var(--vgai-success); border-color: var(--vgai-success); background: var(--vgai-success-muted); }
931
+ .vgai-banner-icon { display: inline-flex; flex: 0 0 auto; }
932
+ .vgai-banner-content { min-width: 0; flex: 1; color: var(--vgai-content-primary); }
933
+ .vgai-banner-actions { display: flex; flex: 0 0 auto; align-items: center; gap: var(--vgai-space-2); }
934
+
935
+ .vgai-popover {
936
+ color: var(--vgai-content-primary);
937
+ background: var(--vgai-surface-chrome);
938
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-strong);
939
+ border-radius: var(--vgai-radius-md);
940
+ box-shadow: var(--vgai-shadow-md);
941
+ }
942
+ .vgai-drop-indicator {
943
+ position: absolute;
944
+ z-index: var(--vgai-z-overlay-low);
945
+ pointer-events: none;
946
+ border: var(--vgai-stroke-active) solid var(--vgai-accent);
947
+ background: var(--vgai-accent-muted);
948
+ box-sizing: border-box;
949
+ }
950
+ .vgai-drop-indicator[data-position='before'] { inset: 0 0 auto; height: var(--vgai-stroke-active); }
951
+ .vgai-drop-indicator[data-position='after'] { inset: auto 0 0; height: var(--vgai-stroke-active); }
952
+ .vgai-drop-indicator[data-position='inside'] { inset: 1px; border-radius: var(--vgai-radius-sm); }
953
+
954
+ .vgai-model-tree-item { text-align: left; }
955
+ .vgai-operation-card {
956
+ display: block;
957
+ width: 100%;
958
+ margin-top: 10px;
959
+ padding: 10px;
960
+ border: var(--vgai-stroke-resting) solid var(--vgai-boundary-default);
961
+ border-radius: var(--vgai-radius-md);
962
+ background: var(--vgai-surface-panel);
963
+ text-align: left;
964
+ }
965
+
966
+ .vgai-resize-handle {
967
+ position: relative;
968
+ z-index: var(--vgai-z-overlay-low);
969
+ flex: 0 0 5px;
970
+ background: transparent;
971
+ touch-action: none;
972
+ }
973
+ .vgai-resize-handle[data-orientation='vertical'] { cursor: col-resize; }
974
+ .vgai-resize-handle[data-orientation='horizontal'] { cursor: row-resize; }
975
+ .vgai-resize-handle::before {
976
+ position: absolute;
977
+ background: var(--vgai-boundary-default);
978
+ content: '';
979
+ transition: background-color 80ms ease, transform 80ms ease;
980
+ }
981
+ .vgai-resize-handle[data-orientation='vertical']::before { inset: 0 auto 0 2px; width: 1px; }
982
+ .vgai-resize-handle[data-orientation='horizontal']::before { inset: 2px 0 auto; height: 1px; }
983
+ .vgai-resize-handle:hover::before,
984
+ .vgai-resize-handle:focus-visible::before { background: var(--vgai-accent); }
985
+ .vgai-resize-handle[data-orientation='vertical']:hover::before,
986
+ .vgai-resize-handle[data-orientation='vertical']:focus-visible::before { transform: scaleX(2); }
987
+ .vgai-resize-handle[data-orientation='horizontal']:hover::before,
988
+ .vgai-resize-handle[data-orientation='horizontal']:focus-visible::before { transform: scaleY(2); }
989
+
990
+ /* ---------------------------------------------------------------------- */
991
+ /* Scrollbar policy (closes C-12, root cause of L-8/L-19) — REPLACES the */
992
+ /* old global *::-webkit-scrollbar{display:none} suppression. Thin, dark, */
993
+ /* themed; visible only where content actually overflows. */
994
+ /* ---------------------------------------------------------------------- */
995
+
996
+ .${EDITOR_THEME_CLASS},
997
+ .${EDITOR_THEME_CLASS} * {
998
+ scrollbar-width: thin;
999
+ scrollbar-color: var(--vgai-bg-3) transparent;
1000
+ }
1001
+ .${EDITOR_THEME_CLASS}::-webkit-scrollbar,
1002
+ .${EDITOR_THEME_CLASS} *::-webkit-scrollbar {
1003
+ width: 9px;
1004
+ height: 9px;
1005
+ }
1006
+ .${EDITOR_THEME_CLASS}::-webkit-scrollbar-track,
1007
+ .${EDITOR_THEME_CLASS} *::-webkit-scrollbar-track {
1008
+ background: transparent;
1009
+ }
1010
+ .${EDITOR_THEME_CLASS}::-webkit-scrollbar-thumb,
1011
+ .${EDITOR_THEME_CLASS} *::-webkit-scrollbar-thumb {
1012
+ background-color: var(--vgai-bg-3);
1013
+ border-radius: 999px;
1014
+ border: 2px solid var(--vgai-bg-1);
1015
+ background-clip: padding-box;
1016
+ }
1017
+ .${EDITOR_THEME_CLASS}::-webkit-scrollbar-thumb:hover,
1018
+ .${EDITOR_THEME_CLASS} *::-webkit-scrollbar-thumb:hover {
1019
+ background-color: var(--vgai-border-2);
1020
+ }
1021
+ .${EDITOR_THEME_CLASS}::-webkit-scrollbar-corner,
1022
+ .${EDITOR_THEME_CLASS} *::-webkit-scrollbar-corner {
1023
+ background: transparent;
1024
+ }
1025
+
1026
+ /* ---------------------------------------------------------------------- */
1027
+ /* Keyframes — keep editor-spin as-is; add the missing blink keyframe */
1028
+ /* (closes C-9, referenced by BuildPanel.tsx:325's build-log cursor). */
1029
+ /* ---------------------------------------------------------------------- */
1030
+
1031
+ @keyframes editor-spin { to { transform: rotate(360deg); } }
1032
+ @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
1033
+ `;
1034
+ }
1035
+
1036
+ /**
1037
+ * Injects the editor theme `<style>` tag into `document.head` exactly once
1038
+ * (idempotent — safe to call from every SPA entry that mounts editor chrome
1039
+ * without risking a duplicate tag on remount/HMR). No-ops outside a DOM
1040
+ * environment (SSR/node import safety).
1041
+ */
1042
+ export function ensureEditorTheme(): void {
1043
+ if (typeof document === 'undefined') return;
1044
+ if (document.getElementById(STYLE_TAG_ID)) return;
1045
+ const styleEl = document.createElement('style');
1046
+ styleEl.id = STYLE_TAG_ID;
1047
+ styleEl.textContent = buildCss();
1048
+ document.head.appendChild(styleEl);
1049
+ }