@dailies-studio/shot-editor 0.1.0 → 0.2.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 (432) hide show
  1. package/dist/.vite/manifest.json +382 -0
  2. package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
  3. package/dist/assets/AgentPanel-DJEphah0.css +1 -0
  4. package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
  5. package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
  6. package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
  7. package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
  8. package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
  9. package/dist/assets/CurvePane-BjFVabKX.css +1 -0
  10. package/dist/assets/CurvePane-R22WzllJ.js +1 -0
  11. package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
  12. package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
  13. package/dist/assets/FontPicker-v0IOIArM.css +1 -0
  14. package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
  15. package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
  16. package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
  17. package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
  18. package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
  19. package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
  20. package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
  21. package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
  22. package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
  23. package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
  24. package/dist/assets/SoundMode-BmcZru3i.js +3 -0
  25. package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
  26. package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
  27. package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
  28. package/dist/assets/board-B88EPuLO.css +1 -0
  29. package/dist/assets/board-CL-he7SL.js +3 -0
  30. package/dist/assets/components-0oOSPN0l.js +1 -0
  31. package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
  32. package/dist/assets/googleFonts-BNon6M7X.js +1 -0
  33. package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
  34. package/dist/assets/index-4F5NQmI8.css +1 -0
  35. package/dist/assets/index-BGHQGV5z.js +117 -0
  36. package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  37. package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  38. package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  39. package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  40. package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  41. package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  42. package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  43. package/dist/assets/libraryModel-CpIwfFha.js +1 -0
  44. package/dist/assets/lucide-6iK64tTB.js +9319 -0
  45. package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
  46. package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
  47. package/dist/assets/webmcp-BsB9gxWC.js +2 -0
  48. package/dist/index.html +34 -3
  49. package/package.json +12 -9
  50. package/src/addFamilies.ts +66 -0
  51. package/src/api.ts +1631 -55
  52. package/src/app/App.tsx +977 -198
  53. package/src/app/lazyPanel.tsx +137 -0
  54. package/src/app/lazySurfaces.tsx +203 -0
  55. package/src/audio/index.tsx +41 -10
  56. package/src/audio/meter.ts +485 -0
  57. package/src/audio/meterMath.ts +273 -0
  58. package/src/audio/meterStore.ts +155 -0
  59. package/src/audio/offlineMix.ts +289 -0
  60. package/src/audio/preview.ts +928 -118
  61. package/src/bridge.ts +15 -5
  62. package/src/bridgeTypes.ts +1611 -36
  63. package/src/channels.ts +17 -32
  64. package/src/fonts/googleFonts.ts +4 -0
  65. package/src/hostApi.ts +174 -0
  66. package/src/icons.tsx +770 -0
  67. package/src/layerWords.ts +61 -0
  68. package/src/main.tsx +56 -4
  69. package/src/panels/ResizeHandle.tsx +33 -43
  70. package/src/panels/agent/AgentDots.tsx +36 -0
  71. package/src/panels/agent/AgentPanel.tsx +119 -43
  72. package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
  73. package/src/panels/agent/agent.css +113 -97
  74. package/src/panels/agent/agentGate.ts +35 -0
  75. package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
  76. package/src/panels/code/CodeStudio.tsx +373 -0
  77. package/src/panels/code/FileTree.tsx +265 -0
  78. package/src/panels/code/codeBufferGuard.ts +52 -0
  79. package/src/panels/code/codeParts.tsx +321 -0
  80. package/src/panels/comments/CommentComposer.tsx +239 -0
  81. package/src/panels/comments/CommentThread.tsx +346 -0
  82. package/src/panels/comments/CommentsPanel.tsx +336 -0
  83. package/src/panels/comments/InboxButton.tsx +131 -0
  84. package/src/panels/comments/MentionMenu.tsx +98 -0
  85. package/src/panels/comments/parts.tsx +171 -0
  86. package/src/panels/export/ExportDialog.tsx +919 -96
  87. package/src/panels/export/ExportScrim.tsx +57 -0
  88. package/src/panels/files/AssetsTab.tsx +656 -0
  89. package/src/panels/files/FilePanel.tsx +1466 -216
  90. package/src/panels/files/LayerMarks.tsx +40 -0
  91. package/src/panels/files/LeftColumn.tsx +37 -0
  92. package/src/panels/files/McpSection.tsx +690 -47
  93. package/src/panels/files/MissingAssetsNotice.tsx +60 -0
  94. package/src/panels/files/assetDrag.ts +79 -0
  95. package/src/panels/files/resourceParts.tsx +255 -0
  96. package/src/panels/fonts/FontPicker.tsx +762 -0
  97. package/src/panels/fonts/faceCache.ts +207 -0
  98. package/src/panels/fonts/fontPicker.css +271 -0
  99. package/src/panels/fonts/pickerModel.ts +265 -0
  100. package/src/panels/fonts/pickerRequest.ts +46 -0
  101. package/src/panels/header/AccountAvatar.tsx +76 -0
  102. package/src/panels/header/AgentChip.tsx +77 -0
  103. package/src/panels/header/AppMenu.tsx +213 -0
  104. package/src/panels/header/Header.tsx +564 -84
  105. package/src/panels/header/HistoryControls.tsx +31 -5
  106. package/src/panels/header/PresenceStack.tsx +329 -0
  107. package/src/panels/header/ProjectTitle.tsx +232 -0
  108. package/src/panels/header/ShareButton.tsx +59 -0
  109. package/src/panels/header/StatusBadges.tsx +358 -27
  110. package/src/panels/header/SyncDeletedDialog.tsx +88 -0
  111. package/src/panels/header/ZoomControls.tsx +46 -15
  112. package/src/panels/header/agentHandoff.ts +52 -0
  113. package/src/panels/header/leave.ts +26 -0
  114. package/src/panels/help/HelpSection.tsx +189 -163
  115. package/src/panels/insert/InsertDrawer.tsx +723 -0
  116. package/src/panels/insert/iconSet.ts +109 -0
  117. package/src/panels/inspector/ExposeDot.tsx +117 -0
  118. package/src/panels/inspector/FramingRows.tsx +314 -44
  119. package/src/panels/inspector/InspectorFooter.tsx +91 -0
  120. package/src/panels/inspector/InspectorHead.tsx +425 -0
  121. package/src/panels/inspector/InspectorPanel.tsx +408 -124
  122. package/src/panels/inspector/KeyframeDot.tsx +373 -0
  123. package/src/panels/inspector/KeyframeSection.tsx +257 -0
  124. package/src/panels/inspector/MarkerSection.tsx +55 -11
  125. package/src/panels/inspector/ParamRow.tsx +84 -53
  126. package/src/panels/inspector/RightColumn.tsx +152 -0
  127. package/src/panels/inspector/TimeSection.tsx +866 -0
  128. package/src/panels/inspector/animate/EaseControl.tsx +244 -0
  129. package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
  130. package/src/panels/inspector/animate/ShotSection.tsx +562 -48
  131. package/src/panels/inspector/design/AlignRow.tsx +95 -31
  132. package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
  133. package/src/panels/inspector/design/ClonerSection.tsx +323 -62
  134. package/src/panels/inspector/design/ComponentSection.tsx +50 -43
  135. package/src/panels/inspector/design/CornerSection.tsx +45 -14
  136. package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
  137. package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
  138. package/src/panels/inspector/design/DeviceSection.tsx +210 -0
  139. package/src/panels/inspector/design/FillSection.tsx +83 -51
  140. package/src/panels/inspector/design/FontField.tsx +196 -0
  141. package/src/panels/inspector/design/HtmlSection.tsx +23 -12
  142. package/src/panels/inspector/design/InstanceSection.tsx +373 -154
  143. package/src/panels/inspector/design/MaskSection.tsx +84 -0
  144. package/src/panels/inspector/design/MaterialSection.tsx +177 -0
  145. package/src/panels/inspector/design/MediaSection.tsx +273 -120
  146. package/src/panels/inspector/design/MeshSection.tsx +910 -82
  147. package/src/panels/inspector/design/PaintRows.tsx +550 -0
  148. package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
  149. package/src/panels/inspector/design/ShadowSection.tsx +221 -48
  150. package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
  151. package/src/panels/inspector/design/StrokeSection.tsx +228 -43
  152. package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
  153. package/src/panels/inspector/design/TransformSection.tsx +244 -50
  154. package/src/panels/inspector/design/TypographySection.tsx +679 -110
  155. package/src/panels/inspector/layout.ts +295 -0
  156. package/src/panels/inspector/propValue.ts +199 -0
  157. package/src/panels/inspector/scene/CameraSection.tsx +232 -22
  158. package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
  159. package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
  160. package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
  161. package/src/panels/inspector/scene/SceneSection.tsx +219 -44
  162. package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
  163. package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
  164. package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
  165. package/src/panels/inspector/timeModel.ts +190 -0
  166. package/src/panels/inspector/useDocWrite.ts +438 -146
  167. package/src/panels/library/LibraryBrowser.tsx +435 -0
  168. package/src/panels/library/LibraryGrid.tsx +190 -0
  169. package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
  170. package/src/panels/library/LibraryRail.tsx +84 -0
  171. package/src/panels/library/LibrarySoundPanel.tsx +293 -0
  172. package/src/panels/library/SoundHistory.tsx +245 -0
  173. package/src/panels/library/StockSounds.tsx +390 -0
  174. package/src/panels/library/libraryModel.ts +147 -0
  175. package/src/panels/library/stockSearch.ts +77 -0
  176. package/src/panels/maskMarks.tsx +117 -0
  177. package/src/panels/material/MaterialCommentNode.tsx +54 -0
  178. package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
  179. package/src/panels/material/MaterialGraphMenu.tsx +45 -0
  180. package/src/panels/material/MaterialGroupNode.tsx +56 -0
  181. package/src/panels/material/MaterialLibrary.tsx +253 -0
  182. package/src/panels/material/MaterialNode.tsx +453 -0
  183. package/src/panels/material/MaterialNodePalette.tsx +349 -0
  184. package/src/panels/material/MaterialParameterControls.tsx +525 -0
  185. package/src/panels/material/MaterialRerouteNode.tsx +42 -0
  186. package/src/panels/material/MaterialWorkspace.tsx +501 -0
  187. package/src/panels/material/NodePreview.tsx +70 -0
  188. package/src/panels/material/flowModel.ts +441 -0
  189. package/src/panels/material/parameterValues.ts +231 -0
  190. package/src/panels/material/previewScheduler.ts +235 -0
  191. package/src/panels/material/reactFlow.css +6 -0
  192. package/src/panels/material/socketGlyph.ts +85 -0
  193. package/src/panels/material/viewportMemory.ts +58 -0
  194. package/src/panels/preferences/PreferencesDialog.tsx +215 -0
  195. package/src/panels/share/ShareComponentDialog.tsx +247 -0
  196. package/src/panels/stage/StageMenu.tsx +35 -5
  197. package/src/panels/stage/StagePanel.tsx +338 -23
  198. package/src/panels/stage/cellSlots.tsx +70 -0
  199. package/src/panels/storyboard/BoardCanvas.tsx +739 -0
  200. package/src/panels/storyboard/BoardCursors.tsx +158 -0
  201. package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
  202. package/src/panels/storyboard/BoardPlan.tsx +42 -0
  203. package/src/panels/storyboard/ComponentSheet.tsx +187 -0
  204. package/src/panels/storyboard/ComponentStage.tsx +235 -0
  205. package/src/panels/storyboard/MiniSketch.tsx +173 -0
  206. package/src/panels/storyboard/PartPicker.tsx +64 -0
  207. package/src/panels/storyboard/PlanPanel.tsx +617 -0
  208. package/src/panels/storyboard/ReferencePreview.tsx +217 -0
  209. package/src/panels/storyboard/ShotBrief.tsx +360 -0
  210. package/src/panels/storyboard/ShotCard.tsx +251 -0
  211. package/src/panels/storyboard/StagePreview.tsx +348 -0
  212. package/src/panels/storyboard/StillThumbs.tsx +162 -0
  213. package/src/panels/storyboard/StoryboardView.tsx +79 -0
  214. package/src/panels/storyboard/board.css +1065 -0
  215. package/src/panels/storyboard/board.ts +12 -0
  216. package/src/panels/storyboard/boardClipboard.ts +111 -0
  217. package/src/panels/storyboard/boardOrder.ts +68 -0
  218. package/src/panels/storyboard/boardRows.tsx +425 -0
  219. package/src/panels/storyboard/liveCap.ts +90 -0
  220. package/src/panels/storyboard/plan.css +295 -0
  221. package/src/panels/storyboard/posterCache.ts +133 -0
  222. package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
  223. package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
  224. package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
  225. package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
  226. package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
  227. package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
  228. package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
  229. package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
  230. package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
  231. package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
  232. package/src/panels/storyboard/shotboard/sketch.css +1392 -0
  233. package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
  234. package/src/panels/storyboard/storyboardDrop.ts +164 -0
  235. package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
  236. package/src/panels/studio/ComponentSidePanel.tsx +355 -0
  237. package/src/panels/studio/ComponentStudio.tsx +243 -0
  238. package/src/panels/studio/ComponentsHome.tsx +318 -0
  239. package/src/panels/studio/ComponentsPreview.tsx +179 -0
  240. package/src/panels/studio/EveryUse.tsx +244 -0
  241. package/src/panels/studio/ThisUsePanel.tsx +679 -0
  242. package/src/panels/studio/componentParts.tsx +341 -0
  243. package/src/panels/studio/components.ts +6 -0
  244. package/src/panels/studio/newCodeComponent.ts +66 -0
  245. package/src/panels/timeline/AudioFxButton.tsx +290 -0
  246. package/src/panels/timeline/AudioLane.tsx +674 -85
  247. package/src/panels/timeline/BlockRow.tsx +154 -85
  248. package/src/panels/timeline/ChannelRow.tsx +378 -129
  249. package/src/panels/timeline/CurvePane.tsx +508 -0
  250. package/src/panels/timeline/Filmstrip.tsx +361 -0
  251. package/src/panels/timeline/GenerateDrawer.tsx +407 -0
  252. package/src/panels/timeline/KeyStretch.tsx +115 -0
  253. package/src/panels/timeline/LifespanRow.tsx +730 -47
  254. package/src/panels/timeline/MarkerLane.tsx +46 -8
  255. package/src/panels/timeline/PlayButton.tsx +91 -0
  256. package/src/panels/timeline/PropertyPicker.tsx +254 -0
  257. package/src/panels/timeline/ShotRow.tsx +400 -0
  258. package/src/panels/timeline/SoundMode.tsx +1406 -0
  259. package/src/panels/timeline/TimelineDock.tsx +2338 -272
  260. package/src/panels/timeline/TransportVolume.tsx +163 -0
  261. package/src/panels/timeline/beatRuler.ts +74 -0
  262. package/src/panels/timeline/curveModel.ts +500 -0
  263. package/src/panels/timeline/duckUnderVoice.ts +68 -0
  264. package/src/panels/timeline/keyframeMenu.ts +138 -0
  265. package/src/panels/timeline/labelWidth.ts +49 -0
  266. package/src/panels/timeline/marquee.ts +155 -0
  267. package/src/panels/timeline/model.ts +1860 -199
  268. package/src/panels/timeline/snap.ts +125 -43
  269. package/src/panels/timeline/staggerPreview.tsx +92 -0
  270. package/src/panels/timeline/takeMeasure.ts +72 -0
  271. package/src/panels/timeline/useLive.ts +48 -0
  272. package/src/panels/timeline/viewport.ts +234 -0
  273. package/src/panels/toolbar/BackChip.tsx +116 -0
  274. package/src/panels/toolbar/CameraViewBar.tsx +118 -49
  275. package/src/panels/toolbar/CanvasBar.tsx +117 -0
  276. package/src/panels/toolbar/InsertButton.tsx +38 -0
  277. package/src/panels/toolbar/IsolationTrail.tsx +156 -0
  278. package/src/panels/toolbar/PanelToggles.tsx +86 -0
  279. package/src/panels/toolbar/ShadingBar.tsx +119 -26
  280. package/src/panels/toolbar/ToolDockBar.tsx +329 -80
  281. package/src/panels/toolbar/ToolFooter.tsx +102 -0
  282. package/src/panels/toolbar/ViewModeBar.tsx +247 -38
  283. package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
  284. package/src/panels/toolbar/useAddRows.tsx +326 -0
  285. package/src/panels/toolbar/useDismiss.ts +122 -0
  286. package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
  287. package/src/panels/versions/versionModel.ts +103 -0
  288. package/src/panels/virtualWindow.ts +271 -0
  289. package/src/shotTokens.css +151 -60
  290. package/src/stage/FrustumGizmo.tsx +504 -84
  291. package/src/stage/GridPlane.tsx +225 -16
  292. package/src/stage/NodePreviews.tsx +628 -0
  293. package/src/stage/PerfHud.tsx +437 -47
  294. package/src/stage/SplitRenderer.tsx +816 -169
  295. package/src/stage/StageApp.tsx +4274 -486
  296. package/src/stage/StageRootBoundary.tsx +114 -0
  297. package/src/stage/StageTools.tsx +651 -151
  298. package/src/stage/TransformGizmo.tsx +696 -0
  299. package/src/stage/adaptivePresentation.ts +145 -0
  300. package/src/stage/bridgeClient.ts +2522 -41
  301. package/src/stage/exportWorker.ts +9 -0
  302. package/src/stage/feed.ts +305 -14
  303. package/src/stage/fontPreview.ts +176 -0
  304. package/src/stage/frustumGeometry.ts +319 -1
  305. package/src/stage/furnitureTokens.ts +33 -0
  306. package/src/stage/gizmoMath.ts +508 -16
  307. package/src/stage/gpuTimer.ts +276 -0
  308. package/src/stage/instanceModules.ts +194 -33
  309. package/src/stage/interactions/move.ts +24 -5
  310. package/src/stage/isolation.ts +291 -33
  311. package/src/stage/jsSelfProfiler.ts +325 -0
  312. package/src/stage/main.tsx +116 -16
  313. package/src/stage/modalState.ts +222 -23
  314. package/src/stage/moduleEpoch.ts +60 -0
  315. package/src/stage/motionPathStage.ts +279 -0
  316. package/src/stage/motionPreview.ts +74 -0
  317. package/src/stage/overlays/Overlays.tsx +1112 -159
  318. package/src/stage/overlays/Rulers.tsx +495 -0
  319. package/src/stage/panes.ts +159 -10
  320. package/src/stage/project.ts +68 -3
  321. package/src/stage/renderScaleController.ts +730 -0
  322. package/src/stage/rulers.ts +129 -0
  323. package/src/stage/sceneExtent.ts +75 -0
  324. package/src/stage/shading.ts +20 -0
  325. package/src/stage/splineStage.ts +632 -0
  326. package/src/stage/stagePerformanceTelemetry.ts +717 -0
  327. package/src/stage/stageTheme.ts +36 -0
  328. package/src/stage/stageWarmup.ts +11 -0
  329. package/src/stage/textAutoSize.ts +124 -0
  330. package/src/stage/tier1Export.ts +641 -0
  331. package/src/stage/tokenColor.ts +14 -9
  332. package/src/stage/view.ts +56 -9
  333. package/src/stage/workingView.ts +277 -33
  334. package/src/state/accountPrefs.ts +261 -0
  335. package/src/state/agentActions.ts +173 -15
  336. package/src/state/agentActivity.ts +198 -0
  337. package/src/state/agentQuestion.ts +239 -0
  338. package/src/state/bootOpen.ts +42 -0
  339. package/src/state/cameraVerbs.ts +139 -0
  340. package/src/state/clientId.ts +6 -1
  341. package/src/state/comments.ts +1099 -0
  342. package/src/state/context.tsx +19 -1
  343. package/src/state/editorPrefs.ts +220 -0
  344. package/src/state/errorReports.ts +121 -0
  345. package/src/state/fieldWrite.ts +161 -0
  346. package/src/state/fontRecents.ts +70 -0
  347. package/src/state/fonts.ts +656 -0
  348. package/src/state/graphClipboard.ts +414 -0
  349. package/src/state/imageThumbs.ts +216 -0
  350. package/src/state/insert.ts +444 -67
  351. package/src/state/isolationTrail.ts +92 -0
  352. package/src/state/keyMoves.ts +134 -0
  353. package/src/state/keyframeClipboard.ts +177 -0
  354. package/src/state/keymap.ts +1153 -117
  355. package/src/state/layoutPrefs.ts +272 -0
  356. package/src/state/layouts.ts +205 -0
  357. package/src/state/measureMedia.ts +167 -0
  358. package/src/state/menu.ts +2341 -28
  359. package/src/state/motionStamp.ts +7 -0
  360. package/src/state/panelSize.ts +375 -5
  361. package/src/state/pendingChanges.ts +119 -0
  362. package/src/state/playHold.ts +78 -0
  363. package/src/state/playbackPreparation.ts +562 -0
  364. package/src/state/posterCapture.ts +242 -0
  365. package/src/state/presence.ts +254 -0
  366. package/src/state/projectComponents.ts +160 -0
  367. package/src/state/renderEvents.ts +298 -18
  368. package/src/state/runtimeErrors.ts +46 -0
  369. package/src/state/selection.ts +12 -0
  370. package/src/state/shortcuts.ts +1606 -0
  371. package/src/state/sketchGuide.ts +51 -0
  372. package/src/state/splineRefs.ts +87 -0
  373. package/src/state/stageHealth.ts +259 -0
  374. package/src/state/stageWatchdog.ts +47 -0
  375. package/src/state/stillStage.ts +330 -0
  376. package/src/state/stillThumbs.ts +474 -0
  377. package/src/state/store.ts +23591 -2982
  378. package/src/state/storyboardModel.ts +528 -0
  379. package/src/state/sync.ts +1257 -0
  380. package/src/state/syncCache.ts +159 -0
  381. package/src/state/triangles.ts +13 -0
  382. package/src/state/types.ts +1698 -55
  383. package/src/state/unsavedGuard.ts +49 -0
  384. package/src/state/viewMode.ts +200 -0
  385. package/src/state/webmcp.ts +1128 -0
  386. package/src/state/workspace.ts +1147 -0
  387. package/src/styles/assets-tab.css +304 -0
  388. package/src/styles/canvas.css +545 -0
  389. package/src/styles/comments.css +1435 -0
  390. package/src/styles/controls.css +162 -0
  391. package/src/styles/dialogs.css +390 -0
  392. package/src/styles/insert-drawer.css +586 -0
  393. package/src/styles/inspector-board.css +207 -0
  394. package/src/styles/inspector-object.css +486 -0
  395. package/src/styles/inspector-shot.css +252 -0
  396. package/src/styles/inspector.css +360 -0
  397. package/src/styles/left-column.css +1628 -0
  398. package/src/styles/library-preview.css +575 -0
  399. package/src/styles/library.css +512 -0
  400. package/src/styles/modes/code.css +569 -0
  401. package/src/styles/modes/component.css +1561 -0
  402. package/src/styles/modes/material.css +1201 -0
  403. package/src/styles/modes/storyboard.css +518 -0
  404. package/src/styles/share-component.css +49 -0
  405. package/src/styles/shell.css +653 -0
  406. package/src/styles/shot-brief.css +360 -0
  407. package/src/styles/states.css +76 -0
  408. package/src/styles/sync.css +380 -0
  409. package/src/styles/timeline-graph.css +384 -0
  410. package/src/styles/timeline-meters.css +89 -0
  411. package/src/styles/timeline-rows.css +1959 -0
  412. package/src/styles/timeline-sound.css +1003 -0
  413. package/src/styles/timeline.css +754 -0
  414. package/src/styles/tool-footer.css +525 -0
  415. package/src/styles/topbar.css +886 -0
  416. package/src/styles/versions.css +262 -0
  417. package/src/styles.css +72 -2921
  418. package/src/tools.ts +108 -23
  419. package/dist/assets/index-B7notge7.css +0 -1
  420. package/dist/assets/index-BBE6Ta9L.js +0 -52
  421. package/src/panels/files/icons.tsx +0 -118
  422. package/src/panels/header/DocSwitcher.tsx +0 -85
  423. package/src/panels/header/TransportBar.tsx +0 -86
  424. package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
  425. package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
  426. package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
  427. package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
  428. package/src/panels/inspector/animate/useBlocks.ts +0 -43
  429. package/src/panels/material/MaterialPicker.tsx +0 -172
  430. package/src/panels/timeline/SceneStrip.tsx +0 -145
  431. package/src/panels/toolbar/AddMenu.tsx +0 -230
  432. package/src/stage/MoveGizmo.tsx +0 -411
@@ -1,5 +1,19 @@
1
- // The left rail's Manual: how the editor works, the tool table and the keymap,
2
- // rendered where a first-time author actually looks.
1
+ // The manual: the dialog the app menu's Help row opens.
2
+ //
3
+ // ── WHY A DIALOG AND NOT A PANEL SECTION ────────────────────────────────
4
+ //
5
+ // The left rail is the layer outliner. The manual is a five-line first-run
6
+ // guide, thirteen tool rows and fifty-six shortcut rows, and the full MCP guide is
7
+ // setup documentation. The Shot outliner now keeps only a compact MCP status
8
+ // and connection footer tied to the open Project. Parking the complete manual
9
+ // in the column the author reads to find a layer made that column harder to
10
+ // scan. A `<details>` made that cost one summary line at rest, which is one
11
+ // line more than a reference nobody has open deserves, and it read the whole
12
+ // manual into a 232px column when opened.
13
+ //
14
+ // The shared `Dialog` (packages/ui) is what the export dialog and the material
15
+ // picker already use, so Escape, the focus trap and `aria-modal` are answered
16
+ // once for the lane rather than three times.
3
17
  //
4
18
  // ── ONE LIST, PINNED BY A TEST ──────────────────────────────────────────
5
19
  //
@@ -10,181 +24,193 @@
10
24
  // walks every row through `resolveKey`. A binding change without a manual
11
25
  // edit is a red test, not a stale manual.
12
26
  //
13
- // No store, no context: this section is static prose over static tables,
14
- // which is what lets the test mount it bare. The agent connect steps moved to
15
- // the File tab's MCP section (McpSection.tsx), where an author actually looks.
27
+ // THE TABLE ITSELF MOVED to `state/shortcuts.ts` once the app menu became its
28
+ // second reader: a data table reached through a React component drags a Dialog
29
+ // into `state/menu.ts`, which is JSX-free on purpose. Re-exported here because
30
+ // this is where every caller already looks for it.
31
+ //
32
+ // No store, no context: the content is static prose over static tables, which
33
+ // is what lets the test mount it bare.
34
+ import { Dialog } from "@dailies-studio/ui";
35
+ import { McpSection } from "../files/McpSection.js";
16
36
  import { SHOT_TOOLS, specOf } from "../../tools.js";
17
- import type { KeyAction, KeyEventLike } from "../../state/keymap.js";
37
+ import { layoutSpec } from "../../state/layouts.js";
38
+ import { VIEW_MODE_SPECS } from "../../state/viewMode.js";
39
+ import {
40
+ MATERIAL_SHORTCUTS,
41
+ STORYBOARD_SHORTCUTS,
42
+ SHORTCUTS,
43
+ SHORTCUT_GROUPS,
44
+ comboOf,
45
+ formatCombo,
46
+ toolKey,
47
+ } from "../../state/shortcuts.js";
48
+ import type { ShortcutGroup } from "../../state/shortcuts.js";
18
49
 
19
- export interface ShortcutRow {
20
- /** What the manual shows, house glyph style (⌘ ⇧ ⌥ — ⌘ is Ctrl on Windows). */
21
- combo: string;
22
- does: string;
23
- group: "View" | "Working view" | "Edit" | "Animate & camera";
24
- /** The event this combo produces, so the test can ask the keymap itself. */
25
- probe: KeyEventLike;
26
- /** Arrows answer differently with a selection; everything else omits it. */
27
- hasSelection?: boolean;
28
- /** The pen's two rows answer differently with a path open, and ONLY with one
29
- * open — Escape means deselect the rest of the time, which is why the
30
- * context carries "holds points" and not "the pen tool is armed". */
31
- penActive?: boolean;
32
- /** Escape's third meaning: leave one level of isolation. It only answers
33
- * that with NOTHING selected, so the row carries the bit and the test
34
- * probes with `hasSelection` false. */
35
- isolation?: boolean;
36
- /** The modal starters (G/R/S) answer only with the cursor over the working
37
- * pane — the same letters arm tools everywhere else, and both readings
38
- * have rows. */
39
- workingPane?: boolean;
40
- /** The axis and terminator rows answer only while a transform is LIVE. */
41
- transformModal?: boolean;
42
- /** The action `resolveKey(probe)` must return. */
43
- action: KeyAction["kind"];
44
- }
50
+ export { MATERIAL_SHORTCUTS, SHORTCUTS, STORYBOARD_SHORTCUTS };
51
+ export type { ShortcutRow } from "../../state/shortcuts.js";
45
52
 
46
- const probe = (
47
- key: string,
48
- m: { shift?: boolean; ctrl?: boolean; alt?: boolean; code?: string } = {},
49
- ): KeyEventLike => ({
50
- key,
51
- shiftKey: m.shift === true,
52
- altKey: m.alt === true,
53
- ctrlKey: m.ctrl === true,
54
- metaKey: false,
55
- ...(m.code === undefined ? {} : { code: m.code }),
56
- });
53
+ /**
54
+ * The material graph's keys, listed apart from the four groups below.
55
+ *
56
+ * They live in their own table because they answer a DIFFERENT question of the
57
+ * keymap: every row here resolves with `materialGraph: true`, meaning the key
58
+ * landed inside the node canvas, and the same combo means something else
59
+ * everywhere else (P is a tool, ⌘G groups layers). Folding them into
60
+ * `SHORTCUTS` would make that table's own test walk them through the wrong
61
+ * context and assert the wrong answer.
62
+ *
63
+ * Typed as a `ShortcutGroup` rather than left a bare literal: a section heading
64
+ * that no row can carry is a heading over an empty list.
65
+ */
66
+ const MATERIAL_GROUP: ShortcutGroup = "Material nodes";
57
67
 
58
- export const SHORTCUTS: readonly ShortcutRow[] = [
59
- { group: "View", combo: "Space", does: "Play / pause", probe: probe(" "), action: "playToggle" },
60
- { group: "View", combo: "← →", does: "Step one frame (nothing selected)", probe: probe("ArrowRight"), action: "step" },
61
- { group: "View", combo: "1 / 2 / 3", does: "Working / split / camera view", probe: probe("1"), action: "stageLayout" },
62
- { group: "View", combo: "[", does: "Hide / show the left panel", probe: probe("["), action: "togglePanel" },
63
- { group: "View", combo: "]", does: "Hide / show the right panel", probe: probe("]"), action: "togglePanel" },
64
- { group: "View", combo: ".", does: "Hide every panel", probe: probe("."), action: "togglePanel" },
65
- { group: "View", combo: "\\", does: "Fit the timeline", probe: probe("\\"), action: "fitTimeline" },
66
- { group: "View", combo: "⌘+ / ⌘−", does: "Zoom in / out", probe: probe("=", { ctrl: true }), action: "zoom" },
67
- { group: "View", combo: "⌘0", does: "Zoom to 100%", probe: probe("0", { ctrl: true }), action: "zoomReset" },
68
- { group: "View", combo: "Home", does: "Fit the active pane", probe: probe("Home"), action: "fit" },
69
- { group: "View", combo: "⇧C", does: "Fit the active pane (Blender's frame all)", probe: probe("c", { shift: true }), action: "fit" },
70
- { group: "View", combo: "Z", does: "Cycle working-pane shading (solid / wire / material / rendered)", probe: probe("z"), action: "shadingCycle" },
71
- { group: "View", combo: "⇧Z", does: "Wireframe on / off", probe: probe("z", { shift: true }), action: "wireframeToggle" },
68
+ /** The board's keys, apart for the same reason: every row resolves only with
69
+ * `storyboard: true`, and Delete means "remove a layer" outside it. */
70
+ const STORYBOARD_GROUP: ShortcutGroup = "Storyboard";
72
71
 
73
- { group: "Working view", combo: "G", does: "Grab the selection — move it with the mouse, click to place", probe: probe("g"), workingPane: true, hasSelection: true, action: "modalStart" },
74
- { group: "Working view", combo: "R", does: "Rotate the selection (roll)", probe: probe("r"), workingPane: true, hasSelection: true, action: "modalStart" },
75
- { group: "Working view", combo: "S", does: "Scale the selection", probe: probe("s"), workingPane: true, hasSelection: true, action: "modalStart" },
76
- { group: "Working view", combo: "G / S", does: "Nothing selected: move / zoom the camera", probe: probe("g"), workingPane: true, action: "modalStart" },
77
- { group: "Working view", combo: "X / Y / Z", does: "Constrain the transform to an axis (again clears; G+Z = depth)", probe: probe("x"), transformModal: true, action: "modalAxis" },
78
- { group: "Working view", combo: "0-9", does: "Type an exact value: G X 200 Enter", probe: probe("2"), transformModal: true, action: "modalNumber" },
79
- // `hasSelection` because R is the one that needs it: the CAMERA has no modal
80
- // roll, so switching to rotate on a camera transform would arm one that could
81
- // never emit.
82
- { group: "Working view", combo: "G / R / S", does: "Switch transform without leaving the gesture", probe: probe("r"), transformModal: true, hasSelection: true, action: "modalStart" },
83
- { group: "Working view", combo: "Enter", does: "Confirm the transform (or click)", probe: probe("Enter"), transformModal: true, action: "modalConfirm" },
84
- { group: "Working view", combo: "Esc", does: "Cancel the transform (or right-click)", probe: probe("Escape"), transformModal: true, action: "modalCancel" },
85
- { group: "Working view", combo: "Num1 / 3 / 7", does: "Front / right / top view (⌘ = the opposite)", probe: probe("1", { code: "Numpad1" }), action: "workingViewPreset" },
86
- { group: "Working view", combo: "Num0", does: "Camera view, and back again", probe: probe("0", { code: "Numpad0" }), action: "stageLayout" },
87
- { group: "Working view", combo: "Num.", does: "Frame the selection", probe: probe(".", { code: "NumpadDecimal" }), action: "fitSelection" },
88
- { group: "Working view", combo: "Num2 / 4 / 6 / 8", does: "Orbit 15°; Num9 looks from the opposite side", probe: probe("4", { code: "Numpad4" }), action: "orbitStep" },
89
- { group: "Working view", combo: "Num5", does: "Orthographic / perspective", probe: probe("5", { code: "Numpad5" }), action: "toggleWorkingOrtho" },
90
- { group: "Working view", combo: "Num/", does: "Go inside the selection, and back out", probe: probe("/", { code: "NumpadDivide" }), action: "toggleIsolation" },
91
- { group: "Working view", combo: "Num+ / Num−", does: "Zoom the active pane", probe: probe("+", { code: "NumpadAdd" }), action: "zoom" },
72
+ /** The groups the main table prints, in the manual's own order: every one
73
+ * `state/shortcuts.ts` declares, less the two that own a table and a section
74
+ * of their own. Derived rather than re-listed, so a new group is one edit
75
+ * there and not a second one here that nobody remembers to make. */
76
+ const GROUPS = SHORTCUT_GROUPS.filter(
77
+ (group) => group !== MATERIAL_GROUP && group !== STORYBOARD_GROUP,
78
+ );
92
79
 
93
- { group: "Edit", combo: "Arrows", does: "Nudge selection 1 px (⇧ = 10)", probe: probe("ArrowRight"), hasSelection: true, action: "nudge" },
94
- { group: "Edit", combo: "⌘Z", does: "Undo", probe: probe("z", { ctrl: true }), action: "undo" },
95
- { group: "Edit", combo: "⌘⇧Z", does: "Redo", probe: probe("z", { ctrl: true, shift: true }), action: "redo" },
96
- { group: "Edit", combo: "⌘S", does: "Save", probe: probe("s", { ctrl: true }), action: "save" },
97
- { group: "Edit", combo: "⌘D", does: "Duplicate", probe: probe("d", { ctrl: true }), action: "duplicate" },
98
- { group: "Edit", combo: "⌘A / A", does: "Select all, in the scope you are in", probe: probe("a", { ctrl: true }), action: "selectAll" },
99
- { group: "Edit", combo: "⌥A", does: "Deselect all", probe: probe("a", { alt: true }), action: "deselect" },
100
- { group: "Edit", combo: "B", does: "Box select with the next drag", probe: probe("b"), action: "boxSelect" },
101
- { group: "Edit", combo: "⇧D", does: "Duplicate", probe: probe("d", { shift: true }), action: "duplicate" },
102
- { group: "Edit", combo: "Esc", does: "Deselect", probe: probe("Escape"), action: "deselect" },
103
- { group: "Edit", combo: "Del", does: "Delete selection", probe: probe("Delete"), action: "deleteSelection" },
104
- { group: "Edit", combo: "⌘G", does: "Group", probe: probe("g", { ctrl: true }), action: "group" },
105
- { group: "Edit", combo: "⌘⇧G", does: "Ungroup", probe: probe("g", { ctrl: true, shift: true }), action: "ungroup" },
106
- { group: "Edit", combo: "⌥L", does: "Lock / unlock", probe: probe("l", { alt: true }), action: "toggleLock" },
107
- { group: "Edit", combo: "H", does: "Hide the selection", probe: probe("h"), action: "setHidden" },
108
- { group: "Edit", combo: "⇧H", does: "Hide everything else", probe: probe("h", { shift: true }), action: "setHidden" },
109
- { group: "Edit", combo: "⌥H", does: "Show everything again", probe: probe("h", { alt: true }), action: "setHidden" },
110
- { group: "Edit", combo: "⌥G / ⌥R", does: "Clear the position / the rotation", probe: probe("g", { alt: true }), action: "clearTransform" },
111
- { group: "Edit", combo: "Enter", does: "Edit inside the selection", probe: probe("Enter"), hasSelection: true, action: "enterIsolation" },
112
- { group: "Edit", combo: "Esc", does: "Come back out one level", probe: probe("Escape"), isolation: true, action: "exitIsolation" },
113
- { group: "Edit", combo: "Enter", does: "Finish the path you are drawing", probe: probe("Enter"), penActive: true, action: "penCommit" },
114
- { group: "Edit", combo: "Esc", does: "Throw away the path you are drawing", probe: probe("Escape"), penActive: true, action: "penAbandon" },
80
+ /** The three layouts by name and key, out of the one table the toolbar chips,
81
+ * the View menu and the refusal sentences all read. Renaming the third from
82
+ * "Frame" to "Camera" (founder order, 2026-09-05) left this manual teaching
83
+ * the withdrawn word for exactly as long as it took someone to read it,
84
+ * because prose was the one surface with nothing tying it to the control. */
85
+ const WORKING = layoutSpec("working");
86
+ const SPLIT = layoutSpec("split");
87
+ const CAMERA = layoutSpec("camera");
115
88
 
116
- { group: "Animate & camera", combo: "⇧A", does: "Animate mode — edits become blocks", probe: probe("a", { shift: true }), action: "animateToggle" },
117
- { group: "Animate & camera", combo: "M", does: "Drop a marker at the playhead", probe: probe("m"), action: "addMarker" },
118
- { group: "Animate & camera", combo: "⌥C", does: "Point the camera at the working view", probe: probe("c", { alt: true }), action: "alignCameraToView" },
119
- { group: "Animate & camera", combo: "⌘B", does: "Split layer at the playhead", probe: probe("b", { ctrl: true }), action: "splitAtPlayhead" },
120
- { group: "Animate & camera", combo: "⌘E", does: "Export video", probe: probe("e", { ctrl: true }), action: "openExport" },
121
- ];
89
+ /** The two words the switch shows, from the same table the control and the
90
+ * View menu read. The paragraph below taught "Video (4)" as a literal, which
91
+ * is a rebind away from being wrong in the one place an author looks first. */
92
+ const EDIT = VIEW_MODE_SPECS.edit;
93
+ const VIDEO = VIEW_MODE_SPECS.video;
122
94
 
123
- const GROUPS = ["View", "Working view", "Edit", "Animate & camera"] as const;
124
-
125
- /** The sentences a first session needs, in the order a session meets them.
126
- * Mouse gestures live HERE and not in the shortcut table below, because every
127
- * row of that table is walked through the real keymap by its test — a row for
128
- * a gesture no key produces would have to carry a fake event to pass. */
95
+ /** The first-run guide: the few sentences a first session needs, in the order
96
+ * it meets them. Everything else is in the key tables below. Mouse gestures
97
+ * live HERE and not in those tables, because every row there is walked
98
+ * through the real keymap by its test, and a gesture has no key to walk. */
129
99
  const BASICS: readonly string[] = [
130
- "Camera view: scroll to pan, ctrl+scroll to zoom at the pointer, space-drag to pan.",
131
- "Working view (1 / 2): drag empty space or middle-drag to orbit, scroll to dolly, space-drag or ⇧middle-drag to pan. Click a layer to select it, then G / R / S transform it Blender-style; the panels tuck away while you work.",
132
- "Working view aids: a ground grid under the frame that coarsens as you pull back, three coloured world axes (X red, Y green, Z blue) through the canvas centre, and an axis ball top-right — click an end to look down that axis.",
133
- "Right-click a layer, on the stage or in the outline, for duplicate, hide, lock, isolate, delete — and on a model, a material.",
134
- "Models: the outline shows each one's triangle count, and tints it once the scene gets heavy enough to feel it. Give a model a surface with right-click → Apply material; a toon model also grows a sun handle you can drag to aim its key.",
135
- "Double-click a layer to go INSIDE it: the working pane frames that subtree flat and head-on and everything else dims. Orbit, pan or dolly and the camera is yours; Home puts it back head-on. A blue bar over the pane says you are inside; Esc backs out one level, or click a crumb in the left panel.",
136
- "Drag arms (red/green/blue) sit on the selection, or on the CAMERA when nothing is selected — the same subject G and S pick. Z moves a layer in depth; on the camera it dollies.",
137
- "Header zoom, ⌘+ / ⌘− and ⇧C all act on the pane you last clicked. ⇧Z is the wireframe toggle.",
138
- "Draw: arm a tool in the top bar, then drag on the stage. Text takes a click.",
139
- "Animate: toggle ⇧A, then edit — the change becomes a block ending at the playhead.",
140
- "Camera: use the timeline's + shot button for a move, or in the working view (1) drag the yellow frustum's edge to pan, its apex to zoom, or its arms for one axis at a time.",
141
- "Audio: drop a file on the timeline's audio lane. Markers ride their clip.",
142
- "Everything exports exactly as previewed — same engine, same frames.",
100
+ `${EDIT.label} is where you build. ${VIDEO.label} (${VIDEO.key}) is the finished picture. Space plays it, and a click on anything brings ${EDIT.label} back.`,
101
+ `${EDIT.label} has three views: ${CAMERA.title} (${CAMERA.key}) is the shot's picture, where you draw. ${WORKING.title} (${WORKING.key}) is free to look around: drag to orbit, scroll to dolly. ${SPLIT.title} (${SPLIT.key}) is both.`,
102
+ "Draw: pick a tool in the footer under the picture (on the Storyboard, the rail beside the frame), then drag on the stage. Text takes a click, then type.",
103
+ "Double-click a layer to go inside it. Esc backs out. Right-click a layer for more.",
104
+ "Animate: turn on ⇧A, then change something. Edits write keyframes at the playhead.",
143
105
  ];
144
106
 
145
- export function HelpSection() {
107
+ /**
108
+ * The manual itself, CONTROLLED, and opened from ONE surface: the app menu's
109
+ * Help row (AppMenu owns the `open` bit).
110
+ *
111
+ * There used to be a second door, a "?" in the left column's foot. The Studio
112
+ * redesign dropped it: a 28px glyph over the foot's end was a second Help
113
+ * entry the founder questioned, and the foot itself is gone now. The menu row
114
+ * is reachable with no document open, which was the "?"'s whole reason to live
115
+ * in the column rather than in the Files panel.
116
+ *
117
+ * `Dialog` returns null while closed, so this copy of `McpSection` does not
118
+ * probe health until the author asks for Help. The top bar's Agent chip owns
119
+ * a separate Project-targeted copy.
120
+ */
121
+ export function HelpDialog(props: { open: boolean; onClose(): void }) {
122
+ const close = props.onClose;
146
123
  return (
147
- <details className="help-section" data-testid="help-section">
148
- <summary className="file-section-label help-summary">Manual</summary>
149
-
150
- <ul className="help-basics">
151
- {BASICS.map((line) => (
152
- <li key={line}>{line}</li>
153
- ))}
154
- </ul>
155
-
156
- <div className="file-section-label">Tools</div>
157
- <ul className="help-rows">
158
- {SHOT_TOOLS.map((tool) => {
159
- const spec = specOf(tool);
160
- return (
161
- <li key={tool} className="help-row">
162
- <span>{spec.label}</span>
163
- {spec.key !== null && (
164
- <kbd>{`${spec.shift === true ? "⇧" : ""}${spec.key.toUpperCase()}`}</kbd>
165
- )}
166
- </li>
167
- );
168
- })}
169
- </ul>
124
+ <Dialog
125
+ open={props.open}
126
+ title="Help"
127
+ // The shared dialog is a hard 320px, which is a confirm's width: the
128
+ // shortcut rows are a combo and a sentence on one line, and at 320
129
+ // every one of them wraps.
130
+ className="shot-help-dialog"
131
+ onClose={close}
132
+ actions={
133
+ <button type="button" className="btn" onClick={close}>
134
+ Close
135
+ </button>
136
+ }
137
+ >
138
+ <div className="help-manual" data-testid="help-manual">
139
+ <ul className="help-basics">
140
+ {/* In this machine's spelling, like every table row below: the
141
+ lines name keys in the house glyphs ("⇧1", "⇧A"). */}
142
+ {BASICS.map((line) => (
143
+ <li key={line}>{formatCombo(line)}</li>
144
+ ))}
145
+ </ul>
170
146
 
171
- {GROUPS.map((group) => (
172
- <div key={group}>
173
- <div className="file-section-label">{group}</div>
174
- <ul className="help-rows">
175
- {SHORTCUTS.filter((row) => row.group === group).map((row) => (
176
- // Keyed on the combo AND what it does: Esc and Enter each mean
177
- // three things now, depending on what is open, and every one of
178
- // them is a row.
179
- <li key={`${row.combo}:${row.does}`} className="help-row">
180
- <span>{row.does}</span>
181
- <kbd>{row.combo}</kbd>
147
+ <div className="file-section-label">Tools</div>
148
+ <ul className="help-rows">
149
+ {SHOT_TOOLS.map((tool) => {
150
+ const spec = specOf(tool);
151
+ return (
152
+ <li key={tool} className="help-row">
153
+ <span>{spec.label}</span>
154
+ {spec.key !== null && <kbd>{toolKey(tool)}</kbd>}
182
155
  </li>
183
- ))}
184
- </ul>
156
+ );
157
+ })}
158
+ </ul>
159
+
160
+ <div className="help-groups">
161
+ {GROUPS.map((group) => (
162
+ <div key={group}>
163
+ <div className="file-section-label">{group}</div>
164
+ <ul className="help-rows">
165
+ {SHORTCUTS.filter((row) => row.group === group).map((row) => (
166
+ // Keyed on the combo AND what it does: Esc and Enter each
167
+ // mean three things now, depending on what is open, and
168
+ // every one of them is a row.
169
+ <li key={`${row.combo}:${row.does}`} className="help-row">
170
+ <span>{row.does}</span>
171
+ <kbd>{comboOf(row)}</kbd>
172
+ </li>
173
+ ))}
174
+ </ul>
175
+ </div>
176
+ ))}
177
+ <div>
178
+ <div className="file-section-label">{MATERIAL_GROUP}</div>
179
+ <ul className="help-rows">
180
+ {MATERIAL_SHORTCUTS.map((row) => (
181
+ <li key={`${row.combo}:${row.does}`} className="help-row">
182
+ <span>{row.does}</span>
183
+ <kbd>{comboOf(row)}</kbd>
184
+ </li>
185
+ ))}
186
+ </ul>
187
+ </div>
188
+ <div>
189
+ <div className="file-section-label">{STORYBOARD_GROUP}</div>
190
+ <ul className="help-rows">
191
+ {STORYBOARD_SHORTCUTS.map((row) => (
192
+ <li key={`${row.combo}:${row.does}`} className="help-row">
193
+ <span>{row.does}</span>
194
+ <kbd>{comboOf(row)}</kbd>
195
+ </li>
196
+ ))}
197
+ </ul>
198
+ </div>
185
199
  </div>
186
- ))}
187
- <p className="help-note">⌘ is Ctrl on Windows and Linux.</p>
188
- </details>
200
+ {/* The "⌘ is Ctrl on Windows and Linux" footnote used to live here and
201
+ is gone on purpose: every row above is printed through
202
+ `comboOf`, so on Windows and Linux the table already says Ctrl.
203
+ A footnote translating a glyph the reader is not being shown is
204
+ worse than no footnote. */}
205
+ <p className="help-note">
206
+ The Material nodes keys act only inside the node canvas, and the
207
+ Storyboard keys only while the Storyboard is open.
208
+ </p>
209
+
210
+ {/* The general doorway, repeated from the Agent chip so setup stays
211
+ findable from Help. */}
212
+ <McpSection />
213
+ </div>
214
+ </Dialog>
189
215
  );
190
216
  }